233 lines
6.6 KiB
JavaScript
233 lines
6.6 KiB
JavaScript
import React from "react";
|
|
import { Tree, Empty, Button, Spin, Modal } from "antd";
|
|
import MainLayout from "../../../layout/MainLayout";
|
|
import styles from "./index.module.less";
|
|
import { batchDelete, renderTreeNodes, onDrop } from "./function.js";
|
|
import {
|
|
cacheBookmarkData,
|
|
getBookmarkList,
|
|
checkCacheStatus,
|
|
clearCache
|
|
} from "../../../util/cacheUtil";
|
|
import httpUtil from "../../../util/httpUtil";
|
|
import AddModal from "./AddModal";
|
|
import Search from "../../../components/Search";
|
|
|
|
import * as action from "../../../redux/action/BookmarkTreeOverview";
|
|
import { connect } from "react-redux";
|
|
|
|
const { confirm } = Modal;
|
|
|
|
function mapStateToProps(state) {
|
|
return state[action.DATA_NAME];
|
|
}
|
|
|
|
function mapDispatchToProps(dispatch) {
|
|
return {
|
|
refresh: () => dispatch(action.refresh()),
|
|
updateTreeData: treeData => dispatch(action.updateTreeData(treeData)),
|
|
setIsEdit: isEdit => dispatch(action.setIsEdit(isEdit)),
|
|
addNode: (item, e) => dispatch(action.addNode(item, e)),
|
|
editNode: (item, e) => dispatch(action.editNode(item, e)),
|
|
changeIsInit: value => dispatch(action.changeIsInit(value)),
|
|
changeCheckedKeys: (keys, nodes) =>
|
|
dispatch(action.changeCheckedKeys(keys, nodes)),
|
|
changeExpandedKeys: keys => dispatch(action.changeExpandedKeys(keys)),
|
|
changeCurrentClickItem: item =>
|
|
dispatch(action.changeCurrentClickItem(item)),
|
|
changeLoadedKeys: keys => dispatch(action.changeLoadedKeys(keys))
|
|
};
|
|
}
|
|
|
|
class OverView extends React.Component {
|
|
constructor(props) {
|
|
super(props);
|
|
this.state = {
|
|
//书签树节点是否显示loading
|
|
isLoading: false
|
|
};
|
|
}
|
|
|
|
async componentWillUnmount() {
|
|
if (this.state.timer != null) {
|
|
clearInterval(this.state.timer);
|
|
}
|
|
}
|
|
|
|
async componentWillMount() {
|
|
await httpUtil.get("/user/loginStatus");
|
|
this.state.timer = setInterval(this.checkCache.bind(this), 10000);
|
|
setTimeout(this.checkCache.bind(this), 5000);
|
|
this.props.refresh();
|
|
await cacheBookmarkData();
|
|
this.props.updateTreeData(getBookmarkList(""));
|
|
this.props.changeIsInit(true);
|
|
}
|
|
|
|
async checkCache() {
|
|
//检查缓存情况
|
|
if (this.state.showDialog) {
|
|
return;
|
|
}
|
|
let _this = this;
|
|
if (!(await checkCacheStatus())) {
|
|
this.state.showDialog = true;
|
|
confirm({
|
|
title: "缓存过期",
|
|
content: "书签数据有更新,是否立即刷新?",
|
|
async onOk() {
|
|
_this.state.showDialog = false;
|
|
await clearCache();
|
|
window.location.reload();
|
|
},
|
|
onCancel() {
|
|
_this.state.showDialog = false;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 异步加载
|
|
*/
|
|
loadData = e => {
|
|
const { loadedKeys } = this.props;
|
|
return new Promise(resolve => {
|
|
const item = e.props.dataRef;
|
|
const newPath = item.path + "." + item.bookmarkId;
|
|
item.children = getBookmarkList(newPath);
|
|
this.props.updateTreeData([...getBookmarkList("")]);
|
|
loadedKeys.push(item.bookmarkId.toString());
|
|
this.props.changeLoadedKeys(loadedKeys);
|
|
resolve();
|
|
});
|
|
};
|
|
/**
|
|
* 节点选择
|
|
* @param {*} key
|
|
* @param {*} e
|
|
*/
|
|
treeNodeSelect(key, e) {
|
|
const { expandedKeys, changeExpandedKeys } = this.props;
|
|
const item = e.node.props.dataRef;
|
|
if (item.type === 0) {
|
|
window.open(
|
|
item.url.startsWith("http") ? item.url : "http://" + item.url
|
|
);
|
|
} else {
|
|
const id = item.bookmarkId.toString();
|
|
const index = expandedKeys.indexOf(id);
|
|
index === -1 ? expandedKeys.push(id) : expandedKeys.splice(index, 1);
|
|
changeExpandedKeys([...expandedKeys]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 同步书签数据
|
|
*/
|
|
async refreshTree() {
|
|
await clearCache();
|
|
window.location.reload();
|
|
}
|
|
|
|
render() {
|
|
const {
|
|
isEdit,
|
|
setIsEdit,
|
|
treeData,
|
|
addNode,
|
|
isInit,
|
|
expandedKeys,
|
|
checkedKeys,
|
|
loadedKeys
|
|
} = this.props;
|
|
const { isLoading } = this.state;
|
|
const { changeExpandedKeys } = this.props;
|
|
return (
|
|
<MainLayout>
|
|
<div className={styles.main}>
|
|
<Search />
|
|
<div className={styles.header}>
|
|
<div className={styles.left}>
|
|
<span className={styles.myTree}>我的书签树</span>
|
|
<Button
|
|
size="small"
|
|
type="primary"
|
|
icon="sync"
|
|
shape="circle"
|
|
onClick={this.refreshTree.bind(this, null)}
|
|
/>
|
|
<Button
|
|
size="small"
|
|
type="primary"
|
|
icon="plus"
|
|
shape="circle"
|
|
onClick={addNode.bind(this, null)}
|
|
/>
|
|
{expandedKeys.length > 0 ? (
|
|
<Button
|
|
type="primary"
|
|
size="small"
|
|
onClick={changeExpandedKeys.bind(this, [])}
|
|
>
|
|
收起
|
|
</Button>
|
|
) : null}
|
|
<a
|
|
className={styles.help}
|
|
href="https://github.com/FleyX/bookmark/blob/master/README.md"
|
|
>
|
|
使用帮助
|
|
</a>
|
|
</div>
|
|
<div className={styles.right}>
|
|
{isEdit ? (
|
|
<React.Fragment>
|
|
<Button
|
|
size="small"
|
|
type="danger"
|
|
onClick={batchDelete.bind(this)}
|
|
>
|
|
删除选中
|
|
</Button>
|
|
</React.Fragment>
|
|
) : null}
|
|
<Button
|
|
size="small"
|
|
type="primary"
|
|
onClick={setIsEdit.bind(this, !isEdit)}
|
|
>
|
|
{isEdit ? "完成" : "编辑"}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
<Spin spinning={isLoading} delay={200}>
|
|
<Tree
|
|
showIcon
|
|
loadedKeys={loadedKeys}
|
|
checkedKeys={checkedKeys}
|
|
onCheck={this.props.changeCheckedKeys}
|
|
expandedKeys={expandedKeys}
|
|
loadData={this.loadData}
|
|
onExpand={this.props.changeExpandedKeys}
|
|
checkable={isEdit}
|
|
onSelect={this.treeNodeSelect.bind(this)}
|
|
draggable
|
|
onDrop={onDrop.bind(this)}
|
|
blockNode
|
|
>
|
|
{renderTreeNodes.call(this, treeData)}
|
|
</Tree>
|
|
{isInit && treeData.length === 0 ? (
|
|
<Empty description="还没有数据" />
|
|
) : null}
|
|
</Spin>
|
|
<AddModal />
|
|
</div>
|
|
</MainLayout>
|
|
);
|
|
}
|
|
}
|
|
|
|
export default connect(mapStateToProps, mapDispatchToProps)(OverView);
|