diff --git a/Gemfile b/Gemfile index 6a114b9..10683f7 100644 --- a/Gemfile +++ b/Gemfile @@ -70,6 +70,8 @@ gem 'jquery-rails' gem 'twitter-bootstrap-rails' gem "high_voltage" +gem "will_paginate_mongoid" +gem 'bootstrap-will_paginate' gem "nokogiri" diff --git a/Gemfile.lock b/Gemfile.lock index af24f4d..e4a4716 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -53,6 +53,8 @@ GEM bbenezech-nested_form (0.0.6) bcrypt-ruby (3.0.1) bootstrap-sass (2.0.4.2) + bootstrap-will_paginate (0.0.9) + will_paginate bson (1.6.2) bson_ext (1.6.2) bson (~> 1.6.2) @@ -286,6 +288,10 @@ GEM uuidtools (2.1.3) warden (1.2.1) rack (>= 1.0) + will_paginate (3.0.4) + will_paginate_mongoid (1.1.0) + mongoid (>= 2.4) + will_paginate (~> 3.0) yajl-ruby (1.1.0) PLATFORMS @@ -293,6 +299,7 @@ PLATFORMS DEPENDENCIES aws-sdk + bootstrap-will_paginate bson_ext coffee-rails (~> 3.2.1) compass-rails @@ -331,4 +338,5 @@ DEPENDENCIES twitter-bootstrap-rails uglifier (>= 1.0.3) unicorn + will_paginate_mongoid yajl-ruby diff --git a/app/assets/images/load.gif b/app/assets/images/load.gif new file mode 100644 index 0000000..1572476 Binary files /dev/null and b/app/assets/images/load.gif differ diff --git a/app/assets/javascripts/ads.js.coffee b/app/assets/javascripts/ads.js.coffee index 6015e9c..3fe5145 100644 --- a/app/assets/javascripts/ads.js.coffee +++ b/app/assets/javascripts/ads.js.coffee @@ -25,4 +25,6 @@ column_count++ return ) + if options.doNotDelete != true then $("#post_list").empty() + return grid diff --git a/app/assets/javascripts/libs/jquery.pageless.js b/app/assets/javascripts/libs/jquery.pageless.js new file mode 100644 index 0000000..df3bbba --- /dev/null +++ b/app/assets/javascripts/libs/jquery.pageless.js @@ -0,0 +1,210 @@ +// https://raw.github.com/jney/jquery.pageless/master/lib/jquery.pageless.js +// +// ======================================================================= +// PageLess - endless page +// +// Pageless is a jQuery plugin. +// As you scroll down you see more results coming back at you automatically. +// It provides an automatic pagination in an accessible way : if javascript +// is disabled your standard pagination is supposed to work. +// +// Licensed under the MIT: +// http://www.opensource.org/licenses/mit-license.php +// +// Parameters: +// currentPage: current page (params[:page]) +// distance: distance to the end of page in px when ajax query is fired +// loader: selector of the loader div (ajax activity indicator) +// loaderHtml: html code of the div if loader not used +// loaderImage: image inside the loader +// loaderMsg: displayed ajax message +// pagination: selector of the paginator divs. +// if javascript is disabled paginator is provided +// params: paramaters for the ajax query, you can pass auth_token here +// totalPages: total number of pages +// url: URL used to request more data +// method: HTML method for call URL, default - get +// +// Callback Parameters: +// scrape: A function to modify the incoming data. +// complete: A function to call when a new page has been loaded (optional) +// end: A function to call when the last page has been loaded (optional) +// +// Usage: +// $('#results').pageless({ totalPages: 10 +// , url: '/articles/' +// , loaderMsg: 'Loading more results' +// }); +// +// Requires: jquery +// +// Author: Jean-Sébastien Ney (https://github.com/jney) +// +// Contributors: +// Alexander Lang (https://github.com/langalex) +// Lukas Rieder (https://github.com/Overbryd) +// Kathryn Reeve (https://github.com/BinaryKitten) +// +// Thanks to: +// * codemonky.com/post/34940898 +// * www.unspace.ca/discover/pageless/ +// * famspam.com/facebox +// ======================================================================= + +(function($) { + + var FALSE = !1 + , TRUE = !FALSE + , element + , isLoading = FALSE + , loader + , namespace = '.pageless' + , SCROLL = 'scroll' + namespace + , RESIZE = 'resize' + namespace + , settings = { container: window + , currentPage: 1 + , distance: 100 + , pagination: '.pagination' + , params: {} + , url: location.href + , loaderImage: "/images/load.gif" + , method: 'get' + } + , container + , $container; + + $.pageless = function(opts) { + $.isFunction(opts) ? opts.call() : init(opts); + }; + + $.pagelessReset = function() { + settings = { container: window + , currentPage: 1 + , distance: 100 + , pagination: '.pagination' + , params: {} + , url: location.href + , loaderImage: "/images/load.gif" + , method: 'get' + }; + stopListener(); + // if there is a afterStopListener callback we call it + if (settings.end) settings.end.call(); + }; + + var loaderHtml = function () { + return settings.loaderHtml || '\ +'; + }; + + // settings params: totalPages + var init = function (opts) { + if (settings.inited) return; + settings.inited = TRUE; + + if (opts) $.extend(settings, opts); + + container = settings.container; + $container = $(container); + + // for accessibility we can keep pagination links + // but since we have javascript enabled we remove pagination links + if(settings.pagination) $(settings.pagination).remove(); + + // start the listener + startListener(); + }; + + $.fn.pageless = function (opts) { + var $el = $(this) + , $loader = $(opts.loader, $el); + + init(opts); + element = $el; + + // loader element + if (opts.loader && $loader.length) { + loader = $loader; + } else { + loader = $(loaderHtml()); + $el.append(loader); + // if we use the default loader, set the message + if (!opts.loaderHtml) { + $('#pageless-loader .msg').html(opts.loaderMsg).css(opts.msgStyles || {}); + } + } + }; + + // + var loading = function (bool) { + (isLoading = bool) + ? (loader && loader.fadeIn('normal')) + : (loader && loader.fadeOut('normal')); + }; + + // distance to end of the container + var distanceToBottom = function () { + return (container === window) + ? $(document).height() + - $container.scrollTop() + - $container.height() + : $container[0].scrollHeight + - $container.scrollTop() + - $container.height(); + }; + + var stopListener = function() { + $container.unbind(namespace); + }; + + // * bind a scroll event + // * trigger is once in case of reload + var startListener = function() { + $container.bind(SCROLL+' '+RESIZE, watch) + .trigger(SCROLL); + }; + + var watch = function() { + // listener was stopped or we've run out of pages + if (settings.totalPages <= settings.currentPage) { + stopListener(); + // if there is a afterStopListener callback we call it + if (settings.end) settings.end.call(); + return; + } + + // if slider past our scroll offset, then fire a request for more data + if(!isLoading && (distanceToBottom() < settings.distance)) { + loading(TRUE); + // move to next page + settings.currentPage++; + // set up ajax query params + $.extend( settings.params + , { page: settings.currentPage }); + // finally ajax query + if (settings.method == 'post') { + $.post( settings.url + , settings.params + , function (data) { + $.isFunction(settings.scrape) ? settings.scrape(data) : data; + loader ? loader.before(data) : element.append(data); + loading(FALSE); + // if there is a complete callback we call it + if (settings.complete) settings.complete.call(); + }, 'html'); + } else { + $.get( settings.url + , settings.params + , function (data) { + $.isFunction(settings.scrape) ? settings.scrape(data) : data; + loader ? loader.before(data) : element.append(data); + loading(FALSE); + if (settings.complete) settings.complete.call(); + }, 'html'); + } + } + }; +})(jQuery); \ No newline at end of file diff --git a/app/controllers/ads_controller.rb b/app/controllers/ads_controller.rb index bc0765d..3363c4f 100644 --- a/app/controllers/ads_controller.rb +++ b/app/controllers/ads_controller.rb @@ -22,7 +22,7 @@ def index end end - pp @ads #DEBUG + # pp @ads #DEBUG else # nope, no search, normal index if @category @ads = @category.all_ads @@ -33,7 +33,14 @@ def index end respond_to do |format| - format.html + format.html { + @ads = @ads.paginate(:per_page => 16, :page => params[:page]) + if request.xhr? + render partial: @ads + else + render "index" + end + } format.json { render json: @ads, except: [:admin_token, :email, :publish_email, :user_id] } format.atom end @@ -112,6 +119,7 @@ def set_youtube_thumbnail (ad) if ad.photo.blank? video = extract_youtube_videos(ad.text).first ad.alternative_thumbnail_url = video.thumbnail_url unless video.blank? || video.thumbnail_url.blank? + params[:ad][:alternative_thumbnail_url] = ad.alternative_thumbnail_url end end diff --git a/app/helpers/ads_helper.rb b/app/helpers/ads_helper.rb index ec0bf3b..26b26b0 100644 --- a/app/helpers/ads_helper.rb +++ b/app/helpers/ads_helper.rb @@ -4,4 +4,33 @@ def convert_links(html_string) "#{url}" end end + + # https://github.com/jney/jquery.pageless + def pageless(total_pages, url=nil, container=nil) + content_for :javascript do + js = <<-JS + + JS + js.html_safe + end + end + + end diff --git a/app/models/ad.rb b/app/models/ad.rb index 7a6e909..1b8df12 100644 --- a/app/models/ad.rb +++ b/app/models/ad.rb @@ -7,6 +7,8 @@ class Ad include Tire::Model::Search include Tire::Model::Callbacks + + attr_protected :views mapping do indexes :id, :index => :not_analyzed diff --git a/app/views/ads/index.html.erb b/app/views/ads/index.html.erb index 406f35f..24e2d2a 100644 --- a/app/views/ads/index.html.erb +++ b/app/views/ads/index.html.erb @@ -36,14 +36,16 @@ <% if @ads.count == 0 %>

