trying to scope all the modules per map or topic

This commit is contained in:
Connor Turland 2017-03-22 19:20:10 -04:00
parent 663706b1f7
commit f07b97d573
29 changed files with 1366 additions and 1311 deletions

View file

@ -22,11 +22,16 @@
<div class="clearfloat"></div> <div class="clearfloat"></div>
<script> <script>
Metamaps.ServerData = Metamaps.ServerData || {}
Metamaps.ServerData.selectedMetacodes = []
Metamaps.ServerData.newSelectedMetacodes = []
Metamaps.ServerData.selectedMetacodeNames = []
Metamaps.ServerData.newSelectedMetacodeNames = []
<% @metacodes.each do |metacode| %> <% @metacodes.each do |metacode| %>
Metamaps.Create.selectedMetacodes.push("<%= metacode.id %>"); Metamaps.ServerData.selectedMetacodes.push("<%= metacode.id %>");
Metamaps.Create.newSelectedMetacodes.push("<%= metacode.id %>"); Metamaps.ServerData.newSelectedMetacodes.push("<%= metacode.id %>");
Metamaps.Create.selectedMetacodeNames.push("<%= metacode.name %>"); Metamaps.ServerData.selectedMetacodeNames.push("<%= metacode.name %>");
Metamaps.Create.newSelectedMetacodeNames.push("<%= metacode.name %>"); Metamaps.ServerData.newSelectedMetacodeNames.push("<%= metacode.name %>");
<% end %> <% end %>
</script> </script>
<% end %> <% end %>

View file

@ -116,6 +116,7 @@
<div class="clearfloat"></div> <div class="clearfloat"></div>
<script> <script>
Metamaps.Create.selectedMetacodeSet = "metacodeset-<%= selectedSet %>" Metamaps.ServerData = Metamaps.ServerData || {}
Metamaps.Create.selectedMetacodeSetIndex = <%= index %> Metamaps.ServerData.selectedMetacodeSet = "metacodeset-<%= selectedSet %>"
Metamaps.ServerData.selectedMetacodeSetIndex = <%= index %>
</script> </script>

View file

@ -1,7 +1,9 @@
const Active = { const Active = (map = null, mapper = null, topic = null) => {
Map: null, return {
Mapper: null, Map: map,
Topic: null Mapper: mapper,
Topic: topic
}
} }
export default Active export default Active

View file

@ -1,4 +1,5 @@
const AutoLayout = { const AutoLayout = () => {
return {
nextX: 0, nextX: 0,
nextY: 0, nextY: 0,
sideLength: 1, sideLength: 1,
@ -74,5 +75,6 @@ const AutoLayout = {
self.turnCount = 0 self.turnCount = 0
} }
} }
}
export default AutoLayout export default AutoLayout

View file

@ -2,24 +2,13 @@
import { indexOf } from 'lodash' import { indexOf } from 'lodash'
import Active from './Active'
import Control from './Control'
import DataModel from './DataModel'
import Map from './Map'
import Mapper from './Mapper' import Mapper from './Mapper'
import Synapse from './Synapse'
import Topic from './Topic'
import { ChatView } from './Views'
import Visualize from './Visualize'
const Cable = { const Cable = ({Active, Control, DataModel, Map, Synapse, Topic, ChatView, Visualize}) => {
init: () => { const toExport = {
let self = Cable
self.cable = ActionCable.createConsumer()
},
subscribeToMap: id => { subscribeToMap: id => {
let self = Cable let self = toExport
self.sub = self.cable.subscriptions.create({ self.sub = Cable.cable.subscriptions.create({
channel: 'MapChannel', channel: 'MapChannel',
id: id id: id
}, { }, {
@ -27,7 +16,7 @@ const Cable = {
}) })
}, },
unsubscribeFromMap: () => { unsubscribeFromMap: () => {
let self = Cable let self = toExport
self.sub.unsubscribe() self.sub.unsubscribe()
delete self.sub delete self.sub
}, },
@ -230,5 +219,10 @@ const Cable = {
}) })
} }
} }
return toExport
}
Cable.init = () => {
Cable.cable = ActionCable.createConsumer()
}
export default Cable export default Cable

View file

