Skip to content
Snippets Groups Projects
Commit 4f266f68 authored by Aaron Ogle's avatar Aaron Ogle
Browse files

Merge pull request #1382 from graywolf336/change-pin-messages-method

Add Pinning Functionality
parents 152aabd0 79281ae4
No related branches found
No related tags found
No related merge requests found
Showing
with 273 additions and 28 deletions
......@@ -52,6 +52,7 @@ rocketchat:mailer
rocketchat:markdown
rocketchat:me
rocketchat:mentions
rocketchat:message-pin
rocketchat:message-star
rocketchat:oembed
rocketchat:slashcommands-invite
......
......@@ -138,6 +138,7 @@ rocketchat:mailer@0.0.1
rocketchat:markdown@0.0.1
rocketchat:me@0.0.1
rocketchat:mentions@0.0.1
rocketchat:message-pin@0.0.1
rocketchat:message-star@0.0.1
rocketchat:oembed@0.0.1
rocketchat:slashcommands-invite@0.0.1
......
......@@ -93,6 +93,14 @@ RocketChat.models.Messages = new class extends RocketChat.models._Base
return @find query, options
findPinnedByRoom: (roomId, options) ->
query =
_hidden: { $ne: true }
pinned: true
rid: roomId
return @find query, options
cloneAndSaveAsHistoryById: (_id) ->
me = RocketChat.models.Users.findOneById Meteor.userId()
record = @findOneById _id
......@@ -102,6 +110,11 @@ RocketChat.models.Messages = new class extends RocketChat.models._Base
record.editedBy =
_id: Meteor.userId()
username: me.username
message.pinned = record.pinned
message.pinnedAt = record.pinnedAt
message.pinnedBy =
_id: record.pinnedBy?._id
username: record.pinnedBy?.username
delete record._id
return @insert record
......@@ -134,15 +147,15 @@ RocketChat.models.Messages = new class extends RocketChat.models._Base
return @update query, update
setPinnedByIdAndUserId: (_id, userId, pinned=true) ->
setPinnedByIdAndUserId: (_id, pinnedBy, pinned=true) ->
query =
_id: _id
'u._id': userId
update =
$set:
pinned: pinned
pts: new Date
pinnedAt: new Date
pinnedBy: pinnedBy
return @update query, update
......
Meteor.startup ->
RocketChat.MessageAction.addButton
id: 'pin-message'
icon: 'icon-pin'
i18nLabel: 'Pin_Message'
action: (event, instance) ->
message = @_arguments[1]
message.pinned = true
Meteor.call 'pinMessage', message, (error, result) ->
if error
return Errors.throw error.reason
validation: (message) ->
if message.pinned or not RocketChat.settings.get('Message_AllowPinning')
return false
if RocketChat.settings.get('Message_AllowPinningByAnyone') or RocketChat.authz.hasRole Meteor.userId(), 'admin'
return true
return room.u?._id is Meteor.userId()
order: 20
RocketChat.MessageAction.addButton
id: 'unpin-message'
icon: 'icon-pin'
i18nLabel: 'Unpin_Message'
action: (event, instance) ->
message = @_arguments[1]
message.pinned = false
Meteor.call 'unpinMessage', message, (error, result) ->
if error
return Errors.throw error.reason
validation: (message) ->
if not message.pinned or not RocketChat.settings.get('Message_AllowPinning')
return false
if RocketChat.settings.get('Message_AllowPinningByAnyone') or RocketChat.authz.hasRole Meteor.userId(), 'admin'
return true
return room.u?._id is Meteor.userId()
order: 21
@PinnedMessage = new Meteor.Collection 'rocketchat_pinned_message'
Meteor.startup ->
RocketChat.callbacks.add 'enter-room', ->
if RocketChat.settings.get 'Message_AllowPinning'
RocketChat.TabBar.addButton({ id: 'pinned-messages', i18nTitle: 'Pinned_Messages', icon: 'icon-pin', template: 'pinnedMessages', order: 10 })
, RocketChat.callbacks.priority.MEDIUM, 'enter-room-tabbar-pin'
Template.pinnedMessages.helpers
hasMessages: ->
return PinnedMessage.find({ rid: this.rid }, { sort: { ts: -1 } }).count() > 0
messages: ->
return PinnedMessage.find { rid: this.rid }, { sort: { ts: -1 } }
notReadySubscription: ->
return 'notready' unless Template.instance().subscriptionsReady()
Template.pinnedMessages.onCreated ->
this.autorun =>
this.subscribe 'pinnedMessages', Template.currentData().rid
Template.pinnedMessages.events
'click .message-cog': (e) ->
e.stopPropagation()
e.preventDefault()
message_id = $(e.currentTarget).closest('.message').attr('id')
$('.message-dropdown:visible').hide()
$(".pinned-messages-list \##{message_id} .message-dropdown").show()
<template name="pinnedMessages">
<div class="control">
<div class="header">
<h2>{{_ "Pinned_Messages"}}</h2>
</div>
</div>
<ul class="pinned-messages-list scrollable">
{{#if Template.subscriptionsReady}}
{{#if hasMessages}}
{{#each messages}}
{{#nrr nrrargs 'message' .}}{{/nrr}}
{{/each}}
{{else}}
<li class="empty">
{{_ "No_pinned_messages"}}
</li>
{{/if}}
{{else}}
{{> loading}}
{{/if}}
</ul>
</template>
.pinned-messages-list {
padding: 30px 0;
&.notready {
background-image: url(/images/logo/loading.gif);
background-repeat: no-repeat;
background-position: 50% 50%;
height: 100px;
.message {
display: none;
}
}
li.empty {
color: #7f7f7f;
text-align: center;
margin-top: 60px;
}
.message-cog-container {
.edit-message, .delete-message, .star-message, .unstar-message {
display: none !important;
}
}
}
{
"Message_AllowPinning" : "Allow Message Pinning",
"Message_AllowPinning_Description": "Allow messages to be pinned to any of the channels.",
"Message_AllowPinningByAnyone": "Allow Anyone to Pin Messages",
"Message_AllowPinningByAnyone_Description": "If true, anyone will be able to pin a messages in any channels but if false then only channel owners and admins will be allowed to.",
"Pin_Message" : "Pin Message",
"Unpin_Message" : "Unpin Message",
"Pinned_Messages" : "Pinned Messages",
"No_pinned_messages" : "No pinned messages"
}
Package.describe({
name: 'rocketchat:message-pin',
version: '0.0.1',
summary: 'Pin Messages'
});
Package.onUse(function(api) {
api.versionsFrom('1.0');
api.use([
'coffeescript',
'less@2.5.0',
'rocketchat:lib@0.0.1'
]);
api.addFiles([
'client/lib/PinnedMessage.coffee',
'client/actionButton.coffee',
'client/tabBar.coffee',
'client/views/pinnedMessages.html',
'client/views/pinnedMessages.coffee',
'client/views/stylesheets/messagepin.less',
], 'client');
api.addFiles([
'server/settings.coffee',
'server/pinMessage.coffee',
'server/publications/pinnedMessages.coffee',
'server/startup/indexes.coffee'
], 'server');
// TAPi18n
api.use('templating', 'client');
var _ = Npm.require('underscore');
var fs = Npm.require('fs');
tapi18nFiles = _.compact(_.map(fs.readdirSync('packages/rocketchat-message-pin/i18n'), function(filename) {
if (fs.statSync('packages/rocketchat-message-pin/i18n/' + filename).size > 16) {
return 'i18n/' + filename;
}
}));
api.use(["tap:i18n@1.5.1"], ["client", "server"]);
api.imply('tap:i18n');
api.addFiles(tapi18nFiles, ["client", "server"]);
});
Package.onTest(function(api) {
});
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()
# If we keep history of edits, insert a new message to store history information
if RocketChat.settings.get 'Message_KeepHistory'
RocketChat.models.Messages.cloneAndSaveAsHistoryById message._id
me = RocketChat.models.Users.findOneById Meteor.userId()
message.pinned = true
message.pinnedAt = Date.now
message.pinnedBy =
_id: Meteor.userId()
username: me.username
message = RocketChat.callbacks.run 'beforeSaveMessage', message
RocketChat.models.Messages.setPinnedByIdAndUserId message._id, message.pinnedBy, message.pinned
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"
throw new Meteor.Error 'message-pinning-not-allowed', '[methods] pinMessage -> Message pinning not allowed'
console.log '[methods] unpinMessage -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments
console.log '[methods] unpinMessage -> '.green, 'userId:', Meteor.userId()
# If we keep history of edits, insert a new message to store history information
if RocketChat.settings.get 'Message_KeepHistory'
RocketChat.models.Messages.cloneAndSaveAsHistoryById message._id
me = RocketChat.models.Users.findOneById Meteor.userId()
message.pinned = false
message.pinnedBy =
_id: Meteor.userId()
username: me.username
message = RocketChat.callbacks.run 'beforeSaveMessage', message
RocketChat.models.Messages.setPinnedByIdAndUserId message._id, Meteor.userId(), message.pinned
RocketChat.models.Messages.setPinnedByIdAndUserId message._id, message.pinnedBy, message.pinned
# Meteor.defer ->
......
Meteor.publish 'pinnedMessages', (rid, options = {}) ->
unless this.userId
return this.ready()
console.log '[publish] pinnedMessages -> '.green, 'rid:', rid, 'options:', options
publication = @
cursorHandle = RocketChat.models.Messages.findPinnedByRoom(rid, { sort: { ts: -1 }, limit: 50 }).observeChanges
added: (_id, record) ->
publication.added('rocketchat_pinned_message', _id, record)
changed: (_id, record) ->
publication.changed('rocketchat_pinned_message', _id, record)
removed: (_id) ->
publication.removed('rocketchat_pinned_message', _id)
@ready()
@onStop ->
cursorHandle.stop()
Meteor.startup ->
RocketChat.settings.add 'Message_AllowPinning', true, { type: 'boolean', group: 'Message', public: true }
RocketChat.settings.add 'Message_AllowPinningByAnyone', false, { type: 'boolean', group: 'Message', public: true }
Meteor.startup ->
Meteor.defer ->
RocketChat.models.Messages.tryEnsureIndex { 'pinnedBy._id': 1 }, { sparse: 1 }
......@@ -19,8 +19,8 @@
}
.message-cog-container {
.edit-message, .delete-message {
.edit-message, .delete-message, .pin-message, .unpin-message {
display: none !important;
}
}
}
}
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'
RocketChat.models.Messages.cloneAndSaveAsHistoryById message._id
message.pinned = true
message = RocketChat.callbacks.run 'beforeSaveMessage', message
RocketChat.models.Messages.setPinnedByIdAndUserId message._id, Meteor.userId(), message.pinned
# Meteor.defer ->
# RocketChat.callbacks.run 'afterSaveMessage', RocketChat.models.Messages.findOneById(message.id)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment