From 7e8ac14c077a0051710b36162082981bdbac4e70 Mon Sep 17 00:00:00 2001 From: Diego Sampaio Date: Thu, 25 Jun 2020 15:09:15 -0300 Subject: [PATCH 1/3] Fix threads indicators --- app/models/server/models/Subscriptions.js | 7 ++++++- .../client/imports/components/header.css | 10 +++++++++- app/threads/client/components/ThreadList.js | 18 ++++++++--------- app/threads/client/flextab/threadlist.js | 20 ++++++++++++++++--- app/threads/server/functions.js | 17 +++++++++++++--- app/ui-flextab/client/flexTabBar.html | 6 +++--- app/ui-message/client/message.html | 6 +++--- app/ui-message/client/message.js | 17 +++++++++++++--- app/ui-sidenav/client/sidebarItem.js | 6 +++--- app/ui-utils/client/lib/messageContext.js | 2 ++ app/ui-utils/client/lib/openRoom.js | 3 +++ server/publications/subscription/index.js | 2 ++ 12 files changed, 85 insertions(+), 29 deletions(-) diff --git a/app/models/server/models/Subscriptions.js b/app/models/server/models/Subscriptions.js index 460d6b20bdaa..c98ebdd69523 100644 --- a/app/models/server/models/Subscriptions.js +++ b/app/models/server/models/Subscriptions.js @@ -1365,16 +1365,19 @@ export class Subscriptions extends Base { // ////////////////////////////////////////////////////////////////// // threads - addUnreadThreadByRoomIdAndUserIds(rid, users, tmid) { + addUnreadThreadByRoomIdAndUserIds(rid, users, tmid, { groupMention = false, userMention = false } = {}) { if (!users) { return; } + return this.update({ 'u._id': { $in: users }, rid, }, { $addToSet: { tunread: tmid, + ...groupMention && { tunreadGroup: tmid }, + ...userMention && { tunreadUser: tmid }, }, }, { multi: true }); } @@ -1386,6 +1389,8 @@ export class Subscriptions extends Base { }, { $pull: { tunread: tmid, + tunreadGroup: tmid, + tunreadUser: tmid, }, }); } diff --git a/app/theme/client/imports/components/header.css b/app/theme/client/imports/components/header.css index e2217d6c715c..1d70c1acde2d 100644 --- a/app/theme/client/imports/components/header.css +++ b/app/theme/client/imports/components/header.css @@ -18,13 +18,21 @@ color: white; border-radius: calc(4 * var(--badge-font-size)); - background: var(--rc-color-button-primary); + background-color: var(--rc-color-button-primary); box-shadow: 0 0 0 2px #ffffff; font-size: var(--badge-font-size); font-weight: 600; align-items: center; justify-content: center; + + &--user-mentions { + background-color: var(--badge-user-mentions-background); + } + + &--group-mentions { + background-color: var(--badge-group-mentions-background); + } } &__first-icon { diff --git a/app/threads/client/components/ThreadList.js b/app/threads/client/components/ThreadList.js index 6f7a136f8608..13ea603df54e 100644 --- a/app/threads/client/components/ThreadList.js +++ b/app/threads/client/components/ThreadList.js @@ -14,7 +14,7 @@ import RawText from '../../../../client/components/basic/RawText'; import { useRoute } from '../../../../client/contexts/RouterContext'; import { roomTypes } from '../../../utils/client'; import { call, renderMessageBody } from '../../../ui-utils/client'; -import { useUserId, useUser } from '../../../../client/contexts/UserContext'; +import { useUserId } from '../../../../client/contexts/UserContext'; import { Messages } from '../../../models/client'; import { useEndpointDataExperimental, ENDPOINT_STATES } from '../../../../client/hooks/useEndpointDataExperimental'; import { getConfig } from '../../../ui-utils/client/config'; @@ -51,7 +51,7 @@ const LIST_SIZE = parseInt(getConfig('threadsListSize')) || 25; const filterProps = ({ msg, u, replies, mentions, tcount, ts, _id, tlm, attachments }) => ({ ..._id && { _id }, attachments, mentions, msg, u, replies, tcount, ts: new Date(ts), tlm: new Date(tlm) }); -const subscriptionFields = { tunread: 1 }; +const subscriptionFields = { tunread: 1, tunreadUser: 1, tunreadGroup: 1 }; const roomFields = { t: 1, name: 1 }; export function withData(WrappedComponent) { @@ -128,7 +128,9 @@ export function withData(WrappedComponent) { return { } }; -export function ThreadList({ total = 10, threads = [], room, unread = [], type, setType, loadMoreItems, loading, onClose, error, userId, text, setText }) { +export function ThreadList({ total = 10, threads = [], room, unread = [], unreadUser = [], unreadGroup = [], type, setType, loadMoreItems, loading, onClose, error, userId, text, setText }) { const showRealNames = useSetting('UI_Use_Real_Name'); const threadsRef = useRef(); const t = useTranslation(); - const user = useUser(); - const channelRoute = useRoute(roomTypes.getConfig(room.t).route.name); const onClick = useCallback((e) => { @@ -209,8 +209,8 @@ export function ThreadList({ total = 10, threads = [], room, unread = [], type, username={ thread.u.username } style={style} unread={unread.includes(thread._id)} - mention={thread.mentions && thread.mentions.includes(user.username)} - all={thread.mentions && thread.mentions.includes('all')} + mention={unreadUser.includes(thread._id)} + all={unreadGroup.includes(thread._id)} following={thread.replies && thread.replies.includes(userId)} data-id={thread._id} msg={msg} @@ -218,7 +218,7 @@ export function ThreadList({ total = 10, threads = [], room, unread = [], type, formatDate={formatDate} handleFollowButton={handleFollowButton} onClick={onClick} />; - }), [unread, showRealNames]); + }), [unread, unreadUser, unreadGroup, showRealNames]); const isItemLoaded = useCallback((index) => index < threadsRef.current.length, []); const { ref, contentBoxSize: { inlineSize = 378, blockSize = 750 } = {} } = useResizeObserver(); diff --git a/app/threads/client/flextab/threadlist.js b/app/threads/client/flextab/threadlist.js index 5b72beb01979..ea7653a861e2 100644 --- a/app/threads/client/flextab/threadlist.js +++ b/app/threads/client/flextab/threadlist.js @@ -13,10 +13,24 @@ Meteor.startup(function() { icon: 'thread', template: 'threads', badge: () => { - const subscription = Subscriptions.findOne({ rid: Session.get('openedRoom') }, { fields: { tunread: 1 } }); - if (subscription) { - return subscription.tunread && subscription.tunread.length && { body: subscription.tunread.length > 99 ? '99+' : subscription.tunread.length }; + const subscription = Subscriptions.findOne({ rid: Session.get('openedRoom') }, { fields: { tunread: 1, tunreadUser: 1, tunreadGroup: 1 } }); + if (!subscription?.tunread?.length) { + return; } + + const badgeClass = (() => { + if (subscription.tunreadUser?.length > 0) { + return 'rc-badge--user-mentions'; + } + if (subscription.tunreadGroup?.length > 0) { + return 'rc-badge--group-mentions'; + } + })(); + + return { + body: subscription.tunread.length > 99 ? '99+' : subscription.tunread.length, + class: badgeClass, + }; }, order: 2, }); diff --git a/app/threads/server/functions.js b/app/threads/server/functions.js index 979f56cd21c9..f9d3d3fff81a 100644 --- a/app/threads/server/functions.js +++ b/app/threads/server/functions.js @@ -7,7 +7,7 @@ export const reply = ({ tmid }, message, parentMessage, followers) => { return false; } - const { mentionIds } = getMentions(message); + const { toAll, toHere, mentionIds } = getMentions(message); const addToReplies = [ ...new Set([ @@ -21,8 +21,19 @@ export const reply = ({ tmid }, message, parentMessage, followers) => { const replies = Messages.getThreadFollowsByThreadId(tmid); - // doesnt need to update the sender (u._id) subscription, so filter it - Subscriptions.addUnreadThreadByRoomIdAndUserIds(rid, replies.filter((userId) => userId !== u._id), tmid); + const repliesFiltered = replies + .filter((userId) => userId !== u._id) + .filter((userId) => !mentionIds.includes(userId)); + + if (toAll || toHere) { + Subscriptions.addUnreadThreadByRoomIdAndUserIds(rid, repliesFiltered, tmid, { groupMention: true }); + } else { + Subscriptions.addUnreadThreadByRoomIdAndUserIds(rid, repliesFiltered, tmid); + } + + mentionIds.forEach((mentionId) => + Subscriptions.addUnreadThreadByRoomIdAndUserIds(rid, [mentionId], tmid, { userMention: true }), + ); }; export const undoReply = ({ tmid }) => { diff --git a/app/ui-flextab/client/flexTabBar.html b/app/ui-flextab/client/flexTabBar.html index 14a35ae8ecfd..edad99e560d1 100644 --- a/app/ui-flextab/client/flexTabBar.html +++ b/app/ui-flextab/client/flexTabBar.html @@ -45,9 +45,9 @@

{{_ label}}

{{#each buttons}}
- {{#if badge}} - {{badge.body}} - {{/if}} + {{#with badge}} + {{body}} + {{/with}} diff --git a/app/ui-message/client/message.html b/app/ui-message/client/message.html index 12e7269a9998..9996b0f9ccdf 100644 --- a/app/ui-message/client/message.html +++ b/app/ui-message/client/message.html @@ -147,9 +147,9 @@ {{{_ 'reply_counter' counter=i18nReplyCounter count=msg.tcount }}} {{ formatDateAndTime msg.tlm}} - {{# if unread }} -
- {{/if}} + {{#with unread }} +
+ {{/with}}
{{/if}} diff --git a/app/ui-message/client/message.js b/app/ui-message/client/message.js index 422e46562774..157d617756ae 100644 --- a/app/ui-message/client/message.js +++ b/app/ui-message/client/message.js @@ -236,11 +236,22 @@ Template.message.helpers({ }, unread() { const { msg, subscription } = this; - - if (!subscription) { + if (!subscription?.tunread?.includes(msg._id)) { return false; } - return subscription.tunread?.includes(msg._id); + + const badgeClass = (() => { + if (subscription.tunreadUser?.includes(msg._id)) { + return 'badge--user-mentions'; + } + if (subscription.tunreadGroup?.includes(msg._id)) { + return 'badge--group-mentions'; + } + })(); + + return { + class: badgeClass, + }; }, showTranslated() { const { msg, subscription, settings, u } = this; diff --git a/app/ui-sidenav/client/sidebarItem.js b/app/ui-sidenav/client/sidebarItem.js index bafff57d9fac..18169ea9e0d1 100644 --- a/app/ui-sidenav/client/sidebarItem.js +++ b/app/ui-sidenav/client/sidebarItem.js @@ -41,13 +41,13 @@ Template.sidebarItem.helpers({ return unread + tunread.length; }, badgeClass() { - const { unread, userMentions, groupMentions, tunread = [] } = this; + const { unread, userMentions, groupMentions, tunread = [], tunreadGroup = [], tunreadUser = [] } = this; - if (userMentions) { + if (userMentions || tunreadUser.length > 0) { return 'badge badge--user-mentions'; } - if (groupMentions) { + if (groupMentions || tunreadGroup.length > 0) { return 'badge badge--group-mentions'; } diff --git a/app/ui-utils/client/lib/messageContext.js b/app/ui-utils/client/lib/messageContext.js index 6848c2e857f9..52c516c621e5 100644 --- a/app/ui-utils/client/lib/messageContext.js +++ b/app/ui-utils/client/lib/messageContext.js @@ -27,6 +27,8 @@ export function messageContext({ rid } = Template.instance()) { autoTranslate: 1, rid: 1, tunread: 1, + tunreadUser: 1, + tunreadGroup: 1, }, }), settings: { diff --git a/app/ui-utils/client/lib/openRoom.js b/app/ui-utils/client/lib/openRoom.js index 6142d7ffdde8..7bac8594eae1 100644 --- a/app/ui-utils/client/lib/openRoom.js +++ b/app/ui-utils/client/lib/openRoom.js @@ -18,6 +18,9 @@ import { RoomManager, fireGlobalEvent, RoomHistoryManager } from '..'; window.currentTracker = undefined; +// cleanup session when hot reloading +Session.set('openedRoom', null); + const getDomOfLoading = mem(function getDomOfLoading() { const loadingDom = document.createElement('div'); const contentAsFunc = (content) => () => content; diff --git a/server/publications/subscription/index.js b/server/publications/subscription/index.js index 0cf12fcc7d72..e01534f56049 100644 --- a/server/publications/subscription/index.js +++ b/server/publications/subscription/index.js @@ -39,6 +39,8 @@ export const fields = { ignored: 1, E2EKey: 1, tunread: 1, + tunreadGroup: 1, + tunreadUser: 1, }; Meteor.methods({ From d458205fd6193011609cc7853bb58df8cdfe6d1f Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Fri, 26 Jun 2020 16:11:45 -0300 Subject: [PATCH 2/3] Fix missing title status, changed style review --- .../client/public/stylesheets/discussion.css | 13 +++++++-- .../client/components/ThreadListMessage.js | 2 +- .../components/hooks/useLocalstorage.js | 2 +- app/threads/client/threads.css | 28 +++++++++++++++++-- app/ui-message/client/message.html | 19 +++++++++---- app/ui-message/client/message.js | 12 +++++++- 6 files changed, 64 insertions(+), 12 deletions(-) diff --git a/app/discussion/client/public/stylesheets/discussion.css b/app/discussion/client/public/stylesheets/discussion.css index b4dc9737f02a..14083f8d0686 100644 --- a/app/discussion/client/public/stylesheets/discussion.css +++ b/app/discussion/client/public/stylesheets/discussion.css @@ -7,17 +7,26 @@ flex-wrap: wrap; } -.discussion-reply-lm { - padding: 4px 8px; +.discussion-reply-lm, +.reply-counter { + padding: 4px; color: var(--color-gray); font-size: 12px; + font-style: italic; flex-grow: 0; flex-shrink: 0; } +.reply-counter { + color: var(--color-dark-light); + + font-weight: 600; + margin-inline-start: 4px; +} + .discussions-list .load-more { text-align: center; text-transform: lowercase; diff --git a/app/threads/client/components/ThreadListMessage.js b/app/threads/client/components/ThreadListMessage.js index 9b9250315c51..4fe07ce40113 100644 --- a/app/threads/client/components/ThreadListMessage.js +++ b/app/threads/client/components/ThreadListMessage.js @@ -67,7 +67,7 @@ export default function ThreadListMessage({ _id, msg, following, username, name, - + { (mention && ) || (all && ) diff --git a/app/threads/client/components/hooks/useLocalstorage.js b/app/threads/client/components/hooks/useLocalstorage.js index 59fe97a598d5..1fa0c81c66ff 100644 --- a/app/threads/client/components/hooks/useLocalstorage.js +++ b/app/threads/client/components/hooks/useLocalstorage.js @@ -32,7 +32,7 @@ export function useLocalStorage(key, initialValue) { } window.addEventListener('storage', handleEvent); return () => window.removeEventListener('storage', handleEvent); - }, []); + }, [key]); return [storedValue, setValue]; } diff --git a/app/threads/client/threads.css b/app/threads/client/threads.css index 618f2fc2ccac..d6d81e046fe5 100644 --- a/app/threads/client/threads.css +++ b/app/threads/client/threads.css @@ -75,6 +75,15 @@ flex-flow: row nowrap; } + &:hover, + &:focus { + .thread-icons { + &--bell-off { + opacity: 1; + } + } + } + .thread-icons { display: block; flex: 0 0 20px; @@ -90,13 +99,21 @@ color: var(--rc-color-alert-message-primary); } + &--bell-off { + opacity: 0; + } + &--bell, &--bell-off { cursor: pointer; - color: #a0a0a0; + color: #6c727a; + + font-size: 1.25rem; + } - font-size: 1rem; + &--large { + font-size: 1.25rem; } } @@ -108,6 +125,13 @@ font-size: 12px; align-items: center; + + .thread-icons { + &--bell, + &--bell-off { + font-size: 1rem; + } + } } .thread-quote__message { diff --git a/app/ui-message/client/message.html b/app/ui-message/client/message.html index 9996b0f9ccdf..d572e9e4e022 100644 --- a/app/ui-message/client/message.html +++ b/app/ui-message/client/message.html @@ -1,5 +1,5 @@