From 71ae4dd3d2dbafc1ef6e7716c379d01ea194aafe Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 19 Mar 2016 14:02:30 +0100 Subject: [PATCH] Adding public following and followers pages, fix #3 --- app/assets/stylesheets/accounts.scss | 123 +++++++++++++++++- app/controllers/accounts_controller.rb | 8 ++ app/helpers/accounts_helper.rb | 4 +- app/views/accounts/_grid_card.html.haml | 8 ++ app/views/accounts/_header.html.haml | 20 +++ app/views/accounts/_nothing_here.html.haml | 1 + app/views/accounts/followers.html.haml | 14 ++ app/views/accounts/following.html.haml | 15 +++ app/views/accounts/show.html.haml | 20 +-- config/routes.rb | 5 + spec/controllers/accounts_controller_spec.rb | 18 ++- spec/controllers/home_controller_spec.rb | 2 +- .../stream_entries_controller_spec.rb | 4 +- spec/controllers/xrd_controller_spec.rb | 6 +- 14 files changed, 220 insertions(+), 28 deletions(-) create mode 100644 app/views/accounts/_grid_card.html.haml create mode 100644 app/views/accounts/_header.html.haml create mode 100644 app/views/accounts/_nothing_here.html.haml create mode 100644 app/views/accounts/followers.html.haml create mode 100644 app/views/accounts/following.html.haml diff --git a/app/assets/stylesheets/accounts.scss b/app/assets/stylesheets/accounts.scss index 57cc6e832..303360b1a 100644 --- a/app/assets/stylesheets/accounts.scss +++ b/app/assets/stylesheets/accounts.scss @@ -2,7 +2,7 @@ background: #282c37; background-size: cover; padding: 60px 0; - padding-bottom: 10px; + padding-bottom: 0; border-radius: 4px 4px 0 0; box-shadow: 0 0 15px rgba(0, 0, 0, 0.2); overflow: hidden; @@ -64,8 +64,45 @@ width: 80px; color: #9baec8; padding: 0 10px; + margin-bottom: 10px; border-right: 1px solid #9baec8; cursor: default; + position: relative; + + a { + display: block; + } + + &:after { + display: block; + content: ""; + position: absolute; + bottom: -10px; + left: 0; + width: 100%; + border-bottom: 4px solid #9baec8; + opacity: 0.5; + transition: all 0.8s ease; + } + + &.active { + &:after { + border-bottom: 4px solid #2b90d9; + opacity: 1; + } + } + + &:hover { + &:after { + opacity: 1; + transition-duration: 0.2s; + } + } + + a { + text-decoration: none; + color: inherit; + } .counter-label { font-size: 12px; @@ -145,3 +182,87 @@ color: lighten(#282c37, 10%); } } + +.accounts-grid { + clear: both; + box-shadow: 0 0 15px rgba(0, 0, 0, 0.2); + background: #fff; + border-radius: 0 0 4px 4px; + padding: 20px 10px; + padding-bottom: 10px; + overflow: hidden; + + .account-grid-card { + box-sizing: border-box; + width: 335px; + float: left; + border: 1px solid #d9e1e8; + border-radius: 4px; + color: #282c37; + height: 160px; + margin-bottom: 10px; + + &:nth-child(odd) { + margin-right: 10px; + } + + .account-grid-card__header { + overflow: hidden; + padding: 10px; + border-bottom: 1px solid #d9e1e8; + } + + .avatar { + width: 60px; + height: 60px; + float: left; + margin-right: 15px; + + img { + display: block; + width: 60px; + height: 60px; + border-radius: 60px; + } + } + + .name { + padding-top: 10px; + + a { + color: #282c37; + text-decoration: none; + + &:hover { + .display_name { + text-decoration: underline; + } + } + } + } + + .display_name { + font-size: 14px; + display: block; + } + + .username { + color: #2b90d9; + } + + .note { + padding: 10px; + padding-top: 15px; + color: #9baec8; + } + } +} + +.nothing-here { + color: #9baec8; + font-size: 14px; + font-weight: 500; + text-align: center; + padding: 15px 0; + cursor: default; +} diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index c46200811..374591a5c 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -13,6 +13,14 @@ class AccountsController < ApplicationController end end + def followers + @followers = @account.followers.paginate(page: params[:page], per_page: 6) + end + + def following + @following = @account.following.paginate(page: params[:page], per_page: 6) + end + private def set_account diff --git a/app/helpers/accounts_helper.rb b/app/helpers/accounts_helper.rb index 51fe6bc4e..8d303cb63 100644 --- a/app/helpers/accounts_helper.rb +++ b/app/helpers/accounts_helper.rb @@ -1,3 +1,5 @@ module AccountsHelper - + def pagination_options + { previous_label: "#{fa_icon('chevron-left')} Prev".html_safe, next_label: "Next #{fa_icon('chevron-right')}".html_safe, inner_window: 2 } + end end diff --git a/app/views/accounts/_grid_card.html.haml b/app/views/accounts/_grid_card.html.haml new file mode 100644 index 000000000..6245e910d --- /dev/null +++ b/app/views/accounts/_grid_card.html.haml @@ -0,0 +1,8 @@ +.account-grid-card + .account-grid-card__header + .avatar= image_tag account.avatar.url(:medium) + .name + = link_to url_for_target(account) do + %span.display_name= display_name(account) + %span.username= "@#{account.acct}" + %p.note= account.note diff --git a/app/views/accounts/_header.html.haml b/app/views/accounts/_header.html.haml new file mode 100644 index 000000000..deb70b30c --- /dev/null +++ b/app/views/accounts/_header.html.haml @@ -0,0 +1,20 @@ +.card{ style: "background-image: url(#{@account.header.url(:medium)})" } + .avatar= image_tag @account.avatar.url(:large) + %h1.name + = display_name(@account) + %small= "@#{@account.username}" + .details + .counter{ class: active_nav_class(account_url(@account)) } + = link_to account_url(@account) do + %span.counter-label Posts + %span.counter-number= @account.statuses.count + .counter{ class: active_nav_class(following_account_url(@account)) } + = link_to following_account_url(@account) do + %span.counter-label Following + %span.counter-number= @account.following.count + .counter{ class: active_nav_class(followers_account_url(@account)) } + = link_to followers_account_url(@account) do + %span.counter-label Followers + %span.counter-number= @account.followers.count + .bio + %p= @account.note diff --git a/app/views/accounts/_nothing_here.html.haml b/app/views/accounts/_nothing_here.html.haml new file mode 100644 index 000000000..faa1feb20 --- /dev/null +++ b/app/views/accounts/_nothing_here.html.haml @@ -0,0 +1 @@ +%p.nothing-here There is nothing here! diff --git a/app/views/accounts/followers.html.haml b/app/views/accounts/followers.html.haml new file mode 100644 index 000000000..75e464957 --- /dev/null +++ b/app/views/accounts/followers.html.haml @@ -0,0 +1,14 @@ +- content_for :page_title do + People who follow + = display_name(@account) + += render partial: 'header' + +.accounts-grid + - @followers.each do |f| + = render partial: 'grid_card', locals: { account: f } + + - if @followers.empty? + = render partial: 'nothing_here' + += will_paginate @followers, pagination_options diff --git a/app/views/accounts/following.html.haml b/app/views/accounts/following.html.haml new file mode 100644 index 000000000..6e1ba583c --- /dev/null +++ b/app/views/accounts/following.html.haml @@ -0,0 +1,15 @@ +- content_for :page_title do + People whom + = display_name(@account) + follows + += render partial: 'header' + +.accounts-grid + - @following.each do |f| + = render partial: 'grid_card', locals: { account: f } + + - if @following.empty? + = render partial: 'nothing_here' + += will_paginate @following, pagination_options diff --git a/app/views/accounts/show.html.haml b/app/views/accounts/show.html.haml index 43a99a3b0..f99460083 100644 --- a/app/views/accounts/show.html.haml +++ b/app/views/accounts/show.html.haml @@ -5,26 +5,10 @@ %link{ rel: 'salmon', href: api_salmon_url(@account.id) }/ %link{ rel: 'alternate', type: 'application/atom+xml', href: account_url(@account, format: 'atom') }/ -.card{ style: "background-image: url(#{@account.header.url(:medium)})" } - .avatar= image_tag @account.avatar.url(:large) - %h1.name - = display_name(@account) - %small= "@#{@account.username}" - .details - .counter - %span.counter-label Posts - %span.counter-number= @account.statuses.count - .counter - %span.counter-label Following - %span.counter-number= @account.following.count - .counter - %span.counter-label Followers - %span.counter-number= @account.followers.count - .bio - %p= @account.note += render partial: 'header' .activity-stream - @statuses.each do |status| = render partial: 'stream_entries/status', locals: { status: status, include_threads: false, is_successor: false, is_predecessor: false } -= will_paginate @statuses, previous_label: "#{fa_icon('chevron-left')} Prev".html_safe, next_label: "Next #{fa_icon('chevron-right')}".html_safe, inner_window: 2 += will_paginate @statuses, pagination_options diff --git a/config/routes.rb b/config/routes.rb index 3dd6e3469..2c7b3aa32 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -14,6 +14,11 @@ Rails.application.routes.draw do resources :accounts, path: 'users', only: [:show], param: :username do resources :stream_entries, path: 'updates', only: [:show] + + member do + get :followers + get :following + end end resource :settings, only: [:show, :update] diff --git a/spec/controllers/accounts_controller_spec.rb b/spec/controllers/accounts_controller_spec.rb index b1646b314..b0a5181da 100644 --- a/spec/controllers/accounts_controller_spec.rb +++ b/spec/controllers/accounts_controller_spec.rb @@ -4,14 +4,28 @@ RSpec.describe AccountsController, type: :controller do let(:alice) { Fabricate(:account, username: 'alice') } describe 'GET #show' do - it 'returns 200' do + it 'returns http success' do get :show, username: alice.username expect(response).to have_http_status(:success) end - it 'returns 200 with Atom' do + it 'returns http success with Atom' do get :show, username: alice.username, format: 'atom' expect(response).to have_http_status(:success) end end + + describe 'GET #followers' do + it 'returns http success' do + get :followers, username: alice.username + expect(response).to have_http_status(:success) + end + end + + describe 'GET #following' do + it 'returns http success' do + get :following, username: alice.username + expect(response).to have_http_status(:success) + end + end end diff --git a/spec/controllers/home_controller_spec.rb b/spec/controllers/home_controller_spec.rb index cf85c5f79..0b108c96a 100644 --- a/spec/controllers/home_controller_spec.rb +++ b/spec/controllers/home_controller_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' RSpec.describe HomeController, type: :controller do describe 'GET #index' do - it 'returns 200' do + it 'redirects to login page' do get :index expect(response).to redirect_to(new_user_session_path) end diff --git a/spec/controllers/stream_entries_controller_spec.rb b/spec/controllers/stream_entries_controller_spec.rb index 5fa3195eb..1b5f1fd7a 100644 --- a/spec/controllers/stream_entries_controller_spec.rb +++ b/spec/controllers/stream_entries_controller_spec.rb @@ -5,12 +5,12 @@ RSpec.describe StreamEntriesController, type: :controller do let(:status) { Fabricate(:status, account: alice) } describe 'GET #show' do - it 'returns 200 with HTML' do + it 'returns http success with HTML' do get :show, account_username: alice.username, id: status.stream_entry.id expect(response).to have_http_status(:success) end - it 'returns 200 with Atom' do + it 'returns http success with Atom' do get :show, account_username: alice.username, id: status.stream_entry.id, format: 'atom' expect(response).to have_http_status(:success) end diff --git a/spec/controllers/xrd_controller_spec.rb b/spec/controllers/xrd_controller_spec.rb index a74b5c143..c6bc5eab5 100644 --- a/spec/controllers/xrd_controller_spec.rb +++ b/spec/controllers/xrd_controller_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' RSpec.describe XrdController, type: :controller do describe 'GET #host_meta' do - it 'returns 200' do + it 'returns http success' do get :host_meta expect(response).to have_http_status(:success) end @@ -11,12 +11,12 @@ RSpec.describe XrdController, type: :controller do describe 'GET #webfinger' do let(:alice) { Fabricate(:account, username: 'alice') } - it 'returns 200 when account can be found' do + it 'returns http success when account can be found' do get :webfinger, resource: "acct:#{alice.username}@anything.com" expect(response).to have_http_status(:success) end - it 'returns 404 when account cannot be found' do + it 'returns http not found when account cannot be found' do get :webfinger, resource: 'acct:not@existing.com' expect(response).to have_http_status(:not_found) end