Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New feature: Room announcement #6351

Merged
merged 9 commits into from
Mar 29, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions packages/rocketchat-analytics/client/trackEvents.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ if (!window._paq || window.ga) {
}
}, RocketChat.callbacks.priority.MEDIUM, 'analytics-room-topic-changed');

RocketChat.callbacks.add('roomAnnouncementChanged', (room) => {
if (RocketChat.settings.get('Analytics_features_rooms')) {
trackEvent('Room', 'Changed Announcement', room.name + ' (' + room._id + ')');
}
}, RocketChat.callbacks.priority.MEDIUM, 'analytics-room-announcement-changed');

RocketChat.callbacks.add('roomTypeChanged', (room) => {
if (RocketChat.settings.get('Analytics_features_rooms')) {
trackEvent('Room', 'Changed Room Type', room.name + ' (' + room._id + ')');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ Meteor.startup ->
room_topic: message.msg
}

RocketChat.MessageTypes.registerType
id: 'room_changed_announcement'
system: true
message: 'room_changed_announcement'
data: (message) ->
return {
user_by: message.u?.username
room_announcement: message.msg
}

RocketChat.MessageTypes.registerType
id: 'room_changed_description'
system: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,17 @@ Template.channelSettings.onCreated ->
toastr.success TAPi18n.__ 'Room_topic_changed_successfully'
RocketChat.callbacks.run 'roomTopicChanged', room

announcement:
type: 'markdown'
label: 'Announcement'
canView: (room) => true
canEdit: (room) => RocketChat.authz.hasAllPermission('edit-room', room._id)
save: (value, room) ->
Meteor.call 'saveRoomSettings', room._id, 'roomAnnouncement', value, (err, result) ->
return handleError err if err
toastr.success TAPi18n.__ 'Room_announcement_changed_successfully'
RocketChat.callbacks.run 'roomAnnouncementChanged', room

description:
type: 'text'
label: 'Description'
Expand Down
1 change: 1 addition & 0 deletions packages/rocketchat-channel-settings/package.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Package.onUse(function(api) {
'server/functions/saveReactWhenReadOnly.js',
'server/functions/saveRoomType.coffee',
'server/functions/saveRoomTopic.coffee',
'server/functions/saveRoomAnnouncement.js',
'server/functions/saveRoomName.coffee',
'server/functions/saveRoomReadOnly.coffee',
'server/functions/saveRoomDescription.coffee',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
RocketChat.saveRoomAnnouncement = function(rid, roomAnnouncement, user, sendMessage=true) {
if (!Match.test(rid, String)) {
throw new Meteor.Error('invalid-room', 'Invalid room', { function: 'RocketChat.saveRoomAnnouncement' });
}

roomAnnouncement = s.escapeHTML(roomAnnouncement);
const updated = RocketChat.models.Rooms.setAnnouncementById(rid, roomAnnouncement);
if (updated && sendMessage) {
RocketChat.models.Messages.createRoomSettingsChangedWithTypeRoomIdMessageAndUser('room_changed_announcement', rid, roomAnnouncement, user);
}

return updated;
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Meteor.methods
unless Match.test rid, String
throw new Meteor.Error 'error-invalid-room', 'Invalid room', { method: 'saveRoomSettings' }

if setting not in ['roomName', 'roomTopic', 'roomDescription', 'roomType', 'readOnly', 'reactWhenReadOnly', 'systemMessages', 'default', 'joinCode']
if setting not in ['roomName', 'roomTopic', 'roomAnnouncement', 'roomDescription', 'roomType', 'readOnly', 'reactWhenReadOnly', 'systemMessages', 'default', 'joinCode']
throw new Meteor.Error 'error-invalid-settings', 'Invalid settings provided', { method: 'saveRoomSettings' }

unless RocketChat.authz.hasPermission(Meteor.userId(), 'edit-room', rid)
Expand All @@ -29,6 +29,9 @@ Meteor.methods
when 'roomTopic'
if value isnt room.topic
RocketChat.saveRoomTopic(rid, value, Meteor.user())
when 'roomAnnouncement'
if value isnt room.announcement
RocketChat.saveRoomAnnouncement(rid, value, Meteor.user())
when 'roomDescription'
if value isnt room.description
RocketChat.saveRoomDescription rid, value, Meteor.user()
Expand Down
3 changes: 3 additions & 0 deletions packages/rocketchat-i18n/i18n/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@
"and": "and",
"And_more": "And __length__ more",
"Animals_and_Nature": "Animals & Nature",
"Announcement": "Announcement",
"API": "API",
"API_Allow_Infinite_Count": "Allow Getting Everything",
"API_Allow_Infinite_Count_Description": "Should calls to the REST API be allowed to return everything in one call?",
Expand Down Expand Up @@ -1224,10 +1225,12 @@
"Role_Editing": "Role Editing",
"Role_removed": "Role removed",
"Room": "Room",
"Room_announcement_changed_successfully": "Room announcement changed successfully",
"Room_archivation_state": "State",
"Room_archivation_state_false": "Active",
"Room_archivation_state_true": "Archived",
"Room_archived": "Room archived",
"room_changed_announcement": "Room announcement changed to: <em>__room_announcement__</em> by <em>__user_by__</em>",
"room_changed_description": "Room description changed to: <em>__room_description__</em> by <em>__user_by__</em>",
"room_changed_privacy": "Room type changed to: <em>__room_type__</em> by <em>__user_by__</em>",
"room_changed_topic": "Room topic changed to: <em>__room_topic__</em> by <em>__user_by__</em>",
Expand Down
3 changes: 3 additions & 0 deletions packages/rocketchat-i18n/i18n/zh.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"and": "和",
"And_more": "以及其它 __length__ 条",
"Animals_and_Nature": "动物与自然",
"Announcement": "公告",
"API": "API",
"API_Analytics": "分析",
"API_Embed": "嵌入",
Expand Down Expand Up @@ -911,10 +912,12 @@
"Role_Editing": "编辑角色",
"Role_removed": "角色已删除",
"Room": "聊天室",
"Room_announcement_changed_successfully": "公告已成功修改",
"Room_archivation_state": "状态",
"Room_archivation_state_false": "活跃",
"Room_archivation_state_true": "已归档",
"Room_archived": "房间已归档",
"room_changed_announcement": "<em>__user_by__</em> 将公告修改为:<em>__room_announcement__</em>",
"room_changed_description": "房间描述由 <em>__user_by__</em> 修改为:<em>__room_description__</em>",
"room_changed_privacy": "<em>__user_by__</em> 将房间类型修改为:<em>__room_type__</em>",
"room_changed_topic": "<em>__user_by__</em> 将房间主题修改为:<em>__room_topic__</em>",
Expand Down
10 changes: 10 additions & 0 deletions packages/rocketchat-lib/server/models/Rooms.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,16 @@ class ModelRooms extends RocketChat.models._Base

return @update query, update

setAnnouncementById: (_id, announcement) ->
query =
_id: _id

update =
$set:
announcement: announcement

return @update query, update

muteUsernameByRoomId: (_id, username) ->
query =
_id: _id
Expand Down
20 changes: 20 additions & 0 deletions packages/rocketchat-theme/client/imports/base.less
Original file line number Diff line number Diff line change
Expand Up @@ -1776,6 +1776,26 @@ label.required::after {
}
}

.announcement {
margin-top: 61px;
height: 40px;
line-height: 40px;
overflow: hidden;
font-size: 1.2em;
background-color: #04436a;
color: white;
text-align: center;
display: block;

~ .container-bars {
top: 95px;
}

~ .messages-box {
margin-top: 100px;
}
}

.cms-page {
max-width: 800px;
margin: 40px auto;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,13 @@ Template.adminRoomInfo.onCreated ->
return handleError(err)
toastr.success TAPi18n.__ 'Room_topic_changed_successfully'
RocketChat.callbacks.run 'roomTopicChanged', AdminChatRoom.findOne(rid)
when 'roomAnnouncement'
if @validateRoomTopic(rid)
Meteor.call 'saveRoomSettings', rid, 'roomAnnouncement', @$('input[name=roomAnnouncement]').val(), (err, result) ->
if err
return handleError(err)
toastr.success TAPi18n.__ 'Room_announcement_changed_successfully'
RocketChat.callbacks.run 'roomAnnouncementChanged', AdminChatRoom.findOne(rid)
when 'roomType'
if @validateRoomType(rid)
RocketChat.callbacks.run 'roomTypeChanged', AdminChatRoom.findOne(rid)
Expand Down
1 change: 1 addition & 0 deletions packages/rocketchat-ui/client/lib/chatMessages.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class @ChatMessages

resize: ->
dif = (if RocketChat.Layout.isEmbedded() then 0 else 60) + $(".messages-container").find("footer").outerHeight()
dif += if $(".announcement").length > 0 then 40 else 0
$(".messages-box").css
height: "calc(100% - #{dif}px)"

Expand Down
13 changes: 13 additions & 0 deletions packages/rocketchat-ui/client/views/app/room.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,19 @@ Template.room.helpers
return '' unless roomData
return roomData.topic

showAnnouncement: ->
roomData = Session.get('roomData' + this._id)
return false unless roomData
Meteor.defer =>
if window.chatMessages and window.chatMessages[roomData._id]
window.chatMessages[roomData._id].resize()
return roomData.announcement isnt undefined and roomData.announcement isnt ''

roomAnnouncement: ->
roomData = Session.get('roomData' + this._id)
return '' unless roomData
return roomData.announcement

roomIcon: ->
roomData = Session.get('roomData' + this._id)
return '' unless roomData?.t
Expand Down
33 changes: 19 additions & 14 deletions packages/rocketchat-ui/client/views/app/room.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,25 @@
<div class="main-content-flex">
<section class="messages-container flex-tab-main-content {{adminClass}}" id="{{windowId}}" aria-label="{{_ "Channel"}}">
{{#unless embeddedVersion}}
<header class="fixed-title content-background-color border-component-color">
{{> burger}}
<h2>
{{#if showToggleFavorite}}
<a href="#favorite" class="toggle-favorite"><i class="{{favorite}}" aria-label="{{_ favoriteLabel}}"></i></a>
{{/if}}
<i class="{{roomIcon}} status-{{userStatus}}"></i>
<span class="room-title">{{roomName}}</span>
{{#if isTranslated}}
<i class="icon-language" aria-label="{{_ "Translated"}}"></i>
{{/if}}
<span class="room-topic">{{{RocketChatMarkdown roomTopic}}}</span>
</h2>
</header>
<header class="fixed-title content-background-color border-component-color">
{{> burger}}
<h2>
{{#if showToggleFavorite}}
<a href="#favorite" class="toggle-favorite"><i class="{{favorite}}" aria-label="{{_ favoriteLabel}}"></i></a>
{{/if}}
<i class="{{roomIcon}} status-{{userStatus}}"></i>
<span class="room-title">{{roomName}}</span>
{{#if isTranslated}}
<i class="icon-language" aria-label="{{_ "Translated"}}"></i>
{{/if}}
<span class="room-topic">{{{RocketChatMarkdown roomTopic}}}</span>
</h2>
</header>
{{#if showAnnouncement}}
<div class="fixed-title announcement">
{{{RocketChatMarkdown roomAnnouncement}}}
</div>
{{/if}}
{{/unless}}
<div class="container-bars {{containerBarsShow unreadData uploading}}">
{{#with unreadData}}
Expand Down
1 change: 1 addition & 0 deletions server/publications/room.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const options = {
u: 1,
// usernames: 1,
topic: 1,
announcement: 1,
muted: 1,
archived: 1,
jitsiTimeout: 1,
Expand Down
2 changes: 2 additions & 0 deletions server/startup/roomPublishes.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Meteor.startup(function() {
u: 1,
usernames: 1,
topic: 1,
announcement: 1,
muted: 1,
archived: 1,
ro: 1,
Expand Down Expand Up @@ -44,6 +45,7 @@ Meteor.startup(function() {
u: 1,
usernames: 1,
topic: 1,
announcement: 1,
muted: 1,
archived: 1,
ro: 1,
Expand Down
34 changes: 33 additions & 1 deletion tests/end-to-end/ui/09-channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,38 @@ describe('channel', ()=> {
});
});

describe('Channel announcement edit', ()=> {
before(()=> {
flexTab.operateFlexTab('info', true);
});

after(()=> {
if (Global.toastAlert.isVisible()) {
Global.dismissToast();
Global.toastAlert.waitForVisible(5000, true);
}
flexTab.operateFlexTab('info', false);
});

it('click the edit announcement', ()=> {
flexTab.editAnnouncementBtn.waitForVisible(5000);
flexTab.editAnnouncementBtn.click();
});

it('edit the announcement input', ()=> {
flexTab.editAnnouncementTextInput.waitForVisible(5000);
flexTab.editAnnouncementTextInput.setValue('ANNOUNCEMENT EDITED');
});

it('save the announcement', ()=> {
flexTab.editNameSave.click();
});

it('should show the new announcement', ()=> {
flexTab.thirdSetting.getText().should.equal('ANNOUNCEMENT EDITED');
});
});

describe('Channel description edit', ()=> {
before(()=> {
flexTab.operateFlexTab('info', true);
Expand Down Expand Up @@ -248,7 +280,7 @@ describe('channel', ()=> {
});

it('should show the new description', ()=> {
flexTab.thirdSetting.getText().should.equal('DESCRIPTION EDITED');
flexTab.fourthSetting.getText().should.equal('DESCRIPTION EDITED');
});
});
});
Expand Down
3 changes: 3 additions & 0 deletions tests/pageobjects/flex-tab.page.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class FlexTab extends Page {
get archiveSave() { return browser.element('.save'); }
get editNameBtn() { return browser.element('[data-edit="name"]'); }
get editTopicBtn() { return browser.element('[data-edit="topic"]'); }
get editAnnouncementBtn() { return browser.element('[data-edit="announcement"]'); }
get editDescriptionBtn() { return browser.element('[data-edit="description"]'); }
get editNotificationBtn() { return browser.element('[data-edit="desktopNotifications"]'); }
get editMobilePushBtn() { return browser.element('[data-edit="mobilePushNotifications"]'); }
Expand All @@ -56,10 +57,12 @@ class FlexTab extends Page {

get editNameTextInput() { return browser.element('.channel-settings input[name="name"]'); }
get editTopicTextInput() { return browser.element('.channel-settings input[name="topic"]'); }
get editAnnouncementTextInput() { return browser.element('.channel-settings input[name="announcement"]'); }
get editDescriptionTextInput() { return browser.element('.channel-settings input[name="description"]'); }
get firstSetting() { return browser.element('.clearfix li:nth-child(1) .current-setting'); }
get secondSetting() { return browser.element('.clearfix li:nth-child(2) .current-setting'); }
get thirdSetting() { return browser.element('.clearfix li:nth-child(3) .current-setting'); }
get fourthSetting() { return browser.element('.clearfix li:nth-child(4) .current-setting'); }
get editNameTextInput() { return browser.element('.channel-settings input[name="name"]'); }
get editNameSave() { return browser.element('.channel-settings .save'); }
get memberUserName() { return browser.element('.info h3'); }
Expand Down