diff --git a/app/controllers/settings/preferences_controller.rb b/app/controllers/settings/preferences_controller.rb index f46e23584..45ca404a5 100644 --- a/app/controllers/settings/preferences_controller.rb +++ b/app/controllers/settings/preferences_controller.rb @@ -68,6 +68,7 @@ class Settings::PreferencesController < Settings::BaseController :setting_show_target, :setting_enable_limited_timeline, :setting_enable_reaction, + :setting_show_reply_tree_button, notification_emails: %i(follow follow_request reblog favourite emoji_reaction mention digest report pending_account trending_tag), interactions: %i(must_be_follower must_be_following must_be_following_dm) ) diff --git a/app/javascript/mastodon/components/status_content.js b/app/javascript/mastodon/components/status_content.js index 7a8b84648..2493dbb52 100644 --- a/app/javascript/mastodon/components/status_content.js +++ b/app/javascript/mastodon/components/status_content.js @@ -6,7 +6,7 @@ import Permalink from './permalink'; import classnames from 'classnames'; import PollContainer from 'mastodon/containers/poll_container'; import Icon from 'mastodon/components/icon'; -import { autoPlayGif } from 'mastodon/initial_state'; +import { autoPlayGif, show_reply_tree_button } from 'mastodon/initial_state'; const MAX_HEIGHT = 642; // 20px * 32 (+ 2px padding at the top) @@ -193,7 +193,10 @@ export default class StatusContent extends React.PureComponent { const hidden = this.props.onExpandedToggle ? !this.props.expanded : this.state.hidden; const renderReadMore = this.props.onClick && status.get('collapsed'); - const renderViewThread = this.props.showThread && status.get('in_reply_to_id') && status.get('in_reply_to_account_id') === status.getIn(['account', 'id']); + const renderViewThread = this.props.showThread && ( + status.get('in_reply_to_id') && status.get('in_reply_to_account_id') === status.getIn(['account', 'id']) || + show_reply_tree_button && (status.get('in_reply_to_id') || !!status.get('replies_count')) + ); const renderShowPoll = !!status.get('poll'); const content = { __html: status.get('contentHtml') }; diff --git a/app/javascript/mastodon/initial_state.js b/app/javascript/mastodon/initial_state.js index e53b55c48..98eecb11a 100644 --- a/app/javascript/mastodon/initial_state.js +++ b/app/javascript/mastodon/initial_state.js @@ -40,5 +40,6 @@ export const place_tab_bar_at_bottom = getMeta('place_tab_bar_at_bottom'); export const show_tab_bar_label = getMeta('show_tab_bar_label'); export const enable_limited_timeline = getMeta('enable_limited_timeline'); export const enableReaction = getMeta('enable_reaction'); +export const show_reply_tree_button = getMeta('show_reply_tree_button'); export default initialState; diff --git a/app/javascript/mastodon/reducers/statuses.js b/app/javascript/mastodon/reducers/statuses.js index 6a718a5ca..fe842f2ea 100644 --- a/app/javascript/mastodon/reducers/statuses.js +++ b/app/javascript/mastodon/reducers/statuses.js @@ -25,7 +25,12 @@ import { TIMELINE_DELETE } from '../actions/timelines'; import { STATUS_IMPORT, STATUSES_IMPORT } from '../actions/importer'; import { Map as ImmutableMap, fromJS } from 'immutable'; -const importStatus = (state, status) => state.set(status.id, fromJS(status)); +const importStatus = (state, status) => { + if (state.getIn([status.in_reply_to_id, 'replies_count'], null) == 0) { + state = state.setIn([status.in_reply_to_id, 'replies_count'], 1); + } + return state.set(status.id, fromJS(status)); +}; const importStatuses = (state, statuses) => state.withMutations(mutable => statuses.forEach(status => importStatus(mutable, status))); diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb index f268dc1d1..a77393672 100644 --- a/app/lib/user_settings_decorator.rb +++ b/app/lib/user_settings_decorator.rb @@ -52,6 +52,7 @@ class UserSettingsDecorator user.settings['show_tab_bar_label'] = show_tab_bar_label_preference if change?('setting_show_tab_bar_label') user.settings['enable_limited_timeline'] = enable_limited_timeline_preference if change?('setting_enable_limited_timeline') user.settings['enable_reaction'] = enable_reaction_preference if change?('setting_enable_reaction') + user.settings['show_reply_tree_button'] = show_reply_tree_button_preference if change?('setting_show_reply_tree_button') end def merged_notification_emails @@ -202,6 +203,10 @@ class UserSettingsDecorator boolean_cast_setting 'setting_enable_reaction' end + def show_reply_tree_button_preference + boolean_cast_setting 'setting_show_reply_tree_button' + end + def boolean_cast_setting(key) ActiveModel::Type::Boolean.new.cast(settings[key]) end diff --git a/app/models/user.rb b/app/models/user.rb index 17d6b6e91..c24657a74 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -130,6 +130,7 @@ class User < ApplicationRecord :show_follow_button_on_timeline, :show_subscribe_button_on_timeline, :show_followed_by, :show_target, :follow_button_to_list_adder, :show_navigation_panel, :show_quote_button, :show_bookmark_button, :place_tab_bar_at_bottom,:show_tab_bar_label, :enable_limited_timeline, :enable_reaction, + :show_reply_tree_button, to: :settings, prefix: :setting, allow_nil: false diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb index d771bdfee..19c36e856 100644 --- a/app/serializers/initial_state_serializer.rb +++ b/app/serializers/initial_state_serializer.rb @@ -54,6 +54,7 @@ class InitialStateSerializer < ActiveModel::Serializer store[:show_tab_bar_label] = object.current_account.user.setting_show_tab_bar_label store[:enable_limited_timeline] = object.current_account.user.setting_enable_limited_timeline store[:enable_reaction] = object.current_account.user.setting_enable_reaction + store[:show_reply_tree_button] = object.current_account.user.setting_show_reply_tree_button else store[:auto_play_gif] = Setting.auto_play_gif store[:display_media] = Setting.display_media diff --git a/app/views/settings/preferences/other/show.html.haml b/app/views/settings/preferences/other/show.html.haml index 59f1d9694..366d87ac5 100644 --- a/app/views/settings/preferences/other/show.html.haml +++ b/app/views/settings/preferences/other/show.html.haml @@ -66,6 +66,9 @@ .fields-group = f.input :setting_enable_reaction, as: :boolean, wrapper: :with_label + .fields-group + = f.input :setting_show_reply_tree_button, as: :boolean, wrapper: :with_label + -# .fields-group -# = f.input :setting_show_target, as: :boolean, wrapper: :with_label diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index 244c30d92..e50787daa 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -62,6 +62,7 @@ en: setting_show_follow_button_on_timeline: You can easily check the follow status and build a follow list quickly setting_show_navigation_panel: Show the navigation panel at the right end of the advanced UI setting_show_quote_button: Selects whether to display the button on the action bar. It does not enable/disable the citation function. + setting_show_reply_tree_button: When turned off, the "Show thread" button will only appear if the poster is replying to themselves in a series of posts setting_show_subscribe_button_on_timeline: You can easily check the status of your subscriptions and quickly build a subscription list setting_show_tab_bar_label: When adding a list etc. to the tab bar, it is recommended to display the label because it is not possible to distinguish by the icon alone setting_show_followed_by: "The color of the follow button changes according to the follow status (gray: no follow relationship, yellow: followed, blue: following, green: mutual follow)" @@ -201,6 +202,7 @@ en: setting_show_follow_button_on_timeline: Show follow button on timeline setting_show_navigation_panel: Show the navigation panel setting_show_quote_button: Show the quote button on the action bar + setting_show_reply_tree_button: Show "Show thread" button on posts that have reply tree setting_show_subscribe_button_on_timeline: Show subscribe button on timeline setting_show_tab_bar_label: Show labels in the tab bar setting_show_followed_by: Reflect the following status on the follow button diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml index 46ef3706d..e9a17bcbb 100644 --- a/config/locales/simple_form.ja.yml +++ b/config/locales/simple_form.ja.yml @@ -62,6 +62,7 @@ ja: setting_show_follow_button_on_timeline: フォロー状態を確認し易くなり、素早くフォローリストを構築できます setting_show_navigation_panel: 上級者向け UI の右端にナビゲーションパネルを表示します setting_show_quote_button: アクションバーへボタンを表示するかどうかの設定です。引用機能の有効・無効を切り替えるものではありません + setting_show_reply_tree_button: オフにした場合、投稿者本人が自分自身にリプライで投稿を連ねている場合にのみ『スレッドを表示』ボタンが表示されます setting_show_subscribe_button_on_timeline: 購読状態を確認し易くなり、素早く購読リストを構築できます setting_show_tab_bar_label: リスト等をタブバーに追加する場合、アイコンだけでは区別がつかないので、ラベルを表示することをおすすめします setting_show_followed_by: フォロー状態に応じてフォローボタンの色が変わります(灰色:フォロー関係なし、黄色:フォローされている、青色:フォローしている、緑色:相互フォロー) @@ -201,6 +202,7 @@ ja: setting_show_follow_button_on_timeline: タイムライン上にフォローボタンを表示する setting_show_navigation_panel: ナビゲーションパネルを表示する setting_show_quote_button: 引用ボタンをアクションバーに表示する + setting_show_reply_tree_button: リプライツリーの存在する投稿に『スレッドを表示』ボタンを表示する setting_show_subscribe_button_on_timeline: タイムライン上に購読ボタンを表示する setting_show_tab_bar_label: タブバーにラベルを表示する setting_show_followed_by: 被フォロー状態をフォローボタンに反映する diff --git a/config/settings.yml b/config/settings.yml index 451cf1f76..2213b552b 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -51,6 +51,7 @@ defaults: &defaults show_tab_bar_label: false enable_limited_timeline: false enable_reaction: true + show_reply_tree_button: true notification_emails: follow: false reblog: false