Move some ui function to ui-utils (#13123)
* Move rocketchat settings to specific package * WIP: Move models from rocketchat-lib to a specific package (server) * Move function from rocketchat:lib to rocketchat:utils to use it in rocketchat:models * Move client models from rocketchat:lib to rocketchat:models * Fix lint * Move rocketchat.info from lib to utils * Remove directly dependency between lib and migrations * Move statistics Model to rocketchat:models * Create rocketchat:metrics to be able to depacking rocketchat callbacks * Move callbacks to specific package * Remove unused dependency * Move rocketchat-notifications to a specific package * Move rocketchat-promises to a specific package * remove directly dependency from metrics and models * Move CachedCollection from lib to models * Move ui models/collections from ui to models * Move authorization client/ui models to rocketchat:models to be able to remove lib dependency * Creation of rocketchat:ui-utils to help decouple rocketchat:lib and rocketchat:authz * Move some common functions to rocketchat:utils * Change imports to dynamic imports to avoid directly dependency between some packages * Move authz models to rocketchat:models * Remove directly dependency between rocketchat:authz and rocketchat:lib * Move some functions from rocketchat:lib to rocketchat:utils * Add functions to settings package * Convert rocketchat:file-upload to main module structure * Import FileUpload where it is being used * Remove FileUpload and fileUploadHandler from globals eslintrc * Move some functions to rocketchat:ui-utils * Remove directly dependency between rocketchat:authorization and rocketchat:ui-utils * Remove dependency between lazy-load and lib * Change imports of renderMessageBody from ui-message to ui-utils * Add import of main ready from ui-utils * Convert rocketchat-ui-sidenav to main module structure * Add imports of toolbarSearch from ui-sidenav * Remove toolbarSearch from eslintrc globals * Move CachedCollection to a specific package * Change imports of CachedCollection to new package * Move some functions to rocketchat:ui-utils * Remove directly dependency between tooltip and lib * Remove directly dependency between settings and metrics * Move some settings client function from lib to settings * Convert rocketchat-ui-master to main module structure * Remove directly dependency between rocketchat:e2e and rocketchat:lib * Fix wrong import and lint * Convert rocketchat-webrtc to main module structure * Fix missing export * Remove directly dependency between rocketchat:emoji and lib * Add emoji dependencies inside RocketChat namespace * Merge branch 'develop' into globals/move-rocketchat-callbacks * Move some functions to utils * Fix lint * Move some ui functions to ui-utils * Fix import missed objects inside RocketChat namespace * Fix lint * Revert commented test file * Fix lint * Remove old code * Remove old code * Use openedRoom * Remove old code * Change import to a local file instead from package * import emoji in message properties * Move message properties to ui-utils package * Fix lint * Move openedRoom to RoomManager * Fix console errorspull/13131/head^2
parent
8d23486314
commit
af96bd990d
@ -1,75 +1 @@ |
||||
import { ReactiveVar } from 'meteor/reactive-var'; |
||||
import { Tracker } from 'meteor/tracker'; |
||||
|
||||
export class RocketChatTabBar { |
||||
constructor() { |
||||
this.template = new ReactiveVar(); |
||||
this.id = new ReactiveVar(); |
||||
this.group = new ReactiveVar(); |
||||
this.state = new ReactiveVar(); |
||||
this.data = new ReactiveVar(); |
||||
} |
||||
|
||||
getTemplate() { |
||||
return this.template.get(); |
||||
} |
||||
|
||||
getId() { |
||||
return this.id.get(); |
||||
} |
||||
|
||||
setTemplate(template) { |
||||
this.template.set(template); |
||||
} |
||||
|
||||
currentGroup() { |
||||
return this.group.get(); |
||||
} |
||||
|
||||
showGroup(group) { |
||||
this.group.set(group); |
||||
} |
||||
|
||||
setData(d) { |
||||
this.data.set(d); |
||||
} |
||||
|
||||
getData() { |
||||
return this.data.get(); |
||||
} |
||||
|
||||
getButtons() { |
||||
return RocketChat.TabBar.getButtons(); |
||||
} |
||||
|
||||
getState() { |
||||
return this.state.get(); |
||||
} |
||||
|
||||
open(button) { |
||||
this.state.set('opened'); |
||||
Tracker.afterFlush(() => { |
||||
$('.contextual-bar__container').scrollTop(0).find('input[type=text]:first').focus(); |
||||
}); |
||||
|
||||
if (!button) { |
||||
return; |
||||
} |
||||
if (typeof button !== 'object' || !button.id) { |
||||
button = RocketChat.TabBar.getButton(button); |
||||
} |
||||
$('.flex-tab, .contextual-bar').css('width', button.width ? `${ button.width }px` : ''); |
||||
this.template.set(button.template); |
||||
this.id.set(button.id); |
||||
return button; |
||||
} |
||||
|
||||
close() { |
||||
this.state.set(''); |
||||
|
||||
$('.flex-tab, .contextual-bar').css('width', ''); |
||||
|
||||
this.template.set(); |
||||
this.id.set(); |
||||
} |
||||
} |
||||
export { RocketChatTabBar } from 'meteor/rocketchat:ui-utils'; |
||||
|
@ -1,83 +1,3 @@ |
||||
import _ from 'underscore'; |
||||
import { ReactiveVar } from 'meteor/reactive-var'; |
||||
import { TabBar } from 'meteor/rocketchat:ui-utils'; |
||||
|
||||
RocketChat.TabBar = new (class TabBar { |
||||
get size() { |
||||
return this._size.get(); |
||||
} |
||||
set size(s) { |
||||
this._size.set(s); |
||||
} |
||||
constructor() { |
||||
this.buttons = new ReactiveVar({}); |
||||
this._size = new ReactiveVar(4); |
||||
this.extraGroups = {}; |
||||
} |
||||
|
||||
show() { |
||||
$('.flex-tab-bar').show(); |
||||
} |
||||
|
||||
hide() { |
||||
$('.flex-tab-bar').hide(); |
||||
} |
||||
|
||||
addButton(config) { |
||||
if (!config || !config.id) { |
||||
return false; |
||||
} |
||||
|
||||
const btns = this.buttons.curValue; |
||||
btns[config.id] = config; |
||||
|
||||
if (this.extraGroups[config.id]) { |
||||
btns[config.id].groups = _.union((btns[config.id].groups || []), this.extraGroups[config.id]); |
||||
} |
||||
|
||||
this.buttons.set(btns); |
||||
} |
||||
|
||||
removeButton(id) { |
||||
const btns = this.buttons.curValue; |
||||
delete btns[id]; |
||||
this.buttons.set(btns); |
||||
} |
||||
|
||||
updateButton(id, config) { |
||||
const btns = this.buttons.curValue; |
||||
if (btns[id]) { |
||||
btns[id] = _.extend(btns[id], config); |
||||
this.buttons.set(btns); |
||||
} |
||||
} |
||||
|
||||
getButtons() { |
||||
const buttons = _.toArray(this.buttons.get()).filter((button) => !button.condition || button.condition()); |
||||
|
||||
return _.sortBy(buttons, 'order'); |
||||
} |
||||
|
||||
getButton(id) { |
||||
return _.findWhere(this.buttons.get(), { id }); |
||||
} |
||||
|
||||
addGroup(id, groups) { |
||||
const btns = this.buttons.curValue; |
||||
if (btns[id]) { |
||||
btns[id].groups = _.union((btns[id].groups || []), groups); |
||||
this.buttons.set(btns); |
||||
} else { |
||||
this.extraGroups[id] = _.union((this.extraGroups[id] || []), groups); |
||||
} |
||||
} |
||||
|
||||
removeGroup(id, groups) { |
||||
const btns = this.buttons.curValue; |
||||
if (btns[id]) { |
||||
btns[id].groups = _.difference((btns[id].groups || []), groups); |
||||
this.buttons.set(btns); |
||||
} else { |
||||
this.extraGroups[id] = _.difference((this.extraGroups[id] || []), groups); |
||||
} |
||||
} |
||||
}); |
||||
RocketChat.TabBar = TabBar; |
||||
|
@ -1,43 +1,25 @@ |
||||
import { AdminBox } from './lib/AdminBox'; |
||||
import { modal } from './lib/modal'; |
||||
import { SideNav } from './lib/SideNav'; |
||||
import { AccountBox } from './lib/AccountBox'; |
||||
import { menu } from './lib/menu'; |
||||
import { call } from './lib/callMethod'; |
||||
import { erase, hide, leave } from './lib/ChannelActions'; |
||||
import { MessageAction } from './lib/MessageAction'; |
||||
import { messageBox } from './lib/messageBox'; |
||||
import { popover } from './lib/popover'; |
||||
import { readMessage } from './lib/readMessages'; |
||||
import { RoomManager } from './lib/RoomManager'; |
||||
import { upsertMessage, RoomHistoryManager } from './lib/RoomHistoryManager'; |
||||
import { mainReady } from './lib/mainReady'; |
||||
import { renderMessageBody } from './lib/renderMessageBody'; |
||||
import { Layout } from './lib/Layout'; |
||||
import { IframeLogin, iframeLogin } from './lib/IframeLogin'; |
||||
import { fireGlobalEvent } from './lib/fireGlobalEvent'; |
||||
|
||||
export { |
||||
AdminBox, |
||||
modal, |
||||
SideNav, |
||||
AccountBox, |
||||
menu, |
||||
call, |
||||
erase, |
||||
hide, |
||||
leave, |
||||
MessageAction, |
||||
messageBox, |
||||
popover, |
||||
readMessage, |
||||
RoomManager, |
||||
RoomHistoryManager, |
||||
mainReady, |
||||
renderMessageBody, |
||||
upsertMessage, |
||||
Layout, |
||||
IframeLogin, |
||||
iframeLogin, |
||||
fireGlobalEvent, |
||||
}; |
||||
export { AdminBox } from './lib/AdminBox'; |
||||
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 { erase, hide, leave } from './lib/ChannelActions'; |
||||
export { MessageAction } from './lib/MessageAction'; |
||||
export { messageBox } from './lib/messageBox'; |
||||
export { popover } from './lib/popover'; |
||||
export { readMessage } from './lib/readMessages'; |
||||
export { RoomManager } from './lib/RoomManager'; |
||||
export { upsertMessage, RoomHistoryManager } from './lib/RoomHistoryManager'; |
||||
export { mainReady } from './lib/mainReady'; |
||||
export { renderMessageBody } from './lib/renderMessageBody'; |
||||
export { Layout } from './lib/Layout'; |
||||
export { IframeLogin, iframeLogin } from './lib/IframeLogin'; |
||||
export { fireGlobalEvent } from './lib/fireGlobalEvent'; |
||||
export { getAvatarAsPng, updateAvatarOfUsername } from './lib/avatar'; |
||||
export { TabBar } from './lib/TabBar'; |
||||
export { RocketChatTabBar } from './lib/RocketChatTabBar'; |
||||
export { popout } from './lib/popout'; |
||||
export { messageProperties } from '../lib/MessageProperties'; |
||||
export { MessageTypes } from '../lib/MessageTypes'; |
||||
export { alerts } from './lib/alerts'; |
||||
|
@ -0,0 +1,76 @@ |
||||
import { ReactiveVar } from 'meteor/reactive-var'; |
||||
import { Tracker } from 'meteor/tracker'; |
||||
import { TabBar } from './TabBar'; |
||||
|
||||
export class RocketChatTabBar { |
||||
constructor() { |
||||
this.template = new ReactiveVar(); |
||||
this.id = new ReactiveVar(); |
||||
this.group = new ReactiveVar(); |
||||
this.state = new ReactiveVar(); |
||||
this.data = new ReactiveVar(); |
||||
} |
||||
|
||||
getTemplate() { |
||||
return this.template.get(); |
||||
} |
||||
|
||||
getId() { |
||||
return this.id.get(); |
||||
} |
||||
|
||||
setTemplate(template) { |
||||
this.template.set(template); |
||||
} |
||||
|
||||
currentGroup() { |
||||
return this.group.get(); |
||||
} |
||||
|
||||
showGroup(group) { |
||||
this.group.set(group); |
||||
} |
||||
|
||||
setData(d) { |
||||
this.data.set(d); |
||||
} |
||||
|
||||
getData() { |
||||
return this.data.get(); |
||||
} |
||||
|
||||
getButtons() { |
||||
return TabBar.getButtons(); |
||||
} |
||||
|
||||
getState() { |
||||
return this.state.get(); |
||||
} |
||||
|
||||
open(button) { |
||||
this.state.set('opened'); |
||||
Tracker.afterFlush(() => { |
||||
$('.contextual-bar__container').scrollTop(0).find('input[type=text]:first').focus(); |
||||
}); |
||||
|
||||
if (!button) { |
||||
return; |
||||
} |
||||
if (typeof button !== 'object' || !button.id) { |
||||
button = TabBar.getButton(button); |
||||
} |
||||
$('.flex-tab, .contextual-bar').css('width', button.width ? `${ button.width }px` : ''); |
||||
this.template.set(button.template); |
||||
this.id.set(button.id); |
||||
return button; |
||||
} |
||||
|
||||
close() { |
||||
this.state.set(''); |
||||
|
||||
$('.flex-tab, .contextual-bar').css('width', ''); |
||||
|
||||
this.template.set(); |
||||
this.id.set(); |
||||
} |
||||
} |
@ -0,0 +1,83 @@ |
||||
import _ from 'underscore'; |
||||
import { ReactiveVar } from 'meteor/reactive-var'; |
||||
|
||||
export const TabBar = new (class TabBar { |
||||
get size() { |
||||
return this._size.get(); |
||||
} |
||||
set size(s) { |
||||
this._size.set(s); |
||||
} |
||||
constructor() { |
||||
this.buttons = new ReactiveVar({}); |
||||
this._size = new ReactiveVar(4); |
||||
this.extraGroups = {}; |
||||
} |
||||
|
||||
show() { |
||||
$('.flex-tab-bar').show(); |
||||
} |
||||
|
||||
hide() { |
||||
$('.flex-tab-bar').hide(); |
||||
} |
||||
|
||||
addButton(config) { |
||||
if (!config || !config.id) { |
||||
return false; |
||||
} |
||||
|
||||
const btns = this.buttons.curValue; |
||||
btns[config.id] = config; |
||||
|
||||
if (this.extraGroups[config.id]) { |
||||
btns[config.id].groups = _.union((btns[config.id].groups || []), this.extraGroups[config.id]); |
||||
} |
||||
|
||||
this.buttons.set(btns); |
||||
} |
||||
|
||||
removeButton(id) { |
||||
const btns = this.buttons.curValue; |
||||
delete btns[id]; |
||||
this.buttons.set(btns); |
||||
} |
||||
|
||||
updateButton(id, config) { |
||||
const btns = this.buttons.curValue; |
||||
if (btns[id]) { |
||||
btns[id] = _.extend(btns[id], config); |
||||
this.buttons.set(btns); |
||||
} |
||||
} |
||||
|
||||
getButtons() { |
||||
const buttons = _.toArray(this.buttons.get()).filter((button) => !button.condition || button.condition()); |
||||
|
||||
return _.sortBy(buttons, 'order'); |
||||
} |
||||
|
||||
getButton(id) { |
||||
return _.findWhere(this.buttons.get(), { id }); |
||||
} |
||||
|
||||
addGroup(id, groups) { |
||||
const btns = this.buttons.curValue; |
||||
if (btns[id]) { |
||||
btns[id].groups = _.union((btns[id].groups || []), groups); |
||||
this.buttons.set(btns); |
||||
} else { |
||||
this.extraGroups[id] = _.union((this.extraGroups[id] || []), groups); |
||||
} |
||||
} |
||||
|
||||
removeGroup(id, groups) { |
||||
const btns = this.buttons.curValue; |
||||
if (btns[id]) { |
||||
btns[id].groups = _.difference((btns[id].groups || []), groups); |
||||
this.buttons.set(btns); |
||||
} else { |
||||
this.extraGroups[id] = _.difference((this.extraGroups[id] || []), groups); |
||||
} |
||||
} |
||||
}); |
@ -0,0 +1,73 @@ |
||||
import './alerts.html'; |
||||
import { Blaze } from 'meteor/blaze'; |
||||
import { Template } from 'meteor/templating'; |
||||
|
||||
export const alerts = { |
||||
renderedAlert: null, |
||||
open(config) { |
||||
this.close(false); |
||||
|
||||
config.closable = typeof(config.closable) === typeof(true) ? config.closable : true; |
||||
|
||||
if (config.timer) { |
||||
this.timer = setTimeout(() => this.close(), config.timer); |
||||
} |
||||
|
||||
this.renderedAlert = Blaze.renderWithData(Template.alerts, config, document.body, document.body.querySelector('#alert-anchor')); |
||||
}, |
||||
close(dismiss = true) { |
||||
if (this.timer) { |
||||
clearTimeout(this.timer); |
||||
delete this.timer; |
||||
} |
||||
if (!this.renderedAlert) { |
||||
return false; |
||||
} |
||||
|
||||
Blaze.remove(this.renderedAlert); |
||||
|
||||
const { activeElement } = this.renderedAlert.dataVar.curValue; |
||||
if (activeElement) { |
||||
$(activeElement).removeClass('active'); |
||||
} |
||||
|
||||
dismiss && this.renderedAlert.dataVar.curValue.onClose && this.renderedAlert.dataVar.curValue.onClose(); |
||||
}, |
||||
}; |
||||
|
||||
Template.alerts.helpers({ |
||||
hasAction() { |
||||
return Template.instance().data.action ? 'rc-alerts--has-action' : ''; |
||||
}, |
||||
modifiers() { |
||||
return (Template.instance().data.modifiers || []).map((mod) => `rc-alerts--${ mod }`).join(' '); |
||||
}, |
||||
}); |
||||
|
||||
Template.alerts.onRendered(function() { |
||||
if (this.data.onRendered) { |
||||
this.data.onRendered(); |
||||
} |
||||
}); |
||||
|
||||
Template.alerts.onDestroyed(function() { |
||||
if (this.data.onDestroyed) { |
||||
this.data.onDestroyed(); |
||||
} |
||||
}); |
||||
|
||||
Template.alerts.events({ |
||||
'click .js-action'(e, instance) { |
||||
if (!this.action) { |
||||
return; |
||||
} |
||||
this.action.call(this, e, instance.data.data); |
||||
}, |
||||
'click .js-close'() { |
||||
alerts.close(); |
||||
}, |
||||
}); |
||||
|
||||
Template.alerts.helpers({ |
||||
isSafariIos: /iP(ad|hone|od).+Version\/[\d\.]+.*Safari/i.test(navigator.userAgent), |
||||
}); |
@ -0,0 +1,39 @@ |
||||
import { Blaze } from 'meteor/blaze'; |
||||
import { Session } from 'meteor/session'; |
||||
import { getAvatarUrlFromUsername } from 'meteor/rocketchat:utils'; |
||||
import { RoomManager } from './RoomManager'; |
||||
|
||||
Blaze.registerHelper('avatarUrlFromUsername', getAvatarUrlFromUsername); |
||||
|
||||
export const getAvatarAsPng = function(username, cb) { |
||||
const image = new Image; |
||||
image.src = getAvatarUrlFromUsername(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(''); |
||||
} |
||||
}; |
||||
return image.onerror = function() { |
||||
return cb(''); |
||||
}; |
||||
}; |
||||
|
||||
export const updateAvatarOfUsername = function(username) { |
||||
const key = `avatar_random_${ username }`; |
||||
Session.set(key, Math.round(Math.random() * 1000)); |
||||
|
||||
Object.keys(RoomManager.openedRooms).forEach((key) => { |
||||
const room = RoomManager.openedRooms[key]; |
||||
const url = getAvatarUrlFromUsername(username); |
||||
$(room.dom).find(`.message[data-username='${ username }'] .avatar-image`).css('background-image', `url(${ url })`); |
||||
}); |
||||
return true; |
||||
}; |
@ -0,0 +1,211 @@ |
||||
import './popout.html'; |
||||
import { Blaze } from 'meteor/blaze'; |
||||
import { ReactiveVar } from 'meteor/reactive-var'; |
||||
import { Template } from 'meteor/templating'; |
||||
import { callbacks } from 'meteor/rocketchat:callbacks'; |
||||
|
||||
export const popout = { |
||||
context: null, |
||||
isAudioOnly: false, |
||||
showVideoControls: true, |
||||
showStreamControls: false, |
||||
x: 0, |
||||
y: 0, |
||||
open(config = {}, fn) { |
||||
this.close(); |
||||
this.context = Blaze.renderWithData(Template.popout, config, document.body); |
||||
this.fn = fn; |
||||
this.config = config; |
||||
this.onCloseCallback = config.onCloseCallback || null; |
||||
this.timer = null; |
||||
if (config.timer) { |
||||
this.timer = setTimeout(() => this.close(), config.timer); |
||||
} |
||||
if (config.data) { |
||||
this.isAudioOnly = config.data.isAudioOnly; |
||||
this.showVideoControls = config.data.showVideoControls; |
||||
this.showStreamControls = config.data.showStreamControls; |
||||
} |
||||
}, |
||||
close() { |
||||
if (this.context) { |
||||
Blaze.remove(this.context); |
||||
} |
||||
this.context = null; |
||||
this.fn = null; |
||||
if (this.timer) { |
||||
clearTimeout(this.timer); |
||||
} |
||||
if (typeof(this.onCloseCallback) === 'function') { |
||||
this.onCloseCallback(); |
||||
} |
||||
}, |
||||
dragstart(event) { |
||||
if (!event.target.classList.contains('dropzone-overlay')) { |
||||
const popoutElement = document.querySelector('.rc-popout-wrapper'); |
||||
setTimeout(function() { |
||||
popoutElement.style.display = 'none'; |
||||
}, 0); |
||||
} |
||||
}, |
||||
dragover(event) { |
||||
const e = event.originalEvent || event; |
||||
e.dataTransfer.dropEffect = 'move'; |
||||
e.preventDefault(); |
||||
}, |
||||
dragend(event) { |
||||
if (!event.target.classList.contains('dropzone-overlay')) { |
||||
const popoutElement = document.querySelector('.rc-popout-wrapper'); |
||||
popoutElement.style.display = 'initial'; |
||||
} |
||||
}, |
||||
drop(event) { |
||||
const e = event.originalEvent || event; |
||||
e.preventDefault(); |
||||
// do not mess with the position if we are dropping files in the dropzone
|
||||
if (!event.target.classList.contains('dropzone-overlay')) { |
||||
const popoutElement = document.querySelector('.rc-popout-wrapper'); |
||||
const positionTop = e.clientY - popout.y; |
||||
const positionLeft = e.clientX - popout.x; |
||||
popoutElement.style.left = `${ positionLeft >= 0 ? positionLeft : 0 }px`; |
||||
popoutElement.style.top = `${ positionTop >= 0 ? positionTop : 0 }px`; |
||||
} |
||||
}, |
||||
}; |
||||
|
||||
Template.popout.helpers({ |
||||
state() { |
||||
return Template.instance().isMinimized.get() ? 'closed' : 'open'; |
||||
}, |
||||
isAudioOnly() { |
||||
return Template.instance().isAudioOnly.get(); |
||||
}, |
||||
isMuted() { |
||||
return Template.instance().isMuted.get(); |
||||
}, |
||||
isPlaying() { |
||||
return Template.instance().isPlaying.get(); |
||||
}, |
||||
showVideoControls() { |
||||
return Template.instance().showVideoControls.get(); |
||||
}, |
||||
showStreamControls() { |
||||
return Template.instance().showStreamControls.get(); |
||||
}, |
||||
getStreamStatus() { |
||||
return Template.instance().streamStatus.get(); |
||||
}, |
||||
}); |
||||
|
||||
Template.popout.onRendered(function() { |
||||
Template.instance().isMinimized.set(popout.isAudioOnly); |
||||
Template.instance().isAudioOnly.set(popout.isAudioOnly); |
||||
Template.instance().showVideoControls.set(popout.showVideoControls); |
||||
Template.instance().showStreamControls.set(popout.showStreamControls); |
||||
|
||||
|
||||
if (this.data.onRendered) { |
||||
this.data.onRendered(); |
||||
} |
||||
}); |
||||
Template.popout.onCreated(function() { |
||||
this.isMinimized = new ReactiveVar(popout.isAudioOnly); |
||||
this.isAudioOnly = new ReactiveVar(popout.isAudioOnly); |
||||
this.canOpenExternal = new ReactiveVar(popout.canOpenExternal); |
||||
this.showVideoControls = new ReactiveVar(popout.showVideoControls); |
||||
this.showStreamControls = new ReactiveVar(popout.showStreamControls); |
||||
|
||||
this.isMuted = new ReactiveVar(false); |
||||
this.isPlaying = new ReactiveVar(true); |
||||
this.streamStatus = new ReactiveVar('preparing'); |
||||
document.body.addEventListener('dragstart', popout.dragstart, true); |
||||
document.body.addEventListener('dragover', popout.dragover, true); |
||||
document.body.addEventListener('dragend', popout.dragend, true); |
||||
document.body.addEventListener('drop', popout.drop, true); |
||||
}); |
||||
|
||||
Template.popout.onDestroyed(function() { |
||||
popout.context = null; |
||||
document.body.removeEventListener('dragstart', popout.dragstart, true); |
||||
document.body.removeEventListener('dragover', popout.dragover, true); |
||||
document.body.removeEventListener('dragend', popout.dragend, true); |
||||
document.body.removeEventListener('drop', popout.drop, true); |
||||
}); |
||||
|
||||
Template.popout.events({ |
||||
'click .js-action'(e, instance) { |
||||
!this.action || this.action.call(instance.data.data, e, instance); |
||||
e.stopPropagation(); |
||||
popout.close(); |
||||
}, |
||||
'click .js-close'(e) { |
||||
e.stopPropagation(); |
||||
popout.close(); |
||||
}, |
||||
'click .js-minimize'(e, i) { |
||||
e.stopPropagation(); |
||||
if (i.isMinimized.get()) { |
||||
i.isMinimized.set(false); |
||||
window.liveStreamPlayer.setSize(380, 214); |
||||
} else { |
||||
i.isMinimized.set(true); |
||||
window.liveStreamPlayer.setSize(0, 0); |
||||
} |
||||
}, |
||||
'dragstart .rc-popout-wrapper'(event) { |
||||
const e = event.originalEvent || event; |
||||
const url = (this.data && this.data.streamingSource) || '.rc-popout-wrapper'; |
||||
popout.x = e.offsetX; |
||||
popout.y = e.offsetY; |
||||
e.dataTransfer.setData('application/x-moz-node', e.currentTarget); |
||||
e.dataTransfer.setData('text/plain', url); |
||||
e.dataTransfer.effectAllowed = 'move'; |
||||
}, |
||||
'dragend .rc-popout-wrapper'(event) { |
||||
event.preventDefault(); |
||||
}, |
||||
'click .rc-popout__controls--record'(e, i) { |
||||
e.preventDefault(); |
||||
if (i.streamStatus.get() === 'ready') { |
||||
document.querySelector('.streaming-popup').dispatchEvent(new Event('startStreaming')); |
||||
i.streamStatus.set('starting'); |
||||
} else if (i.streamStatus.get() === 'broadcasting') { |
||||
document.querySelector('.streaming-popup').dispatchEvent(new Event('stopStreaming')); |
||||
i.streamStatus.set('finished'); |
||||
setTimeout(() => popout && popout.close(), 2000); |
||||
} |
||||
}, |
||||
'broadcastStreamReady .streaming-popup'(e, i) { |
||||
e.preventDefault(); |
||||
i.streamStatus.set('ready'); |
||||
}, |
||||
'broadcastStream .streaming-popup'(e, i) { |
||||
e.preventDefault(); |
||||
i.streamStatus.set('broadcasting'); |
||||
}, |
||||
'click .rc-popout__controls--play'(e, i) { |
||||
window.liveStreamPlayer.playVideo(); |
||||
i.isPlaying.set(true); |
||||
}, |
||||
'click .rc-popout__controls--pause'(e, i) { |
||||
window.liveStreamPlayer.pauseVideo(); |
||||
i.isPlaying.set(false); |
||||
}, |
||||
'click .rc-popout__controls--mute'(e, i) { |
||||
window.liveStreamPlayer.mute(); |
||||
i.isMuted.set(true); |
||||
}, |
||||
'click .rc-popout__controls--unmute'(e, i) { |
||||
window.liveStreamPlayer.unMute(); |
||||
i.isMuted.set(false); |
||||
}, |
||||
'playerStateChanged .rc-popout'(e, i) { |
||||
if (e.detail === window.YT.PlayerState.PLAYING) { |
||||
i.isPlaying.set(true); |
||||
} else if (e.detail === window.YT.PlayerState.PAUSED) { |
||||
i.isPlaying.set(false); |
||||
} |
||||
}, |
||||
}); |
||||
|
||||
callbacks.add('afterLogoutCleanUp', () => popout.close(), callbacks.priority.MEDIUM, 'popout-close-after-logout-cleanup'); |
@ -0,0 +1,16 @@ |
||||
import { emoji } from 'meteor/rocketchat:emoji'; |
||||
import GraphemeSplitter from 'grapheme-splitter'; |
||||
|
||||
const splitter = new GraphemeSplitter(); |
||||
|
||||
export const messageProperties = { |
||||
|
||||
length: ((message) => splitter.countGraphemes(message)), |
||||
|
||||
messageWithoutEmojiShortnames: ((message) => message.replace(/:\w+:/gm, (match) => { |
||||
if (emoji.list[match] !== undefined) { |
||||
return ' '; |
||||
} |
||||
return match; |
||||
})), |
||||
}; |
@ -0,0 +1,19 @@ |
||||
export const MessageTypes = new class { |
||||
constructor() { |
||||
this.types = {}; |
||||
} |
||||
|
||||
registerType(options) { |
||||
return this.types[options.id] = options; |
||||
} |
||||
|
||||
getType(message) { |
||||
return this.types[message && message.t]; |
||||
} |
||||
|
||||
isSystemMessage(message) { |
||||
const type = this.types[message && message.t]; |
||||
return type && type.system; |
||||
} |
||||
|
||||
}; |
@ -0,0 +1,2 @@ |
||||
export { messageProperties } from '../lib/MessageProperties'; |
||||
export { MessageTypes } from '../lib/MessageTypes'; |
@ -0,0 +1,8 @@ |
||||
import mock from 'mock-require'; |
||||
|
||||
mock('meteor/rocketchat:emoji', { |
||||
emoji: { |
||||
list: { |
||||
}, |
||||
}, |
||||
}); |
@ -0,0 +1,22 @@ |
||||
/* eslint-env mocha */ |
||||
import 'babel-polyfill'; |
||||
import assert from 'assert'; |
||||
import './server.mocks.js'; |
||||
import { messageProperties } from '../lib/MessageProperties'; |
||||
|
||||
const messages = { |
||||
'Sample Message': 14, |
||||
'Sample 1 ⛳': 10, |
||||
'Sample 2 ❤': 10, |
||||
'Sample 3 ⛳❤⛳❤': 13, |
||||
}; |
||||
|
||||
describe('Message Properties', () => { |
||||
describe('Check Message Length', () => { |
||||
Object.keys(messages).forEach((objectKey) => { |
||||
it('should treat emojis as single characters', () => { |
||||
assert.equal(messageProperties.length(objectKey), messages[objectKey]); |
||||
}); |
||||
}); |
||||
}); |
||||
}); |
@ -1,37 +1,7 @@ |
||||
import { Blaze } from 'meteor/blaze'; |
||||
import { Session } from 'meteor/session'; |
||||
import { getAvatarAsPng, updateAvatarOfUsername as _updateAvatarOfUsername } from 'meteor/rocketchat:ui-utils'; |
||||
|
||||
Blaze.registerHelper('avatarUrlFromUsername', getAvatarUrlFromUsername); |
||||
|
||||
export const getAvatarAsPng = function(username, cb) { |
||||
const image = new Image; |
||||
image.src = getAvatarUrlFromUsername(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(''); |
||||
} |
||||
}; |
||||
return image.onerror = function() { |
||||
return cb(''); |
||||
}; |
||||
export { |
||||
getAvatarAsPng, |
||||
}; |
||||
|
||||
updateAvatarOfUsername = function(username) { |
||||
const key = `avatar_random_${ username }`; |
||||
Session.set(key, Math.round(Math.random() * 1000)); |
||||
|
||||
Object.keys(RoomManager.openedRooms).forEach((key) => { |
||||
const room = RoomManager.openedRooms[key]; |
||||
const url = getAvatarUrlFromUsername(username); |
||||
$(room.dom).find(`.message[data-username='${ username }'] .avatar-image`).css('background-image', `url(${ url })`); |
||||
}); |
||||
return true; |
||||
}; |
||||
updateAvatarOfUsername = _updateAvatarOfUsername; |
||||
|
@ -1,72 +1,3 @@ |
||||
import { Blaze } from 'meteor/blaze'; |
||||
import { Template } from 'meteor/templating'; |
||||
import { alerts as _alerts } from 'meteor/rocketchat:ui-utils'; |
||||
|
||||
alerts = { |
||||
renderedAlert: null, |
||||
open(config) { |
||||
this.close(false); |
||||
|
||||
config.closable = typeof(config.closable) === typeof(true) ? config.closable : true; |
||||
|
||||
if (config.timer) { |
||||
this.timer = setTimeout(() => this.close(), config.timer); |
||||
} |
||||
|
||||
this.renderedAlert = Blaze.renderWithData(Template.alerts, config, document.body, document.body.querySelector('#alert-anchor')); |
||||
}, |
||||
close(dismiss = true) { |
||||
if (this.timer) { |
||||
clearTimeout(this.timer); |
||||
delete this.timer; |
||||
} |
||||
if (!this.renderedAlert) { |
||||
return false; |
||||
} |
||||
|
||||
Blaze.remove(this.renderedAlert); |
||||
|
||||
const { activeElement } = this.renderedAlert.dataVar.curValue; |
||||
if (activeElement) { |
||||
$(activeElement).removeClass('active'); |
||||
} |
||||
|
||||
dismiss && this.renderedAlert.dataVar.curValue.onClose && this.renderedAlert.dataVar.curValue.onClose(); |
||||
}, |
||||
}; |
||||
|
||||
Template.alerts.helpers({ |
||||
hasAction() { |
||||
return Template.instance().data.action ? 'rc-alerts--has-action' : ''; |
||||
}, |
||||
modifiers() { |
||||
return (Template.instance().data.modifiers || []).map((mod) => `rc-alerts--${ mod }`).join(' '); |
||||
}, |
||||
}); |
||||
|
||||
Template.alerts.onRendered(function() { |
||||
if (this.data.onRendered) { |
||||
this.data.onRendered(); |
||||
} |
||||
}); |
||||
|
||||
Template.alerts.onDestroyed(function() { |
||||
if (this.data.onDestroyed) { |
||||
this.data.onDestroyed(); |
||||
} |
||||
}); |
||||
|
||||
Template.alerts.events({ |
||||
'click .js-action'(e, instance) { |
||||
if (!this.action) { |
||||
return; |
||||
} |
||||
this.action.call(this, e, instance.data.data); |
||||
}, |
||||
'click .js-close'() { |
||||
alerts.close(); |
||||
}, |
||||
}); |
||||
|
||||
Template.alerts.helpers({ |
||||
isSafariIos: /iP(ad|hone|od).+Version\/[\d\.]+.*Safari/i.test(navigator.userAgent), |
||||
}); |
||||
alerts = _alerts; |
||||
|
@ -1,209 +1,3 @@ |
||||
import { Blaze } from 'meteor/blaze'; |
||||
import { ReactiveVar } from 'meteor/reactive-var'; |
||||
import { Template } from 'meteor/templating'; |
||||
import { popout as _popout } from 'meteor/rocketchat:ui-utils'; |
||||
|
||||
popout = { |
||||
context: null, |
||||
isAudioOnly: false, |
||||
showVideoControls: true, |
||||
showStreamControls: false, |
||||
x: 0, |
||||
y: 0, |
||||
open(config = {}, fn) { |
||||
this.close(); |
||||
this.context = Blaze.renderWithData(Template.popout, config, document.body); |
||||
this.fn = fn; |
||||
this.config = config; |
||||
this.onCloseCallback = config.onCloseCallback || null; |
||||
this.timer = null; |
||||
if (config.timer) { |
||||
this.timer = setTimeout(() => this.close(), config.timer); |
||||
} |
||||
if (config.data) { |
||||
this.isAudioOnly = config.data.isAudioOnly; |
||||
this.showVideoControls = config.data.showVideoControls; |
||||
this.showStreamControls = config.data.showStreamControls; |
||||
} |
||||
}, |
||||
close() { |
||||
if (this.context) { |
||||
Blaze.remove(this.context); |
||||
} |
||||
this.context = null; |
||||
this.fn = null; |
||||
if (this.timer) { |
||||
clearTimeout(this.timer); |
||||
} |
||||
if (typeof(this.onCloseCallback) === 'function') { |
||||
this.onCloseCallback(); |
||||
} |
||||
}, |
||||
dragstart(event) { |
||||
if (!event.target.classList.contains('dropzone-overlay')) { |
||||
const popoutElement = document.querySelector('.rc-popout-wrapper'); |
||||
setTimeout(function() { |
||||
popoutElement.style.display = 'none'; |
||||
}, 0); |
||||
} |
||||
}, |
||||
dragover(event) { |
||||
const e = event.originalEvent || event; |
||||
e.dataTransfer.dropEffect = 'move'; |
||||
e.preventDefault(); |
||||
}, |
||||
dragend(event) { |
||||
if (!event.target.classList.contains('dropzone-overlay')) { |
||||
const popoutElement = document.querySelector('.rc-popout-wrapper'); |
||||
popoutElement.style.display = 'initial'; |
||||
} |
||||
}, |
||||
drop(event) { |
||||
const e = event.originalEvent || event; |
||||
e.preventDefault(); |
||||
// do not mess with the position if we are dropping files in the dropzone
|
||||
if (!event.target.classList.contains('dropzone-overlay')) { |
||||
const popoutElement = document.querySelector('.rc-popout-wrapper'); |
||||
const positionTop = e.clientY - popout.y; |
||||
const positionLeft = e.clientX - popout.x; |
||||
popoutElement.style.left = `${ positionLeft >= 0 ? positionLeft : 0 }px`; |
||||
popoutElement.style.top = `${ positionTop >= 0 ? positionTop : 0 }px`; |
||||
} |
||||
}, |
||||
}; |
||||
|
||||
Template.popout.helpers({ |
||||
state() { |
||||
return Template.instance().isMinimized.get() ? 'closed' : 'open'; |
||||
}, |
||||
isAudioOnly() { |
||||
return Template.instance().isAudioOnly.get(); |
||||
}, |
||||
isMuted() { |
||||
return Template.instance().isMuted.get(); |
||||
}, |
||||
isPlaying() { |
||||
return Template.instance().isPlaying.get(); |
||||
}, |
||||
showVideoControls() { |
||||
return Template.instance().showVideoControls.get(); |
||||
}, |
||||
showStreamControls() { |
||||
return Template.instance().showStreamControls.get(); |
||||
}, |
||||
getStreamStatus() { |
||||
return Template.instance().streamStatus.get(); |
||||
}, |
||||
}); |
||||
|
||||
Template.popout.onRendered(function() { |
||||
Template.instance().isMinimized.set(popout.isAudioOnly); |
||||
Template.instance().isAudioOnly.set(popout.isAudioOnly); |
||||
Template.instance().showVideoControls.set(popout.showVideoControls); |
||||
Template.instance().showStreamControls.set(popout.showStreamControls); |
||||
|
||||
|
||||
if (this.data.onRendered) { |
||||
this.data.onRendered(); |
||||
} |
||||
}); |
||||
Template.popout.onCreated(function() { |
||||
this.isMinimized = new ReactiveVar(popout.isAudioOnly); |
||||
this.isAudioOnly = new ReactiveVar(popout.isAudioOnly); |
||||
this.canOpenExternal = new ReactiveVar(popout.canOpenExternal); |
||||
this.showVideoControls = new ReactiveVar(popout.showVideoControls); |
||||
this.showStreamControls = new ReactiveVar(popout.showStreamControls); |
||||
|
||||
this.isMuted = new ReactiveVar(false); |
||||
this.isPlaying = new ReactiveVar(true); |
||||
this.streamStatus = new ReactiveVar('preparing'); |
||||
document.body.addEventListener('dragstart', popout.dragstart, true); |
||||
document.body.addEventListener('dragover', popout.dragover, true); |
||||
document.body.addEventListener('dragend', popout.dragend, true); |
||||
document.body.addEventListener('drop', popout.drop, true); |
||||
}); |
||||
|
||||
Template.popout.onDestroyed(function() { |
||||
popout.context = null; |
||||
document.body.removeEventListener('dragstart', popout.dragstart, true); |
||||
document.body.removeEventListener('dragover', popout.dragover, true); |
||||
document.body.removeEventListener('dragend', popout.dragend, true); |
||||
document.body.removeEventListener('drop', popout.drop, true); |
||||
}); |
||||
|
||||
Template.popout.events({ |
||||
'click .js-action'(e, instance) { |
||||
!this.action || this.action.call(instance.data.data, e, instance); |
||||
e.stopPropagation(); |
||||
popout.close(); |
||||
}, |
||||
'click .js-close'(e) { |
||||
e.stopPropagation(); |
||||
popout.close(); |
||||
}, |
||||
'click .js-minimize'(e, i) { |
||||
e.stopPropagation(); |
||||
if (i.isMinimized.get()) { |
||||
i.isMinimized.set(false); |
||||
window.liveStreamPlayer.setSize(380, 214); |
||||
} else { |
||||
i.isMinimized.set(true); |
||||
window.liveStreamPlayer.setSize(0, 0); |
||||
} |
||||
}, |
||||
'dragstart .rc-popout-wrapper'(event) { |
||||
const e = event.originalEvent || event; |
||||
const url = (this.data && this.data.streamingSource) || '.rc-popout-wrapper'; |
||||
popout.x = e.offsetX; |
||||
popout.y = e.offsetY; |
||||
e.dataTransfer.setData('application/x-moz-node', e.currentTarget); |
||||
e.dataTransfer.setData('text/plain', url); |
||||
e.dataTransfer.effectAllowed = 'move'; |
||||
}, |
||||
'dragend .rc-popout-wrapper'(event) { |
||||
event.preventDefault(); |
||||
}, |
||||
'click .rc-popout__controls--record'(e, i) { |
||||
e.preventDefault(); |
||||
if (i.streamStatus.get() === 'ready') { |
||||
document.querySelector('.streaming-popup').dispatchEvent(new Event('startStreaming')); |
||||
i.streamStatus.set('starting'); |
||||
} else if (i.streamStatus.get() === 'broadcasting') { |
||||
document.querySelector('.streaming-popup').dispatchEvent(new Event('stopStreaming')); |
||||
i.streamStatus.set('finished'); |
||||
setTimeout(() => popout && popout.close(), 2000); |
||||
} |
||||
}, |
||||
'broadcastStreamReady .streaming-popup'(e, i) { |
||||
e.preventDefault(); |
||||
i.streamStatus.set('ready'); |
||||
}, |
||||
'broadcastStream .streaming-popup'(e, i) { |
||||
e.preventDefault(); |
||||
i.streamStatus.set('broadcasting'); |
||||
}, |
||||
'click .rc-popout__controls--play'(e, i) { |
||||
window.liveStreamPlayer.playVideo(); |
||||
i.isPlaying.set(true); |
||||
}, |
||||
'click .rc-popout__controls--pause'(e, i) { |
||||
window.liveStreamPlayer.pauseVideo(); |
||||
i.isPlaying.set(false); |
||||
}, |
||||
'click .rc-popout__controls--mute'(e, i) { |
||||
window.liveStreamPlayer.mute(); |
||||
i.isMuted.set(true); |
||||
}, |
||||
'click .rc-popout__controls--unmute'(e, i) { |
||||
window.liveStreamPlayer.unMute(); |
||||
i.isMuted.set(false); |
||||
}, |
||||
'playerStateChanged .rc-popout'(e, i) { |
||||
if (e.detail === window.YT.PlayerState.PLAYING) { |
||||
i.isPlaying.set(true); |
||||
} else if (e.detail === window.YT.PlayerState.PAUSED) { |
||||
i.isPlaying.set(false); |
||||
} |
||||
}, |
||||
}); |
||||
|
||||
RocketChat.callbacks.add('afterLogoutCleanUp', () => popout.close(), RocketChat.callbacks.priority.MEDIUM, 'popout-close-after-logout-cleanup'); |
||||
popout = _popout; |
||||
|
Loading…
Reference in new issue