From 7cb57463e8f1711f8176f47e86981c09d8799fb4 Mon Sep 17 00:00:00 2001 From: Ritik Srivastava Date: Wed, 14 Jul 2021 03:05:28 +0530 Subject: [PATCH 1/7] Add Reactions Widget --- .../client/imports/components/message-box.css | 34 ++++--- .../imports/components/messageBubble.css | 12 ++- app/theme/client/imports/general/base_old.css | 93 +++++++++++++++++++ app/ui-master/public/icons.svg | 16 ++++ app/ui-master/public/icons/exclamation.svg | 4 + app/ui-master/public/icons/heart.svg | 3 + app/ui-master/public/icons/question.svg | 3 + app/ui-master/public/icons/thumbsdown.svg | 3 + app/ui-master/public/icons/thumbsup.svg | 3 + app/ui-message/client/messageBubble.js | 56 ++++++++++- app/ui/client/views/app/room.html | 11 +++ private/public/icons.svg | 16 ++++ 12 files changed, 234 insertions(+), 20 deletions(-) create mode 100644 app/ui-master/public/icons/exclamation.svg create mode 100644 app/ui-master/public/icons/heart.svg create mode 100644 app/ui-master/public/icons/question.svg create mode 100644 app/ui-master/public/icons/thumbsdown.svg create mode 100644 app/ui-master/public/icons/thumbsup.svg diff --git a/app/theme/client/imports/components/message-box.css b/app/theme/client/imports/components/message-box.css index 7209396f5c28d..9afd1974b9456 100644 --- a/app/theme/client/imports/components/message-box.css +++ b/app/theme/client/imports/components/message-box.css @@ -103,32 +103,37 @@ &__container-friendlyUI { display: flex; + padding: 0.75rem 0; cursor: text; transition: background-color 0.3s; - align-items: center; + background-color: #f2f5f8; - background-color: #F2F5F8; + align-items: center; } &__insert-attachment-container { display: flex; - align-items: center; + padding: 0.75rem; - background-color: #F2F5F8; + + background-color: #f2f5f8; + align-items: center; .attachment-tile { - padding: 0.5rem 0; - background-color: #FFFFFF; display: flex; flex-direction: column; - margin: 0 0.5rem 0 0; flex: 1 0; - align-items: center; + + margin: 0 0.5rem 0 0; + padding: 0.5rem 0; + border-radius: 0.5rem; + background-color: #ffffff; + align-items: center; &__last { margin: 0; @@ -137,27 +142,28 @@ .rc-icon { height: 2em; } + .attachment-description { + font-size: 0.75rem; font-weight: 300; - font-size: 0.75rem } } } &__textarea-friendlyUI { display: flex; - + + flex: 1 0; + padding: 0.5rem; border-width: var(--message-box-container-border-width); border-color: var(--message-box-container-border-color); border-radius: 100rem; - align-items: center; - - flex: 1 0; - background-color: white; + + align-items: center; } &__textarea-input-friendlyUI { diff --git a/app/theme/client/imports/components/messageBubble.css b/app/theme/client/imports/components/messageBubble.css index 7a8f1ea2a8e61..09270e1270b2f 100644 --- a/app/theme/client/imports/components/messageBubble.css +++ b/app/theme/client/imports/components/messageBubble.css @@ -218,10 +218,12 @@ background-color: var(--friendly-message-color); } - &.firstMsg > .message-body-wrapper { + &.firstMsg { margin-top: 10px; - border-bottom-right-radius: 6px; + > .message-body-wrapper { + border-bottom-right-radius: 6px; + } } &.midMsg > .message-body-wrapper { @@ -254,10 +256,12 @@ background-color: #dee4e8; } - &.firstMsg > .message-body-wrapper { + &.firstMsg { margin-top: 10px; - border-bottom-left-radius: 6px; + > .message-body-wrapper { + border-bottom-left-radius: 6px; + } } &.midMsg > .message-body-wrapper { diff --git a/app/theme/client/imports/general/base_old.css b/app/theme/client/imports/general/base_old.css index 7a8068481a6fc..fae750fa34077 100644 --- a/app/theme/client/imports/general/base_old.css +++ b/app/theme/client/imports/general/base_old.css @@ -1481,6 +1481,99 @@ word-wrap: break-word; -webkit-overflow-scrolling: touch; + + > ul { + > li { + transition: opacity 0.15s ease-out; + } + + > .reactions-backdrop { + position: fixed; + top: 0; + left: 0; + + display: none; + + width: 100%; + height: 100%; + } + + > .reactions { + --reactionSize: 45px; + + position: absolute; + + display: flex; + overflow: hidden; + + height: var(--reactionSize); + padding: 6px 15px; + box-sizing: content-box; + gap: 6px; + + transition: transform 0.15s cubic-bezier(0.175, 0.885, 0.32, 1.275), opacity 0.15s ease-out; + transform: translateY(20px) scale(0.7); + pointer-events: none; + + opacity: 0; + border-radius: var(--reactionSize); + background-color: white; + box-shadow: 0 0 5px 0 #cccccc; + + > .reaction-icon { + width: var(--reactionSize); + height: var(--reactionSize); + padding: 10px; + border-radius: 50%; + + > .rc-icon { + width: 100%; + height: 100%; + + color: var(--friendly-message-color); + } + + @media (hover: hover) { + &:hover { + background-color: var(--friendly-message-color); + + > .rc-icon { + color: #ffffff; + } + } + } + + &:active { + background-color: var(--friendly-message-color); + + > .rc-icon { + color: #ffffff; + } + } + } + } + } + + &.show-reactions { + > ul { + > li { + pointer-events: none; + + opacity: 0.35; + } + + > .reactions-backdrop { + display: unset; + } + + > .reactions { + transform: translateY(0) scale(1); + pointer-events: all; + + opacity: 1; + } + } + } } & .footer { diff --git a/app/ui-master/public/icons.svg b/app/ui-master/public/icons.svg index eef102df4ea8f..87567bba282c8 100644 --- a/app/ui-master/public/icons.svg +++ b/app/ui-master/public/icons.svg @@ -112,6 +112,10 @@ + + + + @@ -183,6 +187,9 @@ + + + @@ -300,6 +307,9 @@ + + + @@ -385,6 +395,12 @@ + + + + + + diff --git a/app/ui-master/public/icons/exclamation.svg b/app/ui-master/public/icons/exclamation.svg new file mode 100644 index 0000000000000..832c0607233b5 --- /dev/null +++ b/app/ui-master/public/icons/exclamation.svg @@ -0,0 +1,4 @@ + + + + diff --git a/app/ui-master/public/icons/heart.svg b/app/ui-master/public/icons/heart.svg new file mode 100644 index 0000000000000..2c7bd966feb3e --- /dev/null +++ b/app/ui-master/public/icons/heart.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/ui-master/public/icons/question.svg b/app/ui-master/public/icons/question.svg new file mode 100644 index 0000000000000..0f607b4d9f76a --- /dev/null +++ b/app/ui-master/public/icons/question.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/ui-master/public/icons/thumbsdown.svg b/app/ui-master/public/icons/thumbsdown.svg new file mode 100644 index 0000000000000..0db3eecdaefd4 --- /dev/null +++ b/app/ui-master/public/icons/thumbsdown.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/ui-master/public/icons/thumbsup.svg b/app/ui-master/public/icons/thumbsup.svg new file mode 100644 index 0000000000000..c968bb478c30b --- /dev/null +++ b/app/ui-master/public/icons/thumbsup.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/ui-message/client/messageBubble.js b/app/ui-message/client/messageBubble.js index 83a98092b6d28..859e5f705d2bf 100644 --- a/app/ui-message/client/messageBubble.js +++ b/app/ui-message/client/messageBubble.js @@ -11,6 +11,7 @@ import { renderMessageBody } from '../../../client/lib/renderMessageBody'; import { settings } from '../../settings/client'; import './messageBubble.html'; +let activeReactionMessage; const renderBody = (msg, settings) => { const searchedText = msg.searchedText ? msg.searchedText : ''; const isSystemMessage = MessageTypes.isSystemMessage(msg); @@ -270,21 +271,56 @@ const setCornerClasses = (previousNode, currentNode, nextNode, iterateCount) => setCornerClasses(getPreviousSentMessage(previousNode), previousNode, currentNode, iterateCount); } }; +const showReactions = (target) => { + activeReactionMessage = target; + const wrapper = document.querySelector('.messages-box .wrapper'); + const reactions = document.querySelector('.messages-box .wrapper .reactions'); + + activeReactionMessage.style.opacity = '1'; + reactions.style.top = `${ activeReactionMessage.offsetTop - reactions.offsetHeight - 5 }px`; + + if (activeReactionMessage?.classList.contains('messageSent')) { + reactions.style.left = ''; + reactions.style.right = '15px'; + } else if (activeReactionMessage?.classList.contains('messageReceived')) { + reactions.style.left = '15px'; + reactions.style.right = ''; + } + wrapper.classList.add('show-reactions'); +}; const processSequentials = ({ index, currentNode, settings, forceDate, showDateSeparator = true, groupable, shouldCollapseReplies }) => { if (!showDateSeparator && !groupable) { return; } - // const currentDataset = currentNode.dataset; const previousNode = (index === undefined || index > 0) && getPreviousSentMessage(currentNode); - const nextNode = currentNode.nextElementSibling; + let nextNode = currentNode.nextElementSibling; if (nextNode) { nextNode.previousElementSibling = currentNode; + if (nextNode?.tagName === 'DIV') { + nextNode = null; + } } setCornerClasses(previousNode, currentNode, nextNode, 2); + if (currentNode.getAttribute('longPressListener') !== 'true') { + currentNode.setAttribute('longPressListener', 'true'); + + let longPressTimeout; + const mouseDown = () => { + longPressTimeout = setTimeout(() => showReactions(currentNode), 500); + }; + const mouseUp = () => clearTimeout(longPressTimeout); + + currentNode.addEventListener('mousedown', mouseDown); + currentNode.addEventListener('mouseup', mouseUp); + currentNode.addEventListener('touchstart', mouseDown); + currentNode.addEventListener('touchend', mouseUp); + currentNode.addEventListener('contextmenu', (event) => event.preventDefault()); + } + if (!previousNode) { setTimeout(() => { currentNode.dispatchEvent(new CustomEvent('MessageGroup', { bubbles: true })); @@ -319,5 +355,21 @@ const processSequentials = ({ index, currentNode, settings, forceDate, showDateS Template.messageBubble.onRendered(function() { const currentNode = this.firstNode; + + const wrapper = document.querySelector('.messages-box .wrapper'); + const reactionBackdrop = document.querySelector('.reactions-backdrop'); + reactionBackdrop.addEventListener('contextmenu', (event) => event.preventDefault()); + reactionBackdrop.addEventListener('click', () => { + activeReactionMessage.style.opacity = ''; + wrapper.classList.remove('show-reactions'); + }); + + $('.reaction-icon').on('click', function(event) { + event.stopPropagation(); + event.stopImmediatePropagation(); + console.log($(this)); + reactionBackdrop.click(); + }); + this.autorun(() => processSequentials({ currentNode, ...Template.currentData() })); }); diff --git a/app/ui/client/views/app/room.html b/app/ui/client/views/app/room.html index 1bf3458d22e78..093ccf6d5bc2a 100644 --- a/app/ui/client/views/app/room.html +++ b/app/ui/client/views/app/room.html @@ -131,6 +131,17 @@ {{/if}} {{/if}} + + {{#if isMobile}} +
+
+ {{> icon block="reactions__heart-icon" icon="heart" }} + {{> icon block="reactions__thumbsup-icon" icon="thumbsup" }} + {{> icon block="reactions__thumbsdown-icon" icon="thumbsdown" }} + {{> icon block="reactions__question-icon" icon="question" }} + {{> icon block="reactions__exclamation-icon" icon="exclamation" }} +
+ {{/if}} diff --git a/private/public/icons.svg b/private/public/icons.svg index eef102df4ea8f..87567bba282c8 100644 --- a/private/public/icons.svg +++ b/private/public/icons.svg @@ -112,6 +112,10 @@ + + + + @@ -183,6 +187,9 @@ + + + @@ -300,6 +307,9 @@ + + + @@ -385,6 +395,12 @@ + + + + + + From 1313dbddcd9180afa74af61d26239d02e1d8229a Mon Sep 17 00:00:00 2001 From: Ritik Srivastava Date: Wed, 14 Jul 2021 04:20:56 +0530 Subject: [PATCH 2/7] Add Set Emoji Action --- app/theme/client/imports/general/base_old.css | 2 +- app/ui-message/client/messageBubble.js | 3 ++- app/ui/client/views/app/room.html | 10 +++++----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/theme/client/imports/general/base_old.css b/app/theme/client/imports/general/base_old.css index fae750fa34077..ac3ef62a3c4c1 100644 --- a/app/theme/client/imports/general/base_old.css +++ b/app/theme/client/imports/general/base_old.css @@ -1529,7 +1529,7 @@ > .rc-icon { width: 100%; height: 100%; - + pointer-events: none; color: var(--friendly-message-color); } diff --git a/app/ui-message/client/messageBubble.js b/app/ui-message/client/messageBubble.js index 859e5f705d2bf..c47825efd01dc 100644 --- a/app/ui-message/client/messageBubble.js +++ b/app/ui-message/client/messageBubble.js @@ -1,3 +1,4 @@ +import { Meteor } from 'meteor/meteor'; import { Tracker } from 'meteor/tracker'; import { Template } from 'meteor/templating'; import { TAPi18n } from 'meteor/rocketchat:tap-i18n'; @@ -367,7 +368,7 @@ Template.messageBubble.onRendered(function() { $('.reaction-icon').on('click', function(event) { event.stopPropagation(); event.stopImmediatePropagation(); - console.log($(this)); + Meteor.call('setReaction', `:${ event.target.getAttribute('data') }:`, activeReactionMessage.id); reactionBackdrop.click(); }); diff --git a/app/ui/client/views/app/room.html b/app/ui/client/views/app/room.html index 093ccf6d5bc2a..e7fbee3218ecd 100644 --- a/app/ui/client/views/app/room.html +++ b/app/ui/client/views/app/room.html @@ -135,11 +135,11 @@ {{#if isMobile}}
- {{> icon block="reactions__heart-icon" icon="heart" }} - {{> icon block="reactions__thumbsup-icon" icon="thumbsup" }} - {{> icon block="reactions__thumbsdown-icon" icon="thumbsdown" }} - {{> icon block="reactions__question-icon" icon="question" }} - {{> icon block="reactions__exclamation-icon" icon="exclamation" }} + {{> icon block="reactions__heart-icon" icon="heart" }} + {{> icon block="reactions__thumbsup-icon" icon="thumbsup" }} + {{> icon block="reactions__thumbsdown-icon" icon="thumbsdown" }} + {{> icon block="reactions__question-icon" icon="question" }} + {{> icon block="reactions__exclamation-icon" icon="exclamation" }}
{{/if}} From b40329ace8de2ff65f576945d24b8566955af291 Mon Sep 17 00:00:00 2001 From: Ritik Srivastava Date: Thu, 15 Jul 2021 02:26:01 +0530 Subject: [PATCH 3/7] Add reactions bubble --- .../imports/components/messageBubble.css | 83 +++++++++++++++---- app/theme/client/imports/general/base_old.css | 9 +- app/ui-message/client/messageBubble.html | 9 +- app/ui-message/client/messageBubble.js | 15 ++++ 4 files changed, 95 insertions(+), 21 deletions(-) diff --git a/app/theme/client/imports/components/messageBubble.css b/app/theme/client/imports/components/messageBubble.css index 09270e1270b2f..b65cef0ad382f 100644 --- a/app/theme/client/imports/components/messageBubble.css +++ b/app/theme/client/imports/components/messageBubble.css @@ -7,23 +7,48 @@ padding: 0 15px; .message-body-wrapper { - overflow: hidden; - width: fit-content; max-width: 75%; margin-top: 2px; - border-radius: 20px; - font-family: 'Source Sans Pro', sans-serif; font-weight: 400; .body { position: relative; - + overflow: hidden; width: 100%; height: 100%; padding: 11px 16px; + border-radius: 21px; + } + .reaction { + position: relative; + width: 100%; + height: 0; + transition: height 0.18s ease-out; + + .reaction-icon { + position: absolute; + left: -6px; + top: -16px; + width: 25px; + height: 25px; + background-color: var(--friendly-message-color); + border: 2px solid white; + border-radius: 30px; + display: flex; + padding: 4px; + justify-content: center; + align-items: center; + transform: scale(0); + transition: transform 0.18s ease-out; + + > .rc-icon { + flex: 1; + color: white; + } + } } } @@ -46,6 +71,19 @@ } } + &.hasReaction { + .message-body-wrapper { + .reaction { + height: 8px; + + .reaction-icon { + transform: scale(1); + transition: transform 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275); + } + } + } + } + &.attachment { &.image .body { overflow: hidden; @@ -221,17 +259,17 @@ &.firstMsg { margin-top: 10px; - > .message-body-wrapper { + > .message-body-wrapper .body { border-bottom-right-radius: 6px; } } - &.midMsg > .message-body-wrapper { + &.midMsg > .message-body-wrapper .body { border-top-right-radius: 6px; border-bottom-right-radius: 6px; } - &.lastMsg > .message-body-wrapper { + &.lastMsg > .message-body-wrapper .body { border-top-right-radius: 6px; } @@ -247,29 +285,42 @@ &.messageReceived { align-items: flex-start; - .message-body-wrapper .body { - color: #202e39; - - * { + .message-body-wrapper { + .body { color: #202e39; + + * { + color: #202e39; + } + background-color: #dee4e8; + } + .reaction { + .reaction-icon { + left: unset; + right: -6px; + background-color: #dee4e8; + + > .rc-icon { + color: var(--friendly-message-color); + } + } } - background-color: #dee4e8; } &.firstMsg { margin-top: 10px; - > .message-body-wrapper { + > .message-body-wrapper .body { border-bottom-left-radius: 6px; } } - &.midMsg > .message-body-wrapper { + &.midMsg > .message-body-wrapper .body { border-top-left-radius: 6px; border-bottom-left-radius: 6px; } - &.lastMsg > .message-body-wrapper { + &.lastMsg > .message-body-wrapper .body { border-top-left-radius: 6px; } } diff --git a/app/theme/client/imports/general/base_old.css b/app/theme/client/imports/general/base_old.css index ac3ef62a3c4c1..c20bc51c4844f 100644 --- a/app/theme/client/imports/general/base_old.css +++ b/app/theme/client/imports/general/base_old.css @@ -1511,9 +1511,9 @@ box-sizing: content-box; gap: 6px; - transition: transform 0.15s cubic-bezier(0.175, 0.885, 0.32, 1.275), opacity 0.15s ease-out; - transform: translateY(20px) scale(0.7); pointer-events: none; + transform: translateY(30px) scale(0.6); + transition: transform 0.15s ease-out, opacity 0.15s linear; opacity: 0; border-radius: var(--reactionSize); @@ -1567,10 +1567,11 @@ } > .reactions { - transform: translateY(0) scale(1); pointer-events: all; - + opacity: 1; + transform: translateY(0) scale(1); + transition: transform 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275), opacity 0.18s linear; } } } diff --git a/app/ui-message/client/messageBubble.html b/app/ui-message/client/messageBubble.html index d9f59192efe64..b08d3a10c1d77 100644 --- a/app/ui-message/client/messageBubble.html +++ b/app/ui-message/client/messageBubble.html @@ -1,5 +1,5 @@