Add featured hashtags to profiles (#9755)
* Add hashtag filter to profiles GET /@:username/tagged/:hashtag GET /api/v1/accounts/:id/statuses?tagged=:hashtag * Display featured hashtags on public profile * Use separate model for featured tags * Update featured hashtag counters on-write * Limit featured tags to 10master
parent
d14c276e58
commit
364f2ff9aa
@ -0,0 +1,51 @@ |
|||||||
|
# frozen_string_literal: true |
||||||
|
|
||||||
|
class Settings::FeaturedTagsController < Settings::BaseController |
||||||
|
layout 'admin' |
||||||
|
|
||||||
|
before_action :authenticate_user! |
||||||
|
before_action :set_featured_tags, only: :index |
||||||
|
before_action :set_featured_tag, except: [:index, :create] |
||||||
|
before_action :set_most_used_tags, only: :index |
||||||
|
|
||||||
|
def index |
||||||
|
@featured_tag = FeaturedTag.new |
||||||
|
end |
||||||
|
|
||||||
|
def create |
||||||
|
@featured_tag = current_account.featured_tags.new(featured_tag_params) |
||||||
|
@featured_tag.reset_data |
||||||
|
|
||||||
|
if @featured_tag.save |
||||||
|
redirect_to settings_featured_tags_path |
||||||
|
else |
||||||
|
set_featured_tags |
||||||
|
set_most_used_tags |
||||||
|
|
||||||
|
render :index |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
def destroy |
||||||
|
@featured_tag.destroy! |
||||||
|
redirect_to settings_featured_tags_path |
||||||
|
end |
||||||
|
|
||||||
|
private |
||||||
|
|
||||||
|
def set_featured_tag |
||||||
|
@featured_tag = current_account.featured_tags.find(params[:id]) |
||||||
|
end |
||||||
|
|
||||||
|
def set_featured_tags |
||||||
|
@featured_tags = current_account.featured_tags.reject(&:new_record?) |
||||||
|
end |
||||||
|
|
||||||
|
def set_most_used_tags |
||||||
|
@most_used_tags = Tag.most_used(current_account).where.not(id: @featured_tags.map(&:id)).limit(10) |
||||||
|
end |
||||||
|
|
||||||
|
def featured_tag_params |
||||||
|
params.require(:featured_tag).permit(:name) |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,46 @@ |
|||||||
|
# frozen_string_literal: true |
||||||
|
# == Schema Information |
||||||
|
# |
||||||
|
# Table name: featured_tags |
||||||
|
# |
||||||
|
# id :bigint(8) not null, primary key |
||||||
|
# account_id :bigint(8) |
||||||
|
# tag_id :bigint(8) |
||||||
|
# statuses_count :bigint(8) default(0), not null |
||||||
|
# last_status_at :datetime |
||||||
|
# created_at :datetime not null |
||||||
|
# updated_at :datetime not null |
||||||
|
# |
||||||
|
|
||||||
|
class FeaturedTag < ApplicationRecord |
||||||
|
belongs_to :account, inverse_of: :featured_tags, required: true |
||||||
|
belongs_to :tag, inverse_of: :featured_tags, required: true |
||||||
|
|
||||||
|
delegate :name, to: :tag, allow_nil: true |
||||||
|
|
||||||
|
validates :name, presence: true |
||||||
|
validate :validate_featured_tags_limit, on: :create |
||||||
|
|
||||||
|
def name=(str) |
||||||
|
self.tag = Tag.find_or_initialize_by(name: str.delete('#').mb_chars.downcase.to_s) |
||||||
|
end |
||||||
|
|
||||||
|
def increment(timestamp) |
||||||
|
update(statuses_count: statuses_count + 1, last_status_at: timestamp) |
||||||
|
end |
||||||
|
|
||||||
|
def decrement(deleted_status_id) |
||||||
|
update(statuses_count: [0, statuses_count - 1].max, last_status_at: account.statuses.where(visibility: %i(public unlisted)).tagged_with(tag).where.not(id: deleted_status_id).select(:created_at).first&.created_at) |
||||||
|
end |
||||||
|
|
||||||
|
def reset_data |
||||||
|
self.statuses_count = account.statuses.where(visibility: %i(public unlisted)).tagged_with(tag).count |
||||||
|
self.last_status_at = account.statuses.where(visibility: %i(public unlisted)).tagged_with(tag).select(:created_at).first&.created_at |
||||||
|
end |
||||||
|
|
||||||
|
private |
||||||
|
|
||||||
|
def validate_featured_tags_limit |
||||||
|
errors.add(:base, I18n.t('featured_tags.errors.limit')) if account.featured_tags.count >= 10 |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,27 @@ |
|||||||
|
- content_for :page_title do |
||||||
|
= t('settings.featured_tags') |
||||||
|
|
||||||
|
= simple_form_for @featured_tag, url: settings_featured_tags_path do |f| |
||||||
|
= render 'shared/error_messages', object: @featured_tag |
||||||
|
|
||||||
|
.fields-group |
||||||
|
= f.input :name, wrapper: :with_block_label, hint: safe_join([t('simple_form.hints.featured_tag.name'), safe_join(@most_used_tags.map { |tag| link_to("##{tag.name}", settings_featured_tags_path(featured_tag: { name: tag.name }), method: :post) }, ', ')], ' ') |
||||||
|
|
||||||
|
.actions |
||||||
|
= f.button :button, t('featured_tags.add_new'), type: :submit |
||||||
|
|
||||||
|
%hr.spacer/ |
||||||
|
|
||||||
|
- @featured_tags.each do |featured_tag| |
||||||
|
.directory__tag{ class: params[:tag] == featured_tag.name ? 'active' : nil } |
||||||
|
%div |
||||||
|
%h4 |
||||||
|
= fa_icon 'hashtag' |
||||||
|
= featured_tag.name |
||||||
|
%small |
||||||
|
- if featured_tag.last_status_at.nil? |
||||||
|
= t('accounts.nothing_here') |
||||||
|
- else |
||||||
|
%time{ datetime: featured_tag.last_status_at.iso8601, title: l(featured_tag.last_status_at) }= l featured_tag.last_status_at |
||||||
|
= table_link_to 'trash', t('filters.index.delete'), settings_featured_tag_path(featured_tag), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') } |
||||||
|
.trends__item__current= number_to_human featured_tag.statuses_count, strip_insignificant_zeros: true |
@ -0,0 +1,12 @@ |
|||||||
|
class CreateFeaturedTags < ActiveRecord::Migration[5.2] |
||||||
|
def change |
||||||
|
create_table :featured_tags do |t| |
||||||
|
t.references :account, foreign_key: { on_delete: :cascade } |
||||||
|
t.references :tag, foreign_key: { on_delete: :cascade } |
||||||
|
t.bigint :statuses_count, default: 0, null: false |
||||||
|
t.datetime :last_status_at |
||||||
|
|
||||||
|
t.timestamps |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,6 @@ |
|||||||
|
Fabricator(:featured_tag) do |
||||||
|
account |
||||||
|
tag |
||||||
|
statuses_count 1_337 |
||||||
|
last_status_at Time.now.utc |
||||||
|
end |
@ -0,0 +1,4 @@ |
|||||||
|
require 'rails_helper' |
||||||
|
|
||||||
|
RSpec.describe FeaturedTag, type: :model do |
||||||
|
end |
Loading…
Reference in new issue