Resolve "when uploading multiple media files, send and display it as a thread"
This commit is contained in:
parent
a5ff54842c
commit
5ac61eac7c
7 changed files with 369 additions and 173 deletions
159
src/components/sendAttachmentsMixin.js
Normal file
159
src/components/sendAttachmentsMixin.js
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
import util from "../plugins/utils";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
sendStatuses: Object.freeze({
|
||||
INITIAL: 0,
|
||||
SENDING: 1,
|
||||
SENT: 2,
|
||||
CANCELED: 3,
|
||||
FAILED: 4,
|
||||
}),
|
||||
sendingStatus: 0,
|
||||
sendingPromise: null,
|
||||
sendingRootEventId: null,
|
||||
sendingAttachments: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
attachmentsSentCount() {
|
||||
return this.sendingAttachments ? this.sendingAttachments.reduce((a, elem, ignoredidx, ignoredarray) => elem.status == this.sendStatuses.SENT ? a + 1 : a, 0) : 0
|
||||
},
|
||||
attachmentsSending() {
|
||||
return this.sendingAttachments ? this.sendingAttachments.filter(elem => elem.status == this.sendStatuses.INITIAL || elem.status == this.sendStatuses.SENDING) : []
|
||||
},
|
||||
attachmentsSent() {
|
||||
this.sortSendingAttachments();
|
||||
return this.sendingAttachments ? this.sendingAttachments.filter(elem => elem.status == this.sendStatuses.SENT) : []
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
sendAttachments(text, attachments) {
|
||||
this.sendingStatus = this.sendStatuses.SENDING;
|
||||
|
||||
this.sendingAttachments = attachments.map((attachment) => {
|
||||
let file = (() => {
|
||||
// other than file type image
|
||||
if(attachment instanceof File) {
|
||||
return attachment;
|
||||
} else {
|
||||
if (attachment.scaled && attachment.useScaled) {
|
||||
// Send scaled version of image instead!
|
||||
return attachment.scaled;
|
||||
} else {
|
||||
// Send actual file image when not scaled!
|
||||
return attachment.actualFile;
|
||||
}
|
||||
}
|
||||
})();
|
||||
let sendInfo = {
|
||||
id: attachment.name,
|
||||
status: this.sendStatuses.INITIAL,
|
||||
statusDate: Date.now,
|
||||
attachment: file,
|
||||
preview: attachment.image,
|
||||
progress: 0,
|
||||
randomRotation: 0,
|
||||
randomTranslationX: 0,
|
||||
randomTranslationY: 0
|
||||
};
|
||||
attachment.sendInfo = sendInfo;
|
||||
return sendInfo;
|
||||
});
|
||||
|
||||
this.sendingPromise = util.sendTextMessage(this.$matrix.matrixClient, this.room.roomId, text)
|
||||
.then((eventId) => {
|
||||
this.sendingRootEventId = eventId;
|
||||
|
||||
// Use the eventId as a thread root for all the media
|
||||
let promiseChain = Promise.resolve();
|
||||
const getItemPromise = (index) => {
|
||||
if (index < this.sendingAttachments.length) {
|
||||
const item = this.sendingAttachments[index];
|
||||
if (item.status !== this.sendStatuses.INITIAL) {
|
||||
return getItemPromise(++index);
|
||||
}
|
||||
const itemPromise = util.sendImage(this.$matrix.matrixClient, this.room.roomId, item.attachment, ({ loaded, total }) => {
|
||||
if (loaded == total) {
|
||||
item.progress = 100;
|
||||
} else if (total > 0) {
|
||||
item.progress = 100 * loaded / total;
|
||||
}
|
||||
}, eventId)
|
||||
.then(() => {
|
||||
// Look at last item rotation, flipping the sign on this, so looks more like a true stack
|
||||
let signR = 1;
|
||||
let signX = 1;
|
||||
let signY = 1;
|
||||
if (this.attachmentsSent.length > 0) {
|
||||
if (this.attachmentsSent[0].randomRotation >= 0) {
|
||||
signR = -1;
|
||||
}
|
||||
if (this.attachmentsSent[0].randomTranslationX >= 0) {
|
||||
signX = -1;
|
||||
}
|
||||
if (this.attachmentsSent[0].randomTranslationY >= 0) {
|
||||
signY = -1;
|
||||
}
|
||||
}
|
||||
item.randomRotation = signR * (2 + Math.random() * 10);
|
||||
item.randomTranslationX = signX * Math.random() * 20;
|
||||
item.randomTranslationY = signY * Math.random() * 20;
|
||||
item.status = this.sendStatuses.SENT;
|
||||
item.statusDate = Date.now;
|
||||
}).catch(ignorederr => {
|
||||
if (item.promise.aborted) {
|
||||
item.status = this.sendStatuses.CANCELED;
|
||||
} else {
|
||||
console.error("ERROR", ignorederr);
|
||||
item.status = this.sendStatuses.FAILED;
|
||||
}
|
||||
});
|
||||
item.promise = itemPromise;
|
||||
return itemPromise.then(() => getItemPromise(++index));
|
||||
}
|
||||
else return Promise.resolve();
|
||||
};
|
||||
|
||||
return promiseChain.then(() => getItemPromise(0));
|
||||
})
|
||||
.then(() => {
|
||||
this.sendingStatus = this.sendStatuses.SENT;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("ERROR", err);
|
||||
});
|
||||
return this.sendingPromise;
|
||||
},
|
||||
|
||||
cancelSendAttachments() {
|
||||
this.sendingAttachments.toReversed().forEach(item => {
|
||||
this.cancelSendAttachmentItem(item);
|
||||
});
|
||||
this.sendingStatus = this.sendStatuses.CANCELED;
|
||||
if (this.sendingRootEventId && this.room) {
|
||||
// Redact the root event.
|
||||
this.$matrix.matrixClient
|
||||
.redactEvent(this.room.roomId, this.sendingRootEventId, undefined, { reason: "cancel" })
|
||||
.then(() => {
|
||||
console.log("Message redacted");
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("Redaction failed: ", err);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
cancelSendAttachmentItem(item) {
|
||||
if (item.promise && item.status != this.sendStatuses.INITIAL) {
|
||||
item.promise.abort();
|
||||
}
|
||||
item.status = this.sendStatuses.CANCELED;
|
||||
},
|
||||
|
||||
sortSendingAttachments() {
|
||||
this.sendingAttachments.sort((a, b) => b.statusDate - a.statusDate);
|
||||
},
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue