diff --git a/client/lib/chatMessages.coffee b/client/lib/chatMessages.coffee index f72fe0cc28af2c6032a411a267260e8c768f619c..5945871243e82bfc3fca790c7f5f783f970878af 100644 --- a/client/lib/chatMessages.coffee +++ b/client/lib/chatMessages.coffee @@ -98,6 +98,18 @@ class @ChatMessages if error return Errors.throw error.reason + pinMsg: (message) -> + message.pinned = true + Meteor.call 'pinMessage', message, (error, result) -> + if error + return Errors.throw error.reason + + unpinMsg: (message) -> + message.pinned = false + Meteor.call 'unpinMessage', message, (error, result) -> + if error + return Errors.throw error.reason + update: (id, rid, input) -> if _.trim(input.value) isnt '' msg = input.value diff --git a/client/methods/pinMessage.coffee b/client/methods/pinMessage.coffee new file mode 100644 index 0000000000000000000000000000000000000000..a46e6bdde718526144240141037d1b4c65306330 --- /dev/null +++ b/client/methods/pinMessage.coffee @@ -0,0 +1,21 @@ +Meteor.methods + pinMessage: (message) -> + if not Meteor.userId() + throw new Meteor.Error 203, t('User_logged_out') + + if not RocketChat.settings.get 'Message_AllowPinning' + throw new Meteor.Error 'message-pinning-not-allowed', t('Message_pinning_not_allowed') + + Tracker.nonreactive -> + + message.pts = new Date(Date.now() + TimeSync.serverOffset()) + message.pinned = true + message = RocketChat.callbacks.run 'beforeSaveMessage', message + + ChatMessage.update + _id: message.id + 'u._id': Meteor.userId() + , + $set: + pinned: message.pinned + pts: message.pts diff --git a/client/methods/unpinMessage.coffee b/client/methods/unpinMessage.coffee new file mode 100644 index 0000000000000000000000000000000000000000..a60e28960e3b6f36793a57b9fe1213295c469888 --- /dev/null +++ b/client/methods/unpinMessage.coffee @@ -0,0 +1,21 @@ +Meteor.methods + unpinMessage: (message) -> + if not Meteor.userId() + throw new Meteor.Error 203, t('User_logged_out') + + if not RocketChat.settings.get 'Message_AllowPinning' + throw new Meteor.Error 'message-pinning-not-allowed', t('Message_pinning_not_allowed') + + Tracker.nonreactive -> + + message.pts = new Date(Date.now() + TimeSync.serverOffset()) + message.pinned = false + message = RocketChat.callbacks.run 'beforeSaveMessage', message + + ChatMessage.update + _id: message.id + 'u._id': Meteor.userId() + , + $set: + pinned: message.pinned + pts: message.pts diff --git a/client/views/app/message.coffee b/client/views/app/message.coffee index 669387a6ba066be75336559b2a2e60c5653f362d..06b17f5c5169f752b3549b11c15e0f9de069227b 100644 --- a/client/views/app/message.coffee +++ b/client/views/app/message.coffee @@ -1,7 +1,7 @@ Template.message.helpers own: -> - return 'own' if this.u?._id is Meteor.userId() + return 'own' if this.u?._id is Meteor.userId() time: -> return moment(this.ts).format('HH:mm') @@ -37,10 +37,14 @@ Template.message.helpers return 'system' if this.t in ['s', 'p', 'f', 'r', 'au', 'ru', 'ul', 'nu', 'wm', 'uj', 'rm'] edited: -> return @ets and @t not in ['s', 'p', 'f', 'r', 'au', 'ru', 'ul', 'nu', 'wm', 'uj', 'rm'] + pinned: -> + return this.pinned canEdit: -> return RocketChat.settings.get 'Message_AllowEditing' canDelete: -> return RocketChat.settings.get 'Message_AllowDeleting' + canPin: -> + return RocketChat.settings.get 'Message_AllowPinning' showEditedStatus: -> return RocketChat.settings.get 'Message_ShowEditedStatus' diff --git a/client/views/app/message.html b/client/views/app/message.html index a43ed499ac8dab2cbda1bf4d2cb3bd27bc101ac0..9bedaa658f065b69dfec8c5bba626040b12c7381 100644 --- a/client/views/app/message.html +++ b/client/views/app/message.html @@ -7,6 +7,7 @@ {{#if edited}} <span class="edited">({{_ "edited"}})</span> {{/if}} + {{#if canEdit}} <i class="icon-pencil edit-message"></i> {{/if}} diff --git a/client/views/app/room.coffee b/client/views/app/room.coffee index 6b6abc52cb2a9ff331ed4a522ef2ae52c4fd258c..35bfc97dd93821641e60716c5499648701db72b3 100644 --- a/client/views/app/room.coffee +++ b/client/views/app/room.coffee @@ -228,7 +228,7 @@ Template.room.helpers userData = { username: String(username) } - + return userData seeAll: -> @@ -283,14 +283,14 @@ Template.room.helpers utc: -> if @utcOffset? return "UTC #{@utcOffset}" - + phoneNumber: -> return '' unless @phoneNumber if @phoneNumber.length > 10 return "(#{@phoneNumber.substr(0,2)}) #{@phoneNumber.substr(2,5)}-#{@phoneNumber.substr(7)}" else return "(#{@phoneNumber.substr(0,2)}) #{@phoneNumber.substr(2,4)}-#{@phoneNumber.substr(6)}" - + lastLogin: -> if @lastLogin return moment(@lastLogin).format('LLL') @@ -543,14 +543,22 @@ Template.room.events closeOnConfirm: false html: false }, -> - swal + swal title: t('Deleted') text: t('Your_entry_has_been_deleted') type: 'success' timer: 1000 - showConfirmButton: false + showConfirmButton: false instance.chatMessages.deleteMsg(message) + 'click .pin-message': (event) -> + message = @_arguments[1] + instance = Template.instance() + + if message.pinned + instance.chatMessages.unpinMsg(message) + else + instance.chatMessages.pinMsg(message) 'click .start-video': (event) -> _id = Template.instance().data._id @@ -635,7 +643,7 @@ Template.room.events toastr.success t('User_has_been_deactivated') if error toastr.error error.reason - + 'click .activate': -> username = Session.get('showUserInfo') user = Meteor.users.findOne { username: String(username) } diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json index 4457570b00122b06b6b259f38ab252a975a0dba1..a985352dd4d9eebb65657e9ce61d7424c409e3e4 100644 --- a/i18n/en.i18n.json +++ b/i18n/en.i18n.json @@ -131,10 +131,13 @@ "Message" : "Message", "Message_AllowDeleting" : "Allow Message Deleting", "Message_AllowEditing" : "Allow Message Editing", - "Message_deleting_not_allowed": "Message deleting not allowed", - "Message_editing_not_allowed": "Message editing not allowed", + "Message_AllowPinning" : "Allow Message Pinning", + "Message_deleting_not_allowed" : "Message deleting not allowed", + "Message_editing_not_allowed" : "Message editing not allowed", + "Message_pinning_not_allowed" : "Message pinning not allowed", "Message_KeepHistory" : "Keep Message History", "Message_removed" : "Message removed", + "Message_pinned" : "Message pinned", "Message_ShowDeletedStatus" : "Show Deleted Status", "Message_ShowEditedStatus" : "Show Edited Status", "Meta_fb_app_id" : "Facebook APP ID", @@ -293,4 +296,4 @@ "You_will_not_be_able_to_recover" : "You will not be able to recover!", "Your_entry_has_been_deleted" : "Your entry has been deleted.", "Your_Open_Source_solution" : "Your own Open Source chat solution" -} \ No newline at end of file +} diff --git a/packages/rocketchat-lib/settings/server/startup.coffee b/packages/rocketchat-lib/settings/server/startup.coffee index d2cc1de78325dac2733165a5a27aa55c0ff9d5c6..6e8dd9bff39ca8e48aeba943c29bbe4cb7a829d2 100644 --- a/packages/rocketchat-lib/settings/server/startup.coffee +++ b/packages/rocketchat-lib/settings/server/startup.coffee @@ -40,6 +40,7 @@ Meteor.startup -> RocketChat.settings.addGroup 'Message' RocketChat.settings.add 'Message_AllowEditing', true, { type: 'boolean', group: 'Message', public: true } RocketChat.settings.add 'Message_AllowDeleting', true, { type: 'boolean', group: 'Message', public: true } + RocketChat.settings.add 'Message_AllowPinning', true, { type: 'boolean', group: 'Message', public: true } RocketChat.settings.add 'Message_ShowEditedStatus', true, { type: 'boolean', group: 'Message', public: true } RocketChat.settings.add 'Message_ShowDeletedStatus', false, { type: 'boolean', group: 'Message', public: true } RocketChat.settings.add 'Message_KeepHistory', false, { type: 'boolean', group: 'Message', public: true } diff --git a/server/methods/pinMessage.coffee b/server/methods/pinMessage.coffee new file mode 100644 index 0000000000000000000000000000000000000000..e4076e1149e33a8bc73e5d2a4d76043b031c6aa8 --- /dev/null +++ b/server/methods/pinMessage.coffee @@ -0,0 +1,35 @@ +Meteor.methods + pinMessage: (message) -> + if not Meteor.userId() + throw new Meteor.Error('invalid-user', "[methods] pinMessage -> Invalid user") + + if not RocketChat.settings.get 'Message_AllowPinning' + throw new Meteor.Error 'message-pinning-not-allowed', "[methods] pinMessage -> Message pinning not allowed" + + console.log '[methods] pinMessage -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments + + # If we keep history of edits, insert a new message to store history information + if RocketChat.settings.get 'Message_KeepHistory' + history = ChatMessage.findOne message._id + history._hidden = true + history.parent = history._id + history.pts = new Date() + delete history._id + ChatMessage.insert history + + message.pts = new Date() + message.pinned = true + + message = RocketChat.callbacks.run 'beforeSaveMessage', message + + ChatMessage.update + _id: message._id + 'u._id': Meteor.userId() + , + $set: + pinned: message.pinned + pts : message.pts + + + # Meteor.defer -> + # RocketChat.callbacks.run 'afterSaveMessage', ChatMessage.findOne(message.id) diff --git a/server/methods/unpinMessage.coffee b/server/methods/unpinMessage.coffee new file mode 100644 index 0000000000000000000000000000000000000000..4bce5a9bcd7a0cc702e6113e0c933977fd62ff50 --- /dev/null +++ b/server/methods/unpinMessage.coffee @@ -0,0 +1,35 @@ +Meteor.methods + unpinMessage: (message) -> + if not Meteor.userId() + throw new Meteor.Error('invalid-user', "[methods] unpinMessage -> Invalid user") + + if not RocketChat.settings.get 'Message_AllowPinning' + throw new Meteor.Error 'message-pinning-not-allowed', "[methods] unpinMessage -> Message pinning not allowed" + + console.log '[methods] unpinMessage -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments + + # If we keep history of edits, insert a new message to store history information + if RocketChat.settings.get 'Message_KeepHistory' + history = ChatMessage.findOne message._id + history._hidden = true + history.parent = history._id + history.pts = new Date() + delete history._id + ChatMessage.insert history + + message.pts = new Date() + message.pinned = false + + message = RocketChat.callbacks.run 'beforeSaveMessage', message + + ChatMessage.update + _id: message._id + 'u._id': Meteor.userId() + , + $set: + pinned: message.pinned + pts : message.pts + + + # Meteor.defer -> + # RocketChat.callbacks.run 'afterSaveMessage', ChatMessage.findOne(message.id)