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
|
|
@ -44,7 +44,7 @@
|
|||
sendCurrentTextMessage();
|
||||
}
|
||||
" />
|
||||
<v-btn @click="send" :disabled="!attachments || attachments.length == 0">{{ $t("menu.send") }}</v-btn>
|
||||
<v-btn @click="sendAll" :disabled="!attachments || attachments.length == 0">{{ $t("menu.send") }}</v-btn>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -54,13 +54,13 @@
|
|||
v-if="attachments && attachments.length > 0 && (status == mainStatuses.SENDING || status == mainStatuses.SENT)">
|
||||
<div class="attachment-wrapper">
|
||||
<div class="file-drop-sent-stack" ref="stackContainer">
|
||||
<div v-if="status == mainStatuses.SENDING && countSent == 0" class="no-items">
|
||||
<div v-if="status == mainStatuses.SENDING && attachmentsSentCount == 0" class="no-items">
|
||||
<div class="file-drop-stack-item direct" :style="stackItemTransform(null, -1)"></div>
|
||||
<div>{{ $t('file_mode.sending_progress') }}</div>
|
||||
</div>
|
||||
<div v-else v-for="(item, index) in sentItems" :key="item.id" class="file-drop-stack-item animated"
|
||||
:style="stackItemTransform(item, index)">
|
||||
<v-img v-if="item.attachment && item.attachment.image" :src="item.attachment.image" />
|
||||
<div v-else v-for="(info, index) in attachmentsSent" :key="info.id" class="file-drop-stack-item animated"
|
||||
:style="stackItemTransform(info, index)">
|
||||
<v-img v-if="info.preview" :src="info.preview" />
|
||||
</div>
|
||||
<div v-if="status == mainStatuses.SENT" class="items-sent" :style="stackItemTransform(null, -1)">
|
||||
<v-icon>$vuetify.icons.ic_check_circle</v-icon>
|
||||
|
|
@ -69,18 +69,18 @@
|
|||
|
||||
<!-- Middle section -->
|
||||
<div v-if="status == mainStatuses.SENDING" class="file-drop-sending-container">
|
||||
<div class="file-drop-sending-item" v-for="(info, index) in sendingItems" :key="index">
|
||||
<v-img v-if="info.attachment && info.attachment.image" :src="info.attachment.image" />
|
||||
<div class="file-drop-sending-item" v-for="(info, index) in attachmentsSending" :key="index">
|
||||
<v-img v-if="info.preview" :src="info.preview" />
|
||||
<div v-else class="filename">{{ info.attachment.name }}</div>
|
||||
<v-progress-linear :value="info.progress"></v-progress-linear>
|
||||
<div class="file-drop-cancel clickable" @click.stop="cancelSendingItem(info)">
|
||||
<div class="file-drop-cancel clickable" @click.stop="cancelSendAttachmentItem(info)">
|
||||
<v-icon size="14" color="white">close</v-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="status == mainStatuses.SENT" class="file-drop-sending-container">
|
||||
<div class="file-drop-files-sent">{{ $tc((this.messageInput && this.messageInput.length > 0) ?
|
||||
"file_mode.files_sent_with_note" : "file_mode.files_sent", sentItems.length) }}</div>
|
||||
"file_mode.files_sent_with_note" : "file_mode.files_sent", attachmentsSent.length) }}</div>
|
||||
<div class="file-drop-section">
|
||||
<v-textarea disabled full-width solo flat auto-grow v-model="messageInput" no-resize class="input-area-text"
|
||||
rows="1" hide-details background-color="transparent" />
|
||||
|
|
@ -105,11 +105,11 @@
|
|||
|
||||
<script>
|
||||
import messageMixin from "../messages/messageMixin";
|
||||
import util from "../../plugins/utils";
|
||||
import sendAttachmentsMixin from "../sendAttachmentsMixin";
|
||||
const prettyBytes = require("pretty-bytes");
|
||||
|
||||
export default {
|
||||
mixins: [messageMixin],
|
||||
mixins: [messageMixin, sendAttachmentsMixin],
|
||||
components: {},
|
||||
props: {
|
||||
attachments: {
|
||||
|
|
@ -129,13 +129,6 @@ export default {
|
|||
SENT: 2,
|
||||
}),
|
||||
status: 0,
|
||||
statuses: Object.freeze({
|
||||
INITIAL: 0,
|
||||
SENT: 1,
|
||||
CANCELED: 2,
|
||||
FAILED: 3,
|
||||
}),
|
||||
sendInfo: [],
|
||||
dropTarget: false,
|
||||
};
|
||||
},
|
||||
|
|
@ -151,20 +144,6 @@ export default {
|
|||
return this.currentItemIndex >= 0 && this.currentItemIndex < this.attachments.length &&
|
||||
this.attachments[this.currentItemIndex].image
|
||||
},
|
||||
countSent() {
|
||||
return this.sendInfo ? this.sendInfo.reduce((a, elem, ignoredidx, ignoredarray) => elem.status == this.statuses.SENT ? a + 1 : a, 0) : 0
|
||||
},
|
||||
sendingItems() {
|
||||
return this.sendInfo ? this.sendInfo.filter(elem => elem.status == this.statuses.INITIAL) : []
|
||||
},
|
||||
sentItems() {
|
||||
this.sortSendinfo();
|
||||
return this.sendInfo ? this.sendInfo.filter(elem => elem.status == this.statuses.SENT) : []
|
||||
},
|
||||
sentItemsReversed() {
|
||||
const array = this.sentItems;
|
||||
return array.map((ignoreditem, idx) => array[array.length - 1 - idx])
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
attachments(newValue, oldValue) {
|
||||
|
|
@ -207,7 +186,7 @@ export default {
|
|||
},
|
||||
reset() {
|
||||
this.$emit('reset');
|
||||
this.sendInfo = [];
|
||||
this.sendingAttachments = [];
|
||||
this.status = this.mainStatuses.SELECTING;
|
||||
this.messageInput = "";
|
||||
this.currentItemIndex = 0;
|
||||
|
|
@ -218,97 +197,13 @@ export default {
|
|||
console.log("Error leaving", err);
|
||||
});
|
||||
},
|
||||
send() {
|
||||
sendAll() {
|
||||
this.status = this.mainStatuses.SENDING;
|
||||
this.sendInfo = this.attachments.map((attachment) => {
|
||||
return {
|
||||
id: attachment.name,
|
||||
status: this.statuses.INITIAL,
|
||||
statusDate: Date.now,
|
||||
attachment: attachment.actualFile || attachment,
|
||||
progress: 0,
|
||||
randomRotation: 0,
|
||||
randomTranslationX: 0,
|
||||
randomTranslationY: 0
|
||||
}
|
||||
});
|
||||
|
||||
const text = (this.messageInput && this.messageInput.length > 0) ? this.messageInput : this.$t('file_mode.files');
|
||||
util.sendTextMessage(this.$matrix.matrixClient, this.room.roomId, text)
|
||||
.then((eventId) => {
|
||||
// Use the eventId as a thread root for all the media
|
||||
let promiseChain = Promise.resolve();
|
||||
const getItemPromise = (index) => {
|
||||
if (index < this.sendInfo.length) {
|
||||
const item = this.sendInfo[index];
|
||||
if (item.status !== this.statuses.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.sentItems.length > 0) {
|
||||
if (this.sentItems[0].randomRotation >= 0) {
|
||||
signR = -1;
|
||||
}
|
||||
if (this.sentItems[0].randomTranslationX >= 0) {
|
||||
signX = -1;
|
||||
}
|
||||
if (this.sentItems[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.statuses.SENT;
|
||||
item.statusDate = Date.now;
|
||||
}).catch(ignorederr => {
|
||||
if (item.promise.aborted) {
|
||||
item.status = this.statuses.CANCELED;
|
||||
} else {
|
||||
console.error("ERROR", ignorederr);
|
||||
item.status = this.statuses.FAILED;
|
||||
}
|
||||
});
|
||||
item.promise = itemPromise;
|
||||
return itemPromise.then(() => getItemPromise(++index));
|
||||
}
|
||||
else return Promise.resolve();
|
||||
};
|
||||
|
||||
return promiseChain.then(() => getItemPromise(0));
|
||||
})
|
||||
this.sendAttachments((this.messageInput && this.messageInput.length > 0) ? this.messageInput : this.$t('file_mode.files'), this.attachments)
|
||||
.then(() => {
|
||||
this.status = this.mainStatuses.SENT;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("ERROR", err);
|
||||
});
|
||||
},
|
||||
cancelSendingItem(item) {
|
||||
if (item.promise && item.status == this.statuses.INITIAL) {
|
||||
item.promise.abort();
|
||||
}
|
||||
item.status = this.statuses.CANCELED;
|
||||
},
|
||||
checkDone() {
|
||||
if (!this.sendInfo.some(a => a.status == this.statuses.INITIAL)) {
|
||||
this.status = this.mainStatuses.SENT;
|
||||
}
|
||||
},
|
||||
sortSendinfo() {
|
||||
this.sendInfo.sort((a, b) => b.statusDate - a.statusDate);
|
||||
},
|
||||
stackItemTransform(item, index) {
|
||||
const size = 0.6 * (this.$refs.stackContainer ? Math.min(this.$refs.stackContainer.clientWidth, this.$refs.stackContainer.clientHeight) : 176);
|
||||
let transform = ""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue