diff --git a/app/mentions/client/mentionLink.css b/app/mentions/client/mentionLink.css index 620238c7d210..70c1be80838d 100644 --- a/app/mentions/client/mentionLink.css +++ b/app/mentions/client/mentionLink.css @@ -1,27 +1,37 @@ +.message .mention-link, .mention-link { padding: 0 6px 2px; - transition: border-radius 0.3s; + transition: opacity 0.3s, background-color 0.3s, color 0.3s; - color: var(--mention-link-text-color) !important; + color: var(--mention-link-text-color); border-radius: var(--mention-link-radius); - background-color: var(--mention-link-background) !important; + background-color: var(--mention-link-background); font-weight: 700; &:hover { - border-radius: var(--border-radius); + opacity: 0.6; + color: var(--mention-link-text-color); } &--me { - color: var(--mention-link-me-text-color) !important; - background-color: var(--mention-link-me-background) !important; + color: var(--mention-link-me-text-color); + background-color: var(--mention-link-me-background); + + &:hover { + color: var(--mention-link-me-text-color); + } } &--group { - color: var(--mention-link-group-text-color) !important; - background-color: var(--mention-link-group-background) !important; + color: var(--mention-link-group-text-color); + background-color: var(--mention-link-group-background); + + &:hover { + color: var(--mention-link-group-text-color); + } } } diff --git a/app/mentions/lib/MentionsParser.js b/app/mentions/lib/MentionsParser.js index 270e3cd90411..0921f66e2b3b 100644 --- a/app/mentions/lib/MentionsParser.js +++ b/app/mentions/lib/MentionsParser.js @@ -41,18 +41,25 @@ export class MentionsParser { replaceUsers = (msg, { mentions, temp }, me) => msg .replace(this.userMentionRegex, (match, prefix, mention) => { - const isGroupMention = ['all', 'here'].includes(mention); - const className = [ - 'mention-link', - 'mention-link--user', - mention === 'all' && 'mention-link--all', - mention === 'here' && 'mention-link--here', - mention === me && 'mention-link--me', - isGroupMention && 'mention-link--group', - ].filter(Boolean).join(' '); - - if (isGroupMention) { - return `${ prefix }${ mention }`; + const classNames = ['mention-link']; + + if (mention === 'all') { + classNames.push('mention-link--all'); + classNames.push('mention-link--group'); + } else if (mention === 'here') { + classNames.push('mention-link--here'); + classNames.push('mention-link--group'); + } else if (mention === me) { + classNames.push('mention-link--me'); + classNames.push('mention-link--user'); + } else { + classNames.push('mention-link--user'); + } + + const className = classNames.join(' '); + + if (mention === 'all' || mention === 'here') { + return `${ prefix }${ mention }`; } const label = temp ? diff --git a/app/mentions/tests/client.tests.js b/app/mentions/tests/client.tests.js index 32f27f8241ca..d3af918771ad 100644 --- a/app/mentions/tests/client.tests.js +++ b/app/mentions/tests/client.tests.js @@ -215,7 +215,7 @@ describe('replace methods', function() { describe('replaceUsers', () => { it('should render for @all', () => { const result = mentionsParser.replaceUsers('@all', message, 'me'); - assert.equal('all', result); + assert.equal(result, 'all'); }); const str2 = 'rocket.cat'; @@ -237,7 +237,7 @@ describe('replace methods', function() { it('should render for me', () => { const result = mentionsParser.replaceUsers('hello @me', message, 'me'); - assert.equal(result, 'hello me'); + assert.equal(result, 'hello me'); }); }); @@ -248,7 +248,7 @@ describe('replace methods', function() { it('should render for @all', () => { const result = mentionsParser.replaceUsers('@all', message, 'me'); - assert.equal(result, 'all'); + assert.equal(result, 'all'); }); const str2 = 'rocket.cat'; @@ -284,7 +284,7 @@ describe('replace methods', function() { it('should render for me', () => { const result = mentionsParser.replaceUsers('hello @me', message, 'me'); - assert.equal(result, 'hello Me'); + assert.equal(result, 'hello Me'); }); }); diff --git a/app/theme/client/imports/general/variables.css b/app/theme/client/imports/general/variables.css index 902aad513931..428f602e4f90 100644 --- a/app/theme/client/imports/general/variables.css +++ b/app/theme/client/imports/general/variables.css @@ -1,4 +1,28 @@ :root { + /* + * Color palette + */ + --color-dark-100: #0c0d0f; + --color-dark-90: #1e232a; + --color-dark-80: #2e343e; + --color-dark-70: #53585f; + --color-dark-30: #9da2a9; + --color-dark-20: #caced1; + --color-dark-10: #e0e5e8; + --color-dark-05: #f1f2f4; + --color-dark-blue: #175cc4; + --color-blue: #1d74f5; + --color-light-blue: #4eb2f5; + --color-lighter-blue: #e8f2ff; + --color-purple: #861da8; + --color-red: #f5455c; + --color-dark-red: #e0364d; + --color-orange: #f59547; + --color-yellow: #ffd21f; + --color-dark-yellow: #f6c502; + --color-green: #2de0a5; + --color-dark-green: #26d198; + /* * General Colors */ @@ -12,15 +36,15 @@ --color-gray-lightest: #f2f3f5; --color-black: #000000; --color-white: #ffffff; - --rc-color-error: #f5455c; + --rc-color-error: var(--color-red); --rc-color-error-light: #e1364c; - --rc-color-alert: #ffd21f; - --rc-color-alert-light: #f6c502; - --rc-color-success: #2de0a5; + --rc-color-alert: var(--color-yellow); + --rc-color-alert-light: var(--color-dark-yellow); + --rc-color-success: var(--color-green); --rc-color-success-light: #25d198; - --rc-color-button-primary: #1d74f5; - --rc-color-button-primary-light: #175cc4; - --rc-color-alert-message-primary: var(--rc-color-button-primary); + --rc-color-button-primary: var(--color-blue); + --rc-color-button-primary-light: var(--color-dark-blue); + --rc-color-alert-message-primary: var(--color-blue); --rc-color-alert-message-primary-background: #f1f6ff; --rc-color-alert-message-secondary: #7ca52b; --rc-color-alert-message-secondary-background: #fafff1; @@ -258,16 +282,16 @@ --badge-background: var(--rc-color-primary-dark); --badge-unread-background: var(--rc-color-primary-dark); --badge-dm-background: var(--rc-color-primary-dark); - --badge-user-mentions-background: var(--rc-color-button-primary); + --badge-user-mentions-background: var(--color-dark-blue); --badge-group-mentions-background: var(--rc-color-primary-dark); /* * Mention link */ --mention-link-radius: 10px; - --mention-link-background: rgba(29, 116, 245, 0.2); - --mention-link-text-color: var(--rc-color-button-primary); - --mention-link-me-background: var(--rc-color-button-primary); + --mention-link-background: var(--color-lighter-blue); + --mention-link-text-color: var(--color-dark-blue); + --mention-link-me-background: var(--color-dark-blue); --mention-link-me-text-color: var(--color-white); --mention-link-group-background: var(--rc-color-primary-dark); --mention-link-group-text-color: var(--color-white); diff --git a/app/ui-flextab/client/tabs/membersList.html b/app/ui-flextab/client/tabs/membersList.html index 6a1ada15a98e..cf36d6ed7a6b 100644 --- a/app/ui-flextab/client/tabs/membersList.html +++ b/app/ui-flextab/client/tabs/membersList.html @@ -13,9 +13,9 @@ diff --git a/app/ui-flextab/client/tabs/membersList.js b/app/ui-flextab/client/tabs/membersList.js index d3f667cb830a..05de342aeb30 100644 --- a/app/ui-flextab/client/tabs/membersList.js +++ b/app/ui-flextab/client/tabs/membersList.js @@ -1,6 +1,5 @@ import { Meteor } from 'meteor/meteor'; import { ReactiveVar } from 'meteor/reactive-var'; -import { Tracker } from 'meteor/tracker'; import { Session } from 'meteor/session'; import { Template } from 'meteor/templating'; import { RoomManager, popover } from '../../../ui-utils'; @@ -171,8 +170,7 @@ Template.membersList.events({ instance.filter.set(e.target.value.trim()); }, 'change .js-type'(e, instance) { - const seeAll = instance.showAllUsers.get(); - instance.showAllUsers.set(!seeAll); + instance.showAllUsers.set(e.currentTarget.value === 'all'); instance.usersLimit.set(100); }, 'click .js-more'(e, instance) { @@ -278,7 +276,7 @@ Template.membersList.onCreated(function() { this.tabBar = Template.instance().tabBar; - Tracker.autorun(() => { + this.autorun(() => { if (this.data.rid == null) { return; } this.loading.set(true); return Meteor.call('getUsersOfRoom', this.data.rid, this.showAllUsers.get(), { limit: 100, skip: 0 }, (error, users) => { @@ -298,16 +296,29 @@ Template.membersList.onCreated(function() { return setTimeout(() => this.clearRoomUserDetail(), 500); }; - this.showUserDetail = (username) => { - this.showDetail.set(username != null); - return this.userDetail.set(username); + this.showUserDetail = (username, group) => { + this.showDetail.set(!!username); + this.userDetail.set(username); + if (group) { + this.showAllUsers.set(group === 'all'); + } }; this.clearRoomUserDetail = this.data.clearUserDetail; - return this.autorun(() => { - const data = Template.currentData(); - return this.showUserDetail(data.userDetail); - } - ); + this.autorun(() => { + const { userDetail, groupDetail } = Template.currentData(); + + this.showUserDetail(userDetail, groupDetail); + }); +}); + +Template.membersList.onRendered(function() { + this.autorun(() => { + const showAllUsers = this.showAllUsers.get(); + const statusTypeSelect = this.find('.js-type'); + if (statusTypeSelect) { + statusTypeSelect.value = showAllUsers ? 'all' : 'online'; + } + }); }); diff --git a/app/ui-utils/client/lib/RoomManager.js b/app/ui-utils/client/lib/RoomManager.js index de0b51158c60..16ab3968accc 100644 --- a/app/ui-utils/client/lib/RoomManager.js +++ b/app/ui-utils/client/lib/RoomManager.js @@ -15,6 +15,8 @@ import _ from 'underscore'; import { upsertMessage, RoomHistoryManager } from './RoomHistoryManager'; import { mainReady } from './mainReady'; + + const maxRoomsOpen = parseInt(localStorage && localStorage.getItem('rc-maxRoomsOpen')) || 5 ; const onDeleteMessageStream = (msg) => { @@ -235,7 +237,9 @@ export const RoomManager = new function() { const scrollTop = $('> .wrapper', messagesBox).scrollTop() - 50; const totalHeight = $(' > .wrapper > ul', messagesBox).height() + 40; - ticksBar.innerHTML = Array.from(messagesBox.querySelectorAll('.message .body .mention-link--me, .message .body .mention-link--group')) + // TODO: thread quotes should NOT have mention links at all + const mentionsSelector = '.message .body .mention-link--me, .message .body .mention-link--group'; + ticksBar.innerHTML = Array.from(messagesBox.querySelectorAll(mentionsSelector)) .map((mentionLink) => { const topOffset = $(mentionLink).offset().top + scrollTop; const percent = (100 / totalHeight) * topOffset; diff --git a/app/ui/client/views/app/room.js b/app/ui/client/views/app/room.js index d7f2f3f73f5f..4fe56353ff57 100644 --- a/app/ui/client/views/app/room.js +++ b/app/ui/client/views/app/room.js @@ -41,9 +41,14 @@ const favoritesEnabled = () => settings.get('Favorite_Rooms'); const userCanDrop = (_id) => !roomTypes.readOnly(_id, Users.findOne({ _id: Meteor.userId() }, { fields: { username: 1 } })); -const openProfileTab = (e, instance, username) => { - const roomData = Session.get(`roomData${ RoomManager.openedRoom }`); +const openMembersListTab = (instance, group) => { + instance.userDetail.set(null); + instance.groupDetail.set(group); + instance.tabBar.setTemplate('membersList'); + instance.tabBar.open(); +}; +const openProfileTab = (e, instance, username) => { if (Layout.isEmbedded()) { fireGlobalEvent('click-user-card-message', { username }); e.preventDefault(); @@ -51,10 +56,12 @@ const openProfileTab = (e, instance, username) => { return; } + const roomData = Session.get(`roomData${ RoomManager.openedRoom }`); if (roomTypes.roomTypes[roomData.t].enableMembersListProfile()) { - instance.setUserDetail(username); + instance.userDetail.set(username); } + instance.groupDetail.set(null); instance.tabBar.setTemplate('membersList'); instance.tabBar.open(); }; @@ -408,6 +415,7 @@ Template.room.helpers({ data: { rid: this._id, userDetail: Template.instance().userDetail.get(), + groupDetail: Template.instance().groupDetail.get(), clearUserDetail: Template.instance().clearUserDetail, }, }; @@ -746,7 +754,9 @@ Template.room.events({ if (!Meteor.userId()) { return; } - const channel = $(e.currentTarget).data('channel'); + + const { currentTarget: { dataset: { channel, group, username } } } = e; + if (channel) { if (Layout.isEmbedded()) { fireGlobalEvent('click-mention-link', { path: FlowRouter.path('channel', { name: channel }), channel }); @@ -754,9 +764,18 @@ Template.room.events({ FlowRouter.goToRoomById(channel); return; } - const username = $(e.currentTarget).data('username'); - openProfileTabOrOpenDM(e, instance, username); + if (group) { + e.stopPropagation(); + e.preventDefault(); + openMembersListTab(instance, group); + return; + } + + if (username) { + openProfileTabOrOpenDM(e, instance, username); + return; + } }, 'click .image-to-download'(event) { @@ -938,6 +957,7 @@ Template.room.onCreated(function() { this.flexTemplate = new ReactiveVar; this.userDetail = new ReactiveVar(FlowRouter.getParam('username')); + this.groupDetail = new ReactiveVar(); this.tabBar = new RocketChatTabBar(); this.tabBar.showGroup(FlowRouter.current().route.name); diff --git a/private/client/imports/general/variables.css b/private/client/imports/general/variables.css index 0c7ad35acd3a..428f602e4f90 100644 --- a/private/client/imports/general/variables.css +++ b/private/client/imports/general/variables.css @@ -1,4 +1,28 @@ :root { + /* + * Color palette + */ + --color-dark-100: #0c0d0f; + --color-dark-90: #1e232a; + --color-dark-80: #2e343e; + --color-dark-70: #53585f; + --color-dark-30: #9da2a9; + --color-dark-20: #caced1; + --color-dark-10: #e0e5e8; + --color-dark-05: #f1f2f4; + --color-dark-blue: #175cc4; + --color-blue: #1d74f5; + --color-light-blue: #4eb2f5; + --color-lighter-blue: #e8f2ff; + --color-purple: #861da8; + --color-red: #f5455c; + --color-dark-red: #e0364d; + --color-orange: #f59547; + --color-yellow: #ffd21f; + --color-dark-yellow: #f6c502; + --color-green: #2de0a5; + --color-dark-green: #26d198; + /* * General Colors */ @@ -12,15 +36,15 @@ --color-gray-lightest: #f2f3f5; --color-black: #000000; --color-white: #ffffff; - --rc-color-error: #f5455c; + --rc-color-error: var(--color-red); --rc-color-error-light: #e1364c; - --rc-color-alert: #ffd21f; - --rc-color-alert-light: #f6c502; - --rc-color-success: #2de0a5; + --rc-color-alert: var(--color-yellow); + --rc-color-alert-light: var(--color-dark-yellow); + --rc-color-success: var(--color-green); --rc-color-success-light: #25d198; - --rc-color-button-primary: #1d74f5; - --rc-color-button-primary-light: #175cc4; - --rc-color-alert-message-primary: var(--rc-color-button-primary); + --rc-color-button-primary: var(--color-blue); + --rc-color-button-primary-light: var(--color-dark-blue); + --rc-color-alert-message-primary: var(--color-blue); --rc-color-alert-message-primary-background: #f1f6ff; --rc-color-alert-message-secondary: #7ca52b; --rc-color-alert-message-secondary-background: #fafff1; @@ -258,16 +282,16 @@ --badge-background: var(--rc-color-primary-dark); --badge-unread-background: var(--rc-color-primary-dark); --badge-dm-background: var(--rc-color-primary-dark); - --badge-user-mentions-background: var(--rc-color-button-primary); + --badge-user-mentions-background: var(--color-dark-blue); --badge-group-mentions-background: var(--rc-color-primary-dark); /* * Mention link */ --mention-link-radius: 10px; - --mention-link-background: rgba(29, 116, 245, 0.2); - --mention-link-text-color: var(--rc-color-button-primary); - --mention-link-me-background: var(--rc-color-button-primary); + --mention-link-background: var(--color-lighter-blue); + --mention-link-text-color: var(--color-dark-blue); + --mention-link-me-background: var(--color-dark-blue); --mention-link-me-text-color: var(--color-white); --mention-link-group-background: var(--rc-color-primary-dark); --mention-link-group-text-color: var(--color-white); @@ -352,5 +376,4 @@ */ --badge-size: 14px; --badge-font-size: 0.625rem; - }