From b2700774e306da9311ea5c11a874a49e7aaa91f9 Mon Sep 17 00:00:00 2001 From: rhenium Date: Fri, 30 Jan 2015 09:06:14 +0900 Subject: web: rewrite javascripts with coffeescript --- app/assets/javascripts/_define_application.coffee | 5 ++++ app/assets/javascripts/_define_application.js | 7 ----- app/assets/javascripts/_helpers.coffee.erb | 18 ++++++++++++ app/assets/javascripts/_helpers.js.erb | 25 ----------------- app/assets/javascripts/_html-autoload.coffee | 27 ++++++++++++++++++ app/assets/javascripts/_html-autoload.js | 32 --------------------- app/assets/javascripts/apidocs.coffee | 10 +++++++ app/assets/javascripts/apidocs.js | 13 --------- app/assets/javascripts/application.coffee | 21 ++++++++++++++ app/assets/javascripts/application.js.erb | 24 ---------------- app/assets/javascripts/layouts.coffee | 24 ++++++++++++++++ app/assets/javascripts/layouts.js.erb | 34 ----------------------- app/assets/javascripts/tweets.coffee | 22 +++++++++++++++ app/assets/javascripts/tweets.js.erb | 33 ---------------------- app/controllers/tweets_controller.rb | 3 +- app/controllers/users_controller.rb | 2 +- config/routes.rb | 6 ++-- 17 files changed, 132 insertions(+), 174 deletions(-) create mode 100644 app/assets/javascripts/_define_application.coffee delete mode 100644 app/assets/javascripts/_define_application.js create mode 100644 app/assets/javascripts/_helpers.coffee.erb delete mode 100644 app/assets/javascripts/_helpers.js.erb create mode 100644 app/assets/javascripts/_html-autoload.coffee delete mode 100644 app/assets/javascripts/_html-autoload.js create mode 100644 app/assets/javascripts/apidocs.coffee delete mode 100644 app/assets/javascripts/apidocs.js create mode 100644 app/assets/javascripts/application.coffee delete mode 100644 app/assets/javascripts/application.js.erb create mode 100644 app/assets/javascripts/layouts.coffee delete mode 100644 app/assets/javascripts/layouts.js.erb create mode 100644 app/assets/javascripts/tweets.coffee delete mode 100644 app/assets/javascripts/tweets.js.erb diff --git a/app/assets/javascripts/_define_application.coffee b/app/assets/javascripts/_define_application.coffee new file mode 100644 index 0000000..b09dd19 --- /dev/null +++ b/app/assets/javascripts/_define_application.coffee @@ -0,0 +1,5 @@ +if window.Application is undefined + window.Application = + Views: {} + Helpers: {} + Partials: {} diff --git a/app/assets/javascripts/_define_application.js b/app/assets/javascripts/_define_application.js deleted file mode 100644 index c91c7ae..0000000 --- a/app/assets/javascripts/_define_application.js +++ /dev/null @@ -1,7 +0,0 @@ -if (this.Application === undefined) { - this.Application = { - Views: {}, - Helpers: {}, - Partials: {} - }; -} diff --git a/app/assets/javascripts/_helpers.coffee.erb b/app/assets/javascripts/_helpers.coffee.erb new file mode 100644 index 0000000..65d15b7 --- /dev/null +++ b/app/assets/javascripts/_helpers.coffee.erb @@ -0,0 +1,18 @@ +Application.Helpers = + controller: () -> $("body").data("controller") + action: () -> $("body").data("action") + user_id: () -> $("body").data("user-id") + tweet_id: () -> $("body").data("tweet-id") + rescue_profile_image: (range) -> + $("img.twitter-icon", range).each () -> + $(this).on "error", () -> + this.src = '<%= image_path("profile_image_missing.png") %>' + localize_time: (range) -> + $("time", range).each () -> + $(this).text(new Date($(this).attr("datetime")).toLocaleString()) + call_api: (endpoint, params, callback) -> + $.getJSON "/i/api/" + endpoint, params, (json) -> + if json.error + throw "api unsuccessful: " + json.error.message + else + callback(json) diff --git a/app/assets/javascripts/_helpers.js.erb b/app/assets/javascripts/_helpers.js.erb deleted file mode 100644 index 49b8161..0000000 --- a/app/assets/javascripts/_helpers.js.erb +++ /dev/null @@ -1,25 +0,0 @@ -Application.Helpers = { - controller: function() { return $("body").data("controller"); }, - action: function() { return $("body").data("action"); }, - user_id: function() { return $("body").data("user-id"); }, - tweet_id: function() { return $("body").data("tweet-id"); }, - rescue_profile_image: function(range) { - $("img.twitter-icon", range).each(function() { - $(this).on("error", function() { this.src = '<%= image_path("profile_image_missing.png") %>'; }); - }); - }, - localize_time: function(range) { - $("time", range).each(function() { - $(this).text(new Date($(this).attr("datetime")).toLocaleString()); - }); - }, - call_api: function(endpoint, params, callback) { - $.getJSON("/api/internal/" + endpoint, params, function(json) { - if (json.error) { - throw "api unsuccessful: " + json.error.message; - } else { - callback(json); - } - }); - }, -}; diff --git a/app/assets/javascripts/_html-autoload.coffee b/app/assets/javascripts/_html-autoload.coffee new file mode 100644 index 0000000..3ba2c99 --- /dev/null +++ b/app/assets/javascripts/_html-autoload.coffee @@ -0,0 +1,27 @@ +$ -> + loading = false + opts = null + + $.autopager = (_opts) -> + defaults = + content: $("#content") + link: $("link[rel=next]") + onStart: -> + onReceived: (obj) -> + onComplete: -> + opts = $.extend({}, defaults, _opts) + + $(window).scroll -> + if (opts.content.offset().top + opts.content.height()) - ($(document).scrollTop() + $(window).height()) < 100 + if loading || !opts.link || !opts.link.attr("href") + return + + opts.onStart() + loading = true + $.getJSON opts.link.attr("href"), (json, status) -> + obj = $(json.html) + opts.onReceived(obj) + opts.content.append(obj) + opts.link.attr("href", json.next_url) + loading = false + opts.onComplete() diff --git a/app/assets/javascripts/_html-autoload.js b/app/assets/javascripts/_html-autoload.js deleted file mode 100644 index 1f56e86..0000000 --- a/app/assets/javascripts/_html-autoload.js +++ /dev/null @@ -1,32 +0,0 @@ -(function($) { - var loading = false; - var opts = null; - - $.autopager = function(_opts) { - var defaults = { - content: $("#content"), - link: $("link[rel=next]"), - onStart: function() { }, - onReceived: function(obj) { }, - onComplete: function() { } - }; - opts = $.extend({}, defaults, _opts); - - $(window).scroll(function() { - if ((opts.content.offset().top + opts.content.height()) - ($(document).scrollTop() + $(window).height()) < 100) { - if (loading || !opts.link || !opts.link.attr("href")) return; - - opts.onStart(); - loading = true; - $.getJSON(opts.link.attr("href"), function(json, status) { - var obj = $(json.html) - opts.onReceived(obj); - opts.content.append(obj); - opts.link.attr("href", json.next_url); - loading = false; - opts.onComplete(); - }); - } - }); - } -})($); diff --git a/app/assets/javascripts/apidocs.coffee b/app/assets/javascripts/apidocs.coffee new file mode 100644 index 0000000..c14445c --- /dev/null +++ b/app/assets/javascripts/apidocs.coffee @@ -0,0 +1,10 @@ +Application.Views.apidocs = + endpoint: -> + loading = $("#example_request_loading") + if loading isnt null + code = loading.parent() + $.ajax($("#example_request_uri").text()).done((data) -> + code.text(JSON.stringify(data, null, 2)) + ).fail(-> + code.text("failed to load example....") + ) diff --git a/app/assets/javascripts/apidocs.js b/app/assets/javascripts/apidocs.js deleted file mode 100644 index 3994145..0000000 --- a/app/assets/javascripts/apidocs.js +++ /dev/null @@ -1,13 +0,0 @@ -Application.Views.apidocs = { - endpoint: function() { - var loading = $("#example_request_loading"); - if (loading) { - var code = loading.parent(); - $.ajax($("#example_request_uri").text()).done(function(data) { - code.text(JSON.stringify(data, null, 2)); - }).fail(function() { - code.text("failed to load example...."); - }); - } - } -}; diff --git a/app/assets/javascripts/application.coffee b/app/assets/javascripts/application.coffee new file mode 100644 index 0000000..1f64343 --- /dev/null +++ b/app/assets/javascripts/application.coffee @@ -0,0 +1,21 @@ +#= require jquery +#= require jquery_ujs +#= require turbolinks +#= require bootstrap-sprockets +#= require _widgets +#= require _define_application +#= require_tree . + +$ -> + controller = $("body").data("controller") + action = $("body").data("action") + partials = ($("body").data("partial") || "").split(" ") + + ac = Application.Views[controller] + if ac + ac["_"]?() + ac["action"]?() + + partials.forEach (par) -> + pa = Application.Partials[par] + pa?() diff --git a/app/assets/javascripts/application.js.erb b/app/assets/javascripts/application.js.erb deleted file mode 100644 index beb0133..0000000 --- a/app/assets/javascripts/application.js.erb +++ /dev/null @@ -1,24 +0,0 @@ -//= require jquery -//= require jquery_ujs -//= require turbolinks -//= require bootstrap-sprockets -//= require _widgets -//= require _define_application -//= require_tree . - -$(function() { - var controller = $("body").data("controller"); - var action = $("body").data("action"); - var partials = ($("body").data("partial") || "").split(" "); - - var ac = Application.Views[controller]; - if (ac !== undefined) { - if (ac["_"] !== undefined) { ac["_"](); } - if (ac[action] !== undefined) { ac[action](); } - } - - partials.forEach(function(par) { - var pa = Application.Partials[par]; - if (pa !== undefined) { pa(); } - }); -}); diff --git a/app/assets/javascripts/layouts.coffee b/app/assets/javascripts/layouts.coffee new file mode 100644 index 0000000..f009247 --- /dev/null +++ b/app/assets/javascripts/layouts.coffee @@ -0,0 +1,24 @@ +$ -> + $("#user-jump-dropdown .dropdown-toggle").click () -> + setTimeout (-> $("#user-jump-dropdown input").focus()), 0 + + previousText = "" + $("#user-jump-dropdown input").on "keyup", () -> + if $(this).val() isnt previousText + previousText = $(this).val() + $("#user-jump-dropdown .user-jump-suggestion").remove() + + if previousText.length > 0 + Application.Helpers.call_api "users/suggest_screen_name", { head: previousText }, (json) -> + menu = $("#user-jump-dropdown .dropdown-menu") + json.forEach (s) -> + img = $("").addClass("twitter-icon").attr("src", s.profile_image_url).attr("alt", "@" + s.screen_name) + + menu.append($("
  • ").addClass("user-jump-suggestion") + .append($("").attr("href", "/" + s.screen_name).attr("title", s.name + " (@" + s.screen_name + ")") + .append(img) + .append($("").text("@" + s.screen_name)))) + Application.Helpers.rescue_profile_image(menu) + $("#user-jump-dropdown form").on "submit", () -> + window.location = "/" + $("input", this).val() + return false diff --git a/app/assets/javascripts/layouts.js.erb b/app/assets/javascripts/layouts.js.erb deleted file mode 100644 index f7943dd..0000000 --- a/app/assets/javascripts/layouts.js.erb +++ /dev/null @@ -1,34 +0,0 @@ -$(function() { - $("#user-jump-dropdown .dropdown-toggle").click(function() { - setTimeout(function() { $("#user-jump-dropdown input").focus(); }, 0); - }); - - var previousText = ""; - $("#user-jump-dropdown input").on("keyup", function() { - if ($(this).val() != previousText) { - previousText = $(this).val(); - $("#user-jump-dropdown .user-jump-suggestion").remove(); - - if (previousText.length > 0) { - $.getJSON("/i/user_jump_suggest.json", { head: previousText }, function(json) { - var menu = $("#user-jump-dropdown .dropdown-menu"); - json.forEach(function(s) { - var img = $("").addClass("twitter-icon").attr("src", s.profile_image_url).attr("alt", "@" + s.screen_name); - img.on("error", function() { this.src = '<%= image_path("profile_image_missing.png") %>'; }); - - menu.append($("
  • ").addClass("user-jump-suggestion") - .append($("").attr("href", "/" + s.screen_name).attr("title", s.name + " (@" + s.screen_name + ")") - .append(img) - .append($("").text("@" + s.screen_name)))); - }); - }); - } - } - }); - $("#user-jump-dropdown form").on("submit", function() { - window.location = "/" + $("input", this).val(); - return false; - }); - - $("img.twitter-icon").on("error", function() { this.src = '<%= image_path("profile_image_missing.png") %>'; }); -}); diff --git a/app/assets/javascripts/tweets.coffee b/app/assets/javascripts/tweets.coffee new file mode 100644 index 0000000..62e79a7 --- /dev/null +++ b/app/assets/javascripts/tweets.coffee @@ -0,0 +1,22 @@ +Application.Views.tweets = + _: -> + formatTweet = (d) -> + Application.Helpers.localize_time(d) + Application.Helpers.rescue_profile_image(d) + formatTweet $(".statuses") + + if $("link[rel=next]") isnt null + $.autopager + content: $(".statuses") + link: $("link[rel=next]") + onStart: -> $(".loading").show() + onReceived: (obj) -> formatTweet(obj) + onComplete: -> $(".loading").hide() + + $(".statuses").on "click", ".expand-responses-button", -> + id = $(this).data("id") + type = $(this).data("type") + Application.Helpers.call_api "tweets/responses", { id: id, type: type }, (json) -> + obj = $(".status[data-id=\"" + id + "\"] .status-responses-" + type).html(json.html) + Application.Helpers.rescue_profile_image obj + return false diff --git a/app/assets/javascripts/tweets.js.erb b/app/assets/javascripts/tweets.js.erb deleted file mode 100644 index fbd489f..0000000 --- a/app/assets/javascripts/tweets.js.erb +++ /dev/null @@ -1,33 +0,0 @@ -Application.Views.tweets = { - _: function() { - var formatTweet = function(d) { - Application.Helpers.localize_time(d); - Application.Helpers.rescue_profile_image(d); - }; - formatTweet($(".statuses")); - - if ($("link[rel=next]") !== null) { - $.autopager({ - content: $(".statuses"), - link: $("link[rel=next]"), - onStart: function() { - $(".loading").show(); - }, - onReceived: function(obj) { - formatTweet(obj); - }, - onComplete: function() { - $(".loading").hide(); - } - }); - } - - $(".statuses").on("click", ".expand-responses-button", function() { - var id = $(this).data("id"); - var type = $(this).data("type"); - Application.Helpers.call_api("tweets/responses", { id: id, type: type }, function(json) { - $(".status[data-id=\"" + id + "\"] .status-responses-" + type).html(json.html); - }); - }); - } -}; diff --git a/app/controllers/tweets_controller.rb b/app/controllers/tweets_controller.rb index cfe96cd..2b2d77f 100644 --- a/app/controllers/tweets_controller.rb +++ b/app/controllers/tweets_controller.rb @@ -74,8 +74,7 @@ class TweetsController < ApplicationController @tweets = paginate Tweet.recent((params[:period] || 7).days).filter_by_query(params[:q].to_s).order_by_id end - # /i/:id/{favorites,retweets}.json - def tweet_responses + def i_responses show users = params[:type] == "favorites" ? @tweet.favoriters : @tweet.retweeters render json: { html: render_to_string("_tweet_stats_users", locals: { tweet: @tweet, users: users, count: nil }, formats: :html, layout: nil) } diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index b50ff50..d6c775b 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -13,7 +13,7 @@ class UsersController < ApplicationController @cached_users = User.find(@result.map(&:first)).map {|user| [user.id, user] }.to_h end - def user_jump_suggest + def i_suggest_screen_name users = User.suggest_screen_name(params[:head].to_s).limit(10) filtered = users.map {|user| { name: user.name, screen_name: user.screen_name, profile_image_url: user.profile_image_url(:mini) } } render json: filtered diff --git a/config/routes.rb b/config/routes.rb index 25a60c2..a9b3f70 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -9,11 +9,8 @@ Rails.application.routes.draw do get "/i/callback" => "sessions#create" get "/i/logout" => "sessions#destroy", as: "logout" - get "/i/user_jump_suggest" => "users#user_jump_suggest", as: "user_jump_suggest" - get "/i/:id" => "tweets#show", as: "tweet", constraints: { id: /\d+/ } post "/i/:id/import" => "tweets#import", as: "import", constraints: { id: /\d+/ } - get "/i/:id/:type" => "tweets#tweet_responses", as: "tweet_responses", constraints: { id: /\d+/ } get "/i/settings" => "settings#index", as: "settings" post "/i/settings/update" => "settings#update" @@ -24,6 +21,9 @@ Rails.application.routes.draw do get "/i/timeline" => "tweets#all_timeline", as: "timeline" get "/i/filter" => "tweets#filter", as: "filter" + get "/i/api/users/suggest_screen_name" => "users#i_suggest_screen_name" + get "/i/api/tweets/responses" => "tweets#i_responses", as: "tweet_responses" + get "/about/api" => "apidocs#index", as: "about_api" get "/about/api/:method/:namespace/:path" => "apidocs#endpoint", as: "about_api_endpoint", constraints: { namespace: /[\w\/]+/ } -- cgit v1.2.3