From 3bcbbb74636db32fc3929f5bf38e9fa9ba213537 Mon Sep 17 00:00:00 2001 From: noellabo Date: Sun, 5 Jan 2020 15:36:28 +0900 Subject: [PATCH] Add hashtag follow and account subscribe support to list --- .../settings/account_subscribes_controller.rb | 63 ++++++++++++------- .../settings/follow_tags_controller.rb | 36 ++++++++++- .../mastodon/features/subscribing/index.js | 2 +- app/models/account_subscribe.rb | 21 +++++++ app/models/concerns/account_interactions.rb | 22 ++++--- app/models/follow_tag.rb | 3 + app/models/form/account_subscribe.rb | 13 ++++ app/services/account_subscribe_service.rb | 22 ++++--- app/services/fan_out_on_write_service.rb | 30 +++++++-- .../account_subscribes/_fields.html.haml | 11 ++++ .../account_subscribes/edit.html.haml | 9 +++ .../account_subscribes/index.html.haml | 45 ++++++++----- .../settings/account_subscribes/new.html.haml | 9 +++ .../domain_subscribes/index.html.haml | 2 +- .../settings/follow_tags/_fields.html.haml | 8 +++ app/views/settings/follow_tags/edit.html.haml | 9 +++ .../settings/follow_tags/index.html.haml | 42 +++++++------ app/views/settings/follow_tags/new.html.haml | 9 +++ config/locales/en.yml | 19 ++++-- config/locales/ja.yml | 17 +++-- config/locales/simple_form.en.yml | 17 ++++- config/locales/simple_form.ja.yml | 15 ++++- config/navigation.rb | 8 +-- config/routes.rb | 4 +- ...5_add_show_reblogs_to_account_subscribe.rb | 17 +++++ db/schema.rb | 23 +++++++ 26 files changed, 373 insertions(+), 103 deletions(-) create mode 100644 app/models/form/account_subscribe.rb create mode 100644 app/views/settings/account_subscribes/_fields.html.haml create mode 100644 app/views/settings/account_subscribes/edit.html.haml create mode 100644 app/views/settings/account_subscribes/new.html.haml create mode 100644 app/views/settings/follow_tags/_fields.html.haml create mode 100644 app/views/settings/follow_tags/edit.html.haml create mode 100644 app/views/settings/follow_tags/new.html.haml create mode 100644 db/migrate/20200105023325_add_show_reblogs_to_account_subscribe.rb diff --git a/app/controllers/settings/account_subscribes_controller.rb b/app/controllers/settings/account_subscribes_controller.rb index 4ca838ac3..e21badd4e 100644 --- a/app/controllers/settings/account_subscribes_controller.rb +++ b/app/controllers/settings/account_subscribes_controller.rb @@ -3,28 +3,20 @@ class Settings::AccountSubscribesController < Settings::BaseController layout 'admin' before_action :authenticate_user! + before_action :set_lists, only: [:index, :new, :edit, :update] before_action :set_account_subscribings, only: :index - - class AccountInput - include ActiveModel::Model - include ActiveModel::Attributes - - attribute :acct, :string - end + before_action :set_account_subscribing, only: [:edit, :update, :destroy] def index - @account_input = AccountInput.new + end + + def new + @form_account_subscribing = Form::AccountSubscribe.new end def create - acct = account_subscribe_params[:acct].strip - acct = acct[1..-1] if acct.start_with?("@") - - begin - target_account = AccountSubscribeService.new.call(current_account, acct) - rescue - target_account = nil - end + @form_account_subscribing = Form::AccountSubscribe.new(account_subscribe_params) + target_account = AccountSubscribeService.new.call(current_account, @form_account_subscribing.acct, @form_account_subscribing.show_reblogs, @form_account_subscribing.list_id) if target_account redirect_to settings_account_subscribes_path @@ -35,21 +27,48 @@ class Settings::AccountSubscribesController < Settings::BaseController end end + def edit; end + + def update + if @account_subscribing.update(account_subscribe_params.merge(account: current_account)) + redirect_to settings_account_subscribes_path + else + render action: :edit + end + end + def destroy - target_account = current_account.active_subscribes.find(params[:id]).target_account - UnsubscribeAccountService.new.call(current_account, target_account) + UnsubscribeAccountService.new.call(current_account, @account_subscribing.target_account) redirect_to settings_account_subscribes_path end private + def set_account_subscribing + @account_subscribing = current_account.active_subscribes.find(params[:id]) + @form_account_subscribing = Form::AccountSubscribe.new(id: @account_subscribing.id, acct: @account_subscribing.target_account.acct, show_reblogs: @account_subscribing.show_reblogs, list_id: @account_subscribing.list_id) + end + def set_account_subscribings - @account_subscribings = current_account.active_subscribes.order(:updated_at).reject(&:new_record?).map do |subscribing| - {id: subscribing.id, acct: subscribing.target_account.acct} - end + @account_subscribings = current_account.active_subscribes.order('list_id NULLS FIRST', :updated_at).reject(&:new_record?) + end + + def set_lists + @lists = List.where(account: current_account).all end def account_subscribe_params - params.require(:account_input).permit(:acct) + new_params = resource_params.permit!.to_h + + if resource_params[:list_id] == '-1' + list = List.find_or_create_by!({ account: current_account, title: new_params[:acct] }) + new_params.merge!({list_id: list.id}) + end + + new_params + end + + def resource_params + params.require(:form_account_subscribe).permit(:acct, :show_reblogs, :list_id) end end diff --git a/app/controllers/settings/follow_tags_controller.rb b/app/controllers/settings/follow_tags_controller.rb index 776a48504..a42c00c34 100644 --- a/app/controllers/settings/follow_tags_controller.rb +++ b/app/controllers/settings/follow_tags_controller.rb @@ -4,13 +4,18 @@ class Settings::FollowTagsController < Settings::BaseController layout 'admin' before_action :authenticate_user! + before_action :set_lists, only: [:index, :new, :edit, :update] before_action :set_follow_tags, only: :index - before_action :set_follow_tag, except: [:index, :create] + before_action :set_follow_tag, only: [:edit, :update, :destroy] def index @follow_tag = FollowTag.new end + def new + @follow_tag = current_account.follow_tags.build + end + def create @follow_tag = current_account.follow_tags.new(follow_tag_params) @@ -23,6 +28,16 @@ class Settings::FollowTagsController < Settings::BaseController end end + def edit; end + + def update + if @follow_tag.update(follow_tag_params) + redirect_to settings_follow_tag_path + else + render action: :edit + end + end + def destroy @follow_tag.destroy! redirect_to settings_follow_tags_path @@ -35,10 +50,25 @@ class Settings::FollowTagsController < Settings::BaseController end def set_follow_tags - @follow_tags = current_account.follow_tags.order(:updated_at).reject(&:new_record?) + @follow_tags = current_account.follow_tags.order('list_id NULLS FIRST', :updated_at).reject(&:new_record?) + end + + def set_lists + @lists = List.where(account: current_account).all end def follow_tag_params - params.require(:follow_tag).permit(:name) + new_params = resource_params.permit!.to_h + + if resource_params[:list_id] == '-1' + list = List.find_or_create_by!({ account: current_account, title: new_params[:name] }) + new_params.merge!({list_id: list.id}) + end + + new_params + end + + def resource_params + params.require(:follow_tag).permit(:name, :list_id) end end diff --git a/app/javascript/mastodon/features/subscribing/index.js b/app/javascript/mastodon/features/subscribing/index.js index cdc6ae620..e682bf85e 100644 --- a/app/javascript/mastodon/features/subscribing/index.js +++ b/app/javascript/mastodon/features/subscribing/index.js @@ -54,7 +54,7 @@ class Subscribing extends ImmutablePureComponent { } handleLoadMore = debounce(() => { - this.props.dispatch(expandSubscribing()); + this.props.dispatch(expandSubscribing(this.props.params.accountId)); }, 300, { leading: true }); render () { diff --git a/app/models/account_subscribe.rb b/app/models/account_subscribe.rb index e6663c61c..46776feac 100644 --- a/app/models/account_subscribe.rb +++ b/app/models/account_subscribe.rb @@ -5,6 +5,7 @@ # id :bigint(8) not null, primary key # account_id :bigint(8) # target_account_id :bigint(8) +# show_reblogs :boolean default(TRUE), not null # created_at :datetime not null # updated_at :datetime not null # list_id :bigint(8) @@ -22,12 +23,32 @@ class AccountSubscribe < ApplicationRecord scope :recent, -> { reorder(id: :desc) } scope :subscribed_lists, ->(account) { AccountSubscribe.where(target_account_id: account.id).where.not(list_id: nil).select(:list_id).uniq } + scope :home, -> { where(list_id: nil) } + scope :list, -> { where.not(list_id: nil) } + scope :with_reblog, ->(reblog) { where(show_reblogs: true) if reblog } after_create :increment_cache_counters after_destroy :decrement_cache_counters + attr_accessor :acct + + def acct=(val) + return if val.nil? + + target_account = ResolveAccountService.new.call(acct, skip_webfinger: true) + target_account ||= ResolveAccountService.new.call(acct, skip_webfinger: false) + end + + def acct + target_account&.acct + end + private + def home? + list_id.nil? + end + def increment_cache_counters account&.increment_count!(:subscribing_count) end diff --git a/app/models/concerns/account_interactions.rb b/app/models/concerns/account_interactions.rb index fcbc69641..92912e0bc 100644 --- a/app/models/concerns/account_interactions.rb +++ b/app/models/concerns/account_interactions.rb @@ -194,8 +194,8 @@ module AccountInteractions block&.destroy end - def subscribe!(other_account) - rel = active_subscribes.find_or_create_by!(target_account: other_account) + def subscribe!(other_account, show_reblogs = true, list_id = nil) + rel = active_subscribes.find_or_create_by!(target_account: other_account, show_reblogs: show_reblogs, list_id: list_id) remove_potential_friendship(other_account) @@ -262,8 +262,8 @@ module AccountInteractions account_pins.where(target_account: account).exists? end - def subscribing?(other_account) - active_subscribes.where(target_account: other_account).exists? + def subscribing?(other_account, list_id = nil) + active_subscribes.where(target_account: other_account, list_id: list_id).exists? end def followers_for_local_distribution @@ -273,9 +273,10 @@ module AccountInteractions end def subscribers_for_local_distribution - subscribers.local - .joins(:user) - .where('users.current_sign_in_at > ?', User::ACTIVE_DURATION.ago) + AccountSubscribe.home + .joins(account: :user) + .where(target_account_id: id) + .where('users.current_sign_in_at > ?', User::ACTIVE_DURATION.ago) end def lists_for_local_distribution @@ -283,6 +284,13 @@ module AccountInteractions .where('users.current_sign_in_at > ?', User::ACTIVE_DURATION.ago) end + def list_subscribers_for_local_distribution + AccountSubscribe.list + .joins(account: :user) + .where(target_account_id: id) + .where('users.current_sign_in_at > ?', User::ACTIVE_DURATION.ago) + end + def remote_followers_hash(url) url_prefix = url[Account::URL_PREFIX_RE] return if url_prefix.blank? diff --git a/app/models/follow_tag.rb b/app/models/follow_tag.rb index 90b428b74..25ed799f9 100644 --- a/app/models/follow_tag.rb +++ b/app/models/follow_tag.rb @@ -21,6 +21,9 @@ class FollowTag < ApplicationRecord validates :name, presence: true, on: :create validates :account_id, uniqueness: { scope: [:tag_id, :list_id] } + scope :home, -> { where(list_id: nil) } + scope :list, -> { where.not(list_id: nil) } + def name=(str) self.tag = Tag.find_or_create_by_names(str.strip)&.first end diff --git a/app/models/form/account_subscribe.rb b/app/models/form/account_subscribe.rb new file mode 100644 index 000000000..664ac914e --- /dev/null +++ b/app/models/form/account_subscribe.rb @@ -0,0 +1,13 @@ +class Form::AccountSubscribe + include ActiveModel::Model + include ActiveModel::Attributes + + attribute :id, :integer + attribute :acct, :string + attribute :show_reblogs, :boolean, default: true + attribute :list_id, :integer + + def acct=(val) + super(val.to_s.strip.gsub(/\A@/, '')) + end +end diff --git a/app/services/account_subscribe_service.rb b/app/services/account_subscribe_service.rb index 05e10953e..d70f62789 100644 --- a/app/services/account_subscribe_service.rb +++ b/app/services/account_subscribe_service.rb @@ -4,25 +4,29 @@ class AccountSubscribeService < BaseService # Subscribe a remote user # @param [Account] source_account From which to subscribe # @param [String, Account] uri User URI to subscribe in the form of username@domain (or account record) - def call(source_account, target_account) - begin - target_account = ResolveAccountService.new.call(target_account, skip_webfinger: true) - target_account ||= ResolveAccountService.new.call(target_account, skip_webfinger: false) - rescue - target_account = nil + def call(source_account, target_acct, show_reblogs = true, list_id = nil) + if target_acct.class.name == 'Account' + target_account = target_acct + else + begin + target_account = ResolveAccountService.new.call(target_acct, skip_webfinger: true) + target_account ||= ResolveAccountService.new.call(target_acct, skip_webfinger: false) + rescue + target_account = nil + end end raise ActiveRecord::RecordNotFound if target_account.nil? || target_account.id == source_account.id || target_account.suspended? raise Mastodon::NotPermittedError if target_account.blocking?(source_account) || source_account.blocking?(target_account) || (!target_account.local? && target_account.ostatus?) || source_account.domain_blocking?(target_account.domain) - if source_account.subscribing?(target_account) + if source_account.subscribing?(target_account, list_id) return end ActivityTracker.increment('activity:interactions') - subscribe = source_account.subscribe!(target_account) - MergeWorker.perform_async(target_account.id, source_account.id, true) + subscribe = source_account.subscribe!(target_account, show_reblogs, list_id) + MergeWorker.perform_async(target_account.id, source_account.id, true) if list_id.nil? subscribe end end diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb index 8d24bc02f..5ed19eb0a 100644 --- a/app/services/fan_out_on_write_service.rb +++ b/app/services/fan_out_on_write_service.rb @@ -21,6 +21,8 @@ class FanOutOnWriteService < BaseService return if status.account.silenced? || !status.public_visibility? deliver_to_domain_subscribers(status) + deliver_to_subscribers(status) + deliver_to_subscribers_lists(status) return if status.reblog? @@ -28,7 +30,6 @@ class FanOutOnWriteService < BaseService deliver_to_hashtags(status) deliver_to_hashtag_followers(status) - deliver_to_subscribers(status) deliver_to_keyword_subscribers(status) return if status.reply? && status.in_reply_to_account_id != status.account_id @@ -57,9 +58,19 @@ class FanOutOnWriteService < BaseService def deliver_to_subscribers(status) Rails.logger.debug "Delivering status #{status.id} to subscribers" - status.account.subscribers_for_local_distribution.select(:id).reorder(nil).find_in_batches do |subscribings| + status.account.subscribers_for_local_distribution.with_reblog(status.reblog?).select(:id, :account_id).reorder(nil).find_in_batches do |subscribings| FeedInsertWorker.push_bulk(subscribings) do |subscribing| - [status.id, subscribing.id, :home] + [status.id, subscribing.account_id, :home] + end + end + end + + def deliver_to_subscribers_lists(status) + Rails.logger.debug "Delivering status #{status.id} to subscribers lists" + + status.account.list_subscribers_for_local_distribution.with_reblog(status.reblog?).select(:id, :list_id).reorder(nil).find_in_batches do |subscribings| + FeedInsertWorker.push_bulk(subscribings) do |subscribing| + [status.id, subscribing.list_id, :list] end end end @@ -157,11 +168,22 @@ class FanOutOnWriteService < BaseService def deliver_to_hashtag_followers(status) Rails.logger.debug "Delivering status #{status.id} to hashtag followers" - FeedInsertWorker.push_bulk(FollowTag.where(tag: status.tags).pluck(:account_id).uniq) do |follower| + deliver_to_hashtag_followers_home(status) + deliver_to_hashtag_followers_list(status) + end + + def deliver_to_hashtag_followers_home(status) + FeedInsertWorker.push_bulk(FollowTag.home.where(tag: status.tags).pluck(:account_id).uniq) do |follower| [status.id, follower, :home] end end + def deliver_to_hashtag_followers_list(status) + FeedInsertWorker.push_bulk(FollowTag.list.where(tag: status.tags).pluck(:list_id).uniq) do |list_id| + [status.id, list_id, :list] + end + end + def deliver_to_public(status) Rails.logger.debug "Delivering status #{status.id} to public timeline" diff --git a/app/views/settings/account_subscribes/_fields.html.haml b/app/views/settings/account_subscribes/_fields.html.haml new file mode 100644 index 000000000..1662dc86c --- /dev/null +++ b/app/views/settings/account_subscribes/_fields.html.haml @@ -0,0 +1,11 @@ +.fields-group + = f.input :acct, wrapper: :with_label + +.fields-group + = f.input :show_reblogs, as: :boolean, wrapper: :with_label + +.fields-group + = f.label :list_id + = f.collection_select :list_id, home_list_new(@lists), :first, :last + +%hr.spacer/ diff --git a/app/views/settings/account_subscribes/edit.html.haml b/app/views/settings/account_subscribes/edit.html.haml new file mode 100644 index 000000000..25a329099 --- /dev/null +++ b/app/views/settings/account_subscribes/edit.html.haml @@ -0,0 +1,9 @@ +- content_for :page_title do + = t('account_subscribes.edit.title') + += simple_form_for @form_account_subscribing, url: settings_account_subscribe_path(@form_account_subscribing.id), method: :put do |f| + = render 'shared/error_messages', object: @form_account_subscribing + = render 'fields', f: f + + .actions + = f.button :button, t('generic.save_changes'), type: :submit diff --git a/app/views/settings/account_subscribes/index.html.haml b/app/views/settings/account_subscribes/index.html.haml index 0cbb8aab5..e3bf6af8f 100644 --- a/app/views/settings/account_subscribes/index.html.haml +++ b/app/views/settings/account_subscribes/index.html.haml @@ -5,21 +5,32 @@ %hr.spacer/ -= simple_form_for :account_input, url: settings_account_subscribes_path do |f| +.table-wrapper + %table.table + %thead + %tr + %th= t('simple_form.labels.form_account_subscribe.acct') + %th.nowrap= t('simple_form.labels.form_account_subscribe.reblog') + %th.nowrap= t('simple_form.labels.form_account_subscribe.timeline') + %th.nowrap + %tbody + - @account_subscribings.each do |account_subscribe| + %tr + %td + = fa_icon 'user' + = account_subscribe.target_account.acct + %td.nowrap + - if account_subscribe.show_reblogs + = fa_icon('check') + %td.nowrap + - if account_subscribe.list_id + = fa_icon 'list-ul' + = account_subscribe.list&.title + - else + = fa_icon 'home' + = t 'lists.home' + %td.nowrap + = table_link_to 'pencil', t('account_subscribes.edit.title'), edit_settings_account_subscribe_path(account_subscribe) + = table_link_to 'trash', t('filters.index.delete'), settings_account_subscribe_path(account_subscribe), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') } - .fields-group - = f.input :acct, wrapper: :with_block_label, hint: false - - .actions - = f.button :button, t('account_subscribes.add_new'), type: :submit - -%hr.spacer/ - -- @account_subscribings.each do |account_subscribing| - .directory__tag - %div - %h4 - = fa_icon 'user' - = account_subscribing[:acct] - %small - = table_link_to 'trash', t('filters.index.delete'), settings_account_subscribe_path(account_subscribing), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') } += link_to t('account_subscribes.new.title'), new_settings_account_subscribe_path, class: 'button' diff --git a/app/views/settings/account_subscribes/new.html.haml b/app/views/settings/account_subscribes/new.html.haml new file mode 100644 index 000000000..194da0dac --- /dev/null +++ b/app/views/settings/account_subscribes/new.html.haml @@ -0,0 +1,9 @@ +- content_for :page_title do + = t('account_subscribes.new.title') + += simple_form_for @form_account_subscribing, url: settings_account_subscribes_path do |f| + = render 'shared/error_messages', object: @form_account_subscribing + = render 'fields', f: f + + .actions + = f.button :button, t('account_subscribes.new.title'), type: :submit diff --git a/app/views/settings/domain_subscribes/index.html.haml b/app/views/settings/domain_subscribes/index.html.haml index 7602eff3f..762cf89d6 100644 --- a/app/views/settings/domain_subscribes/index.html.haml +++ b/app/views/settings/domain_subscribes/index.html.haml @@ -27,7 +27,7 @@ = domain_subscribe.list&.title - else = fa_icon 'home' - = t 'domain_subscribes.home' + = t 'lists.home' %td.nowrap = table_link_to 'pencil', t('domain_subscribes.edit.title'), edit_settings_domain_subscribe_path(domain_subscribe) = table_link_to 'trash', t('filters.index.delete'), settings_domain_subscribe_path(domain_subscribe), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') } diff --git a/app/views/settings/follow_tags/_fields.html.haml b/app/views/settings/follow_tags/_fields.html.haml new file mode 100644 index 000000000..a6612fc5e --- /dev/null +++ b/app/views/settings/follow_tags/_fields.html.haml @@ -0,0 +1,8 @@ +.fields-group + = f.input :name, wrapper: :with_label + +.fields-group + = f.label :list_id + = f.collection_select :list_id, home_list_new(@lists), :first, :last + +%hr.spacer/ diff --git a/app/views/settings/follow_tags/edit.html.haml b/app/views/settings/follow_tags/edit.html.haml new file mode 100644 index 000000000..3b3c73d94 --- /dev/null +++ b/app/views/settings/follow_tags/edit.html.haml @@ -0,0 +1,9 @@ +- content_for :page_title do + = t('follow_tags.edit.title') + += simple_form_for @follow_tag, url: settings_follow_tag_path(@follow_tag), method: :put do |f| + = render 'shared/error_messages', object: @follow_tag + = render 'fields', f: f + + .actions + = f.button :button, t('generic.save_changes'), type: :submit diff --git a/app/views/settings/follow_tags/index.html.haml b/app/views/settings/follow_tags/index.html.haml index 18fce3987..c26bc7e37 100644 --- a/app/views/settings/follow_tags/index.html.haml +++ b/app/views/settings/follow_tags/index.html.haml @@ -5,22 +5,28 @@ %hr.spacer/ -= simple_form_for @follow_tag, url: settings_follow_tags_path do |f| - = render 'shared/error_messages', object: @follow_tag +.table-wrapper + %table.table + %thead + %tr + %th= t('simple_form.labels.follow_tag.name') + %th.nowrap= t('simple_form.labels.follow_tag.timeline') + %th.nowrap + %tbody + - @follow_tags.each do |follow_tag| + %tr + %td + = fa_icon 'hashtag' + = follow_tag.name + %td.nowrap + - if follow_tag.list_id + = fa_icon 'list-ul' + = follow_tag.list&.title + - else + = fa_icon 'home' + = t 'lists.home' + %td.nowrap + = table_link_to 'pencil', t('follow_tags.edit.title'), edit_settings_follow_tag_path(follow_tag) + = table_link_to 'trash', t('filters.index.delete'), settings_follow_tag_path(follow_tag), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') } - .fields-group - = f.input :name, wrapper: :with_block_label, hint: false - - .actions - = f.button :button, t('follow_tags.add_new'), type: :submit - -%hr.spacer/ - -- @follow_tags.each do |follow_tag| - .directory__tag{ class: params[:tag] == follow_tag.name ? 'active' : nil } - %div - %h4 - = fa_icon 'hashtag' - = follow_tag.name - %small - = table_link_to 'trash', t('filters.index.delete'), settings_follow_tag_path(follow_tag), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') } += link_to t('follow_tags.new.title'), new_settings_follow_tag_path, class: 'button' diff --git a/app/views/settings/follow_tags/new.html.haml b/app/views/settings/follow_tags/new.html.haml new file mode 100644 index 000000000..095ab4ed2 --- /dev/null +++ b/app/views/settings/follow_tags/new.html.haml @@ -0,0 +1,9 @@ +- content_for :page_title do + = t('follow_tags.new.title') + += simple_form_for @follow_tag, url: settings_follow_tags_path do |f| + = render 'shared/error_messages', object: @follow_tag + = render 'fields', f: f + + .actions + = f.button :button, t('follow_tags.new.title'), type: :submit diff --git a/config/locales/en.yml b/config/locales/en.yml index 8d3547e41..9cdb9b782 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -89,7 +89,11 @@ en: unfollow: Unfollow account_subscribes: add_new: Add - hint_html: "What are account subscription? Insert public posts from the specified account into the home timeline. Posts received by the server (federated timeline) are targets. You cannot subscribe if you are following." + edit: + title: Edit + hint_html: "What are account subscription? Insert public posts from the specified account into the home or list timeline. Posts received by the server (federated timeline) are targets." + new: + title: Add new account subscription admin: account_actions: action: Perform action @@ -902,7 +906,6 @@ en: title: Edit exclude_reblog: Exclude hint_html: "What are domain subscription? Insert public posts from the specified domain into the home or list timeline. Posts received by the server (federated timeline) are targets." - home: Home include_reblog: Include new: title: Add new domain subscription @@ -970,8 +973,12 @@ en: new: title: Add new filter follow_tags: - add_new: Add new - hint_html: "What are follow hashtags? They are a collection of hashtags you follow. From the posts with hashtags received by the server, the one with the hashtag specified here is inserted into the home timeline." + add_new: Add + edit: + title: Edit + hint_html: "What are follow hashtags? They are a collection of hashtags you follow. From the posts with hashtags received by the server, the one with the hashtag specified here is inserted into the home or list timeline." + new: + title: Add new hashtag follow footer: developers: Developers more: More… @@ -1060,8 +1067,7 @@ en: duplicate: The same content has already been registered limit: You have reached the maximum number of "Keyword subscribes" that can be registered regexp: "Regular expression error: %{message}" - hint_html: "What is a keyword subscribes? Inserts a public post that matches one of the specified words or a regular expression into the home timeline. Posts received by the server (federated timeline) are targets." - home: Home + hint_html: "What is a keyword subscribes? Inserts a public post that matches one of the specified words or a regular expression into the home or list timeline. Posts received by the server (federated timeline) are targets." ignorecase: enabled: Ignore disabled: Sensitive @@ -1078,6 +1084,7 @@ en: add_new: Add new list errors: limit: You have reached the maximum amount of lists + home: Home login_activities: authentication_methods: otp: two-factor authentication app diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 668cc50c3..fa693d889 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -83,7 +83,11 @@ ja: unfollow: フォロー解除 account_subscribes: add_new: 追加 - hint_html: "アカウントの購読とは何ですか? 指定したアカウントの公開投稿をホームタイムラインに挿入します。サーバが受け取っている投稿(連合タイムライン)が対象です。フォローしている場合は購読できません。" + edit: + title: 編集 + hint_html: "アカウントの購読とは何ですか? 指定したアカウントの公開投稿をホームタイムラインまたはリストに挿入します。サーバが受け取っている投稿(連合タイムライン)が対象です。" + new: + title: 新規アカウント購読を追加 admin: account_actions: action: アクションを実行 @@ -863,7 +867,6 @@ ja: title: 編集 exclude_reblog: 含めない hint_html: "ドメインの購読とは何ですか? 指定したドメインの公開投稿をホームタイムラインまたはリストに挿入します。サーバが受け取っている投稿(連合タイムライン)が対象です。" - home: ホーム include_reblog: 含める new: title: 新規ドメイン購読を追加 @@ -914,7 +917,11 @@ ja: hint_html: "注目のハッシュタグとは?プロフィールページに目立つ形で表示され、そのハッシュタグのついたあなたの公開投稿だけを抽出して閲覧できるようにします。クリエイティブな仕事や長期的なプロジェクトを追うのに優れた機能です。" follow_tags: add_new: 追加 - hint_html: "ハッシュタグのフォローとは何ですか? それらはあなたがフォローするハッシュタグのコレクションです。サーバが受け取ったハッシュタグ付きの投稿の中から、ここで指定したハッシュタグのついた投稿をホームタイムラインに挿入します。" + edit: + title: 編集 + hint_html: "ハッシュタグのフォローとは何ですか? それらはあなたがフォローするハッシュタグのコレクションです。サーバが受け取ったハッシュタグ付きの投稿の中から、ここで指定したハッシュタグのついた投稿をホームタイムラインまたはリストに挿入します。" + new: + title: ハッシュタグのフォローを追加 filters: contexts: account: プロフィール @@ -1019,8 +1026,7 @@ ja: duplicate: 既に同じ内容が登録されています limit: キーワード購読の登録可能数の上限に達しました regexp: "正規表現に誤りがあります: %{message}" - hint_html: "キーワードの購読とは何ですか? 指定した単語のいずれか、または正規表現に一致する公開投稿をホームタイムラインに挿入します。サーバが受け取っている投稿(連合タイムライン)が対象です。" - home: ホーム + hint_html: "キーワードの購読とは何ですか? 指定した単語のいずれか、または正規表現に一致する公開投稿をホームタイムラインまたはリストに挿入します。サーバが受け取っている投稿(連合タイムライン)が対象です。" ignorecase: enabled: 無視 disabled: 区別 @@ -1037,6 +1043,7 @@ ja: add_new: 新しいリストを追加 errors: limit: リストの上限に達しました + home: ホーム media_attachments: validations: images_and_video: 既に画像が追加されているため、動画を追加することはできません diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index 7993a79fc..df87eb31a 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -68,6 +68,11 @@ en: with_dns_records: An attempt to resolve the given domain's DNS records will be made and the results will also be blocked featured_tag: name: 'You might want to use one of these:' + follow_tag: + name: Specify the name of the hashtag without '#' you want to follow + form_account_subscribe: + acct: Specify the username@domain of the account you want to subscribe + show_reblogs: Show boosted posts from subscription form_challenge: current_password: You are entering a secure area imports: @@ -103,8 +108,6 @@ en: value: Content account_alias: acct: Handle of the old account - account_input: - acct: Account account_migration: acct: Handle of the new account account_warning_preset: @@ -197,6 +200,16 @@ en: with_dns_records: Include MX records and IPs of the domain featured_tag: name: Hashtag + follow_tag: + list_id: Target timeline + name: Tag name + timeline: Timeline + form_account_subscribe: + acct: Account + list_id: Target timeline + reblog: Boost + show_reblogs: Show boost + timeline: Timeline interactions: must_be_follower: Block notifications from non-followers must_be_following: Block notifications from people you don't follow diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml index 9c642aa24..f2b96cf39 100644 --- a/config/locales/simple_form.ja.yml +++ b/config/locales/simple_form.ja.yml @@ -68,6 +68,11 @@ ja: with_dns_records: 指定したドメインのDNSレコードを取得し、その結果もメールドメインブロックに登録されます featured_tag: name: 'これらを使うといいかもしれません:' + follow_tag: + name: フォローしたいハッシュタグを '#' 抜きで指定します + form_account_subscribe: + acct: 購読したいアカウントを username@domain 形式で指定します + show_reblogs: ブーストされた投稿を購読に含めます form_challenge: current_password: セキュリティ上重要なエリアにアクセスしています imports: @@ -103,8 +108,6 @@ ja: value: 内容 account_alias: acct: 引っ越し元のユーザー ID - account_input: - acct: アカウント (account@domain.tld) account_migration: acct: 引っ越し先のユーザー ID account_warning_preset: @@ -200,7 +203,15 @@ ja: featured_tag: name: ハッシュタグ follow_tag: + list_id: 対象タイムライン name: ハッシュタグ + timeline: タイムライン + form_account_subscribe: + acct: アカウント + list_id: 対象タイムライン + reblog: ブースト + show_reblogs: ブーストを表示 + timeline: タイムライン interactions: must_be_follower: フォロワー以外からの通知をブロック must_be_following: フォローしていないユーザーからの通知をブロック diff --git a/config/navigation.rb b/config/navigation.rb index d7f537beb..b833d68ad 100644 --- a/config/navigation.rb +++ b/config/navigation.rb @@ -19,10 +19,10 @@ SimpleNavigation::Configuration.run do |navigation| n.item :follow_and_subscriptions, safe_join([fa_icon('users fw'), t('settings.follow_and_subscriptions')]), relationships_url, if: -> { current_user.functional? } do |s| s.item :relationships, safe_join([fa_icon('users fw'), t('settings.relationships')]), relationships_url, highlights_on: %r{/relationships} - s.item :follow_tags, safe_join([fa_icon('hashtag fw'), t('settings.follow_tags')]), settings_follow_tags_url - s.item :account_subscribes, safe_join([fa_icon('users fw'), t('settings.account_subscribes')]), settings_account_subscribes_url - s.item :domain_subscribes, safe_join([fa_icon('server fw'), t('settings.domain_subscribes')]), settings_domain_subscribes_url - s.item :keyword_subscribes, safe_join([fa_icon('search fw'), t('settings.keyword_subscribes')]), settings_keyword_subscribes_url + s.item :follow_tags, safe_join([fa_icon('hashtag fw'), t('settings.follow_tags')]), settings_follow_tags_url, highlights_on: %r{/follow_tags} + s.item :account_subscribes, safe_join([fa_icon('users fw'), t('settings.account_subscribes')]), settings_account_subscribes_url, highlights_on: %r{/account_subscribes} + s.item :domain_subscribes, safe_join([fa_icon('server fw'), t('settings.domain_subscribes')]), settings_domain_subscribes_url, highlights_on: %r{/domain_subscribes} + s.item :keyword_subscribes, safe_join([fa_icon('search fw'), t('settings.keyword_subscribes')]), settings_keyword_subscribes_url, highlights_on: %r{/keyword_subscribes} end n.item :filters, safe_join([fa_icon('filter fw'), t('filters.index.title')]), filters_path, highlights_on: %r{/filters}, if: -> { current_user.functional? } diff --git a/config/routes.rb b/config/routes.rb index ff86fda5c..f25a08671 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -165,8 +165,8 @@ Rails.application.routes.draw do resources :sessions, only: [:destroy] resources :featured_tags, only: [:index, :create, :destroy] resources :favourite_tags, only: [:index, :create, :destroy] - resources :follow_tags, only: [:index, :create, :destroy] - resources :account_subscribes, only: [:index, :create, :destroy] + resources :follow_tags, except: [:show] + resources :account_subscribes, except: [:show] resources :domain_subscribes, except: [:show] resources :keyword_subscribes, except: [:show] resources :login_activities, only: [:index] diff --git a/db/migrate/20200105023325_add_show_reblogs_to_account_subscribe.rb b/db/migrate/20200105023325_add_show_reblogs_to_account_subscribe.rb new file mode 100644 index 000000000..c364fd2f9 --- /dev/null +++ b/db/migrate/20200105023325_add_show_reblogs_to_account_subscribe.rb @@ -0,0 +1,17 @@ +require Rails.root.join('lib', 'mastodon', 'migration_helpers') + +class AddShowReblogsToAccountSubscribe < ActiveRecord::Migration[5.2] + include Mastodon::MigrationHelpers + + disable_ddl_transaction! + + def up + safety_assured do + add_column_with_default :account_subscribes, :show_reblogs, :boolean, default: true, allow_null: false + end + end + + def down + remove_column :account_subscribes, :show_reblogs + end +end diff --git a/db/schema.rb b/db/schema.rb index 9a875f232..bdce7910a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -138,6 +138,7 @@ ActiveRecord::Schema.define(version: 2021_08_08_071221) do t.datetime "created_at", null: false t.datetime "updated_at", null: false t.bigint "list_id" + t.boolean "show_reblogs", default: true, null: false t.index ["account_id"], name: "index_account_subscribes_on_account_id" t.index ["list_id"], name: "index_account_subscribes_on_list_id" t.index ["target_account_id"], name: "index_account_subscribes_on_target_account_id" @@ -398,6 +399,27 @@ ActiveRecord::Schema.define(version: 2021_08_08_071221) do t.index ["list_id"], name: "index_domain_subscribes_on_list_id" end + create_table "domains", force: :cascade do |t| + t.string "domain", default: "", null: false + t.string "title", default: "", null: false + t.string "short_description", default: "", null: false + t.string "email", default: "", null: false + t.string "version", default: "", null: false + t.string "thumbnail_remote_url", default: "", null: false + t.string "languages", array: true + t.boolean "registrations" + t.boolean "approval_required" + t.bigint "contact_account_id" + t.string "software", default: "", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "thumbnail_file_name" + t.string "thumbnail_content_type" + t.integer "thumbnail_file_size" + t.datetime "thumbnail_updated_at" + t.index ["contact_account_id"], name: "index_domains_on_contact_account_id" + end + create_table "email_domain_blocks", force: :cascade do |t| t.string "domain", default: "", null: false t.datetime "created_at", null: false @@ -1089,6 +1111,7 @@ ActiveRecord::Schema.define(version: 2021_08_08_071221) do add_foreign_key "devices", "oauth_access_tokens", column: "access_token_id", on_delete: :cascade add_foreign_key "domain_subscribes", "accounts", on_delete: :cascade add_foreign_key "domain_subscribes", "lists", on_delete: :cascade + add_foreign_key "domains", "accounts", column: "contact_account_id" add_foreign_key "email_domain_blocks", "email_domain_blocks", column: "parent_id", on_delete: :cascade add_foreign_key "encrypted_messages", "accounts", column: "from_account_id", on_delete: :cascade add_foreign_key "encrypted_messages", "devices", on_delete: :cascade