diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index c01adce7dbb..6360ae8a74d 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -211,6 +211,7 @@ "Back_to_integrations" : "Back to integrations", "Back_to_login" : "Back to login", "Back_to_permissions" : "Back to permissions", + "Beta_feature_Depends_on_Video_Conference_to_be_enabled" : "Beta feature. Depends on Video Conference to be enabled.", "Body" : "Body", "bold" : "bold", "bot_request" : "Bot request", @@ -1335,6 +1336,7 @@ "Verified" : "Verified", "Version" : "Version", "Videocall_declined" : "Videocall declined.", + "Videocall_enabled" : "Videocall enabled", "Video_Chat_Window" : "Video Chat", "View_All" : "View All", "View_Logs" : "View Logs", diff --git a/packages/rocketchat-i18n/i18n/pt.i18n.json b/packages/rocketchat-i18n/i18n/pt.i18n.json index 7f677914bda..a95295436c0 100644 --- a/packages/rocketchat-i18n/i18n/pt.i18n.json +++ b/packages/rocketchat-i18n/i18n/pt.i18n.json @@ -203,6 +203,7 @@ "Back_to_integrations" : "Voltar para integrações", "Back_to_login" : "Voltar para o login", "Back_to_permissions" : "Voltar para permissões", + "Beta_feature_Depends_on_Video_Conference_to_be_enabled" : "Funcionalidade Beta! Depende que Vídeo Conferência esteja habilitado", "Body" : "Corpo", "bold" : "negrito", "BotHelpers_userFields" : "Campos de usuário", @@ -1223,6 +1224,7 @@ "Verified" : "Verificado", "Version" : "Versão", "Videocall_declined" : "Chamada de vídeo negada.", + "Videocall_enabled" : "Vídeoconferência habilitada", "Video_Chat_Window" : "Vídeo Chat", "View_All" : "Ver Todos", "View_Logs" : "Ver Logs", diff --git a/packages/rocketchat-livechat/app/client/lib/LivechatVideoCall.js b/packages/rocketchat-livechat/app/client/lib/LivechatVideoCall.js new file mode 100644 index 00000000000..5cae7ca0863 --- /dev/null +++ b/packages/rocketchat-livechat/app/client/lib/LivechatVideoCall.js @@ -0,0 +1,80 @@ +/* globals LivechatVideoCall, cordova, JitsiMeetExternalAPI */ + +LivechatVideoCall = new (class LivechatVideoCall { + constructor() { + this.live = new ReactiveVar(false); + this.calling = new ReactiveVar(false); + + if (typeof JitsiMeetExternalAPI === 'undefined') { + $.getScript('/packages/rocketchat_videobridge/client/public/external_api.js'); + } + } + + askPermissions(callback) { + if (Meteor.isCordova) { + cordova.plugins.diagnostic.requestCameraAuthorization(() => { + cordova.plugins.diagnostic.requestMicrophoneAuthorization(() => { + callback(true); + }, (error) => { + console.error(error); + }); + }, (error) => { + console.error(error); + }); + } else { + return callback(true); + } + } + + request() { + this.askPermissions((granted) => { + if (granted) { + this.calling.set(true); + Meteor.call('livechat:startVideoCall', visitor.getRoom(true), (error, result) => { + if (error) { + return; + } + visitor.subscribeToRoom(result.roomId); + + // after get ok from server, start the chat + this.start(result.domain, result.jitsiRoom); + }); + } + }); + } + + start(domain, room) { + Meteor.defer(() => { + let interfaceConfig = {}; + interfaceConfig['TOOLBAR_BUTTONS'] = '[""]'; + interfaceConfig['APP_NAME'] = '"Livechat"'; + interfaceConfig['INITIAL_TOOLBAR_TIMEOUT'] = '5000'; + interfaceConfig['MIN_WIDTH'] = '300'; + interfaceConfig['FILM_STRIP_MAX_HEIGHT'] = '50'; + + this.api = new JitsiMeetExternalAPI(domain, room, $('.video-call').width(), $('.video-call').height(), $('.video-call .container').get(0), {}, interfaceConfig); + + this.api.addEventListener('videoConferenceJoined', () => { + this.api.executeCommand('toggleFilmStrip', []); + }); + + this.live.set(true); + }); + } + + finish() { + this.live.set(false); + this.calling.set(false); + this.api.dispose(); + } + + isActive() { + return this.live.get() || this.calling.get(); + } + + isLive() { + return this.live.get(); + } +}); + +/* exported LivechatVideoCall */ diff --git a/packages/rocketchat-livechat/app/client/lib/_livechat.js b/packages/rocketchat-livechat/app/client/lib/_livechat.js index f804d92ebaf..c08c9b3fa0b 100644 --- a/packages/rocketchat-livechat/app/client/lib/_livechat.js +++ b/packages/rocketchat-livechat/app/client/lib/_livechat.js @@ -16,6 +16,7 @@ this.Livechat = new (class Livechat { this._offlineUnavailableMessage = new ReactiveVar(''); this._displayOfflineForm = new ReactiveVar(true); this._offlineSuccessMessage = new ReactiveVar(TAPi18n.__('Thanks_We_ll_get_back_to_you_soon')); + this._videoCall = new ReactiveVar(false); } get online() { @@ -51,6 +52,9 @@ this.Livechat = new (class Livechat { get offlineSuccessMessage() { return this._offlineSuccessMessage.get(); } + get videoCall() { + return this._videoCall.get(); + } set online(value) { this._online.set(value); @@ -93,4 +97,7 @@ this.Livechat = new (class Livechat { set offlineFontColor(value) { this._offlineFontColor.set(value); } + set videoCall(value) { + this._videoCall.set(value); + } })(); diff --git a/packages/rocketchat-livechat/app/client/lib/_visitor.coffee b/packages/rocketchat-livechat/app/client/lib/_visitor.coffee index 032d2bdc5b0..37a282df0f8 100644 --- a/packages/rocketchat-livechat/app/client/lib/_visitor.coffee +++ b/packages/rocketchat-livechat/app/client/lib/_visitor.coffee @@ -35,14 +35,17 @@ msgStream = new Meteor.Streamer 'room-messages' subscribeToRoom = (roomId) -> msgStream.on roomId, (msg) -> if msg.t is 'command' - if msg.msg is 'survey' - unless $('body #survey').length - Blaze.render(Template.survey, $('body').get(0)) - else + switch msg.msg + when 'survey' + unless $('body #survey').length + Blaze.render(Template.survey, $('body').get(0)) + when 'endCall' + LivechatVideoCall.finish() + else if msg.t isnt 'livechat_video_call' ChatMessage.upsert { _id: msg._id }, msg - # notification sound - if Session.equals('sound', true) + # notification sound + if Session.equals('sound', true) if msg.u._id isnt Meteor.user()._id $('#chatAudioNotification')[0].play(); diff --git a/packages/rocketchat-livechat/app/client/stylesheets/main.less b/packages/rocketchat-livechat/app/client/stylesheets/main.less index ffa6e1a71e9..3f567615d83 100644 --- a/packages/rocketchat-livechat/app/client/stylesheets/main.less +++ b/packages/rocketchat-livechat/app/client/stylesheets/main.less @@ -388,39 +388,52 @@ input:focus { border-left: 1px solid @window-border-color; border-right: 1px solid @window-border-color; - .input-wrapper { - padding: 6px 6px 0 6px; - padding-right: 30px; - textarea { - display: block; - padding: 6px 8px; - padding-right: 38px; - overflow-y: auto; - resize: none; - margin: 0; - max-height: 200px; - width: 100%; - font-size: 12px; - -webkit-appearance: none; - height: 28px; - line-height: normal; - background-color: #fff; - position: relative; + .message-bar { + display: flex; + flex-direction: row; + padding-top: 6px; + + .input-wrapper { + flex-grow: 1; + padding-left: 6px; + + textarea { + display: block; + padding: 6px 8px; + padding-right: 38px; + overflow-y: auto; + resize: none; + margin: 0; + max-height: 200px; + width: 100%; + font-size: 12px; + -webkit-appearance: none; + height: 28px; + line-height: normal; + background-color: #fff; + position: relative; + } } - } - .send-button { - float: right; - position: relative; - width: 15px; - height: 15px; - right: 10px; - top: -22px; - fill: @secondary-font-color; - cursor: pointer; - .transition(color .15s ease-out); - &:hover { - fill: @primary-font-color; + .buttons { + color: @secondary-font-color; + fill: @secondary-font-color; + + display: flex; + align-items: center; + padding: 0 5px; + + svg { + width: 15px; + height: 15px; + margin: 0 4px; + cursor: pointer; + .transition(fill .15s ease-out); + + &:hover { + fill: @primary-font-color; + } + } } } .toggle-options { @@ -657,6 +670,62 @@ input:focus { border-top-left-radius: inherit; } +.video-call { + position: fixed; + top: @header-min-height; + bottom: 0; + left: 0; + right: 0; + background-color: #000; + z-index: 11; + + .video-overlay { + position: fixed; + top: @header-min-height; + bottom: 0; + left: 0; + right: 0; + z-index: 13; + + .toolbar { + position: absolute; + bottom: 40px; + width: 100%; + text-align: center; + opacity: 0; + visibility: hidden; + .transform(translateY(50px)); + + .transition(opacity 0.175s ease-out, transform 0.175s ease-out, visibility 0.175s ease-out); + + &.visible { + opacity: 1; + visibility: visible; + .transform(translateY(0px)); + } + + .end-call { + background-color: red; + fill: white; + border-radius: 50%; + height: 60px; + width: 60px; + text-align: center; + outline: none; + + svg { + width: 30px; + height: 30px; + } + } + } + } + + .container { + z-index: 12; + } +} + @media all and(max-height: 200px) { .livechat-room { .title { diff --git a/packages/rocketchat-livechat/app/client/views/livechatWindow.html b/packages/rocketchat-livechat/app/client/views/livechatWindow.html index ed2916c45be..c7eb3fc4c3d 100644 --- a/packages/rocketchat-livechat/app/client/views/livechatWindow.html +++ b/packages/rocketchat-livechat/app/client/views/livechatWindow.html @@ -36,4 +36,7 @@ {{> poweredBy }} {{/if}} + {{#if videoCalling}} + {{> videoCall}} + {{/if}} diff --git a/packages/rocketchat-livechat/app/client/views/livechatWindow.js b/packages/rocketchat-livechat/app/client/views/livechatWindow.js index dfa98e3ce24..a48321e3921 100644 --- a/packages/rocketchat-livechat/app/client/views/livechatWindow.js +++ b/packages/rocketchat-livechat/app/client/views/livechatWindow.js @@ -1,4 +1,5 @@ -/* globals Department, Livechat */ +/* globals Department, Livechat, LivechatVideoCall */ + Template.livechatWindow.helpers({ title() { return Livechat.title; @@ -37,6 +38,9 @@ Template.livechatWindow.helpers({ offlineUnavailableMessage: Livechat.offlineUnavailableMessage.replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1
$2'), displayOfflineForm: Livechat.displayOfflineForm }; + }, + videoCalling() { + return LivechatVideoCall.isActive(); } }); @@ -92,6 +96,7 @@ Template.livechatWindow.onCreated(function() { Livechat.onlineColor = result.color; Livechat.online = true; } + Livechat.videoCall = result.videoCall; Livechat.registrationForm = result.registrationForm; if (result.room) { diff --git a/packages/rocketchat-livechat/app/client/views/messages.html b/packages/rocketchat-livechat/app/client/views/messages.html index a3c5ae05a58..0f8004e3fac 100644 --- a/packages/rocketchat-livechat/app/client/views/messages.html +++ b/packages/rocketchat-livechat/app/client/views/messages.html @@ -16,10 +16,17 @@