159 lines
5.5 KiB
JavaScript
159 lines
5.5 KiB
JavaScript
|
|
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);
|
||
|
|
},
|
||
|
|
}
|
||
|
|
}
|