Skip to content

Commit

Permalink
feat(replies): add message replies (#133)
Browse files Browse the repository at this point in the history
* feat(replies): add reply component and replies under messages

* feat(replies): reply logic

* fix(replies): rebase and minors

* fix(replies): minors

* fix(replies): minors
  • Loading branch information
molimauro committed Sep 11, 2021
1 parent f4feab7 commit 8a61cbd
Show file tree
Hide file tree
Showing 25 changed files with 426 additions and 19 deletions.
2 changes: 1 addition & 1 deletion components/tailored/commands/preview/Preview.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div id="command-preview" v-if="hasCommand">
<div id="command-preview" v-if="hasCommand" :class="$store.state.ui.replyChatbarContent.id ? 'has-reply' : ''">
<TypographySubtitle :size="6" text="Commands" />
<div id="commands" class="hidden-scroll" v-scroll-lock="true">
<UiScroll verticalScroll scrollbarVisibility="scroll">
Expand Down
4 changes: 4 additions & 0 deletions components/tailored/commands/preview/Preview.less
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,8 @@
.command-desc {
font-size: @mini-text-size;
}

&.has-reply {
margin-bottom: 30px;
}
}
2 changes: 1 addition & 1 deletion components/tailored/core/chatbar/Chatbar.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div id="chatbar" ref="chatbar">
<div id="chatbar" ref="chatbar" :class="$store.state.ui.replyChatbarContent.id ? 'has-reply' : ''">
<div
:class="`chatbar-wrap ${charlimit ? 'is-error' : 'is-normal'}`"
ref="wrap"
Expand Down
5 changes: 5 additions & 0 deletions components/tailored/core/chatbar/Chatbar.less
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
#chatbar {
margin-top: @light-spacing;
width: 100%;

&.has-reply {
margin-top: 0;
}

