Adding public following and followers pages, fix #3

master
Eugen Rochko 9 years ago
parent c349200761
commit 71ae4dd3d2
  1. 123
      app/assets/stylesheets/accounts.scss
  2. 8
      app/controllers/accounts_controller.rb
  3. 4
      app/helpers/accounts_helper.rb
  4. 8
      app/views/accounts/_grid_card.html.haml
  5. 20
      app/views/accounts/_header.html.haml
  6. 1
      app/views/accounts/_nothing_here.html.haml
  7. 14
      app/views/accounts/followers.html.haml
  8. 15
      app/views/accounts/following.html.haml
  9. 20
      app/views/accounts/show.html.haml
  10. 5
      config/routes.rb
  11. 18
      spec/controllers/accounts_controller_spec.rb
  12. 2
      spec/controllers/home_controller_spec.rb
  13. 4
      spec/controllers/stream_entries_controller_spec.rb
  14. 6
      spec/controllers/xrd_controller_spec.rb

@ -2,7 +2,7 @@
background: #282c37; background: #282c37;
background-size: cover; background-size: cover;
padding: 60px 0; padding: 60px 0;
padding-bottom: 10px; padding-bottom: 0;
border-radius: 4px 4px 0 0; border-radius: 4px 4px 0 0;
box-shadow: 0 0 15px rgba(0, 0, 0, 0.2); box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
overflow: hidden; overflow: hidden;
@ -64,8 +64,45 @@
width: 80px; width: 80px;
color: #9baec8; color: #9baec8;
padding: 0 10px; padding: 0 10px;
margin-bottom: 10px;
border-right: 1px solid #9baec8; border-right: 1px solid #9baec8;
cursor: default; 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 { .counter-label {
font-size: 12px; font-size: 12px;
@ -145,3 +182,87 @@
color: lighten(#282c37, 10%); 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;
}

@ -13,6 +13,14 @@ class AccountsController < ApplicationController
end end
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 private
def set_account def set_account

@ -1,3 +1,5 @@
module AccountsHelper 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 end

@ -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

@ -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

@ -0,0 +1 @@
%p.nothing-here There is nothing here!

@ -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

@ -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

@ -5,26 +5,10 @@
%link{ rel: 'salmon', href: api_salmon_url(@account.id) }/ %link{ rel: 'salmon', href: api_salmon_url(@account.id) }/
%link{ rel: 'alternate', type: 'application/atom+xml', href: account_url(@account, format: 'atom') }/ %link{ rel: 'alternate', type: 'application/atom+xml', href: account_url(@account, format: 'atom') }/
.card{ style: "background-image: url(#{@account.header.url(:medium)})" } = render partial: 'header'
.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
.activity-stream .activity-stream
- @statuses.each do |status| - @statuses.each do |status|
= render partial: 'stream_entries/status', locals: { status: status, include_threads: false, is_successor: false, is_predecessor: false } = 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

@ -14,6 +14,11 @@ Rails.application.routes.draw do
resources :accounts, path: 'users', only: [:show], param: :username do resources :accounts, path: 'users', only: [:show], param: :username do
resources :stream_entries, path: 'updates', only: [:show] resources :stream_entries, path: 'updates', only: [:show]
member do
get :followers
get :following
end
end end
resource :settings, only: [:show, :update] resource :settings, only: [:show, :update]

@ -4,14 +4,28 @@ RSpec.describe AccountsController, type: :controller do
let(:alice) { Fabricate(:account, username: 'alice') } let(:alice) { Fabricate(:account, username: 'alice') }
describe 'GET #show' do describe 'GET #show' do
it 'returns 200' do it 'returns http success' do
get :show, username: alice.username get :show, username: alice.username
expect(response).to have_http_status(:success) expect(response).to have_http_status(:success)
end end
it 'returns 200 with Atom' do it 'returns http success with Atom' do
get :show, username: alice.username, format: 'atom' get :show, username: alice.username, format: 'atom'
expect(response).to have_http_status(:success) expect(response).to have_http_status(:success)
end end
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 end

@ -2,7 +2,7 @@ require 'rails_helper'
RSpec.describe HomeController, type: :controller do RSpec.describe HomeController, type: :controller do
describe 'GET #index' do describe 'GET #index' do
it 'returns 200' do it 'redirects to login page' do
get :index get :index
expect(response).to redirect_to(new_user_session_path) expect(response).to redirect_to(new_user_session_path)
end end

@ -5,12 +5,12 @@ RSpec.describe StreamEntriesController, type: :controller do
let(:status) { Fabricate(:status, account: alice) } let(:status) { Fabricate(:status, account: alice) }
describe 'GET #show' do 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 get :show, account_username: alice.username, id: status.stream_entry.id
expect(response).to have_http_status(:success) expect(response).to have_http_status(:success)
end 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' get :show, account_username: alice.username, id: status.stream_entry.id, format: 'atom'
expect(response).to have_http_status(:success) expect(response).to have_http_status(:success)
end end

@ -2,7 +2,7 @@ require 'rails_helper'
RSpec.describe XrdController, type: :controller do RSpec.describe XrdController, type: :controller do
describe 'GET #host_meta' do describe 'GET #host_meta' do
it 'returns 200' do it 'returns http success' do
get :host_meta get :host_meta
expect(response).to have_http_status(:success) expect(response).to have_http_status(:success)
end end
@ -11,12 +11,12 @@ RSpec.describe XrdController, type: :controller do
describe 'GET #webfinger' do describe 'GET #webfinger' do
let(:alice) { Fabricate(:account, username: 'alice') } 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" get :webfinger, resource: "acct:#{alice.username}@anything.com"
expect(response).to have_http_status(:success) expect(response).to have_http_status(:success)
end 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' get :webfinger, resource: 'acct:not@existing.com'
expect(response).to have_http_status(:not_found) expect(response).to have_http_status(:not_found)
end end

Loading…
Cancel
Save