diff --git a/Gemfile b/Gemfile index 0d31318b8dc..e70ab2d89f0 100644 --- a/Gemfile +++ b/Gemfile @@ -57,7 +57,8 @@ gem "actionpack-page_caching" # Omniauth for authentication gem "omniauth" gem "omniauth-openid" -gem "openstreetmap-omniauth-google-oauth2", ">= 0.2.6.1", :require => "omniauth-google-oauth2" +gem "omniauth-google-oauth2" +#gem "openstreetmap-omniauth-google-oauth2", ">= 0.2.6.1", :require => "omniauth-google-oauth2" gem "omniauth-facebook" gem "omniauth-windowslive" @@ -85,6 +86,9 @@ gem "soap4r-ruby1.9" gem "dalli" gem "kgio" +# indexing city in algolia +gem "algoliasearch" + # Gems useful for development group :development do gem "vendorer" @@ -103,4 +107,5 @@ group :development, :test do gem "konacha" gem "poltergeist" gem "coveralls", :require => false + gem "pry-rails" end diff --git a/Gemfile.lock b/Gemfile.lock index a19d2e7fa60..b7d9229f9fe 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -39,6 +39,10 @@ GEM minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) + addressable (2.3.8) + algoliasearch (1.6.1) + httpclient (~> 2.4) + json (>= 1.5.1) arel (6.0.0) ast (2.0.0) astrolabe (1.3.0) @@ -59,6 +63,7 @@ GEM cliver (0.3.2) cocaine (0.5.7) climate_control (>= 0.0.3, < 1.0) + coderay (1.1.0) coffee-rails (4.1.0) coffee-script (>= 2.2.0) railties (>= 4.0.0, < 5.0) @@ -127,6 +132,7 @@ GEM nokogiri (>= 1.5.9) mail (2.6.3) mime-types (>= 1.16, < 3) + method_source (0.8.2) mime-types (2.6.1) mini_portile (0.6.2) minitest (5.7.0) @@ -155,6 +161,12 @@ GEM rack (~> 1.0) omniauth-facebook (2.0.1) omniauth-oauth2 (~> 1.2) + omniauth-google-oauth2 (0.2.8) + addressable (~> 2.3) + jwt (~> 1.0) + multi_json (~> 1.3) + omniauth (>= 1.1.1) + omniauth-oauth2 (>= 1.1.1) omniauth-oauth2 (1.3.0) oauth2 (~> 1.0) omniauth (~> 1.2) @@ -164,11 +176,6 @@ GEM omniauth-windowslive (0.0.9) multi_json (>= 1.0.3) omniauth-oauth2 (~> 1.0) - openstreetmap-omniauth-google-oauth2 (0.2.6.1) - jwt (~> 1.0) - multi_json (~> 1.3) - omniauth (>= 1.1.1) - omniauth-oauth2 (>= 1.1.1) paperclip (4.2.2) activemodel (>= 3.0.0) activesupport (>= 3.0.0) @@ -183,6 +190,12 @@ GEM multi_json (~> 1.0) websocket-driver (>= 0.2.0) powerpack (0.1.1) + pry (0.10.3) + coderay (~> 1.1.0) + method_source (~> 0.8.1) + slop (~> 3.4) + pry-rails (0.3.4) + pry (>= 0.9.10) psych (2.0.13) r2 (0.2.5) rack (1.6.2) @@ -252,6 +265,7 @@ GEM json (~> 1.8) simplecov-html (~> 0.10.0) simplecov-html (0.10.0) + slop (3.6.0) soap4r-ruby1.9 (2.0.5) sprockets (2.12.3) hike (~> 1.2) @@ -295,6 +309,7 @@ PLATFORMS DEPENDENCIES SystemTimer (>= 1.1.3) actionpack-page_caching + algoliasearch autoprefixer-rails bigdecimal (~> 1.1.0) coffee-rails (~> 4.1.0) @@ -319,12 +334,13 @@ DEPENDENCIES oauth-plugin (>= 0.5.1) omniauth omniauth-facebook + omniauth-google-oauth2 omniauth-openid omniauth-windowslive - openstreetmap-omniauth-google-oauth2 (>= 0.2.6.1) paperclip (~> 4.0) pg poltergeist + pry-rails psych r2 rack-cors @@ -341,3 +357,6 @@ DEPENDENCIES uglifier (>= 1.3.0) validates_email_format_of (>= 1.5.1) vendorer + +BUNDLED WITH + 1.10.6 diff --git a/app/assets/images/pin.svg b/app/assets/images/pin.svg new file mode 100644 index 00000000000..43bd920409b --- /dev/null +++ b/app/assets/images/pin.svg @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/app/assets/images/pin_disabled.svg b/app/assets/images/pin_disabled.svg new file mode 100644 index 00000000000..c24d9a33ca2 --- /dev/null +++ b/app/assets/images/pin_disabled.svg @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/app/assets/javascripts/index.js b/app/assets/javascripts/index.js index 5e437c6ec47..fbb4c9b0d35 100644 --- a/app/assets/javascripts/index.js +++ b/app/assets/javascripts/index.js @@ -8,6 +8,7 @@ //= require leaflet.polyline //= require leaflet.query //= require index/search +//= require index/search_algolia //= require index/browse //= require index/export //= require index/notes diff --git a/app/assets/javascripts/index/search_algolia.js b/app/assets/javascripts/index/search_algolia.js new file mode 100644 index 00000000000..01c8ce7a7ba --- /dev/null +++ b/app/assets/javascripts/index/search_algolia.js @@ -0,0 +1,128 @@ +// Component responsible for displaying the search results +var SearchResultComponent = function ( cities ){ + this.cities = cities; + this.container = $('#sidebar_content'); +} + +SearchResultComponent.prototype = { + + clear: function () { + this.container.html(""); + }, + + render: function ( cities ) { + + this.cities = cities; + this.container.css('display','block'); + this.clear(); + this.displayCities( this.cities ); + }, + + displayCity: function ( city ) { + + var country_code = city.country_code.toLowerCase(); + var search_result = $(" ") + search_result.attr( "href", "/#map=9/"+ city._geoloc.lat + "/" + city._geoloc.lng ); + flag = $("
") + block = $("

