129 lines
No EOL
3.8 KiB
Vue
129 lines
No EOL
3.8 KiB
Vue
<template>
|
|
<div class="quick-reaction-container">
|
|
<div
|
|
class="emoji"
|
|
v-for="(value, name) in reactionMap"
|
|
:key="name"
|
|
v-show="name == '❤️'"
|
|
>
|
|
<v-tooltip location="top" v-if="value.includes($matrix.currentUserId)">
|
|
<template v-slot:activator="{ props }">
|
|
<v-icon class="ma-1 ml-0 clickable" v-bind="props" @click="onClickEmoji(name)" color="#ff3300">$vuetify.icons.ic_like_filled</v-icon>
|
|
</template>
|
|
<span>{{ $t("global.click_to_remove") }}</span>
|
|
</v-tooltip>
|
|
<v-icon v-else class="ma-1 ml-0 clickable" @click="onClickEmoji(name)">$vuetify.icons.ic_like</v-icon> {{ utils.toLocalNumbers(value.length.toFixed()) }}
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import messageOperationsMixin from "../messageOperationsMixin";
|
|
import utils from "@/plugins/utils"
|
|
|
|
export default {
|
|
mixins: [messageOperationsMixin],
|
|
props: {
|
|
event: {
|
|
type: Object,
|
|
default: function () {
|
|
return {}
|
|
}
|
|
},
|
|
timelineSet: {
|
|
type: Object,
|
|
default: function () {
|
|
return null
|
|
}
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
utils,
|
|
reactionMap: {"❤️": []},
|
|
reactions: null,
|
|
REACTION_LIMIT: 5,
|
|
showAllReaction: false
|
|
}
|
|
},
|
|
mounted() {
|
|
this.reactions = this.timelineSet.relations.getChildEventsForEvent(this.event.getId(), 'm.annotation', 'm.reaction');
|
|
this.event.on("Event.relationsCreated", this.onRelationsCreated);
|
|
},
|
|
beforeUnmount() {
|
|
this.event.off("Event.relationsCreated", this.onRelationsCreated);
|
|
if (this.reactions) {
|
|
this.reactions.off('Relations.add', this.onAddRelation);
|
|
}
|
|
},
|
|
computed: {
|
|
totalReaction() {
|
|
return Object.keys(this.reactionMap).length
|
|
},
|
|
otherReactionText() {
|
|
return this.showAllReaction ? this.$t("global.show_less") : this.$t("message.reaction_count_more", { reactionCount: this.totalReaction - this.REACTION_LIMIT })
|
|
}
|
|
},
|
|
methods: {
|
|
onRelationsCreated() {
|
|
this.reactions = this.timelineSet.relations.getChildEventsForEvent(this.event.getId(), 'm.annotation', 'm.reaction');
|
|
},
|
|
onClickEmoji(emoji) {
|
|
this.$bubble('send-quick-reaction', {reaction:emoji, event:this.event});
|
|
},
|
|
onAddRelation(ignoredevent) {
|
|
this.processReactions();
|
|
},
|
|
onRemoveRelation(ignoredevent) {
|
|
this.processReactions();
|
|
},
|
|
onRedactRelation(ignoredevent) {
|
|
this.processReactions();
|
|
},
|
|
processReactions() {
|
|
var reactionMap = {"❤️": []};
|
|
if (this.reactions && this.reactions._eventsCount > 0) {
|
|
const relations = this.reactions.getRelations();
|
|
for (const r of relations) {
|
|
const emoji = r.getRelation().key;
|
|
const sender = r.getSender();
|
|
if (reactionMap[emoji]) {
|
|
const array = reactionMap[emoji];
|
|
if (r.isRedacted()) {
|
|
delete array[sender];
|
|
}
|
|
if (!array.includes(sender)) {
|
|
array.push(sender)
|
|
}
|
|
} else if (!r.isRedacted()) {
|
|
reactionMap[emoji] = [sender];
|
|
}
|
|
}
|
|
}
|
|
this.reactionMap = reactionMap;
|
|
}
|
|
},
|
|
watch: {
|
|
reactions: {
|
|
handler(newValue, oldValue) {
|
|
if (oldValue) {
|
|
oldValue.off('Relations.add', this.onAddRelation);
|
|
oldValue.off('Relations.remove', this.onRemoveRelation);
|
|
oldValue.off('Relations.redaction', this.onRedactRelation);
|
|
}
|
|
if (newValue) {
|
|
newValue.on('Relations.add', this.onAddRelation);
|
|
newValue.on('Relations.remove', this.onRemoveRelation);
|
|
newValue.on('Relations.redaction', this.onRedactRelation);
|
|
}
|
|
this.processReactions();
|
|
},
|
|
immediate: true
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
@use "@/assets/css/chat.scss" as *;
|
|
</style> |