From 657f9e9e4bc18f00bcca0a4869704b91b9199c81 Mon Sep 17 00:00:00 2001 From: N Pex Date: Tue, 24 May 2022 13:15:48 +0000 Subject: [PATCH] Room export fixes --- package-lock.json | 147 +++++++++++---------------- package.json | 2 +- src/assets/translations/en.json | 3 +- src/components/RoomExport.vue | 43 ++++++-- src/components/messages/pollMixin.js | 53 ++++++---- 5 files changed, 134 insertions(+), 114 deletions(-) diff --git a/package-lock.json b/package-lock.json index a0e9f0a..11c5532 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1441,9 +1441,9 @@ "dev": true }, "@types/retry": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz", - "integrity": "sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==" + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" }, "@types/serve-static": { "version": "1.13.10", @@ -1841,6 +1841,17 @@ "color-convert": "^2.0.1" } }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "optional": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, "cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -1873,6 +1884,13 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "optional": true + }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -1908,6 +1926,28 @@ "ansi-regex": "^5.0.0" } }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "optional": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "vue-loader-v16": { + "version": "npm:vue-loader@16.8.3", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.8.3.tgz", + "integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==", + "dev": true, + "optional": true, + "requires": { + "chalk": "^4.1.0", + "hash-sum": "^2.0.0", + "loader-utils": "^2.0.0" + } + }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -2294,7 +2334,7 @@ "another-json": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/another-json/-/another-json-0.2.0.tgz", - "integrity": "sha1-tfQBnJc7bdXGUGotk0acttMq7tw=" + "integrity": "sha512-/Ndrl68UQLhnCdsAzEXLMFuOR546o2qbYRqCglaNHbjXrwG1ayTcdwr3zkSGOGtGXDyR5X9nCFfnyG2AFJIsqg==" }, "ansi-colors": { "version": "3.2.4", @@ -2923,7 +2963,7 @@ "browser-request": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/browser-request/-/browser-request-0.3.3.tgz", - "integrity": "sha1-ns5bWsqJopkyJC4Yv5M975h2zBc=" + "integrity": "sha512-YyNI4qJJ+piQG6MMEuo7J3Bzaqssufx04zpEKYfSrl/1Op59HWali9zMtBpXnkmqMcOuWJPZvudrm9wISmnCbg==" }, "browserify-aes": { "version": "1.2.0", @@ -3041,7 +3081,7 @@ "bs58": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", "requires": { "base-x": "^3.0.2" } @@ -8012,10 +8052,15 @@ "resolved": "https://registry.npmjs.org/material-design-icons-iconfont/-/material-design-icons-iconfont-6.1.0.tgz", "integrity": "sha512-wRJtOo1v1ch+gN8PRsj0IGJznk+kQ8mz13ds/nuhLI+Qyf/931ZlRpd92oq0IRPpZIb+bhX8pRjzIVdcPDKmiQ==" }, + "matrix-events-sdk": { + "version": "0.0.1-beta.7", + "resolved": "https://registry.npmjs.org/matrix-events-sdk/-/matrix-events-sdk-0.0.1-beta.7.tgz", + "integrity": "sha512-9jl4wtWanUFSy2sr2lCjErN/oC8KTAtaeaozJtrgot1JiQcEI4Rda9OLgQ7nLKaqb4Z/QUx/fR3XpDzm5Jy1JA==" + }, "matrix-js-sdk": { - "version": "15.2.0", - "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-15.2.0.tgz", - "integrity": "sha512-jZOM8Fn86oNvU3zVQcc+JTKKrtYq4ADN6rPZs4Mwxj/X/GDP+2YIP5176GtviF0GM6VO1dcnPZY73ykl8DayjA==", + "version": "17.2.0", + "resolved": "https://registry.npmjs.org/matrix-js-sdk/-/matrix-js-sdk-17.2.0.tgz", + "integrity": "sha512-/IrgHCSVUZNVcKoPO20OF9Xog9X79a1ckmR7FwF5lSTNdmC7eQvU0XcFYCi5IXo57du+im69lEw8dLbPngZhoQ==", "requires": { "@babel/runtime": "^7.12.5", "another-json": "^0.2.0", @@ -8023,6 +8068,7 @@ "bs58": "^4.0.1", "content-type": "^1.0.4", "loglevel": "^1.7.1", + "matrix-events-sdk": "^0.0.1-beta.7", "p-retry": "^4.5.0", "qs": "^6.9.6", "request": "^2.88.2", @@ -8891,11 +8937,11 @@ "dev": true }, "p-retry": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.1.tgz", - "integrity": "sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", "requires": { - "@types/retry": "^0.12.0", + "@types/retry": "0.12.0", "retry": "^0.13.1" } }, @@ -10804,9 +10850,9 @@ } }, "qs": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.2.tgz", - "integrity": "sha512-mSIdjzqznWgfd4pMii7sHtaYF8rx8861hBO80SraY5GT0XQibWZWJSid0avzHGkDIZLImux2S5mXO0Hfct2QCw==", + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", "requires": { "side-channel": "^1.0.4" } @@ -13267,75 +13313,6 @@ } } }, - "vue-loader-v16": { - "version": "npm:vue-loader@16.8.3", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.8.3.tgz", - "integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==", - "dev": true, - "optional": true, - "requires": { - "chalk": "^4.1.0", - "hash-sum": "^2.0.0", - "loader-utils": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "optional": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "optional": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "optional": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "optional": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "optional": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "optional": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "vue-property-decorator": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/vue-property-decorator/-/vue-property-decorator-9.1.2.tgz", diff --git a/package.json b/package.json index 2f8cfa9..f563dfa 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "jszip": "^3.9.1", "linkifyjs": "3.0.0-beta.3", "material-design-icons-iconfont": "^6.1", - "matrix-js-sdk": "^15.2.0", + "matrix-js-sdk": "^17.2.0", "md-gum-polyfill": "^1.0.0", "mic-recorder-to-mp3": "^2.2.2", "pretty-bytes": "^5.6.0", diff --git a/src/assets/translations/en.json b/src/assets/translations/en.json index 0b1f817..45a13bb 100644 --- a/src/assets/translations/en.json +++ b/src/assets/translations/en.json @@ -263,6 +263,7 @@ "exported_date": "Exported on {date}", "fetched_n_events": "Fetched {count} events", "fetched_n_of_total_events": "Fetched {count} of {total} events", - "processed_n_of_total_events": "Processed media for {count} of {total} events" + "processed_n_of_total_events": "Processed media for {count} of {total} events", + "export_filename": "Exported chat {date}" } } diff --git a/src/components/RoomExport.vue b/src/components/RoomExport.vue index 769e603..8ed0640 100644 --- a/src/components/RoomExport.vue +++ b/src/components/RoomExport.vue @@ -6,7 +6,7 @@ - + @@ -104,6 +104,7 @@ import chatMixin from "./chatMixin"; import util from "../plugins/utils"; import JSZip from "jszip"; import { saveAs } from "file-saver"; +import { EventTimelineSet } from "matrix-js-sdk"; export default { name: "RoomExport", @@ -159,6 +160,7 @@ export default { }, data() { return { + timelineSet: null, events: [], fetchedEvents: 0, totalEvents: 0, @@ -182,10 +184,7 @@ export default { }, computed: { exportDate() { - return this.$t("export.exported_date", {date: util.formatDay(Date.now().valueOf())}); - }, - timelineSet() { - return this.room.getUnfilteredTimelineSet(); + return this.$t("export.exported_date", { date: util.formatDay(Date.now().valueOf()) }); }, }, methods: { @@ -241,7 +240,28 @@ export default { this.getEvents() .then((events) => { - this.events = events.reverse(); + var decryptionPromises = []; + for (const event of this.events) { + if (event.isEncrypted()) { + decryptionPromises.push( + this.$matrix.matrixClient.decryptEventIfNeeded(event, { + isRetry: true, + emit: false, + }) + ); + } + } + return Promise.all(decryptionPromises).then(() => { + return events; + }); + }) + .then((events) => { + // Create a timeline and add the events to that, so that relations etc are aggregated correctly! + this.timelineSet = new EventTimelineSet(null, { unstableClientRelationAggregation: true }); + this.timelineSet.addEventsToTimeline(events.reverse(), true, this.timelineSet.getLiveTimeline(), ""); + this.events = events; + + // Wait a tick so UI is updated. return new Promise((resolve, ignoredReject) => { this.$nextTick(() => { resolve(true); @@ -382,7 +402,8 @@ export default { console.log("All media added, total size: " + currentMediaSize); let root = this.$refs.exportRoot; - var doc = "\n"; + + var doc = "\n\n\n"; for (const sheet of document.styleSheets) { doc += "\n"; } - doc += "
"; + doc += + "
"; const getCssRules = function(el) { if (el.classList.contains("op-button")) { el.innerHTML = ""; @@ -412,7 +434,10 @@ export default { zip.file("chat.html", doc); zip.generateAsync({ type: "blob" }).then((content) => { - saveAs(content, "example.zip"); + saveAs( + content, + this.$t("export.export_filename", { date: util.formatDay(Date.now().valueOf()) }) + ".zip" + ); this.status = ""; this.$emit("close"); }); diff --git a/src/components/messages/pollMixin.js b/src/components/messages/pollMixin.js index e723c65..7544764 100644 --- a/src/components/messages/pollMixin.js +++ b/src/components/messages/pollMixin.js @@ -16,7 +16,13 @@ export default { mounted() { this.$matrix.on("Room.timeline", this.pollMixinOnEvent); this.pollQuestion = - (this.event && this.event.getContent()["org.matrix.msc3381.poll.start"]["question"]["body"]) || ""; + (this.event && + this.event.getContent()["m.poll.start"] && + this.event.getContent()["m.poll.start"]["question"]["body"]) || + (this.event && + this.event.getContent()["org.matrix.msc3381.poll.start"] && + this.event.getContent()["org.matrix.msc3381.poll.start"]["question"]["body"]) || + ""; this.updateAnswers(); }, destroyed() { @@ -34,7 +40,12 @@ export default { }, methods: { updateAnswers() { - let answers = (this.event && this.event.getContent()["org.matrix.msc3381.poll.start"]["answers"]) || []; + let answers = + (this.event && this.event.getContent()["m.poll.start"] && this.event.getContent()["m.poll.start"]["answers"]) || + (this.event && + this.event.getContent()["org.matrix.msc3381.poll.start"] && + this.event.getContent()["org.matrix.msc3381.poll.start"]["answers"]) || + []; var answerMap = {}; var answerArray = []; answers.forEach((a) => { @@ -45,17 +56,21 @@ export default { }); // Kind of poll - this.pollIsDisclosed = - (this.event && - this.event.getContent()["org.matrix.msc3381.poll.start"]["kind"] != "org.matrix.msc3381.poll.undisclosed") || - false; + this.pollIsDisclosed = false; + if (this.event) { + if (this.event.getContent()["m.poll.start"]) { + this.pollIssDisclosed = this.event.getContent()["m.poll.start"]["kind"] != "m.poll.undisclosed" || false; + } else if (this.event.getContent()["org.matrix.msc3381.poll.start"]) { + this.pollIssDisclosed = + this.event.getContent()["org.matrix.msc3381.poll.start"]["kind"] != "org.matrix.msc3381.poll.undisclosed" || + false; + } + } // Look for poll end - this.pollEndRelations = this.timelineSet.getRelationsForEvent( - this.event.getId(), - "m.reference", - "org.matrix.msc3381.poll.end" - ); + this.pollEndRelations = + this.timelineSet.getRelationsForEvent(this.event.getId(), "m.reference", "m.poll.end") || + this.timelineSet.getRelationsForEvent(this.event.getId(), "m.reference", "org.matrix.msc3381.poll.end"); if (this.pollEndRelations) { const endMessages = this.pollEndRelations.getRelations() || []; if (endMessages.length > 0) { @@ -64,11 +79,9 @@ export default { } // Process votes - this.pollResponseRelations = this.timelineSet.getRelationsForEvent( - this.event.getId(), - "m.reference", - "org.matrix.msc3381.poll.response" - ); + this.pollResponseRelations = + this.timelineSet.getRelationsForEvent(this.event.getId(), "m.reference", "m.poll.response") || + this.timelineSet.getRelationsForEvent(this.event.getId(), "m.reference", "org.matrix.msc3381.poll.response"); var userVotes = {}; if (this.pollResponseRelations) { const votes = this.pollResponseRelations.getRelations() || []; @@ -78,7 +91,11 @@ export default { continue; // Invalid vote, after poll was closed. } const sender = vote.getSender(); - const answersFromThisUser = vote.getContent()["org.matrix.msc3381.poll.response"]["answers"] || []; + const answersFromThisUser = + (vote.getContent()["m.poll.response"] && vote.getContent()["m.poll.response"]["answers"]) || + (vote.getContent()["org.matrix.msc3381.poll.response"] && + vote.getContent()["org.matrix.msc3381.poll.response"]["answers"]) || + []; if (answersFromThisUser.length == 0) { delete userVotes[sender]; } else { @@ -158,7 +175,7 @@ export default { return; // Not for this room } this.$matrix.matrixClient.decryptEventIfNeeded(event).then(() => { - if (event.getType().startsWith("org.matrix.msc3381.poll.")) { + if (event.getType().startsWith("m.poll.") || event.getType().startsWith("org.matrix.msc3381.poll.")) { this.updateAnswers(); } });