Add note creation to the sidebar
This commit is contained in:
parent
85282f5cdd
commit
1b19974b12
9 changed files with 169 additions and 213 deletions
|
@ -11,6 +11,7 @@
|
||||||
//= require index/notes
|
//= require index/notes
|
||||||
//= require index/history
|
//= require index/history
|
||||||
//= require index/note
|
//= require index/note
|
||||||
|
//= require index/new_note
|
||||||
//= require router
|
//= require router
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
|
@ -221,6 +222,7 @@ $(document).ready(function () {
|
||||||
"/search": OSM.Search(map),
|
"/search": OSM.Search(map),
|
||||||
"/export": OSM.Export(map),
|
"/export": OSM.Export(map),
|
||||||
"/history": history,
|
"/history": history,
|
||||||
|
"/new_note": OSM.NewNote(map),
|
||||||
"/user/:display_name/edits": history,
|
"/user/:display_name/edits": history,
|
||||||
"/browse/friends": history,
|
"/browse/friends": history,
|
||||||
"/browse/nearby": history,
|
"/browse/nearby": history,
|
||||||
|
|
144
app/assets/javascripts/index/new_note.js.erb
Normal file
144
app/assets/javascripts/index/new_note.js.erb
Normal file
|
@ -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;
|
||||||
|
}
|
|
@ -1,6 +1,3 @@
|
||||||
//= require templates/notes/show
|
|
||||||
//= require templates/notes/new
|
|
||||||
|
|
||||||
OSM.Note = function(map) {
|
OSM.Note = function(map) {
|
||||||
var noteLayer = map.noteLayer,
|
var noteLayer = map.noteLayer,
|
||||||
content = $('#sidebar_content'),
|
content = $('#sidebar_content'),
|
||||||
|
@ -66,7 +63,7 @@ OSM.Note = function(map) {
|
||||||
content.find("textarea").val('').trigger("input");
|
content.find("textarea").val('').trigger("input");
|
||||||
}
|
}
|
||||||
|
|
||||||
page.pushstate = page.popstate = function(path) {
|
page.pushstate = page.popstate = function() {
|
||||||
page.load();
|
page.load();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
//= require templates/notes/show
|
|
||||||
//= require templates/notes/new
|
|
||||||
|
|
||||||
function initializeNotes(map) {
|
function initializeNotes(map) {
|
||||||
var noteLayer = map.noteLayer,
|
var noteLayer = map.noteLayer,
|
||||||
notes = {},
|
notes = {},
|
||||||
|
@ -102,157 +99,4 @@ function initializeNotes(map) {
|
||||||
noteLoader = null;
|
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();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
|
|
@ -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>
|
|
20
app/views/browse/new_note.html.erb
Normal file
20
app/views/browse/new_note.html.erb
Normal file
|
@ -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>
|
|
@ -282,6 +282,7 @@ en:
|
||||||
edit: "Edit way"
|
edit: "Edit way"
|
||||||
note:
|
note:
|
||||||
title: "Note"
|
title: "Note"
|
||||||
|
new_note: "Add a note"
|
||||||
open_title: "Unresolved note: %{note_name}"
|
open_title: "Unresolved note: %{note_name}"
|
||||||
closed_title: "Resolved note: %{note_name}"
|
closed_title: "Resolved note: %{note_name}"
|
||||||
opened: "Opened"
|
opened: "Opened"
|
||||||
|
|
|
@ -110,6 +110,7 @@ OpenStreetMap::Application.routes.draw do
|
||||||
match '/browse/relation/:id/history' => 'browse#relation_history', :via => :get, :id => /\d+/
|
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/changeset/:id' => 'browse#changeset', :via => :get, :as => :changeset, :id => /\d+/
|
||||||
match '/browse/note/:id' => 'browse#note', :via => :get, :id => /\d+/, :as => "browse_note"
|
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' => 'changeset#list', :via => :get
|
||||||
match '/user/:display_name/edits/feed' => 'changeset#feed', :via => :get, :defaults => { :format => :atom }
|
match '/user/:display_name/edits/feed' => 'changeset#feed', :via => :get, :defaults => { :format => :atom }
|
||||||
match '/user/:display_name/notes' => 'notes#mine', :via => :get
|
match '/user/:display_name/notes' => 'notes#mine', :via => :get
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue