diff options
author | Julius Härtl <jus@bitgrid.net> | 2019-10-25 16:18:40 +0300 |
---|---|---|
committer | Julius Härtl <jus@bitgrid.net> | 2019-10-28 13:51:12 +0300 |
commit | 7b3edd3989e4656db414c20f5aad6541c9c39a1e (patch) | |
tree | bdcc9d3263b0e1268d963c9179a2ddd5f9e0d692 | |
parent | e322c247a347c703bdab35f0ba423114bc898d49 (diff) |
Add preview plugin
Signed-off-by: Julius Härtl <jus@bitgrid.net>
-rw-r--r-- | css/prosemirror.scss | 15 | ||||
-rw-r--r-- | css/style.scss | 11 | ||||
-rw-r--r-- | src/components/EditorWrapper.vue | 5 | ||||
-rw-r--r-- | src/components/ReadOnlyEditor.vue | 13 | ||||
-rw-r--r-- | src/files.js | 3 | ||||
-rw-r--r-- | src/files/PreviewPlugin.js | 92 |
6 files changed, 124 insertions, 15 deletions
diff --git a/css/prosemirror.scss b/css/prosemirror.scss index 4b4bae934..0cd43af70 100644 --- a/css/prosemirror.scss +++ b/css/prosemirror.scss @@ -1,5 +1,5 @@ /* Document rendering styles */ -#editor-wrapper .ProseMirror { +.ProseMirror { margin-top: 44px; height: 100%; position: relative; @@ -12,6 +12,17 @@ font-size: 14px; outline: none; + &[contenteditable=true], + &[contenteditable=false] { + border: none !important; + width: 100%; + background-color: transparent; + color: var(--color-main-text); + opacity: 1; + -webkit-user-select: text; + user-select: text; + } + p:first-child, h1:first-child, h2:first-child, @@ -133,7 +144,7 @@ .ProseMirror-focused .ProseMirror-gapcursor { display: block; } -#editor-wrapper:not(.richEditor) .ProseMirror { +&:not(.richEditor) .ProseMirror { pre { background-color: var(--color-main-background); diff --git a/css/style.scss b/css/style.scss index 1d0b944cf..b5923a2ca 100644 --- a/css/style.scss +++ b/css/style.scss @@ -52,14 +52,3 @@ li.ProseMirror-selectednode:after { visibility: hidden; } } - -div[contenteditable=true], -div[contenteditable=false] { - border: none !important; - width: 100%; - background-color: transparent; - color: var(--color-main-text); - opacity: 1; - -webkit-user-select: text; - user-select: text; -}
\ No newline at end of file diff --git a/src/components/EditorWrapper.vue b/src/components/EditorWrapper.vue index 877fc979a..8abaa0a3c 100644 --- a/src/components/EditorWrapper.vue +++ b/src/components/EditorWrapper.vue @@ -557,5 +557,8 @@ export default { </style> <style lang="scss"> @import './../../css/style'; - @import './../../css/prosemirror'; + + #editor-wrapper { + @import './../../css/prosemirror'; + } </style> diff --git a/src/components/ReadOnlyEditor.vue b/src/components/ReadOnlyEditor.vue index 43b4eee74..244ea812b 100644 --- a/src/components/ReadOnlyEditor.vue +++ b/src/components/ReadOnlyEditor.vue @@ -60,10 +60,21 @@ export default { } </script> -<style scoped lang="scss"> +<style lang="scss"> #read-only-editor { + @import './../../css/prosemirror'; overflow: scroll; } + .thumbnailContainer #read-only-editor { + width: 100%; + + .ProseMirror { + height: auto; + margin: 0 0 0 0; + padding: 0; + } + } + </style> diff --git a/src/files.js b/src/files.js index 4c17c4d3f..0ab1a7d32 100644 --- a/src/files.js +++ b/src/files.js @@ -21,6 +21,7 @@ */ import FilesEditor from './components/FilesEditor' +import PreviewPlugin from './files/PreviewPlugin' import { registerFileActionFallback, registerFileCreate } from './helpers/files' import { openMimetypesMarkdown, openMimetypesPlainText } from './helpers/mime' @@ -41,6 +42,8 @@ document.addEventListener('DOMContentLoaded', () => { component: FilesEditor, group: null }) + OC.Plugins.register('OCA.Files.SidebarPreviewManager', new PreviewPlugin()) + }) OCA.Text = { diff --git a/src/files/PreviewPlugin.js b/src/files/PreviewPlugin.js new file mode 100644 index 000000000..1bc49ffb1 --- /dev/null +++ b/src/files/PreviewPlugin.js @@ -0,0 +1,92 @@ +/* + * @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net> + * + * @author Julius Härtl <jus@bitgrid.net> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +import axios from '@nextcloud/axios' + +export default class PreviewPlugin { + + constructor() { + this.initPromise = null + this.vue = null + this.ReadOnlyEditor = null + this.view = null + } + + init() { + if (!this.initPromise) { + this.initPromise = Promise.all([ + import('vue'), + import('./../components/ReadOnlyEditor') + ]).then((exports) => { + this.Vue = exports[0].default + this.ReadOnlyEditor = exports[1].default + }) + } + return this.initPromise + } + + attach(manager) { + manager.addPreviewHandler('text/markdown', this.handlePreview.bind(this)) + } + + handlePreview(model, $thumbnailDiv, $thumbnailContainer, fallback) { + if (this.view !== null) { + this.view.$destroy() + this.view = null + } + + const previewWidth = ($thumbnailContainer.parent().width()) + const previewHeight = previewWidth / (16 / 9) + + Promise.all([ + this.getFileContent(model.getFullPath()), + this.init() + ]).then(([{ data }]) => { + $thumbnailContainer.addClass('text') + const textPreview = document.createElement('div') + $thumbnailDiv.children('.stretcher').remove() + $thumbnailDiv.append(textPreview) + $thumbnailDiv.css('max-height', previewHeight) + $thumbnailDiv.css('display', 'flex') + $thumbnailDiv.removeClass('icon-loading icon-32') + this.Vue.prototype.t = window.t + this.Vue.prototype.n = window.n + this.Vue.prototype.OCA = window.OCA + this.view = new this.Vue({ + render: h => h(this.ReadOnlyEditor, { + props: { + content: data, + isRichEditor: model.get('mimetype') === 'text/markdown' + } + }) + }) + this.view.$mount(textPreview) + }).catch(() => { + fallback() + }) + } + + getFileContent(path) { + const url = OC.linkToRemoteBase('files' + path) + return axios.get(url) + } + +} |