@ -1,16 +1,11 @@
import _ from 'lodash' import _ from 'lodash'
import outdent from 'outdent' import outdent from 'outdent'
import Active from './Active'
import DataModel from './DataModel'
import Filter from './Filter'
import GlobalUI from './GlobalUI' import GlobalUI from './GlobalUI'
import Mouse from './Mouse'
import Selected from './Selected'
import Settings from './Settings' import Settings from './Settings'
import Visualize from './Visualize'
const Control = { const Control = ({Active, DataModel, Filter, Mouse, Selected, Visualize}) => {
return {
selectNode: function(node, e) { selectNode: function(node, e) {
var filtered = node.getData('alpha') === 0 var filtered = node.getData('alpha') === 0
@ -449,5 +444,6 @@ const Control = {
Visualize.mGraph.plot() Visualize.mGraph.plot()
} }
} }
}
export default Control export default Control

View file

@ -1,15 +1,9 @@
/* global $, Hogan, Bloodhound */ /* global $, Hogan, Bloodhound */
import DataModel from './DataModel'
import Map from './Map'
import Mouse from './Mouse'
import Selected from './Selected'
import Synapse from './Synapse'
import Topic from './Topic'
import Visualize from './Visualize'
import GlobalUI from './GlobalUI' import GlobalUI from './GlobalUI'
const Create = { const toExport = ({DataModel, Map, Mouse, Selected, Synapse, Topic, Visualize}) => {
const toExport = {
isSwitchingSet: false, // indicates whether the metacode set switch lightbox is open isSwitchingSet: false, // indicates whether the metacode set switch lightbox is open
selectedMetacodeSet: null, selectedMetacodeSet: null,
selectedMetacodeSetIndex: null, selectedMetacodeSetIndex: null,
@ -17,52 +11,54 @@ const Create = {
newSelectedMetacodeNames: [], newSelectedMetacodeNames: [],
selectedMetacodes: [], selectedMetacodes: [],
newSelectedMetacodes: [], newSelectedMetacodes: [],
init: function() { init: function(serverData) {
var self = Create toExport.newTopic.init()
self.newTopic.init() toExport.newSynapse.init()
self.newSynapse.init() toExport.selectedMetacodeSet = serverData.selectedMetacodeSet
toExport.selectedMetacodeSetIndex = serverData.selectedMetacodeSetIndex
toExport.selectedMetacodes = serverData.selectedMetacodes
toExport.newSelectedMetacodes = serverData.newSelectedMetacodes
toExport.selectedMetacodeNames = serverData.newSelectedMetacodeNames
toExport.newSelectedMetacodeNames = serverData.newSelectedMetacodeNames
// // SWITCHING METACODE SETS // // SWITCHING METACODE SETS
$('#metacodeSwitchTabs').tabs({ $('#metacodeSwitchTabs').tabs({
active: self.selectedMetacodeSetIndex active: toExport.selectedMetacodeSetIndex
}).addClass('ui-tabs-vertical ui-helper-clearfix') }).addClass('ui-tabs-vertical ui-helper-clearfix')
$('#metacodeSwitchTabs .ui-tabs-nav li').removeClass('ui-corner-top').addClass('ui-corner-left') $('#metacodeSwitchTabs .ui-tabs-nav li').removeClass('ui-corner-top').addClass('ui-corner-left')
$('.customMetacodeList li').click(self.toggleMetacodeSelected) // within the custom metacode set tab $('.customMetacodeList li').click(toExport.toggleMetacodeSelected) // within the custom metacode set tab
$('.selectAll').click(self.metacodeSelectorSelectAll) $('.selectAll').click(toExport.metacodeSelectorSelectAll)
$('.selectNone').click(self.metacodeSelectorSelectNone) $('.selectNone').click(toExport.metacodeSelectorSelectNone)
}, },
toggleMetacodeSelected: function() { toggleMetacodeSelected: function() {
var self = Create
if ($(this).attr('class') !== 'toggledOff') { if ($(this).attr('class') !== 'toggledOff') {
$(this).addClass('toggledOff') $(this).addClass('toggledOff')
var valueToRemove = $(this).attr('id') var valueToRemove = $(this).attr('id')
var nameToRemove = $(this).attr('data-name') var nameToRemove = $(this).attr('data-name')
self.newSelectedMetacodes.splice(self.newSelectedMetacodes.indexOf(valueToRemove), 1) toExport.newSelectedMetacodes.splice(self.newSelectedMetacodes.indexOf(valueToRemove), 1)
self.newSelectedMetacodeNames.splice(self.newSelectedMetacodeNames.indexOf(nameToRemove), 1) toExport.newSelectedMetacodeNames.splice(self.newSelectedMetacodeNames.indexOf(nameToRemove), 1)
} else if ($(this).attr('class') === 'toggledOff') { } else if ($(this).attr('class') === 'toggledOff') {
$(this).removeClass('toggledOff') $(this).removeClass('toggledOff')
self.newSelectedMetacodes.push($(this).attr('id')) toExport.newSelectedMetacodes.push($(this).attr('id'))
self.newSelectedMetacodeNames.push($(this).attr('data-name')) toExport.newSelectedMetacodeNames.push($(this).attr('data-name'))
} }
self.updateSelectAllColors() toExport.updateSelectAllColors()
}, },
updateSelectAllColors: function() { updateSelectAllColors: function() {
$('.selectAll, .selectNone').removeClass('selected') $('.selectAll, .selectNone').removeClass('selected')
if (Create.metacodeSelectorAreAllSelected()) { if (toExport.metacodeSelectorAreAllSelected()) {
$('.selectAll').addClass('selected') $('.selectAll').addClass('selected')
} else if (Create.metacodeSelectorAreNoneSelected()) { } else if (toExport.metacodeSelectorAreNoneSelected()) {
$('.selectNone').addClass('selected') $('.selectNone').addClass('selected')
} }
}, },
metacodeSelectorSelectAll: function() { metacodeSelectorSelectAll: function() {
$('.customMetacodeList li.toggledOff').each(Create.toggleMetacodeSelected) $('.customMetacodeList li.toggledOff').each(toExport.toggleMetacodeSelected)
Create.updateSelectAllColors() toExport.updateSelectAllColors()
}, },
metacodeSelectorSelectNone: function() { metacodeSelectorSelectNone: function() {
$('.customMetacodeList li').not('.toggledOff').each(Create.toggleMetacodeSelected) $('.customMetacodeList li').not('.toggledOff').each(toExport.toggleMetacodeSelected)
Create.updateSelectAllColors() toExport.updateSelectAllColors()
}, },
metacodeSelectorAreAllSelected: function() { metacodeSelectorAreAllSelected: function() {
return $('.customMetacodeList li').toArray() return $('.customMetacodeList li').toArray()
@ -75,41 +71,41 @@ const Create = {
.reduce((curr, prev) => curr && prev) .reduce((curr, prev) => curr && prev)
}, },
metacodeSelectorToggleSelectAll: function() { metacodeSelectorToggleSelectAll: function() {
// should be called when Create.isSwitchingSet is true and .customMetacodeList is visible // should be called when toExport.isSwitchingSet is true and .customMetacodeList is visible
if (!Create.isSwitchingSet) return if (!toExport.isSwitchingSet) return
if (!$('.customMetacodeList').is(':visible')) return if (!$('.customMetacodeList').is(':visible')) return
// If all are selected, then select none. Otherwise, select all. // If all are selected, then select none. Otherwise, select all.
if (Create.metacodeSelectorAreAllSelected()) { if (toExport.metacodeSelectorAreAllSelected()) {
Create.metacodeSelectorSelectNone() toExport.metacodeSelectorSelectNone()
} else { } else {
// if some, but not all, are selected, it still runs this function // if some, but not all, are selected, it still runs this function
Create.metacodeSelectorSelectAll() toExport.metacodeSelectorSelectAll()
} }
}, },
updateMetacodeSet: function(set, index, custom) { updateMetacodeSet: function(set, index, custom) {
if (custom && Create.newSelectedMetacodes.length === 0) { if (custom && toExport.newSelectedMetacodes.length === 0) {
window.alert('Please select at least one metacode to use!') window.alert('Please select at least one metacode to use!')
return false return false
} }
var codesToSwitchToIds var codesToSwitchToIds
var metacodeModels = new DataModel.MetacodeCollection() var metacodeModels = new DataModel.MetacodeCollection()
Create.selectedMetacodeSetIndex = index toExport.selectedMetacodeSetIndex = index
Create.selectedMetacodeSet = 'metacodeset-' + set toExport.selectedMetacodeSet = 'metacodeset-' + set
if (!custom) { if (!custom) {
codesToSwitchToIds = $('#metacodeSwitchTabs' + set).attr('data-metacodes').split(',') codesToSwitchToIds = $('#metacodeSwitchTabs' + set).attr('data-metacodes').split(',')
$('.customMetacodeList li').addClass('toggledOff') $('.customMetacodeList li').addClass('toggledOff')
Create.selectedMetacodes = [] toExport.selectedMetacodes = []
Create.selectedMetacodeNames = [] toExport.selectedMetacodeNames = []
Create.newSelectedMetacodes = [] toExport.newSelectedMetacodes = []
Create.newSelectedMetacodeNames = [] toExport.newSelectedMetacodeNames = []
} else if (custom) { } else if (custom) {
// uses .slice to avoid setting the two arrays to the same actual array // uses .slice to avoid setting the two arrays to the same actual array
Create.selectedMetacodes = Create.newSelectedMetacodes.slice(0) toExport.selectedMetacodes = Create.newSelectedMetacodes.slice(0)
Create.selectedMetacodeNames = Create.newSelectedMetacodeNames.slice(0) toExport.selectedMetacodeNames = Create.newSelectedMetacodeNames.slice(0)
codesToSwitchToIds = Create.selectedMetacodes.slice(0) codesToSwitchToIds = toExport.selectedMetacodes.slice(0)
} }
// sort by name // sort by name
@ -141,7 +137,7 @@ const Create = {
var mdata = { var mdata = {
'metacodes': { 'metacodes': {
'value': custom ? Create.selectedMetacodes.toString() : Create.selectedMetacodeSet 'value': custom ? toExport.selectedMetacodes.toString() : Create.selectedMetacodeSet
} }
} }
$.ajax({ $.ajax({
@ -158,26 +154,25 @@ const Create = {
}) })
}, },
cancelMetacodeSetSwitch: function() { cancelMetacodeSetSwitch: function() {
var self = Create toExport.isSwitchingSet = false
self.isSwitchingSet = false
if (self.selectedMetacodeSet !== 'metacodeset-custom') { if (toExport.selectedMetacodeSet !== 'metacodeset-custom') {
$('.customMetacodeList li').addClass('toggledOff') $('.customMetacodeList li').addClass('toggledOff')
self.selectedMetacodes = [] toExport.selectedMetacodes = []
self.selectedMetacodeNames = [] toExport.selectedMetacodeNames = []
self.newSelectedMetacodes = [] toExport.newSelectedMetacodes = []
self.newSelectedMetacodeNames = [] toExport.newSelectedMetacodeNames = []
} else { // custom set is selected } else { // custom set is selected
// reset it to the current actual selection // reset it to the current actual selection
$('.customMetacodeList li').addClass('toggledOff') $('.customMetacodeList li').addClass('toggledOff')
for (var i = 0; i < self.selectedMetacodes.length; i++) { for (var i = 0; i < toExport.selectedMetacodes.length; i++) {
$('#' + self.selectedMetacodes[i]).removeClass('toggledOff') $('#' + toExport.selectedMetacodes[i]).removeClass('toggledOff')
} }
// uses .slice to avoid setting the two arrays to the same actual array // uses .slice to avoid setting the two arrays to the same actual array
self.newSelectedMetacodeNames = self.selectedMetacodeNames.slice(0) toExport.newSelectedMetacodeNames = self.selectedMetacodeNames.slice(0)
self.newSelectedMetacodes = self.selectedMetacodes.slice(0) toExport.newSelectedMetacodes = self.selectedMetacodes.slice(0)
} }
$('#metacodeSwitchTabs').tabs('option', 'active', self.selectedMetacodeSetIndex) $('#metacodeSwitchTabs').tabs('option', 'active', toExport.selectedMetacodeSetIndex)
$('#topic_name').focus() $('#topic_name').focus()
}, },
newTopic: { newTopic: {
@ -186,19 +181,19 @@ const Create = {
const ESC = 27 const ESC = 27
if (e.keyCode === ESC) { if (e.keyCode === ESC) {
Create.newTopic.hide() toExport.newTopic.hide()
} // if } // if
Create.newTopic.name = $(this).val() toExport.newTopic.name = $(this).val()
}) })
$('.pinCarousel').click(function() { $('.pinCarousel').click(function() {
if (Create.newTopic.pinned) { if (toExport.newTopic.pinned) {
$('.pinCarousel').removeClass('isPinned') $('.pinCarousel').removeClass('isPinned')
Create.newTopic.pinned = false toExport.newTopic.pinned = false
} else { } else {
$('.pinCarousel').addClass('isPinned') $('.pinCarousel').addClass('isPinned')
Create.newTopic.pinned = true toExport.newTopic.pinned = true
} }
}) })
@ -232,7 +227,7 @@ const Create = {
// tell the autocomplete to submit the form with the topic you clicked on if you pick from the autocomplete // tell the autocomplete to submit the form with the topic you clicked on if you pick from the autocomplete
$('#topic_name').bind('typeahead:select', function(event, datum, dataset) { $('#topic_name').bind('typeahead:select', function(event, datum, dataset) {
Create.newTopic.beingCreated = false toExport.newTopic.beingCreated = false
if (datum.rtype === 'topic') { if (datum.rtype === 'topic') {
Topic.getTopicFromAutocomplete(datum.id) Topic.getTopicFromAutocomplete(datum.id)
} else if (datum.rtype === 'map') { } else if (datum.rtype === 'map') {
@ -259,7 +254,7 @@ const Create = {
}, },
name: null, name: null,
newId: 1, newId: 1,
beingCreated: false, beingtoExportd: false,
metacode: null, metacode: null,
x: null, x: null,
y: null, y: null,
@ -269,22 +264,22 @@ const Create = {
$('#new_topic').fadeIn('fast', function() { $('#new_topic').fadeIn('fast', function() {
$('#topic_name').focus() $('#topic_name').focus()
}) })
Create.newTopic.beingCreated = true toExport.newTopic.beingCreated = true
Create.newTopic.name = '' toExport.newTopic.name = ''
Map.setHasLearnedTopicCreation(true) //Map.setHasLearnedTopicCreation(true)
}, },
hide: function(force) { hide: function(force) {
if (force || !Create.newTopic.pinned) { if (force || !toExport.newTopic.pinned) {
$('#new_topic').fadeOut('fast') $('#new_topic').fadeOut('fast')
} }
if (force) { if (force) {
$('.pinCarousel').removeClass('isPinned') $('.pinCarousel').removeClass('isPinned')
Create.newTopic.pinned = false toExport.newTopic.pinned = false
} }
if (DataModel.Topics.length === 0) { if (DataModel.Topics.length === 0) {
Map.setHasLearnedTopicCreation(false) Map.setHasLearnedTopicCreation(false)
} }
Create.newTopic.beingCreated = false toExport.newTopic.beingCreated = false
}, },
reset: function() { reset: function() {
$('#topic_name').typeahead('val', '') $('#topic_name').typeahead('val', '')
@ -306,9 +301,8 @@ const Create = {
remote: { remote: {
url: '/search/synapses?topic1id=%TOPIC1&topic2id=%TOPIC2', url: '/search/synapses?topic1id=%TOPIC1&topic2id=%TOPIC2',
prepare: function(query, settings) { prepare: function(query, settings) {
var self = Create.newSynapse if (Selected.Nodes.length < 2 && toExport.newSynapse.topic1id && self.newSynapse.topic2id) {
if (Selected.Nodes.length < 2 && self.topic1id && self.topic2id) { settings.url = settings.url.replace('%TOPIC1', toExport.newSynapse.topic1id).replace('%TOPIC2', toExport.newSynapse.topic2id)
settings.url = settings.url.replace('%TOPIC1', self.topic1id).replace('%TOPIC2', self.topic2id)
return settings return settings
} else { } else {
return null return null
@ -351,21 +345,21 @@ const Create = {
const ESC = 27 const ESC = 27
if (e.keyCode === ESC) { if (e.keyCode === ESC) {
Create.newSynapse.hide() toExport.newSynapse.hide()
} // if } // if
Create.newSynapse.description = $(this).val() toExport.newSynapse.description = $(this).val()
}) })
$('#synapse_desc').focusout(function() { $('#synapse_desc').focusout(function() {
if (Create.newSynapse.beingCreated) { if (toExport.newSynapse.beingCreated) {
Synapse.createSynapseLocally() Synapse.createSynapseLocally()
} }
}) })
$('#synapse_desc').keydown(function(e) { $('#synapse_desc').keydown(function(e) {
const TAB = 9 const TAB = 9
if (Create.newSynapse.beingCreated && e.keyCode === TAB) { if (toExport.newSynapse.beingCreated && e.keyCode === TAB) {
e.preventDefault() e.preventDefault()
Synapse.createSynapseLocally() Synapse.createSynapseLocally()
} }
@ -375,12 +369,12 @@ const Create = {
if (datum.id) { // if they clicked on an existing synapse get it if (datum.id) { // if they clicked on an existing synapse get it
Synapse.getSynapseFromAutocomplete(datum.id) Synapse.getSynapseFromAutocomplete(datum.id)
} else { } else {
Create.newSynapse.description = datum.value toExport.newSynapse.description = datum.value
Synapse.createSynapseLocally() Synapse.createSynapseLocally()
} }
}) })
}, },
beingCreated: false, beingtoExportd: false,
description: null, description: null,
topic1id: null, topic1id: null,
topic2id: null, topic2id: null,
@ -389,19 +383,21 @@ const Create = {
$('#new_synapse').fadeIn(100, function() { $('#new_synapse').fadeIn(100, function() {
$('#synapse_desc').focus() $('#synapse_desc').focus()
}) })
Create.newSynapse.beingCreated = true toExport.newSynapse.beingCreated = true
}, },
hide: function() { hide: function() {
$('#new_synapse').fadeOut('fast') $('#new_synapse').fadeOut('fast')
$('#synapse_desc').typeahead('val', '') $('#synapse_desc').typeahead('val', '')
Create.newSynapse.beingCreated = false toExport.newSynapse.beingCreated = false
Create.newTopic.addSynapse = false toExport.newTopic.addSynapse = false
Create.newSynapse.topic1id = 0 toExport.newSynapse.topic1id = 0
Create.newSynapse.topic2id = 0 toExport.newSynapse.topic2id = 0
Mouse.synapseStartCoordinates = [] Mouse.synapseStartCoordinates = []
if (Visualize.mGraph) Visualize.mGraph.plot() if (Visualize.mGraph) Visualize.mGraph.plot()
} }
} }
} }
return toExport
}
export default Create export default toExport

View file

@ -1,7 +1,3 @@
import Active from '../Active'
import Filter from '../Filter'
import { InfoBox } from '../Map'
import Map from './Map' import Map from './Map'
import MapCollection from './MapCollection' import MapCollection from './MapCollection'
import Message from './Message' import Message from './Message'
@ -17,27 +13,60 @@ import SynapseCollection from './SynapseCollection'
import Mapping from './Mapping' import Mapping from './Mapping'
import MappingCollection from './MappingCollection' import MappingCollection from './MappingCollection'
const DataModel = { const DataModel = ({Filter, InfoBox}) => {
Map: Map, const toExport = {
MapCollection: MapCollection,
Message: Message,
MessageCollection: MessageCollection,
Mapper: Mapper,
MapperCollection: MapperCollection,
Metacode: Metacode,
MetacodeCollection: MetacodeCollection,
Topic: Topic,
TopicCollection: TopicCollection,
Synapse: Synapse,
SynapseCollection: SynapseCollection,
Mapping: Mapping,
MappingCollection: MappingCollection,
Collaborators: new MapperCollection(), Collaborators: new MapperCollection(),
Creators: new MapperCollection(), Creators: new MapperCollection(),
Mappers: new MapperCollection(), Mappers: new MapperCollection(),
Mappings: new MappingCollection(), Mappings: new MappingCollection(),
Maps: { Messages: [],
Metacodes: new MetacodeCollection(),
Stars: [],
Synapses: new SynapseCollection(),
Topics: new TopicCollection(),
setMap: function(serverData) {
var self = toExport
if (serverData.Collaborators) self.Collaborators = new MapperCollection(serverData.Collaborators)
if (serverData.Mappers) self.Mappers = new MapperCollection(serverData.Mappers)
if (serverData.Mappings) self.Mappings = new MappingCollection(serverData.Mappings)
if (serverData.Messages) self.Messages = serverData.Messages
if (serverData.Metacodes) self.Metacodes = new MetacodeCollection(serverData.Metacodes)
if (serverData.Stars) self.Stars = serverData.Stars
if (serverData.Synapses) self.Synapses = new SynapseCollection(serverData.Synapses)
if (serverData.Topics) self.Topics = new TopicCollection(serverData.Topics)
self.attachCollectionEvents()
},
setTopic: function(serverData) {
var self = toExport
if (serverData.Creators) self.Creators = new MapperCollection(serverData.Creators)
if (serverData.Metacodes) self.Metacodes = new MetacodeCollection(serverData.Metacodes)
if (serverData.Synapses) self.Synapses = new SynapseCollection(serverData.Synapses)
if (serverData.Topics) self.Topics = new TopicCollection(serverData.Topics)
self.attachCollectionEvents()
},
attachCollectionEvents: function() {
toExport.Topics.on('add remove', function(topic) {
InfoBox.updateNumbers()
Filter.checkMetacodes()
Filter.checkMappers()
})
toExport.Synapses.on('add remove', function(synapse) {
InfoBox.updateNumbers()
Filter.checkSynapses()
Filter.checkMappers()
})
toExport.Mappings.on('add remove', function(mapping) {
InfoBox.updateNumbers()
Filter.checkSynapses()
Filter.checkMetacodes()
Filter.checkMappers()
})
}
}
return toExport
}
DataModel.Maps = {
Mine: [], Mine: [],
Shared: [], Shared: [],
Starred: [], Starred: [],
@ -47,35 +76,10 @@ const DataModel = {
}, },
Featured: [], Featured: [],
Active: [] Active: []
}, }
Messages: [], DataModel.init = function(serverData) {
Metacodes: new MetacodeCollection(),
Stars: [],
Synapses: new SynapseCollection(),
Topics: new TopicCollection(),
init: function(serverData) {
var self = DataModel var self = DataModel
// workaround circular import problem
if (!self.MapCollection.model) self.MapCollection.model = Map
self.synapseIconUrl = serverData['synapse16.png'] self.synapseIconUrl = serverData['synapse16.png']
if (serverData.ActiveMap) Active.Map = new Map(serverData.ActiveMap)
if (serverData.ActiveMapper) Active.Mapper = new Mapper(serverData.ActiveMapper)
if (serverData.ActiveTopic) Active.Topic = new Topic(serverData.ActiveTopic)
if (serverData.Collaborators) self.Collaborators = new MapperCollection(serverData.Collaborators)
if (serverData.Creators) self.Creators = new MapperCollection(serverData.Creators)
if (serverData.Mappers) self.Mappers = new MapperCollection(serverData.Mappers)
if (serverData.Mappings) self.Mappings = new MappingCollection(serverData.Mappings)
if (serverData.Messages) self.Messages = serverData.Messages
if (serverData.Metacodes) self.Metacodes = new MetacodeCollection(serverData.Metacodes)
if (serverData.Stars) self.Stars = serverData.Stars
if (serverData.Synapses) self.Synapses = new SynapseCollection(serverData.Synapses)
if (serverData.Topics) self.Topics = new TopicCollection(serverData.Topics)
// initialize global backbone models and collections // initialize global backbone models and collections
var myCollection = serverData.Mine ? serverData.Mine : [] var myCollection = serverData.Mine ? serverData.Mine : []
var sharedCollection = serverData.Shared ? serverData.Shared : [] var sharedCollection = serverData.Shared ? serverData.Shared : []
@ -88,7 +92,6 @@ const DataModel = {
} }
var featuredCollection = serverData.Featured ? serverData.Featured : [] var featuredCollection = serverData.Featured ? serverData.Featured : []
var activeCollection = serverData.Active ? serverData.Active : [] var activeCollection = serverData.Active ? serverData.Active : []
self.Maps.Mine = new MapCollection(myCollection, { id: 'mine', sortBy: 'updated_at' }) self.Maps.Mine = new MapCollection(myCollection, { id: 'mine', sortBy: 'updated_at' })
self.Maps.Shared = new MapCollection(sharedCollection, { id: 'shared', sortBy: 'updated_at' }) self.Maps.Shared = new MapCollection(sharedCollection, { id: 'shared', sortBy: 'updated_at' })
self.Maps.Starred = new MapCollection(starredCollection, { id: 'starred', sortBy: 'updated_at' }) self.Maps.Starred = new MapCollection(starredCollection, { id: 'starred', sortBy: 'updated_at' })
@ -96,29 +99,7 @@ const DataModel = {
self.Maps.Mapper = new MapCollection(mapperCollection, mapperOptionsObj) self.Maps.Mapper = new MapCollection(mapperCollection, mapperOptionsObj)
self.Maps.Featured = new MapCollection(featuredCollection, { id: 'featured', sortBy: 'updated_at' }) self.Maps.Featured = new MapCollection(featuredCollection, { id: 'featured', sortBy: 'updated_at' })
self.Maps.Active = new MapCollection(activeCollection, { id: 'active', sortBy: 'updated_at' }) self.Maps.Active = new MapCollection(activeCollection, { id: 'active', sortBy: 'updated_at' })
self.attachCollectionEvents()
},
attachCollectionEvents: function() {
DataModel.Topics.on('add remove', function(topic) {
InfoBox.updateNumbers()
Filter.checkMetacodes()
Filter.checkMappers()
})
DataModel.Synapses.on('add remove', function(synapse) {
InfoBox.updateNumbers()
Filter.checkSynapses()
Filter.checkMappers()
})
DataModel.Mappings.on('add remove', function(mapping) {
InfoBox.updateNumbers()
Filter.checkSynapses()
Filter.checkMetacodes()
Filter.checkMappers()
})
} }
}
// Note: Topics, Metacodes, Synapses, Mappers, Mappings, Collaborators, Creators are not exported // Note: Topics, Metacodes, Synapses, Mappers, Mappings, Collaborators, Creators are not exported
// You can access them by importing DataModel // You can access them by importing DataModel

View file

@ -2,14 +2,11 @@
import _ from 'lodash' import _ from 'lodash'
import Active from './Active'
import Control from './Control'
import DataModel from './DataModel'
import GlobalUI, { ReactApp } from './GlobalUI' import GlobalUI, { ReactApp } from './GlobalUI'
import Settings from './Settings' import Settings from './Settings'
import Visualize from './Visualize'
const Filter = { const Filter = ({Active, Control, DataModel, Visualize}) => {
const toExport = {
dataForPresentation: { dataForPresentation: {
metacodes: {}, metacodes: {},
mappers: {}, mappers: {},
@ -26,7 +23,7 @@ const Filter = {
synapses: [] synapses: []
}, },
reset: function() { reset: function() {
var self = Filter var self = toExport
self.filters.metacodes = [] self.filters.metacodes = []
self.filters.mappers = [] self.filters.mappers = []
self.filters.synapses = [] self.filters.synapses = []
@ -41,7 +38,7 @@ const Filter = {
// 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 = Filter var self = toExport
var newList = [] var newList = []
var removed = [] var removed = []
var added = [] var added = []
@ -97,11 +94,11 @@ const Filter = {
ReactApp.render() ReactApp.render()
}, },
checkMetacodes: function() { checkMetacodes: function() {
var self = Filter var self = toExport
self.updateFilters('Topics', 'metacode_id', 'Metacodes', 'metacodes', 'metacode') self.updateFilters('Topics', 'metacode_id', 'Metacodes', 'metacodes', 'metacode')
}, },
checkMappers: function() { checkMappers: function() {
var self = Filter var self = toExport
if (Active.Map) { if (Active.Map) {
self.updateFilters('Mappings', 'user_id', 'Mappers', 'mappers', 'mapper') self.updateFilters('Mappings', 'user_id', 'Mappers', 'mappers', 'mapper')
} else { } else {
@ -110,23 +107,23 @@ const Filter = {
} }
}, },
checkSynapses: function() { checkSynapses: function() {
var self = Filter var self = toExport
self.updateFilters('Synapses', 'desc', 'Synapses', 'synapses', 'synapse') self.updateFilters('Synapses', 'desc', 'Synapses', 'synapses', 'synapse')
}, },
filterAllMetacodes: function(toVisible) { filterAllMetacodes: function(toVisible) {
var self = Filter var self = toExport
self.visible.metacodes = toVisible ? self.filters.metacodes.slice() : [] self.visible.metacodes = toVisible ? self.filters.metacodes.slice() : []
ReactApp.render() ReactApp.render()
self.passFilters() self.passFilters()
}, },
filterAllMappers: function(toVisible) { filterAllMappers: function(toVisible) {
var self = Filter var self = toExport
self.visible.mappers = toVisible ? self.filters.mappers.slice() : [] self.visible.mappers = toVisible ? self.filters.mappers.slice() : []
ReactApp.render() ReactApp.render()
self.passFilters() self.passFilters()
}, },
filterAllSynapses: function(toVisible) { filterAllSynapses: function(toVisible) {
var self = Filter var self = toExport
self.visible.synapses = toVisible ? self.filters.synapses.slice() : [] self.visible.synapses = toVisible ? self.filters.synapses.slice() : []
ReactApp.render() ReactApp.render()
self.passFilters() self.passFilters()
@ -135,7 +132,7 @@ const Filter = {
// to reduce code redundancy // to reduce code redundancy
// gets called in the context of a list item in a filter box // gets called in the context of a list item in a filter box
toggleLi: function(whichToFilter, id) { toggleLi: function(whichToFilter, id) {
var self = Filter var self = toExport
if (self.visible[whichToFilter].indexOf(id) === -1) { if (self.visible[whichToFilter].indexOf(id) === -1) {
self.visible[whichToFilter].push(id) self.visible[whichToFilter].push(id)
} else { } else {
@ -146,19 +143,19 @@ const Filter = {
self.passFilters() self.passFilters()
}, },
toggleMetacode: function(id) { toggleMetacode: function(id) {
var self = Filter var self = toExport
self.toggleLi('metacodes', id) self.toggleLi('metacodes', id)
}, },
toggleMapper: function(id) { toggleMapper: function(id) {
var self = Filter var self = toExport
self.toggleLi('mappers', id) self.toggleLi('mappers', id)
}, },
toggleSynapse: function(id) { toggleSynapse: function(id) {
var self = Filter var self = toExport
self.toggleLi('synapses', id) self.toggleLi('synapses', id)
}, },
passFilters: function() { passFilters: function() {
var self = Filter var self = toExport
var visible = self.visible var visible = self.visible
var passesMetacode, passesMapper, passesSynapse var passesMetacode, passesMapper, passesSynapse
@ -276,5 +273,7 @@ const Filter = {
}) })
} }
} }
return toExport
}
export default Filter export default Filter

View file

@ -7,13 +7,12 @@ import { merge } from 'lodash'
import { notifyUser } from './index.js' import { notifyUser } from './index.js'
import ImportDialog from './ImportDialog' import ImportDialog from './ImportDialog'
import Active from '../Active' import Mapper from '../DataModel/Mapper'
import DataModel from '../DataModel'
import { ExploreMaps, ChatView, TopicCard } from '../Views' import { ExploreMaps, ChatView, TopicCard } from '../Views'
import Filter from '../Filter' import Filter from '../Filter'
import JIT from '../JIT' import JIT from '../JIT'
import Realtime from '../Realtime' import Realtime from '../Realtime'
import Map, { InfoBox } from '../Map' import Map, { mapControl } from '../Map'
import Topic from '../Topic' import Topic from '../Topic'
import Visualize from '../Visualize' import Visualize from '../Visualize'
import makeRoutes from '../../components/makeRoutes' import makeRoutes from '../../components/makeRoutes'
@ -27,8 +26,11 @@ const MAX_COLUMNS = 4
const ReactApp = { const ReactApp = {
serverData: {}, serverData: {},
currentUser: null,
mapId: null, mapId: null,
openMap: null,
topicId: null, topicId: null,
openTopic: null,
unreadNotificationsCount: 0, unreadNotificationsCount: 0,
mapsWidth: 0, mapsWidth: 0,
toast: '', toast: '',
@ -36,9 +38,11 @@ const ReactApp = {
mobileTitle: '', mobileTitle: '',
mobileTitleWidth: 0, mobileTitleWidth: 0,
metacodeSets: [], metacodeSets: [],
juntoState: { connectedPeople: {}, liveMaps: {} },
init: function(serverData, openLightbox) { init: function(serverData, openLightbox) {
const self = ReactApp const self = ReactApp
self.serverData = serverData self.serverData = serverData
self.currentUser = new Mapper(serverData.ActiveMapper)
self.unreadNotificationsCount = serverData.unreadNotificationsCount self.unreadNotificationsCount = serverData.unreadNotificationsCount
self.mobileTitle = serverData.mobileTitle self.mobileTitle = serverData.mobileTitle
self.openLightbox = openLightbox self.openLightbox = openLightbox
@ -52,12 +56,13 @@ const ReactApp = {
const pathname = this.state.location.pathname const pathname = this.state.location.pathname
switch (pathname.split('/')[1]) { switch (pathname.split('/')[1]) {
case '': case '':
if (Active.Mapper && Active.Mapper.id) { if (self.currentUser && self.currentUser.id) {
$('#yield').hide() $('#yield').hide()
ExploreMaps.updateFromPath(pathname) ExploreMaps.updateFromPath(pathname)
self.mapId = null self.mapId = null
Active.Map = null self.topicId = null
Active.Topic = null self.openMap = null
self.openTopic = null
} }
break break
case 'explore': case 'explore':
@ -65,19 +70,19 @@ const ReactApp = {
ExploreMaps.updateFromPath(pathname) ExploreMaps.updateFromPath(pathname)
self.mapId = null self.mapId = null
self.topicId = null self.topicId = null
Active.Map = null self.openMap = null
Active.Topic = null self.openTopic = null
break break
case 'topics': case 'topics':
$('#yield').hide() $('#yield').hide()
Active.Map = null self.openMap = null
self.mapId = null self.mapId = null
self.topicId = pathname.split('/')[2] self.topicId = pathname.split('/')[2]
break break
case 'maps': case 'maps':
if (!pathname.includes('request_access')) { if (!pathname.includes('request_access')) {
$('#yield').hide() $('#yield').hide()
Active.Topic = null self.openTopic = null
self.topicId = null self.topicId = null
self.mapId = pathname.split('/')[2] self.mapId = pathname.split('/')[2]
} }
@ -99,14 +104,18 @@ const ReactApp = {
const self = ReactApp const self = ReactApp
return merge({ return merge({
unreadNotificationsCount: self.unreadNotificationsCount, unreadNotificationsCount: self.unreadNotificationsCount,
currentUser: Active.Mapper, currentUser: self.currentUser,
toast: self.toast, toast: self.toast,
mobile: self.mobile, mobile: self.mobile,
mobileTitle: self.mobileTitle, mobileTitle: self.mobileTitle,
mobileTitleWidth: self.mobileTitleWidth, mobileTitleWidth: self.mobileTitleWidth,
mobileTitleClick: (e) => Active.Map && 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,
launchNewMap: mapControl.launch,
mapId: self.mapId,
topicId: self.topicId
}, },
self.getMapProps(), self.getMapProps(),
self.getTopicProps(), self.getTopicProps(),
@ -118,27 +127,27 @@ const ReactApp = {
}, },
getMapProps: function() { getMapProps: function() {
const self = ReactApp const self = ReactApp
if (!self.openMap) return {}
return { return {
mapId: self.mapId, map: self.openMap.Active.Map,
map: Active.Map, hasLearnedTopicCreation: self.openMap.Map.hasLearnedTopicCreation,
hasLearnedTopicCreation: Map.hasLearnedTopicCreation, userRequested: self.openMap.Map.userRequested,
userRequested: Map.userRequested, requestAnswered: self.openMap.Map.requestAnswered,
requestAnswered: Map.requestAnswered, requestApproved: self.openMap.Map.requestApproved,
requestApproved: Map.requestApproved, onRequestAccess: self.openMap.Map.requestAccess,
onRequestAccess: Map.requestAccess, mapIsStarred: self.openMap.Map.mapIsStarred,
mapIsStarred: Map.mapIsStarred, toggleMapInfoBox: self.openMap.InfoBox.toggleBox,
endActiveMap: Map.end, infoBoxHtml: self.openMap.InfoBox.html,
launchNewMap: Map.launch,
toggleMapInfoBox: InfoBox.toggleBox,
infoBoxHtml: InfoBox.html,
openImportLightbox: () => ImportDialog.show(), openImportLightbox: () => ImportDialog.show(),
forkMap: Map.fork, forkMap: self.openMap.Map.fork,
onMapStar: Map.star, onMapStar: self.openMap.Map.star,
onMapUnstar: Map.unstar onMapUnstar: self.openMap.Map.unstar
} }
}, },
getCommonProps: function() { getCommonProps: function() {
const self = ReactApp const self = ReactApp
if (!(self.openMap || self.openTopic)) return {}
const { JIT, Visualize } = self.openMap || self.openTopic
return { return {
openHelpLightbox: () => self.openLightbox('cheatsheet'), openHelpLightbox: () => self.openLightbox('cheatsheet'),
onZoomExtents: event => JIT.zoomExtents(event, Visualize.mGraph.canvas), onZoomExtents: event => JIT.zoomExtents(event, Visualize.mGraph.canvas),
@ -148,20 +157,22 @@ const ReactApp = {
}, },
getTopicCardProps: function() { getTopicCardProps: function() {
const self = ReactApp const self = ReactApp
if (!(self.openMap || self.openTopic)) return {}
const { TopicCard } = self.openMap || self.openTopic
return { return {
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 onTopicFollow: Topic.onTopicFollow // todo
} }
}, },
getTopicProps: function() { getTopicProps: function() {
const self = ReactApp const self = ReactApp
if (!self.openTopic) return {}
return { return {
topicId: self.topicId, topic: self.openTopic.Active.Topic,
topic: Active.Topic, endActiveTopic: Topic.end, // todo
endActiveTopic: Topic.end, launchNewTopic: Topic.launch // todo
launchNewTopic: Topic.launch
} }
}, },
getMapsProps: function() { getMapsProps: function() {
@ -169,7 +180,7 @@ const ReactApp = {
return { return {
section: ExploreMaps.collection && ExploreMaps.collection.id, section: ExploreMaps.collection && ExploreMaps.collection.id,
maps: ExploreMaps.collection, maps: ExploreMaps.collection,
juntoState: Realtime.juntoState, juntoState: self.juntoState,
moreToLoad: ExploreMaps.collection && ExploreMaps.collection.page !== 'loadedAll', moreToLoad: ExploreMaps.collection && ExploreMaps.collection.page !== 'loadedAll',
user: ExploreMaps.collection && ExploreMaps.collection.id === 'mapper' ? ExploreMaps.mapper : null, user: ExploreMaps.collection && ExploreMaps.collection.id === 'mapper' ? ExploreMaps.mapper : null,
loadMore: ExploreMaps.loadMore, loadMore: ExploreMaps.loadMore,
@ -182,6 +193,11 @@ const ReactApp = {
}, },
getChatProps: function() { getChatProps: function() {
const self = ReactApp const self = ReactApp
if (!self.openMap) return {
participants: [],
messages: []
}
const { ChatView, Realtime } = self.openMap
return { return {
unreadMessages: ChatView.unreadMessages, unreadMessages: ChatView.unreadMessages,
conversationLive: ChatView.conversationLive, conversationLive: ChatView.conversationLive,
@ -204,6 +220,8 @@ const ReactApp = {
}, },
getFilterProps: function() { getFilterProps: function() {
const self = ReactApp const self = ReactApp
if (!self.openMap) return {}
const { Filter } = self.openMap
return { return {
filterData: Filter.dataForPresentation, filterData: Filter.dataForPresentation,
allForFiltering: Filter.filters, allForFiltering: Filter.filters,
@ -219,7 +237,7 @@ const ReactApp = {
resize: function() { resize: function() {
const self = ReactApp const self = ReactApp
const maps = ExploreMaps.collection const maps = ExploreMaps.collection
const currentUser = Active.Mapper const currentUser = self.currentUser
const user = maps && maps.id === 'mapper' ? ExploreMaps.mapper : null const user = maps && maps.id === 'mapper' ? ExploreMaps.mapper : null
const numCards = (maps ? maps.length : 0) + (user || currentUser ? 1 : 0) const numCards = (maps ? maps.length : 0) + (user || currentUser ? 1 : 0)
const mapSpaces = Math.floor(document.body.clientWidth / MAP_WIDTH) const mapSpaces = Math.floor(document.body.clientWidth / MAP_WIDTH)

View file

@ -3,15 +3,10 @@
import parse from 'csv-parse' import parse from 'csv-parse'
import _ from 'lodash' import _ from 'lodash'
import Active from './Active'
import AutoLayout from './AutoLayout'
import DataModel from './DataModel'
import GlobalUI from './GlobalUI' import GlobalUI from './GlobalUI'
import Map from './Map'
import Synapse from './Synapse'
import Topic from './Topic'
const Import = { const Import = ({Active, AutoLayout, DataModel, Map, Synapse, Topic}) => {
const toExport = {
// note that user is not imported // note that user is not imported
topicWhitelist: [ topicWhitelist: [
'id', 'name', 'metacode', 'x', 'y', 'description', 'link', 'permission' 'id', 'name', 'metacode', 'x', 'y', 'description', 'link', 'permission'
@ -22,12 +17,12 @@ const Import = {
cidMappings: {}, // to be filled by importId => cid mappings cidMappings: {}, // to be filled by importId => cid mappings
handleTSV: function(text) { handleTSV: function(text) {
const results = Import.parseTabbedString(text) const results = toExport.parseTabbedString(text)
Import.handle(results) toExport.handle(results)
}, },
handleCSV: function(text, parserOpts = {}) { handleCSV: function(text, parserOpts = {}) {
const self = Import const self = toExport
const topicsRegex = /("?Topics"?[, \t"]*)([\s\S]*)/mi const topicsRegex = /("?Topics"?[, \t"]*)([\s\S]*)/mi
const synapsesRegex = /("?Synapses"?[, \t"]*)([\s\S]*)/mi const synapsesRegex = /("?Synapses"?[, \t"]*)([\s\S]*)/mi
@ -68,11 +63,11 @@ const Import = {
handleJSON: function(text) { handleJSON: function(text) {
const results = JSON.parse(text) const results = JSON.parse(text)
Import.handle(results) toExport.handle(results)
}, },
handle: function(results) { handle: function(results) {
var self = Import var self = toExport
var topics = results.topics.map(topic => self.normalizeKeys(topic)) var topics = results.topics.map(topic => self.normalizeKeys(topic))
var synapses = results.synapses.map(synapse => self.normalizeKeys(synapse)) var synapses = results.synapses.map(synapse => self.normalizeKeys(synapse))
@ -87,7 +82,7 @@ const Import = {
}, },
parseTabbedString: function(text) { parseTabbedString: function(text) {
var self = Import var self = toExport
// determine line ending and split lines // determine line ending and split lines
var delim = '\n' var delim = '\n'
@ -213,7 +208,7 @@ const Import = {
}, },
importTopics: function(parsedTopics) { importTopics: function(parsedTopics) {
var self = Import var self = toExport
parsedTopics.forEach(topic => { parsedTopics.forEach(topic => {
let coords = { x: topic.x, y: topic.y } let coords = { x: topic.x, y: topic.y }
@ -240,7 +235,7 @@ const Import = {
}, },
importSynapses: function(parsedSynapses) { importSynapses: function(parsedSynapses) {
var self = Import var self = toExport
parsedSynapses.forEach(function(synapse) { parsedSynapses.forEach(function(synapse) {
// only createSynapseWithParameters once both topics are persisted // only createSynapseWithParameters once both topics are persisted
@ -279,7 +274,7 @@ const Import = {
createTopicWithParameters: function(name, metacodeName, permission, desc, createTopicWithParameters: function(name, metacodeName, permission, desc,
link, xloc, yloc, importId, opts = {}) { link, xloc, yloc, importId, opts = {}) {
var self = Import var self = toExport
$(document).trigger(Map.events.editedByActiveMapper) $(document).trigger(Map.events.editedByActiveMapper)
var metacode = DataModel.Metacodes.where({name: metacodeName})[0] || null var metacode = DataModel.Metacodes.where({name: metacodeName})[0] || null
if (metacode === null) { if (metacode === null) {
@ -359,7 +354,7 @@ const Import = {
const permission = opts.permission || null // use default const permission = opts.permission || null // use default
const desc = opts.desc || url const desc = opts.desc || url
Import.createTopicWithParameters( toExport.createTopicWithParameters(
name, name,
metacode, metacode,
permission, permission,
@ -423,5 +418,7 @@ const Import = {
}) })
} }
} }
return toExport
}
export default Import export default Import

View file

@ -35,17 +35,6 @@ return {
animationDone: 'Metamaps:JIT:events:animationDone' animationDone: 'Metamaps:JIT:events:animationDone'
}, },
vizData: [], // contains the visualization-compatible graph vizData: [], // contains the visualization-compatible graph
/**
* This method will bind the event handlers it is interested and initialize the class.
*/
init: function(serverData) {
const self = JIT
self.topicDescImage = new Image()
self.topicDescImage.src = serverData['topic_description_signifier.png']
self.topicLinkImage = new Image()
self.topicLinkImage.src = serverData['topic_link_signifier.png']
},
/** /**
* convert our topic JSON into something JIT can use * convert our topic JSON into something JIT can use
*/ */
@ -1968,5 +1957,12 @@ return {
} }
} }
} }
JIT.init = function(serverData) {
JIT.topicDescImage = new Image()
JIT.topicDescImage.src = serverData['topic_description_signifier.png']
JIT.topicLinkImage = new Image()
JIT.topicLinkImage.src = serverData['topic_link_signifier.png']
}
export default JIT export default JIT

View file

@ -5,9 +5,9 @@ import { Search } from './GlobalUI'
const Listeners = ({ Active, Create, Control, DataModel, JIT, Realtime, Selected, Topic, Visualize }) => { const Listeners = ({ Active, Create, Control, DataModel, JIT, Realtime, Selected, Topic, Visualize }) => {
return { return {
init: function() { activate: function() {
var self = this var self = this
$(document).on('keydown', function(e) { $(document).on('keydown.map', function(e) {
if (!(Active.Map || Active.Topic)) return if (!(Active.Map || Active.Topic)) return
const onCanvas = e.target.tagName === 'BODY' const onCanvas = e.target.tagName === 'BODY'
@ -131,7 +131,7 @@ return {
break break
} }
}) })
$(window).resize(function() { $(window).on('resize.map', function() {
if (Visualize && Visualize.mGraph) { if (Visualize && Visualize.mGraph) {
Util.resizeCanvas(Visualize.mGraph.canvas) Util.resizeCanvas(Visualize.mGraph.canvas)
} }

View file

@ -3,12 +3,11 @@
import outdent from 'outdent' import outdent from 'outdent'
import { browserHistory } from 'react-router' import { browserHistory } from 'react-router'
import Active from '../Active'
import DataModel from '../DataModel'
import GlobalUI, { ReactApp } from '../GlobalUI' import GlobalUI, { ReactApp } from '../GlobalUI'
import Util from '../Util' import Util from '../Util'
const InfoBox = { const InfoBox = ({Active, DataModel}) => {
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>",
@ -36,32 +35,32 @@ const InfoBox = {
userImageUrl: '', userImageUrl: '',
html: '', html: '',
init: function(serverData, updateThumbnail) { init: function(serverData, updateThumbnail) {
var self = InfoBox var self = toExport
self.updateThumbnail = updateThumbnail self.updateThumbnail = updateThumbnail
$('.mapInfoBox').click(function(event) { $('.maptoExport').click(function(event) {
event.stopPropagation() event.stopPropagation()
}) })
$('body').click(self.close) $('body').click(self.close)
self.attachEventListeners() self.attachEventListeners()
self.generateBoxHTML = Hogan.compile($('#mapInfoBoxTemplate').html()) self.generateBoxHTML = Hogan.compile($('#maptoExportTemplate').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()
$('.mapInfoBox').addClass('mapRequestTitle') $('.maptoExport').addClass('mapRequestTitle')
$('#mapInfoName').trigger('click') $('#mapInfoName').trigger('click')
$('#mapInfoName textarea').focus() $('#mapInfoName textarea').focus()
$('#mapInfoName textarea').select() $('#mapInfoName textarea').select()
} }
}, },
toggleBox: function(event) { toggleBox: function(event) {
var self = InfoBox var self = toExport
if (self.isOpen) self.close() if (self.isOpen) self.close()
else self.open() else self.open()
@ -69,23 +68,23 @@ const InfoBox = {
event.stopPropagation() event.stopPropagation()
}, },
open: function() { open: function() {
var self = InfoBox var self = toExport
$('.mapInfoIcon div').addClass('hide') $('.mapInfoIcon div').addClass('hide')
$('.mapInfoBox').fadeIn(200, function() { $('.maptoExport').fadeIn(200, function() {
self.isOpen = true self.isOpen = true
}) })
}, },
close: function() { close: function() {
var self = InfoBox var self = toExport
$('.mapInfoIcon div').removeClass('hide') $('.mapInfoIcon div').removeClass('hide')
$('.mapInfoBox').fadeOut(200, function() { $('.maptoExport').fadeOut(200, function() {
self.isOpen = false self.isOpen = false
self.hidePermissionSelect() self.hidePermissionSelect()
$('.mapContributors .tip').hide() $('.mapContributors .tip').hide()
}) })
}, },
load: function() { load: function() {
var self = InfoBox var self = toExport
var map = Active.Map var map = Active.Map
@ -115,12 +114,12 @@ const InfoBox = {
self.attachEventListeners() self.attachEventListeners()
}, },
attachEventListeners: function() { attachEventListeners: function() {
var self = InfoBox var self = toExport
$('.mapInfoBox.canEdit .best_in_place').best_in_place() $('.maptoExport.canEdit .best_in_place').best_in_place()
// because anyone who can edit the map can change the map title // because anyone who can edit the map can change the map title
var bipName = $('.mapInfoBox .best_in_place_name') var bipName = $('.maptoExport .best_in_place_name')
bipName.unbind('best_in_place:activate').bind('best_in_place:activate', function() { bipName.unbind('best_in_place:activate').bind('best_in_place:activate', function() {
var $el = bipName.find('textarea') var $el = bipName.find('textarea')
var el = $el[0] var el = $el[0]
@ -144,7 +143,7 @@ const InfoBox = {
Active.Map.trigger('saved') Active.Map.trigger('saved')
// mobile menu // mobile menu
$('#header_content').html(name) $('#header_content').html(name)
$('.mapInfoBox').removeClass('mapRequestTitle') $('.maptoExport').removeClass('mapRequestTitle')
document.title = `${name} | Metamaps` document.title = `${name} | Metamaps`
window.history.replaceState('', `${name} | Metamaps`, window.location.pathname) window.history.replaceState('', `${name} | Metamaps`, window.location.pathname)
}) })
@ -164,8 +163,8 @@ const InfoBox = {
$('.yourMap .mapPermission').unbind().click(self.onPermissionClick) $('.yourMap .mapPermission').unbind().click(self.onPermissionClick)
// .yourMap in the unbind/bind is just a namespace for the events // .yourMap in the unbind/bind is just a namespace for the events
// not a reference to the class .yourMap on the .mapInfoBox // not a reference to the class .yourMap on the .maptoExport
$('.mapInfoBox.yourMap').unbind('.yourMap').bind('click.yourMap', self.hidePermissionSelect) $('.maptoExport.yourMap').unbind('.yourMap').bind('click.yourMap', self.hidePermissionSelect)
$('.yourMap .mapInfoDelete').unbind().click(self.deleteActiveMap) $('.yourMap .mapInfoDelete').unbind().click(self.deleteActiveMap)
$('.mapInfoThumbnail').unbind().click(self.updateThumbnail) $('.mapInfoThumbnail').unbind().click(self.updateThumbnail)
@ -178,14 +177,14 @@ const InfoBox = {
event.stopPropagation() event.stopPropagation()
}) })
$('.mapInfoBox').unbind('.hideTip').bind('click.hideTip', function() { $('.maptoExport').unbind('.hideTip').bind('click.hideTip', function() {
$('.mapContributors .tip').hide() $('.mapContributors .tip').hide()
}) })
self.addTypeahead() self.addTypeahead()
}, },
addTypeahead: function() { addTypeahead: function() {
var self = InfoBox var self = toExport
if (!Active.Map) return if (!Active.Map) return
@ -232,14 +231,14 @@ const InfoBox = {
} }
}, },
removeCollaborator: function(collaboratorId) { removeCollaborator: function(collaboratorId) {
var self = InfoBox var self = toExport
DataModel.Collaborators.remove(DataModel.Collaborators.get(collaboratorId)) DataModel.Collaborators.remove(DataModel.Collaborators.get(collaboratorId))
var mapperIds = DataModel.Collaborators.models.map(function(mapper) { return mapper.id }) var mapperIds = DataModel.Collaborators.models.map(function(mapper) { return mapper.id })
$.post('/maps/' + Active.Map.id + '/access', { access: mapperIds }) $.post('/maps/' + Active.Map.id + '/access', { access: mapperIds })
self.updateNumbers() self.updateNumbers()
}, },
addCollaborator: function(newCollaboratorId) { addCollaborator: function(newCollaboratorId) {
var self = InfoBox var self = toExport
if (DataModel.Collaborators.get(newCollaboratorId)) { if (DataModel.Collaborators.get(newCollaboratorId)) {
GlobalUI.notifyUser('That user already has access') GlobalUI.notifyUser('That user already has access')
@ -258,16 +257,16 @@ const InfoBox = {
$.getJSON('/users/' + newCollaboratorId + '.json', callback) $.getJSON('/users/' + newCollaboratorId + '.json', callback)
}, },
handleResultClick: function(event, item) { handleResultClick: function(event, item) {
var self = InfoBox var self = toExport
self.addCollaborator(item.id) self.addCollaborator(item.id)
$('.collaboratorSearchField').typeahead('val', '') $('.collaboratorSearchField').typeahead('val', '')
}, },
updateNameDescPerm: function(name, desc, perm) { updateNameDescPerm: function(name, desc, perm) {
$('.mapInfoBox').removeClass('mapRequestTitle') $('.maptoExport').removeClass('mapRequestTitle')
$('.mapInfoName .best_in_place_name').html(name) $('.mapInfoName .best_in_place_name').html(name)
$('.mapInfoDesc .best_in_place_desc').html(desc) $('.mapInfoDesc .best_in_place_desc').html(desc)
$('.mapInfoBox .mapPermission').removeClass('commons public private').addClass(perm) $('.maptoExport .mapPermission').removeClass('commons public private').addClass(perm)
}, },
createContributorList: function() { createContributorList: function() {
var relevantPeople = Active.Map.get('permission') === 'commons' ? DataModel.Mappers : DataModel.Collaborators var relevantPeople = Active.Map.get('permission') === 'commons' ? DataModel.Mappers : DataModel.Collaborators
@ -294,7 +293,7 @@ const InfoBox = {
updateNumbers: function() { updateNumbers: function() {
if (!Active.Map) return if (!Active.Map) return
const self = InfoBox const self = toExport
var relevantPeople = Active.Map.get('permission') === 'commons' ? DataModel.Mappers : DataModel.Collaborators var relevantPeople = Active.Map.get('permission') === 'commons' ? DataModel.Mappers : DataModel.Collaborators
@ -323,7 +322,7 @@ const InfoBox = {
$('.mapEditedAt').html('<span>Last edited: </span>' + Util.nowDateFormatted()) $('.mapEditedAt').html('<span>Last edited: </span>' + Util.nowDateFormatted())
}, },
onPermissionClick: function(event) { onPermissionClick: function(event) {
var self = InfoBox var self = toExport
if (!self.selectingPermission) { if (!self.selectingPermission) {
self.selectingPermission = true self.selectingPermission = true
@ -340,14 +339,14 @@ const InfoBox = {
} }
}, },
hidePermissionSelect: function() { hidePermissionSelect: function() {
var self = InfoBox var self = toExport
self.selectingPermission = false self.selectingPermission = false
$('.mapPermission').removeClass('minimize') // this line flips the pull up arrow to a drop down arrow $('.mapPermission').removeClass('minimize') // this line flips the pull up arrow to a drop down arrow
$('.mapPermission .permissionSelect').remove() $('.mapPermission .permissionSelect').remove()
}, },
selectPermission: function(event) { selectPermission: function(event) {
var self = InfoBox var self = toExport
self.selectingPermission = false self.selectingPermission = false
var permission = $(this).attr('class') var permission = $(this).attr('class')
@ -358,7 +357,7 @@ const InfoBox = {
const shareable = permission === 'private' ? '' : 'shareable' const shareable = permission === 'private' ? '' : 'shareable'
$('.mapPermission').removeClass('commons public private minimize').addClass(permission) $('.mapPermission').removeClass('commons public private minimize').addClass(permission)
$('.mapPermission .permissionSelect').remove() $('.mapPermission .permissionSelect').remove()
$('.mapInfoBox').removeClass('shareable').addClass(shareable) $('.maptoExport').removeClass('shareable').addClass(shareable)
event.stopPropagation() event.stopPropagation()
}, },
deleteActiveMap: function() { deleteActiveMap: function() {
@ -371,7 +370,7 @@ const InfoBox = {
var authorized = map.authorizePermissionChange(mapper) var authorized = map.authorizePermissionChange(mapper)
if (doIt && authorized) { if (doIt && authorized) {
InfoBox.close() toExport.close()
DataModel.Maps.Active.remove(map) DataModel.Maps.Active.remove(map)
DataModel.Maps.Featured.remove(map) DataModel.Maps.Featured.remove(map)
DataModel.Maps.Mine.remove(map) DataModel.Maps.Mine.remove(map)
@ -384,5 +383,7 @@ const InfoBox = {
} }
} }
} }
return toExport
}
export default InfoBox export default InfoBox

View file

@ -6,29 +6,142 @@ import { browserHistory } from 'react-router'
import Active from '../Active' import Active from '../Active'
import AutoLayout from '../AutoLayout' import AutoLayout from '../AutoLayout'
import Cable from '../Cable'
import Control from '../Control'
import Create from '../Create' import Create from '../Create'
import DataModel from '../DataModel' import DataModel from '../DataModel'
import DataModelMap from '../DataModel/Map' import DataModelMap from '../DataModel/Map'
import MapperCollection from '../DataModel/MapperCollection'
import TopicCollection from '../DataModel/TopicCollection'
import SynapseCollection from '../DataModel/SynapseCollection'
import MappingCollection from '../DataModel/MappingCollection'
import Filter from '../Filter' import Filter from '../Filter'
import GlobalUI, { ReactApp } from '../GlobalUI' import GlobalUI, { ReactApp } from '../GlobalUI'
import Import from '../Import'
import InfoBox from './InfoBox'
import JIT from '../JIT' import JIT from '../JIT'
import Listeners from '../Listeners' import Listeners from '../Listeners'
import Loading from '../Loading' import Loading from '../Loading'
import Mouse from '../Mouse'
import Organize from '../Organize' import Organize from '../Organize'
import PasteInput from '../PasteInput'
import Realtime from '../Realtime' import Realtime from '../Realtime'
import Selected from '../Selected' import Selected from '../Selected'
import Synapse from '../Synapse'
import SynapseCard from '../SynapseCard' import SynapseCard from '../SynapseCard'
import Topic from '../Topic' import Topic from '../Topic'
import TopicCard from '../Views/TopicCard' import TopicCard from '../Views/TopicCard'
import ChatView from '../Views/ChatView'
import Visualize from '../Visualize' import Visualize from '../Visualize'
import CheatSheet from './CheatSheet' import CheatSheet from './CheatSheet'
import InfoBox from './InfoBox'
const Map = { const mapControl = {
events: { launch: function(id, serverData) {
editedByActiveMapper: 'Metamaps:Map:events:editedByActiveMapper' var dataIsReadySetupMap = function(data) {
const newMap = {
Active: null,
AutoLayout: null,
Cable: null,
ChatView: null,
Control: null,
Create: null,
DataModel: null,
Filter: null,
Import: null,
JIT: null,
Listeners: null,
Mouse: null,
Organize: null,
PasteInput: null,
Realtime: null,
Selected: null,
Synapse: null,
SynapseCard: null,
Topic: null,
TopicCard: null,
Visualize: null
}
newMap.Active = Active()
newMap.AutoLayout = AutoLayout(newMap)
newMap.Cable = Cable(newMap)
newMap.ChatView = ChatView(newMap)
newMap.Control = Control(newMap)
newMap.Create = Create(newMap)
newMap.DataModel = DataModel(newMap)
newMap.Filter = Filter(newMap)
newMap.Import = Import(newMap)
newMap.InfoBox = InfoBox(newMap)
newMap.JIT = JIT(newMap)
newMap.Listeners = Listeners(newMap)
newMap.Map = Map(newMap)
newMap.Mouse = Mouse(newMap)
newMap.Organize = Organize(newMap)
newMap.PasteInput = PasteInput(newMap)
newMap.Realtime = Realtime(newMap)
newMap.Selected = Selected(newMap)
newMap.Synapse = Synapse(newMap)
newMap.SynapseCard = SynapseCard(newMap)
newMap.Topic = Topic(newMap)
newMap.TopicCard = TopicCard(newMap)
newMap.Visualize = Visualize(newMap)
console.log(newMap)
newMap.Active.Map = new DataModelMap(data.map)
newMap.DataModel.Mappers = new MapperCollection(data.mappers)
newMap.DataModel.Collaborators = new MapperCollection(data.collaborators)
newMap.DataModel.Topics = new TopicCollection(data.topics)
newMap.DataModel.Synapses = new SynapseCollection(data.synapses)
newMap.DataModel.Mappings = new MappingCollection(data.mappings)
newMap.DataModel.Messages = data.messages
newMap.DataModel.Stars = data.stars
newMap.DataModel.attachCollectionEvents()
newMap.Map.requests = data.requests
newMap.Map.setAccessRequest()
newMap.Visualize.type = 'ForceDirected'
newMap.JIT.prepareVizData()
newMap.InfoBox.load()
newMap.Filter.checkMetacodes()
newMap.Filter.checkSynapses()
newMap.Filter.checkMappers()
newMap.Realtime.startActiveMap()
Loading.hide()
document.title = newMap.Active.Map.get('name') + ' | Metamaps'
ReactApp.openMap = newMap
ReactApp.mobileTitle = newMap.Active.Map.get('name')
ReactApp.render()
}
if (false) {
// do something with serverData here
dataIsReadySetupMap()
}
else {
Loading.show()
$.ajax({
url: '/maps/' + id + '/contains.json',
success: dataIsReadySetupMap
})
}
}, },
end: function(map) {
$('.main').removeClass('compressed')
$('.rightclickmenu').remove()
map.AutoLayout.resetSpiral()
map.TopicCard.hideCard()
map.SynapseCard.hideCard()
map.Create.newTopic.hide(true) // true means force (and override pinned)
map.Create.newSynapse.hide()
map.InfoBox.close()
map.Realtime.endActiveMap()
map.Map.requests = []
map.Map.hasLearnedTopicCreation = true
}
}
export { mapControl }
const Map = ({Active, DataModel, JIT, Visualize, Realtime}) => {
const toExport = {
mapIsStarred: false, mapIsStarred: false,
requests: [], requests: [],
userRequested: false, userRequested: false,
@ -36,7 +149,7 @@ const Map = {
requestApproved: false, requestApproved: false,
hasLearnedTopicCreation: true, hasLearnedTopicCreation: true,
init: function(serverData) { init: function(serverData) {
var self = Map var self = toExport
self.mapIsStarred = serverData.mapIsStarred self.mapIsStarred = serverData.mapIsStarred
self.requests = serverData.requests self.requests = serverData.requests
self.setAccessRequest() self.setAccessRequest()
@ -44,19 +157,19 @@ const Map = {
if (e.button === 1) return false if (e.button === 1) return false
}) })
GlobalUI.CreateMap.emptyForkMapForm = $('#fork_map').html() GlobalUI.CreateMap.emptyForkMapForm = $('#fork_map').html()
InfoBox.init(serverData, function updateThumbnail() { //InfoBox.init(serverData, function updateThumbnail() {
self.uploadMapScreenshot() // self.uploadMapScreenshot()
}) //})
CheatSheet.init(serverData) CheatSheet.init(serverData)
$(document).on(Map.events.editedByActiveMapper, self.editedByActiveMapper) $(document).on(Map.events.editedByActiveMapper, self.editedByActiveMapper)
}, },
setHasLearnedTopicCreation: function(value) { setHasLearnedTopicCreation: function(value) {
const self = Map const self = toExport
self.hasLearnedTopicCreation = value self.hasLearnedTopicCreation = value
ReactApp.render() ReactApp.render()
}, },
requestAccess: function() { requestAccess: function() {
const self = Map const self = toExport
self.requests.push({ self.requests.push({
user_id: Active.Mapper.id, user_id: Active.Mapper.id,
answered: false, answered: false,
@ -70,7 +183,7 @@ const Map = {
GlobalUI.notifyUser('Map creator will be notified of your request') GlobalUI.notifyUser('Map creator will be notified of your request')
}, },
setAccessRequest: function() { setAccessRequest: function() {
const self = Map const self = toExport
if (Active.Mapper) { if (Active.Mapper) {
const request = _find(self.requests, r => r.user_id === Active.Mapper.id) const request = _find(self.requests, r => r.user_id === Active.Mapper.id)
if (!request) { if (!request) {
@ -91,98 +204,8 @@ const Map = {
} }
ReactApp.render() ReactApp.render()
}, },
launch: function(id) {
const self = Map
const newMap = {
Active: null,
AutoLayout: null,
Cable: null,
Control: null,
Create: null,
DataModel: null,
Filter: null,
Import: null,
JIT: null,
Listeners: null,
Loading: null,
Map: null,
Mouse: null,
Organize: null,
PasteInput: null,
Realtime: null,
Selected: null,
Settings: null,
Synapse: null,
SynapseCard: null,
Topic: null,
Views: null,
Visualize: null
}
newMap.JIT = JIT(newMap)
newMap.Listeners = Listeners(newMap)
console.log(newMap)
var dataIsReadySetupMap = function() {
Map.setAccessRequest()
Visualize.type = 'ForceDirected'
newMap.JIT.prepareVizData()
Selected.reset()
InfoBox.load()
Filter.reset()
Filter.checkMetacodes()
Filter.checkSynapses()
Filter.checkMappers()
Realtime.startActiveMap()
Loading.hide()
document.title = Active.Map.get('name') + ' | Metamaps'
ReactApp.mobileTitle = Active.Map.get('name')
ReactApp.render()
}
function isLoaded() {
if (InfoBox.generateBoxHTML) dataIsReadySetupMap()
else setTimeout(() => isLoaded(), 50)
}
if (Active.Map && Active.Map.id === id) {
isLoaded()
}
else {
Loading.show()
$.ajax({
url: '/maps/' + id + '/contains.json',
success: function(data) {
Active.Map = new DataModelMap(data.map)
DataModel.Mappers = new DataModel.MapperCollection(data.mappers)
DataModel.Collaborators = new DataModel.MapperCollection(data.collaborators)
DataModel.Topics = new DataModel.TopicCollection(data.topics)
DataModel.Synapses = new DataModel.SynapseCollection(data.synapses)
DataModel.Mappings = new DataModel.MappingCollection(data.mappings)
DataModel.Messages = data.messages
DataModel.Stars = data.stars
DataModel.attachCollectionEvents()
self.requests = data.requests
isLoaded()
}
})
}
},
end: function() {
if (Active.Map) {
$('.main').removeClass('compressed')
AutoLayout.resetSpiral()
$('.rightclickmenu').remove()
TopicCard.hideCard()
SynapseCard.hideCard()
Create.newTopic.hide(true) // true means force (and override pinned)
Create.newSynapse.hide()
InfoBox.close()
Realtime.endActiveMap()
self.requests = []
self.hasLearnedTopicCreation = true
}
},
star: function() { star: function() {
var self = Map var self = toExport
if (!Active.Map) return if (!Active.Map) return
$.post('/maps/' + Active.Map.id + '/star') $.post('/maps/' + Active.Map.id + '/star')
@ -193,7 +216,7 @@ const Map = {
ReactApp.render() ReactApp.render()
}, },
unstar: function() { unstar: function() {
var self = Map var self = toExport
if (!Active.Map) return if (!Active.Map) return
$.post('/maps/' + Active.Map.id + '/unstar') $.post('/maps/' + Active.Map.id + '/unstar')
@ -272,8 +295,8 @@ const Map = {
} }
}, },
offerScreenshotDownload: () => { offerScreenshotDownload: () => {
const canvas = Map.getMapCanvasForScreenshots() const canvas = toExport.getMapCanvasForScreenshots()
const filename = Map.getMapScreenshotFilename(Active.Map) const filename = toExport.getMapScreenshotFilename(Active.Map)
var downloadMessage = outdent` var downloadMessage = outdent`
Captured map screenshot! Captured map screenshot!
@ -286,8 +309,8 @@ const Map = {
GlobalUI.notifyUser(downloadMessage) GlobalUI.notifyUser(downloadMessage)
}, },
uploadMapScreenshot: () => { uploadMapScreenshot: () => {
const canvas = Map.getMapCanvasForScreenshots() const canvas = toExport.getMapCanvasForScreenshots()
const filename = Map.getMapScreenshotFilename(Active.Map) const filename = toExport.getMapScreenshotFilename(Active.Map)
canvas.canvas.toBlob(imageBlob => { canvas.canvas.toBlob(imageBlob => {
const formData = new window.FormData() const formData = new window.FormData()
@ -414,6 +437,11 @@ const Map = {
return filename return filename
} }
} }
return toExport
}
Map.events = {
editedByActiveMapper: 'Metamaps:Map:events:editedByActiveMapper'
}
export { CheatSheet, InfoBox } export { CheatSheet }
export default Map export default Map

View file

@ -1,4 +1,5 @@
const Mouse = { const Mouse = () => {
return {
didPan: false, didPan: false,
didBoxZoom: false, didBoxZoom: false,
changeInX: 0, changeInX: 0,
@ -12,5 +13,6 @@ const Mouse = {
lastCanvasClick: 0, lastCanvasClick: 0,
DOUBLE_CLICK_TOLERANCE: 300 DOUBLE_CLICK_TOLERANCE: 300
} }
}
export default Mouse export default Mouse

View file

@ -2,10 +2,8 @@ import _ from 'lodash'
import $jit from '../patched/JIT' import $jit from '../patched/JIT'
import Visualize from './Visualize' const Organize = ({Visualize, JIT}) => {
import JIT from './JIT' const toExport = {
const Organize = {
arrange: function(layout, centerNode) { arrange: function(layout, centerNode) {
// first option for layout to implement is 'grid', will do an evenly spaced grid with its center at the 0,0 origin // first option for layout to implement is 'grid', will do an evenly spaced grid with its center at the 0,0 origin
if (layout === 'grid') { if (layout === 'grid') {
@ -112,5 +110,7 @@ const Organize = {
} }
} }
} }
return toExport
}
export default Organize export default Organize

View file

@ -1,16 +1,15 @@
/* global $ */ /* global $ */
import Import from './Import'
import Util from './Util' import Util from './Util'
import Visualize from './Visualize'
const PasteInput = { const PasteInput = ({Import, Visualize}) => {
const toReturn = {
// thanks to https://github.com/kevva/url-regex // thanks to https://github.com/kevva/url-regex
// eslint-disable-next-line no-useless-escape // eslint-disable-next-line no-useless-escape
URL_REGEX: new RegExp('^(?:(?:(?:[a-z]+:)?//)|www\.)(?:\S+(?::\S*)?@)?(?:localhost|(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#][^\s"]*)?$'), URL_REGEX: new RegExp('^(?:(?:(?:[a-z]+:)?//)|www\.)(?:\S+(?::\S*)?@)?(?:localhost|(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#][^\s"]*)?$'),
init: function() { init: function() {
var self = PasteInput var self = toReturn
// intercept dragged files // intercept dragged files
// see http://stackoverflow.com/questions/6756583 // see http://stackoverflow.com/questions/6756583
@ -50,7 +49,7 @@ const PasteInput = {
}, },
handleFile: (file, coords = null) => { handleFile: (file, coords = null) => {
var self = PasteInput var self = toReturn
var fileReader = new window.FileReader() var fileReader = new window.FileReader()
fileReader.readAsText(file) fileReader.readAsText(file)
fileReader.onload = function(e) { fileReader.onload = function(e) {
@ -64,7 +63,7 @@ const PasteInput = {
}, },
handle: function(text, coords = {}) { handle: function(text, coords = {}) {
var self = PasteInput var self = toReturn
if (text.match(self.URL_REGEX)) { if (text.match(self.URL_REGEX)) {
Import.handleURL(text, coords) Import.handleURL(text, coords)
@ -78,5 +77,7 @@ const PasteInput = {
} }
} }
} }
return toReturn
}
export default PasteInput export default PasteInput

View file

@ -3,13 +3,8 @@
import SimpleWebRTC from 'simplewebrtc' import SimpleWebRTC from 'simplewebrtc'
import SocketIoConnection from 'simplewebrtc/socketioconnection' import SocketIoConnection from 'simplewebrtc/socketioconnection'
import Active from '../Active'
import Cable from '../Cable'
import DataModel from '../DataModel'
import JIT from '../JIT'
import Util from '../Util' import Util from '../Util'
import Views, { ChatView } from '../Views' import Views from '../Views'
import Visualize from '../Visualize'
import { import {
JUNTO_UPDATED, JUNTO_UPDATED,
@ -63,8 +58,8 @@ import {
dragTopic dragTopic
} from './sendable' } from './sendable'
let Realtime = { const Realtime = ({Active, Cable, DataModel, JIT, Visualize}) => {
juntoState: { connectedPeople: {}, liveMaps: {} }, const toExport = {
videoId: 'video-wrapper', videoId: 'video-wrapper',
socket: null, socket: null,
webrtc: null, webrtc: null,
@ -78,7 +73,7 @@ let Realtime = {
localVideo: null, localVideo: null,
'junto_spinner_darkgrey.gif': '', 'junto_spinner_darkgrey.gif': '',
init: function(serverData) { init: function(serverData) {
var self = Realtime var self = toExport
self.addJuntoListeners() self.addJuntoListeners()
@ -154,7 +149,7 @@ let Realtime = {
} // if Active.Mapper } // if Active.Mapper
}, },
addJuntoListeners: function() { addJuntoListeners: function() {
var self = Realtime var self = toExport
$(document).on(ChatView.events.openTray, function() { $(document).on(ChatView.events.openTray, function() {
$('.main').addClass('compressed') $('.main').addClass('compressed')
@ -180,7 +175,7 @@ let Realtime = {
}) })
}, },
startActiveMap: function() { startActiveMap: function() {
var self = Realtime var self = toExport
if (Active.Map && Active.Mapper) { if (Active.Map && Active.Mapper) {
if (Active.Map.authorizeToEdit(Active.Mapper)) { if (Active.Map.authorizeToEdit(Active.Mapper)) {
self.turnOn() self.turnOn()
@ -192,7 +187,7 @@ let Realtime = {
} }
}, },
endActiveMap: function() { endActiveMap: function() {
var self = Realtime var self = toExport
$(document).off('.map') $(document).off('.map')
// leave the appropriate rooms to leave // leave the appropriate rooms to leave
if (self.inConversation) self.leaveCall() if (self.inConversation) self.leaveCall()
@ -202,7 +197,7 @@ let Realtime = {
Cable.unsubscribeFromMap() Cable.unsubscribeFromMap()
}, },
turnOn: function(notify) { turnOn: function(notify) {
var self = Realtime var self = toExport
$('.collabCompass').show() $('.collabCompass').show()
self.room.room = 'map-' + Active.Map.id self.room.room = 'map-' + Active.Map.id
self.activeMapper = { self.activeMapper = {
@ -219,13 +214,13 @@ let Realtime = {
self.setupLocalEvents() self.setupLocalEvents()
}, },
setupChat: function() { setupChat: function() {
const self = Realtime const self = toExport
ChatView.setNewMap() ChatView.setNewMap()
ChatView.addParticipant(self.activeMapper) ChatView.addParticipant(self.activeMapper)
ChatView.addMessages(new DataModel.MessageCollection(DataModel.Messages), true) ChatView.addMessages(new DataModel.MessageCollection(DataModel.Messages), true)
}, },
setupLocalEvents: function() { setupLocalEvents: function() {
var self = Realtime var self = toExport
// local event listeners that trigger events // local event listeners that trigger events
$(document).on(JIT.events.zoom + '.map', self.positionPeerIcons) $(document).on(JIT.events.zoom + '.map', self.positionPeerIcons)
$(document).on(JIT.events.pan + '.map', self.positionPeerIcons) $(document).on(JIT.events.pan + '.map', self.positionPeerIcons)
@ -242,7 +237,7 @@ let Realtime = {
}) })
}, },
countOthersInConversation: function() { countOthersInConversation: function() {
var self = Realtime var self = toExport
var count = 0 var count = 0
for (var key in self.mappersOnMap) { for (var key in self.mappersOnMap) {
if (self.mappersOnMap[key].inConversation) count++ if (self.mappersOnMap[key].inConversation) count++
@ -250,7 +245,7 @@ let Realtime = {
return count return count
}, },
handleVideoAdded: function(v, id) { handleVideoAdded: function(v, id) {
var self = Realtime var self = toExport
self.positionVideos() self.positionVideos()
v.setParent($('#wrapper')) v.setParent($('#wrapper'))
v.$container.find('.video-cutoff').css({ v.$container.find('.video-cutoff').css({
@ -259,7 +254,7 @@ let Realtime = {
$('#wrapper').append(v.$container) $('#wrapper').append(v.$container)
}, },
positionVideos: function() { positionVideos: function() {
var self = Realtime var self = toExport
var videoIds = Object.keys(self.room.videos) var videoIds = Object.keys(self.room.videos)
// var numOfVideos = videoIds.length // var numOfVideos = videoIds.length
// var numOfVideosToPosition = _.filter(videoIds, function(id) { // var numOfVideosToPosition = _.filter(videoIds, function(id) {
@ -290,7 +285,7 @@ let Realtime = {
} }
// do self first // do self first
var myVideo = Realtime.localVideo.view var myVideo = toExport.localVideo.view
if (!myVideo.manuallyPositioned) { if (!myVideo.manuallyPositioned) {
myVideo.$container.css({ myVideo.$container.css({
top: yFormula() + 'px', top: yFormula() + 'px',
@ -308,7 +303,7 @@ let Realtime = {
}) })
}, },
callEnded: function() { callEnded: function() {
var self = Realtime var self = toExport
ChatView.conversationEnded() ChatView.conversationEnded()
self.room.leaveVideoOnly() self.room.leaveVideoOnly()
@ -336,13 +331,13 @@ let Realtime = {
}) })
}, },
positionPeerIcons: function() { positionPeerIcons: function() {
var self = Realtime var self = toExport
for (var key in self.mappersOnMap) { for (var key in self.mappersOnMap) {
self.positionPeerIcon(key) self.positionPeerIcon(key)
} }
}, },
positionPeerIcon: function(id) { positionPeerIcon: function(id) {
var self = Realtime var self = toExport
var mapper = self.mappersOnMap[id] var mapper = self.mappersOnMap[id]
var origPixels = Util.coordsToPixels(Visualize.mGraph, mapper.coords) var origPixels = Util.coordsToPixels(Visualize.mGraph, mapper.coords)
@ -371,7 +366,7 @@ let Realtime = {
} }
}, },
limitPixelsToScreen: function(pixels) { limitPixelsToScreen: function(pixels) {
var self = Realtime var self = toExport
var boundary = self.chatOpen ? '#wrapper' : document var boundary = self.chatOpen ? '#wrapper' : document
var xLimit, yLimit var xLimit, yLimit
@ -405,25 +400,28 @@ const sendables = [
['dragTopic', dragTopic] ['dragTopic', dragTopic]
] ]
sendables.forEach(sendable => { sendables.forEach(sendable => {
Realtime[sendable[0]] = sendable[1](Realtime) toExport[sendable[0]] = sendable[1](toExport)
}) })
const subscribeToEvents = (Realtime, socket) => { const subscribeToEvents = (toExport, socket) => {
socket.on(JUNTO_UPDATED, juntoUpdated(Realtime)) socket.on(JUNTO_UPDATED, juntoUpdated(toExport))
socket.on(INVITED_TO_CALL, invitedToCall(Realtime)) socket.on(INVITED_TO_CALL, invitedToCall(toExport))
socket.on(INVITED_TO_JOIN, invitedToJoin(Realtime)) socket.on(INVITED_TO_JOIN, invitedToJoin(toExport))
socket.on(CALL_ACCEPTED, callAccepted(Realtime)) socket.on(CALL_ACCEPTED, callAccepted(toExport))
socket.on(CALL_DENIED, callDenied(Realtime)) socket.on(CALL_DENIED, callDenied(toExport))
socket.on(INVITE_DENIED, inviteDenied(Realtime)) socket.on(INVITE_DENIED, inviteDenied(toExport))
socket.on(CALL_IN_PROGRESS, callInProgress(Realtime)) socket.on(CALL_IN_PROGRESS, callInProgress(toExport))
socket.on(CALL_STARTED, callStarted(Realtime)) socket.on(CALL_STARTED, callStarted(toExport))
socket.on(MAPPER_LIST_UPDATED, mapperListUpdated(Realtime)) socket.on(MAPPER_LIST_UPDATED, mapperListUpdated(toExport))
socket.on(MAPPER_JOINED_CALL, mapperJoinedCall(Realtime)) socket.on(MAPPER_JOINED_CALL, mapperJoinedCall(toExport))
socket.on(MAPPER_LEFT_CALL, mapperLeftCall(Realtime)) socket.on(MAPPER_LEFT_CALL, mapperLeftCall(toExport))
socket.on(PEER_COORDS_UPDATED, peerCoordsUpdated(Realtime)) socket.on(PEER_COORDS_UPDATED, peerCoordsUpdated(toExport))
socket.on(NEW_MAPPER, newMapper(Realtime)) socket.on(NEW_MAPPER, newMapper(toExport))
socket.on(LOST_MAPPER, lostMapper(Realtime)) socket.on(LOST_MAPPER, lostMapper(toExport))
socket.on(TOPIC_DRAGGED, topicDragged(Realtime)) socket.on(TOPIC_DRAGGED, topicDragged(toExport))
}
return toExport
} }
export default Realtime export default Realtime

View file

@ -9,12 +9,12 @@ import { JUNTO_UPDATED } from './events'
import Active from '../Active' import Active from '../Active'
import { ChatView } from '../Views' import { ChatView } from '../Views'
import DataModel from '../DataModel' import DataModel from '../DataModel'
import GlobalUI from '../GlobalUI' import GlobalUI, { ReactApp } from '../GlobalUI'
import Util from '../Util' import Util from '../Util'
import Visualize from '../Visualize' import Visualize from '../Visualize'
export const juntoUpdated = self => state => { export const juntoUpdated = self => state => {
self.juntoState = state ReactApp.juntoState = state
$(document).trigger(JUNTO_UPDATED) $(document).trigger(JUNTO_UPDATED)
} }

View file

@ -1,11 +1,14 @@
const Selected = { const Selected = () => {
const toExport = {
reset: function() { reset: function() {
var self = Selected var self = toExport
self.Nodes = [] self.Nodes = []
self.Edges = [] self.Edges = []
}, },
Nodes: [], Nodes: [],
Edges: [] Edges: []
} }
return toExport
}
export default Selected export default Selected

View file

@ -1,17 +1,11 @@
/* global $ */ /* global $ */
import Active from './Active'
import Control from './Control'
import Create from './Create'
import DataModel from './DataModel'
import Map from './Map'
import Selected from './Selected'
import Settings from './Settings' import Settings from './Settings'
import Visualize from './Visualize'
const noOp = () => {} const noOp = () => {}
const Synapse = { const Synapse = ({Active, Control, Create, DataModel, Map, Selected, Visualize}) => {
const toExport = {
// this function is to retrieve a synapse JSON object from the database // this function is to retrieve a synapse JSON object from the database
// @param id = the id of the synapse to retrieve // @param id = the id of the synapse to retrieve
get: function(id, callback = noOp) { get: function(id, callback = noOp) {
@ -77,7 +71,7 @@ const Synapse = {
} }
}, },
createSynapseLocally: function() { createSynapseLocally: function() {
var self = Synapse var self = toExport
let topic1 let topic1
let topic2 let topic2
let node1 let node1
@ -124,7 +118,7 @@ const Synapse = {
Create.newSynapse.hide() Create.newSynapse.hide()
}, },
getSynapseFromAutocomplete: function(id) { getSynapseFromAutocomplete: function(id) {
var self = Synapse var self = toExport
self.get(id, synapse => { self.get(id, synapse => {
const mapping = new DataModel.Mapping({ const mapping = new DataModel.Mapping({
@ -141,5 +135,7 @@ const Synapse = {
}) })
} }
} }
return toExport
}
export default Synapse export default Synapse

View file

@ -1,13 +1,11 @@
/* global $ */ /* global $ */
import Active from './Active'
import Control from './Control'
import Mapper from './Mapper' import Mapper from './Mapper'
import Visualize from './Visualize'
const SynapseCard = { const SynapseCard = ({Active, Control, Visualize}) => {
const toExport = {
openSynapseCard: null, openSynapseCard: null,
showCard: function(edge, e) { showCard: function(edge, e) {
var self = SynapseCard var self = toExport
// reset so we don't interfere with other edges, but first, save its x and y // reset so we don't interfere with other edges, but first, save its x and y
var myX = $('#edit_synapse').css('left') var myX = $('#edit_synapse').css('left')
@ -53,11 +51,11 @@ const SynapseCard = {
hideCard: function() { hideCard: function() {
$('#edit_synapse').remove() $('#edit_synapse').remove()
SynapseCard.openSynapseCard = null toExport.openSynapseCard = null
}, },
populateShowCard: function(edge, synapse) { populateShowCard: function(edge, synapse) {
var self = SynapseCard var self = toExport
self.add_synapse_count(edge) self.add_synapse_count(edge)
self.add_desc_form(synapse) self.add_desc_form(synapse)
@ -156,7 +154,7 @@ const SynapseCard = {
var index = parseInt($(this).attr('data-synapse-index')) var index = parseInt($(this).attr('data-synapse-index'))
edge.setData('displayIndex', index) edge.setData('displayIndex', index)
Visualize.mGraph.plot() Visualize.mGraph.plot()
SynapseCard.showCard(edge, false) toExport.showCard(edge, false)
}) })
} }
}, },
@ -291,5 +289,7 @@ const SynapseCard = {
} // if } // if
} // add_direction_form } // add_direction_form
} }
return toExport
}
export default SynapseCard export default SynapseCard

View file

@ -2,27 +2,15 @@
import $jit from '../patched/JIT' import $jit from '../patched/JIT'
import Active from './Active'
import AutoLayout from './AutoLayout'
import Create from './Create'
import DataModel from './DataModel'
import Filter from './Filter'
import GlobalUI, { ReactApp } from './GlobalUI' import GlobalUI, { ReactApp } from './GlobalUI'
import JIT from './JIT'
import Loading from './Loading' import Loading from './Loading'
import Map from './Map'
import Selected from './Selected'
import Settings from './Settings' import Settings from './Settings'
import SynapseCard from './SynapseCard'
import TopicCard from './Views/TopicCard'
import Util from './Util' import Util from './Util'
import Visualize from './Visualize'
const noOp = () => {} const noOp = () => {}
const Topic = { const Topic = ({Active, AutoLayout, Create, DataModel, Filter, JIT, MAP, Selected, SynapseCard, TopicCard, Visualize}) => {
// this function is to retrieve a topic JSON object from the database const toExport = {
// @param id = the id of the topic to retrieve
get: function(id, callback = noOp) { get: function(id, callback = noOp) {
// if the desired topic is not yet in the local topic repository, fetch it // if the desired topic is not yet in the local topic repository, fetch it
if (DataModel.Topics.get(id) === undefined) { if (DataModel.Topics.get(id) === undefined) {
@ -101,7 +89,7 @@ const Topic = {
ReactApp.render() ReactApp.render()
}, },
fetchRelatives: function(nodes, metacodeId) { fetchRelatives: function(nodes, metacodeId) {
var self = this var self = toExport
var node = $.isArray(nodes) ? nodes[0] : nodes var node = $.isArray(nodes) ? nodes[0] : nodes
@ -292,7 +280,7 @@ const Topic = {
} }
}, },
createTopicLocally: function() { createTopicLocally: function() {
var self = Topic var self = toExport
if (Create.newTopic.name === '') { if (Create.newTopic.name === '') {
GlobalUI.notifyUser('Please enter a topic title...') GlobalUI.notifyUser('Please enter a topic title...')
@ -330,7 +318,7 @@ const Topic = {
self.renderTopic(mapping, topic, true, true) // this function also includes the creation of the topic in the database self.renderTopic(mapping, topic, true, true) // this function also includes the creation of the topic in the database
}, },
getTopicFromAutocomplete: function(id) { getTopicFromAutocomplete: function(id) {
var self = Topic var self = toExport
Map.setHasLearnedTopicCreation(true) Map.setHasLearnedTopicCreation(true)
@ -357,7 +345,7 @@ const Topic = {
}) })
}, },
getMapFromAutocomplete: function(data) { getMapFromAutocomplete: function(data) {
var self = Topic var self = toExport
$(document).trigger(Map.events.editedByActiveMapper) $(document).trigger(Map.events.editedByActiveMapper)
@ -387,7 +375,7 @@ const Topic = {
if (Create.newTopic.pinned) Create.newTopic.beingCreated = true if (Create.newTopic.pinned) Create.newTopic.beingCreated = true
}, },
getTopicFromSearch: function(event, id) { getTopicFromSearch: function(event, id) {
var self = Topic var self = toExport
$(document).trigger(Map.events.editedByActiveMapper) $(document).trigger(Map.events.editedByActiveMapper)
@ -409,5 +397,7 @@ const Topic = {
return false return false
} }
} }
return toExport
}
export default Topic export default Topic

View file

@ -3,18 +3,17 @@
import Backbone from 'backbone' import Backbone from 'backbone'
import { Howl } from 'howler' import { Howl } from 'howler'
import Active from '../Active'
import DataModel from '../DataModel'
import ReactApp from '../GlobalUI/ReactApp' import ReactApp from '../GlobalUI/ReactApp'
const ChatView = { const ChatView = ({Active, DataModel}) => {
const toExport = {
isOpen: false, isOpen: false,
unreadMessages: 0, unreadMessages: 0,
messages: new Backbone.Collection(), messages: new Backbone.Collection(),
conversationLive: false, conversationLive: false,
isParticipating: false, isParticipating: false,
init: function(urls) { init: function(urls) {
const self = ChatView const self = toExport
self.sound = new Howl({ self.sound = new Howl({
src: urls, src: urls,
sprite: { sprite: {
@ -27,7 +26,7 @@ const ChatView = {
}) })
}, },
setNewMap: function() { setNewMap: function() {
const self = ChatView const self = toExport
self.unreadMessages = 0 self.unreadMessages = 0
self.isOpen = false self.isOpen = false
self.conversationLive = false self.conversationLive = false
@ -41,74 +40,74 @@ const ChatView = {
}, },
render: () => { render: () => {
if (!Active.Map) return if (!Active.Map) return
const self = ChatView const self = toExport
ReactApp.render() ReactApp.render()
}, },
onOpen: () => { onOpen: () => {
const self = ChatView const self = toExport
self.isOpen = true self.isOpen = true
self.unreadMessages = 0 self.unreadMessages = 0
self.render() self.render()
$(document).trigger(ChatView.events.openTray) $(document).trigger(ChatView.events.openTray)
}, },
onClose: () => { onClose: () => {
const self = ChatView const self = toExport
self.isOpen = false self.isOpen = false
$(document).trigger(ChatView.events.closeTray) $(document).trigger(ChatView.events.closeTray)
}, },
addParticipant: participant => { addParticipant: participant => {
ChatView.participants.add(participant) toExport.participants.add(participant)
ChatView.render() toExport.render()
}, },
removeParticipant: participant => { removeParticipant: participant => {
ChatView.participants.remove(participant) toExport.participants.remove(participant)
ChatView.render() toExport.render()
}, },
leaveConversation: () => { leaveConversation: () => {
ChatView.isParticipating = false toExport.isParticipating = false
ChatView.render() toExport.render()
}, },
mapperJoinedCall: id => { mapperJoinedCall: id => {
const mapper = ChatView.participants.findWhere({id}) const mapper = toExport.participants.findWhere({id})
mapper && mapper.set('isParticipating', true) mapper && mapper.set('isParticipating', true)
ChatView.render() toExport.render()
}, },
mapperLeftCall: id => { mapperLeftCall: id => {
const mapper = ChatView.participants.findWhere({id}) const mapper = toExport.participants.findWhere({id})
mapper && mapper.set('isParticipating', false) mapper && mapper.set('isParticipating', false)
ChatView.render() toExport.render()
}, },
invitationPending: id => { invitationPending: id => {
const mapper = ChatView.participants.findWhere({id}) const mapper = toExport.participants.findWhere({id})
mapper && mapper.set('isPending', true) mapper && mapper.set('isPending', true)
ChatView.render() toExport.render()
}, },
invitationAnswered: id => { invitationAnswered: id => {
const mapper = ChatView.participants.findWhere({id}) const mapper = toExport.participants.findWhere({id})
mapper && mapper.set('isPending', false) mapper && mapper.set('isPending', false)
ChatView.render() toExport.render()
}, },
conversationInProgress: participating => { conversationInProgress: participating => {
ChatView.conversationLive = true toExport.conversationLive = true
ChatView.isParticipating = participating toExport.isParticipating = participating
ChatView.render() toExport.render()
}, },
conversationEnded: () => { conversationEnded: () => {
ChatView.conversationLive = false toExport.conversationLive = false
ChatView.isParticipating = false toExport.isParticipating = false
ChatView.participants.forEach(p => p.set({isParticipating: false, isPending: false})) toExport.participants.forEach(p => p.set({isParticipating: false, isPending: false}))
ChatView.render() toExport.render()
}, },
videoToggleClick: function() { videoToggleClick: function() {
ChatView.videosShowing = !ChatView.videosShowing toExport.videosShowing = !toExport.videosShowing
$(document).trigger(ChatView.videosShowing ? ChatView.events.videosOn : ChatView.events.videosOff) $(document).trigger(toExport.videosShowing ? ChatView.events.videosOn : ChatView.events.videosOff)
}, },
cursorToggleClick: function() { cursorToggleClick: function() {
ChatView.cursorsShowing = !ChatView.cursorsShowing toExport.cursorsShowing = !toExport.cursorsShowing
$(document).trigger(ChatView.cursorsShowing ? ChatView.events.cursorsOn : ChatView.events.cursorsOff) $(document).trigger(toExport.cursorsShowing ? ChatView.events.cursorsOn : ChatView.events.cursorsOff)
}, },
soundToggleClick: function() { soundToggleClick: function() {
ChatView.alertSound = !ChatView.alertSound toExport.alertSound = !toExport.alertSound
}, },
inputFocus: () => { inputFocus: () => {
$(document).trigger(ChatView.events.inputFocus) $(document).trigger(ChatView.events.inputFocus)
@ -117,15 +116,15 @@ const ChatView = {
$(document).trigger(ChatView.events.inputBlur) $(document).trigger(ChatView.events.inputBlur)
}, },
addMessage: (message, isInitial, wasMe) => { addMessage: (message, isInitial, wasMe) => {
const self = ChatView 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) self.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 = ChatView var self = toExport
if (ChatView.alertSound) ChatView.sound.play('sendchat') if (toExport.alertSound) toExport.sound.play('sendchat')
var m = new DataModel.Message({ var m = new DataModel.Message({
message: message.message, message: message.message,
resource_id: Active.Map.id, resource_id: Active.Map.id,
@ -141,14 +140,16 @@ const ChatView = {
}) })
}, },
handleInputMessage: text => { handleInputMessage: text => {
ChatView.sendChatMessage({message: text}) toExport.sendChatMessage({message: text})
}, },
// they should be instantiated as backbone models before they get // they should be instantiated as backbone models before they get
// passed to this function // passed to this function
addMessages: (messages, isInitial, wasMe) => { addMessages: (messages, isInitial, wasMe) => {
messages.models.forEach(m => ChatView.addMessage(m, isInitial, wasMe)) messages.models.forEach(m => toExport.addMessage(m, isInitial, wasMe))
} }
} }
return toExport
}
/** /**
* @class * @class

View file

@ -1,15 +1,18 @@
import { ReactApp } from '../GlobalUI' import { ReactApp } from '../GlobalUI'
const TopicCard = { const TopicCard = () => {
const toExport = {
openTopic: null, openTopic: null,
showCard: function(node) { showCard: function(node) {
TopicCard.openTopic = node.getData('topic') toExport.openTopic = node.getData('topic')
ReactApp.render() ReactApp.render()
}, },
hideCard: function() { hideCard: function() {
TopicCard.openTopic = null toExport.openTopic = null
ReactApp.render() ReactApp.render()
} }
} }
return toExport
}
export default TopicCard export default TopicCard

View file

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

View file

@ -10,14 +10,15 @@ import JIT from './JIT'
import Loading from './Loading' import Loading from './Loading'
import TopicCard from './Views/TopicCard' import TopicCard from './Views/TopicCard'
const Visualize = { const Visualize = ({Active, DataModel, JIT, TopicCard}) => {
const toExport = {
mGraph: null, // a reference to the graph object. mGraph: null, // a reference to the graph object.
cameraPosition: null, // stores the camera position when using a 3D visualization cameraPosition: null, // stores the camera position when using a 3D visualization
type: 'ForceDirected', // the type of graph we're building, could be "RGraph", "ForceDirected", or "ForceDirected3D" type: 'ForceDirected', // the type of graph we're building, could be "RGraph", "ForceDirected", or "ForceDirected3D"
loadLater: false, // indicates whether there is JSON that should be loaded right in the offset, or whether to wait till the first topic is created loadLater: false, // indicates whether there is JSON that should be loaded right in the offset, or whether to wait till the first topic is created
touchDragNode: null, touchDragNode: null,
init: function(serverData) { init: function(serverData) {
var self = Visualize var self = toExport
if (serverData.VisualizeType) self.type = serverData.VisualizeType if (serverData.VisualizeType) self.type = serverData.VisualizeType
@ -45,7 +46,7 @@ const Visualize = {
}) })
}, },
computePositions: function() { computePositions: function() {
const self = Visualize const self = toExport
if (self.type === 'RGraph') { if (self.type === 'RGraph') {
let i let i
@ -107,7 +108,7 @@ const Visualize = {
* *
*/ */
render: function() { render: function() {
const self = Visualize const self = toExport
if (self.type === 'RGraph') { if (self.type === 'RGraph') {
// clear the previous canvas from #infovis // clear the previous canvas from #infovis
@ -199,11 +200,14 @@ const Visualize = {
hold() hold()
}, },
clearVisualization: function() { clearVisualization: function() {
Visualize.mGraph.graph.empty() const self = toExport
Visualize.mGraph.plot() self.mGraph.graph.empty()
self.mGraph.plot()
JIT.centerMap(Visualize.mGraph.canvas) JIT.centerMap(Visualize.mGraph.canvas)
$('#infovis').empty() $('#infovis').empty()
} }
} }
return toExport
}
export default Visualize export default Visualize

View file

@ -1,32 +1,72 @@
import Account from './Account' import Account from './Account'
import Active from './Active' import Active from './Active'
import Admin from './Admin' import Admin from './Admin'
import AutoLayout from './AutoLayout'
import Cable from './Cable'
import Control from './Control'
import Create from './Create'
import DataModel from './DataModel'
import Debug from './Debug' import Debug from './Debug'
import Filter from './Filter'
import GlobalUI, { import GlobalUI, {
ReactApp, Search, CreateMap, ImportDialog ReactApp, Search, CreateMap, ImportDialog
} from './GlobalUI' } from './GlobalUI'
import Import from './Import' import Import from './Import'
import JIT from './JIT'
import Listeners from './Listeners'
import Loading from './Loading' import Loading from './Loading'
import Map, { CheatSheet } from './Map'
import Mapper from './Mapper' import Mapper from './Mapper'
import Mouse from './Mouse'
import Organize from './Organize'
import PasteInput from './PasteInput'
import Realtime from './Realtime'
import Selected from './Selected'
import Settings from './Settings'
import Synapse from './Synapse'
import SynapseCard from './SynapseCard'
import Topic from './Topic' import Topic from './Topic'
import Util from './Util' import Util from './Util'
import Views from './Views'
import Visualize from './Visualize'
const Metamaps = window.Metamaps || {} const Metamaps = window.Metamaps || {}
Metamaps.Account = Account Metamaps.Account = Account
Metamaps.Active = Active Metamaps.Active = Active
Metamaps.Admin = Admin Metamaps.Admin = Admin
Metamaps.AutoLayout = AutoLayout
Metamaps.Cable = Cable
Metamaps.Control = Control
Metamaps.Create = Create
Metamaps.DataModel = DataModel
Metamaps.Debug = Debug Metamaps.Debug = Debug
Metamaps.Filter = Filter
Metamaps.Import = Import
Metamaps.JIT = JIT
Metamaps.Listeners = Listeners
Metamaps.Loading = Loading
Metamaps.Map = Map
Metamaps.Map.CheatSheet = CheatSheet
Metamaps.Maps = {}
Metamaps.Mapper = Mapper
Metamaps.Mouse = Mouse
Metamaps.Organize = Organize
Metamaps.PasteInput = PasteInput
Metamaps.Realtime = Realtime
Metamaps.Selected = Selected
Metamaps.Settings = Settings
Metamaps.Synapse = Synapse
Metamaps.SynapseCard = SynapseCard
Metamaps.Topic = Topic
Metamaps.Util = Util
Metamaps.Views = Views
Metamaps.Visualize = Visualize
Metamaps.GlobalUI = GlobalUI Metamaps.GlobalUI = GlobalUI
Metamaps.GlobalUI.ReactApp = ReactApp Metamaps.GlobalUI.ReactApp = ReactApp
Metamaps.GlobalUI.Search = Search Metamaps.GlobalUI.Search = Search
Metamaps.GlobalUI.CreateMap = CreateMap Metamaps.GlobalUI.CreateMap = CreateMap
Metamaps.GlobalUI.ImportDialog = ImportDialog Metamaps.GlobalUI.ImportDialog = ImportDialog
Metamaps.Import = Import
Metamaps.Loading = Loading
Metamaps.Maps = {}
Metamaps.Mapper = Mapper
Metamaps.Topic = Topic
Metamaps.Util = Util
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
// initialize all the modules // initialize all the modules
@ -37,6 +77,7 @@ 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)
} }
} }