diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 2dd2a463..26164843 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -9,6 +9,8 @@
controller-<%= controller_name %> action-<%= action_name %>"> + + <%= content_tag :div, class: "main" do %> diff --git a/frontend/src/Metamaps/Realtime/index.js b/frontend/src/Metamaps/Realtime/index.js index 4e02223b..dd1e4d51 100644 --- a/frontend/src/Metamaps/Realtime/index.js +++ b/frontend/src/Metamaps/Realtime/index.js @@ -8,6 +8,7 @@ import DataModel from '../DataModel' import JIT from '../JIT' import Util from '../Util' import Views from '../Views' +import { ChatView } from '../Views' import Visualize from '../Visualize' import { @@ -178,17 +179,9 @@ let Realtime = { room: 'global', $video: self.localVideo.$video, myVideoView: self.localVideo.view, - config: { DOUBLE_CLICK_TOLERANCE: 200 }, - soundUrls: [ - serverData['sounds/MM_sounds.mp3'], - serverData['sounds/MM_sounds.ogg'] - ] + config: { DOUBLE_CLICK_TOLERANCE: 200 } }) self.room.videoAdded(self.handleVideoAdded) - - if (Active.Map) { - self.room.chat.render() - } } // if Active.Mapper }, addJuntoListeners: function() { @@ -237,14 +230,14 @@ let Realtime = { $('.collabCompass').remove() if (self.room) { self.room.leave() - self.room.chat.hide() - self.room.chat.close() + ChatView.hide() + ChatView.close() } }, turnOn: function(notify) { var self = Realtime $('.collabCompass').show() - self.room.chat.show() + ChatView.show() self.room.room = 'map-' + Active.Map.id self.activeMapper = { id: Active.Mapper.id, @@ -257,7 +250,7 @@ let Realtime = { self.localVideo.view.$container.find('.video-cutoff').css({ border: '4px solid ' + self.activeMapper.color }) - self.room.chat.addParticipant(self.activeMapper) + ChatView.addParticipant(self.activeMapper) }, setupSocket: function() { var self = Realtime diff --git a/frontend/src/Metamaps/Views/ChatView.js b/frontend/src/Metamaps/Views/ChatView.js index c2f49be2..09bf67d6 100644 --- a/frontend/src/Metamaps/Views/ChatView.js +++ b/frontend/src/Metamaps/Views/ChatView.js @@ -10,6 +10,7 @@ import ReactDOM from 'react-dom' // TODO is this line good or bad // Backbone.$ = window.$ +import Active from '../Active' import Realtime from '../Realtime' import MapChat from '../../components/MapChat' @@ -18,7 +19,21 @@ const linker = new Autolinker({ newWindow: true, truncate: 50, email: false, pho const ChatView = { isOpen: false, mapChat: null, - init: function(messages, mapper, room, opts = {}) { + domId: 'chat-box-wrapper', + init: function(urls) { + const self = ChatView + self.sound = new Howl({ + src: urls, + sprite: { + joinmap: [0, 561], + leavemap: [1000, 592], + receivechat: [2000, 318], + sendchat: [3000, 296], + sessioninvite: [4000, 5393, true] + } + }) + }, + setNewMap: function(messages, mapper, room) { const self = ChatView self.room = room self.mapper = mapper @@ -28,20 +43,16 @@ const ChatView = { self.cursorsShowing = true self.videosShowing = true self.participants = [] - - self.sound = new Howl({ - src: opts.soundUrls, - sprite: { - joinmap: [0, 561], - leavemap: [1000, 592], - receivechat: [2000, 318], - sendchat: [3000, 296], - sessioninvite: [4000, 5393, true] - } - }) - $('body').prepend('') + self.render() + }, + show: () => { + $('#' + ChatView.domId).show() + }, + hide: () => { + $('#' + ChatView.domId).hide() }, render: () => { + if (!Active.Map) return const self = ChatView self.mapChat = ReactDOM.render(React.createElement(MapChat, { onOpen: self.onOpen, @@ -55,11 +66,8 @@ const ChatView = { soundToggleClick: self.soundToggleClick, inputBlur: self.inputBlur, inputFocus: self.inputFocus, - videosShowing: self.videosShowing, - cursorsShowing: self.cursorsShowing, - alertSound: self.alertSound, handleInputMessage: self.handleInputMessage - }), document.getElementById('chat-box-wrapper')) + }), document.getElementById(ChatView.domId)) }, onOpen: () => { $(document).trigger(ChatView.events.openTray) @@ -144,21 +152,15 @@ const ChatView = { // this.scrollMessages(0) }, videoToggleClick: function() { - const self = ChatView - self.videosShowing = !self.videosShowing - $(document).trigger(self.videosShowing ? ChatView.events.videosOn : ChatView.events.videosOff) - ChatView.render() + ChatView.videosShowing = !ChatView.videosShowing + $(document).trigger(ChatView.videosShowing ? ChatView.events.videosOn : ChatView.events.videosOff) }, cursorToggleClick: function() { - const self = ChatView - self.cursorsShowing = !self.cursorsShowing - $(document).trigger(self.cursorsShowing ? ChatView.events.cursorsOn : ChatView.events.cursorsOff) - ChatView.render() + ChatView.cursorsShowing = !ChatView.cursorsShowing + $(document).trigger(ChatView.cursorsShowing ? ChatView.events.cursorsOn : ChatView.events.cursorsOff) }, soundToggleClick: function() { - const self = ChatView - this.alertSound = !this.alertSound - ChatView.render() + ChatView.alertSound = !ChatView.alertSound }, inputFocus: () => { $(document).trigger(ChatView.events.inputFocus) diff --git a/frontend/src/Metamaps/Views/Room.js b/frontend/src/Metamaps/Views/Room.js index 29c604e2..1f49ed84 100644 --- a/frontend/src/Metamaps/Views/Room.js +++ b/frontend/src/Metamaps/Views/Room.js @@ -26,10 +26,7 @@ const Room = function(opts = {}) { this.messages = new Backbone.Collection() this.currentMapper = new Backbone.Model({ name: opts.username, image: opts.image }) - this.chat = ChatView - this.chat.init(this.messages, this.currentMapper, this.room, { - soundUrls: opts.soundUrls - }) + ChatView.setNewMap(this.messages, this.currentMapper, this.room) this.videos = {} @@ -39,19 +36,19 @@ const Room = function(opts = {}) { Room.prototype.join = function(cb) { this.isActiveRoom = true this.webrtc.joinRoom(this.room, cb) - this.chat.conversationInProgress(true) // true indicates participation + ChatView.conversationInProgress(true) // true indicates participation } Room.prototype.conversationInProgress = function() { - this.chat.conversationInProgress(false) // false indicates not participating + ChatView.conversationInProgress(false) // false indicates not participating } Room.prototype.conversationEnding = function() { - this.chat.conversationEnded() + ChatView.conversationEnded() } Room.prototype.leaveVideoOnly = function() { - this.chat.leaveConversation() // the conversation will carry on without you + ChatView.leaveConversation() // the conversation will carry on without you for (var id in this.videos) { this.removeVideo(id) } @@ -67,9 +64,9 @@ Room.prototype.leave = function() { this.isActiveRoom = false this.webrtc.leaveRoom() this.webrtc.stopLocalVideo() - this.chat.conversationEnded() - this.chat.removeParticipants() - this.chat.clearMessages() + ChatView.conversationEnded() + ChatView.removeParticipants() + ChatView.clearMessages() this.messages.reset() } @@ -161,8 +158,7 @@ Room.prototype.removeVideo = function(peer) { Room.prototype.sendChatMessage = function(data) { var self = this - // this.roomRef.child('messages').push(data) - if (self.chat.alertSound) self.chat.sound.play('sendchat') + if (ChatView.alertSound) ChatView.sound.play('sendchat') var m = new DataModel.Message({ message: data.message, resource_id: Active.Map.id, @@ -185,7 +181,7 @@ Room.prototype.addMessages = function(messages, isInitial, wasMe) { var self = this messages.models.forEach(function(message) { - self.chat.addMessage(message, isInitial, wasMe) + ChatView.addMessage(message, isInitial, wasMe) }) } diff --git a/frontend/src/Metamaps/Views/index.js b/frontend/src/Metamaps/Views/index.js index 89d22ad7..ab96e552 100644 --- a/frontend/src/Metamaps/Views/index.js +++ b/frontend/src/Metamaps/Views/index.js @@ -7,8 +7,9 @@ import Room from './Room' import { JUNTO_UPDATED } from '../Realtime/events' const Views = { - init: () => { + init: (serverData) => { $(document).on(JUNTO_UPDATED, () => ExploreMaps.render()) + ChatView.init([serverData['sounds/MM_sounds.mp3'],serverData['sounds/MM_sounds.ogg']]) }, ExploreMaps, ChatView, diff --git a/frontend/src/components/MapChat/index.js b/frontend/src/components/MapChat/index.js index e000ffe4..f6b73c5d 100644 --- a/frontend/src/components/MapChat/index.js +++ b/frontend/src/components/MapChat/index.js @@ -10,7 +10,10 @@ class MapChat extends Component { this.state = { unreadMessages: 0, open: false, - messageText: '' + messageText: '', + alertSound: true, // whether to play sounds on arrival of new messages or not + cursorsShowing: true, + videosShowing: true } } @@ -33,6 +36,21 @@ class MapChat extends Component { else if (!this.state.open) this.open() } + toggleAlertSound = () => { + this.setState({alertSound: !this.state.alertSound}) + this.props.soundToggleClick() + } + + toggleCursorsShowing = () => { + this.setState({cursorsShowing: !this.state.cursorsShowing}) + this.props.cursorToggleClick() + } + + toggleVideosShowing = () => { + this.setState({videosShowing: !this.state.videosShowing}) + this.props.videoToggleClick() + } + handleChange = key => e => { this.setState({ [key]: e.target.value @@ -50,16 +68,15 @@ class MapChat extends Component { render = () => { const rightOffset = this.state.open ? '0' : '-300px' - const { videosShowing, cursorsShowing, alertSound } = this.props - const { unreadMessages } = this.state + const { videosShowing, cursorsShowing, alertSound, unreadMessages } = this.state return (