Merge branch '418-more-emojis-reaction-support' into 'dev'
ux: new emojis UI and display all added emojis reactions See merge request keanuapp/keanuapp-weblite!174
This commit is contained in:
commit
e32afa78cf
7 changed files with 102 additions and 65 deletions
|
|
@ -1,9 +1 @@
|
||||||
@mixin emoji-reaction-transform($type: 'right') {
|
// Sass Mixins
|
||||||
@if $type == 'right' {
|
|
||||||
transform: translateX(20px) translateX(100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
@if $type == 'left' {
|
|
||||||
transform: translateX(-20px) translateX(-100%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -352,6 +352,10 @@ body {
|
||||||
.message-wrapper {
|
.message-wrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
|
.quick-reaction-container .emoji {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.messageIn {
|
.messageIn {
|
||||||
|
|
@ -438,6 +442,13 @@ body {
|
||||||
.link {
|
.link {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
.quick-reaction-container {
|
||||||
|
margin-left: 42px;
|
||||||
|
|
||||||
|
[dir="rtl"] & {
|
||||||
|
margin-right: 42px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.messageOut {
|
.messageOut {
|
||||||
|
|
@ -539,6 +550,13 @@ body {
|
||||||
.link {
|
.link {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
.quick-reaction-container {
|
||||||
|
margin-right: 42px;
|
||||||
|
|
||||||
|
[dir="rtl"] & {
|
||||||
|
margin-left: 42px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sender,
|
.sender,
|
||||||
|
|
@ -712,53 +730,6 @@ body {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.quick-reaction-container {
|
|
||||||
display: inline-block;
|
|
||||||
position: relative;
|
|
||||||
vertical-align: bottom;
|
|
||||||
top: 18px;
|
|
||||||
z-index: 2;
|
|
||||||
background-color: #f7f7f7;
|
|
||||||
border: 1px solid rgba(white, 0.9);
|
|
||||||
border-radius: 13px;
|
|
||||||
height: 26px;
|
|
||||||
width: max-content;
|
|
||||||
padding: 0px 6px;
|
|
||||||
@include emoji-reaction-transform('left');
|
|
||||||
|
|
||||||
.messageOut & {
|
|
||||||
@include emoji-reaction-transform('right');
|
|
||||||
|
|
||||||
[dir="rtl"] & {
|
|
||||||
@include emoji-reaction-transform('left');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.quick-reaction {
|
|
||||||
position: relative;
|
|
||||||
top: -2px;
|
|
||||||
margin: 0px 0px;
|
|
||||||
padding: 1px;
|
|
||||||
font-size: 10px;
|
|
||||||
&:hover {
|
|
||||||
//border: 1px solid #888888;
|
|
||||||
background-color: #e2e2e2;
|
|
||||||
}
|
|
||||||
.quick-reaction-count {
|
|
||||||
color: #888888;
|
|
||||||
font-size: 0.7rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.sent .quick-reaction-count {
|
|
||||||
color: black;
|
|
||||||
font-weight: 700;
|
|
||||||
// background-color: palegreen;
|
|
||||||
}
|
|
||||||
|
|
||||||
[dir="rtl"] & {
|
|
||||||
@include emoji-reaction-transform('right');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.download-overlay {
|
.download-overlay {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,11 @@
|
||||||
"global": {
|
"global": {
|
||||||
"save": "Save",
|
"save": "Save",
|
||||||
"password_didnot_match": "Password didn't match",
|
"password_didnot_match": "Password didn't match",
|
||||||
"password_hint": "Minimum 12 character containing atleast one numeric, one uppercase and one lowercase letter"
|
"password_hint": "Minimum 12 character containing atleast one numeric, one uppercase and one lowercase letter",
|
||||||
|
"show_less": "Show less",
|
||||||
|
"show_more": "Show more",
|
||||||
|
"add_reaction": "Add reaction",
|
||||||
|
"click_to_remove": "Click to remove"
|
||||||
},
|
},
|
||||||
"menu": {
|
"menu": {
|
||||||
"start_private_chat": "Private chat with this user",
|
"start_private_chat": "Private chat with this user",
|
||||||
|
|
@ -83,7 +87,8 @@
|
||||||
"time_ago": "Today | Yesterday | {count} days ago",
|
"time_ago": "Today | Yesterday | {count} days ago",
|
||||||
"outgoing_message_deleted_text": "You deleted this message.",
|
"outgoing_message_deleted_text": "You deleted this message.",
|
||||||
"incoming_message_deleted_text": "This message was deleted.",
|
"incoming_message_deleted_text": "This message was deleted.",
|
||||||
"not_allowed_to_send": "Only admins and moderators are allowed to send to the room"
|
"not_allowed_to_send": "Only admins and moderators are allowed to send to the room",
|
||||||
|
"reaction_count_more": "{reactionCount} more"
|
||||||
},
|
},
|
||||||
"room": {
|
"room": {
|
||||||
"invitations": "You have no invitations | You have 1 invitation | You have {count} invitations",
|
"invitations": "You have no invitations | You have 1 invitation | You have {count} invitations",
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,12 @@
|
||||||
:timelineSet="timelineSet" v-on:send-quick-reaction.stop="sendQuickReaction"
|
:timelineSet="timelineSet" v-on:send-quick-reaction.stop="sendQuickReaction"
|
||||||
v-on:context-menu="showContextMenuForEvent($event)" v-on:own-avatar-clicked="viewProfile"
|
v-on:context-menu="showContextMenuForEvent($event)" v-on:own-avatar-clicked="viewProfile"
|
||||||
v-on:other-avatar-clicked="showAvatarMenuForEvent($event)" v-on:download="download(event)"
|
v-on:other-avatar-clicked="showAvatarMenuForEvent($event)" v-on:download="download(event)"
|
||||||
v-on:poll-closed="pollWasClosed(event)" />
|
v-on:poll-closed="pollWasClosed(event)"
|
||||||
|
v-on:more="
|
||||||
|
isEmojiQuickReaction = true
|
||||||
|
showMoreMessageOperations($event)
|
||||||
|
"
|
||||||
|
/>
|
||||||
<!-- <div v-if="debugging" style="user-select:text">EventID: {{ event.getId() }}</div> -->
|
<!-- <div v-if="debugging" style="user-select:text">EventID: {{ event.getId() }}</div> -->
|
||||||
<!-- <div v-if="debugging" style="user-select:text">Event: {{ JSON.stringify(event) }}</div> -->
|
<!-- <div v-if="debugging" style="user-select:text">Event: {{ JSON.stringify(event) }}</div> -->
|
||||||
<div v-if="event.getId() == readMarker && index < events.length - 1" class="read-marker"
|
<div v-if="event.getId() == readMarker && index < events.length - 1" class="read-marker"
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
<v-icon>more_vert</v-icon>
|
<v-icon>more_vert</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</div>
|
</div>
|
||||||
<QuickReactions :event="event" :timelineSet="timelineSet" />
|
<QuickReactions :event="event" :timelineSet="timelineSet" v-on="$listeners"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
<div class="status">{{ event.status }}</div>
|
<div class="status">{{ event.status }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<QuickReactions :event="event" :timelineSet="timelineSet" />
|
|
||||||
<div class="op-button" ref="opbutton" v-if="!event.isRedacted()">
|
<div class="op-button" ref="opbutton" v-if="!event.isRedacted()">
|
||||||
<v-btn id="btn-show-menu" icon @click.stop="showContextMenu($refs.opbutton)">
|
<v-btn id="btn-show-menu" icon @click.stop="showContextMenu($refs.opbutton)">
|
||||||
<v-icon>more_vert</v-icon>
|
<v-icon>more_vert</v-icon>
|
||||||
|
|
@ -25,6 +24,7 @@
|
||||||
<img v-if="userAvatar" :src="userAvatar" />
|
<img v-if="userAvatar" :src="userAvatar" />
|
||||||
<span v-else class="white--text headline">{{ userAvatarLetter }}</span>
|
<span v-else class="white--text headline">{{ userAvatarLetter }}</span>
|
||||||
</v-avatar>
|
</v-avatar>
|
||||||
|
<QuickReactions :event="event" :timelineSet="timelineSet" v-on="$listeners"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,67 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="quick-reaction-container" v-show="reactions">
|
<div class="quick-reaction-container" v-show="reactions">
|
||||||
<span :class="{'quick-reaction':true,'sent':value.includes($matrix.currentUserId)}" v-for="(value, name) in reactionMap" :key="name" @click.stop="onClickEmoji(name)">
|
<div
|
||||||
{{ name }} <span class="quick-reaction-count">{{ value.length }}</span>
|
class="emoji"
|
||||||
</span>
|
v-for="(value, name, index) in reactionMap"
|
||||||
|
:key="name"
|
||||||
|
v-show="showAllReaction || index < REACTION_LIMIT"
|
||||||
|
>
|
||||||
|
<v-tooltip top v-if="value.includes($matrix.currentUserId)">
|
||||||
|
<template v-slot:activator="{ on, attrs }">
|
||||||
|
<v-chip
|
||||||
|
class="pa-2 ma-1 ml-0"
|
||||||
|
outlined
|
||||||
|
small
|
||||||
|
v-bind="attrs"
|
||||||
|
v-on="on"
|
||||||
|
@click="onClickEmoji(name)"
|
||||||
|
>
|
||||||
|
{{ name }} {{ value.length }}
|
||||||
|
</v-chip>
|
||||||
|
</template>
|
||||||
|
<span v-if="value.includes($matrix.currentUserId)">{{ $t("global.click_to_remove") }}</span>
|
||||||
|
</v-tooltip>
|
||||||
|
<v-chip
|
||||||
|
v-else
|
||||||
|
class="pa-2 ma-1 ml-0"
|
||||||
|
outlined
|
||||||
|
small
|
||||||
|
>
|
||||||
|
{{ name }} {{ value.length }}
|
||||||
|
</v-chip>
|
||||||
|
</div>
|
||||||
|
<v-chip
|
||||||
|
v-if="totalReaction > REACTION_LIMIT"
|
||||||
|
@click="showAllReaction = !showAllReaction"
|
||||||
|
class="pa-2 ma-1 ml-0"
|
||||||
|
outlined
|
||||||
|
small
|
||||||
|
>
|
||||||
|
{{ otherReactionText }}
|
||||||
|
</v-chip>
|
||||||
|
<v-tooltip top v-if="!!totalReaction">
|
||||||
|
<template v-slot:activator="{ on, attrs }">
|
||||||
|
<v-chip
|
||||||
|
outlined
|
||||||
|
small
|
||||||
|
class="pa-2 ma-1 ml-0"
|
||||||
|
v-bind="attrs"
|
||||||
|
v-on="on"
|
||||||
|
@click="more"
|
||||||
|
>
|
||||||
|
<v-icon small> $vuetify.icons.addReaction </v-icon>
|
||||||
|
</v-chip>
|
||||||
|
</template>
|
||||||
|
<span>{{ $t("global.add_reaction") }}</span>
|
||||||
|
</v-tooltip>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import messageOperationsMixin from "./messageOperationsMixin";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
mixins: [messageOperationsMixin],
|
||||||
props: {
|
props: {
|
||||||
event: {
|
event: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
|
@ -25,7 +79,9 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
reactionMap: {},
|
reactionMap: {},
|
||||||
reactions: null
|
reactions: null,
|
||||||
|
REACTION_LIMIT: 5,
|
||||||
|
showAllReaction: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
@ -38,6 +94,14 @@ export default {
|
||||||
this.reactions.off('Relations.add', this.onAddRelation);
|
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: {
|
methods: {
|
||||||
onRelationsCreated() {
|
onRelationsCreated() {
|
||||||
this.reactions = this.timelineSet.relations.getChildEventsForEvent(this.event.getId(), 'm.annotation', 'm.reaction');
|
this.reactions = this.timelineSet.relations.getChildEventsForEvent(this.event.getId(), 'm.annotation', 'm.reaction');
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue