organize more sanely
This commit is contained in:
parent
b5e8fa0fc2
commit
7d43abeefe
6 changed files with 76 additions and 62 deletions
|
@ -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 %>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Add table
Reference in a new issue