Quick reactions
This commit is contained in:
parent
5589131c86
commit
29acde8604
15 changed files with 454 additions and 137 deletions
|
|
@ -4,6 +4,7 @@
|
|||
<div class="sender">{{ messageEventDisplayName(event) }}</div>
|
||||
<div class="bubble image-bubble">
|
||||
<v-img :aspect-ratio="16 / 9" ref="image" :src="src" cover />
|
||||
<QuickReactions :event="event" :reactions="reactions" />
|
||||
</div>
|
||||
<v-avatar class="avatar" size="40" color="grey">
|
||||
<img
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
<div class="bubble">
|
||||
<div class="message">{{ event.getContent().body }}</div>
|
||||
<QuickReactions :event="event" :reactions="reactions" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="time">
|
||||
|
|
|
|||
40
src/components/messages/MessageOperations.vue
Normal file
40
src/components/messages/MessageOperations.vue
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<template>
|
||||
<div :class="{'messageOperations':true,'incoming':incoming,'outgoing':!incoming}">
|
||||
<v-btn icon @click="addReaction" class="ma-0 pa-0">
|
||||
<v-icon>mood</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import messageMixin from "./messageMixin";
|
||||
|
||||
export default {
|
||||
mixins: [messageMixin],
|
||||
|
||||
props: {
|
||||
incoming: {
|
||||
type: Boolean,
|
||||
default: function () {
|
||||
return true
|
||||
}
|
||||
},
|
||||
event: {
|
||||
type: Object,
|
||||
default: function () {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
addReaction() {
|
||||
this.$emit("addreaction", {event:this.event});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/assets/css/chat.scss";
|
||||
</style>
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
<div class="sender">{{ "You" }}</div>
|
||||
<div class="bubble image-bubble">
|
||||
<v-img :aspect-ratio="16/9" ref="image" :src="src" cover />
|
||||
<QuickReactions :event="event" :reactions="reactions" />
|
||||
</div>
|
||||
<div class="status">{{ event.status }}</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
<div class="sender">{{ "You" }}</div>
|
||||
<div class="bubble">
|
||||
<div class="message">{{ event.getContent().body }}</div>
|
||||
<QuickReactions :event="event" :reactions="reactions" />
|
||||
</div>
|
||||
<div class="status">{{ event.status }}</div>
|
||||
</div>
|
||||
|
|
@ -20,7 +21,6 @@ export default {
|
|||
mixins: [messageMixin],
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/assets/css/chat.scss";
|
||||
</style>
|
||||
81
src/components/messages/QuickReactions.vue
Normal file
81
src/components/messages/QuickReactions.vue
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
<template>
|
||||
<div class="quick-reaction-container">
|
||||
<span :class="{'quick-reaction':true,'sent':value.includes($matrix.currentUserId)}" v-for="(value, name) in reactionMap" :key="name" @mousedown="onClickEmoji(name)">
|
||||
{{ name }} <span class="quick-reaction-count">{{ value.length }}</span>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
event: {
|
||||
type: Object,
|
||||
default: function () {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
reactions: {
|
||||
type: Object,
|
||||
default: function () {
|
||||
return null
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
reactionMap: {}
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.reactions) {
|
||||
this.reactions.off('Relations.add', this.onAddRelation);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onClickEmoji(emoji) {
|
||||
this.$bubble('send-quick-reaction', {reaction:emoji, event:this.event});
|
||||
},
|
||||
onAddRelation(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 (!array.includes(sender)) {
|
||||
array.push(sender)
|
||||
}
|
||||
} else {
|
||||
reactionMap[emoji] = [sender];
|
||||
}
|
||||
}
|
||||
}
|
||||
this.reactionMap = reactionMap;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
reactions: {
|
||||
handler(newValue, oldValue) {
|
||||
if (oldValue) {
|
||||
oldValue.off('Relations.add', this.onAddRelation);
|
||||
}
|
||||
if (newValue) {
|
||||
newValue.on('Relations.add', this.onAddRelation);
|
||||
}
|
||||
this.processReactions();
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/assets/css/chat.scss";
|
||||
</style>
|
||||
|
|
@ -1,4 +1,9 @@
|
|||
import QuickReactions from './QuickReactions.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
QuickReactions
|
||||
},
|
||||
props: {
|
||||
room: {
|
||||
type: Object,
|
||||
|
|
@ -12,6 +17,12 @@ export default {
|
|||
return {}
|
||||
}
|
||||
},
|
||||
reactions: {
|
||||
type: Object,
|
||||
default: function () {
|
||||
return null
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
|
|
@ -20,6 +31,9 @@ export default {
|
|||
* Get a display name given an event.
|
||||
*/
|
||||
stateEventDisplayName(event) {
|
||||
if (event.getSender() == this.$matrix.currentUserId) {
|
||||
return "You";
|
||||
}
|
||||
if (this.room) {
|
||||
const member = this.room.getMember(event.getSender());
|
||||
if (member) {
|
||||
|
|
@ -64,5 +78,5 @@ export default {
|
|||
}
|
||||
return date.toLocaleString();
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue