Style quick reactions.

Issue #65. Move "edit" and "delete" to emoji picker dialog, accessible through the "..." button.
This commit is contained in:
N-Pex 2021-04-09 14:03:40 +02:00
parent 779e53c3b2
commit 61dbcad131
6 changed files with 193 additions and 71 deletions

View file

@ -1,86 +1,54 @@
<template>
<div :class="{'message-operations':true,'incoming':incoming,'outgoing':!incoming}">
<v-btn icon @click.stop="addReaction" class="ma-0 pa-0">
<v-icon>mood</v-icon>
</v-btn>
<template v-for="(item,index) in emojis">
<v-btn v-if="index < maxRecents" :key="item.data" icon @click.stop="addQuickReaction(item.data)" class="ma-0 pa-0">
<span class="recent-emoji" >{{ item.data }}</span>
</v-btn>
</template>
<v-btn v-if="incoming" icon @click.stop="addReply" class="ma-0 pa-0">
<v-icon>reply</v-icon>
</v-btn>
<v-btn v-if="isEditable" icon @click.stop="edit" class="ma-0 pa-0">
<v-icon>edit</v-icon>
</v-btn>
<v-btn v-if="isRedactable" icon @click.stop="redact" class="ma-0 pa-0">
<v-icon>delete</v-icon>
</v-btn>
<v-btn v-if="isDownloadable" icon @click.stop="download" class="ma-0 pa-0">
<v-icon>get_app</v-icon>
</v-btn>
</div>
<v-btn icon @click.stop="more" class="ma-0 pa-0">
<v-icon>more_horiz</v-icon>
</v-btn> </div>
</template>
<script>
import messageMixin from "./messageMixin";
import messageOperationsMixin from "./messageOperationsMixin";
export default {
mixins: [messageMixin],
mixins: [messageMixin, messageOperationsMixin],
data() {
return {
maxRecents: 5
}
},
props: {
incoming: {
type: Boolean,
emojis: {
type: Array,
default: function () {
return true
return []
}
},
event: {
type: Object,
default: function () {
return {}
}
},
}
},
computed: {
isEditable() {
return !this.incoming && this.event.getContent().msgtype == "m.text";
},
isDownloadable() {
const msgtype = this.event.getContent().msgtype;
return ['m.video','m.audio','m.image','m.file'].includes(msgtype);
},
isRedactable() {
const room = this.$matrix.matrixClient.getRoom(this.event.getRoomId());
if (room && room.currentState && room.currentState.maySendRedactionForEvent(this.event, this.$matrix.currentUserId)) {
return true;
watch: {
emojis: {
immediate: true,
handler(newVal, oldVal) {
console.log("Emojis changed", newVal, oldVal);
}
return false;
}
},
},
methods: {
addReaction() {
this.$emit("close");
this.$emit("addreaction", {event:this.event});
},
addReply() {
this.$emit("close");
this.$emit("addreply", {event:this.event});
},
edit() {
this.$emit("close");
this.$emit("edit", {event:this.event});
},
redact() {
this.$emit("close");
this.$emit("redact", {event:this.event});
},
download() {
this.$emit("close");
this.$emit("download", {event:this.event});
}
}
};
</script>
<style lang="scss">
@import "@/assets/css/chat.scss";
// .recent-emoji {
// width: 30px;
// }
</style>

View file

@ -0,0 +1,51 @@
<template>
<div
:class="{
'message-operations-picker': true,
incoming: incoming,
outgoing: !incoming,
}"
>
<v-container fluid>
<v-row>
<v-col v-if="incoming">
<v-btn icon @click.stop="addReply" class="ma-0 pa-0">
<v-icon>reply</v-icon>
</v-btn>
<div>Reply</div>
</v-col>
<v-col v-if="isEditable">
<v-btn icon @click.stop="edit" class="ma-0 pa-0">
<v-icon>edit</v-icon>
</v-btn>
<div>Edit</div>
</v-col>
<v-col v-if="isRedactable">
<v-btn icon @click.stop="redact" class="ma-0 pa-0">
<v-icon>delete</v-icon>
</v-btn>
<div>Delete</div>
</v-col>
<v-col v-if="isDownloadable">
<v-btn icon @click.stop="download" class="ma-0 pa-0">
<v-icon>get_app</v-icon>
</v-btn>
<div>Download</div>
</v-col>
</v-row>
</v-container>
</div>
</template>
<script>
import messageMixin from "./messageMixin";
import messageOperationsMixin from "./messageOperationsMixin";
export default {
mixins: [messageMixin, messageOperationsMixin],
};
</script>
<style lang="scss">
@import "@/assets/css/chat.scss";
</style>

View file

@ -62,6 +62,10 @@ export default {
}
},
computed: {
incoming() {
return this.event && this.event.getSender() != this.$matrix.currentUserId;
},
/**
* Don't show sender and time if the next event is within 2 minutes and also from us (= back to back messages)
*/

View file

@ -0,0 +1,49 @@
export default {
computed: {
isEditable() {
return !this.incoming && this.event.getContent().msgtype == "m.text";
},
isDownloadable() {
const msgtype = this.event.getContent().msgtype;
return ['m.video','m.audio','m.image','m.file'].includes(msgtype);
},
isRedactable() {
const room = this.$matrix.matrixClient.getRoom(this.event.getRoomId());
if (room && room.currentState && room.currentState.maySendRedactionForEvent(this.event, this.$matrix.currentUserId)) {
return true;
}
return false;
}
},
methods: {
addReaction() {
this.$emit("close");
this.$emit("addreaction", {event:this.event});
},
addQuickReaction(emoji) {
this.$emit("close");
this.$emit("addquickreaction", {event:this.event,emoji:emoji});
},
addReply() {
this.$emit("close");
this.$emit("addreply", {event:this.event});
},
edit() {
this.$emit("close");
this.$emit("edit", {event:this.event});
},
redact() {
this.$emit("close");
this.$emit("redact", {event:this.event});
},
download() {
this.$emit("close");
this.$emit("download", {event:this.event});
},
more() {
this.$emit("close");
this.$emit("more", {event:this.event});
},
}
}