eslint frontend folder (#923)

This commit is contained in:
Devin Howard 2016-11-07 15:25:08 -05:00 committed by GitHub
parent 9df974a037
commit a176cdf231
61 changed files with 1723 additions and 1809 deletions

View file

@ -20,6 +20,7 @@ module.exports = {
"rules": {
"react/jsx-uses-react": [2],
"react/jsx-uses-vars": [2],
"space-before-function-paren": [2, "never"],
"yoda": [2, "never", { "exceptRange": true }]
}
}

View file

@ -1,33 +1,33 @@
/* global $, CanvasLoader */
const Account = {
init: function (serverData) {
init: function(serverData) {
Account.userIconUrl = serverData['user.png']
},
listenersInitialized: false,
userIconUrl: null,
initListeners: function () {
initListeners: function() {
var self = Account
$('#user_image').change(self.showImagePreview)
self.listenersInitialized = true
},
toggleChangePicture: function () {
toggleChangePicture: function() {
var self = Account
$('.userImageMenu').toggle()
if (!self.listenersInitialized) self.initListeners()
},
openChangePicture: function () {
openChangePicture: function() {
var self = Account
$('.userImageMenu').show()
if (!self.listenersInitialized) self.initListeners()
},
closeChangePicture: function () {
closeChangePicture: function() {
$('.userImageMenu').hide()
},
showLoading: function () {
showLoading: function() {
var loader = new CanvasLoader('accountPageLoading')
loader.setColor('#4FC059') // default is '#000000'
loader.setDiameter(28) // default is 40
@ -36,12 +36,12 @@ const Account = {
loader.show() // Hidden by default
$('#accountPageLoading').show()
},
showImagePreview: function () {
showImagePreview: function() {
var file = $('#user_image')[0].files[0]
var reader = new window.FileReader()
reader.onload = function (e) {
reader.onload = function(e) {
var $canvas = $('<canvas>').attr({
width: 84,
height: 84
@ -49,7 +49,7 @@ const Account = {
var context = $canvas[0].getContext('2d')
var imageObj = new window.Image()
imageObj.onload = function () {
imageObj.onload = function() {
$('.userImageDiv canvas').remove()
$('.userImageDiv img').hide()
@ -80,7 +80,7 @@ const Account = {
$('#remove_image').val('0')
}
},
removePicture: function () {
removePicture: function() {
var self = Account
$('.userImageDiv canvas').remove()
@ -91,15 +91,15 @@ const Account = {
input.replaceWith(input.val('').clone(true))
$('#remove_image').val('1')
},
changeName: function () {
changeName: function() {
$('.accountName').hide()
$('.changeName').show()
},
showPass: function () {
showPass: function() {
$('.toHide').show()
$('.changePass').hide()
},
hidePass: function () {
hidePass: function() {
$('.toHide').hide()
$('.changePass').show()

View file

@ -3,44 +3,43 @@
const Admin = {
selectMetacodes: [],
allMetacodes: [],
init: function () {
init: function() {
var self = Admin
$('#metacodes_value').val(self.selectMetacodes.toString())
},
selectAll: function () {
selectAll: function() {
var self = Admin
$('.editMetacodes li').removeClass('toggledOff')
self.selectMetacodes = self.allMetacodes.slice(0)
$('#metacodes_value').val(self.selectMetacodes.toString())
},
deselectAll: function () {
deselectAll: function() {
var self = Admin
$('.editMetacodes li').addClass('toggledOff')
self.selectMetacodes = []
$('#metacodes_value').val(0)
},
liClickHandler: function () {
liClickHandler: function() {
var self = Admin
if ($(this).attr('class') != 'toggledOff') {
if ($(this).attr('class') !== 'toggledOff') {
$(this).addClass('toggledOff')
var value_to_remove = $(this).attr('id')
self.selectMetacodes.splice(self.selectMetacodes.indexOf(value_to_remove), 1)
const valueToRemove = $(this).attr('id')
self.selectMetacodes.splice(self.selectMetacodes.indexOf(valueToRemove), 1)
$('#metacodes_value').val(self.selectMetacodes.toString())
}
else if ($(this).attr('class') == 'toggledOff') {
} else if ($(this).attr('class') === 'toggledOff') {
$(this).removeClass('toggledOff')
self.selectMetacodes.push($(this).attr('id'))
$('#metacodes_value').val(self.selectMetacodes.toString())
}
},
validate: function () {
validate: function() {
var self = Admin
if (self.selectMetacodes.length == 0) {
if (self.selectMetacodes.length === 0) {
window.alert('Would you pretty please select at least one metacode for the set?')
return false
}

View file

@ -7,7 +7,7 @@ const AutoLayout = {
nextYshift: 0,
timeToTurn: 0,
getNextCoord: function (opts = {}) {
getNextCoord: function(opts = {}) {
var self = AutoLayout
var nextX = self.nextX
var nextY = self.nextY
@ -28,22 +28,19 @@ const AutoLayout = {
self.timeToTurn = 0
// going right? turn down
if (self.nextXshift == 1 && self.nextYshift == 0) {
if (self.nextXshift === 1 && self.nextYshift === 0) {
self.nextXshift = 0
self.nextYshift = 1
}
// going down? turn left
else if (self.nextXshift == 0 && self.nextYshift == 1) {
} else if (self.nextXshift === 0 && self.nextYshift === 1) {
// going down? turn left
self.nextXshift = -1
self.nextYshift = 0
}
// going left? turn up
else if (self.nextXshift == -1 && self.nextYshift == 0) {
} else if (self.nextXshift === -1 && self.nextYshift === 0) {
// going left? turn up
self.nextXshift = 0
self.nextYshift = -1
}
// going up? turn right
else if (self.nextXshift == 0 && self.nextYshift == -1) {
} else if (self.nextXshift === 0 && self.nextYshift === -1) {
// going up? turn right
self.nextXshift = 1
self.nextYshift = 0
}
@ -59,14 +56,14 @@ const AutoLayout = {
}
}
},
coordsTaken: function (x, y, mappings) {
coordsTaken: function(x, y, mappings) {
if (mappings.findWhere({ xloc: x, yloc: y })) {
return true
} else {
return false
}
},
resetSpiral: function () {
resetSpiral: function() {
var self = AutoLayout
self.nextX = 0
self.nextY = 0

View file

@ -14,16 +14,16 @@ import Settings from './Settings'
import Visualize from './Visualize'
const Control = {
init: function () {},
selectNode: function (node, e) {
init: function() {},
selectNode: function(node, e) {
var filtered = node.getData('alpha') === 0
if (filtered || Selected.Nodes.indexOf(node) != -1) return
if (filtered || Selected.Nodes.indexOf(node) !== -1) return
node.selected = true
node.setData('dim', 30, 'current')
Selected.Nodes.push(node)
},
deselectAllNodes: function () {
deselectAllNodes: function() {
var l = Selected.Nodes.length
for (var i = l - 1; i >= 0; i -= 1) {
var node = Selected.Nodes[i]
@ -31,7 +31,7 @@ const Control = {
}
Visualize.mGraph.plot()
},
deselectNode: function (node) {
deselectNode: function(node) {
delete node.selected
node.setData('dim', 25, 'current')
@ -39,7 +39,7 @@ const Control = {
Selected.Nodes.splice(
Selected.Nodes.indexOf(node), 1)
},
deleteSelected: function () {
deleteSelected: function() {
if (!Active.Map) return
var n = Selected.Nodes.length
@ -67,7 +67,7 @@ const Control = {
GlobalUI.showDiv('#instructions')
}
},
deleteSelectedNodes: function () { // refers to deleting topics permanently
deleteSelectedNodes: function() { // refers to deleting topics permanently
if (!Active.Map) return
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
@ -83,7 +83,7 @@ const Control = {
Control.deleteNode(node.id)
}
},
deleteNode: function (nodeid) { // refers to deleting topics permanently
deleteNode: function(nodeid) { // refers to deleting topics permanently
if (!Active.Map) return
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
@ -110,7 +110,7 @@ const Control = {
GlobalUI.notifyUser('Only topics you created can be deleted')
}
},
removeSelectedNodes: function () { // refers to removing topics permanently from a map
removeSelectedNodes: function() { // refers to removing topics permanently from a map
if (Active.Topic) {
// hideNode will handle synapses as well
var nodeids = _.map(Selected.Nodes, function(node) {
@ -126,22 +126,20 @@ const Control = {
}
if (!Active.Map) return
var l = Selected.Nodes.length,
i,
node,
authorized = Active.Map.authorizeToEdit(Active.Mapper)
const l = Selected.Nodes.length
const authorized = Active.Map.authorizeToEdit(Active.Mapper)
if (!authorized) {
GlobalUI.notifyUser('Cannot edit Public map.')
return
}
for (i = l - 1; i >= 0; i -= 1) {
node = Selected.Nodes[i]
for (let i = l - 1; i >= 0; i -= 1) {
const node = Selected.Nodes[i]
Control.removeNode(node.id)
}
},
removeNode: function (nodeid) { // refers to removing topics permanently from a map
removeNode: function(nodeid) { // refers to removing topics permanently from a map
if (!Active.Map) return
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
@ -162,24 +160,21 @@ const Control = {
}])
Control.hideNode(nodeid)
},
hideSelectedNodes: function () {
var l = Selected.Nodes.length,
i,
node
for (i = l - 1; i >= 0; i -= 1) {
node = Selected.Nodes[i]
hideSelectedNodes: function() {
const l = Selected.Nodes.length
for (let i = l - 1; i >= 0; i -= 1) {
const node = Selected.Nodes[i]
Control.hideNode(node.id)
}
},
hideNode: function (nodeid) {
hideNode: function(nodeid) {
var node = Visualize.mGraph.graph.getNode(nodeid)
var graph = Visualize.mGraph
Control.deselectNode(node)
node.setData('alpha', 0, 'end')
node.eachAdjacency(function (adj) {
node.eachAdjacency(function(adj) {
adj.setData('alpha', 0, 'end')
})
Visualize.mGraph.fx.animate({
@ -188,9 +183,9 @@ const Control = {
],
duration: 500
})
setTimeout(function () {
setTimeout(function() {
if (nodeid === Visualize.mGraph.root) { // && Visualize.type === "RGraph"
var newroot = _.find(graph.graph.nodes, function (n) { return n.id !== nodeid; })
var newroot = _.find(graph.graph.nodes, function(n) { return n.id !== nodeid })
graph.root = newroot ? newroot.id : null
}
Visualize.mGraph.graph.removeNode(nodeid)
@ -198,10 +193,10 @@ const Control = {
Filter.checkMetacodes()
Filter.checkMappers()
},
selectEdge: function (edge) {
var filtered = edge.getData('alpha') === 0; // don't select if the edge is filtered
selectEdge: function(edge) {
var filtered = edge.getData('alpha') === 0 // don't select if the edge is filtered
if (filtered || Selected.Edges.indexOf(edge) != -1) return
if (filtered || Selected.Edges.indexOf(edge) !== -1) return
var width = Mouse.edgeHoveringOver === edge ? 4 : 2
edge.setDataset('current', {
@ -213,7 +208,7 @@ const Control = {
Selected.Edges.push(edge)
},
deselectAllEdges: function () {
deselectAllEdges: function() {
var l = Selected.Edges.length
for (var i = l - 1; i >= 0; i -= 1) {
var edge = Selected.Edges[i]
@ -221,7 +216,7 @@ const Control = {
}
Visualize.mGraph.plot()
},
deselectEdge: function (edge) {
deselectEdge: function(edge) {
edge.setData('showDesc', false, 'current')
edge.setDataset('current', {
@ -242,10 +237,7 @@ const Control = {
Selected.Edges.splice(
Selected.Edges.indexOf(edge), 1)
},
deleteSelectedEdges: function () { // refers to deleting topics permanently
var edge,
l = Selected.Edges.length
deleteSelectedEdges: function() { // refers to deleting topics permanently
if (!Active.Map) return
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
@ -255,12 +247,13 @@ const Control = {
return
}
for (var i = l - 1; i >= 0; i -= 1) {
edge = Selected.Edges[i]
const l = Selected.Edges.length
for (let i = l - 1; i >= 0; i -= 1) {
const edge = Selected.Edges[i]
Control.deleteEdge(edge)
}
},
deleteEdge: function (edge) {
deleteEdge: function(edge) {
if (!Active.Map) return
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
@ -297,13 +290,11 @@ const Control = {
GlobalUI.notifyUser('Only synapses you created can be deleted')
}
},
removeSelectedEdges: function () {
removeSelectedEdges: function() {
// Topic view is handled by removeSelectedNodes
if (!Active.Map) return
var l = Selected.Edges.length,
i,
edge
const l = Selected.Edges.length
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
@ -312,13 +303,13 @@ const Control = {
return
}
for (i = l - 1; i >= 0; i -= 1) {
edge = Selected.Edges[i]
for (let i = l - 1; i >= 0; i -= 1) {
const edge = Selected.Edges[i]
Control.removeEdge(edge)
}
Selected.Edges = [ ]
},
removeEdge: function (edge) {
removeEdge: function(edge) {
if (!Active.Map) return
var authorized = Active.Map.authorizeToEdit(Active.Mapper)
@ -350,17 +341,15 @@ const Control = {
mappableid: mappableid
}])
},
hideSelectedEdges: function () {
var edge,
l = Selected.Edges.length,
i
for (i = l - 1; i >= 0; i -= 1) {
edge = Selected.Edges[i]
hideSelectedEdges: function() {
const l = Selected.Edges.length
for (let i = l - 1; i >= 0; i -= 1) {
const edge = Selected.Edges[i]
Control.hideEdge(edge)
}
Selected.Edges = [ ]
},
hideEdge: function (edge) {
hideEdge: function(edge) {
var from = edge.nodeFrom.id
var to = edge.nodeTo.id
edge.setData('alpha', 0, 'end')
@ -369,24 +358,24 @@ const Control = {
modes: ['edge-property:alpha'],
duration: 500
})
setTimeout(function () {
setTimeout(function() {
Visualize.mGraph.graph.removeAdjacence(from, to)
}, 500)
Filter.checkSynapses()
Filter.checkMappers()
},
updateSelectedPermissions: function (permission) {
updateSelectedPermissions: function(permission) {
var edge, synapse, node, topic
GlobalUI.notifyUser('Working...')
// variables to keep track of how many nodes and synapses you had the ability to change the permission of
var nCount = 0,
sCount = 0
var nCount = 0
var sCount = 0
// change the permission of the selected synapses, if logged in user is the original creator
var l = Selected.Edges.length
for (var i = l - 1; i >= 0; i -= 1) {
const edgesLength = Selected.Edges.length
for (let i = edgesLength - 1; i >= 0; i -= 1) {
edge = Selected.Edges[i]
synapse = edge.getData('synapses')[0]
@ -399,8 +388,8 @@ const Control = {
}
// change the permission of the selected topics, if logged in user is the original creator
var l = Selected.Nodes.length
for (var i = l - 1; i >= 0; i -= 1) {
const nodesLength = Selected.Nodes.length
for (let i = nodesLength - 1; i >= 0; i -= 1) {
node = Selected.Nodes[i]
topic = node.getData('topic')
@ -418,12 +407,12 @@ const Control = {
var message = nString + sString + ' you created updated to ' + permission
GlobalUI.notifyUser(message)
},
updateSelectedMetacodes: function (metacode_id) {
updateSelectedMetacodes: function(metacodeId) {
var node, topic
GlobalUI.notifyUser('Working...')
var metacode = DataModel.Metacodes.get(metacode_id)
var metacode = DataModel.Metacodes.get(metacodeId)
// variables to keep track of how many nodes and synapses you had the ability to change the permission of
var nCount = 0
@ -436,7 +425,7 @@ const Control = {
if (topic.authorizeToEdit(Active.Mapper)) {
topic.save({
'metacode_id': metacode_id
'metacode_id': metacodeId
})
nCount++
}

View file

@ -16,7 +16,7 @@ const Create = {
newSelectedMetacodeNames: [],
selectedMetacodes: [],
newSelectedMetacodes: [],
init: function () {
init: function() {
var self = Create
self.newTopic.init()
self.newSynapse.init()
@ -29,23 +29,23 @@ const Create = {
$('#metacodeSwitchTabs .ui-tabs-nav li').removeClass('ui-corner-top').addClass('ui-corner-left')
$('.customMetacodeList li').click(self.toggleMetacodeSelected) // within the custom metacode set tab
},
toggleMetacodeSelected: function () {
toggleMetacodeSelected: function() {
var self = Create
if ($(this).attr('class') != 'toggledOff') {
if ($(this).attr('class') !== 'toggledOff') {
$(this).addClass('toggledOff')
var value_to_remove = $(this).attr('id')
var name_to_remove = $(this).attr('data-name')
self.newSelectedMetacodes.splice(self.newSelectedMetacodes.indexOf(value_to_remove), 1)
self.newSelectedMetacodeNames.splice(self.newSelectedMetacodeNames.indexOf(name_to_remove), 1)
} else if ($(this).attr('class') == 'toggledOff') {
var valueToRemove = $(this).attr('id')
var nameToRemove = $(this).attr('data-name')
self.newSelectedMetacodes.splice(self.newSelectedMetacodes.indexOf(valueToRemove), 1)
self.newSelectedMetacodeNames.splice(self.newSelectedMetacodeNames.indexOf(nameToRemove), 1)
} else if ($(this).attr('class') === 'toggledOff') {
$(this).removeClass('toggledOff')
self.newSelectedMetacodes.push($(this).attr('id'))
self.newSelectedMetacodeNames.push($(this).attr('data-name'))
}
},
updateMetacodeSet: function (set, index, custom) {
if (custom && Create.newSelectedMetacodes.length == 0) {
updateMetacodeSet: function(set, index, custom) {
if (custom && Create.newSelectedMetacodes.length === 0) {
window.alert('Please select at least one metacode to use!')
return false
}
@ -62,8 +62,7 @@ const Create = {
Create.selectedMetacodeNames = []
Create.newSelectedMetacodes = []
Create.newSelectedMetacodeNames = []
}
else if (custom) {
} else if (custom) {
// uses .slice to avoid setting the two arrays to the same actual array
Create.selectedMetacodes = Create.newSelectedMetacodes.slice(0)
Create.selectedMetacodeNames = Create.newSelectedMetacodeNames.slice(0)
@ -79,7 +78,7 @@ const Create = {
$('#metacodeImg, #metacodeImgTitle').empty()
$('#metacodeImg').removeData('cloudcarousel')
var newMetacodes = ''
metacodeModels.each(function (metacode) {
metacodeModels.each(function(metacode) {
newMetacodes += '<img class="cloudcarousel" width="40" height="40" src="' + metacode.get('icon') + '" data-id="' + metacode.id + '" title="' + metacode.get('name') + '" alt="' + metacode.get('name') + '"/>'
})
@ -107,20 +106,20 @@ const Create = {
dataType: 'json',
url: '/user/updatemetacodes',
data: mdata,
success: function (data) {
success: function(data) {
console.log('selected metacodes saved')
},
error: function () {
error: function() {
console.log('failed to save selected metacodes')
}
})
},
cancelMetacodeSetSwitch: function () {
cancelMetacodeSetSwitch: function() {
var self = Create
self.isSwitchingSet = false
if (self.selectedMetacodeSet != 'metacodeset-custom') {
if (self.selectedMetacodeSet !== 'metacodeset-custom') {
$('.customMetacodeList li').addClass('toggledOff')
self.selectedMetacodes = []
self.selectedMetacodeNames = []
@ -140,17 +139,16 @@ const Create = {
$('#topic_name').focus()
},
newTopic: {
init: function () {
$('#topic_name').keyup(function () {
init: function() {
$('#topic_name').keyup(function() {
Create.newTopic.name = $(this).val()
})
$('.pinCarousel').click(function() {
if (Create.newTopic.pinned) {
$('.pinCarousel').removeClass('isPinned')
Create.newTopic.pinned = false
}
else {
} else {
$('.pinCarousel').addClass('isPinned')
Create.newTopic.pinned = true
}
@ -174,18 +172,18 @@ const Create = {
[{
name: 'topic_autocomplete',
limit: 8,
display: function (s) { return s.label; },
display: function(s) { return s.label },
templates: {
suggestion: function (s) {
suggestion: function(s) {
return Hogan.compile($('#topicAutocompleteTemplate').html()).render(s)
}
},
source: topicBloodhound,
source: topicBloodhound
}]
)
// 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
if (datum.rtype === 'topic') {
Topic.getTopicFromAutocomplete(datum.id)
@ -209,7 +207,7 @@ const Create = {
bringToFront: true
})
$('.new_topic').hide()
$('#new_topic').attr('oncontextmenu','return false') //prevents the mouse up event from opening the default context menu on this element
$('#new_topic').attr('oncontextmenu', 'return false') // prevents the mouse up event from opening the default context menu on this element
},
name: null,
newId: 1,
@ -219,15 +217,15 @@ const Create = {
y: null,
addSynapse: false,
pinned: false,
open: function () {
$('#new_topic').fadeIn('fast', function () {
open: function() {
$('#new_topic').fadeIn('fast', function() {
$('#topic_name').focus()
})
Create.newTopic.beingCreated = true
Create.newTopic.name = ''
GlobalUI.hideDiv('#instructions')
},
hide: function (force) {
hide: function(force) {
if (force || !Create.newTopic.pinned) {
$('#new_topic').fadeOut('fast')
}
@ -240,28 +238,26 @@ const Create = {
}
Create.newTopic.beingCreated = false
},
reset: function () {
reset: function() {
$('#topic_name').typeahead('val', '')
}
},
newSynapse: {
init: function () {
var self = Create.newSynapse
init: function() {
var synapseBloodhound = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: '/search/synapses?term=%QUERY',
wildcard: '%QUERY',
},
wildcard: '%QUERY'
}
})
var existingSynapseBloodhound = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: '/search/synapses?topic1id=%TOPIC1&topic2id=%TOPIC2',
prepare: function (query, settings) {
prepare: function(query, settings) {
var self = Create.newSynapse
if (Selected.Nodes.length < 2 && self.topic1id && self.topic2id) {
settings.url = settings.url.replace('%TOPIC1', self.topic1id).replace('%TOPIC2', self.topic2id)
@ -269,42 +265,44 @@ const Create = {
} else {
return null
}
},
},
}
}
})
// initialize the autocomplete results for synapse creation
$('#synapse_desc').typeahead(
{
highlight: true,
minLength: 2,
minLength: 2
},
[{
name: 'synapse_autocomplete',
display: function (s) { return s.label; },
display: function(s) { return s.label },
templates: {
suggestion: function (s) {
suggestion: function(s) {
return Hogan.compile("<div class='genericSynapseDesc'>{{label}}</div>").render(s)
},
}
},
source: synapseBloodhound,
source: synapseBloodhound
},
{
name: 'existing_synapses',
limit: 50,
display: function (s) { return s.label; },
display: function(s) { return s.label },
templates: {
suggestion: function (s) {
suggestion: function(s) {
return Hogan.compile($('#synapseAutocompleteTemplate').html()).render(s)
},
header: '<h3>Existing synapses</h3>'
},
source: existingSynapseBloodhound,
source: existingSynapseBloodhound
}]
)
$('#synapse_desc').keyup(function (e) {
var ESC = 27, BACKSPACE = 8, DELETE = 46
$('#synapse_desc').keyup(function(e) {
const ESC = 27
const BACKSPACE = 8
const DELETE = 46
if (e.keyCode === BACKSPACE && $(this).val() === '' ||
e.keyCode === DELETE && $(this).val() === '' ||
e.keyCode === ESC) {
@ -313,13 +311,13 @@ const Create = {
Create.newSynapse.description = $(this).val()
})
$('#synapse_desc').focusout(function () {
$('#synapse_desc').focusout(function() {
if (Create.newSynapse.beingCreated) {
Synapse.createSynapseLocally()
}
})
$('#synapse_desc').bind('typeahead:select', function (event, datum, dataset) {
$('#synapse_desc').bind('typeahead:select', function(event, datum, dataset) {
if (datum.id) { // if they clicked on an existing synapse get it
Synapse.getSynapseFromAutocomplete(datum.id)
} else {
@ -333,13 +331,13 @@ const Create = {
topic1id: null,
topic2id: null,
newSynapseId: null,
open: function () {
$('#new_synapse').fadeIn(100, function () {
open: function() {
$('#new_synapse').fadeIn(100, function() {
$('#synapse_desc').focus()
})
Create.newSynapse.beingCreated = true
},
hide: function () {
hide: function() {
$('#new_synapse').fadeOut('fast')
$('#synapse_desc').typeahead('val', '')
Create.newSynapse.beingCreated = false
@ -348,7 +346,7 @@ const Create = {
Create.newSynapse.topic2id = 0
Mouse.synapseStartCoordinates = []
if (Visualize.mGraph) Visualize.mGraph.plot()
},
}
}
}

View file

@ -9,18 +9,13 @@ import InfoBox from '../Map/InfoBox'
import Mapper from '../Mapper'
import Realtime from '../Realtime'
import MapperCollection from './MapperCollection'
import TopicCollection from './TopicCollection'
import SynapseCollection from './SynapseCollection'
import MappingCollection from './MappingCollection'
const Map = Backbone.Model.extend({
urlRoot: '/maps',
blacklist: ['created_at', 'updated_at', 'created_at_clean', 'updated_at_clean', 'user_name', 'contributor_count', 'topic_count', 'synapse_count', 'topics', 'synapses', 'mappings', 'mappers'],
toJSON: function (options) {
toJSON: function(options) {
return _.omit(this.attributes, this.blacklist)
},
save: function (key, val, options) {
save: function(key, val, options) {
var attrs
// Handle both `"key", value` and `{key: value}` -style arguments.
@ -34,20 +29,20 @@ const Map = Backbone.Model.extend({
var newOptions = options || {}
var s = newOptions.success
newOptions.success = function (model, response, opt) {
newOptions.success = function(model, response, opt) {
if (s) s(model, response, opt)
model.trigger('saved')
}
return Backbone.Model.prototype.save.call(this, attrs, newOptions)
},
initialize: function () {
initialize: function() {
this.on('changeByOther', this.updateView)
this.on('saved', this.savedEvent)
},
savedEvent: function () {
savedEvent: function() {
Realtime.updateMap(this)
},
authorizeToEdit: function (mapper) {
authorizeToEdit: function(mapper) {
if (mapper && (
this.get('permission') === 'commons' ||
(this.get('collaborator_ids') || []).includes(mapper.get('id')) ||
@ -57,17 +52,17 @@ const Map = Backbone.Model.extend({
return false
}
},
authorizePermissionChange: function (mapper) {
authorizePermissionChange: function(mapper) {
if (mapper && this.get('user_id') === mapper.get('id')) {
return true
} else {
return false
}
},
getUser: function () {
getUser: function() {
return Mapper.get(this.get('user_id'))
},
updateView: function () {
updateView: function() {
var map = Active.Map
var isActiveMap = this.id === map.id
if (isActiveMap) {
@ -78,7 +73,7 @@ const Map = Backbone.Model.extend({
document.title = this.get('name') + ' | Metamaps'
}
},
updateMapWrapper: function () {
updateMapWrapper: function() {
var map = Active.Map
var isActiveMap = this.id === map.id
var authorized = map && map.authorizeToEdit(Active.Mapper) ? 'canEditMap' : ''

View file

@ -7,7 +7,7 @@ import Map from './Map'
const MapCollection = Backbone.Collection.extend({
model: Map,
initialize: function (models, options) {
initialize: function(models, options) {
this.id = options.id
this.sortBy = options.sortBy
@ -18,14 +18,14 @@ const MapCollection = Backbone.Collection.extend({
// this.page represents the NEXT page to fetch
this.page = models.length > 0 ? (models.length < 20 ? 'loadedAll' : 2) : 1
},
url: function () {
url: function() {
if (!this.mapperId) {
return '/explore/' + this.id + '.json'
} else {
return '/explore/mapper/' + this.mapperId + '.json'
}
},
comparator: function (a, b) {
comparator: function(a, b) {
a = a.get(this.sortBy)
b = b.get(this.sortBy)
var temp
@ -42,7 +42,7 @@ const MapCollection = Backbone.Collection.extend({
}
return a > b ? 1 : a < b ? -1 : 0
},
getMaps: function (cb) {
getMaps: function(cb) {
var self = this
Loading.show()
@ -53,7 +53,7 @@ const MapCollection = Backbone.Collection.extend({
remove: false,
silent: true,
data: { page: this.page },
success: function (collection, response, options) {
success: function(collection, response, options) {
// you can pass additional options to the event you trigger here as well
if (collection.length - numBefore < 20) {
self.page = 'loadedAll'
@ -62,7 +62,7 @@ const MapCollection = Backbone.Collection.extend({
}
self.trigger('successOnFetch', cb)
},
error: function (collection, response, options) {
error: function(collection, response, options) {
// you can pass additional options to the event you trigger here as well
self.trigger('errorOnFetch')
}

View file

@ -6,10 +6,10 @@ import outdent from 'outdent'
const Mapper = Backbone.Model.extend({
urlRoot: '/users',
blacklist: ['created_at', 'updated_at'],
toJSON: function (options) {
toJSON: function(options) {
return _.omit(this.attributes, this.blacklist)
},
prepareLiForFilter: function () {
prepareLiForFilter: function() {
return outdent`
<li data-id="${this.id}">
<img src="${this.get('image')}" data-id="${this.id}" alt="${this.get('name')}" />

View file

@ -10,10 +10,10 @@ import Topic from '../Topic'
const Mapping = Backbone.Model.extend({
urlRoot: '/mappings',
blacklist: ['created_at', 'updated_at'],
toJSON: function (options) {
toJSON: function(options) {
return _.omit(this.attributes, this.blacklist)
},
initialize: function () {
initialize: function() {
if (this.isNew()) {
this.set({
'user_id': Active.Mapper.id,
@ -21,14 +21,14 @@ const Mapping = Backbone.Model.extend({
})
}
},
getMap: function () {
getMap: function() {
return Map.get(this.get('map_id'))
},
getTopic: function () {
getTopic: function() {
if (this.get('mappable_type') !== 'Topic') return false
return Topic.get(this.get('mappable_id'))
},
getSynapse: function () {
getSynapse: function() {
if (this.get('mappable_type') !== 'Synapse') return false
return Synapse.get(this.get('mappable_id'))
}

View file

@ -5,7 +5,7 @@ try { Backbone.$ = window.$ } catch (err) {}
const Message = Backbone.Model.extend({
urlRoot: '/messages',
blacklist: ['created_at', 'updated_at'],
toJSON: function (options) {
toJSON: function(options) {
return _.omit(this.attributes, this.blacklist)
}
})

View file

@ -3,13 +3,13 @@ try { Backbone.$ = window.$ } catch (err) {}
import outdent from 'outdent'
const Metacode = Backbone.Model.extend({
initialize: function () {
initialize: function() {
var image = new window.Image()
image.crossOrigin = 'Anonymous'
image.src = this.get('icon')
this.set('image', image)
},
prepareLiForFilter: function () {
prepareLiForFilter: function() {
return outdent`
<li data-id="${this.id}">
<img src="${this.get('icon')}" data-id="${this.id}" alt="${this.get('name')}" />

View file

@ -6,7 +6,7 @@ import Metacode from './Metacode'
const MetacodeCollection = Backbone.Collection.extend({
model: Metacode,
url: '/metacodes',
comparator: function (a, b) {
comparator: function(a, b) {
a = a.get('name').toLowerCase()
b = b.get('name').toLowerCase()
return a > b ? 1 : a < b ? -1 : 0

View file

@ -17,10 +17,10 @@ import DataModel from './index'
const Synapse = Backbone.Model.extend({
urlRoot: '/synapses',
blacklist: ['edge', 'created_at', 'updated_at'],
toJSON: function (options) {
toJSON: function(options) {
return _.omit(this.attributes, this.blacklist)
},
save: function (key, val, options) {
save: function(key, val, options) {
var attrs
// Handle both `"key", value` and `{key: value}` -style arguments.
@ -36,7 +36,7 @@ const Synapse = Backbone.Model.extend({
var permBefore = this.get('permission')
newOptions.success = function (model, response, opt) {
newOptions.success = function(model, response, opt) {
if (s) s(model, response, opt)
model.trigger('saved')
@ -48,7 +48,7 @@ const Synapse = Backbone.Model.extend({
}
return Backbone.Model.prototype.save.call(this, attrs, newOptions)
},
initialize: function () {
initialize: function() {
if (this.isNew()) {
this.set({
'user_id': Active.Mapper.id,
@ -60,7 +60,7 @@ const Synapse = Backbone.Model.extend({
this.on('changeByOther', this.updateCardView)
this.on('change', this.updateEdgeView)
this.on('saved', this.savedEvent)
this.on('noLongerPrivate', function () {
this.on('noLongerPrivate', function() {
var newSynapseData = {
mappingid: this.getMapping().id,
mappableid: this.id
@ -68,7 +68,7 @@ const Synapse = Backbone.Model.extend({
$(document).trigger(JIT.events.newSynapse, [newSynapseData])
})
this.on('nowPrivate', function () {
this.on('nowPrivate', function() {
$(document).trigger(JIT.events.removeSynapse, [{
mappableid: this.id
}])
@ -76,28 +76,28 @@ const Synapse = Backbone.Model.extend({
this.on('change:desc', Filter.checkSynapses, this)
},
prepareLiForFilter: function () {
prepareLiForFilter: function() {
return outdent`
<li data-id="${this.get('desc')}">
<img src="${DataModel.synapseIconUrl}" alt="synapse icon" />
<p>${this.get('desc')}</p>
</li>`
},
authorizeToEdit: function (mapper) {
authorizeToEdit: function(mapper) {
if (mapper && (this.get('calculated_permission') === 'commons' || this.get('collaborator_ids').includes(mapper.get('id')) || this.get('user_id') === mapper.get('id'))) return true
else return false
},
authorizePermissionChange: function (mapper) {
authorizePermissionChange: function(mapper) {
if (mapper && this.get('user_id') === mapper.get('id')) return true
else return false
},
getTopic1: function () {
getTopic1: function() {
return DataModel.Topics.get(this.get('topic1_id'))
},
getTopic2: function () {
getTopic2: function() {
return DataModel.Topics.get(this.get('topic2_id'))
},
getDirection: function () {
getDirection: function() {
var t1 = this.getTopic1()
var t2 = this.getTopic2()
@ -106,7 +106,7 @@ const Synapse = Backbone.Model.extend({
t2.get('node').id
] : false
},
getMapping: function () {
getMapping: function() {
if (!Active.Map) return false
return DataModel.Mappings.findWhere({
@ -115,7 +115,7 @@ const Synapse = Backbone.Model.extend({
mappable_id: this.isNew() ? this.cid : this.id
})
},
createEdge: function (providedMapping) {
createEdge: function(providedMapping) {
var mapping, mappingID
var synapseID = this.isNew() ? this.cid : this.id
@ -137,7 +137,7 @@ const Synapse = Backbone.Model.extend({
return edge
},
updateEdge: function () {
updateEdge: function() {
var mapping
var edge = this.get('edge')
edge.getData('synapses').push(this)
@ -149,14 +149,14 @@ const Synapse = Backbone.Model.extend({
return edge
},
savedEvent: function () {
savedEvent: function() {
Realtime.updateSynapse(this)
},
updateViews: function () {
updateViews: function() {
this.updateCardView()
this.updateEdgeView()
},
updateCardView: function () {
updateCardView: function() {
var onPageWithSynapseCard = Active.Map || Active.Topic
var edge = this.get('edge')
@ -165,7 +165,7 @@ const Synapse = Backbone.Model.extend({
SynapseCard.showCard(edge)
}
},
updateEdgeView: function () {
updateEdgeView: function() {
var onPageWithSynapseCard = Active.Map || Active.Topic
var edge = this.get('edge')

View file

@ -16,10 +16,10 @@ import DataModel from './index'
const Topic = Backbone.Model.extend({
urlRoot: '/topics',
blacklist: ['node', 'created_at', 'updated_at', 'user_name', 'user_image', 'map_count', 'synapse_count'],
toJSON: function (options) {
toJSON: function(options) {
return _.omit(this.attributes, this.blacklist)
},
save: function (key, val, options) {
save: function(key, val, options) {
var attrs
// Handle both `"key", value` and `{key: value}` -style arguments.
@ -35,7 +35,7 @@ const Topic = Backbone.Model.extend({
var permBefore = this.get('permission')
newOptions.success = function (model, response, opt) {
newOptions.success = function(model, response, opt) {
if (s) s(model, response, opt)
model.trigger('saved')
model.set('calculated_permission', model.get('permission'))
@ -48,7 +48,7 @@ const Topic = Backbone.Model.extend({
}
return Backbone.Model.prototype.save.call(this, attrs, newOptions)
},
initialize: function () {
initialize: function() {
if (this.isNew()) {
this.set({
'user_id': Active.Mapper.id,
@ -61,14 +61,14 @@ const Topic = Backbone.Model.extend({
this.on('changeByOther', this.updateCardView)
this.on('change', this.updateNodeView)
this.on('saved', this.savedEvent)
this.on('nowPrivate', function () {
this.on('nowPrivate', function() {
var removeTopicData = {
mappableid: this.id
}
$(document).trigger(JIT.events.removeTopic, [removeTopicData])
})
this.on('noLongerPrivate', function () {
this.on('noLongerPrivate', function() {
var newTopicData = {
mappingid: this.getMapping().id,
mappableid: this.id
@ -79,7 +79,7 @@ const Topic = Backbone.Model.extend({
this.on('change:metacode_id', Filter.checkMetacodes, this)
},
authorizeToEdit: function (mapper) {
authorizeToEdit: function(mapper) {
if (mapper &&
(this.get('user_id') === mapper.get('id') ||
this.get('calculated_permission') === 'commons' ||
@ -89,15 +89,15 @@ const Topic = Backbone.Model.extend({
return false
}
},
authorizePermissionChange: function (mapper) {
authorizePermissionChange: function(mapper) {
if (mapper && this.get('user_id') === mapper.get('id')) return true
else return false
},
getDate: function () {},
getMetacode: function () {
getDate: function() {},
getMetacode: function() {
return DataModel.Metacodes.get(this.get('metacode_id'))
},
getMapping: function () {
getMapping: function() {
if (!Active.Map) return false
return DataModel.Mappings.findWhere({
@ -106,7 +106,7 @@ const Topic = Backbone.Model.extend({
mappable_id: this.isNew() ? this.cid : this.id
})
},
createNode: function () {
createNode: function() {
var mapping
var node = {
adjacencies: [],
@ -124,7 +124,7 @@ const Topic = Backbone.Model.extend({
return node
},
updateNode: function () {
updateNode: function() {
var mapping
var node = this.get('node')
node.setData('topic', this)
@ -136,10 +136,10 @@ const Topic = Backbone.Model.extend({
return node
},
savedEvent: function () {
savedEvent: function() {
Realtime.updateTopic(this)
},
updateViews: function () {
updateViews: function() {
var onPageWithTopicCard = Active.Map || Active.Topic
var node = this.get('node')
// update topic card, if this topic is the one open there
@ -153,7 +153,7 @@ const Topic = Backbone.Model.extend({
Visualize.mGraph.plot()
}
},
updateCardView: function () {
updateCardView: function() {
var onPageWithTopicCard = Active.Map || Active.Topic
var node = this.get('node')
// update topic card, if this topic is the one open there
@ -161,7 +161,7 @@ const Topic = Backbone.Model.extend({
TopicCard.showCard(node)
}
},
updateNodeView: function () {
updateNodeView: function() {
var onPageWithTopicCard = Active.Map || Active.Topic
var node = this.get('node')

View file

@ -54,7 +54,7 @@ const DataModel = {
Synapses: new SynapseCollection(),
Topics: new TopicCollection(),
init: function (serverData) {
init: function(serverData) {
var self = DataModel
// workaround circular import problem
@ -101,18 +101,18 @@ const DataModel = {
self.attachCollectionEvents()
},
attachCollectionEvents: function () {
DataModel.Topics.on('add remove', function (topic) {
attachCollectionEvents: function() {
DataModel.Topics.on('add remove', function(topic) {
InfoBox.updateNumbers()
Filter.checkMetacodes()
Filter.checkMappers()
})
DataModel.Synapses.on('add remove', function (synapse) {
DataModel.Synapses.on('add remove', function(synapse) {
InfoBox.updateNumbers()
Filter.checkSynapses()
Filter.checkMappers()
})
DataModel.Mappings.on('add remove', function (mapping) {
DataModel.Mappings.on('add remove', function(mapping) {
InfoBox.updateNumbers()
Filter.checkSynapses()
Filter.checkMetacodes()

View file

@ -23,7 +23,7 @@ const Filter = {
},
isOpen: false,
changing: false,
init: function () {
init: function() {
var self = Filter
$('.sidebarFilterIcon').click(self.toggleBox)
@ -38,7 +38,7 @@ const Filter = {
self.bindLiClicks()
self.getFilterData()
},
toggleBox: function (event) {
toggleBox: function(event) {
var self = Filter
if (self.isOpen) self.close()
@ -46,7 +46,7 @@ const Filter = {
event.stopPropagation()
},
open: function () {
open: function() {
var self = Filter
GlobalUI.Account.close()
@ -56,26 +56,26 @@ const Filter = {
self.changing = true
var height = $(document).height() - 108
$('.sidebarFilterBox').css('max-height', height + 'px').fadeIn(200, function () {
$('.sidebarFilterBox').css('max-height', height + 'px').fadeIn(200, function() {
self.changing = false
self.isOpen = true
})
}
},
close: function () {
close: function() {
var self = Filter
$('.sidebarFilterIcon div').removeClass('hide')
if (!self.changing) {
self.changing = true
$('.sidebarFilterBox').fadeOut(200, function () {
$('.sidebarFilterBox').fadeOut(200, function() {
self.changing = false
self.isOpen = false
})
}
},
reset: function () {
reset: function() {
var self = Filter
self.filters.metacodes = []
@ -95,30 +95,30 @@ const Filter = {
Most of this data essentially depends on the ruby function which are happening for filter inside view filterBox
But what these function do is load this data into three accessible array within java : metacodes, mappers and synapses
*/
getFilterData: function () {
getFilterData: function() {
var self = Filter
var metacode, mapper, synapse
$('#filter_by_metacode li').each(function () {
$('#filter_by_metacode li').each(function() {
metacode = $(this).attr('data-id')
self.filters.metacodes.push(metacode)
self.visible.metacodes.push(metacode)
})
$('#filter_by_mapper li').each(function () {
$('#filter_by_mapper li').each(function() {
mapper = ($(this).attr('data-id'))
self.filters.mappers.push(mapper)
self.visible.mappers.push(mapper)
})
$('#filter_by_synapse li').each(function () {
$('#filter_by_synapse li').each(function() {
synapse = ($(this).attr('data-id'))
self.filters.synapses.push(synapse)
self.visible.synapses.push(synapse)
})
},
bindLiClicks: function () {
bindLiClicks: function() {
var self = Filter
$('#filter_by_metacode ul li').unbind().click(self.toggleMetacode)
$('#filter_by_mapper ul li').unbind().click(self.toggleMapper)
@ -129,7 +129,7 @@ const Filter = {
/*
@param
*/
updateFilters: function (collection, propertyToCheck, correlatedModel, filtersToUse, listToModify) {
updateFilters: function(collection, propertyToCheck, correlatedModel, filtersToUse, listToModify) {
var self = Filter
var newList = []
@ -139,7 +139,7 @@ const Filter = {
// the first option enables us to accept
// ['Topics', 'Synapses'] as 'collection'
if (typeof collection === 'object') {
DataModel[collection[0]].each(function (model) {
DataModel[collection[0]].each(function(model) {
var prop = model.get(propertyToCheck)
if (prop !== null) {
prop = prop.toString()
@ -148,7 +148,7 @@ const Filter = {
}
}
})
DataModel[collection[1]].each(function (model) {
DataModel[collection[1]].each(function(model) {
var prop = model.get(propertyToCheck)
if (prop !== null) {
prop = prop.toString()
@ -158,7 +158,7 @@ const Filter = {
}
})
} else if (typeof collection === 'string') {
DataModel[collection].each(function (model) {
DataModel[collection].each(function(model) {
var prop = model.get(propertyToCheck)
if (prop !== null) {
prop = prop.toString()
@ -173,8 +173,8 @@ const Filter = {
added = _.difference(newList, self.filters[filtersToUse])
// remove the list items for things no longer present on the map
_.each(removed, function (identifier) {
$('#filter_by_' + listToModify + ' li[data-id="' + identifier + '"]').fadeOut('fast', function () {
_.each(removed, function(identifier) {
$('#filter_by_' + listToModify + ' li[data-id="' + identifier + '"]').fadeOut('fast', function() {
$(this).remove()
})
const index = self.visible[filtersToUse].indexOf(identifier)
@ -182,13 +182,13 @@ const Filter = {
})
var model, li, jQueryLi
function sortAlpha (a, b) {
function sortAlpha(a, b) {
return a.childNodes[1].innerHTML.toLowerCase() > b.childNodes[1].innerHTML.toLowerCase() ? 1 : -1
}
// for each new filter to be added, create a list item for it and fade it in
_.each(added, function (identifier) {
_.each(added, function(identifier) {
model = DataModel[correlatedModel].get(identifier) ||
DataModel[correlatedModel].find(function (model) {
DataModel[correlatedModel].find(function(model) {
return model.get(propertyToCheck) === identifier
})
li = model.prepareLiForFilter()
@ -204,25 +204,24 @@ const Filter = {
// make sure clicks on list items still trigger the right events
self.bindLiClicks()
},
checkMetacodes: function () {
checkMetacodes: function() {
var self = Filter
self.updateFilters('Topics', 'metacode_id', 'Metacodes', 'metacodes', 'metacode')
},
checkMappers: function () {
checkMappers: function() {
var self = Filter
var onMap = Active.Map ? true : false
if (onMap) {
if (Active.Map) {
self.updateFilters('Mappings', 'user_id', 'Mappers', 'mappers', 'mapper')
} else {
// on topic view
self.updateFilters(['Topics', 'Synapses'], 'user_id', 'Creators', 'mappers', 'mapper')
}
},
checkSynapses: function () {
checkSynapses: function() {
var self = Filter
self.updateFilters('Synapses', 'desc', 'Synapses', 'synapses', 'synapse')
},
filterAllMetacodes: function (e) {
filterAllMetacodes: function(e) {
var self = Filter
$('#filter_by_metacode ul li').addClass('toggledOff')
$('.showAllMetacodes').removeClass('active')
@ -230,7 +229,7 @@ const Filter = {
self.visible.metacodes = []
self.passFilters()
},
filterNoMetacodes: function (e) {
filterNoMetacodes: function(e) {
var self = Filter
$('#filter_by_metacode ul li').removeClass('toggledOff')
$('.showAllMetacodes').addClass('active')
@ -238,7 +237,7 @@ const Filter = {
self.visible.metacodes = self.filters.metacodes.slice()
self.passFilters()
},
filterAllMappers: function (e) {
filterAllMappers: function(e) {
var self = Filter
$('#filter_by_mapper ul li').addClass('toggledOff')
$('.showAllMappers').removeClass('active')
@ -246,7 +245,7 @@ const Filter = {
self.visible.mappers = []
self.passFilters()
},
filterNoMappers: function (e) {
filterNoMappers: function(e) {
var self = Filter
$('#filter_by_mapper ul li').removeClass('toggledOff')
$('.showAllMappers').addClass('active')
@ -254,7 +253,7 @@ const Filter = {
self.visible.mappers = self.filters.mappers.slice()
self.passFilters()
},
filterAllSynapses: function (e) {
filterAllSynapses: function(e) {
var self = Filter
$('#filter_by_synapse ul li').addClass('toggledOff')
$('.showAllSynapses').removeClass('active')
@ -262,7 +261,7 @@ const Filter = {
self.visible.synapses = []
self.passFilters()
},
filterNoSynapses: function (e) {
filterNoSynapses: function(e) {
var self = Filter
$('#filter_by_synapse ul li').removeClass('toggledOff')
$('.showAllSynapses').addClass('active')
@ -273,28 +272,27 @@ const Filter = {
// an abstraction function for toggleMetacode, toggleMapper, toggleSynapse
// to reduce code redundancy
// gets called in the context of a list item in a filter box
toggleLi: function (whichToFilter) {
var self = Filter, index
toggleLi: function(whichToFilter) {
var self = Filter
var id = $(this).attr('data-id')
if (self.visible[whichToFilter].indexOf(id) == -1) {
if (self.visible[whichToFilter].indexOf(id) === -1) {
self.visible[whichToFilter].push(id)
$(this).removeClass('toggledOff')
} else {
index = self.visible[whichToFilter].indexOf(id)
const index = self.visible[whichToFilter].indexOf(id)
self.visible[whichToFilter].splice(index, 1)
$(this).addClass('toggledOff')
}
self.passFilters()
},
toggleMetacode: function () {
toggleMetacode: function() {
var self = Filter
self.toggleLi.call(this, 'metacodes')
if (self.visible.metacodes.length === self.filters.metacodes.length) {
$('.showAllMetacodes').addClass('active')
$('.hideAllMetacodes').removeClass('active')
}
else if (self.visible.metacodes.length === 0) {
} else if (self.visible.metacodes.length === 0) {
$('.showAllMetacodes').removeClass('active')
$('.hideAllMetacodes').addClass('active')
} else {
@ -302,15 +300,14 @@ const Filter = {
$('.hideAllMetacodes').removeClass('active')
}
},
toggleMapper: function () {
toggleMapper: function() {
var self = Filter
self.toggleLi.call(this, 'mappers')
if (self.visible.mappers.length === self.filters.mappers.length) {
$('.showAllMappers').addClass('active')
$('.hideAllMappers').removeClass('active')
}
else if (self.visible.mappers.length === 0) {
} else if (self.visible.mappers.length === 0) {
$('.showAllMappers').removeClass('active')
$('.hideAllMappers').addClass('active')
} else {
@ -318,15 +315,14 @@ const Filter = {
$('.hideAllMappers').removeClass('active')
}
},
toggleSynapse: function () {
toggleSynapse: function() {
var self = Filter
self.toggleLi.call(this, 'synapses')
if (self.visible.synapses.length === self.filters.synapses.length) {
$('.showAllSynapses').addClass('active')
$('.hideAllSynapses').removeClass('active')
}
else if (self.visible.synapses.length === 0) {
} else if (self.visible.synapses.length === 0) {
$('.showAllSynapses').removeClass('active')
$('.hideAllSynapses').addClass('active')
} else {
@ -334,71 +330,65 @@ const Filter = {
$('.hideAllSynapses').removeClass('active')
}
},
passFilters: function () {
passFilters: function() {
var self = Filter
var visible = self.visible
var passesMetacode, passesMapper, passesSynapse
var onMap
if (Active.Map) {
onMap = true
}
else if (Active.Topic) {
onMap = false
}
var opacityForFilter = Active.Map ? 0 : 0.4
var opacityForFilter = onMap ? 0 : 0.4
DataModel.Topics.each(function (topic) {
DataModel.Topics.each(function(topic) {
var n = topic.get('node')
var metacode_id = topic.get('metacode_id').toString()
var metacodeId = topic.get('metacode_id').toString()
if (visible.metacodes.indexOf(metacode_id) == -1) passesMetacode = false
if (visible.metacodes.indexOf(metacodeId) === -1) passesMetacode = false
else passesMetacode = true
if (onMap) {
if (Active.Map) {
// when on a map,
// we filter by mapper according to the person who added the
// topic or synapse to the map
var user_id = topic.getMapping().get('user_id').toString()
if (visible.mappers.indexOf(user_id) == -1) passesMapper = false
let userId = topic.getMapping().get('user_id').toString()
if (visible.mappers.indexOf(userId) === -1) passesMapper = false
else passesMapper = true
} else {
// when on a topic view,
// we filter by mapper according to the person who created the
// topic or synapse
var user_id = topic.get('user_id').toString()
if (visible.mappers.indexOf(user_id) == -1) passesMapper = false
let userId = topic.get('user_id').toString()
if (visible.mappers.indexOf(userId) === -1) passesMapper = false
else passesMapper = true
}
if (passesMetacode && passesMapper) {
if (n) {
n.setData('alpha', 1, 'end')
} else {
console.log(topic)
}
else console.log(topic)
} else {
if (n) {
Control.deselectNode(n, true)
n.setData('alpha', opacityForFilter, 'end')
n.eachAdjacency(function (e) {
n.eachAdjacency(function(e) {
Control.deselectEdge(e, true)
})
} else {
console.log(topic)
}
else console.log(topic)
}
})
// flag all the edges back to 'untouched'
DataModel.Synapses.each(function (synapse) {
DataModel.Synapses.each(function(synapse) {
var e = synapse.get('edge')
e.setData('touched', false)
})
DataModel.Synapses.each(function (synapse) {
DataModel.Synapses.each(function(synapse) {
var e = synapse.get('edge')
var desc
var user_id = synapse.get('user_id').toString()
var userId = synapse.get('user_id').toString()
if (e && !e.getData('touched')) {
var synapses = e.getData('synapses')
@ -406,7 +396,7 @@ const Filter = {
// if any of the synapses represent by the edge are still unfiltered
// leave the edge visible
passesSynapse = false
for (var i = 0; i < synapses.length; i++) {
for (let i = 0; i < synapses.length; i++) {
desc = synapses[i].get('desc')
if (visible.synapses.indexOf(desc) > -1) passesSynapse = true
}
@ -416,9 +406,9 @@ const Filter = {
var displayIndex = e.getData('displayIndex') ? e.getData('displayIndex') : 0
var displayedSynapse = synapses[displayIndex]
desc = displayedSynapse.get('desc')
if (passesSynapse && visible.synapses.indexOf(desc) == -1) {
if (passesSynapse && visible.synapses.indexOf(desc) === -1) {
// iterate and find an unfiltered one
for (var i = 0; i < synapses.length; i++) {
for (let i = 0; i < synapses.length; i++) {
desc = synapses[i].get('desc')
if (visible.synapses.indexOf(desc) > -1) {
e.setData('displayIndex', i)
@ -427,13 +417,13 @@ const Filter = {
}
}
if (onMap) {
if (Active.Map) {
// when on a map,
// we filter by mapper according to the person who added the
// topic or synapse to the map
user_id = synapse.getMapping().get('user_id').toString()
userId = synapse.getMapping().get('user_id').toString()
}
if (visible.mappers.indexOf(user_id) == -1) passesMapper = false
if (visible.mappers.indexOf(userId) === -1) passesMapper = false
else passesMapper = true
var color = Settings.colors.synapses.normal
@ -446,8 +436,9 @@ const Filter = {
}
e.setData('touched', true)
} else if (!e) {
console.log(synapse)
}
else if (!e) console.log(synapse)
})
// run the animation

View file

@ -5,16 +5,16 @@ import Filter from '../Filter'
const Account = {
isOpen: false,
changing: false,
init: function () {
init: function() {
var self = Account
$('.sidebarAccountIcon').click(self.toggleBox)
$('.sidebarAccountBox').click(function (event) {
$('.sidebarAccountBox').click(function(event) {
event.stopPropagation()
})
$('body').click(self.close)
},
toggleBox: function (event) {
toggleBox: function(event) {
var self = Account
if (self.isOpen) self.close()
@ -22,7 +22,7 @@ const Account = {
event.stopPropagation()
},
open: function () {
open: function() {
var self = Account
Filter.close()
@ -30,21 +30,21 @@ const Account = {
if (!self.isOpen && !self.changing) {
self.changing = true
$('.sidebarAccountBox').fadeIn(200, function () {
$('.sidebarAccountBox').fadeIn(200, function() {
self.changing = false
self.isOpen = true
$('.sidebarAccountBox #user_email').focus()
})
}
},
close: function () {
close: function() {
var self = Account
$('.sidebarAccountIcon .tooltipsUnder').removeClass('hide')
if (!self.changing) {
self.changing = true
$('.sidebarAccountBox #user_email').blur()
$('.sidebarAccountBox').fadeOut(200, function () {
$('.sidebarAccountBox').fadeOut(200, function() {
self.changing = false
self.isOpen = false
})

View file

@ -13,7 +13,7 @@ const CreateMap = {
emptyForkMapForm: '',
topicsToMap: [],
synapsesToMap: [],
init: function () {
init: function() {
var self = CreateMap
self.newMap = new DataModelMap({ permission: 'commons' })
@ -22,14 +22,14 @@ const CreateMap = {
self.emptyMapForm = $('#new_map').html()
},
bindFormEvents: function () {
bindFormEvents: function() {
var self = CreateMap
$('.new_map input, .new_map div').unbind('keypress').bind('keypress', function (event) {
$('.new_map input, .new_map div').unbind('keypress').bind('keypress', function(event) {
if (event.keyCode === 13) self.submit()
})
$('.new_map button.cancel').unbind().bind('click', function (event) {
$('.new_map button.cancel').unbind().bind('click', function(event) {
event.preventDefault()
GlobalUI.closeLightbox()
})
@ -38,12 +38,12 @@ const CreateMap = {
// bind permission changer events on the createMap form
$('.permIcon').unbind().bind('click', self.switchPermission)
},
closeSuccess: function () {
$('#mapCreatedSuccess').fadeOut(300, function () {
closeSuccess: function() {
$('#mapCreatedSuccess').fadeOut(300, function() {
$(this).remove()
})
},
switchPermission: function () {
switchPermission: function() {
var self = CreateMap
self.newMap.set('permission', $(this).attr('data-permission'))
@ -53,7 +53,7 @@ const CreateMap = {
var permText = $(this).find('.tip').html()
$(this).parents('.new_map').find('.permText').html(permText)
},
submit: function (event) {
submit: function(event) {
if (event) event.preventDefault()
var self = CreateMap
@ -82,22 +82,20 @@ const CreateMap = {
GlobalUI.closeLightbox()
GlobalUI.notifyUser('Working...')
},
throwMapNameError: function () {
throwMapNameError: function() {
var formId = GlobalUI.lightbox === 'forkmap' ? '#fork_map' : '#new_map'
var $form = $(formId)
var message = $("<div class='feedback_message'>Please enter a map name...</div>")
$form.find('#map_name').after(message)
setTimeout(function () {
message.fadeOut('fast', function () {
setTimeout(function() {
message.fadeOut('fast', function() {
message.remove()
})
}, 5000)
},
success: function (model) {
var self = CreateMap
success: function(model) {
// push the new map onto the collection of 'my maps'
DataModel.Maps.Mine.add(model)
@ -117,7 +115,7 @@ const CreateMap = {
return false
})
},
reset: function (id) {
reset: function(id) {
var self = CreateMap
var form = $('#' + id)

View file

@ -12,7 +12,7 @@ const ImportDialog = {
openLightbox: null,
closeLightbox: null,
init: function (serverData, openLightbox, closeLightbox) {
init: function(serverData, openLightbox, closeLightbox) {
const self = ImportDialog
self.openLightbox = openLightbox
self.closeLightbox = closeLightbox
@ -27,10 +27,10 @@ const ImportDialog = {
exampleImageUrl: serverData['import-example.png']
}), $('.importDialogWrapper').get(0))
},
show: function () {
show: function() {
ImportDialog.openLightbox('import-dialog')
},
hide: function () {
hide: function() {
ImportDialog.closeLightbox('import-dialog')
}
}

View file

@ -10,7 +10,7 @@ const Search = {
limitMapsToMe: false,
changing: false,
optionsInitialized: false,
init: function (serverData) {
init: function(serverData) {
var self = Search
self.wildcardIconUrl = serverData['icons/wildcard.png']
@ -24,10 +24,10 @@ const Search = {
loader.setRange(0.9) // default is 1.3
loader.show() // Hidden by default
$('.sidebarSearchIcon').click(function (e) {
$('.sidebarSearchIcon').click(function(e) {
$('.sidebarSearchField').focus()
})
$('.sidebarSearch').click(function (e) {
$('.sidebarSearch').click(function(e) {
e.stopPropagation()
})
@ -36,7 +36,7 @@ const Search = {
focus: function() {
$('.sidebarSearchField').focus()
},
startTypeahead: function () {
startTypeahead: function() {
var self = Search
var mapheader = Active.Mapper ? '<div class="searchMapsHeader searchHeader"><h3 class="search-heading">Maps</h3><input type="checkbox" class="limitToMe" id="limitMapsToMe"></input><label for="limitMapsToMe" class="limitToMeLabel">added by me</label><div class="minimizeResults minimizeMapResults"></div><div class="clearfloat"></div></div>' : '<div class="searchMapsHeader searchHeader"><h3 class="search-heading">Maps</h3><div class="minimizeResults minimizeMapResults"></div><div class="clearfloat"></div></div>'
@ -49,7 +49,7 @@ const Search = {
display: s => s.label,
templates: {
notFound: function (s) {
notFound: function(s) {
return Hogan.compile(topicheader + $('#topicSearchTemplate').html()).render({
value: 'No results',
label: 'No results',
@ -58,7 +58,7 @@ const Search = {
})
},
header: topicheader,
suggestion: function (s) {
suggestion: function(s) {
return Hogan.compile($('#topicSearchTemplate').html()).render(s)
}
},
@ -67,7 +67,7 @@ const Search = {
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: '/search/topics',
prepare: function (query, settings) {
prepare: function(query, settings) {
settings.url += '?term=' + query
if (Active.Mapper && self.limitTopicsToMe) {
settings.url += '&user=' + Active.Mapper.id.toString()
@ -83,7 +83,7 @@ const Search = {
limit: 9999,
display: s => s.label,
templates: {
notFound: function (s) {
notFound: function(s) {
return Hogan.compile(mapheader + $('#mapSearchTemplate').html()).render({
value: 'No results',
label: 'No results',
@ -91,7 +91,7 @@ const Search = {
})
},
header: mapheader,
suggestion: function (s) {
suggestion: function(s) {
return Hogan.compile($('#mapSearchTemplate').html()).render(s)
}
},
@ -100,7 +100,7 @@ const Search = {
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: '/search/maps',
prepare: function (query, settings) {
prepare: function(query, settings) {
settings.url += '?term=' + query
if (Active.Mapper && self.limitMapsToMe) {
settings.url += '&user=' + Active.Mapper.id.toString()
@ -116,7 +116,7 @@ const Search = {
limit: 9999,
display: s => s.label,
templates: {
notFound: function (s) {
notFound: function(s) {
return Hogan.compile(mapperheader + $('#mapperSearchTemplate').html()).render({
value: 'No results',
label: 'No results',
@ -125,7 +125,7 @@ const Search = {
})
},
header: mapperheader,
suggestion: function (s) {
suggestion: function(s) {
return Hogan.compile($('#mapperSearchTemplate').html()).render(s)
}
},
@ -148,7 +148,7 @@ const Search = {
)
// Set max height of the search results box to prevent it from covering bottom left footer
$('.sidebarSearchField').bind('typeahead:render', function (event) {
$('.sidebarSearchField').bind('typeahead:render', function(event) {
self.initSearchOptions()
self.hideLoader()
var h = $(window).height()
@ -160,7 +160,7 @@ const Search = {
$('#limitMapsToMe').prop('checked', true)
}
})
$(window).resize(function () {
$(window).resize(function() {
var h = $(window).height()
$('.tt-dropdown-menu').css('max-height', h - 100)
})
@ -169,12 +169,12 @@ const Search = {
$('.sidebarSearchField').bind('typeahead:select', self.handleResultClick)
// don't do it, if they clicked on a 'addToMap' button
$('.sidebarSearch button.addToMap').click(function (event) {
$('.sidebarSearch button.addToMap').click(function(event) {
event.stopPropagation()
})
// make sure that when you click on 'limit to me' or 'toggle section' it works
$('.sidebarSearchField.tt-input').keyup(function () {
$('.sidebarSearchField.tt-input').keyup(function() {
if ($('.sidebarSearchField.tt-input').val() === '') {
self.hideLoader()
} else {
@ -182,7 +182,7 @@ const Search = {
}
})
},
handleResultClick: function (event, datum, dataset) {
handleResultClick: function(event, datum, dataset) {
var self = Search
self.hideLoader()
@ -197,10 +197,10 @@ const Search = {
}
}
},
initSearchOptions: function () {
initSearchOptions: function() {
var self = Search
function toggleResultSet (set) {
function toggleResultSet(set) {
var s = $('.tt-dataset-' + set + ' .tt-suggestion, .tt-dataset-' + set + ' .resultnoresult')
if (s.is(':visible')) {
s.hide()
@ -211,7 +211,7 @@ const Search = {
}
}
$('.limitToMe').unbind().bind('change', function (e) {
$('.limitToMe').unbind().bind('change', function(e) {
if ($(this).attr('id') === 'limitTopicsToMe') {
self.limitTopicsToMe = !self.limitTopicsToMe
}
@ -227,20 +227,20 @@ const Search = {
})
// when the user clicks minimize section, hide the results for that section
$('.minimizeMapperResults').unbind().click(function (e) {
$('.minimizeMapperResults').unbind().click(function(e) {
toggleResultSet.call(this, 'mappers')
})
$('.minimizeTopicResults').unbind().click(function (e) {
$('.minimizeTopicResults').unbind().click(function(e) {
toggleResultSet.call(this, 'topics')
})
$('.minimizeMapResults').unbind().click(function (e) {
$('.minimizeMapResults').unbind().click(function(e) {
toggleResultSet.call(this, 'maps')
})
},
hideLoader: function () {
hideLoader: function() {
$('#searchLoading').hide()
},
showLoader: function () {
showLoader: function() {
$('#searchLoading').show()
}
}

View file

@ -12,7 +12,7 @@ import ImportDialog from './ImportDialog'
const GlobalUI = {
notifyTimeout: null,
lightbox: null,
init: function (serverData) {
init: function(serverData) {
var self = GlobalUI
self.Search.init(serverData)
@ -23,7 +23,7 @@ const GlobalUI = {
if ($('#toast').html().trim()) self.notifyUser($('#toast').html())
// bind lightbox clicks
$('.openLightbox').click(function (event) {
$('.openLightbox').click(function(event) {
self.openLightbox($(this).attr('data-open'))
event.preventDefault()
return false
@ -31,18 +31,18 @@ const GlobalUI = {
$('#lightbox_screen, #lightbox_close').click(self.closeLightbox)
},
showDiv: function (selector) {
showDiv: function(selector) {
$(selector).show()
$(selector).animate({
opacity: 1
}, 200, 'easeOutCubic')
},
hideDiv: function (selector) {
hideDiv: function(selector) {
$(selector).animate({
opacity: 0
}, 200, 'easeInCubic', function () { $(this).hide() })
}, 200, 'easeInCubic', function() { $(this).hide() })
},
openLightbox: function (which) {
openLightbox: function(which) {
var self = GlobalUI
$('.lightboxContent').hide()
@ -69,7 +69,7 @@ const GlobalUI = {
}
},
closeLightbox: function (event) {
closeLightbox: function(event) {
var self = GlobalUI
if (event) event.preventDefault()
@ -83,7 +83,7 @@ const GlobalUI = {
// fade the black overlay out
$('#lightbox_screen').animate({
'opacity': '0.0'
}, 200, function () {
}, 200, function() {
$('#lightbox_overlay').hide()
})
@ -94,25 +94,25 @@ const GlobalUI = {
}
self.lightbox = null
},
notifyUser: function (message, leaveOpen) {
notifyUser: function(message, leaveOpen) {
var self = GlobalUI
$('#toast').html(message)
self.showDiv('#toast')
clearTimeout(self.notifyTimeOut)
if (!leaveOpen) {
self.notifyTimeOut = setTimeout(function () {
self.notifyTimeOut = setTimeout(function() {
self.hideDiv('#toast')
}, 8000)
}
},
clearNotify: function () {
clearNotify: function() {
var self = GlobalUI
clearTimeout(self.notifyTimeOut)
self.hideDiv('#toast')
},
shareInvite: function (inviteLink) {
shareInvite: function(inviteLink) {
clipboard.copy({
'text/plain': inviteLink
}).then(() => {

View file

@ -19,14 +19,14 @@ const Import = {
synapseWhitelist: [
'topic1', 'topic2', 'category', 'direction', 'desc', 'description', 'permission'
],
cidMappings: {}, // to be filled by import_id => cid mappings
cidMappings: {}, // to be filled by importId => cid mappings
handleTSV: function (text) {
handleTSV: function(text) {
const results = Import.parseTabbedString(text)
Import.handle(results)
},
handleCSV: function (text, parserOpts = {}) {
handleCSV: function(text, parserOpts = {}) {
const self = Import
const topicsRegex = /("?Topics"?)([\s\S]*)/mi
@ -37,14 +37,14 @@ const Import = {
if (synapsesText) synapsesText = synapsesText[2].replace(topicsRegex, '')
// merge default options and extra options passed in parserOpts argument
const csv_parser_options = Object.assign({
const csvParserOptions = Object.assign({
columns: true, // get headers
relax_column_count: true,
skip_empty_lines: true
}, parserOpts)
const topicsPromise = $.Deferred()
parse(topicsText, csv_parser_options, (err, data) => {
parse(topicsText, csvParserOptions, (err, data) => {
if (err) {
console.warn(err)
return topicsPromise.resolve([])
@ -53,7 +53,7 @@ const Import = {
})
const synapsesPromise = $.Deferred()
parse(synapsesText, csv_parser_options, (err, data) => {
parse(synapsesText, csvParserOptions, (err, data) => {
if (err) {
console.warn(err)
return synapsesPromise.resolve([])
@ -62,11 +62,11 @@ const Import = {
})
$.when(topicsPromise, synapsesPromise).done((topics, synapses) => {
self.handle({ topics, synapses})
self.handle({ topics, synapses })
})
},
handleJSON: function (text) {
handleJSON: function(text) {
const results = JSON.parse(text)
Import.handle(results)
},
@ -80,13 +80,13 @@ const Import = {
if (window.confirm('Are you sure you want to create ' + topics.length +
' new topics and ' + synapses.length + ' new synapses?')) {
self.importTopics(topics)
//window.setTimeout(() => self.importSynapses(synapses), 5000)
// window.setTimeout(() => self.importSynapses(synapses), 5000)
self.importSynapses(synapses)
} // if
} // if
},
parseTabbedString: function (text) {
parseTabbedString: function(text) {
var self = Import
// determine line ending and split lines
@ -113,9 +113,9 @@ const Import = {
var topicHeaders = []
var synapseHeaders = []
lines.forEach(function (line_raw, index) {
var line = line_raw.split('\t')
var noblanks = line.filter(function (elt) {
lines.forEach(function(lineRaw, index) {
const line = lineRaw.split('\t')
var noblanks = line.filter(function(elt) {
return elt !== ''
})
switch (state) {
@ -139,7 +139,7 @@ const Import = {
self.abort('Not enough topic headers on line ' + index)
state = STATES.ABORT
}
topicHeaders = line.map(function (header, index) {
topicHeaders = line.map(function(header, index) {
return self.normalizeKey(header)
})
state = STATES.TOPICS
@ -150,7 +150,7 @@ const Import = {
self.abort('Not enough synapse headers on line ' + index)
state = STATES.ABORT
}
synapseHeaders = line.map(function (header, index) {
synapseHeaders = line.map(function(header, index) {
return self.normalizeKey(header)
})
state = STATES.SYNAPSES
@ -165,7 +165,7 @@ const Import = {
state = STATES.SYNAPSES_NEED_HEADERS
} else {
var topic = {}
line.forEach(function (field, index) {
line.forEach(function(field, index) {
var header = topicHeaders[index]
if (self.topicWhitelist.indexOf(header) === -1) return
topic[header] = field
@ -186,7 +186,7 @@ const Import = {
state = STATES.SYNAPSES_NEED_HEADERS
} else {
var synapse = {}
line.forEach(function (field, index) {
line.forEach(function(field, index) {
var header = synapseHeaders[index]
if (self.synapseWhitelist.indexOf(header) === -1) return
synapse[header] = field
@ -212,7 +212,7 @@ const Import = {
}
},
importTopics: function (parsedTopics) {
importTopics: function(parsedTopics) {
var self = Import
parsedTopics.forEach(topic => {
@ -227,7 +227,7 @@ const Import = {
coords,
name: topic.name,
permission: topic.permission,
import_id: topic.id
importId: topic.id
})
return // "continue"
}
@ -239,10 +239,10 @@ const Import = {
})
},
importSynapses: function (parsedSynapses) {
importSynapses: function(parsedSynapses) {
var self = Import
parsedSynapses.forEach(function (synapse) {
parsedSynapses.forEach(function(synapse) {
// only createSynapseWithParameters once both topics are persisted
// if there isn't a cidMapping, check by topic name instead
var topic1 = DataModel.Topics.get(self.cidMappings[synapse.topic1])
@ -277,31 +277,31 @@ const Import = {
})
},
createTopicWithParameters: function (name, metacode_name, permission, desc,
link, xloc, yloc, import_id, opts = {}) {
createTopicWithParameters: function(name, metacodeName, permission, desc,
link, xloc, yloc, importId, opts = {}) {
var self = Import
$(document).trigger(Map.events.editedByActiveMapper)
var metacode = DataModel.Metacodes.where({name: metacode_name})[0] || null
var metacode = DataModel.Metacodes.where({name: metacodeName})[0] || null
if (metacode === null) {
metacode = DataModel.Metacodes.where({ name: 'Wildcard' })[0]
console.warn("Couldn't find metacode " + metacode_name + ' so used Wildcard instead.')
console.warn("Couldn't find metacode " + metacodeName + ' so used Wildcard instead.')
}
var topic_permission = permission || Active.Map.get('permission')
var defer_to_map_id = permission === topic_permission ? Active.Map.get('id') : null
const topicPermision = permission || Active.Map.get('permission')
var deferToMapId = permission === topicPermision ? Active.Map.get('id') : null
var topic = new DataModel.Topic({
name: name,
metacode_id: metacode.id,
permission: topic_permission,
defer_to_map_id: defer_to_map_id,
permission: topicPermision,
defer_to_map_id: deferToMapId,
desc: desc || '',
link: link || '',
calculated_permission: Active.Map.get('permission')
})
DataModel.Topics.add(topic)
if (import_id !== null && import_id !== undefined) {
self.cidMappings[import_id] = topic.cid
if (importId !== null && importId !== undefined) {
self.cidMappings[importId] = topic.cid
}
var mapping = new DataModel.Mapping({
@ -320,7 +320,7 @@ const Import = {
GlobalUI.hideDiv('#instructions')
},
createSynapseWithParameters: function (desc, category, permission,
createSynapseWithParameters: function(desc, category, permission,
topic1, topic2) {
var node1 = topic1.get('node')
var node2 = topic2.get('node')
@ -348,7 +348,7 @@ const Import = {
Synapse.renderSynapse(mapping, synapse, node1, node2, true)
},
handleURL: function (url, opts = {}) {
handleURL: function(url, opts = {}) {
let coords = opts.coords
if (!coords || coords.x === undefined || coords.y === undefined) {
coords = AutoLayout.getNextCoord({ mappings: DataModel.Mappings })
@ -356,7 +356,7 @@ const Import = {
const name = opts.name || 'Link'
const metacode = opts.metacode || 'Reference'
const import_id = opts.import_id || null // don't store a cidMapping
const importId = opts.importId || null // don't store a cidMapping
const permission = opts.permission || null // use default
const desc = opts.desc || url
@ -368,7 +368,7 @@ const Import = {
url,
coords.x,
coords.y,
import_id,
importId,
{
success: function(topic) {
if (topic.get('name') !== 'Link') return
@ -393,12 +393,12 @@ const Import = {
* helper functions
*/
abort: function (message) {
abort: function(message) {
console.error(message)
},
// TODO investigate replacing with es6 (?) trim()
simplify: function (string) {
simplify: function(string) {
return string
.replace(/(^\s*|\s*$)/g, '')
.toLowerCase()

File diff suppressed because it is too large Load diff

View file

@ -12,9 +12,9 @@ import Visualize from './Visualize'
import { Search } from './GlobalUI'
const Listeners = {
init: function () {
init: function() {
var self = this
$(document).on('keydown', function (e) {
$(document).on('keydown', function(e) {
if (!(Active.Map || Active.Topic)) return
const onCanvas = e.target.tagName === 'BODY'
@ -35,7 +35,7 @@ const Listeners = {
Control.deselectAllEdges()
e.preventDefault()
Visualize.mGraph.graph.eachNode(function (n) {
Visualize.mGraph.graph.eachNode(function(n) {
Control.selectNode(n, e)
})
@ -110,7 +110,7 @@ const Listeners = {
}
})
$(window).resize(function () {
$(window).resize(function() {
if (Visualize && Visualize.mGraph) {
Util.resizeCanvas(Visualize.mGraph.canvas)
}
@ -119,11 +119,11 @@ const Listeners = {
Mobile.resizeTitle()
})
},
centerAndReveal: function (nodes, opts) {
centerAndReveal: function(nodes, opts) {
if (nodes.length < 1) return
var node = nodes[nodes.length - 1]
if (opts.center && opts.reveal) {
Topic.centerOn(node.id, function () {
Topic.centerOn(node.id, function() {
Topic.fetchRelatives(nodes)
})
} else if (opts.center) {

View file

@ -2,13 +2,13 @@
const Loading = {
loader: null, // needs CanvasLoader to be defined
hide: function () {
hide: function() {
$('#loading').hide()
},
show: function () {
show: function() {
$('#loading').show()
},
setup: function () {
setup: function() {
if (!Loading.loader) Loading.loader = new CanvasLoader('loading')
Loading.loader.setColor('#4fb5c0') // default is '#000000'
Loading.loader.setDiameter(28) // default is 40

View file

@ -1,28 +1,28 @@
/* global $ */
const CheatSheet = {
init: function () {
init: function() {
// tab the cheatsheet
$('#cheatSheet').tabs()
$('#quickReference').tabs().addClass('ui-tabs-vertical ui-helper-clearfix')
$('#quickReference .ui-tabs-nav li').removeClass('ui-corner-top').addClass('ui-corner-left')
// id = the id of a vimeo video
var switchVideo = function (element, id) {
$('.tutorialItem').removeClass('active')
$(element).addClass('active')
$('#tutorialVideo').attr('src', '//player.vimeo.com/video/' + id)
}
// // id = the id of a vimeo video
// var switchVideo = function(element, id) {
// $('.tutorialItem').removeClass('active')
// $(element).addClass('active')
// $('#tutorialVideo').attr('src', '//player.vimeo.com/video/' + id)
// }
$('#gettingStarted').click(function () {
// switchVideo(this,'88334167')
})
$('#upYourSkillz').click(function () {
// switchVideo(this,'100118167')
})
$('#advancedMapping').click(function () {
// switchVideo(this,'88334167')
})
// $('#gettingStarted').click(function() {
// switchVideo(this,'88334167')
// })
// $('#upYourSkillz').click(function() {
// switchVideo(this,'100118167')
// })
// $('#advancedMapping').click(function() {
// switchVideo(this,'88334167')
// })
}
}

View file

@ -35,23 +35,23 @@ const InfoBox = {
data-bip-value="{{desc}}"
>{{desc}}</span>`,
userImageUrl: '',
init: function (serverData) {
init: function(serverData) {
var self = InfoBox
$('.mapInfoIcon').click(self.toggleBox)
$('.mapInfoBox').click(function (event) {
$('.mapInfoBox').click(function(event) {
event.stopPropagation()
})
$('body').click(self.close)
self.attachEventListeners()
self.attachEventListeners()
self.generateBoxHTML = Hogan.compile($('#mapInfoBoxTemplate').html())
self.userImageUrl = serverData['user.png']
var querystring = window.location.search.replace(/^\?/, '')
if (querystring == 'new') {
if (querystring === 'new') {
self.open()
$('.mapInfoBox').addClass('mapRequestTitle')
$('#mapInfoName').trigger('click')
@ -59,7 +59,7 @@ const InfoBox = {
$('#mapInfoName textarea').select()
}
},
toggleBox: function (event) {
toggleBox: function(event) {
var self = InfoBox
if (self.isOpen) self.close()
@ -67,24 +67,24 @@ const InfoBox = {
event.stopPropagation()
},
open: function () {
open: function() {
var self = InfoBox
$('.mapInfoIcon div').addClass('hide')
if (!self.isOpen && !self.changing) {
self.changing = true
$('.mapInfoBox').fadeIn(200, function () {
$('.mapInfoBox').fadeIn(200, function() {
self.changing = false
self.isOpen = true
})
}
},
close: function () {
close: function() {
var self = InfoBox
$('.mapInfoIcon div').removeClass('hide')
if (!self.changing) {
self.changing = true
$('.mapInfoBox').fadeOut(200, function () {
$('.mapInfoBox').fadeOut(200, function() {
self.changing = false
self.isOpen = false
self.hidePermissionSelect()
@ -92,7 +92,7 @@ const InfoBox = {
})
}
},
load: function () {
load: function() {
var self = InfoBox
var map = Active.Map
@ -127,14 +127,14 @@ const InfoBox = {
self.attachEventListeners()
},
attachEventListeners: function () {
attachEventListeners: function() {
var self = InfoBox
$('.mapInfoBox.canEdit .best_in_place').best_in_place()
// because anyone who can edit the map can change the map title
var bipName = $('.mapInfoBox .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 = $el[0]
@ -142,16 +142,16 @@ const InfoBox = {
$('.mapInfoName').append('<div class="nameCounter forMap"></div>')
var callback = function (data) {
var callback = function(data) {
$('.nameCounter.forMap').html(data.all + '/140')
}
Countable.live(el, callback)
})
bipName.unbind('best_in_place:deactivate').bind('best_in_place:deactivate', function () {
bipName.unbind('best_in_place:deactivate').bind('best_in_place:deactivate', function() {
$('.nameCounter.forMap').remove()
})
$('.mapInfoName .best_in_place_name').unbind('ajax:success').bind('ajax:success', function () {
$('.mapInfoName .best_in_place_name').unbind('ajax:success').bind('ajax:success', function() {
var name = $(this).html()
Active.Map.set('name', name)
Active.Map.trigger('saved')
@ -162,7 +162,7 @@ const InfoBox = {
window.history.replaceState('', `${name} | Metamaps`, window.location.pathname)
})
$('.mapInfoDesc .best_in_place_desc').unbind('ajax:success').bind('ajax:success', function () {
$('.mapInfoDesc .best_in_place_desc').unbind('ajax:success').bind('ajax:success', function() {
var desc = $(this).html()
Active.Map.set('desc', desc)
Active.Map.trigger('saved')
@ -182,76 +182,76 @@ const InfoBox = {
$('.yourMap .mapInfoDelete').unbind().click(self.deleteActiveMap)
$('.mapContributors span, #mapContribs').unbind().click(function (event) {
$('.mapContributors span, #mapContribs').unbind().click(function(event) {
$('.mapContributors .tip').toggle()
event.stopPropagation()
})
$('.mapContributors .tip').unbind().click(function (event) {
$('.mapContributors .tip').unbind().click(function(event) {
event.stopPropagation()
})
$('.mapContributors .tip li a').click(Router.intercept)
$('.mapInfoBox').unbind('.hideTip').bind('click.hideTip', function () {
$('.mapInfoBox').unbind('.hideTip').bind('click.hideTip', function() {
$('.mapContributors .tip').hide()
})
self.addTypeahead()
self.addTypeahead()
},
addTypeahead: function () {
addTypeahead: function() {
var self = InfoBox
if (!Active.Map) return
// for autocomplete
var collaborators = {
name: 'collaborators',
limit: 9999,
display: function(s) { return s.label; },
templates: {
notFound: function(s) {
return Hogan.compile($('#collaboratorSearchTemplate').html()).render({
value: "No results",
label: "No results",
rtype: "noresult",
profile: self.userImageUrl
});
},
suggestion: function(s) {
return Hogan.compile($('#collaboratorSearchTemplate').html()).render(s);
},
name: 'collaborators',
limit: 9999,
display: function(s) { return s.label },
templates: {
notFound: function(s) {
return Hogan.compile($('#collaboratorSearchTemplate').html()).render({
value: 'No results',
label: 'No results',
rtype: 'noresult',
profile: self.userImageUrl
})
},
source: new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: '/search/mappers?term=%QUERY',
wildcard: '%QUERY',
},
})
suggestion: function(s) {
return Hogan.compile($('#collaboratorSearchTemplate').html()).render(s)
}
},
source: new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: '/search/mappers?term=%QUERY',
wildcard: '%QUERY'
}
})
}
// for adding map collaborators, who will have edit rights
if (Active.Mapper && Active.Mapper.id === Active.Map.get('user_id')) {
$('.collaboratorSearchField').typeahead(
{
highlight: false,
highlight: false
},
[collaborators]
)
$('.collaboratorSearchField').bind('typeahead:select', self.handleResultClick)
$('.mapContributors .removeCollaborator').click(function () {
$('.mapContributors .removeCollaborator').click(function() {
self.removeCollaborator(parseInt($(this).data('id')))
})
}
}
},
removeCollaborator: function (collaboratorId) {
removeCollaborator: function(collaboratorId) {
var self = InfoBox
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 })
self.updateNumbers()
},
addCollaborator: function (newCollaboratorId) {
addCollaborator: function(newCollaboratorId) {
var self = InfoBox
if (DataModel.Collaborators.get(newCollaboratorId)) {
@ -261,7 +261,7 @@ const InfoBox = {
function callback(mapper) {
DataModel.Collaborators.add(mapper)
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 })
var name = DataModel.Collaborators.get(newCollaboratorId).get('name')
GlobalUI.notifyUser(name + ' will be notified by email')
@ -270,29 +270,28 @@ const InfoBox = {
$.getJSON('/users/' + newCollaboratorId + '.json', callback)
},
handleResultClick: function (event, item) {
handleResultClick: function(event, item) {
var self = InfoBox
self.addCollaborator(item.id)
$('.collaboratorSearchField').typeahead('val', '')
self.addCollaborator(item.id)
$('.collaboratorSearchField').typeahead('val', '')
},
updateNameDescPerm: function (name, desc, perm) {
updateNameDescPerm: function(name, desc, perm) {
$('.mapInfoBox').removeClass('mapRequestTitle')
$('.mapInfoName .best_in_place_name').html(name)
$('.mapInfoDesc .best_in_place_desc').html(desc)
$('.mapInfoBox .mapPermission').removeClass('commons public private').addClass(perm)
},
createContributorList: function () {
var self = InfoBox
createContributorList: function() {
var relevantPeople = Active.Map.get('permission') === 'commons' ? DataModel.Mappers : DataModel.Collaborators
var activeMapperIsCreator = Active.Mapper && Active.Mapper.id === Active.Map.get('user_id')
var string = ''
string += '<ul>'
relevantPeople.each(function (m) {
relevantPeople.each(function(m) {
var isCreator = Active.Map.get('user_id') === m.get('id')
string += '<li><a href="/explore/mapper/' + m.get('id') + '">' + '<img class="rtUserImage" width="25" height="25" src="' + m.get('image') + '" />' + m.get('name')
if (isCreator) string += ' (creator)'
if (isCreator) string += ' (creator)'
string += '</a>'
if (activeMapperIsCreator && !isCreator) string += '<span class="removeCollaborator" data-id="' + m.get('id') + '"></span>'
string += '</li>'
@ -305,27 +304,30 @@ const InfoBox = {
}
return string
},
updateNumbers: function () {
updateNumbers: function() {
if (!Active.Map) return
var self = InfoBox
var mapper = Active.Mapper
const self = InfoBox
var relevantPeople = Active.Map.get('permission') === 'commons' ? DataModel.Mappers : DataModel.Collaborators
var contributors_class = ''
if (relevantPeople.length === 2) contributors_class = 'multiple mTwo'
else if (relevantPeople.length > 2) contributors_class = 'multiple'
let contributorsClass = ''
if (relevantPeople.length === 2) {
contributorsClass = 'multiple mTwo'
} else if (relevantPeople.length > 2) {
contributorsClass = 'multiple'
}
var contributors_image = self.userImageUrl
let contributorsImage = self.userImageUrl
if (relevantPeople.length > 0) {
// get the first contributor and use their image
contributors_image = relevantPeople.models[0].get('image')
contributorsImage = relevantPeople.models[0].get('image')
}
$('.mapContributors img').attr('src', contributors_image).removeClass('multiple mTwo').addClass(contributors_class)
$('.mapContributors img').attr('src', contributorsImage).removeClass('multiple mTwo').addClass(contributorsClass)
$('.mapContributors span').text(relevantPeople.length)
$('.mapContributors .tip').html(self.createContributorList())
self.addTypeahead()
$('.mapContributors .tip').unbind().click(function (event) {
$('.mapContributors .tip').unbind().click(function(event) {
event.stopPropagation()
})
$('.mapTopics').text(DataModel.Topics.length)
@ -333,7 +335,7 @@ const InfoBox = {
$('.mapEditedAt').html('<span>Last edited: </span>' + Util.nowDateFormatted())
},
onPermissionClick: function (event) {
onPermissionClick: function(event) {
var self = InfoBox
if (!self.selectingPermission) {
@ -350,14 +352,14 @@ const InfoBox = {
event.stopPropagation()
}
},
hidePermissionSelect: function () {
hidePermissionSelect: function() {
var self = InfoBox
self.selectingPermission = false
$('.mapPermission').removeClass('minimize') // this line flips the pull up arrow to a drop down arrow
$('.mapPermission .permissionSelect').remove()
},
selectPermission: function (event) {
selectPermission: function(event) {
var self = InfoBox
self.selectingPermission = false
@ -372,7 +374,7 @@ const InfoBox = {
$('.mapInfoBox').removeClass('shareable').addClass(shareable)
event.stopPropagation()
},
deleteActiveMap: function () {
deleteActiveMap: function() {
var confirmString = 'Are you sure you want to delete this map? '
confirmString += 'This action is irreversible. It will not delete the topics and synapses on the map.'
@ -390,8 +392,7 @@ const InfoBox = {
map.destroy()
Router.home()
GlobalUI.notifyUser('Map eliminated!')
}
else if (!authorized) {
} else if (!authorized) {
window.alert("Hey now. We can't just go around willy nilly deleting other people's maps now can we? Run off and find something constructive to do, eh?")
}
}

View file

@ -1,6 +1,7 @@
/* global $ */
import outdent from 'outdent'
import { find as _find } from 'lodash'
import Active from '../Active'
import AutoLayout from '../AutoLayout'
@ -25,19 +26,19 @@ const Map = {
events: {
editedByActiveMapper: 'Metamaps:Map:events:editedByActiveMapper'
},
init: function (serverData) {
init: function(serverData) {
var self = Map
$('#wrapper').mousedown(function (e){
if(e.button === 1)return false;
});
$('.starMap').click(function () {
$('#wrapper').mousedown(function(e) {
if (e.button === 1) return false
})
$('.starMap').click(function() {
if ($(this).is('.starred')) self.unstar()
else self.star()
})
$('.sidebarFork').click(function () {
$('.sidebarFork').click(function() {
self.fork()
})
@ -51,26 +52,26 @@ const Map = {
$(document).on(Map.events.editedByActiveMapper, self.editedByActiveMapper)
},
requestAccess: function () {
requestAccess: function() {
$('.viewOnly').removeClass('sendRequest').addClass('sentRequest')
const mapId = Active.Map.id
$.post({
url: `/maps/${mapId}/access_request`
})
GlobalUI.notifyUser('Map creator will be notified of your request')
GlobalUI.notifyUser('Map creator will be notified of your request')
},
setAccessRequest: function (requests, activeMapper) {
setAccessRequest: function(requests, activeMapper) {
let className = 'isViewOnly '
if (activeMapper) {
const request = _.find(requests, r => r.user_id === activeMapper.id)
if (!request) className += 'sendRequest'
else if (request && !request.answered) className += 'sentRequest'
const request = _find(requests, r => r.user_id === activeMapper.id)
if (!request) className += 'sendRequest'
else if (request && !request.answered) className += 'sentRequest'
else if (request && request.answered && !request.approved) className += 'requestDenied'
}
$('.viewOnly').removeClass('sendRequest sentRequest requestDenied').addClass(className)
},
launch: function (id) {
var start = function (data) {
launch: function(id) {
var start = function(data) {
Active.Map = new DataModelMap(data.map)
DataModel.Mappers = new DataModel.MapperCollection(data.mappers)
DataModel.Collaborators = new DataModel.MapperCollection(data.collaborators)
@ -89,8 +90,7 @@ const Map = {
// add class to .wrapper for specifying whether you can edit the map
if (map.authorizeToEdit(mapper)) {
$('.wrapper').addClass('canEditMap')
}
else {
} else {
Map.setAccessRequest(data.requests, mapper)
}
@ -100,7 +100,7 @@ const Map = {
$('.wrapper').addClass('commonsMap')
}
Map.updateStar()
Map.updateStar()
// set filter mapper H3 text
$('#filter_by_mapper h3').html('MAPPERS')
@ -125,7 +125,7 @@ const Map = {
Realtime.startActiveMap()
Loading.hide()
// for mobile
$('#header_content').html(map.get('name'))
}
@ -135,7 +135,7 @@ const Map = {
success: start
})
},
end: function () {
end: function() {
if (Active.Map) {
$('.wrapper').removeClass('canEditMap commonsMap')
AutoLayout.resetSpiral()
@ -151,10 +151,10 @@ const Map = {
$('.viewOnly').removeClass('isViewOnly')
}
},
updateStar: function () {
updateStar: function() {
if (!Active.Mapper || !DataModel.Stars) return
// update the star/unstar icon
if (DataModel.Stars.find(function (s) { return s.user_id === Active.Mapper.id })) {
if (DataModel.Stars.find(function(s) { return s.user_id === Active.Mapper.id })) {
$('.starMap').addClass('starred')
$('.starMap .tooltipsAbove').html('Unstar')
} else {
@ -162,7 +162,7 @@ const Map = {
$('.starMap .tooltipsAbove').html('Star')
}
},
star: function () {
star: function() {
var self = Map
if (!Active.Map) return
@ -172,72 +172,72 @@ const Map = {
GlobalUI.notifyUser('Map is now starred')
self.updateStar()
},
unstar: function () {
unstar: function() {
var self = Map
if (!Active.Map) return
$.post('/maps/' + Active.Map.id + '/unstar')
DataModel.Stars = DataModel.Stars.filter(function (s) { return s.user_id != Active.Mapper.id })
DataModel.Stars = DataModel.Stars.filter(function(s) { return s.user_id !== Active.Mapper.id })
DataModel.Maps.Starred.remove(Active.Map)
self.updateStar()
self.updateStar()
},
fork: function () {
fork: function() {
GlobalUI.openLightbox('forkmap')
var nodes_data = '',
synapses_data = ''
var nodes_array = []
var synapses_array = []
let nodesData = ''
let synapsesData = ''
let nodesArray = []
let synapsesArray = []
// collect the unfiltered topics
Visualize.mGraph.graph.eachNode(function (n) {
Visualize.mGraph.graph.eachNode(function(n) {
// if the opacity is less than 1 then it's filtered
if (n.getData('alpha') === 1) {
var id = n.getData('topic').id
nodes_array.push(id)
var x, y
nodesArray.push(id)
let x, y
if (n.pos.x && n.pos.y) {
x = n.pos.x
y = n.pos.y
} else {
var x = Math.cos(n.pos.theta) * n.pos.rho
var y = Math.sin(n.pos.theta) * n.pos.rho
x = Math.cos(n.pos.theta) * n.pos.rho
y = Math.sin(n.pos.theta) * n.pos.rho
}
nodes_data += id + '/' + x + '/' + y + ','
nodesData += id + '/' + x + '/' + y + ','
}
})
// collect the unfiltered synapses
DataModel.Synapses.each(function (synapse) {
DataModel.Synapses.each(function(synapse) {
var desc = synapse.get('desc')
var descNotFiltered = Filter.visible.synapses.indexOf(desc) > -1
// make sure that both topics are being added, otherwise, it
// doesn't make sense to add the synapse
var topicsNotFiltered = nodes_array.indexOf(synapse.get('topic1_id')) > -1
topicsNotFiltered = topicsNotFiltered && nodes_array.indexOf(synapse.get('topic2_id')) > -1
var topicsNotFiltered = nodesArray.indexOf(synapse.get('topic1_id')) > -1
topicsNotFiltered = topicsNotFiltered && nodesArray.indexOf(synapse.get('topic2_id')) > -1
if (descNotFiltered && topicsNotFiltered) {
synapses_array.push(synapse.id)
synapsesArray.push(synapse.id)
}
})
synapses_data = synapses_array.join()
nodes_data = nodes_data.slice(0, -1)
synapsesData = synapsesArray.join()
nodesData = nodesData.slice(0, -1)
GlobalUI.CreateMap.topicsToMap = nodes_data
GlobalUI.CreateMap.synapsesToMap = synapses_data
GlobalUI.CreateMap.topicsToMap = nodesData
GlobalUI.CreateMap.synapsesToMap = synapsesData
},
leavePrivateMap: function () {
leavePrivateMap: function() {
var map = Active.Map
DataModel.Maps.Active.remove(map)
DataModel.Maps.Featured.remove(map)
Router.home()
GlobalUI.notifyUser('Sorry! That map has been changed to Private.')
},
cantEditNow: function () {
Realtime.turnOff(true); // true is for 'silence'
cantEditNow: function() {
Realtime.turnOff(true) // true is for 'silence'
GlobalUI.notifyUser('Map was changed to Public. Editing is disabled.')
Active.Map.trigger('changeByOther')
},
canEditNow: function () {
canEditNow: function() {
var confirmString = "You've been granted permission to edit this map. "
confirmString += 'Do you want to reload and enable realtime collaboration?'
var c = window.confirm(confirmString)
@ -245,12 +245,12 @@ const Map = {
Router.maps(Active.Map.id)
}
},
editedByActiveMapper: function () {
editedByActiveMapper: function() {
if (Active.Mapper) {
DataModel.Mappers.add(Active.Mapper)
}
},
exportImage: function () {
exportImage: function() {
var canvas = {}
canvas.canvas = document.createElement('canvas')
@ -263,7 +263,7 @@ const Map = {
canvas.translateOffsetX = 0
canvas.denySelected = true
canvas.getSize = function () {
canvas.getSize = function() {
if (this.size) return this.size
var canvas = this.canvas
this.size = {
@ -272,24 +272,24 @@ const Map = {
}
return this.size
}
canvas.scale = function (x, y) {
var px = this.scaleOffsetX * x,
py = this.scaleOffsetY * y
var dx = this.translateOffsetX * (x - 1) / px,
dy = this.translateOffsetY * (y - 1) / py
canvas.scale = function(x, y) {
const px = this.scaleOffsetX * x
const py = this.scaleOffsetY * y
const dx = this.translateOffsetX * (x - 1) / px
const dy = this.translateOffsetY * (y - 1) / py
this.scaleOffsetX = px
this.scaleOffsetY = py
this.getCtx().scale(x, y)
this.translate(dx, dy)
}
canvas.translate = function (x, y) {
var sx = this.scaleOffsetX,
sy = this.scaleOffsetY
canvas.translate = function(x, y) {
const sx = this.scaleOffsetX
const sy = this.scaleOffsetY
this.translateOffsetX += x * sx
this.translateOffsetY += y * sy
this.getCtx().translate(x, y)
}
canvas.getCtx = function () {
canvas.getCtx = function() {
return this.canvas.getContext('2d')
}
// center it
@ -304,20 +304,20 @@ const Map = {
// pass true to avoid basing it on a selection
JIT.zoomExtents(null, canvas, true)
var c = canvas.canvas,
ctx = canvas.getCtx(),
scale = canvas.scaleOffsetX
const c = canvas.canvas
const ctx = canvas.getCtx()
const scale = canvas.scaleOffsetX
// draw a grey background
ctx.fillStyle = '#d8d9da'
var xPoint = (-(c.width / scale) / 2) - (canvas.translateOffsetX / scale),
yPoint = (-(c.height / scale) / 2) - (canvas.translateOffsetY / scale)
const xPoint = (-(c.width / scale) / 2) - (canvas.translateOffsetX / scale)
const yPoint = (-(c.height / scale) / 2) - (canvas.translateOffsetY / scale)
ctx.fillRect(xPoint, yPoint, c.width / scale, c.height / scale)
// draw the graph
mGraph.graph.eachNode(function (node) {
mGraph.graph.eachNode(function(node) {
var nodeAlpha = node.getData('alpha')
node.eachAdjacency(function (adj) {
node.eachAdjacency(function(adj) {
var nodeTo = adj.nodeTo
if (!!nodeTo.visited === T && node.drawn && nodeTo.drawn) {
mGraph.fx.plotLine(adj, canvas)
@ -340,7 +340,7 @@ const Map = {
var today = new Date()
var dd = today.getDate()
var mm = today.getMonth() + 1; // January is 0!
var mm = today.getMonth() + 1 // January is 0!
var yyyy = today.getFullYear()
if (dd < 10) {
dd = '0' + dd
@ -359,7 +359,7 @@ const Map = {
GlobalUI.notifyUser(downloadMessage)
canvas.canvas.toBlob(imageBlob => {
const formData = new window.FormData();
const formData = new window.FormData()
formData.append('map[screenshot]', imageBlob, filename)
$.ajax({
type: 'PATCH',
@ -368,10 +368,10 @@ const Map = {
data: formData,
processData: false,
contentType: false,
success: function (data) {
success: function(data) {
console.log('successfully uploaded map screenshot')
},
error: function () {
error: function() {
console.log('failed to save map screenshot')
}
})

View file

@ -5,7 +5,7 @@ import DataModel from './DataModel'
const Mapper = {
// this function is to retrieve a mapper JSON object from the database
// @param id = the id of the mapper to retrieve
get: function (id, callback) {
get: function(id, callback) {
$.ajax({
url: `/users/${id}.json`,
success: data => {

View file

@ -4,27 +4,27 @@ import Active from './Active'
import Map from './Map'
const Mobile = {
init: function () {
init: function() {
var self = Mobile
$('#menu_icon').click(self.toggleMenu)
$('#mobile_menu li a').click(self.liClick)
$('#header_content').click(self.titleClick)
self.resizeTitle()
},
resizeTitle: function () {
resizeTitle: function() {
// the 70 relates to padding
$('#header_content').width($(document).width() - 70)
},
liClick: function () {
liClick: function() {
var self = Mobile
$('#header_content').html($(this).text())
self.toggleMenu()
},
toggleMenu: function () {
toggleMenu: function() {
$('#mobile_menu').toggle()
},
titleClick: function () {
titleClick: function() {
if (Active.Map) {
Map.InfoBox.open()
}

View file

@ -6,16 +6,16 @@ import Visualize from './Visualize'
import JIT from './JIT'
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
if (layout == 'grid') {
var numNodes = _.size(Visualize.mGraph.graph.nodes); // this will always be an integer, the # of nodes on your graph visualization
var numColumns = Math.floor(Math.sqrt(numNodes)) // the number of columns to make an even grid
var GRIDSPACE = 400
var row = 0
var column = 0
Visualize.mGraph.graph.eachNode(function (n) {
if (column == numColumns) {
if (layout === 'grid') {
const numNodes = _.size(Visualize.mGraph.graph.nodes) // this will always be an integer, the # of nodes on your graph visualization
const numColumns = Math.floor(Math.sqrt(numNodes)) // the number of columns to make an even grid
const GRIDSPACE = 400
let row = 0
let column = 0
Visualize.mGraph.graph.eachNode(function(n) {
if (column === numColumns) {
column = 0
row += 1
}
@ -26,25 +26,25 @@ const Organize = {
column += 1
})
Visualize.mGraph.animate(JIT.ForceDirected.animateSavedLayout)
} else if (layout == 'grid_full') {
} else if (layout === 'grid_full') {
// this will always be an integer, the # of nodes on your graph visualization
var numNodes = _.size(Visualize.mGraph.graph.nodes)
// var numColumns = Math.floor(Math.sqrt(numNodes)) // the number of columns to make an even grid
// var GRIDSPACE = 400
var height = Visualize.mGraph.canvas.getSize(0).height
var width = Visualize.mGraph.canvas.getSize(0).width
var totalArea = height * width
var cellArea = totalArea / numNodes
var ratio = height / width
var cellWidth = sqrt(cellArea / ratio)
var cellHeight = cellArea / cellWidth
var row = floor(height / cellHeight)
var column = floor(width / cellWidth)
var totalCells = row * column
const numNodes = _.size(Visualize.mGraph.graph.nodes)
const numColumns = Math.floor(Math.sqrt(numNodes)) // the number of columns to make an even grid
const height = Visualize.mGraph.canvas.getSize(0).height
const width = Visualize.mGraph.canvas.getSize(0).width
const totalArea = height * width
const cellArea = totalArea / numNodes
const ratio = height / width
const cellWidth = Math.sqrt(cellArea / ratio)
const cellHeight = cellArea / cellWidth
const GRIDSPACE = 400
let row = Math.floor(height / cellHeight)
let column = Math.floor(width / cellWidth)
const totalCells = row * column
if (totalCells) {
Visualize.mGraph.graph.eachNode(function (n) {
if (column == numColumns) {
Visualize.mGraph.graph.eachNode(function(n) {
if (column === numColumns) {
column = 0
row += 1
}
@ -56,7 +56,7 @@ const Organize = {
})
}
Visualize.mGraph.animate(JIT.ForceDirected.animateSavedLayout)
} else if (layout == 'radial') {
} else if (layout === 'radial') {
var centerX = centerNode.getPos().x
var centerY = centerNode.getPos().y
centerNode.setPos(centerNode.getPos(), 'end')
@ -65,16 +65,16 @@ const Organize = {
var lineLength = 200
var usedNodes = {}
usedNodes[centerNode.id] = centerNode
var radial = function (node, level, degree) {
if (level == 1) {
var radial = function(node, level, degree) {
if (level === 1) {
var numLinksTemp = _.size(node.adjacencies)
var angleTemp = 2 * Math.PI / numLinksTemp
} else {
angleTemp = 2 * Math.PI / 20
}
node.eachAdjacency(function (a) {
var isSecondLevelNode = (centerNode.adjacencies[a.nodeTo.id] != undefined && level > 1)
if (usedNodes[a.nodeTo.id] == undefined && !isSecondLevelNode) {
node.eachAdjacency(function(a) {
var isSecondLevelNode = (centerNode.adjacencies[a.nodeTo.id] !== undefined && level > 1)
if (usedNodes[a.nodeTo.id] === undefined && !isSecondLevelNode) {
var newPos = new $jit.Complex()
newPos.x = level * lineLength * Math.sin(degree) + centerX
newPos.y = level * lineLength * Math.cos(degree) + centerY
@ -88,15 +88,13 @@ const Organize = {
}
radial(centerNode, 1, 0)
Visualize.mGraph.animate(JIT.ForceDirected.animateSavedLayout)
} else if (layout == 'center_viewport') {
var lowX = 0,
lowY = 0,
highX = 0,
highY = 0
var oldOriginX = Visualize.mGraph.canvas.translateOffsetX
var oldOriginY = Visualize.mGraph.canvas.translateOffsetY
} else if (layout === 'center_viewport') {
let lowX = 0
let lowY = 0
let highX = 0
let highY = 0
Visualize.mGraph.graph.eachNode(function (n) {
Visualize.mGraph.graph.eachNode(function(n) {
if (n.id === 1) {
lowX = n.getPos().x
lowY = n.getPos().y
@ -109,9 +107,9 @@ const Organize = {
if (n.getPos().y > highY) highY = n.getPos().y
})
console.log(lowX, lowY, highX, highY)
var newOriginX = (lowX + highX) / 2
var newOriginY = (lowY + highY) / 2
} else window.alert('please call function with a valid layout dammit!')
} else {
window.alert('please call function with a valid layout dammit!')
}
}
}

View file

@ -8,18 +8,18 @@ const PasteInput = {
// thanks to https://github.com/kevva/url-regex
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
// intercept dragged files
// see http://stackoverflow.com/questions/6756583
window.addEventListener("dragover", function(e) {
e = e || window.event;
e.preventDefault();
}, false);
window.addEventListener("drop", function(e) {
e = e || window.event;
e.preventDefault();
window.addEventListener('dragover', function(e) {
e = e || window.event
e.preventDefault()
}, false)
window.addEventListener('drop', function(e) {
e = e || window.event
e.preventDefault()
var coords = Util.pixelsToCoords(Visualize.mGraph, { x: e.clientX, y: e.clientY })
if (e.dataTransfer.files.length > 0) {
self.handleFile(e.dataTransfer.files[0], coords)
@ -32,10 +32,10 @@ const PasteInput = {
}
})
}
}, false);
}, false)
// allow pasting onto canvas (but don't break existing inputs/textareas)
$('body').bind('paste', function (e) {
$('body').bind('paste', function(e) {
if (e.target.tagName === 'INPUT') return
if (e.target.tagName === 'TEXTAREA') return
@ -50,7 +50,7 @@ const PasteInput = {
fileReader.readAsText(file)
fileReader.onload = function(e) {
var text = e.currentTarget.result
if (text.substring(0,5) === '<?xml') {
if (text.substring(0, 5) === '<?xml') {
// assume this is a macOS .webloc link
text = text.replace(/[\s\S]*<string>(.*)<\/string>[\s\S]*/m, '$1')
}

View file

@ -1,15 +1,11 @@
/* global $ */
import _ from 'lodash'
import SimpleWebRTC from 'simplewebrtc'
import SocketIoConnection from 'simplewebrtc/socketioconnection'
import Active from '../Active'
import DataModel from '../DataModel'
import GlobalUI from '../GlobalUI'
import JIT from '../JIT'
import Synapse from '../Synapse'
import Topic from '../Topic'
import Util from '../Util'
import Views from '../Views'
import Visualize from '../Visualize'
@ -67,7 +63,7 @@ import {
synapseUpdated,
synapseRemoved,
synapseDeleted,
mapUpdated,
mapUpdated
} from './receivable'
import {
@ -110,15 +106,15 @@ let Realtime = {
inConversation: false,
localVideo: null,
'junto_spinner_darkgrey.gif': '',
init: function (serverData) {
init: function(serverData) {
var self = Realtime
self.addJuntoListeners()
self.socket = new SocketIoConnection({ url: serverData['REALTIME_SERVER']})
self.socket = new SocketIoConnection({ url: serverData['REALTIME_SERVER'] })
self['junto_spinner_darkgrey.gif'] = serverData['junto_spinner_darkgrey.gif']
self.socket.on('connect', function () {
self.socket.on('connect', function() {
console.log('connected')
subscribeToEvents(self, self.socket)
@ -126,7 +122,7 @@ let Realtime = {
self.startActiveMap()
} else self.disconnected = false
})
self.socket.on('disconnect', function () {
self.socket.on('disconnect', function() {
self.disconnected = true
})
@ -136,7 +132,7 @@ let Realtime = {
localVideoEl: self.videoId,
remoteVideosEl: '',
debug: true,
detectSpeakingEvents: false, //true,
detectSpeakingEvents: false, // true,
autoAdjustMic: false, // true,
autoRequestMedia: false,
localVideo: {
@ -150,11 +146,11 @@ let Realtime = {
},
nick: Active.Mapper.id
})
self.webrtc.webrtc.on('iceFailed', function (peer) {
self.webrtc.webrtc.on('iceFailed', function(peer) {
console.log('local ice failure', peer)
// local ice failure
})
self.webrtc.webrtc.on('connectivityError', function (peer) {
self.webrtc.webrtc.on('connectivityError', function(peer) {
console.log('remote ice failure', peer)
// remote ice failure
})
@ -186,33 +182,33 @@ let Realtime = {
$('body').prepend(self.room.chat.$container)
} // if Active.Mapper
},
addJuntoListeners: function () {
addJuntoListeners: function() {
var self = Realtime
$(document).on(Views.ChatView.events.openTray, function () {
$(document).on(Views.ChatView.events.openTray, function() {
$('.main').addClass('compressed')
self.chatOpen = true
self.positionPeerIcons()
})
$(document).on(Views.ChatView.events.closeTray, function () {
$(document).on(Views.ChatView.events.closeTray, function() {
$('.main').removeClass('compressed')
self.chatOpen = false
self.positionPeerIcons()
})
$(document).on(Views.ChatView.events.videosOn, function () {
$(document).on(Views.ChatView.events.videosOn, function() {
$('#wrapper').removeClass('hideVideos')
})
$(document).on(Views.ChatView.events.videosOff, function () {
$(document).on(Views.ChatView.events.videosOff, function() {
$('#wrapper').addClass('hideVideos')
})
$(document).on(Views.ChatView.events.cursorsOn, function () {
$(document).on(Views.ChatView.events.cursorsOn, function() {
$('#wrapper').removeClass('hideCursors')
})
$(document).on(Views.ChatView.events.cursorsOff, function () {
$(document).on(Views.ChatView.events.cursorsOff, function() {
$('#wrapper').addClass('hideCursors')
})
},
startActiveMap: function () {
startActiveMap: function() {
var self = Realtime
if (Active.Map && Active.Mapper) {
if (Active.Map.authorizeToEdit(Active.Mapper)) {
@ -223,7 +219,7 @@ let Realtime = {
self.room.addMessages(new DataModel.MessageCollection(DataModel.Messages), true)
}
},
endActiveMap: function () {
endActiveMap: function() {
var self = Realtime
$(document).off('.map')
// leave the appropriate rooms to leave
@ -236,7 +232,7 @@ let Realtime = {
self.room.chat.close()
}
},
turnOn: function (notify) {
turnOn: function(notify) {
var self = Realtime
$('.collabCompass').show()
self.room.chat.$container.show()
@ -254,16 +250,16 @@ let Realtime = {
})
self.room.chat.addParticipant(self.activeMapper)
},
setupSocket: function () {
setupSocket: function() {
var self = Realtime
self.checkForCall()
self.joinMap()
},
setupLocalSendables: function () {
setupLocalSendables: function() {
var self = Realtime
// local event listeners that trigger events
var sendCoords = function (event) {
var sendCoords = function(event) {
var pixels = {
x: event.pageX,
y: event.pageY
@ -273,7 +269,7 @@ let Realtime = {
}
$(document).on('mousemove.map', sendCoords)
var zoom = function (event, e) {
var zoom = function(event, e) {
if (e) {
var pixels = {
x: e.pageX,
@ -288,47 +284,47 @@ let Realtime = {
$(document).on(JIT.events.pan + '.map', self.positionPeerIcons)
var dragTopic = function (event, positions) {
var dragTopic = function(event, positions) {
self.dragTopic(positions)
}
$(document).on(JIT.events.topicDrag + '.map', dragTopic)
var createTopic = function (event, data) {
var createTopic = function(event, data) {
self.createTopic(data)
}
$(document).on(JIT.events.newTopic + '.map', createTopic)
var deleteTopic = function (event, data) {
var deleteTopic = function(event, data) {
self.deleteTopic(data)
}
$(document).on(JIT.events.deleteTopic + '.map', deleteTopic)
var removeTopic = function (event, data) {
var removeTopic = function(event, data) {
self.removeTopic(data)
}
$(document).on(JIT.events.removeTopic + '.map', removeTopic)
var createSynapse = function (event, data) {
var createSynapse = function(event, data) {
self.createSynapse(data)
}
$(document).on(JIT.events.newSynapse + '.map', createSynapse)
var deleteSynapse = function (event, data) {
var deleteSynapse = function(event, data) {
self.deleteSynapse(data)
}
$(document).on(JIT.events.deleteSynapse + '.map', deleteSynapse)
var removeSynapse = function (event, data) {
var removeSynapse = function(event, data) {
self.removeSynapse(data)
}
$(document).on(JIT.events.removeSynapse + '.map', removeSynapse)
var createMessage = function (event, data) {
var createMessage = function(event, data) {
self.createMessage(data)
}
$(document).on(Views.Room.events.newMessage + '.map', createMessage)
},
countOthersInConversation: function () {
countOthersInConversation: function() {
var self = Realtime
var count = 0
for (var key in self.mappersOnMap) {
@ -336,7 +332,7 @@ let Realtime = {
}
return count
},
handleVideoAdded: function (v, id) {
handleVideoAdded: function(v, id) {
var self = Realtime
self.positionVideos()
v.setParent($('#wrapper'))
@ -345,16 +341,15 @@ let Realtime = {
})
$('#wrapper').append(v.$container)
},
positionVideos: function () {
positionVideos: function() {
var self = Realtime
var videoIds = Object.keys(self.room.videos)
var numOfVideos = videoIds.length
var numOfVideosToPosition = _.filter(videoIds, function (id) {
return !self.room.videos[id].manuallyPositioned
}).length
// var numOfVideos = videoIds.length
// var numOfVideosToPosition = _.filter(videoIds, function(id) {
// return !self.room.videos[id].manuallyPositioned
// }).length
var screenHeight = $(document).height()
var screenWidth = $(document).width()
var topExtraPadding = 20
var topPadding = 30
var leftPadding = 30
@ -362,7 +357,7 @@ let Realtime = {
var videoWidth = 180
var column = 0
var row = 0
var yFormula = function () {
var yFormula = function() {
var y = topExtraPadding + (topPadding + videoHeight) * row + topPadding
if (y + videoHeight > screenHeight) {
row = 0
@ -372,7 +367,7 @@ let Realtime = {
row++
return y
}
var xFormula = function () {
var xFormula = function() {
var x = (leftPadding + videoWidth) * column + leftPadding
return x
}
@ -385,7 +380,7 @@ let Realtime = {
left: xFormula() + 'px'
})
}
videoIds.forEach(function (id) {
videoIds.forEach(function(id) {
var video = self.room.videos[id]
if (!video.manuallyPositioned) {
video.$container.css({
@ -395,7 +390,7 @@ let Realtime = {
}
})
},
callEnded: function () {
callEnded: function() {
var self = Realtime
self.room.conversationEnding()
@ -408,7 +403,7 @@ let Realtime = {
self.localVideo.view.audioOn()
self.localVideo.view.videoOn()
},
createCompass: function (name, id, image, color) {
createCompass: function(name, id, image, color) {
var str = '<img width="28" height="28" src="' + image + '" /><p>' + name + '</p>'
str += '<div id="compassArrow' + id + '" class="compassArrow"></div>'
$('#compass' + id).remove()
@ -423,20 +418,15 @@ let Realtime = {
'background-color': color
})
},
positionPeerIcons: function () {
positionPeerIcons: function() {
var self = Realtime
for (var key in self.mappersOnMap) {
self.positionPeerIcon(key)
}
},
positionPeerIcon: function (id) {
positionPeerIcon: function(id) {
var self = Realtime
var boundary = self.chatOpen ? '#wrapper' : document
var mapper = self.mappersOnMap[id]
var xMax = $(boundary).width()
var yMax = $(boundary).height()
var compassDiameter = 56
var compassArrowSize = 24
var origPixels = Util.coordsToPixels(Visualize.mGraph, mapper.coords)
var pixels = self.limitPixelsToScreen(origPixels)
@ -448,12 +438,11 @@ let Realtime = {
if (origPixels.x !== pixels.x || origPixels.y !== pixels.y) {
var dy = origPixels.y - pixels.y // opposite
var dx = origPixels.x - pixels.x // adjacent
var ratio = dy / dx
var angle = Math.atan2(dy, dx)
$('#compassArrow' + id).show().css({
transform: 'rotate(' + angle + 'rad)',
'-webkit-transform': 'rotate(' + angle + 'rad)',
'-webkit-transform': 'rotate(' + angle + 'rad)'
})
if (dx > 0) {
@ -464,7 +453,7 @@ let Realtime = {
$('#compass' + id).removeClass('labelLeft')
}
},
limitPixelsToScreen: function (pixels) {
limitPixelsToScreen: function(pixels) {
var self = Realtime
var boundary = self.chatOpen ? '#wrapper' : document
@ -479,65 +468,65 @@ let Realtime = {
yLimit = Math.max(0 + compassArrowSize, pixels.y)
yLimit = Math.min(yLimit, yMax - compassDiameter)
return {x: xLimit,y: yLimit}
return {x: xLimit, y: yLimit}
}
}
const sendables = [
['joinMap',joinMap],
['leaveMap',leaveMap],
['checkForCall',checkForCall],
['acceptCall',acceptCall],
['denyCall',denyCall],
['denyInvite',denyInvite],
['inviteToJoin',inviteToJoin],
['inviteACall',inviteACall],
['joinCall',joinCall],
['leaveCall',leaveCall],
['sendMapperInfo',sendMapperInfo],
['sendCoords',sendCoords],
['createMessage',createMessage],
['dragTopic',dragTopic],
['createTopic',createTopic],
['updateTopic',updateTopic],
['removeTopic',removeTopic],
['deleteTopic',deleteTopic],
['createSynapse',createSynapse],
['updateSynapse',updateSynapse],
['removeSynapse',removeSynapse],
['deleteSynapse',deleteSynapse],
['updateMap',updateMap]
['joinMap', joinMap],
['leaveMap', leaveMap],
['checkForCall', checkForCall],
['acceptCall', acceptCall],
['denyCall', denyCall],
['denyInvite', denyInvite],
['inviteToJoin', inviteToJoin],
['inviteACall', inviteACall],
['joinCall', joinCall],
['leaveCall', leaveCall],
['sendMapperInfo', sendMapperInfo],
['sendCoords', sendCoords],
['createMessage', createMessage],
['dragTopic', dragTopic],
['createTopic', createTopic],
['updateTopic', updateTopic],
['removeTopic', removeTopic],
['deleteTopic', deleteTopic],
['createSynapse', createSynapse],
['updateSynapse', updateSynapse],
['removeSynapse', removeSynapse],
['deleteSynapse', deleteSynapse],
['updateMap', updateMap]
]
sendables.forEach(sendable => {
Realtime[sendable[0]] = sendable[1](Realtime)
})
const subscribeToEvents = (Realtime, socket) => {
socket.on(JUNTO_UPDATED, juntoUpdated(Realtime))
socket.on(INVITED_TO_CALL, invitedToCall(Realtime))
socket.on(INVITED_TO_JOIN, invitedToJoin(Realtime))
socket.on(CALL_ACCEPTED, callAccepted(Realtime))
socket.on(CALL_DENIED, callDenied(Realtime))
socket.on(INVITE_DENIED, inviteDenied(Realtime))
socket.on(CALL_IN_PROGRESS, callInProgress(Realtime))
socket.on(CALL_STARTED, callStarted(Realtime))
socket.on(MAPPER_LIST_UPDATED, mapperListUpdated(Realtime))
socket.on(MAPPER_JOINED_CALL, mapperJoinedCall(Realtime))
socket.on(MAPPER_LEFT_CALL, mapperLeftCall(Realtime))
socket.on(PEER_COORDS_UPDATED, peerCoordsUpdated(Realtime))
socket.on(NEW_MAPPER, newMapper(Realtime))
socket.on(LOST_MAPPER, lostMapper(Realtime))
socket.on(MESSAGE_CREATED, messageCreated(Realtime))
socket.on(TOPIC_DRAGGED, topicDragged(Realtime))
socket.on(TOPIC_CREATED, topicCreated(Realtime))
socket.on(TOPIC_UPDATED, topicUpdated(Realtime))
socket.on(TOPIC_REMOVED, topicRemoved(Realtime))
socket.on(TOPIC_DELETED, topicDeleted(Realtime))
socket.on(SYNAPSE_CREATED, synapseCreated(Realtime))
socket.on(SYNAPSE_UPDATED, synapseUpdated(Realtime))
socket.on(SYNAPSE_REMOVED, synapseRemoved(Realtime))
socket.on(SYNAPSE_DELETED, synapseDeleted(Realtime))
socket.on(MAP_UPDATED, mapUpdated(Realtime))
socket.on(JUNTO_UPDATED, juntoUpdated(Realtime))
socket.on(INVITED_TO_CALL, invitedToCall(Realtime))
socket.on(INVITED_TO_JOIN, invitedToJoin(Realtime))
socket.on(CALL_ACCEPTED, callAccepted(Realtime))
socket.on(CALL_DENIED, callDenied(Realtime))
socket.on(INVITE_DENIED, inviteDenied(Realtime))
socket.on(CALL_IN_PROGRESS, callInProgress(Realtime))
socket.on(CALL_STARTED, callStarted(Realtime))
socket.on(MAPPER_LIST_UPDATED, mapperListUpdated(Realtime))
socket.on(MAPPER_JOINED_CALL, mapperJoinedCall(Realtime))
socket.on(MAPPER_LEFT_CALL, mapperLeftCall(Realtime))
socket.on(PEER_COORDS_UPDATED, peerCoordsUpdated(Realtime))
socket.on(NEW_MAPPER, newMapper(Realtime))
socket.on(LOST_MAPPER, lostMapper(Realtime))
socket.on(MESSAGE_CREATED, messageCreated(Realtime))
socket.on(TOPIC_DRAGGED, topicDragged(Realtime))
socket.on(TOPIC_CREATED, topicCreated(Realtime))
socket.on(TOPIC_UPDATED, topicUpdated(Realtime))
socket.on(TOPIC_REMOVED, topicRemoved(Realtime))
socket.on(TOPIC_DELETED, topicDeleted(Realtime))
socket.on(SYNAPSE_CREATED, synapseCreated(Realtime))
socket.on(SYNAPSE_UPDATED, synapseUpdated(Realtime))
socket.on(SYNAPSE_REMOVED, synapseRemoved(Realtime))
socket.on(SYNAPSE_DELETED, synapseDeleted(Realtime))
socket.on(MAP_UPDATED, mapUpdated(Realtime))
}
export default Realtime

View file

@ -4,6 +4,8 @@
everthing in this file happens as a result of websocket events
*/
import { indexOf } from 'lodash'
import { JUNTO_UPDATED } from './events'
import Active from '../Active'
@ -31,7 +33,7 @@ export const synapseRemoved = self => data => {
Control.hideEdge(edge)
}
var index = _.indexOf(edge.getData('synapses'), synapse)
var index = indexOf(edge.getData('synapses'), synapse)
edge.getData('mappings').splice(index, 1)
edge.getData('synapses').splice(index, 1)
if (edge.getData('displayIndex')) {
@ -49,8 +51,7 @@ export const synapseDeleted = self => data => {
export const synapseCreated = self => data => {
var topic1, topic2, node1, node2, synapse, mapping, cancel, mapper
function waitThenRenderSynapse () {
function waitThenRenderSynapse() {
if (synapse && mapping && mapper) {
topic1 = synapse.getTopic1()
node1 = topic1.get('node')
@ -58,8 +59,7 @@ export const synapseCreated = self => data => {
node2 = topic2.get('node')
Synapse.renderSynapse(mapping, synapse, node1, node2, false)
}
else if (!cancel) {
} else if (!cancel) {
setTimeout(waitThenRenderSynapse, 10)
}
}
@ -73,21 +73,21 @@ export const synapseCreated = self => data => {
}
$.ajax({
url: '/synapses/' + data.mappableid + '.json',
success: function (response) {
success: function(response) {
DataModel.Synapses.add(response)
synapse = DataModel.Synapses.get(response.id)
},
error: function () {
error: function() {
cancel = true
}
})
$.ajax({
url: '/mappings/' + data.mappingid + '.json',
success: function (response) {
success: function(response) {
DataModel.Mappings.add(response)
mapping = DataModel.Mappings.get(response.id)
},
error: function () {
error: function() {
cancel = true
}
})
@ -112,11 +112,10 @@ export const topicDeleted = self => data => {
export const topicCreated = self => data => {
var topic, mapping, mapper, cancel
function waitThenRenderTopic () {
function waitThenRenderTopic() {
if (topic && mapping && mapper) {
Topic.renderTopic(mapping, topic, false, false)
}
else if (!cancel) {
} else if (!cancel) {
setTimeout(waitThenRenderTopic, 10)
}
}
@ -130,21 +129,21 @@ export const topicCreated = self => data => {
}
$.ajax({
url: '/topics/' + data.mappableid + '.json',
success: function (response) {
success: function(response) {
DataModel.Topics.add(response)
topic = DataModel.Topics.get(response.id)
},
error: function () {
error: function() {
cancel = true
}
})
$.ajax({
url: '/mappings/' + data.mappingid + '.json',
success: function (response) {
success: function(response) {
DataModel.Mappings.add(response)
mapping = DataModel.Mappings.get(response.id)
},
error: function () {
error: function() {
cancel = true
}
})
@ -163,20 +162,18 @@ export const mapUpdated = self => data => {
var couldEditBefore = map.authorizeToEdit(Active.Mapper)
var idBefore = map.id
map.fetch({
success: function (model, response) {
var idNow = model.id
var canEditNow = model.authorizeToEdit(Active.Mapper)
if (idNow !== idBefore) {
Map.leavePrivateMap() // this means the map has been changed to private
}
else if (couldEditBefore && !canEditNow) {
Map.cantEditNow()
}
else if (!couldEditBefore && canEditNow) {
Map.canEditNow()
} else {
model.trigger('changeByOther')
}
success: function(model, response) {
var idNow = model.id
var canEditNow = model.authorizeToEdit(Active.Mapper)
if (idNow !== idBefore) {
Map.leavePrivateMap() // this means the map has been changed to private
} else if (couldEditBefore && !canEditNow) {
Map.cantEditNow()
} else if (!couldEditBefore && canEditNow) {
Map.canEditNow()
} else {
model.trigger('changeByOther')
}
}
})
}
@ -187,9 +184,9 @@ export const topicUpdated = self => data => {
if (topic) {
var node = topic.get('node')
topic.fetch({
success: function (model) {
model.set({ node: node })
model.trigger('changeByOther')
success: function(model) {
model.set({ node: node })
model.trigger('changeByOther')
}
})
}
@ -201,9 +198,9 @@ export const synapseUpdated = self => data => {
// edge reset necessary because fetch causes model reset
var edge = synapse.get('edge')
synapse.fetch({
success: function (model) {
model.set({ edge: edge })
model.trigger('changeByOther')
success: function(model) {
model.set({ edge: edge })
model.trigger('changeByOther')
}
})
}
@ -225,7 +222,7 @@ export const topicDragged = self => positions => {
export const peerCoordsUpdated = self => data => {
if (!self.mappersOnMap[data.userid]) return
self.mappersOnMap[data.userid].coords = {x: data.usercoords.x,y: data.usercoords.y}
self.mappersOnMap[data.userid].coords = {x: data.usercoords.x, y: data.usercoords.y}
self.positionPeerIcon(data.userid)
}
@ -311,7 +308,7 @@ export const newMapper = self => data => {
}
export const callAccepted = self => userid => {
var username = self.mappersOnMap[userid].name
// const username = self.mappersOnMap[userid].name
GlobalUI.notifyUser('Conversation starting...')
self.joinCall()
self.room.chat.invitationAnswered(userid)

View file

@ -1,3 +1,5 @@
/* global $ */
import Active from '../Active'
import GlobalUI from '../GlobalUI'
@ -42,7 +44,7 @@ export const leaveMap = self => () => {
}
export const checkForCall = self => () => {
self.socket.emit(CHECK_FOR_CALL, { room: self.room.room, mapid: Active.Map.id })
self.socket.emit(CHECK_FOR_CALL, { room: self.room.room, mapid: Active.Map.id })
}
export const sendMapperInfo = self => userid => {
@ -60,7 +62,7 @@ export const sendMapperInfo = self => userid => {
export const joinCall = self => () => {
self.webrtc.off('readyToCall')
self.webrtc.once('readyToCall', function () {
self.webrtc.once('readyToCall', function() {
self.videoInitialized = true
self.readyToCall = true
self.localVideo.view.manuallyPositioned = false

View file

@ -23,7 +23,7 @@ const _Router = Backbone.Router.extend({
'maps/:id': 'maps', // #maps/7
'topics/:id': 'topics' // #topics/7
},
home: function () {
home: function() {
let self = this
clearTimeout(this.timeoutId)
@ -37,8 +37,8 @@ const _Router = Backbone.Router.extend({
var classes = Active.Mapper ? 'homePage explorePage' : 'homePage'
$('.wrapper').addClass(classes)
var navigate = function () {
self.timeoutId = setTimeout(function () {
var navigate = function() {
self.timeoutId = setTimeout(function() {
self.navigate('')
}, 300)
}
@ -71,7 +71,7 @@ const _Router = Backbone.Router.extend({
Active.Map = null
Active.Topic = null
},
explore: function (section, id) {
explore: function(section, id) {
var self = this
clearTimeout(this.timeoutId)
@ -84,16 +84,16 @@ const _Router = Backbone.Router.extend({
} else if (section === 'mapper') {
$.ajax({
url: '/users/' + id + '.json',
success: function (response) {
success: function(response) {
document.title = response.name + ' | Metamaps'
},
error: function () {}
error: function() {}
})
} else if (section === 'mine') {
document.title = 'Explore My Maps | Metamaps'
}
if (Active.Mapper && section != 'mapper') $('.homeButton a').attr('href', '/explore/' + section)
if (Active.Mapper && section !== 'mapper') $('.homeButton a').attr('href', '/explore/' + section)
$('.wrapper').removeClass('homePage mapPage topicPage')
$('.wrapper').addClass('explorePage')
@ -113,23 +113,23 @@ const _Router = Backbone.Router.extend({
Views.ExploreMaps.setCollection(DataModel.Maps[capitalize])
var navigate = function () {
var navigate = function() {
var path = '/explore/' + self.currentPage
// alter url if for mapper profile page
if (self.currentPage === 'mapper') {
path += '/' + DataModel.Maps.Mapper.mapperId
}
self.navigate(path)
}
var navigateTimeout = function () {
var navigateTimeout = function() {
self.timeoutId = setTimeout(navigate, 300)
}
if (DataModel.Maps[capitalize].length === 0) {
Loading.show()
Views.ExploreMaps.pending = true
setTimeout(function () {
setTimeout(function() {
DataModel.Maps[capitalize].getMaps(navigate) // this will trigger an explore maps render
}, 300) // wait 300 milliseconds till the other animations are done to do the fetch
} else {
@ -149,7 +149,7 @@ const _Router = Backbone.Router.extend({
Active.Map = null
Active.Topic = null
},
maps: function (id) {
maps: function(id) {
clearTimeout(this.timeoutId)
this.currentSection = 'map'
@ -175,7 +175,7 @@ const _Router = Backbone.Router.extend({
Map.end()
Map.launch(id)
},
topics: function (id) {
topics: function(id) {
clearTimeout(this.timeoutId)
this.currentSection = 'topic'
@ -202,7 +202,7 @@ const _Router = Backbone.Router.extend({
const Router = new _Router()
Router.intercept = function (evt) {
Router.intercept = function(evt) {
var segments
var href = {
@ -227,7 +227,7 @@ Router.intercept = function (evt) {
}
}
Router.init = function () {
Router.init = function() {
Backbone.history.start({
silent: true,
pushState: true,

View file

@ -1,5 +1,5 @@
const Selected = {
reset: function () {
reset: function() {
var self = Selected
self.Nodes = []
self.Edges = []

View file

@ -15,12 +15,12 @@ const noOp = () => {}
const Synapse = {
// this function is to retrieve a synapse JSON object from the database
// @param id = the id of the synapse 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 (DataModel.Synapses.get(id) == undefined) {
if (DataModel.Synapses.get(id) === undefined) {
$.ajax({
url: '/synapses/' + id + '.json',
success: function (data) {
success: function(data) {
DataModel.Synapses.add(data)
callback(DataModel.Synapses.get(id))
}
@ -28,9 +28,7 @@ const Synapse = {
} else callback(DataModel.Synapses.get(id))
},
renderSynapse: function (mapping, synapse, node1, node2, createNewInDB) {
var self = Synapse
renderSynapse: function(mapping, synapse, node1, node2, createNewInDB) {
var edgeOnViz
var newedge = synapse.createEdge(mapping)
@ -42,7 +40,7 @@ const Synapse = {
Control.selectEdge(edgeOnViz)
var mappingSuccessCallback = function (mappingModel, response) {
var mappingSuccessCallback = function(mappingModel, response) {
var newSynapseData = {
mappingid: mappingModel.id,
mappableid: mappingModel.get('mappable_id')
@ -50,7 +48,7 @@ const Synapse = {
$(document).trigger(JIT.events.newSynapse, [newSynapseData])
}
var synapseSuccessCallback = function (synapseModel, response) {
var synapseSuccessCallback = function(synapseModel, response) {
if (Active.Map) {
mapping.save({ mappable_id: synapseModel.id }, {
success: mappingSuccessCallback
@ -62,7 +60,7 @@ const Synapse = {
if (synapse.isNew()) {
synapse.save(null, {
success: synapseSuccessCallback,
error: function (model, response) {
error: function(model, response) {
console.log('error saving synapse to database')
}
})
@ -73,14 +71,14 @@ const Synapse = {
}
}
},
createSynapseLocally: function () {
var self = Synapse,
topic1,
topic2,
node1,
node2,
synapse,
mapping
createSynapseLocally: function() {
var self = Synapse
let topic1
let topic2
let node1
let node2
let synapse
let mapping
$(document).trigger(Map.events.editedByActiveMapper)
@ -91,7 +89,7 @@ const Synapse = {
node2 = topic2.get('node')
var len = Selected.Nodes.length
if (len == 0) {
if (len === 0) {
topic1 = DataModel.Topics.get(Create.newSynapse.topic1id)
synapsesToCreate[0] = topic1.get('node')
} else if (len > 0) {
@ -104,13 +102,13 @@ const Synapse = {
synapse = new DataModel.Synapse({
desc: Create.newSynapse.description,
topic1_id: topic1.isNew() ? topic1.cid : topic1.id,
topic2_id: topic2.isNew() ? topic2.cid : topic2.id,
topic2_id: topic2.isNew() ? topic2.cid : topic2.id
})
DataModel.Synapses.add(synapse)
mapping = new DataModel.Mapping({
mappable_type: 'Synapse',
mappable_id: synapse.cid,
mappable_id: synapse.cid
})
DataModel.Mappings.add(mapping)
@ -120,23 +118,19 @@ const Synapse = {
Create.newSynapse.hide()
},
getSynapseFromAutocomplete: function (id) {
var self = Synapse,
topic1,
topic2,
node1,
node2
getSynapseFromAutocomplete: function(id) {
var self = Synapse
self.get(id, synapse => {
var mapping = new DataModel.Mapping({
const mapping = new DataModel.Mapping({
mappable_type: 'Synapse',
mappable_id: synapse.id,
mappable_id: synapse.id
})
DataModel.Mappings.add(mapping)
topic1 = DataModel.Topics.get(Create.newSynapse.topic1id)
node1 = topic1.get('node')
topic2 = DataModel.Topics.get(Create.newSynapse.topic2id)
node2 = topic2.get('node')
const topic1 = DataModel.Topics.get(Create.newSynapse.topic1id)
const node1 = topic1.get('node')
const topic2 = DataModel.Topics.get(Create.newSynapse.topic2id)
const node2 = topic2.get('node')
Create.newSynapse.hide()
self.renderSynapse(mapping, synapse, node1, node2, true)
})

View file

@ -6,7 +6,7 @@ import Visualize from './Visualize'
const SynapseCard = {
openSynapseCard: null,
showCard: function (edge, e) {
showCard: function(edge, e) {
var self = SynapseCard
// reset so we don't interfere with other edges, but first, save its x and y
@ -18,20 +18,20 @@ const SynapseCard = {
Control.deselectEdge(edge)
var index = edge.getData('displayIndex') ? edge.getData('displayIndex') : 0
var synapse = edge.getData('synapses')[index]; // for now, just get the first synapse
var synapse = edge.getData('synapses')[index] // for now, just get the first synapse
// create the wrapper around the form elements, including permissions
// classes to make best_in_place happy
var edit_div = document.createElement('div')
edit_div.innerHTML = '<div id="editSynUpperBar"></div><div id="editSynLowerBar"></div>'
edit_div.setAttribute('id', 'edit_synapse')
var editDiv = document.createElement('div')
editDiv.innerHTML = '<div id="editSynUpperBar"></div><div id="editSynLowerBar"></div>'
editDiv.setAttribute('id', 'edit_synapse')
if (synapse.authorizeToEdit(Active.Mapper)) {
edit_div.className = 'permission canEdit'
edit_div.className += synapse.authorizePermissionChange(Active.Mapper) ? ' yourEdge' : ''
editDiv.className = 'permission canEdit'
editDiv.className += synapse.authorizePermissionChange(Active.Mapper) ? ' yourEdge' : ''
} else {
edit_div.className = 'permission cannotEdit'
editDiv.className = 'permission cannotEdit'
}
$('#wrapper').append(edit_div)
$('#wrapper').append(editDiv)
self.populateShowCard(edge, synapse)
@ -51,12 +51,12 @@ const SynapseCard = {
self.openSynapseCard = edge
},
hideCard: function () {
hideCard: function() {
$('#edit_synapse').remove()
SynapseCard.openSynapseCard = null
},
populateShowCard: function (edge, synapse) {
populateShowCard: function(edge, synapse) {
var self = SynapseCard
self.add_synapse_count(edge)
@ -66,13 +66,13 @@ const SynapseCard = {
self.add_perms_form(synapse)
self.add_direction_form(synapse)
},
add_synapse_count: function (edge) {
add_synapse_count: function(edge) {
var count = edge.getData('synapses').length
$('#editSynUpperBar').append('<div id="synapseCardCount">' + count + '</div>')
},
add_desc_form: function (synapse) {
var data_nil = 'Click to add description.'
add_desc_form: function(synapse) {
var dataNil = 'Click to add description.'
// TODO make it so that this would work even in sandbox mode,
// currently with Best_in_place it won't
@ -83,29 +83,29 @@ const SynapseCard = {
$('#edit_synapse_desc').attr('data-bip-object', 'synapse')
$('#edit_synapse_desc').attr('data-bip-attribute', 'desc')
$('#edit_synapse_desc').attr('data-bip-type', 'textarea')
$('#edit_synapse_desc').attr('data-bip-nil', data_nil)
$('#edit_synapse_desc').attr('data-bip-nil', dataNil)
$('#edit_synapse_desc').attr('data-bip-url', '/synapses/' + synapse.id)
$('#edit_synapse_desc').attr('data-bip-value', synapse.get('desc'))
$('#edit_synapse_desc').html(synapse.get('desc'))
// if edge data is blank or just whitespace, populate it with data_nil
if ($('#edit_synapse_desc').html().trim() == '') {
// if edge data is blank or just whitespace, populate it with dataNil
if ($('#edit_synapse_desc').html().trim() === '') {
if (synapse.authorizeToEdit(Active.Mapper)) {
$('#edit_synapse_desc').html(data_nil)
$('#edit_synapse_desc').html(dataNil)
} else {
$('#edit_synapse_desc').html('(no description)')
}
}
$('#edit_synapse_desc').keypress(function (e) {
$('#edit_synapse_desc').keypress(function(e) {
const ENTER = 13
if (e.which === ENTER) {
$(this).data('bestInPlaceEditor').update()
}
})
$('#edit_synapse_desc').bind('ajax:success', function () {
$('#edit_synapse_desc').bind('ajax:success', function() {
var desc = $(this).html()
if (desc == data_nil) {
if (desc === dataNil) {
synapse.set('desc', '')
} else {
synapse.set('desc', desc)
@ -115,7 +115,7 @@ const SynapseCard = {
Visualize.mGraph.plot()
})
},
add_drop_down: function (edge, synapse) {
add_drop_down: function(edge, synapse) {
var list, i, synapses, l, desc
synapses = edge.getData('synapses')
@ -124,13 +124,13 @@ const SynapseCard = {
if (l > 1) {
// append the element that you click to show dropdown select
$('#editSynUpperBar').append('<div id="dropdownSynapses"></div>')
$('#dropdownSynapses').click(function (e) {
$('#dropdownSynapses').click(function(e) {
e.preventDefault()
e.stopPropagation() // stop it from immediately closing it again
$('#switchSynapseList').toggle()
})
// hide the dropdown again if you click anywhere else on the synapse card
$('#edit_synapse').click(function () {
$('#edit_synapse').click(function() {
$('#switchSynapseList').hide()
})
@ -150,7 +150,7 @@ const SynapseCard = {
// attach click listeners to list items that
// will cause it to switch the displayed synapse
// when you click it
$('#switchSynapseList li').click(function (e) {
$('#switchSynapseList li').click(function(e) {
e.stopPropagation()
var index = parseInt($(this).attr('data-synapse-index'))
edge.setData('displayIndex', index)
@ -159,26 +159,26 @@ const SynapseCard = {
})
}
},
add_user_info: function (synapse) {
add_user_info: function(synapse) {
var u = '<div id="edgeUser" class="hoverForTip">'
u += '<a href="/explore/mapper/' + synapse.get('user_id') + '"> <img src="" width="24" height="24" /></a>'
u += '<div class="tip">' + synapse.get('user_name') + '</div></div>'
$('#editSynLowerBar').append(u)
// get mapper image
var setMapperImage = function (mapper) {
var setMapperImage = function(mapper) {
$('#edgeUser img').attr('src', mapper.get('image'))
}
Mapper.get(synapse.get('user_id'), setMapperImage)
},
add_perms_form: function (synapse) {
add_perms_form: function(synapse) {
// permissions - if owner, also allow permission editing
$('#editSynLowerBar').append('<div class="mapPerm ' + synapse.get('calculated_permission').substring(0, 2) + '"></div>')
// ability to change permission
var selectingPermission = false
var permissionLiClick = function (event) {
var permissionLiClick = function(event) {
selectingPermission = false
var permission = $(this).attr('class')
synapse.save({
@ -190,7 +190,7 @@ const SynapseCard = {
event.stopPropagation()
}
var openPermissionSelect = function (event) {
var openPermissionSelect = function(event) {
if (!selectingPermission) {
selectingPermission = true
$(this).addClass('minimize') // this line flips the drop down arrow to a pull up arrow
@ -206,7 +206,7 @@ const SynapseCard = {
}
}
var hidePermissionSelect = function () {
var hidePermissionSelect = function() {
selectingPermission = false
$('#edit_synapse.yourEdge .mapPerm').removeClass('minimize') // this line flips the pull up arrow to a drop down arrow
$('#edit_synapse .permissionSelect').remove()
@ -218,7 +218,7 @@ const SynapseCard = {
}
}, // add_perms_form
add_direction_form: function (synapse) {
add_direction_form: function(synapse) {
// directionality checkboxes
$('#editSynLowerBar').append('<div id="edit_synapse_left"></div>')
$('#editSynLowerBar').append('<div id="edit_synapse_right"></div>')
@ -227,14 +227,16 @@ const SynapseCard = {
// determine which node is to the left and the right
// if directly in a line, top is left
let left
let right
if (edge.nodeFrom.pos.x < edge.nodeTo.pos.x ||
edge.nodeFrom.pos.x == edge.nodeTo.pos.x &&
edge.nodeFrom.pos.x === edge.nodeTo.pos.x &&
edge.nodeFrom.pos.y < edge.nodeTo.pos.y) {
var left = edge.nodeTo.getData('topic')
var right = edge.nodeFrom.getData('topic')
left = edge.nodeTo.getData('topic')
right = edge.nodeFrom.getData('topic')
} else {
var left = edge.nodeFrom.getData('topic')
var right = edge.nodeTo.getData('topic')
left = edge.nodeFrom.getData('topic')
right = edge.nodeTo.getData('topic')
}
/*
@ -243,24 +245,24 @@ const SynapseCard = {
* Else check the 'left' checkbox since the arrow is incoming.
*/
var directionCat = synapse.get('category'); // both, none, from-to
if (directionCat == 'from-to') {
var from_to = [synapse.get('topic1_id'), synapse.get('topic2_id')]
if (from_to[0] == left.id) {
var directionCat = synapse.get('category') // both, none, from-to
if (directionCat === 'from-to') {
var fromTo = [synapse.get('topic1_id'), synapse.get('topic2_id')]
if (fromTo[0] === left.id) {
// check left checkbox
$('#edit_synapse_left').addClass('checked')
} else {
// check right checkbox
$('#edit_synapse_right').addClass('checked')
}
} else if (directionCat == 'both') {
} else if (directionCat === 'both') {
// check both checkboxes
$('#edit_synapse_left').addClass('checked')
$('#edit_synapse_right').addClass('checked')
}
if (synapse.authorizeToEdit(Active.Mapper)) {
$('#edit_synapse_left, #edit_synapse_right').click(function () {
$('#edit_synapse_left, #edit_synapse_right').click(function() {
$(this).toggleClass('checked')
var leftChecked = $('#edit_synapse_left').is('.checked')

View file

@ -23,20 +23,20 @@ const noOp = () => {}
const Topic = {
// this function is to retrieve a topic JSON object from the database
// @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 (DataModel.Topics.get(id) == undefined) {
if (DataModel.Topics.get(id) === undefined) {
$.ajax({
url: '/topics/' + id + '.json',
success: function (data) {
success: function(data) {
DataModel.Topics.add(data)
callback(DataModel.Topics.get(id))
}
})
} else callback(DataModel.Topics.get(id))
},
launch: function (id) {
var start = function (data) {
launch: function(id) {
var start = function(data) {
Active.Topic = new DataModel.Topic(data.topic)
DataModel.Creators = new DataModel.MapperCollection(data.creators)
DataModel.Topics = new DataModel.TopicCollection([data.topic].concat(data.relatives))
@ -62,7 +62,7 @@ const Topic = {
Filter.checkMetacodes()
Filter.checkSynapses()
Filter.checkMappers()
// for mobile
$('#header_content').html(Active.Topic.get('name'))
}
@ -72,7 +72,7 @@ const Topic = {
success: start
})
},
end: function () {
end: function() {
if (Active.Topic) {
$('.rightclickmenu').remove()
TopicCard.hideCard()
@ -80,13 +80,13 @@ const Topic = {
Filter.close()
}
},
centerOn: function (nodeid, callback) {
centerOn: function(nodeid, callback) {
// don't clash with fetchRelatives
if (!Visualize.mGraph.busy) {
Visualize.mGraph.onClick(nodeid, {
hideLabels: false,
duration: 1000,
onComplete: function () {
onComplete: function() {
if (callback) callback()
}
})
@ -94,21 +94,21 @@ const Topic = {
Active.Topic = DataModel.Topics.get(nodeid)
}
},
fetchRelatives: function (nodes, metacode_id) {
fetchRelatives: function(nodes, metacodeId) {
var self = this
var node = $.isArray(nodes) ? nodes[0] : nodes
var topics = DataModel.Topics.map(function (t) { return t.id })
var topics_string = topics.join()
var topics = DataModel.Topics.map(function(t) { return t.id })
var topicsString = topics.join()
var creators = DataModel.Creators.map(function (t) { return t.id })
var creators_string = creators.join()
var creators = DataModel.Creators.map(function(t) { return t.id })
var creatorsString = creators.join()
var topic = node.getData('topic')
var successCallback;
successCallback = function (data) {
var successCallback
successCallback = function(data) {
if (Visualize.mGraph.busy) {
// don't clash with centerOn
window.setTimeout(function() { successCallback(data) }, 100)
@ -131,12 +131,12 @@ const Topic = {
var i, l, t, s
Visualize.mGraph.graph.eachNode(function (n) {
Visualize.mGraph.graph.eachNode(function(n) {
t = DataModel.Topics.get(n.id)
t.set({ node: n }, { silent: true })
t.updateNode()
n.eachAdjacency(function (edge) {
n.eachAdjacency(function(edge) {
if (!edge.getData('init')) {
edge.setData('init', true)
@ -150,31 +150,30 @@ const Topic = {
})
})
if ($.isArray(nodes) && nodes.length > 1) {
self.fetchRelatives(nodes.slice(1), metacode_id)
self.fetchRelatives(nodes.slice(1), metacodeId)
}
}
var paramsString = metacode_id ? 'metacode=' + metacode_id + '&' : ''
paramsString += 'network=' + topics_string + '&creators=' + creators_string
let paramsString = metacodeId ? 'metacode=' + metacodeId + '&' : ''
paramsString += 'network=' + topicsString + '&creators=' + creatorsString
$.ajax({
type: 'GET',
url: '/topics/' + topic.id + '/relatives.json?' + paramsString,
success: successCallback,
error: function () {}
error: function() {}
})
},
// opts is additional options in a hash
// TODO: move createNewInDB and permitCreateSynapseAfter into opts
renderTopic: function (mapping, topic, createNewInDB, permitCreateSynapseAfter, opts = {}) {
var self = Topic
renderTopic: function(mapping, topic, createNewInDB, permitCreateSynapseAfter, opts = {}) {
var nodeOnViz, tempPos
var newnode = topic.createNode()
var midpoint = {}, pixelPos
var midpoint = {}
var pixelPos
if (!$.isEmptyObject(Visualize.mGraph.graph.nodes)) {
Visualize.mGraph.graph.addNode(newnode)
@ -209,7 +208,7 @@ const Topic = {
Visualize.mGraph.fx.animate({
modes: ['node-property:dim'],
duration: 500,
onComplete: function () {
onComplete: function() {
JIT.tempNode = null
JIT.tempNode2 = null
JIT.tempInit = false
@ -220,7 +219,7 @@ const Topic = {
Visualize.mGraph.fx.animate({
modes: ['node-property:dim'],
duration: 500,
onComplete: function () {}
onComplete: function() {}
})
}
} else {
@ -238,11 +237,11 @@ const Topic = {
Visualize.mGraph.fx.animate({
modes: ['node-property:dim'],
duration: 500,
onComplete: function () {}
onComplete: function() {}
})
}
var mappingSuccessCallback = function (mappingModel, response, topicModel) {
var mappingSuccessCallback = function(mappingModel, response, topicModel) {
var newTopicData = {
mappingid: mappingModel.id,
mappableid: mappingModel.get('mappable_id')
@ -254,13 +253,13 @@ const Topic = {
opts.success(topicModel)
}
}
var topicSuccessCallback = function (topicModel, response) {
var topicSuccessCallback = function(topicModel, response) {
if (Active.Map) {
mapping.save({ mappable_id: topicModel.id }, {
success: function (model, response) {
success: function(model, response) {
mappingSuccessCallback(model, response, topicModel)
},
error: function (model, response) {
error: function(model, response) {
console.log('error saving mapping to database')
}
})
@ -275,7 +274,7 @@ const Topic = {
if (topic.isNew()) {
topic.save(null, {
success: topicSuccessCallback,
error: function (model, response) {
error: function(model, response) {
console.log('error saving topic to database')
}
})
@ -286,7 +285,7 @@ const Topic = {
}
}
},
createTopicLocally: function () {
createTopicLocally: function() {
var self = Topic
if (Create.newTopic.name === '') {
@ -315,7 +314,7 @@ const Topic = {
xloc: nextCoords ? nextCoords.x : Create.newTopic.x,
yloc: nextCoords ? nextCoords.y : Create.newTopic.y,
mappable_id: topic.cid,
mappable_type: 'Topic',
mappable_type: 'Topic'
})
DataModel.Mappings.add(mapping)
@ -325,7 +324,7 @@ const Topic = {
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
// hide the 'double-click to add a topic' message
@ -344,7 +343,7 @@ const Topic = {
xloc: nextCoords ? nextCoords.x : Create.newTopic.x,
yloc: nextCoords ? nextCoords.y : Create.newTopic.y,
mappable_type: 'Topic',
mappable_id: topic.id,
mappable_id: topic.id
})
DataModel.Mappings.add(mapping)
@ -353,7 +352,7 @@ const Topic = {
if (Create.newTopic.pinned) Create.newTopic.beingCreated = true
})
},
getMapFromAutocomplete: function (data) {
getMapFromAutocomplete: function(data) {
var self = Topic
$(document).trigger(Map.events.editedByActiveMapper)
@ -371,7 +370,7 @@ const Topic = {
xloc: Create.newTopic.x,
yloc: Create.newTopic.y,
mappable_id: topic.cid,
mappable_type: 'Topic',
mappable_type: 'Topic'
})
DataModel.Mappings.add(mapping)
@ -383,7 +382,7 @@ const Topic = {
// this blocked the enterKeyHandler from creating a new topic as well
if (Create.newTopic.pinned) Create.newTopic.beingCreated = true
},
getTopicFromSearch: function (event, id) {
getTopicFromSearch: function(event, id) {
var self = Topic
$(document).trigger(Map.events.editedByActiveMapper)
@ -394,7 +393,7 @@ const Topic = {
xloc: nextCoords.x,
yloc: nextCoords.y,
mappable_type: 'Topic',
mappable_id: topic.id,
mappable_id: topic.id
})
DataModel.Mappings.add(mapping)
self.renderTopic(mapping, topic, true, true)

View file

@ -12,7 +12,7 @@ const TopicCard = {
openTopicCard: null, // stores the topic that's currently open
authorizedToEdit: false, // stores boolean for edit permission for open topic card
RAILS_ENV: undefined,
init: function (serverData) {
init: function(serverData) {
var self = TopicCard
if (serverData.RAILS_ENV) {
@ -40,7 +40,7 @@ const TopicCard = {
* Will open the Topic Card for the node that it's passed
* @param {$jit.Graph.Node} node
*/
showCard: function (node, opts) {
showCard: function(node, opts) {
var self = TopicCard
if (!opts) opts = {}
var topic = node.getData('topic')
@ -55,16 +55,14 @@ const TopicCard = {
}
})
},
hideCard: function () {
hideCard: function() {
var self = TopicCard
$('.showcard').fadeOut('fast')
self.openTopicCard = null
self.authorizedToEdit = false
},
embedlyCardRendered: function (iframe) {
var self = TopicCard
embedlyCardRendered: function(iframe) {
$('#embedlyLinkLoader').hide()
// means that the embedly call returned 404 not found
@ -81,7 +79,7 @@ const TopicCard = {
$('#linkremove').click(TopicCard.removeLink)
}
},
removeLink: function () {
removeLink: function() {
var self = TopicCard
self.openTopicCard.save({
link: null
@ -93,43 +91,43 @@ const TopicCard = {
},
showLinkLoader: function() {
var loader = new CanvasLoader('embedlyLinkLoader')
loader.setColor('#4fb5c0'); // default is '#000000'
loader.setColor('#4fb5c0') // default is '#000000'
loader.setDiameter(28) // default is 40
loader.setDensity(41) // default is 40
loader.setRange(0.9); // default is 1.3
loader.setRange(0.9) // default is 1.3
loader.show() // Hidden by default
},
showLink: function(topic) {
var e = embedly('card', document.getElementById('embedlyLink'))
if (!e && TopicCard.RAILS_ENV != 'development') {
if (!e && TopicCard.RAILS_ENV !== 'development') {
TopicCard.handleInvalidLink()
} else if (!e) {
$('#embedlyLink').attr('target', '_blank').html(topic.get('link')).show()
$('#embedlyLinkLoader').hide()
}
},
bindShowCardListeners: function (topic) {
bindShowCardListeners: function(topic) {
var self = TopicCard
var showCard = document.getElementById('showcard')
var authorized = self.authorizedToEdit
// get mapper image
var setMapperImage = function (mapper) {
var setMapperImage = function(mapper) {
$('.contributorIcon').attr('src', mapper.get('image'))
}
Mapper.get(topic.get('user_id'), setMapperImage)
// starting embed.ly
var resetFunc = function () {
var resetFunc = function() {
$('#addLinkInput input').val('')
$('#addLinkInput input').focus()
}
var inputEmbedFunc = function (event) {
var inputEmbedFunc = function(event) {
var element = this
setTimeout(function () {
setTimeout(function() {
var text = $(element).val()
if (event.type == 'paste' || (event.type == 'keyup' && event.which == 13)) {
if (event.type === 'paste' || (event.type === 'keyup' && event.which === 13)) {
// TODO evaluate converting this to '//' no matter what (infer protocol)
if (text.slice(0, 7) !== 'http://' &&
text.slice(0, 8) !== 'https://' &&
@ -165,18 +163,18 @@ const TopicCard = {
var selectingMetacode = false
// attach the listener that shows the metacode title when you hover over the image
$('.showcard .metacodeImage').mouseenter(function () {
$('.showcard .metacodeImage').mouseenter(function() {
$('.showcard .icon').css('z-index', '4')
$('.showcard .metacodeTitle').show()
})
$('.showcard .linkItem.icon').mouseleave(function () {
$('.showcard .linkItem.icon').mouseleave(function() {
if (!selectingMetacode) {
$('.showcard .metacodeTitle').hide()
$('.showcard .icon').css('z-index', '1')
}
})
var metacodeLiClick = function () {
var metacodeLiClick = function() {
selectingMetacode = false
var metacodeId = parseInt($(this).attr('data-id'))
var metacode = DataModel.Metacodes.get(metacodeId)
@ -193,7 +191,7 @@ const TopicCard = {
$('.showcard .icon').css('z-index', '1')
}
var openMetacodeSelect = function (event) {
var openMetacodeSelect = function(event) {
var TOPICCARD_WIDTH = 300
var METACODESELECT_WIDTH = 404
var MAX_METACODELIST_HEIGHT = 270
@ -219,7 +217,6 @@ const TopicCard = {
var windowHeight = $(window).height()
var showcardTop = parseInt($('.showcard').css('top'))
var topicTitleHeight = $('.showcard .title').height() + parseInt($('.showcard .title').css('padding-top')) + parseInt($('.showcard .title').css('padding-bottom'))
var heightOfSetList = $('.showcard .metacodeSelect').height()
var distanceFromBottom = windowHeight - (showcardTop + topicTitleHeight)
if (distanceFromBottom < MAX_METACODELIST_HEIGHT) {
$('.metacodeSelect').addClass('onBottomEdge')
@ -230,7 +227,7 @@ const TopicCard = {
}
}
var hideMetacodeSelect = function () {
var hideMetacodeSelect = function() {
selectingMetacode = false
$('.metacodeSelect').hide().removeClass('onRightEdge onBottomEdge')
$('.metacodeTitle').hide()
@ -240,13 +237,13 @@ const TopicCard = {
if (authorized) {
$('.showcard .metacodeTitle').click(openMetacodeSelect)
$('.showcard').click(hideMetacodeSelect)
$('.metacodeSelect > ul > li').click(function (event) {
$('.metacodeSelect > ul > li').click(function(event) {
event.stopPropagation()
})
$('.metacodeSelect li li').click(metacodeLiClick)
var bipName = $(showCard).find('.best_in_place_name')
bipName.bind('best_in_place:activate', function () {
bipName.bind('best_in_place:activate', function() {
var $el = bipName.find('textarea')
var el = $el[0]
@ -254,12 +251,12 @@ const TopicCard = {
$('.showcard .title').append('<div class="nameCounter forTopic"></div>')
var callback = function (data) {
var callback = function(data) {
$('.nameCounter.forTopic').html(data.all + '/140')
}
Countable.live(el, callback)
})
bipName.bind('best_in_place:deactivate', function () {
bipName.bind('best_in_place:deactivate', function() {
$('.nameCounter.forTopic').remove()
})
bipName.keypress(function(e) {
@ -270,7 +267,7 @@ const TopicCard = {
})
// bind best_in_place ajax callbacks
bipName.bind('ajax:success', function () {
bipName.bind('ajax:success', function() {
var name = Util.decodeEntities($(this).html())
topic.set('name', name)
topic.trigger('saved')
@ -278,7 +275,7 @@ const TopicCard = {
// this is for all subsequent renders after in-place editing the desc field
const bipDesc = $(showCard).find('.best_in_place_desc')
bipDesc.bind('ajax:success', function () {
bipDesc.bind('ajax:success', function() {
var desc = $(this).html() === $(this).data('bip-nil')
? ''
: $(this).text()
@ -296,7 +293,7 @@ const TopicCard = {
})
}
var permissionLiClick = function (event) {
var permissionLiClick = function(event) {
selectingPermission = false
var permission = $(this).attr('class')
topic.save({
@ -308,7 +305,7 @@ const TopicCard = {
event.stopPropagation()
}
var openPermissionSelect = function (event) {
var openPermissionSelect = function(event) {
if (!selectingPermission) {
selectingPermission = true
$(this).addClass('minimize') // this line flips the drop down arrow to a pull up arrow
@ -324,7 +321,7 @@ const TopicCard = {
}
}
var hidePermissionSelect = function () {
var hidePermissionSelect = function() {
selectingPermission = false
$('.showcard .yourTopic .mapPerm').removeClass('minimize') // this line flips the pull up arrow to a drop down arrow
$('.showcard .permissionSelect').remove()
@ -336,15 +333,15 @@ const TopicCard = {
$('.showcard').click(hidePermissionSelect)
}
$('.links .mapCount').unbind().click(function (event) {
$('.links .mapCount').unbind().click(function(event) {
$('.mapCount .tip').toggle()
$('.showcard .hoverTip').toggleClass('hide')
event.stopPropagation()
})
$('.mapCount .tip').unbind().click(function (event) {
$('.mapCount .tip').unbind().click(function(event) {
event.stopPropagation()
})
$('.showcard').unbind('.hideTip').bind('click.hideTip', function () {
$('.showcard').unbind('.hideTip').bind('click.hideTip', function() {
$('.mapCount .tip').hide()
$('.showcard .hoverTip').removeClass('hide')
})
@ -353,26 +350,26 @@ const TopicCard = {
var originalText = $('.showMore').html()
$('.mapCount .tip .showMore').unbind().toggle(
function (event) {
function(event) {
$('.extraText').toggleClass('hideExtra')
$('.showMore').html('Show less...')
},
function (event) {
function(event) {
$('.extraText').toggleClass('hideExtra')
$('.showMore').html(originalText)
})
$('.mapCount .tip showMore').unbind().click(function (event) {
$('.mapCount .tip showMore').unbind().click(function(event) {
event.stopPropagation()
})
},
handleInvalidLink: function () {
handleInvalidLink: function() {
var self = TopicCard
self.removeLink()
GlobalUI.notifyUser('Invalid link')
},
populateShowCard: function (topic) {
populateShowCard: function(topic) {
var self = TopicCard
var showCard = document.getElementById('showcard')
@ -383,7 +380,7 @@ const TopicCard = {
var html = self.generateShowcardHTML.render(topicForTemplate)
if (topic.authorizeToEdit(Active.Mapper)) {
var perm = document.createElement('div')
let perm = document.createElement('div')
var string = 'permission canEdit'
if (topic.authorizePermissionChange(Active.Mapper)) string += ' yourTopic'
@ -391,7 +388,7 @@ const TopicCard = {
perm.innerHTML = html
showCard.appendChild(perm)
} else {
var perm = document.createElement('div')
let perm = document.createElement('div')
perm.className = 'permission cannotEdit'
perm.innerHTML = html
showCard.appendChild(perm)
@ -401,9 +398,7 @@ const TopicCard = {
},
generateShowcardHTML: null, // will be initialized into a Hogan template within init function
// generateShowcardHTML
buildObject: function (topic) {
var self = TopicCard
buildObject: function(topic) {
var nodeValues = {}
var authorized = topic.authorizeToEdit(Active.Mapper)
@ -438,18 +433,18 @@ const TopicCard = {
nodeValues.inmaps = ''
if (inmapsAr.length < 6) {
for (let i = 0; i < inmapsAr.length; i++) {
var url = '/maps/' + inmapsLinks[i]
const url = '/maps/' + inmapsLinks[i]
nodeValues.inmaps += '<li><a href="' + url + '">' + inmapsAr[i] + '</a></li>'
}
} else {
for (let i = 0; i < 5; i++) {
var url = '/maps/' + inmapsLinks[i]
const url = '/maps/' + inmapsLinks[i]
nodeValues.inmaps += '<li><a href="' + url + '">' + inmapsAr[i] + '</a></li>'
}
var extra = inmapsAr.length - 5
const extra = inmapsAr.length - 5
nodeValues.inmaps += '<li><span class="showMore">See ' + extra + ' more...</span></li>'
for (let i = 5; i < inmapsAr.length; i++) {
var url = '/maps/' + inmapsLinks[i]
const url = '/maps/' + inmapsLinks[i]
nodeValues.inmaps += '<li class="hideExtra extraText"><a href="' + url + '">' + inmapsAr[i] + '</a></li>'
}
}

View file

@ -7,22 +7,22 @@ const Util = {
// Line Splitter Function
// copyright Stephen Chapman, 19th April 2006
// you may copy this code but please keep the copyright notice as well
splitLine: function (st, n) {
splitLine: function(st, n) {
var b = ''
var s = st ? st : ''
var s = st || ''
while (s.length > n) {
var c = s.substring(0, n)
var d = c.lastIndexOf(' ')
var e = c.lastIndexOf('\n')
if (e != -1) d = e
if (d == -1) d = n
if (e !== -1) d = e
if (d === -1) d = n
b += c.substring(0, d) + '\n'
s = s.substring(d + 1)
}
return b + s
},
nowDateFormatted: function (date = new Date(Date.now())) {
nowDateFormatted: function(date = new Date(Date.now())) {
const month = (date.getMonth() + 1) < 10 ? '0' + (date.getMonth() + 1) : (date.getMonth() + 1)
const day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
const year = date.getFullYear()
@ -30,33 +30,32 @@ const Util = {
return month + '/' + day + '/' + year
},
decodeEntities: function (desc) {
var str, temp = document.createElement('p')
decodeEntities: function(desc) {
let temp = document.createElement('p')
temp.innerHTML = desc // browser handles the topics
str = temp.textContent || temp.innerText
let str = temp.textContent || temp.innerText
temp = null // delete the element
return str
}, // decodeEntities
getDistance: function (p1, p2) {
getDistance: function(p1, p2) {
return Math.sqrt(Math.pow((p2.x - p1.x), 2) + Math.pow((p2.y - p1.y), 2))
},
// Try using Visualize.mGraph
coordsToPixels: function (mGraph, coords) {
coordsToPixels: function(mGraph, coords) {
if (mGraph) {
var canvas = mGraph.canvas,
s = canvas.getSize(),
p = canvas.getPos(),
ox = canvas.translateOffsetX,
oy = canvas.translateOffsetY,
sx = canvas.scaleOffsetX,
sy = canvas.scaleOffsetY
var pixels = {
const canvas = mGraph.canvas
const s = canvas.getSize()
const p = canvas.getPos()
const ox = canvas.translateOffsetX
const oy = canvas.translateOffsetY
const sx = canvas.scaleOffsetX
const sy = canvas.scaleOffsetY
return {
x: (coords.x / (1 / sx)) + p.x + s.width / 2 + ox,
y: (coords.y / (1 / sy)) + p.y + s.height / 2 + oy
}
return pixels
} else {
return {
x: 0,
@ -66,29 +65,27 @@ const Util = {
},
// Try using Visualize.mGraph
pixelsToCoords: function (mGraph, pixels) {
var coords
pixelsToCoords: function(mGraph, pixels) {
if (mGraph) {
var canvas = mGraph.canvas,
s = canvas.getSize(),
p = canvas.getPos(),
ox = canvas.translateOffsetX,
oy = canvas.translateOffsetY,
sx = canvas.scaleOffsetX,
sy = canvas.scaleOffsetY
coords = {
const canvas = mGraph.canvas
const s = canvas.getSize()
const p = canvas.getPos()
const ox = canvas.translateOffsetX
const oy = canvas.translateOffsetY
const sx = canvas.scaleOffsetX
const sy = canvas.scaleOffsetY
return {
x: (pixels.x - p.x - s.width / 2 - ox) * (1 / sx),
y: (pixels.y - p.y - s.height / 2 - oy) * (1 / sy),
y: (pixels.y - p.y - s.height / 2 - oy) * (1 / sy)
}
} else {
coords = {
return {
x: 0,
y: 0
}
}
return coords
},
getPastelColor: function (opts = {}) {
getPastelColor: function(opts = {}) {
const rseed = opts.rseed === undefined ? Math.random() : opts.rseed
const gseed = opts.gseed === undefined ? Math.random() : opts.gseed
const bseed = opts.bseed === undefined ? Math.random() : opts.bseed
@ -98,7 +95,7 @@ const Util = {
return Util.colorLuminance('#' + r + g + b, -0.4)
},
// darkens a hex value by 'lum' percentage
colorLuminance: function (hex, lum) {
colorLuminance: function(hex, lum) {
// validate hex string
hex = String(hex).replace(/[^0-9a-f]/gi, '')
if (hex.length < 6) {
@ -107,25 +104,25 @@ const Util = {
lum = lum || 0
// convert to decimal and change luminosity
var rgb = '#', c, i
for (i = 0; i < 3; i++) {
c = parseInt(hex.substr(i * 2, 2), 16)
var rgb = '#'
for (let i = 0; i < 3; i++) {
let c = parseInt(hex.substr(i * 2, 2), 16)
c = Math.round(Math.min(Math.max(0, c + (c * lum)), 255)).toString(16)
rgb += ('00' + c).substr(c.length)
}
return rgb
},
openLink: function(url){
var win = (url !== "") ? window.open(url, '_blank') : "empty";
openLink: function(url) {
var win = (url !== '') ? window.open(url, '_blank') : 'empty'
if (win) {
//Browser has allowed it to be opened
return true;
// Browser has allowed it to be opened
return true
} else {
//Browser has blocked it
alert('Please allow popups in order to open the link');
return false;
// Browser has blocked it
window.alert('Please allow popups in order to open the link')
return false
}
},
mdToHTML: text => {
@ -134,24 +131,24 @@ const Util = {
return new HtmlRenderer({ safe: true })
.render(new Parser().parse(safeText))
},
logCanvasAttributes: function(canvas){
logCanvasAttributes: function(canvas) {
const fakeMgraph = { canvas }
return {
scaleX: canvas.scaleOffsetX,
scaleY: canvas.scaleOffsetY,
centreCoords: Util.pixelsToCoords(fakeMgraph, { x: canvas.canvases[0].size.width / 2, y: canvas.canvases[0].size.height / 2 }),
};
centreCoords: Util.pixelsToCoords(fakeMgraph, { x: canvas.canvases[0].size.width / 2, y: canvas.canvases[0].size.height / 2 })
}
},
resizeCanvas: function(canvas){
resizeCanvas: function(canvas) {
// Store the current canvas attributes, i.e. scale and map-coordinate at the centre of the user's screen
const oldAttr = Util.logCanvasAttributes(canvas);
const oldAttr = Util.logCanvasAttributes(canvas)
// Resize the canvas to fill the new window size. Based on how JIT works, this also resets the map back to scale 1 and tranlations = 0
canvas.resize($(window).width(), $(window).height())
// Return the map to the original scale, and then put the previous central map-coordinate back to the centre of user's newly resized screen
canvas.scale(oldAttr.scaleX, oldAttr.scaleY)
const newAttr = Util.logCanvasAttributes(canvas);
const newAttr = Util.logCanvasAttributes(canvas)
canvas.translate(newAttr.centreCoords.x - oldAttr.centreCoords.x, newAttr.centreCoords.y - oldAttr.centreCoords.y)
}
}

View file

@ -40,7 +40,7 @@ var Private = {
</span>
<div class='clearfloat'></div>
</div>`,
templates: function () {
templates: function() {
underscore.templateSettings = {
interpolate: /\{\{(.+?)\}\}/g
}
@ -48,7 +48,7 @@ var Private = {
this.participantTemplate = underscore.template(Private.participantHTML)
},
createElements: function () {
createElements: function() {
this.$unread = $('<div class="chat-unread"></div>')
this.$button = $('<div class="chat-button"><div class="tooltips">Chat</div></div>')
this.$messageInput = $('<textarea placeholder="Send a message..." class="chat-input"></textarea>')
@ -71,7 +71,7 @@ var Private = {
this.$messages = $('<div class="chat-messages"></div>')
this.$container = $('<div class="chat-box"></div>')
},
attachElements: function () {
attachElements: function() {
this.$button.append(this.$unread)
this.$juntoHeader.append(this.$videoToggle)
@ -88,40 +88,40 @@ var Private = {
this.$container.append(this.$messages)
this.$container.append(this.$messageInput)
},
addEventListeners: function () {
addEventListeners: function() {
var self = this
this.participants.on('add', function (participant) {
this.participants.on('add', function(participant) {
Private.addParticipant.call(self, participant)
})
this.participants.on('remove', function (participant) {
this.participants.on('remove', function(participant) {
Private.removeParticipant.call(self, participant)
})
this.$button.on('click', function () {
this.$button.on('click', function() {
Handlers.buttonClick.call(self)
})
this.$videoToggle.on('click', function () {
this.$videoToggle.on('click', function() {
Handlers.videoToggleClick.call(self)
})
this.$cursorToggle.on('click', function () {
this.$cursorToggle.on('click', function() {
Handlers.cursorToggleClick.call(self)
})
this.$soundToggle.on('click', function () {
this.$soundToggle.on('click', function() {
Handlers.soundToggleClick.call(self)
})
this.$messageInput.on('keyup', function (event) {
this.$messageInput.on('keyup', function(event) {
Handlers.keyUp.call(self, event)
})
this.$messageInput.on('focus', function () {
this.$messageInput.on('focus', function() {
Handlers.inputFocus.call(self)
})
this.$messageInput.on('blur', function () {
this.$messageInput.on('blur', function() {
Handlers.inputBlur.call(self)
})
},
initializeSounds: function (soundUrls) {
initializeSounds: function(soundUrls) {
this.sound = new Howl({
src: soundUrls,
sprite: {
@ -133,15 +133,15 @@ var Private = {
}
})
},
incrementUnread: function () {
incrementUnread: function() {
this.unreadMessages++
this.$unread.html(this.unreadMessages)
this.$unread.show()
},
addMessage: function (message, isInitial, wasMe) {
addMessage: function(message, isInitial, wasMe) {
if (!this.isOpen && !isInitial) Private.incrementUnread.call(this)
function addZero (i) {
function addZero(i) {
if (i < 10) {
i = '0' + i
}
@ -162,20 +162,20 @@ var Private = {
if (!wasMe && !isInitial && this.alertSound) this.sound.play('receivechat')
},
initialMessages: function () {
initialMessages: function() {
var messages = this.messages.models
for (var i = 0; i < messages.length; i++) {
Private.addMessage.call(this, messages[i], true)
}
},
handleInputMessage: function () {
handleInputMessage: function() {
var message = {
message: this.$messageInput.val()
}
this.$messageInput.val('')
$(document).trigger(ChatView.events.message + '-' + this.room, [message])
},
addParticipant: function (participant) {
addParticipant: function(participant) {
var p = _.clone(participant.attributes)
if (p.self) {
p.selfClass = 'is-self'
@ -187,46 +187,46 @@ var Private = {
var html = this.participantTemplate(p)
this.$participants.append(html)
},
removeParticipant: function (participant) {
removeParticipant: function(participant) {
this.$container.find('.participant-' + participant.get('id')).remove()
}
}
var Handlers = {
buttonClick: function () {
buttonClick: function() {
if (this.isOpen) this.close()
else if (!this.isOpen) this.open()
},
videoToggleClick: function () {
videoToggleClick: function() {
this.$videoToggle.toggleClass('active')
this.videosShowing = !this.videosShowing
$(document).trigger(this.videosShowing ? ChatView.events.videosOn : ChatView.events.videosOff)
},
cursorToggleClick: function () {
cursorToggleClick: function() {
this.$cursorToggle.toggleClass('active')
this.cursorsShowing = !this.cursorsShowing
$(document).trigger(this.cursorsShowing ? ChatView.events.cursorsOn : ChatView.events.cursorsOff)
},
soundToggleClick: function () {
soundToggleClick: function() {
this.alertSound = !this.alertSound
this.$soundToggle.toggleClass('active')
},
keyUp: function (event) {
keyUp: function(event) {
switch (event.which) {
case 13: // enter
Private.handleInputMessage.call(this)
break
}
},
inputFocus: function () {
inputFocus: function() {
$(document).trigger(ChatView.events.inputFocus)
},
inputBlur: function () {
inputBlur: function() {
$(document).trigger(ChatView.events.inputBlur)
}
}
const ChatView = function (messages, mapper, room) {
const ChatView = function(messages, mapper, room) {
this.room = room
this.mapper = mapper
this.messages = messages // backbone collection
@ -249,7 +249,7 @@ const ChatView = function (messages, mapper, room) {
})
}
ChatView.prototype.conversationInProgress = function (participating) {
ChatView.prototype.conversationInProgress = function(participating) {
this.$conversationInProgress.show()
this.$participants.addClass('is-live')
if (participating) this.$participants.addClass('is-participating')
@ -258,7 +258,7 @@ ChatView.prototype.conversationInProgress = function (participating) {
// hide invite to call buttons
}
ChatView.prototype.conversationEnded = function () {
ChatView.prototype.conversationEnded = function() {
this.$conversationInProgress.hide()
this.$participants.removeClass('is-live')
this.$participants.removeClass('is-participating')
@ -267,42 +267,42 @@ ChatView.prototype.conversationEnded = function () {
this.$participants.find('.participant').removeClass('pending')
}
ChatView.prototype.leaveConversation = function () {
ChatView.prototype.leaveConversation = function() {
this.$participants.removeClass('is-participating')
}
ChatView.prototype.mapperJoinedCall = function (id) {
ChatView.prototype.mapperJoinedCall = function(id) {
this.$participants.find('.participant-' + id).addClass('active')
}
ChatView.prototype.mapperLeftCall = function (id) {
ChatView.prototype.mapperLeftCall = function(id) {
this.$participants.find('.participant-' + id).removeClass('active')
}
ChatView.prototype.invitationPending = function (id) {
ChatView.prototype.invitationPending = function(id) {
this.$participants.find('.participant-' + id).addClass('pending')
}
ChatView.prototype.invitationAnswered = function (id) {
ChatView.prototype.invitationAnswered = function(id) {
this.$participants.find('.participant-' + id).removeClass('pending')
}
ChatView.prototype.addParticipant = function (participant) {
ChatView.prototype.addParticipant = function(participant) {
this.participants.add(participant)
}
ChatView.prototype.removeParticipant = function (username) {
ChatView.prototype.removeParticipant = function(username) {
var p = this.participants.find(p => p.get('username') === username)
if (p) {
this.participants.remove(p)
}
}
ChatView.prototype.removeParticipants = function () {
ChatView.prototype.removeParticipants = function() {
this.participants.remove(this.participants.models)
}
ChatView.prototype.open = function () {
ChatView.prototype.open = function() {
this.$container.css({
right: '0'
})
@ -314,12 +314,12 @@ ChatView.prototype.open = function () {
$(document).trigger(ChatView.events.openTray)
}
ChatView.prototype.addMessage = function (message, isInitial, wasMe) {
ChatView.prototype.addMessage = function(message, isInitial, wasMe) {
this.messages.add(message)
Private.addMessage.call(this, message, isInitial, wasMe)
}
ChatView.prototype.scrollMessages = function (duration) {
ChatView.prototype.scrollMessages = function(duration) {
duration = duration || 0
this.$messages.animate({
@ -327,13 +327,13 @@ ChatView.prototype.scrollMessages = function (duration) {
}, duration)
}
ChatView.prototype.clearMessages = function () {
ChatView.prototype.clearMessages = function() {
this.unreadMessages = 0
this.$unread.hide()
this.$messages.empty()
}
ChatView.prototype.close = function () {
ChatView.prototype.close = function() {
this.$container.css({
right: '-300px'
})
@ -342,7 +342,7 @@ ChatView.prototype.close = function () {
$(document).trigger(ChatView.events.closeTray)
}
ChatView.prototype.remove = function () {
ChatView.prototype.remove = function() {
this.$button.off()
this.$container.remove()
}

View file

@ -4,6 +4,7 @@ import React from 'react'
import ReactDOM from 'react-dom' // TODO ensure this isn't a double import
import Active from '../Active'
import DataModel from '../DataModel'
import GlobalUI from '../GlobalUI'
import Realtime from '../Realtime'
import Loading from '../Loading'
@ -12,7 +13,7 @@ import Maps from '../../components/Maps'
const ExploreMaps = {
pending: false,
mapper: null,
setCollection: function (collection) {
setCollection: function(collection) {
var self = ExploreMaps
if (self.collection) {
@ -25,7 +26,7 @@ const ExploreMaps = {
self.collection.on('successOnFetch', self.handleSuccess)
self.collection.on('errorOnFetch', self.handleError)
},
render: function (cb) {
render: function(cb) {
var self = ExploreMaps
if (!self.collection) return
@ -35,19 +36,19 @@ const ExploreMaps = {
section: self.collection.id,
maps: self.collection,
juntoState: Realtime.juntoState,
moreToLoad: self.collection.page != 'loadedAll',
moreToLoad: self.collection.page !== 'loadedAll',
user: self.collection.id === 'mapper' ? self.mapper : null,
loadMore: self.loadMore,
pending: self.pending,
onStar: function (map) {
onStar: function(map) {
$.post('/maps/' + map.id + '/star')
map.set('star_count', map.get('star_count') + 1)
if (Metamaps.Stars) Metamaps.Stars.push({ user_id: Active.Mapper.id, map_id: map.id })
Metamaps.Maps.Starred.add(map)
if (DataModel.Stars) DataModel.Stars.push({ user_id: Active.Mapper.id, map_id: map.id })
DataModel.Maps.Starred.add(map)
GlobalUI.notifyUser('Map is now starred')
self.render()
},
onRequest: function (map) {
onRequest: function(map) {
$.post({
url: `/maps/${map.id}/access_request`
})
@ -62,47 +63,47 @@ const ExploreMaps = {
if (cb) cb()
Loading.hide()
},
loadMore: function () {
loadMore: function() {
var self = ExploreMaps
if (self.collection.page != "loadedAll") {
if (self.collection.page !== 'loadedAll') {
self.collection.getMaps()
self.pending = true
}
self.render()
},
handleSuccess: function (cb) {
handleSuccess: function(cb) {
var self = ExploreMaps
self.pending = false
if (self.collection && self.collection.id === 'mapper') {
self.fetchUserThenRender(cb)
} else {
self.render(cb)
Metamaps.Loading.hide()
Loading.hide()
}
},
handleError: function () {
handleError: function() {
console.log('error loading maps!') // TODO
Metamaps.Loading.hide()
Loading.hide()
},
fetchUserThenRender: function (cb) {
fetchUserThenRender: function(cb) {
var self = ExploreMaps
if (self.mapper && self.mapper.id === self.collection.mapperId) {
self.render(cb)
return Metamaps.Loading.hide()
return Loading.hide()
}
// first load the mapper object and then call the render function
$.ajax({
url: '/users/' + self.collection.mapperId + '/details.json',
success: function (response) {
success: function(response) {
self.mapper = response
self.render(cb)
Metamaps.Loading.hide()
Loading.hide()
},
error: function () {
error: function() {
self.render(cb)
Metamaps.Loading.hide()
Loading.hide()
}
})
}

View file

@ -14,8 +14,6 @@ import ChatView from './ChatView'
import VideoView from './VideoView'
const Room = function(opts = {}) {
var self = this
this.isActiveRoom = false
this.socket = opts.socket
this.webrtc = opts.webrtc
@ -77,128 +75,124 @@ Room.prototype.setPeopleCount = function(count) {
this.peopleCount = count
}
Room.prototype.init = function () {
var self = this
Room.prototype.init = function() {
var self = this
$(document).on(VideoView.events.audioControlClick, function (event, videoView) {
if (!videoView.audioStatus) self.webrtc.mute()
else if (videoView.audioStatus) self.webrtc.unmute()
})
$(document).on(VideoView.events.videoControlClick, function (event, videoView) {
if (!videoView.videoStatus) self.webrtc.pauseVideo()
else if (videoView.videoStatus) self.webrtc.resumeVideo()
})
$(document).on(VideoView.events.audioControlClick, function(event, videoView) {
if (!videoView.audioStatus) self.webrtc.mute()
else if (videoView.audioStatus) self.webrtc.unmute()
})
$(document).on(VideoView.events.videoControlClick, function(event, videoView) {
if (!videoView.videoStatus) self.webrtc.pauseVideo()
else if (videoView.videoStatus) self.webrtc.resumeVideo()
})
this.webrtc.webrtc.off('peerStreamAdded')
this.webrtc.webrtc.off('peerStreamRemoved')
this.webrtc.on('peerStreamAdded', function (peer) {
var mapper = Realtime.mappersOnMap[peer.nick]
peer.avatar = mapper.image
peer.username = mapper.name
if (self.isActiveRoom) {
self.addVideo(peer)
}
})
this.webrtc.on('peerStreamRemoved', function (peer) {
if (self.isActiveRoom) {
self.removeVideo(peer)
}
})
this.webrtc.on('mute', function (data) {
var v = self.videos[data.id]
if (!v) return
if (data.name === 'audio') {
v.audioStatus = false
}
else if (data.name === 'video') {
v.videoStatus = false
v.$avatar.show()
}
if (!v.audioStatus && !v.videoStatus) v.$container.hide()
})
this.webrtc.on('unmute', function (data) {
var v = self.videos[data.id]
if (!v) return
if (data.name === 'audio') {
v.audioStatus = true
}
else if (data.name === 'video') {
v.videoStatus = true
v.$avatar.hide()
}
v.$container.show()
})
var sendChatMessage = function (event, data) {
self.sendChatMessage(data)
this.webrtc.webrtc.off('peerStreamAdded')
this.webrtc.webrtc.off('peerStreamRemoved')
this.webrtc.on('peerStreamAdded', function(peer) {
var mapper = Realtime.mappersOnMap[peer.nick]
peer.avatar = mapper.image
peer.username = mapper.name
if (self.isActiveRoom) {
self.addVideo(peer)
}
$(document).on(ChatView.events.message + '-' + this.room, sendChatMessage)
})
this.webrtc.on('peerStreamRemoved', function(peer) {
if (self.isActiveRoom) {
self.removeVideo(peer)
}
})
this.webrtc.on('mute', function(data) {
var v = self.videos[data.id]
if (!v) return
if (data.name === 'audio') {
v.audioStatus = false
} else if (data.name === 'video') {
v.videoStatus = false
v.$avatar.show()
}
if (!v.audioStatus && !v.videoStatus) v.$container.hide()
})
this.webrtc.on('unmute', function(data) {
const v = self.videos[data.id]
if (!v) return
if (data.name === 'audio') {
v.audioStatus = true
} else if (data.name === 'video') {
v.videoStatus = true
v.$avatar.hide()
}
v.$container.show()
})
var sendChatMessage = function(event, data) {
self.sendChatMessage(data)
}
$(document).on(ChatView.events.message + '-' + this.room, sendChatMessage)
}
Room.prototype.videoAdded = function (callback) {
this._videoAdded = callback
Room.prototype.videoAdded = function(callback) {
this._videoAdded = callback
}
Room.prototype.addVideo = function(peer) {
const id = this.webrtc.getDomId(peer)
const video = attachMediaStream(peer.stream)
const v = new VideoView(video, null, id, false, { DOUBLE_CLICK_TOLERANCE: 200, avatar: peer.avatar, username: peer.username })
this.videos[peer.id] = v
if (this._videoAdded) this._videoAdded(v, peer.nick)
}
Room.prototype.removeVideo = function(peer) {
var id = typeof peer === 'string' ? peer : peer.id
if (this.videos[id]) {
this.videos[id].remove()
delete this.videos[id]
}
}
Room.prototype.addVideo = function (peer) {
var
id = this.webrtc.getDomId(peer),
video = attachMediaStream(peer.stream)
var
v = new VideoView(video, null, id, false, { DOUBLE_CLICK_TOLERANCE: 200, avatar: peer.avatar, username: peer.username })
this.videos[peer.id] = v
if (this._videoAdded) this._videoAdded(v, peer.nick)
}
Room.prototype.removeVideo = function (peer) {
var id = typeof peer == 'string' ? peer : peer.id
if (this.videos[id]) {
this.videos[id].remove()
delete this.videos[id]
}
}
Room.prototype.sendChatMessage = function (data) {
var self = this
//this.roomRef.child('messages').push(data)
if (self.chat.alertSound) self.chat.sound.play('sendchat')
var m = new DataModel.Message({
message: data.message,
resource_id: Active.Map.id,
resource_type: "Map"
})
m.save(null, {
success: function (model, response) {
self.addMessages(new DataModel.MessageCollection(model), false, true)
$(document).trigger(Room.events.newMessage, [model])
},
error: function (model, response) {
console.log('error!', response)
}
})
}
Room.prototype.sendChatMessage = function(data) {
var self = this
// this.roomRef.child('messages').push(data)
if (self.chat.alertSound) self.chat.sound.play('sendchat')
var m = new DataModel.Message({
message: data.message,
resource_id: Active.Map.id,
resource_type: 'Map'
})
m.save(null, {
success: function(model, response) {
self.addMessages(new DataModel.MessageCollection(model), false, true)
$(document).trigger(Room.events.newMessage, [model])
},
error: function(model, response) {
console.log('error!', response)
}
})
}
// they should be instantiated as backbone models before they get
// passed to this function
Room.prototype.addMessages = function (messages, isInitial, wasMe) {
var self = this
Room.prototype.addMessages = function(messages, isInitial, wasMe) {
var self = this
messages.models.forEach(function (message) {
self.chat.addMessage(message, isInitial, wasMe)
})
}
messages.models.forEach(function(message) {
self.chat.addMessage(message, isInitial, wasMe)
})
}
/**
* @class
* @static
*/
Room.events = {
newMessage: "Room:newMessage"
newMessage: 'Room:newMessage'
}
export default Room

View file

@ -1,189 +1,188 @@
/* global $ */
var Private = {
addControls: function() {
var self = this;
addControls: function() {
var self = this
this.$audioControl = $('<div class="video-audio"></div>');
this.$videoControl = $('<div class="video-video"></div>');
this.$audioControl = $('<div class="video-audio"></div>')
this.$videoControl = $('<div class="video-video"></div>')
this.$audioControl.on('click', function () {
Handlers.audioControlClick.call(self);
});
this.$audioControl.on('click', function() {
Handlers.audioControlClick.call(self)
})
this.$videoControl.on('click', function () {
Handlers.videoControlClick.call(self);
});
this.$videoControl.on('click', function() {
Handlers.videoControlClick.call(self)
})
this.$container.append(this.$audioControl);
this.$container.append(this.$videoControl);
},
cancelClick: function() {
this.mouseIsDown = false;
this.$container.append(this.$audioControl)
this.$container.append(this.$videoControl)
},
cancelClick: function() {
this.mouseIsDown = false
if (this.hasMoved) {
if (this.hasMoved) {
}
$(document).trigger(VideoView.events.dragEnd);
}
};
$(document).trigger(VideoView.events.dragEnd)
}
}
var Handlers = {
mousedown: function(event) {
this.mouseIsDown = true;
this.hasMoved = false;
this.mouseMoveStart = {
x: event.pageX,
y: event.pageY
};
this.posStart = {
x: parseInt(this.$container.css('left'), '10'),
y: parseInt(this.$container.css('top'), '10')
}
$(document).trigger(VideoView.events.mousedown);
},
mouseup: function(event) {
$(document).trigger(VideoView.events.mouseup, [this]);
var storedTime = this.lastClick;
var now = Date.now();
this.lastClick = now;
if (now - storedTime < this.config.DOUBLE_CLICK_TOLERANCE) {
$(document).trigger(VideoView.events.doubleClick, [this]);
}
},
mousemove: function(event) {
var
diffX,
diffY,
newX,
newY;
if (this.$parent && this.mouseIsDown) {
this.manuallyPositioned = true;
this.hasMoved = true;
diffX = event.pageX - this.mouseMoveStart.x;
diffY = this.mouseMoveStart.y - event.pageY;
newX = this.posStart.x + diffX;
newY = this.posStart.y - diffY;
this.$container.css({
top: newY,
left: newX
});
}
},
audioControlClick: function() {
if (this.audioStatus) {
this.audioOff();
} else {
this.audioOn();
}
$(document).trigger(VideoView.events.audioControlClick, [this]);
},
videoControlClick: function() {
if (this.videoStatus) {
this.videoOff();
} else {
this.videoOn();
}
$(document).trigger(VideoView.events.videoControlClick, [this]);
},
};
var VideoView = function(video, $parent, id, isMyself, config) {
var self = this;
this.$parent = $parent; // mapView
this.video = video;
this.id = id;
this.config = config;
this.mouseIsDown = false;
this.mouseDownOffset = { x: 0, y: 0 };
this.lastClick = null;
this.hasMoved = false;
this.audioStatus = true;
this.videoStatus = true;
this.$container = $('<div></div>');
this.$container.addClass('collaborator-video' + (isMyself ? ' my-video' : ''));
this.$container.attr('id', 'container_' + id);
var $vidContainer = $('<div></div>');
$vidContainer.addClass('video-cutoff');
$vidContainer.append(this.video);
this.avatar = config.avatar;
this.$avatar = $('<img draggable="false" class="collaborator-video-avatar" src="' + config.avatar + '" width="150" height="150" />');
$vidContainer.append(this.$avatar);
this.$container.append($vidContainer);
this.$container.on('mousedown', function (event) {
Handlers.mousedown.call(self, event);
});
if (isMyself) {
Private.addControls.call(this);
mousedown: function(event) {
this.mouseIsDown = true
this.hasMoved = false
this.mouseMoveStart = {
x: event.pageX,
y: event.pageY
}
this.posStart = {
x: parseInt(this.$container.css('left'), '10'),
y: parseInt(this.$container.css('top'), '10')
}
// suppress contextmenu
this.video.oncontextmenu = function () { return false; };
$(document).trigger(VideoView.events.mousedown)
},
mouseup: function(event) {
$(document).trigger(VideoView.events.mouseup, [this])
if (this.$parent) this.setParent(this.$parent);
};
var storedTime = this.lastClick
var now = Date.now()
this.lastClick = now
if (now - storedTime < this.config.DOUBLE_CLICK_TOLERANCE) {
$(document).trigger(VideoView.events.doubleClick, [this])
}
},
mousemove: function(event) {
var
diffX,
diffY,
newX,
newY
if (this.$parent && this.mouseIsDown) {
this.manuallyPositioned = true
this.hasMoved = true
diffX = event.pageX - this.mouseMoveStart.x
diffY = this.mouseMoveStart.y - event.pageY
newX = this.posStart.x + diffX
newY = this.posStart.y - diffY
this.$container.css({
top: newY,
left: newX
})
}
},
audioControlClick: function() {
if (this.audioStatus) {
this.audioOff()
} else {
this.audioOn()
}
$(document).trigger(VideoView.events.audioControlClick, [this])
},
videoControlClick: function() {
if (this.videoStatus) {
this.videoOff()
} else {
this.videoOn()
}
$(document).trigger(VideoView.events.videoControlClick, [this])
}
}
var VideoView = function(video, $parent, id, isMyself, config) {
var self = this
this.$parent = $parent // mapView
this.video = video
this.id = id
this.config = config
this.mouseIsDown = false
this.mouseDownOffset = { x: 0, y: 0 }
this.lastClick = null
this.hasMoved = false
this.audioStatus = true
this.videoStatus = true
this.$container = $('<div></div>')
this.$container.addClass('collaborator-video' + (isMyself ? ' my-video' : ''))
this.$container.attr('id', 'container_' + id)
var $vidContainer = $('<div></div>')
$vidContainer.addClass('video-cutoff')
$vidContainer.append(this.video)
this.avatar = config.avatar
this.$avatar = $('<img draggable="false" class="collaborator-video-avatar" src="' + config.avatar + '" width="150" height="150" />')
$vidContainer.append(this.$avatar)
this.$container.append($vidContainer)
this.$container.on('mousedown', function(event) {
Handlers.mousedown.call(self, event)
})
if (isMyself) {
Private.addControls.call(this)
}
// suppress contextmenu
this.video.oncontextmenu = function() { return false }
if (this.$parent) this.setParent(this.$parent)
}
VideoView.prototype.setParent = function($parent) {
var self = this;
this.$parent = $parent;
this.$parent.off('.video' + this.id);
this.$parent.on('mouseup.video' + this.id, function (event) {
Handlers.mouseup.call(self, event);
Private.cancelClick.call(self);
});
this.$parent.on('mousemove.video' + this.id, function (event) {
Handlers.mousemove.call(self, event);
});
var self = this
this.$parent = $parent
this.$parent.off('.video' + this.id)
this.$parent.on('mouseup.video' + this.id, function(event) {
Handlers.mouseup.call(self, event)
Private.cancelClick.call(self)
})
this.$parent.on('mousemove.video' + this.id, function(event) {
Handlers.mousemove.call(self, event)
})
}
VideoView.prototype.setAvatar = function (src) {
this.$avatar.attr('src', src);
this.avatar = src;
VideoView.prototype.setAvatar = function(src) {
this.$avatar.attr('src', src)
this.avatar = src
}
VideoView.prototype.remove = function () {
this.$container.off();
if (this.$parent) this.$parent.off('.video' + this.id);
this.$container.remove();
VideoView.prototype.remove = function() {
this.$container.off()
if (this.$parent) this.$parent.off('.video' + this.id)
this.$container.remove()
}
VideoView.prototype.videoOff = function () {
this.$videoControl.addClass('active');
this.$avatar.show();
this.videoStatus = false;
VideoView.prototype.videoOff = function() {
this.$videoControl.addClass('active')
this.$avatar.show()
this.videoStatus = false
}
VideoView.prototype.videoOn = function () {
this.$videoControl.removeClass('active');
this.$avatar.hide();
this.videoStatus = true;
VideoView.prototype.videoOn = function() {
this.$videoControl.removeClass('active')
this.$avatar.hide()
this.videoStatus = true
}
VideoView.prototype.audioOff = function () {
this.$audioControl.addClass('active');
this.audioStatus = false;
VideoView.prototype.audioOff = function() {
this.$audioControl.addClass('active')
this.audioStatus = false
}
VideoView.prototype.audioOn = function () {
this.$audioControl.removeClass('active');
this.audioStatus = true;
VideoView.prototype.audioOn = function() {
this.$audioControl.removeClass('active')
this.audioStatus = true
}
/**
@ -191,12 +190,12 @@ VideoView.prototype.audioOn = function () {
* @static
*/
VideoView.events = {
mousedown: "VideoView:mousedown",
mouseup: "VideoView:mouseup",
doubleClick: "VideoView:doubleClick",
dragEnd: "VideoView:dragEnd",
audioControlClick: "VideoView:audioControlClick",
videoControlClick: "VideoView:videoControlClick",
};
mousedown: 'VideoView:mousedown',
mouseup: 'VideoView:mouseup',
doubleClick: 'VideoView:doubleClick',
dragEnd: 'VideoView:dragEnd',
audioControlClick: 'VideoView:audioControlClick',
videoControlClick: 'VideoView:videoControlClick'
}
export default VideoView

View file

@ -6,9 +6,9 @@ import VideoView from './VideoView'
import Room from './Room'
import { JUNTO_UPDATED } from '../Realtime/events'
const Views = {
const Views = {
init: () => {
$(document).on(JUNTO_UPDATED, () => ExploreMaps.render())
$(document).on(JUNTO_UPDATED, () => ExploreMaps.render())
},
ExploreMaps,
ChatView,

View file

@ -17,54 +17,53 @@ const Visualize = {
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
touchDragNode: null,
init: function (serverData) {
init: function(serverData) {
var self = Visualize
if (serverData.VisualizeType) self.type = serverData.VisualizeType
// disable awkward dragging of the canvas element that would sometimes happen
$('#infovis-canvas').on('dragstart', function (event) {
$('#infovis-canvas').on('dragstart', function(event) {
event.preventDefault()
})
// prevent touch events on the canvas from default behaviour
$('#infovis-canvas').bind('touchstart', function (event) {
$('#infovis-canvas').bind('touchstart', function(event) {
event.preventDefault()
self.mGraph.events.touched = true
})
// prevent touch events on the canvas from default behaviour
$('#infovis-canvas').bind('touchmove', function (event) {
$('#infovis-canvas').bind('touchmove', function(event) {
// JIT.touchPanZoomHandler(event)
})
// prevent touch events on the canvas from default behaviour
$('#infovis-canvas').bind('touchend touchcancel', function (event) {
lastDist = 0
$('#infovis-canvas').bind('touchend touchcancel', function(event) {
if (!self.mGraph.events.touchMoved && !Visualize.touchDragNode) TopicCard.hideCurrentCard()
self.mGraph.events.touched = self.mGraph.events.touchMoved = false
Visualize.touchDragNode = false
})
},
computePositions: function () {
var self = Visualize,
mapping
computePositions: function() {
const self = Visualize
if (self.type == 'RGraph') {
var i, l, startPos, endPos, topic, synapse
if (self.type === 'RGraph') {
let i
let l
self.mGraph.graph.eachNode(function (n) {
topic = DataModel.Topics.get(n.id)
self.mGraph.graph.eachNode(function(n) {
const topic = DataModel.Topics.get(n.id)
topic.set({ node: n }, { silent: true })
topic.updateNode()
n.eachAdjacency(function (edge) {
n.eachAdjacency(function(edge) {
if (!edge.getData('init')) {
edge.setData('init', true)
l = edge.getData('synapseIDs').length
for (i = 0; i < l; i++) {
synapse = DataModel.Synapses.get(edge.getData('synapseIDs')[i])
const synapse = DataModel.Synapses.get(edge.getData('synapseIDs')[i])
synapse.set({ edge: edge }, { silent: true })
synapse.updateEdge()
}
@ -75,34 +74,32 @@ const Visualize = {
pos.setc(-200, -200)
})
self.mGraph.compute('end')
} else if (self.type == 'ForceDirected') {
var i, l, startPos, endPos, topic, synapse
self.mGraph.graph.eachNode(function (n) {
topic = DataModel.Topics.get(n.id)
} else if (self.type === 'ForceDirected') {
self.mGraph.graph.eachNode(function(n) {
const topic = DataModel.Topics.get(n.id)
topic.set({ node: n }, { silent: true })
topic.updateNode()
mapping = topic.getMapping()
const mapping = topic.getMapping()
n.eachAdjacency(function (edge) {
n.eachAdjacency(function(edge) {
if (!edge.getData('init')) {
edge.setData('init', true)
l = edge.getData('synapseIDs').length
for (i = 0; i < l; i++) {
synapse = DataModel.Synapses.get(edge.getData('synapseIDs')[i])
const l = edge.getData('synapseIDs').length
for (let i = 0; i < l; i++) {
const synapse = DataModel.Synapses.get(edge.getData('synapseIDs')[i])
synapse.set({ edge: edge }, { silent: true })
synapse.updateEdge()
}
}
})
startPos = new $jit.Complex(0, 0)
endPos = new $jit.Complex(mapping.get('xloc'), mapping.get('yloc'))
const startPos = new $jit.Complex(0, 0)
const endPos = new $jit.Complex(mapping.get('xloc'), mapping.get('yloc'))
n.setPos(startPos, 'start')
n.setPos(endPos, 'end')
})
} else if (self.type == 'ForceDirected3D') {
} else if (self.type === 'ForceDirected3D') {
self.mGraph.compute()
}
},
@ -110,14 +107,14 @@ const Visualize = {
* render does the heavy lifting of creating the engine that renders the graph with the properties we desire
*
*/
render: function () {
var self = Visualize, RGraphSettings, FDSettings
render: function() {
const self = Visualize
if (self.type == 'RGraph') {
if (self.type === 'RGraph') {
// clear the previous canvas from #infovis
$('#infovis').empty()
RGraphSettings = $.extend(true, {}, JIT.ForceDirected.graphSettings)
const RGraphSettings = $.extend(true, {}, JIT.ForceDirected.graphSettings)
$jit.RGraph.Plot.NodeTypes.implement(JIT.ForceDirected.nodeSettings)
$jit.RGraph.Plot.EdgeTypes.implement(JIT.ForceDirected.edgeSettings)
@ -128,11 +125,11 @@ const Visualize = {
RGraphSettings.levelDistance = JIT.RGraph.levelDistance
self.mGraph = new $jit.RGraph(RGraphSettings)
} else if (self.type == 'ForceDirected') {
} else if (self.type === 'ForceDirected') {
// clear the previous canvas from #infovis
$('#infovis').empty()
FDSettings = $.extend(true, {}, JIT.ForceDirected.graphSettings)
const FDSettings = $.extend(true, {}, JIT.ForceDirected.graphSettings)
$jit.ForceDirected.Plot.NodeTypes.implement(JIT.ForceDirected.nodeSettings)
$jit.ForceDirected.Plot.EdgeTypes.implement(JIT.ForceDirected.edgeSettings)
@ -141,10 +138,10 @@ const Visualize = {
FDSettings.height = $('body').height()
self.mGraph = new $jit.ForceDirected(FDSettings)
} else if (self.type == 'ForceDirected3D' && !self.mGraph) {
} else if (self.type === 'ForceDirected3D' && !self.mGraph) {
// clear the previous canvas from #infovis
$('#infovis').empty()
// init ForceDirected3D
self.mGraph = new $jit.ForceDirected3D(JIT.ForceDirected3D.graphSettings)
self.cameraPosition = self.mGraph.canvas.canvases[0].camera.position
@ -152,17 +149,16 @@ const Visualize = {
self.mGraph.graph.empty()
}
if (self.type === 'ForceDirected' && Active.Mapper) $.post('/maps/' + Active.Map.id + '/events/user_presence')
if (self.type == 'ForceDirected' && Active.Mapper) $.post('/maps/' + Active.Map.id + '/events/user_presence')
function runAnimation () {
function runAnimation() {
Loading.hide()
// load JSON data, if it's not empty
if (!self.loadLater) {
// load JSON data.
var rootIndex = 0
if (Active.Topic) {
var node = _.find(JIT.vizData, function (node) {
var node = _.find(JIT.vizData, function(node) {
return node.id === Active.Topic.id
})
rootIndex = _.indexOf(JIT.vizData, node)
@ -171,11 +167,11 @@ const Visualize = {
// compute positions and plot.
self.computePositions()
self.mGraph.busy = true
if (self.type == 'RGraph') {
if (self.type === 'RGraph') {
self.mGraph.fx.animate(JIT.RGraph.animate)
} else if (self.type == 'ForceDirected') {
} else if (self.type === 'ForceDirected') {
self.mGraph.animate(JIT.ForceDirected.animateSavedLayout)
} else if (self.type == 'ForceDirected3D') {
} else if (self.type === 'ForceDirected3D') {
self.mGraph.animate(JIT.ForceDirected.animateFDLayout)
}
}
@ -183,35 +179,37 @@ const Visualize = {
// hold until all the needed metacode images are loaded
// hold for a maximum of 80 passes, or 4 seconds of waiting time
var tries = 0
function hold () {
var unique = _.uniq(DataModel.Topics.models, function (metacode) { return metacode.get('metacode_id'); }),
requiredMetacodes = _.map(unique, function (metacode) { return metacode.get('metacode_id'); }),
loadedCount = 0
function hold() {
const unique = _.uniq(DataModel.Topics.models, function(metacode) { return metacode.get('metacode_id') })
const requiredMetacodes = _.map(unique, function(metacode) { return metacode.get('metacode_id') })
let loadedCount = 0
_.each(requiredMetacodes, function (metacode_id) {
var metacode = DataModel.Metacodes.get(metacode_id),
img = metacode ? metacode.get('image') : false
_.each(requiredMetacodes, function(metacodeId) {
const metacode = DataModel.Metacodes.get(metacodeId)
const img = metacode ? metacode.get('image') : false
if (img && (img.complete || (typeof img.naturalWidth !== 'undefined' && img.naturalWidth !== 0))) {
loadedCount += 1
}
})
if (loadedCount === requiredMetacodes.length || tries > 80) runAnimation()
else setTimeout(function () { tries++; hold() }, 50)
if (loadedCount === requiredMetacodes.length || tries > 80) {
runAnimation()
} else {
setTimeout(function() { tries++; hold() }, 50)
}
}
hold()
// update the url now that the map is ready
clearTimeout(Router.timeoutId)
Router.timeoutId = setTimeout(function () {
Router.timeoutId = setTimeout(function() {
var m = Active.Map
var t = Active.Topic
if (m && window.location.pathname !== '/maps/' + m.id) {
Router.navigate('/maps/' + m.id)
}
else if (t && window.location.pathname !== '/topics/' + t.id) {
} else if (t && window.location.pathname !== '/topics/' + t.id) {
Router.navigate('/topics/' + t.id)
}
}, 800)
@ -221,7 +219,7 @@ const Visualize = {
Visualize.mGraph.plot()
JIT.centerMap(Visualize.mGraph.canvas)
$('#infovis').empty()
},
}
}
export default Visualize

View file

@ -70,13 +70,9 @@ Metamaps.Topic = Topic
Metamaps.TopicCard = TopicCard
Metamaps.Util = Util
Metamaps.Views = Views
Metamaps.Views.ExploreMaps = ExploreMaps
Metamaps.Views.ChatView = ChatView
Metamaps.Views.VideoView = VideoView
Metamaps.Views.Room = Room
Metamaps.Visualize = Visualize
document.addEventListener('DOMContentLoaded', function () {
document.addEventListener('DOMContentLoaded', function() {
// initialize all the modules
for (const prop in Metamaps) {
// this runs the init function within each sub-object on the Metamaps one
@ -94,14 +90,14 @@ document.addEventListener('DOMContentLoaded', function () {
Views.ExploreMaps.setCollection(DataModel.Maps[capitalize])
if (Metamaps.currentPage === 'mapper') {
ExploreMaps.fetchUserThenRender()
Views.ExploreMaps.fetchUserThenRender()
} else {
ExploreMaps.render()
Views.ExploreMaps.render()
}
GlobalUI.showDiv('#explore')
} else if (Metamaps.currentSection === '' && Active.Mapper) {
ExploreMaps.setCollection(DataModel.Maps.Active)
ExploreMaps.render()
Views.ExploreMaps.setCollection(DataModel.Maps.Active)
Views.ExploreMaps.render()
GlobalUI.showDiv('#explore')
} else if (Active.Map || Active.Topic) {
Loading.show()

View file

@ -2,7 +2,7 @@ import React, { PropTypes, Component } from 'react'
import Dropzone from 'react-dropzone'
class ImportDialogBox extends Component {
constructor (props) {
constructor(props) {
super(props)
this.state = {

View file

@ -87,10 +87,6 @@ class MapCard extends Component {
const hasMapper = hasMap && !hasConversation
const mapperList = hasMap && Object.keys(hasMap).map(id => juntoState.connectedPeople[id])
function capitalize (string) {
return string.charAt(0).toUpperCase() + string.slice(1)
}
const n = map.get('name')
const d = map.get('desc')

View file

@ -31,22 +31,22 @@ class Maps extends Component {
const { maps, user, currentUser } = this.props
const numCards = maps.length + (user || currentUser ? 1 : 0)
const mapSpaces = Math.floor(document.body.clientWidth / MAP_WIDTH)
const mapsWidth = document.body.clientWidth <= MOBILE_VIEW_BREAKPOINT ?
document.body.clientWidth - MOBILE_VIEW_PADDING :
Math.min(MAX_COLUMNS, Math.min(numCards, mapSpaces)) * MAP_WIDTH
const mapsWidth = document.body.clientWidth <= MOBILE_VIEW_BREAKPOINT
? document.body.clientWidth - MOBILE_VIEW_PADDING
: Math.min(MAX_COLUMNS, Math.min(numCards, mapSpaces)) * MAP_WIDTH
this.setState({ mapsWidth })
}
scroll = () => {
const { loadMore, moreToLoad, pending } = this.props
const { maps } = this.refs
if (moreToLoad && !pending && maps.scrollTop + maps.offsetHeight > maps.scrollHeight - 300 ) {
if (moreToLoad && !pending && maps.scrollTop + maps.offsetHeight > maps.scrollHeight - 300) {
loadMore()
}
}
render = () => {
const { maps, currentUser, juntoState, pending, section, user, moreToLoad, loadMore, onStar, onRequest } = this.props
const { maps, currentUser, juntoState, pending, section, user, onStar, onRequest } = this.props
const style = { width: this.state.mapsWidth + 'px' }
const mobile = document && document.body.clientWidth <= MOBILE_VIEW_BREAKPOINT

View file

@ -6,8 +6,8 @@ import Import from '../src/Metamaps/Import'
const { expect } = chai
describe('Metamaps.Import.js', function () {
it('has a topic whitelist', function () {
describe('Metamaps.Import.js', function() {
it('has a topic whitelist', function() {
expect(Import.topicWhitelist).to.deep.equal(
['id', 'name', 'metacode', 'x', 'y', 'description', 'link', 'permission']
)

View file

@ -6,123 +6,123 @@ import Util from '../src/Metamaps/Util'
const { expect } = chai
describe('Metamaps.Util.js', function () {
describe('splitLine', function () {
it('splits on words', function () {
describe('Metamaps.Util.js', function() {
describe('splitLine', function() {
it('splits on words', function() {
expect(Util.splitLine('test test test', 10))
.to.equal('test test\ntest')
})
// TODO this test seems like it's incorrect behaviour
it('splits mid-word if need be', function () {
it('splits mid-word if need be', function() {
expect(Util.splitLine('test test', 2))
.to.equal('te\nt\nte\nt')
})
it('splits words over 30 chars', function () {
it('splits words over 30 chars', function() {
expect(Util.splitLine('suprainterpostantidisestablishmentarianism', 30))
.to.equal('suprainterpostantidisestablish\nentarianism')
})
})
describe('nowDateFormatted', function () {
describe('nowDateFormatted', function() {
it.skip('TODO need `Date`')
})
describe('decodeEntities', function () {
describe('decodeEntities', function() {
it.skip('TODO need `document`')
})
describe('getDistance', function () {
it('(0,0) -> (0,0) = 0', function () {
describe('getDistance', function() {
it('(0,0) -> (0,0) = 0', function() {
expect(Util.getDistance({ x: 0, y: 0 }, { x: 0, y: 0 }))
.to.equal(0)
})
it('(-5,0) -> (5,0) = 10', function () {
it('(-5,0) -> (5,0) = 10', function() {
expect(Util.getDistance({ x: -5, y: 0 }, { x: 5, y: 0 }))
.to.equal(10)
})
it('(0,0) -> (5,7) = 8.6023', function () {
it('(0,0) -> (5,7) = 8.6023', function() {
expect(Util.getDistance({ x: 0, y: 0 }, { x: 5, y: 7 }).toFixed(4))
.to.equal('8.6023')
})
})
describe('coordsToPixels', function () {
it('returns 0,0 for null canvas', function () {
describe('coordsToPixels', function() {
it('returns 0,0 for null canvas', function() {
expect(Util.coordsToPixels(null, {}).x).to.equal(0)
expect(Util.coordsToPixels(null, {}).y).to.equal(0)
})
it.skip('TODO need initialized mGraph to test further')
})
describe('pixelsToCoords', function () {
it('returns 0,0 for null canvas', function () {
describe('pixelsToCoords', function() {
it('returns 0,0 for null canvas', function() {
expect(Util.pixelsToCoords(null, {}).x).to.equal(0)
expect(Util.pixelsToCoords(null, {}).y).to.equal(0)
})
it.skip('TODO need initialized mGraph to test further')
})
describe('getPastelColor', function () {
it('1 => fefefe', function () {
describe('getPastelColor', function() {
it('1 => fefefe', function() {
expect(Util.getPastelColor({ rseed: 1, gseed: 1, bseed: 1 }))
.to.equal(Util.colorLuminance('#fefefe', -0.4))
})
it('0 => 7f7f7f', function () {
it('0 => 7f7f7f', function() {
expect(Util.getPastelColor({ rseed: 0, gseed: 0, bseed: 0 }))
.to.equal(Util.colorLuminance('#7f7f7f', -0.4))
})
})
describe('colorLuminance', function () {
describe('-0.4 lum', function () {
it('white => ?', function () {
describe('colorLuminance', function() {
describe('-0.4 lum', function() {
it('white => ?', function() {
expect(Util.colorLuminance('#ffffff', -0.4)).to.equal('#999999')
})
it('black => ?', function () {
it('black => ?', function() {
expect(Util.colorLuminance('#000000', -0.4)).to.equal('#000000')
})
it('7f7f7f => ?', function () {
it('7f7f7f => ?', function() {
expect(Util.colorLuminance('#7f7f7f', -0.4)).to.equal('#4c4c4c')
})
})
describe('other lum values', function () {
it('-1', function () {
describe('other lum values', function() {
it('-1', function() {
expect(Util.colorLuminance('#7f7f7f', -1)).to.equal('#000000')
})
it('-0.5', function () {
it('-0.5', function() {
expect(Util.colorLuminance('#7f7f7f', -0.5)).to.equal('#404040')
})
it('0', function () {
it('0', function() {
expect(Util.colorLuminance('#7f7f7f', 0)).to.equal('#7f7f7f')
})
it('0.5', function () {
it('0.5', function() {
expect(Util.colorLuminance('#7f7f7f', 0.5)).to.equal('#bfbfbf')
})
it('1', function () {
it('1', function() {
expect(Util.colorLuminance('#7f7f7f', 1)).to.equal('#fefefe')
})
})
})
describe('openLink', function () {
describe('openLink', function() {
it.skip('TODO need `window`')
})
describe('mdToHTML', function () {
it('filters xss', function () {
describe('mdToHTML', function() {
it('filters xss', function() {
const md = '<script>alert("xss");</script>'
const html = '<!-- raw HTML omitted -->'
expect(Util.mdToHTML(md).trim()).to.equal(html)
})
it('bold and italics', function () {
it('bold and italics', function() {
const md = '**Bold** *Italics*'
const html = '<p><strong>Bold</strong> <em>Italics</em></p>'
expect(Util.mdToHTML(md).trim()).to.equal(html)
})
it('links and images', function () {
it('links and images', function() {
const md = '[Link](https://metamaps.cc) ![Image](https://example.org/image.png)'
const html = '<p><a href="https://metamaps.cc">Link</a> <img src="https://example.org/image.png" alt="Image" /></p>'
expect(Util.mdToHTML(md).trim()).to.equal(html)
})
})
describe('logCanvasAttributes', function () {
describe('logCanvasAttributes', function() {
it.skip('TODO need a canvas')
})
describe('resizeCanvas', function () {
describe('resizeCanvas', function() {
it.skip('TODO need a canvas')
})
})

View file

@ -19,14 +19,13 @@ const {
UPDATE_MAP
} = require('../frontend/src/Metamaps/Realtime/events')
module.exports = function (io, store) {
module.exports = function(io, store) {
store.subscribe(() => {
console.log(store.getState())
io.sockets.emit(JUNTO_UPDATED, store.getState())
})
io.on('connection', function (socket) {
io.on('connection', function(socket) {
io.sockets.emit(JUNTO_UPDATED, store.getState())
socket.on(JOIN_MAP, data => store.dispatch({ type: JOIN_MAP, payload: data }))
@ -35,23 +34,23 @@ module.exports = function (io, store) {
socket.on(LEAVE_CALL, () => store.dispatch({ type: LEAVE_CALL, payload: socket }))
socket.on('disconnect', () => store.dispatch({ type: 'DISCONNECT', payload: socket }))
socket.on(UPDATE_TOPIC, function (data) {
socket.on(UPDATE_TOPIC, function(data) {
socket.broadcast.emit(TOPIC_UPDATED, data)
})
socket.on(DELETE_TOPIC, function (data) {
socket.on(DELETE_TOPIC, function(data) {
socket.broadcast.emit(TOPIC_DELETED, data)
})
socket.on(UPDATE_SYNAPSE, function (data) {
socket.on(UPDATE_SYNAPSE, function(data) {
socket.broadcast.emit(SYNAPSE_UPDATED, data)
})
socket.on(DELETE_SYNAPSE, function (data) {
socket.on(DELETE_SYNAPSE, function(data) {
socket.broadcast.emit(SYNAPSE_DELETED, data)
})
socket.on(UPDATE_MAP, function (data) {
socket.on(UPDATE_MAP, function(data) {
socket.broadcast.emit(MAP_UPDATED, data)
})
})

View file

@ -21,41 +21,40 @@ const {
const { mapRoom, userMapRoom } = require('./rooms')
module.exports = function (io, store) {
io.on('connection', function (socket) {
socket.on(CHECK_FOR_CALL, function (data) {
module.exports = function(io, store) {
io.on('connection', function(socket) {
socket.on(CHECK_FOR_CALL, function(data) {
var callInProgress = Object.keys(io.nsps['/'].adapter.rooms[data.room] || {}).length
if (callInProgress) socket.emit(CALL_IN_PROGRESS)
})
socket.on(INVITE_A_CALL, function (data) {
socket.on(INVITE_A_CALL, function(data) {
socket.broadcast.in(userMapRoom(data.invited, data.mapid)).emit(INVITED_TO_CALL, data.inviter)
})
socket.on(INVITE_TO_JOIN, function (data) {
socket.on(INVITE_TO_JOIN, function(data) {
socket.broadcast.in(userMapRoom(data.invited, data.mapid)).emit(INVITED_TO_JOIN, data.inviter)
})
socket.on(ACCEPT_CALL, function (data) {
socket.on(ACCEPT_CALL, function(data) {
socket.broadcast.in(userMapRoom(data.inviter, data.mapid)).emit(CALL_ACCEPTED, data.invited)
socket.broadcast.in(mapRoom(data.mapid)).emit(CALL_STARTED)
})
socket.on(DENY_CALL, function (data) {
socket.on(DENY_CALL, function(data) {
socket.broadcast.in(userMapRoom(data.inviter, data.mapid)).emit(CALL_DENIED, data.invited)
})
socket.on(DENY_INVITE, function (data) {
socket.on(DENY_INVITE, function(data) {
socket.broadcast.in(userMapRoom(data.inviter, data.mapid)).emit(INVITE_DENIED, data.invited)
})
socket.on(JOIN_CALL, function (data) {
socket.on(JOIN_CALL, function(data) {
socket.broadcast.in(mapRoom(data.mapid)).emit(MAPPER_JOINED_CALL, data.id)
})
socket.on(LEAVE_CALL, function (data) {
socket.on(LEAVE_CALL, function(data) {
socket.broadcast.in(mapRoom(data.mapid)).emit(MAPPER_LEFT_CALL, data.id)
})
})
}
}

View file

@ -24,11 +24,10 @@ const {
const { mapRoom, userMapRoom } = require('./rooms')
module.exports = function (io, store) {
io.on('connection', function (socket) {
module.exports = function(io, store) {
io.on('connection', function(socket) {
// this will ping everyone on a map that there's a person just joined the map
socket.on(JOIN_MAP, function (data) {
socket.on(JOIN_MAP, function(data) {
socket.mapid = data.mapid
socket.userid = data.userid
socket.username = data.username
@ -52,12 +51,12 @@ module.exports = function (io, store) {
socket.leave(userMapRoom(socket.userid, socket.mapid))
socket.broadcast.in(mapRoom(socket.mapid)).emit(LOST_MAPPER, data)
socket.mapid = null
}
}
socket.on(LEAVE_MAP, leaveMap)
socket.on('disconnect', leaveMap)
// this will ping a new person with awareness of who's already on the map
socket.on(SEND_MAPPER_INFO, function (data) {
socket.on(SEND_MAPPER_INFO, function(data) {
var existingUser = {
userid: data.userid,
username: data.username,
@ -67,7 +66,7 @@ module.exports = function (io, store) {
socket.broadcast.in(userMapRoom(data.userToNotify, data.mapid)).emit(MAPPER_LIST_UPDATED, existingUser)
})
socket.on(SEND_COORDS, function (data) {
socket.on(SEND_COORDS, function(data) {
var peer = {
userid: data.userid,
usercoords: data.usercoords
@ -75,37 +74,37 @@ module.exports = function (io, store) {
socket.broadcast.in(mapRoom(data.mapid)).emit(PEER_COORDS_UPDATED, peer)
})
socket.on(CREATE_MESSAGE, function (data) {
socket.on(CREATE_MESSAGE, function(data) {
var mapId = data.mapid
delete data.mapid
socket.broadcast.in(mapRoom(mapId)).emit(MESSAGE_CREATED, data)
})
socket.on(DRAG_TOPIC, function (data) {
socket.on(DRAG_TOPIC, function(data) {
var mapId = data.mapid
delete data.mapid
socket.broadcast.in(mapRoom(mapId)).emit(TOPIC_DRAGGED, data)
})
socket.on(CREATE_TOPIC, function (data) {
socket.on(CREATE_TOPIC, function(data) {
var mapId = data.mapid
delete data.mapid
socket.broadcast.in(mapRoom(mapId)).emit(TOPIC_CREATED, data)
})
socket.on(REMOVE_TOPIC, function (data) {
socket.on(REMOVE_TOPIC, function(data) {
var mapId = data.mapid
delete data.mapid
socket.broadcast.in(mapRoom(mapId)).emit(TOPIC_REMOVED, data)
})
socket.on(CREATE_SYNAPSE, function (data) {
socket.on(CREATE_SYNAPSE, function(data) {
var mapId = data.mapid
delete data.mapid
socket.broadcast.in(mapRoom(mapId)).emit(SYNAPSE_CREATED, data)
})
socket.on(REMOVE_SYNAPSE, function (data) {
socket.on(REMOVE_SYNAPSE, function(data) {
var mapId = data.mapid
delete data.mapid
socket.broadcast.in(mapRoom(mapId)).emit(SYNAPSE_REMOVED, data)

View file

@ -1,10 +1,9 @@
var
io = require('socket.io')(),
signalling = require('./signal'),
junto = require('./junto'),
map = require('./map'),
global = require('./global'),
stunservers = [{"url": "stun:stun.l.google.com:19302"}]
const io = require('socket.io')()
const signalling = require('./signal')
const junto = require('./junto')
const map = require('./map')
const global = require('./global')
const stunservers = [{'url': 'stun:stun.l.google.com:19302'}]
const { createStore } = require('redux')
const reducer = require('./reducer')

View file

@ -9,7 +9,7 @@ const {
const NOT_IN_CONVERSATION = 0
const IN_CONVERSATION = 1
const addMapperToMap = (map, userId) => { return Object.assign({}, map, { [userId]: NOT_IN_CONVERSATION })}
const addMapperToMap = (map, userId) => { return Object.assign({}, map, { [userId]: NOT_IN_CONVERSATION }) }
const reducer = (state = { connectedPeople: {}, liveMaps: {} }, action) => {
const { type, payload } = action
@ -19,56 +19,56 @@ const reducer = (state = { connectedPeople: {}, liveMaps: {} }, action) => {
const callWillFinish = map && (type === LEAVE_CALL || type === 'DISCONNECT') && Object.keys(map).length === 2
switch (type) {
case JOIN_MAP:
return Object.assign({}, state, {
connectedPeople: Object.assign({}, connectedPeople, {
[payload.userid]: {
id: payload.userid,
username: payload.username,
avatar: payload.avatar
}
}),
liveMaps: Object.assign({}, liveMaps, {
[payload.mapid]: addMapperToMap(map || {}, payload.userid)
case JOIN_MAP:
return Object.assign({}, state, {
connectedPeople: Object.assign({}, connectedPeople, {
[payload.userid]: {
id: payload.userid,
username: payload.username,
avatar: payload.avatar
}
}),
liveMaps: Object.assign({}, liveMaps, {
[payload.mapid]: addMapperToMap(map || {}, payload.userid)
})
})
})
case LEAVE_MAP:
case LEAVE_MAP:
// if the map will empty, remove it from liveMaps, if the map will not empty, just remove the mapper
const newLiveMaps = mapWillEmpty
const newLiveMaps = mapWillEmpty
? omit(liveMaps, payload.mapid)
: Object.assign({}, liveMaps, { [payload.mapid]: omit(map, payload.userid) })
return {
connectedPeople: omit(connectedPeople, payload.userid),
liveMaps: omitBy(newLiveMaps, isNil)
}
case JOIN_CALL:
return {
connectedPeople: omit(connectedPeople, payload.userid),
liveMaps: omitBy(newLiveMaps, isNil)
}
case JOIN_CALL:
// update the user (payload.id is user id) in the given map to be marked in the conversation
return Object.assign({}, state, {
liveMaps: Object.assign({}, liveMaps, {
[payload.mapid]: Object.assign({}, map, {
[payload.id]: IN_CONVERSATION
return Object.assign({}, state, {
liveMaps: Object.assign({}, liveMaps, {
[payload.mapid]: Object.assign({}, map, {
[payload.id]: IN_CONVERSATION
})
})
})
})
case LEAVE_CALL:
const newMap = callWillFinish
case LEAVE_CALL:
const newMap = callWillFinish
? mapValues(map, () => NOT_IN_CONVERSATION)
: Object.assign({}, map, { [payload.userid]: NOT_IN_CONVERSATION })
return Object.assign({}, state, {
liveMaps: Object.assign({}, liveMaps, { map: newMap })
})
case 'DISCONNECT':
const mapWithoutUser = omit(map, payload.userid)
const newMapWithoutUser = callWillFinish ? mapValues(mapWithoutUser, () => NOT_IN_CONVERSATION) : mapWithoutUser
const newLiveMapsWithoutUser = mapWillEmpty ? omit(liveMaps, payload.mapid) : Object.assign({}, liveMaps, { [payload.mapid]: newMapWithoutUser })
return {
connectedPeople: omit(connectedPeople, payload.userid),
liveMaps: omitBy(newLiveMapsWithoutUser, isNil)
}
default:
return state
return Object.assign({}, state, {
liveMaps: Object.assign({}, liveMaps, { map: newMap })
})
case 'DISCONNECT':
const mapWithoutUser = omit(map, payload.userid)
const newMapWithoutUser = callWillFinish ? mapValues(mapWithoutUser, () => NOT_IN_CONVERSATION) : mapWithoutUser
const newLiveMapsWithoutUser = mapWillEmpty ? omit(liveMaps, payload.mapid) : Object.assign({}, liveMaps, { [payload.mapid]: newMapWithoutUser })
return {
connectedPeople: omit(connectedPeople, payload.userid),
liveMaps: omitBy(newLiveMapsWithoutUser, isNil)
}
default:
return state
}
}

View file

@ -5,14 +5,14 @@ const uuid = require('node-uuid')
function safeCb(cb) {
if (typeof cb === 'function') {
return cb;
return cb
} else {
return function () {};
return function() {}
}
}
module.exports = function(io, stunservers, state) {
io.on('connection', function (socket) {
io.on('connection', function(socket) {
socket.resources = {
screen: false,
video: true,
@ -20,7 +20,7 @@ module.exports = function(io, stunservers, state) {
}
// pass a message to another id
socket.on('message', function (details) {
socket.on('message', function(details) {
if (!details) return
var otherClient = io.to(details.to)
@ -30,11 +30,11 @@ module.exports = function(io, stunservers, state) {
otherClient.emit('message', details)
})
socket.on('shareScreen', function () {
socket.on('shareScreen', function() {
socket.resources.screen = true
})
socket.on('unshareScreen', function (type) {
socket.on('unshareScreen', function(type) {
socket.resources.screen = false
removeFeed('screen')
})
@ -66,16 +66,16 @@ module.exports = function(io, stunservers, state) {
// we don't want to pass "leave" directly because the
// event type string of "socket end" gets passed too.
socket.on('disconnect', function () {
socket.on('disconnect', function() {
removeFeed()
})
socket.on('leave', function () {
socket.on('leave', function() {
removeFeed()
})
socket.on('create', function (name, cb) {
if (arguments.length == 2) {
cb = (typeof cb == 'function') ? cb : function () {}
socket.on('create', function(name, cb) {
if (arguments.length === 2) {
cb = (typeof cb === 'function') ? cb : function() {}
name = name || uuid()
} else {
cb = name
@ -93,7 +93,7 @@ module.exports = function(io, stunservers, state) {
// support for logging full webrtc traces to stdout
// useful for large-scale error monitoring
socket.on('trace', function (data) {
socket.on('trace', function(data) {
console.log('trace', JSON.stringify(
[data.type, data.session, data.prefix, data.peer, data.time, data.value]
))
@ -106,13 +106,9 @@ module.exports = function(io, stunservers, state) {
var result = {
clients: {}
}
Object.keys(sockets).forEach(function (id) {
Object.keys(sockets).forEach(function(id) {
result.clients[id] = adapter.nsp.connected[id].resources
})
return result
}
function socketsInRoom(name) {
return io.sockets.sockets(name).length
}
}