From 8a61cbdcfb7c43c8de99ec4a8e591d11cec7880f Mon Sep 17 00:00:00 2001 From: molimauro <50131258+molimauro@users.noreply.github.com> Date: Sat, 11 Sep 2021 04:33:20 +0200 Subject: [PATCH] feat(replies): add message replies (#133) * feat(replies): add reply component and replies under messages * feat(replies): reply logic * fix(replies): rebase and minors * fix(replies): minors * fix(replies): minors --- .../tailored/commands/preview/Preview.html | 2 +- .../tailored/commands/preview/Preview.less | 4 + components/tailored/core/chatbar/Chatbar.html | 2 +- components/tailored/core/chatbar/Chatbar.less | 5 ++ components/tailored/core/chatbar/Chatbar.vue | 2 +- .../tailored/core/chatbar/reply/Reply.html | 6 ++ .../tailored/core/chatbar/reply/Reply.less | 44 +++++++++++ .../tailored/core/chatbar/reply/Reply.vue | 21 +++++ .../tailored/messaging/group/Group.html | 2 +- .../tailored/messaging/group/Group.less | 1 + .../tailored/messaging/message/Message.html | 31 ++++++-- .../tailored/messaging/message/Message.less | 78 ++++++++++++++++++- .../tailored/messaging/message/Message.vue | 54 ++++++++++++- .../messaging/message/reply/Reply.html | 21 +++++ .../messaging/message/reply/Reply.less | 30 +++++++ .../messaging/message/reply/Reply.vue | 31 ++++++++ layouts/chat/Chat.html | 1 + layouts/chat/Chat.less | 11 +++ layouts/server/Server.less | 11 +++ locales/en-US.js | 5 ++ mock/messages.ts | 38 +++++++++ plugins/thirdparty/fontawesome.ts | 15 ++-- store/ui/mutations.ts | 14 ++++ store/ui/state.ts | 6 ++ types/messaging.d.ts | 10 +++ 25 files changed, 426 insertions(+), 19 deletions(-) create mode 100644 components/tailored/core/chatbar/reply/Reply.html create mode 100644 components/tailored/core/chatbar/reply/Reply.less create mode 100644 components/tailored/core/chatbar/reply/Reply.vue create mode 100644 components/tailored/messaging/message/reply/Reply.html create mode 100644 components/tailored/messaging/message/reply/Reply.less create mode 100644 components/tailored/messaging/message/reply/Reply.vue diff --git a/components/tailored/commands/preview/Preview.html b/components/tailored/commands/preview/Preview.html index b8b8620b87..917c94ef64 100644 --- a/components/tailored/commands/preview/Preview.html +++ b/components/tailored/commands/preview/Preview.html @@ -1,4 +1,4 @@ -
+
diff --git a/components/tailored/commands/preview/Preview.less b/components/tailored/commands/preview/Preview.less index 5108dfcff5..e13bd1fe1b 100644 --- a/components/tailored/commands/preview/Preview.less +++ b/components/tailored/commands/preview/Preview.less @@ -49,4 +49,8 @@ .command-desc { font-size: @mini-text-size; } + + &.has-reply { + margin-bottom: 30px; + } } \ No newline at end of file diff --git a/components/tailored/core/chatbar/Chatbar.html b/components/tailored/core/chatbar/Chatbar.html index e6fc0a5e33..54261205dc 100644 --- a/components/tailored/core/chatbar/Chatbar.html +++ b/components/tailored/core/chatbar/Chatbar.html @@ -1,4 +1,4 @@ -
+
+ +
+ +
+
\ No newline at end of file diff --git a/components/tailored/core/chatbar/reply/Reply.less b/components/tailored/core/chatbar/reply/Reply.less new file mode 100644 index 0000000000..958fdf74a4 --- /dev/null +++ b/components/tailored/core/chatbar/reply/Reply.less @@ -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); + } +} \ No newline at end of file diff --git a/components/tailored/core/chatbar/reply/Reply.vue b/components/tailored/core/chatbar/reply/Reply.vue new file mode 100644 index 0000000000..4d89992436 --- /dev/null +++ b/components/tailored/core/chatbar/reply/Reply.vue @@ -0,0 +1,21 @@ + + + diff --git a/components/tailored/messaging/group/Group.html b/components/tailored/messaging/group/Group.html index 96a30c9d06..c31d77aaaf 100644 --- a/components/tailored/messaging/group/Group.html +++ b/components/tailored/messaging/group/Group.html @@ -12,7 +12,7 @@
- +
\ No newline at end of file diff --git a/components/tailored/messaging/group/Group.less b/components/tailored/messaging/group/Group.less index e28e16fe41..93d1af5e95 100644 --- a/components/tailored/messaging/group/Group.less +++ b/components/tailored/messaging/group/Group.less @@ -17,6 +17,7 @@ margin-left: 0.75rem; width: 100%; .group-heading { + width: 100%; display: inline-flex; flex-direction: row; align-items: center; diff --git a/components/tailored/messaging/message/Message.html b/components/tailored/messaging/message/Message.html index ebae81efef..255a75ec25 100644 --- a/components/tailored/messaging/message/Message.html +++ b/components/tailored/messaging/message/Message.html @@ -1,7 +1,28 @@
- - - - - +
+
+
+ +
+
+ +
+
+ +
+
+ + + + + +
+
+
{{message.replies.length}} {{$tc('conversation.reply', message.replies.length)}} >
+ +
Collapse <
+
\ No newline at end of file diff --git a/components/tailored/messaging/message/Message.less b/components/tailored/messaging/message/Message.less index 83fe777dd5..a47740395f 100644 --- a/components/tailored/messaging/message/Message.less +++ b/components/tailored/messaging/message/Message.less @@ -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; + } +} \ No newline at end of file diff --git a/components/tailored/messaging/message/Message.vue b/components/tailored/messaging/message/Message.vue index 8fca46ac08..e7100febbb 100644 --- a/components/tailored/messaging/message/Message.vue +++ b/components/tailored/messaging/message/Message.vue @@ -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, @@ -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 }, @@ -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, + }) + }, }, }) diff --git a/components/tailored/messaging/message/reply/Reply.html b/components/tailored/messaging/message/reply/Reply.html new file mode 100644 index 0000000000..48ad382424 --- /dev/null +++ b/components/tailored/messaging/message/reply/Reply.html @@ -0,0 +1,21 @@ +
+ + + +
+
+ + + + +
+
+ + + + + +
+
+
\ No newline at end of file diff --git a/components/tailored/messaging/message/reply/Reply.less b/components/tailored/messaging/message/reply/Reply.less new file mode 100644 index 0000000000..40b4c3f663 --- /dev/null +++ b/components/tailored/messaging/message/reply/Reply.less @@ -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; + } + } + } +} \ No newline at end of file diff --git a/components/tailored/messaging/message/reply/Reply.vue b/components/tailored/messaging/message/reply/Reply.vue new file mode 100644 index 0000000000..88653fbb44 --- /dev/null +++ b/components/tailored/messaging/message/reply/Reply.vue @@ -0,0 +1,31 @@ + + + diff --git a/layouts/chat/Chat.html b/layouts/chat/Chat.html index f0bbeb3855..8f8885e1de 100644 --- a/layouts/chat/Chat.html +++ b/layouts/chat/Chat.html @@ -31,6 +31,7 @@ +
({ createServer: false, }, chatbarContent: '', + replyChatbarContent: { id: '', from: '', payload: '' }, fullscreen: false, showEnhancers: false, messages: [], diff --git a/types/messaging.d.ts b/types/messaging.d.ts index a1280e81e7..11eedc4712 100644 --- a/types/messaging.d.ts +++ b/types/messaging.d.ts @@ -5,11 +5,21 @@ export type ImagePayload = { url: string } +export type Reply = { + id: string + at: number + to: string + from: string + type: string + payload: TextPayload | ImagePayload +} + export type Message = { id: string at: number type: string payload: TextPayload | ImagePayload + replies: Array } export type Group = {