UI updates

This commit is contained in:
N-Pex 2020-12-14 16:11:45 +01:00
parent 3dc1fa3567
commit 24b72cab1e
9 changed files with 193 additions and 58 deletions

View file

@ -120,6 +120,21 @@ $chat-text-size: 0.7pt;
}
}
}
.op-button {
position:absolute;
right:-30px;
top:0;
.v-icon {
color: #cccccc;
&:hover {
color: #888888;
}
}
}
.messageOut .op-button {
right:70%;
}
}
.messageJoin {
@ -139,6 +154,9 @@ $chat-text-size: 0.7pt;
border-radius: 10px 10px 0 10px;
padding: 8px;
}
.audio-bubble {
overflow: scroll;
}
.bubble.image-bubble {
padding: 0px;
overflow: hidden;
@ -179,6 +197,7 @@ $chat-text-size: 0.7pt;
}
.audio-bubble {
margin-left: 40px;
overflow: scroll;
}
.bubble.image-bubble {
padding: 0px;
@ -248,14 +267,21 @@ $chat-text-size: 0.7pt;
margin: 20px;
}
.messageOperations {
.message-operations-strut {
position: relative;
height: 0px;
z-index: 1;
}
.message-operations {
position: absolute;
bottom: 10px;
width: auto;
background-color: #ffe2e2;
&.incoming {
left: -20px;
right: 30%;
}
&.outgoing {
right: 20px;
left: 30%;
}
}

View file

@ -6,17 +6,32 @@
ref="chatContainer"
style="overflow-x: hidden; overflow-y: auto"
v-on:scroll="onScroll"
@click.prevent="closeContextMenuIfOpen"
>
<div class="message-operations-strut">
<message-operations
:style="opStyle"
v-on:close="showContextMenu = false"
v-if="selectedEvent && showContextMenu"
v-on:addreaction="addReaction"
v-on:edit="edit(selectedEvent)"
:event="selectedEvent"
:incoming="selectedEvent.getSender() != $matrix.currentUserId"
/>
</div>
<!-- Handle resizes, e.g. when soft keyboard is shown/hidden -->
<resize-observer
ref="chatContainerResizer"
@notify="handleChatContainerResize"
/>
<div v-for="event in events" :key="event.getId()">
<div
v-if="
!event.isRelation() && !event.isRedacted() && !event.isRedaction()
"
:ref="event.getId()"
>
<div
style="position: relative; user-select: none"
@ -41,14 +56,15 @@
)
"
v-on:send-quick-reaction="sendQuickReaction"
v-on:context-menu="showContextMenuForEvent($event)"
/>
<message-operations
<!-- <message-operations
v-on:close="showContextMenu = false"
v-if="selectedEvent == event && showContextMenu"
v-on:addreaction="addReaction"
:event="event"
:incoming="event.getSender() != $matrix.currentUserId"
/>
/> -->
</div>
</div>
</div>
@ -239,6 +255,7 @@ export default {
currentSendError: null,
showEmojiPicker: false,
selectedEvent: null,
editedEvent: null,
showContextMenu: false,
/**
* Current chat container size. We need to keep track of this so that if and when
@ -287,7 +304,18 @@ export default {
} else {
return "";
}
},
opStyle() {
// Calculate where to show the context menu.
//
const ref = this.selectedEvent && this.$refs[this.selectedEvent.getId()];
if (ref && ref[0]) {
const offset = ref[0].offsetTop - this.scrollPosition.node.offsetTop;
return "top:" + offset + "px";
}
return "top:0px";
}
},
watch: {
@ -459,7 +487,7 @@ export default {
) {
scrollToSeeNew = true;
}
if (event.forwardLooking) {
if (event.forwardLooking && !event.isRelation()) {
this.handleScrolledToBottom(scrollToSeeNew);
}
},
@ -483,6 +511,13 @@ export default {
sendMessage() {
if (this.currentInput.length > 0) {
// Is this an edit?
if (this.editedEvent) {
console.log("Edit");
}
this.editedEvent = null; //TODO - Is this a good place to reset this?
util
.sendTextMessage(
this.$matrix.matrixClient,
@ -640,6 +675,11 @@ export default {
this.showEmojiPicker = true;
},
edit(event) {
this.editedEvent = event;
this.currentInput = event.getContent().body;
},
emojiSelected(e) {
this.showEmojiPicker = false;
if (this.selectedEvent) {
@ -664,6 +704,22 @@ export default {
console.log("Failed to send quick reaction:", err);
});
},
showContextMenuForEvent(event) {
const ref = this.$refs[event.getId()];
if (ref) {
console.log("Got the ref", ref);
}
this.selectedEvent = event;
this.showContextMenu = true;
},
closeContextMenuIfOpen(e) {
if (this.showContextMenu) {
this.showContextMenu = false;
e.preventDefault();
}
}
},
};
</script>

View file

@ -44,6 +44,16 @@
</v-card-text>
</v-card>
<v-card class="account ma-3">
<v-card-title>Your account</v-card-title>
<v-card-text>
<div v-if="$matrix.currentUser.is_guest">
<div>You don't have a Keanu account, yet ;)</div>
<v-btn dark block @click.stop="upgradeAccount">Login</v-btn>
</div>
</v-card-text>
</v-card>
<!-- EDIT dialog -->
<v-dialog v-model="showEditDialog" class="ma-0 pa-0" width="50%">
<v-card>
@ -130,6 +140,16 @@ export default {
}
return null;
},
upgradeAccount() {
this.$matrix.upgradeGuestAccount()
.then(() => {
console.log("Done");
})
.catch(err => {
console.log("ERROR", err);
})
}
},
};
</script>

View file

@ -1,19 +1,19 @@
<template>
<div class="messageIn">
<div class="audio-bubble">
<audio controls :src="src">Audio file</audio>
<QuickReactions :event="event" :reactions="reactions" />
</div>
<v-avatar class="avatar" size="32" color="#ededed">
<img
v-if="messageEventAvatar(event)"
:src="messageEventAvatar(event)"
/>
<span v-else class="white--text headline">{{
messageEventDisplayName(event).substring(0, 1).toUpperCase()
}}</span>
</v-avatar>
<div class="sender">{{ messageEventDisplayName(event) }}</div>
<div class="audio-bubble">
<audio controls :src="src">Audio file</audio>
<QuickReactions :event="event" :reactions="reactions" />
</div>
<v-btn icon class="op-button" @click.stop="showContextMenu"
><v-icon>more_vert</v-icon></v-btn
>
<v-avatar class="avatar" size="32" color="#ededed">
<img v-if="messageEventAvatar(event)" :src="messageEventAvatar(event)" />
<span v-else class="white--text headline">{{
messageEventDisplayName(event).substring(0, 1).toUpperCase()
}}</span>
</v-avatar>
<div class="sender">{{ messageEventDisplayName(event) }}</div>
<div class="time">
{{ formatTime(event.event.origin_server_ts) }}
</div>

View file

@ -1,19 +1,19 @@
<template>
<div class="messageIn">
<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
v-if="messageEventAvatar(event)"
:src="messageEventAvatar(event)"
/>
<span v-else class="white--text headline">{{
messageEventDisplayName(event).substring(0, 1).toUpperCase()
}}</span>
</v-avatar>
<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-btn icon class="op-button" @click.stop="showContextMenu"
><v-icon>more_vert</v-icon></v-btn
>
<v-avatar class="avatar" size="32" color="#ededed">
<img v-if="messageEventAvatar(event)" :src="messageEventAvatar(event)" />
<span v-else class="white--text headline">{{
messageEventDisplayName(event).substring(0, 1).toUpperCase()
}}</span>
</v-avatar>
<div class="sender">{{ messageEventDisplayName(event) }}</div>
<div class="time">
{{ formatTime(event.event.origin_server_ts) }}
</div>

View file

@ -1,22 +1,25 @@
<template>
<div class="messageIn">
<v-avatar class="avatar" size="32" color="#ededed">
<img
v-if="messageEventAvatar(event)"
:src="messageEventAvatar(event)"
/>
<span v-else class="white--text headline">{{
messageEventDisplayName(event).substring(0, 1).toUpperCase()
}}</span>
</v-avatar>
<v-avatar class="avatar" size="32" color="#ededed">
<img v-if="messageEventAvatar(event)" :src="messageEventAvatar(event)" />
<span v-else class="white--text headline">{{
messageEventDisplayName(event).substring(0, 1).toUpperCase()
}}</span>
</v-avatar>
<div class="bubble">
<div class="message">{{ event.getContent().body }}
<span class="edit-marker" v-if="event.replacingEventId()">(edited)</span>
</div>
<QuickReactions :event="event" :reactions="reactions" />
<div class="bubble">
<div class="message">
{{ event.getContent().body }}
<span class="edit-marker" v-if="event.replacingEventId()"
>(edited)</span
>
</div>
<div class="sender">{{ messageEventDisplayName(event) }}</div>
<QuickReactions :event="event" :reactions="reactions" />
</div>
<v-btn icon class="op-button" @click.stop="showContextMenu"
><v-icon>more_vert</v-icon></v-btn
>
<div class="sender">{{ messageEventDisplayName(event) }}</div>
<div class="time">
{{ formatTime(event.event.origin_server_ts) }}
</div>

View file

@ -1,8 +1,14 @@
<template>
<div :class="{'messageOperations':true,'incoming':incoming,'outgoing':!incoming}">
<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>
<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>
</div>
</template>
@ -27,10 +33,24 @@ export default {
},
},
computed: {
isEditable() {
return !this.incoming && this.event.getContent().msgtype == "m.text";
}
},
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});
}
}
};

View file

@ -1,16 +1,22 @@
<template>
<div class="messageOut">
<div class="bubble">
<div class="message">{{ event.getContent().body }}
<span class="edit-marker" v-if="event.replacingEventId()">(edited)</span>
</div>
<QuickReactions :event="event" :reactions="reactions" />
<div class="bubble">
<div class="message">
{{ event.getContent().body }}
<span class="edit-marker" v-if="event.replacingEventId()"
>(edited)</span
>
</div>
<!-- <div class="sender">{{ "You" }}</div> -->
<QuickReactions :event="event" :reactions="reactions" />
</div>
<v-btn icon class="op-button" @click.stop="showContextMenu"
><v-icon>more_vert</v-icon></v-btn
>
<!-- <div class="sender">{{ "You" }}</div> -->
<div class="time">
{{ formatTime(event.event.origin_server_ts) }}
</div>
<div class="status">{{ event.status }}</div>
<div class="status">{{ event.status }}</div>
</div>
</template>

View file

@ -27,6 +27,10 @@ export default {
computed: {
},
methods: {
showContextMenu() {
this.$emit("context-menu", this.event);
},
/**
* Get a display name given an event.
*/