mirror of
https://github.com/haiwen/seahub.git
synced 2025-07-31 06:40:39 +00:00
optimize md dir
This commit is contained in:
parent
57f28a9a73
commit
d06c0be185
@ -1,9 +1,9 @@
|
||||
// Import React!
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import MarkdownEditor from './markdown-editor';
|
||||
import { I18nextProvider } from 'react-i18next';
|
||||
import i18n from './i18n-seafile-editor';
|
||||
import MarkdownEditor from './pages/markdown-editor';
|
||||
|
||||
import './index.css';
|
||||
|
||||
|
232
frontend/src/pages/markdown-editor/editor-api.js
Normal file
232
frontend/src/pages/markdown-editor/editor-api.js
Normal file
@ -0,0 +1,232 @@
|
||||
import { seafileAPI } from './utils/seafile-api';
|
||||
import { Utils } from './utils/utils';
|
||||
|
||||
import './css/markdown-viewer/markdown-editor.css';
|
||||
|
||||
const { repoID, repoName, filePath, fileName, draftID } = window.app.pageOptions;
|
||||
const { serviceUrl } = window.app.config;
|
||||
const userInfo = window.app.userInfo;
|
||||
const userName = userInfo.username;
|
||||
let dirPath = Utils.getDirName(filePath);
|
||||
|
||||
function getImageFileNameWithTimestamp() {
|
||||
var d = Date.now();
|
||||
return 'image-' + d.toString() + '.png';
|
||||
}
|
||||
|
||||
class EditorApi {
|
||||
|
||||
constructor () {
|
||||
this.repoID = repoID;
|
||||
this.filePath = filePath;
|
||||
this.serviceUrl = serviceUrl;
|
||||
this.name = userInfo.name;
|
||||
this.contact_email = userInfo.contact_email;
|
||||
this.fileName = fileName;
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
saveContent(content) {
|
||||
return (
|
||||
seafileAPI.getUpdateLink(repoID, dirPath).then((res) => {
|
||||
const uploadLink = res.data;
|
||||
return seafileAPI.updateFile(uploadLink, filePath, fileName, content);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
unstarItem () {
|
||||
return (
|
||||
seafileAPI.unstarItem(this.repoID, this.filePath)
|
||||
);
|
||||
}
|
||||
|
||||
starItem() {
|
||||
return (
|
||||
seafileAPI.starItem(this.repoID, this.filePath)
|
||||
);
|
||||
}
|
||||
|
||||
getParentDectionaryUrl() {
|
||||
let parentPath = this.filePath.substring(0, this.filePath.lastIndexOf('/'));
|
||||
let libName = encodeURIComponent(repoName);
|
||||
let path = Utils.encodePath(parentPath);
|
||||
return this.serviceUrl + '/library/' + this.repoID + '/' + libName + path;
|
||||
}
|
||||
|
||||
_getImageURL(fileName) {
|
||||
const url = this.serviceUrl + '/lib/' + repoID + '/file/images/auto-upload/' + fileName + '?raw=1';
|
||||
return url;
|
||||
}
|
||||
|
||||
uploadLocalImage = (imageFile) => {
|
||||
return (
|
||||
seafileAPI.getFileServerUploadLink(repoID, '/').then((res) => {
|
||||
const uploadLink = res.data + '?ret-json=1';
|
||||
const name = getImageFileNameWithTimestamp();
|
||||
const newFile = new File([imageFile], name, {type: imageFile.type});
|
||||
const formData = new FormData();
|
||||
formData.append('parent_dir', '/');
|
||||
formData.append('relative_path', 'images/auto-upload');
|
||||
formData.append('file', newFile);
|
||||
return seafileAPI.uploadImage(uploadLink, formData);
|
||||
}).then ((res) => {
|
||||
return this._getImageURL(res.data[0].name);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
getFileURL(fileNode) {
|
||||
var url;
|
||||
if (fileNode.type === 'file') {
|
||||
if (fileNode.isImage()) {
|
||||
url = serviceUrl + '/lib/' + repoID + '/file' + Utils.encodePath(fileNode.path()) + '?raw=1';
|
||||
} else {
|
||||
url = serviceUrl + '/lib/' + repoID + '/file' + Utils.encodePath(fileNode.path());
|
||||
}
|
||||
} else {
|
||||
url = serviceUrl + '/library/' + repoID + '/' + encodeURIComponent(repoName) + Utils.encodePath(fileNode.path());
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
isInternalFileLink(url) {
|
||||
var re = new RegExp(this.serviceUrl + '/lib/[0-9a-f-]{36}/file.*');
|
||||
return re.test(url);
|
||||
}
|
||||
|
||||
isInternalDirLink(url) {
|
||||
var re = new RegExp(serviceUrl + '/library/' + '[0-9a-f\-]{36}.*');
|
||||
return re.test(url);
|
||||
}
|
||||
|
||||
getFiles() {
|
||||
const rootPath = '/';
|
||||
return seafileAPI.listDir(repoID, rootPath, { recursive: true} ).then((response) => {
|
||||
var files = response.data.dirent_list.map((item) => {
|
||||
return {
|
||||
name: item.name,
|
||||
type: item.type === 'dir' ? 'dir' : 'file',
|
||||
parent_path: item.parent_dir
|
||||
};
|
||||
});
|
||||
return files;
|
||||
});
|
||||
}
|
||||
|
||||
getFileHistory() {
|
||||
return seafileAPI.getFileHistory(repoID, filePath);
|
||||
}
|
||||
|
||||
getFileInfo() {
|
||||
return seafileAPI.getFileInfo(repoID, filePath);
|
||||
}
|
||||
|
||||
getRepoInfo(newRepoID) {
|
||||
return seafileAPI.getRepoInfo(newRepoID);
|
||||
}
|
||||
|
||||
getInternalLink() {
|
||||
return seafileAPI.getInternalLink(repoID, filePath);
|
||||
}
|
||||
|
||||
getShareLink() {
|
||||
return seafileAPI.getShareLink(repoID, filePath);
|
||||
}
|
||||
|
||||
createShareLink (repoID, filePath, userPassword, userValidDays, permissions) {
|
||||
return seafileAPI.createShareLink(repoID, filePath, userPassword, userValidDays, permissions);
|
||||
}
|
||||
|
||||
deleteShareLink(token){
|
||||
return seafileAPI.deleteShareLink(token);
|
||||
}
|
||||
|
||||
getDraftKey() {
|
||||
return (repoID + filePath);
|
||||
}
|
||||
|
||||
getFileContent(url) {
|
||||
return seafileAPI.getFileContent(url);
|
||||
}
|
||||
|
||||
listFileHistoryRecords(page, perPage) {
|
||||
return seafileAPI.listFileHistoryRecords(repoID, filePath, page, perPage);
|
||||
}
|
||||
|
||||
getFileHistoryVersion(commitID, filePath) {
|
||||
return seafileAPI.getFileRevision(repoID, commitID, filePath);
|
||||
}
|
||||
|
||||
getCommentsNumber() {
|
||||
return seafileAPI.getCommentsNumber(this.repoID, filePath);
|
||||
}
|
||||
|
||||
postComment(comment, detail) {
|
||||
return seafileAPI.postComment(this.repoID, this.filePath, comment, detail);
|
||||
}
|
||||
|
||||
listComments() {
|
||||
return seafileAPI.listComments(this.repoID, this.filePath);
|
||||
}
|
||||
|
||||
updateComment(commentID, resolved, detail, newComment) {
|
||||
return seafileAPI.updateComment(this.repoID, commentID, resolved, detail, newComment);
|
||||
}
|
||||
|
||||
deleteComment(commentID) {
|
||||
return seafileAPI.deleteComment(this.repoID, commentID);
|
||||
}
|
||||
|
||||
getUserAvatar(size) {
|
||||
return seafileAPI.getUserAvatar(userName, size);
|
||||
}
|
||||
|
||||
goDraftPage() {
|
||||
window.location.href = serviceUrl + '/drafts/' + draftID + '/';
|
||||
}
|
||||
|
||||
createDraftFile() {
|
||||
return seafileAPI.createDraft(repoID, filePath).then(res => {
|
||||
window.location.href = serviceUrl + '/lib/' + res.data.origin_repo_id + '/file' + Utils.encodePath(res.data.draft_file_path) + '?mode=edit';
|
||||
});
|
||||
}
|
||||
|
||||
publishDraftFile() {
|
||||
return seafileAPI.publishDraft(draftID).then(res => {
|
||||
window.location.href = serviceUrl + '/lib/' + repoID + '/file' + Utils.encodePath(res.data.published_file_path);
|
||||
});
|
||||
}
|
||||
|
||||
fileMetaData() {
|
||||
return seafileAPI.fileMetaData(repoID, filePath);
|
||||
}
|
||||
|
||||
listFileTags = () => {
|
||||
return seafileAPI.listFileTags(repoID, filePath);
|
||||
}
|
||||
|
||||
listRepoTags = () => {
|
||||
return seafileAPI.listRepoTags(repoID);
|
||||
}
|
||||
|
||||
markdownLint(slateValue) {
|
||||
return seafileAPI.markdownLint(slateValue);
|
||||
}
|
||||
|
||||
listFileParticipant() {
|
||||
return seafileAPI.listFileParticipants(repoID, filePath);
|
||||
}
|
||||
|
||||
addFileParticipants(emails) {
|
||||
return seafileAPI.addFileParticipants(repoID, filePath, emails);
|
||||
}
|
||||
|
||||
listRepoRelatedUsers() {
|
||||
return seafileAPI.listRepoRelatedUsers(repoID);
|
||||
}
|
||||
}
|
||||
|
||||
const editorApi = new EditorApi();
|
||||
|
||||
export default editorApi;
|
@ -1,252 +1,31 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import { SeafileEditor } from '@seafile/seafile-editor/dist/editor/editor.js';
|
||||
import 'whatwg-fetch';
|
||||
import { seafileAPI } from './utils/seafile-api';
|
||||
import { Utils } from './utils/utils';
|
||||
import { gettext, isDocs, mediaUrl } from './utils/constants';
|
||||
import io from 'socket.io-client';
|
||||
import toaster from './components/toast';
|
||||
import ModalPortal from './components/modal-portal';
|
||||
import ShareDialog from './components/dialog/share-dialog';
|
||||
import InsertFileDialog from './components/dialog/insert-file-dialog';
|
||||
import InsertRepoImageDialog from './components/dialog/insert-repo-image-dialog';
|
||||
import FileParticipantDialog from './components/dialog/file-participant-dialog';
|
||||
import { SeafileEditor } from '@seafile/seafile-editor/dist/editor/editor.js';
|
||||
import { serialize, deserialize } from '@seafile/seafile-editor/dist/utils/slate2markdown';
|
||||
import LocalDraftDialog from './components/dialog/local-draft-dialog';
|
||||
import MarkdownViewerToolbar from './components/toolbar/markdown-viewer-toolbar';
|
||||
import EditFileTagDialog from './components/dialog/edit-filetag-dialog';
|
||||
import 'whatwg-fetch';
|
||||
import { Utils } from '../../utils/utils';
|
||||
import { seafileAPI } from '../../utils/seafile-api';
|
||||
import { gettext, isDocs, mediaUrl } from '../../utils/constants';
|
||||
import toaster from '../../components/toast';
|
||||
import ModalPortal from '../../components/modal-portal';
|
||||
import ShareDialog from '../../components/dialog/share-dialog';
|
||||
import InsertFileDialog from '../../components/dialog/insert-file-dialog';
|
||||
import LocalDraftDialog from '../../components/dialog/local-draft-dialog';
|
||||
import EditFileTagDialog from '../../components/dialog/edit-filetag-dialog';
|
||||
import InsertRepoImageDialog from '../../components/dialog/insert-repo-image-dialog';
|
||||
import FileParticipantDialog from '../../components/dialog/file-participant-dialog';
|
||||
import MarkdownViewerToolbar from '../../components/toolbar/markdown-viewer-toolbar';
|
||||
import editorApi from './editor-api';
|
||||
|
||||
import './css/markdown-viewer/markdown-editor.css';
|
||||
import '../../css/markdown-viewer/markdown-editor.css';
|
||||
|
||||
const CryptoJS = require('crypto-js');
|
||||
const URL = require('url-parse');
|
||||
const { repoID, repoName, filePath, fileName, mode, draftID, isDraft, hasDraft, isLocked, lockedByMe } = window.app.pageOptions;
|
||||
const { repoID, filePath, fileName, draftID, isDraft, hasDraft, isLocked, lockedByMe } = window.app.pageOptions;
|
||||
const { siteRoot, serviceUrl, seafileCollabServer } = window.app.config;
|
||||
const userInfo = window.app.userInfo;
|
||||
const userName = userInfo.username;
|
||||
let dirPath = Utils.getDirName(filePath);
|
||||
const IMAGE_SUFFIXES = ['png', 'PNG', 'jpg', 'JPG', 'jpeg', 'JPEG', 'gif', 'GIF'];
|
||||
|
||||
function getImageFileNameWithTimestamp() {
|
||||
var d = Date.now();
|
||||
return 'image-' + d.toString() + '.png';
|
||||
}
|
||||
|
||||
|
||||
class EditorApi {
|
||||
|
||||
constructor () {
|
||||
this.repoID = repoID;
|
||||
this.filePath = filePath;
|
||||
this.serviceUrl = serviceUrl;
|
||||
this.name = userInfo.name;
|
||||
this.contact_email = userInfo.contact_email;
|
||||
this.fileName = fileName;
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
saveContent(content) {
|
||||
return (
|
||||
seafileAPI.getUpdateLink(repoID, dirPath).then((res) => {
|
||||
const uploadLink = res.data;
|
||||
return seafileAPI.updateFile(uploadLink, filePath, fileName, content);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
unstarItem () {
|
||||
return (
|
||||
seafileAPI.unstarItem(this.repoID, this.filePath)
|
||||
);
|
||||
}
|
||||
|
||||
starItem() {
|
||||
return (
|
||||
seafileAPI.starItem(this.repoID, this.filePath)
|
||||
);
|
||||
}
|
||||
|
||||
getParentDectionaryUrl() {
|
||||
let parentPath = this.filePath.substring(0, this.filePath.lastIndexOf('/'));
|
||||
let libName = encodeURIComponent(repoName);
|
||||
let path = Utils.encodePath(parentPath);
|
||||
return this.serviceUrl + '/library/' + this.repoID + '/' + libName + path;
|
||||
}
|
||||
|
||||
_getImageURL(fileName) {
|
||||
const url = this.serviceUrl + '/lib/' + repoID + '/file/images/auto-upload/' + fileName + '?raw=1';
|
||||
return url;
|
||||
}
|
||||
|
||||
uploadLocalImage = (imageFile) => {
|
||||
return (
|
||||
seafileAPI.getFileServerUploadLink(repoID, '/').then((res) => {
|
||||
const uploadLink = res.data + '?ret-json=1';
|
||||
const name = getImageFileNameWithTimestamp();
|
||||
const newFile = new File([imageFile], name, {type: imageFile.type});
|
||||
const formData = new FormData();
|
||||
formData.append('parent_dir', '/');
|
||||
formData.append('relative_path', 'images/auto-upload');
|
||||
formData.append('file', newFile);
|
||||
return seafileAPI.uploadImage(uploadLink, formData);
|
||||
}).then ((res) => {
|
||||
return this._getImageURL(res.data[0].name);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
getFileURL(fileNode) {
|
||||
var url;
|
||||
if (fileNode.type === 'file') {
|
||||
if (fileNode.isImage()) {
|
||||
url = serviceUrl + '/lib/' + repoID + '/file' + Utils.encodePath(fileNode.path()) + '?raw=1';
|
||||
} else {
|
||||
url = serviceUrl + '/lib/' + repoID + '/file' + Utils.encodePath(fileNode.path());
|
||||
}
|
||||
} else {
|
||||
url = serviceUrl + '/library/' + repoID + '/' + encodeURIComponent(repoName) + Utils.encodePath(fileNode.path());
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
isInternalFileLink(url) {
|
||||
var re = new RegExp(this.serviceUrl + '/lib/[0-9a-f-]{36}/file.*');
|
||||
return re.test(url);
|
||||
}
|
||||
|
||||
isInternalDirLink(url) {
|
||||
var re = new RegExp(serviceUrl + '/library/' + '[0-9a-f\-]{36}.*');
|
||||
return re.test(url);
|
||||
}
|
||||
|
||||
getFiles() {
|
||||
const rootPath = '/';
|
||||
return seafileAPI.listDir(repoID, rootPath, { recursive: true} ).then((response) => {
|
||||
var files = response.data.dirent_list.map((item) => {
|
||||
return {
|
||||
name: item.name,
|
||||
type: item.type === 'dir' ? 'dir' : 'file',
|
||||
parent_path: item.parent_dir
|
||||
};
|
||||
});
|
||||
return files;
|
||||
});
|
||||
}
|
||||
|
||||
getFileHistory() {
|
||||
return seafileAPI.getFileHistory(repoID, filePath);
|
||||
}
|
||||
|
||||
getFileInfo() {
|
||||
return seafileAPI.getFileInfo(repoID, filePath);
|
||||
}
|
||||
|
||||
getRepoInfo(newRepoID) {
|
||||
return seafileAPI.getRepoInfo(newRepoID);
|
||||
}
|
||||
|
||||
getInternalLink() {
|
||||
return seafileAPI.getInternalLink(repoID, filePath);
|
||||
}
|
||||
|
||||
getShareLink() {
|
||||
return seafileAPI.getShareLink(repoID, filePath);
|
||||
}
|
||||
|
||||
createShareLink (repoID, filePath, userPassword, userValidDays, permissions) {
|
||||
return seafileAPI.createShareLink(repoID, filePath, userPassword, userValidDays, permissions);
|
||||
}
|
||||
|
||||
deleteShareLink(token){
|
||||
return seafileAPI.deleteShareLink(token);
|
||||
}
|
||||
|
||||
getDraftKey() {
|
||||
return (repoID + filePath);
|
||||
}
|
||||
|
||||
getFileContent(url) {
|
||||
return seafileAPI.getFileContent(url);
|
||||
}
|
||||
|
||||
listFileHistoryRecords(page, perPage) {
|
||||
return seafileAPI.listFileHistoryRecords(repoID, filePath, page, perPage);
|
||||
}
|
||||
|
||||
getFileHistoryVersion(commitID, filePath) {
|
||||
return seafileAPI.getFileRevision(repoID, commitID, filePath);
|
||||
}
|
||||
|
||||
getCommentsNumber() {
|
||||
return seafileAPI.getCommentsNumber(this.repoID, filePath);
|
||||
}
|
||||
|
||||
postComment(comment, detail) {
|
||||
return seafileAPI.postComment(this.repoID, this.filePath, comment, detail);
|
||||
}
|
||||
|
||||
listComments() {
|
||||
return seafileAPI.listComments(this.repoID, this.filePath);
|
||||
}
|
||||
|
||||
updateComment(commentID, resolved, detail, newComment) {
|
||||
return seafileAPI.updateComment(this.repoID, commentID, resolved, detail, newComment);
|
||||
}
|
||||
|
||||
deleteComment(commentID) {
|
||||
return seafileAPI.deleteComment(this.repoID, commentID);
|
||||
}
|
||||
|
||||
getUserAvatar(size) {
|
||||
return seafileAPI.getUserAvatar(userName, size);
|
||||
}
|
||||
|
||||
goDraftPage() {
|
||||
window.location.href = serviceUrl + '/drafts/' + draftID + '/';
|
||||
}
|
||||
|
||||
createDraftFile() {
|
||||
return seafileAPI.createDraft(repoID, filePath).then(res => {
|
||||
window.location.href = serviceUrl + '/lib/' + res.data.origin_repo_id + '/file' + Utils.encodePath(res.data.draft_file_path) + '?mode=edit';
|
||||
});
|
||||
}
|
||||
|
||||
publishDraftFile() {
|
||||
return seafileAPI.publishDraft(draftID).then(res => {
|
||||
window.location.href = serviceUrl + '/lib/' + repoID + '/file' + Utils.encodePath(res.data.published_file_path);
|
||||
});
|
||||
}
|
||||
|
||||
fileMetaData() {
|
||||
return seafileAPI.fileMetaData(repoID, filePath);
|
||||
}
|
||||
|
||||
listFileTags = () => {
|
||||
return seafileAPI.listFileTags(repoID, filePath);
|
||||
}
|
||||
|
||||
listRepoTags = () => {
|
||||
return seafileAPI.listRepoTags(repoID);
|
||||
}
|
||||
|
||||
markdownLint(slateValue) {
|
||||
return seafileAPI.markdownLint(slateValue);
|
||||
}
|
||||
|
||||
listFileParticipant() {
|
||||
return seafileAPI.listFileParticipants(repoID, filePath);
|
||||
}
|
||||
|
||||
addFileParticipants(emails) {
|
||||
return seafileAPI.addFileParticipants(repoID, filePath, emails);
|
||||
}
|
||||
|
||||
listRepoRelatedUsers() {
|
||||
return seafileAPI.listRepoRelatedUsers(repoID);
|
||||
}
|
||||
}
|
||||
|
||||
const editorApi = new EditorApi();
|
||||
|
||||
class MarkdownEditor extends React.Component {
|
||||
constructor(props) {
|
||||
@ -503,7 +282,6 @@ class MarkdownEditor extends React.Component {
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
||||
this.socket.emit('repo_update', {
|
||||
request: 'unwatch_update',
|
||||
repo_id: editorApi.repoID,
|
Loading…
Reference in New Issue
Block a user