more crazy refactoring
This commit is contained in:
parent
b7a6e615a0
commit
79839a4b48
19 changed files with 2737 additions and 2733 deletions
|
@ -108,7 +108,7 @@ const ReactApp = {
|
||||||
mobileTitleClick: (e) => self.openMap && self.openMap.InfoBox.toggleBox(e),
|
mobileTitleClick: (e) => self.openMap && self.openMap.InfoBox.toggleBox(e),
|
||||||
openInviteLightbox: () => self.openLightbox('invite'),
|
openInviteLightbox: () => self.openLightbox('invite'),
|
||||||
serverData: self.serverData,
|
serverData: self.serverData,
|
||||||
endActiveMap: mapControl.end,
|
endActiveMap: () => mapControl.end(self.openMap),
|
||||||
launchNewMap: mapControl.launch,
|
launchNewMap: mapControl.launch,
|
||||||
mapId: self.mapId,
|
mapId: self.mapId,
|
||||||
topicId: self.topicId
|
topicId: self.topicId
|
||||||
|
@ -159,7 +159,7 @@ const ReactApp = {
|
||||||
openTopic: TopicCard.openTopic,
|
openTopic: TopicCard.openTopic,
|
||||||
metacodeSets: self.metacodeSets,
|
metacodeSets: self.metacodeSets,
|
||||||
updateTopic: (topic, obj) => topic.save(obj),
|
updateTopic: (topic, obj) => topic.save(obj),
|
||||||
onTopicFollow: Topic.onTopicFollow // todo
|
onTopicFollow: () => {} // Topic.onTopicFollow // todo
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getTopicProps: function() {
|
getTopicProps: function() {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ReactApp.currentUserReactApp.currentUser/* global $, Hogan, Bloodhound, CanvasLoader */
|
/* global $, Hogan, Bloodhound, CanvasLoader */
|
||||||
|
|
||||||
import { browserHistory } from 'react-router'
|
import { browserHistory } from 'react-router'
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import Backbone from 'backbone'
|
||||||
import { Howl } from 'howler'
|
import { Howl } from 'howler'
|
||||||
|
|
||||||
import ReactApp from '../GlobalUI/ReactApp'
|
import ReactApp from '../GlobalUI/ReactApp'
|
||||||
|
import MessageCollection from '../DataModel/MessageCollection'
|
||||||
|
|
||||||
const ChatView = (map) => {
|
const ChatView = (map) => {
|
||||||
const toExport = {
|
const toExport = {
|
||||||
|
@ -12,19 +13,6 @@ const toExport = {
|
||||||
messages: new Backbone.Collection(),
|
messages: new Backbone.Collection(),
|
||||||
conversationLive: false,
|
conversationLive: false,
|
||||||
isParticipating: false,
|
isParticipating: false,
|
||||||
init: function(urls) {
|
|
||||||
const self = toExport
|
|
||||||
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() {
|
setNewMap: function() {
|
||||||
const self = toExport
|
const self = toExport
|
||||||
self.unreadMessages = 0
|
self.unreadMessages = 0
|
||||||
|
@ -118,13 +106,13 @@ const toExport = {
|
||||||
addMessage: (message, isInitial, wasMe) => {
|
addMessage: (message, isInitial, wasMe) => {
|
||||||
const self = toExport
|
const self = toExport
|
||||||
if (!isInitial && !self.isOpen) self.unreadMessages += 1
|
if (!isInitial && !self.isOpen) self.unreadMessages += 1
|
||||||
if (!wasMe && !isInitial && self.alertSound) self.sound.play('receivechat')
|
if (!wasMe && !isInitial && self.alertSound) ChatView.sound.play('receivechat')
|
||||||
self.messages.add(message)
|
self.messages.add(message)
|
||||||
if (!isInitial && self.isOpen) self.render()
|
if (!isInitial && self.isOpen) self.render()
|
||||||
},
|
},
|
||||||
sendChatMessage: message => {
|
sendChatMessage: message => {
|
||||||
var self = toExport
|
var self = toExport
|
||||||
if (toExport.alertSound) toExport.sound.play('sendchat')
|
if (toExport.alertSound) ChatView.sound.play('sendchat')
|
||||||
var m = new DataModel.Message({
|
var m = new DataModel.Message({
|
||||||
message: message.message,
|
message: message.message,
|
||||||
resource_id: map.Active.Map.id,
|
resource_id: map.Active.Map.id,
|
||||||
|
@ -132,7 +120,7 @@ const toExport = {
|
||||||
})
|
})
|
||||||
m.save(null, {
|
m.save(null, {
|
||||||
success: function(model, response) {
|
success: function(model, response) {
|
||||||
self.addMessages(new DataModel.MessageCollection(model), false, true)
|
self.addMessages(new MessageCollection(model), false, true)
|
||||||
},
|
},
|
||||||
error: function(model, response) {
|
error: function(model, response) {
|
||||||
console.log('error!', response)
|
console.log('error!', response)
|
||||||
|
@ -150,7 +138,6 @@ const toExport = {
|
||||||
}
|
}
|
||||||
return toExport
|
return toExport
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class
|
* @class
|
||||||
* @static
|
* @static
|
||||||
|
@ -165,5 +152,17 @@ ChatView.events = {
|
||||||
videosOff: 'ChatView:videosOff',
|
videosOff: 'ChatView:videosOff',
|
||||||
videosOn: 'ChatView:videosOn'
|
videosOn: 'ChatView:videosOn'
|
||||||
}
|
}
|
||||||
|
ChatView.init = function(urls) {
|
||||||
|
ChatView.sound = new Howl({
|
||||||
|
src: urls,
|
||||||
|
sprite: {
|
||||||
|
joinmap: [0, 561],
|
||||||
|
leavemap: [1000, 592],
|
||||||
|
receivechat: [2000, 318],
|
||||||
|
sendchat: [3000, 296],
|
||||||
|
sessioninvite: [4000, 5393, true]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export default ChatView
|
export default ChatView
|
||||||
|
|
|
@ -266,7 +266,7 @@ const toExport = {
|
||||||
})
|
})
|
||||||
toExport.newTopic.beingCreated = true
|
toExport.newTopic.beingCreated = true
|
||||||
toExport.newTopic.name = ''
|
toExport.newTopic.name = ''
|
||||||
//Map.setHasLearnedTopicCreation(true)
|
map.Map.setHasLearnedTopicCreation(true)
|
||||||
},
|
},
|
||||||
hide: function(force) {
|
hide: function(force) {
|
||||||
if (force || !toExport.newTopic.pinned) {
|
if (force || !toExport.newTopic.pinned) {
|
||||||
|
@ -277,7 +277,7 @@ const toExport = {
|
||||||
toExport.newTopic.pinned = false
|
toExport.newTopic.pinned = false
|
||||||
}
|
}
|
||||||
if (map.DataModel.Topics.length === 0) {
|
if (map.DataModel.Topics.length === 0) {
|
||||||
Map.setHasLearnedTopicCreation(false)
|
map.Map.setHasLearnedTopicCreation(false)
|
||||||
}
|
}
|
||||||
toExport.newTopic.beingCreated = false
|
toExport.newTopic.beingCreated = false
|
||||||
},
|
},
|
||||||
|
|
|
@ -6,274 +6,274 @@ import GlobalUI, { ReactApp } from '../GlobalUI'
|
||||||
import Settings from '../Settings'
|
import Settings from '../Settings'
|
||||||
|
|
||||||
const Filter = (map) => {
|
const Filter = (map) => {
|
||||||
const toExport = {
|
const toExport = {
|
||||||
dataForPresentation: {
|
dataForPresentation: {
|
||||||
metacodes: {},
|
metacodes: {},
|
||||||
mappers: {},
|
mappers: {},
|
||||||
synapses: {}
|
synapses: {}
|
||||||
},
|
},
|
||||||
filters: {
|
filters: {
|
||||||
metacodes: [],
|
metacodes: [],
|
||||||
mappers: [],
|
mappers: [],
|
||||||
synapses: []
|
synapses: []
|
||||||
},
|
},
|
||||||
visible: {
|
visible: {
|
||||||
metacodes: [],
|
metacodes: [],
|
||||||
mappers: [],
|
mappers: [],
|
||||||
synapses: []
|
synapses: []
|
||||||
},
|
},
|
||||||
reset: function() {
|
reset: function() {
|
||||||
var self = toExport
|
var self = toExport
|
||||||
self.filters.metacodes = []
|
self.filters.metacodes = []
|
||||||
self.filters.mappers = []
|
self.filters.mappers = []
|
||||||
self.filters.synapses = []
|
self.filters.synapses = []
|
||||||
self.visible.metacodes = []
|
self.visible.metacodes = []
|
||||||
self.visible.mappers = []
|
self.visible.mappers = []
|
||||||
self.visible.synapses = []
|
self.visible.synapses = []
|
||||||
self.dataForPresentation.metacodes = {}
|
self.dataForPresentation.metacodes = {}
|
||||||
self.dataForPresentation.mappers = {}
|
self.dataForPresentation.mappers = {}
|
||||||
self.dataForPresentation.synapses = {}
|
self.dataForPresentation.synapses = {}
|
||||||
ReactApp.render()
|
ReactApp.render()
|
||||||
},
|
},
|
||||||
// an abstraction function for checkMetacodes, checkMappers, checkSynapses to reduce
|
// an abstraction function for checkMetacodes, checkMappers, checkSynapses to reduce
|
||||||
// code redundancy
|
// code redundancy
|
||||||
updateFilters: function(collection, propertyToCheck, correlatedModel, filtersToUse, listToModify) {
|
updateFilters: function(collection, propertyToCheck, correlatedModel, filtersToUse, listToModify) {
|
||||||
var self = toExport
|
var self = toExport
|
||||||
var newList = []
|
var newList = []
|
||||||
var removed = []
|
var removed = []
|
||||||
var added = []
|
var added = []
|
||||||
// the first option enables us to accept
|
// the first option enables us to accept
|
||||||
// ['Topics', 'Synapses'] as 'collection'
|
// ['Topics', 'Synapses'] as 'collection'
|
||||||
if (typeof collection === 'object') {
|
if (typeof collection === 'object') {
|
||||||
DataModel[collection[0]].each(function(model) {
|
map.DataModel[collection[0]].each(function(model) {
|
||||||
var prop = model.get(propertyToCheck)
|
var prop = model.get(propertyToCheck)
|
||||||
if (prop !== null) {
|
if (prop !== null) {
|
||||||
prop = prop.toString()
|
prop = prop.toString()
|
||||||
if (newList.indexOf(prop) === -1) {
|
if (newList.indexOf(prop) === -1) {
|
||||||
newList.push(prop)
|
newList.push(prop)
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
DataModel[collection[1]].each(function(model) {
|
|
||||||
var prop = model.get(propertyToCheck)
|
|
||||||
if (prop !== null) {
|
|
||||||
prop = prop.toString()
|
|
||||||
if (newList.indexOf(prop) === -1) {
|
|
||||||
newList.push(prop)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else if (typeof collection === 'string') {
|
|
||||||
DataModel[collection].each(function(model) {
|
|
||||||
var prop = model.get(propertyToCheck)
|
|
||||||
if (prop !== null) {
|
|
||||||
prop = prop.toString()
|
|
||||||
if (newList.indexOf(prop) === -1) {
|
|
||||||
newList.push(prop)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
removed = _.difference(self.filters[filtersToUse], newList)
|
|
||||||
added = _.difference(newList, self.filters[filtersToUse])
|
|
||||||
_.each(removed, function(identifier) {
|
|
||||||
const index = self.visible[filtersToUse].indexOf(identifier)
|
|
||||||
self.visible[filtersToUse].splice(index, 1)
|
|
||||||
delete self.dataForPresentation[filtersToUse][identifier]
|
|
||||||
})
|
|
||||||
_.each(added, function(identifier) {
|
|
||||||
const model = DataModel[correlatedModel].get(identifier) ||
|
|
||||||
DataModel[correlatedModel].find(function(m) {
|
|
||||||
return m.get(propertyToCheck) === identifier
|
|
||||||
})
|
|
||||||
self.dataForPresentation[filtersToUse][identifier] = model.prepareDataForFilter()
|
|
||||||
self.visible[filtersToUse].push(identifier)
|
|
||||||
})
|
|
||||||
// update the list of filters with the new list we just generated
|
|
||||||
self.filters[filtersToUse] = newList
|
|
||||||
ReactApp.render()
|
|
||||||
},
|
|
||||||
checkMetacodes: function() {
|
|
||||||
var self = toExport
|
|
||||||
self.updateFilters('Topics', 'metacode_id', 'Metacodes', 'metacodes', 'metacode')
|
|
||||||
},
|
|
||||||
checkMappers: function() {
|
|
||||||
var self = toExport
|
|
||||||
if (map.Active.Map) {
|
|
||||||
self.updateFilters('Mappings', 'user_id', 'Mappers', 'mappers', 'mapper')
|
|
||||||
} else {
|
|
||||||
// on topic view
|
|
||||||
self.updateFilters(['Topics', 'Synapses'], 'user_id', 'Creators', 'mappers', 'mapper')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
checkSynapses: function() {
|
|
||||||
var self = toExport
|
|
||||||
self.updateFilters('Synapses', 'desc', 'Synapses', 'synapses', 'synapse')
|
|
||||||
},
|
|
||||||
filterAllMetacodes: function(toVisible) {
|
|
||||||
var self = toExport
|
|
||||||
self.visible.metacodes = toVisible ? self.filters.metacodes.slice() : []
|
|
||||||
ReactApp.render()
|
|
||||||
self.passFilters()
|
|
||||||
},
|
|
||||||
filterAllMappers: function(toVisible) {
|
|
||||||
var self = toExport
|
|
||||||
self.visible.mappers = toVisible ? self.filters.mappers.slice() : []
|
|
||||||
ReactApp.render()
|
|
||||||
self.passFilters()
|
|
||||||
},
|
|
||||||
filterAllSynapses: function(toVisible) {
|
|
||||||
var self = toExport
|
|
||||||
self.visible.synapses = toVisible ? self.filters.synapses.slice() : []
|
|
||||||
ReactApp.render()
|
|
||||||
self.passFilters()
|
|
||||||
},
|
|
||||||
// an abstraction function for toggleMetacode, toggleMapper, toggleSynapse
|
|
||||||
// to reduce code redundancy
|
|
||||||
// gets called in the context of a list item in a filter box
|
|
||||||
toggleLi: function(whichToFilter, id) {
|
|
||||||
var self = toExport
|
|
||||||
if (self.visible[whichToFilter].indexOf(id) === -1) {
|
|
||||||
self.visible[whichToFilter].push(id)
|
|
||||||
} else {
|
|
||||||
const index = self.visible[whichToFilter].indexOf(id)
|
|
||||||
self.visible[whichToFilter].splice(index, 1)
|
|
||||||
}
|
|
||||||
ReactApp.render()
|
|
||||||
self.passFilters()
|
|
||||||
},
|
|
||||||
toggleMetacode: function(id) {
|
|
||||||
var self = toExport
|
|
||||||
self.toggleLi('metacodes', id)
|
|
||||||
},
|
|
||||||
toggleMapper: function(id) {
|
|
||||||
var self = toExport
|
|
||||||
self.toggleLi('mappers', id)
|
|
||||||
},
|
|
||||||
toggleSynapse: function(id) {
|
|
||||||
var self = toExport
|
|
||||||
self.toggleLi('synapses', id)
|
|
||||||
},
|
|
||||||
passFilters: function() {
|
|
||||||
var self = toExport
|
|
||||||
var visible = self.visible
|
|
||||||
|
|
||||||
var passesMetacode, passesMapper, passesSynapse
|
|
||||||
|
|
||||||
var opacityForFilter = map.Active.Map ? 0 : 0.4
|
|
||||||
|
|
||||||
map.DataModel.Topics.each(function(topic) {
|
|
||||||
var n = topic.get('node')
|
|
||||||
var metacodeId = topic.get('metacode_id').toString()
|
|
||||||
|
|
||||||
if (visible.metacodes.indexOf(metacodeId) === -1) passesMetacode = false
|
|
||||||
else passesMetacode = true
|
|
||||||
|
|
||||||
if (map.Active.Map) {
|
|
||||||
// when on a map,
|
|
||||||
// we filter by mapper according to the person who added the
|
|
||||||
// topic or synapse to the map
|
|
||||||
let userId = topic.getMapping().get('user_id').toString()
|
|
||||||
if (visible.mappers.indexOf(userId) === -1) passesMapper = false
|
|
||||||
else passesMapper = true
|
|
||||||
} else {
|
|
||||||
// when on a topic view,
|
|
||||||
// we filter by mapper according to the person who created the
|
|
||||||
// topic or synapse
|
|
||||||
let userId = topic.get('user_id').toString()
|
|
||||||
if (visible.mappers.indexOf(userId) === -1) passesMapper = false
|
|
||||||
else passesMapper = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (passesMetacode && passesMapper) {
|
|
||||||
if (n) {
|
|
||||||
n.setData('alpha', 1, 'end')
|
|
||||||
} else {
|
|
||||||
console.log(topic)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (n) {
|
|
||||||
map.Control.deselectNode(n, true)
|
|
||||||
n.setData('alpha', opacityForFilter, 'end')
|
|
||||||
n.eachAdjacency(function(e) {
|
|
||||||
map.Control.deselectEdge(e, true)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
console.log(topic)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// flag all the edges back to 'untouched'
|
|
||||||
map.DataModel.Synapses.each(function(synapse) {
|
|
||||||
var e = synapse.get('edge')
|
|
||||||
e.setData('touched', false)
|
|
||||||
})
|
|
||||||
map.DataModel.Synapses.each(function(synapse) {
|
|
||||||
var e = synapse.get('edge')
|
|
||||||
var desc
|
|
||||||
var userId = synapse.get('user_id').toString()
|
|
||||||
|
|
||||||
if (e && !e.getData('touched')) {
|
|
||||||
var synapses = e.getData('synapses')
|
|
||||||
|
|
||||||
// if any of the synapses represent by the edge are still unfiltered
|
|
||||||
// leave the edge visible
|
|
||||||
passesSynapse = false
|
|
||||||
for (let i = 0; i < synapses.length; i++) {
|
|
||||||
desc = synapses[i].get('desc')
|
|
||||||
if (visible.synapses.indexOf(desc) > -1) passesSynapse = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the synapse description being displayed is now being
|
|
||||||
// filtered, set the displayIndex to the first unfiltered synapse if there is one
|
|
||||||
var displayIndex = e.getData('displayIndex') ? e.getData('displayIndex') : 0
|
|
||||||
var displayedSynapse = synapses[displayIndex]
|
|
||||||
desc = displayedSynapse.get('desc')
|
|
||||||
if (passesSynapse && visible.synapses.indexOf(desc) === -1) {
|
|
||||||
// iterate and find an unfiltered one
|
|
||||||
for (let i = 0; i < synapses.length; i++) {
|
|
||||||
desc = synapses[i].get('desc')
|
|
||||||
if (visible.synapses.indexOf(desc) > -1) {
|
|
||||||
e.setData('displayIndex', i)
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
map.DataModel[collection[1]].each(function(model) {
|
||||||
|
var prop = model.get(propertyToCheck)
|
||||||
|
if (prop !== null) {
|
||||||
|
prop = prop.toString()
|
||||||
|
if (newList.indexOf(prop) === -1) {
|
||||||
|
newList.push(prop)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else if (typeof collection === 'string') {
|
||||||
|
map.DataModel[collection].each(function(model) {
|
||||||
|
var prop = model.get(propertyToCheck)
|
||||||
|
if (prop !== null) {
|
||||||
|
prop = prop.toString()
|
||||||
|
if (newList.indexOf(prop) === -1) {
|
||||||
|
newList.push(prop)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
removed = _.difference(self.filters[filtersToUse], newList)
|
||||||
|
added = _.difference(newList, self.filters[filtersToUse])
|
||||||
|
_.each(removed, function(identifier) {
|
||||||
|
const index = self.visible[filtersToUse].indexOf(identifier)
|
||||||
|
self.visible[filtersToUse].splice(index, 1)
|
||||||
|
delete self.dataForPresentation[filtersToUse][identifier]
|
||||||
|
})
|
||||||
|
_.each(added, function(identifier) {
|
||||||
|
const model = map.DataModel[correlatedModel].get(identifier) ||
|
||||||
|
map.DataModel[correlatedModel].find(function(m) {
|
||||||
|
return m.get(propertyToCheck) === identifier
|
||||||
|
})
|
||||||
|
self.dataForPresentation[filtersToUse][identifier] = model.prepareDataForFilter()
|
||||||
|
self.visible[filtersToUse].push(identifier)
|
||||||
|
})
|
||||||
|
// update the list of filters with the new list we just generated
|
||||||
|
self.filters[filtersToUse] = newList
|
||||||
|
ReactApp.render()
|
||||||
|
},
|
||||||
|
checkMetacodes: function() {
|
||||||
|
var self = toExport
|
||||||
|
self.updateFilters('Topics', 'metacode_id', 'Metacodes', 'metacodes', 'metacode')
|
||||||
|
},
|
||||||
|
checkMappers: function() {
|
||||||
|
var self = toExport
|
||||||
|
if (map.Active.Map) {
|
||||||
|
self.updateFilters('Mappings', 'user_id', 'Mappers', 'mappers', 'mapper')
|
||||||
|
} else {
|
||||||
|
// on topic view
|
||||||
|
self.updateFilters(['Topics', 'Synapses'], 'user_id', 'Creators', 'mappers', 'mapper')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
checkSynapses: function() {
|
||||||
|
var self = toExport
|
||||||
|
self.updateFilters('Synapses', 'desc', 'Synapses', 'synapses', 'synapse')
|
||||||
|
},
|
||||||
|
filterAllMetacodes: function(toVisible) {
|
||||||
|
var self = toExport
|
||||||
|
self.visible.metacodes = toVisible ? self.filters.metacodes.slice() : []
|
||||||
|
ReactApp.render()
|
||||||
|
self.passFilters()
|
||||||
|
},
|
||||||
|
filterAllMappers: function(toVisible) {
|
||||||
|
var self = toExport
|
||||||
|
self.visible.mappers = toVisible ? self.filters.mappers.slice() : []
|
||||||
|
ReactApp.render()
|
||||||
|
self.passFilters()
|
||||||
|
},
|
||||||
|
filterAllSynapses: function(toVisible) {
|
||||||
|
var self = toExport
|
||||||
|
self.visible.synapses = toVisible ? self.filters.synapses.slice() : []
|
||||||
|
ReactApp.render()
|
||||||
|
self.passFilters()
|
||||||
|
},
|
||||||
|
// an abstraction function for toggleMetacode, toggleMapper, toggleSynapse
|
||||||
|
// to reduce code redundancy
|
||||||
|
// gets called in the context of a list item in a filter box
|
||||||
|
toggleLi: function(whichToFilter, id) {
|
||||||
|
var self = toExport
|
||||||
|
if (self.visible[whichToFilter].indexOf(id) === -1) {
|
||||||
|
self.visible[whichToFilter].push(id)
|
||||||
|
} else {
|
||||||
|
const index = self.visible[whichToFilter].indexOf(id)
|
||||||
|
self.visible[whichToFilter].splice(index, 1)
|
||||||
|
}
|
||||||
|
ReactApp.render()
|
||||||
|
self.passFilters()
|
||||||
|
},
|
||||||
|
toggleMetacode: function(id) {
|
||||||
|
var self = toExport
|
||||||
|
self.toggleLi('metacodes', id)
|
||||||
|
},
|
||||||
|
toggleMapper: function(id) {
|
||||||
|
var self = toExport
|
||||||
|
self.toggleLi('mappers', id)
|
||||||
|
},
|
||||||
|
toggleSynapse: function(id) {
|
||||||
|
var self = toExport
|
||||||
|
self.toggleLi('synapses', id)
|
||||||
|
},
|
||||||
|
passFilters: function() {
|
||||||
|
var self = toExport
|
||||||
|
var visible = self.visible
|
||||||
|
|
||||||
|
var passesMetacode, passesMapper, passesSynapse
|
||||||
|
|
||||||
|
var opacityForFilter = map.Active.Map ? 0 : 0.4
|
||||||
|
|
||||||
|
map.DataModel.Topics.each(function(topic) {
|
||||||
|
var n = topic.get('node')
|
||||||
|
var metacodeId = topic.get('metacode_id').toString()
|
||||||
|
|
||||||
|
if (visible.metacodes.indexOf(metacodeId) === -1) passesMetacode = false
|
||||||
|
else passesMetacode = true
|
||||||
|
|
||||||
if (map.Active.Map) {
|
if (map.Active.Map) {
|
||||||
// when on a map,
|
// when on a map,
|
||||||
// we filter by mapper according to the person who added the
|
// we filter by mapper according to the person who added the
|
||||||
// topic or synapse to the map
|
// topic or synapse to the map
|
||||||
userId = synapse.getMapping().get('user_id').toString()
|
let userId = topic.getMapping().get('user_id').toString()
|
||||||
}
|
if (visible.mappers.indexOf(userId) === -1) passesMapper = false
|
||||||
if (visible.mappers.indexOf(userId) === -1) passesMapper = false
|
else passesMapper = true
|
||||||
else passesMapper = true
|
|
||||||
|
|
||||||
var color = Settings.colors.synapses.normal
|
|
||||||
if (passesSynapse && passesMapper) {
|
|
||||||
e.setData('alpha', 1, 'end')
|
|
||||||
e.setData('color', color, 'end')
|
|
||||||
} else {
|
} else {
|
||||||
map.Control.deselectEdge(e, true)
|
// when on a topic view,
|
||||||
e.setData('alpha', opacityForFilter, 'end')
|
// we filter by mapper according to the person who created the
|
||||||
|
// topic or synapse
|
||||||
|
let userId = topic.get('user_id').toString()
|
||||||
|
if (visible.mappers.indexOf(userId) === -1) passesMapper = false
|
||||||
|
else passesMapper = true
|
||||||
}
|
}
|
||||||
|
|
||||||
e.setData('touched', true)
|
if (passesMetacode && passesMapper) {
|
||||||
} else if (!e) {
|
if (n) {
|
||||||
console.log(synapse)
|
n.setData('alpha', 1, 'end')
|
||||||
}
|
} else {
|
||||||
})
|
console.log(topic)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (n) {
|
||||||
|
map.Control.deselectNode(n, true)
|
||||||
|
n.setData('alpha', opacityForFilter, 'end')
|
||||||
|
n.eachAdjacency(function(e) {
|
||||||
|
map.Control.deselectEdge(e, true)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
console.log(topic)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// run the animation
|
// flag all the edges back to 'untouched'
|
||||||
map.Visualize.mGraph.fx.animate({
|
map.DataModel.Synapses.each(function(synapse) {
|
||||||
modes: ['node-property:alpha',
|
var e = synapse.get('edge')
|
||||||
'edge-property:alpha'],
|
e.setData('touched', false)
|
||||||
duration: 200
|
})
|
||||||
})
|
map.DataModel.Synapses.each(function(synapse) {
|
||||||
|
var e = synapse.get('edge')
|
||||||
|
var desc
|
||||||
|
var userId = synapse.get('user_id').toString()
|
||||||
|
|
||||||
|
if (e && !e.getData('touched')) {
|
||||||
|
var synapses = e.getData('synapses')
|
||||||
|
|
||||||
|
// if any of the synapses represent by the edge are still unfiltered
|
||||||
|
// leave the edge visible
|
||||||
|
passesSynapse = false
|
||||||
|
for (let i = 0; i < synapses.length; i++) {
|
||||||
|
desc = synapses[i].get('desc')
|
||||||
|
if (visible.synapses.indexOf(desc) > -1) passesSynapse = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the synapse description being displayed is now being
|
||||||
|
// filtered, set the displayIndex to the first unfiltered synapse if there is one
|
||||||
|
var displayIndex = e.getData('displayIndex') ? e.getData('displayIndex') : 0
|
||||||
|
var displayedSynapse = synapses[displayIndex]
|
||||||
|
desc = displayedSynapse.get('desc')
|
||||||
|
if (passesSynapse && visible.synapses.indexOf(desc) === -1) {
|
||||||
|
// iterate and find an unfiltered one
|
||||||
|
for (let i = 0; i < synapses.length; i++) {
|
||||||
|
desc = synapses[i].get('desc')
|
||||||
|
if (visible.synapses.indexOf(desc) > -1) {
|
||||||
|
e.setData('displayIndex', i)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (map.Active.Map) {
|
||||||
|
// when on a map,
|
||||||
|
// we filter by mapper according to the person who added the
|
||||||
|
// topic or synapse to the map
|
||||||
|
userId = synapse.getMapping().get('user_id').toString()
|
||||||
|
}
|
||||||
|
if (visible.mappers.indexOf(userId) === -1) passesMapper = false
|
||||||
|
else passesMapper = true
|
||||||
|
|
||||||
|
var color = Settings.colors.synapses.normal
|
||||||
|
if (passesSynapse && passesMapper) {
|
||||||
|
e.setData('alpha', 1, 'end')
|
||||||
|
e.setData('color', color, 'end')
|
||||||
|
} else {
|
||||||
|
map.Control.deselectEdge(e, true)
|
||||||
|
e.setData('alpha', opacityForFilter, 'end')
|
||||||
|
}
|
||||||
|
|
||||||
|
e.setData('touched', true)
|
||||||
|
} else if (!e) {
|
||||||
|
console.log(synapse)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// run the animation
|
||||||
|
map.Visualize.mGraph.fx.animate({
|
||||||
|
modes: ['node-property:alpha',
|
||||||
|
'edge-property:alpha'],
|
||||||
|
duration: 200
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return toExport
|
||||||
return toExport
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Filter
|
export default Filter
|
||||||
|
|
|
@ -3,387 +3,389 @@
|
||||||
import outdent from 'outdent'
|
import outdent from 'outdent'
|
||||||
import { browserHistory } from 'react-router'
|
import { browserHistory } from 'react-router'
|
||||||
|
|
||||||
|
import DataModel from '../DataModel'
|
||||||
import GlobalUI, { ReactApp } from '../GlobalUI'
|
import GlobalUI, { ReactApp } from '../GlobalUI'
|
||||||
import Util from '../Util'
|
import Util from '../Util'
|
||||||
|
|
||||||
const InfoBox = (map) => {
|
const InfoBox = (map) => {
|
||||||
const toExport = {
|
const toExport = {
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
selectingPermission: false,
|
selectingPermission: false,
|
||||||
changePermissionText: "<div class='tooltips'>As the creator, you can change the permission of this map, and the permission of all the topics and synapses you have authority to change will change as well.</div>",
|
changePermissionText: "<div class='tooltips'>As the creator, you can change the permission of this map, and the permission of all the topics and synapses you have authority to change will change as well.</div>",
|
||||||
nameHTML: outdent`
|
nameHTML: outdent`
|
||||||
<span class="best_in_place best_in_place_name"
|
<span class="best_in_place best_in_place_name"
|
||||||
id="best_in_place_map_{{id}}_name"
|
id="best_in_place_map_{{id}}_name"
|
||||||
data-bip-url="/maps/{{id}}"
|
data-bip-url="/maps/{{id}}"
|
||||||
data-bip-object="map"
|
data-bip-object="map"
|
||||||
data-bip-attribute="name"
|
data-bip-attribute="name"
|
||||||
data-bip-type="textarea"
|
data-bip-type="textarea"
|
||||||
data-bip-activator="#mapInfoName"
|
data-bip-activator="#mapInfoName"
|
||||||
data-bip-value="{{name}}"
|
data-bip-value="{{name}}"
|
||||||
>{{name}}</span>`,
|
>{{name}}</span>`,
|
||||||
descHTML: outdent`
|
descHTML: outdent`
|
||||||
<span class="best_in_place best_in_place_desc"
|
<span class="best_in_place best_in_place_desc"
|
||||||
id="best_in_place_map_{{id}}_desc"
|
id="best_in_place_map_{{id}}_desc"
|
||||||
data-bip-url="/maps/{{id}}"
|
data-bip-url="/maps/{{id}}"
|
||||||
data-bip-object="map"
|
data-bip-object="map"
|
||||||
data-bip-attribute="desc"
|
data-bip-attribute="desc"
|
||||||
data-bip-nil="Click to add description..."
|
data-bip-nil="Click to add description..."
|
||||||
data-bip-type="textarea"
|
data-bip-type="textarea"
|
||||||
data-bip-activator="#mapInfoDesc"
|
data-bip-activator="#mapInfoDesc"
|
||||||
data-bip-value="{{desc}}"
|
data-bip-value="{{desc}}"
|
||||||
>{{desc}}</span>`,
|
>{{desc}}</span>`,
|
||||||
userImageUrl: '',
|
userImageUrl: '',
|
||||||
html: '',
|
html: '',
|
||||||
init: function(serverData, updateThumbnail) {
|
init: function(serverData, updateThumbnail) {
|
||||||
var self = toExport
|
var self = toExport
|
||||||
|
|
||||||
self.updateThumbnail = updateThumbnail
|
self.updateThumbnail = updateThumbnail
|
||||||
|
|
||||||
$('.maptoExport').click(function(event) {
|
$('.mapInfoBox').click(function(event) {
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
})
|
})
|
||||||
$('body').click(self.close)
|
$('body').click(self.close)
|
||||||
|
|
||||||
self.attachEventListeners()
|
self.attachEventListeners()
|
||||||
|
|
||||||
self.generateBoxHTML = Hogan.compile($('#maptoExportTemplate').html())
|
self.generateBoxHTML = Hogan.compile($('#mapInfoBoxTemplate').html())
|
||||||
|
|
||||||
self.userImageUrl = serverData['user.png']
|
self.userImageUrl = serverData['user.png']
|
||||||
|
|
||||||
var querystring = window.location.search.replace(/^\?/, '')
|
var querystring = window.location.search.replace(/^\?/, '')
|
||||||
if (querystring === 'new') {
|
if (querystring === 'new') {
|
||||||
self.open()
|
self.open()
|
||||||
$('.maptoExport').addClass('mapRequestTitle')
|
$('.mapInfoBox').addClass('mapRequestTitle')
|
||||||
$('#mapInfoName').trigger('click')
|
$('#mapInfoName').trigger('click')
|
||||||
$('#mapInfoName textarea').focus()
|
$('#mapInfoName textarea').focus()
|
||||||
$('#mapInfoName textarea').select()
|
$('#mapInfoName textarea').select()
|
||||||
}
|
|
||||||
},
|
|
||||||
toggleBox: function(event) {
|
|
||||||
var self = toExport
|
|
||||||
|
|
||||||
if (self.isOpen) self.close()
|
|
||||||
else self.open()
|
|
||||||
|
|
||||||
event.stopPropagation()
|
|
||||||
},
|
|
||||||
open: function() {
|
|
||||||
var self = toExport
|
|
||||||
$('.mapInfoIcon div').addClass('hide')
|
|
||||||
$('.maptoExport').fadeIn(200, function() {
|
|
||||||
self.isOpen = true
|
|
||||||
})
|
|
||||||
},
|
|
||||||
close: function() {
|
|
||||||
var self = toExport
|
|
||||||
$('.mapInfoIcon div').removeClass('hide')
|
|
||||||
$('.maptoExport').fadeOut(200, function() {
|
|
||||||
self.isOpen = false
|
|
||||||
self.hidePermissionSelect()
|
|
||||||
$('.mapContributors .tip').hide()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
load: function() {
|
|
||||||
var self = toExport
|
|
||||||
|
|
||||||
var map = map.Active.Map
|
|
||||||
|
|
||||||
var obj = map.pick('permission', 'topic_count', 'synapse_count')
|
|
||||||
|
|
||||||
var isCreator = map.authorizePermissionChange(map.Active.Mapper)
|
|
||||||
var canEdit = map.authorizeToEdit(map.Active.Mapper)
|
|
||||||
var relevantPeople = map.get('permission') === 'commons' ? map.DataModel.Mappers : map.DataModel.Collaborators
|
|
||||||
var shareable = map.get('permission') !== 'private'
|
|
||||||
|
|
||||||
obj['name'] = canEdit ? Hogan.compile(self.nameHTML).render({id: map.id, name: map.get('name')}) : map.get('name')
|
|
||||||
obj['desc'] = canEdit ? Hogan.compile(self.descHTML).render({id: map.id, desc: map.get('desc')}) : map.get('desc')
|
|
||||||
obj['map_creator_tip'] = isCreator ? self.changePermissionText : ''
|
|
||||||
|
|
||||||
obj['contributor_count'] = relevantPeople.length
|
|
||||||
obj['contributors_class'] = relevantPeople.length > 1 ? 'multiple' : ''
|
|
||||||
obj['contributors_class'] += relevantPeople.length === 2 ? ' mTwo' : ''
|
|
||||||
obj['contributor_image'] = relevantPeople.length > 0 ? relevantPeople.models[0].get('image') : self.userImageUrl
|
|
||||||
obj['contributor_list'] = self.createContributorList()
|
|
||||||
|
|
||||||
obj['user_name'] = isCreator ? 'You' : map.get('user_name')
|
|
||||||
obj['created_at'] = map.get('created_at_clean')
|
|
||||||
obj['updated_at'] = map.get('updated_at_clean')
|
|
||||||
|
|
||||||
self.html = self.generateBoxHTML.render(obj)
|
|
||||||
ReactApp.render()
|
|
||||||
self.attachEventListeners()
|
|
||||||
},
|
|
||||||
attachEventListeners: function() {
|
|
||||||
var self = toExport
|
|
||||||
|
|
||||||
$('.maptoExport.canEdit .best_in_place').best_in_place()
|
|
||||||
|
|
||||||
// because anyone who can edit the map can change the map title
|
|
||||||
var bipName = $('.maptoExport .best_in_place_name')
|
|
||||||
bipName.unbind('best_in_place:activate').bind('best_in_place:activate', function() {
|
|
||||||
var $el = bipName.find('textarea')
|
|
||||||
var el = $el[0]
|
|
||||||
|
|
||||||
$el.attr('maxlength', '140')
|
|
||||||
|
|
||||||
$('.mapInfoName').append('<div class="nameCounter forMap"></div>')
|
|
||||||
|
|
||||||
var callback = function(data) {
|
|
||||||
$('.nameCounter.forMap').html(data.all + '/140')
|
|
||||||
}
|
}
|
||||||
Countable.live(el, callback)
|
},
|
||||||
})
|
toggleBox: function(event) {
|
||||||
bipName.unbind('best_in_place:deactivate').bind('best_in_place:deactivate', function() {
|
var self = toExport
|
||||||
$('.nameCounter.forMap').remove()
|
|
||||||
})
|
|
||||||
|
|
||||||
$('.mapInfoName .best_in_place_name').unbind('ajax:success').bind('ajax:success', function() {
|
if (self.isOpen) self.close()
|
||||||
var name = $(this).html()
|
else self.open()
|
||||||
map.Active.Map.set('name', name)
|
|
||||||
map.Active.Map.trigger('saved')
|
|
||||||
// mobile menu
|
|
||||||
$('#header_content').html(name)
|
|
||||||
$('.maptoExport').removeClass('mapRequestTitle')
|
|
||||||
document.title = `${name} | Metamaps`
|
|
||||||
window.history.replaceState('', `${name} | Metamaps`, window.location.pathname)
|
|
||||||
})
|
|
||||||
|
|
||||||
$('.mapInfoDesc .best_in_place_desc').unbind('ajax:success').bind('ajax:success', function() {
|
|
||||||
var desc = $(this).html()
|
|
||||||
map.Active.Map.set('desc', desc)
|
|
||||||
map.Active.Map.trigger('saved')
|
|
||||||
})
|
|
||||||
|
|
||||||
$('.mapInfoDesc .best_in_place_desc, .mapInfoName .best_in_place_name').unbind('keypress').keypress(function(e) {
|
|
||||||
const ENTER = 13
|
|
||||||
if (e.which === ENTER) {
|
|
||||||
$(this).data('bestInPlaceEditor').update()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
$('.yourMap .mapPermission').unbind().click(self.onPermissionClick)
|
|
||||||
// .yourMap in the unbind/bind is just a namespace for the events
|
|
||||||
// not a reference to the class .yourMap on the .maptoExport
|
|
||||||
$('.maptoExport.yourMap').unbind('.yourMap').bind('click.yourMap', self.hidePermissionSelect)
|
|
||||||
|
|
||||||
$('.yourMap .mapInfoDelete').unbind().click(self.deleteActiveMap)
|
|
||||||
$('.mapInfoThumbnail').unbind().click(self.updateThumbnail)
|
|
||||||
|
|
||||||
$('.mapContributors span, #mapContribs').unbind().click(function(event) {
|
|
||||||
$('.mapContributors .tip').toggle()
|
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
})
|
},
|
||||||
$('.mapContributors .tip').unbind().click(function(event) {
|
open: function() {
|
||||||
event.stopPropagation()
|
var self = toExport
|
||||||
})
|
$('.mapInfoIcon div').addClass('hide')
|
||||||
|
$('.maptoExport').fadeIn(200, function() {
|
||||||
|
self.isOpen = true
|
||||||
|
})
|
||||||
|
},
|
||||||
|
close: function() {
|
||||||
|
var self = toExport
|
||||||
|
$('.mapInfoIcon div').removeClass('hide')
|
||||||
|
$('.mapInfoBox').fadeOut(200, function() {
|
||||||
|
self.isOpen = false
|
||||||
|
self.hidePermissionSelect()
|
||||||
|
$('.mapContributors .tip').hide()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
load: function() {
|
||||||
|
var self = toExport
|
||||||
|
|
||||||
$('.maptoExport').unbind('.hideTip').bind('click.hideTip', function() {
|
var m = map.Active.Map
|
||||||
$('.mapContributors .tip').hide()
|
|
||||||
})
|
|
||||||
|
|
||||||
self.addTypeahead()
|
var obj = m.pick('permission', 'topic_count', 'synapse_count')
|
||||||
},
|
|
||||||
addTypeahead: function() {
|
|
||||||
var self = toExport
|
|
||||||
|
|
||||||
if (!map.Active.Map) return
|
var isCreator = m.authorizePermissionChange(map.Active.Mapper)
|
||||||
|
var canEdit = m.authorizeToEdit(map.Active.Mapper)
|
||||||
|
var relevantPeople = m.get('permission') === 'commons' ? map.DataModel.Mappers : map.DataModel.Collaborators
|
||||||
|
var shareable = m.get('permission') !== 'private'
|
||||||
|
|
||||||
// for autocomplete
|
obj['name'] = canEdit ? Hogan.compile(self.nameHTML).render({id: m.id, name: m.get('name')}) : m.get('name')
|
||||||
var collaborators = {
|
obj['desc'] = canEdit ? Hogan.compile(self.descHTML).render({id: m.id, desc: m.get('desc')}) : m.get('desc')
|
||||||
name: 'collaborators',
|
obj['map_creator_tip'] = isCreator ? self.changePermissionText : ''
|
||||||
limit: 9999,
|
|
||||||
display: function(s) { return s.label },
|
obj['contributor_count'] = relevantPeople.length
|
||||||
templates: {
|
obj['contributors_class'] = relevantPeople.length > 1 ? 'multiple' : ''
|
||||||
notFound: function(s) {
|
obj['contributors_class'] += relevantPeople.length === 2 ? ' mTwo' : ''
|
||||||
return Hogan.compile($('#collaboratorSearchTemplate').html()).render({
|
obj['contributor_image'] = relevantPeople.length > 0 ? relevantPeople.models[0].get('image') : self.userImageUrl
|
||||||
value: 'No results',
|
obj['contributor_list'] = self.createContributorList()
|
||||||
label: 'No results',
|
|
||||||
rtype: 'noresult',
|
obj['user_name'] = isCreator ? 'You' : m.get('user_name')
|
||||||
profile: self.userImageUrl
|
obj['created_at'] = m.get('created_at_clean')
|
||||||
})
|
obj['updated_at'] = m.get('updated_at_clean')
|
||||||
},
|
|
||||||
suggestion: function(s) {
|
self.generateBoxHTML = self.generateBoxHTML || Hogan.compile($('#mapInfoBoxTemplate').html())
|
||||||
return Hogan.compile($('#collaboratorSearchTemplate').html()).render(s)
|
self.html = self.generateBoxHTML.render(obj)
|
||||||
|
ReactApp.render()
|
||||||
|
self.attachEventListeners()
|
||||||
|
},
|
||||||
|
attachEventListeners: function() {
|
||||||
|
var self = toExport
|
||||||
|
|
||||||
|
$('.maptoExport.canEdit .best_in_place').best_in_place()
|
||||||
|
|
||||||
|
// because anyone who can edit the map can change the map title
|
||||||
|
var bipName = $('.maptoExport .best_in_place_name')
|
||||||
|
bipName.unbind('best_in_place:activate').bind('best_in_place:activate', function() {
|
||||||
|
var $el = bipName.find('textarea')
|
||||||
|
var el = $el[0]
|
||||||
|
|
||||||
|
$el.attr('maxlength', '140')
|
||||||
|
|
||||||
|
$('.mapInfoName').append('<div class="nameCounter forMap"></div>')
|
||||||
|
|
||||||
|
var callback = function(data) {
|
||||||
|
$('.nameCounter.forMap').html(data.all + '/140')
|
||||||
}
|
}
|
||||||
},
|
Countable.live(el, callback)
|
||||||
source: new Bloodhound({
|
})
|
||||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
|
bipName.unbind('best_in_place:deactivate').bind('best_in_place:deactivate', function() {
|
||||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
$('.nameCounter.forMap').remove()
|
||||||
remote: {
|
})
|
||||||
url: '/search/mappers?term=%QUERY',
|
|
||||||
wildcard: '%QUERY'
|
$('.mapInfoName .best_in_place_name').unbind('ajax:success').bind('ajax:success', function() {
|
||||||
|
var name = $(this).html()
|
||||||
|
map.Active.Map.set('name', name)
|
||||||
|
map.Active.Map.trigger('saved')
|
||||||
|
// mobile menu
|
||||||
|
$('#header_content').html(name)
|
||||||
|
$('.maptoExport').removeClass('mapRequestTitle')
|
||||||
|
document.title = `${name} | Metamaps`
|
||||||
|
window.history.replaceState('', `${name} | Metamaps`, window.location.pathname)
|
||||||
|
})
|
||||||
|
|
||||||
|
$('.mapInfoDesc .best_in_place_desc').unbind('ajax:success').bind('ajax:success', function() {
|
||||||
|
var desc = $(this).html()
|
||||||
|
map.Active.Map.set('desc', desc)
|
||||||
|
map.Active.Map.trigger('saved')
|
||||||
|
})
|
||||||
|
|
||||||
|
$('.mapInfoDesc .best_in_place_desc, .mapInfoName .best_in_place_name').unbind('keypress').keypress(function(e) {
|
||||||
|
const ENTER = 13
|
||||||
|
if (e.which === ENTER) {
|
||||||
|
$(this).data('bestInPlaceEditor').update()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
// for adding map collaborators, who will have edit rights
|
$('.yourMap .mapPermission').unbind().click(self.onPermissionClick)
|
||||||
if (map.Active.Mapper && map.Active.Mapper.id === map.Active.Map.get('user_id')) {
|
// .yourMap in the unbind/bind is just a namespace for the events
|
||||||
$('.collaboratorSearchField').typeahead(
|
// not a reference to the class .yourMap on the .maptoExport
|
||||||
{
|
$('.maptoExport.yourMap').unbind('.yourMap').bind('click.yourMap', self.hidePermissionSelect)
|
||||||
highlight: false
|
|
||||||
},
|
$('.yourMap .mapInfoDelete').unbind().click(self.deleteActiveMap)
|
||||||
[collaborators]
|
$('.mapInfoThumbnail').unbind().click(self.updateThumbnail)
|
||||||
)
|
|
||||||
$('.collaboratorSearchField').bind('typeahead:select', self.handleResultClick)
|
$('.mapContributors span, #mapContribs').unbind().click(function(event) {
|
||||||
$('.mapContributors .removeCollaborator').click(function() {
|
$('.mapContributors .tip').toggle()
|
||||||
self.removeCollaborator(parseInt($(this).data('id')))
|
event.stopPropagation()
|
||||||
|
})
|
||||||
|
$('.mapContributors .tip').unbind().click(function(event) {
|
||||||
|
event.stopPropagation()
|
||||||
})
|
})
|
||||||
}
|
|
||||||
},
|
|
||||||
removeCollaborator: function(collaboratorId) {
|
|
||||||
var self = toExport
|
|
||||||
map.DataModel.Collaborators.remove(map.DataModel.Collaborators.get(collaboratorId))
|
|
||||||
var mapperIds = map.DataModel.Collaborators.models.map(function(mapper) { return mapper.id })
|
|
||||||
$.post('/maps/' + map.Active.Map.id + '/access', { access: mapperIds })
|
|
||||||
self.updateNumbers()
|
|
||||||
},
|
|
||||||
addCollaborator: function(newCollaboratorId) {
|
|
||||||
var self = toExport
|
|
||||||
|
|
||||||
if (map.DataModel.Collaborators.get(newCollaboratorId)) {
|
$('.maptoExport').unbind('.hideTip').bind('click.hideTip', function() {
|
||||||
GlobalUI.notifyUser('That user already has access')
|
$('.mapContributors .tip').hide()
|
||||||
return
|
})
|
||||||
}
|
|
||||||
|
|
||||||
function callback(mapper) {
|
self.addTypeahead()
|
||||||
map.DataModel.Collaborators.add(mapper)
|
},
|
||||||
|
addTypeahead: function() {
|
||||||
|
var self = toExport
|
||||||
|
|
||||||
|
if (!map.Active.Map) return
|
||||||
|
|
||||||
|
// for autocomplete
|
||||||
|
var collaborators = {
|
||||||
|
name: 'collaborators',
|
||||||
|
limit: 9999,
|
||||||
|
display: function(s) { return s.label },
|
||||||
|
templates: {
|
||||||
|
notFound: function(s) {
|
||||||
|
return Hogan.compile($('#collaboratorSearchTemplate').html()).render({
|
||||||
|
value: 'No results',
|
||||||
|
label: 'No results',
|
||||||
|
rtype: 'noresult',
|
||||||
|
profile: self.userImageUrl
|
||||||
|
})
|
||||||
|
},
|
||||||
|
suggestion: function(s) {
|
||||||
|
return Hogan.compile($('#collaboratorSearchTemplate').html()).render(s)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
source: new Bloodhound({
|
||||||
|
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
|
||||||
|
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||||
|
remote: {
|
||||||
|
url: '/search/mappers?term=%QUERY',
|
||||||
|
wildcard: '%QUERY'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// for adding map collaborators, who will have edit rights
|
||||||
|
if (map.Active.Mapper && map.Active.Mapper.id === map.Active.Map.get('user_id')) {
|
||||||
|
$('.collaboratorSearchField').typeahead(
|
||||||
|
{
|
||||||
|
highlight: false
|
||||||
|
},
|
||||||
|
[collaborators]
|
||||||
|
)
|
||||||
|
$('.collaboratorSearchField').bind('typeahead:select', self.handleResultClick)
|
||||||
|
$('.mapContributors .removeCollaborator').click(function() {
|
||||||
|
self.removeCollaborator(parseInt($(this).data('id')))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
removeCollaborator: function(collaboratorId) {
|
||||||
|
var self = toExport
|
||||||
|
map.DataModel.Collaborators.remove(map.DataModel.Collaborators.get(collaboratorId))
|
||||||
var mapperIds = map.DataModel.Collaborators.models.map(function(mapper) { return mapper.id })
|
var mapperIds = map.DataModel.Collaborators.models.map(function(mapper) { return mapper.id })
|
||||||
$.post('/maps/' + map.Active.Map.id + '/access', { access: mapperIds })
|
$.post('/maps/' + map.Active.Map.id + '/access', { access: mapperIds })
|
||||||
var name = map.DataModel.Collaborators.get(newCollaboratorId).get('name')
|
|
||||||
GlobalUI.notifyUser(name + ' will be notified')
|
|
||||||
self.updateNumbers()
|
self.updateNumbers()
|
||||||
}
|
},
|
||||||
|
addCollaborator: function(newCollaboratorId) {
|
||||||
|
var self = toExport
|
||||||
|
|
||||||
$.getJSON('/users/' + newCollaboratorId + '.json', callback)
|
if (map.DataModel.Collaborators.get(newCollaboratorId)) {
|
||||||
},
|
GlobalUI.notifyUser('That user already has access')
|
||||||
handleResultClick: function(event, item) {
|
return
|
||||||
var self = toExport
|
|
||||||
|
|
||||||
self.addCollaborator(item.id)
|
|
||||||
$('.collaboratorSearchField').typeahead('val', '')
|
|
||||||
},
|
|
||||||
updateNameDescPerm: function(name, desc, perm) {
|
|
||||||
$('.maptoExport').removeClass('mapRequestTitle')
|
|
||||||
$('.mapInfoName .best_in_place_name').html(name)
|
|
||||||
$('.mapInfoDesc .best_in_place_desc').html(desc)
|
|
||||||
$('.maptoExport .mapPermission').removeClass('commons public private').addClass(perm)
|
|
||||||
},
|
|
||||||
createContributorList: function() {
|
|
||||||
var relevantPeople = map.Active.Map.get('permission') === 'commons' ? map.DataModel.Mappers : map.DataModel.Collaborators
|
|
||||||
var activeMapperIsCreator = map.Active.Mapper && map.Active.Mapper.id === map.Active.Map.get('user_id')
|
|
||||||
var string = ''
|
|
||||||
string += '<ul>'
|
|
||||||
|
|
||||||
relevantPeople.each(function(m) {
|
|
||||||
var isCreator = map.Active.Map.get('user_id') === m.get('id')
|
|
||||||
string += '<li><a href="/explore/mapper/' + m.get('id') + '">' + '<img class="rtUserImage" width="25" height="25" src="' + m.get('image') + '" />' + m.get('name')
|
|
||||||
if (isCreator) string += ' (creator)'
|
|
||||||
string += '</a>'
|
|
||||||
if (activeMapperIsCreator && !isCreator) string += '<span class="removeCollaborator" data-id="' + m.get('id') + '"></span>'
|
|
||||||
string += '</li>'
|
|
||||||
})
|
|
||||||
|
|
||||||
string += '</ul>'
|
|
||||||
|
|
||||||
if (activeMapperIsCreator) {
|
|
||||||
string += '<div class="collabSearchField"><span class="addCollab"></span><input class="collaboratorSearchField" placeholder="Add a collaborator"></input></div>'
|
|
||||||
}
|
|
||||||
return string
|
|
||||||
},
|
|
||||||
updateNumbers: function() {
|
|
||||||
if (!map.Active.Map) return
|
|
||||||
|
|
||||||
const self = toExport
|
|
||||||
|
|
||||||
var relevantPeople = map.Active.Map.get('permission') === 'commons' ? map.DataModel.Mappers : map.DataModel.Collaborators
|
|
||||||
|
|
||||||
let contributorsClass = ''
|
|
||||||
if (relevantPeople.length === 2) {
|
|
||||||
contributorsClass = 'multiple mTwo'
|
|
||||||
} else if (relevantPeople.length > 2) {
|
|
||||||
contributorsClass = 'multiple'
|
|
||||||
}
|
|
||||||
|
|
||||||
let contributorsImage = self.userImageUrl
|
|
||||||
if (relevantPeople.length > 0) {
|
|
||||||
// get the first contributor and use their image
|
|
||||||
contributorsImage = relevantPeople.models[0].get('image')
|
|
||||||
}
|
|
||||||
$('.mapContributors img').attr('src', contributorsImage).removeClass('multiple mTwo').addClass(contributorsClass)
|
|
||||||
$('.mapContributors span').text(relevantPeople.length)
|
|
||||||
$('.mapContributors .tip').html(self.createContributorList())
|
|
||||||
self.addTypeahead()
|
|
||||||
$('.mapContributors .tip').unbind().click(function(event) {
|
|
||||||
event.stopPropagation()
|
|
||||||
})
|
|
||||||
$('.mapTopics').text(map.DataModel.Topics.length)
|
|
||||||
$('.mapSynapses').text(map.DataModel.Synapses.length)
|
|
||||||
|
|
||||||
$('.mapEditedAt').html('<span>Last edited: </span>' + Util.nowDateFormatted())
|
|
||||||
},
|
|
||||||
onPermissionClick: function(event) {
|
|
||||||
var self = toExport
|
|
||||||
|
|
||||||
if (!self.selectingPermission) {
|
|
||||||
self.selectingPermission = true
|
|
||||||
$(this).addClass('minimize') // this line flips the drop down arrow to a pull up arrow
|
|
||||||
if ($(this).hasClass('commons')) {
|
|
||||||
$(this).append('<ul class="permissionSelect"><li class="public"></li><li class="private"></li></ul>')
|
|
||||||
} else if ($(this).hasClass('public')) {
|
|
||||||
$(this).append('<ul class="permissionSelect"><li class="commons"></li><li class="private"></li></ul>')
|
|
||||||
} else if ($(this).hasClass('private')) {
|
|
||||||
$(this).append('<ul class="permissionSelect"><li class="commons"></li><li class="public"></li></ul>')
|
|
||||||
}
|
}
|
||||||
$('.mapPermission .permissionSelect li').click(self.selectPermission)
|
|
||||||
|
function callback(mapper) {
|
||||||
|
map.DataModel.Collaborators.add(mapper)
|
||||||
|
var mapperIds = map.DataModel.Collaborators.models.map(function(mapper) { return mapper.id })
|
||||||
|
$.post('/maps/' + map.Active.Map.id + '/access', { access: mapperIds })
|
||||||
|
var name = map.DataModel.Collaborators.get(newCollaboratorId).get('name')
|
||||||
|
GlobalUI.notifyUser(name + ' will be notified')
|
||||||
|
self.updateNumbers()
|
||||||
|
}
|
||||||
|
|
||||||
|
$.getJSON('/users/' + newCollaboratorId + '.json', callback)
|
||||||
|
},
|
||||||
|
handleResultClick: function(event, item) {
|
||||||
|
var self = toExport
|
||||||
|
|
||||||
|
self.addCollaborator(item.id)
|
||||||
|
$('.collaboratorSearchField').typeahead('val', '')
|
||||||
|
},
|
||||||
|
updateNameDescPerm: function(name, desc, perm) {
|
||||||
|
$('.maptoExport').removeClass('mapRequestTitle')
|
||||||
|
$('.mapInfoName .best_in_place_name').html(name)
|
||||||
|
$('.mapInfoDesc .best_in_place_desc').html(desc)
|
||||||
|
$('.maptoExport .mapPermission').removeClass('commons public private').addClass(perm)
|
||||||
|
},
|
||||||
|
createContributorList: function() {
|
||||||
|
var relevantPeople = map.Active.Map.get('permission') === 'commons' ? map.DataModel.Mappers : map.DataModel.Collaborators
|
||||||
|
var activeMapperIsCreator = map.Active.Mapper && map.Active.Mapper.id === map.Active.Map.get('user_id')
|
||||||
|
var string = ''
|
||||||
|
string += '<ul>'
|
||||||
|
|
||||||
|
relevantPeople.each(function(m) {
|
||||||
|
var isCreator = map.Active.Map.get('user_id') === m.get('id')
|
||||||
|
string += '<li><a href="/explore/mapper/' + m.get('id') + '">' + '<img class="rtUserImage" width="25" height="25" src="' + m.get('image') + '" />' + m.get('name')
|
||||||
|
if (isCreator) string += ' (creator)'
|
||||||
|
string += '</a>'
|
||||||
|
if (activeMapperIsCreator && !isCreator) string += '<span class="removeCollaborator" data-id="' + m.get('id') + '"></span>'
|
||||||
|
string += '</li>'
|
||||||
|
})
|
||||||
|
|
||||||
|
string += '</ul>'
|
||||||
|
|
||||||
|
if (activeMapperIsCreator) {
|
||||||
|
string += '<div class="collabSearchField"><span class="addCollab"></span><input class="collaboratorSearchField" placeholder="Add a collaborator"></input></div>'
|
||||||
|
}
|
||||||
|
return string
|
||||||
|
},
|
||||||
|
updateNumbers: function() {
|
||||||
|
if (!map.Active.Map) return
|
||||||
|
|
||||||
|
const self = toExport
|
||||||
|
|
||||||
|
var relevantPeople = map.Active.Map.get('permission') === 'commons' ? map.DataModel.Mappers : map.DataModel.Collaborators
|
||||||
|
|
||||||
|
let contributorsClass = ''
|
||||||
|
if (relevantPeople.length === 2) {
|
||||||
|
contributorsClass = 'multiple mTwo'
|
||||||
|
} else if (relevantPeople.length > 2) {
|
||||||
|
contributorsClass = 'multiple'
|
||||||
|
}
|
||||||
|
|
||||||
|
let contributorsImage = self.userImageUrl
|
||||||
|
if (relevantPeople.length > 0) {
|
||||||
|
// get the first contributor and use their image
|
||||||
|
contributorsImage = relevantPeople.models[0].get('image')
|
||||||
|
}
|
||||||
|
$('.mapContributors img').attr('src', contributorsImage).removeClass('multiple mTwo').addClass(contributorsClass)
|
||||||
|
$('.mapContributors span').text(relevantPeople.length)
|
||||||
|
$('.mapContributors .tip').html(self.createContributorList())
|
||||||
|
self.addTypeahead()
|
||||||
|
$('.mapContributors .tip').unbind().click(function(event) {
|
||||||
|
event.stopPropagation()
|
||||||
|
})
|
||||||
|
$('.mapTopics').text(map.DataModel.Topics.length)
|
||||||
|
$('.mapSynapses').text(map.DataModel.Synapses.length)
|
||||||
|
|
||||||
|
$('.mapEditedAt').html('<span>Last edited: </span>' + Util.nowDateFormatted())
|
||||||
|
},
|
||||||
|
onPermissionClick: function(event) {
|
||||||
|
var self = toExport
|
||||||
|
|
||||||
|
if (!self.selectingPermission) {
|
||||||
|
self.selectingPermission = true
|
||||||
|
$(this).addClass('minimize') // this line flips the drop down arrow to a pull up arrow
|
||||||
|
if ($(this).hasClass('commons')) {
|
||||||
|
$(this).append('<ul class="permissionSelect"><li class="public"></li><li class="private"></li></ul>')
|
||||||
|
} else if ($(this).hasClass('public')) {
|
||||||
|
$(this).append('<ul class="permissionSelect"><li class="commons"></li><li class="private"></li></ul>')
|
||||||
|
} else if ($(this).hasClass('private')) {
|
||||||
|
$(this).append('<ul class="permissionSelect"><li class="commons"></li><li class="public"></li></ul>')
|
||||||
|
}
|
||||||
|
$('.mapPermission .permissionSelect li').click(self.selectPermission)
|
||||||
|
event.stopPropagation()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hidePermissionSelect: function() {
|
||||||
|
var self = toExport
|
||||||
|
|
||||||
|
self.selectingPermission = false
|
||||||
|
$('.mapPermission').removeClass('minimize') // this line flips the pull up arrow to a drop down arrow
|
||||||
|
$('.mapPermission .permissionSelect').remove()
|
||||||
|
},
|
||||||
|
selectPermission: function(event) {
|
||||||
|
var self = toExport
|
||||||
|
|
||||||
|
self.selectingPermission = false
|
||||||
|
var permission = $(this).attr('class')
|
||||||
|
map.Active.Map.save({
|
||||||
|
permission: permission
|
||||||
|
})
|
||||||
|
map.Active.Map.updateMapWrapper()
|
||||||
|
const shareable = permission === 'private' ? '' : 'shareable'
|
||||||
|
$('.mapPermission').removeClass('commons public private minimize').addClass(permission)
|
||||||
|
$('.mapPermission .permissionSelect').remove()
|
||||||
|
$('.maptoExport').removeClass('shareable').addClass(shareable)
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
}
|
},
|
||||||
},
|
deleteActiveMap: function() {
|
||||||
hidePermissionSelect: function() {
|
var confirmString = 'Are you sure you want to delete this map? '
|
||||||
var self = toExport
|
confirmString += 'This action is irreversible. It will not delete the topics and synapses on the map.'
|
||||||
|
|
||||||
self.selectingPermission = false
|
var doIt = window.confirm(confirmString)
|
||||||
$('.mapPermission').removeClass('minimize') // this line flips the pull up arrow to a drop down arrow
|
var m = map.Active.Map
|
||||||
$('.mapPermission .permissionSelect').remove()
|
var mapper = map.Active.Mapper
|
||||||
},
|
var authorized = map.authorizePermissionChange(mapper)
|
||||||
selectPermission: function(event) {
|
|
||||||
var self = toExport
|
|
||||||
|
|
||||||
self.selectingPermission = false
|
if (doIt && authorized) {
|
||||||
var permission = $(this).attr('class')
|
toExport.close()
|
||||||
map.Active.Map.save({
|
DataModel.Maps.map.Active.remove(m)
|
||||||
permission: permission
|
DataModel.Maps.Featured.remove(m)
|
||||||
})
|
DataModel.Maps.Mine.remove(m)
|
||||||
map.Active.Map.updateMapWrapper()
|
DataModel.Maps.Shared.remove(m)
|
||||||
const shareable = permission === 'private' ? '' : 'shareable'
|
m.destroy()
|
||||||
$('.mapPermission').removeClass('commons public private minimize').addClass(permission)
|
browserHistory.push('/')
|
||||||
$('.mapPermission .permissionSelect').remove()
|
GlobalUI.notifyUser('Map eliminated')
|
||||||
$('.maptoExport').removeClass('shareable').addClass(shareable)
|
} else if (!authorized) {
|
||||||
event.stopPropagation()
|
window.alert("Hey now. We can't just go around willy nilly deleting other people's maps now can we? Run off and find something constructive to do, eh?")
|
||||||
},
|
}
|
||||||
deleteActiveMap: function() {
|
|
||||||
var confirmString = 'Are you sure you want to delete this map? '
|
|
||||||
confirmString += 'This action is irreversible. It will not delete the topics and synapses on the map.'
|
|
||||||
|
|
||||||
var doIt = window.confirm(confirmString)
|
|
||||||
var map = map.Active.Map
|
|
||||||
var mapper = map.Active.Mapper
|
|
||||||
var authorized = map.authorizePermissionChange(mapper)
|
|
||||||
|
|
||||||
if (doIt && authorized) {
|
|
||||||
toExport.close()
|
|
||||||
DataModel.Maps.map.Active.remove(map)
|
|
||||||
DataModel.Maps.Featured.remove(map)
|
|
||||||
DataModel.Maps.Mine.remove(map)
|
|
||||||
DataModel.Maps.Shared.remove(map)
|
|
||||||
map.destroy()
|
|
||||||
browserHistory.push('/')
|
|
||||||
GlobalUI.notifyUser('Map eliminated')
|
|
||||||
} else if (!authorized) {
|
|
||||||
window.alert("Hey now. We can't just go around willy nilly deleting other people's maps now can we? Run off and find something constructive to do, eh?")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return toExport
|
||||||
return toExport
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default InfoBox
|
export default InfoBox
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -3,8 +3,12 @@
|
||||||
import SimpleWebRTC from 'simplewebrtc'
|
import SimpleWebRTC from 'simplewebrtc'
|
||||||
import SocketIoConnection from 'simplewebrtc/socketioconnection'
|
import SocketIoConnection from 'simplewebrtc/socketioconnection'
|
||||||
|
|
||||||
|
import MessageCollection from '../../DataModel/MessageCollection'
|
||||||
import Util from '../../Util'
|
import Util from '../../Util'
|
||||||
import Views from '../Views'
|
import Views from '../Views'
|
||||||
|
import ChatView from '../ChatView'
|
||||||
|
import { ReactApp } from '../../GlobalUI'
|
||||||
|
import JIT from '../JIT'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
JUNTO_UPDATED,
|
JUNTO_UPDATED,
|
||||||
|
@ -25,7 +29,6 @@ import {
|
||||||
} from './events'
|
} from './events'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
juntoUpdated,
|
|
||||||
invitedToCall,
|
invitedToCall,
|
||||||
invitedToJoin,
|
invitedToJoin,
|
||||||
callAccepted,
|
callAccepted,
|
||||||
|
@ -59,49 +62,63 @@ import {
|
||||||
} from './sendable'
|
} from './sendable'
|
||||||
|
|
||||||
const Realtime = (map) => {
|
const Realtime = (map) => {
|
||||||
const toExport = {
|
const toExport = {
|
||||||
videoId: 'video-wrapper',
|
videoId: 'video-wrapper',
|
||||||
socket: null,
|
webrtc: null,
|
||||||
webrtc: null,
|
readyToCall: false,
|
||||||
readyToCall: false,
|
mappersOnMap: {},
|
||||||
mappersOnMap: {},
|
chatOpen: false,
|
||||||
disconnected: false,
|
soundId: null,
|
||||||
chatOpen: false,
|
broadcastingStatus: false,
|
||||||
soundId: null,
|
inConversation: false,
|
||||||
broadcastingStatus: false,
|
localVideo: null,
|
||||||
inConversation: false,
|
onSocketConnect: () => {},
|
||||||
localVideo: null,
|
startActiveMap: function() {
|
||||||
'junto_spinner_darkgrey.gif': '',
|
var self = toExport
|
||||||
init: function(serverData) {
|
if (map.Active.Map.authorizeToEdit(map.Active.Mapper)) {
|
||||||
var self = toExport
|
self.addJuntoListeners()
|
||||||
|
if (Realtime.socket && !Realtime.socket.disconnected) self.onSocketConnect = self._onSocketConnect
|
||||||
self.addJuntoListeners()
|
else self._onSocketConnect()
|
||||||
|
}
|
||||||
self.socket = new SocketIoConnection({
|
if (map.Active.Mapper) {
|
||||||
url: serverData['REALTIME_SERVER'],
|
self.setupChat() // chat can happen on public maps too
|
||||||
socketio: {
|
map.Cable.subscribeToMap(map.Active.Map.id) // people with viewing rights can still see live updates
|
||||||
// don't poll forever if in development
|
}
|
||||||
reconnectionAttempts: serverData.RAILS_ENV === 'development' ? 5 : Infinity
|
},
|
||||||
}
|
endActiveMap: function() {
|
||||||
})
|
var self = toExport
|
||||||
self['junto_spinner_darkgrey.gif'] = serverData['junto_spinner_darkgrey.gif']
|
$(document).off('.map')
|
||||||
|
// leave the appropriate rooms to leave
|
||||||
self.socket.on('connect', function() {
|
if (self.inConversation) self.leaveCall()
|
||||||
console.log('connected')
|
self.leaveMap()
|
||||||
if (map.Active.Map && map.Active.Mapper && map.Active.Map.authorizeToEdit(map.Active.Mapper)) {
|
$('.collabCompass').remove()
|
||||||
self.checkForCall()
|
if (self.room) self.room.leave()
|
||||||
self.joinMap()
|
if (!Realtime.socket.disconnected) self.unsubscribeFromEvents()
|
||||||
}
|
map.Cable.unsubscribeFromMap()
|
||||||
subscribeToEvents(self, self.socket)
|
},
|
||||||
self.disconnected = false
|
_onSocketConnect: function() {
|
||||||
})
|
console.log('testing')
|
||||||
self.socket.on('disconnect', function() {
|
const self = toExport
|
||||||
self.disconnected = true
|
const sendables = [
|
||||||
})
|
['joinMap', joinMap],
|
||||||
|
['leaveMap', leaveMap],
|
||||||
if (map.Active.Mapper) {
|
['checkForCall', checkForCall],
|
||||||
|
['acceptCall', acceptCall],
|
||||||
|
['denyCall', denyCall],
|
||||||
|
['denyInvite', denyInvite],
|
||||||
|
['inviteToJoin', inviteToJoin],
|
||||||
|
['inviteACall', inviteACall],
|
||||||
|
['joinCall', joinCall],
|
||||||
|
['leaveCall', leaveCall],
|
||||||
|
['sendMapperInfo', sendMapperInfo],
|
||||||
|
['sendCoords', sendCoords],
|
||||||
|
['dragTopic', dragTopic]
|
||||||
|
]
|
||||||
|
sendables.forEach(sendable => {
|
||||||
|
toExport[sendable[0]] = sendable[1](Realtime.socket, toExport, map)
|
||||||
|
})
|
||||||
self.webrtc = new SimpleWebRTC({
|
self.webrtc = new SimpleWebRTC({
|
||||||
connection: self.socket,
|
connection: Realtime.socket,
|
||||||
localVideoEl: self.videoId,
|
localVideoEl: self.videoId,
|
||||||
remoteVideosEl: '',
|
remoteVideosEl: '',
|
||||||
debug: true,
|
debug: true,
|
||||||
|
@ -127,7 +144,6 @@ const toExport = {
|
||||||
console.log('remote ice failure', peer)
|
console.log('remote ice failure', peer)
|
||||||
// remote ice failure
|
// remote ice failure
|
||||||
})
|
})
|
||||||
|
|
||||||
var $video = $('<video></video>').attr('id', self.videoId)
|
var $video = $('<video></video>').attr('id', self.videoId)
|
||||||
self.localVideo = {
|
self.localVideo = {
|
||||||
$video: $video,
|
$video: $video,
|
||||||
|
@ -136,291 +152,291 @@ const toExport = {
|
||||||
avatar: map.Active.Mapper ? map.Active.Mapper.get('image') : ''
|
avatar: map.Active.Mapper ? map.Active.Mapper.get('image') : ''
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
self.room = new Views.Room({
|
self.room = new Views.Room({
|
||||||
webrtc: self.webrtc,
|
webrtc: self.webrtc,
|
||||||
socket: self.socket,
|
room: 'map-' + map.Active.Map.id,
|
||||||
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 }
|
||||||
})
|
})
|
||||||
self.room.videoAdded(self.handleVideoAdded)
|
self.room.videoAdded(self.handleVideoAdded)
|
||||||
} // if map.Active.Mapper
|
self.subscribeToEvents()
|
||||||
},
|
self.turnOn()
|
||||||
addJuntoListeners: function() {
|
self.checkForCall()
|
||||||
var self = toExport
|
self.joinMap()
|
||||||
|
},
|
||||||
$(document).on(ChatView.events.openTray, function() {
|
addJuntoListeners: function() {
|
||||||
$('.main').addClass('compressed')
|
var self = toExport
|
||||||
self.chatOpen = true
|
$(document).on(ChatView.events.openTray, function() {
|
||||||
self.positionPeerIcons()
|
$('.main').addClass('compressed')
|
||||||
})
|
self.chatOpen = true
|
||||||
$(document).on(ChatView.events.closeTray, function() {
|
self.positionPeerIcons()
|
||||||
$('.main').removeClass('compressed')
|
|
||||||
self.chatOpen = false
|
|
||||||
self.positionPeerIcons()
|
|
||||||
})
|
|
||||||
$(document).on(ChatView.events.videosOn, function() {
|
|
||||||
$('#wrapper').removeClass('hideVideos')
|
|
||||||
})
|
|
||||||
$(document).on(ChatView.events.videosOff, function() {
|
|
||||||
$('#wrapper').addClass('hideVideos')
|
|
||||||
})
|
|
||||||
$(document).on(ChatView.events.cursorsOn, function() {
|
|
||||||
$('#wrapper').removeClass('hideCursors')
|
|
||||||
})
|
|
||||||
$(document).on(ChatView.events.cursorsOff, function() {
|
|
||||||
$('#wrapper').addClass('hideCursors')
|
|
||||||
})
|
|
||||||
},
|
|
||||||
startActiveMap: function() {
|
|
||||||
var self = toExport
|
|
||||||
if (map.Active.Map && map.Active.Mapper) {
|
|
||||||
if (map.Active.Map.authorizeToEdit(map.Active.Mapper)) {
|
|
||||||
self.turnOn()
|
|
||||||
self.checkForCall()
|
|
||||||
self.joinMap()
|
|
||||||
}
|
|
||||||
self.setupChat() // chat can happen on public maps too
|
|
||||||
map.Cable.subscribeToMap(map.Active.Map.id) // people with edit rights can still see live updates
|
|
||||||
}
|
|
||||||
},
|
|
||||||
endActiveMap: function() {
|
|
||||||
var self = toExport
|
|
||||||
$(document).off('.map')
|
|
||||||
// leave the appropriate rooms to leave
|
|
||||||
if (self.inConversation) self.leaveCall()
|
|
||||||
self.leaveMap()
|
|
||||||
$('.collabCompass').remove()
|
|
||||||
if (self.room) self.room.leave()
|
|
||||||
map.Cable.unsubscribeFromMap()
|
|
||||||
},
|
|
||||||
turnOn: function(notify) {
|
|
||||||
var self = toExport
|
|
||||||
$('.collabCompass').show()
|
|
||||||
self.room.room = 'map-' + map.Active.Map.id
|
|
||||||
self.activeMapper = {
|
|
||||||
id: map.Active.Mapper.id,
|
|
||||||
name: map.Active.Mapper.get('name'),
|
|
||||||
username: map.Active.Mapper.get('name'),
|
|
||||||
image: map.Active.Mapper.get('image'),
|
|
||||||
color: Util.getPastelColor(),
|
|
||||||
self: true
|
|
||||||
}
|
|
||||||
self.localVideo.view.$container.find('.video-cutoff').css({
|
|
||||||
border: '4px solid ' + self.activeMapper.color
|
|
||||||
})
|
|
||||||
self.setupLocalEvents()
|
|
||||||
},
|
|
||||||
setupChat: function() {
|
|
||||||
const self = toExport
|
|
||||||
map.ChatView.setNewMap()
|
|
||||||
map.ChatView.addParticipant(self.activeMapper)
|
|
||||||
map.ChatView.addMessages(new DataModel.MessageCollection(map.DataModel.Messages), true)
|
|
||||||
},
|
|
||||||
setupLocalEvents: function() {
|
|
||||||
var self = toExport
|
|
||||||
// local event listeners that trigger events
|
|
||||||
$(document).on(map.JIT.events.zoom + '.map', self.positionPeerIcons)
|
|
||||||
$(document).on(map.JIT.events.pan + '.map', self.positionPeerIcons)
|
|
||||||
$(document).on('mousemove.map', function(event) {
|
|
||||||
var pixels = {
|
|
||||||
x: event.pageX,
|
|
||||||
y: event.pageY
|
|
||||||
}
|
|
||||||
var coords = Util.pixelsToCoords(map.Visualize.mGraph, pixels)
|
|
||||||
self.sendCoords(coords)
|
|
||||||
})
|
|
||||||
$(document).on(map.JIT.events.topicDrag + '.map', function(event, positions) {
|
|
||||||
self.dragTopic(positions)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
countOthersInConversation: function() {
|
|
||||||
var self = toExport
|
|
||||||
var count = 0
|
|
||||||
for (var key in self.mappersOnMap) {
|
|
||||||
if (self.mappersOnMap[key].inConversation) count++
|
|
||||||
}
|
|
||||||
return count
|
|
||||||
},
|
|
||||||
handleVideoAdded: function(v, id) {
|
|
||||||
var self = toExport
|
|
||||||
self.positionVideos()
|
|
||||||
v.setParent($('#wrapper'))
|
|
||||||
v.$container.find('.video-cutoff').css({
|
|
||||||
border: '4px solid ' + self.mappersOnMap[id].color
|
|
||||||
})
|
|
||||||
$('#wrapper').append(v.$container)
|
|
||||||
},
|
|
||||||
positionVideos: function() {
|
|
||||||
var self = toExport
|
|
||||||
var videoIds = Object.keys(self.room.videos)
|
|
||||||
// var numOfVideos = videoIds.length
|
|
||||||
// var numOfVideosToPosition = _.filter(videoIds, function(id) {
|
|
||||||
// return !self.room.videos[id].manuallyPositioned
|
|
||||||
// }).length
|
|
||||||
|
|
||||||
var screenHeight = $(document).height()
|
|
||||||
var topExtraPadding = 20
|
|
||||||
var topPadding = 30
|
|
||||||
var leftPadding = 30
|
|
||||||
var videoHeight = 150
|
|
||||||
var videoWidth = 180
|
|
||||||
var column = 0
|
|
||||||
var row = 0
|
|
||||||
var yFormula = function() {
|
|
||||||
var y = topExtraPadding + (topPadding + videoHeight) * row + topPadding
|
|
||||||
if (y + videoHeight > screenHeight) {
|
|
||||||
row = 0
|
|
||||||
column += 1
|
|
||||||
y = yFormula()
|
|
||||||
}
|
|
||||||
row++
|
|
||||||
return y
|
|
||||||
}
|
|
||||||
var xFormula = function() {
|
|
||||||
var x = (leftPadding + videoWidth) * column + leftPadding
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
|
|
||||||
// do self first
|
|
||||||
var myVideo = toExport.localVideo.view
|
|
||||||
if (!myVideo.manuallyPositioned) {
|
|
||||||
myVideo.$container.css({
|
|
||||||
top: yFormula() + 'px',
|
|
||||||
left: xFormula() + 'px'
|
|
||||||
})
|
})
|
||||||
}
|
$(document).on(ChatView.events.closeTray, function() {
|
||||||
videoIds.forEach(function(id) {
|
$('.main').removeClass('compressed')
|
||||||
var video = self.room.videos[id]
|
self.chatOpen = false
|
||||||
if (!video.manuallyPositioned) {
|
self.positionPeerIcons()
|
||||||
video.$container.css({
|
})
|
||||||
|
$(document).on(ChatView.events.videosOn, function() {
|
||||||
|
$('#wrapper').removeClass('hideVideos')
|
||||||
|
})
|
||||||
|
$(document).on(ChatView.events.videosOff, function() {
|
||||||
|
$('#wrapper').addClass('hideVideos')
|
||||||
|
})
|
||||||
|
$(document).on(ChatView.events.cursorsOn, function() {
|
||||||
|
$('#wrapper').removeClass('hideCursors')
|
||||||
|
})
|
||||||
|
$(document).on(ChatView.events.cursorsOff, function() {
|
||||||
|
$('#wrapper').addClass('hideCursors')
|
||||||
|
})
|
||||||
|
},
|
||||||
|
turnOn: function(notify) {
|
||||||
|
var self = toExport
|
||||||
|
$('.collabCompass').show()
|
||||||
|
self.activeMapper = {
|
||||||
|
id: map.Active.Mapper.id,
|
||||||
|
name: map.Active.Mapper.get('name'),
|
||||||
|
username: map.Active.Mapper.get('name'),
|
||||||
|
image: map.Active.Mapper.get('image'),
|
||||||
|
color: Util.getPastelColor(),
|
||||||
|
self: true
|
||||||
|
}
|
||||||
|
self.localVideo.view.$container.find('.video-cutoff').css({
|
||||||
|
border: '4px solid ' + self.activeMapper.color
|
||||||
|
})
|
||||||
|
self.setupLocalEvents()
|
||||||
|
},
|
||||||
|
setupChat: function() {
|
||||||
|
const self = toExport
|
||||||
|
map.ChatView.setNewMap()
|
||||||
|
map.ChatView.addParticipant(self.activeMapper)
|
||||||
|
map.ChatView.addMessages(new MessageCollection(map.DataModel.Messages), true)
|
||||||
|
},
|
||||||
|
setupLocalEvents: function() {
|
||||||
|
var self = toExport
|
||||||
|
// local event listeners that trigger events
|
||||||
|
$(document).on(JIT.events.zoom + '.map', self.positionPeerIcons)
|
||||||
|
$(document).on(JIT.events.pan + '.map', self.positionPeerIcons)
|
||||||
|
$(document).on('mousemove.map', function(event) {
|
||||||
|
var pixels = {
|
||||||
|
x: event.pageX,
|
||||||
|
y: event.pageY
|
||||||
|
}
|
||||||
|
var coords = Util.pixelsToCoords(map.Visualize.mGraph, pixels)
|
||||||
|
self.sendCoords(coords)
|
||||||
|
})
|
||||||
|
$(document).on(JIT.events.topicDrag + '.map', function(event, positions) {
|
||||||
|
self.dragTopic(positions)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
subscribeToEvents: function() {
|
||||||
|
// todo scope these event listeners to map
|
||||||
|
const socket = Realtime.socket
|
||||||
|
socket.on(INVITED_TO_CALL, invitedToCall(toExport, map))
|
||||||
|
socket.on(INVITED_TO_JOIN, invitedToJoin(toExport, map))
|
||||||
|
socket.on(CALL_ACCEPTED, callAccepted(toExport, map))
|
||||||
|
socket.on(CALL_DENIED, callDenied(toExport, map))
|
||||||
|
socket.on(INVITE_DENIED, inviteDenied(toExport, map))
|
||||||
|
socket.on(CALL_IN_PROGRESS, callInProgress(toExport, map))
|
||||||
|
socket.on(CALL_STARTED, callStarted(toExport, map))
|
||||||
|
socket.on(MAPPER_LIST_UPDATED, mapperListUpdated(toExport, map))
|
||||||
|
socket.on(MAPPER_JOINED_CALL, mapperJoinedCall(toExport, map))
|
||||||
|
socket.on(MAPPER_LEFT_CALL, mapperLeftCall(toExport, map))
|
||||||
|
socket.on(PEER_COORDS_UPDATED, peerCoordsUpdated(toExport, map))
|
||||||
|
socket.on(NEW_MAPPER, newMapper(toExport, map))
|
||||||
|
socket.on(LOST_MAPPER, lostMapper(toExport, map))
|
||||||
|
socket.on(TOPIC_DRAGGED, topicDragged(toExport, map))
|
||||||
|
},
|
||||||
|
unsubscribeFromEvents: function() {
|
||||||
|
// todo scope these event listeners to map
|
||||||
|
const socket = Realtime.socket
|
||||||
|
socket.off(INVITED_TO_JOIN)
|
||||||
|
socket.off(CALL_ACCEPTED)
|
||||||
|
socket.off(INVITED_TO_CALL)
|
||||||
|
socket.off(CALL_DENIED)
|
||||||
|
socket.off(INVITE_DENIED)
|
||||||
|
socket.off(CALL_IN_PROGRESS)
|
||||||
|
socket.off(CALL_STARTED)
|
||||||
|
socket.off(MAPPER_LIST_UPDATED)
|
||||||
|
socket.off(MAPPER_JOINED_CALL)
|
||||||
|
socket.off(MAPPER_LEFT_CALL)
|
||||||
|
socket.off(PEER_COORDS_UPDATED)
|
||||||
|
socket.off(NEW_MAPPER)
|
||||||
|
socket.off(LOST_MAPPER)
|
||||||
|
socket.off(TOPIC_DRAGGED)
|
||||||
|
},
|
||||||
|
countOthersInConversation: function() {
|
||||||
|
var self = toExport
|
||||||
|
var count = 0
|
||||||
|
for (var key in self.mappersOnMap) {
|
||||||
|
if (self.mappersOnMap[key].inConversation) count++
|
||||||
|
}
|
||||||
|
return count
|
||||||
|
},
|
||||||
|
handleVideoAdded: function(v, id) {
|
||||||
|
var self = toExport
|
||||||
|
self.positionVideos()
|
||||||
|
v.setParent($('#wrapper'))
|
||||||
|
v.$container.find('.video-cutoff').css({
|
||||||
|
border: '4px solid ' + self.mappersOnMap[id].color
|
||||||
|
})
|
||||||
|
$('#wrapper').append(v.$container)
|
||||||
|
},
|
||||||
|
positionVideos: function() {
|
||||||
|
var self = toExport
|
||||||
|
var videoIds = Object.keys(self.room.videos)
|
||||||
|
// var numOfVideos = videoIds.length
|
||||||
|
// var numOfVideosToPosition = _.filter(videoIds, function(id) {
|
||||||
|
// return !self.room.videos[id].manuallyPositioned
|
||||||
|
// }).length
|
||||||
|
|
||||||
|
var screenHeight = $(document).height()
|
||||||
|
var topExtraPadding = 20
|
||||||
|
var topPadding = 30
|
||||||
|
var leftPadding = 30
|
||||||
|
var videoHeight = 150
|
||||||
|
var videoWidth = 180
|
||||||
|
var column = 0
|
||||||
|
var row = 0
|
||||||
|
var yFormula = function() {
|
||||||
|
var y = topExtraPadding + (topPadding + videoHeight) * row + topPadding
|
||||||
|
if (y + videoHeight > screenHeight) {
|
||||||
|
row = 0
|
||||||
|
column += 1
|
||||||
|
y = yFormula()
|
||||||
|
}
|
||||||
|
row++
|
||||||
|
return y
|
||||||
|
}
|
||||||
|
var xFormula = function() {
|
||||||
|
var x = (leftPadding + videoWidth) * column + leftPadding
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
// do self first
|
||||||
|
var myVideo = toExport.localVideo.view
|
||||||
|
if (!myVideo.manuallyPositioned) {
|
||||||
|
myVideo.$container.css({
|
||||||
top: yFormula() + 'px',
|
top: yFormula() + 'px',
|
||||||
left: xFormula() + 'px'
|
left: xFormula() + 'px'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
videoIds.forEach(function(id) {
|
||||||
},
|
var video = self.room.videos[id]
|
||||||
callEnded: function() {
|
if (!video.manuallyPositioned) {
|
||||||
var self = toExport
|
video.$container.css({
|
||||||
|
top: yFormula() + 'px',
|
||||||
map.ChatView.conversationEnded()
|
left: xFormula() + 'px'
|
||||||
self.room.leaveVideoOnly()
|
})
|
||||||
self.inConversation = false
|
}
|
||||||
self.localVideo.view.$container.hide().css({
|
|
||||||
top: '72px',
|
|
||||||
left: '30px'
|
|
||||||
})
|
|
||||||
self.localVideo.view.audioOn()
|
|
||||||
self.localVideo.view.videoOn()
|
|
||||||
},
|
|
||||||
createCompass: function(name, id, image, color) {
|
|
||||||
var str = '<img width="28" height="28" src="' + image + '" /><p>' + name + '</p>'
|
|
||||||
str += '<div id="compassArrow' + id + '" class="compassArrow"></div>'
|
|
||||||
$('#compass' + id).remove()
|
|
||||||
$('<div/>', {
|
|
||||||
id: 'compass' + id,
|
|
||||||
class: 'collabCompass'
|
|
||||||
}).html(str).appendTo('#wrapper')
|
|
||||||
$('#compass' + id + ' img').css({
|
|
||||||
'border': '2px solid ' + color
|
|
||||||
})
|
|
||||||
$('#compass' + id + ' p').css({
|
|
||||||
'background-color': color
|
|
||||||
})
|
|
||||||
},
|
|
||||||
positionPeerIcons: function() {
|
|
||||||
var self = toExport
|
|
||||||
for (var key in self.mappersOnMap) {
|
|
||||||
self.positionPeerIcon(key)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
positionPeerIcon: function(id) {
|
|
||||||
var self = toExport
|
|
||||||
var mapper = self.mappersOnMap[id]
|
|
||||||
|
|
||||||
var origPixels = Util.coordsToPixels(map.Visualize.mGraph, mapper.coords)
|
|
||||||
var pixels = self.limitPixelsToScreen(origPixels)
|
|
||||||
$('#compass' + id).css({
|
|
||||||
left: pixels.x + 'px',
|
|
||||||
top: pixels.y + 'px'
|
|
||||||
})
|
|
||||||
/* showing the arrow if the collaborator is off of the viewport screen */
|
|
||||||
if (origPixels.x !== pixels.x || origPixels.y !== pixels.y) {
|
|
||||||
var dy = origPixels.y - pixels.y // opposite
|
|
||||||
var dx = origPixels.x - pixels.x // adjacent
|
|
||||||
var angle = Math.atan2(dy, dx)
|
|
||||||
|
|
||||||
$('#compassArrow' + id).show().css({
|
|
||||||
transform: 'rotate(' + angle + 'rad)',
|
|
||||||
'-webkit-transform': 'rotate(' + angle + 'rad)'
|
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
callEnded: function() {
|
||||||
|
var self = toExport
|
||||||
|
|
||||||
if (dx > 0) {
|
map.ChatView.conversationEnded()
|
||||||
$('#compass' + id).addClass('labelLeft')
|
self.room.leaveVideoOnly()
|
||||||
|
self.inConversation = false
|
||||||
|
self.localVideo.view.$container.hide().css({
|
||||||
|
top: '72px',
|
||||||
|
left: '30px'
|
||||||
|
})
|
||||||
|
self.localVideo.view.audioOn()
|
||||||
|
self.localVideo.view.videoOn()
|
||||||
|
},
|
||||||
|
createCompass: function(name, id, image, color) {
|
||||||
|
var str = '<img width="28" height="28" src="' + image + '" /><p>' + name + '</p>'
|
||||||
|
str += '<div id="compassArrow' + id + '" class="compassArrow"></div>'
|
||||||
|
$('#compass' + id).remove()
|
||||||
|
$('<div/>', {
|
||||||
|
id: 'compass' + id,
|
||||||
|
class: 'collabCompass'
|
||||||
|
}).html(str).appendTo('#wrapper')
|
||||||
|
$('#compass' + id + ' img').css({
|
||||||
|
'border': '2px solid ' + color
|
||||||
|
})
|
||||||
|
$('#compass' + id + ' p').css({
|
||||||
|
'background-color': color
|
||||||
|
})
|
||||||
|
},
|
||||||
|
positionPeerIcons: function() {
|
||||||
|
var self = toExport
|
||||||
|
for (var key in self.mappersOnMap) {
|
||||||
|
self.positionPeerIcon(key)
|
||||||
}
|
}
|
||||||
} else {
|
},
|
||||||
$('#compassArrow' + id).hide()
|
positionPeerIcon: function(id) {
|
||||||
$('#compass' + id).removeClass('labelLeft')
|
var self = toExport
|
||||||
|
var mapper = self.mappersOnMap[id]
|
||||||
|
|
||||||
|
var origPixels = Util.coordsToPixels(map.Visualize.mGraph, mapper.coords)
|
||||||
|
var pixels = self.limitPixelsToScreen(origPixels)
|
||||||
|
$('#compass' + id).css({
|
||||||
|
left: pixels.x + 'px',
|
||||||
|
top: pixels.y + 'px'
|
||||||
|
})
|
||||||
|
/* showing the arrow if the collaborator is off of the viewport screen */
|
||||||
|
if (origPixels.x !== pixels.x || origPixels.y !== pixels.y) {
|
||||||
|
var dy = origPixels.y - pixels.y // opposite
|
||||||
|
var dx = origPixels.x - pixels.x // adjacent
|
||||||
|
var angle = Math.atan2(dy, dx)
|
||||||
|
|
||||||
|
$('#compassArrow' + id).show().css({
|
||||||
|
transform: 'rotate(' + angle + 'rad)',
|
||||||
|
'-webkit-transform': 'rotate(' + angle + 'rad)'
|
||||||
|
})
|
||||||
|
|
||||||
|
if (dx > 0) {
|
||||||
|
$('#compass' + id).addClass('labelLeft')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$('#compassArrow' + id).hide()
|
||||||
|
$('#compass' + id).removeClass('labelLeft')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
limitPixelsToScreen: function(pixels) {
|
||||||
|
var self = toExport
|
||||||
|
|
||||||
|
var boundary = self.chatOpen ? '#wrapper' : document
|
||||||
|
var xLimit, yLimit
|
||||||
|
var xMax = $(boundary).width()
|
||||||
|
var yMax = $(boundary).height()
|
||||||
|
var compassDiameter = 56
|
||||||
|
var compassArrowSize = 24
|
||||||
|
|
||||||
|
xLimit = Math.max(0 + compassArrowSize, pixels.x)
|
||||||
|
xLimit = Math.min(xLimit, xMax - compassDiameter)
|
||||||
|
yLimit = Math.max(0 + compassArrowSize, pixels.y)
|
||||||
|
yLimit = Math.min(yLimit, yMax - compassDiameter)
|
||||||
|
|
||||||
|
return {x: xLimit, y: yLimit}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
limitPixelsToScreen: function(pixels) {
|
|
||||||
var self = toExport
|
|
||||||
|
|
||||||
var boundary = self.chatOpen ? '#wrapper' : document
|
|
||||||
var xLimit, yLimit
|
|
||||||
var xMax = $(boundary).width()
|
|
||||||
var yMax = $(boundary).height()
|
|
||||||
var compassDiameter = 56
|
|
||||||
var compassArrowSize = 24
|
|
||||||
|
|
||||||
xLimit = Math.max(0 + compassArrowSize, pixels.x)
|
|
||||||
xLimit = Math.min(xLimit, xMax - compassDiameter)
|
|
||||||
yLimit = Math.max(0 + compassArrowSize, pixels.y)
|
|
||||||
yLimit = Math.min(yLimit, yMax - compassDiameter)
|
|
||||||
|
|
||||||
return {x: xLimit, y: yLimit}
|
|
||||||
}
|
}
|
||||||
|
return toExport
|
||||||
}
|
}
|
||||||
|
|
||||||
const sendables = [
|
Realtime.init = function(serverData) {
|
||||||
['joinMap', joinMap],
|
var self = Realtime
|
||||||
['leaveMap', leaveMap],
|
self.socket = new SocketIoConnection({
|
||||||
['checkForCall', checkForCall],
|
url: serverData['REALTIME_SERVER'],
|
||||||
['acceptCall', acceptCall],
|
socketio: {
|
||||||
['denyCall', denyCall],
|
// don't poll forever if in development
|
||||||
['denyInvite', denyInvite],
|
reconnectionAttempts: serverData.RAILS_ENV === 'development' ? 5 : Infinity
|
||||||
['inviteToJoin', inviteToJoin],
|
}
|
||||||
['inviteACall', inviteACall],
|
})
|
||||||
['joinCall', joinCall],
|
self['junto_spinner_darkgrey.gif'] = serverData['junto_spinner_darkgrey.gif']
|
||||||
['leaveCall', leaveCall],
|
self.socket.on('connect', function() {
|
||||||
['sendMapperInfo', sendMapperInfo],
|
console.log('connected')
|
||||||
['sendCoords', sendCoords],
|
self.socket.on(JUNTO_UPDATED, (state) => {
|
||||||
['dragTopic', dragTopic]
|
ReactApp.juntoState = state
|
||||||
]
|
ReactApp.render()
|
||||||
sendables.forEach(sendable => {
|
})
|
||||||
toExport[sendable[0]] = sendable[1](toExport, map)
|
self.disconnected = false
|
||||||
})
|
ReactApp.openMap && ReactApp.openMap.Realtime.onSocketConnect()
|
||||||
|
})
|
||||||
const subscribeToEvents = (toExport, socket) => {
|
self.socket.on('disconnect', function() {
|
||||||
socket.on(JUNTO_UPDATED, juntoUpdated(toExport, map))
|
self.disconnected = true
|
||||||
socket.on(INVITED_TO_CALL, invitedToCall(toExport, map))
|
})
|
||||||
socket.on(INVITED_TO_JOIN, invitedToJoin(toExport, map))
|
|
||||||
socket.on(CALL_ACCEPTED, callAccepted(toExport, map))
|
|
||||||
socket.on(CALL_DENIED, callDenied(toExport, map))
|
|
||||||
socket.on(INVITE_DENIED, inviteDenied(toExport, map))
|
|
||||||
socket.on(CALL_IN_PROGRESS, callInProgress(toExport, map))
|
|
||||||
socket.on(CALL_STARTED, callStarted(toExport, map))
|
|
||||||
socket.on(MAPPER_LIST_UPDATED, mapperListUpdated(toExport, map))
|
|
||||||
socket.on(MAPPER_JOINED_CALL, mapperJoinedCall(toExport, map))
|
|
||||||
socket.on(MAPPER_LEFT_CALL, mapperLeftCall(toExport, map))
|
|
||||||
socket.on(PEER_COORDS_UPDATED, peerCoordsUpdated(toExport, map))
|
|
||||||
socket.on(NEW_MAPPER, newMapper(toExport, map))
|
|
||||||
socket.on(LOST_MAPPER, lostMapper(toExport, map))
|
|
||||||
socket.on(TOPIC_DRAGGED, topicDragged(toExport, map))
|
|
||||||
}
|
|
||||||
return toExport
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,16 +4,9 @@
|
||||||
everthing in this file happens as a result of websocket events
|
everthing in this file happens as a result of websocket events
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { JUNTO_UPDATED } from './events'
|
import GlobalUI from '../../GlobalUI'
|
||||||
|
|
||||||
import GlobalUI, { ReactApp } from '../../GlobalUI'
|
|
||||||
import Util from '../../Util'
|
import Util from '../../Util'
|
||||||
|
|
||||||
export const juntoUpdated = (self, map) => state => {
|
|
||||||
ReactApp.juntoState = state
|
|
||||||
$(document).trigger(JUNTO_UPDATED)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* All the following events are received through the nodejs realtime server
|
/* All the following events are received through the nodejs realtime server
|
||||||
and are done this way because they are transient data, not persisted to the server */
|
and are done this way because they are transient data, not persisted to the server */
|
||||||
export const topicDragged = (self, map) => positions => {
|
export const topicDragged = (self, map) => positions => {
|
||||||
|
|
|
@ -18,8 +18,8 @@ import {
|
||||||
DRAG_TOPIC
|
DRAG_TOPIC
|
||||||
} from './events'
|
} from './events'
|
||||||
|
|
||||||
export const joinMap = (self, map) => () => {
|
export const joinMap = (socket, self, map) => () => {
|
||||||
self.socket.emit(JOIN_MAP, {
|
socket.emit(JOIN_MAP, {
|
||||||
userid: map.Active.Mapper.id,
|
userid: map.Active.Mapper.id,
|
||||||
username: map.Active.Mapper.get('name'),
|
username: map.Active.Mapper.get('name'),
|
||||||
avatar: map.Active.Mapper.get('image'),
|
avatar: map.Active.Mapper.get('image'),
|
||||||
|
@ -28,15 +28,15 @@ export const joinMap = (self, map) => () => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const leaveMap = (self, map) => () => {
|
export const leaveMap = (socket, self, map) => () => {
|
||||||
self.socket.emit(LEAVE_MAP)
|
socket.emit(LEAVE_MAP)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const checkForCall = (self, map) => () => {
|
export const checkForCall = (socket, self, map) => () => {
|
||||||
self.socket.emit(CHECK_FOR_CALL, { room: self.room.room, mapid: map.Active.Map.id })
|
socket.emit(CHECK_FOR_CALL, { room: self.room.room, mapid: map.Active.Map.id })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const sendMapperInfo = (self, map) => userid => {
|
export const sendMapperInfo = (socket, self, map) => userid => {
|
||||||
// send this new mapper back your details, and the awareness that you've loaded the map
|
// send this new mapper back your details, and the awareness that you've loaded the map
|
||||||
var update = {
|
var update = {
|
||||||
userToNotify: userid,
|
userToNotify: userid,
|
||||||
|
@ -46,10 +46,10 @@ export const sendMapperInfo = (self, map) => userid => {
|
||||||
userinconversation: self.inConversation,
|
userinconversation: self.inConversation,
|
||||||
mapid: map.Active.Map.id
|
mapid: map.Active.Map.id
|
||||||
}
|
}
|
||||||
self.socket.emit(SEND_MAPPER_INFO, update)
|
socket.emit(SEND_MAPPER_INFO, update)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const joinCall = (self, map) => () => {
|
export const joinCall = (socket, self, map) => () => {
|
||||||
self.webrtc.off('readyToCall')
|
self.webrtc.off('readyToCall')
|
||||||
self.webrtc.once('readyToCall', function() {
|
self.webrtc.once('readyToCall', function() {
|
||||||
self.videoInitialized = true
|
self.videoInitialized = true
|
||||||
|
@ -64,7 +64,7 @@ export const joinCall = (self, map) => () => {
|
||||||
map.ChatView.conversationInProgress(true)
|
map.ChatView.conversationInProgress(true)
|
||||||
})
|
})
|
||||||
self.inConversation = true
|
self.inConversation = true
|
||||||
self.socket.emit(JOIN_CALL, {
|
socket.emit(JOIN_CALL, {
|
||||||
mapid: map.Active.Map.id,
|
mapid: map.Active.Map.id,
|
||||||
id: map.Active.Mapper.id
|
id: map.Active.Mapper.id
|
||||||
})
|
})
|
||||||
|
@ -73,8 +73,8 @@ export const joinCall = (self, map) => () => {
|
||||||
map.ChatView.mapperJoinedCall(map.Active.Mapper.id)
|
map.ChatView.mapperJoinedCall(map.Active.Mapper.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const leaveCall = (self, map) => () => {
|
export const leaveCall = (socket, self, map) => () => {
|
||||||
self.socket.emit(LEAVE_CALL, {
|
socket.emit(LEAVE_CALL, {
|
||||||
mapid: map.Active.Map.id,
|
mapid: map.Active.Map.id,
|
||||||
id: map.Active.Mapper.id
|
id: map.Active.Mapper.id
|
||||||
})
|
})
|
||||||
|
@ -92,9 +92,9 @@ export const leaveCall = (self, map) => () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const acceptCall = (self, map) => userid => {
|
export const acceptCall = (socket, self, map) => userid => {
|
||||||
map.ChatView.sound.stop(self.soundId)
|
map.ChatView.sound.stop(self.soundId)
|
||||||
self.socket.emit(ACCEPT_CALL, {
|
socket.emit(ACCEPT_CALL, {
|
||||||
mapid: map.Active.Map.id,
|
mapid: map.Active.Map.id,
|
||||||
invited: map.Active.Mapper.id,
|
invited: map.Active.Mapper.id,
|
||||||
inviter: userid
|
inviter: userid
|
||||||
|
@ -104,9 +104,9 @@ export const acceptCall = (self, map) => userid => {
|
||||||
GlobalUI.clearNotify()
|
GlobalUI.clearNotify()
|
||||||
}
|
}
|
||||||
|
|
||||||
export const denyCall = (self, map) => userid => {
|
export const denyCall = (socket, self, map) => userid => {
|
||||||
map.ChatView.sound.stop(self.soundId)
|
map.ChatView.sound.stop(self.soundId)
|
||||||
self.socket.emit(DENY_CALL, {
|
socket.emit(DENY_CALL, {
|
||||||
mapid: map.Active.Map.id,
|
mapid: map.Active.Map.id,
|
||||||
invited: map.Active.Mapper.id,
|
invited: map.Active.Mapper.id,
|
||||||
inviter: userid
|
inviter: userid
|
||||||
|
@ -114,9 +114,9 @@ export const denyCall = (self, map) => userid => {
|
||||||
GlobalUI.clearNotify()
|
GlobalUI.clearNotify()
|
||||||
}
|
}
|
||||||
|
|
||||||
export const denyInvite = (self, map) => userid => {
|
export const denyInvite = (socket, self, map) => userid => {
|
||||||
map.ChatView.sound.stop(self.soundId)
|
map.ChatView.sound.stop(self.soundId)
|
||||||
self.socket.emit(DENY_INVITE, {
|
socket.emit(DENY_INVITE, {
|
||||||
mapid: map.Active.Map.id,
|
mapid: map.Active.Map.id,
|
||||||
invited: map.Active.Mapper.id,
|
invited: map.Active.Mapper.id,
|
||||||
inviter: userid
|
inviter: userid
|
||||||
|
@ -124,8 +124,8 @@ export const denyInvite = (self, map) => userid => {
|
||||||
GlobalUI.clearNotify()
|
GlobalUI.clearNotify()
|
||||||
}
|
}
|
||||||
|
|
||||||
export const inviteACall = (self, map) => userid => {
|
export const inviteACall = (socket, self, map) => userid => {
|
||||||
self.socket.emit(INVITE_A_CALL, {
|
socket.emit(INVITE_A_CALL, {
|
||||||
mapid: map.Active.Map.id,
|
mapid: map.Active.Map.id,
|
||||||
inviter: map.Active.Mapper.id,
|
inviter: map.Active.Mapper.id,
|
||||||
invited: userid
|
invited: userid
|
||||||
|
@ -134,8 +134,8 @@ export const inviteACall = (self, map) => userid => {
|
||||||
GlobalUI.clearNotify()
|
GlobalUI.clearNotify()
|
||||||
}
|
}
|
||||||
|
|
||||||
export const inviteToJoin = (self, map) => userid => {
|
export const inviteToJoin = (socket, self, map) => userid => {
|
||||||
self.socket.emit(INVITE_TO_JOIN, {
|
socket.emit(INVITE_TO_JOIN, {
|
||||||
mapid: map.Active.Map.id,
|
mapid: map.Active.Map.id,
|
||||||
inviter: map.Active.Mapper.id,
|
inviter: map.Active.Mapper.id,
|
||||||
invited: userid
|
invited: userid
|
||||||
|
@ -143,22 +143,22 @@ export const inviteToJoin = (self, map) => userid => {
|
||||||
map.ChatView.invitationPending(userid)
|
map.ChatView.invitationPending(userid)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const sendCoords = (self, map) => coords => {
|
export const sendCoords = (socket, self, map) => coords => {
|
||||||
var map = map.Active.Map
|
var m = map.Active.Map
|
||||||
var mapper = map.Active.Mapper
|
var mapper = map.Active.Mapper
|
||||||
if (map && map.authorizeToEdit(mapper)) {
|
if (m && m.authorizeToEdit(mapper)) {
|
||||||
var update = {
|
var update = {
|
||||||
usercoords: coords,
|
usercoords: coords,
|
||||||
userid: map.Active.Mapper.id,
|
userid: map.Active.Mapper.id,
|
||||||
mapid: map.Active.Map.id
|
mapid: m.id
|
||||||
}
|
}
|
||||||
self.socket.emit(SEND_COORDS, update)
|
socket.emit(SEND_COORDS, update)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const dragTopic = (self, map) => positions => {
|
export const dragTopic = (socket, self, map) => positions => {
|
||||||
if (map.Active.Map) {
|
if (map.Active.Map) {
|
||||||
positions.mapid = map.Active.Map.id
|
positions.mapid = map.Active.Map.id
|
||||||
self.socket.emit(DRAG_TOPIC, positions)
|
socket.emit(DRAG_TOPIC, positions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import VideoView from './VideoView'
|
||||||
|
|
||||||
const Room = function(opts = {}) {
|
const Room = function(opts = {}) {
|
||||||
this.isActiveRoom = false
|
this.isActiveRoom = false
|
||||||
this.socket = opts.socket
|
|
||||||
this.webrtc = opts.webrtc
|
this.webrtc = opts.webrtc
|
||||||
this.room = opts.room
|
this.room = opts.room
|
||||||
this.config = opts.config
|
this.config = opts.config
|
||||||
|
|
|
@ -2,13 +2,8 @@
|
||||||
|
|
||||||
import VideoView from './VideoView'
|
import VideoView from './VideoView'
|
||||||
import Room from './Room'
|
import Room from './Room'
|
||||||
import { JUNTO_UPDATED } from '../Realtime/events'
|
|
||||||
|
|
||||||
const Views = {
|
const Views = {
|
||||||
init: (serverData) => {
|
|
||||||
$(document).on(JUNTO_UPDATED, () => ExploreMaps.render())
|
|
||||||
//map.ChatView.init([serverData['sounds/MM_sounds.mp3'], serverData['sounds/MM_sounds.ogg']])
|
|
||||||
},
|
|
||||||
VideoView,
|
VideoView,
|
||||||
Room
|
Room
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,8 +91,8 @@ const mapControl = {
|
||||||
newMap.Active.Mapper = ReactApp.currentUser
|
newMap.Active.Mapper = ReactApp.currentUser
|
||||||
newMap.DataModel.Mappers = new MapperCollection(data.mappers)
|
newMap.DataModel.Mappers = new MapperCollection(data.mappers)
|
||||||
newMap.DataModel.Collaborators = new MapperCollection(data.collaborators)
|
newMap.DataModel.Collaborators = new MapperCollection(data.collaborators)
|
||||||
newMap.DataModel.Topics = new TopicCollection(data.topics)
|
//newMap.DataModel.Topics = new TopicCollection(data.topics)
|
||||||
newMap.DataModel.Synapses = new SynapseCollection(data.synapses)
|
//newMap.DataModel.Synapses = new SynapseCollection(data.synapses)
|
||||||
newMap.DataModel.Mappings = new MappingCollection(data.mappings)
|
newMap.DataModel.Mappings = new MappingCollection(data.mappings)
|
||||||
newMap.DataModel.Messages = data.messages
|
newMap.DataModel.Messages = data.messages
|
||||||
newMap.DataModel.Stars = data.stars
|
newMap.DataModel.Stars = data.stars
|
||||||
|
@ -127,15 +127,15 @@ const mapControl = {
|
||||||
end: function(map) {
|
end: function(map) {
|
||||||
$('.main').removeClass('compressed')
|
$('.main').removeClass('compressed')
|
||||||
$('.rightclickmenu').remove()
|
$('.rightclickmenu').remove()
|
||||||
map.AutoLayout.resetSpiral()
|
//map.AutoLayout.resetSpiral()
|
||||||
map.TopicCard.hideCard()
|
//map.TopicCard.hideCard()
|
||||||
map.map.SynapseCard.hideCard()
|
map.SynapseCard.hideCard()
|
||||||
map.Create.newTopic.hide(true) // true means force (and override pinned)
|
map.Create.newTopic.hide(true) // true means force (and override pinned)
|
||||||
map.Create.newSynapse.hide()
|
map.Create.newSynapse.hide()
|
||||||
map.InfoBox.close()
|
map.InfoBox.close()
|
||||||
|
//map.Map.requests = []
|
||||||
|
//map.Map.hasLearnedTopicCreation = true
|
||||||
map.Realtime.endActiveMap()
|
map.Realtime.endActiveMap()
|
||||||
map.Map.requests = []
|
|
||||||
map.Map.hasLearnedTopicCreation = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export { mapControl }
|
export { mapControl }
|
||||||
|
@ -442,6 +442,9 @@ const Map = (map) => {
|
||||||
Map.events = {
|
Map.events = {
|
||||||
editedByActiveMapper: 'Metamaps:Map:events:editedByActiveMapper'
|
editedByActiveMapper: 'Metamaps:Map:events:editedByActiveMapper'
|
||||||
}
|
}
|
||||||
|
Map.init = (serverData) => {
|
||||||
|
ChatView.init([serverData['sounds/MM_sounds.mp3'], serverData['sounds/MM_sounds.ogg']])
|
||||||
|
}
|
||||||
|
|
||||||
export { CheatSheet }
|
export { CheatSheet }
|
||||||
export default Map
|
export default Map
|
||||||
|
|
|
@ -58,7 +58,6 @@ Metamaps.Synapse = Synapse
|
||||||
Metamaps.SynapseCard = SynapseCard
|
Metamaps.SynapseCard = SynapseCard
|
||||||
Metamaps.Topic = Topic
|
Metamaps.Topic = Topic
|
||||||
Metamaps.Util = Util
|
Metamaps.Util = Util
|
||||||
Metamaps.Views = Views
|
|
||||||
Metamaps.Visualize = Visualize
|
Metamaps.Visualize = Visualize
|
||||||
|
|
||||||
Metamaps.GlobalUI = GlobalUI
|
Metamaps.GlobalUI = GlobalUI
|
||||||
|
@ -76,7 +75,6 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
Metamaps[prop].hasOwnProperty('init') &&
|
Metamaps[prop].hasOwnProperty('init') &&
|
||||||
typeof (Metamaps[prop].init) === 'function'
|
typeof (Metamaps[prop].init) === 'function'
|
||||||
) {
|
) {
|
||||||
console.log(prop)
|
|
||||||
Metamaps[prop].init(Metamaps.ServerData)
|
Metamaps[prop].init(Metamaps.ServerData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ class MapChat extends Component {
|
||||||
|
|
||||||
scroll = () => {
|
scroll = () => {
|
||||||
// hack: figure out how to do this right
|
// hack: figure out how to do this right
|
||||||
this.messagesDiv.scrollTop = this.messagesDiv.scrollHeight + 100
|
if (this.messagesDiv) this.messagesDiv.scrollTop = this.messagesDiv.scrollHeight + 100
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleDrawer = () => {
|
toggleDrawer = () => {
|
||||||
|
|
|
@ -7,7 +7,7 @@ const {
|
||||||
LEAVE_CALL,
|
LEAVE_CALL,
|
||||||
JOIN_MAP,
|
JOIN_MAP,
|
||||||
LEAVE_MAP
|
LEAVE_MAP
|
||||||
} = require('../frontend/src/Metamaps/Realtime/events')
|
} = require('../frontend/src/Metamaps/Map/Realtime/events')
|
||||||
|
|
||||||
module.exports = function(io, store) {
|
module.exports = function(io, store) {
|
||||||
store.subscribe(() => {
|
store.subscribe(() => {
|
||||||
|
|
|
@ -17,7 +17,7 @@ const {
|
||||||
INVITE_A_CALL,
|
INVITE_A_CALL,
|
||||||
JOIN_CALL,
|
JOIN_CALL,
|
||||||
LEAVE_CALL
|
LEAVE_CALL
|
||||||
} = require('../frontend/src/Metamaps/Realtime/events')
|
} = require('../frontend/src/Metamaps/Map/Realtime/events')
|
||||||
|
|
||||||
const { mapRoom, userMapRoom } = require('./rooms')
|
const { mapRoom, userMapRoom } = require('./rooms')
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ const {
|
||||||
SEND_COORDS,
|
SEND_COORDS,
|
||||||
SEND_MAPPER_INFO,
|
SEND_MAPPER_INFO,
|
||||||
DRAG_TOPIC
|
DRAG_TOPIC
|
||||||
} = require('../frontend/src/Metamaps/Realtime/events')
|
} = require('../frontend/src/Metamaps/Map/Realtime/events')
|
||||||
|
|
||||||
const { mapRoom, userMapRoom } = require('./rooms')
|
const { mapRoom, userMapRoom } = require('./rooms')
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ const {
|
||||||
LEAVE_MAP,
|
LEAVE_MAP,
|
||||||
JOIN_CALL,
|
JOIN_CALL,
|
||||||
LEAVE_CALL
|
LEAVE_CALL
|
||||||
} = require('../frontend/src/Metamaps/Realtime/events')
|
} = require('../frontend/src/Metamaps/Map/Realtime/events')
|
||||||
|
|
||||||
const NOT_IN_CONVERSATION = 0
|
const NOT_IN_CONVERSATION = 0
|
||||||
const IN_CONVERSATION = 1
|
const IN_CONVERSATION = 1
|
||||||
|
|
Loading…
Add table
Reference in a new issue