Commit 4aab8762 authored by Marco Gallardo's avatar Marco Gallardo
Browse files

Locator feature

added marker image for publisher, showing div for address, and added
functionality to close it when clicking 'X' image

showing marker image in publisher

renamed map-marker to locator

fixed style for map marker image in publisher

added locator.js to get user's location

loading google maps api

removed unecessary append and showing location next to publisher

moved location address inside div and  added image to close location

styled div location address an image to close location

removing location when clicking close image

cleaned code

cleaned code

showing loader while location is being obtained, translated normal js to
backbone structure, created locations db stuff, and removing location
div when clicking 'share'

refactored code; started to move code to backbone

refactored js code; moving functionality to backbone structure

created address function to make accessible address variable value

refactored locator.js

showing and removing location div from dom

created location; it belongs_to status_message

added location model and created association with status_message

added hidden field for location address and added respective code on js files to retrieve it on ajax call

saving location for status_message (post)

removing location when sharing

renamed locator backbone view to location, added template, showing
location, and saving lat and lng

prepared and added template to show location

added location to post model in order to have it accessible in backbone

retrieving location to show it in template

removed console.log XD

fixes when removing location

cleanind location_address hidden field when location is removed

more fixes; showing location when sharing

saving location just when it exists

created method to retrieve location address just when location was created

fixed issue about showing 'Near from' message when there was not any location

added style for location

cleaned code

renamed locator view

retrieving lat and lng from locator.js

saving lat and lng in location_coords

saving lat and lng

added style for input location_address

removed location_address  hidden field; the value will be taken directly from input with the location

replaced div with location for input; the user will be able to edit the place

avoiding submitting the form when pressing Enter key on new input for location

added missed spec file for location model

refactored location_view code

refactored location_view code

cleaned code

added sinon library for testing

added describes for new publisher's view functions

created test for destroyLocation function

added test for showLocation publisher view function

created test for avoidEnter publisher view function

removed unnecessary div

Created first test for locations view, added more specs, added Sinon.js,
and fixed issue with assets

loading locator.js for tests

moved location stuff to app/assets

moved locator.js and sinon.js to app/assets

fixed route for images

included locator.js to assets

fixed issue when post object is different than StatusMessage; also fixed issue with lat and lng

loading Sinon for specs

refactoring locator errorGettingposition and start replacing google maps stuff with OSM

added OpenLayers JS, osmlocator, and added them into the main js

changing the locator from Google to OSM instance

changing lat and lng value in the backbone view

removing google javascript tag in application layout

adding jasmine to locator test and removed locator.js

adding jasmine to locator test using OSM

adding Jasmine test to OSM locator

removed locator.js

removed require locator and updated schema

fixed js response; added location

since we are using OSM Locator we don't need locator-spec test

fixed spec for location view; we are not using google maps anymore

changed description of osmlocator-spec

fixed issue with status-message-location template

fixed style for location_address textbox

fixed tests for locator

moved split function to model

created test for location model

removed puts

added effect for location marker

added translations for locator

removed conflicting-unnecessary lines that were loading files for specs

removed sinon library; using sinon-rails gem

removed useless code

removed puts; added Rails.logger.error

added sinon.js file

added specific version of sinon-rails gem

improving validations sintax

using openlayers-rails gem

removed 'google API' text

using sinon gem

isolating LocationStream view

refactored validation

getting location when post is a Reshare

refactored code

fixed aligment for elements under location message

improved styling for location message

refactored begin-rescue block

getting absolute root instead of just the root

added address method to retrive address of location

removed code from Post model; also added descriptinon why it was removed

removed validation when retrieving address; with latest refactorizations we dont need them any more

interpolated location; using file in locales

fixed width for div of location

moved Sinon gem into development and test group

fixed method's description

added missed indexes

updated schema with locations table

removed openlayers-rails gem

preventing location to be saved if there are not coordinates

