From cb673aeafc8f6d683d780ebbd897c4b94cc738b1 Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Thu, 1 Mar 2018 00:48:33 -0300 Subject: [PATCH 1/7] [NEW] Broadcast Channels --- .../client/views/channelSettings.html | 23 +++++++++++++++- .../client/views/channelSettings.js | 26 ++++++++++++++++--- .../server/methods/saveRoomSettings.js | 9 ++++++- packages/rocketchat-i18n/i18n/en.i18n.json | 3 +++ .../rocketchat-lib/client/defaultTabBars.js | 21 ++++++++++++++- .../server/functions/createRoom.js | 5 ++++ .../client/imports/components/header.css | 1 + .../client/imports/forms/button.css | 9 +++++++ .../client/imports/forms/input.css | 3 +++ .../client/imports/forms/popup-list.css | 2 ++ .../client/imports/forms/switch.css | 22 ++++++++-------- .../rocketchat-ui-master/public/icons.svg | 2 ++ .../rocketchat-ui-message/client/message.html | 5 ++++ .../rocketchat-ui-message/client/message.js | 16 ++++++++++-- .../client/messageBox.js | 3 +-- .../client/components/popupList.html | 9 +++++++ .../rocketchat-ui/client/lib/chatMessages.js | 5 +++- .../client/views/app/createChannel.html | 16 +++++++++++- .../client/views/app/createChannel.js | 26 ++++++++++++++++--- .../rocketchat-ui/client/views/app/room.html | 4 +-- .../rocketchat-ui/client/views/app/room.js | 4 +++ .../client/views/app/roomSearch.html | 2 +- server/publications/room.js | 3 ++- 23 files changed, 187 insertions(+), 32 deletions(-) diff --git a/packages/rocketchat-channel-settings/client/views/channelSettings.html b/packages/rocketchat-channel-settings/client/views/channelSettings.html index 735b947029ec..c26a5e04851f 100644 --- a/packages/rocketchat-channel-settings/client/views/channelSettings.html +++ b/packages/rocketchat-channel-settings/client/views/channelSettings.html @@ -163,6 +163,23 @@ {{/if}} {{/with}} + {{#with settings.broadcast}} + {{#if canView}} +
+
+ +
+
+ {{/if}} + {{/with}} {{#with settings.joinCode}}
@@ -228,7 +245,11 @@
- + {{#if broadcast}} + + {{/if}} {{/with}} {{#each channelSettings}}
{{readOnlyDescription}}
+
+ + + {{_"Broadcast_channel_Description"}} + +
diff --git a/packages/rocketchat-ui/client/views/app/createChannel.js b/packages/rocketchat-ui/client/views/app/createChannel.js index 45930c9f862e..411066ee15fd 100644 --- a/packages/rocketchat-ui/client/views/app/createChannel.js +++ b/packages/rocketchat-ui/client/views/app/createChannel.js @@ -83,6 +83,12 @@ Template.createChannel.helpers({ typeDescription() { return t(Template.instance().type.get() === 'p' ? t('Just_invited_people_can_access_this_channel') : t('Everyone_can_access_this_channel')); }, + broadcast() { + return Template.instance().broadcast.get(); + }, + readOnly() { + return Template.instance().readOnly.get(); + }, readOnlyDescription() { return t(Template.instance().readOnly.get() ? t('Only_authorized_users_can_write_new_messages') : t('All_users_in_the_channel_can_write_new_messages')); }, @@ -113,8 +119,8 @@ Template.createChannel.helpers({ extensionsConfig() { const instance = Template.instance(); return { - validations : Template.instance().extensions_validations, - submits: Template.instance().extensions_submits, + validations : instance.extensions_validations, + submits: instance.extensions_submits, change: instance.change }; }, @@ -158,6 +164,10 @@ Template.createChannel.events({ t.type.set(e.target.checked ? e.target.value : 'd'); t.change(); }, + 'change [name="broadcast"]'(e, t) { + t.broadcast.set(e.target.checked); + t.change(); + }, 'change [name="readOnly"]'(e, t) { t.readOnly.set(e.target.checked); }, @@ -192,6 +202,7 @@ Template.createChannel.events({ const name = e.target.name.value; const type = instance.type.get(); const readOnly = instance.readOnly.get(); + const broadcast = instance.broadcast.get(); const isPrivate = type === 'p'; if (instance.invalid.get() || instance.inUse.get()) { @@ -204,7 +215,7 @@ Template.createChannel.events({ const extraData = Object.keys(instance.extensions_submits) .reduce((result, key) => { return { ...result, ...instance.extensions_submits[key](instance) }; - }, {}); + }, {broadcast}); Meteor.call(isPrivate ? 'createPrivateGroup' : 'createChannel', name, instance.selectedUsers.get().map(user => user.username), readOnly, {}, extraData, function(err, result) { if (err) { @@ -253,6 +264,7 @@ Template.createChannel.onCreated(function() { this.name = new ReactiveVar(''); this.type = new ReactiveVar('p'); this.readOnly = new ReactiveVar(false); + this.broadcast = new ReactiveVar(false); this.inUse = new ReactiveVar(undefined); this.invalid = new ReactiveVar(false); this.extensions_invalid = new ReactiveVar(false); @@ -261,6 +273,14 @@ Template.createChannel.onCreated(function() { Object.keys(this.extensions_validations).map(key => this.extensions_validations[key]).forEach(f => (valid = f(this) && valid)); this.extensions_invalid.set(!valid); }, 300); + + Deps.autorun(() => { + const broadcast = this.broadcast.get(); + if (broadcast) { + this.readOnly.set(true); + } + }); + this.userFilter = new ReactiveVar(''); this.tokensRequired = new ReactiveVar(false); this.checkChannel = _.debounce((name) => { diff --git a/packages/rocketchat-ui/client/views/app/room.html b/packages/rocketchat-ui/client/views/app/room.html index 7efff1838b00..1dd0d5a1ba36 100644 --- a/packages/rocketchat-ui/client/views/app/room.html +++ b/packages/rocketchat-ui/client/views/app/room.html @@ -112,9 +112,7 @@ {{/if}} {{/if}} - {{#each messagesHistory}} - {{#nrr nrrargs 'message' .}}{{/nrr}} - {{/each}} + {{#each messagesHistory}}{{#nrr nrrargs 'message' .}}{{/nrr}}{{/each}} {{#if hasMoreNext}}
  • {{#if isLoading}} diff --git a/packages/rocketchat-ui/client/views/app/room.js b/packages/rocketchat-ui/client/views/app/room.js index 7364d45f9aa0..540d1e9566ae 100644 --- a/packages/rocketchat-ui/client/views/app/room.js +++ b/packages/rocketchat-ui/client/views/app/room.js @@ -378,6 +378,10 @@ let lastTouchY = null; let lastScrollTop; Template.room.events({ + 'click .js-reply-broadcast'(e, i) { + const message = this._arguments[1]; + RocketChat.roomTypes.openRouteLink('d', {name: this._arguments[1].u.username}, {...FlowRouter.current().queryParams, reply: message._id}); + }, 'click, touchend'(e, t) { Meteor.setTimeout(() => t.sendToBottomIfNecessaryDebounced(), 100); }, diff --git a/packages/rocketchat-ui/client/views/app/roomSearch.html b/packages/rocketchat-ui/client/views/app/roomSearch.html index fe3610237e24..e6cf00da96c1 100644 --- a/packages/rocketchat-ui/client/views/app/roomSearch.html +++ b/packages/rocketchat-ui/client/views/app/roomSearch.html @@ -2,5 +2,5 @@ {{name}} diff --git a/server/publications/room.js b/server/publications/room.js index 9dfe5637f707..90216804a50a 100644 --- a/server/publications/room.js +++ b/server/publications/room.js @@ -33,7 +33,8 @@ const fields = { reactWhenReadOnly: 1, sentiment: 1, tokenpass: 1, - streamingOptions: 1 + streamingOptions: 1, + broadcast: 1 }; const roomMap = (record) => { From 70bb3f0bf817a3f0fedddb0d181f36031c3ed906 Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Thu, 1 Mar 2018 01:07:37 -0300 Subject: [PATCH 2/7] code guidelines --- .../client/views/channelSettings.js | 6 +++--- packages/rocketchat-lib/lib/RoomTypeConfig.js | 3 ++- packages/rocketchat-lib/lib/roomTypes/private.js | 6 ++++-- packages/rocketchat-lib/lib/roomTypes/public.js | 11 +++++++++++ packages/rocketchat-ui/client/views/app/room.js | 2 +- 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/packages/rocketchat-channel-settings/client/views/channelSettings.js b/packages/rocketchat-channel-settings/client/views/channelSettings.js index ca926c5d0539..5aed0f5594b4 100644 --- a/packages/rocketchat-channel-settings/client/views/channelSettings.js +++ b/packages/rocketchat-channel-settings/client/views/channelSettings.js @@ -219,7 +219,7 @@ Template.channelSettingsEditing.onCreated(function() { isToggle: true, processing: new ReactiveVar(false), canView() { - return !room.broadcast && ocketChat.roomTypes.roomTypes[room.t].allowRoomSettingChange(room, RoomSettingsEnum.READ_ONLY); + return RocketChat.roomTypes.roomTypes[room.t].allowRoomSettingChange(room, RoomSettingsEnum.READ_ONLY); }, canEdit() { return !room.broadcast && RocketChat.authz.hasAllPermission('set-readonly', room._id); @@ -234,7 +234,7 @@ Template.channelSettingsEditing.onCreated(function() { isToggle: true, processing: new ReactiveVar(false), canView() { - return RocketChat.roomTypes.roomTypes[room.t].allowRoomSettingChange(room, RoomSettingsEnum.REACT_WHEN_READ_ONLY) && room.ro && !room.broadcast; + return RocketChat.roomTypes.roomTypes[room.t].allowRoomSettingChange(room, RoomSettingsEnum.REACT_WHEN_READ_ONLY); }, canEdit() { return !room.broadcast && RocketChat.authz.hasAllPermission('set-react-when-readonly', room._id); @@ -297,7 +297,7 @@ Template.channelSettingsEditing.onCreated(function() { canEdit() { return false; }, - save(value) { + save() { return Promise.resolve(); } }, diff --git a/packages/rocketchat-lib/lib/RoomTypeConfig.js b/packages/rocketchat-lib/lib/RoomTypeConfig.js index 43027c05dada..20bb932467b4 100644 --- a/packages/rocketchat-lib/lib/RoomTypeConfig.js +++ b/packages/rocketchat-lib/lib/RoomTypeConfig.js @@ -6,7 +6,8 @@ export const RoomSettingsEnum = { READ_ONLY: 'readOnly', REACT_WHEN_READ_ONLY: 'reactWhenReadOnly', ARCHIVE_OR_UNARCHIVE: 'archiveOrUnarchive', - JOIN_CODE: 'joinCode' + JOIN_CODE: 'joinCode', + BROADCAST: 'broadcast' }; export const UiTextContext = { diff --git a/packages/rocketchat-lib/lib/roomTypes/private.js b/packages/rocketchat-lib/lib/roomTypes/private.js index 5522d95a8110..e45d81e2ca6f 100644 --- a/packages/rocketchat-lib/lib/roomTypes/private.js +++ b/packages/rocketchat-lib/lib/roomTypes/private.js @@ -58,8 +58,10 @@ export class PrivateRoomType extends RoomTypeConfig { allowRoomSettingChange(room, setting) { switch (setting) { - case RoomSettingsEnum.JOIN_CODE: - return false; + case RoomSettingsEnum.READ_ONLY: + return !room.broadcast; + case RoomSettingsEnum.REACT_WHEN_READ_ONLY: + return !room.broadcast && room.ro; default: return true; } diff --git a/packages/rocketchat-lib/lib/roomTypes/public.js b/packages/rocketchat-lib/lib/roomTypes/public.js index fb9c9e277ad3..daaeaa4ac5c1 100644 --- a/packages/rocketchat-lib/lib/roomTypes/public.js +++ b/packages/rocketchat-lib/lib/roomTypes/public.js @@ -71,6 +71,17 @@ export class PublicRoomType extends RoomTypeConfig { return true; } + allowRoomSettingChange(room, setting) { + switch (setting) { + case RoomSettingsEnum.READ_ONLY: + return !room.broadcast; + case RoomSettingsEnum.REACT_WHEN_READ_ONLY: + return !room.broadcast && room.ro; + default: + return true; + } + } + getUiText(context) { switch (context) { case UiTextContext.HIDE_WARNING: diff --git a/packages/rocketchat-ui/client/views/app/room.js b/packages/rocketchat-ui/client/views/app/room.js index 540d1e9566ae..5c85bc77f21e 100644 --- a/packages/rocketchat-ui/client/views/app/room.js +++ b/packages/rocketchat-ui/client/views/app/room.js @@ -378,7 +378,7 @@ let lastTouchY = null; let lastScrollTop; Template.room.events({ - 'click .js-reply-broadcast'(e, i) { + 'click .js-reply-broadcast'() { const message = this._arguments[1]; RocketChat.roomTypes.openRouteLink('d', {name: this._arguments[1].u.username}, {...FlowRouter.current().queryParams, reply: message._id}); }, From 7580754ff342a8e6891134a22a041dcb16d664ff Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Thu, 1 Mar 2018 17:01:01 -0300 Subject: [PATCH 3/7] fix createroom type p extradata --- .../client/views/channelSettings.js | 2 +- packages/rocketchat-lib/lib/roomTypes/private.js | 2 ++ packages/rocketchat-lib/lib/roomTypes/public.js | 8 +++----- packages/rocketchat-lib/server/methods/createChannel.js | 5 ++--- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/rocketchat-channel-settings/client/views/channelSettings.js b/packages/rocketchat-channel-settings/client/views/channelSettings.js index 5aed0f5594b4..e4784d99a4fe 100644 --- a/packages/rocketchat-channel-settings/client/views/channelSettings.js +++ b/packages/rocketchat-channel-settings/client/views/channelSettings.js @@ -292,7 +292,7 @@ Template.channelSettingsEditing.onCreated(function() { isToggle: true, processing: new ReactiveVar(false), canView() { - return room.broadcast; + return RocketChat.roomTypes.roomTypes[room.t].allowRoomSettingChange(room, RoomSettingsEnum.BROADCAST); }, canEdit() { return false; diff --git a/packages/rocketchat-lib/lib/roomTypes/private.js b/packages/rocketchat-lib/lib/roomTypes/private.js index e45d81e2ca6f..af2e5f91ce80 100644 --- a/packages/rocketchat-lib/lib/roomTypes/private.js +++ b/packages/rocketchat-lib/lib/roomTypes/private.js @@ -58,6 +58,8 @@ export class PrivateRoomType extends RoomTypeConfig { allowRoomSettingChange(room, setting) { switch (setting) { + case RoomSettingsEnum.BROADCAST: + return room.broadcast; case RoomSettingsEnum.READ_ONLY: return !room.broadcast; case RoomSettingsEnum.REACT_WHEN_READ_ONLY: diff --git a/packages/rocketchat-lib/lib/roomTypes/public.js b/packages/rocketchat-lib/lib/roomTypes/public.js index daaeaa4ac5c1..8569b4a7c508 100644 --- a/packages/rocketchat-lib/lib/roomTypes/public.js +++ b/packages/rocketchat-lib/lib/roomTypes/public.js @@ -1,5 +1,5 @@ /* globals openRoom */ -import {RoomTypeConfig, RoomTypeRouteConfig, UiTextContext} from '../RoomTypeConfig'; +import { RoomTypeConfig, RoomTypeRouteConfig, RoomSettingsEnum, UiTextContext } from '../RoomTypeConfig'; export class PublicRoomRoute extends RoomTypeRouteConfig { constructor() { @@ -63,16 +63,14 @@ export class PublicRoomType extends RoomTypeConfig { return RocketChat.authz.hasAtLeastOnePermission(['add-user-to-any-c-room', 'add-user-to-joined-room'], room._id); } - allowRoomSettingChange() { - return true; - } - enableMembersListProfile() { return true; } allowRoomSettingChange(room, setting) { switch (setting) { + case RoomSettingsEnum.BROADCAST: + return room.broadcast; case RoomSettingsEnum.READ_ONLY: return !room.broadcast; case RoomSettingsEnum.REACT_WHEN_READ_ONLY: diff --git a/packages/rocketchat-lib/server/methods/createChannel.js b/packages/rocketchat-lib/server/methods/createChannel.js index 1515ecd3f228..e40b06d4f727 100644 --- a/packages/rocketchat-lib/server/methods/createChannel.js +++ b/packages/rocketchat-lib/server/methods/createChannel.js @@ -1,5 +1,5 @@ Meteor.methods({ - createChannel(name, members, readOnly = false, customFields = {}) { + createChannel(name, members, readOnly = false, customFields = {}, extraData = {}) { check(name, String); check(members, Match.Optional([String])); @@ -10,7 +10,6 @@ Meteor.methods({ if (!RocketChat.authz.hasPermission(Meteor.userId(), 'create-c')) { throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'createChannel' }); } - - return RocketChat.createRoom('c', name, Meteor.user() && Meteor.user().username, members, readOnly, {customFields}); + return RocketChat.createRoom('c', name, Meteor.user() && Meteor.user().username, members, readOnly, {customFields, ...extraData}); } }); From 872780deb72cc3d9e38015e0c65e28fa50ad5e01 Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Thu, 1 Mar 2018 17:10:02 -0300 Subject: [PATCH 4/7] fix private room can change join_code --- packages/rocketchat-lib/lib/roomTypes/private.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/rocketchat-lib/lib/roomTypes/private.js b/packages/rocketchat-lib/lib/roomTypes/private.js index af2e5f91ce80..e887fa392102 100644 --- a/packages/rocketchat-lib/lib/roomTypes/private.js +++ b/packages/rocketchat-lib/lib/roomTypes/private.js @@ -58,6 +58,8 @@ export class PrivateRoomType extends RoomTypeConfig { allowRoomSettingChange(room, setting) { switch (setting) { + case RoomSettingsEnum.JOIN_CODE: + return false; case RoomSettingsEnum.BROADCAST: return room.broadcast; case RoomSettingsEnum.READ_ONLY: From 67201e36c30158d27c7c6fc67d7d1c17f025e76b Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Thu, 1 Mar 2018 17:18:08 -0300 Subject: [PATCH 5/7] test to show member list --- packages/rocketchat-lib/client/defaultTabBars.js | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/packages/rocketchat-lib/client/defaultTabBars.js b/packages/rocketchat-lib/client/defaultTabBars.js index 973d0f95d690..ac6ac732032e 100644 --- a/packages/rocketchat-lib/client/defaultTabBars.js +++ b/packages/rocketchat-lib/client/defaultTabBars.js @@ -32,15 +32,8 @@ RocketChat.TabBar.addButton({ if (!room || !room.broadcast) { return true; } - const subscription = RocketChat.models.Subscriptions.findOne({ - rid - }, { - fields: { - roles: 1 - } - }); - const user = Meteor.user(); - return [...user.roles, ...(subscription.roles||[])].some(role => ['admin', 'moderator', 'owner'].includes(role)); + + return RocketChat.authz.hasRole(Meteor.userId(), ['admin', 'moderator', 'owner'], rid); } }); From 0c52c4baa988963274d19ba7da4cd7dc1cfba337 Mon Sep 17 00:00:00 2001 From: Diego Sampaio Date: Fri, 20 Apr 2018 18:52:34 -0300 Subject: [PATCH 6/7] Code cleanup --- packages/rocketchat-lib/server/functions/createRoom.js | 2 +- .../rocketchat-theme/client/imports/components/header.css | 4 ++-- packages/rocketchat-ui/client/views/app/createChannel.js | 6 +++--- packages/rocketchat-ui/client/views/app/roomSearch.html | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/rocketchat-lib/server/functions/createRoom.js b/packages/rocketchat-lib/server/functions/createRoom.js index 65ea6e5972e9..3c969410c930 100644 --- a/packages/rocketchat-lib/server/functions/createRoom.js +++ b/packages/rocketchat-lib/server/functions/createRoom.js @@ -19,7 +19,7 @@ RocketChat.createRoom = function(type, name, owner, members, readOnly, extraData if (!_.contains(members, owner.username)) { members.push(owner.username); } - + if (extraData.broadcast) { readOnly = true; delete extraData.reactWhenReadOnly; diff --git a/packages/rocketchat-theme/client/imports/components/header.css b/packages/rocketchat-theme/client/imports/components/header.css index 813a884d0bf3..b05a45e848cd 100644 --- a/packages/rocketchat-theme/client/imports/components/header.css +++ b/packages/rocketchat-theme/client/imports/components/header.css @@ -10,8 +10,8 @@ margin: 0 -0.5rem; - display: flex; - flex: 0 0 auto; + display: flex; + flex: 0 0 auto; padding: var(--header-padding); diff --git a/packages/rocketchat-ui/client/views/app/createChannel.js b/packages/rocketchat-ui/client/views/app/createChannel.js index 74f9fb585a0b..79561556292b 100644 --- a/packages/rocketchat-ui/client/views/app/createChannel.js +++ b/packages/rocketchat-ui/client/views/app/createChannel.js @@ -246,13 +246,13 @@ Template.createChannel.onRendered(function() { users.set(usersArr); }); }); -/* global AutoComplete Deps */ +/* global AutoComplete */ Template.createChannel.onCreated(function() { this.selectedUsers = new ReactiveVar([]); const filter = {exceptions :[Meteor.user().username].concat(this.selectedUsers.get().map(u => u.username))}; // this.onViewRead:??y(function() { - Deps.autorun(() => { + Tracker.autorun(() => { filter.exceptions = [Meteor.user().username].concat(this.selectedUsers.get().map(u => u.username)); }); this.extensions_validations = {}; @@ -270,7 +270,7 @@ Template.createChannel.onCreated(function() { this.extensions_invalid.set(!valid); }, 300); - Deps.autorun(() => { + Tracker.autorun(() => { const broadcast = this.broadcast.get(); if (broadcast) { this.readOnly.set(true); diff --git a/packages/rocketchat-ui/client/views/app/roomSearch.html b/packages/rocketchat-ui/client/views/app/roomSearch.html index e6cf00da96c1..f8ac8eb37893 100644 --- a/packages/rocketchat-ui/client/views/app/roomSearch.html +++ b/packages/rocketchat-ui/client/views/app/roomSearch.html @@ -2,5 +2,5 @@ {{name}} From 061ac359e9b67250fa45b3faeaefe393bbe744d6 Mon Sep 17 00:00:00 2001 From: Rodrigo Nascimento Date: Fri, 20 Apr 2018 21:21:41 -0300 Subject: [PATCH 7/7] Update message.js --- packages/rocketchat-ui-message/client/message.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rocketchat-ui-message/client/message.js b/packages/rocketchat-ui-message/client/message.js index 5891692b4481..86c1382da62f 100644 --- a/packages/rocketchat-ui-message/client/message.js +++ b/packages/rocketchat-ui-message/client/message.js @@ -9,7 +9,7 @@ Template.message.helpers({ broadcast() { const instance = Template.instance(); return this.u._id !== Meteor.userId() && instance.room && instance.room.broadcast; - }, + }, isIgnored() { return this.ignored; },