From 06b0a03d46366c508a0efc6cf2e8bfca1d8831d5 Mon Sep 17 00:00:00 2001 From: Marcelo Schmidt Date: Fri, 18 Sep 2015 15:16:28 -0300 Subject: [PATCH] Message Action Buttons --- client/lib/tapi18n.coffee | 3 + client/views/app/message.coffee | 11 +- client/views/app/message.html | 11 +- client/views/app/room.coffee | 44 +------ .../client/MessageAction.coffee | 114 +++++++++++++++--- packages/rocketchat-lib/i18n/en.i18n.json | 4 + packages/rocketchat-lib/i18n/pt.i18n.json | 4 + packages/rocketchat-lib/package-tap.i18n | 0 packages/rocketchat-lib/package.js | 18 ++- 9 files changed, 130 insertions(+), 79 deletions(-) create mode 100644 packages/rocketchat-lib/i18n/en.i18n.json create mode 100644 packages/rocketchat-lib/i18n/pt.i18n.json create mode 100644 packages/rocketchat-lib/package-tap.i18n diff --git a/client/lib/tapi18n.coffee b/client/lib/tapi18n.coffee index 1cf705e3952..b93b8f8193a 100644 --- a/client/lib/tapi18n.coffee +++ b/client/lib/tapi18n.coffee @@ -13,3 +13,6 @@ @isRtl = (language) -> # https://en.wikipedia.org/wiki/Right-to-left#cite_note-2 return language?.split('-').shift().toLowerCase() in ['ar', 'dv', 'fa', 'he', 'ku', 'ps', 'sd', 'ug', 'ur', 'yi'] + +UI.registerHelper '_t', (key) -> + return TAPi18next.t key \ No newline at end of file diff --git a/client/views/app/message.coffee b/client/views/app/message.coffee index 66189490c1f..75764bda858 100644 --- a/client/views/app/message.coffee +++ b/client/views/app/message.coffee @@ -1,7 +1,7 @@ Template.message.helpers actions: -> - return Template.instance()?.actions?.getButtons() - + return RocketChat.MessageAction.getButtons(this) + own: -> return 'own' if this.u?._id is Meteor.userId() @@ -59,7 +59,6 @@ Template.message.helpers Template.message.onViewRendered = (context) -> view = this - console.log view this._domrange.onAttached (domRange) -> lastNode = domRange.lastNode() if lastNode.previousElementSibling?.dataset?.date isnt lastNode.dataset.date @@ -95,9 +94,3 @@ Template.message.onViewRendered = (context) -> if view.parentView.parentView.parentView.parentView.parentView.templateInstance?().atBottom isnt true newMessage = document.querySelector(".new-message") newMessage.className = "new-message" - - # if RocketChat.authz.hasAtLeastOnePermission('edit-message', context.rid ) or (RocketChat.settings.get('Message_AllowEditing') and context.u?._id is Meteor.userId()) - # view.instance().actions.addButton({ id: 'edit-message', icon: 'icon-pencil', label: 'Edit' }) - -Template.message.onCreated -> - @actions = new MessageAction diff --git a/client/views/app/message.html b/client/views/app/message.html index 626d0164edf..3c0a4f29863 100644 --- a/client/views/app/message.html +++ b/client/views/app/message.html @@ -15,18 +15,9 @@
diff --git a/client/views/app/room.coffee b/client/views/app/room.coffee index b55b095ce00..d77c44733b0 100644 --- a/client/views/app/room.coffee +++ b/client/views/app/room.coffee @@ -405,17 +405,6 @@ Template.room.events 'click .see-all': (e, instance) -> instance.showUsersOffline.set(!instance.showUsersOffline.get()) - "click .edit-message": (e) -> - message = e.currentTarget.parentNode.parentNode - Template.instance().chatMessages.edit(message) - - $("\##{message.id} .message-dropdown").hide() - - input = Template.instance().find('.input-message') - Meteor.setTimeout -> - input.focus() - , 200 - 'click .message-cog': (e) -> message_id = e.currentTarget.parentNode.parentNode.id @@ -440,33 +429,6 @@ Template.room.events 'click .image-to-download': (event) -> ChatMessage.update {_id: this._arguments[1]._id, 'urls.url': $(event.currentTarget).data('url')}, {$set: {'urls.$.downloadImages': true}} - 'click .delete-message': (event) -> - message = @_arguments[1] - msg = event.currentTarget.parentNode.parentNode - - $("\##{msg.id} .message-dropdown").hide() - - instance = Template.instance() - return if msg.classList.contains("system") - swal { - title: t('Are_you_sure') - text: t('You_will_not_be_able_to_recover') - type: 'warning' - showCancelButton: true - confirmButtonColor: '#DD6B55' - confirmButtonText: t('Yes_delete_it') - cancelButtonText: t('Cancel') - closeOnConfirm: false - html: false - }, -> - swal - title: t('Deleted') - text: t('Your_entry_has_been_deleted') - type: 'success' - timer: 1000 - showConfirmButton: false - - instance.chatMessages.deleteMsg(message) 'click .pin-message': (event) -> message = @_arguments[1] instance = Template.instance() @@ -581,6 +543,12 @@ Template.room.onCreated -> @autorun -> self.subscribe 'fullUserData', Session.get('showUserInfo'), 1 + for button in RocketChat.MessageAction.getButtons() + if _.isFunction button.action + evt = {} + evt["click .#{button.id}"] = button.action + Template.room.events evt + Template.room.onDestroyed -> RocketChat.TabBar.resetButtons() diff --git a/packages/rocketchat-lib/client/MessageAction.coffee b/packages/rocketchat-lib/client/MessageAction.coffee index 2d29afe658b..108d15ab941 100644 --- a/packages/rocketchat-lib/client/MessageAction.coffee +++ b/packages/rocketchat-lib/client/MessageAction.coffee @@ -1,31 +1,105 @@ -class @MessageAction - constructor: -> - @buttons = new ReactiveVar {} - - addButton: (config) => +RocketChat.MessageAction = new class + buttons = new ReactiveVar {} + + ### + config expects the following keys (only id is mandatory): + id (mandatory) + icon: string + i18nLabel: string + action: function(event, instance) + validation: function(message) + order: integer + ### + addButton = (config) -> unless config?.id throw new Meteor.Error "MessageAction-addButton-error", "Button id was not informed." - Tracker.nonreactive => - btns = @buttons.get() + Tracker.nonreactive -> + btns = buttons.get() btns[config.id] = config - @buttons.set btns + buttons.set btns - removeButton: (id) => - Tracker.nonreactive => - btns = @buttons.get() + removeButton = (id) -> + Tracker.nonreactive -> + btns = buttons.get() delete btns[id] - @buttons.set btns + buttons.set btns - updateButton: (id, config) => - Tracker.nonreactive => - btns = @buttons.get() + updateButton = (id, config) -> + Tracker.nonreactive -> + btns = buttons.get() if btns[id] btns[id] = _.extend btns[id], config - @buttons.set btns + buttons.set btns + + getButtons = (message) -> + allButtons = _.toArray buttons.get() + if message + allowedButtons = _.compact _.map allButtons, (button) -> + unless button.validation? + return true + if button.validation(message) + return button + else + allowedButtons = allButtons + + return _.sortBy allowedButtons, 'order' + + resetButtons = -> + buttons.set {} + + addButton: addButton + removeButton: removeButton + updateButton: updateButton + getButtons: getButtons + resetButtons: resetButtons + +Meteor.startup -> + RocketChat.MessageAction.addButton + id: 'edit-message' + icon: 'icon-pencil' + i18nLabel: 'rocketchat-lib:Edit' + action: (event, instance) -> + message = event.currentTarget.parentNode.parentNode + instance.chatMessages.edit(message) + $("\##{message.id} .message-dropdown").hide() + input = instance.find('.input-message') + Meteor.setTimeout -> + input.focus() + , 200 + validation: (message) -> + return RocketChat.authz.hasAtLeastOnePermission('edit-message', message.rid ) or RocketChat.settings.get('Message_AllowEditing') and message.u?._id is Meteor.userId() + order: 1 + RocketChat.MessageAction.addButton + id: 'delete-message' + icon: 'icon-trash-1' + i18nLabel: 'rocketchat-lib:Delete' + action: (event, instance) -> + message = @_arguments[1] + msg = event.currentTarget.parentNode.parentNode + + $("\##{msg.id} .message-dropdown").hide() - getButtons: => - return _.sortBy (_.toArray @buttons.get()), 'order' + return if msg.classList.contains("system") + swal { + title: t('Are_you_sure') + text: t('You_will_not_be_able_to_recover') + type: 'warning' + showCancelButton: true + confirmButtonColor: '#DD6B55' + confirmButtonText: t('Yes_delete_it') + cancelButtonText: t('Cancel') + closeOnConfirm: false + html: false + }, -> + swal + title: t('Deleted') + text: t('Your_entry_has_been_deleted') + type: 'success' + timer: 1000 + showConfirmButton: false - resetButtons: => - @buttons.set {} + instance.chatMessages.deleteMsg(message) + validation: (message) -> + return RocketChat.authz.hasAtLeastOnePermission('delete-message', message.rid ) or RocketChat.settings.get('Message_AllowDeleting') and message.u?._id is Meteor.userId() + order: 2 \ No newline at end of file diff --git a/packages/rocketchat-lib/i18n/en.i18n.json b/packages/rocketchat-lib/i18n/en.i18n.json new file mode 100644 index 00000000000..9c76e8e402a --- /dev/null +++ b/packages/rocketchat-lib/i18n/en.i18n.json @@ -0,0 +1,4 @@ +{ + "Edit": "Edit", + "Delete": "Delete" +} \ No newline at end of file diff --git a/packages/rocketchat-lib/i18n/pt.i18n.json b/packages/rocketchat-lib/i18n/pt.i18n.json new file mode 100644 index 00000000000..a5227168f1f --- /dev/null +++ b/packages/rocketchat-lib/i18n/pt.i18n.json @@ -0,0 +1,4 @@ +{ + "Edit": "Editar", + "Delete": "Excluir" +} \ No newline at end of file diff --git a/packages/rocketchat-lib/package-tap.i18n b/packages/rocketchat-lib/package-tap.i18n new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/rocketchat-lib/package.js b/packages/rocketchat-lib/package.js index e63f11d6715..0e7854b0ad5 100644 --- a/packages/rocketchat-lib/package.js +++ b/packages/rocketchat-lib/package.js @@ -15,6 +15,19 @@ Package.onUse(function(api) { api.use('underscore'); api.use('underscorestring:underscore.string'); + // TAPi18n + api.use('templating', 'client'); + var _ = Npm.require('underscore'); + var fs = Npm.require('fs'); + tapi18nFiles = _.compact(_.map(fs.readdirSync('packages/rocketchat-lib/i18n'), function(filename) { + if (fs.statSync('packages/rocketchat-lib/i18n/' + filename).size > 16) { + return 'i18n/' + filename; + } + })); + api.use(["tap:i18n@1.5.1"], ["client", "server"]); + api.imply('tap:i18n'); + api.addFiles("package-tap.i18n", ["client", "server"]); + // COMMON api.addFiles('lib/core.coffee'); api.addFiles('lib/callbacks.coffee'); @@ -23,7 +36,6 @@ Package.onUse(function(api) { api.addFiles('settings/lib/settings.coffee'); api.addFiles('settings/lib/rocketchat.coffee'); - // CLIENT api.addFiles('client/Notifications.coffee', 'client'); api.addFiles('client/TabBar.coffee', 'client'); @@ -32,7 +44,6 @@ Package.onUse(function(api) { api.addFiles('settings/client/startup.coffee', 'client'); api.addFiles('settings/client/rocketchat.coffee', 'client'); - // SERVER api.addFiles('server/functions/checkUsernameAvailability.coffee', 'server'); api.addFiles('server/functions/setUsername.coffee', 'server'); @@ -47,6 +58,7 @@ Package.onUse(function(api) { api.addFiles('server/Notifications.coffee', 'server'); + // Settings api.addFiles('settings/server/methods.coffee', 'server'); api.addFiles('settings/server/publication.coffee', 'server'); api.addFiles('settings/server/startup.coffee', 'server'); @@ -55,6 +67,8 @@ Package.onUse(function(api) { api.addFiles('server/cdn.coffee', 'server'); + // TAPi18n -- needs to be added last + api.addFiles(tapi18nFiles, ["client", "server"]); // EXPORT api.export('RocketChat');