mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-12 13:24:52 +00:00
Update public wiki (#2868)
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import MarkdownViewer from '@seafile/seafile-editor/dist/viewer/markdown-viewer';
|
||||
import { gettext } from '../utils/constants';
|
||||
import { gettext, repoID, slug, serviceURL, isPublicWiki } from '../utils/constants';
|
||||
import Loading from './loading';
|
||||
import { Utils } from '../utils/utils';
|
||||
|
||||
const propTypes = {
|
||||
children: PropTypes.object,
|
||||
@@ -10,7 +11,8 @@ const propTypes = {
|
||||
markdownContent: PropTypes.string.isRequired,
|
||||
latestContributor: PropTypes.string.isRequired,
|
||||
lastModified: PropTypes.string.isRequired,
|
||||
onLinkClick: PropTypes.func.isRequired
|
||||
onLinkClick: PropTypes.func.isRequired,
|
||||
isWiki: PropTypes.bool
|
||||
};
|
||||
|
||||
const contentClass = 'wiki-page-content';
|
||||
@@ -102,6 +104,76 @@ class WikiMarkdownViewer extends React.Component {
|
||||
this.setState({activeTitleIndex: activeTitleIndex});
|
||||
}
|
||||
|
||||
changeInlineNode = (item) => {
|
||||
if (item.object == 'inline') {
|
||||
let url;
|
||||
|
||||
// change image url
|
||||
if (item.type == 'image' && isPublicWiki) {
|
||||
url = item.data.src;
|
||||
const re = new RegExp(serviceURL + '/lib/' + repoID +'/file.*raw=1');
|
||||
// different repo
|
||||
if (!re.test(url)) {
|
||||
return;
|
||||
}
|
||||
// get image path
|
||||
let index = url.indexOf('/file');
|
||||
let index2 = url.indexOf('?');
|
||||
const imagePath = url.substring(index + 5, index2);
|
||||
// replace url
|
||||
item.data.src = serviceURL + '/view-image-via-public-wiki/?slug=' + slug + '&path=' + imagePath;
|
||||
}
|
||||
|
||||
else if (item.type == 'link') {
|
||||
url = item.data.href;
|
||||
// change file url
|
||||
if (Utils.isInternalMarkdownLink(url, repoID)) {
|
||||
let path = Utils.getPathFromInternalMarkdownLink(url, repoID);
|
||||
// replace url
|
||||
item.data.href = serviceURL + '/wikis/' + slug + path;
|
||||
}
|
||||
// change dir url
|
||||
else if (Utils.isInternalDirLink(url, repoID)) {
|
||||
let path = Utils.getPathFromInternalDirLink(url, repoID, slug);
|
||||
// replace url
|
||||
item.data.href = serviceURL + '/wikis/' + slug + path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
modifyValueBeforeRender = (value) => {
|
||||
let nodes = value.document.nodes;
|
||||
let newNodes = Utils.changeMarkdownNodes(nodes, this.changeInlineNode);
|
||||
value.document.nodes = newNodes;
|
||||
return value;
|
||||
}
|
||||
|
||||
renderMarkdown = () => {
|
||||
if (this.props.isWiki) {
|
||||
return (
|
||||
<MarkdownViewer
|
||||
showTOC={true}
|
||||
markdownContent={this.props.markdownContent}
|
||||
activeTitleIndex={this.state.activeTitleIndex}
|
||||
onContentRendered={this.onContentRendered}
|
||||
modifyValueBeforeRender={this.modifyValueBeforeRender}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<MarkdownViewer
|
||||
showTOC={true}
|
||||
markdownContent={this.props.markdownContent}
|
||||
activeTitleIndex={this.state.activeTitleIndex}
|
||||
onContentRendered={this.onContentRendered}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.props.isFileLoading) {
|
||||
return <Loading />
|
||||
@@ -110,12 +182,7 @@ class WikiMarkdownViewer extends React.Component {
|
||||
<div ref={this.markdownContainer} className="wiki-page-container" onScroll={this.onScrollHandler.bind(this)}>
|
||||
<div className={contentClass}>
|
||||
{this.props.children}
|
||||
<MarkdownViewer
|
||||
showTOC={true}
|
||||
markdownContent={this.props.markdownContent}
|
||||
activeTitleIndex={this.state.activeTitleIndex}
|
||||
onContentRendered={this.onContentRendered}
|
||||
/>
|
||||
{this.renderMarkdown()}
|
||||
<p id="wiki-page-last-modified">{gettext('Last modified by')} {this.props.latestContributor}, <span>{this.props.lastModified}</span></p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -123,6 +190,11 @@ class WikiMarkdownViewer extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
const defaultProps = {
|
||||
isWiki: false,
|
||||
}
|
||||
|
||||
WikiMarkdownViewer.propTypes = propTypes;
|
||||
MarkdownViewer.defaultProps = defaultProps;
|
||||
|
||||
export default WikiMarkdownViewer;
|
||||
|
@@ -117,6 +117,7 @@ class MainPanel extends Component {
|
||||
lastModified = {this.props.lastModified}
|
||||
latestContributor={this.props.latestContributor}
|
||||
onLinkClick={this.props.onLinkClick}
|
||||
isWiki={true}
|
||||
/>
|
||||
}
|
||||
{!this.props.isViewFileState &&
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import Account from './components/common/account';
|
||||
import { gettext, siteRoot, mediaUrl, logoPath, logoWidth, logoHeight, siteTitle } from './utils/constants';
|
||||
import { serviceURL, gettext, siteRoot, mediaUrl, logoPath, logoWidth, logoHeight, siteTitle } from './utils/constants';
|
||||
import { Button } from 'reactstrap';
|
||||
import { seafileAPI } from './utils/seafile-api';
|
||||
import { Utils } from './utils/utils';
|
||||
@@ -17,7 +17,7 @@ import './assets/css/fa-regular.css';
|
||||
import './assets/css/fontawesome.css';
|
||||
|
||||
let loginUser = window.app.pageOptions.name;
|
||||
const { serviceURL, repoID, sharedToken, trafficOverLimit, fileName, fileSize, rawPath, sharedBy, siteName, enableWatermark, download } = window.shared.pageOptions;
|
||||
const { repoID, sharedToken, trafficOverLimit, fileName, fileSize, rawPath, sharedBy, siteName, enableWatermark, download } = window.shared.pageOptions;
|
||||
|
||||
class SharedFileViewMarkdown extends React.Component {
|
||||
|
||||
@@ -62,6 +62,33 @@ class SharedFileViewMarkdown extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
changeImageURL = (innerNode) => {
|
||||
if (innerNode.type == 'image') {
|
||||
let imageUrl = innerNode.data.src;
|
||||
|
||||
const re = new RegExp(serviceURL + '/lib/' + repoID +'/file.*raw=1');
|
||||
|
||||
// different repo
|
||||
if (!re.test(imageUrl)) {
|
||||
return;
|
||||
}
|
||||
// get image path
|
||||
let index = imageUrl.indexOf('/file');
|
||||
let index2 = imageUrl.indexOf('?');
|
||||
const imagePath = imageUrl.substring(index + 5, index2);
|
||||
// change image url
|
||||
innerNode.data.src = serviceURL + '/view-image-via-share-link/?token=' + sharedToken + '&path=' + imagePath;
|
||||
}
|
||||
return innerNode;
|
||||
}
|
||||
|
||||
modifyValueBeforeRender = (value) => {
|
||||
let nodes = value.document.nodes;
|
||||
let newNodes = Utils.changeMarkdownNodes(nodes, this.changeImageURL);
|
||||
value.document.nodes = newNodes;
|
||||
return value;
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.loading) {
|
||||
return <Loading />
|
||||
@@ -102,9 +129,9 @@ class SharedFileViewMarkdown extends React.Component {
|
||||
<MarkdownViewer markdownContent={this.state.markdownContent}
|
||||
showTOC={false}
|
||||
serviceURL={serviceURL}
|
||||
isShared={true}
|
||||
sharedToken={sharedToken}
|
||||
repoID={repoID}
|
||||
modifyValueBeforeRender={this.modifyValueBeforeRender}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -13,6 +13,7 @@ export const isPro = window.app.config.isPro === 'True';
|
||||
export const lang = window.app.config.lang;
|
||||
export const fileServerRoot = window.app.config.fileServerRoot;
|
||||
export const seafileVersion = window.app.config.seafileVersion;
|
||||
export const serviceURL = window.app.config.serviceURL;
|
||||
|
||||
//pageOptions
|
||||
export const seafileCollabServer = window.app.pageOptions.seafileCollabServer;
|
||||
@@ -46,6 +47,7 @@ export const initialPath = window.wiki ? window.wiki.config.initial_path : '';
|
||||
export const permission = window.wiki ? window.wiki.config.permission === 'True' : '';
|
||||
export const isDir = window.wiki ? window.wiki.config.isDir : '';
|
||||
export const serviceUrl = window.wiki ? window.wiki.config.serviceUrl : '';
|
||||
export const isPublicWiki = window.wiki ? window.wiki.config.isPublicWiki === 'True': '';
|
||||
|
||||
// file history
|
||||
export const PER_PAGE = 25;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { mediaUrl, gettext, siteRoot } from './constants';
|
||||
import { mediaUrl, gettext, serviceURL } from './constants';
|
||||
import { strChineseFirstPY } from './pinyin-by-unicode';
|
||||
|
||||
export const Utils = {
|
||||
@@ -404,30 +404,59 @@ export const Utils = {
|
||||
},
|
||||
|
||||
isInternalMarkdownLink: function(url, repoID) {
|
||||
var re = new RegExp(siteRoot + 'lib/' + repoID + '.*\.md$');
|
||||
var re = new RegExp(serviceURL + '/lib/' + repoID + '.*\.md$');
|
||||
return re.test(url);
|
||||
},
|
||||
|
||||
isInternalDirLink: function(url, repoID) {
|
||||
var re = new RegExp(siteRoot + 'library/' + repoID + '.*');
|
||||
var re = new RegExp(serviceURL + '/library/' + repoID + '.*');
|
||||
return re.test(url);
|
||||
},
|
||||
|
||||
getPathFromInternalMarkdownLink: function(url, repoID) {
|
||||
var re = new RegExp(siteRoot + 'lib/' + repoID + '/file' + '(.*\.md)');
|
||||
var re = new RegExp(serviceURL + '/lib/' + repoID + '/file' + '(.*\.md)');
|
||||
var array = re.exec(url);
|
||||
var path = decodeURIComponent(array[1]);
|
||||
return path;
|
||||
},
|
||||
|
||||
getPathFromInternalDirLink: function(url, repoID, repoName) {
|
||||
var re = new RegExp(siteRoot + 'library/' + repoID + '/' + repoName + '(/.*)');
|
||||
var repoName = encodeURIComponent(repoName);
|
||||
var re = new RegExp(serviceURL + '/library/' + repoID + '/' + repoName + '(/.*)');
|
||||
var array = re.exec(url);
|
||||
var path = decodeURIComponent(array[1]);
|
||||
|
||||
return path;
|
||||
},
|
||||
|
||||
isWikiInternalMarkdownLink: function(url, slug) {
|
||||
var slug = encodeURIComponent(slug);
|
||||
var re = new RegExp(serviceURL + '/wikis/' + slug + '.*\.md$');
|
||||
return re.test(url);
|
||||
},
|
||||
|
||||
isWikiInternalDirLink: function(url, slug) {
|
||||
var slug = encodeURIComponent(slug);
|
||||
var re = new RegExp(serviceURL + '/wikis/' + slug + '.*');
|
||||
return re.test(url);
|
||||
},
|
||||
|
||||
getPathFromWikiInternalMarkdownLink: function(url, slug) {
|
||||
var slug = encodeURIComponent(slug);
|
||||
var re = new RegExp(serviceURL + '/wikis/' + slug + '(.*\.md)');
|
||||
var array = re.exec(url);
|
||||
var path = decodeURIComponent(array[1]);
|
||||
return path;
|
||||
},
|
||||
|
||||
getPathFromWikiInternalDirLink: function(url, slug) {
|
||||
var slug = encodeURIComponent(slug);
|
||||
var re = new RegExp(serviceURL + '/wikis/' + slug+ '(/.*)');
|
||||
var array = re.exec(url);
|
||||
var path = decodeURIComponent(array[1]);
|
||||
return path;
|
||||
},
|
||||
|
||||
compareTwoWord: function(wordA, wordB) {
|
||||
// compare wordA and wordB at lower case
|
||||
// if wordA >= wordB, return 1
|
||||
@@ -577,6 +606,17 @@ export const Utils = {
|
||||
}
|
||||
});
|
||||
return items;
|
||||
}
|
||||
},
|
||||
|
||||
changeMarkdownNodes: function(nodes, fn) {
|
||||
nodes.map((item) => {
|
||||
fn(item);
|
||||
if (item.nodes && item.nodes.length > 0){
|
||||
Utils.changeMarkdownNodes(item.nodes, fn);
|
||||
}
|
||||
});
|
||||
|
||||
return nodes;
|
||||
},
|
||||
|
||||
};
|
||||
|
@@ -119,11 +119,11 @@ class Wiki extends Component {
|
||||
|
||||
onLinkClick = (link) => {
|
||||
const url = link;
|
||||
if (Utils.isInternalMarkdownLink(url, repoID)) {
|
||||
let path = Utils.getPathFromInternalMarkdownLink(url, repoID);
|
||||
if (Utils.isWikiInternalMarkdownLink(url, slug)) {
|
||||
let path = Utils.getPathFromWikiInternalMarkdownLink(url, slug);
|
||||
this.initMainPanelData(path);
|
||||
} else if (Utils.isInternalDirLink(url, repoID)) {
|
||||
let path = Utils.getPathFromInternalDirLink(url, repoID, slug);
|
||||
} else if (Utils.isWikiInternalDirLink(url, slug)) {
|
||||
let path = Utils.getPathFromWikiInternalDirLink(url, slug);
|
||||
this.initWikiData(path);
|
||||
} else {
|
||||
window.location.href = url;
|
||||
|
Reference in New Issue
Block a user