2018-08-06 10:29:12 +00:00
|
|
|
import React, { Component } from 'react';
|
|
|
|
import ReactDOM from 'react-dom';
|
2018-08-30 07:10:52 +00:00
|
|
|
import SidePanel from './pages/wiki/side-panel';
|
|
|
|
import MainPanel from './pages/wiki/main-panel';
|
2018-08-06 10:29:12 +00:00
|
|
|
import moment from 'moment';
|
2018-11-30 03:22:58 +00:00
|
|
|
import { slug, repoID, siteRoot, initialPath } from './utils/constants';
|
2018-09-04 09:16:50 +00:00
|
|
|
import editorUtilities from './utils/editor-utilties';
|
2018-12-13 12:42:51 +00:00
|
|
|
import { Utils } from './utils/utils';
|
2018-09-19 01:57:17 +00:00
|
|
|
import Node from './components/tree-view/node';
|
|
|
|
import Tree from './components/tree-view/tree';
|
2018-08-06 10:29:12 +00:00
|
|
|
import './assets/css/fa-solid.css';
|
|
|
|
import './assets/css/fa-regular.css';
|
|
|
|
import './assets/css/fontawesome.css';
|
2018-09-21 06:16:15 +00:00
|
|
|
import './css/layout.css';
|
2018-08-06 10:29:12 +00:00
|
|
|
import './css/side-panel.css';
|
|
|
|
import './css/wiki.css';
|
2018-09-19 01:57:17 +00:00
|
|
|
import './css/toolbar.css';
|
2018-08-17 04:23:55 +00:00
|
|
|
import './css/search.css';
|
2018-08-06 10:29:12 +00:00
|
|
|
|
|
|
|
class Wiki extends Component {
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
this.state = {
|
|
|
|
content: '',
|
2018-09-04 09:16:50 +00:00
|
|
|
tree_data: new Tree(),
|
2018-08-06 10:29:12 +00:00
|
|
|
closeSideBar: false,
|
|
|
|
filePath: '',
|
|
|
|
latestContributor: '',
|
|
|
|
lastModified: '',
|
2018-08-17 04:23:55 +00:00
|
|
|
permission: '',
|
2018-09-01 03:34:27 +00:00
|
|
|
isFileLoading: false,
|
2018-09-04 09:16:50 +00:00
|
|
|
changedNode: null,
|
|
|
|
isViewFileState: true
|
2018-08-06 10:29:12 +00:00
|
|
|
};
|
|
|
|
window.onpopstate = this.onpopstate;
|
|
|
|
}
|
|
|
|
|
|
|
|
componentDidMount() {
|
2018-11-30 03:22:58 +00:00
|
|
|
this.initWikiData(initialPath);
|
2018-08-06 10:29:12 +00:00
|
|
|
}
|
|
|
|
|
2018-09-05 02:44:58 +00:00
|
|
|
initWikiData(filePath){
|
|
|
|
this.setState({isFileLoading: true});
|
|
|
|
editorUtilities.getFiles().then((files) => {
|
|
|
|
// construct the tree object
|
|
|
|
var treeData = new Tree();
|
|
|
|
treeData.parseListToTree(files);
|
|
|
|
|
|
|
|
let node = treeData.getNodeByPath(filePath);
|
2018-09-12 03:50:41 +00:00
|
|
|
treeData.expandNode(node);
|
2018-09-05 02:44:58 +00:00
|
|
|
if (node.isDir()) {
|
|
|
|
this.exitViewFileState(treeData, node);
|
|
|
|
this.setState({isFileLoading: false});
|
|
|
|
} else {
|
2018-09-12 03:50:41 +00:00
|
|
|
treeData.expandNode(node);
|
2018-09-05 02:44:58 +00:00
|
|
|
editorUtilities.getWikiFileContent(slug, filePath).then(res => {
|
|
|
|
this.setState({
|
|
|
|
tree_data: treeData,
|
|
|
|
content: res.data.content,
|
|
|
|
latestContributor: res.data.latest_contributor,
|
|
|
|
lastModified: moment.unix(res.data.last_modified).fromNow(),
|
|
|
|
permission: res.data.permission,
|
|
|
|
filePath: filePath,
|
|
|
|
isFileLoading: false
|
2018-09-19 01:57:17 +00:00
|
|
|
});
|
2018-09-05 02:44:58 +00:00
|
|
|
});
|
|
|
|
const hash = window.location.hash;
|
2018-11-29 09:55:14 +00:00
|
|
|
let fileUrl = siteRoot + 'wikis/' + slug + filePath + hash;
|
2018-09-05 02:44:58 +00:00
|
|
|
window.history.pushState({urlPath: fileUrl, filePath: filePath}, filePath, fileUrl);
|
|
|
|
}
|
|
|
|
}, () => {
|
|
|
|
this.setState({
|
|
|
|
isLoadFailed: true
|
2018-09-19 01:57:17 +00:00
|
|
|
});
|
|
|
|
});
|
2018-08-06 10:29:12 +00:00
|
|
|
}
|
|
|
|
|
2018-09-05 09:44:14 +00:00
|
|
|
initMainPanelData(filePath){
|
2018-09-04 09:16:50 +00:00
|
|
|
this.setState({isFileLoading: true});
|
|
|
|
editorUtilities.getWikiFileContent(slug, filePath)
|
|
|
|
.then(res => {
|
|
|
|
this.setState({
|
|
|
|
content: res.data.content,
|
|
|
|
latestContributor: res.data.latest_contributor,
|
|
|
|
lastModified: moment.unix(res.data.last_modified).fromNow(),
|
|
|
|
permission: res.data.permission,
|
|
|
|
filePath: filePath,
|
|
|
|
isFileLoading: false
|
2018-09-19 01:57:17 +00:00
|
|
|
});
|
|
|
|
});
|
2018-08-06 10:29:12 +00:00
|
|
|
|
2018-09-19 01:57:17 +00:00
|
|
|
const hash = window.location.hash;
|
2018-11-29 09:55:14 +00:00
|
|
|
let fileUrl = siteRoot + 'wikis/' + slug + filePath + hash;
|
2018-09-19 01:57:17 +00:00
|
|
|
window.history.pushState({urlPath: fileUrl, filePath: filePath}, filePath, fileUrl);
|
2018-08-06 10:29:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
onLinkClick = (event) => {
|
|
|
|
const url = event.target.href;
|
|
|
|
if (this.isInternalMarkdownLink(url)) {
|
|
|
|
let path = this.getPathFromInternalMarkdownLink(url);
|
2018-09-04 09:16:50 +00:00
|
|
|
this.initMainPanelData(path);
|
2018-09-07 14:25:13 +00:00
|
|
|
} else if (this.isInternalDirLink(url)) {
|
|
|
|
let path = this.getPathFromInternalDirLink(url);
|
|
|
|
this.initWikiData(path);
|
2018-08-28 03:34:03 +00:00
|
|
|
} else {
|
|
|
|
window.location.href = url;
|
2018-08-06 10:29:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-04 09:16:50 +00:00
|
|
|
onpopstate = (event) => {
|
|
|
|
if (event.state && event.state.filePath) {
|
|
|
|
this.initMainPanelData(event.state.filePath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-18 02:11:37 +00:00
|
|
|
onSearchedClick = (item) => {
|
2018-12-13 12:42:51 +00:00
|
|
|
if (item.is_dir) {
|
|
|
|
let path = item.path.slice(0, item.path.length - 1);
|
|
|
|
if (this.state.filePath !== path) {
|
|
|
|
let tree = this.state.tree_data.clone();
|
|
|
|
let node = tree.getNodeByPath(path);
|
|
|
|
tree.expandNode(node);
|
|
|
|
this.exitViewFileState(tree, node);
|
|
|
|
}
|
|
|
|
} else if (Utils.isMarkdownFile(item.path)) {
|
|
|
|
let path = item.path;
|
|
|
|
if (this.state.filePath !== path) {
|
|
|
|
this.initMainPanelData(path);
|
|
|
|
|
|
|
|
let tree = this.state.tree_data.clone();
|
|
|
|
let node = tree.getNodeByPath(path);
|
|
|
|
tree.expandNode(node);
|
|
|
|
this.enterViewFileState(tree, node, node.path);
|
|
|
|
}
|
|
|
|
} else {
|
2018-12-14 13:52:54 +00:00
|
|
|
let url = siteRoot + 'lib/' + item.repo_id + '/file' + Utils.encodePath(item.path);
|
2018-12-13 12:42:51 +00:00
|
|
|
let newWindow = window.open('about:blank');
|
|
|
|
newWindow.location.href = url;
|
2018-08-17 04:23:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-04 09:16:50 +00:00
|
|
|
onMainNavBarClick = (nodePath) => {
|
|
|
|
let tree = this.state.tree_data.clone();
|
|
|
|
let node = tree.getNodeByPath(nodePath);
|
2018-09-12 03:50:41 +00:00
|
|
|
tree.expandNode(node);
|
2018-09-04 09:16:50 +00:00
|
|
|
|
|
|
|
this.exitViewFileState(tree, node);
|
|
|
|
|
|
|
|
// update location url
|
2018-11-29 09:55:14 +00:00
|
|
|
let fileUrl = siteRoot + 'wikis/' + slug + node.path;
|
2018-09-04 09:16:50 +00:00
|
|
|
window.history.pushState({urlPath: fileUrl, filePath: node.path},node.path, fileUrl);
|
|
|
|
}
|
|
|
|
|
|
|
|
onMainNodeClick = (node) => {
|
|
|
|
let tree = this.state.tree_data.clone();
|
2018-09-12 03:50:41 +00:00
|
|
|
tree.expandNode(node);
|
2018-08-06 10:29:12 +00:00
|
|
|
if (node.isMarkdown()) {
|
2018-09-04 09:16:50 +00:00
|
|
|
this.initMainPanelData(node.path);
|
|
|
|
this.enterViewFileState(tree, node, node.path);
|
|
|
|
} else if (node.isDir()){
|
|
|
|
this.exitViewFileState(tree, node);
|
2018-08-30 03:35:56 +00:00
|
|
|
} else {
|
|
|
|
const w=window.open('about:blank');
|
2018-12-14 13:52:54 +00:00
|
|
|
const url = siteRoot + 'lib/' + repoID + '/file' + Utils.encodePath(node.path);
|
2018-08-30 03:35:56 +00:00
|
|
|
w.location.href = url;
|
2018-08-06 10:29:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-30 03:22:58 +00:00
|
|
|
onNodeClick = (node) => {
|
2018-09-04 09:16:50 +00:00
|
|
|
if (node instanceof Node && node.isMarkdown()){
|
|
|
|
let tree = this.state.tree_data.clone();
|
|
|
|
this.initMainPanelData(node.path);
|
|
|
|
this.enterViewFileState(tree, node, node.path);
|
|
|
|
} else if(node instanceof Node && node.isDir()){
|
|
|
|
let tree = this.state.tree_data.clone();
|
2018-09-12 03:50:41 +00:00
|
|
|
if (this.state.filePath === node.path) {
|
|
|
|
if (node.isExpanded) {
|
|
|
|
tree.collapseNode(node);
|
|
|
|
} else {
|
|
|
|
tree.expandNode(node);
|
|
|
|
}
|
|
|
|
}
|
2018-09-04 09:16:50 +00:00
|
|
|
this.exitViewFileState(tree, node);
|
|
|
|
} else {
|
|
|
|
const w=window.open('about:blank');
|
2018-11-29 09:55:14 +00:00
|
|
|
const url = siteRoot + 'lib/' + repoID + '/file' + node.path;
|
2018-09-04 09:16:50 +00:00
|
|
|
w.location.href = url;
|
|
|
|
}
|
2018-08-06 10:29:12 +00:00
|
|
|
}
|
|
|
|
|
2018-11-30 03:22:58 +00:00
|
|
|
onDirCollapse = (node) => {
|
2018-09-04 09:16:50 +00:00
|
|
|
let tree = this.state.tree_data.clone();
|
|
|
|
let findNode = tree.getNodeByPath(node.path);
|
|
|
|
findNode.isExpanded = !findNode.isExpanded;
|
|
|
|
this.setState({tree_data: tree});
|
2018-08-06 10:29:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
onMenuClick = () => {
|
|
|
|
this.setState({
|
|
|
|
closeSideBar: !this.state.closeSideBar,
|
2018-09-19 01:57:17 +00:00
|
|
|
});
|
2018-08-06 10:29:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
onCloseSide = () => {
|
|
|
|
this.setState({
|
|
|
|
closeSideBar: !this.state.closeSideBar,
|
2018-09-19 01:57:17 +00:00
|
|
|
});
|
2018-08-06 10:29:12 +00:00
|
|
|
}
|
|
|
|
|
2018-09-04 09:16:50 +00:00
|
|
|
onAddFolderNode = (dirPath) => {
|
|
|
|
editorUtilities.createDir(dirPath).then(res => {
|
|
|
|
let tree = this.state.tree_data.clone();
|
|
|
|
let name = this.getFileNameByPath(dirPath);
|
2018-09-19 01:57:17 +00:00
|
|
|
let index = dirPath.lastIndexOf('/');
|
2018-09-04 09:16:50 +00:00
|
|
|
let parentPath = dirPath.substring(0, index);
|
|
|
|
if (!parentPath) {
|
2018-09-19 01:57:17 +00:00
|
|
|
parentPath = '/';
|
2018-09-04 09:16:50 +00:00
|
|
|
}
|
2018-09-19 01:57:17 +00:00
|
|
|
let node = this.buildNewNode(name, 'dir');
|
2018-09-04 09:16:50 +00:00
|
|
|
let parentNode = tree.getNodeByPath(parentPath);
|
|
|
|
tree.addNodeToParent(node, parentNode);
|
|
|
|
if (this.state.isViewFileState) {
|
2018-09-12 03:50:41 +00:00
|
|
|
tree.expandNode(node);
|
2018-09-04 09:16:50 +00:00
|
|
|
this.setState({
|
|
|
|
tree_data: tree,
|
|
|
|
changedNode: node
|
2018-09-19 01:57:17 +00:00
|
|
|
});
|
2018-09-04 09:16:50 +00:00
|
|
|
} else {
|
|
|
|
this.exitViewFileState(tree, parentNode);
|
|
|
|
}
|
2018-09-19 01:57:17 +00:00
|
|
|
});
|
2018-09-04 09:16:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
onAddFileNode = (filePath) => {
|
|
|
|
editorUtilities.createFile(filePath).then(res => {
|
|
|
|
let tree = this.state.tree_data.clone();
|
|
|
|
let name = this.getFileNameByPath(filePath);
|
2018-09-19 01:57:17 +00:00
|
|
|
let index = filePath.lastIndexOf('/');
|
2018-09-04 09:16:50 +00:00
|
|
|
let parentPath = filePath.substring(0, index);
|
|
|
|
if (!parentPath) {
|
2018-09-19 01:57:17 +00:00
|
|
|
parentPath = '/';
|
2018-09-04 09:16:50 +00:00
|
|
|
}
|
2018-09-19 01:57:17 +00:00
|
|
|
let node = this.buildNewNode(name, 'file');
|
2018-09-04 09:16:50 +00:00
|
|
|
let parentNode = tree.getNodeByPath(parentPath);
|
|
|
|
tree.addNodeToParent(node, parentNode);
|
|
|
|
if (this.state.isViewFileState) {
|
2018-09-12 03:50:41 +00:00
|
|
|
tree.expandNode(node);
|
2018-09-04 09:16:50 +00:00
|
|
|
this.setState({
|
|
|
|
tree_data: tree,
|
|
|
|
changedNode: node
|
2018-09-19 01:57:17 +00:00
|
|
|
});
|
2018-09-04 09:16:50 +00:00
|
|
|
} else {
|
|
|
|
this.exitViewFileState(tree, parentNode);
|
|
|
|
}
|
2018-09-19 01:57:17 +00:00
|
|
|
});
|
2018-09-04 09:16:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
onRenameNode = (node, newName) => {
|
|
|
|
let tree = this.state.tree_data.clone();
|
|
|
|
let filePath = node.path;
|
|
|
|
if (node.isMarkdown()) {
|
|
|
|
editorUtilities.renameFile(filePath, newName).then(res => {
|
2018-09-05 09:44:14 +00:00
|
|
|
let cloneNode = node.clone();
|
|
|
|
|
2018-09-19 01:57:17 +00:00
|
|
|
tree.updateNodeParam(node, 'name', newName);
|
2018-09-04 09:16:50 +00:00
|
|
|
node.name = newName;
|
2018-09-05 09:44:14 +00:00
|
|
|
let date = new Date().getTime()/1000;
|
2018-09-19 01:57:17 +00:00
|
|
|
tree.updateNodeParam(node, 'last_update_time', moment.unix(date).fromNow());
|
2018-09-04 09:16:50 +00:00
|
|
|
node.last_update_time = moment.unix(date).fromNow();
|
2018-09-05 09:44:14 +00:00
|
|
|
|
2018-09-04 09:16:50 +00:00
|
|
|
if (this.state.isViewFileState) {
|
2018-09-05 09:44:14 +00:00
|
|
|
if (this.isModifyCurrentFile(cloneNode)) {
|
2018-09-12 03:50:41 +00:00
|
|
|
tree.expandNode(node);
|
2018-09-04 09:16:50 +00:00
|
|
|
this.setState({
|
|
|
|
tree_data: tree,
|
|
|
|
changedNode: node
|
|
|
|
});
|
|
|
|
this.initMainPanelData(node.path);
|
|
|
|
} else {
|
|
|
|
this.setState({tree_data: tree});
|
|
|
|
}
|
|
|
|
} else {
|
2018-09-05 09:44:14 +00:00
|
|
|
let parentNode = tree.findNodeParentFromTree(node);
|
|
|
|
this.setState({
|
|
|
|
tree_data: tree,
|
|
|
|
changedNode: parentNode
|
|
|
|
});
|
2018-09-04 09:16:50 +00:00
|
|
|
}
|
2018-09-19 01:57:17 +00:00
|
|
|
});
|
2018-09-04 09:16:50 +00:00
|
|
|
} else if (node.isDir()) {
|
|
|
|
editorUtilities.renameDir(filePath, newName).then(res => {
|
2018-09-05 02:44:58 +00:00
|
|
|
|
2018-09-05 09:44:14 +00:00
|
|
|
let currentFilePath = this.state.filePath;
|
2018-09-04 09:16:50 +00:00
|
|
|
let currentFileNode = tree.getNodeByPath(currentFilePath);
|
2018-09-05 09:44:14 +00:00
|
|
|
let nodePath = node.path;
|
|
|
|
|
2018-09-19 01:57:17 +00:00
|
|
|
tree.updateNodeParam(node, 'name', newName);
|
2018-09-05 09:44:14 +00:00
|
|
|
node.name = newName;
|
|
|
|
let date = new Date().getTime()/1000;
|
2018-09-19 01:57:17 +00:00
|
|
|
tree.updateNodeParam(node, 'last_update_time', moment.unix(date).fromNow());
|
2018-09-04 09:16:50 +00:00
|
|
|
node.last_update_time = moment.unix(date).fromNow();
|
2018-09-05 02:44:58 +00:00
|
|
|
|
2018-09-04 09:16:50 +00:00
|
|
|
if (this.state.isViewFileState) {
|
2018-09-05 09:44:14 +00:00
|
|
|
if (currentFilePath.indexOf(nodePath) > -1) {
|
2018-09-12 03:50:41 +00:00
|
|
|
tree.expandNode(currentFileNode);
|
2018-09-04 09:16:50 +00:00
|
|
|
this.setState({
|
|
|
|
tree_data: tree,
|
|
|
|
changedNode: currentFileNode
|
|
|
|
});
|
|
|
|
this.initMainPanelData(currentFileNode.path);
|
|
|
|
} else {
|
|
|
|
this.setState({tree_data: tree});
|
|
|
|
}
|
|
|
|
} else {
|
2018-09-05 09:44:14 +00:00
|
|
|
if (nodePath === currentFilePath) { // old node
|
2018-09-12 03:50:41 +00:00
|
|
|
tree.expandNode(node);
|
2018-09-05 09:44:14 +00:00
|
|
|
this.exitViewFileState(tree, node);
|
|
|
|
} else if (node.path.indexOf(currentFilePath) > -1) { // new node
|
2018-09-12 03:50:41 +00:00
|
|
|
tree.expandNode(currentFileNode);
|
2018-09-04 09:16:50 +00:00
|
|
|
this.exitViewFileState(tree, currentFileNode);
|
|
|
|
} else {
|
|
|
|
this.setState({tree_data: tree});
|
|
|
|
}
|
|
|
|
}
|
2018-09-19 01:57:17 +00:00
|
|
|
});
|
2018-09-04 09:16:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
onDeleteNode = (node) => {
|
|
|
|
let filePath = node.path;
|
2018-09-29 07:47:53 +00:00
|
|
|
if (node.isDir()) {
|
2018-09-04 09:16:50 +00:00
|
|
|
editorUtilities.deleteDir(filePath);
|
|
|
|
} else {
|
2018-09-29 07:47:53 +00:00
|
|
|
editorUtilities.deleteFile(filePath);
|
2018-09-04 09:16:50 +00:00
|
|
|
}
|
|
|
|
|
2018-09-29 07:47:53 +00:00
|
|
|
|
2018-09-04 09:16:50 +00:00
|
|
|
let isCurrentFile = false;
|
|
|
|
if (node.isDir()) {
|
|
|
|
isCurrentFile = this.isModifyContainsCurrentFile(node);
|
|
|
|
} else {
|
|
|
|
isCurrentFile = this.isModifyCurrentFile(node);
|
|
|
|
}
|
|
|
|
|
|
|
|
let tree = this.state.tree_data.clone();
|
|
|
|
|
|
|
|
if (this.state.isViewFileState) {
|
|
|
|
if (isCurrentFile) {
|
|
|
|
let homeNode = this.getHomeNode(tree);
|
2018-09-12 03:50:41 +00:00
|
|
|
tree.expandNode(homeNode);
|
2018-09-04 09:16:50 +00:00
|
|
|
this.setState({
|
|
|
|
tree_data: tree,
|
|
|
|
changedNode: homeNode
|
2018-09-19 01:57:17 +00:00
|
|
|
});
|
2018-09-04 09:16:50 +00:00
|
|
|
this.initMainPanelData(homeNode.path);
|
|
|
|
} else {
|
2018-09-19 01:57:17 +00:00
|
|
|
this.setState({tree_data: tree});
|
2018-09-04 09:16:50 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
let parentNode = tree.getNodeByPath(this.state.filePath);
|
|
|
|
let isChild = tree.isNodeChild(parentNode, node);
|
|
|
|
if (isChild) {
|
|
|
|
this.exitViewFileState(tree, parentNode);
|
|
|
|
} else {
|
|
|
|
this.setState({tree_data: tree});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tree.deleteNode(node);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
enterViewFileState(newTree, newNode, newPath) {
|
|
|
|
this.setState({
|
|
|
|
tree_data: newTree,
|
|
|
|
changedNode: newNode,
|
|
|
|
filePath: newPath,
|
|
|
|
isViewFileState: true
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
exitViewFileState(newTree, newNode) {
|
|
|
|
this.setState({
|
|
|
|
tree_data: newTree,
|
|
|
|
changedNode: newNode,
|
|
|
|
filePath: newNode.path,
|
|
|
|
isViewFileState: false
|
|
|
|
});
|
2018-11-29 09:55:14 +00:00
|
|
|
let fileUrl = siteRoot + 'wikis/' + slug + newNode.path;
|
2018-09-04 09:16:50 +00:00
|
|
|
window.history.pushState({urlPath: fileUrl, filePath: newNode.path}, newNode.path, fileUrl);
|
|
|
|
}
|
|
|
|
|
|
|
|
getFileNameByPath(path) {
|
2018-09-19 01:57:17 +00:00
|
|
|
let index = path.lastIndexOf('/');
|
2018-09-04 09:16:50 +00:00
|
|
|
if (index === -1) {
|
2018-09-19 01:57:17 +00:00
|
|
|
return '';
|
2018-09-04 09:16:50 +00:00
|
|
|
}
|
|
|
|
return path.slice(index+1);
|
|
|
|
}
|
|
|
|
|
|
|
|
getHomeNode(treeData) {
|
2018-09-19 01:57:17 +00:00
|
|
|
return treeData.getNodeByPath('/home.md');
|
2018-09-04 09:16:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
buildNewNode(name, type) {
|
|
|
|
let date = new Date().getTime()/1000;
|
|
|
|
let node = new Node({
|
2018-09-19 01:57:17 +00:00
|
|
|
name : name,
|
|
|
|
type: type,
|
|
|
|
size: '0',
|
|
|
|
last_update_time: moment.unix(date).fromNow(),
|
|
|
|
isExpanded: false,
|
|
|
|
children: []
|
2018-09-04 09:16:50 +00:00
|
|
|
});
|
|
|
|
return node;
|
|
|
|
}
|
|
|
|
|
|
|
|
isModifyCurrentFile(node) {
|
|
|
|
let nodeName = node.name;
|
|
|
|
let fileName = this.getFileNameByPath(this.state.filePath);
|
|
|
|
return nodeName === fileName;
|
|
|
|
}
|
|
|
|
|
|
|
|
isModifyContainsCurrentFile(node) {
|
|
|
|
let filePath = this.state.filePath;
|
|
|
|
let nodePath = node.path;
|
|
|
|
|
|
|
|
if (filePath.indexOf(nodePath) > -1) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
isMarkdownFile(filePath) {
|
2018-09-19 01:57:17 +00:00
|
|
|
let index = filePath.lastIndexOf('.');
|
2018-09-04 09:16:50 +00:00
|
|
|
if (index === -1) {
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
let type = filePath.substring(index).toLowerCase();
|
2018-09-19 01:57:17 +00:00
|
|
|
if (type === '.md' || type === '.markdown') {
|
2018-09-04 09:16:50 +00:00
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
isInternalMarkdownLink(url) {
|
2018-11-29 09:55:14 +00:00
|
|
|
var re = new RegExp(siteRoot + 'lib/' + repoID + '/file' + '.*\.md$');
|
2018-09-04 09:16:50 +00:00
|
|
|
return re.test(url);
|
|
|
|
}
|
|
|
|
|
2018-09-07 14:25:13 +00:00
|
|
|
isInternalDirLink(url) {
|
2018-11-29 09:55:14 +00:00
|
|
|
var re = new RegExp(siteRoot + '#[a-z\-]*?/lib/' + repoID + '/.*');
|
2018-09-07 14:25:13 +00:00
|
|
|
return re.test(url);
|
|
|
|
}
|
|
|
|
|
2018-09-04 09:16:50 +00:00
|
|
|
getPathFromInternalMarkdownLink(url) {
|
2018-11-29 09:55:14 +00:00
|
|
|
var re = new RegExp(siteRoot + 'lib/' + repoID + '/file' + '(.*\.md)');
|
2018-09-04 09:16:50 +00:00
|
|
|
var array = re.exec(url);
|
|
|
|
var path = decodeURIComponent(array[1]);
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
2018-09-07 14:25:13 +00:00
|
|
|
getPathFromInternalDirLink(url) {
|
2018-11-29 09:55:14 +00:00
|
|
|
var re = new RegExp(siteRoot + '#[a-z\-]*?/lib/' + repoID + '(/.*)');
|
2018-09-07 14:25:13 +00:00
|
|
|
var array = re.exec(url);
|
|
|
|
var path = decodeURIComponent(array[1]);
|
|
|
|
|
|
|
|
var dirPath = path.substring(1);
|
2018-09-19 01:57:17 +00:00
|
|
|
re = new RegExp('(^/.*)');
|
2018-09-07 14:25:13 +00:00
|
|
|
if (re.test(dirPath)) {
|
|
|
|
path = dirPath;
|
|
|
|
} else {
|
2018-09-19 01:57:17 +00:00
|
|
|
path = '/' + dirPath;
|
2018-09-07 14:25:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
2018-08-06 10:29:12 +00:00
|
|
|
render() {
|
|
|
|
return (
|
|
|
|
<div id="main" className="wiki-main">
|
|
|
|
<SidePanel
|
2018-09-04 09:16:50 +00:00
|
|
|
onNodeClick={this.onNodeClick}
|
2018-08-06 10:29:12 +00:00
|
|
|
closeSideBar={this.state.closeSideBar}
|
|
|
|
onCloseSide ={this.onCloseSide}
|
2018-09-04 09:16:50 +00:00
|
|
|
treeData={this.state.tree_data}
|
2018-11-30 03:22:58 +00:00
|
|
|
currentPath={this.state.filePath}
|
2018-09-04 09:16:50 +00:00
|
|
|
changedNode={this.state.changedNode}
|
|
|
|
onAddFolderNode={this.onAddFolderNode}
|
|
|
|
onAddFileNode={this.onAddFileNode}
|
|
|
|
onRenameNode={this.onRenameNode}
|
|
|
|
onDeleteNode={this.onDeleteNode}
|
|
|
|
onDirCollapse={this.onDirCollapse}
|
2018-08-06 10:29:12 +00:00
|
|
|
/>
|
|
|
|
<MainPanel
|
|
|
|
content={this.state.content}
|
|
|
|
filePath={this.state.filePath}
|
|
|
|
latestContributor={this.state.latestContributor}
|
|
|
|
lastModified={this.state.lastModified}
|
|
|
|
permission={this.state.permission}
|
2018-09-04 09:16:50 +00:00
|
|
|
isViewFileState={this.state.isViewFileState}
|
|
|
|
changedNode={this.state.changedNode}
|
2018-08-17 04:23:55 +00:00
|
|
|
isFileLoading={this.state.isFileLoading}
|
2018-09-04 09:16:50 +00:00
|
|
|
onLinkClick={this.onLinkClick}
|
|
|
|
onMenuClick={this.onMenuClick}
|
|
|
|
onSearchedClick={this.onSearchedClick}
|
|
|
|
onMainNavBarClick={this.onMainNavBarClick}
|
|
|
|
onMainNodeClick={this.onMainNodeClick}
|
2018-09-29 07:47:53 +00:00
|
|
|
onDeleteNode={this.onDeleteNode}
|
|
|
|
onRenameNode={this.onRenameNode}
|
2018-08-06 10:29:12 +00:00
|
|
|
/>
|
|
|
|
</div>
|
2018-09-19 01:57:17 +00:00
|
|
|
);
|
2018-08-06 10:29:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ReactDOM.render (
|
|
|
|
<Wiki />,
|
|
|
|
document.getElementById('wrapper')
|
2018-09-19 01:57:17 +00:00
|
|
|
);
|