forked from mirrors/catstodon
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:
parent
c19e74051c
commit
47d0271957
9 changed files with 42 additions and 16 deletions
|
@ -270,7 +270,7 @@ MAX_POLL_OPTIONS=5
|
||||||
MAX_POLL_OPTION_CHARS=100
|
MAX_POLL_OPTION_CHARS=100
|
||||||
|
|
||||||
# Maximum number of emoji reactions per toot and user (minimum 1)
|
# Maximum number of emoji reactions per toot and user (minimum 1)
|
||||||
MAX_REACTIONS=8
|
MAX_REACTIONS=1
|
||||||
|
|
||||||
# Maximum image and video/audio upload sizes
|
# Maximum image and video/audio upload sizes
|
||||||
# Units are in bytes
|
# Units are in bytes
|
||||||
|
|
|
@ -808,6 +808,7 @@ class Status extends ImmutablePureComponent {
|
||||||
<StatusReactions
|
<StatusReactions
|
||||||
statusId={status.get('id')}
|
statusId={status.get('id')}
|
||||||
reactions={status.get('reactions')}
|
reactions={status.get('reactions')}
|
||||||
|
numVisible={settings.get('num_visible_reactions')}
|
||||||
addReaction={this.props.onReactionAdd}
|
addReaction={this.props.onReactionAdd}
|
||||||
removeReaction={this.props.onReactionRemove}
|
removeReaction={this.props.onReactionRemove}
|
||||||
emojiMap={this.props.emojiMap}
|
emojiMap={this.props.emojiMap}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
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 spring from 'react-motion/lib/spring';
|
||||||
import TransitionMotion from 'react-motion/lib/TransitionMotion';
|
import TransitionMotion from 'react-motion/lib/TransitionMotion';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
@ -16,16 +16,12 @@ export default class StatusReactions extends ImmutablePureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
statusId: PropTypes.string.isRequired,
|
statusId: PropTypes.string.isRequired,
|
||||||
reactions: ImmutablePropTypes.list.isRequired,
|
reactions: ImmutablePropTypes.list.isRequired,
|
||||||
|
numVisible: PropTypes.number,
|
||||||
addReaction: PropTypes.func.isRequired,
|
addReaction: PropTypes.func.isRequired,
|
||||||
removeReaction: PropTypes.func.isRequired,
|
removeReaction: PropTypes.func.isRequired,
|
||||||
emojiMap: ImmutablePropTypes.map.isRequired,
|
emojiMap: ImmutablePropTypes.map.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
handleEmojiPick = data => {
|
|
||||||
const { addReaction, statusId } = this.props;
|
|
||||||
addReaction(statusId, data.native.replace(/:/g, ''));
|
|
||||||
}
|
|
||||||
|
|
||||||
willEnter() {
|
willEnter() {
|
||||||
return { scale: reduceMotion ? 1 : 0 };
|
return { scale: reduceMotion ? 1 : 0 };
|
||||||
}
|
}
|
||||||
|
@ -35,11 +31,18 @@ export default class StatusReactions extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { reactions } = this.props;
|
const { reactions, numVisible } = this.props;
|
||||||
const visibleReactions = reactions
|
let visibleReactions = reactions
|
||||||
.filter(x => x.get('count') > 0)
|
.filter(x => x.get('count') > 0)
|
||||||
.sort((a, b) => b.get('count') - a.get('count'))
|
.sort((a, b) => b.get('count') - a.get('count'));
|
||||||
.filter((_, i) => i < maxReactions);
|
|
||||||
|
// 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 => ({
|
const styles = visibleReactions.map(reaction => ({
|
||||||
key: reaction.get('name'),
|
key: reaction.get('name'),
|
||||||
|
|
|
@ -29,6 +29,8 @@ const messages = defineMessages({
|
||||||
rewrite_mentions_username: { id: 'settings.rewrite_mentions_username', defaultMessage: 'Rewrite with username' },
|
rewrite_mentions_username: { id: 'settings.rewrite_mentions_username', defaultMessage: 'Rewrite with username' },
|
||||||
pop_in_left: { id: 'settings.pop_in_left', defaultMessage: 'Left' },
|
pop_in_left: { id: 'settings.pop_in_left', defaultMessage: 'Left' },
|
||||||
pop_in_right: { id: 'settings.pop_in_right', defaultMessage: 'Right' },
|
pop_in_right: { id: 'settings.pop_in_right', defaultMessage: 'Right' },
|
||||||
|
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' },
|
||||||
});
|
});
|
||||||
|
|
||||||
export default @injectIntl
|
export default @injectIntl
|
||||||
|
@ -92,6 +94,16 @@ class LocalSettingsPage extends React.PureComponent {
|
||||||
>
|
>
|
||||||
<FormattedMessage id='settings.rewrite_mentions' defaultMessage='Rewrite mentions in displayed statuses' />
|
<FormattedMessage id='settings.rewrite_mentions' defaultMessage='Rewrite mentions in displayed statuses' />
|
||||||
</LocalSettingsPageItem>
|
</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>
|
<section>
|
||||||
<h2><FormattedMessage id='settings.notifications_opts' defaultMessage='Notifications options' /></h2>
|
<h2><FormattedMessage id='settings.notifications_opts' defaultMessage='Notifications options' /></h2>
|
||||||
<LocalSettingsPageItem
|
<LocalSettingsPageItem
|
||||||
|
|
|
@ -21,20 +21,21 @@ export default class LocalSettingsPageItem extends React.PureComponent {
|
||||||
})),
|
})),
|
||||||
settings: ImmutablePropTypes.map.isRequired,
|
settings: ImmutablePropTypes.map.isRequired,
|
||||||
placeholder: PropTypes.string,
|
placeholder: PropTypes.string,
|
||||||
|
number: PropTypes.bool,
|
||||||
disabled: PropTypes.bool,
|
disabled: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
handleChange = e => {
|
handleChange = e => {
|
||||||
const { target } = 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);
|
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);
|
else onChange(item, target.checked);
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { handleChange } = this;
|
const { handleChange } = this;
|
||||||
const { settings, item, id, options, children, dependsOn, dependsOnNot, placeholder, disabled } = this.props;
|
const { settings, item, id, options, children, dependsOn, dependsOnNot, placeholder, number, disabled } = this.props;
|
||||||
let enabled = !disabled;
|
let enabled = !disabled;
|
||||||
|
|
||||||
if (dependsOn) {
|
if (dependsOn) {
|
||||||
|
@ -76,7 +77,7 @@ export default class LocalSettingsPageItem extends React.PureComponent {
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else if (placeholder) {
|
} else if (placeholder || number) {
|
||||||
return (
|
return (
|
||||||
<div className='glitch local-settings__page__item string'>
|
<div className='glitch local-settings__page__item string'>
|
||||||
<label htmlFor={id}>
|
<label htmlFor={id}>
|
||||||
|
@ -84,7 +85,7 @@ export default class LocalSettingsPageItem extends React.PureComponent {
|
||||||
<p>
|
<p>
|
||||||
<input
|
<input
|
||||||
id={id}
|
id={id}
|
||||||
type='text'
|
type={number ? 'number' : 'text'}
|
||||||
value={settings.getIn(item)}
|
value={settings.getIn(item)}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
|
|
|
@ -6,6 +6,9 @@ const messages = {
|
||||||
|
|
||||||
'tooltips.reactions': 'Reaktionen',
|
'tooltips.reactions': 'Reaktionen',
|
||||||
|
|
||||||
|
'settings.enter_amount_prompt': 'Gib eine Zahl ein',
|
||||||
|
'settings.num_visible_reactions': 'Anzahl sichtbarer Reaktionen',
|
||||||
|
|
||||||
'status.react': 'Reagieren',
|
'status.react': 'Reagieren',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ const messages = {
|
||||||
'settings.collapsed_statuses': 'Collapsed toots',
|
'settings.collapsed_statuses': 'Collapsed toots',
|
||||||
'settings.enable_collapsed': 'Enable 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.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.general': 'General',
|
||||||
'settings.compose_box_opts': 'Compose box',
|
'settings.compose_box_opts': 'Compose box',
|
||||||
'settings.side_arm': 'Secondary toot button:',
|
'settings.side_arm': 'Secondary toot button:',
|
||||||
|
@ -104,6 +105,7 @@ const messages = {
|
||||||
'settings.media_letterbox': 'Letterbox 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_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.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.inline_preview_cards': 'Inline preview cards for external links',
|
||||||
'settings.media_reveal_behind_cw': 'Reveal sensitive media behind a CW by default',
|
'settings.media_reveal_behind_cw': 'Reveal sensitive media behind a CW by default',
|
||||||
'settings.pop_in_player': 'Enable pop-in player',
|
'settings.pop_in_player': 'Enable pop-in player',
|
||||||
|
|
|
@ -6,6 +6,9 @@ const messages = {
|
||||||
|
|
||||||
'tooltips.reactions': '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',
|
'status.react': 'Réagir',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ const initialState = ImmutableMap({
|
||||||
show_content_type_choice: false,
|
show_content_type_choice: false,
|
||||||
tag_misleading_links: true,
|
tag_misleading_links: true,
|
||||||
rewrite_mentions: 'no',
|
rewrite_mentions: 'no',
|
||||||
|
num_visible_reactions: 6,
|
||||||
content_warnings : ImmutableMap({
|
content_warnings : ImmutableMap({
|
||||||
filter : null,
|
filter : null,
|
||||||
media_outside: false,
|
media_outside: false,
|
||||||
|
|
Loading…
Reference in a new issue