diff --git a/app/javascript/mastodon/components/status.jsx b/app/javascript/mastodon/components/status.jsx index 80e4f79288a03b..cf6a924d27fe47 100644 --- a/app/javascript/mastodon/components/status.jsx +++ b/app/javascript/mastodon/components/status.jsx @@ -28,7 +28,7 @@ import Card from '../features/status/components/card'; // to use the progress bar to show download progress import Bundle from '../features/ui/components/bundle'; import { MediaGallery, Video, Audio } from '../features/ui/util/async-components'; -import { displayMedia, enableEmojiReaction, showEmojiReactionOnTimeline, showQuoteInHome, showQuoteInPublic } from '../initial_state'; +import { displayMedia, enableEmojiReaction, isShowItem } from '../initial_state'; import { Avatar } from './avatar'; import { AvatarOverlay } from './avatar_overlay'; @@ -610,7 +610,7 @@ class Status extends ImmutablePureComponent { if (!this.props.withoutEmojiReactions && status.get('emoji_reactions')) { const emojiReactions = status.get('emoji_reactions'); if (emojiReactions.size > 0 && enableEmojiReaction) { - emojiReactionsBar = ; + emojiReactionsBar = ; } } @@ -622,7 +622,7 @@ class Status extends ImmutablePureComponent { const withReference = (!withQuote && status.get('status_references_count') > 0) ? : null; const withExpiration = status.get('expires_at') ? : null; - const quote = !muted && status.get('quote_id') && (['public', 'community'].includes(contextType) ? showQuoteInPublic : showQuoteInHome) && ; + const quote = !muted && status.get('quote_id') && (['public', 'community'].includes(contextType) ? isShowItem('quote_in_public') : isShowItem('quote_in_home')) && ; return ( diff --git a/app/javascript/mastodon/components/status_action_bar.jsx b/app/javascript/mastodon/components/status_action_bar.jsx index 2a533a0c5f40ac..086f288a82e29e 100644 --- a/app/javascript/mastodon/components/status_action_bar.jsx +++ b/app/javascript/mastodon/components/status_action_bar.jsx @@ -26,7 +26,7 @@ import { WithRouterPropTypes } from 'mastodon/utils/react_router'; import DropdownMenuContainer from '../containers/dropdown_menu_container'; import EmojiPickerDropdown from '../features/compose/containers/emoji_picker_dropdown_container'; -import { enableEmojiReaction , bookmarkCategoryNeeded, simpleTimelineMenu, me, hideEmojiReactionUnavailableServer } from '../initial_state'; +import { enableEmojiReaction , bookmarkCategoryNeeded, simpleTimelineMenu, me, isHideItem } from '../initial_state'; import { IconButton } from './icon_button'; @@ -453,7 +453,7 @@ class StatusActionBar extends ImmutablePureComponent { ); - const emojiReactionAvailableServer = !hideEmojiReactionUnavailableServer || status.get('emoji_reaction_available_server'); + const emojiReactionAvailableServer = !isHideItem('emoji_reaction_unavailable_server') || status.get('emoji_reaction_available_server'); const emojiReactionPolicy = account.getIn(['other_settings', 'emoji_reaction_policy']) || 'allow'; const following = emojiReactionPolicy !== 'following_only' || (relationship && relationship.get('following')); const followed = emojiReactionPolicy !== 'followers_only' || (relationship && relationship.get('followed_by')); diff --git a/app/javascript/mastodon/features/compose/containers/emoji_picker_dropdown_container.js b/app/javascript/mastodon/features/compose/containers/emoji_picker_dropdown_container.js index 5ca6a5da1e1176..d51507e1426117 100644 --- a/app/javascript/mastodon/features/compose/containers/emoji_picker_dropdown_container.js +++ b/app/javascript/mastodon/features/compose/containers/emoji_picker_dropdown_container.js @@ -2,7 +2,7 @@ import { Map as ImmutableMap, List as ImmutableList } from 'immutable'; import { connect } from 'react-redux'; import { createSelector } from 'reselect'; -import { hideRecentEmojis } from 'mastodon/initial_state'; +import { isHideItem } from 'mastodon/initial_state'; import { useEmoji } from '../../../actions/emojis'; import { changeSetting } from '../../../actions/settings'; @@ -51,7 +51,7 @@ const getFrequentlyUsedEmojis = createSelector([ deckEmojis = [...new Set(deckEmojis)]; let emojis; - if (!hideRecentEmojis) { + if (!isHideItem('recent_emojis')) { emojis = emojiCounters .keySeq() .filter((ee) => deckEmojis.indexOf(ee) < 0) diff --git a/app/javascript/mastodon/features/status/components/action_bar.jsx b/app/javascript/mastodon/features/status/components/action_bar.jsx index e6436aa5f37f69..44b9be861fa770 100644 --- a/app/javascript/mastodon/features/status/components/action_bar.jsx +++ b/app/javascript/mastodon/features/status/components/action_bar.jsx @@ -25,7 +25,7 @@ import { WithRouterPropTypes } from 'mastodon/utils/react_router'; import { IconButton } from '../../../components/icon_button'; import DropdownMenuContainer from '../../../containers/dropdown_menu_container'; -import { enableEmojiReaction , bookmarkCategoryNeeded, me, hideEmojiReactionUnavailableServer } from '../../../initial_state'; +import { enableEmojiReaction , bookmarkCategoryNeeded, me, isHideItem } from '../../../initial_state'; import EmojiPickerDropdown from '../../compose/containers/emoji_picker_dropdown_container'; const messages = defineMessages({ @@ -358,7 +358,7 @@ class ActionBar extends PureComponent { reblogTitle = intl.formatMessage(messages.cannot_reblog); } - const emojiReactionAvailableServer = !hideEmojiReactionUnavailableServer || status.get('emoji_reaction_available_server'); + const emojiReactionAvailableServer = !isHideItem('emoji_reaction_unavailable_server') || status.get('emoji_reaction_available_server'); const emojiReactionPolicy = account.getIn(['other_settings', 'emoji_reaction_policy']) || 'allow'; const following = emojiReactionPolicy !== 'following_only' || (relationship && relationship.get('following')); const followed = emojiReactionPolicy !== 'followers_only' || (relationship && relationship.get('followed_by')); diff --git a/app/javascript/mastodon/features/status/components/detailed_status.jsx b/app/javascript/mastodon/features/status/components/detailed_status.jsx index 709ea8527ca153..08d88c89606eb9 100644 --- a/app/javascript/mastodon/features/status/components/detailed_status.jsx +++ b/app/javascript/mastodon/features/status/components/detailed_status.jsx @@ -21,7 +21,7 @@ import { Icon } from 'mastodon/components/icon'; import PictureInPicturePlaceholder from 'mastodon/components/picture_in_picture_placeholder'; import { SearchabilityIcon } from 'mastodon/components/searchability_icon'; import { VisibilityIcon } from 'mastodon/components/visibility_icon'; -import { enableEmojiReaction, hideEmojiReactionUnavailableServer } from 'mastodon/initial_state'; +import { enableEmojiReaction, isHideItem } from 'mastodon/initial_state'; import { WithRouterPropTypes } from 'mastodon/utils/react_router'; import { Avatar } from '../../../components/avatar'; @@ -233,7 +233,7 @@ class DetailedStatus extends ImmutablePureComponent { if (status.get('emoji_reactions')) { const emojiReactions = status.get('emoji_reactions'); const emojiReactionPolicy = status.getIn(['account', 'other_settings', 'emoji_reaction_policy']) || 'allow'; - const emojiReactionAvailableServer = !hideEmojiReactionUnavailableServer || status.get('emoji_reaction_available_server'); + const emojiReactionAvailableServer = !isHideItem('emoji_reaction_unavailable_server') || status.get('emoji_reaction_available_server'); if (emojiReactions.size > 0 && enableEmojiReaction && emojiReactionAvailableServer && emojiReactionPolicy !== 'block') { emojiReactionsBar = ; } diff --git a/app/javascript/mastodon/features/ui/components/navigation_panel.jsx b/app/javascript/mastodon/features/ui/components/navigation_panel.jsx index c602bd07b550cd..6d0dca5b992179 100644 --- a/app/javascript/mastodon/features/ui/components/navigation_panel.jsx +++ b/app/javascript/mastodon/features/ui/components/navigation_panel.jsx @@ -21,7 +21,7 @@ import { ReactComponent as AntennaIcon } from '@material-symbols/svg-600/outline import { WordmarkLogo } from 'mastodon/components/logo'; import { NavigationPortal } from 'mastodon/components/navigation_portal'; -import { enableDtlMenu, timelinePreview, trendsEnabled, dtlTag, enableLocalTimeline } from 'mastodon/initial_state'; +import { enableDtlMenu, timelinePreview, trendsEnabled, dtlTag, enableLocalTimeline, isHideItem } from 'mastodon/initial_state'; import { transientSingleColumn } from 'mastodon/is_mobile'; import ColumnLink from './column_link'; @@ -151,7 +151,7 @@ class NavigationPanel extends Component { {signedIn && ( <> - + { !isHideItem('favourite_menu') && }
diff --git a/app/javascript/mastodon/initial_state.js b/app/javascript/mastodon/initial_state.js index fbccfce26e8748..480c4edb3be8d3 100644 --- a/app/javascript/mastodon/initial_state.js +++ b/app/javascript/mastodon/initial_state.js @@ -1,6 +1,17 @@ // @ts-check +/** + * @typedef { 'blocking_quote' + * | 'emoji_reaction_on_timeline' + * | 'emoji_reaction_unavailable_server' + * | 'favourite_menu' + * | 'quote_in_home' + * | 'quote_in_public' + * | 'recent_emojis' + * } HideItemsDefinition + */ + /** * @typedef {[code: string, name: string, localName: string]} InitialStateLanguage */ @@ -27,9 +38,7 @@ * @property {boolean} enable_local_timeline * @property {boolean} enable_dtl_menu * @property {boolean=} expand_spoilers - * @property {boolean} hide_blocking_quote - * @property {boolean} hide_emoji_reaction_unavailable_server - * @property {boolean} hide_recent_emojis + * @property {HideItemsDefinition[]} hide_items * @property {boolean} limited_federation_mode * @property {string} locale * @property {string | null} mascot @@ -42,9 +51,6 @@ * @property {string} repository * @property {boolean} search_enabled * @property {boolean} trends_enabled - * @property {boolean} show_emoji_reaction_on_timeline - * @property {boolean} show_quote_in_home - * @property {boolean} show_quote_in_public * @property {string} simple_timeline_menu * @property {boolean} single_user_mode * @property {string} source_url @@ -87,6 +93,20 @@ export const hasMultiColumnPath = initialPath === '/' */ const getMeta = (prop) => initialState?.meta && initialState.meta[prop]; +const hideItems = getMeta('hide_items'); + +/** + * @param {HideItemsDefinition} key + * @returns {boolean} + */ +export const isHideItem = (key) => (hideItems && hideItems.includes(key)) || false; + +/** + * @param {HideItemsDefinition} key + * @returns {boolean} + */ +export const isShowItem = (key) => !isHideItem(key); + export const activityApiEnabled = getMeta('activity_api_enabled'); export const autoPlayGif = getMeta('auto_play_gif'); export const bookmarkCategoryNeeded = getMeta('bookmark_category_needed'); @@ -105,9 +125,6 @@ export const enableLoginPrivacy = getMeta('enable_login_privacy'); export const enableDtlMenu = getMeta('enable_dtl_menu'); export const expandSpoilers = getMeta('expand_spoilers'); export const forceSingleColumn = !getMeta('advanced_layout'); -export const hideBlockingQuote = getMeta('hide_blocking_quote'); -export const hideEmojiReactionUnavailableServer = getMeta('hide_emoji_reaction_unavailable_server'); -export const hideRecentEmojis = getMeta('hide_recent_emojis'); export const limitedFederationMode = getMeta('limited_federation_mode'); export const mascot = getMeta('mascot'); export const me = getMeta('me'); @@ -119,9 +136,6 @@ export const registrationsOpen = getMeta('registrations_open'); export const repository = getMeta('repository'); export const searchEnabled = getMeta('search_enabled'); export const trendsEnabled = getMeta('trends_enabled'); -export const showEmojiReactionOnTimeline = getMeta('show_emoji_reaction_on_timeline'); -export const showQuoteInHome = getMeta('show_quote_in_home'); -export const showQuoteInPublic = getMeta('show_quote_in_public'); export const showTrends = getMeta('show_trends'); export const simpleTimelineMenu = getMeta('simple_timeline_menu'); export const singleUserMode = getMeta('single_user_mode'); diff --git a/app/javascript/mastodon/selectors/index.js b/app/javascript/mastodon/selectors/index.js index 7c5f864cc376bd..f98ccc4417a953 100644 --- a/app/javascript/mastodon/selectors/index.js +++ b/app/javascript/mastodon/selectors/index.js @@ -3,7 +3,7 @@ import { createSelector } from 'reselect'; import { toServerSideType } from 'mastodon/utils/filters'; -import { me, hideBlockingQuote } from '../initial_state'; +import { me, isHideItem } from '../initial_state'; export { makeGetAccount } from "./accounts"; @@ -40,7 +40,7 @@ export const makeGetStatus = () => { statusReblog = null; } - if (hideBlockingQuote && (statusReblog || statusBase).getIn(['quote', 'quote_muted'])) { + if (isHideItem('blocking_quote') && (statusReblog || statusBase).getIn(['quote', 'quote_muted'])) { return null; } diff --git a/app/models/concerns/has_user_settings.rb b/app/models/concerns/has_user_settings.rb index 0b1a41bc25c200..b2af4ff30a1468 100644 --- a/app/models/concerns/has_user_settings.rb +++ b/app/models/concerns/has_user_settings.rb @@ -263,6 +263,10 @@ def setting_hide_emoji_reaction_unavailable_server settings['web.hide_emoji_reaction_unavailable_server'] end + def setting_hide_favourite_menu + settings['web.hide_favourite_menu'] + end + def allows_report_emails? settings['notification_emails.report'] end diff --git a/app/models/user_settings.rb b/app/models/user_settings.rb index 3bfded889c81bb..99a0394da8afda 100644 --- a/app/models/user_settings.rb +++ b/app/models/user_settings.rb @@ -72,6 +72,7 @@ class KeyError < Error; end setting :show_quote_in_public, default: false setting :hide_blocking_quote, default: true setting :hide_emoji_reaction_unavailable_server, default: false + setting :hide_favourite_menu, default: false end namespace :notification_emails do diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb index c064ac23ddfbc0..0a01f86e8bde72 100644 --- a/app/serializers/initial_state_serializer.rb +++ b/app/serializers/initial_state_serializer.rb @@ -51,10 +51,8 @@ def meta store[:display_media_expand] = object.current_account.user.setting_display_media_expand store[:expand_spoilers] = object.current_account.user.setting_expand_spoilers store[:enable_emoji_reaction] = object.current_account.user.setting_enable_emoji_reaction && Setting.enable_emoji_reaction - store[:show_emoji_reaction_on_timeline] = object.current_account.user.setting_show_emoji_reaction_on_timeline store[:enable_login_privacy] = object.current_account.user.setting_enable_login_privacy store[:enable_dtl_menu] = object.current_account.user.setting_enable_dtl_menu - store[:hide_recent_emojis] = object.current_account.user.setting_hide_recent_emojis store[:reduce_motion] = object.current_account.user.setting_reduce_motion store[:disable_swiping] = object.current_account.user.setting_disable_swiping store[:advanced_layout] = object.current_account.user.setting_advanced_layout @@ -63,19 +61,24 @@ def meta store[:show_trends] = Setting.trends && object.current_account.user.setting_trends store[:bookmark_category_needed] = object.current_account.user.setting_bookmark_category_needed store[:simple_timeline_menu] = object.current_account.user.setting_simple_timeline_menu - store[:show_quote_in_home] = object.current_account.user.setting_show_quote_in_home - store[:show_quote_in_public] = object.current_account.user.setting_show_quote_in_public - store[:hide_blocking_quote] = object.current_account.user.setting_hide_blocking_quote - store[:hide_emoji_reaction_unavailable_server] = object.current_account.user.setting_hide_emoji_reaction_unavailable_server + store[:hide_items] = [ + object.current_account.user.setting_hide_favourite_menu ? 'favourite_menu' : nil, + object.current_account.user.setting_hide_recent_emojis ? 'recent_emojis' : nil, + object.current_account.user.setting_hide_blocking_quote ? 'blocking_quote' : nil, + object.current_account.user.setting_hide_emoji_reaction_unavailable_server ? 'emoji_reaction_unavailable_server' : nil, + object.current_account.user.setting_show_emoji_reaction_on_timeline ? nil : 'emoji_reaction_on_timeline', + object.current_account.user.setting_show_quote_in_home ? nil : 'quote_in_home', + object.current_account.user.setting_show_quote_in_public ? nil : 'quote_in_public', + ].compact else store[:auto_play_gif] = Setting.auto_play_gif store[:display_media] = Setting.display_media store[:reduce_motion] = Setting.reduce_motion store[:use_blurhash] = Setting.use_blurhash store[:enable_emoji_reaction] = Setting.enable_emoji_reaction - store[:show_emoji_reaction_on_timeline] = Setting.enable_emoji_reaction - store[:show_quote_in_home] = true - store[:show_quote_in_public] = true + store[:hide_items] = [ + Setting.enable_emoji_reaction ? nil : 'emoji_reaction_on_timeline', + ].compact end store[:disabled_account_id] = object.disabled_account.id.to_s if object.disabled_account diff --git a/app/views/settings/preferences/appearance/show.html.haml b/app/views/settings/preferences/appearance/show.html.haml index 2690c46748fac3..dee1e52e2e276c 100644 --- a/app/views/settings/preferences/appearance/show.html.haml +++ b/app/views/settings/preferences/appearance/show.html.haml @@ -46,6 +46,7 @@ .fields-group = ff.input :'web.bookmark_category_needed', wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_bookmark_category_needed'), hint: I18n.t('simple_form.hints.defaults.setting_bookmark_category_needed') + = ff.input :'web.hide_favourite_menu', wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_hide_favourite_menu') .fields-group = ff.input :'web.show_quote_in_home', wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_show_quote_in_home'), hint: false diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index 6f0705e816ee31..d4c0f41bf8f9c9 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -269,6 +269,7 @@ en: setting_expand_spoilers: Always expand posts marked with content warnings setting_hide_blocking_quote: Hide posts which have a quote written by the user you are blocking setting_hide_emoji_reaction_unavailable_server: Hide stamp button from unavailable server + setting_hide_favourite_menu: Hide favourite menu setting_hide_followers_count: Hide followers count setting_hide_following_count: Hide following count setting_hide_network: Hide your social graph diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml index 3229fb13e5e166..e3c01b7f58daa4 100644 --- a/config/locales/simple_form.ja.yml +++ b/config/locales/simple_form.ja.yml @@ -280,6 +280,7 @@ ja: setting_expand_spoilers: 閲覧注意としてマークされた投稿を常に展開する setting_hide_blocking_quote: ブロックしたユーザーの投稿を引用した投稿を隠す setting_hide_emoji_reaction_unavailable_server: スタンプに対応していないと思われるサーバーの投稿からスタンプボタンを隠す + setting_hide_favourite_menu: 右サイドメニューから「お気に入り」を隠す setting_hide_followers_count: フォロワー数を隠す setting_hide_following_count: フォロー数を隠す setting_hide_network: 繋がりを隠す