<%= t ".no_entries" %>

<% end %> -
- +
+
+
+<%= will_paginate(@ads) %> <% content_for :head, auto_discovery_link_tag(:atom, params.merge({format: :atom, locale: nil}), {title: "iUPB Kleinanzeigen #{@category ? "("+@category.name+")" : "Feed"}"}) %> @@ -51,8 +53,9 @@ <% content_for :javascript do %> -<% end %> \ No newline at end of file +<% end %> + +<% pageless(@ads.total_pages, ads_path, "#post_list") %> \ No newline at end of file diff --git a/config/initializers/requires.rb b/config/initializers/requires.rb index e40f371..5499b15 100644 --- a/config/initializers/requires.rb +++ b/config/initializers/requires.rb @@ -1,4 +1,5 @@ require 'digest/md5' require 'ipaddr' require 'ostruct' -require "oembed" \ No newline at end of file +require "oembed" +require 'will_paginate/array' # https://github.com/mislav/will_paginate/issues/163#issuecomment-1837948 \ No newline at end of file diff --git a/config/locales/recaptcha.yml b/config/locales/gems.yml similarity index 65% rename from config/locales/recaptcha.yml rename to config/locales/gems.yml index 340f135..4ad807d 100644 --- a/config/locales/recaptcha.yml +++ b/config/locales/gems.yml @@ -5,6 +5,11 @@ en: errors: incorrect-captcha-sol: 'Invalid Captcha code' + will_paginate: + previous_label: Previous + previous_label: Next + + de: @@ -14,5 +19,8 @@ de: errors: incorrect-captcha-sol: 'Ungültiger Captcha-Code' + will_paginate: + previous_label: "Zurück" + previous_label: Weiter + -