From c3465f699e345e6909271a3159293783df0f0891 Mon Sep 17 00:00:00 2001 From: "chr v1.x" Date: Thu, 27 Dec 2018 04:15:39 -0800 Subject: [PATCH] Add local followers page to admin account UI (#9610) * Add local followers page to admin account UI For moderation, I often find myself wondering who, locally, is following a remote user. Currently, to see this, I have to go back to the web UI, paste in their full handle, click their profile, and go to the "Followers" tab (plus, this information is incidental, and if mastodon ever decides to resolve all of the follower information, there will be no place local followers are shown). This PR adds a new page which is accessible via the "following" count on the admin's account view page, which shows the local followers. (It has filter parameters for account location to indicate that only local followers are shown, and leave room for expansion if mastodon ever decides to store the entire remote follow list). * Normalize en.yml --- app/controllers/admin/followers_controller.rb | 22 ++++++++++++++ app/models/account.rb | 4 +++ app/views/admin/accounts/show.html.haml | 4 ++- app/views/admin/followers/index.html.haml | 29 +++++++++++++++++++ config/locales/en.yml | 4 +++ config/routes.rb | 1 + 6 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 app/controllers/admin/followers_controller.rb create mode 100644 app/views/admin/followers/index.html.haml diff --git a/app/controllers/admin/followers_controller.rb b/app/controllers/admin/followers_controller.rb new file mode 100644 index 0000000000..819628b201 --- /dev/null +++ b/app/controllers/admin/followers_controller.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Admin + class FollowersController < BaseController + before_action :set_account + + PER_PAGE = 40 + + def index + authorize :account, :index? + @followers = followers.recent.page(params[:page]).per(PER_PAGE) + end + + def set_account + @account = Account.find(params[:account_id]) + end + + def followers + Follow.includes(:account).where(target_account: @account) + end + end +end diff --git a/app/models/account.rb b/app/models/account.rb index cf804fc678..66f02b27d7 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -139,6 +139,10 @@ class Account < ApplicationRecord "#{username}@#{Rails.configuration.x.local_domain}" end + def local_followers_count + Follow.where(target_account_id: id).count + end + def to_webfinger_s "acct:#{local_username_and_domain}" end diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml index 226aef732e..47cf41073d 100644 --- a/app/views/admin/accounts/show.html.haml +++ b/app/views/admin/accounts/show.html.haml @@ -89,7 +89,9 @@ %td= number_to_human @account.following_count %tr %th= t('admin.accounts.followers') - %td= number_to_human @account.followers_count + %td + = number_to_human @account.followers_count + = link_to t('admin.accounts.followers_local', local: number_to_human(@account.local_followers_count)), admin_account_followers_path(@account.id) %tr %th= t('admin.accounts.statuses') %td= link_to number_to_human(@account.statuses_count), admin_account_statuses_path(@account.id) diff --git a/app/views/admin/followers/index.html.haml b/app/views/admin/followers/index.html.haml new file mode 100644 index 0000000000..baf34bc95d --- /dev/null +++ b/app/views/admin/followers/index.html.haml @@ -0,0 +1,29 @@ +- content_for :header_tags do + = javascript_pack_tag 'admin', integrity: true, async: true, crossorigin: 'anonymous' + +- content_for :page_title do + = t('admin.followers.title', acct: @account.acct) + +.filters + .filter-subset + %strong= t('admin.accounts.location.title') + %ul + %li= link_to t('admin.accounts.location.local'), admin_account_followers_path(@account.id), class: 'selected' + .back-link{ style: 'flex: 1 1 auto; text-align: right' } + = link_to admin_account_path(@account.id) do + %i.fa.fa-chevron-left.fa-fw + = t('admin.followers.back_to_account') + +.table-wrapper + %table.table + %thead + %tr + %th= t('admin.accounts.username') + %th= t('admin.accounts.role') + %th= t('admin.accounts.most_recent_ip') + %th= t('admin.accounts.most_recent_activity') + %th + %tbody + = render partial: 'admin/accounts/account', collection: @followers.map{|a| a.account} + += paginate @followers diff --git a/config/locales/en.yml b/config/locales/en.yml index 091a4b72c6..7ccff2ffdd 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -105,6 +105,7 @@ en: enabled: Enabled feed_url: Feed URL followers: Followers + followers_local: "(%{local} local)" followers_url: Followers URL follows: Follows header: Header @@ -296,6 +297,9 @@ en: create: Add domain title: New e-mail blacklist entry title: E-mail blacklist + followers: + back_to_account: Back To Account + title: "%{acct}'s Followers" instances: account_count: Known accounts domain_name: Domain diff --git a/config/routes.rb b/config/routes.rb index 808bb5acd6..1556aa5774 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -191,6 +191,7 @@ Rails.application.routes.draw do resource :reset, only: [:create] resource :action, only: [:new, :create], controller: 'account_actions' resources :statuses, only: [:index, :create, :update, :destroy] + resources :followers, only: [:index] resource :confirmation, only: [:create] do collection do