.chat-label {
background: @primary-color;
font-size: @mini-text-size;
Expand Down
2 changes: 1 addition & 1 deletion components/tailored/core/chatbar/Chatbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export default Vue.extend({
chatbarGroup.style.height = `${messageBox.scrollHeight + 42}px`
} else {
messageBox.style.height = '112px'
chatbarGroup.style.height = '152px'
chatbarGroup.style.height = `152px`
}
messageBox.scrollTop = messageBox.scrollHeight
},
Expand Down
6 changes: 6 additions & 0 deletions components/tailored/core/chatbar/reply/Reply.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<div v-if="$store.state.ui.replyChatbarContent.id" class="is-chatbar-reply">
<VueMarkdown :source="`${$t('conversation.reply_to')} **${$store.state.ui.replyChatbarContent.from}**: ${$store.state.ui.replyChatbarContent.payload}`" class="markdown" />
<div class="reply-close" @click="setReplyChatbarContent">
<font-awesome-icon :icon="['far', 'times-circle']" />
</div>
</div>
44 changes: 44 additions & 0 deletions components/tailored/core/chatbar/reply/Reply.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
.is-chatbar-reply {
min-height: 36px;
max-height: 36px;
display: flex;
justify-content: space-between;
width: calc(100% - 2rem);
padding: 0.25rem 0.5rem;
font-size: @text-size;
font-family: @secondary-font;
margin: 0 1rem;
background-color: @light-gray;
border-top-left-radius: @corner-rounding;
border-top-right-radius: @corner-rounding;
border: 1px solid transparent;
align-items: center;

strong {
color: @bright-text;
}

.markdown {
width: calc(100% - @small-icon-size - 0.25rem);
p {
font-size: @text-size;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
}

.reply-close {
cursor: pointer;
display: flex;
font-size: @small-icon-size;
color: @text;
}
}

@media only screen and (max-width: 768px) {
.is-chatbar-reply {
margin: 0 @light-spacing;
width: calc(100% - @normal-spacing);
}
}
21 changes: 21 additions & 0 deletions components/tailored/core/chatbar/reply/Reply.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<template src="./Reply.html"></template>
<script lang="ts">
import Vue from 'vue'
import VueMarkdown from 'vue-markdown'
export default Vue.extend({
components: {
VueMarkdown,
},
methods: {
setReplyChatbarContent() {
this.$store.commit('setReplyChatbarContent', {
id: '',
payload: '',
from: '',
})
},
},
})
</script>
<style lang="less" src="./Reply.less"></style>
2 changes: 1 addition & 1 deletion components/tailored/messaging/group/Group.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<TypographyText :text="$dayjs(group.at).from()" />
</div>
<div class="group-messages">
<TailoredMessagingMessage v-for="message in group.messages" :message="message" :key="message.id" />
<TailoredMessagingMessage v-for="message in group.messages" :message="message" :from="$mock.users.filter(u => u.address === group.from)[0].name" :key="message.id" />
</div>
</div>
</div>
1 change: 1 addition & 0 deletions components/tailored/messaging/group/Group.less
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
margin-left: 0.75rem;
width: 100%;
.group-heading {
width: 100%;
display: inline-flex;
flex-direction: row;
align-items: center;
Expand Down
31 changes: 26 additions & 5 deletions components/tailored/messaging/message/Message.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,28 @@
<div class="is-message" @contextmenu="contextMenu">
<VueMarkdown v-if="message.type === 'text'" :source="message.payload" class="markdown" />
<UiImage v-else-if="message.type === 'image'" :source="message.payload.url" alt="" />
<UiEmbedsVideoPlayer v-else-if="message.type === 'video'" :data="message.payload" />
<UiEmbedsAudioPlayer v-else-if="message.type === 'audio'" :data="message.payload" />
<UiEmbedsFile v-else-if="message.type === 'file'" :data="message.payload" />
<div @mouseenter="mouseOver" @mouseleave="mouseOver" :class="`message-container ${messageHover ? 'message-hover' : '' }`">
<div v-if="messageHover" class="reply-button">
<div class="reply-command" :data-tooltip="$t('global.glyphs')">
<font-awesome-icon
:icon="['far', 'grin-tongue-wink']"
:class="`control-icon emoji-icon ${$store.state.ui.showEnhancers ? 'primary' : ''}`"
/>
</div>
<div class="reply-command" :data-tooltip="$t('global.reply')" @click="setReplyChatbarContent">
<font-awesome-icon :icon="['fas', 'reply']" :class="'control-icon'" />
</div>
<div class="reply-command" :data-tooltip="$t('global.more')">
<font-awesome-icon :icon="['fas', 'ellipsis-h']" :class="'control-icon'" />
</div>
</div>
<VueMarkdown v-if="message.type === 'text'" :source="message.payload" class="markdown" />
<UiImage v-else-if="message.type === 'image'" :source="message.payload.url" alt="" />
<UiEmbedsVideoPlayer v-else-if="message.type === 'video'" :data="message.payload" />
<UiEmbedsAudioPlayer v-else-if="message.type === 'audio'" :data="message.payload" />
<UiEmbedsFile v-else-if="message.type === 'file'" :data="message.payload" />
</div>
<div v-if="message.replies.length" class="reply-container">
<div v-if="!showReplies" class="reply-preview" @click="toggleReplies"> {{message.replies.length}} {{$tc('conversation.reply', message.replies.length)}} > </div>
<TailoredMessagingMessageReply v-if="showReplies" v-for="reply in message.replies" :reply="reply" :key="reply.id"/>
<div v-if="showReplies" @click="toggleReplies" class="reply-close"> Collapse < </div>
</div>
</div>
78 changes: 77 additions & 1 deletion components/tailored/messaging/message/Message.less
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,80 @@
font-size: @text-size;
}
}
}

.message-container{
position: relative;

.reply-button {
position: absolute;
border: 1px solid @darker-alt;
border-radius: @corner-rounding;
background-color: @darker;
top: -18px;
right: 0;
display: flex;
box-sizing: border-box;
height: 36px;

&:hover {
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
}

.reply-command {
width: 35px;
// height: 35px;
padding: 0.25rem;
display: flex;
justify-content: center;
cursor: pointer;

&:hover {
background-color: @dark-gray;

.control-icon {
color: @bright-text;
}
}

.control-icon {
justify-self: center;
align-self: center;
font-size: @larger-icon-size;
color: @text;
}

.emoji-icon:hover {
transition: 200ms;
transform: rotate(1turn);
}
}
}
}

.reply-container {
border: 1px solid @gray;
border-radius: @corner-rounding;
padding: 0.5rem;
margin-top: 0.5rem;
margin-bottom: 0.5rem;
}

.reply-preview {
padding: 0.25rem;
cursor: pointer;
font-size: @text-size;
color: @primary-color;
}

