aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2016-01-23 23:34:30 +0900
committerKazuki Yamaguchi <k@rhe.jp>2016-01-23 23:34:30 +0900
commit841e9796cdeda4288675a3df7b2e984454698a49 (patch)
tree494e7071b4efcf4d9ca999e718edaaa04475afab
parentc3d4489f007ecd22328c90e4dbcf873776014735 (diff)
downloadaclog-841e9796cdeda4288675a3df7b2e984454698a49.tar.gz
web: get rid of page=x in user/public best
-rw-r--r--app/controllers/tweets_controller.rb74
-rw-r--r--app/models/tweet.rb14
-rw-r--r--frontend/src/lib/aclog.js44
3 files changed, 64 insertions, 68 deletions
diff --git a/app/controllers/tweets_controller.rb b/app/controllers/tweets_controller.rb
index 29eb603..5cfaf3e 100644
--- a/app/controllers/tweets_controller.rb
+++ b/app/controllers/tweets_controller.rb
@@ -27,39 +27,39 @@ class TweetsController < ApplicationController
end
def user_best
- @tweets = @user.tweets.reacted.parse_recent(params[:recent]).order_by_reactions.paginate(params)
- render_tweets
+ @tweets = @user.tweets.reacted.parse_recent(params[:recent]).order_by_reactions
+ render_tweets(:reactions_count)
end
def user_timeline
- @tweets = @user.tweets.reacted(params[:reactions]).order_by_id.paginate(params)
- render_tweets
+ @tweets = @user.tweets.reacted(params[:reactions]).order_by_id
+ render_tweets(:id)
end
def user_favorites
- @tweets = Tweet.reacted(params[:reactions]).favorited_by(@user).order("favorites.id DESC").includes(user: :account).paginate(params)
- render_tweets
+ @tweets = Tweet.reacted(params[:reactions]).favorited_by(@user).order("favorites.id DESC").includes(user: :account)
+ render_tweets(:page)
end
def user_favorited_by
@source_user = authorize! User.find(screen_name: params[:source_screen_name])
- @tweets = @user.tweets.reacted(params[:reactions]).favorited_by(@source_user).order("favorites.tweet_id DESC").paginate(params)
- render_tweets
+ @tweets = @user.tweets.reacted(params[:reactions]).favorited_by(@source_user).order("favorites.tweet_id DESC")
+ render_tweets(:id)
end
def all_best
- @tweets = Tweet.reacted.parse_recent(params[:recent]).order_by_reactions.includes(user: :account).paginate(params)
- render_tweets
+ @tweets = Tweet.reacted.parse_recent(params[:recent]).order_by_reactions.includes(user: :account)
+ render_tweets(:reactions_count)
end
def all_timeline
- @tweets = Tweet.reacted(params[:reactions]).order_by_id.includes(user: :account).paginate(params)
- render_tweets
+ @tweets = Tweet.reacted(params[:reactions]).order_by_id.includes(user: :account)
+ render_tweets(:id)
end
def filter
- @tweets = Tweet.recent((params[:period] || 7).days).filter_by_query(params[:q].to_s).order_by_id.includes(user: :account).paginate(params)
- render_tweets
+ @tweets = Tweet.recent((params[:period] || 7).days).filter_by_query(params[:q].to_s).order_by_id.includes(user: :account)
+ render_tweets(:id)
end
private
@@ -77,27 +77,37 @@ class TweetsController < ApplicationController
statuses: sts }
end
- def render_tweets
- if request.format.atom?
- return render("tweets")
+ def paginate_tweets(type)
+ qhash = Rack::Utils.parse_query(request.query_string)
+ page_per = params[:count] ? [params[:count].to_i, Settings.tweets.count.max].min : Settings.tweets.count.default
+
+ case type
+ when :id
+ @tweets = @tweets.limit(page_per).max_id(params[:max_id]).since_id(params[:since_id])
+ { prev: qhash.merge(since_id: @tweets.first.id.to_s, max_id: ""),
+ next: qhash.merge(since_id: "", max_id: (@tweets.last.id - 1).to_s) }
+ when :reactions_count
+ @tweets = @tweets.limit(page_per).not_reacted_than(params[:last_reactions], params[:last_id])
+ { next: qhash.merge(last_reactions: @tweets.last.reactions_count, last_id: @tweets.last.id.to_s) }
+ when :page
+ page = [params[:page].to_i, 1].max
+ @tweets = @tweets.page(page, page_per)
+ { prev: page == 1 ? nil : params.merge(page: page - 1),
+ next: params.merge(page: page + 1) }
end
+ end
- hash = {
- user: @user.as_json(methods: :registered),
- statuses: @tweets.map(&method(:transform_tweet)) }
-
- if @tweets.length > 0
- if !params[:page] && @tweets.order_values.all? {|o| !o.is_a?(String) && o.expr.name == :id }
- hash[:prev] = params.dup.tap {|h| h.delete(:max_id) }.merge!(since_id: @tweets.first.id.to_s)
- hash[:next] = params.dup.tap {|h| h.delete(:since_id) }.merge!(max_id: (@tweets.last.id - 1).to_s)
- else
- page = [params[:page].to_i, 1].max
- hash[:prev] = page == 1 ? nil : params.merge(page: page - 1)
- hash[:next] = params.merge(page: page + 1)
- end
- end
+ def render_tweets(pagination)
+ qhash = paginate_tweets(pagination)
- render_json data: hash
+ if request.format.atom?
+ render "tweets"
+ else
+ qhash.merge!(user: @user.as_json(methods: :registered),
+ statuses: @tweets.map(&method(:transform_tweet)))
+
+ render_json data: qhash
+ end
end
def transform_tweet(tweet)
diff --git a/app/models/tweet.rb b/app/models/tweet.rb
index 9dbb289..ba39f78 100644
--- a/app/models/tweet.rb
+++ b/app/models/tweet.rb
@@ -17,24 +17,14 @@ class Tweet < ActiveRecord::Base
scope :max_id, ->(id) { where("tweets.id <= ?", id.to_i) if id }
scope :since_id, ->(id) { where("tweets.id > ?", id.to_i) if id }
+ scope :not_reacted_than, ->(last_count, last_id) { where("reactions_count < ? OR (reactions_count = ? AND id < ?)", last_count, last_count, last_id) if last_count }
scope :page, ->(page, page_per) { limit(page_per).offset((page - 1) * page_per) }
scope :order_by_id, -> { order(id: :desc) }
- scope :order_by_reactions, -> { order(reactions_count: :desc) }
+ scope :order_by_reactions, -> { order(reactions_count: :desc, id: :desc) }
scope :favorited_by, ->(user) { joins(:favorites).where(favorites: { user: user }) }
- # should be called in last
- scope :paginate, ->(params) {
- page_per = params[:count] ? [params[:count].to_i, Settings.tweets.count.max].min : Settings.tweets.count.default
-
- if !params[:page] && self.all.order_values.all? {|o| !o.is_a?(String) && o.expr.name == :id }
- limit(page_per).max_id(params[:max_id]).since_id(params[:since_id])
- else
- page([params[:page].to_i, 1].max, page_per)
- end
- }
-
class << self
# Builds a new instance of Tweet and initialize with JSON data from Twitter API.
# @note This method just builds an instance, doesn't save it.
diff --git a/frontend/src/lib/aclog.js b/frontend/src/lib/aclog.js
index 1e7ec6d..b41f459 100644
--- a/frontend/src/lib/aclog.js
+++ b/frontend/src/lib/aclog.js
@@ -2,7 +2,7 @@ import Settings from "../../settings";
import Storage from "storage";
import utils from "utils";
-var encodeQuery = (params) => {
+var encodeQuery = params => {
if (!params) return "";
var keys = Object.keys(params);
if (keys.length === 0) return "";
@@ -10,8 +10,23 @@ var encodeQuery = (params) => {
return keys.map(key => [key, params[key]].map(encodeURIComponent).join("=")).join("&");
}
-var continueRequest = promise => {
- return promise.then(res => res.json().then(json => [res, json])).then(xx => {
+var request = (method, endpoint, params, body) => {
+ if (Settings.debug) console.log("[API Request] " + method + " " + endpoint + " query: " + encodeQuery(params) + " body: " + encodeQuery(body));
+ var url = utils.getCurrentBaseUrl() + "/i/api/" + endpoint + ".json";
+ var opts = {
+ method: method,
+ credentials: "include",
+ headers: { },
+ };
+
+ if (method === "post") {
+ opts.headers["content-type"] = "application/x-www-form-urlencoded; charset=UTF-8";
+ opts.body = encodeQuery(Object.assign({ authenticity_token: Storage.store.authenticity_token }, body));
+ } else {
+ url += "?" + encodeQuery(params);
+ }
+
+ return fetch(url, opts).then(res => res.json().then(json => [res, json])).then(xx => {
var [res, json] = xx;
if (res.status >= 400) {
var error = new Error(res.statusText);
@@ -24,27 +39,8 @@ var continueRequest = promise => {
});
};
-var get = (endpoint, params) => {
- if (Settings.debug) console.log("[API Request] " + endpoint + " query: " + encodeQuery(params));
- var url = utils.getCurrentBaseUrl() + "/i/api/" + endpoint + ".json?" + encodeQuery(params);
- return continueRequest(fetch(url, {
- method: "get",
- credentials: "include",
- }));
-}
-
-var post = (endpoint, body) => {
- if (Settings.debug) console.log("[API Request] " + endpoint + " body: " + encodeQuery(body));
- var url = utils.getCurrentBaseUrl() + "/i/api/" + endpoint + ".json";
- return continueRequest(fetch(url, {
- method: "post",
- credentials: "include",
- headers: {
- "content-type": "application/x-www-form-urlencoded; charset=UTF-8"
- },
- body: encodeQuery(Object.assign({ authenticity_token: Storage.store.authenticity_token }, body))
- }));
-}
+var get = (endpoint, params) => request("get", endpoint, params, null);
+var post = (endpoint, body) => request("post", endpoint, null, body);
export default {
users: {