Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/richdocuments.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulius Härtl <jus@bitgrid.net>2021-03-08 14:54:38 +0300
committerGitHub <noreply@github.com>2021-03-08 14:54:38 +0300
commit1742973c77f8fbf6282606d227bc376398670165 (patch)
treef4f7d1b1edebc243d3d3ac432ef3a34d7c840af4
parentc1114b08eaa9da681a966a0f45120bd8ad8f9083 (diff)
parent2d3cdac28df9b6695698a532a64ab117d4c1978a (diff)
Merge pull request #1413 from nextcloud/backport/1397/stable3.7
-rw-r--r--docs/frontend-integration.md87
-rw-r--r--package-lock.json64
-rw-r--r--package.json1
-rw-r--r--src/document.js24
-rw-r--r--src/files.js26
-rw-r--r--src/view/FilesAppIntegration.js16
6 files changed, 198 insertions, 20 deletions
diff --git a/docs/frontend-integration.md b/docs/frontend-integration.md
index ce9e6c02..84948c64 100644
--- a/docs/frontend-integration.md
+++ b/docs/frontend-integration.md
@@ -149,3 +149,90 @@ The following code shows an example on how to register the different handlers:
})()
```
+
+## Events
+
+Events are emitted through the `@nextcloud/event-bus` for the different document loading states.
+
+### Files app scope
+
+When Collabora files are opened through the files app integration (either in the files app or on public share pages), the following events will be emitted to be able to track document opening progress and its success or failure state.
+
+```
+subscribe('richdocuments:file-open:started', data => console.error('richdocuments:file-open:started', data))
+subscribe('richdocuments:file-open:succeeded', data => console.error('richdocuments:file-open:succeeded', data))
+subscribe('richdocuments:file-open:failed', data => console.error('richdocuments:file-open:failed', data))
+```
+
+Event names:
+- richdocuments:file-open:started
+- richdocuments:file-open:succeeded
+- richdocuments:file-open:failed
+
+Data properties:
+
+
+- currentUser (string|null): user id of the currently logged-in user
+- file (object)
+ - fileId (integer|undefined): undefined for single public shares, otherwise the file id is available
+ - filePath (string): "/testfile.odt"
+ - sharingToken (string|undefined): Optional sharing token when opened on a public share link
+- reason (string): Only for a failed event, timeout|collabora
+- collaboraResponse (object); Optional when reason is collabora
+
+Example succeeded event data:
+```
+{
+ "currentUser": "admin",
+ "file": {
+ "fileId": "204",
+ "filePath": "/test.odt",
+ "sharingToken": undefined
+ }
+}
+```
+
+Example failed event data:
+```
+{
+ "reason": "collabora",
+ "collaboraResponse": "WOPI::GetFile failed: []",
+ "currentUser": "admin",
+ "file": {
+ "fileId": "204",
+ "filePath": "/test.odt",
+ "sharingToken": undefined
+ }
+}
+```
+
+### Document scope
+
+The event in the document scope is also emitted on direct editing through mobile apps, as there the files app integration is not available.
+
+```
+subscribe('richdocuments:wopi-load:started', data => console.error('richdocuments:wopi-load:started', data))
+subscribe('richdocuments:wopi-load:succeeded', data => console.error('richdocuments:wopi-load:succeeded', data))
+subscribe('richdocuments:wopi-load:failed', data => console.error('richdocuments:wopi-load:failed', data))
+```
+
+Event names:
+- richdocuments:wopi-load:started
+- richdocuments:wopi-load:succeeded
+- richdocuments:wopi-load:failed
+
+Data properties:
+
+- wopiFileId (string): file id constructed to be used by Collabora for the WOPI access
+- reason (string): Only for a failed event, timeout|collabora
+- collaboraResponse (string): Optional when failure reason is collabora
+
+
+Example failed event data:
+```
+{
+ "reason": "collabora",
+ "collaboraResponse": "WOPI::GetFile failed: []",
+ "wopiFileId": "288_oct9lk1km6wy"
+}
+```
diff --git a/package-lock.json b/package-lock.json
index e76212ce..538227cd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4416,24 +4416,40 @@
}
},
"@nextcloud/event-bus": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/@nextcloud/event-bus/-/event-bus-1.1.4.tgz",
- "integrity": "sha512-It27KzmUaSQ7w22nHFwOn8XgeVG0HYYOSNG9gs4UkP5VqcZ16m4ydt3GkMpWcyFec4OUjJc+yf7omRc3pNxsSw==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@nextcloud/event-bus/-/event-bus-1.2.0.tgz",
+ "integrity": "sha512-pNS0R6Mvgj4WnbJQ8LYjxRjCbRndpwjHNyZYm0zl8U71gbHsUvQIIzTdW7WYg6Nz/FjAlrdmDXJDFLh1DDcIFA==",
"requires": {
- "@types/semver": "^6.2.1",
+ "@types/semver": "^7.1.0",
"core-js": "^3.6.2",
- "semver": "^6.3.0"
+ "semver": "^7.3.2"
},
"dependencies": {
"core-js": {
- "version": "3.6.5",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz",
- "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA=="
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.9.0.tgz",
+ "integrity": "sha512-PyFBJaLq93FlyYdsndE5VaueA9K5cNB7CGzeCj191YYLhkQM0gdZR2SKihM70oF0wdqKSKClv/tEBOpoRmdOVQ=="
+ },
+ "lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "requires": {
+ "yallist": "^4.0.0"
+ }
},
"semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
+ "version": "7.3.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
+ "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
}
}
},
@@ -4766,9 +4782,9 @@
"dev": true
},
"@types/semver": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/@types/semver/-/semver-6.2.1.tgz",
- "integrity": "sha512-+beqKQOh9PYxuHvijhVl+tIHvT6tuwOrE9m14zd+MT2A38KoKZhh7pYJ0SNleLtwDsiIxHDsIk9bv01oOxvSvA=="
+ "version": "7.3.4",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.4.tgz",
+ "integrity": "sha512-+nVsLKlcUCeMzD2ufHEYuJ9a2ovstb6Dp52A5VsoKxDXgvE051XgHI/33I1EymwkRGQkwnA0LkhnUzituGs4EQ=="
},
"@types/stack-utils": {
"version": "1.0.1",
@@ -10558,7 +10574,8 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
"integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
- "dev": true
+ "dev": true,
+ "optional": true
},
"hammerjs": {
"version": "2.0.8",
@@ -11226,7 +11243,8 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz",
"integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==",
- "dev": true
+ "dev": true,
+ "optional": true
},
"is-extendable": {
"version": "0.1.1",
@@ -16652,6 +16670,7 @@
"resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.1.tgz",
"integrity": "sha512-BvEXF+UmsnAfYfoapKM9nGxnP+Wn7P91YfXmrKnfcYCx6VBeoN5Ez5Ogck6I8Bi5k4RlpqRYaw75pAwzX9OphA==",
"dev": true,
+ "optional": true,
"requires": {
"growly": "^1.3.0",
"is-wsl": "^2.2.0",
@@ -16666,6 +16685,7 @@
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
"integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
"dev": true,
+ "optional": true,
"requires": {
"is-docker": "^2.0.0"
}
@@ -16675,6 +16695,7 @@
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
+ "optional": true,
"requires": {
"yallist": "^4.0.0"
}
@@ -16684,6 +16705,7 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
"integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
"dev": true,
+ "optional": true,
"requires": {
"lru-cache": "^6.0.0"
}
@@ -16692,13 +16714,15 @@
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
- "dev": true
+ "dev": true,
+ "optional": true
},
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
+ "optional": true,
"requires": {
"isexe": "^2.0.0"
}
@@ -16707,7 +16731,8 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
+ "dev": true,
+ "optional": true
}
}
},
@@ -19104,7 +19129,8 @@
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
"integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==",
- "dev": true
+ "dev": true,
+ "optional": true
},
"sigmund": {
"version": "1.0.1",
diff --git a/package.json b/package.json
index 14c67122..2ad14a50 100644
--- a/package.json
+++ b/package.json
@@ -26,6 +26,7 @@
"@nextcloud/auth": "^1.3.0",
"@nextcloud/axios": "^1.6.0",
"@nextcloud/capabilities": "^1.0.2",
+ "@nextcloud/event-bus": "^1.2.0",
"@nextcloud/l10n": "^1.4.1",
"@nextcloud/router": "^1.2.0",
"@nextcloud/vue": "^3.5.4",
diff --git a/src/document.js b/src/document.js
index 145a7759..4d000da0 100644
--- a/src/document.js
+++ b/src/document.js
@@ -1,3 +1,4 @@
+import { emit } from '@nextcloud/event-bus'
import { getRootUrl } from '@nextcloud/router'
import { getRequestToken } from '@nextcloud/auth'
import Config from './services/config'
@@ -275,12 +276,27 @@ const documentsMain = {
$('#mainContainer').append(form)
$('#mainContainer').append(frame)
+ emit('richdocuments:wopi-load:started', {
+ wopiFileId: fileId
+ })
// Listen for App_LoadingStatus as soon as possible
$('#loleafletframe').ready(function() {
const editorInitListener = ({ parsed, data }) => {
console.debug('[document] editorInitListener: Received post message ', parsed)
const { msgId, args } = parsed
+ if (msgId === 'Action_Load_Resp') {
+ if (!parsed.args.success) {
+ emit('richdocuments:wopi-load:failed', {
+ reason: 'collabora',
+ collaboraResponse: parsed?.args?.errorMsg,
+ wopiFileId: fileId
+ })
+ }
+ if (!isDirectEditing()) {
+ PostMessages.sendPostMessage('parent', data)
+ }
+ }
if (msgId !== 'App_LoadingStatus') {
return
}
@@ -312,10 +328,18 @@ const documentsMain = {
PostMessages.sendWOPIPostMessage('loolframe', 'Hide_Menu_Item', { id: 'insertgraphicremote' })
}
+ emit('richdocuments:wopi-load:succeeded', {
+ wopiFileId: fileId
+ })
break
case 'Failed':
// Loading failed but editor shows the error
documentsMain.isFrameReady = true
+ emit('richdocuments:wopi-load:failed', {
+ reason: 'collabora',
+ collaboraResponse: 'App_LoadingStatus Failed',
+ wopiFileId: fileId
+ })
break
}
}
diff --git a/src/files.js b/src/files.js
index fd5e8dd4..7868159d 100644
--- a/src/files.js
+++ b/src/files.js
@@ -1,3 +1,4 @@
+import { emit } from '@nextcloud/event-bus'
import { getDocumentUrlFromTemplate, getDocumentUrlForPublicFile, getDocumentUrlForFile } from './helpers/url'
import PostMessageService from './services/postMessage'
import Config from './services/config'
@@ -174,12 +175,16 @@ const odfViewer = {
FilesAppIntegration.init({
fileName,
fileId,
+ filePath: fileDir,
fileList: context ? context.fileList : undefined,
fileModel: context ? context.fileModel : undefined,
sendPostMessage: (msgId, values) => {
PostMessages.sendWOPIPostMessage(FRAME_DOCUMENT, msgId, values)
}
})
+ emit('richdocuments:file-open:started', {
+ ...FilesAppIntegration.loggingContext()
+ })
})
},
@@ -217,6 +222,10 @@ const odfViewer = {
onTimeout: function() {
if (!odfViewer.receivedLoading && !odfViewer.isProxyStarting) {
+ emit('richdocuments:file-open:failed', {
+ reason: 'timeout',
+ ...FilesAppIntegration.loggingContext()
+ })
odfViewer.onClose()
OC.Notification.showTemporary(t('richdocuments', 'Failed to load {productName} - please try again later', { productName: OC.getCapabilities().richdocuments.productName || 'Collabora Online' }))
} else if (!odfViewer.receivedLoading) {
@@ -319,8 +328,25 @@ $(document).ready(function() {
case 'loading':
odfViewer.onReceiveLoading()
break
+ case 'Action_Load_Resp':
+ if (!args?.success) {
+ emit('richdocuments:file-open:failed', {
+ reason: 'collabora',
+ collaboraResponse: parsed?.args?.errorMsg,
+ ...FilesAppIntegration.loggingContext()
+ })
+ } else {
+ emit('richdocuments:file-open:succeeded', {
+ ...FilesAppIntegration.loggingContext()
+ })
+ }
+ break
case 'App_LoadingStatus':
if (args.Status === 'Timeout') {
+ emit('richdocuments:file-open:failed', {
+ reason: 'timeout',
+ ...FilesAppIntegration.loggingContext()
+ })
odfViewer.onClose()
OC.Notification.showTemporary(t('richdocuments', 'Failed to connect to {productName}. Please try again later or contact your server administrator.',
{ productName: OC.getCapabilities().richdocuments.productName }
diff --git a/src/view/FilesAppIntegration.js b/src/view/FilesAppIntegration.js
index 01e41ba9..6a657c8f 100644
--- a/src/view/FilesAppIntegration.js
+++ b/src/view/FilesAppIntegration.js
@@ -34,6 +34,8 @@ export default {
fileList: undefined,
+ filePath: undefined,
+
/* Views: people currently editing the file */
views: {},
@@ -50,10 +52,11 @@ export default {
}
},
- init({ fileName, fileId, sendPostMessage, fileList, fileModel }) {
+ init({ fileName, fileId, filePath, sendPostMessage, fileList, fileModel }) {
this.fileName = fileName
this.fileId = fileId
this.fileList = fileList
+ this.filePath = filePath
this.fileModel = fileModel
this.sendPostMessage = sendPostMessage
@@ -595,6 +598,17 @@ export default {
NewFileMenu._openTemplatePicker(Preload.create.type, fileType.mime, Preload.create.filename + '.' + fileType.extension)
})
}, 250)
+ },
+
+ loggingContext: function() {
+ return {
+ currentUser: OC.getCurrentUser()?.uid,
+ file: {
+ sharingToken: document.getElementById('sharingToken')?.value,
+ fileId: this.fileId,
+ filePath: (this.filePath ?? '') + '/' + this.fileName
+ }
+ }
}
}