commit: 71ae4dd3d2dbafc1ef6e7716c379d01ea194aafe
parent: c349200761bdbf5beac22648da07b0768addc4d6
Author: Eugen Rochko <eugen@zeonfederated.com>
Date: Sat, 19 Mar 2016 14:02:30 +0100
Adding public following and followers pages, fix #3
Diffstat:
14 files changed, 220 insertions(+), 28 deletions(-)
diff --git 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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