organize more sanely

This commit is contained in:
Connor Turland 2016-12-19 17:09:49 -05:00
parent b5e8fa0fc2
commit 7d43abeefe
6 changed files with 76 additions and 62 deletions

View file

@ -9,6 +9,8 @@
<body class="<%= authenticated? ? "authenticated" : "unauthenticated" %> controller-<%= controller_name %> action-<%= action_name %>"> <body class="<%= authenticated? ? "authenticated" : "unauthenticated" %> controller-<%= controller_name %> action-<%= action_name %>">
<div id="chat-box-wrapper"></div>
<a class='feedback-icon' target='_blank' href='https://hylo.com/c/metamaps'></a> <a class='feedback-icon' target='_blank' href='https://hylo.com/c/metamaps'></a>
<%= content_tag :div, class: "main" do %> <%= content_tag :div, class: "main" do %>

View file

@ -8,6 +8,7 @@ import DataModel from '../DataModel'
import JIT from '../JIT' import JIT from '../JIT'
import Util from '../Util' import Util from '../Util'
import Views from '../Views' import Views from '../Views'
import { ChatView } from '../Views'
import Visualize from '../Visualize' import Visualize from '../Visualize'
import { import {
@ -178,17 +179,9 @@ let Realtime = {
room: 'global', room: 'global',
$video: self.localVideo.$video, $video: self.localVideo.$video,
myVideoView: self.localVideo.view, myVideoView: self.localVideo.view,
config: { DOUBLE_CLICK_TOLERANCE: 200 }, config: { DOUBLE_CLICK_TOLERANCE: 200 }
soundUrls: [
serverData['sounds/MM_sounds.mp3'],
serverData['sounds/MM_sounds.ogg']
]
}) })
self.room.videoAdded(self.handleVideoAdded) self.room.videoAdded(self.handleVideoAdded)
if (Active.Map) {
self.room.chat.render()
}
} // if Active.Mapper } // if Active.Mapper
}, },
addJuntoListeners: function() { addJuntoListeners: function() {
@ -237,14 +230,14 @@ let Realtime = {
$('.collabCompass').remove() $('.collabCompass').remove()
if (self.room) { if (self.room) {
self.room.leave() self.room.leave()
self.room.chat.hide() ChatView.hide()
self.room.chat.close() ChatView.close()
} }
}, },
turnOn: function(notify) { turnOn: function(notify) {
var self = Realtime var self = Realtime
$('.collabCompass').show() $('.collabCompass').show()
self.room.chat.show() ChatView.show()
self.room.room = 'map-' + Active.Map.id self.room.room = 'map-' + Active.Map.id
self.activeMapper = { self.activeMapper = {
id: Active.Mapper.id, id: Active.Mapper.id,
@ -257,7 +250,7 @@ let Realtime = {
self.localVideo.view.$container.find('.video-cutoff').css({ self.localVideo.view.$container.find('.video-cutoff').css({
border: '4px solid ' + self.activeMapper.color border: '4px solid ' + self.activeMapper.color
}) })
self.room.chat.addParticipant(self.activeMapper) ChatView.addParticipant(self.activeMapper)
}, },
setupSocket: function() { setupSocket: function() {
var self = Realtime var self = Realtime

View file

@ -10,6 +10,7 @@ import ReactDOM from 'react-dom'
// TODO is this line good or bad // TODO is this line good or bad
// Backbone.$ = window.$ // Backbone.$ = window.$
import Active from '../Active'
import Realtime from '../Realtime' import Realtime from '../Realtime'
import MapChat from '../../components/MapChat' import MapChat from '../../components/MapChat'
@ -18,7 +19,21 @@ const linker = new Autolinker({ newWindow: true, truncate: 50, email: false, pho
const ChatView = { const ChatView = {
isOpen: false, isOpen: false,
mapChat: null, 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 const self = ChatView
self.room = room self.room = room
self.mapper = mapper self.mapper = mapper
@ -28,20 +43,16 @@ const ChatView = {
self.cursorsShowing = true self.cursorsShowing = true
self.videosShowing = true self.videosShowing = true
self.participants = [] self.participants = []
self.render()
self.sound = new Howl({ },
src: opts.soundUrls, show: () => {
sprite: { $('#' + ChatView.domId).show()
joinmap: [0, 561], },
leavemap: [1000, 592], hide: () => {
receivechat: [2000, 318], $('#' + ChatView.domId).hide()
sendchat: [3000, 296],
sessioninvite: [4000, 5393, true]
}
})
$('body').prepend('<div id="chat-box-wrapper"></div>')
}, },
render: () => { render: () => {
if (!Active.Map) return
const self = ChatView const self = ChatView
self.mapChat = ReactDOM.render(React.createElement(MapChat, { self.mapChat = ReactDOM.render(React.createElement(MapChat, {
onOpen: self.onOpen, onOpen: self.onOpen,
@ -55,11 +66,8 @@ const ChatView = {
soundToggleClick: self.soundToggleClick, soundToggleClick: self.soundToggleClick,
inputBlur: self.inputBlur, inputBlur: self.inputBlur,
inputFocus: self.inputFocus, inputFocus: self.inputFocus,
videosShowing: self.videosShowing,
cursorsShowing: self.cursorsShowing,
alertSound: self.alertSound,
handleInputMessage: self.handleInputMessage handleInputMessage: self.handleInputMessage
}), document.getElementById('chat-box-wrapper')) }), document.getElementById(ChatView.domId))
}, },
onOpen: () => { onOpen: () => {
$(document).trigger(ChatView.events.openTray) $(document).trigger(ChatView.events.openTray)
@ -144,21 +152,15 @@ const ChatView = {
// this.scrollMessages(0) // this.scrollMessages(0)
}, },
videoToggleClick: function() { videoToggleClick: function() {
const self = ChatView ChatView.videosShowing = !ChatView.videosShowing
self.videosShowing = !self.videosShowing $(document).trigger(ChatView.videosShowing ? ChatView.events.videosOn : ChatView.events.videosOff)
$(document).trigger(self.videosShowing ? ChatView.events.videosOn : ChatView.events.videosOff)
ChatView.render()
}, },
cursorToggleClick: function() { cursorToggleClick: function() {
const self = ChatView ChatView.cursorsShowing = !ChatView.cursorsShowing
self.cursorsShowing = !self.cursorsShowing $(document).trigger(ChatView.cursorsShowing ? ChatView.events.cursorsOn : ChatView.events.cursorsOff)
$(document).trigger(self.cursorsShowing ? ChatView.events.cursorsOn : ChatView.events.cursorsOff)
ChatView.render()
}, },
soundToggleClick: function() { soundToggleClick: function() {
const self = ChatView ChatView.alertSound = !ChatView.alertSound
this.alertSound = !this.alertSound
ChatView.render()
}, },
inputFocus: () => { inputFocus: () => {
$(document).trigger(ChatView.events.inputFocus) $(document).trigger(ChatView.events.inputFocus)

View file

@ -26,10 +26,7 @@ const Room = function(opts = {}) {
this.messages = new Backbone.Collection() this.messages = new Backbone.Collection()
this.currentMapper = new Backbone.Model({ name: opts.username, image: opts.image }) this.currentMapper = new Backbone.Model({ name: opts.username, image: opts.image })
this.chat = ChatView ChatView.setNewMap(this.messages, this.currentMapper, this.room)
this.chat.init(this.messages, this.currentMapper, this.room, {
soundUrls: opts.soundUrls
})
this.videos = {} this.videos = {}
@ -39,19 +36,19 @@ const Room = function(opts = {}) {
Room.prototype.join = function(cb) { Room.prototype.join = function(cb) {
this.isActiveRoom = true this.isActiveRoom = true
this.webrtc.joinRoom(this.room, cb) this.webrtc.joinRoom(this.room, cb)
this.chat.conversationInProgress(true) // true indicates participation ChatView.conversationInProgress(true) // true indicates participation
} }
Room.prototype.conversationInProgress = function() { Room.prototype.conversationInProgress = function() {
this.chat.conversationInProgress(false) // false indicates not participating ChatView.conversationInProgress(false) // false indicates not participating
} }
Room.prototype.conversationEnding = function() { Room.prototype.conversationEnding = function() {
this.chat.conversationEnded() ChatView.conversationEnded()
} }
Room.prototype.leaveVideoOnly = function() { 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) { for (var id in this.videos) {
this.removeVideo(id) this.removeVideo(id)
} }
@ -67,9 +64,9 @@ Room.prototype.leave = function() {
this.isActiveRoom = false this.isActiveRoom = false
this.webrtc.leaveRoom() this.webrtc.leaveRoom()
this.webrtc.stopLocalVideo() this.webrtc.stopLocalVideo()
this.chat.conversationEnded() ChatView.conversationEnded()
this.chat.removeParticipants() ChatView.removeParticipants()
this.chat.clearMessages() ChatView.clearMessages()
this.messages.reset() this.messages.reset()
} }
@ -161,8 +158,7 @@ Room.prototype.removeVideo = function(peer) {
Room.prototype.sendChatMessage = function(data) { Room.prototype.sendChatMessage = function(data) {
var self = this var self = this
// this.roomRef.child('messages').push(data) if (ChatView.alertSound) ChatView.sound.play('sendchat')
if (self.chat.alertSound) self.chat.sound.play('sendchat')
var m = new DataModel.Message({ var m = new DataModel.Message({
message: data.message, message: data.message,
resource_id: Active.Map.id, resource_id: Active.Map.id,
@ -185,7 +181,7 @@ Room.prototype.addMessages = function(messages, isInitial, wasMe) {
var self = this var self = this
messages.models.forEach(function(message) { messages.models.forEach(function(message) {
self.chat.addMessage(message, isInitial, wasMe) ChatView.addMessage(message, isInitial, wasMe)
}) })
} }

View file

@ -7,8 +7,9 @@ import Room from './Room'
import { JUNTO_UPDATED } from '../Realtime/events' import { JUNTO_UPDATED } from '../Realtime/events'
const Views = { const Views = {
init: () => { init: (serverData) => {
$(document).on(JUNTO_UPDATED, () => ExploreMaps.render()) $(document).on(JUNTO_UPDATED, () => ExploreMaps.render())
ChatView.init([serverData['sounds/MM_sounds.mp3'],serverData['sounds/MM_sounds.ogg']])
}, },
ExploreMaps, ExploreMaps,
ChatView, ChatView,

View file

@ -10,7 +10,10 @@ class MapChat extends Component {
this.state = { this.state = {
unreadMessages: 0, unreadMessages: 0,
open: false, 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() 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 => { handleChange = key => e => {
this.setState({ this.setState({
[key]: e.target.value [key]: e.target.value
@ -50,16 +68,15 @@ class MapChat extends Component {
render = () => { render = () => {
const rightOffset = this.state.open ? '0' : '-300px' const rightOffset = this.state.open ? '0' : '-300px'
const { videosShowing, cursorsShowing, alertSound } = this.props const { videosShowing, cursorsShowing, alertSound, unreadMessages } = this.state
const { unreadMessages } = this.state
return ( return (
<div className="chat-box" <div className="chat-box"
style={{ right: rightOffset }} style={{ right: rightOffset }}
> >
<div className="junto-header"> <div className="junto-header">
PARTICIPANTS PARTICIPANTS
<div className={`video-toggle ${videosShowing ? 'active' : ''}`} /> <div onClick={this.toggleVideosShowing} className={`video-toggle ${videosShowing ? '' : 'active'}`} />
<div className={`cursor-toggle ${cursorsShowing ? 'active' : ''}`} /> <div onClick={this.toggleCursorsShowing} className={`cursor-toggle ${cursorsShowing ? '' : 'active'}`} />
</div> </div>
<div className="participants"> <div className="participants">
<div className="conversation-live"> <div className="conversation-live">
@ -77,7 +94,7 @@ class MapChat extends Component {
</div> </div>
<div className="chat-header"> <div className="chat-header">
CHAT CHAT
<div className={`sound-toggle ${alertSound ? 'active' : ''}`}></div> <div onClick={this.toggleAlertSound} className={`sound-toggle ${alertSound ? '' : 'active'}`}></div>
</div> </div>
<div className="chat-button" onClick={this.toggleDrawer}> <div className="chat-button" onClick={this.toggleDrawer}>
<div className="tooltips">Chat</div> <div className="tooltips">Chat</div>
@ -106,6 +123,9 @@ MapChat.propTypes = {
onClose: PropTypes.func, onClose: PropTypes.func,
leaveCall: PropTypes.func, leaveCall: PropTypes.func,
joinCall: PropTypes.func, joinCall: PropTypes.func,
videoToggleClick: PropTypes.func,
cursorToggleClick: PropTypes.func,
soundToggleClick: PropTypes.func,
participants: PropTypes.arrayOf(PropTypes.shape({ participants: PropTypes.arrayOf(PropTypes.shape({
color: PropTypes.string, // css color color: PropTypes.string, // css color
id: PropTypes.number, id: PropTypes.number,