parent
155cf12680
commit
73be8f38c1
@ -0,0 +1,44 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
class TagsController < BaseController
|
||||
before_action :set_tags, only: :index
|
||||
before_action :set_tag, except: :index
|
||||
before_action :set_filter_params
|
||||
|
||||
def index
|
||||
authorize :tag, :index?
|
||||
end
|
||||
|
||||
def hide
|
||||
authorize @tag, :hide?
|
||||
@tag.account_tag_stat.update!(hidden: true)
|
||||
redirect_to admin_tags_path(@filter_params)
|
||||
end
|
||||
|
||||
def unhide
|
||||
authorize @tag, :unhide?
|
||||
@tag.account_tag_stat.update!(hidden: true)
|
||||
redirect_to admin_tags_path(@filter_params)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_tags
|
||||
@tags = Tag.discoverable
|
||||
@tags.merge!(Tag.hidden) if filter_params[:hidden]
|
||||
end
|
||||
|
||||
def set_tag
|
||||
@tag = Tag.find(params[:id])
|
||||
end
|
||||
|
||||
def set_filter_params
|
||||
@filter_params = filter_params.to_hash.symbolize_keys
|
||||
end
|
||||
|
||||
def filter_params
|
||||
params.permit(:hidden)
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,48 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class DirectoriesController < ApplicationController
|
||||
layout 'public'
|
||||
|
||||
before_action :set_instance_presenter
|
||||
before_action :set_tag, only: :show
|
||||
before_action :set_tags
|
||||
before_action :set_accounts
|
||||
|
||||
def index
|
||||
render :index
|
||||
end
|
||||
|
||||
def show
|
||||
render :index
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_tag
|
||||
@tag = Tag.discoverable.find_by!(name: params[:id].downcase)
|
||||
end
|
||||
|
||||
def set_tags
|
||||
@tags = Tag.discoverable.limit(30)
|
||||
end
|
||||
|
||||
def set_accounts
|
||||
@accounts = Account.searchable.discoverable.page(params[:page]).per(50).tap do |query|
|
||||
query.merge!(Account.tagged_with(@tag.id)) if @tag
|
||||
|
||||
if popular_requested?
|
||||
query.merge!(Account.popular)
|
||||
else
|
||||
query.merge!(Account.by_recent_status)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def set_instance_presenter
|
||||
@instance_presenter = InstancePresenter.new
|
||||
end
|
||||
|
||||
def popular_requested?
|
||||
request.path.ends_with?('/popular')
|
||||
end
|
||||
end
|
@ -0,0 +1,24 @@
|
||||
# frozen_string_literal: true
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: account_tag_stats
|
||||
#
|
||||
# id :bigint(8) not null, primary key
|
||||
# tag_id :bigint(8) not null
|
||||
# accounts_count :bigint(8) default(0), not null
|
||||
# hidden :boolean default(FALSE), not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
|
||||
class AccountTagStat < ApplicationRecord
|
||||
belongs_to :tag, inverse_of: :account_tag_stat
|
||||
|
||||
def increment_count!(key)
|
||||
update(key => public_send(key) + 1)
|
||||
end
|
||||
|
||||
def decrement_count!(key)
|
||||
update(key => [public_send(key) - 1, 0].max)
|
||||
end
|
||||
end
|
@ -0,0 +1,15 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class TagPolicy < ApplicationPolicy
|
||||
def index?
|
||||
staff?
|
||||
end
|
||||
|
||||
def hide?
|
||||
staff?
|
||||
end
|
||||
|
||||
def unhide?
|
||||
staff?
|
||||
end
|
||||
end
|
@ -0,0 +1,12 @@
|
||||
%tr
|
||||
%td
|
||||
= link_to explore_hashtag_path(tag) do
|
||||
= fa_icon 'hashtag'
|
||||
= tag.name
|
||||
%td
|
||||
= t('directories.people', count: tag.accounts_count)
|
||||
%td
|
||||
- if tag.hidden?
|
||||
= table_link_to 'eye', t('admin.tags.unhide'), unhide_admin_tag_path(tag.id, **@filter_params), method: :post
|
||||
- else
|
||||
= table_link_to 'eye-slash', t('admin.tags.hide'), hide_admin_tag_path(tag.id, **@filter_params), method: :post
|
@ -0,0 +1,19 @@
|
||||
- content_for :page_title do
|
||||
= t('admin.tags.title')
|
||||
|
||||
.filters
|
||||
.filter-subset
|
||||
%strong= t('admin.reports.status')
|
||||
%ul
|
||||
%li= filter_link_to t('admin.tags.visible'), hidden: nil
|
||||
%li= filter_link_to t('admin.tags.hidden'), hidden: '1'
|
||||
|
||||
.table-wrapper
|
||||
%table.table
|
||||
%thead
|
||||
%tr
|
||||
%th= t('admin.tags.name')
|
||||
%th= t('admin.tags.accounts')
|
||||
%th
|
||||
%tbody
|
||||
= render @tags
|
@ -0,0 +1,59 @@
|
||||
- content_for :page_title do
|
||||
= t('directories.explore_mastodon')
|
||||
|
||||
- content_for :header_tags do
|
||||
%meta{ name: 'description', content: t('directories.explanation') }
|
||||
|
||||
= opengraph 'og:site_name', site_title
|
||||
= opengraph 'og:title', t('directories.explore_mastodon', title: site_title)
|
||||
= opengraph 'og:description', t('directories.explanation')
|
||||
|
||||
.page-header
|
||||
%h1= t('directories.explore_mastodon', title: site_title)
|
||||
%p= t('directories.explanation')
|
||||
|
||||
.grid
|
||||
.column-0
|
||||
.account__section-headline
|
||||
= active_link_to t('directories.most_recently_active'), @tag ? explore_hashtag_path(@tag) : explore_path
|
||||
= active_link_to t('directories.most_popular'), @tag ? explore_hashtag_popular_path(@tag) : explore_popular_path
|
||||
|
||||
- if @accounts.empty?
|
||||
= nothing_here
|
||||
- else
|
||||
.directory
|
||||
%table.accounts-table
|
||||
%tbody
|
||||
- @accounts.each do |account|
|
||||
%tr
|
||||
%td= account_link_to account
|
||||
%td.accounts-table__count
|
||||
= number_to_human account.statuses_count, strip_insignificant_zeros: true
|
||||
%small= t('accounts.posts', count: account.statuses_count)
|
||||
%td.accounts-table__count
|
||||
= number_to_human account.followers_count, strip_insignificant_zeros: true
|
||||
%small= t('accounts.followers', count: account.followers_count)
|
||||
%td.accounts-table__count
|
||||
- if account.last_status_at.present?
|
||||
%time.time-ago{ datetime: account.last_status_at.iso8601, title: l(account.last_status_at) }= l account.last_status_at
|
||||
- else
|
||||
\-
|
||||
%small= t('accounts.last_active')
|
||||
|
||||
= paginate @accounts
|
||||
|
||||
.column-1
|
||||
- if @tags.empty?
|
||||
.nothing-here.nothing-here--flexible
|
||||
- else
|
||||
- @tags.each do |tag|
|
||||
.directory__tag{ class: tag.id == @tag&.id ? 'active' : nil }
|
||||
= link_to explore_hashtag_path(tag) do
|
||||
%h4
|
||||
= fa_icon 'hashtag'
|
||||
= tag.name
|
||||
%small= t('directories.people', count: tag.accounts_count)
|
||||
|
||||
.avatar-stack
|
||||
- tag.accounts.limit(3).each do |account|
|
||||
= image_tag current_account&.user&.setting_auto_play_gif ? account.avatar_original_url : account.avatar_static_url, width: 48, height: 48, alt: '', class: 'account__avatar'
|
@ -0,0 +1,8 @@
|
||||
class CreateAccountsTagsJoinTable < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_join_table :accounts, :tags do |t|
|
||||
t.index [:account_id, :tag_id]
|
||||
t.index [:tag_id, :account_id], unique: true
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,5 @@
|
||||
class AddDiscoverableToAccounts < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :accounts, :discoverable, :boolean
|
||||
end
|
||||
end
|
@ -0,0 +1,5 @@
|
||||
class AddLastStatusAtToAccountStats < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :account_stats, :last_status_at, :datetime
|
||||
end
|
||||
end
|
@ -0,0 +1,11 @@
|
||||
class CreateAccountTagStats < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_table :account_tag_stats do |t|
|
||||
t.belongs_to :tag, null: false, foreign_key: { on_delete: :cascade }, index: { unique: true }
|
||||
t.bigint :accounts_count, default: 0, null: false
|
||||
t.boolean :hidden, default: false, null: false
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,3 @@
|
||||
Fabricator(:account_tag_stat) do
|
||||
accounts_count ""
|
||||
end
|
@ -0,0 +1,5 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe AccountTagStat, type: :model do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
Loading…
Reference in new issue