diff --git a/MacInstallation.md b/MacInstallation.md
index c2b9d80d..2d36494e 100644
--- a/MacInstallation.md
+++ b/MacInstallation.md
@@ -4,9 +4,9 @@ install homebrew
\curl -sSL https://get.rvm.io | bash -s stable --rails
- rvm install 1.9.3 --with-gcc=clang
+ rvm install 2.1.3 --with-gcc=clang
- rvm use 1.9.3
+ rvm use 2.1.3
gem install lunchy
diff --git a/app/assets/images/linkedmedia.png b/app/assets/images/linkedmedia.png
deleted file mode 100755
index 2009b7a3..00000000
Binary files a/app/assets/images/linkedmedia.png and /dev/null differ
diff --git a/app/assets/images/screenshot_sprite.png b/app/assets/images/screenshot_sprite.png
new file mode 100644
index 00000000..d3c87c5a
Binary files /dev/null and b/app/assets/images/screenshot_sprite.png differ
diff --git a/app/assets/images/synapse32padded.png b/app/assets/images/synapse32padded.png
new file mode 100644
index 00000000..09e52fc0
Binary files /dev/null and b/app/assets/images/synapse32padded.png differ
diff --git a/app/assets/images/synapsestar.png b/app/assets/images/synapsestar.png
deleted file mode 100755
index ba9a7dd3..00000000
Binary files a/app/assets/images/synapsestar.png and /dev/null differ
diff --git a/app/assets/images/topic_description_signifier.png b/app/assets/images/topic_description_signifier.png
new file mode 100644
index 00000000..956db0a3
Binary files /dev/null and b/app/assets/images/topic_description_signifier.png differ
diff --git a/app/assets/images/topic_link_signifier.png b/app/assets/images/topic_link_signifier.png
new file mode 100644
index 00000000..a8b8b8e5
Binary files /dev/null and b/app/assets/images/topic_link_signifier.png differ
diff --git a/app/assets/javascripts/src/JIT.js b/app/assets/javascripts/src/JIT.js
index 7483a544..498183ef 100644
--- a/app/assets/javascripts/src/JIT.js
+++ b/app/assets/javascripts/src/JIT.js
@@ -2477,7 +2477,6 @@ Extras.Classes.Navigation = new Class({
// START METAMAPS CODE
jQuery(document).trigger(Metamaps.JIT.events.zoom, [e]);
// END METAMAPS CODE
-
},
onMouseDown: function(e, win, eventInfo) {
@@ -7097,7 +7096,7 @@ Graph.Plot = {
ctx.restore();
}
//END METAMAPS CODE
-
+
aGraph.eachNode(function(node) {
var nodeAlpha = node.getData('alpha');
node.eachAdjacency(function(adj) {
@@ -7427,6 +7426,7 @@ Graph.Label.Native = new Class({
(end code)
*/
plotLabel: function(canvas, node, controller) {
+
var ctx = canvas.getCtx();
var pos = node.pos.getc(true);
@@ -7493,7 +7493,7 @@ Graph.Label.Native = new Class({
// START METAMAPS CODE
var index;
for (index = 0; index < customLabel.length; ++index) {
- ctx.fillText(customLabel[index], pos.x, pos.y + node.getData("height") + 8 + (25*index));
+ ctx.fillText(customLabel[index], pos.x, pos.y + node.getData("height") + 9 + (25*index));
}
// END METAMAPS CODE
},
diff --git a/app/assets/javascripts/src/Metamaps.Backbone.js b/app/assets/javascripts/src/Metamaps.Backbone.js
index f8c89493..7ed0adfe 100644
--- a/app/assets/javascripts/src/Metamaps.Backbone.js
+++ b/app/assets/javascripts/src/Metamaps.Backbone.js
@@ -5,6 +5,34 @@ Metamaps.Backbone.Map = Backbone.Model.extend({
toJSON: function (options) {
return _.omit(this.attributes, this.blacklist);
},
+ save: function (key, val, options) {
+
+ var attrs;
+
+ // Handle both `"key", value` and `{key: value}` -style arguments.
+ if (key == null || typeof key === 'object') {
+ attrs = key;
+ options = val;
+ } else {
+ (attrs = {})[key] = val;
+ }
+
+ var newOptions = options || {};
+ var s = newOptions.success;
+
+ 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 () {
+ this.on('changeByOther', this.updateView);
+ this.on('saved', this.savedEvent);
+ },
+ savedEvent: function() {
+ Metamaps.Realtime.sendMapChange(this);
+ },
authorizeToEdit: function (mapper) {
if (mapper && (this.get('permission') === "commons" || this.get('user_id') === mapper.get('id'))) return true;
else return false;
@@ -24,11 +52,12 @@ Metamaps.Backbone.Map = Backbone.Model.extend({
that.set('topics', new bb.TopicCollection(data.topics));
that.set('synapses', new bb.SynapseCollection(data.synapses));
that.set('mappings', new bb.MappingCollection(data.mappings));
- }
+ };
- $.ajax({
+ var e = $.ajax({
url: "/maps/" + this.id + "/contains.json",
success: start,
+ error: errorFunc,
async: false
});
},
@@ -75,6 +104,25 @@ Metamaps.Backbone.Map = Backbone.Model.extend({
screenshot: '
'
};
return obj;
+ },
+ updateView: function() {
+ var map = Metamaps.Active.Map;
+ var isActiveMap = this.id === map.id;
+ var authorized = map && map.authorizeToEdit(Metamaps.Active.Mapper) ? 'canEditMap' : '';
+ var commonsMap = map && map.get('permission') === 'commons' ? 'commonsMap' : '';
+ if (isActiveMap) {
+ Metamaps.Map.InfoBox.updateNameDescPerm(this.get('name'), this.get('desc'), this.get('permission'));
+ this.updateMapWrapper();
+ }
+ },
+ updateMapWrapper: function() {
+ var map = Metamaps.Active.Map;
+ var isActiveMap = this.id === map.id;
+ var authorized = map && map.authorizeToEdit(Metamaps.Active.Mapper) ? 'canEditMap' : '';
+ var commonsMap = map && map.get('permission') === 'commons' ? 'commonsMap' : '';
+ if (isActiveMap) {
+ $('.wrapper').removeClass('canEditMap commonsMap').addClass(authorized + ' ' + commonsMap);
+ }
}
});
Metamaps.Backbone.MapsCollection = Backbone.Collection.extend({
diff --git a/app/assets/javascripts/src/Metamaps.GlobalUI.js b/app/assets/javascripts/src/Metamaps.GlobalUI.js
index fd393c71..0fcc6971 100644
--- a/app/assets/javascripts/src/Metamaps.GlobalUI.js
+++ b/app/assets/javascripts/src/Metamaps.GlobalUI.js
@@ -223,7 +223,7 @@ Metamaps.GlobalUI.CreateMap = {
$(this).parents('.new_map').find('.permText').html(permText);
},
submit: function (event) {
- event.preventDefault();
+ if (event) event.preventDefault();
var self = Metamaps.GlobalUI.CreateMap;
@@ -233,23 +233,15 @@ Metamaps.GlobalUI.CreateMap = {
}
var formId = Metamaps.GlobalUI.lightbox === 'forkmap' ? '#fork_map' : '#new_map';
- var form = $(formId)
+ var $form = $(formId);
- self.newMap.set('name', form.find('#map_name').val());
- self.newMap.set('desc', form.find('#map_desc').val());
+ self.newMap.set('name', $form.find('#map_name').val());
+ self.newMap.set('desc', $form.find('#map_desc').val());
- // TODO validate map attributes
if (self.newMap.get('name').length===0){
- console.log('Empty map name.');
- Metamaps.GlobalUI.notifyUser('map name is mandatory.');
- return;
-
- } else if (self.newMap.get('name').length>140){
- console.log('map name cannot exceed 140 characteres.');
- Metamaps.GlobalUI.notifyUser('map name cannot exceed 140 characteres.');
+ self.throwMapNameError();
return;
}
- //console.log('self.newMap.get("name").length='+self.newMap.get("name").length.toString());
self.newMap.save(null, {
success: self.success
@@ -259,6 +251,21 @@ Metamaps.GlobalUI.CreateMap = {
Metamaps.GlobalUI.closeLightbox();
Metamaps.GlobalUI.notifyUser('Working...');
},
+ throwMapNameError: function () {
+ var self = Metamaps.GlobalUI.CreateMap;
+
+ var formId = Metamaps.GlobalUI.lightbox === 'forkmap' ? '#fork_map' : '#new_map';
+ var $form = $(formId);
+
+ var message = $("
Please enter a map name...
");
+
+ $form.find('#map_name').after(message);
+ setTimeout(function(){
+ message.fadeOut('fast', function(){
+ message.remove();
+ });
+ }, 5000);
+ },
success: function (model) {
var self = Metamaps.GlobalUI.CreateMap;
diff --git a/app/assets/javascripts/src/Metamaps.JIT.js b/app/assets/javascripts/src/Metamaps.JIT.js
index 4ecda48b..88436a80 100644
--- a/app/assets/javascripts/src/Metamaps.JIT.js
+++ b/app/assets/javascripts/src/Metamaps.JIT.js
@@ -1,6 +1,5 @@
Metamaps.JIT = {
events: {
- mouseMove: 'Metamaps:JIT:events:mouseMove',
topicDrag: 'Metamaps:JIT:events:topicDrag',
newTopic: 'Metamaps:JIT:events:newTopic',
deleteTopic: 'Metamaps:JIT:events:deleteTopic',
@@ -21,13 +20,26 @@ Metamaps.JIT = {
$(".zoomIn").click(self.zoomIn);
$(".zoomOut").click(self.zoomOut);
- $(".zoomExtents").click(self.zoomExtents);
+
+ var zoomExtents = function (event) {
+ self.zoomExtents(event, Metamaps.Visualize.mGraph.canvas);
+ };
+ $(".zoomExtents").click(zoomExtents);
+
+ $(".takeScreenshot").click(Metamaps.Map.exportImage);
+
+ self.topicDescImage = new Image();
+ self.topicDescImage.src = '/assets/topic_description_signifier.png';
+
+ self.topicLinkImage = new Image();
+ self.topicLinkImage.src = '/assets/topic_link_signifier.png';
},
/**
* convert our topic JSON into something JIT can use
*/
- prepareVizData: function () {
- var self = Metamaps.JIT;
+ convertModelsToJIT: function(topics, synapses) {
+ var jitReady = [];
+
var synapsesToRemove = [];
var topic;
var mapping;
@@ -37,18 +49,14 @@ Metamaps.JIT = {
var edge;
var edges = [];
- // reset/empty vizData
- self.vizData = [];
- Metamaps.Visualize.loadLater = false;
-
- Metamaps.Topics.each(function (t) {
+ topics.each(function (t) {
node = t.createNode();
nodes[node.id] = node;
});
- Metamaps.Synapses.each(function (s) {
+ synapses.each(function (s) {
edge = s.createEdge();
- if(Metamaps.Topics.get(s.get('node1_id')) === undefined || Metamaps.Topics.get(s.get('node2_id')) === undefined) {
+ if (topics.get(s.get('node1_id')) === undefined || topics.get(s.get('node2_id')) === undefined) {
// this means it's an invalid synapse
synapsesToRemove.push(s);
}
@@ -78,17 +86,31 @@ Metamaps.JIT = {
}
});
+ _.each(nodes, function (node) {
+ jitReady.push(node);
+ });
+
+ return [jitReady, synapsesToRemove];
+ },
+ prepareVizData: function () {
+ var self = Metamaps.JIT;
+ var mapping;
+
+ // reset/empty vizData
+ self.vizData = [];
+ Metamaps.Visualize.loadLater = false;
+
+ var results = self.convertModelsToJIT(Metamaps.Topics, Metamaps.Synapses);
+
+ self.vizData = results[0];
+
// clean up the synapses array in case of any faulty data
- _.each(synapsesToRemove, function (synapse) {
+ _.each(results[1], function (synapse) {
mapping = synapse.getMapping();
Metamaps.Synapses.remove(synapse);
Metamaps.Mappings.remove(mapping);
});
- _.each(nodes, function (node) {
- self.vizData.push(node);
- });
-
if (self.vizData.length == 0) {
Metamaps.Visualize.loadLater = true;
}
@@ -118,14 +140,45 @@ Metamaps.JIT = {
var directionCat = synapse.get("category");
//label placement on edges
- Metamaps.JIT.renderEdgeArrows($jit.Graph.Plot.edgeHelper, adj, synapse);
+ if (canvas.denySelected) {
+ var color = Metamaps.Settings.colors.synapses.normal;
+ canvas.getCtx().fillStyle = canvas.getCtx().strokeStyle = color;
+ }
+ Metamaps.JIT.renderEdgeArrows($jit.Graph.Plot.edgeHelper, adj, synapse, canvas);
//check for edge label in data
var desc = synapse.get("desc");
var showDesc = adj.getData("showDesc");
- if (desc != "" && showDesc) {
+ var drawSynapseCount = function (context, x, y, count) {
+ /*
+ circle size: 16x16px
+ positioning: overlay and center on top right corner of synapse label - 8px left and 8px down
+ color: #dab539
+ border color: #424242
+ border size: 1.5px
+ font: DIN medium
+ font-size: 14pt
+ font-color: #424242
+ */
+ context.beginPath();
+ context.arc(x, y, 8, 0, 2 * Math.PI, false);
+ context.fillStyle = '#DAB539';
+ context.strokeStyle = '#424242';
+ context.lineWidth = 1.5;
+ context.closePath();
+ context.fill();
+ context.stroke();
+
+ // add the synapse count
+ context.fillStyle = '#424242';
+ context.textAlign = 'center';
+ context.font = '14px din-medium';
+ context.fillText(count, x, y - 6);
+ };
+
+ if (!canvas.denySelected && desc != "" && showDesc) {
// '&' to '&'
desc = Metamaps.Util.decodeEntities(desc);
@@ -140,11 +193,12 @@ Metamaps.JIT = {
for (index = 0; index < arrayOfLabelLines.length; ++index) {
lineWidths.push(ctx.measureText(arrayOfLabelLines[index]).width)
}
- var width = Math.max.apply(null, lineWidths) + 8;
+ var width = Math.max.apply(null, lineWidths) + 16;
var height = (16 * arrayOfLabelLines.length) + 8;
var x = (pos.x + posChild.x - width) / 2;
var y = ((pos.y + posChild.y) / 2) - height / 2;
+
var radius = 5;
//render background
@@ -161,70 +215,33 @@ Metamaps.JIT = {
ctx.closePath();
ctx.fill();
+ // get number of synapses
+ var synapseNum = adj.getData("synapses").length;
+
//render text
- ctx.fillStyle = '#222222';
+ ctx.fillStyle = '#424242';
ctx.textAlign = 'center';
for (index = 0; index < arrayOfLabelLines.length; ++index) {
- ctx.fillText(arrayOfLabelLines[index], x + (width / 2), y + 5 + (16 * index));
+ ctx.fillText(arrayOfLabelLines[index], x + (width / 2), y + 7 + (16 * index));
+ }
+
+ if (synapseNum > 1) {
+ drawSynapseCount(ctx, x + width, y, synapseNum);
}
}
+ else if (!canvas.denySelected && showDesc) {
+ // get number of synapses
+ var synapseNum = adj.getData("synapses").length;
+
+ if (synapseNum > 1) {
+ var ctx = canvas.getCtx();
+ var x = (pos.x + posChild.x) / 2;
+ var y = (pos.y + posChild.y) / 2;
+ drawSynapseCount(ctx, x, y, synapseNum);
+ }
+ }
+
}, // edgeRender
- edgeRenderEmbed: function (adj, canvas) {
- //get nodes cartesian coordinates
- var pos = adj.nodeFrom.pos.getc(true);
- var posChild = adj.nodeTo.pos.getc(true);
-
- var directionCat = adj.getData("category");
- //label placement on edges
- Metamaps.JIT.renderEdgeArrows(this.edgeHelper, adj);
-
- //check for edge label in data
- var desc = adj.getData("desc");
- var showDesc = adj.getData("showDesc");
- if (desc != "" && showDesc) {
- // '&' to '&'
- desc = Metamaps.Util.decodeEntities(desc);
-
- //now adjust the label placement
- var ctx = canvas.getCtx();
- ctx.font = 'bold 14px arial';
- ctx.fillStyle = '#FFF';
- ctx.textBaseline = 'hanging';
-
- var arrayOfLabelLines = Metamaps.Util.splitLine(desc, 30).split('\n');
- var index, lineWidths = [];
- for (index = 0; index < arrayOfLabelLines.length; ++index) {
- lineWidths.push(ctx.measureText(arrayOfLabelLines[index]).width)
- }
- var width = Math.max.apply(null, lineWidths) + 8;
- var height = (16 * arrayOfLabelLines.length) + 8;
-
- var x = (pos.x + posChild.x - width) / 2;
- var y = ((pos.y + posChild.y) / 2) - height / 2;
- var radius = 5;
-
- //render background
- ctx.beginPath();
- ctx.moveTo(x + radius, y);
- ctx.lineTo(x + width - radius, y);
- ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
- ctx.lineTo(x + width, y + height - radius);
- ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
- ctx.lineTo(x + radius, y + height);
- ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
- ctx.lineTo(x, y + radius);
- ctx.quadraticCurveTo(x, y, x + radius, y);
- ctx.closePath();
- ctx.fill();
-
- //render text
- ctx.fillStyle = '#222222';
- ctx.textAlign = 'center';
- for (index = 0; index < arrayOfLabelLines.length; ++index) {
- ctx.fillText(arrayOfLabelLines[index], x + (width / 2), y + 5 + (16 * index));
- }
- }
- }, // edgeRenderEmbed
ForceDirected: {
animateSavedLayout: {
modes: ['linear'],
@@ -427,7 +444,7 @@ Metamaps.JIT = {
ctx = canvas.getCtx();
// if the topic is selected draw a circle around it
- if (node.selected) {
+ if (!canvas.denySelected && node.selected) {
ctx.beginPath();
ctx.arc(pos.x, pos.y, dim + 3, 0, 2 * Math.PI, false);
ctx.strokeStyle = Metamaps.Settings.colors.topics.selected;
@@ -447,6 +464,26 @@ Metamaps.JIT = {
} else {
ctx.drawImage(metacode.get('image'), pos.x - dim, pos.y - dim, dim * 2, dim * 2);
}
+
+ // if the topic has a link, draw a small image to indicate that
+ var hasLink = topic && topic.get('link') !== "" && topic.get('link') !== null;
+ var linkImage = Metamaps.JIT.topicLinkImage;
+ var linkImageLoaded = linkImage.complete ||
+ (typeof linkImage.naturalWidth !== "undefined" &&
+ linkImage.naturalWidth !== 0)
+ if (hasLink && linkImageLoaded) {
+ ctx.drawImage(linkImage, pos.x - dim - 8, pos.y - dim - 8, 16, 16);
+ }
+
+ // if the topic has a desc, draw a small image to indicate that
+ var hasDesc = topic && topic.get('desc') !== "" && topic.get('desc') !== null;
+ var descImage = Metamaps.JIT.topicDescImage;
+ var descImageLoaded = descImage.complete ||
+ (typeof descImage.naturalWidth !== "undefined" &&
+ descImage.naturalWidth !== 0)
+ if (hasDesc && descImageLoaded) {
+ ctx.drawImage(descImage, pos.x + dim - 8, pos.y - dim - 8, 16, 16);
+ }
},
'contains': function (node, pos) {
var npos = node.pos.getc(true),
@@ -486,7 +523,7 @@ Metamaps.JIT = {
if (-1 < pos.x && pos.x < 1) pos.x = 0;
if (-1 < pos.y && pos.y < 1) pos.y = 0;
- return $jit.Graph.Plot.edgeHelper.line.contains(from, to, pos, adj.Edge.epsilon);
+ return $jit.Graph.Plot.edgeHelper.line.contains(from, to, pos, adj.Edge.epsilon + 5);
}
}
}
@@ -677,15 +714,18 @@ Metamaps.JIT = {
if (!node && !edge) {
$('canvas').css('cursor', 'default');
}
-
- var pos = eventInfo.getPos();
- $(document).trigger(Metamaps.JIT.events.mouseMove, [pos]);
}, // onMouseMoveHandler
enterKeyHandler: function () {
+ var creatingMap = Metamaps.GlobalUI.lightbox;
+ if (creatingMap === "newmap" || creatingMap === "forkmap") {
+ Metamaps.GlobalUI.CreateMap.submit();
+ }
// this is to submit new topic creation
- if (Metamaps.Create.newTopic.beingCreated) {
+ else if (Metamaps.Create.newTopic.beingCreated) {
Metamaps.Topic.createTopicLocally();
- } else if (Metamaps.Create.newSynapse.beingCreated) {
+ }
+ // to submit new synapse creation
+ else if (Metamaps.Create.newSynapse.beingCreated) {
Metamaps.Synapse.createSynapseLocally();
}
}, //enterKeyHandler
@@ -751,6 +791,8 @@ Metamaps.JIT = {
var positionsToSend = {};
var topic;
+ var authorized = Metamaps.Active.Map && Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper);
+
if (node && !node.nodeFrom) {
var pos = eventInfo.getPos();
// if it's a left click, or a touch, move the node
@@ -773,7 +815,6 @@ Metamaps.JIT = {
// maps
positionsToSend[topic.id] = pos;
$(document).trigger(Metamaps.JIT.events.topicDrag, [positionsToSend]);
- $(document).trigger(Metamaps.JIT.events.mouseMove, [pos]);
}
} else {
var len = Metamaps.Selected.Nodes.length;
@@ -805,7 +846,6 @@ Metamaps.JIT = {
if (Metamaps.Active.Map) {
$(document).trigger(Metamaps.JIT.events.topicDrag, [positionsToSend]);
- $(document).trigger(Metamaps.JIT.events.mouseMove, [pos]);
}
} //if
@@ -815,7 +855,7 @@ Metamaps.JIT = {
Metamaps.Visualize.mGraph.plot();
}
// if it's a right click or holding down alt, start synapse creation ->third option is for firefox
- else if ((e.button == 2 || (e.button == 0 && e.altKey) || e.buttons == 2) && Metamaps.Active.Mapper) {
+ else if ((e.button == 2 || (e.button == 0 && e.altKey) || e.buttons == 2) && authorized) {
if (tempInit == false) {
tempNode = node;
tempInit = true;
@@ -877,9 +917,14 @@ Metamaps.JIT = {
x: pos.x,
y: pos.y
};
- $(document).trigger(Metamaps.JIT.events.mouseMove, [pos]);
}
}
+ else if ((e.button == 2 || (e.button == 0 && e.altKey) || e.buttons == 2) && Metamaps.Active.Topic) {
+ Metamaps.GlobalUI.notifyUser("Cannot create in Topic view.");
+ }
+ else if ((e.button == 2 || (e.button == 0 && e.altKey) || e.buttons == 2) && !authorized) {
+ Metamaps.GlobalUI.notifyUser("Cannot edit Public map.");
+ }
}
}, // onDragMoveTopicHandler
onDragCancelHandler: function (node, eventInfo, e) {
@@ -921,6 +966,9 @@ Metamaps.JIT = {
// check whether to save mappings
var checkWhetherToSave = function() {
var map = Metamaps.Active.Map;
+
+ if (!map) return false;
+
var mapper = Metamaps.Active.Mapper;
// this case
// covers when it is a public map owned by you
@@ -961,7 +1009,17 @@ Metamaps.JIT = {
var now = Date.now(); //not compatible with IE8 FYI
Metamaps.Mouse.lastCanvasClick = now;
+ var authorized = Metamaps.Active.Map && Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper);
+
if (now - storedTime < Metamaps.Mouse.DOUBLE_CLICK_TOLERANCE && !Metamaps.Mouse.didPan) {
+ if (Metamaps.Active.Map && !authorized) {
+ Metamaps.GlobalUI.notifyUser("Cannot edit Public map.");
+ return;
+ }
+ else if (Metamaps.Active.Topic) {
+ Metamaps.GlobalUI.notifyUser("Cannot create in Topic view.");
+ return;
+ }
// DOUBLE CLICK
//pop up node creation :)
Metamaps.Create.newTopic.addSynapse = false;
@@ -1263,12 +1321,18 @@ Metamaps.JIT = {
// add the proper options to the menu
var menustring = '';
- menustring += '- Hide until refresh
';
- if (Metamaps.Active.Map && Metamaps.Active.Mapper) menustring += '- Remove from map
';
- if (Metamaps.Active.Mapper) menustring += '- Delete
';
+ var authorized = Metamaps.Active.Map && Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper);
+
+ var disabled = authorized ? "" : "disabled";
+
+ if (Metamaps.Active.Map) menustring += '- Hide until refresh
';
+ if (Metamaps.Active.Map && Metamaps.Active.Mapper) menustring += '- Remove from map
';
+ if (Metamaps.Active.Map && Metamaps.Active.Mapper) menustring += '- Delete
';
- if (!Metamaps.Active.Map) menustring += '- Center this topic
';
+ if (Metamaps.Active.Topic) {
+ menustring += '- Center this topic
';
+ }
menustring += '- Open in new tab
';
if (Metamaps.Active.Mapper) {
var options = '- commons
\
@@ -1282,6 +1346,15 @@ Metamaps.JIT = {
menustring += '- Change metacode' + metacodeOptions + '
';
}
+ if (Metamaps.Active.Topic) {
+ // set up the get sibling menu as a "lazy load"
+ // only fill in the submenu when they hover over the get siblings list item
+ var siblingMenu = '';
+ menustring += '- Get siblings' + siblingMenu + '
';
+ }
menustring += '
';
rightclickmenu.innerHTML = menustring;
@@ -1325,17 +1398,21 @@ Metamaps.JIT = {
// attach events to clicks on the list items
// delete the selected things from the database
- $('.rc-delete').click(function () {
- $('.rightclickmenu').remove();
- Metamaps.Control.deleteSelected();
- });
+ if (authorized) {
+ $('.rc-delete').click(function () {
+ $('.rightclickmenu').remove();
+ Metamaps.Control.deleteSelected();
+ });
+ }
// remove the selected things from the map
- $('.rc-remove').click(function () {
- $('.rightclickmenu').remove();
- Metamaps.Control.removeSelectedEdges();
- Metamaps.Control.removeSelectedNodes();
- });
+ if (authorized) {
+ $('.rc-remove').click(function () {
+ $('.rightclickmenu').remove();
+ Metamaps.Control.removeSelectedEdges();
+ Metamaps.Control.removeSelectedNodes();
+ });
+ }
// hide selected nodes and synapses until refresh
$('.rc-hide').click(function () {
@@ -1371,7 +1448,70 @@ Metamaps.JIT = {
Metamaps.Control.updateSelectedMetacodes($(this).attr('data-id'));
});
- }, //selectNodeOnRightClickHandler
+
+ // fetch relatives
+ var fetched = false;
+ $('.rc-siblings').hover(function () {
+ if (!fetched) {
+ Metamaps.JIT.populateRightClickSiblings(node);
+ fetched = true;
+ }
+ });
+ $('.rc-siblings .fetchAll').click(function () {
+ $('.rightclickmenu').remove();
+ // data-id is a metacode id
+ Metamaps.Topic.fetchRelatives(node);
+ });
+ }, //selectNodeOnRightClickHandler,
+ populateRightClickSiblings: function(node) {
+ var self = Metamaps.JIT;
+
+ // depending on how many topics are selected, do different things
+ /*if (Metamaps.Selected.Nodes.length > 1) {
+ // we don't bother filling the submenu with
+ // specific numbers, because there are too many topics
+ // selected to find those numbers
+ $('#loadingSiblings').remove();
+ return;
+ }*/
+
+ var topic = node.getData('topic');
+
+ // add a loading icon for now
+ var loader = new CanvasLoader('loadingSiblings');
+ loader.setColor('#4FC059'); // default is '#000000'
+ loader.setDiameter(15); // default is 40
+ loader.setDensity(41); // default is 40
+ loader.setRange(0.9); // default is 1.3
+ loader.show(); // Hidden by default
+
+ var topics = Metamaps.Topics.map(function(t){ return t.id });
+ var topics_string = topics.join();
+
+ var successCallback = function(data) {
+ $('#loadingSiblings').remove();
+
+ for (var key in data) {
+ var string = Metamaps.Metacodes.get(key).get('name') + ' (' + data[key] + ')';
+ $('#fetchSiblingList').append('- ' + string + '
');
+ }
+
+ $('.rc-siblings .getSiblings').click(function () {
+ $('.rightclickmenu').remove();
+ // data-id is a metacode id
+ Metamaps.Topic.fetchRelatives(node, $(this).attr('data-id'));
+ });
+ };
+
+ $.ajax({
+ type: "Get",
+ url: "/topics/" + topic.id + "/relative_numbers.json?network=" + topics_string,
+ success: successCallback,
+ error: function () {
+
+ }
+ });
+ },
selectEdgeOnClickHandler: function (adj, e) {
if (Metamaps.Visualize.mGraph.busy) return;
@@ -1439,11 +1579,13 @@ Metamaps.JIT = {
// add the proper options to the menu
var menustring = '';
- menustring += '- Hide until refresh
';
- if (Metamaps.Active.Map && Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper)) {
- menustring += '- Remove from map
';
- }
- if (Metamaps.Active.Mapper) menustring += '- Delete
';
+ var authorized = Metamaps.Active.Map && Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper);
+
+ var disabled = authorized ? "" : "disabled";
+
+ if (Metamaps.Active.Map) menustring += '- Hide until refresh
';
+ if (Metamaps.Active.Map && Metamaps.Active.Mapper) menustring += '- Remove from map
';
+ if (Metamaps.Active.Map && Metamaps.Active.Mapper) menustring += '- Delete
';
if (Metamaps.Active.Mapper) {
var permOptions = '- commons
\
@@ -1494,17 +1636,21 @@ Metamaps.JIT = {
// attach events to clicks on the list items
// delete the selected things from the database
- $('.rc-delete').click(function () {
- $('.rightclickmenu').remove();
- Metamaps.Control.deleteSelected();
- });
+ if (authorized) {
+ $('.rc-delete').click(function () {
+ $('.rightclickmenu').remove();
+ Metamaps.Control.deleteSelected();
+ });
+ }
// remove the selected things from the map
- $('.rc-remove').click(function () {
- $('.rightclickmenu').remove();
- Metamaps.Control.removeSelectedEdges();
- Metamaps.Control.removeSelectedNodes();
- });
+ if (authorized) {
+ $('.rc-remove').click(function () {
+ $('.rightclickmenu').remove();
+ Metamaps.Control.removeSelectedEdges();
+ Metamaps.Control.removeSelectedNodes();
+ });
+ }
// hide selected nodes and synapses until refresh
$('.rc-hide').click(function () {
@@ -1584,12 +1730,10 @@ Metamaps.JIT = {
ctx.lineTo(v2.x, v2.y);
ctx.stroke();
}, // renderMidArrow
- renderEdgeArrows: function (edgeHelper, adj, synapse) {
+ renderEdgeArrows: function (edgeHelper, adj, synapse, canvas) {
var self = Metamaps.JIT;
- var canvas = Metamaps.Visualize.mGraph.canvas;
-
var directionCat = synapse.get('category');
var direction = synapse.getDirection();
@@ -1646,8 +1790,7 @@ Metamaps.JIT = {
Metamaps.Visualize.mGraph.canvas.scale(0.8,0.8);
$(document).trigger(Metamaps.JIT.events.zoom, [event]);
},
- centerMap: function () {
- var canvas = Metamaps.Visualize.mGraph.canvas;
+ centerMap: function (canvas) {
var offsetScale = canvas.scaleOffsetX;
canvas.scale(1/offsetScale,1/offsetScale);
@@ -1663,7 +1806,8 @@ Metamaps.JIT = {
eX = Metamaps.Mouse.boxEndCoordinates.x,
eY = Metamaps.Mouse.boxEndCoordinates.y;
- Metamaps.JIT.centerMap();
+ var canvas = Metamaps.Visualize.mGraph.canvas;
+ Metamaps.JIT.centerMap(canvas);
var height = $(document).height(),
width = $(document).width();
@@ -1675,8 +1819,6 @@ Metamaps.JIT = {
var newRatio = Math.min(ratioX,ratioY);
- var canvas = Metamaps.Visualize.mGraph.canvas;
-
if(canvas.scaleOffsetX *newRatio<= 5 && canvas.scaleOffsetX*newRatio >= 0.2){
canvas.scale(newRatio,newRatio);
}
@@ -1700,15 +1842,14 @@ Metamaps.JIT = {
Metamaps.Visualize.mGraph.plot();
},
- zoomExtents: function (event) {
- Metamaps.JIT.centerMap();
- var height = $(document).height(),
- width = $(document).width(),
+ zoomExtents: function (event, canvas, denySelected) {
+ Metamaps.JIT.centerMap(canvas);
+ var height = canvas.getSize().height,
+ width = canvas.getSize().width,
maxX, minX, maxY, minY, counter = 0;
- var canvas = Metamaps.Visualize.mGraph.canvas;
- if (Metamaps.Selected.Nodes.length > 0) {
+ if (!denySelected && Metamaps.Selected.Nodes.length > 0) {
var nodes = Metamaps.Selected.Nodes;
}
else {
diff --git a/app/assets/javascripts/src/Metamaps.Router.js b/app/assets/javascripts/src/Metamaps.Router.js
index aa4fa338..466326d2 100644
--- a/app/assets/javascripts/src/Metamaps.Router.js
+++ b/app/assets/javascripts/src/Metamaps.Router.js
@@ -125,7 +125,7 @@
if (Metamaps.Visualize.mGraph) {
Metamaps.Visualize.mGraph.graph.empty();
Metamaps.Visualize.mGraph.plot();
- Metamaps.JIT.centerMap();
+ Metamaps.JIT.centerMap(Metamaps.Visualize.mGraph.canvas);
}
Metamaps.Famous.viz.show();
Metamaps.Topic.end();
@@ -156,7 +156,7 @@
if (Metamaps.Visualize.mGraph) {
Metamaps.Visualize.mGraph.graph.empty();
Metamaps.Visualize.mGraph.plot();
- Metamaps.JIT.centerMap();
+ Metamaps.JIT.centerMap(Metamaps.Visualize.mGraph.canvas);
}
Metamaps.Famous.viz.show();
Metamaps.Map.end();
diff --git a/app/assets/javascripts/src/Metamaps.js b/app/assets/javascripts/src/Metamaps.js
index 910d55a2..4e00cd5f 100644
--- a/app/assets/javascripts/src/Metamaps.js
+++ b/app/assets/javascripts/src/Metamaps.js
@@ -82,6 +82,7 @@ Metamaps.Backbone.init = function () {
self.Metacode = Backbone.Model.extend({
initialize: function () {
var image = new Image();
+ image.crossOrigin = "Anonymous";
image.src = this.get('icon');
this.set('image',image);
},
@@ -218,7 +219,6 @@ Metamaps.Backbone.init = function () {
var mapping;
var node = this.get('node');
node.setData('topic', this);
- node.id = this.isNew() ? this.cid : this.id;
if (Metamaps.Active.Map) {
mapping = this.getMapping();
@@ -476,6 +476,9 @@ Metamaps.Backbone.init = function () {
Metamaps.Mappers = Metamaps.Mappers ? new self.MapperCollection(Metamaps.Mappers) : new self.MapperCollection();
+ // this is for topic view
+ Metamaps.Creators = Metamaps.Creators ? new self.MapperCollection(Metamaps.Creators) : new self.MapperCollection();
+
if (Metamaps.Active.Map) {
Metamaps.Mappings = Metamaps.Mappings ? new self.MappingCollection(Metamaps.Mappings) : new self.MappingCollection();
@@ -701,6 +704,7 @@ Metamaps.Create = {
$('#topic_name').focus();
});
Metamaps.Create.newTopic.beingCreated = true;
+ Metamaps.Create.newTopic.name = "";
},
hide: function () {
$('#new_topic').fadeOut('fast');
@@ -831,7 +835,14 @@ Metamaps.TopicCard = {
var self = Metamaps.TopicCard;
$('#embedlyLinkLoader').hide();
- $('#embedlyLink').fadeIn('fast');
+
+ // means that the embedly call returned 404 not found
+ if ($('#embedlyLink')[0]) {
+ $('#embedlyLink').css('display', 'block').fadeIn('fast');
+ $('.embeds').addClass('nonEmbedlyLink');
+ }
+
+ $('.CardOnGraph').addClass('hasAttachment');
if (self.authorizedToEdit) {
$('.embeds').append('');
$('#linkremove').click(self.removeLink);
@@ -842,7 +853,7 @@ Metamaps.TopicCard = {
self.openTopicCard.save({
link: null
});
- $('.embeds').empty();
+ $('.embeds').empty().removeClass('nonEmbedlyLink');
$('#addLinkInput input').val("");
$('.attachments').removeClass('hidden');
$('.CardOnGraph').removeClass('hasAttachment');
@@ -891,8 +902,10 @@ Metamaps.TopicCard = {
loader.setDensity(41); // default is 40
loader.setRange(0.9); // default is 1.3
loader.show(); // Hidden by default
- embedly('card', document.getElementById('embedlyLink'));
- $('.CardOnGraph').addClass('hasAttachment');
+ var e = embedly('card', document.getElementById('embedlyLink'));
+ if (!e) {
+ self.handleInvalidLink();
+ }
}
}, 100);
};
@@ -907,7 +920,10 @@ Metamaps.TopicCard = {
loader.setDensity(41); // default is 40
loader.setRange(0.9); // default is 1.3
loader.show(); // Hidden by default
- embedly('card', document.getElementById('embedlyLink'));
+ var e = embedly('card', document.getElementById('embedlyLink'));
+ if (!e) {
+ self.handleInvalidLink();
+ }
}
@@ -1074,6 +1090,12 @@ Metamaps.TopicCard = {
$('.showcard').click(hidePermissionSelect);
}
},
+ handleInvalidLink: function() {
+ var self = Metamaps.TopicCard;
+
+ self.removeLink();
+ Metamaps.GlobalUI.notifyUser("Invalid link");
+ },
populateShowCard: function (topic) {
var self = Metamaps.TopicCard;
@@ -1485,6 +1507,8 @@ Metamaps.Visualize = {
mapping;
if (self.type == "RGraph") {
+ var i, l, startPos, endPos, topic, synapse;
+
self.mGraph.graph.eachNode(function (n) {
topic = Metamaps.Topics.get(n.id);
topic.set({ node: n }, { silent: true });
@@ -1686,17 +1710,26 @@ Metamaps.Util = {
}
},
pixelsToCoords: function (pixels) {
- var canvas = Metamaps.Visualize.mGraph.canvas,
- s = canvas.getSize(),
- p = canvas.getPos(),
- ox = canvas.translateOffsetX,
- oy = canvas.translateOffsetY,
- sx = canvas.scaleOffsetX,
- sy = canvas.scaleOffsetY;
- var coords = {
- x: (pixels.x - p.x - s.width/2 - ox) * (1/sx),
- y: (pixels.y - p.y - s.height/2 - oy) * (1/sy),
- };
+ var coords;
+ if (Metamaps.Visualize.mGraph) {
+ var canvas = Metamaps.Visualize.mGraph.canvas,
+ s = canvas.getSize(),
+ p = canvas.getPos(),
+ ox = canvas.translateOffsetX,
+ oy = canvas.translateOffsetY,
+ sx = canvas.scaleOffsetX,
+ sy = canvas.scaleOffsetY;
+ coords = {
+ x: (pixels.x - p.x - s.width/2 - ox) * (1/sx),
+ y: (pixels.y - p.y - s.height/2 - oy) * (1/sy),
+ };
+ }
+ else {
+ coords = {
+ x: 0,
+ y: 0
+ };
+ }
return coords;
},
getPastelColor: function () {
@@ -1761,8 +1794,11 @@ Metamaps.Realtime = {
var reenableRealtime = function () {
self.reenableRealtime();
};
+ var turnOff = function () {
+ self.turnOff();
+ };
$(".rtOn").click(reenableRealtime);
- $(".rtOff").click(self.turnOff);
+ $(".rtOff").click(turnOff);
$('.sidebarCollaborateIcon').click(self.toggleBox);
$('.sidebarCollaborateBox').click(function(event){
@@ -1813,19 +1849,23 @@ Metamaps.Realtime = {
startActiveMap: function () {
var self = Metamaps.Realtime;
- if (Metamaps.Active.Map) {
+ if (Metamaps.Active.Map && Metamaps.Active.Mapper) {
var commonsMap = Metamaps.Active.Map.get('permission') === 'commons';
+ var publicMap = Metamaps.Active.Map.get('permission') === 'public';
if (commonsMap) {
self.turnOn();
self.setupSocket();
}
+ else if (publicMap) {
+ self.attachMapListener();
+ }
}
},
endActiveMap: function () {
var self = Metamaps.Realtime;
- $(document).off(Metamaps.JIT.events.mouseMove);
+ $(document).off('mousemove');
self.socket.removeAllListeners();
self.socket.emit('endMapperNotify');
$(".collabCompass").remove();
@@ -1852,11 +1892,11 @@ Metamaps.Realtime = {
$(".collabCompass").show();
}
},
- turnOff: function () {
+ turnOff: function (silent) {
var self = Metamaps.Realtime;
if (self.status) {
- self.sendRealtimeOff();
+ if (!silent) self.sendRealtimeOff();
$(".rtMapperSelf").removeClass('littleRtOn').addClass('littleRtOff');
self.status = false;
$(".sidebarCollaborateIcon").removeClass("blue");
@@ -1914,13 +1954,18 @@ Metamaps.Realtime = {
socket.on('topicChangeFromServer', self.topicChange);
socket.on('synapseChangeFromServer', self.synapseChange);
- socket.on('mapChangeFromServer', self.mapChange);
+ self.attachMapListener();
// local event listeners that trigger events
- var sendCoords = function (event, coords) {
+ var sendCoords = function (event) {
+ var pixels = {
+ x: event.pageX,
+ y: event.pageY
+ };
+ var coords = Metamaps.Util.pixelsToCoords(pixels);
self.sendCoords(coords);
};
- $(document).on(Metamaps.JIT.events.mouseMove, sendCoords);
+ $(document).mousemove(sendCoords);
var zoom = function (event, e) {
if (e) {
@@ -1973,6 +2018,12 @@ Metamaps.Realtime = {
$(document).on(Metamaps.JIT.events.removeSynapse, sendRemoveSynapse);
},
+ attachMapListener: function(){
+ var self = Metamaps.Realtime;
+ var socket = Metamaps.Realtime.socket;
+
+ socket.on('mapChangeFromServer', self.mapChange);
+ },
sendRealtimeOn: function () {
var self = Metamaps.Realtime;
var socket = Metamaps.Realtime.socket;
@@ -2023,7 +2074,8 @@ Metamaps.Realtime = {
mapperListItem += '" class="rtMapper littleRt';
mapperListItem += onOff;
mapperListItem += '">';
- mapperListItem += '
';
+ mapperListItem += '
';
mapperListItem += data.username;
mapperListItem += '';
mapperListItem += '';
@@ -2057,9 +2109,10 @@ Metamaps.Realtime = {
};
// create an item for them in the realtime box
- if (data.userid !== Metamaps.Active.Mapper.id) {
+ if (data.userid !== Metamaps.Active.Mapper.id && self.status) {
var mapperListItem = '- ';
- mapperListItem += '
';
+ mapperListItem += '
';
mapperListItem += data.username;
mapperListItem += '';
mapperListItem += ' ';
@@ -2314,18 +2367,32 @@ Metamaps.Realtime = {
socket.emit('mapChangeFromClient', data);
},
mapChange: function (data) {
- /*var map = Metamaps.Topics.get(data.topicId);
- if (map) {
- var node = topic.get('node');
- topic.fetch({
- success: function (model) {
- // must be set using silent:true otherwise
- // will trigger a change event and an infinite
- // loop with other clients of change events
- model.set({ node: node });
+ var map = Metamaps.Active.Map;
+ var isActiveMap = map && data.mapId === map.id;
+ if (isActiveMap) {
+ var permBefore = map.get('permission');
+ var idBefore = map.id;
+ map.fetch({
+ success: function (model, response) {
+
+ var idNow = model.id;
+ var permNow = model.get('permission');
+ if (idNow !== idBefore) {
+ Metamaps.Map.leavePrivateMap(); // this means the map has been changed to private
+ }
+ else if (permNow === 'public' && permBefore === 'commons') {
+ Metamaps.Map.commonsToPublic();
+ }
+ else if (permNow === 'commons' && permBefore === 'public') {
+ Metamaps.Map.publicToCommons();
+ }
+ else {
+ model.fetchContained();
+ model.trigger('changeByOther');
+ }
}
});
- }*/
+ }
},
// newTopic
sendNewTopic: function (data) {
@@ -2564,12 +2631,22 @@ Metamaps.Control = {
Metamaps.Selected.Nodes.indexOf(node), 1);
},
deleteSelected: function () {
+
+ if (!Metamaps.Active.Map) return;
+
var n = Metamaps.Selected.Nodes.length;
var e = Metamaps.Selected.Edges.length;
var ntext = n == 1 ? "1 topic" : n + " topics";
var etext = e == 1 ? "1 synapse" : e + " synapses";
var text = "You have " + ntext + " and " + etext + " selected. ";
+ var authorized = Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper);
+
+ if (!authorized) {
+ Metamaps.GlobalUI.notifyUser("Cannot edit Public map.");
+ return;
+ }
+
var r = confirm(text + "Are you sure you want to permanently delete them all? This will remove them from all maps they appear on.");
if (r == true) {
Metamaps.Control.deleteSelectedEdges();
@@ -2577,6 +2654,16 @@ Metamaps.Control = {
}
},
deleteSelectedNodes: function () { // refers to deleting topics permanently
+
+ if (!Metamaps.Active.Map) return;
+
+ var authorized = Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper);
+
+ if (!authorized) {
+ Metamaps.GlobalUI.notifyUser("Cannot edit Public map.");
+ return;
+ }
+
var l = Metamaps.Selected.Nodes.length;
for (var i = l - 1; i >= 0; i -= 1) {
var node = Metamaps.Selected.Nodes[i];
@@ -2584,6 +2671,16 @@ Metamaps.Control = {
}
},
deleteNode: function (nodeid) { // refers to deleting topics permanently
+
+ if (!Metamaps.Active.Map) return;
+
+ var authorized = Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper);
+
+ if (!authorized) {
+ Metamaps.GlobalUI.notifyUser("Cannot edit Public map.");
+ return;
+ }
+
var node = Metamaps.Visualize.mGraph.graph.getNode(nodeid);
var topic = node.getData('topic');
var topicid = topic.id;
@@ -2596,33 +2693,45 @@ Metamaps.Control = {
Metamaps.Control.hideNode(nodeid);
},
removeSelectedNodes: function () { // refers to removing topics permanently from a map
+
+ if (!Metamaps.Active.Map) return;
+
var l = Metamaps.Selected.Nodes.length,
i,
node,
- mapperm = Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper);
+ authorized = Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper);
- if (mapperm) {
- for (i = l - 1; i >= 0; i -= 1) {
- node = Metamaps.Selected.Nodes[i];
- Metamaps.Control.removeNode(node.id);
- }
+ if (!authorized) {
+ Metamaps.GlobalUI.notifyUser("Cannot edit Public map.");
+ return;
+ }
+
+ for (i = l - 1; i >= 0; i -= 1) {
+ node = Metamaps.Selected.Nodes[i];
+ Metamaps.Control.removeNode(node.id);
}
},
removeNode: function (nodeid) { // refers to removing topics permanently from a map
- var mapperm = Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper);
+
+ if (!Metamaps.Active.Map) return;
+
+ var authorized = Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper);
var node = Metamaps.Visualize.mGraph.graph.getNode(nodeid);
- if (mapperm) {
- var topic = node.getData('topic');
- var topicid = topic.id;
- var mapping = node.getData('mapping');
- mapping.destroy();
- Metamaps.Topics.remove(topic);
- $(document).trigger(Metamaps.JIT.events.removeTopic, [{
- topicid: topicid
- }]);
- Metamaps.Control.hideNode(nodeid);
+ if (!authorized) {
+ Metamaps.GlobalUI.notifyUser("Cannot edit Public map.");
+ return;
}
+
+ var topic = node.getData('topic');
+ var topicid = topic.id;
+ var mapping = node.getData('mapping');
+ mapping.destroy();
+ Metamaps.Topics.remove(topic);
+ $(document).trigger(Metamaps.JIT.events.removeTopic, [{
+ topicid: topicid
+ }]);
+ Metamaps.Control.hideNode(nodeid);
},
hideSelectedNodes: function () {
var l = Metamaps.Selected.Nodes.length,
@@ -2707,6 +2816,16 @@ Metamaps.Control = {
deleteSelectedEdges: function () { // refers to deleting topics permanently
var edge,
l = Metamaps.Selected.Edges.length;
+
+ if (!Metamaps.Active.Map) return;
+
+ var authorized = Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper);
+
+ if (!authorized) {
+ Metamaps.GlobalUI.notifyUser("Cannot edit Public map.");
+ return;
+ }
+
for (var i = l - 1; i >= 0; i -= 1) {
edge = Metamaps.Selected.Edges[i];
Metamaps.Control.deleteEdge(edge);
@@ -2714,6 +2833,15 @@ Metamaps.Control = {
},
deleteEdge: function (edge) {
+ if (!Metamaps.Active.Map) return;
+
+ var authorized = Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper);
+
+ if (!authorized) {
+ Metamaps.GlobalUI.notifyUser("Cannot edit Public map.");
+ return;
+ }
+
if (edge.getData("synapses").length - 1 === 0) {
Metamaps.Control.hideEdge(edge);
}
@@ -2741,16 +2869,32 @@ Metamaps.Control = {
i,
edge;
- if (Metamaps.Active.Map) {
- for (i = l - 1; i >= 0; i -= 1) {
- edge = Metamaps.Selected.Edges[i];
- Metamaps.Control.removeEdge(edge);
- }
- Metamaps.Selected.Edges = new Array();
+ if (!Metamaps.Active.Map) return;
+
+ var authorized = Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper);
+
+ if (!authorized) {
+ Metamaps.GlobalUI.notifyUser("Cannot edit Public map.");
+ return;
}
+
+ for (i = l - 1; i >= 0; i -= 1) {
+ edge = Metamaps.Selected.Edges[i];
+ Metamaps.Control.removeEdge(edge);
+ }
+ Metamaps.Selected.Edges = new Array();
},
removeEdge: function (edge) {
+ if (!Metamaps.Active.Map) return;
+
+ var authorized = Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper);
+
+ if (!authorized) {
+ Metamaps.GlobalUI.notifyUser("Cannot edit Public map.");
+ return;
+ }
+
if (edge.getData("mappings").length - 1 === 0) {
Metamaps.Control.hideEdge(edge);
}
@@ -3005,12 +3149,30 @@ Metamaps.Filter = {
var removed = [];
var added = [];
- Metamaps[collection].each(function(model) {
- var prop = model.get(propertyToCheck) ? model.get(propertyToCheck).toString() : false;
- if (prop && newList.indexOf(prop) === -1) {
- newList.push(prop);
- }
- });
+ // the first option enables us to accept
+ // ['Topics', 'Synapses'] as 'collection'
+ if (typeof collection === "object") {
+ Metamaps[collection[0]].each(function(model) {
+ var prop = model.get(propertyToCheck) ? model.get(propertyToCheck).toString() : false;
+ if (prop && newList.indexOf(prop) === -1) {
+ newList.push(prop);
+ }
+ });
+ Metamaps[collection[1]].each(function(model) {
+ var prop = model.get(propertyToCheck) ? model.get(propertyToCheck).toString() : false;
+ if (prop && newList.indexOf(prop) === -1) {
+ newList.push(prop);
+ }
+ });
+ }
+ else if (typeof collection === "string") {
+ Metamaps[collection].each(function(model) {
+ var prop = model.get(propertyToCheck) ? model.get(propertyToCheck).toString() : false;
+ if (prop && newList.indexOf(prop) === -1) {
+ newList.push(prop);
+ }
+ });
+ }
removed = _.difference(self.filters[filtersToUse], newList);
added = _.difference(newList, self.filters[filtersToUse]);
@@ -3053,7 +3215,14 @@ Metamaps.Filter = {
},
checkMappers: function () {
var self = Metamaps.Filter;
- self.updateFilters('Mappings', 'user_id', 'Mappers', 'mappers', 'mapper');
+ var onMap = Metamaps.Active.Map ? true : false;
+ if (onMap) {
+ self.updateFilters('Mappings', 'user_id', 'Mappers', 'mappers', 'mapper');
+ }
+ else {
+ // on topic view
+ self.updateFilters(['Topics', 'Synapses'], 'user_id', 'Creators', 'mappers', 'mapper');
+ }
},
checkSynapses: function () {
var self = Metamaps.Filter;
@@ -3134,7 +3303,11 @@ Metamaps.Filter = {
if (Metamaps.Active.Map) {
onMap = true;
}
- else passesMapper = true; // for when you're on a topic page
+ else if (Metamaps.Active.Topic) {
+ onMap = false;
+ }
+
+ var opacityForFilter = onMap ? 0 : 0.4;
Metamaps.Topics.each(function(topic) {
var n = topic.get('node');
@@ -3144,10 +3317,21 @@ Metamaps.Filter = {
else passesMetacode = true;
if (onMap) {
+ // 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;
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;
+ else passesMapper = true;
+ }
if (passesMetacode && passesMapper) {
if (n) {
@@ -3158,7 +3342,7 @@ Metamaps.Filter = {
else {
if (n) {
Metamaps.Control.deselectNode(n, true);
- n.setData('alpha', 0, 'end');
+ n.setData('alpha', opacityForFilter, 'end');
n.eachAdjacency(function(e){
Metamaps.Control.deselectEdge(e, true);
});
@@ -3175,10 +3359,13 @@ Metamaps.Filter = {
else passesSynapse = true;
if (onMap) {
- var user_id = synapse.getMapping().get("user_id").toString();
- if (visible.mappers.indexOf(user_id) == -1) passesMapper = false;
- else passesMapper = true;
+ // 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();
}
+ if (visible.mappers.indexOf(user_id) == -1) passesMapper = false;
+ else passesMapper = true;
var color = Metamaps.Settings.colors.synapses.normal;
if (passesSynapse && passesMapper) {
@@ -3191,10 +3378,10 @@ Metamaps.Filter = {
else {
if (e) {
Metamaps.Control.deselectEdge(e, true);
- e.setData('alpha', 0, 'end');
+ e.setData('alpha', opacityForFilter, 'end');
}
else console.log(synapse);
- }
+ }
});
// run the animation
@@ -3244,7 +3431,7 @@ Metamaps.Listeners = {
case 69: //if e or E is pressed
if (e.ctrlKey){
e.preventDefault();
- Metamaps.JIT.zoomExtents();
+ Metamaps.JIT.zoomExtents(null, Metamaps.Visualize.mGraph.canvas);
}
break;
case 77: //if m or M is pressed
@@ -3445,10 +3632,14 @@ Metamaps.Topic = {
var bb = Metamaps.Backbone;
var start = function (data) {
Metamaps.Active.Topic = new bb.Topic(data.topic);
+ Metamaps.Creators = new bb.MapperCollection(data.creators);
Metamaps.Topics = new bb.TopicCollection([data.topic].concat(data.relatives));
Metamaps.Synapses = new bb.SynapseCollection(data.synapses);
Metamaps.Backbone.attachCollectionEvents();
+ // set filter mapper H3 text
+ $('#filter_by_mapper h3').html('CREATORS');
+
// build and render the visualization
Metamaps.Visualize.type = "RGraph";
Metamaps.JIT.prepareVizData();
@@ -3475,12 +3666,12 @@ Metamaps.Topic = {
$('.rightclickmenu').remove();
Metamaps.TopicCard.hideCard();
Metamaps.SynapseCard.hideCard();
+ Metamaps.Filter.close();
}
},
centerOn: function (nodeid) {
if (!Metamaps.Visualize.mGraph.busy) {
- var node = Metamaps.Visualize.mGraph.graph.getNode(nodeid);
- Metamaps.Visualize.mGraph.onClick(node.id, {
+ Metamaps.Visualize.mGraph.onClick(nodeid, {
hideLabels: false,
duration: 1000,
onComplete: function () {
@@ -3489,6 +3680,66 @@ Metamaps.Topic = {
});
}
},
+ fetchRelatives: function(node, metacode_id) {
+
+ var topics = Metamaps.Topics.map(function(t){ return t.id });
+ var topics_string = topics.join();
+
+ var creators = Metamaps.Creators.map(function(t){ return t.id });
+ var creators_string = creators.join();
+
+ var topic = node.getData('topic');
+
+ var successCallback = function(data) {
+ if (data.creators.length > 0) Metamaps.Creators.add(data.creators);
+ if (data.topics.length > 0) Metamaps.Topics.add(data.topics);
+ if (data.synapses.length > 0) Metamaps.Synapses.add(data.synapses);
+
+ var topicColl = new Metamaps.Backbone.TopicCollection(data.topics);
+ topicColl.add(topic);
+ var synapseColl = new Metamaps.Backbone.SynapseCollection(data.synapses);
+
+ var graph = Metamaps.JIT.convertModelsToJIT(topicColl, synapseColl)[0];
+ Metamaps.Visualize.mGraph.op.sum(graph, {
+ type: 'fade',
+ duration: 500,
+ hideLabels: false
+ });
+
+ var i, l, t, s;
+
+ Metamaps.Visualize.mGraph.graph.eachNode(function (n) {
+ t = Metamaps.Topics.get(n.id);
+ t.set({ node: n }, { silent: true });
+ t.updateNode();
+
+ n.eachAdjacency(function (edge) {
+ if(!edge.getData('init')) {
+ edge.setData('init', true);
+
+ l = edge.getData('synapseIDs').length;
+ for (i = 0; i < l; i++) {
+ s = Metamaps.Synapses.get(edge.getData('synapseIDs')[i]);
+ s.set({ edge: edge }, { silent: true });
+ s.updateEdge();
+ }
+ }
+ });
+ });
+ };
+
+ var paramsString = metacode_id ? "metacode=" + metacode_id + "&" : "";
+ paramsString += "network=" + topics_string + "&creators=" + creators_string;
+
+ $.ajax({
+ type: "Get",
+ url: "/topics/" + topic.id + "/relatives.json?" + paramsString,
+ success: successCallback,
+ error: function () {
+
+ }
+ });
+ },
/*
*
*
@@ -3504,14 +3755,9 @@ Metamaps.Topic = {
if (!$.isEmptyObject(Metamaps.Visualize.mGraph.graph.nodes)) {
Metamaps.Visualize.mGraph.graph.addNode(newnode);
- Metamaps.Visualize.mGraph.graph.eachNode(function (n) {
- n.setData("dim", 25, "start");
- n.setData("dim", 25, "end");
- });
nodeOnViz = Metamaps.Visualize.mGraph.graph.getNode(newnode.id);
- topic.set('node', nodeOnViz);
- topic.updateNode(); // links the topic and the mapping to the node
-
+ topic.set('node', nodeOnViz, {silent: true});
+ topic.updateNode(); // links the topic and the mapping to the node
nodeOnViz.setData("dim", 1, "start");
nodeOnViz.setData("dim", 25, "end");
@@ -3559,7 +3805,7 @@ Metamaps.Topic = {
} else {
Metamaps.Visualize.mGraph.loadJSON(newnode);
nodeOnViz = Metamaps.Visualize.mGraph.graph.getNode(newnode.id);
- topic.set('node', nodeOnViz);
+ topic.set('node', nodeOnViz, {silent: true});
topic.updateNode(); // links the topic and the mapping to the node
nodeOnViz.setData("dim", 1, "start");
@@ -3618,6 +3864,11 @@ Metamaps.Topic = {
createTopicLocally: function () {
var self = Metamaps.Topic;
+ if (Metamaps.Create.newTopic.name === "") {
+ Metamaps.GlobalUI.notifyUser("Please enter a topic title...");
+ return;
+ }
+
$(document).trigger(Metamaps.Map.events.editedByActiveMapper);
var metacode = Metamaps.Metacodes.get(Metamaps.Create.newTopic.metacode);
@@ -3903,6 +4154,9 @@ Metamaps.Map = {
$('.wrapper').addClass('commonsMap');
}
+ // set filter mapper H3 text
+ $('#filter_by_mapper h3').html('MAPPERS');
+
// build and render the visualization
Metamaps.Visualize.type = "ForceDirected";
Metamaps.JIT.prepareVizData();
@@ -3941,6 +4195,7 @@ Metamaps.Map = {
Metamaps.SynapseCard.hideCard();
Metamaps.Create.newTopic.hide();
Metamaps.Create.newSynapse.hide();
+ Metamaps.Filter.close();
Metamaps.Realtime.endActiveMap();
}
},
@@ -3949,31 +4204,37 @@ Metamaps.Map = {
var nodes_data = "",
synapses_data = "";
- var synapses_array = new Array();
+ var nodes_array = [];
+ var synapses_array = [];
+ // collect the unfiltered topics
Metamaps.Visualize.mGraph.graph.eachNode(function (n) {
- //don't add to the map if it was filtered out
- // TODO
- //if (categoryVisible[n.getData('metacode')] == false) {
- // return;
- //}
-
- var 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;
+ // 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;
+ 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;
+ }
+ nodes_data += id + '/' + x + '/' + y + ',';
}
- nodes_data += n.id + '/' + x + '/' + y + ',';
- n.eachAdjacency(function (adj) {
- synapses_array.push(adj.getData("synapses")[0].id); // TODO
- });
});
+ // collect the unfiltered synapses
+ Metamaps.Synapses.each(function(synapse){
+ var desc = synapse.get("desc");
- //get unique values only
- synapses_array = $.grep(synapses_array, function (value, key) {
- return $.inArray(value, synapses_array) === key;
+ var descNotFiltered = Metamaps.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('node1_id')) > -1;
+ topicsNotFiltered = topicsNotFiltered && nodes_array.indexOf(synapse.get('node2_id')) > -1;
+ if (descNotFiltered && topicsNotFiltered) {
+ synapses_array.push(synapse.id);
+ }
});
synapses_data = synapses_array.join();
@@ -3982,6 +4243,26 @@ Metamaps.Map = {
Metamaps.GlobalUI.CreateMap.topicsToMap = nodes_data;
Metamaps.GlobalUI.CreateMap.synapsesToMap = synapses_data;
},
+ leavePrivateMap: function(){
+ var map = Metamaps.Active.Map;
+ Metamaps.Maps.Active.remove(map);
+ Metamaps.Maps.Featured.remove(map);
+ Metamaps.Router.home();
+ Metamaps.GlobalUI.notifyUser('Sorry! That map has been changed to Private.');
+ },
+ commonsToPublic: function(){
+ Metamaps.Realtime.turnOff(true); // true is for 'silence'
+ Metamaps.GlobalUI.notifyUser('Map was changed to Public. Editing is disabled.');
+ Metamaps.Active.Map.trigger('changeByOther');
+ },
+ publicToCommons: function(){
+ var confirmString = "This map permission has been changed to Commons! ";
+ confirmString += "Do you want to reload and enable realtime collaboration?";
+ var c = confirm(confirmString);
+ if (c) {
+ Metamaps.Router.maps(Metamaps.Active.Map.id);
+ }
+ },
editedByActiveMapper: function () {
if (Metamaps.Active.Mapper) {
Metamaps.Mappers.add(Metamaps.Active.Mapper);
@@ -4043,6 +4324,131 @@ Metamaps.Map = {
Metamaps.Map.sideLength = 1;
Metamaps.Map.timeToTurn = 0;
Metamaps.Map.turnCount = 0;
+ },
+ exportImage: function() {
+
+ var canvas = {};
+
+ canvas.canvas = document.createElement("canvas");
+ canvas.canvas.width = 1880; // 960;
+ canvas.canvas.height = 1260; // 630
+
+ canvas.scaleOffsetX = 1;
+ canvas.scaleOffsetY = 1;
+ canvas.translateOffsetY = 0;
+ canvas.translateOffsetX = 0;
+ canvas.denySelected = true;
+
+ canvas.getSize = function() {
+ if(this.size) return this.size;
+ var canvas = this.canvas;
+ return this.size = {
+ width: canvas.width,
+ height: canvas.height
+ };
+ };
+ 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;
+ 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;
+ this.translateOffsetX += x*sx;
+ this.translateOffsetY += y*sy;
+ this.getCtx().translate(x, y);
+ };
+ canvas.getCtx = function() {
+ return this.canvas.getContext("2d");
+ };
+ // center it
+ canvas.getCtx().translate(1880/2, 1260/2);
+
+ var mGraph = Metamaps.Visualize.mGraph;
+
+ var id = mGraph.root;
+ var root = mGraph.graph.getNode(id);
+ var T = !!root.visited;
+
+ // pass true to avoid basing it on a selection
+ Metamaps.JIT.zoomExtents(null, canvas, true);
+
+ var c = canvas.canvas,
+ ctx = canvas.getCtx(),
+ 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);
+ ctx.fillRect(xPoint,yPoint,c.width/scale,c.height/scale);
+
+ // draw the graph
+ mGraph.graph.eachNode(function(node) {
+ var nodeAlpha = node.getData('alpha');
+ node.eachAdjacency(function(adj) {
+ var nodeTo = adj.nodeTo;
+ if(!!nodeTo.visited === T && node.drawn && nodeTo.drawn) {
+ mGraph.fx.plotLine(adj, canvas);
+ }
+ });
+ if(node.drawn) {
+ mGraph.fx.plotNode(node, canvas);
+ }
+ if(!mGraph.labelsHidden) {
+ if(node.drawn && nodeAlpha >= 0.95) {
+ mGraph.labels.plotLabel(canvas, node);
+ } else {
+ mGraph.labels.hideLabel(node, false);
+ }
+ }
+ node.visited = !T;
+ });
+
+ var imageData = {
+ encoded_image: canvas.canvas.toDataURL()
+ };
+
+ console.log(imageData.encoded_image);
+ var map = Metamaps.Active.Map;
+
+ var today = new Date();
+ var dd = today.getDate();
+ var mm = today.getMonth()+1; //January is 0!
+ var yyyy = today.getFullYear();
+ if(dd<10) {
+ dd='0'+dd
+ }
+ if(mm<10) {
+ mm='0'+mm
+ }
+ today = mm+'/'+dd+'/'+yyyy;
+
+ var mapName = map.get("name").split(" ").join([separator = '-']);
+ var downloadMessage = "";
+ downloadMessage += "Captured map screenshot! ";
+ downloadMessage += "DOWNLOAD";
+ Metamaps.GlobalUI.notifyUser(downloadMessage);
+
+ $.ajax({
+ type: "POST",
+ dataType: 'json',
+ url: "/maps/" + Metamaps.Active.Map.id + "/upload_screenshot",
+ data: imageData,
+ success: function (data) {
+ console.log('successfully uploaded map screenshot');
+ },
+ error: function () {
+ console.log('failed to save map screenshot');
+ }
+ });
}
};
@@ -4191,11 +4597,16 @@ Metamaps.Map.InfoBox = {
$('.mapInfoName .best_in_place_name').unbind("ajax:success").bind("ajax:success", function () {
var name = $(this).html();
- $('.mapName').html(name);
Metamaps.Active.Map.set('name', name);
Metamaps.Active.Map.trigger('saved');
});
+ $('.mapInfoDesc .best_in_place_desc').unbind("ajax:success").bind("ajax:success", function () {
+ var desc = $(this).html();
+ Metamaps.Active.Map.set('desc', desc);
+ Metamaps.Active.Map.trigger('saved');
+ });
+
$('.yourMap .mapPermission').unbind().click(self.onPermissionClick);
// .yourMap in the unbind/bind is just a namespace for the events
// not a reference to the class .yourMap on the .mapInfoBox
@@ -4203,6 +4614,11 @@ Metamaps.Map.InfoBox = {
$('.yourMap .mapInfoDelete').unbind().click(self.deleteActiveMap);
},
+ updateNameDescPerm: function(name, desc, perm) {
+ $('.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 = Metamaps.Map.InfoBox;
@@ -4260,9 +4676,19 @@ Metamaps.Map.InfoBox = {
self.selectingPermission = false;
var permission = $(this).attr('class');
+ var permBefore = Metamaps.Active.Map.get('permission');
Metamaps.Active.Map.save({
permission: permission
});
+ Metamaps.Active.Map.updateMapWrapper();
+ if (permBefore !== 'commons' && permission === 'commons') {
+ Metamaps.Realtime.setupSocket();
+ Metamaps.Realtime.turnOn();
+ }
+ else if (permBefore === 'commons' && permission === 'public') {
+ Metamaps.Realtime.turnOff(true); // true is to 'silence'
+ // the notification that would otherwise be sent
+ }
shareable = permission === 'private' ? '' : 'shareable';
$('.mapPermission').removeClass('commons public private minimize').addClass(permission);
$('.mapPermission .permissionSelect').remove();
@@ -4328,6 +4754,17 @@ Metamaps.Account = {
$('.userImageMenu').hide();
},
+ showLoading: function(){
+ var self = Metamaps.Account;
+
+ var loader = new CanvasLoader('accountPageLoading');
+ loader.setColor('#4FC059'); // default is '#000000'
+ loader.setDiameter(28); // default is 40
+ loader.setDensity(41); // default is 40
+ loader.setRange(0.9); // default is 1.3
+ loader.show(); // Hidden by default
+ $('#accountPageLoading').show();
+ },
showImagePreview: function(){
var self = Metamaps.Account;
@@ -4336,7 +4773,36 @@ Metamaps.Account = {
var reader = new FileReader();
reader.onload = function(e) {
- $('.userImageDiv img').attr('src', reader.result);
+ var $canvas = $('
diff --git a/app/views/layouts/_lightboxes.html.erb b/app/views/layouts/_lightboxes.html.erb
index 73cac464..7e55002f 100644
--- a/app/views/layouts/_lightboxes.html.erb
+++ b/app/views/layouts/_lightboxes.html.erb
@@ -114,7 +114,6 @@
Underscore.js
Famo.us
Typeahead.js
-
diff --git a/app/views/layouts/_lowermapelements.html.erb b/app/views/layouts/_lowermapelements.html.erb
index c69d475f..42b1820a 100644
--- a/app/views/layouts/_lowermapelements.html.erb
+++ b/app/views/layouts/_lowermapelements.html.erb
@@ -1,4 +1,5 @@
+
diff --git a/app/views/layouts/_newmap.html.erb b/app/views/layouts/_newmap.html.erb
index 91c8b4f1..63825b57 100644
--- a/app/views/layouts/_newmap.html.erb
+++ b/app/views/layouts/_newmap.html.erb
@@ -8,7 +8,7 @@
diff --git a/app/views/layouts/_upperelements.html.erb b/app/views/layouts/_upperelements.html.erb
index f2bbd85f..e83d5977 100644
--- a/app/views/layouts/_upperelements.html.erb
+++ b/app/views/layouts/_upperelements.html.erb
@@ -30,7 +30,7 @@
-
- <%= image_tag user.image.url(:thumb), :size => "24x24", :class => "rtUserImage" %>
+ <%= image_tag user.image.url(:square), :size => "24x24", :class => "rtUserImage" %>
<%= user.name %> (me)
@@ -62,7 +62,7 @@