diff --git a/packages/rocketchat-lib/client/MessageAction.coffee b/packages/rocketchat-lib/client/MessageAction.coffee
deleted file mode 100644
index 80837c3a0be..00000000000
--- a/packages/rocketchat-lib/client/MessageAction.coffee
+++ /dev/null
@@ -1,247 +0,0 @@
-import moment from 'moment'
-import toastr from 'toastr'
-
-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
- return false
-
- Tracker.nonreactive ->
- btns = buttons.get()
- btns[config.id] = config
- buttons.set btns
-
- removeButton = (id) ->
- Tracker.nonreactive ->
- btns = buttons.get()
- delete btns[id]
- buttons.set btns
-
- updateButton = (id, config) ->
- Tracker.nonreactive ->
- btns = buttons.get()
- if btns[id]
- btns[id] = _.extend btns[id], config
- buttons.set btns
-
- getButtonById = (id) ->
- allButtons = buttons.get()
- return allButtons[id]
-
- getButtons = (message, context) ->
- allButtons = _.toArray buttons.get()
- if message
- allowedButtons = _.compact _.map allButtons, (button) ->
- if not button.context? or button.context.indexOf(context) > -1
- if not button.validation? or button.validation(message, context)
- return button
- else
- allowedButtons = allButtons
-
- return _.sortBy allowedButtons, 'order'
-
- resetButtons = ->
- buttons.set {}
-
- getPermaLink = (msgId) ->
- roomData = ChatSubscription.findOne({rid: Session.get('openedRoom')})
- if roomData
- routePath = RocketChat.roomTypes.getRouteLink(roomData.t, roomData)
- else
- routePath = document.location.pathname
- return Meteor.absoluteUrl().replace(/\/$/, '') + routePath + '?msg=' + msgId
-
- hideDropDown = () ->
- $('.message-dropdown:visible').hide()
-
- addButton: addButton
- removeButton: removeButton
- updateButton: updateButton
- getButtons: getButtons
- getButtonById: getButtonById
- resetButtons: resetButtons
- getPermaLink: getPermaLink
- hideDropDown: hideDropDown
-
-Meteor.startup ->
-
- $(document).click (event) =>
- target = $(event.target)
- if !target.closest('.message-cog-container').length and !target.is('.message-cog-container')
- RocketChat.MessageAction.hideDropDown()
-
- RocketChat.MessageAction.addButton
- id: 'reply-message'
- icon: 'icon-reply'
- i18nLabel: 'Reply'
- context: [
- 'message'
- 'message-mobile'
- ]
- action: (event, instance) ->
- message = @_arguments[1]
- input = instance.find('.input-message')
- url = RocketChat.MessageAction.getPermaLink(message._id)
- text = '[ ](' + url + ') @' + message.u.username + ' '
- if input.value
- input.value += if input.value.endsWith(' ') then '' else ' '
- input.value += text
- input.focus()
- RocketChat.MessageAction.hideDropDown()
- validation: (message) ->
- if not RocketChat.models.Subscriptions.findOne({ rid: message.rid })?
- return false
- return true
- order: 1
-
- RocketChat.MessageAction.addButton
- id: 'edit-message'
- icon: 'icon-pencil'
- i18nLabel: 'Edit'
- context: [
- 'message'
- 'message-mobile'
- ]
- action: (e, instance) ->
- message = $(e.currentTarget).closest('.message')[0]
- chatMessages[Session.get('openedRoom')].edit(message)
- RocketChat.MessageAction.hideDropDown()
- input = instance.find('.input-message')
- Meteor.setTimeout ->
- input.focus()
- input.updateAutogrow()
- , 200
- validation: (message) ->
- if not RocketChat.models.Subscriptions.findOne({ rid: message.rid })?
- return false
-
- hasPermission = RocketChat.authz.hasAtLeastOnePermission('edit-message', message.rid)
- isEditAllowed = RocketChat.settings.get 'Message_AllowEditing'
- editOwn = message.u?._id is Meteor.userId()
-
- return unless hasPermission or (isEditAllowed and editOwn)
-
- blockEditInMinutes = RocketChat.settings.get 'Message_AllowEditing_BlockEditInMinutes'
- if blockEditInMinutes? and blockEditInMinutes isnt 0
- msgTs = moment(message.ts) if message.ts?
- currentTsDiff = moment().diff(msgTs, 'minutes') if msgTs?
- return currentTsDiff < blockEditInMinutes
- else
- return true
- order: 2
-
- RocketChat.MessageAction.addButton
- id: 'delete-message'
- icon: 'icon-trash-alt'
- i18nLabel: 'Delete'
- context: [
- 'message'
- 'message-mobile'
- ]
- action: (event, instance) ->
- message = @_arguments[1]
- RocketChat.MessageAction.hideDropDown()
- chatMessages[Session.get('openedRoom')].confirmDeleteMsg(message)
- validation: (message) ->
- if not RocketChat.models.Subscriptions.findOne({ rid: message.rid })?
- return false
-
- hasPermission = RocketChat.authz.hasAtLeastOnePermission('delete-message', message.rid)
- isDeleteAllowed = RocketChat.settings.get 'Message_AllowDeleting'
- deleteOwn = message.u?._id is Meteor.userId()
-
- return unless hasPermission or (isDeleteAllowed and deleteOwn)
-
- blockDeleteInMinutes = RocketChat.settings.get 'Message_AllowDeleting_BlockDeleteInMinutes'
- if blockDeleteInMinutes? and blockDeleteInMinutes isnt 0
- msgTs = moment(message.ts) if message.ts?
- currentTsDiff = moment().diff(msgTs, 'minutes') if msgTs?
- return currentTsDiff < blockDeleteInMinutes
- else
- return true
- order: 3
-
- RocketChat.MessageAction.addButton
- id: 'permalink'
- icon: 'icon-link'
- i18nLabel: 'Permalink'
- classes: 'clipboard'
- context: [
- 'message'
- 'message-mobile'
- ]
- action: (event, instance) ->
- message = @_arguments[1]
- permalink = RocketChat.MessageAction.getPermaLink(message._id)
- RocketChat.MessageAction.hideDropDown()
- if Meteor.isCordova
- cordova.plugins.clipboard.copy(permalink);
- else
- $(event.currentTarget).attr('data-clipboard-text', permalink);
- toastr.success(TAPi18n.__('Copied'))
- validation: (message) ->
- if not RocketChat.models.Subscriptions.findOne({ rid: message.rid })?
- return false
-
- return true
- order: 4
-
- RocketChat.MessageAction.addButton
- id: 'copy'
- icon: 'icon-paste'
- i18nLabel: 'Copy'
- classes: 'clipboard'
- context: [
- 'message'
- 'message-mobile'
- ]
- action: (event, instance) ->
- message = @_arguments[1].msg
- RocketChat.MessageAction.hideDropDown()
- if Meteor.isCordova
- cordova.plugins.clipboard.copy(message);
- else
- $(event.currentTarget).attr('data-clipboard-text', message)
- toastr.success(TAPi18n.__('Copied'))
- validation: (message) ->
- if not RocketChat.models.Subscriptions.findOne({ rid: message.rid })?
- return false
-
- return true
- order: 5
-
- RocketChat.MessageAction.addButton
- id: 'quote-message'
- icon: 'icon-quote-left'
- i18nLabel: 'Quote'
- context: [
- 'message'
- 'message-mobile'
- ]
- action: (event, instance) ->
- message = @_arguments[1]
- input = instance.find('.input-message')
- url = RocketChat.MessageAction.getPermaLink(message._id)
- text = '[ ](' + url + ') '
- if input.value
- input.value += if input.value.endsWith(' ') then '' else ' '
- input.value += text
- input.focus()
- RocketChat.MessageAction.hideDropDown()
- validation: (message) ->
- if not RocketChat.models.Subscriptions.findOne({ rid: message.rid })?
- return false
-
- return true
- order: 6
diff --git a/packages/rocketchat-lib/client/MessageAction.js b/packages/rocketchat-lib/client/MessageAction.js
new file mode 100644
index 00000000000..be10a478362
--- /dev/null
+++ b/packages/rocketchat-lib/client/MessageAction.js
@@ -0,0 +1,289 @@
+import moment from 'moment';
+
+import toastr from 'toastr';
+
+RocketChat.MessageAction = new class {
+ /*
+ config expects the following keys (only id is mandatory):
+ id (mandatory)
+ icon: string
+ i18nLabel: string
+ action: function(event, instance)
+ validation: function(message)
+ order: integer
+ */
+
+ constructor() {
+ this.buttons = new ReactiveVar({});
+ }
+
+ addButton(config) {
+ if (!config || !config.id) {
+ return false;
+ }
+ return Tracker.nonreactive(() => {
+ const btns = this.buttons.get();
+ btns[config.id] = config;
+ return this.buttons.set(btns);
+ });
+ }
+
+ removeButton(id) {
+ return Tracker.nonreactive(() => {
+ const btns = this.buttons.get();
+ delete btns[id];
+ return this.buttons.set(btns);
+ });
+ }
+
+ updateButton(id, config) {
+ return Tracker.nonreactive(() => {
+ const btns = this.buttons.get();
+ if (btns[id]) {
+ btns[id] = _.extend(btns[id], config);
+ return this.buttons.set(btns);
+ }
+ });
+ }
+
+ getButtonById(id) {
+ const allButtons = this.buttons.get();
+ return allButtons[id];
+ }
+
+ getButtons(message, context) {
+ const allButtons = _.toArray(this.buttons.get());
+ let allowedButtons = allButtons;
+ if (message) {
+ allowedButtons = _.compact(_.map(allButtons, function(button) {
+ if (button.context == null || button.context.includes(context)) {
+ if (button.validation == null || button.validation(message, context)) {
+ return button;
+ }
+ }
+ }));
+ }
+ return _.sortBy(allowedButtons, 'order');
+ }
+
+ resetButtons() {
+ return this.buttons.set({});
+ }
+
+ getPermaLink(msgId) {
+ const roomData = ChatSubscription.findOne({
+ rid: Session.get('openedRoom')
+ });
+ let routePath = document.location.pathname;
+ if (roomData) {
+ routePath = RocketChat.roomTypes.getRouteLink(roomData.t, roomData);
+ }
+ return `${ Meteor.absoluteUrl().replace(/\/$/, '') + routePath }?msg=${ msgId }`;
+ }
+
+ hideDropDown() {
+ return $('.message-dropdown:visible').hide();
+ }
+};
+
+Meteor.startup(function() {
+ $(document).click((event) => {
+ const target = $(event.target);
+ if (!target.closest('.message-cog-container').length && !target.is('.message-cog-container')) {
+ return RocketChat.MessageAction.hideDropDown();
+ }
+ });
+
+ RocketChat.MessageAction.addButton({
+ id: 'reply-message',
+ icon: 'icon-reply',
+ i18nLabel: 'Reply',
+ context: ['message', 'message-mobile'],
+ action(event, instance) {
+ const message = this._arguments[1];
+ const input = instance.find('.input-message');
+ const url = RocketChat.MessageAction.getPermaLink(message._id);
+ const text = `[ ](${ url }) @${ message.u.username } `;
+ if (input.value) {
+ input.value += input.value.endsWith(' ') ? '' : ' ';
+ }
+ input.value += text;
+ input.focus();
+ return RocketChat.MessageAction.hideDropDown();
+ },
+ validation(message) {
+ if (RocketChat.models.Subscriptions.findOne({
+ rid: message.rid
+ }) == null) {
+ return false;
+ }
+ return true;
+ },
+ order: 1
+ });
+ /* globals chatMessages*/
+ RocketChat.MessageAction.addButton({
+ id: 'edit-message',
+ icon: 'icon-pencil',
+ i18nLabel: 'Edit',
+ context: ['message', 'message-mobile'],
+ action(e, instance) {
+ const message = $(e.currentTarget).closest('.message')[0];
+ chatMessages[Session.get('openedRoom')].edit(message);
+ RocketChat.MessageAction.hideDropDown();
+ const input = instance.find('.input-message');
+ Meteor.setTimeout(() => {
+ input.focus();
+ input.updateAutogrow();
+ }, 200);
+ },
+ validation(message) {
+ if (RocketChat.models.Subscriptions.findOne({
+ rid: message.rid
+ }) == null) {
+ return false;
+ }
+ const hasPermission = RocketChat.authz.hasAtLeastOnePermission('edit-message', message.rid);
+ const isEditAllowed = RocketChat.settings.get('Message_AllowEditing');
+ const editOwn = message.u && message.u._id === Meteor.userId();
+ if (!(hasPermission || (isEditAllowed && editOwn))) {
+ return;
+ }
+ const blockEditInMinutes = RocketChat.settings.get('Message_AllowEditing_BlockEditInMinutes');
+ if (blockEditInMinutes) {
+ let msgTs;
+ if (message.ts != null) {
+ msgTs = moment(message.ts);
+ }
+ let currentTsDiff;
+ if (msgTs != null) {
+ currentTsDiff = moment().diff(msgTs, 'minutes');
+ }
+ return currentTsDiff < blockEditInMinutes;
+ } else {
+ return true;
+ }
+ },
+ order: 2
+ });
+ RocketChat.MessageAction.addButton({
+ id: 'delete-message',
+ icon: 'icon-trash-alt',
+ i18nLabel: 'Delete',
+ context: ['message', 'message-mobile'],
+ action() {
+ const message = this._arguments[1];
+ RocketChat.MessageAction.hideDropDown();
+ return chatMessages[Session.get('openedRoom')].confirmDeleteMsg(message);
+ },
+ validation(message) {
+ if (RocketChat.models.Subscriptions.findOne({
+ rid: message.rid
+ }) == null) {
+ return false;
+ }
+ const hasPermission = RocketChat.authz.hasAtLeastOnePermission('delete-message', message.rid);
+ const isDeleteAllowed = RocketChat.settings.get('Message_AllowDeleting');
+ const deleteOwn = message.u && message.u_id === Meteor.userId();
+ if (!(hasPermission || (isDeleteAllowed && deleteOwn))) {
+ return;
+ }
+ const blockDeleteInMinutes = RocketChat.settings.get('Message_AllowDeleting_BlockDeleteInMinutes');
+ if ((blockDeleteInMinutes != null) && blockDeleteInMinutes !== 0) {
+ let msgTs;
+ if (message.ts != null) {
+ msgTs = moment(message.ts);
+ }
+ let currentTsDiff;
+ if (msgTs != null) {
+ currentTsDiff = moment().diff(msgTs, 'minutes');
+ }
+ return currentTsDiff < blockDeleteInMinutes;
+ } else {
+ return true;
+ }
+ },
+ order: 3
+ });
+ /* globals cordova*/
+ RocketChat.MessageAction.addButton({
+ id: 'permalink',
+ icon: 'icon-link',
+ i18nLabel: 'Permalink',
+ classes: 'clipboard',
+ context: ['message', 'message-mobile'],
+ action() {
+ const message = this._arguments[1];
+ const permalink = RocketChat.MessageAction.getPermaLink(message._id);
+ RocketChat.MessageAction.hideDropDown();
+ if (Meteor.isCordova) {
+ cordova.plugins.clipboard.copy(permalink);
+ } else {
+ $(event.currentTarget).attr('data-clipboard-text', permalink);
+ }
+ return toastr.success(TAPi18n.__('Copied'));
+ },
+ validation(message) {
+ if (RocketChat.models.Subscriptions.findOne({
+ rid: message.rid
+ }) == null) {
+ return false;
+ }
+ return true;
+ },
+ order: 4
+ });
+ RocketChat.MessageAction.addButton({
+ id: 'copy',
+ icon: 'icon-paste',
+ i18nLabel: 'Copy',
+ classes: 'clipboard',
+ context: ['message', 'message-mobile'],
+ action() {
+ const message = this._arguments[1].msg;
+ RocketChat.MessageAction.hideDropDown();
+ if (Meteor.isCordova) {
+ cordova.plugins.clipboard.copy(message);
+ } else {
+ $(event.currentTarget).attr('data-clipboard-text', message);
+ }
+ return toastr.success(TAPi18n.__('Copied'));
+ },
+ validation(message) {
+ if (RocketChat.models.Subscriptions.findOne({
+ rid: message.rid
+ }) == null) {
+ return false;
+ }
+ return true;
+ },
+ order: 5
+ });
+ return RocketChat.MessageAction.addButton({
+ id: 'quote-message',
+ icon: 'icon-quote-left',
+ i18nLabel: 'Quote',
+ context: ['message', 'message-mobile'],
+ action(event, instance) {
+ const message = this._arguments[1];
+ const input = instance.find('.input-message');
+ const url = RocketChat.MessageAction.getPermaLink(message._id);
+ const text = `[ ](${ url }) `;
+ if (input.value) {
+ input.value += input.value.endsWith(' ') ? '' : ' ';
+ }
+ input.value += text;
+ input.focus();
+ return RocketChat.MessageAction.hideDropDown();
+ },
+ validation(message) {
+ if (RocketChat.models.Subscriptions.findOne({
+ rid: message.rid
+ }) == null) {
+ return false;
+ }
+ return true;
+ },
+ order: 6
+ });
+});
diff --git a/packages/rocketchat-lib/client/Notifications.coffee b/packages/rocketchat-lib/client/Notifications.coffee
deleted file mode 100644
index 9a51ceca348..00000000000
--- a/packages/rocketchat-lib/client/Notifications.coffee
+++ /dev/null
@@ -1,72 +0,0 @@
-RocketChat.Notifications = new class
- constructor: ->
- @logged = Meteor.userId() isnt null
- @loginCb = []
- Tracker.autorun =>
- if Meteor.userId() isnt null and this.logged is false
- cb() for cb in this.loginCb
-
- @logged = Meteor.userId() isnt null
-
- @debug = false
- @streamAll = new Meteor.Streamer 'notify-all'
- @streamLogged = new Meteor.Streamer 'notify-logged'
- @streamRoom = new Meteor.Streamer 'notify-room'
- @streamRoomUsers = new Meteor.Streamer 'notify-room-users'
- @streamUser = new Meteor.Streamer 'notify-user'
-
- if @debug is true
- @onAll -> console.log "RocketChat.Notifications: onAll", arguments
- @onUser -> console.log "RocketChat.Notifications: onAll", arguments
-
- onLogin: (cb) ->
- @loginCb.push(cb)
- if @logged
- cb()
-
- notifyRoom: (room, eventName, args...) ->
- console.log "RocketChat.Notifications: notifyRoom", arguments if @debug is true
-
- args.unshift "#{room}/#{eventName}"
- @streamRoom.emit.apply @streamRoom, args
-
- notifyUser: (userId, eventName, args...) ->
- console.log "RocketChat.Notifications: notifyUser", arguments if @debug is true
-
- args.unshift "#{userId}/#{eventName}"
- @streamUser.emit.apply @streamUser, args
-
- notifyUsersOfRoom: (room, eventName, args...) ->
- console.log "RocketChat.Notifications: notifyUsersOfRoom", arguments if @debug is true
-
- args.unshift "#{room}/#{eventName}"
- @streamRoomUsers.emit.apply @streamRoomUsers, args
-
- onAll: (eventName, callback) ->
- @streamAll.on eventName, callback
-
- onLogged: (eventName, callback) ->
- @onLogin =>
- @streamLogged.on eventName, callback
-
- onRoom: (room, eventName, callback) ->
- if @debug is true
- @streamRoom.on room, -> console.log "RocketChat.Notifications: onRoom #{room}", arguments
-
- @streamRoom.on "#{room}/#{eventName}", callback
-
- onUser: (eventName, callback) ->
- @streamUser.on "#{Meteor.userId()}/#{eventName}", callback
-
-
- unAll: (callback) ->
- @streamAll.removeListener 'notify', callback
-
- unLogged: (callback) ->
- @streamLogged.removeListener 'notify', callback
-
- unRoom: (room, eventName, callback) ->
- @streamRoom.removeListener "#{room}/#{eventName}", callback
-
- unUser: (callback) ->
- @streamUser.removeListener Meteor.userId(), callback
diff --git a/packages/rocketchat-lib/client/Notifications.js b/packages/rocketchat-lib/client/Notifications.js
new file mode 100644
index 00000000000..4a474c9aec2
--- /dev/null
+++ b/packages/rocketchat-lib/client/Notifications.js
@@ -0,0 +1,86 @@
+RocketChat.Notifications = new class {
+ constructor() {
+ this.logged = Meteor.userId() !== null;
+ this.loginCb = [];
+ Tracker.autorun(() => {
+ if (Meteor.userId() !== null && this.logged === false) {
+ this.loginCb.forEach(cb => cb());
+ }
+ return this.logged = Meteor.userId() !== null;
+ });
+ this.debug = false;
+ this.streamAll = new Meteor.Streamer('notify-all');
+ this.streamLogged = new Meteor.Streamer('notify-logged');
+ this.streamRoom = new Meteor.Streamer('notify-room');
+ this.streamRoomUsers = new Meteor.Streamer('notify-room-users');
+ this.streamUser = new Meteor.Streamer('notify-user');
+ if (this.debug === true) {
+ this.onAll(function() {
+ return console.log('RocketChat.Notifications: onAll', arguments);
+ });
+ this.onUser(function() {
+ return console.log('RocketChat.Notifications: onAll', arguments);
+ });
+ }
+ }
+
+ onLogin(cb) {
+ this.loginCb.push(cb);
+ if (this.logged) {
+ return cb();
+ }
+ }
+ notifyRoom(room, eventName, ...args) {
+ if (this.debug === true) {
+ console.log('RocketChat.Notifications: notifyRoom', arguments);
+ }
+ args.unshift(`${ room }/${ eventName }`);
+ return this.streamRoom.emit.apply(this.streamRoom, args);
+ }
+ notifyUser(userId, eventName, ...args) {
+ if (this.debug === true) {
+ console.log('RocketChat.Notifications: notifyUser', arguments);
+ }
+ args.unshift(`${ userId }/${ eventName }`);
+ return this.streamUser.emit.apply(this.streamUser, args);
+ }
+ notifyUsersOfRoom(room, eventName, ...args) {
+ if (this.debug === true) {
+ console.log('RocketChat.Notifications: notifyUsersOfRoom', arguments);
+ }
+ args.unshift(`${ room }/${ eventName }`);
+ return this.streamRoomUsers.emit.apply(this.streamRoomUsers, args);
+ }
+ onAll(eventName, callback) {
+ return this.streamAll.on(eventName, callback);
+ }
+ onLogged(eventName, callback) {
+ return this.onLogin(() => {
+ return this.streamLogged.on(eventName, callback);
+ });
+ }
+ onRoom(room, eventName, callback) {
+ if (this.debug === true) {
+ this.streamRoom.on(room, function() {
+ return console.log(`RocketChat.Notifications: onRoom ${ room }`, arguments);
+ });
+ }
+ return this.streamRoom.on(`${ room }/${ eventName }`, callback);
+ }
+ onUser(eventName, callback) {
+ return this.streamUser.on(`${ Meteor.userId() }/${ eventName }`, callback);
+ }
+ unAll(callback) {
+ return this.streamAll.removeListener('notify', callback);
+ }
+ unLogged(callback) {
+ return this.streamLogged.removeListener('notify', callback);
+ }
+ unRoom(room, eventName, callback) {
+ return this.streamRoom.removeListener(`${ room }/${ eventName }`, callback);
+ }
+ unUser(callback) {
+ return this.streamUser.removeListener(Meteor.userId(), callback);
+ }
+
+};
diff --git a/packages/rocketchat-lib/client/lib/roomExit.coffee b/packages/rocketchat-lib/client/lib/roomExit.coffee
deleted file mode 100644
index d7da9ed4a87..00000000000
--- a/packages/rocketchat-lib/client/lib/roomExit.coffee
+++ /dev/null
@@ -1,20 +0,0 @@
-@roomExit = ->
- RocketChat.callbacks.run 'roomExit'
-
- BlazeLayout.render 'main', {center: 'none'}
-
- if currentTracker?
- currentTracker.stop()
-
- mainNode = document.querySelector('.main-content')
- if mainNode?
- for child in mainNode.children
- if child?
- if child.classList.contains('room-container')
- wrapper = child.querySelector('.messages-box > .wrapper')
- if wrapper
- if wrapper.scrollTop >= wrapper.scrollHeight - wrapper.clientHeight
- child.oldScrollTop = 10e10
- else
- child.oldScrollTop = wrapper.scrollTop
- mainNode.removeChild child
diff --git a/packages/rocketchat-lib/client/lib/roomExit.js b/packages/rocketchat-lib/client/lib/roomExit.js
new file mode 100644
index 00000000000..1612105dfe2
--- /dev/null
+++ b/packages/rocketchat-lib/client/lib/roomExit.js
@@ -0,0 +1,31 @@
+/*globals currentTracker */
+this.roomExit = function() {
+ RocketChat.callbacks.run('roomExit');
+ BlazeLayout.render('main', {
+ center: 'none'
+ });
+
+ if (typeof currentTracker !== 'undefined') {
+ currentTracker.stop();
+ }
+ const mainNode = document.querySelector('.main-content');
+ if (mainNode == null) {
+ return;
+ }
+ return mainNode.children.forEach(child => {
+ if (child == null) {
+ return;
+ }
+ if (child.classList.contains('room-container')) {
+ const wrapper = child.querySelector('.messages-box > .wrapper');
+ if (wrapper) {
+ if (wrapper.scrollTop >= wrapper.scrollHeight - wrapper.clientHeight) {
+ child.oldScrollTop = 10e10;
+ } else {
+ child.oldScrollTop = wrapper.scrollTop;
+ }
+ }
+ }
+ mainNode.removeChild(child);
+ });
+};
diff --git a/packages/rocketchat-lib/client/lib/settings.coffee b/packages/rocketchat-lib/client/lib/settings.coffee
deleted file mode 100644
index 38c08e546ba..00000000000
--- a/packages/rocketchat-lib/client/lib/settings.coffee
+++ /dev/null
@@ -1,65 +0,0 @@
-###
-# RocketChat.settings holds all packages settings
-# @namespace RocketChat.settings
-###
-
-RocketChat.settings.cachedCollection = new RocketChat.CachedCollection({ name: 'public-settings', eventType: 'onAll', userRelated: false })
-RocketChat.settings.collection = RocketChat.settings.cachedCollection.collection
-RocketChat.settings.cachedCollection.init()
-
-RocketChat.settings.dict = new ReactiveDict 'settings'
-
-RocketChat.settings.get = (_id) ->
- return RocketChat.settings.dict.get(_id)
-
-RocketChat.settings.init = ->
- initialLoad = true
- RocketChat.settings.collection.find().observe
- added: (record) ->
- Meteor.settings[record._id] = record.value
- RocketChat.settings.dict.set record._id, record.value
- RocketChat.settings.load record._id, record.value, initialLoad
- changed: (record) ->
- Meteor.settings[record._id] = record.value
- RocketChat.settings.dict.set record._id, record.value
- RocketChat.settings.load record._id, record.value, initialLoad
- removed: (record) ->
- delete Meteor.settings[record._id]
- RocketChat.settings.dict.set record._id, undefined
- RocketChat.settings.load record._id, undefined, initialLoad
- initialLoad = false
-
-RocketChat.settings.init()
-
-Meteor.startup ->
- if Meteor.isCordova is false
- Tracker.autorun (c) ->
- siteUrl = RocketChat.settings.get('Site_Url')
- if not siteUrl or not Meteor.userId()?
- return
-
- if RocketChat.authz.hasRole(Meteor.userId(), 'admin') is false or Meteor.settings.public.sandstorm
- return c.stop()
-
- Meteor.setTimeout ->
- if __meteor_runtime_config__.ROOT_URL isnt location.origin
- currentUrl = location.origin + __meteor_runtime_config__.ROOT_URL_PATH_PREFIX
- swal
- type: 'warning'
- title: t('Warning')
- text: t("The_setting_s_is_configured_to_s_and_you_are_accessing_from_s", t('Site_Url'), siteUrl, currentUrl) + '
' + t("Do_you_want_to_change_to_s_question", currentUrl)
- showCancelButton: true
- confirmButtonText: t('Yes')
- cancelButtonText: t('Cancel')
- closeOnConfirm: false
- html: true
- , ->
- Meteor.call 'saveSetting', 'Site_Url', currentUrl, ->
- swal
- title: t('Saved')
- type: 'success'
- timer: 1000
- showConfirmButton: false
- , 100
-
- return c.stop()
diff --git a/packages/rocketchat-lib/client/lib/settings.js b/packages/rocketchat-lib/client/lib/settings.js
new file mode 100644
index 00000000000..0f0c946ecd8
--- /dev/null
+++ b/packages/rocketchat-lib/client/lib/settings.js
@@ -0,0 +1,87 @@
+
+/*
+* RocketChat.settings holds all packages settings
+* @namespace RocketChat.settings
+*/
+
+/* globals ReactiveDict*/
+
+RocketChat.settings.cachedCollection = new RocketChat.CachedCollection({
+ name: 'public-settings',
+ eventType: 'onAll',
+ userRelated: false
+});
+
+RocketChat.settings.collection = RocketChat.settings.cachedCollection.collection;
+
+RocketChat.settings.cachedCollection.init();
+
+RocketChat.settings.dict = new ReactiveDict('settings');
+
+RocketChat.settings.get = function(_id) {
+ return RocketChat.settings.dict.get(_id);
+};
+
+RocketChat.settings.init = function() {
+ let initialLoad = true;
+ RocketChat.settings.collection.find().observe({
+ added(record) {
+ Meteor.settings[record._id] = record.value;
+ RocketChat.settings.dict.set(record._id, record.value);
+ return RocketChat.settings.load(record._id, record.value, initialLoad);
+ },
+ changed(record) {
+ Meteor.settings[record._id] = record.value;
+ RocketChat.settings.dict.set(record._id, record.value);
+ return RocketChat.settings.load(record._id, record.value, initialLoad);
+ },
+ removed(record) {
+ delete Meteor.settings[record._id];
+ RocketChat.settings.dict.set(record._id, null);
+ return RocketChat.settings.load(record._id, null, initialLoad);
+ }
+ });
+ return initialLoad = false;
+};
+
+RocketChat.settings.init();
+
+Meteor.startup(function() {
+ if (Meteor.isCordova === true) {
+ return;
+ }
+ Tracker.autorun(function(c) {
+ const siteUrl = RocketChat.settings.get('Site_Url');
+ if (!siteUrl || (Meteor.userId() == null)) {
+ return;
+ }
+ if (RocketChat.authz.hasRole(Meteor.userId(), 'admin') === false || Meteor.settings['public'].sandstorm) {
+ return c.stop();
+ }
+ Meteor.setTimeout(function() {
+ if (__meteor_runtime_config__.ROOT_URL !== location.origin) {
+ const currentUrl = location.origin + __meteor_runtime_config__.ROOT_URL_PATH_PREFIX;
+ swal({
+ type: 'warning',
+ title: t('Warning'),
+ text: `${ t('The_setting_s_is_configured_to_s_and_you_are_accessing_from_s', t('Site_Url'), siteUrl, currentUrl) }
${ t('Do_you_want_to_change_to_s_question', currentUrl) }`,
+ showCancelButton: true,
+ confirmButtonText: t('Yes'),
+ cancelButtonText: t('Cancel'),
+ closeOnConfirm: false,
+ html: true
+ }, function() {
+ Meteor.call('saveSetting', 'Site_Url', currentUrl, function() {
+ swal({
+ title: t('Saved'),
+ type: 'success',
+ timer: 1000,
+ showConfirmButton: false
+ });
+ });
+ });
+ }
+ }, 100);
+ return c.stop();
+ });
+});
diff --git a/packages/rocketchat-lib/client/methods/sendMessage.coffee b/packages/rocketchat-lib/client/methods/sendMessage.coffee
deleted file mode 100644
index c8ae9426c32..00000000000
--- a/packages/rocketchat-lib/client/methods/sendMessage.coffee
+++ /dev/null
@@ -1,22 +0,0 @@
-Meteor.methods
- sendMessage: (message) ->
- if not Meteor.userId()
- return false
-
- if _.trim(message.msg) isnt ''
- if isNaN(TimeSync.serverOffset())
- message.ts = new Date()
- else
- message.ts = new Date(Date.now() + TimeSync.serverOffset())
-
- message.u =
- _id: Meteor.userId()
- username: Meteor.user().username
-
- message.temp = true
-
- message = RocketChat.callbacks.run 'beforeSaveMessage', message
-
- RocketChat.promises.run('onClientMessageReceived', message).then (message) ->
- ChatMessage.insert message
- RocketChat.callbacks.run 'afterSaveMessage', message
diff --git a/packages/rocketchat-lib/client/methods/sendMessage.js b/packages/rocketchat-lib/client/methods/sendMessage.js
new file mode 100644
index 00000000000..cc37a2611f5
--- /dev/null
+++ b/packages/rocketchat-lib/client/methods/sendMessage.js
@@ -0,0 +1,18 @@
+Meteor.methods({
+ sendMessage(message) {
+ if (!Meteor.userId() || _.trim(message.msg) === '') {
+ return false;
+ }
+ message.ts = isNaN(TimeSync.serverOffset()) ? new Date() : new Date(Date.now() + TimeSync.serverOffset());
+ message.u = {
+ _id: Meteor.userId(),
+ username: Meteor.user().username
+ };
+ message.temp = true;
+ message = RocketChat.callbacks.run('beforeSaveMessage', message);
+ RocketChat.promises.run('onClientMessageReceived', message).then(function(message) {
+ ChatMessage.insert(message);
+ return RocketChat.callbacks.run('afterSaveMessage', message);
+ });
+ }
+});
diff --git a/packages/rocketchat-lib/client/models/Uploads.coffee b/packages/rocketchat-lib/client/models/Uploads.coffee
deleted file mode 100644
index 4572e735b99..00000000000
--- a/packages/rocketchat-lib/client/models/Uploads.coffee
+++ /dev/null
@@ -1,3 +0,0 @@
-RocketChat.models.Uploads = new class extends RocketChat.models._Base
- constructor: ->
- @_initModel 'uploads'
diff --git a/packages/rocketchat-lib/client/models/Uploads.js b/packages/rocketchat-lib/client/models/Uploads.js
new file mode 100644
index 00000000000..eefe630c708
--- /dev/null
+++ b/packages/rocketchat-lib/client/models/Uploads.js
@@ -0,0 +1,7 @@
+
+RocketChat.models.Uploads = new class extends RocketChat.models._Base {
+ constructor() {
+ super();
+ this._initModel('uploads');
+ }
+};
diff --git a/packages/rocketchat-lib/client/models/_Base.coffee b/packages/rocketchat-lib/client/models/_Base.coffee
deleted file mode 100644
index fb485723241..00000000000
--- a/packages/rocketchat-lib/client/models/_Base.coffee
+++ /dev/null
@@ -1,44 +0,0 @@
-RocketChat.models._Base = class
- _baseName: ->
- return 'rocketchat_'
-
- _initModel: (name) ->
- check name, String
-
- @model = new Mongo.Collection @_baseName() + name
-
- find: ->
- return @model.find.apply @model, arguments
-
- findOne: ->
- return @model.findOne.apply @model, arguments
-
- insert: ->
- return @model.insert.apply @model, arguments
-
- update: ->
- return @model.update.apply @model, arguments
-
- upsert: ->
- return @model.upsert.apply @model, arguments
-
- remove: ->
- return @model.remove.apply @model, arguments
-
- allow: ->
- return @model.allow.apply @model, arguments
-
- deny: ->
- return @model.deny.apply @model, arguments
-
- ensureIndex: ->
- return
-
- dropIndex: ->
- return
-
- tryEnsureIndex: ->
- return
-
- tryDropIndex: ->
- return
diff --git a/packages/rocketchat-lib/client/models/_Base.js b/packages/rocketchat-lib/client/models/_Base.js
new file mode 100644
index 00000000000..55623317be6
--- /dev/null
+++ b/packages/rocketchat-lib/client/models/_Base.js
@@ -0,0 +1,52 @@
+RocketChat.models._Base = class {
+
+ _baseName() {
+ return 'rocketchat_';
+ }
+
+ _initModel(name) {
+ check(name, String);
+ return this.model = new Mongo.Collection(this._baseName() + name);
+ }
+
+ find() {
+ return this.model.find.apply(this.model, arguments);
+ }
+
+ findOne() {
+ return this.model.findOne.apply(this.model, arguments);
+ }
+
+ insert() {
+ return this.model.insert.apply(this.model, arguments);
+ }
+
+ update() {
+ return this.model.update.apply(this.model, arguments);
+ }
+
+ upsert() {
+ return this.model.upsert.apply(this.model, arguments);
+ }
+
+ remove() {
+ return this.model.remove.apply(this.model, arguments);
+ }
+
+ allow() {
+ return this.model.allow.apply(this.model, arguments);
+ }
+
+ deny() {
+ return this.model.deny.apply(this.model, arguments);
+ }
+
+ ensureIndex() {}
+
+ dropIndex() {}
+
+ tryEnsureIndex() {}
+
+ tryDropIndex() {}
+
+};
diff --git a/packages/rocketchat-lib/package.js b/packages/rocketchat-lib/package.js
index 6e7e7c4022e..8aea1663f7b 100644
--- a/packages/rocketchat-lib/package.js
+++ b/packages/rocketchat-lib/package.js
@@ -173,29 +173,29 @@ Package.onUse(function(api) {
api.addFiles('lib/startup/settingsOnLoadSiteUrl.js');
// CLIENT LIB
- api.addFiles('client/Notifications.coffee', 'client');
+ api.addFiles('client/Notifications.js', 'client');
api.addFiles('client/OAuthProxy.js', 'client');
api.addFiles('client/lib/TabBar.js', 'client');
api.addFiles('client/lib/RocketChatTabBar.js', 'client');
api.addFiles('client/lib/cachedCollection.js', 'client');
api.addFiles('client/lib/openRoom.coffee', 'client');
- api.addFiles('client/lib/roomExit.coffee', 'client');
- api.addFiles('client/lib/settings.coffee', 'client');
+ api.addFiles('client/lib/roomExit.js', 'client');
+ api.addFiles('client/lib/settings.js', 'client');
api.addFiles('client/lib/roomTypes.coffee', 'client');
api.addFiles('client/lib/userRoles.js', 'client');
api.addFiles('client/lib/Layout.js', 'client');
// CLIENT METHODS
- api.addFiles('client/methods/sendMessage.coffee', 'client');
+ api.addFiles('client/methods/sendMessage.js', 'client');
api.addFiles('client/AdminBox.js', 'client');
- api.addFiles('client/MessageAction.coffee', 'client');
+ api.addFiles('client/MessageAction.js', 'client');
api.addFiles('client/defaultTabBars.js', 'client');
api.addFiles('client/CustomTranslations.js', 'client');
// CLIENT MODELS
- api.addFiles('client/models/_Base.coffee', 'client');
- api.addFiles('client/models/Uploads.coffee', 'client');
+ api.addFiles('client/models/_Base.js', 'client');
+ api.addFiles('client/models/Uploads.js', 'client');
// CLIENT VIEWS
api.addFiles('client/views/customFieldsForm.html', 'client');