[feature] Move use_blurhash to app settings, enable by default (#5)
Does what it says on the tin! This serves as a decent model (imo) for how to move something from Mastodon's rather opaque server-side settings to client settings. Reviewed-on: https://codeberg.org/superseriousbusiness/masto-fe-standalone/pulls/5 Co-authored-by: tobi <tobi.smethurst@protonmail.com> Co-committed-by: tobi <tobi.smethurst@protonmail.com>
This commit is contained in:
@@ -11,7 +11,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import { debounce } from 'lodash';
|
||||
|
||||
import { Blurhash } from 'flavours/glitch/components/blurhash';
|
||||
import { autoPlayGif, displayMedia, useBlurhash } from 'flavours/glitch/initial_state';
|
||||
import { autoPlayGif, displayMedia } from 'flavours/glitch/initial_state';
|
||||
|
||||
import { IconButton } from './icon_button';
|
||||
|
||||
@@ -51,6 +51,7 @@ class Item extends PureComponent {
|
||||
displayWidth: PropTypes.number,
|
||||
visible: PropTypes.bool.isRequired,
|
||||
autoplay: PropTypes.bool,
|
||||
useBlurhash: PropTypes.bool,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
@@ -105,7 +106,17 @@ class Item extends PureComponent {
|
||||
};
|
||||
|
||||
render () {
|
||||
const { attachment, lang, index, size, standalone, letterbox, displayWidth, visible } = this.props;
|
||||
const {
|
||||
attachment,
|
||||
lang,
|
||||
index,
|
||||
size,
|
||||
standalone,
|
||||
letterbox,
|
||||
displayWidth,
|
||||
visible,
|
||||
useBlurhash,
|
||||
} = this.props;
|
||||
|
||||
let badges = [], thumbnail;
|
||||
|
||||
@@ -243,6 +254,7 @@ class MediaGallery extends PureComponent {
|
||||
visible: PropTypes.bool,
|
||||
autoplay: PropTypes.bool,
|
||||
onToggleVisibility: PropTypes.func,
|
||||
useBlurhash: PropTypes.bool,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
@@ -326,7 +338,7 @@ class MediaGallery extends PureComponent {
|
||||
}
|
||||
|
||||
render () {
|
||||
const { media, lang, intl, sensitive, letterbox, fullwidth, defaultWidth, autoplay } = this.props;
|
||||
const { media, lang, intl, sensitive, letterbox, fullwidth, defaultWidth, autoplay, useBlurhash } = this.props;
|
||||
const { visible } = this.state;
|
||||
const size = media.take(4).size;
|
||||
const uncached = media.every(attachment => attachment.get('type') === 'unknown');
|
||||
@@ -346,9 +358,33 @@ class MediaGallery extends PureComponent {
|
||||
}
|
||||
|
||||
if (this.isStandaloneEligible()) {
|
||||
children = <Item standalone autoplay={autoplay} onClick={this.handleClick} attachment={media.get(0)} lang={lang} displayWidth={width} visible={visible} />;
|
||||
children = (
|
||||
<Item
|
||||
standalone
|
||||
autoplay={autoplay}
|
||||
onClick={this.handleClick}
|
||||
attachment={media.get(0)}
|
||||
lang={lang}
|
||||
displayWidth={width}
|
||||
visible={visible}
|
||||
useBlurhash={useBlurhash}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
children = media.take(4).map((attachment, i) => <Item key={attachment.get('id')} autoplay={autoplay} onClick={this.handleClick} attachment={attachment} index={i} lang={lang} size={size} letterbox={letterbox} displayWidth={width} visible={visible || uncached} />);
|
||||
children = media.take(4).map((attachment, i) => (
|
||||
<Item
|
||||
key={attachment.get('id')}
|
||||
autoplay={autoplay}
|
||||
onClick={this.handleClick}
|
||||
attachment={attachment}
|
||||
index={i}
|
||||
lang={lang}
|
||||
size={size}
|
||||
letterbox={letterbox}
|
||||
displayWidth={width}
|
||||
visible={visible || uncached}
|
||||
useBlurhash={useBlurhash} />
|
||||
));
|
||||
}
|
||||
|
||||
if (uncached) {
|
||||
|
||||
@@ -667,6 +667,7 @@ class Status extends ImmutablePureComponent {
|
||||
blurhash={attachment.get('blurhash')}
|
||||
visible={this.state.showMedia}
|
||||
onToggleVisibility={this.handleToggleMediaVisibility}
|
||||
useBlurhash={settings.getIn(['media', 'use_blurhash'])}
|
||||
/>
|
||||
)}
|
||||
</Bundle>,
|
||||
@@ -694,6 +695,7 @@ class Status extends ImmutablePureComponent {
|
||||
deployPictureInPicture={pictureInPicture.get('available') ? this.handleDeployPictureInPicture : undefined}
|
||||
visible={this.state.showMedia}
|
||||
onToggleVisibility={this.handleToggleMediaVisibility}
|
||||
useBlurhash={settings.getIn(['media', 'use_blurhash'])}
|
||||
/>)}
|
||||
</Bundle>,
|
||||
);
|
||||
@@ -714,6 +716,7 @@ class Status extends ImmutablePureComponent {
|
||||
defaultWidth={this.props.cachedMediaWidth}
|
||||
visible={this.state.showMedia}
|
||||
onToggleVisibility={this.handleToggleMediaVisibility}
|
||||
useBlurhash={settings.getIn(['media', 'use_blurhash'])}
|
||||
/>
|
||||
)}
|
||||
</Bundle>,
|
||||
@@ -731,6 +734,7 @@ class Status extends ImmutablePureComponent {
|
||||
card={status.get('card')}
|
||||
compact
|
||||
sensitive={status.get('sensitive')}
|
||||
useBlurhash={settings.getIn(['media', 'use_blurhash'])}
|
||||
/>,
|
||||
);
|
||||
mediaIcons.push('link');
|
||||
|
||||
@@ -7,9 +7,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
|
||||
import { Blurhash } from 'flavours/glitch/components/blurhash';
|
||||
import { Icon } from 'flavours/glitch/components/icon';
|
||||
import { autoPlayGif, displayMedia, useBlurhash } from 'flavours/glitch/initial_state';
|
||||
|
||||
|
||||
import { autoPlayGif, displayMedia } from 'flavours/glitch/initial_state';
|
||||
|
||||
export default class MediaItem extends ImmutablePureComponent {
|
||||
|
||||
@@ -17,6 +15,7 @@ export default class MediaItem extends ImmutablePureComponent {
|
||||
attachment: ImmutablePropTypes.map.isRequired,
|
||||
displayWidth: PropTypes.number.isRequired,
|
||||
onOpenMedia: PropTypes.func.isRequired,
|
||||
useBlurhash: PropTypes.bool,
|
||||
};
|
||||
|
||||
state = {
|
||||
@@ -58,7 +57,7 @@ export default class MediaItem extends ImmutablePureComponent {
|
||||
};
|
||||
|
||||
render () {
|
||||
const { attachment, displayWidth } = this.props;
|
||||
const { attachment, displayWidth, useBlurhash } = this.props;
|
||||
const { visible, loaded } = this.state;
|
||||
|
||||
const width = `${Math.floor((displayWidth - 4) / 3) - 4}px`;
|
||||
|
||||
@@ -32,6 +32,7 @@ const mapStateToProps = (state, { params: { acct, id } }) => {
|
||||
|
||||
return {
|
||||
accountId,
|
||||
settings: state.get('local_settings'),
|
||||
isAccount: !!state.getIn(['accounts', accountId]),
|
||||
attachments: getAccountGallery(state, accountId),
|
||||
isLoading: state.getIn(['timelines', `account:${accountId}:media`, 'isLoading']),
|
||||
@@ -69,6 +70,7 @@ class AccountGallery extends ImmutablePureComponent {
|
||||
acct: PropTypes.string,
|
||||
id: PropTypes.string,
|
||||
}).isRequired,
|
||||
settings: ImmutablePropTypes.map.isRequired,
|
||||
accountId: PropTypes.string,
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
attachments: ImmutablePropTypes.list.isRequired,
|
||||
@@ -175,7 +177,7 @@ class AccountGallery extends ImmutablePureComponent {
|
||||
};
|
||||
|
||||
render () {
|
||||
const { attachments, isLoading, hasMore, isAccount, multiColumn, suspended } = this.props;
|
||||
const { attachments, isLoading, hasMore, isAccount, settings, multiColumn, suspended } = this.props;
|
||||
const { width } = this.state;
|
||||
|
||||
if (!isAccount) {
|
||||
@@ -215,7 +217,13 @@ class AccountGallery extends ImmutablePureComponent {
|
||||
{attachments.map((attachment, index) => attachment === null ? (
|
||||
<LoadMoreMedia key={'more:' + attachments.getIn(index + 1, 'id')} maxId={index > 0 ? attachments.getIn(index - 1, 'id') : null} onLoadMore={this.handleLoadMore} />
|
||||
) : (
|
||||
<MediaItem key={attachment.get('id')} attachment={attachment} displayWidth={width} onOpenMedia={this.handleOpenMedia} />
|
||||
<MediaItem
|
||||
key={attachment.get('id')}
|
||||
attachment={attachment}
|
||||
displayWidth={width}
|
||||
onOpenMedia={this.handleOpenMedia}
|
||||
useBlurhash={settings.getIn(['media', 'use_blurhash'])}
|
||||
/>
|
||||
))}
|
||||
|
||||
{loadOlder}
|
||||
|
||||
@@ -12,7 +12,7 @@ import { throttle, debounce } from 'lodash';
|
||||
import { Blurhash } from 'flavours/glitch/components/blurhash';
|
||||
import { Icon } from 'flavours/glitch/components/icon';
|
||||
import { formatTime, getPointerPosition, fileNameFromURL } from 'flavours/glitch/features/video';
|
||||
import { displayMedia, useBlurhash } from 'flavours/glitch/initial_state';
|
||||
import { displayMedia } from 'flavours/glitch/initial_state';
|
||||
|
||||
import Visualizer from './visualizer';
|
||||
|
||||
@@ -56,6 +56,7 @@ class Audio extends PureComponent {
|
||||
volume: PropTypes.number,
|
||||
muted: PropTypes.bool,
|
||||
deployPictureInPicture: PropTypes.func,
|
||||
useBlurhash: PropTypes.bool,
|
||||
};
|
||||
|
||||
state = {
|
||||
@@ -472,7 +473,7 @@ class Audio extends PureComponent {
|
||||
};
|
||||
|
||||
render () {
|
||||
const { src, intl, alt, lang, editable, autoPlay, sensitive, blurhash } = this.props;
|
||||
const { src, intl, alt, lang, editable, autoPlay, sensitive, blurhash, useBlurhash } = this.props;
|
||||
const { paused, volume, currentTime, duration, buffer, dragging, revealed } = this.state;
|
||||
const progress = Math.min((currentTime / duration) * 100, 100);
|
||||
const muted = this.state.muted || volume === 0;
|
||||
|
||||
@@ -466,6 +466,14 @@ class LocalSettingsPage extends PureComponent {
|
||||
({ intl, onChange, settings }) => (
|
||||
<div className='glitch local-settings__page media'>
|
||||
<h1><FormattedMessage id='settings.media' defaultMessage='Media' /></h1>
|
||||
<LocalSettingsPageItem
|
||||
settings={settings}
|
||||
item={['media', 'use_blurhash']}
|
||||
id='mastodon-settings--media-use-blurhash'
|
||||
onChange={onChange}
|
||||
>
|
||||
<FormattedMessage id='setting_use_blurhash' defaultMessage='Show colorful gradients for hidden media' />
|
||||
</LocalSettingsPageItem>
|
||||
<LocalSettingsPageItem
|
||||
settings={settings}
|
||||
item={['media', 'letterbox']}
|
||||
|
||||
@@ -10,7 +10,6 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
|
||||
import { Blurhash } from 'flavours/glitch/components/blurhash';
|
||||
import { Icon } from 'flavours/glitch/components/icon';
|
||||
import { useBlurhash } from 'flavours/glitch/initial_state';
|
||||
import { decode as decodeIDNA } from 'flavours/glitch/utils/idna';
|
||||
|
||||
const getHostname = url => {
|
||||
@@ -49,6 +48,7 @@ export default class Card extends PureComponent {
|
||||
onOpenMedia: PropTypes.func.isRequired,
|
||||
compact: PropTypes.bool,
|
||||
sensitive: PropTypes.bool,
|
||||
useBlurhash: PropTypes.bool,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
@@ -138,7 +138,7 @@ export default class Card extends PureComponent {
|
||||
}
|
||||
|
||||
render () {
|
||||
const { card, compact } = this.props;
|
||||
const { card, compact, useBlurhash } = this.props;
|
||||
const { embedded, revealed } = this.state;
|
||||
|
||||
if (card === null) {
|
||||
|
||||
@@ -185,6 +185,7 @@ class DetailedStatus extends ImmutablePureComponent {
|
||||
blurhash={attachment.get('blurhash')}
|
||||
height={150}
|
||||
onToggleVisibility={this.props.onToggleMediaVisibility}
|
||||
useBlurhash={settings.getIn(['media', 'use_blurhash'])}
|
||||
/>,
|
||||
);
|
||||
mediaIcons.push('music');
|
||||
@@ -209,6 +210,7 @@ class DetailedStatus extends ImmutablePureComponent {
|
||||
autoplay
|
||||
visible={this.props.showMedia}
|
||||
onToggleVisibility={this.props.onToggleMediaVisibility}
|
||||
useBlurhash={settings.getIn(['media', 'use_blurhash'])}
|
||||
/>,
|
||||
);
|
||||
mediaIcons.push('video-camera');
|
||||
@@ -225,12 +227,19 @@ class DetailedStatus extends ImmutablePureComponent {
|
||||
onOpenMedia={this.props.onOpenMedia}
|
||||
visible={this.props.showMedia}
|
||||
onToggleVisibility={this.props.onToggleMediaVisibility}
|
||||
useBlurhash={settings.getIn(['media', 'use_blurhash'])}
|
||||
/>,
|
||||
);
|
||||
mediaIcons.push('picture-o');
|
||||
}
|
||||
} else if (status.get('card')) {
|
||||
media.push(<Card sensitive={status.get('sensitive')} onOpenMedia={this.props.onOpenMedia} card={status.get('card')} />);
|
||||
media.push(
|
||||
<Card
|
||||
sensitive={status.get('sensitive')}
|
||||
onOpenMedia={this.props.onOpenMedia}
|
||||
card={status.get('card')}
|
||||
useBlurhash={settings.getIn(['media', 'use_blurhash'])} />
|
||||
);
|
||||
mediaIcons.push('link');
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import { throttle } from 'lodash';
|
||||
|
||||
import { Blurhash } from 'flavours/glitch/components/blurhash';
|
||||
import { Icon } from 'flavours/glitch/components/icon';
|
||||
import { displayMedia, useBlurhash } from 'flavours/glitch/initial_state';
|
||||
import { displayMedia } from 'flavours/glitch/initial_state';
|
||||
|
||||
import { isFullscreen, requestFullscreen, exitFullscreen } from '../ui/util/fullscreen';
|
||||
|
||||
@@ -129,6 +129,7 @@ class Video extends PureComponent {
|
||||
muted: PropTypes.bool,
|
||||
componentIndex: PropTypes.number,
|
||||
autoFocus: PropTypes.bool,
|
||||
useBlurhash: PropTypes.bool,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
@@ -509,8 +510,35 @@ class Video extends PureComponent {
|
||||
}
|
||||
|
||||
render () {
|
||||
const { preview, src, inline, onOpenVideo, onCloseVideo, intl, alt, lang, letterbox, fullwidth, detailed, sensitive, editable, blurhash, autoFocus } = this.props;
|
||||
const { currentTime, duration, volume, buffer, dragging, paused, fullscreen, hovered, revealed } = this.state;
|
||||
const {
|
||||
preview,
|
||||
src,
|
||||
inline,
|
||||
onOpenVideo,
|
||||
onCloseVideo,
|
||||
intl,
|
||||
alt,
|
||||
lang,
|
||||
letterbox,
|
||||
fullwidth,
|
||||
detailed,
|
||||
sensitive,
|
||||
editable,
|
||||
blurhash,
|
||||
autoFocus,
|
||||
useBlurhash
|
||||
} = this.props;
|
||||
const {
|
||||
currentTime,
|
||||
duration,
|
||||
volume,
|
||||
buffer,
|
||||
dragging,
|
||||
paused,
|
||||
fullscreen,
|
||||
hovered,
|
||||
revealed
|
||||
} = this.state;
|
||||
const progress = Math.min((currentTime / duration) * 100, 100);
|
||||
const muted = this.state.muted || volume === 0;
|
||||
|
||||
|
||||
@@ -79,7 +79,6 @@
|
||||
* @property {boolean} show_trends
|
||||
* @property {boolean} trends_as_landing_page
|
||||
* @property {boolean} unfollow_modal
|
||||
* @property {boolean} use_blurhash
|
||||
* @property {boolean=} use_pending_items
|
||||
* @property {string} version
|
||||
* @property {string} sso_redirect
|
||||
@@ -158,7 +157,6 @@ export const timelinePreview = getMeta('timeline_preview');
|
||||
export const title = getMeta('title');
|
||||
export const trendsAsLanding = getMeta('trends_as_landing_page');
|
||||
export const unfollowModal = getMeta('unfollow_modal');
|
||||
export const useBlurhash = getMeta('use_blurhash');
|
||||
export const usePendingItems = getMeta('use_pending_items');
|
||||
export const version = getMeta('version');
|
||||
export const languages = initialState?.languages;
|
||||
|
||||
@@ -45,6 +45,7 @@ const initialState = ImmutableMap({
|
||||
show_action_bar : true,
|
||||
}),
|
||||
media : ImmutableMap({
|
||||
use_blurhash : true,
|
||||
letterbox : false,
|
||||
fullwidth : true,
|
||||
reveal_behind_cw : false,
|
||||
|
||||
Reference in New Issue
Block a user