From 7805871ec2c7b7ce0785c5c42f61ef35193274ee Mon Sep 17 00:00:00 2001 From: Connor Turland Date: Sun, 2 Nov 2014 14:32:42 -0500 Subject: [PATCH 01/32] made IE lightbox auto display when on IE --- app/views/layouts/application.html.erb | 40 ++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 21a04d81..bea00881 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -24,6 +24,46 @@ require.config({baseUrl: '/famous/'}); require(['main']); + + From 3bebc6287375d6333cf8e2ef9ef714eb81efb741 Mon Sep 17 00:00:00 2001 From: Connor Turland Date: Sun, 2 Nov 2014 14:59:23 -0500 Subject: [PATCH 02/32] blocked empty topic creation with message to add title --- app/assets/javascripts/src/Metamaps.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/assets/javascripts/src/Metamaps.js b/app/assets/javascripts/src/Metamaps.js index 2b2af1b5..11594a0a 100644 --- a/app/assets/javascripts/src/Metamaps.js +++ b/app/assets/javascripts/src/Metamaps.js @@ -701,6 +701,7 @@ Metamaps.Create = { $('#topic_name').focus(); }); Metamaps.Create.newTopic.beingCreated = true; + Metamaps.Create.newTopic.name = ""; }, hide: function () { $('#new_topic').fadeOut('fast'); @@ -3619,6 +3620,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); From 2a9a27c6c517f113f09098447d1d80e8318dd5cd Mon Sep 17 00:00:00 2001 From: Connor Turland Date: Sun, 2 Nov 2014 16:04:53 -0500 Subject: [PATCH 03/32] stops user from creating map with empty name, or topic with empty name. sets max length on topic name. allows enter key to create map --- .../javascripts/src/Metamaps.GlobalUI.js | 33 +++++++++++-------- app/assets/javascripts/src/Metamaps.JIT.js | 10 ++++-- app/assets/stylesheets/application.css | 10 ++++++ app/views/layouts/_newmap.html.erb | 2 +- app/views/shared/_forkmap.html.erb | 2 +- 5 files changed, 40 insertions(+), 17 deletions(-) diff --git a/app/assets/javascripts/src/Metamaps.GlobalUI.js b/app/assets/javascripts/src/Metamaps.GlobalUI.js index c257e4f1..81f0956d 100644 --- a/app/assets/javascripts/src/Metamaps.GlobalUI.js +++ b/app/assets/javascripts/src/Metamaps.GlobalUI.js @@ -221,7 +221,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; @@ -231,23 +231,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 @@ -257,6 +249,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 = $(""); + + $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..4cb4ea26 100644 --- a/app/assets/javascripts/src/Metamaps.JIT.js +++ b/app/assets/javascripts/src/Metamaps.JIT.js @@ -682,10 +682,16 @@ Metamaps.JIT = { $(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 diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index a6e71fed..c58e8698 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -2192,6 +2192,16 @@ and it won't be important on password protected instances */ margin: 15px 0 5px; position: relative; } + +.new_map .feedback_message { + float: right; + width: 388px; + background: #c04f4f; + margin: 5px 1px; + padding: 2px 5px; + border-radius: 2px; + color: #FFF; +} .new_map label { float: left; width: 100px; 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 @@
- <%= form.text_field :name %> + <%= form.text_field :name, :maxlength => 140 %>
diff --git a/app/views/shared/_forkmap.html.erb b/app/views/shared/_forkmap.html.erb index 4f45a647..78a7aec4 100644 --- a/app/views/shared/_forkmap.html.erb +++ b/app/views/shared/_forkmap.html.erb @@ -9,7 +9,7 @@
- <%= form.text_field :name %> + <%= form.text_field :name, :maxlength => 140 %>
From ee1ca7853f5bd4d54b9e3580ebf72a6028288425 Mon Sep 17 00:00:00 2001 From: Connor Turland Date: Mon, 3 Nov 2014 08:46:22 -0500 Subject: [PATCH 04/32] removed embed. fixed switch metacode set lightbox overflow. disabled topic creation and topic deletion from public maps by non-owner --- app/assets/javascripts/src/Metamaps.JIT.js | 84 +++++++++----- app/assets/javascripts/src/Metamaps.js | 123 +++++++++++++++++---- app/assets/stylesheets/application.css | 18 ++- app/assets/stylesheets/base.css | 1 + app/controllers/maps_controller.rb | 29 +---- app/controllers/topics_controller.rb | 8 +- app/views/maps/embed.html.erb | 83 -------------- app/views/shared/_switchmetacodes.html.erb | 16 +-- config/routes.rb | 1 - 9 files changed, 191 insertions(+), 172 deletions(-) delete mode 100644 app/views/maps/embed.html.erb diff --git a/app/assets/javascripts/src/Metamaps.JIT.js b/app/assets/javascripts/src/Metamaps.JIT.js index 4cb4ea26..a83db26e 100644 --- a/app/assets/javascripts/src/Metamaps.JIT.js +++ b/app/assets/javascripts/src/Metamaps.JIT.js @@ -757,6 +757,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 @@ -821,7 +823,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; @@ -886,6 +888,9 @@ Metamaps.JIT = { $(document).trigger(Metamaps.JIT.events.mouseMove, [pos]); } } + 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) { @@ -927,6 +932,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 @@ -967,7 +975,13 @@ 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; + } // DOUBLE CLICK //pop up node creation :) Metamaps.Create.newTopic.addSynapse = false; @@ -1269,12 +1283,16 @@ 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
    • \ @@ -1331,17 +1349,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 () { @@ -1445,11 +1467,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
        • \ @@ -1500,17 +1524,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 () { diff --git a/app/assets/javascripts/src/Metamaps.js b/app/assets/javascripts/src/Metamaps.js index 11594a0a..edae4940 100644 --- a/app/assets/javascripts/src/Metamaps.js +++ b/app/assets/javascripts/src/Metamaps.js @@ -2566,12 +2566,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(); @@ -2579,6 +2589,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]; @@ -2586,6 +2606,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; @@ -2598,33 +2628,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, @@ -2709,6 +2751,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); @@ -2716,6 +2768,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); } @@ -2743,16 +2804,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); } diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index c58e8698..f755a6bc 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -1180,6 +1180,13 @@ h3.realtimeBoxTitle { background-color: #E0E0E0; cursor: pointer; } +.rightclickmenu li.disabled { + opacity: 0.4; +} +.rightclickmenu li.disabled:hover { + background-color: transparent; + cursor: default; +} .rightclickmenu > ul > li .rc-icon { position: absolute; top: 0; @@ -1976,6 +1983,8 @@ and it won't be important on password protected instances */ font-family: 'din-medium', helvetica, sans-serif; color: #424242; font-size: 14px; + text-align: justify; + padding-right: 16px; } #switchMetacodes > p { margin: 16px 0 16px 0; @@ -1990,10 +1999,17 @@ and it won't be important on password protected instances */ #metacodeSwitchTabs li.ui-state-active a { color: #00BCD4; } +.metacodeSwitchTab { + max-height: 300px; + overflow-y: auto; + margin-bottom: 16px; +} +.customMetacodeList { + overflow-y: auto; +} .customMetacodeList, .metacodeSetList { height: 301px; - overflow-y: auto; margin: 5px 0 15px 0; } .customMetacodeList ul li { diff --git a/app/assets/stylesheets/base.css b/app/assets/stylesheets/base.css index 03889a5c..9d058933 100644 --- a/app/assets/stylesheets/base.css +++ b/app/assets/stylesheets/base.css @@ -113,6 +113,7 @@ font-size: 12px; line-height:15px; font-family: helvetica, sans-serif; + overflow-y: scroll; } .CardOnGraph.hasAttachment .scroll { height: auto; diff --git a/app/controllers/maps_controller.rb b/app/controllers/maps_controller.rb index 8975870b..0fbad24b 100644 --- a/app/controllers/maps_controller.rb +++ b/app/controllers/maps_controller.rb @@ -81,8 +81,8 @@ class MapsController < ApplicationController respond_to do |format| format.html { @allmappers = @map.contributors - @alltopics = @map.topics # should limit to topics visible to user - @allsynapses = @map.synapses # should also be limited + @alltopics = @map.topics.delete_if {|t| t.permission == "private" && (!authenticated? || (authenticated? && @current.id != t.user_id)) } + @allsynapses = @map.synapses.delete_if {|s| s.permission == "private" && (!authenticated? || (authenticated? && @current.id != s.user_id)) } @allmappings = @map.mappings respond_with(@allmappers, @allmappings, @allsynapses, @alltopics, @map) @@ -102,8 +102,8 @@ class MapsController < ApplicationController end @allmappers = @map.contributors - @alltopics = @map.topics # should limit to topics visible to user - @allsynapses = @map.synapses # should also be limited + @alltopics = @map.topics.delete_if {|t| t.permission == "private" && (!authenticated? || (authenticated? && @current.id != t.user_id)) } + @allsynapses = @map.synapses.delete_if {|s| s.permission == "private" && (!authenticated? || (authenticated? && @current.id != s.user_id)) } @allmappings = @map.mappings @json = Hash.new() @@ -118,27 +118,6 @@ class MapsController < ApplicationController end end - - # GET maps/:id/embed - def embed - @current = current_user - @map = Map.find(params[:id]).authorize_to_show(@current) - - if not @map - redirect_to root_url and return - end - - @alltopics = @map.topics # should limit to topics visible to user - @allsynapses = @map.synapses # should also be limited - @allmappings = @map.mappings - @allmetacodes = Metacode.all - - respond_to do |format| - format.html { respond_with(@allmetacodes, @allmappings, @allsynapses, @alltopics, @map, @user) } - format.json { render json: @map } - end - end - # POST maps def create diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb index c2690756..e63bdc04 100644 --- a/app/controllers/topics_controller.rb +++ b/app/controllers/topics_controller.rb @@ -34,8 +34,8 @@ class TopicsController < ApplicationController respond_to do |format| format.html { - @alltopics = [@topic] + @topic.relatives # should limit to topics visible to user - @allsynapses = @topic.synapses # should also be limited + @alltopics = ([@topic] + @topic.relatives).delete_if {|t| t.permission == "private" && (!authenticated? || (authenticated? && @current.id != t.user_id)) } # should limit to topics visible to user + @allsynapses = @topic.synapses.delete_if {|s| s.permission == "private" && (!authenticated? || (authenticated? && @current.id != s.user_id)) } respond_with(@allsynapses, @alltopics, @topic) } @@ -52,8 +52,8 @@ class TopicsController < ApplicationController redirect_to root_url and return end - @alltopics = @topic.relatives # should limit to topics visible to user - @allsynapses = @topic.synapses # should also be limited + @alltopics = @topic.relatives.delete_if {|t| t.permission == "private" && (!authenticated? || (authenticated? && @current.id != t.user_id)) } + @allsynapses = @topic.synapses.delete_if {|s| s.permission == "private" && (!authenticated? || (authenticated? && @current.id != s.user_id)) } @json = Hash.new() @json['topic'] = @topic diff --git a/app/views/maps/embed.html.erb b/app/views/maps/embed.html.erb deleted file mode 100644 index de875ae2..00000000 --- a/app/views/maps/embed.html.erb +++ /dev/null @@ -1,83 +0,0 @@ -<%# -# @file -# Code to display a map -# /maps/:id -#%> - -<% content_for :title, @map.name + " | Metamaps" %> - -
          - -
          - - -<% if authenticated? %> -
          -
          -
          -
          -
          -<% if @map.permission == "commons" || @map.user == user %> -
          -
          -
          -

          Realtime:

          - ON -
          -
          -
            -
          • - <%= user.name %> (me) -
          • -
          -
          -
          -
          -<% end %> -<% end %> -
          -
          -
          -

          Filter By Metacode

          allnone -
          - <%= render :partial => 'shared/filterbymetacode' %> -
          -
          - -
          -
          - -
          - <%= render :partial => 'maps/mapinfobox' %> -
          - -
          -
          -
          -
          -
          -
          -
          - -<% if authenticated? %> - -<% # add these if you have edit permissions on the map %> -<% if @map.permission == "commons" || @map.user == user %> -<% # for creating and pulling in topics and synapses %> -<%= render :partial => 'newtopic' %> -<%= render :partial => 'newsynapse' %> -<% end %> - -<% # for populating the change metacode list on the topic card %> -<%= render :partial => 'shared/metacodeoptions' %> -<% end %> - - - \ No newline at end of file diff --git a/app/views/shared/_switchmetacodes.html.erb b/app/views/shared/_switchmetacodes.html.erb index bca2f101..fb3962ef 100644 --- a/app/views/shared/_switchmetacodes.html.erb +++ b/app/views/shared/_switchmetacodes.html.erb @@ -24,18 +24,20 @@
        • CUSTOM SELECTION
        <% allMetacodeSets.each_with_index do |m, localindex| %> -
        <% @list = '' %> <% m.metacodes.sort{|x,y| x.name <=> y.name }.each_with_index do |m, index| %> <% @list += '
      • ' + m.name + '

        ' + m.name.downcase + '

      • ' %> <% end %> -

        <%= m.desc %>

        -
        -
          - <%= @list.html_safe %> -
        -
        +
        +

        <%= m.desc %>

        +
        +
          + <%= @list.html_safe %> +
        +
        +
        Oops, don't change password
        - <%= form.submit "Update", class: "update" %> +
        + <%= form.submit "Update", class: "update", onclick: "Metamaps.Account.showLoading()" %> <% end %> From 28fb9a8bae2143c281e8fcb7e5cebbe234519b20 Mon Sep 17 00:00:00 2001 From: Connor Turland Date: Tue, 4 Nov 2014 08:52:45 -0500 Subject: [PATCH 08/32] little fix for profile picture uploading --- app/assets/javascripts/src/Metamaps.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/src/Metamaps.js b/app/assets/javascripts/src/Metamaps.js index fd1b817b..87d6e020 100644 --- a/app/assets/javascripts/src/Metamaps.js +++ b/app/assets/javascripts/src/Metamaps.js @@ -4456,6 +4456,7 @@ Metamaps.Account = { var imageObj = new Image(); imageObj.onload = function() { + $('.userImageDiv canvas').remove(); $('.userImageDiv img').hide(); var imgWidth = imageObj.width; @@ -4491,7 +4492,7 @@ Metamaps.Account = { var self = Metamaps.Account; $('.userImageDiv canvas').remove(); - $('.userImage img').attr('src', '/assets/user.png').show(); + $('.userImageDiv img').attr('src', '/assets/user.png').show(); $('.userImageMenu').hide(); var input = $('#user_image'); From c5907914e3b855d7176d4d279e4e1cfb56e5f409 Mon Sep 17 00:00:00 2001 From: Connor Turland Date: Tue, 4 Nov 2014 12:37:17 -0500 Subject: [PATCH 09/32] fixed user images, set up map updates for realtime --- .../javascripts/src/Metamaps.Backbone.js | 52 +++++++++++- app/assets/javascripts/src/Metamaps.js | 83 +++++++++++++++---- app/helpers/users_helper.rb | 2 +- app/models/user.rb | 17 +--- app/views/layouts/_account.html.erb | 2 +- app/views/layouts/_upperelements.html.erb | 4 +- app/views/maps/_mapinfobox.html.erb | 6 +- app/views/shared/_filterBox.html.erb | 2 +- app/views/users/edit.html.erb | 2 +- 9 files changed, 130 insertions(+), 40 deletions(-) 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.js b/app/assets/javascripts/src/Metamaps.js index 87d6e020..afddbd4d 100644 --- a/app/assets/javascripts/src/Metamaps.js +++ b/app/assets/javascripts/src/Metamaps.js @@ -1835,11 +1835,15 @@ Metamaps.Realtime = { if (Metamaps.Active.Map) { 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 () { @@ -1872,11 +1876,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"); @@ -1934,7 +1938,7 @@ 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) { @@ -1993,6 +1997,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; @@ -2334,18 +2344,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) { @@ -4084,6 +4108,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); @@ -4292,11 +4336,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 @@ -4304,6 +4353,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; @@ -4364,6 +4418,7 @@ Metamaps.Map.InfoBox = { Metamaps.Active.Map.save({ permission: permission }); + Metamaps.Active.Map.updateMapWrapper(); shareable = permission === 'private' ? '' : 'shareable'; $('.mapPermission').removeClass('commons public private minimize').addClass(permission); $('.mapPermission .permissionSelect').remove(); diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index 27d6f8e7..097ecdfb 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -8,7 +8,7 @@ module UsersHelper user['id'] = u.id user['label'] = u.name user['value'] = u.name - user['profile'] = u.image.url(:thumb) + user['profile'] = u.image.url(:square) user['mapCount'] = u.maps.count user['created_at'] = u.created_at.strftime("%m/%d/%Y") user['rtype'] = "mapper" diff --git a/app/models/user.rb b/app/models/user.rb index adea25db..f0c1345f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -37,30 +37,17 @@ class User < ActiveRecord::Base # This method associates the attribute ":image" with a file attachment has_attached_file :image, :styles => { - :thumb => ['100x100>', :png], - :square => ['200x200#', :png], - :round => ['200x200#', :png] + :square => ['84x84#', :png] }, :default_url => "/assets/user.png" - #, :convert_options => {:round => Proc.new{self.convert_options}} - # Validate the attached image is image/jpg, image/png, etc validates_attachment_content_type :image, :content_type => /\Aimage\/.*\Z/ - - def self.convert_options - trans = '' - trans << ' ( +clone -alpha extract ' - trans << '-draw "fill black polygon 0,0 0,100 100,0 fill white circle 100,100 100,0" ' - trans << '( +clone -flip ) -compose multiply -composite ' - trans << '( +clone -flop ) -compose multiply -composite ' - trans << ') -alpha off -compose copy_opacity -composite ' - end def as_json(options={}) { :id => self.id, :name => self.name, - :image => self.image.url + :image => self.image.url(:square) } end diff --git a/app/views/layouts/_account.html.erb b/app/views/layouts/_account.html.erb index ffe69b7e..b48cde3d 100644 --- a/app/views/layouts/_account.html.erb +++ b/app/views/layouts/_account.html.erb @@ -5,7 +5,7 @@ <% if authenticated? %> <% account = current_user %> - <%= image_tag user.image.url(:thumb), :size => "48x48", :class => "sidebarAccountImage" %> + <%= image_tag user.image.url(:square), :size => "48x48", :class => "sidebarAccountImage" %>

        <%= account.name.split[0...1][0] %>

        • diff --git a/app/views/layouts/_upperelements.html.erb b/app/views/layouts/_upperelements.html.erb index 07aea898..a793fa70 100644 --- a/app/views/layouts/_upperelements.html.erb +++ b/app/views/layouts/_upperelements.html.erb @@ -31,7 +31,7 @@
          • - <%= image_tag user.image.url(:thumb), :size => "24x24", :class => "rtUserImage" %> + <%= image_tag user.image.url(:square), :size => "24x24", :class => "rtUserImage" %> <%= user.name %> (me)
          • @@ -70,7 +70,7 @@
            <% if user && user.image %> - <%= image_tag user.image.url(:thumb), :size => "32x32" %> + <%= image_tag user.image.url(:square), :size => "32x32" %> <% elsif !authenticated? %> SIGN IN
            diff --git a/app/views/maps/_mapinfobox.html.erb b/app/views/maps/_mapinfobox.html.erb index c628e084..4989f1c2 100644 --- a/app/views/maps/_mapinfobox.html.erb +++ b/app/views/maps/_mapinfobox.html.erb @@ -15,11 +15,11 @@ <% if @map.contributors.count == 0 %> <% elsif @map.contributors.count == 1 %> - + <% elsif @map.contributors.count == 2 %> - + <% elsif @map.contributors.count > 2 %> - + <% end %> <%= @map.contributors.count %> <% contributorList = '' diff --git a/app/views/shared/_filterBox.html.erb b/app/views/shared/_filterBox.html.erb index e3a633c1..02f69477 100644 --- a/app/views/shared/_filterBox.html.erb +++ b/app/views/shared/_filterBox.html.erb @@ -62,7 +62,7 @@ end @mappers.each_with_index do |mapper, index| @mapperlist += '
          • ' - @mapperlist += '' + mapper.name + '' + @mapperlist += '' + mapper.name + '' @mapperlist += '

            ' + mapper.name + '

          • ' end end diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb index 45904d68..f02903af 100644 --- a/app/views/users/edit.html.erb +++ b/app/views/users/edit.html.erb @@ -10,7 +10,7 @@

            Edit Account

            - <%= image_tag @user.image.url(:round), :size => "84x84" %> + <%= image_tag @user.image.url(:square), :size => "84x84" %>
            From 2bbe2b8eff82eaa88f6483d8ad273dea95381c81 Mon Sep 17 00:00:00 2001 From: Connor Turland Date: Tue, 4 Nov 2014 21:27:40 -0500 Subject: [PATCH 10/32] improvements to realtime --- app/assets/javascripts/src/Metamaps.JIT.js | 7 ------ app/assets/javascripts/src/Metamaps.js | 27 ++++++++++++++++++---- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/app/assets/javascripts/src/Metamaps.JIT.js b/app/assets/javascripts/src/Metamaps.JIT.js index a83db26e..4baca560 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', @@ -677,9 +676,6 @@ 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; @@ -781,7 +777,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; @@ -813,7 +808,6 @@ Metamaps.JIT = { if (Metamaps.Active.Map) { $(document).trigger(Metamaps.JIT.events.topicDrag, [positionsToSend]); - $(document).trigger(Metamaps.JIT.events.mouseMove, [pos]); } } //if @@ -885,7 +879,6 @@ 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) && !authorized) { diff --git a/app/assets/javascripts/src/Metamaps.js b/app/assets/javascripts/src/Metamaps.js index afddbd4d..ab02eb02 100644 --- a/app/assets/javascripts/src/Metamaps.js +++ b/app/assets/javascripts/src/Metamaps.js @@ -1781,8 +1781,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){ @@ -1849,7 +1852,7 @@ Metamaps.Realtime = { endActiveMap: function () { var self = Metamaps.Realtime; - $(document).off(Metamaps.JIT.events.mouseMove); + $(document).off('mousemove'); self.socket.removeAllListeners(); self.socket.emit('endMapperNotify'); $(".collabCompass").remove(); @@ -1941,10 +1944,15 @@ Metamaps.Realtime = { 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) { @@ -2087,7 +2095,7 @@ 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 += data.username; @@ -4415,10 +4423,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(); From 3b2e23b1e04d1a164d4adc18987eceaf6fa46dc2 Mon Sep 17 00:00:00 2001 From: Connor Turland Date: Wed, 5 Nov 2014 10:09:37 -0500 Subject: [PATCH 11/32] removed flicker from topic creation --- app/assets/javascripts/src/Metamaps.js | 40 ++++++++++++++------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/app/assets/javascripts/src/Metamaps.js b/app/assets/javascripts/src/Metamaps.js index ab02eb02..105ee23f 100644 --- a/app/assets/javascripts/src/Metamaps.js +++ b/app/assets/javascripts/src/Metamaps.js @@ -1705,17 +1705,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 () { @@ -3633,14 +3642,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"); From 0b7702062fb4aa5d704ab0f78a419fec86301cec Mon Sep 17 00:00:00 2001 From: Connor Turland Date: Wed, 5 Nov 2014 11:01:18 -0500 Subject: [PATCH 12/32] added little link icon next to metacode to indicate a link within a topic --- app/assets/javascripts/src/Metamaps.JIT.js | 16 ++++++++++++++++ app/assets/javascripts/src/Metamaps.js | 6 ++++-- app/assets/stylesheets/application.css | 9 +++++++-- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/src/Metamaps.JIT.js b/app/assets/javascripts/src/Metamaps.JIT.js index 4baca560..eb8ebe1f 100644 --- a/app/assets/javascripts/src/Metamaps.JIT.js +++ b/app/assets/javascripts/src/Metamaps.JIT.js @@ -21,6 +21,12 @@ Metamaps.JIT = { $(".zoomIn").click(self.zoomIn); $(".zoomOut").click(self.zoomOut); $(".zoomExtents").click(self.zoomExtents); + + self.synapseStarImage = new Image(); + self.synapseStarImage.src = '/assets/synapsestar.png'; + + self.topicMediaImage = new Image(); + self.topicMediaImage.src = '/assets/linkedmedia.png'; }, /** * convert our topic JSON into something JIT can use @@ -446,6 +452,16 @@ 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.get('link') !== "" && topic.get('link') !== null; + var linkImage = Metamaps.JIT.topicMediaImage; + var linkImageLoaded = linkImage.complete || + (typeof linkImage.naturalWidth !== "undefined" && + linkImage.naturalWidth !== 0) + if (hasLink && linkImageLoaded) { + ctx.drawImage(linkImage, pos.x + dim / 2, pos.y - dim - 8, 16, 16); + } }, 'contains': function (node, pos) { var npos = node.pos.getc(true), diff --git a/app/assets/javascripts/src/Metamaps.js b/app/assets/javascripts/src/Metamaps.js index 105ee23f..6ba3a80f 100644 --- a/app/assets/javascripts/src/Metamaps.js +++ b/app/assets/javascripts/src/Metamaps.js @@ -2070,7 +2070,8 @@ Metamaps.Realtime = { mapperListItem += '" class="rtMapper littleRt'; mapperListItem += onOff; mapperListItem += '">'; - mapperListItem += ''; + mapperListItem += ''; mapperListItem += data.username; mapperListItem += '
            '; mapperListItem += '
          • '; @@ -2106,7 +2107,8 @@ Metamaps.Realtime = { // create an item for them in the realtime box if (data.userid !== Metamaps.Active.Mapper.id && self.status) { var mapperListItem = '
          • '; - mapperListItem += ''; + mapperListItem += ''; mapperListItem += data.username; mapperListItem += '
            '; mapperListItem += '
          • '; diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 89d879d7..e925ad4c 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -1118,7 +1118,7 @@ h3.realtimeBoxTitle { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - padding: 9px 32px; + padding: 10px 34px; display: block; height: 14px; font-family: 'din-regular', helvetica, sans-serif; @@ -1126,11 +1126,16 @@ h3.realtimeBoxTitle { line-height: 14px; position: relative; } + +.rtMapperSelf img { + border: 2px solid #424242; +} + .rtUserImage { position: absolute; top: 4px; left: 0; - border-radius: 12px; + border-radius: 14px; } .littleJuntoIcon { width: 24px; From 4d63e643239a97f13820fd441b43aebb27656d95 Mon Sep 17 00:00:00 2001 From: Bashar Jabbour Date: Wed, 5 Nov 2014 11:35:40 -0500 Subject: [PATCH 13/32] Update MacInstallation.md --- MacInstallation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MacInstallation.md b/MacInstallation.md index c2b9d80d..1e999b30 100644 --- a/MacInstallation.md +++ b/MacInstallation.md @@ -6,7 +6,7 @@ install homebrew rvm install 1.9.3 --with-gcc=clang - rvm use 1.9.3 + rvm use 2.1.3 gem install lunchy From b7ecf4ca8ce6560cda1e046a45060e23cb7dfe3a Mon Sep 17 00:00:00 2001 From: Connor Turland Date: Wed, 5 Nov 2014 11:41:26 -0500 Subject: [PATCH 14/32] added star to edges to indicate that there's multiple synapses there --- app/assets/javascripts/src/Metamaps.JIT.js | 80 +++++++--------------- 1 file changed, 24 insertions(+), 56 deletions(-) diff --git a/app/assets/javascripts/src/Metamaps.JIT.js b/app/assets/javascripts/src/Metamaps.JIT.js index eb8ebe1f..d039b145 100644 --- a/app/assets/javascripts/src/Metamaps.JIT.js +++ b/app/assets/javascripts/src/Metamaps.JIT.js @@ -130,6 +130,16 @@ Metamaps.JIT = { var showDesc = adj.getData("showDesc"); + var drawStar = function (context, x, y) { + var starImage = Metamaps.JIT.synapseStarImage; + var starImageLoaded = starImage.complete || + (typeof starImage.naturalWidth !== "undefined" && + starImage.naturalWidth !== 0) + if (starImageLoaded) { + context.drawImage(starImage, x, y, 16, 16); + } + }; + if (desc != "" && showDesc) { // '&' to '&' desc = Metamaps.Util.decodeEntities(desc); @@ -150,6 +160,7 @@ Metamaps.JIT = { var x = (pos.x + posChild.x - width) / 2; var y = ((pos.y + posChild.y) / 2) - height / 2; + var radius = 5; //render background @@ -172,64 +183,21 @@ Metamaps.JIT = { for (index = 0; index < arrayOfLabelLines.length; ++index) { ctx.fillText(arrayOfLabelLines[index], x + (width / 2), y + 5 + (16 * index)); } + + if (adj.getData("synapses").length > 1) { + drawStar(ctx, x + width, y); + } } + else if (showDesc) { + if (adj.getData("synapses").length > 1) { + var ctx = canvas.getCtx(); + var x = (pos.x + posChild.x) / 2; + var y = (pos.y + posChild.y) / 2; + drawStar(ctx, x, y); + } + } + }, // 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'], From ff1dbafe3dc8b3187d9af88886b6c8fc52ca150e Mon Sep 17 00:00:00 2001 From: Bashar Jabbour Date: Wed, 5 Nov 2014 11:48:28 -0500 Subject: [PATCH 15/32] Update MacInstallation.md --- MacInstallation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MacInstallation.md b/MacInstallation.md index 1e999b30..2d36494e 100644 --- a/MacInstallation.md +++ b/MacInstallation.md @@ -4,7 +4,7 @@ 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 2.1.3 From 7193d2a3865c2e75a6bd775d50cec8baf3e1e09d Mon Sep 17 00:00:00 2001 From: Connor Turland Date: Wed, 5 Nov 2014 13:26:14 -0500 Subject: [PATCH 16/32] fixed small render node issue --- app/assets/javascripts/src/JIT.js | 9 ++++++--- app/assets/javascripts/src/Metamaps.JIT.js | 2 +- app/assets/javascripts/src/Metamaps.js | 6 +++--- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/src/JIT.js b/app/assets/javascripts/src/JIT.js index 7483a544..bd8c1565 100644 --- a/app/assets/javascripts/src/JIT.js +++ b/app/assets/javascripts/src/JIT.js @@ -2478,6 +2478,7 @@ Extras.Classes.Navigation = new Class({ jQuery(document).trigger(Metamaps.JIT.events.zoom, [e]); // END METAMAPS CODE + console.log('zooming'); }, onMouseDown: function(e, win, eventInfo) { @@ -7427,6 +7428,7 @@ Graph.Label.Native = new Class({ (end code) */ plotLabel: function(canvas, node, controller) { + /* var ctx = canvas.getCtx(); var pos = node.pos.getc(true); @@ -7437,7 +7439,8 @@ Graph.Label.Native = new Class({ //START METAMAPS CODE - var arrayOfLabelLines = Metamaps.Util.splitLine(node.name,30).split('\n'); + //var arrayOfLabelLines = Metamaps.Util.splitLine(node.name,30).split('\n'); + var arrayOfLabelLines = ["something", "something"]; //render background ctx.fillStyle = ctx.strokeStyle = Metamaps.Settings.colors.labels.background; ctx.lineWidth = 2; @@ -7466,9 +7469,9 @@ Graph.Label.Native = new Class({ ctx.fill(); //ctx.stroke(); - ctx.fillStyle = ctx.strokeStyle = node.getLabelData('color'); + ctx.fillStyle = ctx.strokeStyle = node.getLabelData('color');*/ - this.renderLabel(arrayOfLabelLines, canvas, node, controller); + //this.renderLabel(arrayOfLabelLines, canvas, node, controller); // END METAMAPS CODE // ORIGINAL CODE this.renderLabel(canvas, node, controller); }, diff --git a/app/assets/javascripts/src/Metamaps.JIT.js b/app/assets/javascripts/src/Metamaps.JIT.js index d039b145..faf895f2 100644 --- a/app/assets/javascripts/src/Metamaps.JIT.js +++ b/app/assets/javascripts/src/Metamaps.JIT.js @@ -422,7 +422,7 @@ Metamaps.JIT = { } // if the topic has a link, draw a small image to indicate that - var hasLink = topic.get('link') !== "" && topic.get('link') !== null; + var hasLink = topic && topic.get('link') !== "" && topic.get('link') !== null; var linkImage = Metamaps.JIT.topicMediaImage; var linkImageLoaded = linkImage.complete || (typeof linkImage.naturalWidth !== "undefined" && diff --git a/app/assets/javascripts/src/Metamaps.js b/app/assets/javascripts/src/Metamaps.js index 6ba3a80f..2543f0df 100644 --- a/app/assets/javascripts/src/Metamaps.js +++ b/app/assets/javascripts/src/Metamaps.js @@ -1845,7 +1845,7 @@ 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'; @@ -3645,7 +3645,7 @@ Metamaps.Topic = { if (!$.isEmptyObject(Metamaps.Visualize.mGraph.graph.nodes)) { Metamaps.Visualize.mGraph.graph.addNode(newnode); nodeOnViz = Metamaps.Visualize.mGraph.graph.getNode(newnode.id); - topic.set('node', nodeOnViz, {silent: true}); // + topic.set('node', nodeOnViz, {silent: true}); topic.updateNode(); // links the topic and the mapping to the node nodeOnViz.setData("dim", 1, "start"); @@ -3694,7 +3694,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"); From dc4392ee950dcfd4764a774e6462f02fd7fe5249 Mon Sep 17 00:00:00 2001 From: Connor Turland Date: Wed, 5 Nov 2014 14:41:49 -0500 Subject: [PATCH 17/32] trying requestAnimationFrame --- app/assets/javascripts/src/JIT.js | 70 ++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 11 deletions(-) diff --git a/app/assets/javascripts/src/JIT.js b/app/assets/javascripts/src/JIT.js index bd8c1565..faf1a8b1 100644 --- a/app/assets/javascripts/src/JIT.js +++ b/app/assets/javascripts/src/JIT.js @@ -1,3 +1,6 @@ + +var requestAnimId; + /* Copyright (c) 2011 Sencha Inc. - Author: Nicolas Garcia Belmonte (http://philogb.github.com/) @@ -2477,8 +2480,6 @@ Extras.Classes.Navigation = new Class({ // START METAMAPS CODE jQuery(document).trigger(Metamaps.JIT.events.zoom, [e]); // END METAMAPS CODE - - console.log('zooming'); }, onMouseDown: function(e, win, eventInfo) { @@ -7098,8 +7099,8 @@ Graph.Plot = { ctx.restore(); } //END METAMAPS CODE - - aGraph.eachNode(function(node) { + + function plot(node) { var nodeAlpha = node.getData('alpha'); node.eachAdjacency(function(adj) { var nodeTo = adj.nodeTo; @@ -7122,7 +7123,55 @@ Graph.Plot = { } } node.visited = !T; - }); + } + + function stop() { + cancelAnimationFrame(requestAnimId); + } + stop(); // cancels any previous plot calls + + var i = 0; + var length = aGraph.nodes.length; + var keys = _.keys(aGraph.nodes); + function eachNode() { + var key = keys[i]; + var node = aGraph.nodes[key]; + + if (node) { + i += 1; + requestAnimId = requestAnimationFrame(eachNode); + plot(node); + } + else { + stop(); + } + } + + requestAnimId = requestAnimationFrame(eachNode); + /*aGraph.eachNode(function(node) { + var nodeAlpha = node.getData('alpha'); + node.eachAdjacency(function(adj) { + var nodeTo = adj.nodeTo; + if(!!nodeTo.visited === T && node.drawn && nodeTo.drawn) { + !animating && opt.onBeforePlotLine(adj); + that.plotLine(adj, canvas, animating); + !animating && opt.onAfterPlotLine(adj); + } + }); + if(node.drawn) { + !animating && opt.onBeforePlotNode(node); + that.plotNode(node, canvas, animating); + !animating && opt.onAfterPlotNode(node); + } + if(!that.labelsHidden && opt.withLabels) { + if(node.drawn && nodeAlpha >= 0.95) { + that.labels.plotLabel(canvas, node, opt); + } else { + that.labels.hideLabel(node, false); + } + } + node.visited = !T; + });*/ }, /* @@ -7428,7 +7477,7 @@ Graph.Label.Native = new Class({ (end code) */ plotLabel: function(canvas, node, controller) { - /* + var ctx = canvas.getCtx(); var pos = node.pos.getc(true); @@ -7439,8 +7488,7 @@ Graph.Label.Native = new Class({ //START METAMAPS CODE - //var arrayOfLabelLines = Metamaps.Util.splitLine(node.name,30).split('\n'); - var arrayOfLabelLines = ["something", "something"]; + var arrayOfLabelLines = Metamaps.Util.splitLine(node.name,30).split('\n'); //render background ctx.fillStyle = ctx.strokeStyle = Metamaps.Settings.colors.labels.background; ctx.lineWidth = 2; @@ -7469,9 +7517,9 @@ Graph.Label.Native = new Class({ ctx.fill(); //ctx.stroke(); - ctx.fillStyle = ctx.strokeStyle = node.getLabelData('color');*/ + ctx.fillStyle = ctx.strokeStyle = node.getLabelData('color'); - //this.renderLabel(arrayOfLabelLines, canvas, node, controller); + this.renderLabel(arrayOfLabelLines, canvas, node, controller); // END METAMAPS CODE // ORIGINAL CODE this.renderLabel(canvas, node, controller); }, @@ -7496,7 +7544,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 }, From 22695e53b809125c60f9a6d5ed820a64409aeaea Mon Sep 17 00:00:00 2001 From: Connor Turland Date: Wed, 5 Nov 2014 15:47:43 -0500 Subject: [PATCH 18/32] restored graph plotting to normal --- app/assets/javascripts/src/JIT.js | 52 ++----------------------------- 1 file changed, 2 insertions(+), 50 deletions(-) diff --git a/app/assets/javascripts/src/JIT.js b/app/assets/javascripts/src/JIT.js index faf1a8b1..743a7eef 100644 --- a/app/assets/javascripts/src/JIT.js +++ b/app/assets/javascripts/src/JIT.js @@ -7100,7 +7100,7 @@ Graph.Plot = { } //END METAMAPS CODE - function plot(node) { + aGraph.eachNode(function(node) { var nodeAlpha = node.getData('alpha'); node.eachAdjacency(function(adj) { var nodeTo = adj.nodeTo; @@ -7123,55 +7123,7 @@ Graph.Plot = { } } node.visited = !T; - } - - function stop() { - cancelAnimationFrame(requestAnimId); - } - stop(); // cancels any previous plot calls - - var i = 0; - var length = aGraph.nodes.length; - var keys = _.keys(aGraph.nodes); - function eachNode() { - var key = keys[i]; - var node = aGraph.nodes[key]; - - if (node) { - i += 1; - requestAnimId = requestAnimationFrame(eachNode); - plot(node); - } - else { - stop(); - } - } - - requestAnimId = requestAnimationFrame(eachNode); - /*aGraph.eachNode(function(node) { - var nodeAlpha = node.getData('alpha'); - node.eachAdjacency(function(adj) { - var nodeTo = adj.nodeTo; - if(!!nodeTo.visited === T && node.drawn && nodeTo.drawn) { - !animating && opt.onBeforePlotLine(adj); - that.plotLine(adj, canvas, animating); - !animating && opt.onAfterPlotLine(adj); - } - }); - if(node.drawn) { - !animating && opt.onBeforePlotNode(node); - that.plotNode(node, canvas, animating); - !animating && opt.onAfterPlotNode(node); - } - if(!that.labelsHidden && opt.withLabels) { - if(node.drawn && nodeAlpha >= 0.95) { - that.labels.plotLabel(canvas, node, opt); - } else { - that.labels.hideLabel(node, false); - } - } - node.visited = !T; - });*/ + }); }, /* From af65f8cb47d71af540b2a66825a0c87ecdcdd625 Mon Sep 17 00:00:00 2001 From: Connor Turland Date: Wed, 5 Nov 2014 16:25:10 -0500 Subject: [PATCH 19/32] reset JIT for working with chrome and safari --- app/assets/javascripts/src/JIT.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/assets/javascripts/src/JIT.js b/app/assets/javascripts/src/JIT.js index 743a7eef..498183ef 100644 --- a/app/assets/javascripts/src/JIT.js +++ b/app/assets/javascripts/src/JIT.js @@ -1,6 +1,3 @@ - -var requestAnimId; - /* Copyright (c) 2011 Sencha Inc. - Author: Nicolas Garcia Belmonte (http://philogb.github.com/) From ea689f182c7d51cdcb59485911c908362027c102 Mon Sep 17 00:00:00 2001 From: poietic Date: Thu, 6 Nov 2014 12:42:26 -0800 Subject: [PATCH 20/32] added Donate lightbox! more content changes of about, get involved sections --- app/views/layouts/_lightboxes.html.erb | 73 ++++++++++++++++---------- public/famous/templates.js | 2 +- 2 files changed, 47 insertions(+), 28 deletions(-) diff --git a/app/views/layouts/_lightboxes.html.erb b/app/views/layouts/_lightboxes.html.erb index c4a24a68..e745bcd9 100644 --- a/app/views/layouts/_lightboxes.html.erb +++ b/app/views/layouts/_lightboxes.html.erb @@ -26,11 +26,11 @@
            -

            Metamaps.cc is a free and open source web platform for changemakers, innovators, educators and students. It enables individuals and communities to build and visualize their shared knowledge and unlock their collective intelligence.

            +

            Metamaps.cc is a free and open source web platform that supports real-time sense-making and distributed collaboration between individuals, communities and organizations.

            -

            We're creating tools to help connect people, resources and ideas with rich detail and weave those relationships into actionable insights and stories. The platform is evolving for a range of applications amidst a growing network of designers, developers, practitioners, entrepreneurs, and artists.

            +

            Using an intuitive graph-based interface, Metamaps.cc helps map out networks of people, ideas, resources, stories, experiences, conversations and much more. The platform is evolving for a range of applications amidst a growing network of designers, developers, facilitators, practitioners, entrepreneurs, and artists.

            -

            Metamaps.cc is created and maintained by a distributed, nomadic community comprised of technologists, artists and storytellers. We are currently based between San Francisco, CA and Waterloo, Ontario, Canada. Learn more in the PAQ link below.

            +

            Metamaps.cc is created and maintained by a distributed community of contributors passionate about the evolution of collaboration, alternative forms of value creation and increase of collective intelligence through the lens of the open culture and the peer-to-peer revolution.

            +

            GET INVOLVED!

            -
            +

            Want to help us with design, code, community building, and communications for Metamaps? We're an open value network, which for us means we want to invite and empower peers to participate in creating value together. @@ -206,8 +207,6 @@

            Thanks for your interest in helping out with Metamaps! Hopefully this gets you pointed in the right direction to get involved. The next step is to read the links on this page and then contribute!

            -
            -
            diff --git a/public/famous/templates.js b/public/famous/templates.js index 3575e354..d38b0edc 100644 --- a/public/famous/templates.js +++ b/public/famous/templates.js @@ -6,7 +6,7 @@ t.logoContent = ''; t.logoContent += ''; From 4437270a6b1c44da5315bbfc4725381832e11577 Mon Sep 17 00:00:00 2001 From: poietic Date: Sat, 8 Nov 2014 21:52:46 -0800 Subject: [PATCH 22/32] misc css tweaks --- app/assets/images/synapse32padded.png | Bin 0 -> 423 bytes app/assets/stylesheets/application.css | 27 +++++++++++++------------ app/assets/stylesheets/base.css | 21 +++++++++++-------- app/assets/stylesheets/clean.css | 6 +++--- 4 files changed, 30 insertions(+), 24 deletions(-) create mode 100644 app/assets/images/synapse32padded.png diff --git a/app/assets/images/synapse32padded.png b/app/assets/images/synapse32padded.png new file mode 100644 index 0000000000000000000000000000000000000000..09e52fc03acc054b8a8a1160e0a3f4d29a201ff4 GIT binary patch literal 423 zcmV;Y0a*TtP)I9CUVFEVL5g5TXxrYlmq`ltp zVEB`UaG+oR-nGUcnDx)fvg|zePUI1OrMwq;0LO4acn-0eGyw&FLZlG4rfEK7p9vkp zQw@%)C))xI9;+pidnXkD_@)OZyB8+_@WKEmyB8&(;HFlqIo}frdb}_^V!5}fzz;av zJ!)au<0hf=dw&rsauRO=0gg%_D($|5D8&^}J^oMtst~>f_pRs*Xaj}=Z>ezV7VLZX zJBZ^5ymNjCwW_=aD)Pc)IdJwIP{St~=>O7Yrf}y#Wmvn|!dVpCMZ-(0Y R0mJ|R002ovPDHLkV1n=$sV4vc literal 0 HcmV?d00001 diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index e925ad4c..259e8232 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -519,19 +519,19 @@ input[type="submit"]:active { #new_topic .twitter-typeahead { position: absolute !important; - top: 40px; - left: 35px; + top: 45px; + left: 41px; z-index: 9999; - width: 270px; + width: 256px; height: 42px; } .new_topic #topic_name, .new_topic .tt-hint { - width: 254px; + width: 244px; background: #FFFFFF; height: 14px; margin: 0; - padding: 14px 8px; + padding: 10px 6px; border: none; border-radius: 2px; outline: none; @@ -581,11 +581,11 @@ input[type="submit"]:active { } .new_synapse #synapse_desc, .new_synapse .tt-hint { - width: 254px; + width: 244px; background: #FFFFFF; height: 14px; margin: 0; - padding: 14px 8px; + padding: 10px 6px; border: none; border-radius: 2px; outline: none; @@ -1170,8 +1170,9 @@ h3.realtimeBoxTitle { .rightclickmenu { position: absolute; - width: 300px; + width: 260px; background: #FFFFFF; + padding: 6px 0px 6px 0px; z-index: 20; border-radius: 2px; color: black; @@ -1184,8 +1185,8 @@ h3.realtimeBoxTitle { list-style: none; padding: 6px 10px 6px 32px; font-family: helvetica, sans-serif; - font-size: 12px; - line-height: 12px; + font-size: 13px; + line-height: 15px; position: relative; } .rightclickmenu li:hover { @@ -1337,7 +1338,7 @@ float: left; #new_topic .tt-suggestion, #new_synapse .tt-suggestion { background: #F5F5F5; - width: 270px; + width: 256px; position: relative; } #new_topic .autocompleteSection { @@ -1606,7 +1607,7 @@ float: left; background-position: 13px center; } .mapSynapses { - background-image: url(synapse32.png); + background-image: url(synapse32padded.png); background-position: 13px center; } .mapInfoBox .mapPermission { @@ -1671,7 +1672,7 @@ float: left; .mapInfoBox .mapInfoDesc { font-family: helvetica, sans-serif; color: #E0E0E0; - margin: 8px; + margin: 16px; padding-right: 16px; height: 115px; font-size: 14px; diff --git a/app/assets/stylesheets/base.css b/app/assets/stylesheets/base.css index 6cfa3d69..b894b317 100644 --- a/app/assets/stylesheets/base.css +++ b/app/assets/stylesheets/base.css @@ -110,7 +110,7 @@ display:block; padding: 8px 0 8px 16px; height: 152px; - font-size: 12px; + font-size: 13px; line-height:15px; font-family: helvetica, sans-serif; overflow-y: auto; @@ -120,7 +120,7 @@ } .CardOnGraph .best_in_place_desc textarea { - font-size: 12px; + font-size: 13px; line-height:15px; font-family: helvetica, sans-serif; color: #424242; @@ -170,8 +170,8 @@ resize: none; z-index: 1; position: relative; color: #424242; - font-size: 12px; - line-height:12px; + font-size: 14px; + line-height:14px; height:12px; padding:17px 0; } @@ -187,9 +187,9 @@ resize: none; height: 48px; } .linkItem.contributor { - margin-left:32px; + margin-left:40px; z-index:1; - padding:17px 16px 17px 32px; + padding:17px 16px 17px 30px; position: relative; } .contributor .contributorIcon { @@ -202,8 +202,9 @@ resize: none; display:none; } .linkItem.mapCount { + margin-left: 12px; width: 24px; - padding:17px 0 17px 35px; + padding:17px 0 17px 36px; } .linkItem.mapCount .mapCountIcon { position: absolute; @@ -219,8 +220,9 @@ resize: none; background-position: 0 -32px; } .linkItem.synapseCount { + margin-left: 2px; width: 24px; - padding:17px 0 17px 35px; + padding:17px 0 17px 32px; } .linkItem.synapseCount .synapseCountIcon { position: absolute; @@ -241,6 +243,7 @@ resize: none; padding: 0; min-width: 32px; margin-top: 8px; + margin-left: 8px; background-image: url(permissions32_sprite.png); background-position: 0 0; } @@ -507,6 +510,8 @@ background-color: #E0E0E0; width: 268px; padding: 8px 16px 8px 16px; position: relative; + border: none; + line-height: 14px; } #addLinkInput input{ diff --git a/app/assets/stylesheets/clean.css b/app/assets/stylesheets/clean.css index 5ebcb763..1646ed3f 100644 --- a/app/assets/stylesheets/clean.css +++ b/app/assets/stylesheets/clean.css @@ -191,7 +191,7 @@ .explorePage .sidebarSearchField, .explorePage .sidebarSearch .tt-hint { width: 380px; - padding: 7px 10px 3px 10px; + padding: 5px 10px 5px 10px; } .sidebarSearchField { @@ -207,7 +207,7 @@ border-bottom: 1px solid #BDBDBD; border-left: none; border-right: none; - padding: 7px 0 3px 0; + padding: 5px 0 5px 0; width: 0px; margin: 0; outline: none; @@ -218,7 +218,7 @@ } .sidebarSearch .tt-dropdown-menu { top: 40px !important; - background: #FFF; + background: #F5F5F5; width: 472px; overflow-y: auto; overflow-x: hidden; From 44923eb660c5d8bd7aa360f4246ffa6bc56c0738 Mon Sep 17 00:00:00 2001 From: Connor Turland Date: Sun, 9 Nov 2014 22:10:13 -0500 Subject: [PATCH 23/32] added new map screenshot capture method --- app/assets/images/screenshot_sprite.png | Bin 0 -> 1556 bytes app/assets/javascripts/src/Metamaps.JIT.js | 43 +++--- app/assets/javascripts/src/Metamaps.Router.js | 4 +- app/assets/javascripts/src/Metamaps.js | 126 +++++++++++++++++- app/assets/stylesheets/clean.css | 16 +++ app/controllers/maps_controller.rb | 26 +++- app/models/map.rb | 6 +- app/views/layouts/_lowermapelements.html.erb | 1 + config/routes.rb | 1 + 9 files changed, 197 insertions(+), 26 deletions(-) create mode 100644 app/assets/images/screenshot_sprite.png diff --git a/app/assets/images/screenshot_sprite.png b/app/assets/images/screenshot_sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..d3c87c5a88580bcc443a2acef7c904b4baf93d03 GIT binary patch literal 1556 zcmV+v2J88WP){xF|lUp1*i3@kj9#t1Acr6|ft9|8+DKLiawcn5v) z(;5{8209`QQkjAJLCA#_nu^XK{2=&VrAQIm{0A1Y`~1ds+1%Wpw|TkTyC1x~d(U~# zo^#IcJkRgh7>h+LViAj2{C^`(>cCT{PAPCxxF79r-n<$6Cnp{){5T1q+LV+O$J*Lj zu|}ie2?+^oetw=!PEOiwHk-w6w;M1SaSIo%O-oC2;orG)hbJZ`vbniAHZd__|M>Bv zWnp0FMd}qM{;}nVHFyN~Qed$&<>TKY!|+PG{WI z)RZ;Ki`S{u>Q=p8&*S3a`0((sDI+68efsoiwtxSAR#;dlKXc}c^2d)KI$UAnhqVD0 zFJ5fAcJ11|va&KcW&H5r!)$PHaPP>-$V+U1irOgR@39Mjj=M|@Ob>>ts{{EZtoG?Z!YsHv%O;Xi!%&=0?-rzdRu zZJ{_{yf@%PsOg!ax3`xK3=HTo&UoO!0S-EtkqNt0&YwGX zt_LT;uW!$uJ#1!XMg`s*a3a+7O!4~lYi6}t^%!T&%F5!PLs0zRLd<~!#QNmPlYpH| zOG_>Ve*XNq_5S_)e06n|b#--FcI?T)L-n{-OFRIaxZKdt5U|tXaJcZF zK7DF^{P;1^j=g&I%Cc+MuBxk7ue#oO_wHR#{7@U9fV#fjr0)UL*6z-f*xA|1Q333W zi;Hh>-n?n_=t6F8Zh1#Xhtv&FeERe$Ed18iR*nilQ+TV>>5Lv-fH;=7wY61CIevo4 zWO9n4=yQGk{Mm`@_5~73;+$5io$`MF#fukCv@50HKYRAfiLCluD0$8c7cTS#5=z3q zd-v{?_xqqkQ2bybs3f)D7{qZLeZL*W&ezf%dZE~;6$n8>_LbS$*?x`0aU6X=d}QB+ z55e}qhi3?iFNaM?JS(zkXduJf>2+d-v|#>gsBNp5X*t_(+nGtZ<-MUS1~62#O!744P2aHCVU+ z(_@DEH+c*Xi495=WkN)|BG6!zCb}7Zf%YcUbqy9SfJ$c6_9nNeF}OnothfO26YJ{g z0^&C|HipCx>IBI_$z-y%+1c4|m;?vM6y*0Qz(dL~$0TY|^ULA-e8v)GumJ||V;X4? z{`&g*+Lte1zNMz7a!^b`exD*aIhmo%@edz9)WZ9hZxmmm49aLod|4P=d;or#j~+eB zJ?6#}Hk&E)wMa@>_>%q*K_$=}Ja|y>h#$(M2%4Di@pt0wR{tS_N}xG% 1) { var ctx = canvas.getCtx(); var x = (pos.x + posChild.x) / 2; @@ -400,7 +410,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; @@ -1595,12 +1605,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(); @@ -1657,8 +1665,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); @@ -1674,7 +1681,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(); @@ -1686,8 +1694,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); } @@ -1711,15 +1717,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 2543f0df..7e03ea4e 100644 --- a/app/assets/javascripts/src/Metamaps.js +++ b/app/assets/javascripts/src/Metamaps.js @@ -3384,7 +3384,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 @@ -4203,6 +4203,130 @@ 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 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'); + } + }); } }; diff --git a/app/assets/stylesheets/clean.css b/app/assets/stylesheets/clean.css index 5ebcb763..847ec0ed 100644 --- a/app/assets/stylesheets/clean.css +++ b/app/assets/stylesheets/clean.css @@ -763,6 +763,18 @@ background-position: 0 0; cursor:pointer; } +.takeScreenshot { + margin-bottom: 5px; + border-radius: 2px; + background-image: url(screenshot_sprite.png); + display: none; +} +.takeScreenshot:hover { + background-position: -32px 0; +} +.canEditMap .takeScreenshot { + display: block; +} .zoomExtents { margin-bottom:5px; border-radius: 2px; @@ -883,6 +895,10 @@ line-height:14px; } +.toast a { + color: #4fc059; +} + /* end toast */ /* feedback */ diff --git a/app/controllers/maps_controller.rb b/app/controllers/maps_controller.rb index 0fbad24b..fbf34abc 100644 --- a/app/controllers/maps_controller.rb +++ b/app/controllers/maps_controller.rb @@ -1,6 +1,6 @@ class MapsController < ApplicationController - before_filter :require_user, only: [:create, :update, :destroy] + before_filter :require_user, only: [:create, :update, :screenshot, :destroy] respond_to :html, :json @@ -183,6 +183,30 @@ class MapsController < ApplicationController end end + # POST maps/:id/upload_screenshot + def screenshot + @current = current_user + @map = Map.find(params[:id]).authorize_to_edit(@current) + + if @map + png = Base64.decode64(params[:encoded_image]['data:image/png;base64,'.length .. -1]) + StringIO.open(png) do |data| + data.class.class_eval { attr_accessor :original_filename, :content_type } + data.original_filename = "map-" + @map.id.to_s + "-screenshot.png" + data.content_type = "image/png" + @map.screenshot = data + end + + if @map.save + render :json => {:message => "Successfully uploaded the map screenshot."} + else + render :json => {:message => "Failed to upload image."} + end + else + render :json => {:message => "Unauthorized to set map screenshot."} + end + end + # DELETE maps/:id def destroy @current = current_user diff --git a/app/models/map.rb b/app/models/map.rb index fcfefc81..91bc0a11 100644 --- a/app/models/map.rb +++ b/app/models/map.rb @@ -8,12 +8,12 @@ class Map < ActiveRecord::Base has_many :topics, :through => :topicmappings has_many :synapses, :through => :synapsemappings - after_touch :save_screenshot + #after_touch :save_screenshot # This method associates the attribute ":image" with a file attachment has_attached_file :screenshot, :styles => { - :thumb => ['188x126#', :png], - :full => ['940x630#', :png] + :thumb => ['188x126#', :png] + #:full => ['940x630#', :png] }, :default_url => "/assets/missing-map.png" 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/config/routes.rb b/config/routes.rb index 5031b431..edc19576 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -30,6 +30,7 @@ Metamaps::Application.routes.draw do match 'maps/topics/:id', to: 'maps#index', via: :get, as: :topicmaps resources :maps, except: [:new, :edit] match 'maps/:id/contains', to: 'maps#contains', via: :get, as: :contains + match 'maps/:id/upload_screenshot', to: 'maps#screenshot', via: :post, as: :screenshot devise_for :users, controllers: { registrations: 'users/registrations', passwords: 'users/passwords', sessions: 'devise/sessions' }, :skip => [:sessions] From 218716dee3bb47fb5f1979e90dc60abf948e9af8 Mon Sep 17 00:00:00 2001 From: Connor Turland Date: Mon, 10 Nov 2014 11:06:57 -0500 Subject: [PATCH 24/32] fixed cross origin image draw, so that canvas.toDataURL can work --- app/assets/javascripts/src/Metamaps.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/javascripts/src/Metamaps.js b/app/assets/javascripts/src/Metamaps.js index 7e03ea4e..0049f983 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.setAttribute('crossOrigin', 'anonymous'); image.src = this.get('icon'); this.set('image',image); }, From 20a6a9f44342f041102edbe0982c2f5c6083da16 Mon Sep 17 00:00:00 2001 From: Connor Turland Date: Mon, 10 Nov 2014 11:20:56 -0500 Subject: [PATCH 25/32] another attempt at cross origin --- app/assets/javascripts/src/Metamaps.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/src/Metamaps.js b/app/assets/javascripts/src/Metamaps.js index 0049f983..377ef7ab 100644 --- a/app/assets/javascripts/src/Metamaps.js +++ b/app/assets/javascripts/src/Metamaps.js @@ -82,7 +82,7 @@ Metamaps.Backbone.init = function () { self.Metacode = Backbone.Model.extend({ initialize: function () { var image = new Image(); - image.setAttribute('crossOrigin', 'anonymous'); + image.crossOrigin = "Anonymous"; image.src = this.get('icon'); this.set('image',image); }, From 3bb8256f8f35d1418312760c49e380955ffc13e3 Mon Sep 17 00:00:00 2001 From: Connor Turland Date: Mon, 10 Nov 2014 17:58:15 -0500 Subject: [PATCH 26/32] updated missing map image. added topic description signifier and relocated topic link signifier to top left. added synapse count signifier. --- app/assets/images/linkedmedia.png | Bin 404 -> 0 bytes app/assets/images/missing-map.png | Bin 16291 -> 4242 bytes app/assets/images/synapsestar.png | Bin 304 -> 0 bytes .../images/topic_description_signifier.png | Bin 0 -> 450 bytes app/assets/images/topic_link_signifier.png | Bin 0 -> 621 bytes app/assets/javascripts/src/Metamaps.JIT.js | 77 +++++++++++++----- 6 files changed, 55 insertions(+), 22 deletions(-) delete mode 100755 app/assets/images/linkedmedia.png delete mode 100755 app/assets/images/synapsestar.png create mode 100644 app/assets/images/topic_description_signifier.png create mode 100644 app/assets/images/topic_link_signifier.png diff --git a/app/assets/images/linkedmedia.png b/app/assets/images/linkedmedia.png deleted file mode 100755 index 2009b7a356935d0cad6509c1ed619717f699a636..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 404 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 NX{zc#DwJ)){{u9uFJAxv literal 16291 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 ZU;zH03AX4(D#HK(002ovPDHLkV1jyu&AI>p diff --git a/app/assets/images/synapsestar.png b/app/assets/images/synapsestar.png deleted file mode 100755 index ba9a7dd3f98f7c2388c1a0d40e589fdfeb44a726..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 304 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9GG!XV7ZFl&wkP*AeO zHKHUqKdq!Zu_%?nF(p4KRlzeiF+DXXH8G{K@MNkDP|;pb7srr_TSsWZ73{| z4hRd|#^6$3TBv)^z1T31fgzO1G^*Jv`(fe&)hGaX*ec!;3cbq0mCDw6}>MWD21GBOi*Cj z8^o~W*Toj@M!)$E24W4f9M@Sed_Cr_qThIf&%s&m!Dl8869>}<2PTojJedcidp+11 va-uo5{hW2!Y~j7LP5z0q@#olP$mcypllFENJ*CsfC)kth(bq4HV7kx3E*D(BC>2^ zgGCVXORt#Z-+%U>&x{5=+sFZM0Qv?nem5})f((z4f1Zk>SbuE?P<+)YP8RYz$ALd1 zA^IBQF@;wk*~yS6#E}KOL2jyw8)~wgtbrfkN1k{uq(lT1zTv!C>zneFyaMpByxTrN z-1_7|V@krrV(|l3F9qPKGU~c6ec#V9oNzxUhDB++iMR=h?~F+(;lzRo7I%aa zS=9laFxLppb&DGTzz&ceWE!Cv$68myJ&RJ8O(hzkG*5H&v7+~MQqFMkCY*!7cM$o~ zHTO`XIGuo6@`>bm$uU<}NAcV*W#VJnf>7~3QjFWJ2yJjcwt}?HbRNqtoa$o$d<&+6 ss%;f~CxY)zye5g12RF$1Z^guchMnT zEE}H-9Q;M@+AERaLd*yTw$N0DuA>ugdTnfE2cG z!x;gveUNqLvjl7q!J~x!#D-7gk~^tI!jS;A0`Lj_nfgU)5id(HfE61)!f6vW=aJ@E zE#eFz0T=*5>%=hk$J-q)0N7x>QCx#CTkn{lQ#De6$;HaxUn_vY9i^{gX1V|)_n>)k zvmC}+3wWx=gUB7Q7~c7f1^}(_jn@zQ9{LxIWMC>=3vw_Vr+FWgWQqSwD zrD7$zqOdTU`QGq1kNlf>=>^J`KcouEj)NCoF#!vu%*;}Wc1ms%ccgy>Fa!~?AWY{37=kF63f8od z6yV^R-c1lWljD^R!~lRfB6F=LLPJH=DizTU2&rSM0Vo2GHmH~yDLzq*lrAOxXxTR8 zgkUNFQ9Z$m)w3pr@5TZ+m;7LrE#(4qN2x2-W`~%o{R%JuFVP};@r%Nk00000NkvXX Hu0mjfLW%=q literal 0 HcmV?d00001 diff --git a/app/assets/javascripts/src/Metamaps.JIT.js b/app/assets/javascripts/src/Metamaps.JIT.js index 06ed616f..bbbfd1d7 100644 --- a/app/assets/javascripts/src/Metamaps.JIT.js +++ b/app/assets/javascripts/src/Metamaps.JIT.js @@ -28,11 +28,11 @@ Metamaps.JIT = { $(".takeScreenshot").click(Metamaps.Map.exportImage); - self.synapseStarImage = new Image(); - self.synapseStarImage.src = '/assets/synapsestar.png'; + self.topicDescImage = new Image(); + self.topicDescImage.src = '/assets/topic_description_signifier.png'; - self.topicMediaImage = new Image(); - self.topicMediaImage.src = '/assets/linkedmedia.png'; + self.topicLinkImage = new Image(); + self.topicLinkImage.src = '/assets/topic_link_signifier.png'; }, /** * convert our topic JSON into something JIT can use @@ -140,14 +140,31 @@ Metamaps.JIT = { var showDesc = adj.getData("showDesc"); - var drawStar = function (context, x, y) { - var starImage = Metamaps.JIT.synapseStarImage; - var starImageLoaded = starImage.complete || - (typeof starImage.naturalWidth !== "undefined" && - starImage.naturalWidth !== 0) - if (starImageLoaded) { - context.drawImage(starImage, x, y, 16, 16); - } + 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) { @@ -165,7 +182,7 @@ 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; @@ -187,23 +204,29 @@ 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 (adj.getData("synapses").length > 1) { - drawStar(ctx, x + width, y); + if (synapseNum > 1) { + drawSynapseCount(ctx, x + width, y, synapseNum); } } else if (!canvas.denySelected && showDesc) { - if (adj.getData("synapses").length > 1) { + // 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; - drawStar(ctx, x, y); + drawSynapseCount(ctx, x, y, synapseNum); } } @@ -433,12 +456,22 @@ Metamaps.JIT = { // 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.topicMediaImage; + 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 / 2, pos.y - dim - 8, 16, 16); + 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) { @@ -479,7 +512,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); } } } From 1658c5fb5dd6c4a34b5bfe8e2c00d045c69c1fd1 Mon Sep 17 00:00:00 2001 From: poietic Date: Mon, 10 Nov 2014 17:02:07 -0800 Subject: [PATCH 27/32] lightbox content tweaks --- app/views/layouts/_lightboxes.html.erb | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/views/layouts/_lightboxes.html.erb b/app/views/layouts/_lightboxes.html.erb index c5488536..68b0db68 100644 --- a/app/views/layouts/_lightboxes.html.erb +++ b/app/views/layouts/_lightboxes.html.erb @@ -112,19 +112,19 @@
          • Asana
          • Invision App *
          • Docracy *
          • -
          • Google Hangouts
          • Google Plus *
          • -
          • Hipchat
          • Hackpad *
          • Loomio *
          • Twitter *
          • +
          • Hipchat
          • +
          • Google Hangouts
          • Vimeo
          • Youtube

          -

          Development

          +

          Design & Development

            -
          • Git
          • -
          • Github*
          +
        • Github*
        +
      • Pixelapse*
      • Documentation

        • Dropbox *
        • Google Drive *
        • @@ -158,7 +158,7 @@

        Documentation

        • Dropbox *
        • Google Drive *
        • From 8d3de3867f486d77060e64d0102ee2ed8c5e9a03 Mon Sep 17 00:00:00 2001 From: Connor Turland Date: Tue, 11 Nov 2014 06:48:21 -0500 Subject: [PATCH 32/32] enabled pulling in siblings through right click menus in topic view --- app/assets/javascripts/src/Metamaps.JIT.js | 117 ++++++++++++++++++--- app/assets/javascripts/src/Metamaps.js | 68 +++++++++++- app/assets/javascripts/src/codeleft.js | 34 ------ app/assets/stylesheets/application.css | 33 ++++-- app/controllers/topics_controller.rb | 81 +++++++++++++- config/routes.rb | 2 + 6 files changed, 271 insertions(+), 64 deletions(-) delete mode 100644 app/assets/javascripts/src/codeleft.js diff --git a/app/assets/javascripts/src/Metamaps.JIT.js b/app/assets/javascripts/src/Metamaps.JIT.js index 038f1a67..88436a80 100644 --- a/app/assets/javascripts/src/Metamaps.JIT.js +++ b/app/assets/javascripts/src/Metamaps.JIT.js @@ -37,8 +37,9 @@ Metamaps.JIT = { /** * 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; @@ -48,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); } @@ -89,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; } @@ -1319,7 +1330,9 @@ Metamaps.JIT = { if (Metamaps.Active.Map && Metamaps.Active.Mapper) menustring += '
        • Delete
        • '; - if (Metamaps.Active.Topic) menustring += '
        • Center this topic
        • '; + if (Metamaps.Active.Topic) { + menustring += '
        • Center this topic
        • '; + } menustring += '
        • Open in new tab
        • '; if (Metamaps.Active.Mapper) { var options = '
          • commons
          • \ @@ -1333,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 = '
              \ +
            • All
            • \ +
            • \ +
            '; + menustring += '
          • Get siblings' + siblingMenu + '
          • '; + } menustring += '
          '; rightclickmenu.innerHTML = menustring; @@ -1426,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; diff --git a/app/assets/javascripts/src/Metamaps.js b/app/assets/javascripts/src/Metamaps.js index ff2203c4..5b2109bc 100644 --- a/app/assets/javascripts/src/Metamaps.js +++ b/app/assets/javascripts/src/Metamaps.js @@ -219,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(); @@ -1508,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 }); @@ -3671,8 +3672,7 @@ Metamaps.Topic = { }, 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 () { @@ -3681,6 +3681,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 () { + + } + }); + }, /* * * @@ -4739,8 +4799,6 @@ Metamaps.Account = { var destWidth = 84; var destHeight = 84; - //debugger; - context.drawImage(imageObj, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight); $('.userImageDiv').prepend($canvas); }; diff --git a/app/assets/javascripts/src/codeleft.js b/app/assets/javascripts/src/codeleft.js deleted file mode 100644 index 413fc62a..00000000 --- a/app/assets/javascripts/src/codeleft.js +++ /dev/null @@ -1,34 +0,0 @@ -function fetchRelatives(node) { - var myA = $.ajax({ - type: "Get", - url: "/topics/" + node.id + "?format=json", - success: function (data) { - if (gType == "centered") { - Mconsole.busy = true; - Mconsole.op.sum(data, { - type: 'fade', - duration: 500, - hideLabels: false - }); - Mconsole.graph.eachNode(function (n) { - n.eachAdjacency(function (a) { - if (!a.getData('showDesc')) { - a.setData('alpha', 0.4, 'start'); - a.setData('alpha', 0.4, 'current'); - a.setData('alpha', 0.4, 'end'); - } - }); - }); - Mconsole.busy = false; - } else { - Mconsole.op.sum(data, { - type: 'nothing', - }); - Mconsole.plot(); - } - }, - error: function () { - alert('failure'); - } - }); -} \ No newline at end of file diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 259e8232..7849d889 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -1244,7 +1244,9 @@ h3.realtimeBoxTitle { .rc-metacode li img { float: left; } -.rightclickmenu .rc-permission ul, .rightclickmenu .rc-metacode ul { +.rightclickmenu .rc-permission ul, +.rightclickmenu .rc-metacode ul, +.rightclickmenu .rc-siblings ul { display: none; background: white; top: 0; @@ -1255,7 +1257,9 @@ float: left; border-top-right-radius: 2px; box-shadow: 0px 3px 3px rgba(0,0,0,0.12), 0 3px 3px rgba(0,0,0,0.24); } -.rightclickmenu .rc-permission:hover > ul, .rightclickmenu .rc-metacode:hover > ul { +.rightclickmenu .rc-permission:hover > ul, +.rightclickmenu .rc-metacode:hover > ul, + .rightclickmenu .rc-siblings:hover > ul { display: block; } .rightclickmenu p { @@ -1283,20 +1287,24 @@ float: left; .rightclickmenu li.toPrivate .rc-perm-icon { background-position: -24px 0; } -.rightclickmenu .rc-metacode > ul > li { +.rightclickmenu .rc-metacode > ul > li, +.rightclickmenu .rc-siblings > ul > li { padding: 6px 10px 6px 8px; width: 100px; } -.rightclickmenu .rc-metacode ul ul { +.rightclickmenu .rc-metacode ul ul, +.rightclickmenu .rc-siblings ul ul { display: none; max-height: 270px; overflow-y: auto; overflow-x: hidden; } -.rightclickmenu .rc-metacode li:hover ul { +.rightclickmenu .rc-metacode li:hover ul, +.rightclickmenu .rc-siblings li:hover ul { display: block; } -.rightclickmenu .rc-metacode ul ul li { +.rightclickmenu .rc-metacode ul ul li, +.rightclickmenu .rc-siblings ul ul li { padding: 4px 10px 4px 8px; width: 120px; } @@ -1315,15 +1323,24 @@ float: left; display: block; } -.moveMenusUp .rc-metacode ul, .moveMenusUp .rc-permission ul { +.moveMenusUp .rc-metacode ul, +.moveMenusUp .rc-permission ul, +.moveMenusUp .rc-siblings ul { top: auto; bottom: 0; } -.moveMenusToLeft .rc-metacode ul, .moveMenusToLeft .rc-permission ul { +.moveMenusToLeft .rc-metacode ul, +.moveMenusToLeft .rc-permission ul, +.moveMenusToLeft .rc-siblings ul { left: auto; right: 100%; } +#loadingSiblings div { + width: 15px; + margin: 0 auto; +} + /* end right click menu */ diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb index cd621db5..e39b67a8 100644 --- a/app/controllers/topics_controller.rb +++ b/app/controllers/topics_controller.rb @@ -61,7 +61,7 @@ class TopicsController < ApplicationController @topic = Topic.find(params[:id]).authorize_to_show(@current) if not @topic - redirect_to root_url and return + redirect_to root_url, notice: "Access denied. That topic is private." and return end @alltopics = @topic.relatives.delete_if {|t| t.permission == "private" && (!authenticated? || (authenticated? && @current.id != t.user_id)) } @@ -90,6 +90,85 @@ class TopicsController < ApplicationController end end + # GET topics/:id/relative_numbers + def relative_numbers + @current = current_user + @topic = Topic.find(params[:id]).authorize_to_show(@current) + + if not @topic + redirect_to root_url, notice: "Access denied. That topic is private." and return + end + + @topicsAlreadyHas = params[:network] ? params[:network].split(',') : [] + + @alltopics = @topic.relatives.delete_if {|t| + @topicsAlreadyHas.index(t.id.to_s) != nil || + (t.permission == "private" && (!authenticated? || (authenticated? && @current.id != t.user_id))) + } + + @alltopics.uniq! + + @json = Hash.new() + @alltopics.each do |t| + if @json[t.metacode.id] + @json[t.metacode.id] += 1 + else + @json[t.metacode.id] = 1 + end + end + + respond_to do |format| + format.json { render json: @json } + end + end + + # GET topics/:id/relatives + def relatives + @current = current_user + @topic = Topic.find(params[:id]).authorize_to_show(@current) + + if not @topic + redirect_to root_url, notice: "Access denied. That topic is private." and return + end + + @topicsAlreadyHas = params[:network] ? params[:network].split(',') : [] + + @alltopics = @topic.relatives.delete_if {|t| + @topicsAlreadyHas.index(t.id.to_s) != nil || + (params[:metacode] && t.metacode_id.to_s != params[:metacode]) || + (t.permission == "private" && (!authenticated? || (authenticated? && @current.id != t.user_id))) + } + + @alltopics.uniq! + + @allsynapses = @topic.synapses.delete_if {|s| + (s.topic1 == @topic && @alltopics.index(s.topic2) == nil) || + (s.topic2 == @topic && @alltopics.index(s.topic1) == nil) + } + + @creatorsAlreadyHas = params[:creators] ? params[:creators].split(',') : [] + @allcreators = [] + @alltopics.each do |t| + if @allcreators.index(t.user) == nil && @creatorsAlreadyHas.index(t.user_id.to_s) == nil + @allcreators.push(t.user) + end + end + @allsynapses.each do |s| + if @allcreators.index(s.user) == nil && @creatorsAlreadyHas.index(s.user_id.to_s) == nil + @allcreators.push(s.user) + end + end + + @json = Hash.new() + @json['topics'] = @alltopics + @json['synapses'] = @allsynapses + @json['creators'] = @allcreators + + respond_to do |format| + format.json { render json: @json } + end + end + # POST /topics # POST /topics.json def create diff --git a/config/routes.rb b/config/routes.rb index edc19576..f5ad183f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -22,6 +22,8 @@ Metamaps::Application.routes.draw do get :autocomplete_topic, :on => :collection end match 'topics/:id/network', to: 'topics#network', via: :get, as: :network + match 'topics/:id/relative_numbers', to: 'topics#relative_numbers', via: :get, as: :relative_numbers + match 'topics/:id/relatives', to: 'topics#relatives', via: :get, as: :relatives match 'explore/active', to: 'maps#index', via: :get, as: :activemaps match 'explore/featured', to: 'maps#index', via: :get, as: :featuredmaps