diff --git a/src/components/RoomExport.vue b/src/components/RoomExport.vue
index a7d60b9..2afe1f6 100644
--- a/src/components/RoomExport.vue
+++ b/src/components/RoomExport.vue
@@ -27,12 +27,12 @@
@@ -153,6 +153,7 @@ export default {
return {
timelineSet: null,
events: [],
+ exportComponents: [],
fetchedEvents: 0,
totalEvents: 0,
processedEvents: 0,
@@ -179,6 +180,22 @@ export default {
},
},
methods: {
+ componentForEventForExport(event, forExport) {
+ const comp = this.componentForEvent(event, forExport);
+ const self = this;
+ if (comp) {
+ if (!comp.mixins) {
+ comp.mixins = [];
+ }
+ comp.mixins.push({
+ created: function() {
+ console.error("Created", this.name);
+ self.exportComponents.push(this);
+ }
+ });
+ }
+ return comp;
+ },
cancelExport() {
this.cancelled = true;
},
@@ -230,6 +247,8 @@ export default {
var currentMediaSize = 0;
var maxMediaSize = 1024 * 1024 * 1024; // 1GB
+ this.exportComponents = [];
+
this.getEvents()
.then((events) => {
var decryptionPromises = [];
@@ -282,6 +301,8 @@ export default {
});
})
.then(() => {
+ this.totalEvents = this.exportComponents.length;
+
// UI updated, start processing events
zip = new JSZip();
var avatarFolder = zip.folder("avatars");
@@ -291,186 +312,173 @@ export default {
var filesFolder = zip.folder("files");
var downloadPromises = [];
- let components = this.$refs.exportedEvent;
- for (const parentComp of components) {
- let childComponents = [parentComp];
- // Some components, i.e. the media threads, have subcomponents
- // that we want to export. So pickup subcomponents here as well.
- if (parentComp.$refs && parentComp.$refs.exportedEvent) {
- if (Array.isArray(parentComp.$refs.exportedEvent)) {
- for (const child of parentComp.$refs.exportedEvent) {
- childComponents.push(child);
- }
- } else {
- childComponents.push(parentComp.$refs.exportedEvent);
- }
- }
- for (const comp of childComponents.filter((c) => c.event != undefined)) {
- // Avatars need downloading?
- if (comp.$el && comp.$el.nodeType == 1) {
- const avatars = comp.$el.getElementsByClassName("v-avatar");
- if (avatars && avatars.length > 0) {
- const member = this.room.getMember(comp.event.getSender());
- if (member) {
- const fileName = comp.event.getSender() + ".png";
+ for (const comp of this.exportComponents.filter((c) => c.event != undefined)) {
+ // Avatars need downloading?
+ if (comp.$el && comp.$el.nodeType == 1) {
+ const avatars = comp.$el.getElementsByClassName("v-avatar");
+ if (avatars && avatars.length > 0) {
+ const member = this.room.getMember(comp.event.getSender());
+ if (member) {
+ const fileName = comp.event.getSender() + ".png";
- const setSource = (fileName) => {
- for (let avatarIndex = 0; avatarIndex < avatars.length; avatarIndex++) {
- const avatarElement = avatars[avatarIndex];
- const images = avatarElement.getElementsByTagName("img");
- for (let imageIndex = 0; imageIndex < images.length; imageIndex++) {
- const img = images[imageIndex];
- img.onerror = undefined;
- img.removeAttribute("src");
- img.setAttribute("data-exported-src", "./avatars/" + fileName);
- }
+ const setSource = (fileName) => {
+ for (let avatarIndex = 0; avatarIndex < avatars.length; avatarIndex++) {
+ const avatarElement = avatars[avatarIndex];
+ const images = avatarElement.getElementsByTagName("img");
+ for (let imageIndex = 0; imageIndex < images.length; imageIndex++) {
+ const img = images[imageIndex];
+ img.onerror = undefined;
+ img.removeAttribute("src");
+ img.setAttribute("data-exported-src", "./avatars/" + fileName);
}
- };
-
- if (!avatarFolder.file(fileName)) {
- const url = member.getAvatarUrl(
- this.$matrix.matrixClient.getHomeserverUrl(),
- 40,
- 40,
- "scale",
- true,
- false,
- this.$matrix.useAuthedMedia
- );
- if (url) {
- avatarFolder.file(fileName, "empty");
- downloadPromises.push(
- axios
- .get(url, {
- responseType: "blob",
- headers: this.$matrix.useAuthedMedia
- ? {
- Authorization: `Bearer ${this.$matrix.matrixClient.getAccessToken()}`,
- }
- : undefined,
- })
- .then((result) => {
- if (result.data) {
- avatarFolder.file(fileName, result.data);
- setSource(fileName);
- }
- })
- .catch((err) => {
- console.error("Download error: ", err);
- avatarFolder.remove(fileName);
- })
- );
- }
- } else {
- setSource(fileName);
}
+ };
+
+ if (!avatarFolder.file(fileName)) {
+ const url = member.getAvatarUrl(
+ this.$matrix.matrixClient.getHomeserverUrl(),
+ 40,
+ 40,
+ "scale",
+ true,
+ false,
+ this.$matrix.useAuthedMedia
+ );
+ if (url) {
+ avatarFolder.file(fileName, "empty");
+ downloadPromises.push(
+ axios
+ .get(url, {
+ responseType: "blob",
+ headers: this.$matrix.useAuthedMedia
+ ? {
+ Authorization: `Bearer ${this.$matrix.matrixClient.getAccessToken()}`,
+ }
+ : undefined,
+ })
+ .then((result) => {
+ if (result.data) {
+ avatarFolder.file(fileName, result.data);
+ setSource(fileName);
+ }
+ })
+ .catch((err) => {
+ console.error("Download error: ", err);
+ avatarFolder.remove(fileName);
+ })
+ );
+ }
+ } else {
+ setSource(fileName);
}
}
}
+ }
- let componentClass = comp.$options
- ? comp.$options.__file.split("/").reverse()[0].split(".")[0]
- : "invalid_component";
- let attachment =
- comp.event && comp.event.getId
- ? this.$matrix.attachmentManager.getEventAttachment(comp.event)
- : undefined;
+ let attachment =
+ comp.event && comp.event.getId
+ ? this.$matrix.attachmentManager.getEventAttachment(comp.event)
+ : undefined;
+ let componentClass = comp.$options
+ ? comp.$options.__file.split("/").reverse()[0].split(".")[0]
+ : "invalid_component";
+ console.error("Processi", componentClass, comp.event, comp.originalEvent, attachment);
- if (attachment && (attachment.srcSize = 0 || currentMediaSize + attachment.srcSize <= maxMediaSize)) {
- downloadPromises.push(
- attachment
- .loadSrc({ asBlob: true })
- .then((res) => {
- const blob = res.data;
- if (currentMediaSize + blob.size <= maxMediaSize) {
- currentMediaSize += blob.size;
- switch (componentClass) {
- case "MessageIncomingImageExport":
- case "MessageOutgoingImageExport":
- {
- let mime = blob.type;
- var extension = ".png";
- switch (mime) {
- case "image/jpeg":
- case "image/jpg":
- extension = ".jpg";
- break;
- case "image/gif":
- extension = ".gif";
- }
+ if (attachment && (attachment.srcSize = 0 || currentMediaSize + attachment.srcSize <= maxMediaSize)) {
+ downloadPromises.push(
+ attachment
+ .loadSrc({ asBlob: true })
+ .then((res) => {
+ const blob = res.data;
+ if (currentMediaSize + blob.size <= maxMediaSize) {
+ currentMediaSize += blob.size;
- let fileName = comp.event.getId() + extension;
- imageFolder.file(fileName, blob); // TODO calc bytes
-
- // Update source
- const images = comp.$el.getElementsByTagName("img");
- for (let imageIndex = 0; imageIndex < images.length; imageIndex++) {
- const img = images[imageIndex];
- img.removeAttribute("src");
- img.setAttribute("data-exported-src", "./images/" + fileName);
- }
- this.processedEvents += 1;
+ switch (componentClass) {
+ case "MessageIncomingImageExport":
+ case "MessageOutgoingImageExport":
+ {
+ let mime = blob.type;
+ var extension = ".png";
+ switch (mime) {
+ case "image/jpeg":
+ case "image/jpg":
+ extension = ".jpg";
+ break;
+ case "image/gif":
+ extension = ".gif";
}
- break;
- case "MessageIncomingAudioExport":
- case "MessageOutgoingAudioExport":
- {
- var extension = ".webm";
- let fileName = comp.event.getId() + extension;
- audioFolder.file(fileName, blob); // TODO calc bytes
- let elements = comp.$el.getElementsByTagName("audio");
- let element = elements && elements[0];
- if (element) {
- element.setAttribute("data-exported-src", "./audio/" + fileName);
- }
- this.processedEvents += 1;
- }
- break;
+ let fileName = comp.event.getId() + extension;
+ imageFolder.file(fileName, blob); // TODO calc bytes
- case "MessageIncomingVideoExport":
- case "MessageOutgoingVideoExport":
- {
- var extension = ".mp4";
- let fileName = comp.event.getId() + extension;
- videoFolder.file(fileName, blob); // TODO calc bytes
- // comp.src = "./video/" + fileName;
- let elements = comp.$el.getElementsByTagName("video");
- let element = elements && elements[0];
- if (element) {
- element.setAttribute("data-exported-src", "./video/" + fileName);
- }
- this.processedEvents += 1;
+ // Update source
+ const images = comp.$el.getElementsByTagName("img");
+ for (let imageIndex = 0; imageIndex < images.length; imageIndex++) {
+ const img = images[imageIndex];
+ img.removeAttribute("src");
+ img.setAttribute("data-exported-src", "./images/" + fileName);
}
- break;
+ this.processedEvents += 1;
+ }
+ break;
- case "MessageIncomingFileExport":
- case "MessageOutgoingFileExport":
- {
- var extension = util.getFileExtension(comp.event);
- let fileName = comp.event.getId() + extension;
- filesFolder.file(fileName, blob);
- comp.href = "./files/" + fileName;
- this.processedEvents += 1;
+ case "MessageIncomingAudioExport":
+ case "MessageOutgoingAudioExport":
+ {
+ var extension = ".webm";
+ let fileName = comp.event.getId() + extension;
+ audioFolder.file(fileName, blob); // TODO calc bytes
+ let elements = comp.$el.getElementsByTagName("audio");
+ let element = elements && elements[0];
+ if (element) {
+ element.setAttribute("data-exported-src", "./audio/" + fileName);
}
- break;
- }
- this.processedEvents += 1;
- return true;
- } else {
- this.processedEvents += 1;
- return false;
+ this.processedEvents += 1;
+ }
+ break;
+
+ case "MessageIncomingVideoExport":
+ case "MessageOutgoingVideoExport":
+ {
+ var extension = ".mp4";
+ let fileName = comp.event.getId() + extension;
+ videoFolder.file(fileName, blob); // TODO calc bytes
+ // comp.src = "./video/" + fileName;
+ let elements = comp.$el.getElementsByTagName("video");
+ let element = elements && elements[0];
+ if (element) {
+ element.setAttribute("data-exported-src", "./video/" + fileName);
+ }
+ this.processedEvents += 1;
+ }
+ break;
+
+ case "MessageIncomingFileExport":
+ case "MessageOutgoingFileExport":
+ {
+ var extension = util.getFileExtension(comp.event);
+ let fileName = comp.event.getId() + extension;
+ filesFolder.file(fileName, blob);
+ comp.href = "./files/" + fileName;
+ this.processedEvents += 1;
+ }
+ break;
}
- })
- .catch((ignoredErr) => {
this.processedEvents += 1;
- })
- );
- } else {
- this.processedEvents += 1;
- }
+ return true;
+ } else {
+ this.processedEvents += 1;
+ return false;
+ }
+ })
+ .catch((ignoredErr) => {
+ this.processedEvents += 1;
+ })
+ );
+ } else {
+ this.processedEvents += 1;
}
}
return Promise.all(downloadPromises);
diff --git a/src/components/messages/composition/MessageThreadExport.vue b/src/components/messages/composition/MessageThreadExport.vue
index 8ffdc2d..9dd1add 100644
--- a/src/components/messages/composition/MessageThreadExport.vue
+++ b/src/components/messages/composition/MessageThreadExport.vue
@@ -32,9 +32,6 @@ import { MatrixEvent, MatrixEventEvent } from "matrix-js-sdk";
const { t } = useI18n();
const $matrix: any = inject("globalMatrix");
-type RootType = InstanceType;
-const rootRef = useTemplateRef("root");
-
const emits = defineEmits<
MessageEmits & { (event: "layout-change", value: { element: Element | undefined; action: () => void }): void }
>();
@@ -44,8 +41,7 @@ const props = defineProps();
const processThread = () => {
if (!event.value?.isRedacted()) {
- const el = rootRef.value?.$el;
- emits("layout-change", { element: el, action: _processThread });
+ _processThread();
}
};
diff --git a/src/models/attachmentManager.ts b/src/models/attachmentManager.ts
index 9dfafac..1f77564 100644
--- a/src/models/attachmentManager.ts
+++ b/src/models/attachmentManager.ts
@@ -149,9 +149,10 @@ export class AttachmentManager {
attachment.loadSrc = (options?: EventAttachmentLoadSrcOptions) => {
if (attachment.src && !options?.asBlob) {
return Promise.resolve({data: attachment.src, type: "src"});
- } else if (attachment.srcPromise) {
+ } else if (attachment.srcPromise && !options?.asBlob) {
return attachment.srcPromise;
}
+ Implement loadBlob somewhere here!
attachment.srcPromise = this._loadEventAttachmentOrThumbnail(event, false, !!options?.asBlob, (percent) => {
attachment.srcProgress = percent;
}).then((res) => {