module Admin
class TagsController < BaseController
- before_action :set_tags, only: :index
before_action :set_tag, except: [:index, :batch, :approve_all, :reject_all]
before_action :set_usage_by_domain, except: [:index, :batch, :approve_all, :reject_all]
before_action :set_counters, except: [:index, :batch, :approve_all, :reject_all]
def index
authorize :tag, :index?
+ @tags = filtered_tags.page(params[:page])
@form = Form::TagBatch.new
end
private
- def set_tags
- @tags = filtered_tags.page(params[:page])
- end
-
def set_tag
@tag = Tag.find(params[:id])
end
end
def filtered_tags
- scope = Tag
- scope = scope.discoverable if filter_params[:context] == 'directory'
- scope = scope.unreviewed if filter_params[:review] == 'unreviewed'
- scope = scope.reviewed.order(reviewed_at: :desc) if filter_params[:review] == 'reviewed'
- scope = scope.pending_review.order(requested_review_at: :desc) if filter_params[:review] == 'pending_review'
- scope.order(max_score: :desc)
+ TagFilter.new(filter_params).results
end
def filter_params
- params.slice(:context, :review, :page).permit(:context, :review, :page)
+ params.slice(:directory, :reviewed, :unreviewed, :pending_review, :page, :popular, :active, :name).permit(:directory, :reviewed, :unreviewed, :pending_review, :page, :popular, :active, :name)
end
def tag_params
REPORT_FILTERS = %i(resolved account_id target_account_id).freeze
INVITE_FILTER = %i(available expired).freeze
CUSTOM_EMOJI_FILTERS = %i(local remote by_domain shortcode).freeze
- TAGS_FILTERS = %i(context review).freeze
+ TAGS_FILTERS = %i(directory reviewed unreviewed pending_review popular active name).freeze
INSTANCES_FILTERS = %i(limited by_domain).freeze
FOLLOWERS_FILTERS = %i(relationship status by_domain activity order).freeze
scope :listable, -> { where(listable: [true, nil]) }
scope :discoverable, -> { listable.joins(:account_tag_stat).where(AccountTagStat.arel_table[:accounts_count].gt(0)).order(Arel.sql('account_tag_stats.accounts_count desc')) }
scope :most_used, ->(account) { joins(:statuses).where(statuses: { account: account }).group(:id).order(Arel.sql('count(*) desc')) }
+ scope :matches_name, ->(value) { where(arel_table[:name].matches("#{value}%")) }
delegate :accounts_count,
:accounts_count=,
--- /dev/null
+# frozen_string_literal: true
+
+class TagFilter
+ attr_reader :params
+
+ def initialize(params)
+ @params = params
+ end
+
+ def results
+ scope = Tag.unscoped
+
+ params.each do |key, value|
+ next if key.to_s == 'page'
+
+ scope.merge!(scope_for(key, value.to_s.strip)) if value.present?
+ end
+
+ scope.order(id: :desc)
+ end
+
+ private
+
+ def scope_for(key, value)
+ case key.to_s
+ when 'directory'
+ Tag.discoverable
+ when 'reviewed'
+ Tag.reviewed.order(reviewed_at: :desc)
+ when 'unreviewed'
+ Tag.unreviewed
+ when 'pending_review'
+ Tag.pending_review.order(requested_review_at: :desc)
+ when 'popular'
+ Tag.order('max_score DESC NULLS LAST')
+ when 'active'
+ Tag.order('last_status_at DESC NULLS LAST')
+ when 'name'
+ Tag.matches_name(value)
+ else
+ raise "Unknown filter: #{key}"
+ end
+ end
+end
.filter-subset
%strong= t('admin.tags.context')
%ul
- %li= filter_link_to t('generic.all'), context: nil
- %li= filter_link_to t('admin.tags.directory'), context: 'directory'
+ %li= filter_link_to t('generic.all'), directory: nil
+ %li= filter_link_to t('admin.tags.directory'), directory: '1'
.filter-subset
%strong= t('admin.tags.review')
%ul
- %li= filter_link_to t('generic.all'), review: nil
- %li= filter_link_to t('admin.tags.unreviewed'), review: 'unreviewed'
- %li= filter_link_to t('admin.tags.reviewed'), review: 'reviewed'
- %li= filter_link_to safe_join([t('admin.accounts.moderation.pending'), "(#{Tag.pending_review.count})"], ' '), review: 'pending_review'
+ %li= filter_link_to t('generic.all'), reviewed: nil, unreviewed: nil, pending_review: nil
+ %li= filter_link_to t('admin.tags.unreviewed'), unreviewed: '1', reviewed: nil, pending_review: nil
+ %li= filter_link_to t('admin.tags.reviewed'), reviewed: '1', unreviewed: nil, pending_review: nil
+ %li= filter_link_to safe_join([t('admin.accounts.moderation.pending'), "(#{Tag.pending_review.count})"], ' '), pending_review: '1', reviewed: nil, unreviewed: nil
+
+ .filter-subset
+ %strong= t('generic.order_by')
+ %ul
+ %li= filter_link_to t('admin.tags.most_recent'), popular: nil, active: nil
+ %li= filter_link_to t('admin.tags.most_popular'), popular: '1', active: nil
+ %li= filter_link_to t('admin.tags.last_active'), active: '1', popular: nil
+
+= form_tag admin_tags_url, method: 'GET', class: 'simple_form' do
+ .fields-group
+ - Admin::FilterHelper::TAGS_FILTERS.each do |key|
+ = hidden_field_tag key, params[key] if params[key].present?
+
+ - %i(name).each do |key|
+ .input.string.optional
+ = text_field_tag key, params[key], class: 'string optional', placeholder: I18n.t("admin.tags.#{key}")
+
+ .actions
+ %button= t('admin.accounts.search')
+ = link_to t('admin.accounts.reset'), admin_tags_path, class: 'button negative'
%hr.spacer/
context: Context
directory: In directory
in_directory: "%{count} in directory"
+ last_active: Last active
+ most_popular: Most popular
+ most_recent: Most recent
+ name: Hashtag
review: Review status
reviewed: Reviewed
title: Hashtags
must_be_follower: Block notifications from non-followers
must_be_following: Block notifications from people you don't follow
must_be_following_dm: Block direct messages from people you don't follow
+ invite:
+ comment: Comment
invite_request:
text: Why do you want to join?
notification_emails: