| @@ -14,7 +14,7 @@ gem 'puma' | |||
| gem 'haml-rails' | |||
| gem 'pg' | |||
| gem 'dotenv-rails' | |||
| gem 'font-awesome-sass' | |||
| gem 'font-awesome-rails' | |||
| gem 'paranoia', '~> 2.0' | |||
| gem 'paperclip', '~> 4.3' | |||
| @@ -34,7 +34,6 @@ gem 'hiredis' | |||
| gem 'redis', '~>3.2' | |||
| gem 'fast_blank' | |||
| gem 'htmlentities' | |||
| gem 'message_bus' | |||
| gem 'onebox' | |||
| group :development, :test do | |||
| @@ -52,7 +51,6 @@ end | |||
| group :development do | |||
| gem 'web-console', '~> 2.0' | |||
| gem 'spring' | |||
| gem 'rubocop', require: false | |||
| gem 'better_errors' | |||
| gem 'binding_of_caller' | |||
| @@ -41,7 +41,7 @@ GEM | |||
| ast (2.2.0) | |||
| backport_new_renderer (1.0.0) | |||
| rails | |||
| bcrypt (3.1.10) | |||
| bcrypt (3.1.11) | |||
| better_errors (2.1.1) | |||
| coderay (>= 1.0.0) | |||
| erubis (>= 2.6.6) | |||
| @@ -61,7 +61,7 @@ GEM | |||
| coffee-script-source | |||
| execjs | |||
| coffee-script-source (1.10.0) | |||
| concurrent-ruby (1.0.0) | |||
| concurrent-ruby (1.0.1) | |||
| crack (0.4.3) | |||
| safe_yaml (~> 1.0.0) | |||
| debug_inspector (0.0.2) | |||
| @@ -74,7 +74,7 @@ GEM | |||
| warden (~> 1.2.3) | |||
| diff-lcs (1.2.5) | |||
| docile (1.1.5) | |||
| domain_name (0.5.20160216) | |||
| domain_name (0.5.20160309) | |||
| unf (>= 0.0.5, < 1.0.0) | |||
| doorkeeper (3.1.0) | |||
| railties (>= 3.2) | |||
| @@ -86,8 +86,8 @@ GEM | |||
| execjs (2.6.0) | |||
| fabrication (2.14.1) | |||
| fast_blank (1.0.0) | |||
| font-awesome-sass (4.5.0) | |||
| sass (>= 3.2) | |||
| font-awesome-rails (4.5.0.1) | |||
| railties (>= 3.2, < 5.1) | |||
| fuubar (2.0.0) | |||
| rspec (~> 3.0) | |||
| ruby-progressbar (~> 1.4) | |||
| @@ -126,8 +126,8 @@ GEM | |||
| jbuilder (2.4.1) | |||
| activesupport (>= 3.0.0, < 5.1) | |||
| multi_json (~> 1.2) | |||
| jquery-rails (4.1.0) | |||
| rails-dom-testing (~> 1.0) | |||
| jquery-rails (4.1.1) | |||
| rails-dom-testing (>= 1, < 3) | |||
| railties (>= 4.2.0) | |||
| thor (>= 0.14, < 2.0) | |||
| json (1.8.3) | |||
| @@ -136,11 +136,8 @@ GEM | |||
| nokogiri (>= 1.5.9) | |||
| mail (2.6.3) | |||
| mime-types (>= 1.16, < 3) | |||
| message_bus (1.1.1) | |||
| rack (>= 1.1.3) | |||
| redis | |||
| method_source (0.8.2) | |||
| mime-types (2.99) | |||
| mime-types (2.99.1) | |||
| mimemagic (0.3.0) | |||
| mini_portile2 (2.0.0) | |||
| minitest (5.8.4) | |||
| @@ -149,7 +146,7 @@ GEM | |||
| mustache (1.0.2) | |||
| nokogiri (1.6.7.2) | |||
| mini_portile2 (~> 2.0.0.rc2) | |||
| oj (2.14.5) | |||
| oj (2.14.6) | |||
| onebox (1.5.35) | |||
| htmlentities (~> 4.3.4) | |||
| moneta (~> 0.8) | |||
| @@ -179,7 +176,7 @@ GEM | |||
| slop (~> 3.4) | |||
| pry-rails (0.3.4) | |||
| pry (>= 0.9.10) | |||
| puma (2.16.0) | |||
| puma (3.1.0) | |||
| quiet_assets (1.1.0) | |||
| railties (>= 3.1, < 5.0) | |||
| rabl (0.12.0) | |||
| @@ -221,7 +218,7 @@ GEM | |||
| rake (>= 0.8.7) | |||
| thor (>= 0.18.1, < 2.0) | |||
| rainbow (2.1.0) | |||
| rake (10.5.0) | |||
| rake (11.1.0) | |||
| rdoc (4.2.2) | |||
| json (~> 1.4) | |||
| redis (3.2.2) | |||
| @@ -232,7 +229,7 @@ GEM | |||
| rspec-core (~> 3.4.0) | |||
| rspec-expectations (~> 3.4.0) | |||
| rspec-mocks (~> 3.4.0) | |||
| rspec-core (3.4.3) | |||
| rspec-core (3.4.4) | |||
| rspec-support (~> 3.4.0) | |||
| rspec-expectations (3.4.0) | |||
| diff-lcs (>= 1.2.0, < 2.0) | |||
| @@ -249,12 +246,12 @@ GEM | |||
| rspec-mocks (~> 3.4.0) | |||
| rspec-support (~> 3.4.0) | |||
| rspec-support (3.4.1) | |||
| rubocop (0.37.2) | |||
| parser (>= 2.3.0.4, < 3.0) | |||
| rubocop (0.38.0) | |||
| parser (>= 2.3.0.6, < 3.0) | |||
| powerpack (~> 0.1) | |||
| rainbow (>= 1.99.1, < 3.0) | |||
| ruby-progressbar (~> 1.7) | |||
| unicode-display_width (~> 0.3) | |||
| unicode-display_width (~> 1.0, >= 1.0.1) | |||
| ruby-progressbar (1.7.5) | |||
| ruby_parser (3.8.1) | |||
| sexp_processor (~> 4.1) | |||
| @@ -276,11 +273,10 @@ GEM | |||
| simplecov-html (~> 0.10.0) | |||
| simplecov-html (0.10.0) | |||
| slop (3.6.0) | |||
| spring (1.6.3) | |||
| sprockets (3.5.2) | |||
| concurrent-ruby (~> 1.0) | |||
| rack (> 1, < 3) | |||
| sprockets-rails (3.0.1) | |||
| sprockets-rails (3.0.4) | |||
| actionpack (>= 4.0) | |||
| activesupport (>= 4.0) | |||
| sprockets (>= 3.0.0) | |||
| @@ -299,7 +295,7 @@ GEM | |||
| unf (0.1.4) | |||
| unf_ext | |||
| unf_ext (0.0.7.2) | |||
| unicode-display_width (0.3.1) | |||
| unicode-display_width (1.0.2) | |||
| warden (1.2.6) | |||
| rack (>= 1.0) | |||
| web-console (2.3.0) | |||
| @@ -307,7 +303,7 @@ GEM | |||
| binding_of_caller (>= 0.7.2) | |||
| railties (>= 4.0) | |||
| sprockets-rails (>= 2.0, < 4.0) | |||
| webmock (1.24.1) | |||
| webmock (1.24.2) | |||
| addressable (>= 2.3.6) | |||
| crack (>= 0.3.2) | |||
| hashdiff | |||
| @@ -326,7 +322,7 @@ DEPENDENCIES | |||
| dotenv-rails | |||
| fabrication | |||
| fast_blank | |||
| font-awesome-sass | |||
| font-awesome-rails | |||
| fuubar | |||
| goldfinger | |||
| haml-rails | |||
| @@ -335,7 +331,6 @@ DEPENDENCIES | |||
| http | |||
| jbuilder (~> 2.0) | |||
| jquery-rails | |||
| message_bus | |||
| nokogiri | |||
| oj | |||
| onebox | |||
| @@ -357,7 +352,6 @@ DEPENDENCIES | |||
| sass-rails (~> 5.0) | |||
| sdoc (~> 0.4.0) | |||
| simplecov | |||
| spring | |||
| sqlite3 | |||
| therubyracer | |||
| uglifier (>= 1.3.0) | |||
| @@ -9,7 +9,6 @@ $lighter-text-color: #8b8687; | |||
| @import url(https://fonts.googleapis.com/css?family=Roboto:400,500,400italic); | |||
| @import url(https://fonts.googleapis.com/css?family=Roboto+Mono); | |||
| @import "font-awesome-sprockets"; | |||
| @import "font-awesome"; | |||
| /* http://meyerweb.com/eric/tools/css/reset/ | |||
| @@ -334,3 +333,4 @@ body { | |||
| @import 'home'; | |||
| @import 'accounts'; | |||
| @import 'stream_entries'; | |||
| @import 'dashboard' | |||
| @@ -0,0 +1,130 @@ | |||
| .dashboard-wrapper { | |||
| background: #282c37; | |||
| border-radius: 4px; | |||
| margin: 20px auto; | |||
| width: 940px; | |||
| display: flex; | |||
| .dashboard__sidebar { | |||
| width: 240px; | |||
| border-radius: 4px 0 0 4px; | |||
| .dashboard__top-bar { | |||
| border-radius: 4px 0 0 0; | |||
| } | |||
| ul { | |||
| padding: 20px 0; | |||
| a { | |||
| display: block; | |||
| padding: 7px 20px; | |||
| color: #d9e1e8; | |||
| text-decoration: none; | |||
| font-size: 14px; | |||
| font-weight: 400; | |||
| .fa { | |||
| display: inline-block; | |||
| width: 18px; | |||
| text-align: center; | |||
| margin-right: 5px; | |||
| } | |||
| } | |||
| .active { | |||
| a { | |||
| background: darken(#282c37, 5%); | |||
| border-left: 2px solid #2b90d9; | |||
| padding-left: 18px; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| .dashboard__current-user { | |||
| padding: 20px; | |||
| a { | |||
| text-decoration: none; | |||
| color: inherit; | |||
| } | |||
| .dashboard__current-user__avatar { | |||
| display: block; | |||
| width: 50px; | |||
| height: 50px; | |||
| border-radius: 50px; | |||
| float: left; | |||
| margin-right: 15px; | |||
| } | |||
| .dashboard__current-user__display-name { | |||
| font-weight: 500; | |||
| font-size: 13px; | |||
| color: #d9e1e8; | |||
| display: block; | |||
| margin-top: 5px; | |||
| } | |||
| .dashboard__current-user__username { | |||
| font-size: 12px; | |||
| display: block; | |||
| color: #2b90d9; | |||
| } | |||
| } | |||
| .dashboard__logo { | |||
| color: #2b90d9; | |||
| span { | |||
| font-weight: 500; | |||
| } | |||
| } | |||
| .dashboard__top-bar { | |||
| background: #fff; | |||
| padding: 20px; | |||
| box-shadow: 0 0 5px rgba(0, 0, 0, 0.1); | |||
| border-bottom: 1px solid #d9e1e8; | |||
| color: #282c37; | |||
| font-size: 16px; | |||
| overflow: hidden; | |||
| &.alternate { | |||
| background: lighten(#282c37, 10%); | |||
| border-bottom: 1px solid lighten(#282c37, 10%); | |||
| text-align: center; | |||
| } | |||
| ul { | |||
| float: right; | |||
| list-style: none; | |||
| display: block; | |||
| li { | |||
| display: inline-block; | |||
| } | |||
| } | |||
| a { | |||
| color: #9baec8; | |||
| text-decoration: none; | |||
| } | |||
| } | |||
| .dashboard__content { | |||
| flex: 1; | |||
| background: #d9e1e8; | |||
| border-radius: 0 4px 4px 0; | |||
| .dashboard__content__content { | |||
| //padding: 20px; | |||
| } | |||
| .dashboard__top-bar { | |||
| border-radius: 0 4px 0 0; | |||
| } | |||
| } | |||
| } | |||
| @@ -14,6 +14,14 @@ | |||
| &.entry-predecessor, &.entry-successor { | |||
| background: #d9e1e8; | |||
| border-left-color: #d9e1e8; | |||
| .header { | |||
| .header__right { | |||
| .counter-btn { | |||
| color: darken(#d9e1e8, 15%); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| &.entry-follow, &.entry-favourite { | |||
| @@ -43,6 +51,14 @@ | |||
| } | |||
| } | |||
| &.activity-stream-embedded { | |||
| box-shadow: none; | |||
| .entry { | |||
| border-radius: 0; | |||
| } | |||
| } | |||
| .entry__container { | |||
| display: flex; | |||
| } | |||
| @@ -5,7 +5,7 @@ class AccountsController < ApplicationController | |||
| before_action :set_webfinger_header | |||
| def show | |||
| @statuses = @account.statuses.order('id desc').includes(thread: [:account], reblog: [:account], stream_entry: []) | |||
| @statuses = @account.statuses.order('id desc').with_includes.with_counters | |||
| respond_to do |format| | |||
| format.html | |||
| @@ -15,7 +15,7 @@ class Api::AccountsController < ApiController | |||
| end | |||
| def statuses | |||
| @statuses = @account.statuses.order('created_at desc') | |||
| @statuses = @account.statuses.with_includes.with_counts.order('created_at desc') | |||
| end | |||
| def follow | |||
| @@ -1,8 +1,16 @@ | |||
| class HomeController < ApplicationController | |||
| layout 'dashboard' | |||
| before_action :authenticate_user! | |||
| def index | |||
| feed = Feed.new(:home, current_user.account) | |||
| @statuses = feed.get(20, (params[:offset] || 0).to_i) | |||
| end | |||
| def mentions | |||
| feed = Feed.new(:mentions, current_user.account) | |||
| @statuses = feed.get(20, (params[:offset] || 0).to_i) | |||
| render action: :index | |||
| end | |||
| end | |||
| @@ -49,6 +49,14 @@ class Status < ActiveRecord::Base | |||
| content.truncate(80, omission: "...") | |||
| end | |||
| def reblogs_count | |||
| self.attributes['reblogs_count'] || self.reblogs.count | |||
| end | |||
| def favourites_count | |||
| self.attributes['favourites_count'] || self.favourites.count | |||
| end | |||
| def mentions | |||
| m = [] | |||
| @@ -4,8 +4,8 @@ attributes :id, :created_at, :in_reply_to_id | |||
| node(:uri) { |status| uri_for_target(status) } | |||
| node(:content) { |status| status.local? ? linkify(status) : status.content } | |||
| node(:url) { |status| url_for_target(status) } | |||
| node(:reblogs_count) { |status| status.reblogs.count } | |||
| node(:favourites_count) { |status| status.favourites.count } | |||
| node(:reblogs_count) { |status| status.reblogs_count } | |||
| node(:favourites_count) { |status| status.favourites_count } | |||
| node(:favourited) { |status| current_user.account.favourited?(status) } | |||
| node(:reblogged) { |status| current_user.account.reblogged?(status) } | |||
| @@ -1,3 +1,3 @@ | |||
| .activity-stream.activity-stream-headless | |||
| .activity-stream.activity-stream-embedded | |||
| - @statuses.each do |status| | |||
| = render partial: 'stream_entries/status', locals: { status: status, include_threads: false, is_successor: false, is_predecessor: false } | |||
| @@ -8,5 +8,4 @@ | |||
| = csrf_meta_tags | |||
| = yield :header_tags | |||
| %body | |||
| .container | |||
| = content_for?(:content) ? yield(:content) : yield | |||
| = content_for?(:content) ? yield(:content) : yield | |||
| @@ -1,11 +1,12 @@ | |||
| - content_for :content do | |||
| .logo-container | |||
| %h1 | |||
| = link_to root_path do | |||
| = render partial: 'application/logo', locals: { dim: 200 } | |||
| %small= Rails.configuration.x.local_domain | |||
| .container | |||
| .logo-container | |||
| %h1 | |||
| = link_to root_path do | |||
| = render partial: 'application/logo', locals: { dim: 200 } | |||
| %small= Rails.configuration.x.local_domain | |||
| .form-container | |||
| = yield | |||
| .form-container | |||
| = yield | |||
| = render template: "layouts/application" | |||
| @@ -0,0 +1,45 @@ | |||
| - content_for :content do | |||
| .dashboard-wrapper | |||
| .dashboard__sidebar | |||
| .dashboard__top-bar.alternate | |||
| | |||
| .dashboard__current-user | |||
| = link_to account_path(current_user.account) do | |||
| = image_tag current_user.account.avatar.url(:medium), class: 'dashboard__current-user__avatar' | |||
| %strong.dashboard__current-user__display-name= current_user.account.display_name | |||
| %span.dashboard__current-user__username= "@#{current_user.account.username}" | |||
| %ul | |||
| %li.active | |||
| = link_to root_path do | |||
| = fa_icon 'home' | |||
| Home | |||
| %li | |||
| = link_to mentions_path do | |||
| = fa_icon 'at' | |||
| Mentions | |||
| %li | |||
| = link_to root_path do | |||
| = fa_icon 'group' | |||
| Subscriptions | |||
| %li | |||
| = link_to oauth_authorized_applications_path do | |||
| = fa_icon 'shield' | |||
| Authorized apps | |||
| %li | |||
| = link_to root_path do | |||
| = fa_icon 'user' | |||
| Edit profile | |||
| %li | |||
| = link_to edit_registration_path(current_user) do | |||
| = fa_icon 'wrench' | |||
| Change password | |||
| .dashboard__content | |||
| .dashboard__top-bar | |||
| Home | |||
| %ul | |||
| %li= link_to fa_icon('sign-out'), destroy_user_session_path, method: :delete | |||
| .dashboard__content__content= yield | |||
| .footer | |||
| .domain= Rails.configuration.x.local_domain | |||
| = render template: "layouts/application" | |||
| @@ -1,37 +0,0 @@ | |||
| <!DOCTYPE html> | |||
| <html> | |||
| <head> | |||
| <meta charset="utf-8"> | |||
| <meta http-equiv="X-UA-Compatible" content="IE=edge"> | |||
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |||
| <title>Doorkeeper</title> | |||
| <%= stylesheet_link_tag "doorkeeper/admin/application" %> | |||
| <%= csrf_meta_tags %> | |||
| </head> | |||
| <body> | |||
| <div class="navbar navbar-inverse navbar-static-top" role="navigation"> | |||
| <div class="container-fluid"> | |||
| <div class="navbar-header"> | |||
| <%= link_to t('doorkeeper.layouts.admin.nav.oauth2_provider'), oauth_applications_path, class: 'navbar-brand' %> | |||
| </div> | |||
| <ul class="nav navbar-nav"> | |||
| <%= content_tag :li, class: "#{'active' if request.path == oauth_applications_path}" do %> | |||
| <%= link_to t('doorkeeper.layouts.admin.nav.applications'), oauth_applications_path %> | |||
| <% end %> | |||
| <%= content_tag :li do %> | |||
| <%= link_to 'Home', root_path %> | |||
| <% end %> | |||
| </ul> | |||
| </div> | |||
| </div> | |||
| <div class="container"> | |||
| <%- if flash[:notice].present? %> | |||
| <div class="alert alert-info"> | |||
| <%= flash[:notice] %> | |||
| </div> | |||
| <% end -%> | |||
| <%= yield %> | |||
| </div> | |||
| </body> | |||
| </html> | |||
| @@ -1,23 +0,0 @@ | |||
| <!DOCTYPE html> | |||
| <html> | |||
| <head> | |||
| <title><%= t('doorkeeper.layouts.application.title') %></title> | |||
| <meta charset="utf-8"> | |||
| <meta http-equiv="X-UA-Compatible" content="IE=edge"> | |||
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |||
| <%= stylesheet_link_tag "doorkeeper/application" %> | |||
| <%= csrf_meta_tags %> | |||
| </head> | |||
| <body> | |||
| <div id="container"> | |||
| <%- if flash[:notice].present? %> | |||
| <div class="alert alert-info"> | |||
| <%= flash[:notice] %> | |||
| </div> | |||
| <% end -%> | |||
| <%= yield %> | |||
| </div> | |||
| </body> | |||
| </html> | |||
| @@ -1,5 +1,5 @@ | |||
| - content_for :content do | |||
| = yield | |||
| .container= yield | |||
| .footer | |||
| .domain= Rails.configuration.x.local_domain | |||
| @@ -24,10 +24,10 @@ | |||
| .header__right | |||
| .counter-btn{ class: reblogged_by_me_class(status) } | |||
| %i.fa.fa-retweet | |||
| %span.counter-number= status.reblog? ? status.reblog.reblogs.count : status.reblogs_count | |||
| %span.counter-number= status.reblog? ? status.reblog.reblogs_count : status.reblogs_count | |||
| .counter-btn{ class: favourited_by_me_class(status) } | |||
| %i.fa.fa-star | |||
| %span.counter-number= status.reblog? ? status.reblog.favourites.count : status.favourites_count | |||
| %span.counter-number= status.reblog? ? status.reblog.favourites_count : status.favourites_count | |||
| .content | |||
| = status.reblog? ? (status.reblog.local? ? linkify(status.reblog) : status.reblog.content.html_safe) : (status.local? ? linkify(status) : status.content.html_safe) | |||
| @@ -1,9 +1,4 @@ | |||
| #!/usr/bin/env ruby | |||
| begin | |||
| load File.expand_path('../spring', __FILE__) | |||
| rescue LoadError => e | |||
| raise unless e.message.include?('spring') | |||
| end | |||
| APP_PATH = File.expand_path('../../config/application', __FILE__) | |||
| require_relative '../config/boot' | |||
| require 'rails/commands' | |||
| @@ -1,9 +1,4 @@ | |||
| #!/usr/bin/env ruby | |||
| begin | |||
| load File.expand_path('../spring', __FILE__) | |||
| rescue LoadError => e | |||
| raise unless e.message.include?('spring') | |||
| end | |||
| require_relative '../config/boot' | |||
| require 'rake' | |||
| Rake.application.run | |||
| @@ -1,15 +0,0 @@ | |||
| #!/usr/bin/env ruby | |||
| # This file loads spring without using Bundler, in order to be fast. | |||
| # It gets overwritten when you run the `spring binstub` command. | |||
| unless defined?(Spring) | |||
| require 'rubygems' | |||
| require 'bundler' | |||
| if (match = Bundler.default_lockfile.read.match(/^GEM$.*?^ (?: )*spring \((.*?)\)$.*?^$/m)) | |||
| Gem.paths = { 'GEM_PATH' => [Bundler.bundle_path.to_s, *Gem.path].uniq } | |||
| gem 'spring', match[1] | |||
| require 'spring/binstub' | |||
| end | |||
| end | |||
| @@ -29,8 +29,9 @@ module Mastodon | |||
| config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')] | |||
| config.to_prepare do | |||
| Doorkeeper::AuthorizationsController.layout 'auth' | |||
| Doorkeeper::AuthorizedApplicationsController.layout 'auth' | |||
| Doorkeeper::ApplicationsController.layout 'dashboard' | |||
| Doorkeeper::AuthorizedApplicationsController.layout 'dashboard' | |||
| Doorkeeper::AuthorizationsController.layout 'auth' | |||
| end | |||
| end | |||
| end | |||
| @@ -1 +1 @@ | |||
| $redis = Redis.new(host: ENV['REDIS_HOST'] || 'localhost', port: ENV['REDIS_PORT'] || 6379) | |||
| $redis = Redis.new(host: ENV['REDIS_HOST'] || 'localhost', port: ENV['REDIS_PORT'] || 6379, driver: :hiredis) | |||
| @@ -0,0 +1,13 @@ | |||
| workers Integer(ENV['WEB_CONCURRENCY'] || 2) | |||
| threads_count = Integer(ENV['MAX_THREADS'] || 5) | |||
| threads threads_count, threads_count | |||
| preload_app! | |||
| rackup DefaultRackup | |||
| port ENV['PORT'] || 3000 | |||
| environment ENV['RACK_ENV'] || 'development' | |||
| on_worker_boot do | |||
| ActiveRecord::Base.establish_connection | |||
| end | |||
| @@ -49,5 +49,7 @@ Rails.application.routes.draw do | |||
| end | |||
| end | |||
| get '/mentions', to: 'home#mentions', as: :mentions | |||
| root 'home#index' | |||
| end | |||