make number of displayed reactions a setting

This adds an extra item to the local settings for
specifying the number of reactions shown in toots.
The detailed status view always shows all
reactions.
This commit is contained in:
fef 2022-11-30 13:20:20 +00:00 committed by Jeremy Kescher
parent 5103b384dd
commit f1421b6d7d
No known key found for this signature in database
GPG key ID: 80A419A7A613DFA4
12 changed files with 272 additions and 16 deletions

View file

@ -270,7 +270,7 @@ MAX_POLL_OPTIONS=5
MAX_POLL_OPTION_CHARS=100
# Maximum number of emoji reactions per toot and user (minimum 1)
MAX_REACTIONS=8
MAX_REACTIONS=1
# Maximum image and video/audio upload sizes
# Units are in bytes

View file

@ -823,6 +823,7 @@ class Status extends ImmutablePureComponent {
<StatusReactions
statusId={status.get('id')}
reactions={status.get('reactions')}
numVisible={settings.get('num_visible_reactions')}
addReaction={this.props.onReactionAdd}
removeReaction={this.props.onReactionRemove}
emojiMap={this.props.emojiMap}

View file

@ -1,7 +1,7 @@
import ImmutablePureComponent from 'react-immutable-pure-component';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { maxReactions, reduceMotion } from '../initial_state';
import { reduceMotion } from '../initial_state';
import spring from 'react-motion/lib/spring';
import TransitionMotion from 'react-motion/lib/TransitionMotion';
import classNames from 'classnames';
@ -16,16 +16,12 @@ export default class StatusReactions extends ImmutablePureComponent {
static propTypes = {
statusId: PropTypes.string.isRequired,
reactions: ImmutablePropTypes.list.isRequired,
numVisible: PropTypes.number,
addReaction: PropTypes.func.isRequired,
removeReaction: PropTypes.func.isRequired,
emojiMap: ImmutablePropTypes.map.isRequired,
};
handleEmojiPick = data => {
const { addReaction, statusId } = this.props;
addReaction(statusId, data.native.replace(/:/g, ''));
}
willEnter() {
return { scale: reduceMotion ? 1 : 0 };
}
@ -35,11 +31,18 @@ export default class StatusReactions extends ImmutablePureComponent {
}
render() {
const { reactions } = this.props;
const visibleReactions = reactions
const { reactions, numVisible } = this.props;
let visibleReactions = reactions
.filter(x => x.get('count') > 0)
.sort((a, b) => b.get('count') - a.get('count'))
.filter((_, i) => i < maxReactions);
.sort((a, b) => b.get('count') - a.get('count'));
// numVisible might be NaN because it's pulled from local settings
// which doesn't do a whole lot of input validation, but that's okay
// because NaN >= 0 evaluates false.
// Still, this should be improved at some point.
if (numVisible >= 0) {
visibleReactions = visibleReactions.filter((_, i) => i < numVisible);
}
const styles = visibleReactions.map(reaction => ({
key: reaction.get('name'),

View file

@ -33,6 +33,8 @@ const messages = defineMessages({
unlisted: { id: 'privacy.unlisted.short', defaultMessage: 'Unlisted' },
private: { id: 'privacy.private.short', defaultMessage: 'Followers-only' },
direct: { id: 'privacy.direct.short', defaultMessage: 'Mentioned people only' },
visible_reactions_count: { id: 'settings.visible_reactions_count', defaultMessage: 'Number of visible reactions' },
enter_amount_prompt: { id: 'settings.enter_amount_prompt', defaultMessage: 'Enter an amount' },
});
class LocalSettingsPage extends React.PureComponent {
@ -95,6 +97,16 @@ class LocalSettingsPage extends React.PureComponent {
>
<FormattedMessage id='settings.rewrite_mentions' defaultMessage='Rewrite mentions in displayed statuses' />
</LocalSettingsPageItem>
<LocalSettingsPageItem
settings={settings}
item={['num_visible_reactions']}
id='mastodon-settings--num_visible_reactions'
onChange={onChange}
placeholder={intl.formatMessage(messages.enter_amount_prompt)}
number
>
<FormattedMessage id='settings.num_visible_reactions' defaultMessage='Number of visible reaction badges:' />
</LocalSettingsPageItem>
<section>
<h2><FormattedMessage id='settings.notifications_opts' defaultMessage='Notifications options' /></h2>
<LocalSettingsPageItem

View file

@ -22,20 +22,21 @@ export default class LocalSettingsPageItem extends React.PureComponent {
})),
settings: ImmutablePropTypes.map.isRequired,
placeholder: PropTypes.string,
number: PropTypes.bool,
disabled: PropTypes.bool,
};
handleChange = e => {
const { target } = e;
const { item, onChange, options, placeholder } = this.props;
const { item, onChange, options, placeholder, number } = this.props;
if (options && options.length > 0) onChange(item, target.value);
else if (placeholder) onChange(item, target.value);
else if (placeholder) onChange(item, number ? parseInt(target.value) : target.value);
else onChange(item, target.checked);
};
render () {
const { handleChange } = this;
const { settings, item, id, inputProps, options, children, dependsOn, dependsOnNot, placeholder, disabled } = this.props;
const { settings, item, id, inputProps, options, children, dependsOn, dependsOnNot, placeholder, number, disabled } = this.props;
let enabled = !disabled;
if (dependsOn) {
@ -79,7 +80,7 @@ export default class LocalSettingsPageItem extends React.PureComponent {
</fieldset>
</div>
);
} else if (placeholder) {
} else if (placeholder || number) {
return (
<div className='glitch local-settings__page__item string'>
<label htmlFor={id}>
@ -87,7 +88,7 @@ export default class LocalSettingsPageItem extends React.PureComponent {
<p>
<input
id={id}
type='text'
type={number ? 'number' : 'text'}
value={settings.getIn(item)}
placeholder={placeholder}
onChange={handleChange}

View file

@ -0,0 +1,15 @@
import inherited from 'mastodon/locales/de.json';
const messages = {
'notification.reaction': '{name} hat auf deinen Beitrag reagiert',
'notifications.column_settings.reaction': 'Reaktionen:',
'tooltips.reactions': 'Reaktionen',
'settings.enter_amount_prompt': 'Gib eine Zahl ein',
'settings.num_visible_reactions': 'Anzahl sichtbarer Reaktionen',
'status.react': 'Reagieren',
};
export default Object.assign({}, inherited, messages);

View file

@ -136,6 +136,7 @@
"settings.deprecated_setting": "Diese Einstellung wird nun von Mastodons {settings_page_link} gesteuert",
"settings.enable_collapsed": "Eingeklappte Toots aktivieren",
"settings.enable_collapsed_hint": "Eingeklappte Posts haben einen Teil ihres Inhalts verborgen, um weniger Platz am Bildschirm einzunehmen. Das passiert unabhängig von der Inhaltswarnfunktion",
"settings.enter_amount_prompt": "Gib eine Zahl ein",
"settings.enable_content_warnings_auto_unfold": "Inhaltswarnungen automatisch ausklappen",
"settings.general": "Allgemein",
"settings.hicolor_privacy_icons": "Eingefärbte Privatsphäre-Symbole",
@ -149,6 +150,7 @@
"settings.layout_opts": "Layout-Optionen",
"settings.media": "Medien",
"settings.media_fullwidth": "Medienvorschau in voller Breite",
"settings.num_visible_reactions": "Anzahl sichtbarer Reaktionen",
"settings.media_letterbox": "Mediengröße anpassen",
"settings.media_letterbox_hint": "Medien runterskalieren und einpassen um die Bildbehälter zu füllen anstatt zu strecken und zuzuschneiden",
"settings.media_reveal_behind_cw": "Empfindliche Medien hinter Inhaltswarnungen standardmäßig anzeigen",
@ -191,6 +193,7 @@
"settings.wide_view": "Breite Ansicht (nur für den Desktop-Modus)",
"settings.wide_view_hint": "Verbreitert Spalten, um den verfügbaren Platz besser zu füllen.",
"status.collapse": "Einklappen",
"status.react": "Reagieren",
"status.has_audio": "Hat angehängte Audiodateien",
"status.has_pictures": "Hat angehängte Bilder",
"status.has_preview_card": "Hat eine Vorschaukarte",

View file

@ -0,0 +1,199 @@
import inherited from 'mastodon/locales/en.json';
const messages = {
'getting_started.open_source_notice': 'Glitchsoc is free open source software forked from {Mastodon}. You can contribute or report issues on GitHub at {github}.',
'layout.auto': 'Auto',
'layout.current_is': 'Your current layout is:',
'layout.desktop': 'Desktop',
'layout.single': 'Mobile',
'layout.hint.auto': 'Automatically chose layout based on “Enable advanced web interface” setting and screen size.',
'layout.hint.desktop': 'Use multiple-column layout regardless of the “Enable advanced web interface” setting or screen size.',
'layout.hint.single': 'Use single-column layout regardless of the “Enable advanced web interface” setting or screen size.',
'navigation_bar.app_settings': 'App settings',
'navigation_bar.misc': 'Misc',
'navigation_bar.keyboard_shortcuts': 'Keyboard shortcuts',
'navigation_bar.info': 'Extended information',
'navigation_bar.featured_users': 'Featured users',
'getting_started.onboarding': 'Show me around',
'onboarding.next': 'Next',
'onboarding.done': 'Done',
'onboarding.skip': 'Skip',
'onboarding.page_one.federation': '{domain} is an \'instance\' of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.',
'onboarding.page_one.welcome': 'Welcome to {domain}!',
'onboarding.page_one.handle': 'You are on {domain}, so your full handle is {handle}',
'onboarding.page_two.compose': 'Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.',
'onboarding.page_three.search': 'Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.',
'onboarding.page_three.profile': 'Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.',
'onboarding.page_four.home': 'The home timeline shows posts from people you follow.',
'onboarding.page_four.notifications': 'The notifications column shows when someone interacts with you.',
'onboarding.page_five.public_timelines': 'The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.',
'onboarding.page_six.admin': 'Your instance\'s admin is {admin}.',
'onboarding.page_six.read_guidelines': 'Please read {domain}\'s {guidelines}!',
'onboarding.page_six.guidelines': 'community guidelines',
'onboarding.page_six.almost_done': 'Almost done...',
'onboarding.page_six.github': '{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}, and is compatible with any Mastodon instance or app. Glitchsoc is entirely free and open-source. You can report bugs, request features, or contribute to the code on {github}.',
'onboarding.page_six.apps_available': 'There are {apps} available for iOS, Android and other platforms.',
'onboarding.page_six.various_app': 'mobile apps',
'onboarding.page_six.appetoot': 'Bon Appetoot!',
'settings.auto_collapse': 'Automatic collapsing',
'settings.auto_collapse_all': 'Everything',
'settings.auto_collapse_lengthy': 'Lengthy toots',
'settings.auto_collapse_media': 'Toots with media',
'settings.auto_collapse_notifications': 'Notifications',
'settings.auto_collapse_reblogs': 'Boosts',
'settings.auto_collapse_replies': 'Replies',
'settings.show_action_bar': 'Show action buttons in collapsed toots',
'settings.close': 'Close',
'settings.collapsed_statuses': 'Collapsed toots',
'settings.enable_collapsed': 'Enable collapsed toots',
'settings.enable_collapsed_hint': 'Collapsed posts have parts of their contents hidden to take up less screen space. This is distinct from the Content Warning feature',
'settings.enter_amount_prompt': 'Enter an amount',
'settings.general': 'General',
'settings.compose_box_opts': 'Compose box',
'settings.side_arm': 'Secondary toot button:',
'settings.side_arm.none': 'None',
'settings.side_arm_reply_mode': 'When replying to a toot, the secondary toot button should:',
'settings.side_arm_reply_mode.keep': 'Keep its set privacy',
'settings.side_arm_reply_mode.copy': 'Copy privacy setting of the toot being replied to',
'settings.side_arm_reply_mode.restrict': 'Restrict privacy setting to that of the toot being replied to',
'settings.always_show_spoilers_field': 'Always enable the Content Warning field',
'settings.prepend_cw_re': 'Prepend “re: ” to content warnings when replying',
'settings.preselect_on_reply': 'Pre-select usernames on reply',
'settings.preselect_on_reply_hint': 'When replying to a conversation with multiple participants, pre-select usernames past the first',
'settings.confirm_missing_media_description': 'Show confirmation dialog before sending toots lacking media descriptions',
'settings.confirm_before_clearing_draft': 'Show confirmation dialog before overwriting the message being composed',
'settings.show_content_type_choice': 'Show content-type choice when authoring toots',
'settings.content_warnings': 'Content Warnings',
'settings.content_warnings.regexp': 'Regular expression',
'settings.content_warnings_shared_state': 'Show/hide content of all copies at once',
'settings.content_warnings_shared_state_hint': 'Reproduce upstream Mastodon behavior by having the Content Warning button affect all copies of a post at once. This will prevent automatic collapsing of any copy of a toot with unfolded CW',
'settings.content_warnings_media_outside': 'Display media attachments outside content warnings',
'settings.content_warnings_media_outside_hint': 'Reproduce upstream Mastodon behavior by having the Content Warning toggle not affect media attachments',
'settings.content_warnings_unfold_opts': 'Auto-unfolding options',
'settings.enable_content_warnings_auto_unfold': 'Automatically unfold content-warnings',
'settings.deprecated_setting': 'This setting is now controlled from Mastodon\'s {settings_page_link}',
'settings.shared_settings_link': 'user preferences',
'settings.content_warnings_filter': 'Content warnings to not automatically unfold:',
'settings.layout_opts': 'Layout options',
'settings.rewrite_mentions_no': 'Do not rewrite mentions',
'settings.rewrite_mentions_acct': 'Rewrite with username and domain (when the account is remote)',
'settings.rewrite_mentions_username': 'Rewrite with username',
'settings.show_reply_counter': 'Display an estimate of the reply count',
'settings.hicolor_privacy_icons': 'High color privacy icons',
'settings.hicolor_privacy_icons.hint': 'Display privacy icons in bright and easily distinguishable colors',
'settings.confirm_boost_missing_media_description': 'Show confirmation dialog before boosting toots lacking media descriptions',
'settings.tag_misleading_links': 'Tag misleading links',
'settings.tag_misleading_links.hint': 'Add a visual indication with the link target host to every link not mentioning it explicitly',
'settings.rewrite_mentions': 'Rewrite mentions in displayed statuses',
'settings.notifications_opts': 'Notifications options',
'settings.notifications.tab_badge': 'Unread notifications badge',
'settings.notifications.tab_badge.hint': 'Display a badge for unread notifications in the column icons when the notifications column isn\'t open',
'settings.notifications.favicon_badge': 'Unread notifications favicon badge',
'settings.notifications.favicon_badge.hint': 'Add a badge for unread notifications to the favicon',
'settings.status_icons': 'Toot icons',
'settings.status_icons_language': 'Language indicator',
'settings.status_icons_reply': 'Reply indicator',
'settings.status_icons_local_only': 'Local-only indicator',
'settings.status_icons_media': 'Media and poll indicators',
'settings.status_icons_visibility': 'Toot privacy indicator',
'settings.layout': 'Layout:',
'settings.image_backgrounds': 'Image backgrounds',
'settings.image_backgrounds_media': 'Preview collapsed toot media',
'settings.image_backgrounds_media_hint': 'If the post has any media attachment, use the first one as a background',
'settings.image_backgrounds_users': 'Give collapsed toots an image background',
'settings.media': 'Media',
'settings.media_letterbox': 'Letterbox media',
'settings.media_letterbox_hint': 'Scale down and letterbox media to fill the image containers instead of stretching and cropping them',
'settings.media_fullwidth': 'Full-width media previews',
'settings.num_visible_reactions': 'Number of visible reactions',
'settings.inline_preview_cards': 'Inline preview cards for external links',
'settings.media_reveal_behind_cw': 'Reveal sensitive media behind a CW by default',
'settings.pop_in_player': 'Enable pop-in player',
'settings.pop_in_position': 'Pop-in player position:',
'settings.pop_in_left': 'Left',
'settings.pop_in_right': 'Right',
'settings.preferences': 'User preferences',
'settings.wide_view': 'Wide view (Desktop mode only)',
'settings.wide_view_hint': 'Stretches columns to better fill the available space.',
'settings.navbar_under': 'Navbar at the bottom (Mobile only)',
'status.collapse': 'Collapse',
'status.react': 'React',
'status.uncollapse': 'Uncollapse',
'status.in_reply_to': 'This toot is a reply',
'status.has_preview_card': 'Features an attached preview card',
'status.has_pictures': 'Features attached pictures',
'status.is_poll': 'This toot is a poll',
'status.has_video': 'Features attached videos',
'status.has_audio': 'Features attached audio files',
'status.local_only': 'Only visible from your instance',
'content_type.change': 'Content type',
'compose.content-type.html': 'HTML',
'compose.content-type.markdown': 'Markdown',
'compose.content-type.plain': 'Plain text',
'compose_form.poll.single_choice': 'Allow one choice',
'compose_form.poll.multiple_choices': 'Allow multiple choices',
'compose_form.spoiler': 'Hide text behind warning',
'column.toot': 'Toots and replies',
'column_header.profile': 'Profile',
'column.heading': 'Misc',
'column.subheading': 'Miscellaneous options',
'column_subheading.navigation': 'Navigation',
'column_subheading.lists': 'Lists',
'media_gallery.sensitive': 'Sensitive',
'favourite_modal.combo': 'You can press {combo} to skip this next time',
'home.column_settings.show_direct': 'Show DMs',
'notification.markForDeletion': 'Mark for deletion',
'notification.reaction': '{name} reacted to your post',
'notifications.clear': 'Clear all my notifications',
'notifications.column_settings.reaction': 'Reactions:',
'notifications.marked_clear_confirmation': 'Are you sure you want to permanently clear all selected notifications?',
'notifications.marked_clear': 'Clear selected notifications',
'notification_purge.start': 'Enter notification cleaning mode',
'notification_purge.btn_all': 'Select\nall',
'notification_purge.btn_none': 'Select\nnone',
'notification_purge.btn_invert': 'Invert\nselection',
'notification_purge.btn_apply': 'Clear\nselected',
'compose.attach.upload': 'Upload a file',
'compose.attach.doodle': 'Draw something',
'compose.attach': 'Attach...',
'advanced_options.local-only.short': 'Local-only',
'advanced_options.local-only.long': 'Do not post to other instances',
'advanced_options.local-only.tooltip': 'This post is local-only',
'advanced_options.icon_title': 'Advanced options',
'advanced_options.threaded_mode.short': 'Threaded mode',
'advanced_options.threaded_mode.long': 'Automatically opens a reply on posting',
'advanced_options.threaded_mode.tooltip': 'Threaded mode enabled',
'endorsed_accounts_editor.endorsed_accounts': 'Featured accounts',
'account.add_account_note': 'Add note for @{name}',
'account_note.cancel': 'Cancel',
'account_note.save': 'Save',
'account_note.edit': 'Edit',
'account_note.glitch_placeholder': 'No comment provided',
'account.joined': 'Joined {date}',
'account.follows': 'Follows',
'home.column_settings.advanced': 'Advanced',
'home.column_settings.filter_regex': 'Filter out by regular expressions',
'direct.group_by_conversations': 'Group by conversation',
'community.column_settings.allow_local_only': 'Show local-only toots',
'keyboard_shortcuts.bookmark': 'to bookmark',
'keyboard_shortcuts.toggle_collapse': 'to collapse/uncollapse toots',
'keyboard_shortcuts.secondary_toot': 'to send toot using secondary privacy setting',
'tooltips.reactions': 'Reactions',
};
export default Object.assign({}, inherited, messages);

View file

@ -136,6 +136,7 @@
"settings.deprecated_setting": "This setting is now controlled from Mastodon's {settings_page_link}",
"settings.enable_collapsed": "Enable collapsed toots",
"settings.enable_collapsed_hint": "Collapsed posts have parts of their contents hidden to take up less screen space. This is distinct from the Content Warning feature",
"settings.enter_amount_prompt": "Enter an amount",
"settings.enable_content_warnings_auto_unfold": "Automatically unfold content-warnings",
"settings.general": "General",
"settings.hicolor_privacy_icons": "High color privacy icons",
@ -149,6 +150,7 @@
"settings.layout_opts": "Layout options",
"settings.media": "Media",
"settings.media_fullwidth": "Full-width media previews",
"settings.num_visible_reactions": "Number of visible reactions",
"settings.media_letterbox": "Letterbox media",
"settings.media_letterbox_hint": "Scale down and letterbox media to fill the image containers instead of stretching and cropping them",
"settings.media_reveal_behind_cw": "Reveal sensitive media behind a CW by default",
@ -191,6 +193,7 @@
"settings.wide_view": "Wide view (Desktop mode only)",
"settings.wide_view_hint": "Stretches columns to better fill the available space.",
"status.collapse": "Collapse",
"status.react": "React",
"status.has_audio": "Features attached audio files",
"status.has_pictures": "Features attached pictures",
"status.has_preview_card": "Features an attached preview card",

View file

@ -0,0 +1,15 @@
import inherited from 'mastodon/locales/fr.json';
const messages = {
'notification.reaction': '{name} a réagi·e à votre message',
'notifications.column_settings.reaction': 'Réactions:',
'tooltips.reactions': 'Réactions',
'settings.enter_amount_prompt': 'Entrez un montant',
'settings.num_visible_reactions': 'Nombre de réactions visibles',
'status.react': 'Réagir',
};
export default Object.assign({}, inherited, messages);

View file

@ -129,6 +129,7 @@
"settings.deprecated_setting": "Cette option est maintenant définie par les {settings_page_link} de Mastodon",
"settings.enable_collapsed": "Activer le repliement des posts",
"settings.enable_collapsed_hint": "Les posts repliés ont une partie de leur contenu caché pour libérer de l'espace sur l'écran. C'est une option différente de l'avertissement de contenu",
"settings.enter_amount_prompt": "Entrez un montant",
"settings.enable_content_warnings_auto_unfold": "Déplier automatiquement les avertissements de contenu",
"settings.general": "Général",
"settings.hicolor_privacy_icons": "Indicateurs de confidentialité en couleurs",
@ -142,6 +143,7 @@
"settings.layout_opts": "Mise en page",
"settings.media": "Média",
"settings.media_fullwidth": "Utiliser toute la largeur pour les aperçus",
"settings.num_visible_reactions": "Nombre de réactions visibles",
"settings.media_letterbox": "Afficher les médias en Letterbox",
"settings.media_letterbox_hint": "Réduit le média et utilise une letterbox pour afficher l'image entière plutôt que de l'étirer et de la rogner",
"settings.media_reveal_behind_cw": "Toujours afficher les médias sensibles avec avertissement",
@ -192,6 +194,7 @@
"status.is_poll": "Ce post est un sondage",
"status.local_only": "Visible uniquement depuis votre instance",
"status.sensitive_toggle": "Cliquer pour voir",
"status.react": "Réagir",
"status.uncollapse": "Déplier",
"web_app_crash.change_your_settings": "Changez vos {settings}",
"web_app_crash.content": "Voici les différentes options qui s'offrent à vous :",

View file

@ -22,6 +22,7 @@ const initialState = ImmutableMap({
show_content_type_choice: false,
tag_misleading_links: true,
rewrite_mentions: 'no',
num_visible_reactions: 6,
content_warnings : ImmutableMap({
filter : null,
media_outside: false,