From fd82fd8840407382916a9ebf698b1ddb327fe67e Mon Sep 17 00:00:00 2001 From: N-Pex Date: Wed, 11 Jun 2025 14:59:34 +0200 Subject: [PATCH] Add AttachmentBatch for future removal of sendAttachmentsMixin --- src/assets/css/sendattachments.scss | 100 ++++++-- src/components/Chat.vue | 159 +----------- .../file_mode/SendAttachmentsLayout.vue | 100 ++++---- src/models/attachment.ts | 18 ++ src/models/attachmentManager.ts | 231 +++++++++++++++++- 5 files changed, 377 insertions(+), 231 deletions(-) diff --git a/src/assets/css/sendattachments.scss b/src/assets/css/sendattachments.scss index 6219764..a3094bf 100644 --- a/src/assets/css/sendattachments.scss +++ b/src/assets/css/sendattachments.scss @@ -45,9 +45,11 @@ $hiliteColor: #4642f1; width: 100%; height: 50%; background-color: $background; + &.drop-target { background-color: $backgroundHilite; } + border-radius: 19px; display: flex; flex-direction: column; @@ -79,6 +81,7 @@ $hiliteColor: #4642f1; height: $small-button-height !important; margin-top: $chat-standard-padding-xs; margin-bottom: $chat-standard-padding-xs; + &.large { padding: 16px 23px; height: $large-button-height; @@ -89,6 +92,7 @@ $hiliteColor: #4642f1; textarea { color: rgba($text, 80%) !important; } + textarea::placeholder { color: rgba($text, 80%) !important; } @@ -98,22 +102,28 @@ $hiliteColor: #4642f1; flex: 0 0 100%; overflow-y: auto; display: flex; + flex-direction: column; } + .file-drop-current-item { width: 100%; flex: 1 1 100%; background-color: $backgroundSection; display: flex; + &.drop-target { background-color: $backgroundHilite; } + border-radius: 19px; overflow: hidden; + .v-img { width: 100%; height: 100%; object-fit: cover; } + .filename { width: 100%; height: 100%; @@ -158,9 +168,12 @@ $hiliteColor: #4642f1; &::-webkit-scrollbar { display: none; } + /* Hide scrollbar for IE, Edge and Firefox */ - -ms-overflow-style: none; /* IE and Edge */ - scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; + /* IE and Edge */ + scrollbar-width: none; + /* Firefox */ .file-drop-thumbnail { width: 46px; @@ -171,17 +184,21 @@ $hiliteColor: #4642f1; border: 2px solid white; display: inline-block; position: relative; + &.current { border: 2px solid #4642f1; } + &.noborder { border: 2px solid transparent; } + .v-img { width: 100%; height: 100%; object-fit: cover; } + margin-right: 8px; .add, @@ -195,11 +212,13 @@ $hiliteColor: #4642f1; display: flex; align-items: center; justify-content: center; + .v-icon { width: 14px; height: 15.75px; } } + .remove { // Slight background to make visible background-color: rgba(black, 0.2); @@ -228,31 +247,40 @@ $hiliteColor: #4642f1; border-radius: 19px; display: flex; flex-direction: column; - .input-area-text { - flex: 0 0 auto; - width: 100%; - margin-bottom: 50px; - padding: 16px 18px; - font-family: "Inter", sans-serif; - font-weight: 300; - .v-field { - background-color: transparent !important; - } - } + .input-container__buttons { position: absolute; right: 8px; bottom: 10px; display: flex; - & > *:not(:first-child) { + + &>*:not(:first-child) { margin-left: 8px; } } } + .input-area-text { + flex: 0 0 auto; + width: 100%; + margin-bottom: 50px; + padding: 16px 18px; + font-family: "Inter", sans-serif; + font-weight: 300; + + .v-field { + background-color: transparent !important; + } + } + @keyframes fadeInStackItem { - from {opacity: 0;} - to {opacity: 1;} + from { + opacity: 0; + } + + to { + opacity: 1; + } } // Sending @@ -263,49 +291,63 @@ $hiliteColor: #4642f1; display: flex; align-items: center; justify-content: center; + .no-items { display: flex; align-items: center; justify-content: center; + div { position: absolute; } + .file-drop-stack-item { transform: rotate(-4.4deg); } + color: #fff; text-align: center; font-size: 21 * $chat-text-size; - font-family: "Poppins", sans-serif; + font-family: "Poppins", + sans-serif; font-weight: 700; letter-spacing: 0.34px; } + .items-sent { z-index: 1000; display: flex; align-items: center; justify-content: center; - div, .v-icon { + + div, + .v-icon { position: absolute; } - .v-icon, .v-icon__component { + + .v-icon, + .v-icon__component { width: 30%; height: 30%; } } + .file-drop-stack-item { background: #3a3a3c; position: absolute; overflow: hidden; opacity: 0; + .v-img { width: 100%; height: 100%; object-fit: cover; } + &.direct { opacity: 1 !important; } + &.animated { animation-name: fadeInStackItem; animation-fill-mode: both; @@ -327,9 +369,12 @@ $hiliteColor: #4642f1; &::-webkit-scrollbar { display: none; } + /* Hide scrollbar for IE, Edge and Firefox */ - -ms-overflow-style: none; /* IE and Edge */ - scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; + /* IE and Edge */ + scrollbar-width: none; + /* Firefox */ .file-drop-sending-item { width: 100%; @@ -339,6 +384,7 @@ $hiliteColor: #4642f1; border-radius: 12px; position: relative; padding: 8px; + .v-img { width: $min-touch-target; height: $min-touch-target; @@ -347,18 +393,22 @@ $hiliteColor: #4642f1; flex: 0 0 $min-touch-target; margin-right: 8px; } + margin-bottom: 8px; display: flex; align-items: center; + .filename { position: absolute; top: 18px; left: 8px; font-size: 0.7em; } + .v-progress-linear { align-self: flex-end; } + .file-drop-cancel { position: absolute; right: 8px; @@ -379,7 +429,9 @@ $hiliteColor: #4642f1; .v-progress-circular { margin-left: 8px; } - background: linear-gradient(0deg, #000 0%, #000 100%), #4642f1; + + background: linear-gradient(0deg, #000 0%, #000 100%), + #4642f1; } } @@ -396,10 +448,12 @@ $hiliteColor: #4642f1; .file-drop-sent-input-container { background-color: transparent; + .v-btn { right: unset; left: 8px; background: linear-gradient(0deg, #000 0%, #000 100%), #4642f1; + &.close { right: 8px; left: unset; @@ -407,4 +461,4 @@ $hiliteColor: #4642f1; } } } -} +} \ No newline at end of file diff --git a/src/components/Chat.vue b/src/components/Chat.vue index 541c906..b6e5b3e 100644 --- a/src/components/Chat.vue +++ b/src/components/Chat.vue @@ -228,90 +228,13 @@ - - @@ -490,10 +413,7 @@ export default { scrollPosition: null, currentFileInputs: [], - currentSendShowSendButton: true, - currentSendError: null, - currentSendErrorExceededFile: null, - attachmentCaption: undefined, + uploadBatch: undefined, showEmojiPicker: false, selectedEvent: null, editedEvent: null, @@ -615,29 +535,6 @@ export default { const currentUserId= this.selectedEvent?.sender.userId || this.$matrix.currentUserId return this.joinedAndInvitedMembers.find(({userId}) => userId === currentUserId) }, - nonImageFiles() { - return this.isCurrentFileInputsAnArray && this.currentFileInputs.filter(file => !file?.type.includes("image/")) - }, - imageFiles() { - return this.isCurrentFileInputsAnArray && this.currentFileInputs.filter(file => file?.type.includes("image/")) - }, - isCurrentFileInputsAnArray() { - return Array.isArray(this.currentFileInputs) - }, - showAttachmentCaptionInput() { - // IFF we are sending one PDF, add option to set caption. - const imageFiles = this.imageFiles || []; - const otherFiles = this.nonImageFiles || []; - return imageFiles.length == 0 && otherFiles.length == 1 && (otherFiles[0].type === "application/pdf" || (otherFiles[0].name || "").endsWith(".pdf")); - }, - currentFileInputsDialog: { - get() { - return this.isCurrentFileInputsAnArray - }, - set() { - this.currentFileInputs = []; - } - }, chatContainer() { const container = this.$refs.chatContainer; if (this.useVoiceMode) { @@ -1493,32 +1390,15 @@ export default { this.$refs.attachment.click(); }, - async addAttachment(file) { + addAttachment(file) { if (file) { - this.currentFileInputs = [... this.currentFileInputs, this.$matrix.attachmentManager.createAttachment(file)]; - // let optimizedFileObj; - // if (file.type.startsWith("image/")) { - // const f = await proofmode.proofCheckFile(file); - - // var reader = new FileReader(); - // optimizedFileObj = await new Promise(resolve => { - // reader.onload = evt => { - // resolve(this.optimizeImage(evt, file)); - // } - // reader.readAsDataURL(f); - // }) - // } else { - // optimizedFileObj = file; - // } - // console.error("OPTIMIZED", optimizedFileObj); - // this.currentFileInputs = Array.isArray(this.currentFileInputs) ? [...this.currentFileInputs, optimizedFileObj] : [optimizedFileObj]; + if (!this.uploadBatch) { + this.uploadBatch = this.$matrix.attachmentManager.createUpload(this.room); + } + this.uploadBatch?.addAttachment(this.$matrix.attachmentManager.createAttachment(file)); } }, - removeAttachment(index) { - this.currentFileInputs = this.currentFileInputs.toSpliced(index, 1); - }, - /** * Handle picked attachment */ @@ -1527,24 +1407,7 @@ export default { }, addAttachments(files) { - // TODO - refactor - this.$matrix.matrixClient.getMediaConfig(this.$matrix.useAuthedMedia).then((config) => { - const configUploadSize = config["m.upload.size"]; - const configFormattedUploadSize = this.formatBytes(configUploadSize); - - files.every(file => { - if (configUploadSize && file.size > configUploadSize) { - this.currentSendError = this.$t("message.upload_file_too_large"); - this.currentSendErrorExceededFile = this.$t("message.upload_exceeded_file_limit", { configFormattedUploadSize }); - this.currentSendShowSendButton = false; - return false; - } else { - this.currentSendShowSendButton = true; - } - return true; - }); - files.forEach(file => this.addAttachment(file)); - }); + files.forEach(file => this.addAttachment(file)); }, showStickerPicker() { @@ -1559,7 +1422,6 @@ export default { promise.then(() => { this.sendingAttachments = []; this.currentFileInputs = []; - this.attachmentCaption = undefined; this.sendingStatus = "initial" }) .catch((err) => { @@ -1580,7 +1442,6 @@ export default { this.cancelSendAttachments(); } this.currentFileInputs = []; - this.attachmentCaption = undefined; this.currentSendError = null; this.currentSendErrorExceededFile = null; this.sendingStatus = "initial"; diff --git a/src/components/file_mode/SendAttachmentsLayout.vue b/src/components/file_mode/SendAttachmentsLayout.vue index 1114bcd..d65ff2a 100644 --- a/src/components/file_mode/SendAttachmentsLayout.vue +++ b/src/components/file_mode/SendAttachmentsLayout.vue @@ -3,7 +3,7 @@
{{ $t("message.send_attachements_dialog_title") }}
-