"+ city._highlightResult.name.value +"

" + city.country + "

") + flag.appendTo(search_result); + block.appendTo(search_result); + search_result.on('click', function ( e ){ + $('.query_wrapper input').val(city.name); + }); + search_result.appendTo(this.container); + + }, + + displayCities: function ( cities ) { + if (cities.length == 0 ) { + this.displayNoResults(); + return; + } + + cities.forEach( function ( city ){ + this.displayCity( city ); + }.bind(this)) + }, + + displayNoResults: function (){ + this.container.html("
No city found...
") + } +} + +//initalizer for Algoliasearch +var SearchProxy = function ( ){ + this.client = algoliasearch('3OGRF9NUBE', '1760f1ce147927dfcbe506dc64a822a3'); + this.index = this.client.initIndex('cities_v2'); +} + +SearchComponent = function ( resultComponent ){ + + this.resultComponent = resultComponent; + this.search_input = $('.query_wrapper input'); + this.pin = $('.query_wrapper .pin'); + this.geolocation = false; + this.searchProxy = new SearchProxy(); + +} + +SearchComponent.prototype = { + + init: function() { + // Clear result on focus + this.search_input.on('focus', function ( e ){ + this.resultComponent.clear(); + + }.bind(this)) + + // Auto complete search on keyup + this.search_input.on('keyup', function( e ) { + var query = $(e.target).val(); + this.query = query; + this.refresh(); + + }.bind(this)) + + this.pin.on('click', function ( e ){ + this.toggleGeolocation(); + this.refresh(); + + }.bind(this)) + + }, + + refresh: function (){ + this.search( this.query, this.geolocation ); + + if ( !this.geolocation ) { + this.pin.addClass('disabled'); + } else { + this.pin.removeClass('disabled'); + } + }, + + search: function( query, geoloc ) { + this.query = query; + this.searchProxy.index.search(query, { aroundLatLngViaIP: geoloc, hitsPerPage: 10, page: 0 }, function(err, hits) { + this.resultComponent.render( hits.hits ); + }.bind(this)); + }, + + toggleGeolocation: function (){ + this.geolocation = !this.geolocation + this.refresh(); + + } +} + + +$(document).ready( function ( ){ + + var resultComponent = new SearchResultComponent() + //var search = new SearchProxy(); + var searchComponent = new SearchComponent( resultComponent ); + searchComponent.init(); + + + +}) diff --git a/app/assets/stylesheets/common.scss b/app/assets/stylesheets/common.scss index 21cecaf4aa6..0182d924f25 100644 --- a/app/assets/stylesheets/common.scss +++ b/app/assets/stylesheets/common.scss @@ -1,4 +1,5 @@ @import "parameters"; +@import "search"; /* Styles common to large and small screens */ diff --git a/app/assets/stylesheets/search.scss b/app/assets/stylesheets/search.scss new file mode 100644 index 00000000000..d8ee550919c --- /dev/null +++ b/app/assets/stylesheets/search.scss @@ -0,0 +1,68 @@ + + + +.search_forms { + .query_wrapper input { + + border: #eee 0.5px; + font-size: 20px; + background: #eee; + width: 80% !important; + &:focus { + box-shadow: none; + } + } + .pin { + float: right; + height: 30px; + width: 30px; + background-image: image-url("pin.svg"); + background-size: 30px 30px; + &.disabled { + background-image: image-url("pin_disabled.svg"); + } + } + +} +#sidebar_content { + + .search_results { + display: block; + color: black; + + &:hover { + background-color: #eee; + text-decoration: none + } + height: 50px; + overflow: hidden; + border-bottom: 1px solid #eee; + + .flag { + float: left; + padding: 13px; + } + + .city { + padding-left: 50px; + padding-top: 3px; + + .name { + em { + background-color: rgba(69, 69, 214, 0.07); + } + } + .country { + color: #999; + } + } + .noresults { + padding: 10px; + padding-left: 30px; + font-weight: bold; + } + } + +} + + diff --git a/app/views/layouts/_search_algolia.html.erb b/app/views/layouts/_search_algolia.html.erb new file mode 100644 index 00000000000..7416a9f514f --- /dev/null +++ b/app/views/layouts/_search_algolia.html.erb @@ -0,0 +1,31 @@ +<% content_for :head do %> + <%= javascript_include_tag "//cdn.jsdelivr.net/algoliasearch/3/algoliasearch.min.js" %> +<% end %> + +
+
+
+
+ <%= text_field_tag "query", params[:query], :placeholder => t("site.search.search"), :autofocus => autofocus, :class => 'overflow' , :autocomplete => 'off' %> +
+
+ +
+
+ +
+ <%= image_tag "marker-green.png", :class => "routing_marker", :data => { :type => "from" }, :draggable => "true" %> + <%= text_field_tag "route_from", params[:from], :placeholder => t('site.search.from') %> +
+
+ <%= image_tag "marker-red.png", :class => "routing_marker", :data => { :type => "to" }, :draggable => "true" %> + <%= text_field_tag "route_to" , params[:to] , :placeholder => t('site.search.to') %> +
+
+ + <%= submit_tag t('site.search.submit_text'), :class => "routing_go" %> +
+ +
<%= image_tag "searching.gif" %>
+
+
diff --git a/app/views/layouts/map.html.erb b/app/views/layouts/map.html.erb index 6ae087b06d7..c72ac871137 100644 --- a/app/views/layouts/map.html.erb +++ b/app/views/layouts/map.html.erb @@ -17,12 +17,12 @@ <% end %> <% content_for :header do %> - <%= render :partial => "layouts/search", :locals => { :autofocus => false } %> + <%= render :partial => "layouts/search_algolia", :locals => { :autofocus => false } %> <% end %> <% content_for :content do %>