mirror of
https://github.com/haiwen/seahub.git
synced 2025-04-28 03:10:45 +00:00
add excalidraw viewer (#7719)
Co-authored-by: 小强 <shuntian@xiaoqiangdeMacBook-Pro.local>
This commit is contained in:
parent
1be01e5186
commit
2e5b2797b3
@ -25,6 +25,7 @@ const entryFiles = {
|
||||
sharedFileViewAudio: '/shared-file-view-audio.js',
|
||||
sharedFileViewDocument: '/shared-file-view-document.js',
|
||||
sharedFileViewSpreadsheet: '/shared-file-view-spreadsheet.js',
|
||||
sharedFileViewExdraw: '/shared-file-view-exdraw.js',
|
||||
sharedFileViewSdoc: '/shared-file-view-sdoc.js',
|
||||
sharedFileViewUnknown: '/shared-file-view-unknown.js',
|
||||
historyTrashFileView: '/history-trash-file-view.js',
|
||||
|
15
frontend/src/pages/excalidraw-viewer/constants.js
Normal file
15
frontend/src/pages/excalidraw-viewer/constants.js
Normal file
@ -0,0 +1,15 @@
|
||||
export const SAVE_INTERVAL_TIME = 3 * 60 * 1000;
|
||||
|
||||
export const langList = {
|
||||
'zh-cn': 'zh-CN',
|
||||
'en': 'en',
|
||||
'zh-tw': 'zh-TW',
|
||||
'ru': 'ru-RU',
|
||||
'it': 'it-IT',
|
||||
'fr': 'fr-FR',
|
||||
'es-ms': 'en',
|
||||
'es-ar': 'en',
|
||||
'es': 'es-ES',
|
||||
'de': 'de-DE',
|
||||
'cs': 'cs-CZ',
|
||||
};
|
26
frontend/src/pages/excalidraw-viewer/editor-api.js
Normal file
26
frontend/src/pages/excalidraw-viewer/editor-api.js
Normal file
@ -0,0 +1,26 @@
|
||||
import { seafileAPI } from '../../utils/seafile-api';
|
||||
import { Utils } from '../../utils/utils';
|
||||
|
||||
const { repoID, filePath, fileName } = window.shared.pageOptions;
|
||||
let dirPath = Utils.getDirName(filePath);
|
||||
|
||||
class EditorApi {
|
||||
|
||||
saveContent(content) {
|
||||
return seafileAPI.getUpdateLink(repoID, dirPath).then((res) => {
|
||||
const uploadLink = res.data;
|
||||
return seafileAPI.updateFile(uploadLink, filePath, fileName, content);
|
||||
});
|
||||
}
|
||||
|
||||
getFileContent = () => {
|
||||
return seafileAPI.getFileDownloadLink(repoID, filePath).then(res => {
|
||||
const downLoadUrl = res.data;
|
||||
return seafileAPI.getFileContent(downLoadUrl);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
const editorApi = new EditorApi();
|
||||
|
||||
export default editorApi;
|
8
frontend/src/pages/excalidraw-viewer/index.css
Normal file
8
frontend/src/pages/excalidraw-viewer/index.css
Normal file
@ -0,0 +1,8 @@
|
||||
.dropdown-menu {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.excalidraw .dropdown-menu {
|
||||
--bs-dropdown-padding-x: auto;
|
||||
border: unset;
|
||||
}
|
31
frontend/src/pages/excalidraw-viewer/index.js
Normal file
31
frontend/src/pages/excalidraw-viewer/index.js
Normal file
@ -0,0 +1,31 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import SimpleViewer from './simple-viewer';
|
||||
import editorApi from './editor-api';
|
||||
|
||||
import './index.css';
|
||||
|
||||
const ExcaliViewer = () => {
|
||||
const [fileContent, setFileContent] = useState(null);
|
||||
const [isFetching, setIsFetching] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
editorApi.getFileContent().then(res => {
|
||||
if (res.data?.appState?.collaborators && !Array.isArray(res.data.appState.collaborators)) {
|
||||
// collaborators.forEach is not a function
|
||||
res.data['appState']['collaborators'] = [];
|
||||
}
|
||||
setFileContent(res.data);
|
||||
setIsFetching(false);
|
||||
});
|
||||
}, []);
|
||||
|
||||
|
||||
return (
|
||||
<SimpleViewer
|
||||
isFetching={isFetching}
|
||||
sceneContent={fileContent}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default ExcaliViewer;
|
50
frontend/src/pages/excalidraw-viewer/simple-viewer.js
Normal file
50
frontend/src/pages/excalidraw-viewer/simple-viewer.js
Normal file
@ -0,0 +1,50 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Excalidraw, MainMenu } from '@excalidraw/excalidraw';
|
||||
import CodeMirrorLoading from '../../components/code-mirror-loading';
|
||||
import { langList } from './constants';
|
||||
|
||||
import '@excalidraw/excalidraw/index.css';
|
||||
|
||||
const SimpleViewer = ({ sceneContent = null, isFetching }) => {
|
||||
const [excalidrawAPI, setExcalidrawAPI] = useState(null);
|
||||
const UIOptions = {
|
||||
canvasActions: {
|
||||
saveToActiveFile: false,
|
||||
LoadScene: false
|
||||
},
|
||||
tools: { image: false },
|
||||
};
|
||||
|
||||
if (isFetching) {
|
||||
return (
|
||||
<div className='excali-container'>
|
||||
<CodeMirrorLoading />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='excali-container' style={{ height: '100vh', width: '100vw' }}>
|
||||
<Excalidraw
|
||||
initialData={sceneContent}
|
||||
excalidrawAPI={(api) => setExcalidrawAPI(api)}
|
||||
UIOptions={UIOptions}
|
||||
langCode={langList[window.app.config.lang] || 'en'}
|
||||
viewModeEnabled={true}
|
||||
>
|
||||
<MainMenu>
|
||||
<MainMenu.DefaultItems.Export />
|
||||
<MainMenu.DefaultItems.SaveAsImage />
|
||||
<MainMenu.DefaultItems.Help />
|
||||
<MainMenu.DefaultItems.ClearCanvas />
|
||||
<MainMenu.DefaultItems.ToggleTheme />
|
||||
<MainMenu.DefaultItems.ChangeCanvasBackground />
|
||||
</MainMenu>
|
||||
</Excalidraw>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default SimpleViewer;
|
39
frontend/src/shared-file-view-exdraw.js
Normal file
39
frontend/src/shared-file-view-exdraw.js
Normal file
@ -0,0 +1,39 @@
|
||||
import React from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import { Utils } from './utils/utils';
|
||||
import ExcaliViewer from './pages/excalidraw-viewer';
|
||||
|
||||
const { siteRoot, avatarURL } = window.app.config;
|
||||
const { username } = window.app.pageOptions;
|
||||
const {
|
||||
repoID,
|
||||
canDownload,
|
||||
canEdit,
|
||||
fileName,
|
||||
assetsUrl,
|
||||
sharedFileDownloadURL,
|
||||
} = window.shared.pageOptions;
|
||||
|
||||
// share permission of this sdoc
|
||||
const sharePermission = { 'can_edit': canEdit, 'can_download': canDownload, 'can_upload': false };
|
||||
const sharePermissionStr = Utils.getShareLinkPermissionStr(sharePermission);
|
||||
const sharePermissionText = Utils.getShareLinkPermissionObject(sharePermissionStr).text;
|
||||
|
||||
window.seafile = {
|
||||
repoID,
|
||||
username,
|
||||
avatarURL,
|
||||
siteRoot,
|
||||
sharePermissionText: sharePermissionText,
|
||||
downloadURL: sharedFileDownloadURL,
|
||||
assetsUrl,
|
||||
};
|
||||
|
||||
(function () {
|
||||
const fileIcon = Utils.getFileIconUrl(fileName);
|
||||
document.getElementById('favicon').href = fileIcon;
|
||||
})();
|
||||
|
||||
|
||||
const root = createRoot(document.getElementById('wrapper'));
|
||||
root.render(<ExcaliViewer />);
|
@ -5,18 +5,18 @@
|
||||
{% block sub_title %}{{file_name}} - {% endblock %}
|
||||
|
||||
{% block extra_ogp_tags %}
|
||||
<meta property="og:type" content="object" />
|
||||
<meta property="og:type" content="object">
|
||||
<meta property="og:site_name" content="{{ site_name }}">
|
||||
<meta property="og:url" content="{{ service_url }}{{ file_share_link }}" />
|
||||
<meta property="og:title" content="{{ file_name }}" />
|
||||
<meta property="og:image" content="{{ service_url }}{{ MEDIA_URL }}img/file/{{ icon_path_for_ogp }}" />
|
||||
<meta property="og:description" content="{{ desc_for_ogp }}" />
|
||||
<meta property="og:url" content="{{ service_url }}{{ file_share_link }}">
|
||||
<meta property="og:title" content="{{ file_name }}">
|
||||
<meta property="og:image" content="{{ service_url }}{{ MEDIA_URL }}img/file/{{ icon_path_for_ogp }}">
|
||||
<meta property="og:description" content="{{ desc_for_ogp }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_style %}
|
||||
{% if filetype == 'Markdown' %}
|
||||
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}seafile-editor/seafile-editor-font.css" />
|
||||
{% render_bundle 'sharedFileViewMarkdown' 'css' %}
|
||||
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}seafile-editor/seafile-editor-font.css">
|
||||
{% render_bundle 'sharedFileViewMarkdown' 'css' %}
|
||||
{% elif filetype == 'Text' %}
|
||||
{% render_bundle 'sharedFileViewText' 'css' %}
|
||||
{% elif filetype == 'Image' %}
|
||||
@ -28,20 +28,22 @@
|
||||
{% elif filetype == 'Audio' %}
|
||||
{% render_bundle 'sharedFileViewAudio' 'css' %}
|
||||
{% elif filetype == 'PDF' %}
|
||||
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}js/pdf/web/viewer.css" />
|
||||
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}js/pdf/web/custom.css" />
|
||||
<link rel="resource" type="application/l10n" href="{{ MEDIA_URL }}js/pdf/web/locale/locale.properties" />
|
||||
{% render_bundle 'sharedFileViewPDF' 'css' %}
|
||||
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}js/pdf/web/viewer.css">
|
||||
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}js/pdf/web/custom.css">
|
||||
<link rel="resource" type="application/l10n" href="{{ MEDIA_URL }}js/pdf/web/locale/locale.properties">
|
||||
{% render_bundle 'sharedFileViewPDF' 'css' %}
|
||||
{% elif filetype == 'Document' %}
|
||||
<link rel="resource" type="application/l10n" href="{{ MEDIA_URL }}js/pdf/web/locale/locale.properties" />
|
||||
{% render_bundle 'sharedFileViewDocument' 'css' %}
|
||||
<link rel="resource" type="application/l10n" href="{{ MEDIA_URL }}js/pdf/web/locale/locale.properties">
|
||||
{% render_bundle 'sharedFileViewDocument' 'css' %}
|
||||
{% elif filetype == 'SpreadSheet' %}
|
||||
{% render_bundle 'sharedFileViewSpreadsheet' 'css' %}
|
||||
{% elif filetype == 'SDoc' %}
|
||||
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}sdoc-editor/sdoc-editor-font.css" />
|
||||
{% render_bundle 'sharedFileViewSdoc' 'css' %}
|
||||
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}sdoc-editor/sdoc-editor-font.css">
|
||||
{% render_bundle 'sharedFileViewSdoc' 'css' %}
|
||||
{% elif filetype == 'Unknown' %}
|
||||
{% render_bundle 'sharedFileViewUnknown' 'css' %}
|
||||
{% elif filetype == 'Excalidraw' %}
|
||||
{% render_bundle 'sharedFileViewExdraw' 'css' %}
|
||||
{% endif %}
|
||||
{% if not permissions.can_download %}
|
||||
<style type="text/css">
|
||||
@ -81,7 +83,7 @@ body {
|
||||
fileExt: '{{ fileext }}',
|
||||
commitID: '{{ current_commit.id }}' || '{{ repo.head_cmmt_id }}',
|
||||
enableShareLinkReportAbuse: {% if enable_share_link_report_abuse %}true{% else %}false{% endif %},
|
||||
|
||||
|
||||
// for 'view file in shared dir'
|
||||
{% if zipped %}
|
||||
zipped: (function() {
|
||||
@ -127,25 +129,27 @@ body {
|
||||
{% render_bundle 'sharedFileViewAudio' 'js' %}
|
||||
{% elif filetype == 'PDF' %}
|
||||
{% render_bundle 'sharedFileViewPDF' 'js' %}
|
||||
<script type="text/javascript">
|
||||
<script type="text/javascript">
|
||||
var SEAFILE_FILE_URL = '{{ raw_path|escapejs }}';
|
||||
var SEAFILE_PDFJS_DIR = '{{MEDIA_URL}}js/pdf';
|
||||
</script>
|
||||
<script type="text/javascript" src="{{MEDIA_URL}}js/pdf/build/pdf.js"></script>
|
||||
<script type="text/javascript" src="{{MEDIA_URL}}js/pdf/web/viewer.js"></script>
|
||||
</script>
|
||||
<script type="text/javascript" src="{{MEDIA_URL}}js/pdf/build/pdf.js"></script>
|
||||
<script type="text/javascript" src="{{MEDIA_URL}}js/pdf/web/viewer.js"></script>
|
||||
{% elif filetype == 'Document' %}
|
||||
{% render_bundle 'sharedFileViewDocument' 'js' %}
|
||||
<script type="text/javascript">
|
||||
<script type="text/javascript">
|
||||
var commit_id = '{{ current_commit.id }}' || '{{ repo.head_cmmt_id }}';
|
||||
var SEAFILE_FILE_URL = '{{ SITE_ROOT }}office-convert/static/{{ repo.id }}/' + commit_id + '{{ path|urlencode }}/fake.pdf?token={{shared_token}}';
|
||||
var SEAFILE_PDFJS_DIR = '{{MEDIA_URL}}js/pdf';
|
||||
</script>
|
||||
<script type="text/javascript" src="{{MEDIA_URL}}js/pdf/build/pdf.js"></script>
|
||||
</script>
|
||||
<script type="text/javascript" src="{{MEDIA_URL}}js/pdf/build/pdf.js"></script>
|
||||
{% elif filetype == 'SpreadSheet' %}
|
||||
{% render_bundle 'sharedFileViewSpreadsheet' 'js' %}
|
||||
{% elif filetype == 'SDoc' %}
|
||||
{% render_bundle 'sharedFileViewSdoc' 'js' %}
|
||||
{% elif filetype == 'Unknown' %}
|
||||
{% render_bundle 'sharedFileViewUnknown' 'js' %}
|
||||
{% elif filetype == 'Excalidraw' %}
|
||||
{% render_bundle 'sharedFileViewExdraw' 'js' %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
Loading…
Reference in New Issue
Block a user