.reply-close {
cursor: pointer;
padding-top: 0.25rem;
padding-bottom: 0.25rem;
font-size: @text-size;
color: @primary-color;
}

.message-hover {
background-color: @dark-gray;
}
}
54 changes: 52 additions & 2 deletions components/tailored/messaging/message/Message.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ import { ContextMenu } from '~/components/mixins/UI/ContextMenu'
import { Message } from '~/types/messaging'
declare module 'vue/types/vue' {
interface Vue {
setReplyChatbarContent: () => void
}
}
export default Vue.extend({
components: {
VueMarkdown,
Expand All @@ -21,14 +27,38 @@ export default Vue.extend({
payload: 'Invalid Message',
}),
},
from: {
type: String,
default: '',
},
index: {
type: Number,
default: -1,
},
setMessageHover: {
type: Function,
default: () => {},
},
},
data() {
return {
showReplies: false,
messageHover: false,
disData: 'DataFromTheProperty',
contextMenuValues: [
{ text: 'Add Reaction', func: (this as any).testFunc },
{ text: 'Reply', func: (this as any).testFunc },
{ text: 'Copy Message', func: (this as any).testFunc },
{ text: 'Reply', func: this.setReplyChatbarContent },
{
text: 'Copy Message',
func: () => {
const { type, payload } = this.$props.message
let finalPayload = payload
if (['image', 'video', 'audio', 'file'].includes(type)) {
finalPayload = this.$t('conversation.multimedia')
}
navigator.clipboard.writeText(finalPayload)
},
},
{ text: 'Copy Image', func: (this as any).testFunc },
{ text: 'Save Image', func: (this as any).testFunc },
{ text: 'Copy Link', func: (this as any).testFunc },
Expand All @@ -39,6 +69,26 @@ export default Vue.extend({
testFunc() {
console.log('Message Func Testing ' + this.$data.disData)
},
mouseOver() {
this.$data.messageHover = !this.$data.messageHover
},
toggleReplies() {
this.$data.showReplies = !this.$data.showReplies
},
setReplyChatbarContent() {
this.$data.showReplies = true
const { id, type, payload } = this.$props.message
let finalPayload = payload
if (['image', 'video', 'audio', 'file'].includes(type)) {
finalPayload = `*${this.$t('conversation.multimedia')}*`
}
this.$store.commit('setReplyChatbarContent', {
id,
payload: finalPayload,
from: this.$props.from,
})
},
},
})
</script>
Expand Down
21 changes: 21 additions & 0 deletions components/tailored/messaging/message/reply/Reply.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<div class="is-reply">
<span v-on:click="showQuickProfile">
<UiCircle type="random" :seed="reply.from" :size="35" />
</span>
<div class="reply-body">
<div class="reply-heading">
<span v-on:click="showQuickProfile">
<UiUsername :username="$mock.users.filter(u => u.address === reply.from)[0].name"
:badge="$mock.users.filter(u => u.address === reply.from)[0].badge" />
</span>
<TypographyText :text="$dayjs(reply.at).from()" />
</div>
<div class="reply-content">
<VueMarkdown v-if="reply.type === 'text'" :source="reply.payload" class="markdown" />
<UiImage v-else-if="reply.type === 'image'" :source="reply.payload.url" alt="" />
<UiEmbedsVideoPlayer v-else-if="reply.type === 'video'" :data="reply.payload" />
<UiEmbedsAudioPlayer v-else-if="reply.type === 'audio'" :data="reply.payload" />
<UiEmbedsFile v-else-if="reply.type === 'file'" :data="reply.payload" />
</div>
</div>
</div>
30 changes: 30 additions & 0 deletions components/tailored/messaging/message/reply/Reply.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
.is-reply {
padding: 0.25rem;
display: flex;
margin-bottom: 0.25rem;

.circle {
margin-top: 0.3rem;
cursor: pointer;
}

.reply-body {
margin-left: 0.75rem;
width: 100%;

.reply-heading {
display: inline-flex;
flex-direction: row;
align-items: center;

.is-text {
margin-left: @light-spacing;
font-size: @micro-text-size;
color: @text-muted;
display: flex;
align-items: flex-end;
height: 1.2rem;
}
}
}
}
Loading

0 comments on commit 8a61cbd

Please sign in to comment.