Lots of fixes to "media threads"
This commit is contained in:
parent
fe081edc62
commit
8bcceafcff
23 changed files with 867 additions and 333 deletions
|
|
@ -8,7 +8,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<v-avatar class="avatar" ref="avatar" size="32" color="#ededed" @click.stop="otherAvatarClicked($refs.avatar.$el)">
|
||||
<img v-if="messageEventAvatar(event)" :src="messageEventAvatar(event)" />
|
||||
<img v-if="messageEventAvatar(event)" :src="messageEventAvatar(event)" onerror="this.style.display='none'" />
|
||||
<span v-else class="white--text headline">{{
|
||||
eventSenderDisplayName(event).substring(0, 1).toUpperCase()
|
||||
}}</span>
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
<v-icon>more_vert</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
<QuickReactions :event="event" :timelineSet="timelineSet" v-on="$listeners"/>
|
||||
<QuickReactions :event="eventForReactions" :timelineSet="timelineSet" v-on="$listeners"/>
|
||||
<SeenBy :room="room" :event="event"/>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -2,14 +2,13 @@
|
|||
<message-incoming v-bind="{...$props, ...$attrs}" v-on="$listeners">
|
||||
<div class="bubble">
|
||||
<div class="original-message" v-if="inReplyToText">
|
||||
<div class="original-message-sender">
|
||||
{{ $t('message.user_said', {user: inReplyToSender || "Someone"}) }}
|
||||
</div>
|
||||
<div class="original-message-sender">{{ inReplyToSender }}</div>
|
||||
<div
|
||||
class="original-message-text"
|
||||
v-html="linkify($sanitize(inReplyToText))"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="message">
|
||||
<span>{{ $t('message.file_prefix') }}</span>
|
||||
<span
|
||||
|
|
|
|||
|
|
@ -2,14 +2,13 @@
|
|||
<message-incoming v-bind="{...$props, ...$attrs}" v-on="$listeners">
|
||||
<div class="bubble">
|
||||
<div class="original-message" v-if="inReplyToText">
|
||||
<div class="original-message-sender">
|
||||
{{ $t('message.user_said', {user: inReplyToSender || "Someone"}) }}
|
||||
</div>
|
||||
<div class="original-message-sender">{{ inReplyToSender }}</div>
|
||||
<div
|
||||
class="original-message-text"
|
||||
v-html="linkify($sanitize(inReplyToText))"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="message">
|
||||
<i v-if="event.isRedacted()" class="deleted-text">
|
||||
<v-icon :color="this.senderIsAdminOrModerator(this.event)?'white':''" size="small">block</v-icon>
|
||||
|
|
|
|||
|
|
@ -2,14 +2,13 @@
|
|||
<message-incoming v-bind="{ ...$props, ...$attrs }" v-on="$listeners" v-if="items.length > 1">
|
||||
<div class="bubble">
|
||||
<div class="original-message" v-if="inReplyToText">
|
||||
<div class="original-message-sender">
|
||||
{{ $t('message.user_said', {user: inReplyToSender || "Someone"}) }}
|
||||
</div>
|
||||
<div class="original-message-sender">{{ inReplyToSender }}</div>
|
||||
<div
|
||||
class="original-message-text"
|
||||
v-html="linkify($sanitize(inReplyToText))"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="message">
|
||||
<v-container fluid class="imageCollection">
|
||||
<v-row wrap>
|
||||
|
|
@ -51,54 +50,46 @@ export default {
|
|||
return {
|
||||
items: [],
|
||||
showItem: null,
|
||||
thread: null,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.thread = this.timelineSet.relations.getChildEventsForEvent(this.event.getId(), "m.thread", "m.room.message");
|
||||
this.processThread();
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.thread = null;
|
||||
},
|
||||
watch: {
|
||||
thread: {
|
||||
handler(newValue, oldValue) {
|
||||
if (oldValue) {
|
||||
oldValue.off('Relations.add', this.onAddRelation);
|
||||
}
|
||||
if (newValue) {
|
||||
newValue.on('Relations.add', this.onAddRelation);
|
||||
}
|
||||
this.processThread();
|
||||
},
|
||||
immediate: true
|
||||
if (!this.thread) {
|
||||
this.event.on("Event.relationsCreated", this.onRelationsCreated);
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.event.off("Event.relationsCreated", this.onRelationsCreated);
|
||||
},
|
||||
methods: {
|
||||
onAddRelation() {
|
||||
this.processThread();
|
||||
onRelationsCreated() {
|
||||
this.thread = this.timelineSet.relations.getChildEventsForEvent(this.event.getId(), "m.thread", "m.room.message");
|
||||
this.event.off("Event.relationsCreated", this.onRelationsCreated);
|
||||
},
|
||||
onItemClick(event) {
|
||||
this.showItem = event.item;
|
||||
},
|
||||
processThread() {
|
||||
this.items = this.timelineSet.relations.getAllChildEventsForEvent(this.event.getId()).map(e => {
|
||||
let ret = {
|
||||
event: e,
|
||||
src: null,
|
||||
};
|
||||
ret.promise =
|
||||
util
|
||||
.getThumbnail(this.$matrix.matrixClient, e, 100, 100)
|
||||
.then((url) => {
|
||||
ret.src = url;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("Failed to fetch thumbnail: ", err);
|
||||
});
|
||||
return ret;
|
||||
});
|
||||
this.$emit('layout-change', () => {
|
||||
this.items = this.timelineSet.relations.getAllChildEventsForEvent(this.event.getId())
|
||||
.filter(e => util.downloadableTypes().includes(e.getContent().msgtype))
|
||||
.map(e => {
|
||||
let ret = {
|
||||
event: e,
|
||||
src: null,
|
||||
};
|
||||
ret.promise =
|
||||
util
|
||||
.getThumbnail(this.$matrix.matrixClient, e, 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 [] }
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
<img v-if="userAvatar" :src="userAvatar" />
|
||||
<span v-else class="white--text headline">{{ userAvatarLetter }}</span>
|
||||
</v-avatar>
|
||||
<QuickReactions :event="event" :timelineSet="timelineSet" v-on="$listeners"/>
|
||||
<QuickReactions :event="eventForReactions" :timelineSet="timelineSet" v-on="$listeners"/>
|
||||
<SeenBy :room="room" :event="event"/>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -2,15 +2,14 @@
|
|||
<message-outgoing v-bind="{ ...$props, ...$attrs }" v-on="$listeners">
|
||||
<div class="bubble">
|
||||
<div class="original-message" v-if="inReplyToText">
|
||||
<div class="original-message-sender">
|
||||
{{ $t('message.user_said', {user: inReplyToSender || "Someone"}) }}
|
||||
</div>
|
||||
<div class="original-message-sender">{{ inReplyToSender }}</div>
|
||||
<div
|
||||
class="original-message-text"
|
||||
v-html="linkify($sanitize(inReplyToText))"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="message">
|
||||
<span>{{ $t('message.file_prefix') }}</span>
|
||||
<span
|
||||
|
|
|
|||
|
|
@ -2,9 +2,7 @@
|
|||
<message-outgoing v-bind="{ ...$props, ...$attrs }" v-on="$listeners">
|
||||
<div class="bubble">
|
||||
<div class="original-message" v-if="inReplyToText">
|
||||
<div class="original-message-sender">
|
||||
{{ $t('message.user_said', {user: inReplyToSender || "Someone"}) }}
|
||||
</div>
|
||||
<div class="original-message-sender">{{ inReplyToSender }}</div>
|
||||
<div
|
||||
class="original-message-text"
|
||||
v-html="linkify($sanitize(inReplyToText))"
|
||||
|
|
|
|||
|
|
@ -2,12 +2,14 @@
|
|||
<message-outgoing v-bind="{ ...$props, ...$attrs }" v-on="$listeners" v-if="items.length > 1">
|
||||
<div class="bubble">
|
||||
<div class="original-message" v-if="inReplyToText">
|
||||
<div class="original-message-sender">
|
||||
{{ $t('message.user_said', { user: inReplyToSender || "Someone" }) }}
|
||||
</div>
|
||||
<div class="original-message-text" v-html="linkify($sanitize(inReplyToText))" />
|
||||
<div class="original-message-sender">{{ inReplyToSender }}</div>
|
||||
<div
|
||||
class="original-message-text"
|
||||
v-html="linkify($sanitize(inReplyToText))"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="message">
|
||||
<v-container fluid class="imageCollection">
|
||||
<v-row wrap>
|
||||
|
|
@ -49,54 +51,46 @@ export default {
|
|||
return {
|
||||
items: [],
|
||||
showItem: null,
|
||||
thread: null,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.thread = this.timelineSet.relations.getChildEventsForEvent(this.event.getId(), "m.thread", "m.room.message");
|
||||
this.processThread();
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.thread = null;
|
||||
},
|
||||
watch: {
|
||||
thread: {
|
||||
handler(newValue, oldValue) {
|
||||
if (oldValue) {
|
||||
oldValue.off('Relations.add', this.onAddRelation);
|
||||
}
|
||||
if (newValue) {
|
||||
newValue.on('Relations.add', this.onAddRelation);
|
||||
}
|
||||
this.processThread();
|
||||
},
|
||||
immediate: true
|
||||
if (!this.thread) {
|
||||
this.event.on("Event.relationsCreated", this.onRelationsCreated);
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.event.off("Event.relationsCreated", this.onRelationsCreated);
|
||||
},
|
||||
methods: {
|
||||
onAddRelation() {
|
||||
this.processThread();
|
||||
onRelationsCreated() {
|
||||
this.thread = this.timelineSet.relations.getChildEventsForEvent(this.event.getId(), "m.thread", "m.room.message");
|
||||
this.event.off("Event.relationsCreated", this.onRelationsCreated);
|
||||
},
|
||||
onItemClick(event) {
|
||||
this.showItem = event.item;
|
||||
},
|
||||
processThread() {
|
||||
this.items = this.timelineSet.relations.getAllChildEventsForEvent(this.event.getId()).map(e => {
|
||||
let ret = {
|
||||
event: e,
|
||||
src: null,
|
||||
};
|
||||
ret.promise =
|
||||
util
|
||||
.getThumbnail(this.$matrix.matrixClient, e, 100, 100)
|
||||
.then((url) => {
|
||||
ret.src = url;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("Failed to fetch thumbnail: ", err);
|
||||
});
|
||||
return ret;
|
||||
});
|
||||
this.$emit('layout-change', () => {
|
||||
this.items = this.timelineSet.relations.getAllChildEventsForEvent(this.event.getId())
|
||||
.filter(e => util.downloadableTypes().includes(e.getContent().msgtype))
|
||||
.map(e => {
|
||||
let ret = {
|
||||
event: e,
|
||||
src: null,
|
||||
};
|
||||
ret.promise =
|
||||
util
|
||||
.getThumbnail(this.$matrix.matrixClient, e, 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 [] }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
<template>
|
||||
<message-incoming class="messageIn-thread" v-bind="{ ...$props, ...$attrs }" v-on="$listeners">
|
||||
<component v-for="item in items" :is="componentFn(item.event)" :originalEvent="item.event" :key="item.event.getId()"
|
||||
v-bind="{ ...$props }" v-on="$listeners" ref="exportedEvent" />
|
||||
</message-incoming>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MessageIncoming from "../MessageIncoming.vue";
|
||||
import messageMixin from "./../messageMixin";
|
||||
import util from "../../../plugins/utils";
|
||||
|
||||
export default {
|
||||
extends: MessageIncoming,
|
||||
components: { MessageIncoming },
|
||||
mixins: [messageMixin],
|
||||
data() {
|
||||
return {
|
||||
items: [],
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.thread = this.timelineSet.relations.getChildEventsForEvent(this.event.getId(), "m.thread", "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(), "m.thread", "m.room.message");
|
||||
this.event.off("Event.relationsCreated", this.onRelationsCreated);
|
||||
},
|
||||
processThread() {
|
||||
this.items = this.timelineSet.relations.getAllChildEventsForEvent(this.event.getId())
|
||||
.filter(e => util.downloadableTypes().includes(e.getContent().msgtype))
|
||||
.map(e => {
|
||||
let ret = {
|
||||
event: e,
|
||||
src: null,
|
||||
};
|
||||
return ret;
|
||||
});
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/assets/css/chat.scss";
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.bubble {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
<template>
|
||||
<message-outgoing class="messageOut-thread" v-bind="{ ...$props, ...$attrs }" v-on="$listeners">
|
||||
<component v-for="item in items" :is="componentFn(item.event)" :originalEvent="item.event" :key="item.event.getId()"
|
||||
v-bind="{ ...$props }" v-on="$listeners" ref="exportedEvent" />
|
||||
</message-outgoing>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MessageOutgoing from "../MessageOutgoing.vue";
|
||||
import messageMixin from "./../messageMixin";
|
||||
import util from "../../../plugins/utils";
|
||||
|
||||
export default {
|
||||
extends: MessageOutgoing,
|
||||
components: { MessageOutgoing },
|
||||
mixins: [messageMixin],
|
||||
data() {
|
||||
return {
|
||||
items: [],
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.thread = this.timelineSet.relations.getChildEventsForEvent(this.event.getId(), "m.thread", "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(), "m.thread", "m.room.message");
|
||||
this.event.off("Event.relationsCreated", this.onRelationsCreated);
|
||||
},
|
||||
processThread() {
|
||||
this.items = this.timelineSet.relations.getAllChildEventsForEvent(this.event.getId())
|
||||
.filter(e => util.downloadableTypes().includes(e.getContent().msgtype))
|
||||
.map(e => {
|
||||
let ret = {
|
||||
event: e,
|
||||
src: null,
|
||||
};
|
||||
return ret;
|
||||
});
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/assets/css/chat.scss";
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.bubble {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -2,7 +2,7 @@ import QuickReactions from "./QuickReactions.vue";
|
|||
import * as linkify from 'linkifyjs';
|
||||
import linkifyHtml from 'linkify-html';
|
||||
import utils from "../../plugins/utils"
|
||||
import Vue from "vue";
|
||||
import util from "../../plugins/utils";
|
||||
|
||||
linkify.options.defaults.className = "link";
|
||||
linkify.options.defaults.target = { url: "_blank" };
|
||||
|
|
@ -40,51 +40,22 @@ export default {
|
|||
type: Function,
|
||||
default: function () {
|
||||
return () => {};
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
event: {},
|
||||
inReplyToEvent: null,
|
||||
inReplyToSender: null,
|
||||
utils
|
||||
thread: null,
|
||||
utils,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
const relatesTo = this.validEvent && this.event.getWireContent()["m.relates_to"];
|
||||
if (relatesTo && relatesTo["m.in_reply_to"]) {
|
||||
// Can we find the original message?
|
||||
const originalEventId = relatesTo["m.in_reply_to"].event_id;
|
||||
if (originalEventId && this.timelineSet) {
|
||||
const originalEvent = this.timelineSet.findEventById(originalEventId);
|
||||
if (originalEvent) {
|
||||
this.inReplyToEvent = originalEvent;
|
||||
this.inReplyToSender = this.eventSenderDisplayName(originalEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
beforeUnmount() {
|
||||
if (this.validEvent) {
|
||||
this.event.off("Event.relationsCreated", this.onRelationsCreated);
|
||||
}
|
||||
beforeDestroy() {
|
||||
this.thread = null;
|
||||
},
|
||||
watch: {
|
||||
event: {
|
||||
immediate: true,
|
||||
handler(newValue, oldValue) {
|
||||
if (oldValue && oldValue.getId) {
|
||||
oldValue.off("Event.relationsCreated", this.onRelationsCreated);
|
||||
}
|
||||
if (newValue && newValue.getId) {
|
||||
newValue.on("Event.relationsCreated", this.onRelationsCreated);
|
||||
if (newValue.isThreadRoot) {
|
||||
Vue.set(newValue, "isThread", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
originalEvent: {
|
||||
immediate: true,
|
||||
handler(originalEvent, ignoredOldValue) {
|
||||
|
|
@ -96,7 +67,19 @@ export default {
|
|||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
thread: {
|
||||
handler(newValue, oldValue) {
|
||||
if (oldValue) {
|
||||
oldValue.off("Relations.add", this.onAddRelation);
|
||||
}
|
||||
if (newValue) {
|
||||
newValue.on("Relations.add", this.onAddRelation);
|
||||
}
|
||||
this.processThread();
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
/**
|
||||
|
|
@ -107,6 +90,16 @@ export default {
|
|||
return this.event && Object.keys(this.event).length !== 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* If this is a thread event, we return the root here, so all reactions will land on the root event.
|
||||
*/
|
||||
eventForReactions() {
|
||||
if (this.event.parentThread) {
|
||||
return this.event.parentThread;
|
||||
}
|
||||
return this.event;
|
||||
},
|
||||
|
||||
incoming() {
|
||||
return this.event && this.event.getSender() != this.$matrix.currentUserId;
|
||||
},
|
||||
|
|
@ -123,11 +116,34 @@ export default {
|
|||
return true;
|
||||
},
|
||||
|
||||
inReplyToSender() {
|
||||
const originalEvent = this.validEvent && this.event.replyEvent;
|
||||
if (originalEvent) {
|
||||
const sender = this.eventSenderDisplayName(originalEvent);
|
||||
if (originalEvent.isThreadRoot || originalEvent.isMxThread) {
|
||||
return sender || this.$t("message.someone");
|
||||
} else {
|
||||
return this.$t("message.user_said", { user: sender || this.$t("message.someone") });
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
inReplyToEvent() {
|
||||
return this.validEvent && this.event.replyEvent;
|
||||
},
|
||||
|
||||
inReplyToText() {
|
||||
const relatesTo = this.event.getWireContent()["m.relates_to"];
|
||||
if (relatesTo && relatesTo["m.in_reply_to"]) {
|
||||
if (this.inReplyToEvent && (this.inReplyToEvent.isThreadRoot || this.inReplyToEvent.isMxThread)) {
|
||||
const children = this.timelineSet.relations
|
||||
.getAllChildEventsForEvent(this.inReplyToEvent.getId())
|
||||
.filter((e) => util.downloadableTypes().includes(e.getContent().msgtype));
|
||||
return this.$t("message.sent_media", { count: children.length });
|
||||
}
|
||||
const content = this.event.getContent();
|
||||
if ('body' in content) {
|
||||
if ("body" in content) {
|
||||
const lines = content.body.split("\n").reverse() || [];
|
||||
while (lines.length && !lines[0].startsWith("> ")) lines.shift();
|
||||
// Reply fallback has a blank line after it, so remove it to prevent leading newline
|
||||
|
|
@ -137,12 +153,10 @@ export default {
|
|||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.inReplyToEvent) {
|
||||
var c = this.inReplyToEvent.getContent();
|
||||
return c.body;
|
||||
}
|
||||
|
||||
// We don't have the original text (at the moment at least)
|
||||
return this.$t("fallbacks.original_text");
|
||||
}
|
||||
|
|
@ -153,7 +167,7 @@ export default {
|
|||
const relatesTo = this.event.getWireContent()["m.relates_to"];
|
||||
if (relatesTo && relatesTo["m.in_reply_to"]) {
|
||||
const content = this.event.getContent();
|
||||
if ('body' in content) {
|
||||
if ("body" in content) {
|
||||
// Remove the new text and strip "> " from the old original text
|
||||
const lines = content.body.split("\n");
|
||||
while (lines.length && lines[0].startsWith("> ")) lines.shift();
|
||||
|
|
@ -190,10 +204,9 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
onRelationsCreated(relationType, ignoredEventType) {
|
||||
if (relationType === "m.thread") {
|
||||
Vue.set(this.event, "isThread", true);
|
||||
}
|
||||
onAddRelation() {
|
||||
console.error("onAddRelation");
|
||||
this.processThread();
|
||||
},
|
||||
ownAvatarClicked() {
|
||||
this.$emit("own-avatar-clicked", { event: this.event });
|
||||
|
|
@ -308,5 +321,10 @@ export default {
|
|||
linkify(text) {
|
||||
return linkifyHtml(text);
|
||||
},
|
||||
|
||||
/**
|
||||
* Override this to handle updates to (the) message thread.
|
||||
*/
|
||||
processThread() {},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import util from "../../plugins/utils";
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
|
|
@ -5,8 +6,12 @@ export default {
|
|||
return !this.incoming && this.event.getContent().msgtype == "m.text";
|
||||
},
|
||||
isDownloadable() {
|
||||
if ((this.event.isThreadRoot || this.event.isMxThread) && this.timelineSet) {
|
||||
const children = this.timelineSet.relations.getAllChildEventsForEvent(this.event.getId()).filter(e => util.downloadableTypes().includes(e.getContent().msgtype));
|
||||
return children.length > 0;
|
||||
}
|
||||
const msgtype = this.event.getContent().msgtype;
|
||||
return ['m.video','m.audio','m.image','m.file'].includes(msgtype);
|
||||
return util.downloadableTypes().includes(msgtype);
|
||||
},
|
||||
isRedactable() {
|
||||
const room = this.$matrix.matrixClient.getRoom(this.event.getRoomId());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue