diff options
author | Julius Härtl <jus@bitgrid.net> | 2019-10-16 11:33:39 +0300 |
---|---|---|
committer | Julius Härtl <jus@bitgrid.net> | 2019-12-02 14:28:30 +0300 |
commit | baa11f406390cca2a890c16bf1cf0b404b2fc700 (patch) | |
tree | 4e3d7eb0b39fb23650f89c56e93432041527e272 /src | |
parent | 2dee8b69ce453e7bc0ebcec28cf375f7742d75d8 (diff) |
Start with direct editing
Signed-off-by: Julius Härtl <jus@bitgrid.net>
Diffstat (limited to 'src')
-rw-r--r-- | src/components/EditorWrapper.vue | 33 | ||||
-rw-r--r-- | src/components/FilesEditor.vue | 6 | ||||
-rw-r--r-- | src/main.js | 21 | ||||
-rw-r--r-- | src/services/SyncService.js | 53 | ||||
-rw-r--r-- | src/views/DirectEditing.vue | 115 |
5 files changed, 177 insertions, 51 deletions
diff --git a/src/components/EditorWrapper.vue b/src/components/EditorWrapper.vue index 5c8cf17e3..7b4a7c674 100644 --- a/src/components/EditorWrapper.vue +++ b/src/components/EditorWrapper.vue @@ -45,6 +45,7 @@ <GuestNameDialog v-if="isPublic && currentSession.guestName" :sync-service="syncService" /> </SessionList> </div> + <slot name="header" /> </MenuBar> <div> <MenuBubble v-if="!readOnly && isRichEditor" :editor="tiptap" /> @@ -98,6 +99,10 @@ export default { isMobile, ], props: { + initialSession: { + type: Object, + default: null, + }, relativePath: { type: String, default: null, @@ -192,7 +197,7 @@ export default { } }, hasDocumentParameters() { - return this.fileId || this.shareToken + return this.fileId || this.shareToken || this.initialSession }, isPublic() { return document.getElementById('isPublic') && document.getElementById('isPublic').value === '1' @@ -373,12 +378,20 @@ export default { this.dirty = state.dirty } }) - this.syncService.open({ - fileId: this.fileId, - filePath: this.relativePath, - }).catch((e) => { - this.hasConnectionIssue = true - }) + if (this.initialSession === null) { + this.syncService.open({ + fileId: this.fileId, + filePath: this.relativePath, + }).catch((e) => { + this.hasConnectionIssue = true + }) + } else { + this.syncService.open({ + initialSession: this.initialSession, + }).catch((e) => { + this.hasConnectionIssue = true + }) + } this.forceRecreate = false }, @@ -451,8 +464,7 @@ export default { display: block; width: 100%; max-width: 100%; - height: calc(100% - 50px); - top: 50px; + height: 100%; left: 0; margin: 0 auto; position: relative; @@ -516,8 +528,7 @@ export default { } #editor-session-list { - padding: 9px; - padding-right: 16px; + padding: 4px 16px 4px 4px; display: flex; input, div { diff --git a/src/components/FilesEditor.vue b/src/components/FilesEditor.vue index 28c3df2b7..708df3f3c 100644 --- a/src/components/FilesEditor.vue +++ b/src/components/FilesEditor.vue @@ -64,3 +64,9 @@ export default { }, } </script> +<style> +#editor-container { + height: calc(100% - 50px); + top: 50px; +} +</style> diff --git a/src/main.js b/src/main.js index a9a241f1b..1aed86f45 100644 --- a/src/main.js +++ b/src/main.js @@ -1,29 +1,18 @@ -import FilesEditor from './components/FilesEditor' - __webpack_nonce__ = btoa(OC.requestToken) // eslint-disable-line __webpack_public_path__ = OC.linkTo('text', 'js/') // eslint-disable-line -if (document.getElementById('maineditor')) { +if (document.getElementById('app-content')) { Promise.all([ import(/* webpackChunkName: "editor" */'vue'), - import(/* webpackChunkName: "editor" */'./components/EditorWrapper'), + import(/* webpackChunkName: "editor" */'./views/DirectEditing'), ]).then((imports) => { const Vue = imports[0].default Vue.prototype.t = window.t Vue.prototype.OCA = window.OCA - const Editor = imports[1].default + const DirectEditing = imports[1].default const vm = new Vue({ - render: h => h(Editor, { - props: { - relativePath: '/welcome.md', - active: true, - }, - }), + render: h => h(DirectEditing), }) - vm.$mount(document.getElementById('preview')) + vm.$mount(document.getElementById('app-content')) }) } - -OCA.Text = { - Editor: FilesEditor, -} diff --git a/src/services/SyncService.js b/src/services/SyncService.js index 7af158ab0..0702b2c84 100644 --- a/src/services/SyncService.js +++ b/src/services/SyncService.js @@ -84,28 +84,38 @@ class SyncService { return this } - open({ fileId, filePath }) { - return this._openDocument({ fileId, filePath }).then(() => { - this.emit('opened', { + async open({ fileId, filePath, initialSession }) { + let connectionData = null + if (typeof initialSession === 'undefined') { + try { + const response = await this._openDocument({ fileId, filePath }) + connectionData = response.data + } catch (error) { + if (!error.response || error.code === 'ECONNABORTED') { + this.emit('error', ERROR_TYPE.CONNECTION_FAILED, {}) + } else { + this.emit('error', ERROR_TYPE.LOAD_ERROR, error.response.status) + } + throw error + } + } else { + connectionData = initialSession + } + + this.document = connectionData.document + this.document.readOnly = connectionData.readOnly + this.session = connectionData.session + + this.emit('opened', { + document: this.document, + session: this.session, + }) + return this._fetchDocument().then(({ data }) => { + this.emit('loaded', { document: this.document, session: this.session, + documentSource: '' + data, }) - return this._fetchDocument().then(({ data }) => { - - this.emit('loaded', { - document: this.document, - session: this.session, - documentSource: '' + data, - }) - }) - }).catch((error) => { - if (!error.response || error.code === 'ECONNABORTED') { - this.emit('error', ERROR_TYPE.CONNECTION_FAILED, {}) - } else { - this.emit('error', ERROR_TYPE.LOAD_ERROR, error.response.status) - } - - return Promise.reject(error) }) } @@ -122,11 +132,6 @@ class SyncService { guestName: this.options.guestName, forceRecreate: this.options.forceRecreate, }, - }).then((response) => { - this.document = response.data.document - this.document.readOnly = response.data.readOnly - this.session = response.data.session - return response.data }) } diff --git a/src/views/DirectEditing.vue b/src/views/DirectEditing.vue new file mode 100644 index 000000000..114996977 --- /dev/null +++ b/src/views/DirectEditing.vue @@ -0,0 +1,115 @@ +<!-- + - @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/>. + - + --> + +<template> + <div id="editor-wrapper"> + <EditorWrapper :initial-session="initialSession" :active="true" mime="text/markdown"> + <template #header> + <button class="icon-share" @click="share" /> + <button class="icon-close" @click="close" /> + </template> + </EditorWrapper> + <!--<hr> + <h3>Debug output</h3> + <pre>{{ initialSession }}</pre> + <pre>Last request time: {{ log.mtime }}</pre> + <pre>{{ messages }}</pre>--> + </div> +</template> + +<script> +import Vue from 'vue' +import EditorWrapper from '../components/EditorWrapper' + +const log = Vue.observable({ + messages: [], + mtime: 0, +}) + +window.OCP.DirectEditing = { + close() { + log.messages.push('OCP.DirectEditing.close got called') + }, +} + +window.addEventListener('message', function(message) { + log.messages.push(message.data) +}) +export default { + name: 'DirectEditing', + components: { EditorWrapper }, + data() { + return { + initial: OCP.InitialState.loadState('text', 'file'), + messages: log.messages, + log: log, + } + }, + computed: { + initialSession() { + return JSON.parse(this.initial.session) || null + }, + }, + methods: { + close() { + window.postMessage('close') + }, + share() { + window.postMessage('share') + }, + }, +} +</script> + +<style scoped lang="scss"> + pre { + width: 100%; + max-width: 700px; + margin: auto; + background-color: var(--color-background-dark); + } + + button { + width: 44px; + height: 44px; + margin: 0; + background-size: 16px; + border: 0; + background-color: transparent; + opacity: .5; + color: var(--color-main-text); + background-position: center center; + vertical-align: top; + &:hover, &:focus, &:active { + background-color: var(--color-background-dark); + } + &.is-active, + &:hover, + &:focus { + opacity: 1; + } + + &.icon-undo, &.icon-redo { + opacity: .4; + } + } +</style> |