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: 繋がりを隠す