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');