parent
7a2e9f7786
commit
a8ad6397ef
@ -1,91 +0,0 @@ |
||||
@AccountBox = (-> |
||||
status = 0 |
||||
self = {} |
||||
items = new ReactiveVar [] |
||||
|
||||
setStatus = (status) -> |
||||
Meteor.call('UserPresence:setDefaultStatus', status) |
||||
|
||||
toggle = -> |
||||
if status then close() else open() |
||||
|
||||
open = -> |
||||
if SideNav.flexStatus() |
||||
SideNav.closeFlex() |
||||
return; |
||||
status = 1 |
||||
self.options.removeClass("animated-hidden") |
||||
self.box.addClass("active") |
||||
SideNav.toggleArrow 1 |
||||
|
||||
close = -> |
||||
status = 0 |
||||
self.options.addClass("animated-hidden") |
||||
self.box.removeClass("active") |
||||
SideNav.toggleArrow -1 |
||||
|
||||
openFlex = -> |
||||
status = 0 |
||||
self.options.addClass("animated-hidden") |
||||
self.box.removeClass("active") |
||||
|
||||
init = -> |
||||
self.box = $(".account-box") |
||||
self.options = self.box.find(".options") |
||||
|
||||
### |
||||
# @param newOption: |
||||
# name: Button label |
||||
# icon: Button icon |
||||
# class: Class of the item |
||||
# permissions: Which permissions a user should have (all of them) to see this item |
||||
### |
||||
addItem = (newItem) -> |
||||
Tracker.nonreactive -> |
||||
actual = items.get() |
||||
actual.push newItem |
||||
items.set actual |
||||
|
||||
checkCondition = (item) -> |
||||
return not item.condition? or item.condition() |
||||
|
||||
getItems = -> |
||||
return _.filter items.get(), (item) -> |
||||
if checkCondition(item) |
||||
return true |
||||
|
||||
addRoute = (newRoute, router = FlowRouter) -> |
||||
|
||||
# @TODO check for mandatory fields |
||||
routeConfig = |
||||
center: 'pageContainer' |
||||
pageTemplate: newRoute.pageTemplate |
||||
|
||||
if newRoute.i18nPageTitle? |
||||
routeConfig.i18nPageTitle = newRoute.i18nPageTitle |
||||
|
||||
if newRoute.pageTitle? |
||||
routeConfig.pageTitle = newRoute.pageTitle |
||||
|
||||
router.route newRoute.path, |
||||
name: newRoute.name |
||||
action: -> |
||||
Session.set 'openedRoom' |
||||
BlazeLayout.render 'main', routeConfig |
||||
triggersEnter: [ -> |
||||
if newRoute.sideNav? |
||||
SideNav.setFlex newRoute.sideNav |
||||
SideNav.openFlex() |
||||
] |
||||
|
||||
setStatus: setStatus |
||||
toggle: toggle |
||||
open: open |
||||
close: close |
||||
openFlex: openFlex |
||||
init: init |
||||
|
||||
addRoute: addRoute |
||||
addItem: addItem |
||||
getItems: getItems |
||||
)() |
@ -0,0 +1,106 @@ |
||||
this.AccountBox = (function() { |
||||
let status = 0; |
||||
const self = {}; |
||||
const items = new ReactiveVar([]); |
||||
function setStatus(status) { |
||||
return Meteor.call('UserPresence:setDefaultStatus', status); |
||||
} |
||||
function open() { |
||||
if (SideNav.flexStatus()) { |
||||
SideNav.closeFlex(); |
||||
return; |
||||
} |
||||
status = 1; |
||||
self.options.removeClass('animated-hidden'); |
||||
self.box.addClass('active'); |
||||
return SideNav.toggleArrow(1); |
||||
} |
||||
function close() { |
||||
status = 0; |
||||
self.options.addClass('animated-hidden'); |
||||
self.box.removeClass('active'); |
||||
return SideNav.toggleArrow(-1); |
||||
} |
||||
function toggle() { |
||||
if (status) { |
||||
return close(); |
||||
} else { |
||||
return open(); |
||||
} |
||||
} |
||||
function openFlex() { |
||||
status = 0; |
||||
self.options.addClass('animated-hidden'); |
||||
return self.box.removeClass('active'); |
||||
} |
||||
function init() { |
||||
self.box = $('.account-box'); |
||||
return self.options = self.box.find('.options'); |
||||
} |
||||
|
||||
/* |
||||
* @param newOption: |
||||
* name: Button label |
||||
* icon: Button icon |
||||
* class: Class of the item |
||||
* permissions: Which permissions a user should have (all of them) to see this item |
||||
*/ |
||||
function addItem(newItem) { |
||||
return Tracker.nonreactive(function() { |
||||
const actual = items.get(); |
||||
actual.push(newItem); |
||||
return items.set(actual); |
||||
}); |
||||
} |
||||
function checkCondition(item) { |
||||
return (item.condition == null) || item.condition(); |
||||
} |
||||
function getItems() { |
||||
return _.filter(items.get(), function(item) { |
||||
if (checkCondition(item)) { |
||||
return true; |
||||
} |
||||
}); |
||||
} |
||||
function addRoute(newRoute, router) { |
||||
if (router == null) { |
||||
router = FlowRouter; |
||||
} |
||||
const routeConfig = { |
||||
center: 'pageContainer', |
||||
pageTemplate: newRoute.pageTemplate |
||||
}; |
||||
if (newRoute.i18nPageTitle != null) { |
||||
routeConfig.i18nPageTitle = newRoute.i18nPageTitle; |
||||
} |
||||
if (newRoute.pageTitle != null) { |
||||
routeConfig.pageTitle = newRoute.pageTitle; |
||||
} |
||||
return router.route(newRoute.path, { |
||||
name: newRoute.name, |
||||
action() { |
||||
Session.set('openedRoom'); |
||||
return BlazeLayout.render('main', routeConfig); |
||||
}, |
||||
triggersEnter: [ |
||||
function() { |
||||
if (newRoute.sideNav != null) { |
||||
SideNav.setFlex(newRoute.sideNav); |
||||
return SideNav.openFlex(); |
||||
} |
||||
} |
||||
] |
||||
}); |
||||
} |
||||
return { |
||||
setStatus, |
||||
toggle, |
||||
open, |
||||
close, |
||||
openFlex, |
||||
init, |
||||
addRoute, |
||||
addItem, |
||||
getItems |
||||
}; |
||||
}()); |
@ -1,6 +0,0 @@ |
||||
import toastr from 'toastr' |
||||
Accounts.onEmailVerificationLink (token, done) -> |
||||
Accounts.verifyEmail token, (error) -> |
||||
if not error? |
||||
toastr.success t('Email_verified') |
||||
done() |
@ -0,0 +1,9 @@ |
||||
import toastr from 'toastr'; |
||||
Accounts.onEmailVerificationLink(function(token, done) { |
||||
Accounts.verifyEmail(token, function(error) { |
||||
if (error == null) { |
||||
toastr.success(t('Email_verified')); |
||||
} |
||||
return done(); |
||||
}); |
||||
}); |
@ -1,26 +0,0 @@ |
||||
Blaze.registerHelper 'avatarUrlFromUsername', getAvatarUrlFromUsername |
||||
|
||||
@getAvatarAsPng = (username, cb) -> |
||||
image = new Image |
||||
image.src = getAvatarUrlFromUsername(username) |
||||
|
||||
image.onload = -> |
||||
canvas = document.createElement('canvas') |
||||
canvas.width = image.width |
||||
canvas.height = image.height |
||||
context = canvas.getContext('2d') |
||||
context.drawImage(image, 0, 0) |
||||
cb canvas.toDataURL('image/png') |
||||
image.onerror = -> |
||||
cb '' |
||||
|
||||
@updateAvatarOfUsername = (username) -> |
||||
key = "avatar_random_#{username}" |
||||
Session.set key, Math.round(Math.random() * 1000) |
||||
|
||||
for key, room of RoomManager.openedRooms |
||||
url = getAvatarUrlFromUsername username |
||||
|
||||
$(room.dom).find(".message[data-username='#{username}'] .avatar-image").css('background-image', "url(#{url})"); |
||||
|
||||
return true |
@ -0,0 +1,31 @@ |
||||
Blaze.registerHelper('avatarUrlFromUsername', getAvatarUrlFromUsername); |
||||
|
||||
this.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); |
||||
return cb(canvas.toDataURL('image/png')); |
||||
}; |
||||
return image.onerror = function() { |
||||
return cb(''); |
||||
}; |
||||
}; |
||||
|
||||
this.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; |
||||
}; |
@ -1,29 +0,0 @@ |
||||
Meteor.loginWithFacebookCordova = (options, callback) -> |
||||
if not callback and typeof options is "function" |
||||
callback = options |
||||
options = null |
||||
|
||||
credentialRequestCompleteCallback = Accounts.oauth.credentialRequestCompleteHandler(callback) |
||||
|
||||
fbLoginSuccess = (data) -> |
||||
data.cordova = true |
||||
|
||||
Accounts.callLoginMethod |
||||
methodArguments: [data] |
||||
userCallback: callback |
||||
|
||||
if typeof facebookConnectPlugin isnt "undefined" |
||||
facebookConnectPlugin.getLoginStatus (response) -> |
||||
if response.status isnt "connected" |
||||
facebookConnectPlugin.login ["public_profile", "email"], fbLoginSuccess, (error) -> |
||||
console.log('login', JSON.stringify(error), error) |
||||
callback(error) |
||||
else |
||||
fbLoginSuccess(response) |
||||
|
||||
, (error) -> |
||||
console.log('getLoginStatus', JSON.stringify(error), error) |
||||
callback(error) |
||||
|
||||
else |
||||
Facebook.requestCredential(options, credentialRequestCompleteCallback) |
@ -0,0 +1,31 @@ |
||||
/* globals facebookConnectPlugin Facebook*/ |
||||
Meteor.loginWithFacebookCordova = function(options, callback) { |
||||
if (!callback && typeof options === 'function') { |
||||
callback = options; |
||||
options = null; |
||||
} |
||||
const credentialRequestCompleteCallback = Accounts.oauth.credentialRequestCompleteHandler(callback); |
||||
const fbLoginSuccess = function(data) { |
||||
data.cordova = true; |
||||
return Accounts.callLoginMethod({ |
||||
methodArguments: [data], |
||||
userCallback: callback |
||||
}); |
||||
}; |
||||
if (typeof facebookConnectPlugin !== 'undefined') { |
||||
return facebookConnectPlugin.getLoginStatus(function(response) { |
||||
if (response.status !== 'connected') { |
||||
return facebookConnectPlugin.login(['public_profile', 'email'], fbLoginSuccess, function(error) { |
||||
console.log('login', JSON.stringify(error), error); |
||||
return callback(error); |
||||
}); |
||||
} else { |
||||
return fbLoginSuccess(response); |
||||
} |
||||
}, function(error) { |
||||
console.log('getLoginStatus', JSON.stringify(error), error); |
||||
return callback(error); |
||||
}); |
||||
} |
||||
return Facebook.requestCredential(options, credentialRequestCompleteCallback); |
||||
}; |
@ -1,25 +0,0 @@ |
||||
if Meteor.isCordova |
||||
document.addEventListener 'deviceready', -> |
||||
if device?.platform.toLowerCase() isnt 'android' |
||||
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true); |
||||
cordova.plugins.Keyboard.disableScroll(true); |
||||
|
||||
window.addEventListener 'native.keyboardshow', -> |
||||
if device?.platform.toLowerCase() isnt 'android' |
||||
if Meteor.userId()? |
||||
$('.main-content').css 'height', window.innerHeight |
||||
$('.sweet-alert').css 'transform', "translateY(-#{(document.height - window.innerHeight) / 2}px)" |
||||
$('.sweet-alert').css '-webkit-transform', "translateY(-#{(document.height - window.innerHeight) / 2}px)" |
||||
else |
||||
$(document.body).css 'height', window.innerHeight |
||||
$(document.body).css 'overflow', 'scroll' |
||||
|
||||
window.addEventListener 'native.keyboardhide', -> |
||||
if device?.platform.toLowerCase() isnt 'android' |
||||
if Meteor.userId()? |
||||
$('.main-content').css 'height', window.innerHeight |
||||
$('.sweet-alert').css 'transform', '' |
||||
$('.sweet-alert').css '-webkit-transform', '' |
||||
else |
||||
$(document.body).css 'height', window.innerHeight |
||||
$(document.body).css 'overflow', 'visible' |
@ -0,0 +1,32 @@ |
||||
/* globals device cordova*/ |
||||
if (Meteor.isCordova) { |
||||
const body = $(document.body); |
||||
document.addEventListener('deviceready', function() { |
||||
if (typeof device !== 'undefined' && device !== null && device.platform.toLowerCase() !== 'android') { |
||||
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true); |
||||
return cordova.plugins.Keyboard.disableScroll(true); |
||||
} |
||||
}); |
||||
window.addEventListener('native.keyboardshow', function() { |
||||
if (typeof device !== 'undefined' && device !== null && device.platform.toLowerCase() !== 'android') { |
||||
if (Meteor.userId() != null) { |
||||
$('.main-content').css('height', window.innerHeight); |
||||
$('.sweet-alert').css('transform', `translateY(-${ (document.height - window.innerHeight) / 2 }px)`).css('-webkit-transform', `translateY(-${ (document.height - window.innerHeight) / 2 }px)`); |
||||
} else { |
||||
body.css('height', window.innerHeight); |
||||
body.css('overflow', 'scroll'); |
||||
} |
||||
} |
||||
}); |
||||
window.addEventListener('native.keyboardhide', function() { |
||||
if (typeof device !== 'undefined' && device !== null && device.platform.toLowerCase() !== 'android') { |
||||
if (Meteor.userId() != null) { |
||||
$('.main-content').css('height', window.innerHeight); |
||||
$('.sweet-alert').css('transform', '').css('-webkit-transform', ''); |
||||
} else { |
||||
body.css('height', window.innerHeight); |
||||
body.css('overflow', 'visible'); |
||||
} |
||||
} |
||||
}); |
||||
} |
@ -1,53 +0,0 @@ |
||||
@menu = new class |
||||
init: -> |
||||
@mainContent = $('.main-content') |
||||
@list = $('.rooms-list') |
||||
|
||||
Session.set("isMenuOpen", false) |
||||
|
||||
isOpen: -> |
||||
return Session.get("isMenuOpen") |
||||
|
||||
open: -> |
||||
Session.set("isMenuOpen", true) |
||||
if isRtl localStorage.getItem "userLanguage" |
||||
@mainContent?.css('transform', 'translateX(-260px)') |
||||
else |
||||
@mainContent?.css('transform', 'translateX(260px)') |
||||
|
||||
close: -> |
||||
Session.set("isMenuOpen", false) |
||||
@mainContent?.css('transform', 'translateX(0)') |
||||
|
||||
toggle: -> |
||||
if @isOpen() |
||||
@close() |
||||
else |
||||
@open() |
||||
|
||||
updateUnreadBars: _.throttle -> |
||||
if not @list? |
||||
return |
||||
|
||||
listOffset = @list.offset() |
||||
listHeight = @list.height() |
||||
|
||||
showTop = false |
||||
showBottom = false |
||||
$('li.has-alert').each -> |
||||
if $(this).offset().top < listOffset.top - $(this).height() |
||||
showTop = true |
||||
|
||||
if $(this).offset().top > listOffset.top + listHeight |
||||
showBottom = true |
||||
|
||||
if showTop is true |
||||
$('.top-unread-rooms').removeClass('hidden') |
||||
else |
||||
$('.top-unread-rooms').addClass('hidden') |
||||
|
||||
if showBottom is true |
||||
$('.bottom-unread-rooms').removeClass('hidden') |
||||
else |
||||
$('.bottom-unread-rooms').addClass('hidden') |
||||
, 200 |
@ -0,0 +1,55 @@ |
||||
/* globals isRtl */ |
||||
this.menu = new class { |
||||
constructor() { |
||||
this.updateUnreadBars = _.throttle(() => { |
||||
if (this.list == null) { |
||||
return; |
||||
} |
||||
const listOffset = this.list.offset(); |
||||
const listHeight = this.list.height(); |
||||
let showTop = false; |
||||
let showBottom = false; |
||||
$('li.has-alert').each(function() { |
||||
if ($(this).offset().top < listOffset.top - $(this).height()) { |
||||
showTop = true; |
||||
} |
||||
if ($(this).offset().top > listOffset.top + listHeight) { |
||||
return showBottom = true; |
||||
} |
||||
}); |
||||
if (showTop === true) { |
||||
$('.top-unread-rooms').removeClass('hidden'); |
||||
} else { |
||||
$('.top-unread-rooms').addClass('hidden'); |
||||
} |
||||
if (showBottom === true) { |
||||
return $('.bottom-unread-rooms').removeClass('hidden'); |
||||
} else { |
||||
return $('.bottom-unread-rooms').addClass('hidden'); |
||||
} |
||||
}, 200); |
||||
} |
||||
init() { |
||||
this.mainContent = $('.main-content'); |
||||
this.list = $('.rooms-list'); |
||||
Session.set('isMenuOpen', false); |
||||
} |
||||
|
||||
isOpen() { |
||||
return Session.get('isMenuOpen'); |
||||
} |
||||
|
||||
open() { |
||||
Session.set('isMenuOpen', true); |
||||
this.mainContent && this.mainContent.css('transform', `translateX(${ isRtl(localStorage.getItem('userLanguage'))?'-':'' }260px)`); |
||||
} |
||||
|
||||
close() { |
||||
Session.set('isMenuOpen', false); |
||||
this.mainContent && this.mainContent .css('transform', 'translateX(0)'); |
||||
} |
||||
|
||||
toggle() { |
||||
return this.isOpen() ? this.close() : this.open(); |
||||
} |
||||
}; |
@ -1,145 +0,0 @@ |
||||
@SideNav = (-> |
||||
initiated = false |
||||
sideNav = {} |
||||
flexNav = {} |
||||
arrow = {} |
||||
animating = false |
||||
openQueue = [] |
||||
|
||||
toggleArrow = (status = null) -> |
||||
if status is 0 |
||||
arrow.addClass "close" |
||||
arrow.removeClass "top" |
||||
arrow.removeClass "bottom" |
||||
else if status is -1 or (status isnt 1 and arrow.hasClass "top") |
||||
arrow.removeClass "close" |
||||
arrow.removeClass "top" |
||||
arrow.addClass "bottom" |
||||
else |
||||
arrow.removeClass "close" |
||||
arrow.addClass "top" |
||||
arrow.removeClass "bottom" |
||||
|
||||
toggleCurrent = -> |
||||
if flexNav.opened then closeFlex() else AccountBox.toggle() |
||||
|
||||
overArrow = -> |
||||
arrow.addClass "hover" |
||||
|
||||
leaveArrow = -> |
||||
arrow.removeClass "hover" |
||||
|
||||
arrowBindHover = -> |
||||
arrow.on "mouseenter", -> |
||||
sideNav.find("header").addClass "hover" |
||||
arrow.on "mouseout", -> |
||||
sideNav.find("header").removeClass "hover" |
||||
|
||||
focusInput = -> |
||||
sideNavDivs = _.filter document.querySelectorAll('aside.side-nav')[0].children, (ele) -> |
||||
ele.tagName == 'DIV' and !ele.classList.contains('hidden') |
||||
highestZidx = 0 |
||||
highestZidxElem = undefined |
||||
_.each sideNavDivs, (ele) -> |
||||
zIndex = Number(window.getComputedStyle(ele).zIndex) |
||||
if Number(zIndex) > highestZidx |
||||
highestZidx = Number(zIndex) |
||||
highestZidxElem = ele |
||||
return |
||||
setTimeout -> |
||||
highestZidxElem.querySelector('input')?.focus() |
||||
, 200 |
||||
return |
||||
|
||||
validate = -> |
||||
invalid = [] |
||||
sideNav.find("input.required").each -> |
||||
if not this.value.length |
||||
invalid.push $(this).prev("label").html() |
||||
if invalid.length |
||||
return invalid |
||||
return false; |
||||
|
||||
toggleFlex = (status = null, callback = null) -> |
||||
return if animating == true |
||||
animating = true |
||||
if status is -1 or (status isnt 1 and flexNav.opened) |
||||
flexNav.opened = false |
||||
flexNav.addClass "animated-hidden" |
||||
else |
||||
flexNav.opened = true |
||||
# added a delay to make sure the template is already rendered before animating it |
||||
setTimeout -> |
||||
flexNav.removeClass "animated-hidden" |
||||
, 50 |
||||
setTimeout -> |
||||
animating = false |
||||
callback?() |
||||
, 500 |
||||
|
||||
openFlex = (callback = null) -> |
||||
if not initiated |
||||
return openQueue.push { config: getFlex(), callback: callback } |
||||
|
||||
return if animating == true |
||||
AccountBox.close() |
||||
toggleArrow 0 |
||||
toggleFlex 1, callback |
||||
focusInput() |
||||
|
||||
closeFlex = (callback = null) -> |
||||
if not RocketChat.roomTypes.getTypes().filter((i) -> i.route).map((i) -> i.route.name).includes(FlowRouter.current().route.name) |
||||
subscription = RocketChat.models.Subscriptions.findOne({rid: Session.get('openedRoom')}) |
||||
if subscription? |
||||
RocketChat.roomTypes.openRouteLink(subscription.t, subscription, FlowRouter.current().queryParams); |
||||
else |
||||
FlowRouter.go('home') |
||||
|
||||
return if animating == true |
||||
toggleArrow -1 |
||||
toggleFlex -1, callback |
||||
|
||||
flexStatus = -> |
||||
return flexNav.opened |
||||
|
||||
setFlex = (template, data={}) -> |
||||
Session.set "flex-nav-template", template |
||||
Session.set "flex-nav-data", data |
||||
|
||||
getFlex = -> |
||||
return { |
||||
template: Session.get "flex-nav-template" |
||||
data: Session.get "flex-nav-data" |
||||
} |
||||
|
||||
init = -> |
||||
sideNav = $(".side-nav") |
||||
flexNav = sideNav.find ".flex-nav" |
||||
arrow = sideNav.children ".arrow" |
||||
setFlex "" |
||||
arrowBindHover() |
||||
initiated = true |
||||
|
||||
if openQueue.length > 0 |
||||
openQueue.forEach (item) -> |
||||
setFlex item.config.template, item.config.data |
||||
openFlex item.callback |
||||
|
||||
openQueue = [] |
||||
|
||||
getSideNav = -> |
||||
return sideNav |
||||
|
||||
init: init |
||||
setFlex: setFlex |
||||
getFlex: getFlex |
||||
openFlex: openFlex |
||||
closeFlex: closeFlex |
||||
validate: validate |
||||
flexStatus: flexStatus |
||||
toggleArrow: toggleArrow |
||||
toggleCurrent: toggleCurrent |
||||
overArrow: overArrow |
||||
leaveArrow: leaveArrow |
||||
getSideNav: getSideNav |
||||
)() |
@ -0,0 +1,176 @@ |
||||
this.SideNav = new class { |
||||
constructor() { |
||||
this.initiated = false; |
||||
this.sideNav = {}; |
||||
this.flexNav = {}; |
||||
this.arrow = {}; |
||||
this.animating = false; |
||||
this.openQueue = []; |
||||
} |
||||
|
||||
toggleArrow(status) { |
||||
if (status == null) { |
||||
status = null; |
||||
} |
||||
if (status === 0) { |
||||
this.arrow.addClass('close'); |
||||
this.arrow.removeClass('top'); |
||||
return this.arrow.removeClass('bottom'); |
||||
} else if (status === -1 || (status !== 1 && this.arrow.hasClass('top'))) { |
||||
this.arrow.removeClass('close'); |
||||
this.arrow.removeClass('top'); |
||||
return this.arrow.addClass('bottom'); |
||||
} else { |
||||
this.arrow.removeClass('close'); |
||||
this.arrow.addClass('top'); |
||||
return this.arrow.removeClass('bottom'); |
||||
} |
||||
} |
||||
toggleFlex(status, callback) { |
||||
if (this.animating === true) { |
||||
return; |
||||
} |
||||
this.animating = true; |
||||
if (status === -1 || (status !== 1 && this.flexNav.opened)) { |
||||
this.flexNav.opened = false; |
||||
this.flexNav.addClass('animated-hidden'); |
||||
} else { |
||||
this.flexNav.opened = true; |
||||
setTimeout(() => { |
||||
return this.flexNav.removeClass('animated-hidden'); |
||||
}, 50); |
||||
} |
||||
return setTimeout(() => { |
||||
this.animating = false; |
||||
return typeof callback === 'function' && callback(); |
||||
}, 500); |
||||
} |
||||
closeFlex(callback) { |
||||
let subscription; |
||||
if (callback == null) { |
||||
callback = null; |
||||
} |
||||
if (!RocketChat.roomTypes.getTypes().filter(function(i) { |
||||
return i.route; |
||||
}).map(function(i) { |
||||
return i.route.name; |
||||
}).includes(FlowRouter.current().route.name)) { |
||||
subscription = RocketChat.models.Subscriptions.findOne({ |
||||
rid: Session.get('openedRoom') |
||||
}); |
||||
if (subscription != null) { |
||||
RocketChat.roomTypes.openRouteLink(subscription.t, subscription, FlowRouter.current().queryParams); |
||||
} else { |
||||
FlowRouter.go('home'); |
||||
} |
||||
} |
||||
if (this.animating === true) { |
||||
return; |
||||
} |
||||
this.toggleArrow(-1); |
||||
return this.toggleFlex(-1, callback); |
||||
} |
||||
flexStatus() { |
||||
return this.flexNav.opened; |
||||
} |
||||
setFlex(template, data) { |
||||
if (data == null) { |
||||
data = {}; |
||||
} |
||||
Session.set('flex-nav-template', template); |
||||
return Session.set('flex-nav-data', data); |
||||
} |
||||
getFlex() { |
||||
return { |
||||
template: Session.get('flex-nav-template'), |
||||
data: Session.get('flex-nav-data') |
||||
}; |
||||
} |
||||
|
||||
toggleCurrent() { |
||||
if (this.flexNav && this.flexNav.opened) { |
||||
return this.closeFlex(); |
||||
} else { |
||||
return AccountBox.toggle(); |
||||
} |
||||
} |
||||
overArrow() { |
||||
return this.arrow.addClass('hover'); |
||||
} |
||||
leaveArrow() { |
||||
return this.arrow.removeClass('hover'); |
||||
} |
||||
arrowBindHover() { |
||||
this.arrow.on('mouseenter', () => { |
||||
return this.sideNav.find('header').addClass('hover'); |
||||
}); |
||||
return this.arrow.on('mouseout', () => { |
||||
return this.sideNav.find('header').removeClass('hover'); |
||||
}); |
||||
} |
||||
focusInput() { |
||||
const sideNavDivs = _.filter(document.querySelectorAll('aside.side-nav')[0].children, function(ele) { |
||||
return ele.tagName === 'DIV' && !ele.classList.contains('hidden'); |
||||
}); |
||||
let highestZidx = 0; |
||||
let highestZidxElem; |
||||
_.each(sideNavDivs, (ele) => { |
||||
const zIndex = Number(window.getComputedStyle(ele).zIndex); |
||||
if (Number(zIndex) > highestZidx) { |
||||
highestZidx = Number(zIndex); |
||||
highestZidxElem = ele; |
||||
} |
||||
}); |
||||
setTimeout(() => { |
||||
const ref = highestZidxElem.querySelector('input'); |
||||
return ref && ref.focus(); |
||||
}, 200); |
||||
} |
||||
validate() { |
||||
const invalid = []; |
||||
this.sideNav.find('input.required').each(function() { |
||||
if (!this.value.length) { |
||||
return invalid.push($(this).prev('label').html()); |
||||
} |
||||
}); |
||||
if (invalid.length) { |
||||
return invalid; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
openFlex(callback) { |
||||
if (!this.initiated) { |
||||
return this.openQueue.push({ |
||||
config: this.getFlex(), |
||||
callback |
||||
}); |
||||
} |
||||
if (this.animating === true) { |
||||
return; |
||||
} |
||||
AccountBox.close(); |
||||
this.toggleArrow(0); |
||||
this.toggleFlex(1, callback); |
||||
return this.focusInput(); |
||||
} |
||||
|
||||
init() { |
||||
this.sideNav = $('.side-nav'); |
||||
this.flexNav = this.sideNav.find('.flex-nav'); |
||||
this.arrow = this.sideNav.children('.arrow'); |
||||
this.setFlex(''); |
||||
this.arrowBindHover(); |
||||
this.initiated = true; |
||||
if (this.openQueue.length > 0) { |
||||
this.openQueue.forEach((item) => { |
||||
this.setFlex(item.config.template, item.config.data); |
||||
return this.openFlex(item.callback); |
||||
}); |
||||
return this.openQueue = []; |
||||
} |
||||
} |
||||
getSideNav() { |
||||
return this.sideNav; |
||||
} |
||||
}; |
@ -1,15 +0,0 @@ |
||||
@t = (key, replaces...) -> |
||||
if _.isObject replaces[0] |
||||
return TAPi18n.__ key, replaces |
||||
else |
||||
return TAPi18n.__ key, { postProcess: 'sprintf', sprintf: replaces } |
||||
|
||||
@tr = (key, options, replaces...) -> |
||||
if _.isObject replaces[0] |
||||
return TAPi18n.__ key, options, replaces |
||||
else |
||||
return TAPi18n.__ key, options, { postProcess: 'sprintf', sprintf: replaces } |
||||
|
||||
@isRtl = (language) -> |
||||
# https://en.wikipedia.org/wiki/Right-to-left#cite_note-2 |
||||
return language?.split('-').shift().toLowerCase() in ['ar', 'dv', 'fa', 'he', 'ku', 'ps', 'sd', 'ug', 'ur', 'yi'] |
@ -0,0 +1,23 @@ |
||||
this.t = function(key, ...replaces) { |
||||
if (_.isObject(replaces[0])) { |
||||
return TAPi18n.__(key, replaces); |
||||
} else { |
||||
return TAPi18n.__(key, { |
||||
postProcess: 'sprintf', |
||||
sprintf: replaces |
||||
}); |
||||
} |
||||
}; |
||||
|
||||
this.tr = function(key, options, ...replaces) { |
||||
if (_.isObject(replaces[0])) { |
||||
return TAPi18n.__(key, options, replaces); |
||||
} else { |
||||
return TAPi18n.__(key, options, { |
||||
postProcess: 'sprintf', |
||||
sprintf: replaces |
||||
}); |
||||
} |
||||
}; |
||||
|
||||
this.isRtl = (language) => language != null && ['ar', 'dv', 'fa', 'he', 'ku', 'ps', 'sd', 'ug', 'ur', 'yi'].includes(language.split('-').shift().toLowerCase()); |
@ -0,0 +1,97 @@ |
||||
import moment from 'moment'; |
||||
|
||||
Template.privateHistory.helpers({ |
||||
history() { |
||||
const items = ChatSubscription.find({ |
||||
name: { |
||||
$regex: Session.get('historyFilter'), |
||||
$options: 'i' |
||||
}, |
||||
t: { |
||||
$in: ['d', 'c', 'p'] |
||||
}, |
||||
archived: { |
||||
$ne: true |
||||
} |
||||
}, { |
||||
'sort': { |
||||
'ts': -1 |
||||
} |
||||
}); |
||||
return { |
||||
items, |
||||
length: items.count() |
||||
}; |
||||
}, |
||||
archivedHistory() { |
||||
const items = ChatSubscription.find({ |
||||
name: { |
||||
$regex: Session.get('historyFilter'), |
||||
$options: 'i' |
||||
}, |
||||
t: { |
||||
$in: ['d', 'c', 'p'] |
||||
}, |
||||
archived: true |
||||
}, { |
||||
'sort': { |
||||
'ts': -1 |
||||
} |
||||
}); |
||||
return { |
||||
items, |
||||
length: items.count() |
||||
}; |
||||
}, |
||||
roomOf(rid) { |
||||
return ChatRoom.findOne(rid); |
||||
}, |
||||
type() { |
||||
switch (this.t) { |
||||
case 'd': |
||||
return 'icon-at'; |
||||
case 'c': |
||||
return 'icon-hash'; |
||||
case 'p': |
||||
return 'icon-lock'; |
||||
} |
||||
}, |
||||
creation() { |
||||
return moment(this.ts).format('LLL'); |
||||
}, |
||||
lastMessage() { |
||||
if (this.lm) { |
||||
return moment(this.lm).format('LLL'); |
||||
} |
||||
}, |
||||
path() { |
||||
switch (this.t) { |
||||
case 'c': |
||||
return FlowRouter.path('channel', { |
||||
name: this.name |
||||
}); |
||||
case 'p': |
||||
return FlowRouter.path('group', { |
||||
name: this.name |
||||
}); |
||||
case 'd': |
||||
return FlowRouter.path('direct', { |
||||
username: this.name |
||||
}); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
Template.privateHistory.events({ |
||||
'keydown #history-filter'(event) { |
||||
if (event.which === 13) { |
||||
event.stopPropagation(); |
||||
return event.preventDefault(); |
||||
} |
||||
}, |
||||
'keyup #history-filter'(event) { |
||||
event.stopPropagation(); |
||||
event.preventDefault(); |
||||
return Session.set('historyFilter', event.currentTarget.value); |
||||
} |
||||
}); |
@ -1,23 +0,0 @@ |
||||
Template.videoButtons.helpers |
||||
videoAvaliable: -> |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom'))? |
||||
|
||||
videoActive: -> |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).localUrl.get()? or WebRTC.getInstanceByRoomId(Session.get('openedRoom')).remoteItems.get()?.length > 0 |
||||
|
||||
callInProgress: -> |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).callInProgress.get() |
||||
|
||||
|
||||
Template.videoButtons.events |
||||
'click .start-video-call': -> |
||||
WebRTC.getInstanceByRoomId(Session.get('openedRoom')).startCall({audio: true, video: true}) |
||||
|
||||
'click .start-audio-call': -> |
||||
WebRTC.getInstanceByRoomId(Session.get('openedRoom')).startCall({audio: true}) |
||||
|
||||
'click .join-video-call': -> |
||||
WebRTC.getInstanceByRoomId(Session.get('openedRoom')).joinCall({audio: true, video: true}) |
||||
|
||||
'click .join-audio-call': -> |
||||
WebRTC.getInstanceByRoomId(Session.get('openedRoom')).joinCall({audio: true}) |
@ -0,0 +1,39 @@ |
||||
/* globals WebRTC */ |
||||
Template.videoButtons.helpers({ |
||||
videoAvaliable() { |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')) != null; |
||||
}, |
||||
videoActive() { |
||||
const {localUrl, remoteItems} = WebRTC.getInstanceByRoomId(Session.get('openedRoom')); |
||||
const r = remoteItems.get() || []; |
||||
return localUrl.get() != null || r.length > 0; |
||||
}, |
||||
callInProgress() { |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).callInProgress.get(); |
||||
} |
||||
}); |
||||
|
||||
Template.videoButtons.events({ |
||||
'click .start-video-call'() { |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).startCall({ |
||||
audio: true, |
||||
video: true |
||||
}); |
||||
}, |
||||
'click .start-audio-call'() { |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).startCall({ |
||||
audio: true |
||||
}); |
||||
}, |
||||
'click .join-video-call'() { |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).joinCall({ |
||||
audio: true, |
||||
video: true |
||||
}); |
||||
}, |
||||
'click .join-audio-call'() { |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).joinCall({ |
||||
audio: true |
||||
}); |
||||
} |
||||
}); |
@ -1,121 +0,0 @@ |
||||
Template.videoCall.onCreated -> |
||||
@mainVideo = new ReactiveVar '$auto' |
||||
|
||||
|
||||
Template.videoCall.helpers |
||||
videoAvaliable: -> |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom'))? |
||||
|
||||
videoActive: -> |
||||
webrtc = WebRTC.getInstanceByRoomId(Session.get('openedRoom')) |
||||
overlay = @overlay? |
||||
if overlay isnt webrtc?.overlayEnabled.get() |
||||
return false |
||||
|
||||
return webrtc.localUrl.get()? or webrtc.remoteItems.get()?.length > 0 |
||||
|
||||
callInProgress: -> |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).callInProgress.get() |
||||
|
||||
overlayEnabled: -> |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).overlayEnabled.get() |
||||
|
||||
audioEnabled: -> |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).audioEnabled.get() |
||||
|
||||
videoEnabled: -> |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).videoEnabled.get() |
||||
|
||||
audioAndVideoEnabled: -> |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).audioEnabled.get() and WebRTC.getInstanceByRoomId(Session.get('openedRoom')).videoEnabled.get() |
||||
|
||||
screenShareAvailable: -> |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).screenShareAvailable |
||||
|
||||
screenShareEnabled: -> |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).screenShareEnabled.get() |
||||
|
||||
remoteVideoItems: -> |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).remoteItems.get() |
||||
|
||||
selfVideoUrl: -> |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).localUrl.get() |
||||
|
||||
mainVideoUrl: -> |
||||
template = Template.instance() |
||||
webrtc = WebRTC.getInstanceByRoomId(Session.get('openedRoom')) |
||||
|
||||
if template.mainVideo.get() is '$self' |
||||
return webrtc.localUrl.get() |
||||
|
||||
if template.mainVideo.get() is '$auto' |
||||
remoteItems = webrtc.remoteItems.get() |
||||
if remoteItems?.length > 0 |
||||
return remoteItems[0].url |
||||
|
||||
return webrtc.localUrl.get() |
||||
|
||||
if webrtc.remoteItemsById.get()[template.mainVideo.get()]? |
||||
return webrtc.remoteItemsById.get()[template.mainVideo.get()].url |
||||
else |
||||
template.mainVideo.set '$auto' |
||||
return |
||||
|
||||
mainVideoUsername: -> |
||||
template = Template.instance() |
||||
webrtc = WebRTC.getInstanceByRoomId(Session.get('openedRoom')) |
||||
|
||||
if template.mainVideo.get() is '$self' |
||||
return t 'you' |
||||
|
||||
if template.mainVideo.get() is '$auto' |
||||
remoteItems = webrtc.remoteItems.get() |
||||
if remoteItems?.length > 0 |
||||
return Meteor.users.findOne(remoteItems[0].id)?.username |
||||
|
||||
return t 'you' |
||||
|
||||
if webrtc.remoteItemsById.get()[template.mainVideo.get()]? |
||||
return Meteor.users.findOne(webrtc.remoteItemsById.get()[template.mainVideo.get()].id)?.username |
||||
else |
||||
template.mainVideo.set '$auto' |
||||
return |
||||
|
||||
usernameByUserId: (userId) -> |
||||
return Meteor.users.findOne(userId)?.username |
||||
|
||||
|
||||
Template.videoCall.events |
||||
'click .stop-call': -> |
||||
WebRTC.getInstanceByRoomId(Session.get('openedRoom')).stop() |
||||
|
||||
'click .video-item': (e, t) -> |
||||
t.mainVideo.set $(e.currentTarget).data('username') |
||||
|
||||
'click .disable-audio': (e, t) -> |
||||
WebRTC.getInstanceByRoomId(Session.get('openedRoom')).disableAudio() |
||||
|
||||
'click .enable-audio': (e, t) -> |
||||
WebRTC.getInstanceByRoomId(Session.get('openedRoom')).enableAudio() |
||||
|
||||
'click .disable-video': (e, t) -> |
||||
WebRTC.getInstanceByRoomId(Session.get('openedRoom')).disableVideo() |
||||
|
||||
'click .enable-video': (e, t) -> |
||||
WebRTC.getInstanceByRoomId(Session.get('openedRoom')).enableVideo() |
||||
|
||||
'click .disable-screen-share': (e, t) -> |
||||
WebRTC.getInstanceByRoomId(Session.get('openedRoom')).disableScreenShare() |
||||
|
||||
'click .enable-screen-share': (e, t) -> |
||||
WebRTC.getInstanceByRoomId(Session.get('openedRoom')).enableScreenShare() |
||||
|
||||
'click .disable-overlay': (e, t) -> |
||||
WebRTC.getInstanceByRoomId(Session.get('openedRoom')).overlayEnabled.set(false) |
||||
|
||||
'click .enable-overlay': (e, t) -> |
||||
WebRTC.getInstanceByRoomId(Session.get('openedRoom')).overlayEnabled.set(true) |
||||
|
||||
'loadstart video[muted]': (e) -> |
||||
e.currentTarget.muted = true |
||||
e.currentTarget.volume = 0 |
@ -0,0 +1,129 @@ |
||||
/* globals WebRTC */ |
||||
Template.videoCall.onCreated(function() { |
||||
return this.mainVideo = new ReactiveVar('$auto'); |
||||
}); |
||||
|
||||
Template.videoCall.helpers({ |
||||
videoAvaliable() { |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')) != null; |
||||
}, |
||||
videoActive() { |
||||
const webrtc = WebRTC.getInstanceByRoomId(Session.get('openedRoom')); |
||||
const overlay = this.overlay != null; |
||||
if (overlay !== (webrtc != null ? webrtc.overlayEnabled.get() : null)) { |
||||
return false; |
||||
} |
||||
let { remoteItems } = webrtc; |
||||
const { localUrl } = webrtc; |
||||
remoteItems = remoteItems.get() || []; |
||||
return (localUrl.get() != null) || remoteItems.length > 0; |
||||
}, |
||||
callInProgress() { |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).callInProgress.get(); |
||||
}, |
||||
overlayEnabled() { |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).overlayEnabled.get(); |
||||
}, |
||||
audioEnabled() { |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).audioEnabled.get(); |
||||
}, |
||||
videoEnabled() { |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).videoEnabled.get(); |
||||
}, |
||||
audioAndVideoEnabled() { |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).audioEnabled.get() && WebRTC.getInstanceByRoomId(Session.get('openedRoom')).videoEnabled.get(); |
||||
}, |
||||
screenShareAvailable() { |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).screenShareAvailable; |
||||
}, |
||||
screenShareEnabled() { |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).screenShareEnabled.get(); |
||||
}, |
||||
remoteVideoItems() { |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).remoteItems.get(); |
||||
}, |
||||
selfVideoUrl() { |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).localUrl.get(); |
||||
}, |
||||
mainVideoUrl() { |
||||
const template = Template.instance(); |
||||
const webrtc = WebRTC.getInstanceByRoomId(Session.get('openedRoom')); |
||||
if (template.mainVideo.get() === '$self') { |
||||
return webrtc.localUrl.get(); |
||||
} |
||||
if (template.mainVideo.get() === '$auto') { |
||||
const remoteItems = webrtc.remoteItems.get() | []; |
||||
if (remoteItems.length > 0) { |
||||
return remoteItems[0].url; |
||||
} |
||||
return webrtc.localUrl.get(); |
||||
} |
||||
if (webrtc.remoteItemsById.get()[template.mainVideo.get()] != null) { |
||||
return webrtc.remoteItemsById.get()[template.mainVideo.get()].url; |
||||
} else { |
||||
template.mainVideo.set('$auto'); |
||||
} |
||||
}, |
||||
mainVideoUsername() { |
||||
const template = Template.instance(); |
||||
const webrtc = WebRTC.getInstanceByRoomId(Session.get('openedRoom')); |
||||
if (template.mainVideo.get() === '$self') { |
||||
return t('you'); |
||||
} |
||||
if (template.mainVideo.get() === '$auto') { |
||||
const remoteItems = webrtc.remoteItems.get() || []; |
||||
if (remoteItems.length > 0) { |
||||
const user = Meteor.users.findOne(remoteItems[0].id); |
||||
return user != null ? user.username : undefined; |
||||
} |
||||
return t('you'); |
||||
} |
||||
if (webrtc.remoteItemsById.get()[template.mainVideo.get()] != null) { |
||||
const user = Meteor.users.findOne(webrtc.remoteItemsById.get()[template.mainVideo.get()].id); |
||||
return user != null ? user.username : undefined; |
||||
} else { |
||||
template.mainVideo.set('$auto'); |
||||
} |
||||
}, |
||||
usernameByUserId(userId) { |
||||
const user = Meteor.users.findOne(userId); |
||||
return user != null ? user.username : undefined; |
||||
} |
||||
}); |
||||
|
||||
Template.videoCall.events({ |
||||
'click .stop-call'() { |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).stop(); |
||||
}, |
||||
'click .video-item'(e, t) { |
||||
return t.mainVideo.set($(e.currentTarget).data('username')); |
||||
}, |
||||
'click .disable-audio'() { |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).disableAudio(); |
||||
}, |
||||
'click .enable-audio'() { |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).enableAudio(); |
||||
}, |
||||
'click .disable-video'() { |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).disableVideo(); |
||||
}, |
||||
'click .enable-video'() { |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).enableVideo(); |
||||
}, |
||||
'click .disable-screen-share'() { |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).disableScreenShare(); |
||||
}, |
||||
'click .enable-screen-share'() { |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).enableScreenShare(); |
||||
}, |
||||
'click .disable-overlay'() { |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).overlayEnabled.set(false); |
||||
}, |
||||
'click .enable-overlay'() { |
||||
return WebRTC.getInstanceByRoomId(Session.get('openedRoom')).overlayEnabled.set(true); |
||||
}, |
||||
'loadstart video[muted]'(e) { |
||||
e.currentTarget.muted = true; |
||||
return e.currentTarget.volume = 0; |
||||
} |
||||
}); |
Loading…
Reference in new issue