diff --git a/app/action-links/client/lib/actionLinks.js b/app/action-links/client/lib/actionLinks.js index b3d911398da..d0809e26de8 100644 --- a/app/action-links/client/lib/actionLinks.js +++ b/app/action-links/client/lib/actionLinks.js @@ -1,6 +1,6 @@ import { Meteor } from 'meteor/meteor'; -import { handleError } from '../../../utils/client'; +import { handleError } from '../../../../client/lib/utils/handleError'; import { Messages, Subscriptions } from '../../../models/client'; // Action Links namespace creation. diff --git a/app/apps/client/RealAppsEngineUIHost.js b/app/apps/client/RealAppsEngineUIHost.js index 29802587f9b..d27fdf36ac0 100644 --- a/app/apps/client/RealAppsEngineUIHost.js +++ b/app/apps/client/RealAppsEngineUIHost.js @@ -4,8 +4,8 @@ import { AppsEngineUIHost } from '@rocket.chat/apps-engine/client/AppsEngineUIHo import { Rooms } from '../../models/client'; import { APIClient } from '../../utils/client'; -import { baseURI } from '../../utils/client/lib/baseuri'; import { getUserAvatarURL } from '../../utils/lib/getUserAvatarURL'; +import { baseURI } from '../../../client/lib/baseURI'; export class RealAppsEngineUIHost extends AppsEngineUIHost { constructor() { diff --git a/app/apps/client/gameCenter/gameCenter.js b/app/apps/client/gameCenter/gameCenter.js index 8ffee03cd9c..a23f34837d9 100644 --- a/app/apps/client/gameCenter/gameCenter.js +++ b/app/apps/client/gameCenter/gameCenter.js @@ -2,8 +2,9 @@ import { Template } from 'meteor/templating'; import { ReactiveVar } from 'meteor/reactive-var'; import { modal } from '../../../ui-utils/client'; -import { APIClient, t, handleError } from '../../../utils/client'; +import { APIClient, t } from '../../../utils/client'; import './gameCenter.html'; +import { handleError } from '../../../../client/lib/utils/handleError'; const getExternalComponents = async (instance) => { try { diff --git a/app/apps/client/gameCenter/invitePlayers.js b/app/apps/client/gameCenter/invitePlayers.js index 15579db899c..93f1d9c7309 100644 --- a/app/apps/client/gameCenter/invitePlayers.js +++ b/app/apps/client/gameCenter/invitePlayers.js @@ -10,7 +10,8 @@ import { Session } from 'meteor/session'; import { AutoComplete } from '../../../meteor-autocomplete/client'; import { roomTypes } from '../../../utils/client'; import { ChatRoom } from '../../../models/client'; -import { call, modal } from '../../../ui-utils/client'; +import { modal } from '../../../ui-utils/client'; +import { callWithErrorHandling } from '../../../../client/lib/utils/callWithErrorHandling'; import './invitePlayers.html'; @@ -77,7 +78,7 @@ Template.InvitePlayers.events({ const privateGroupName = `${ name.replace(/\s/g, '-') }-${ Random.id(10) }`; try { - const result = await call('createPrivateGroup', privateGroupName, users); + const result = await callWithErrorHandling('createPrivateGroup', privateGroupName, users); roomTypes.openRouteLink(result.t, result); @@ -90,7 +91,7 @@ Template.InvitePlayers.events({ return; } - call('sendMessage', { + callWithErrorHandling('sendMessage', { _id: Random.id(), rid: result.rid, msg: TAPi18n.__('Apps_Game_Center_Play_Game_Together', { name }), diff --git a/app/authorization/client/hasPermission.js b/app/authorization/client/hasPermission.js deleted file mode 100644 index a48549979c7..00000000000 --- a/app/authorization/client/hasPermission.js +++ /dev/null @@ -1,80 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { Template } from 'meteor/templating'; - -import { ChatPermissions } from './lib/ChatPermissions'; -import * as Models from '../../models'; -import { AuthorizationUtils } from '../lib/AuthorizationUtils'; - -function atLeastOne(permissions = [], scope, userId) { - userId = userId || Meteor.userId(); - const user = Models.Users.findOneById(userId, { fields: { roles: 1 } }); - - return permissions.some((permissionId) => { - if (user && user.roles) { - if (AuthorizationUtils.isPermissionRestrictedForRoleList(permissionId, user.roles)) { - return false; - } - } - - const permission = ChatPermissions.findOne(permissionId, { fields: { roles: 1 } }); - const roles = (permission && permission.roles) || []; - - return roles.some((roleName) => { - const role = Models.Roles.findOne(roleName, { fields: { scope: 1 } }); - const roleScope = role && role.scope; - const model = Models[roleScope]; - - return model && model.isUserInRole && model.isUserInRole(userId, roleName, scope); - }); - }); -} - -function all(permissions = [], scope, userId) { - userId = userId || Meteor.userId(); - const user = Models.Users.findOneById(userId, { fields: { roles: 1 } }); - - return permissions.every((permissionId) => { - if (user && user.roles) { - if (AuthorizationUtils.isPermissionRestrictedForRoleList(permissionId, user.roles)) { - return false; - } - } - - const permission = ChatPermissions.findOne(permissionId, { fields: { roles: 1 } }); - const roles = (permission && permission.roles) || []; - - return roles.some((roleName) => { - const role = Models.Roles.findOne(roleName, { fields: { scope: 1 } }); - const roleScope = role && role.scope; - const model = Models[roleScope]; - - return model && model.isUserInRole && model.isUserInRole(userId, roleName, scope); - }); - }); -} - -function _hasPermission(permissions, scope, strategy, userId) { - userId = userId || Meteor.userId(); - if (!userId) { - return false; - } - - if (!Models.AuthzCachedCollection.ready.get()) { - return false; - } - - permissions = [].concat(permissions); - return strategy(permissions, scope, userId); -} - -Template.registerHelper('hasPermission', function(permission, scope) { - return _hasPermission(permission, scope, atLeastOne); -}); -Template.registerHelper('userHasAllPermission', function(userId, permission, scope) { - return _hasPermission(permission, scope, all, userId); -}); - -export const hasAllPermission = (permissions, scope) => _hasPermission(permissions, scope, all); -export const hasAtLeastOnePermission = (permissions, scope) => _hasPermission(permissions, scope, atLeastOne); -export const userHasAllPermission = (permissions, scope, userId) => _hasPermission(permissions, scope, all, userId); -export const hasPermission = hasAllPermission; diff --git a/app/authorization/client/hasPermission.ts b/app/authorization/client/hasPermission.ts new file mode 100644 index 00000000000..744903bc506 --- /dev/null +++ b/app/authorization/client/hasPermission.ts @@ -0,0 +1,82 @@ +import { Meteor } from 'meteor/meteor'; + +import { ChatPermissions } from './lib/ChatPermissions'; +import * as Models from '../../models/client'; +import { AuthorizationUtils } from '../lib/AuthorizationUtils'; +import { IUser } from '../../../definition/IUser'; +import { IRole } from '../../../definition/IRole'; +import { IPermission } from '../../../definition/IPermission'; + +const isValidScope = (scope: IRole['scope']): scope is keyof typeof Models => + typeof scope === 'string' && scope in Models; + +const createPermissionValidator = (quantifier: (predicate: (permissionId: IPermission['_id']) => boolean) => boolean) => + (permissionIds: IPermission['_id'][], scope: IRole['scope'], userId: IUser['_id']): boolean => { + const user: IUser | null = Models.Users.findOneById(userId, { fields: { roles: 1 } }); + + const checkEachPermission = quantifier.bind(permissionIds); + + return checkEachPermission((permissionId) => { + if (user?.roles) { + if (AuthorizationUtils.isPermissionRestrictedForRoleList(permissionId, user.roles)) { + return false; + } + } + + const permission: IPermission | null = ChatPermissions.findOne(permissionId, { fields: { roles: 1 } }); + const roles = permission?.roles ?? []; + + return roles.some((roleName) => { + const role = Models.Roles.findOne(roleName, { fields: { scope: 1 } }); + const roleScope = role?.scope; + + if (!isValidScope(roleScope)) { + return false; + } + + const model = Models[roleScope]; + return model.isUserInRole && model.isUserInRole(userId, roleName, scope); + }); + }); + }; + +const atLeastOne = createPermissionValidator(Array.prototype.some); + +const all = createPermissionValidator(Array.prototype.every); + +const validatePermissions = ( + permissions: IPermission['_id'] | IPermission['_id'][], + scope: IRole['scope'], + predicate: (permissionIds: IPermission['_id'][], scope: IRole['scope'], userId: IUser['_id']) => boolean, + userId?: IUser['_id'] | null, +): boolean => { + userId = userId ?? Meteor.userId(); + + if (!userId) { + return false; + } + + if (!Models.AuthzCachedCollection.ready.get()) { + return false; + } + + return predicate(([] as IPermission['_id'][]).concat(permissions), scope, userId); +}; + +export const hasAllPermission = ( + permissions: IPermission['_id'] | IPermission['_id'][], + scope?: IRole['scope'], +): boolean => validatePermissions(permissions, scope, all); + +export const hasAtLeastOnePermission = ( + permissions: IPermission['_id'] | IPermission['_id'][], + scope?: IRole['scope'], +): boolean => validatePermissions(permissions, scope, atLeastOne); + +export const userHasAllPermission = ( + permissions: IPermission['_id'] | IPermission['_id'][], + scope?: IRole['scope'], + userId?: IUser['_id'] | null, +): boolean => validatePermissions(permissions, scope, all, userId); + +export const hasPermission = hasAllPermission; diff --git a/app/autotranslate/client/lib/autotranslate.js b/app/autotranslate/client/lib/autotranslate.js index f711bc383a4..1b742b21010 100644 --- a/app/autotranslate/client/lib/autotranslate.js +++ b/app/autotranslate/client/lib/autotranslate.js @@ -5,7 +5,7 @@ import mem from 'mem'; import { Subscriptions, Messages } from '../../../models'; import { hasPermission } from '../../../authorization'; -import { call } from '../../../ui-utils/client'; +import { callWithErrorHandling } from '../../../../client/lib/utils/callWithErrorHandling'; let userLanguage = 'en'; let username = ''; @@ -76,8 +76,8 @@ export const AutoTranslate = { c.stop(); [this.providersMetadata, this.supportedLanguages] = await Promise.all([ - call('autoTranslate.getProviderUiMetadata'), - call('autoTranslate.getSupportedLanguages', 'en'), + callWithErrorHandling('autoTranslate.getProviderUiMetadata'), + callWithErrorHandling('autoTranslate.getSupportedLanguages', 'en'), ]); }); diff --git a/app/callbacks/lib/callbacks.js b/app/callbacks/lib/callbacks.js index 5def1fcfb9b..e91c1af3883 100644 --- a/app/callbacks/lib/callbacks.js +++ b/app/callbacks/lib/callbacks.js @@ -11,7 +11,7 @@ let logger = { }; if (Meteor.isClient) { - const { getConfig } = require('../../ui-utils/client/config'); + const { getConfig } = require('../../../client/lib/utils/getConfig'); timed = [getConfig('debug'), getConfig('timed-callbacks')].includes('true'); } diff --git a/app/chatpal-search/client/template/result.js b/app/chatpal-search/client/template/result.js index 2468ecc30c9..1ed9a1bcafd 100644 --- a/app/chatpal-search/client/template/result.js +++ b/app/chatpal-search/client/template/result.js @@ -2,10 +2,11 @@ import { ReactiveVar } from 'meteor/reactive-var'; import { Template } from 'meteor/templating'; import { TAPi18n } from 'meteor/rocketchat:tap-i18n'; -import { DateFormat } from '../../../lib'; import { roomTypes, getURL } from '../../../utils'; import { Subscriptions } from '../../../models'; import { getUserAvatarURL as getAvatarUrl } from '../../../utils/lib/getUserAvatarURL'; +import { formatTime } from '../../../../client/lib/utils/formatTime'; +import { formatDate } from '../../../../client/lib/utils/formatDate'; const getDMUrl = (username) => getURL(`/direct/${ username }`); @@ -116,10 +117,10 @@ Template.ChatpalSearchSingleMessage.helpers({ }, time() { - return DateFormat.formatTime(this.created); + return formatTime(this.created); }, date() { - return DateFormat.formatDate(this.created); + return formatDate(this.created); }, getAvatarUrl, }); diff --git a/app/e2e/client/logger.ts b/app/e2e/client/logger.ts index 1efd15d8347..50e43b63430 100644 --- a/app/e2e/client/logger.ts +++ b/app/e2e/client/logger.ts @@ -1,4 +1,4 @@ -import { getConfig } from '../../ui-utils/client/config'; +import { getConfig } from '../../../client/lib/utils/getConfig'; let debug: boolean | undefined = undefined; diff --git a/app/e2e/client/rocketchat.e2e.js b/app/e2e/client/rocketchat.e2e.js index 2c0541350ec..974eff7e82a 100644 --- a/app/e2e/client/rocketchat.e2e.js +++ b/app/e2e/client/rocketchat.e2e.js @@ -25,7 +25,7 @@ import { call } from '../../ui-utils'; import './events.js'; import './tabbar'; import { log, logError } from './logger'; -import { waitUntilFind } from '../../utils/client/lib/waitUntilFind'; +import { waitUntilFind } from '../../../client/lib/utils/waitUntilFind'; import { imperativeModal } from '../../../client/lib/imperativeModal'; import SaveE2EPasswordModal from './SaveE2EPasswordModal'; import EnterE2EPasswordModal from './EnterE2EPasswordModal'; diff --git a/app/emoji-custom/client/lib/emojiCustom.js b/app/emoji-custom/client/lib/emojiCustom.js index f1e8b440cfd..177fdfba30e 100644 --- a/app/emoji-custom/client/lib/emojiCustom.js +++ b/app/emoji-custom/client/lib/emojiCustom.js @@ -1,5 +1,4 @@ import { Meteor } from 'meteor/meteor'; -import { Blaze } from 'meteor/blaze'; import { Session } from 'meteor/session'; import { escapeRegExp } from '@rocket.chat/string-helpers'; @@ -26,8 +25,6 @@ export const getEmojiUrlFromName = function(name, extension) { return `${ path }/emoji-custom/${ encodeURIComponent(name) }.${ extension }?_dc=${ random }`; }; -Blaze.registerHelper('emojiUrlFromName', getEmojiUrlFromName); - export const deleteEmojiCustom = function(emojiData) { delete emoji.list[`:${ emojiData.name }:`]; const arrayIndex = emoji.packages.emojiCustom.emojisByCategory.rocket.indexOf(emojiData.name); diff --git a/app/emoji/client/emojiParser.js b/app/emoji/client/emojiParser.js index 71422578b13..770c9147b25 100644 --- a/app/emoji/client/emojiParser.js +++ b/app/emoji/client/emojiParser.js @@ -1,4 +1,4 @@ -import { isIE11 } from '../../ui-utils/client/lib/isIE11'; +import { isIE11 } from '../../../client/lib/utils/isIE11'; import { emoji } from '../lib/rocketchat'; /* diff --git a/app/emoji/client/index.js b/app/emoji/client/index.js index bf02d263352..c1678c647f1 100644 --- a/app/emoji/client/index.js +++ b/app/emoji/client/index.js @@ -1,4 +1,3 @@ export { EmojiPicker } from './lib/EmojiPicker'; -export { renderEmoji } from './lib/emojiRenderer'; export { emoji } from '../lib/rocketchat'; export { createEmojiMessageRenderer } from './emojiParser'; diff --git a/app/emoji/client/lib/emojiRenderer.js b/app/emoji/client/lib/emojiRenderer.js deleted file mode 100644 index d4b2ba2f499..00000000000 --- a/app/emoji/client/lib/emojiRenderer.js +++ /dev/null @@ -1,27 +0,0 @@ -import { Blaze } from 'meteor/blaze'; -import { Template } from 'meteor/templating'; -import { HTML } from 'meteor/htmljs'; - -import { emoji } from '../../lib/rocketchat'; -import { isSetNotNull } from '../function-isSet'; - -export const renderEmoji = function(_emoji) { - if (isSetNotNull(() => emoji.list[_emoji].emojiPackage)) { - const { emojiPackage } = emoji.list[_emoji]; - return emoji.packages[emojiPackage].render(_emoji); - } -}; - -Blaze.registerHelper('renderEmoji', renderEmoji); - -Template.registerHelper('renderEmoji', new Template('renderEmoji', function() { - const view = this; - const _emoji = Blaze.getData(view); - - if (isSetNotNull(() => emoji.list[_emoji].emojiPackage)) { - const { emojiPackage } = emoji.list[_emoji]; - return new HTML.Raw(emoji.packages[emojiPackage].render(_emoji)); - } - - return ''; -})); diff --git a/app/lib/client/UserDeleted.js b/app/lib/client/UserDeleted.js deleted file mode 100644 index 8be7d5ed5d4..00000000000 --- a/app/lib/client/UserDeleted.js +++ /dev/null @@ -1,12 +0,0 @@ -import { Meteor } from 'meteor/meteor'; - -import { ChatMessage } from '../../models'; -import { Notifications } from '../../notifications'; - -Meteor.startup(function() { - Notifications.onLogged('Users:Deleted', ({ userId }) => - ChatMessage.remove({ - 'u._id': userId, - }), - ); -}); diff --git a/app/lib/client/index.js b/app/lib/client/index.js index 64ed16e27b1..5619d577642 100644 --- a/app/lib/client/index.js +++ b/app/lib/client/index.js @@ -1,11 +1,6 @@ import '../lib/startup/settingsOnLoadSiteUrl'; import '../lib/MessageTypes'; -import './CustomTranslations'; import './OAuthProxy'; -import './UserDeleted'; -import './lib/startup/commands'; -import './lib/settings'; -import './lib/userRoles'; import './methods/sendMessage'; import './views/customFieldsForm.html'; import './views/customFieldsForm'; diff --git a/app/lib/client/lib/formatDate.js b/app/lib/client/lib/formatDate.js deleted file mode 100644 index 43251237c9a..00000000000 --- a/app/lib/client/lib/formatDate.js +++ /dev/null @@ -1,53 +0,0 @@ -import moment from 'moment'; -import mem from 'mem'; -import { Meteor } from 'meteor/meteor'; -import { Tracker } from 'meteor/tracker'; - -import { getUserPreference, t } from '../../../utils'; -import { settings } from '../../../settings'; - -let lastDay = t('yesterday'); -let clockMode; -let sameDay; -const dayFormat = ['h:mm A', 'H:mm']; - -Meteor.startup(() => Tracker.autorun(() => { - clockMode = getUserPreference(Meteor.userId(), 'clockMode', false); - sameDay = dayFormat[clockMode - 1] || settings.get('Message_TimeFormat'); - lastDay = t('yesterday'); -})); - -export const formatTime = (time) => { - switch (clockMode) { - case 1: - case 2: - return moment(time).format(sameDay); - default: - return moment(time).format(settings.get('Message_TimeFormat')); - } -}; - -export const formatDateAndTime = (time) => { - switch (clockMode) { - case 1: - return moment(time).format('MMMM D, Y h:mm A'); - case 2: - return moment(time).format('MMMM D, Y H:mm'); - default: - return moment(time).format(settings.get('Message_TimeAndDateFormat')); - } -}; - -const sameElse = function(now) { - const diff = Math.ceil(this.diff(now, 'years', true)); - return diff < 0 ? 'MMM D YYYY' : 'MMM D'; -}; - -export const timeAgo = (date) => moment(date).calendar(null, { - lastDay: `[${ lastDay }]`, - sameDay, - lastWeek: 'dddd', - sameElse, -}); - -export const formatDate = mem((time) => moment(time).format(settings.get('Message_DateFormat')), { maxAge: 5000 }); diff --git a/app/lib/client/lib/index.js b/app/lib/client/lib/index.js index 4cc975c68ce..5cade0413ef 100644 --- a/app/lib/client/lib/index.js +++ b/app/lib/client/lib/index.js @@ -1,12 +1,2 @@ -/* - What is this file? Great question! To make Rocket.Chat more "modular" - and to make the "rocketchat:lib" package more of a core package - with the libraries, this index file contains the exported members - for the *client* pieces of code which does include the shared - library files. -*/ -import * as DateFormat from './formatDate'; - export { RocketChatAnnouncement } from './RocketChatAnnouncement'; export { LoginPresence } from './LoginPresence'; -export { DateFormat }; diff --git a/app/lib/client/lib/startup/commands.js b/app/lib/client/lib/startup/commands.js deleted file mode 100644 index 0d9a7179ae9..00000000000 --- a/app/lib/client/lib/startup/commands.js +++ /dev/null @@ -1,22 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { Tracker } from 'meteor/tracker'; - -import { slashCommands, APIClient } from '../../../../utils'; - -// Track logins and when they login, get the commands -(() => { - let oldUserId = null; - - Tracker.autorun(() => { - const newUserId = Meteor.userId(); - if (oldUserId === null && newUserId) { - APIClient.v1.get('commands.list').then(function _loadedCommands(result) { - result.commands.forEach((command) => { - slashCommands.commands[command.command] = command; - }); - }); - } - - oldUserId = Meteor.userId(); - }); -})(); diff --git a/app/lib/client/lib/userRoles.js b/app/lib/client/lib/userRoles.js deleted file mode 100644 index c0414276b40..00000000000 --- a/app/lib/client/lib/userRoles.js +++ /dev/null @@ -1,42 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { Tracker } from 'meteor/tracker'; - -import { UserRoles, RoomRoles, ChatMessage } from '../../../models'; -import { handleError } from '../../../utils'; -import { Notifications } from '../../../notifications'; - -Meteor.startup(function() { - Tracker.autorun(function() { - if (Meteor.userId()) { - Meteor.call('getUserRoles', (error, results) => { - if (error) { - return handleError(error); - } - - for (const record of results) { - UserRoles.upsert({ _id: record._id }, record); - } - }); - - Notifications.onLogged('roles-change', function(role) { - if (role.type === 'added') { - if (role.scope) { - RoomRoles.upsert({ rid: role.scope, 'u._id': role.u._id }, { $setOnInsert: { u: role.u }, $addToSet: { roles: role._id } }); - } else { - UserRoles.upsert({ _id: role.u._id }, { $addToSet: { roles: role._id }, $set: { username: role.u.username } }); - ChatMessage.update({ 'u._id': role.u._id }, { $addToSet: { roles: role._id } }, { multi: true }); - } - } else if (role.type === 'removed') { - if (role.scope) { - RoomRoles.update({ rid: role.scope, 'u._id': role.u._id }, { $pull: { roles: role._id } }); - } else { - UserRoles.update({ _id: role.u._id }, { $pull: { roles: role._id } }); - ChatMessage.update({ 'u._id': role.u._id }, { $pull: { roles: role._id } }, { multi: true }); - } - } else if (role.type === 'changed') { - ChatMessage.update({ roles: role._id }, { $inc: { rerender: 1 } }, { multi: true }); - } - }); - } - }); -}); diff --git a/app/livechat/client/lib/dateHandler.js b/app/livechat/client/lib/dateHandler.js index ac7d4167aa5..8639280b2ee 100644 --- a/app/livechat/client/lib/dateHandler.js +++ b/app/livechat/client/lib/dateHandler.js @@ -1,7 +1,6 @@ import moment from 'moment'; -import { handleError } from '../../../utils'; - +import { handleError } from '../../../../client/lib/utils/handleError'; /** * Check if given daterange matches any of pre-defined options diff --git a/app/livechat/client/lib/stream/queueManager.js b/app/livechat/client/lib/stream/queueManager.js index 14c2e31eae0..97e9bcf0fb6 100644 --- a/app/livechat/client/lib/stream/queueManager.js +++ b/app/livechat/client/lib/stream/queueManager.js @@ -3,7 +3,7 @@ import { Meteor } from 'meteor/meteor'; import { APIClient } from '../../../../utils/client'; import { LivechatInquiry } from '../../collections/LivechatInquiry'; import { inquiryDataStream } from './inquiry'; -import { call } from '../../../../ui-utils/client'; +import { callWithErrorHandling } from '../../../../../client/lib/utils/callWithErrorHandling'; import { getUserPreference } from '../../../../utils'; import { CustomSounds } from '../../../../custom-sounds/client/lib/CustomSounds'; @@ -79,7 +79,7 @@ const addGlobalListener = () => { const subscribe = async (userId) => { - const config = await call('livechat:getRoutingConfig'); + const config = await callWithErrorHandling('livechat:getRoutingConfig'); if (config && config.autoAssignAgent) { return; } diff --git a/app/livechat/client/views/app/dialog/closeRoom.js b/app/livechat/client/views/app/dialog/closeRoom.js index 2dac3bc7956..42a9f1f5128 100644 --- a/app/livechat/client/views/app/dialog/closeRoom.js +++ b/app/livechat/client/views/app/dialog/closeRoom.js @@ -5,9 +5,10 @@ import { TAPi18n } from 'meteor/rocketchat:tap-i18n'; import { settings } from '../../../../../settings'; import { modal } from '../../../../../ui-utils/client'; -import { APIClient, handleError, t } from '../../../../../utils'; +import { APIClient, t } from '../../../../../utils'; import { hasRole } from '../../../../../authorization'; import './closeRoom.html'; +import { handleError } from '../../../../../../client/lib/utils/handleError'; const validateRoomComment = (comment) => { if (!settings.get('Livechat_request_comment_when_closing_conversation')) { diff --git a/app/livechat/client/views/app/livechatReadOnly.js b/app/livechat/client/views/app/livechatReadOnly.js index 765088722c2..c751c701e9e 100644 --- a/app/livechat/client/views/app/livechatReadOnly.js +++ b/app/livechat/client/views/app/livechatReadOnly.js @@ -4,7 +4,7 @@ import { ReactiveVar } from 'meteor/reactive-var'; import { FlowRouter } from 'meteor/kadira:flow-router'; import { ChatRoom, CachedChatRoom } from '../../../../models'; -import { call } from '../../../../ui-utils/client'; +import { callWithErrorHandling } from '../../../../../client/lib/utils/callWithErrorHandling'; import './livechatReadOnly.html'; import { APIClient } from '../../../../utils/client'; import { inquiryDataStream } from '../../lib/stream/inquiry'; @@ -42,7 +42,7 @@ Template.livechatReadOnly.events({ const inquiry = instance.inquiry.get(); const { _id } = inquiry; - await call('livechat:takeInquiry', _id, { clientAction: true }); + await callWithErrorHandling('livechat:takeInquiry', _id, { clientAction: true }); instance.loadInquiry(inquiry.rid); }, @@ -52,7 +52,7 @@ Template.livechatReadOnly.events({ const room = instance.room.get(); - await call('livechat:resumeOnHold', room._id, { clientAction: true }); + await callWithErrorHandling('livechat:resumeOnHold', room._id, { clientAction: true }); }, }); @@ -64,7 +64,7 @@ Template.livechatReadOnly.onCreated(function() { this.preparing = new ReactiveVar(true); this.updateInquiry = async ({ clientAction, ...inquiry }) => { - if (clientAction === 'removed' || !await call('canAccessRoom', inquiry.rid, Meteor.userId())) { + if (clientAction === 'removed' || !await callWithErrorHandling('canAccessRoom', inquiry.rid, Meteor.userId())) { // this will force to refresh the room // since the client wont get notified of room changes when chats are on queue (no one assigned) // a better approach should be performed when refactoring these templates to use react diff --git a/app/livechat/client/views/app/tabbar/agentEdit.js b/app/livechat/client/views/app/tabbar/agentEdit.js index e46c66e3760..53a11f7ba3b 100644 --- a/app/livechat/client/views/app/tabbar/agentEdit.js +++ b/app/livechat/client/views/app/tabbar/agentEdit.js @@ -6,7 +6,8 @@ import toastr from 'toastr'; import { getCustomFormTemplate } from '../customTemplates/register'; import './agentEdit.html'; import { hasPermission } from '../../../../../authorization'; -import { t, handleError, APIClient } from '../../../../../utils/client'; +import { t, APIClient } from '../../../../../utils/client'; +import { handleError } from '../../../../../../client/lib/utils/handleError'; Template.agentEdit.helpers({ canEditDepartment() { diff --git a/app/livechat/client/views/app/tabbar/agentInfo.js b/app/livechat/client/views/app/tabbar/agentInfo.js index 6894586f32d..c90de337a12 100644 --- a/app/livechat/client/views/app/tabbar/agentInfo.js +++ b/app/livechat/client/views/app/tabbar/agentInfo.js @@ -9,8 +9,9 @@ import s from 'underscore.string'; import { getCustomFormTemplate } from '../customTemplates/register'; import './agentInfo.html'; import { modal } from '../../../../../ui-utils'; -import { t, handleError, APIClient } from '../../../../../utils/client'; +import { t, APIClient } from '../../../../../utils/client'; import { hasPermission } from '../../../../../authorization'; +import { handleError } from '../../../../../../client/lib/utils/handleError'; const customFieldsTemplate = () => getCustomFormTemplate('livechatAgentInfoForm'); diff --git a/app/livechat/client/views/app/tabbar/visitorInfo.js b/app/livechat/client/views/app/tabbar/visitorInfo.js index 56de7d9275c..a58246dbd16 100644 --- a/app/livechat/client/views/app/tabbar/visitorInfo.js +++ b/app/livechat/client/views/app/tabbar/visitorInfo.js @@ -11,14 +11,15 @@ import UAParser from 'ua-parser-js'; import { modal } from '../../../../../ui-utils'; import { Subscriptions } from '../../../../../models'; import { settings } from '../../../../../settings'; -import { t, handleError, roomTypes } from '../../../../../utils'; +import { t, roomTypes } from '../../../../../utils'; import { hasRole, hasPermission, hasAtLeastOnePermission } from '../../../../../authorization'; import './visitorInfo.html'; import { APIClient } from '../../../../../utils/client'; import { RoomManager } from '../../../../../ui-utils/client'; -import { DateFormat } from '../../../../../lib/client'; import { getCustomFormTemplate } from '../customTemplates/register'; import { Markdown } from '../../../../../markdown/client'; +import { handleError } from '../../../../../../client/lib/utils/handleError'; +import { formatDateAndTime } from '../../../../../../client/lib/utils/formatDateAndTime'; const isSubscribedToRoom = () => { const data = Template.currentData(); @@ -213,7 +214,7 @@ Template.visitorInfo.helpers({ roomClosedDateTime() { const { closedAt } = this; - return DateFormat.formatDateAndTime(closedAt); + return formatDateAndTime(closedAt); }, roomClosedBy() { @@ -249,7 +250,7 @@ Template.visitorInfo.helpers({ transcriptRequestedDateTime() { const { requestedAt } = this; - return DateFormat.formatDateAndTime(requestedAt); + return formatDateAndTime(requestedAt); }, markdown(text) { diff --git a/app/livechat/client/views/app/tabbar/visitorTranscript.js b/app/livechat/client/views/app/tabbar/visitorTranscript.js index ae06c775aff..ec26bdf0130 100644 --- a/app/livechat/client/views/app/tabbar/visitorTranscript.js +++ b/app/livechat/client/views/app/tabbar/visitorTranscript.js @@ -3,7 +3,8 @@ import { ReactiveVar } from 'meteor/reactive-var'; import { Template } from 'meteor/templating'; import toastr from 'toastr'; -import { t, isEmail, handleError, roomTypes } from '../../../../../utils'; +import { handleError } from '../../../../../../client/lib/utils/handleError'; +import { t, isEmail, roomTypes } from '../../../../../utils'; import { APIClient } from '../../../../../utils/client'; import './visitorTranscript.html'; diff --git a/app/livestream/client/views/broadcastView.js b/app/livestream/client/views/broadcastView.js index 4fbe6fc554f..afa8f26142d 100644 --- a/app/livestream/client/views/broadcastView.js +++ b/app/livestream/client/views/broadcastView.js @@ -3,8 +3,8 @@ import { ReactiveVar } from 'meteor/reactive-var'; import { Session } from 'meteor/session'; import { Template } from 'meteor/templating'; -import { handleError } from '../../../utils'; -import { settings } from '../../../settings'; +import { handleError } from '../../../../client/lib/utils/handleError'; +import { settings } from '../../../settings/client'; const getMedia = () => navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; const createAndConnect = (url) => { diff --git a/app/livestream/client/views/liveStreamTab.js b/app/livestream/client/views/liveStreamTab.js index 19f64cde929..d73a31336fa 100644 --- a/app/livestream/client/views/liveStreamTab.js +++ b/app/livestream/client/views/liveStreamTab.js @@ -9,11 +9,12 @@ import toastr from 'toastr'; import { auth } from '../oauth.js'; import { RocketChatAnnouncement } from '../../../lib'; import { popout } from '../../../ui-utils'; -import { t, handleError } from '../../../utils'; +import { t } from '../../../utils'; import { settings } from '../../../settings'; import { callbacks } from '../../../callbacks'; import { hasAllPermission } from '../../../authorization'; import { Users, Rooms } from '../../../models'; +import { handleError } from '../../../../client/lib/utils/handleError'; export const call = (...args) => new Promise(function(resolve, reject) { Meteor.call(...args, function(err, result) { diff --git a/app/logger/client/logger.js b/app/logger/client/logger.js index 61eb0bf9c11..4e05f18ba3b 100644 --- a/app/logger/client/logger.js +++ b/app/logger/client/logger.js @@ -1,7 +1,7 @@ import { Template } from 'meteor/templating'; import _ from 'underscore'; -import { getConfig } from '../../ui-utils/client/config'; +import { getConfig } from '../../../client/lib/utils/getConfig'; Template.log = !!(getConfig('debug') || getConfig('debug-template')); diff --git a/app/message-mark-as-unread/client/actionButton.js b/app/message-mark-as-unread/client/actionButton.js index cc0ef68a695..6b79e608d31 100644 --- a/app/message-mark-as-unread/client/actionButton.js +++ b/app/message-mark-as-unread/client/actionButton.js @@ -3,9 +3,9 @@ import { FlowRouter } from 'meteor/kadira:flow-router'; import { RoomManager, MessageAction } from '../../ui-utils'; import { messageArgs } from '../../ui-utils/client/lib/messageArgs'; -import { handleError } from '../../utils'; import { ChatSubscription } from '../../models'; import { roomTypes } from '../../utils/client'; +import { handleError } from '../../../client/lib/utils/handleError'; Meteor.startup(() => { MessageAction.addButton({ diff --git a/app/message-pin/client/actionButton.js b/app/message-pin/client/actionButton.js index 07c0fde808d..9f5accfb832 100644 --- a/app/message-pin/client/actionButton.js +++ b/app/message-pin/client/actionButton.js @@ -6,11 +6,11 @@ import toastr from 'toastr'; import { RoomHistoryManager, MessageAction } from '../../ui-utils'; import { messageArgs } from '../../ui-utils/client/lib/messageArgs'; -import { handleError } from '../../utils'; import { settings } from '../../settings'; import { hasAtLeastOnePermission } from '../../authorization'; import { Rooms } from '../../models/client'; import { roomTypes } from '../../utils/client'; +import { handleError } from '../../../client/lib/utils/handleError'; Meteor.startup(function() { MessageAction.addButton({ diff --git a/app/message-snippet/client/page/snippetPage.js b/app/message-snippet/client/page/snippetPage.js index c4bd5d0b4a6..a65025e547c 100644 --- a/app/message-snippet/client/page/snippetPage.js +++ b/app/message-snippet/client/page/snippetPage.js @@ -3,10 +3,10 @@ import { ReactiveVar } from 'meteor/reactive-var'; import { Template } from 'meteor/templating'; import moment from 'moment'; -import { DateFormat } from '../../../lib'; import { settings } from '../../../settings'; import { Markdown } from '../../../markdown/client'; import { APIClient } from '../../../utils/client'; +import { formatTime } from '../../../../client/lib/utils/formatTime'; Template.snippetPage.helpers({ snippet() { @@ -30,7 +30,7 @@ Template.snippetPage.helpers({ time() { const snippet = Template.instance().message.get(); if (snippet !== undefined) { - return DateFormat.formatTime(snippet.ts); + return formatTime(snippet.ts); } }, }); diff --git a/app/message-star/client/actionButton.js b/app/message-star/client/actionButton.js index 092e3e3c8dc..e77ab4486d5 100644 --- a/app/message-star/client/actionButton.js +++ b/app/message-star/client/actionButton.js @@ -4,12 +4,12 @@ import { TAPi18n } from 'meteor/rocketchat:tap-i18n'; import { FlowRouter } from 'meteor/kadira:flow-router'; import toastr from 'toastr'; -import { handleError } from '../../utils'; import { settings } from '../../settings'; import { RoomHistoryManager, MessageAction } from '../../ui-utils'; import { messageArgs } from '../../ui-utils/client/lib/messageArgs'; import { Rooms } from '../../models/client'; import { roomTypes } from '../../utils/client'; +import { handleError } from '../../../client/lib/utils/handleError'; Meteor.startup(function() { MessageAction.addButton({ diff --git a/app/models/client/models/Roles.js b/app/models/client/models/Roles.js index ed4ed9fc71e..a5b63179e4e 100644 --- a/app/models/client/models/Roles.js +++ b/app/models/client/models/Roles.js @@ -3,9 +3,7 @@ import { ReactiveVar } from 'meteor/reactive-var'; import * as Models from '..'; -const Roles = new Mongo.Collection(null); - -Object.assign(Roles, { +const Roles = Object.assign(new Mongo.Collection(null), { findUsersInRole(name, scope, options) { const role = this.findOne(name); const roleScope = (role && role.scope) || 'Users'; diff --git a/app/nrr/client/nrr.js b/app/nrr/client/nrr.js index d783880c277..5ec665da590 100644 --- a/app/nrr/client/nrr.js +++ b/app/nrr/client/nrr.js @@ -17,7 +17,7 @@ const makeCursorReactive = function(obj) { } }; -Blaze.toHTMLWithDataNonReactive = function(content, data) { +const toHTMLWithDataNonReactive = function(content, data) { makeCursorReactive(data); if (data instanceof Spacebars.kw && Object.keys(data.hash).length > 0) { @@ -27,20 +27,14 @@ Blaze.toHTMLWithDataNonReactive = function(content, data) { return Tracker.nonreactive(() => Blaze.toHTMLWithData(content, data)); }; -Blaze.registerHelper('nrrargs', function(...args) { - return { - _arguments: args, - }; -}); - -Blaze.renderNonReactive = function(templateName, data) { +const renderNonReactive = function(templateName, data) { const { _arguments } = this.parentView.dataVar.get(); [templateName, data] = _arguments; return Tracker.nonreactive(() => { console.warn('Nrr template is deprecated'); - const view = new Blaze.View('nrr', () => HTML.Raw(Blaze.toHTMLWithDataNonReactive(Template[templateName], data))); + const view = new Blaze.View('nrr', () => HTML.Raw(toHTMLWithDataNonReactive(Template[templateName], data))); view.onViewReady(() => { const { onViewReady } = Template[templateName]; @@ -56,4 +50,4 @@ Blaze.renderNonReactive = function(templateName, data) { }); }; -Blaze.registerHelper('nrr', Blaze.Template('nrr', Blaze.renderNonReactive)); +Template.nrr = new Blaze.Template('nrr', renderNonReactive); diff --git a/app/otr/client/rocketchat.otr.room.js b/app/otr/client/rocketchat.otr.room.js index 6dac9aaa085..fa62a462784 100644 --- a/app/otr/client/rocketchat.otr.room.js +++ b/app/otr/client/rocketchat.otr.room.js @@ -10,9 +10,9 @@ import toastr from 'toastr'; import { OTR } from './rocketchat.otr'; import { Notifications } from '../../notifications'; -import { getUidDirectMessage } from '../../ui-utils/client/lib/getUidDirectMessage'; +import { getUidDirectMessage } from '../../../client/lib/utils/getUidDirectMessage'; import { Presence } from '../../../client/lib/presence'; -import { goToRoomById } from '../../../client/lib/goToRoomById'; +import { goToRoomById } from '../../../client/lib/utils/goToRoomById'; import { imperativeModal } from '../../../client/lib/imperativeModal'; import GenericModal from '../../../client/components/GenericModal'; diff --git a/app/search/client/provider/result.js b/app/search/client/provider/result.js index ff2cc972bf1..c5e71b6df3b 100644 --- a/app/search/client/provider/result.js +++ b/app/search/client/provider/result.js @@ -11,7 +11,7 @@ import { MessageAction, RoomHistoryManager } from '../../../ui-utils'; import { messageArgs } from '../../../ui-utils/client/lib/messageArgs'; import { Rooms } from '../../../models/client'; import { getCommonRoomEvents } from '../../../ui/client/views/app/lib/getCommonRoomEvents'; -import { goToRoomById } from '../../../../client/lib/goToRoomById'; +import { goToRoomById } from '../../../../client/lib/utils/goToRoomById'; Meteor.startup(function() { MessageAction.addButton({ diff --git a/app/slashcommands-status/lib/status.js b/app/slashcommands-status/lib/status.js index 9f7a4658846..359068a0cda 100644 --- a/app/slashcommands-status/lib/status.js +++ b/app/slashcommands-status/lib/status.js @@ -1,7 +1,7 @@ import { Meteor } from 'meteor/meteor'; import { TAPi18n } from 'meteor/rocketchat:tap-i18n'; -import { handleError, slashCommands } from '../../utils'; +import { slashCommands } from '../../utils'; import { api } from '../../../server/sdk/api'; function Status(command, params, item) { @@ -11,6 +11,7 @@ function Status(command, params, item) { Meteor.call('setUserStatus', null, params, (err) => { if (err) { if (Meteor.isClient) { + const { handleError } = require('../../../client/lib/utils/handleError'); return handleError(err); } diff --git a/app/slashcommands-topic/lib/topic.js b/app/slashcommands-topic/lib/topic.js index 3b34239ef16..dd904c54108 100644 --- a/app/slashcommands-topic/lib/topic.js +++ b/app/slashcommands-topic/lib/topic.js @@ -1,6 +1,6 @@ import { Meteor } from 'meteor/meteor'; -import { handleError, slashCommands } from '../../utils'; +import { slashCommands } from '../../utils'; import { ChatRoom } from '../../models'; import { callbacks } from '../../callbacks'; import { hasPermission } from '../../authorization'; @@ -11,6 +11,7 @@ function Topic(command, params, item) { Meteor.call('saveRoomSettings', item.rid, 'roomTopic', params, (err) => { if (err) { if (Meteor.isClient) { + const { handleError } = require('../../../client/lib/utils/handleError'); return handleError(err); } throw err; diff --git a/app/threads/client/components/ThreadComponent.tsx b/app/threads/client/components/ThreadComponent.tsx index 6e30d2d57cd..409eb1254c7 100644 --- a/app/threads/client/components/ThreadComponent.tsx +++ b/app/threads/client/components/ThreadComponent.tsx @@ -16,7 +16,7 @@ import ThreadView from './ThreadView'; import { IMessage } from '../../../../definition/IMessage'; import { IRoom } from '../../../../definition/IRoom'; import { useTabBarOpenUserInfo } from '../../../../client/views/room/providers/ToolboxProvider'; -import { mapMessageFromApi } from '../../../../client/lib/fromApi'; +import { mapMessageFromApi } from '../../../../client/lib/utils/mapMessageFromApi'; const subscriptionFields = {}; diff --git a/app/threads/client/flextab/messageBoxFollow.js b/app/threads/client/flextab/messageBoxFollow.js index 42c485381d9..bfd724a3eb8 100644 --- a/app/threads/client/flextab/messageBoxFollow.js +++ b/app/threads/client/flextab/messageBoxFollow.js @@ -1,11 +1,11 @@ import { Template } from 'meteor/templating'; +import { callWithErrorHandling } from '../../../../client/lib/utils/callWithErrorHandling'; import './messageBoxFollow.html'; -import { call } from '../../../ui-utils/client'; Template.messageBoxFollow.events({ 'click .js-follow'() { const { tmid } = this; - call('followMessage', { mid: tmid }); + callWithErrorHandling('followMessage', { mid: tmid }); }, }); diff --git a/app/threads/client/flextab/thread.js b/app/threads/client/flextab/thread.js index b74f61ce94b..ecf508efbf9 100644 --- a/app/threads/client/flextab/thread.js +++ b/app/threads/client/flextab/thread.js @@ -8,7 +8,7 @@ import { Tracker } from 'meteor/tracker'; import { FlowRouter } from 'meteor/kadira:flow-router'; import { chatMessages, ChatMessages } from '../../../ui'; -import { call, keyCodes } from '../../../ui-utils/client'; +import { callWithErrorHandling } from '../../../../client/lib/utils/callWithErrorHandling'; import { messageContext } from '../../../ui-utils/client/lib/messageContext'; import { upsertMessageBulk } from '../../../ui-utils/client/lib/RoomHistoryManager'; import { Messages } from '../../../models'; @@ -20,6 +20,7 @@ import { settings } from '../../../settings/client'; import { callbacks } from '../../../callbacks/client'; import './messageBoxFollow'; import { getCommonRoomEvents } from '../../../ui/client/views/app/lib/getCommonRoomEvents'; +import { keyCodes } from '../../../../client/lib/utils/keyCodes'; const sort = { ts: 1 }; @@ -243,7 +244,7 @@ Template.thread.onCreated(async function() { this.state.set('loading', true); - const messages = await call('getThreadMessages', { tmid }); + const messages = await callWithErrorHandling('getThreadMessages', { tmid }); upsertMessageBulk({ msgs: messages }, this.Threads); diff --git a/app/threads/client/messageAction/follow.js b/app/threads/client/messageAction/follow.js index b2f98475257..821c66d4e6a 100644 --- a/app/threads/client/messageAction/follow.js +++ b/app/threads/client/messageAction/follow.js @@ -5,9 +5,10 @@ import toastr from 'toastr'; import { Messages } from '../../../models/client'; import { settings } from '../../../settings/client'; -import { MessageAction, call } from '../../../ui-utils/client'; +import { MessageAction } from '../../../ui-utils/client'; import { messageArgs } from '../../../ui-utils/client/lib/messageArgs'; import { roomTypes } from '../../../utils/client'; +import { callWithErrorHandling } from '../../../../client/lib/utils/callWithErrorHandling'; Meteor.startup(function() { Tracker.autorun(() => { @@ -21,7 +22,7 @@ Meteor.startup(function() { context: ['message', 'message-mobile', 'threads'], async action() { const { msg } = messageArgs(this); - call('followMessage', { mid: msg._id }).then(() => + callWithErrorHandling('followMessage', { mid: msg._id }).then(() => toastr.success(TAPi18n.__('You_followed_this_message')), ); }, diff --git a/app/threads/client/messageAction/unfollow.js b/app/threads/client/messageAction/unfollow.js index 44e73434445..a77ea9ffdc5 100644 --- a/app/threads/client/messageAction/unfollow.js +++ b/app/threads/client/messageAction/unfollow.js @@ -5,7 +5,8 @@ import toastr from 'toastr'; import { Messages } from '../../../models/client'; import { settings } from '../../../settings/client'; -import { MessageAction, call } from '../../../ui-utils/client'; +import { MessageAction } from '../../../ui-utils/client'; +import { callWithErrorHandling } from '../../../../client/lib/utils/callWithErrorHandling'; import { messageArgs } from '../../../ui-utils/client/lib/messageArgs'; Meteor.startup(function() { @@ -20,7 +21,7 @@ Meteor.startup(function() { context: ['message', 'message-mobile', 'threads'], async action() { const { msg } = messageArgs(this); - call('unfollowMessage', { mid: msg._id }).then(() => + callWithErrorHandling('unfollowMessage', { mid: msg._id }).then(() => toastr.success(TAPi18n.__('You_unfollowed_this_message')), ); }, diff --git a/app/tokenpass/client/tokenpassChannelSettings.js b/app/tokenpass/client/tokenpassChannelSettings.js index 63525138d9f..91044cb68ef 100644 --- a/app/tokenpass/client/tokenpassChannelSettings.js +++ b/app/tokenpass/client/tokenpassChannelSettings.js @@ -4,8 +4,9 @@ import { Template } from 'meteor/templating'; import { TAPi18n } from 'meteor/rocketchat:tap-i18n'; import toastr from 'toastr'; -import { t, handleError } from '../../utils'; +import { t } from '../../utils'; import { ChatRoom } from '../../models'; +import { handleError } from '../../../client/lib/utils/handleError'; Template.channelSettings__tokenpass.helpers({ addDisabled() { diff --git a/app/ui-cached-collection/client/models/CachedCollection.js b/app/ui-cached-collection/client/models/CachedCollection.js index eec9930c90d..506768f79ea 100644 --- a/app/ui-cached-collection/client/models/CachedCollection.js +++ b/app/ui-cached-collection/client/models/CachedCollection.js @@ -10,8 +10,8 @@ import { Emitter } from '@rocket.chat/emitter'; import { callbacks } from '../../../callbacks'; import Notifications from '../../../notifications/client/lib/Notifications'; -import { getConfig } from '../../../ui-utils/client/config'; -import { callMethod } from '../../../ui-utils/client/lib/callMethod'; +import { getConfig } from '../../../../client/lib/utils/getConfig'; +import { call } from '../../../../client/lib/utils/call'; const wrap = (fn) => (...args) => new Promise((resolve, reject) => { fn(...args, (err, result) => { @@ -218,7 +218,7 @@ export class CachedCollection extends Emitter { async loadFromServer() { const startTime = new Date(); const lastTime = this.updatedAt; - const data = await callMethod(this.methodName); + const data = await call(this.methodName); this.log(`${ data.length } records loaded from server`); data.forEach((record) => { callbacks.run(`cachedCollection-loadFromServer-${ this.name }`, record, 'changed'); @@ -318,7 +318,7 @@ export class CachedCollection extends Emitter { this.log(`syncing from ${ this.updatedAt }`); - const data = await callMethod(this.syncMethodName, this.updatedAt); + const data = await call(this.syncMethodName, this.updatedAt); let changes = []; if (data.update && data.update.length > 0) { diff --git a/app/ui-login/client/login/form.js b/app/ui-login/client/login/form.js index 7cfa83b116f..dd9eda6c08b 100644 --- a/app/ui-login/client/login/form.js +++ b/app/ui-login/client/login/form.js @@ -10,7 +10,8 @@ import toastr from 'toastr'; import { settings } from '../../../settings'; import { callbacks } from '../../../callbacks'; -import { t, handleError } from '../../../utils'; +import { t } from '../../../utils'; +import { handleError } from '../../../../client/lib/utils/handleError'; Template.loginForm.helpers({ userName() { diff --git a/app/ui-master/client/body.js b/app/ui-master/client/body.js index 649e3cadab5..5f246e15365 100644 --- a/app/ui-master/client/body.js +++ b/app/ui-master/client/body.js @@ -7,12 +7,14 @@ import { Template } from 'meteor/templating'; import { t } from '../../utils/client'; import { chatMessages } from '../../ui'; -import { Layout, popover, fireGlobalEvent, RoomManager } from '../../ui-utils'; +import { popover, RoomManager } from '../../ui-utils'; import { settings } from '../../settings'; import { ChatSubscription } from '../../models'; import './body.html'; import { imperativeModal } from '../../../client/lib/imperativeModal'; import GenericModal from '../../../client/components/GenericModal'; +import { fireGlobalEvent } from '../../../client/lib/utils/fireGlobalEvent'; +import { isLayoutEmbedded } from '../../../client/lib/utils/isLayoutEmbedded'; Template.body.onRendered(function() { new Clipboard('.clipboard'); @@ -99,7 +101,7 @@ Template.body.onRendered(function() { }; this.autorun(() => { - if (Layout.isEmbedded()) { + if (isLayoutEmbedded()) { $(document.body).on('click', 'a', handleMessageLinkClick); } else { $(document.body).off('click', 'a', handleMessageLinkClick); diff --git a/app/ui-master/client/main.js b/app/ui-master/client/main.js index fd855764af5..46f6a826d52 100644 --- a/app/ui-master/client/main.js +++ b/app/ui-master/client/main.js @@ -5,22 +5,22 @@ import { Session } from 'meteor/session'; import { Template } from 'meteor/templating'; import { getUserPreference } from '../../utils/client'; -import { mainReady, Layout, iframeLogin } from '../../ui-utils'; +import { mainReady, iframeLogin } from '../../ui-utils'; import { settings } from '../../settings'; import { CachedChatSubscription, Roles, Users } from '../../models'; import { CachedCollectionManager } from '../../ui-cached-collection'; import { tooltip } from '../../ui/client/components/tooltip'; import { callbacks } from '../../callbacks/client'; import { isSyncReady } from '../../../client/lib/userData'; -import { fireGlobalEvent } from '../../ui-utils/client'; - +import { fireGlobalEvent } from '../../../client/lib/utils/fireGlobalEvent'; import './main.html'; +import { isLayoutEmbedded } from '../../../client/lib/utils/isLayoutEmbedded'; callbacks.add('afterLogoutCleanUp', () => fireGlobalEvent('Custom_Script_On_Logout'), callbacks.priority.LOW, 'custom-script-on-logout'); Template.main.helpers({ - removeSidenav: () => Layout.isEmbedded() && !/^\/admin/.test(FlowRouter.current().route.path), + removeSidenav: () => isLayoutEmbedded() && !/^\/admin/.test(FlowRouter.current().route.path), logged: () => { if (!!Meteor.userId() || (settings.get('Accounts_AllowAnonymousRead') === true && Session.get('forceLogin') !== true)) { document.documentElement.classList.add('noscroll'); @@ -78,7 +78,7 @@ Template.main.helpers({ fireGlobalEvent('Custom_Script_Logged_In'); }, embeddedVersion: () => { - if (Layout.isEmbedded()) { + if (isLayoutEmbedded()) { return 'embedded-view'; } }, diff --git a/app/ui-message/client/message.html b/app/ui-message/client/message.html index 5e3d05079d9..a5ade319b0c 100644 --- a/app/ui-message/client/message.html +++ b/app/ui-message/client/message.html @@ -26,7 +26,7 @@ {{#if msg.emoji}} {{else}} diff --git a/app/ui-message/client/message.js b/app/ui-message/client/message.js index ecf101d2121..e8adedbfc36 100644 --- a/app/ui-message/client/message.js +++ b/app/ui-message/client/message.js @@ -5,18 +5,20 @@ import { Template } from 'meteor/templating'; import { TAPi18n } from 'meteor/rocketchat:tap-i18n'; import { escapeHTML } from '@rocket.chat/string-helpers'; -import { timeAgo, formatDateAndTime } from '../../lib/client/lib/formatDate'; -import { DateFormat } from '../../lib/client'; +import { timeAgo } from '../../../client/lib/utils/timeAgo'; +import { formatDateAndTime } from '../../../client/lib/utils/formatDateAndTime'; import { normalizeThreadTitle } from '../../threads/client/lib/normalizeThreadTitle'; import { MessageTypes, MessageAction } from '../../ui-utils/client'; import { RoomRoles, UserRoles, Roles } from '../../models/client'; import { Markdown } from '../../markdown/client'; import { t, roomTypes } from '../../utils'; -import './messageThread'; import { AutoTranslate } from '../../autotranslate/client'; import { renderMentions } from '../../mentions/client/client'; -import { renderMessageBody } from '../../../client/lib/renderMessageBody'; +import { renderMessageBody } from '../../../client/lib/utils/renderMessageBody'; import { settings } from '../../settings/client'; +import { formatTime } from '../../../client/lib/utils/formatTime'; +import { formatDate } from '../../../client/lib/utils/formatDate'; +import './messageThread'; import './message.html'; const renderBody = (msg, settings) => { @@ -203,11 +205,11 @@ Template.message.helpers({ time() { const { msg, timeAgo: useTimeAgo } = this; - return useTimeAgo ? timeAgo(msg.ts) : DateFormat.formatTime(msg.ts); + return useTimeAgo ? timeAgo(msg.ts) : formatTime(msg.ts); }, date() { const { msg } = this; - return DateFormat.formatDate(msg.ts); + return formatDate(msg.ts); }, isTemp() { const { msg } = this; @@ -250,7 +252,7 @@ Template.message.helpers({ }, editTime() { const { msg } = this; - return msg.editedAt ? DateFormat.formatDateAndTime(msg.editedAt) : ''; + return msg.editedAt ? formatDateAndTime(msg.editedAt) : ''; }, editedBy() { const { msg } = this; diff --git a/app/ui-message/client/messageBox/messageBox.js b/app/ui-message/client/messageBox/messageBox.js index 7fcf12f371a..d34756527e5 100644 --- a/app/ui-message/client/messageBox/messageBox.js +++ b/app/ui-message/client/messageBox/messageBox.js @@ -22,8 +22,6 @@ import { messageBox, popover, call, - keyCodes, - isRTL, } from '../../../ui-utils'; import { t, @@ -37,6 +35,8 @@ import './messageBoxAudioMessage'; import './messageBoxNotSubscribed'; import './messageBox.html'; import './messageBoxReadOnly'; +import { keyCodes } from '../../../../client/lib/utils/keyCodes'; +import { isRTL } from '../../../../client/lib/utils/isRTL'; Template.messageBox.onCreated(function() { this.state = new ReactiveDict(); diff --git a/app/ui-message/client/messageBox/messageBoxTyping.js b/app/ui-message/client/messageBox/messageBoxTyping.js index 8fa993112a0..ae5738f355a 100644 --- a/app/ui-message/client/messageBox/messageBoxTyping.js +++ b/app/ui-message/client/messageBox/messageBoxTyping.js @@ -2,7 +2,7 @@ import { Template } from 'meteor/templating'; import { MsgTyping } from '../../../ui'; import { t } from '../../../utils'; -import { getConfig } from '../../../ui-utils/client/config'; +import { getConfig } from '../../../../client/lib/utils/getConfig'; import './messageBoxTyping.html'; const maxUsernames = parseInt(getConfig('max-usernames-typing')) || 4; diff --git a/app/ui-message/client/messageThread.js b/app/ui-message/client/messageThread.js index d18ac495600..7f45f140c6d 100644 --- a/app/ui-message/client/messageThread.js +++ b/app/ui-message/client/messageThread.js @@ -2,10 +2,10 @@ import { ReactiveVar } from 'meteor/reactive-var'; import { Template } from 'meteor/templating'; import _ from 'underscore'; -import { call } from '../../ui-utils/client'; +import { callWithErrorHandling } from '../../../client/lib/utils/callWithErrorHandling'; import { Messages } from '../../models/client'; -import './messageThread.html'; import { normalizeThreadTitle } from '../../threads/client/lib/normalizeThreadTitle'; +import './messageThread.html'; const findParentMessage = (() => { const waiting = []; @@ -15,7 +15,7 @@ const findParentMessage = (() => { const getMessages = _.debounce(async function() { const _tmp = [...waiting]; waiting.length = 0; - resolve(call('getMessages', _tmp)); + resolve(callWithErrorHandling('getMessages', _tmp)); pending = new Promise((r) => { resolve = r; }); }, 500); diff --git a/app/ui-message/client/popup/messagePopupConfig.js b/app/ui-message/client/popup/messagePopupConfig.js index 7a0deb077f7..6a37e6c94c5 100644 --- a/app/ui-message/client/popup/messagePopupConfig.js +++ b/app/ui-message/client/popup/messagePopupConfig.js @@ -12,7 +12,7 @@ import { Messages, Subscriptions } from '../../../models/client'; import { settings } from '../../../settings/client'; import { hasAllPermission, hasAtLeastOnePermission } from '../../../authorization/client'; import { EmojiPicker, emoji } from '../../../emoji'; -import { call } from '../../../ui-utils/client'; +import { callWithErrorHandling } from '../../../../client/lib/utils/callWithErrorHandling'; import { t, getUserPreference, slashCommands } from '../../../utils/client'; import { customMessagePopups } from './customMessagePopups'; import './messagePopupConfig.html'; @@ -61,7 +61,7 @@ const reloadUsersFromRoomMessages = (rid, template) => { const fetchUsersFromServer = _.throttle(async (filterText, records, rid, cb) => { const usernames = records.map(({ username }) => username); - const { users } = await call('spotlight', filterText, usernames, { users: true, mentions: true }, rid); + const { users } = await callWithErrorHandling('spotlight', filterText, usernames, { users: true, mentions: true }, rid); if (!users || users.length <= 0) { return; @@ -95,7 +95,7 @@ const fetchRoomsFromServer = _.throttle(async (filterText, records, rid, cb) => return; } - const { rooms } = await call('spotlight', filterText, null, { rooms: true, mentions: true }, rid); + const { rooms } = await callWithErrorHandling('spotlight', filterText, null, { rooms: true, mentions: true }, rid); if (!rooms || rooms.length <= 0) { return; diff --git a/app/ui-message/client/popup/messagePopupEmoji.html b/app/ui-message/client/popup/messagePopupEmoji.html index c554520afd6..c064ff72cbf 100644 --- a/app/ui-message/client/popup/messagePopupEmoji.html +++ b/app/ui-message/client/popup/messagePopupEmoji.html @@ -1,4 +1,4 @@ - {{> renderEmoji _id}} + {{{renderEmoji _id}}} {{_id}} diff --git a/app/ui-utils/client/config.js b/app/ui-utils/client/config.js deleted file mode 100644 index ce484f86a7d..00000000000 --- a/app/ui-utils/client/config.js +++ /dev/null @@ -1,9 +0,0 @@ -import { Meteor } from 'meteor/meteor'; - -const url = new URL(window.location); -const keys = new Set(); - -export const getConfig = (key) => { - keys.add(key); - return url.searchParams.get(key) || Meteor._localStorage.getItem(`rc-config-${ key }`); -}; diff --git a/app/ui-utils/client/index.js b/app/ui-utils/client/index.js index b94a368d4ea..c9ef5475e9c 100644 --- a/app/ui-utils/client/index.js +++ b/app/ui-utils/client/index.js @@ -2,7 +2,6 @@ export { modal } from './lib/modal'; export { SideNav } from './lib/SideNav'; export { AccountBox } from './lib/AccountBox'; export { menu } from './lib/menu'; -export { call } from './lib/callMethod'; export { MessageAction } from './lib/MessageAction'; export { messageBox } from './lib/messageBox'; export { popover } from './lib/popover'; @@ -10,18 +9,11 @@ export { readMessage } from './lib/readMessages'; export { RoomManager } from './lib/RoomManager'; export { upsertMessage, RoomHistoryManager, normalizeThreadMessage } from './lib/RoomHistoryManager'; export { mainReady } from './lib/mainReady'; -export { Layout } from './lib/Layout'; export { IframeLogin, iframeLogin } from './lib/IframeLogin'; -export { fireGlobalEvent } from './lib/fireGlobalEvent'; -export { getAvatarAsPng } from './lib/avatar'; export { popout } from './lib/popout'; export { messageProperties } from '../lib/MessageProperties'; export { MessageTypes } from '../lib/MessageTypes'; export { Message } from '../lib/Message'; export { openRoom } from './lib/openRoom'; -export { warnUserDeletionMayRemoveRooms } from './lib/warnUserDeletionMayRemoveRooms'; -export * from './lib/rtl'; -export * from './lib/keyCodes'; -export * from './lib/prependReplies'; export * from './lib/collapseArrow'; export * from './lib/messageArgs'; diff --git a/app/ui-utils/client/lib/Layout.js b/app/ui-utils/client/lib/Layout.js deleted file mode 100644 index 2158d80f2a9..00000000000 --- a/app/ui-utils/client/lib/Layout.js +++ /dev/null @@ -1,17 +0,0 @@ -import { Tracker } from 'meteor/tracker'; -import { FlowRouter } from 'meteor/kadira:flow-router'; -import { ReactiveVar } from 'meteor/reactive-var'; - -export const Layout = new class RocketChatLayout { - constructor() { - this.embedded = new ReactiveVar(); - Tracker.autorun(() => { - this.layout = FlowRouter.getQueryParam('layout'); - this.embedded.set(this.layout === 'embedded'); - }); - } - - isEmbedded() { - return this.embedded.get(); - } -}(); diff --git a/app/ui-utils/client/lib/MessageAction.js b/app/ui-utils/client/lib/MessageAction.js index f48800e4301..fbcc4b2a4f6 100644 --- a/app/ui-utils/client/lib/MessageAction.js +++ b/app/ui-utils/client/lib/MessageAction.js @@ -10,21 +10,14 @@ import { Tracker } from 'meteor/tracker'; import { Session } from 'meteor/session'; import { messageArgs } from './messageArgs'; -import { roomTypes, canDeleteMessage } from '../../../utils/client'; +import { roomTypes } from '../../../utils/client'; import { Messages, Rooms, Subscriptions } from '../../../models/client'; import { hasAtLeastOnePermission, hasPermission } from '../../../authorization/client'; import { modal } from './modal'; import { imperativeModal } from '../../../../client/lib/imperativeModal'; import ReactionList from '../../../../client/components/modals/ReactionList'; - -const call = (method, ...args) => new Promise((resolve, reject) => { - Meteor.call(method, ...args, function(err, data) { - if (err) { - return reject(err); - } - resolve(data); - }); -}); +import { call } from '../../../../client/lib/utils/call'; +import { canDeleteMessage } from '../../../../client/lib/utils/canDeleteMessage'; export const addMessageToList = (messagesList, message) => { // checks if the message is not already on the list diff --git a/app/ui-utils/client/lib/RoomHistoryManager.js b/app/ui-utils/client/lib/RoomHistoryManager.js index 5e6a169b6d8..7a2e5e9af8f 100644 --- a/app/ui-utils/client/lib/RoomHistoryManager.js +++ b/app/ui-utils/client/lib/RoomHistoryManager.js @@ -10,10 +10,10 @@ import { escapeHTML } from '@rocket.chat/string-helpers'; import { promises } from '../../../promises/client'; import { RoomManager } from './RoomManager'; import { readMessage } from './readMessages'; -import { renderMessageBody } from '../../../../client/lib/renderMessageBody'; -import { getConfig } from '../config'; +import { renderMessageBody } from '../../../../client/lib/utils/renderMessageBody'; +import { getConfig } from '../../../../client/lib/utils/getConfig'; import { ChatMessage, ChatSubscription, ChatRoom } from '../../../models'; -import { call } from './callMethod'; +import { callWithErrorHandling } from '../../../../client/lib/utils/callWithErrorHandling'; import { filterMarkdown } from '../../../markdown/lib/markdown'; import { getUserPreference } from '../../../utils/client'; @@ -190,7 +190,7 @@ export const RoomHistoryManager = new class extends Emitter { } const showMessageInMainThread = getUserPreference(Meteor.userId(), 'showMessageInMainThread', false); - const result = await call('loadHistory', rid, ts, limit, ls, showMessageInMainThread); + const result = await callWithErrorHandling('loadHistory', rid, ts, limit, ls, showMessageInMainThread); this.unqueue(); @@ -269,7 +269,7 @@ export const RoomHistoryManager = new class extends Emitter { const { ts } = lastMessage; if (ts) { - const result = await call('loadNextMessages', rid, ts, limit); + const result = await callWithErrorHandling('loadNextMessages', rid, ts, limit); upsertMessageBulk({ msgs: Array.from(result.messages).filter((msg) => msg.t !== 'command'), subscription, diff --git a/app/ui-utils/client/lib/RoomManager.js b/app/ui-utils/client/lib/RoomManager.js index ed01f1766fd..014d1ac0b75 100644 --- a/app/ui-utils/client/lib/RoomManager.js +++ b/app/ui-utils/client/lib/RoomManager.js @@ -6,7 +6,7 @@ import { Blaze } from 'meteor/blaze'; import { FlowRouter } from 'meteor/kadira:flow-router'; import _ from 'underscore'; -import { fireGlobalEvent } from './fireGlobalEvent'; +import { fireGlobalEvent } from '../../../../client/lib/utils/fireGlobalEvent'; import { upsertMessage, RoomHistoryManager } from './RoomHistoryManager'; import { mainReady } from './mainReady'; import { menu } from './menu'; @@ -15,9 +15,9 @@ import { callbacks } from '../../../callbacks'; import { Notifications } from '../../../notifications'; import { CachedChatRoom, ChatMessage, ChatSubscription, CachedChatSubscription, ChatRoom } from '../../../models'; import { CachedCollectionManager } from '../../../ui-cached-collection'; -import { getConfig } from '../config'; +import { getConfig } from '../../../../client/lib/utils/getConfig'; import { ROOM_DATA_STREAM } from '../../../utils/stream/constants'; -import { call } from '..'; +import { callWithErrorHandling } from '../../../../client/lib/utils/callWithErrorHandling'; import { RoomManager as NewRoomManager } from '../../../../client/lib/RoomManager'; const maxRoomsOpen = parseInt(getConfig('maxRoomsOpen')) || 5; @@ -286,7 +286,7 @@ const loadMissedMessages = async function(rid) { try { - const result = await call('loadMissedMessages', rid, lastMessage.ts); + const result = await callWithErrorHandling('loadMissedMessages', rid, lastMessage.ts); if (result) { const subscription = ChatSubscription.findOne({ rid }); return Promise.all(Array.from(result).map((msg) => upsertMessage({ msg, subscription }))); diff --git a/app/ui-utils/client/lib/avatar.js b/app/ui-utils/client/lib/avatar.js deleted file mode 100644 index c7a038126d8..00000000000 --- a/app/ui-utils/client/lib/avatar.js +++ /dev/null @@ -1,26 +0,0 @@ -import { Blaze } from 'meteor/blaze'; - -import { getUserAvatarURL } from '../../../utils/lib/getUserAvatarURL'; - -Blaze.registerHelper('avatarUrlFromUsername', getUserAvatarURL); - -export const getAvatarAsPng = function(username, cb) { - const image = new Image(); - image.src = getUserAvatarURL(username); - image.onload = function() { - const canvas = document.createElement('canvas'); - canvas.width = image.width; - canvas.height = image.height; - const context = canvas.getContext('2d'); - context.drawImage(image, 0, 0); - try { - return cb(canvas.toDataURL('image/png')); - } catch (e) { - return cb(''); - } - }; - image.onerror = function() { - return cb(''); - }; - return image.onerror; -}; diff --git a/app/ui-utils/client/lib/callMethod.js b/app/ui-utils/client/lib/callMethod.js deleted file mode 100644 index c1b05108ad8..00000000000 --- a/app/ui-utils/client/lib/callMethod.js +++ /dev/null @@ -1,28 +0,0 @@ -import { Meteor } from 'meteor/meteor'; - -import { handleError } from '../../../utils/client/lib/handleError'; - -/** - * Wraps a Meteor method into a Promise. - * This is particularly useful for creating information dialogs after execution of a Meteor method - * @param {The Meteor method to be calls} method - * @param {the method's parameters} params - */ -export const call = (method, ...params) => new Promise((resolve, reject) => { - Meteor.call(method, ...params, (err, result) => { - if (err) { - handleError(err); - return reject(err); - } - return resolve(result); - }); -}); - -export const callMethod = (method, ...params) => new Promise((resolve, reject) => { - Meteor.call(method, ...params, (err, result) => { - if (err) { - return reject(err); - } - return resolve(result); - }); -}); diff --git a/app/ui-utils/client/lib/fireGlobalEvent.js b/app/ui-utils/client/lib/fireGlobalEvent.js deleted file mode 100644 index c179a29496b..00000000000 --- a/app/ui-utils/client/lib/fireGlobalEvent.js +++ /dev/null @@ -1,21 +0,0 @@ -import { Tracker } from 'meteor/tracker'; - -import { settings } from '../../../settings'; - -export const fireGlobalEvent = function _fireGlobalEvent(eventName, params) { - window.dispatchEvent(new CustomEvent(eventName, { detail: params })); - - Tracker.autorun((computation) => { - const enabled = settings.get('Iframe_Integration_send_enable'); - if (enabled === undefined) { - return; - } - computation.stop(); - if (enabled) { - parent.postMessage({ - eventName, - data: params, - }, settings.get('Iframe_Integration_send_target_origin')); - } - }); -}; diff --git a/app/ui-utils/client/lib/getUidDirectMessage.js b/app/ui-utils/client/lib/getUidDirectMessage.js deleted file mode 100644 index ecfe3b48fc9..00000000000 --- a/app/ui-utils/client/lib/getUidDirectMessage.js +++ /dev/null @@ -1,15 +0,0 @@ -import { Meteor } from 'meteor/meteor'; - -import { Rooms } from '../../../models/client'; - -export const getUidDirectMessage = (rid, userId = Meteor.userId()) => { - const room = Rooms.findOne({ _id: rid }, { fields: { uids: 1 } }); - - if (!room || !room.uids || room.uids.length > 2) { - return false; - } - - const other = room && room.uids.filter((uid) => uid !== userId); - - return other && other[0]; -}; diff --git a/app/ui-utils/client/lib/messageContext.js b/app/ui-utils/client/lib/messageContext.js index 89712cb48cb..82cf52c2d1d 100644 --- a/app/ui-utils/client/lib/messageContext.js +++ b/app/ui-utils/client/lib/messageContext.js @@ -6,12 +6,13 @@ import { Tracker } from 'meteor/tracker'; import { Subscriptions, Rooms, Users } from '../../../models/client'; import { hasPermission } from '../../../authorization/client'; import { settings } from '../../../settings/client'; -import { getUserPreference, roomTypes, handleError } from '../../../utils/client'; +import { getUserPreference, roomTypes } from '../../../utils/client'; import { AutoTranslate } from '../../../autotranslate/client'; -import { Layout } from './Layout'; -import { fireGlobalEvent } from './fireGlobalEvent'; +import { fireGlobalEvent } from '../../../../client/lib/utils/fireGlobalEvent'; import { actionLinks } from '../../../action-links/client'; -import { goToRoomById } from '../../../../client/lib/goToRoomById'; +import { goToRoomById } from '../../../../client/lib/utils/goToRoomById'; +import { isLayoutEmbedded } from '../../../../client/lib/utils/isLayoutEmbedded'; +import { handleError } from '../../../../client/lib/utils/handleError'; const fields = { name: 1, username: 1, 'settings.preferences.enableMessageParserEarlyAdoption': 1, 'settings.preferences.showMessageInMainThread': 1, 'settings.preferences.autoImageLoad': 1, 'settings.preferences.saveMobileBandwidth': 1, 'settings.preferences.collapseMediaByDefault': 1, 'settings.preferences.hideRoles': 1 }; @@ -34,7 +35,7 @@ export function messageContext({ rid } = Template.instance()) { e.stopPropagation(); }; - const runAction = Layout.isEmbedded() ? (msg, e) => { + const runAction = isLayoutEmbedded() ? (msg, e) => { const { actionlink } = e.currentTarget.dataset; return fireGlobalEvent('click-action-link', { actionlink, diff --git a/app/ui-utils/client/lib/modal.js b/app/ui-utils/client/lib/modal.js index 1971ba908b0..d7d12baadb4 100644 --- a/app/ui-utils/client/lib/modal.js +++ b/app/ui-utils/client/lib/modal.js @@ -2,8 +2,9 @@ import { Meteor } from 'meteor/meteor'; import { Blaze } from 'meteor/blaze'; import { Template } from 'meteor/templating'; -import { t, getUserPreference, handleError } from '../../../utils'; +import { t, getUserPreference } from '../../../utils'; import './modal.html'; +import { handleError } from '../../../../client/lib/utils/handleError'; let modalStack = []; diff --git a/app/ui-utils/client/lib/openRoom.js b/app/ui-utils/client/lib/openRoom.js index 7d4261f7c29..469145623eb 100644 --- a/app/ui-utils/client/lib/openRoom.js +++ b/app/ui-utils/client/lib/openRoom.js @@ -9,10 +9,12 @@ import { Messages, ChatSubscription } from '../../../models'; import { settings } from '../../../settings'; import { callbacks } from '../../../callbacks'; import { roomTypes } from '../../../utils'; -import { call, callMethod } from './callMethod'; -import { RoomManager, fireGlobalEvent, RoomHistoryManager } from '..'; +import { callWithErrorHandling } from '../../../../client/lib/utils/callWithErrorHandling'; +import { call } from '../../../../client/lib/utils/call'; +import { RoomManager, RoomHistoryManager } from '..'; import { RoomManager as NewRoomManager } from '../../../../client/lib/RoomManager'; import { Rooms } from '../../../models/client'; +import { fireGlobalEvent } from '../../../../client/lib/utils/fireGlobalEvent'; window.currentTracker = undefined; @@ -34,7 +36,7 @@ export const openRoom = async function(type, name, render = true) { } try { - const room = roomTypes.findRoom(type, name, user) || await callMethod('getRoomByTypeAndName', type, name); + const room = roomTypes.findRoom(type, name, user) || await call('getRoomByTypeAndName', type, name); Rooms.upsert({ _id: room._id }, _.omit(room, '_id')); if (room._id !== name && type === 'd') { // Redirect old url using username to rid @@ -67,14 +69,14 @@ export const openRoom = async function(type, name, render = true) { // update user's room subscription const sub = ChatSubscription.findOne({ rid: room._id }); if (sub && sub.open === false) { - call('openRoom', room._id); + callWithErrorHandling('openRoom', room._id); } if (FlowRouter.getQueryParam('msg')) { const messageId = FlowRouter.getQueryParam('msg'); const msg = { _id: messageId, rid: room._id }; - const message = Messages.findOne({ _id: msg._id }) || (await call('getMessages', [msg._id]))[0]; + const message = Messages.findOne({ _id: msg._id }) || (await callWithErrorHandling('getMessages', [msg._id]))[0]; if (message && (message.tmid || message.tcount)) { return FlowRouter.setParams({ tab: 'thread', context: message.tmid || message._id }); @@ -90,7 +92,7 @@ export const openRoom = async function(type, name, render = true) { } catch (error) { c.stop(); if (type === 'd') { - const result = await call('createDirectMessage', ...name.split(', ')); + const result = await callWithErrorHandling('createDirectMessage', ...name.split(', ')); if (result) { return FlowRouter.go('direct', { rid: result.rid }, FlowRouter.current().queryParams); } diff --git a/app/ui-utils/client/lib/prependReplies.js b/app/ui-utils/client/lib/prependReplies.js deleted file mode 100644 index eb9b3a8fd5e..00000000000 --- a/app/ui-utils/client/lib/prependReplies.js +++ /dev/null @@ -1,23 +0,0 @@ -import { Meteor } from 'meteor/meteor'; - -import { MessageAction } from './MessageAction'; -import { Rooms, Users } from '../../../models/client'; - -export const prependReplies = async (msg, replies = [], mention = false) => { - const { username } = Users.findOne({ _id: Meteor.userId() }, { fields: { username: 1 } }); - - const chunks = await Promise.all(replies.map(async ({ _id, rid, u }) => { - const permalink = await MessageAction.getPermaLink(_id); - const room = Rooms.findOne(rid, { fields: { t: 1 } }); - - let chunk = `[ ](${ permalink })`; - if (room.t === 'd' && u.username !== username && mention) { - chunk += ` @${ u.username }`; - } - - return chunk; - })); - - chunks.push(msg); - return chunks.join(' '); -}; diff --git a/app/ui-utils/client/lib/rtl.js b/app/ui-utils/client/lib/rtl.js deleted file mode 100644 index 64a55f8dbc1..00000000000 --- a/app/ui-utils/client/lib/rtl.js +++ /dev/null @@ -1,7 +0,0 @@ -// http://stackoverflow.com/a/14824756 - -const ltrChars = 'A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02B8\u0300-\u0590\u0800-\u1FFF\u2C00-\uFB1C\uFDFE-\uFE6F\uFEFD-\uFFFF'; -const rtlChars = '\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC'; -const rtlRegExp = new RegExp(`^[^${ ltrChars }]*[${ rtlChars }]`); - -export const isRTL = (text) => rtlRegExp.test(text); diff --git a/app/ui-utils/client/lib/warnUserDeletionMayRemoveRooms.js b/app/ui-utils/client/lib/warnUserDeletionMayRemoveRooms.js deleted file mode 100644 index 31c36278c99..00000000000 --- a/app/ui-utils/client/lib/warnUserDeletionMayRemoveRooms.js +++ /dev/null @@ -1,63 +0,0 @@ -import { TAPi18n } from 'meteor/rocketchat:tap-i18n'; - -import { t } from '../../../utils/client'; -import { modal } from './modal'; - -export const warnUserDeletionMayRemoveRooms = async function(userId, callbackFn, { warningKey, confirmButtonKey, closeOnConfirm = false, skipModalIfEmpty = false, shouldChangeOwner, shouldBeRemoved }) { - let warningText = warningKey ? t(warningKey) : false; - - if (shouldBeRemoved.length + shouldChangeOwner.length === 0 && skipModalIfEmpty) { - callbackFn(); - return; - } - - if (shouldChangeOwner.length > 0) { - let newText; - - if (shouldChangeOwner.length === 1) { - newText = TAPi18n.__('A_new_owner_will_be_assigned_automatically_to_the__roomName__room', { roomName: shouldChangeOwner.pop() }); - } else if (shouldChangeOwner.length <= 5) { - newText = TAPi18n.__('A_new_owner_will_be_assigned_automatically_to_those__count__rooms__rooms__', { count: shouldChangeOwner.length, rooms: shouldChangeOwner.join(', ') }); - } else { - newText = TAPi18n.__('A_new_owner_will_be_assigned_automatically_to__count__rooms', { count: shouldChangeOwner.length }); - } - - if (warningText) { - warningText = `${ warningText }
${ newText }
`; - } else { - warningText = newText; - } - } - - if (shouldBeRemoved.length > 0) { - let newText; - - if (shouldBeRemoved.length === 1) { - newText = TAPi18n.__('The_empty_room__roomName__will_be_removed_automatically', { roomName: shouldBeRemoved.pop() }); - } else if (shouldBeRemoved.length <= 5) { - newText = TAPi18n.__('__count__empty_rooms_will_be_removed_automatically__rooms__', { count: shouldBeRemoved.length, rooms: shouldBeRemoved.join(', ') }); - } else { - newText = TAPi18n.__('__count__empty_rooms_will_be_removed_automatically', { count: shouldBeRemoved.length }); - } - - if (warningText) { - warningText = `${ warningText }
${ newText }
`; - } else { - warningText = newText; - } - } - - modal.open({ - title: t('Are_you_sure'), - text: warningText, - type: 'warning', - showCancelButton: true, - confirmButtonColor: '#DD6B55', - confirmButtonText: t(confirmButtonKey || 'Yes_delete_it'), - cancelButtonText: t('Cancel'), - closeOnConfirm, - html: true, - }, () => { - callbackFn(); - }); -}; diff --git a/app/ui/client/components/header/header.js b/app/ui/client/components/header/header.js index 205d52a227f..98f427ac2f3 100644 --- a/app/ui/client/components/header/header.js +++ b/app/ui/client/components/header/header.js @@ -1,6 +1,7 @@ import { Template } from 'meteor/templating'; -import { fireGlobalEvent } from '../../../../ui-utils'; +import { fireGlobalEvent } from '../../../../../client/lib/utils/fireGlobalEvent'; + import './header.html'; Template.header.helpers({ diff --git a/app/ui/client/components/icon.js b/app/ui/client/components/icon.js index 45ef63a494b..e49bec52392 100644 --- a/app/ui/client/components/icon.js +++ b/app/ui/client/components/icon.js @@ -1,7 +1,7 @@ import { FlowRouter } from 'meteor/kadira:flow-router'; import { Template } from 'meteor/templating'; -import { baseURI } from '../../../utils/client/lib/baseuri'; +import { baseURI } from '../../../../client/lib/baseURI'; import './icon.html'; diff --git a/app/ui/client/lib/chatMessages.js b/app/ui/client/lib/chatMessages.js index 35042378fbf..24afc442a02 100644 --- a/app/ui/client/lib/chatMessages.js +++ b/app/ui/client/lib/chatMessages.js @@ -11,15 +11,12 @@ import { escapeHTML } from '@rocket.chat/string-helpers'; import { KonchatNotification } from './notification'; import { MsgTyping } from './msgTyping'; import { fileUpload } from './fileUpload'; -import { t, slashCommands, handleError } from '../../../utils/client'; +import { t, slashCommands } from '../../../utils/client'; import { messageProperties, MessageTypes, readMessage, modal, - call, - keyCodes, - prependReplies, } from '../../../ui-utils/client'; import { settings } from '../../../settings/client'; import { callbacks } from '../../../callbacks/client'; @@ -30,6 +27,10 @@ import { emoji } from '../../../emoji/client'; import { generateTriggerId } from '../../../ui-message/client/ActionManager'; import { imperativeModal } from '../../../../client/lib/imperativeModal'; import GenericModal from '../../../../client/components/GenericModal'; +import { keyCodes } from '../../../../client/lib/utils/keyCodes'; +import { prependReplies } from '../../../../client/lib/utils/prependReplies'; +import { callWithErrorHandling } from '../../../../client/lib/utils/callWithErrorHandling'; +import { handleError } from '../../../../client/lib/utils/handleError'; const messageBoxState = { @@ -102,7 +103,7 @@ export class ChatMessages { return; } - const message = Messages.findOne(mid) || await call('getSingleMessage', mid); + const message = Messages.findOne(mid) || await callWithErrorHandling('getSingleMessage', mid); if (!message) { return; } @@ -257,7 +258,7 @@ export class ChatMessages { MsgTyping.stop(rid); if (!ChatSubscription.findOne({ rid })) { - await call('joinRoom', rid); + await callWithErrorHandling('joinRoom', rid); } messageBoxState.save({ rid, tmid }, this.input); @@ -345,7 +346,7 @@ export class ChatMessages { return; } - await call('sendMessage', message); + await callWithErrorHandling('sendMessage', message); } async processSetReaction({ rid, tmid, msg }) { @@ -359,7 +360,7 @@ export class ChatMessages { } const lastMessage = this.collection.findOne({ rid, tmid }, { fields: { ts: 1 }, sort: { ts: -1 } }); - await call('setReaction', reaction, lastMessage._id); + await callWithErrorHandling('setReaction', reaction, lastMessage._id); return true; } @@ -406,7 +407,7 @@ export class ChatMessages { } this.clearEditing(); - await call('updateMessage', message); + await callWithErrorHandling('updateMessage', message); return true; } @@ -521,7 +522,7 @@ export class ChatMessages { } - await call('deleteMessage', { _id }); + await callWithErrorHandling('deleteMessage', { _id }); } keydown(event) { diff --git a/app/ui/client/lib/fileUpload.js b/app/ui/client/lib/fileUpload.js index 2f008ea0a9a..a5f26c65712 100644 --- a/app/ui/client/lib/fileUpload.js +++ b/app/ui/client/lib/fileUpload.js @@ -4,9 +4,9 @@ import { Random } from 'meteor/random'; import { settings } from '../../../settings/client'; import { fileUploadIsValidContentType, APIClient } from '../../../utils'; -import { prependReplies } from '../../../ui-utils'; import { imperativeModal } from '../../../../client/lib/imperativeModal'; import FileUploadModal from '../../../../client/components/modals/FileUploadModal'; +import { prependReplies } from '../../../../client/lib/utils/prependReplies'; export const uploadFileWithMessage = async (rid, tmid, { description, fileName, msg, file }) => { const data = new FormData(); diff --git a/app/ui/client/lib/iframeCommands.js b/app/ui/client/lib/iframeCommands.js index 6af2f986c30..ded9ac783b0 100644 --- a/app/ui/client/lib/iframeCommands.js +++ b/app/ui/client/lib/iframeCommands.js @@ -7,8 +7,8 @@ import { escapeRegExp } from '@rocket.chat/string-helpers'; import { AccountBox } from '../../../ui-utils'; import { settings } from '../../../settings'; import { callbacks } from '../../../callbacks'; -import { baseURI } from '../../../utils/client/lib/baseuri.js'; import { add, remove } from '../../../../client/views/room/lib/Toolbox/IframeButtons'; +import { baseURI } from '../../../../client/lib/baseURI'; const commands = { go(data) { diff --git a/app/ui/client/lib/notification.js b/app/ui/client/lib/notification.js index b249b451a1a..c656851eb08 100644 --- a/app/ui/client/lib/notification.js +++ b/app/ui/client/lib/notification.js @@ -12,9 +12,9 @@ import { e2e } from '../../../e2e/client'; import { Users, ChatSubscription } from '../../../models'; import { getUserPreference } from '../../../utils'; import { getUserAvatarURL } from '../../../utils/lib/getUserAvatarURL'; -import { getAvatarAsPng } from '../../../ui-utils'; import { promises } from '../../../promises/client'; import { CustomSounds } from '../../../custom-sounds/client/lib/CustomSounds'; +import { getAvatarAsPng } from '../../../../client/lib/utils/getAvatarAsPng'; export const KonchatNotification = { notificationStatus: new ReactiveVar(), diff --git a/app/ui/client/views/app/burger.js b/app/ui/client/views/app/burger.js index a7e34daa2b8..53d2e5d5269 100644 --- a/app/ui/client/views/app/burger.js +++ b/app/ui/client/views/app/burger.js @@ -3,7 +3,8 @@ import { Session } from 'meteor/session'; import { Template } from 'meteor/templating'; import { ChatSubscription } from '../../../../models/client'; -import { Layout, menu } from '../../../../ui-utils/client'; +import { menu } from '../../../../ui-utils/client'; +import { isLayoutEmbedded } from '../../../../../client/lib/utils/isLayoutEmbedded'; import { getUserPreference } from '../../../../utils'; Template.burger.helpers({ @@ -50,7 +51,7 @@ Template.burger.helpers({ }, embeddedVersion() { - return Layout.isEmbedded(); + return isLayoutEmbedded(); }, }); diff --git a/app/ui/client/views/app/lib/getCommonRoomEvents.js b/app/ui/client/views/app/lib/getCommonRoomEvents.js index c273067e36e..869464451fa 100644 --- a/app/ui/client/views/app/lib/getCommonRoomEvents.js +++ b/app/ui/client/views/app/lib/getCommonRoomEvents.js @@ -4,15 +4,13 @@ import { Random } from 'meteor/random'; import { FlowRouter } from 'meteor/kadira:flow-router'; import { - fireGlobalEvent, popover, - Layout, MessageAction, } from '../../../../../ui-utils/client'; import { addMessageToList, } from '../../../../../ui-utils/client/lib/MessageAction'; -import { call } from '../../../../../ui-utils/client/lib/callMethod'; +import { callWithErrorHandling } from '../../../../../../client/lib/utils/callWithErrorHandling'; import { promises } from '../../../../../promises/client'; import { isURL } from '../../../../../utils/lib/isURL'; import { openUserCard } from '../../../lib/UserCard'; @@ -21,7 +19,9 @@ import { ChatMessage, Rooms, Messages } from '../../../../../models'; import { t } from '../../../../../utils/client'; import { chatMessages } from '../room'; import { EmojiEvents } from '../../../../../reactions/client/init'; -import { goToRoomById } from '../../../../../../client/lib/goToRoomById'; +import { goToRoomById } from '../../../../../../client/lib/utils/goToRoomById'; +import { fireGlobalEvent } from '../../../../../../client/lib/utils/fireGlobalEvent'; +import { isLayoutEmbedded } from '../../../../../../client/lib/utils/isLayoutEmbedded'; const mountPopover = (e, i, outerContext) => { let context = $(e.target).parents('.message').data('context'); @@ -163,13 +163,13 @@ export const getCommonRoomEvents = () => ({ e.preventDefault(); e.stopPropagation(); const { msg } = messageArgs(this); - call('followMessage', { mid: msg._id }); + callWithErrorHandling('followMessage', { mid: msg._id }); }, 'click .js-unfollow-thread'(e) { e.preventDefault(); e.stopPropagation(); const { msg } = messageArgs(this); - call('unfollowMessage', { mid: msg._id }); + callWithErrorHandling('unfollowMessage', { mid: msg._id }); }, 'click .js-open-thread'(event) { event.preventDefault(); @@ -259,7 +259,7 @@ export const getCommonRoomEvents = () => ({ return; } - await call('sendMessage', msgObject); + await callWithErrorHandling('sendMessage', msgObject); }, 'click .message-actions__menu'(e, template) { const messageContext = messageArgs(this); @@ -311,7 +311,7 @@ export const getCommonRoomEvents = () => ({ const { currentTarget: { dataset: { channel, group, username } } } = e; if (channel) { - if (Layout.isEmbedded()) { + if (isLayoutEmbedded()) { fireGlobalEvent('click-mention-link', { path: FlowRouter.path('channel', { name: channel }), channel }); } goToRoomById(channel); diff --git a/app/ui/client/views/app/room.js b/app/ui/client/views/app/room.js index 7914043a6c5..2abbeb94d25 100644 --- a/app/ui/client/views/app/room.js +++ b/app/ui/client/views/app/room.js @@ -10,15 +10,13 @@ import { FlowRouter } from 'meteor/kadira:flow-router'; import { Session } from 'meteor/session'; import { Template } from 'meteor/templating'; -import { t, roomTypes, getUserPreference, handleError } from '../../../../utils/client'; +import { t, roomTypes, getUserPreference } from '../../../../utils/client'; import { WebRTC } from '../../../../webrtc/client'; import { ChatMessage, RoomRoles, Users, Subscriptions, Rooms } from '../../../../models'; import { - fireGlobalEvent, RoomHistoryManager, RoomManager, readMessage, - Layout, } from '../../../../ui-utils/client'; import { messageContext } from '../../../../ui-utils/client/lib/messageContext'; import { messageArgs } from '../../../../ui-utils/client/lib/messageArgs'; @@ -30,6 +28,9 @@ import { fileUpload } from '../../lib/fileUpload'; import './room.html'; import { getCommonRoomEvents } from './lib/getCommonRoomEvents'; import { RoomManager as NewRoomManager } from '../../../../../client/lib/RoomManager'; +import { fireGlobalEvent } from '../../../../../client/lib/utils/fireGlobalEvent'; +import { isLayoutEmbedded } from '../../../../../client/lib/utils/isLayoutEmbedded'; +import { handleError } from '../../../../../client/lib/utils/handleError'; export const chatMessages = {}; @@ -39,7 +40,7 @@ const userCanDrop = (_id) => !roomTypes.readOnly(_id, Users.findOne({ _id: Meteo export const openProfileTab = (e, tabBar, username) => { e.stopPropagation(); - if (Layout.isEmbedded()) { + if (isLayoutEmbedded()) { fireGlobalEvent('click-user-card-message', { username }); e.preventDefault(); return; @@ -272,7 +273,7 @@ Template.roomOld.helpers({ messageboxData() { const { sendToBottomIfNecessary, subscription } = Template.instance(); const { _id: rid } = this; - const isEmbedded = Layout.isEmbedded(); + const isEmbedded = isLayoutEmbedded(); const showFormattingTips = settings.get('Message_ShowFormattingTips'); return { diff --git a/app/utils/client/index.js b/app/utils/client/index.js index 4ada524ca0b..98078f775fe 100644 --- a/app/utils/client/index.js +++ b/app/utils/client/index.js @@ -2,7 +2,6 @@ export { t, isRtl } from '../lib/tapi18n'; export { getDefaultSubscriptionPref } from '../lib/getDefaultSubscriptionPref'; export { Info } from '../rocketchat.info'; export { isEmail } from '../lib/isEmail'; -export { handleError } from './lib/handleError'; export { getUserPreference } from '../lib/getUserPreference'; export { fileUploadMediaWhiteList, fileUploadIsValidContentType } from '../lib/fileUploadRestrictions'; export { roomTypes } from './lib/roomTypes'; @@ -11,12 +10,9 @@ export { RoomTypesCommon } from '../lib/RoomTypesCommon'; export { getUserAvatarURL } from '../lib/getUserAvatarURL'; export { slashCommands } from '../lib/slashCommand'; export { getUserNotificationPreference } from '../lib/getUserNotificationPreference'; -export { applyCustomTranslations } from './lib/CustomTranslations'; export { getAvatarColor } from '../lib/getAvatarColor'; export { getURL } from '../lib/getURL'; export { placeholders } from '../lib/placeholders'; export { templateVarHandler } from '../lib/templateVarHandler'; -export { APIClient, mountArrayQueryParameters } from './lib/RestApiClient'; -export { canDeleteMessage } from './lib/canDeleteMessage'; +export { APIClient } from './lib/RestApiClient'; export { secondsToHHMMSS } from '../lib/timeConverter'; -export { waitUntilFind } from './lib/waitUntilFind'; diff --git a/app/utils/client/lib/CustomTranslations.js b/app/utils/client/lib/CustomTranslations.js deleted file mode 100644 index 7754e9a609e..00000000000 --- a/app/utils/client/lib/CustomTranslations.js +++ /dev/null @@ -1,22 +0,0 @@ -import { TAPi18n, TAPi18next } from 'meteor/rocketchat:tap-i18n'; - -import { settings } from '../../../settings'; - -export function applyCustomTranslations() { - let CustomTranslations = settings.get('Custom_Translations'); - if (typeof CustomTranslations === 'string' && CustomTranslations.trim() !== '') { - try { - CustomTranslations = JSON.parse(CustomTranslations); - - for (const lang in CustomTranslations) { - if (CustomTranslations.hasOwnProperty(lang)) { - const translations = CustomTranslations[lang]; - TAPi18next.addResourceBundle(lang, 'project', translations); - } - } - TAPi18n._language_changed_tracker.changed(); - } catch (e) { - console.error('Invalid setting Custom_Translations', e); - } - } -} diff --git a/app/utils/client/lib/RestApiClient.js b/app/utils/client/lib/RestApiClient.js index ba23a1cf3c0..5dae274c803 100644 --- a/app/utils/client/lib/RestApiClient.js +++ b/app/utils/client/lib/RestApiClient.js @@ -1,13 +1,8 @@ import { Meteor } from 'meteor/meteor'; import { Accounts } from 'meteor/accounts-base'; -import { baseURI } from './baseuri'; import { process2faReturn } from '../../../2fa/client/callWithTwoFactorRequired'; - -export const mountArrayQueryParameters = (label, array) => array.reduce((acc, item) => { - acc += `${ label }[]=${ item }&`; - return acc; -}, ''); +import { baseURI } from '../../../../client/lib/baseURI'; export const APIClient = { delete(endpoint, params) { diff --git a/app/utils/client/lib/baseuri.js b/app/utils/client/lib/baseuri.js deleted file mode 100644 index a0545b56ecd..00000000000 --- a/app/utils/client/lib/baseuri.js +++ /dev/null @@ -1,18 +0,0 @@ -import { Meteor } from 'meteor/meteor'; - -export const baseURI = (() => { - if (document.baseURI) { return document.baseURI; } - - // Should be exactly one tag: - // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base - const base = document.getElementsByTagName('base'); - - // Return location from BASE tag. - if (base.length > 0) { return base[0].href; } - - // Else use implementation of documentURI: - // http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-baseURI - return document.URL; -})(); - -Meteor.absoluteUrl.defaultOptions = { ...Meteor.absoluteUrl.defaultOptions, rootUrl: baseURI }; diff --git a/app/utils/client/lib/canDeleteMessage.js b/app/utils/client/lib/canDeleteMessage.js deleted file mode 100644 index 3f35d597452..00000000000 --- a/app/utils/client/lib/canDeleteMessage.js +++ /dev/null @@ -1,41 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import moment from 'moment'; - -import { hasPermission } from '../../../authorization/client'; -import { settings } from '../../../settings/client'; - -export const canDeleteMessage = ({ rid, ts, uid }) => { - const userId = Meteor.userId(); - - const forceDelete = hasPermission('force-delete-message', rid); - if (forceDelete) { - return true; - } - - const isDeleteAllowed = settings.get('Message_AllowDeleting'); - if (!isDeleteAllowed) { - return false; - } - - const allowed = hasPermission('delete-message', rid); - - const deleteOwn = allowed || (uid === userId && hasPermission('delete-own-message')); - if (!allowed && !deleteOwn) { - return false; - } - - const blockDeleteInMinutes = settings.get('Message_AllowDeleting_BlockDeleteInMinutes'); - if (blockDeleteInMinutes != null && blockDeleteInMinutes !== 0) { - let msgTs; - if (ts != null) { - msgTs = moment(ts); - } - let currentTsDiff; - if (msgTs != null) { - currentTsDiff = moment().diff(msgTs, 'minutes'); - } - return currentTsDiff < blockDeleteInMinutes; - } - - return true; -}; diff --git a/app/utils/client/lib/handleError.js b/app/utils/client/lib/handleError.js deleted file mode 100644 index 120c3b7d41f..00000000000 --- a/app/utils/client/lib/handleError.js +++ /dev/null @@ -1,32 +0,0 @@ -import { TAPi18n } from 'meteor/rocketchat:tap-i18n'; -import _ from 'underscore'; -import toastr from 'toastr'; -import { escapeHTML } from '@rocket.chat/string-helpers'; - -export const handleError = function(error, useToastr = true) { - if (error.xhr) { - error = error.xhr.responseJSON || {}; - } - - if (_.isObject(error.details)) { - for (const key in error.details) { - if (error.details.hasOwnProperty(key)) { - error.details[key] = TAPi18n.__(error.details[key]); - } - } - } - - if (useToastr) { - if (error.toastrShowed) { - return; - } - const details = Object.entries(error.details || {}) - .reduce((obj, [key, value]) => ({ ...obj, [key]: escapeHTML(value) }), {}); - const message = TAPi18n.__(error.error || error.message, details); - const title = details.errorTitle && TAPi18n.__(details.errorTitle); - - return toastr.error(message, title); - } - - return escapeHTML(TAPi18n.__(error.error || error.message, error.details)); -}; diff --git a/app/utils/client/lib/waitUntilFind.ts b/app/utils/client/lib/waitUntilFind.ts deleted file mode 100644 index bb07282ef16..00000000000 --- a/app/utils/client/lib/waitUntilFind.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Tracker } from 'meteor/tracker'; - -export const waitUntilFind =