keanu-weblite/src/components/messages/MessageOutgoingThread.vue
2024-10-17 10:22:24 +02:00

163 lines
No EOL
5.4 KiB
Vue

<template>
<message-outgoing v-bind="{ ...$props, ...$attrs }" v-on="$listeners" v-if="items.length > 1 || event.isRedacted()">
<div class="bubble">
<div class="original-message" v-if="inReplyToText">
<div class="original-message-sender">{{ inReplyToSender }}</div>
<div
class="original-message-text"
v-html="linkify($sanitize(inReplyToText))"
/>
</div>
<div class="message">
<SwipeableThumbnailsView :items="items" v-if="!event.isRedacted() && room.displayType == ROOM_TYPE_CHANNEL" />
<v-container v-else-if="!event.isRedacted()" fluid class="imageCollection">
<v-row wrap>
<v-col v-for="({ size, item }) in layoutedItems()" :key="item.event.getId()" :cols="size">
<ThumbnailView :item="item" :previewOnly="true" v-on:itemclick="onItemClick($event)" />
</v-col>
</v-row>
</v-container>
<i v-if="event.isRedacted()" class="deleted-text">
<v-icon size="small">block</v-icon>
{{ redactedBySomeoneElse(event) ? $t('message.incoming_message_deleted_text') : $t('message.outgoing_message_deleted_text')}}
</i>
<span v-html="linkify($sanitize(messageText))" v-else />
<span class="edit-marker" v-if="event.replacingEventId() && !event.isRedacted()">
{{ $t('message.edited') }}
</span>
</div>
</div>
<GalleryItemsView :originalEvent="originalEvent" :items="items" :initialItem="showItem" v-if="!!showItem" v-on:close="showItem = null" />
</message-outgoing>
<component v-else-if="items.length == 1" :is="componentFn(items[0].event)"
:originalEvent="items[0].event"
v-bind="{...$props, ...$attrs}" v-on="$listeners"
/>
</template>
<script>
import MessageOutgoing from "./MessageOutgoing.vue";
import messageMixin from "./messageMixin";
import util, { ROOM_TYPE_CHANNEL } from "../../plugins/utils";
import GalleryItemsView from '../file_mode/GalleryItemsView.vue';
import ThumbnailView from '../file_mode/ThumbnailView.vue';
import SwipeableThumbnailsView from "./channel/SwipeableThumbnailsView.vue";
export default {
extends: MessageOutgoing,
components: { MessageOutgoing, GalleryItemsView, ThumbnailView, SwipeableThumbnailsView },
mixins: [messageMixin],
data() {
return {
ROOM_TYPE_CHANNEL: ROOM_TYPE_CHANNEL,
items: [],
showItem: null,
}
},
mounted() {
this.thread = this.timelineSet.relations.getChildEventsForEvent(this.event.getId(), util.threadMessageType(), "m.room.message");
if (!this.thread) {
this.event.on("Event.relationsCreated", this.onRelationsCreated);
}
},
beforeDestroy() {
this.event.off("Event.relationsCreated", this.onRelationsCreated);
},
methods: {
onRelationsCreated() {
this.thread = this.timelineSet.relations.getChildEventsForEvent(this.event.getId(), util.threadMessageType(), "m.room.message");
this.event.off("Event.relationsCreated", this.onRelationsCreated);
},
onItemClick(event) {
this.showItem = event.item;
},
processThread() {
this.$emit('layout-change', () => {
this.items = this.timelineSet.relations.getAllChildEventsForEvent(this.event.getId())
.filter(e => !e.isRedacted() && util.downloadableTypes().includes(e.getContent().msgtype))
.map(e => {
let ret = {
event: e,
src: null,
};
ret.promise =
util
.getThumbnail(this.$matrix.matrixClient, e, this.$config, 100, 100)
.then((url) => {
ret.src = url;
})
.catch((err) => {
console.log("Failed to fetch thumbnail: ", err);
});
return ret;
});
}, this.$el);
},
layoutedItems() {
if (!this.items || this.items.length == 0) { return [] }
let array = this.items.slice(0);
let rows = []
while (array.length > 0) {
if (array.length >= 7) {
rows.push({ size: 6, item: array[0] });
rows.push({ size: 6, item: array[1] });
rows.push({ size: 12, item: array[2] });
rows.push({ size: 3, item: array[3] });
rows.push({ size: 3, item: array[4] });
rows.push({ size: 3, item: array[5] });
rows.push({ size: 3, item: array[6] });
array = array.slice(7);
} else if (array.length >= 3) {
rows.push({ size: 6, item: array[0] });
rows.push({ size: 6, item: array[1] });
rows.push({ size: 12, item: array[2] });
array = array.slice(3);
} else if (array.length >= 2) {
rows.push({ size: 6, item: array[0] });
rows.push({ size: 6, item: array[1] });
array = array.slice(2);
} else {
rows.push({ size: 12, item: array[0] });
array = array.slice(1);
}
}
return rows
},
}
};
</script>
<style lang="scss">
@import "@/assets/css/chat.scss";
</style>
<style lang="scss" scoped>
.bubble {
width: 100%;
}
.imageCollection {
border-radius: 15px;
padding: 0;
overflow: hidden;
.row {
margin: -4px; // Compensate for column padding, so the border-radius above looks round!
padding: 0;
}
.col {
padding: 2px;
}
.file-item {
display: flex;
align-items: center;
justify-content: center;
font-size: 0.6rem;
flex-direction: column;
padding: 20px;
}
}
</style>