diff --git a/src/assets/css/channel.scss b/src/assets/css/channel.scss index 4cdfcc6..b987e56 100644 --- a/src/assets/css/channel.scss +++ b/src/assets/css/channel.scss @@ -83,6 +83,10 @@ .bubble.image-bubble { /* full bleed */ padding: 0 0 0 0; + border-radius: 0 !important; + .v-image { + border-radius: 0 !important; + } } .quick-reaction-container { order: 6; @@ -139,4 +143,55 @@ white-space: nowrap; } + /* Style file items (i.e. PDF files) */ + .thumbnail-item.file-item { + border: 1px solid black; + border-radius: 8px; + padding: 15px 40px 15px 60px; + align-items: start; + position: relative; + svg { + position: absolute; + top: 12px; + left: 12px; + width: 40px; + height: 40px; + } + &::after { + content: " "; + background: url("~@/assets/icons/ic_export.svg") no-repeat; + background-position: 0 0; + position: absolute; + right: 15px; + height: 24px; + width: 24px; + margin: auto 0; + } + } + + .swipeable-thumbnails-view { + margin-left: -15px; + margin-right: -15px; + .thumbnail-item.file-item { + margin: 15px; + width: auto; + } + .indicator-container { + display: flex; + align-items: center; + justify-content: center; + margin-top: 12px; + .indicator { + width: 6px; + height: 6px; + border-radius: 3px; + margin: 0 2.5px; + background: #D9D9D9; + &.current { + background: #1C1C31; + } + } + + } + } } diff --git a/src/assets/icons/ic_export.svg b/src/assets/icons/ic_export.svg new file mode 100644 index 0000000..d6f2d8e --- /dev/null +++ b/src/assets/icons/ic_export.svg @@ -0,0 +1,4 @@ + + + diff --git a/src/components/Chat.vue b/src/components/Chat.vue index 22170ae..6b9ee74 100644 --- a/src/components/Chat.vue +++ b/src/components/Chat.vue @@ -727,6 +727,11 @@ export default { // Filter out relations and redactions events = this.events.toReversed().filter((e) => !e.isRelation() && !e.isRedaction()); + // If Channel, remove all redacted events as well. + if (this.room && this.room.displayType == ROOM_TYPE_CHANNEL) { + events = events.filter((e) => !e.isRedacted()); + } + // Add read marker, if it is not newer than the "latest" message we are going to display // let showReadMarker = false; @@ -981,20 +986,22 @@ export default { // Handle pinning // - const pinnedEvents = this.$matrix.getPinnedEvents(this.room); - console.log("Pinned events in room", JSON.stringify(pinnedEvents)); - events.forEach((e) => { - Vue.set(e, "isPinned", pinnedEvents.includes(e.getId())); - }); - updated = updated.sort((e1, e2) => { - if (!e1.isPinned && !e2.isPinned) return 0; - else if (e1.isPinned && !e2.isPinned) return this.reverseOrder ? 1 : -1; - else if (e2.isPinned && !e1.isPinned) return this.reverseOrder ? -1 : 1; - else { - // Look at order in "pinned" value in the m.room.pinned_events event! - return pinnedEvents.indexOf(e1.getId()) < pinnedEvents.indexOf(e2.getId()) ? (this.reverseOrder ? 1 : -1) : (this.reverseOrder ? -1 : 1) - } - }); + if (this.room) { + const pinnedEvents = this.$matrix.getPinnedEvents(this.room); + updated.forEach((e) => { + Vue.set(e, "isPinned", pinnedEvents.includes(e.threadParent ? e.threadParent.getId() : e.getId())); + }); + + updated = updated.sort((e1, e2) => { + if (!e1.isPinned && !e2.isPinned) return 0; + else if (e1.isPinned && !e2.isPinned) return this.reverseOrder ? 1 : -1; + else if (e2.isPinned && !e1.isPinned) return this.reverseOrder ? -1 : 1; + else { + // Look at order in "pinned" value in the m.room.pinned_events event! + return pinnedEvents.indexOf(e1.getId()) < pinnedEvents.indexOf(e2.getId()) ? (this.reverseOrder ? 1 : -1) : (this.reverseOrder ? -1 : 1) + } + }); + } if (!onlyIfLengthChanges || updated.length != this.events.length) { this.events = updated; // Changed } @@ -1781,11 +1788,13 @@ export default { }, pin(event) { - this.$matrix.setEventPinned(this.room, event, true); + const eventToPin = event.parentThread ? event.parentThread : event; + this.$matrix.setEventPinned(this.room, eventToPin, true); }, unpin(event) { - this.$matrix.setEventPinned(this.room, event, false); + const eventToUnpin = event.parentThread ? event.parentThread : event; + this.$matrix.setEventPinned(this.room, eventToUnpin, false); }, cancelEditReply() { diff --git a/src/components/messages/MessageIncoming.vue b/src/components/messages/MessageIncoming.vue index 7798445..6dd4a8f 100644 --- a/src/components/messages/MessageIncoming.vue +++ b/src/components/messages/MessageIncoming.vue @@ -17,7 +17,7 @@ -
$vuetify.icons.ic_pin_filled
+
$vuetify.icons.ic_pin_filled
more_vert diff --git a/src/components/messages/MessageIncomingThread.vue b/src/components/messages/MessageIncomingThread.vue index 0b17928..9b0888b 100644 --- a/src/components/messages/MessageIncomingThread.vue +++ b/src/components/messages/MessageIncomingThread.vue @@ -10,7 +10,8 @@
- + + @@ -38,16 +39,18 @@ + + \ No newline at end of file diff --git a/src/components/messages/messageMixin.js b/src/components/messages/messageMixin.js index 432b14d..3340863 100644 --- a/src/components/messages/messageMixin.js +++ b/src/components/messages/messageMixin.js @@ -109,7 +109,7 @@ export default { * Don't show sender and time if the next event is within 2 minutes and also from us (= back to back messages) */ showSenderAndTime() { - if (!this.event.isPinned && this.nextEvent && this.nextEvent.getSender() == this.event.getSender()) { + if (!this.isPinned && this.nextEvent && this.nextEvent.getSender() == this.event.getSender()) { const ts1 = this.nextEvent.event.origin_server_ts; const ts2 = this.event.event.origin_server_ts; return ts1 - ts2 < 2 * 60 * 1000; // less than 2 minutes @@ -180,15 +180,19 @@ export default { return this.event.getContent().body; }, + isPinned() { + return this.event.parentThread ? this.event.parentThread.isPinned : this.event.isPinned; + }, + /** * Classes to set for the message. Currently only for "messageIn" */ messageClasses() { if (this.incoming) { - return { messageIn: true, "from-admin": this.senderIsAdminOrModerator(this.event), "pinned": this.event.isPinned }; + return { messageIn: true, "from-admin": this.senderIsAdminOrModerator(this.event), "pinned": this.isPinned }; } else { - return { messageOut: true, "pinned": this.event.isPinned }; + return { messageOut: true, "pinned": this.isPinned }; } },