Add note creation to the sidebar
authorAaron Lidman <aaronlidman@gmail.com>
Tue, 12 Nov 2013 03:06:07 +0000 (19:06 -0800)
committerAaron Lidman <aaronlidman@gmail.com>
Tue, 12 Nov 2013 03:06:07 +0000 (19:06 -0800)
app/assets/javascripts/index.js
app/assets/javascripts/index/new_note.js.erb [new file with mode: 0644]
app/assets/javascripts/index/note.js.erb
app/assets/javascripts/index/notes.js.erb
app/assets/javascripts/templates/notes/new.jst.ejs [deleted file]
app/assets/javascripts/templates/notes/show.jst.ejs [deleted file]
app/views/browse/new_note.html.erb [new file with mode: 0644]
config/locales/en.yml
config/routes.rb

index 378244db466d3c3232590bbe066ceb79fecf40e5..e0ca66766ff877079a0d118cb2c4e588bf1e4bc2 100644 (file)
@@ -11,6 +11,7 @@
 //= require index/notes
 //= require index/history
 //= require index/note
+//= require index/new_note
 //= require router
 
 $(document).ready(function () {
@@ -221,6 +222,7 @@ $(document).ready(function () {
     "/search":                     OSM.Search(map),
     "/export":                     OSM.Export(map),
     "/history":                    history,
+    "/new_note":                   OSM.NewNote(map),
     "/user/:display_name/edits":   history,
     "/browse/friends":             history,
     "/browse/nearby":              history,
diff --git a/app/assets/javascripts/index/new_note.js.erb b/app/assets/javascripts/index/new_note.js.erb
new file mode 100644 (file)
index 0000000..34d8355
--- /dev/null
@@ -0,0 +1,144 @@
+OSM.NewNote = function(map) {
+    var noteLayer = map.noteLayer,
+        content = $('#sidebar_content'),
+        page = {},
+        addNoteButton = $(".control-note .control-button"),
+        newNote;
+
+    var noteIcons = {
+      "new": L.icon({
+        iconUrl: "<%= image_path 'new_note_marker.png' %>",
+        iconSize: [25, 40],
+        iconAnchor: [12, 40]
+      }),
+      "open": L.icon({
+        iconUrl: "<%= image_path 'open_note_marker.png' %>",
+        iconSize: [25, 40],
+        iconAnchor: [12, 40]
+      }),
+      "closed": L.icon({
+        iconUrl: "<%= image_path 'closed_note_marker.png' %>",
+        iconSize: [25, 40],
+        iconAnchor: [12, 40]
+      })
+    };
+
+    page.pushstate = page.popstate = function() {
+        page.load();
+    };
+
+    addNoteButton.on("click", function (e) {
+      e.preventDefault();
+      e.stopPropagation();
+
+      OSM.route('/new_note');
+    });
+
+    function createNote(marker, form, url) {
+      var location = marker.getLatLng();
+
+      marker.options.draggable = false;
+      marker.dragging.disable();
+
+      $(form).find("input[type=submit]").prop("disabled", true);
+
+      $.ajax({
+        url: url,
+        type: "POST",
+        oauth: true,
+        data: {
+          lat: location.lat,
+          lon: location.lng,
+          text: $(form.text).val()
+        },
+        success: function(feature) {
+          noteCreated(feature, marker);
+        }
+      });
+
+      function noteCreated(feature, marker) {
+        content.find("textarea").val("");
+        updateMarker(feature);
+        newNote = null;
+        noteLayer.removeLayer(marker);
+        addNoteButton.removeClass("active");
+        OSM.route('/browse/note/' + feature.properties.id);
+      }
+    }
+
+    function updateMarker(feature) {
+        marker = L.marker(feature.geometry.coordinates.reverse(), {
+            icon: noteIcons[feature.properties.status],
+            opacity: 0.9,
+            clickable: true
+        });
+        marker.id = feature.properties.id;
+        marker.addTo(noteLayer);
+        return marker;
+    }
+
+    function initialize() {
+        if (addNoteButton.hasClass("disabled")) return;
+        if (addNoteButton.hasClass("active")) return;
+
+        addNoteButton.addClass("active");
+
+        map.addLayer(noteLayer);
+
+        var mapSize = map.getSize();
+        var markerPosition;
+
+        if (mapSize.y > 800) {
+          markerPosition = [mapSize.x / 2, mapSize.y / 2];
+        } else if (mapSize.y > 400) {
+          markerPosition = [mapSize.x / 2, 400];
+        } else {
+          markerPosition = [mapSize.x / 2, mapSize.y];
+        }
+
+        newNote = L.marker(map.containerPointToLatLng(markerPosition), {
+          icon: noteIcons["new"],
+          opacity: 0.9,
+          draggable: true
+        });
+
+        newNote.addTo(noteLayer)
+
+        newNote.on("remove", function (e) {
+          addNoteButton.removeClass("active");
+        }).on("dragstart", function (e) {
+          $(newNote).stopTime("removenote");
+        }).on("dragend", function (e) {
+          content.find("textarea").focus();
+        });
+
+        content.find("textarea")
+            .on("input", disableWhenBlank)
+            .focus();
+
+        function disableWhenBlank(e) {
+          $(e.target.form.add).prop("disabled", $(e.target).val() === "");
+        }
+
+        content.find('input[type=submit]').on('click', function(e) {
+            e.preventDefault();
+            createNote(newNote, e.target.form, '/api/0.6/notes.json');
+        });
+    }
+
+    page.load = function() {
+        content.load(window.location.pathname + "?xhr=1", function(a, b, xhr) {
+            if (xhr.getResponseHeader('X-Page-Title')) {
+                document.title = xhr.getResponseHeader('X-Page-Title');
+            }
+            initialize();
+        });
+    }
+
+    page.unload = function() {
+        noteLayer.removeLayer(newNote);
+        addNoteButton.removeClass("active");
+    }
+
+    return page;
+}
index 74b8e85d0f37f01c73c3569de135eca1fbeec777..9e92c9a1fb7c968e0790db391d3d1a103a41d931 100644 (file)
@@ -1,6 +1,3 @@
-//= require templates/notes/show
-//= require templates/notes/new
-
 OSM.Note = function(map) {
     var noteLayer = map.noteLayer,
         content = $('#sidebar_content'),
@@ -66,7 +63,7 @@ OSM.Note = function(map) {
         content.find("textarea").val('').trigger("input");
     }
 
-    page.pushstate = page.popstate = function(path) {
+    page.pushstate = page.popstate = function() {
         page.load();
     };
 
index 70335748e23185a46abc05579219c26191f0f841..c3169ca09b396108d3d8aa5c304d7d7bdf54b887 100644 (file)
@@ -1,6 +1,3 @@
-//= require templates/notes/show
-//= require templates/notes/new
-
 function initializeNotes(map) {
   var noteLayer = map.noteLayer,
       notes = {},
@@ -102,157 +99,4 @@ function initializeNotes(map) {
       noteLoader = null;
     }
   };
-
-  function popupOptions() {
-    var mapSize = map.getSize();
-
-    return {
-      minWidth: 320,
-      maxWidth: mapSize.y * 1 / 3,
-      maxHeight: mapSize.y * 2 / 3,
-      offset: new L.Point(0, -40),
-      autoPanPadding: new L.Point(60, 40)
-    };
-  }
-
-  function createPopupContent(marker, properties, comment) {
-    var content = $(JST["templates/notes/show"]({ note: properties }));
-
-    content.find("textarea").on("input", function (e) {
-      var form = e.target.form;
-
-      if ($(e.target).val() == "") {
-        $(form.close).val(I18n.t("javascripts.notes.show.resolve"));
-        $(form.comment).prop("disabled", true);
-      } else {
-        $(form.close).val(I18n.t("javascripts.notes.show.comment_and_resolve"));
-        $(form.comment).prop("disabled", false);
-      }
-    });
-
-    content.find("input[type=submit]").on("click", function (e) {
-      e.preventDefault();
-      var data = $(e.target).data();
-      updateNote(marker, e.target.form, data.method, data.url);
-    });
-
-    if (comment) {
-      content.find("textarea").val(comment).trigger("input");
-    }
-
-    return content[0];
-  }
-
-  var addNoteButton = $(".control-note .control-button");
-
-  function createNote(marker, form, url) {
-    var location = marker.getLatLng();
-
-    marker.options.draggable = false;
-    marker.dragging.disable();
-
-    $(form).find("input[type=submit]").prop("disabled", true);
-
-    $.ajax({
-      url: url,
-      type: "POST",
-      oauth: true,
-      data: {
-        lat: location.lat,
-        lon: location.lng,
-        text: $(form.text).val()
-      },
-      success: function(feature) {
-        noteCreated(feature, marker);
-      }
-    });
-
-    function noteCreated(feature, marker) {
-      $(marker._popup._content).find("textarea").val("");
-
-      notes[feature.properties.id] = updateMarker(false, feature);
-      OSM.route('/browse/note/' + feature.properties.id);
-      newNote = null;
-      marker.closePopup();
-      noteLayer.removeLayer(marker);
-      addNoteButton.removeClass("active");
-    }
-  }
-
-  function updateNote(marker, form, method, url) {
-    $(form).find("input[type=submit]").prop("disabled", true);
-
-    $.ajax({
-      url: url,
-      type: method,
-      oauth: true,
-      data: {
-        text: $(form.text).val()
-      },
-      success: function (feature) {
-        if (feature.properties.status == "hidden") {
-          noteLayer.removeLayer(marker);
-
-          delete notes[feature.properties.id];
-        } else {
-          var popupContent = createPopupContent(marker, feature.properties);
-
-          marker.setIcon(noteIcons[feature.properties.status]);
-          marker.setPopupContent(popupContent);
-        }
-      }
-    });
-  }
-
-  addNoteButton.on("click", function (e) {
-    e.preventDefault();
-    e.stopPropagation();
-
-    if (addNoteButton.hasClass("disabled")) return;
-    if (addNoteButton.hasClass("active")) return;
-
-    addNoteButton.addClass("active");
-
-    map.addLayer(noteLayer);
-
-    var mapSize = map.getSize();
-    var markerPosition;
-
-    if (mapSize.y > 800) {
-      markerPosition = [mapSize.x / 2, mapSize.y / 2];
-    } else if (mapSize.y > 400) {
-      markerPosition = [mapSize.x / 2, 400];
-    } else {
-      markerPosition = [mapSize.x / 2, mapSize.y];
-    }
-
-    newNote = L.marker(map.containerPointToLatLng(markerPosition), {
-      icon: noteIcons["new"],
-      opacity: 0.9,
-      draggable: true
-    });
-
-    var popupContent = $(JST["templates/notes/new"]());
-
-    popupContent.find("textarea").on("input", disableWhenBlank);
-
-    function disableWhenBlank(e) {
-      $(e.target.form.add).prop("disabled", $(e.target).val() === "");
-    }
-
-    popupContent.find("input[type=submit]").on("click", function (e) {
-      e.preventDefault();
-      createNote(newNote, e.target.form, '/api/0.6/notes.json');
-    });
-
-    newNote.addTo(noteLayer).bindPopup(popupContent[0], popupOptions()).openPopup();
-
-    newNote.on("remove", function (e) {
-      addNoteButton.removeClass("active");
-    }).on("dragstart", function (e) {
-      $(newNote).stopTime("removenote");
-    }).on("dragend", function (e) {
-      e.target.openPopup();
-    });
-  });
 }
diff --git a/app/assets/javascripts/templates/notes/new.jst.ejs b/app/assets/javascripts/templates/notes/new.jst.ejs
deleted file mode 100644 (file)
index 0039710..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<div class="note">
-  <p><%- I18n.t('javascripts.notes.new.intro') %></p>
-  <form action="#">
-    <input type="hidden" name="lon">
-    <input type="hidden" name="lat">
-    <textarea class="comment" name="text" cols="40" rows="10"></textarea>
-    <br/>
-    <div class="buttons clearfix">
-      <input type="submit" name="add" value="<%- I18n.t('javascripts.notes.new.add') %>" disabled="1">
-    </div>
-  </form>
-</div>
diff --git a/app/assets/javascripts/templates/notes/show.jst.ejs b/app/assets/javascripts/templates/notes/show.jst.ejs
deleted file mode 100644 (file)
index 2402591..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-<div class="note">
-  <a class="icon link permalink deemphasize" href="/browse/note/<%- note.id %>"><span><%- I18n.t('javascripts.notes.show.permalink', { id: note.id }) %></span></a>
-  <% if (note.comments.some(function (comment) { return !comment.user })) { %>
-  <small class="warning"><%- I18n.t('javascripts.notes.show.anonymous_warning') %></small>
-  <% } %>
-  <% note.comments.forEach(function (comment) { %>
-  <div>
-    <small class="deemphasize">
-      <% if (comment.user) { %>
-        <%= I18n.t('javascripts.notes.show.' + comment.action + '_by', {
-           user: comment.user, user_url: comment.user_url,
-           time: I18n.l("time.formats.long", comment.date)
-        }) %>
-      <% } else { %>
-        <%- I18n.t('javascripts.notes.show.' + comment.action + '_by_anonymous', {
-           time: I18n.l("time.formats.long", comment.date)
-        }) %>
-      <% } %>
-    </small>
-    <div class="comment_body"><%= comment.html %></div>
-  </div>
-  <% }) %>
-  <% if (note.status == "open") { %>
-  <form action="#">
-    <textarea class="comment" name="text" cols="40" rows="5"></textarea>
-    <div class="buttons clearfix">
-      <input type="submit" name="hide" value="<%- I18n.t('javascripts.notes.show.hide') %>" class="hide_unless_moderator deemphasize" data-method="DELETE" data-url="<%- note.url %>">
-      <input type="submit" name="close" value="<%- I18n.t('javascripts.notes.show.resolve') %>" class="hide_unless_logged_in" data-method="POST" data-url="<%- note.close_url %>">
-      <input type="submit" name="comment" value="<%- I18n.t('javascripts.notes.show.comment') %>" data-method="POST" data-url="<%- note.comment_url %>" disabled="1">
-    </div>
-  </form>
-  <% } else { %>
-  <form action="#">
-    <input type="hidden" name="text" value="">
-    <div class="buttons clearfix">
-      <input type="submit" name="hide" value="<%- I18n.t('javascripts.notes.show.hide') %>" class="hide_unless_moderator deemphasize" data-method="DELETE" data-url="<%- note.url %>">
-      <input type="submit" name="reopen" value="<%- I18n.t('javascripts.notes.show.reactivate') %>" class="hide_unless_logged_in" data-method="POST" data-url="<%- note.reopen_url %>">
-    </div>
-  </form>
-  <% } %>
-</div>
diff --git a/app/views/browse/new_note.html.erb b/app/views/browse/new_note.html.erb
new file mode 100644 (file)
index 0000000..09af23e
--- /dev/null
@@ -0,0 +1,20 @@
+<% set_title("New Note") %>
+
+<h2>
+  <a class="geolink" href="<%= root_path %>"><span class="icon close"></span></a>
+  <%= t "browse.note.new_note" %>
+</h2>
+
+<div class="note browse-section">
+  <p><%= t('javascripts.notes.new.intro') %></p>
+  <form action="#">
+    <input type="hidden" name="lon">
+    <input type="hidden" name="lat">
+    <br/>
+    <textarea class="comment" name="text" cols="40" rows="10"></textarea>
+    <br/>
+    <div class="buttons clearfix">
+      <input type="submit" name="add" value="<%= t('javascripts.notes.new.add') %>" disabled="1">
+    </div>
+  </form>
+</div>
index 2a546abce81524b783078fd462a07d50eef64134..db6614cb0d39611db3d363e4927b418c661b0418 100644 (file)
@@ -282,6 +282,7 @@ en:
       edit: "Edit way"
     note:
       title: "Note"
+      new_note: "Add a note"
       open_title: "Unresolved note: %{note_name}"
       closed_title: "Resolved note: %{note_name}"
       opened: "Opened"
index 435cff9eb01aaeef28bf72af3dbbb83f4f518625..9eda73015d74cf470b03e74ed145269dd21172ec 100644 (file)
@@ -110,6 +110,7 @@ OpenStreetMap::Application.routes.draw do
   match '/browse/relation/:id/history' => 'browse#relation_history', :via => :get, :id => /\d+/
   match '/browse/changeset/:id' => 'browse#changeset', :via => :get, :as => :changeset, :id => /\d+/
   match '/browse/note/:id' => 'browse#note', :via => :get, :id => /\d+/, :as => "browse_note"
+  match '/new_note' => 'browse#new_note', :via => :get
   match '/user/:display_name/edits' => 'changeset#list', :via => :get
   match '/user/:display_name/edits/feed' => 'changeset#feed', :via => :get, :defaults => { :format => :atom }
   match '/user/:display_name/notes' => 'notes#mine', :via => :get