fixed spec; wrong closing tag
parent 3cd60c30
......@@ -160,7 +160,7 @@ group :development do
gem 'guard-rspec', '2.5.3'
gem 'rb-fsevent', '0.9.3', :require => false
gem 'rb-inotify', '0.9.0', :require => false
# Preloading environment
gem 'guard-spork', '1.5.0'
......@@ -197,4 +197,5 @@ group :development, :test do
# Jasmine (client side application tests (JS))
gem 'jasmine', '1.3.2'
gem 'sinon-rails', '1.4.2.1'
end
......@@ -211,7 +211,6 @@ GEM
rails
multi_json (1.7.2)
multipart-post (1.2.0)
mysql2 (0.3.11)
nested_form (0.3.2)
net-scp (1.1.0)
net-ssh (>= 2.6.5)
......@@ -241,6 +240,7 @@ GEM
multi_json (~> 1.3)
omniauth-oauth (~> 1.0)
orm_adapter (0.4.0)
pg (0.15.1)
polyglot (0.3.3)
pry (0.9.12)
coderay (~> 1.0.5)
......@@ -357,6 +357,8 @@ GEM
rack (~> 1.3, >= 1.3.6)
rack-protection (~> 1.2)
tilt (~> 1.3, >= 1.3.3)
sinon-rails (1.4.2.1)
railties (>= 3.1)
slim (1.3.8)
temple (~> 0.6.3)
tilt (~> 1.3.3)
......@@ -441,12 +443,12 @@ DEPENDENCIES
messagebus_ruby_api (= 1.0.3)
mini_magick (= 3.5)
mobile-fu (= 1.1.1)
mysql2 (= 0.3.11)
nokogiri (= 1.5.9)
omniauth (= 1.1.4)
omniauth-facebook (= 1.4.1)
omniauth-tumblr (= 1.1)
omniauth-twitter (= 0.0.16)
pg (= 0.15.1)
rack-cors (= 0.2.7)
rack-google-analytics (= 0.11.0)
rack-piwik (= 0.2.2)
......@@ -470,6 +472,7 @@ DEPENDENCIES
selenium-webdriver (= 2.32.1)
sidekiq (= 2.11.1)
sinatra (= 1.3.3)
sinon-rails (= 1.4.2.1)
slim (= 1.3.8)
spork (= 1.0.0rc3)
timecop (= 0.6.1)
......
......@@ -7,7 +7,8 @@ app.views.Content = app.views.Base.extend({
return _.extend(this.defaultPresenter(), {
text : app.helpers.textFormatter(this.model.get("text"), this.model),
largePhoto : this.largePhoto(),
smallPhotos : this.smallPhotos()
smallPhotos : this.smallPhotos(),
location: this.location()
});
},
......@@ -34,12 +35,16 @@ app.views.Content = app.views.Base.extend({
$(evt.currentTarget).hide();
},
location: function(){
var address = this.model.get('address')? this.model.get('address') : '';
return address;
},
collapseOversized : function() {
var collHeight = 200
, elem = this.$(".collapsible")
, oembed = elem.find(".oembed")
, addHeight = 0;
if($.trim(oembed.html()) != "") {
addHeight = oembed.height();
}
......@@ -100,4 +105,4 @@ app.views.OEmbed = app.views.Base.extend({
insertHTML.attr("src", insertHTML.attr("src") + paramSeparator + "autoplay=1");
this.$el.html(insertHTML);
}
})
\ No newline at end of file
});
app.views.LocationStream = app.views.Content.extend({
templateName: "status-message-location"
});
app.views.Location = Backbone.View.extend({
el: "#location",
initialize: function(){
this.render();
this.getLocation();
},
render: function(){
$(this.el).append('<img alt="delete location" src="/assets/ajax-loader.gif">');
},
getLocation: function(e){
element = this.el;
locator = new OSM.Locator();
locator.getAddress(function(address, latlng){
$(element).html('<input id="location_address" value="' + address + '"/>');
$('#location_coords').val(latlng.latitude + "," + latlng.longitude);
$(element).append('<a id="hide_location"><img alt="delete location" src="/assets/deletelabel.png"></a>');
});
},
});
......@@ -23,7 +23,10 @@ app.views.Publisher = Backbone.View.extend(_.extend(
"click .post_preview_button" : "createPostPreview",
"click .service_icon": "toggleService",
"textchange #status_message_fake_text": "handleTextchange",
"click .dropdown .dropdown_list li": "toggleAspect"
"click .dropdown .dropdown_list li": "toggleAspect",
"click #locator" : "showLocation",
"click #hide_location" : "destroyLocation",
"keypress #location_address" : "avoidEnter"
},
tooltipSelector: ".service_icon",
......@@ -79,7 +82,9 @@ app.views.Publisher = Backbone.View.extend(_.extend(
},
"aspect_ids" : serializedForm["aspect_ids[]"],
"photos" : serializedForm["photos[]"],
"services" : serializedForm["services[]"]
"services" : serializedForm["services[]"],
"location_address" : $("#location_address").val(),
"location_coords" : serializedForm["location[coords]"]
}, {
url : "/status_messages",
success : function() {
......@@ -94,6 +99,30 @@ app.views.Publisher = Backbone.View.extend(_.extend(
// clear state
this.clear();
// clear location
this.destroyLocation();
},
// creates the location
showLocation: function(){
if($('#location').length == 0){
$('#publisher_textarea_wrapper').after('<div id="location"></div>');
app.views.location = new app.views.Location();
}
},
// destroys the location
destroyLocation: function(){
if(app.views.location){
app.views.location.remove();
}
},
// avoid submitting form when pressing Enter key
avoidEnter: function(evt){
if(evt.keyCode == 13)
return false;
},
createPostPreview : function(evt) {
......
......@@ -7,7 +7,8 @@ app.views.StreamPost = app.views.Post.extend({
".likes" : "likesInfoView",
".comments" : "commentStreamView",
".post-content" : "postContentView",
".oembed" : "oEmbedView"
".oembed" : "oEmbedView",
".status-message-location" : "postLocationStreamView"
},
events: {
......@@ -47,6 +48,10 @@ app.views.StreamPost = app.views.Post.extend({
return new postClass({ model : this.model })
},
postLocationStreamView : function(){
return new app.views.LocationStream({ model : this.model});
},
removeNsfwShield: function(evt){
if(evt){ evt.preventDefault(); }
this.model.set({nsfw : false})
......
......@@ -9,4 +9,5 @@
//= require mobile
//= require profile
//= require people
//= require photos
\ No newline at end of file
//= require photos
//= require sinon
......@@ -42,3 +42,4 @@
//= require bootstrap-popover
//= require bootstrap-dropdown
//= require bootstrap-scrollspy-custom
//= require osmlocator
OSM = {};
OSM.Locator = function(){
var geolocalize = function(callback){
navigator.geolocation.getCurrentPosition(function(position) {
lat=position.coords.latitude;
lon=position.coords.longitude;
var display_name =$.getJSON("http://nominatim.openstreetmap.org/reverse?format=json&lat="+lat+"&lon="+lon+"&addressdetails=3", function(data){
return callback(data.display_name, position.coords);
});
},errorGettingPosition);
};
function errorGettingPosition(err) {
$("#location").remove();
};
return {
getAddress: geolocalize
}
}
......@@ -573,9 +573,22 @@ ul.as-selections
& > .likes, & > .comments
:margin-right 15px
.status-message-location
.near-from
:font-size smaller
:color #aaa
:width 100%
:float left
.address
:font-size 11px
:color #bbb
.stream_element .post-content .reshare
:border-left 2px solid #ddd
.stream_element.loaded .media .bd .feedback
:clear both
form.new_comment
input
:display none
......@@ -697,6 +710,8 @@ form p.checkbox_select
:height 100%
:width 100%
:cursor pointer
img
:margin-right 20px
#publisher
:z-index 1
......@@ -876,6 +891,8 @@ form p.checkbox_select
:position absolute
:bottom 0
:right 35px
:width 430px
:left 5px
:padding 0
li
......@@ -3120,3 +3137,46 @@ body
:bottom 3px solid #3f8fba !important
:background
:color #e8f7ff
#publisher-images
#locator
:bottom 1px !important
:display inline-block
:margin 0
:position absolute !important
:right 30px
:cursor pointer
img
:padding-top 2px
@include opacity(0.4)
&:hover
:color #666
:cursor pointer
img
@include opacity(0.8)
.btn
:height 19px
:width 19px
#location
:border 1px solid #999
:height 20px
#location_address
:border none
:color #aaa
:height 10px
:width 430px
:float left
a#hide_location
:position absolute
:right 22px
:filter alpha(opacity=30)
:-moz-opacity 0.3
:-khtml-opacity 0.3
:opacity 0.3
:z-index 5
a#hide_location:hover
@include opacity(0)
:-khtml-opacity 1
:opacity 1
:cursor pointer
{{#if location}}
<div class='near-from'>
{{ t "publisher.near_from" location=location}}
</div>
{{/if}}
......@@ -55,6 +55,7 @@
</div>
{{/if}}
<div class="post-content"> </div>
<div class="status-message-location"> </div>
<div class="feedback"> </div>
<div class="likes"> </div>
......
......@@ -46,6 +46,7 @@ class StatusMessagesController < ApplicationController
services = [*params[:services]].compact
@status_message = current_user.build_post(:status_message, params[:status_message])
@status_message.build_location(:address => params[:location_address], :coordinates => params[:location_coords]) if params[:location_address].present?
@status_message.attach_photos_by_ids(params[:photos])
if @status_message.save
......
class Location < ActiveRecord::Base
before_validation :split_coords, :on => :create
attr_accessor :coordinates
belongs_to :status_message
def split_coords
coordinates.present? ? (self.lat, self.lng = coordinates.split(',')) : false
end
end
......@@ -66,6 +66,10 @@ class Post < ActiveRecord::Base
def mentioned_people; []; end
def photos; []; end
#prevents error when trying to access @post.address in a post different than Reshare and StatusMessage types;
#check PostPresenter
def address
end
def self.excluding_blocks(user)
people = user.blocks.map{|b| b.person_id}
......
......@@ -79,6 +79,10 @@ class Reshare < Post
current
end
def address
absolute_root.location.try(:address)
end
private
def after_parse
......
......@@ -18,6 +18,8 @@ class StatusMessage < Post
has_many :photos, :dependent => :destroy, :foreign_key => :status_message_guid, :primary_key => :guid
has_one :location
# a StatusMessage is federated before its photos are so presence_of_content() fails erroneously if no text is present
# therefore, we put the validation in a before_destory callback instead of a validation
before_destroy :presence_of_content
......@@ -164,6 +166,10 @@ class StatusMessage < Post
self.oembed_url = urls.find{ |url| !TRUSTED_OEMBED_PROVIDERS.find(url).nil? }
end
def address
location.try(:address)
end
protected
def presence_of_content
unless text_and_photos_blank?
......
......@@ -33,6 +33,7 @@ class PostPresenter
:title => title,
:next_post => next_post_path,
:previous_post => previous_post_path,
:address => @post.address,
:interactions => {
:likes => [user_like].compact,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment