mirror of
https://github.com/lunaisnotaboy/mastodon.git
synced 2024-11-24 07:43:24 +00:00
Merge commit 'ce1f35d7e213327549b960bb64f63c67a141ea40' into glitch-soc/merge-upstream
Conflicts: - `db/schema.rb`: Upstream regenerated the schema file using Rails 7, the conflicts are caused by our extra columns. Applied upstream's changes, but keeping our extra columns.
This commit is contained in:
commit
bd349cb850
4
.github/workflows/test-ruby.yml
vendored
4
.github/workflows/test-ruby.yml
vendored
|
@ -107,6 +107,10 @@ jobs:
|
|||
PAM_ENABLED: true
|
||||
PAM_DEFAULT_SERVICE: pam_test
|
||||
PAM_CONTROLLED_SERVICE: pam_test_controlled
|
||||
OIDC_ENABLED: true
|
||||
OIDC_SCOPE: read
|
||||
SAML_ENABLED: true
|
||||
CAS_ENABLED: true
|
||||
BUNDLE_WITH: 'pam_authentication test'
|
||||
CI_JOBS: ${{ matrix.ci_job }}/4
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ GEM
|
|||
attr_required (1.0.1)
|
||||
awrence (1.2.1)
|
||||
aws-eventstream (1.2.0)
|
||||
aws-partitions (1.786.0)
|
||||
aws-partitions (1.791.0)
|
||||
aws-sdk-core (3.178.0)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
aws-partitions (~> 1, >= 1.651.0)
|
||||
|
@ -112,7 +112,7 @@ GEM
|
|||
aws-sdk-kms (1.71.0)
|
||||
aws-sdk-core (~> 3, >= 3.177.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sdk-s3 (1.130.0)
|
||||
aws-sdk-s3 (1.131.0)
|
||||
aws-sdk-core (~> 3, >= 3.177.0)
|
||||
aws-sdk-kms (~> 1)
|
||||
aws-sigv4 (~> 1.6)
|
||||
|
@ -144,7 +144,7 @@ GEM
|
|||
blurhash (0.1.7)
|
||||
bootsnap (1.16.0)
|
||||
msgpack (~> 1.2)
|
||||
brakeman (6.0.0)
|
||||
brakeman (6.0.1)
|
||||
browser (5.3.1)
|
||||
brpoplpush-redis_script (0.1.3)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.5)
|
||||
|
@ -569,7 +569,7 @@ GEM
|
|||
rake (13.0.6)
|
||||
rdf (3.2.11)
|
||||
link_header (~> 0.0, >= 0.0.8)
|
||||
rdf-normalize (0.6.0)
|
||||
rdf-normalize (0.6.1)
|
||||
rdf (~> 3.2)
|
||||
redcarpet (3.6.0)
|
||||
redis (4.8.1)
|
||||
|
|
|
@ -5,21 +5,13 @@ class Auth::OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
|||
|
||||
def self.provides_callback_for(provider)
|
||||
define_method provider do
|
||||
@provider = provider
|
||||
@user = User.find_for_oauth(request.env['omniauth.auth'], current_user)
|
||||
|
||||
if @user.persisted?
|
||||
LoginActivity.create(
|
||||
user: @user,
|
||||
success: true,
|
||||
authentication_method: :omniauth,
|
||||
provider: provider,
|
||||
ip: request.remote_ip,
|
||||
user_agent: request.user_agent
|
||||
)
|
||||
|
||||
record_login_activity
|
||||
sign_in_and_redirect @user, event: :authentication
|
||||
label = Devise.omniauth_configs[provider]&.strategy&.display_name.presence || I18n.t("auth.providers.#{provider}", default: provider.to_s.chomp('_oauth2').capitalize)
|
||||
set_flash_message(:notice, :success, kind: label) if is_navigational_format?
|
||||
set_flash_message(:notice, :success, kind: label_for_provider) if is_navigational_format?
|
||||
else
|
||||
session["devise.#{provider}_data"] = request.env['omniauth.auth']
|
||||
redirect_to new_user_registration_url
|
||||
|
@ -38,4 +30,29 @@ class Auth::OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
|||
auth_setup_path(missing_email: '1')
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def record_login_activity
|
||||
LoginActivity.create(
|
||||
user: @user,
|
||||
success: true,
|
||||
authentication_method: :omniauth,
|
||||
provider: @provider,
|
||||
ip: request.remote_ip,
|
||||
user_agent: request.user_agent
|
||||
)
|
||||
end
|
||||
|
||||
def label_for_provider
|
||||
provider_display_name || configured_provider_name
|
||||
end
|
||||
|
||||
def provider_display_name
|
||||
Devise.omniauth_configs[@provider]&.strategy&.display_name.presence
|
||||
end
|
||||
|
||||
def configured_provider_name
|
||||
I18n.t("auth.providers.#{@provider}", default: @provider.to_s.chomp('_oauth2').capitalize)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -113,7 +113,7 @@ class Auth::SessionsController < Devise::SessionsController
|
|||
end
|
||||
|
||||
def home_paths(resource)
|
||||
paths = [about_path]
|
||||
paths = [about_path, '/explore']
|
||||
|
||||
paths << short_account_path(username: resource.account) if single_user_mode? && resource.is_a?(User)
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import { debounce } from 'lodash';
|
|||
|
||||
import { Blurhash } from 'mastodon/components/blurhash';
|
||||
|
||||
import { autoPlayGif, cropImages, displayMedia, useBlurhash } from '../initial_state';
|
||||
import { autoPlayGif, displayMedia, useBlurhash } from '../initial_state';
|
||||
|
||||
import { IconButton } from './icon_button';
|
||||
|
||||
|
@ -209,7 +209,6 @@ class MediaGallery extends PureComponent {
|
|||
|
||||
static propTypes = {
|
||||
sensitive: PropTypes.bool,
|
||||
standalone: PropTypes.bool,
|
||||
media: ImmutablePropTypes.list.isRequired,
|
||||
lang: PropTypes.string,
|
||||
size: PropTypes.object,
|
||||
|
@ -223,10 +222,6 @@ class MediaGallery extends PureComponent {
|
|||
onToggleVisibility: PropTypes.func,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
standalone: false,
|
||||
};
|
||||
|
||||
state = {
|
||||
visible: this.props.visible !== undefined ? this.props.visible : (displayMedia !== 'hide_all' && !this.props.sensitive || displayMedia === 'show_all'),
|
||||
width: this.props.defaultWidth,
|
||||
|
@ -295,7 +290,7 @@ class MediaGallery extends PureComponent {
|
|||
}
|
||||
|
||||
render () {
|
||||
const { media, lang, intl, sensitive, defaultWidth, standalone, autoplay } = this.props;
|
||||
const { media, lang, intl, sensitive, defaultWidth, autoplay } = this.props;
|
||||
const { visible } = this.state;
|
||||
const width = this.state.width || defaultWidth;
|
||||
|
||||
|
@ -303,16 +298,16 @@ class MediaGallery extends PureComponent {
|
|||
|
||||
const style = {};
|
||||
|
||||
if (this.isFullSizeEligible() && (standalone || !cropImages)) {
|
||||
if (this.isFullSizeEligible()) {
|
||||
style.aspectRatio = `${this.props.media.getIn([0, 'meta', 'small', 'aspect'])}`;
|
||||
} else {
|
||||
style.aspectRatio = '16 / 9';
|
||||
style.aspectRatio = '3 / 2';
|
||||
}
|
||||
|
||||
const size = media.take(4).size;
|
||||
const uncached = media.every(attachment => attachment.get('type') === 'unknown');
|
||||
|
||||
if (standalone && this.isFullSizeEligible()) {
|
||||
if (this.isFullSizeEligible()) {
|
||||
children = <Item standalone autoplay={autoplay} onClick={this.handleClick} attachment={media.get(0)} lang={lang} displayWidth={width} visible={visible} />;
|
||||
} 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} displayWidth={width} visible={visible || uncached} />);
|
||||
|
|
|
@ -12,6 +12,7 @@ class PictureInPicturePlaceholder extends PureComponent {
|
|||
|
||||
static propTypes = {
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
aspectRatio: PropTypes.string,
|
||||
};
|
||||
|
||||
handleClick = () => {
|
||||
|
@ -20,8 +21,10 @@ class PictureInPicturePlaceholder extends PureComponent {
|
|||
};
|
||||
|
||||
render () {
|
||||
const { aspectRatio } = this.props;
|
||||
|
||||
return (
|
||||
<div className='picture-in-picture-placeholder' role='button' tabIndex={0} onClick={this.handleClick}>
|
||||
<div className='picture-in-picture-placeholder' style={{ aspectRatio }} role='button' tabIndex={0} onClick={this.handleClick}>
|
||||
<Icon id='window-restore' />
|
||||
<FormattedMessage id='picture_in_picture.restore' defaultMessage='Put it back' />
|
||||
</div>
|
||||
|
|
|
@ -19,7 +19,6 @@ import Bundle from '../features/ui/components/bundle';
|
|||
import { MediaGallery, Video, Audio } from '../features/ui/util/async-components';
|
||||
import { displayMedia } from '../initial_state';
|
||||
|
||||
import AttachmentList from './attachment_list';
|
||||
import { Avatar } from './avatar';
|
||||
import { AvatarOverlay } from './avatar_overlay';
|
||||
import { DisplayName } from './display_name';
|
||||
|
@ -191,17 +190,35 @@ class Status extends ImmutablePureComponent {
|
|||
this.props.onTranslate(this._properStatus());
|
||||
};
|
||||
|
||||
renderLoadingMediaGallery () {
|
||||
return <div className='media-gallery' style={{ height: '110px' }} />;
|
||||
getAttachmentAspectRatio () {
|
||||
const attachments = this._properStatus().get('media_attachments');
|
||||
|
||||
if (attachments.getIn([0, 'type']) === 'video') {
|
||||
return `${attachments.getIn([0, 'meta', 'original', 'width'])} / ${attachments.getIn([0, 'meta', 'original', 'height'])}`;
|
||||
} else if (attachments.getIn([0, 'type']) === 'audio') {
|
||||
return '16 / 9';
|
||||
} else {
|
||||
return (attachments.size === 1 && attachments.getIn([0, 'meta', 'small', 'aspect'])) ? attachments.getIn([0, 'meta', 'small', 'aspect']) : '3 / 2'
|
||||
}
|
||||
}
|
||||
|
||||
renderLoadingVideoPlayer () {
|
||||
return <div className='video-player' style={{ height: '110px' }} />;
|
||||
}
|
||||
renderLoadingMediaGallery = () => {
|
||||
return (
|
||||
<div className='media-gallery' style={{ aspectRatio: this.getAttachmentAspectRatio() }} />
|
||||
);
|
||||
};
|
||||
|
||||
renderLoadingAudioPlayer () {
|
||||
return <div className='audio-player' style={{ height: '110px' }} />;
|
||||
}
|
||||
renderLoadingVideoPlayer = () => {
|
||||
return (
|
||||
<div className='video-player' style={{ aspectRatio: this.getAttachmentAspectRatio() }} />
|
||||
);
|
||||
};
|
||||
|
||||
renderLoadingAudioPlayer = () => {
|
||||
return (
|
||||
<div className='audio-player' style={{ aspectRatio: this.getAttachmentAspectRatio() }} />
|
||||
);
|
||||
};
|
||||
|
||||
handleOpenVideo = (options) => {
|
||||
const status = this._properStatus();
|
||||
|
@ -426,18 +443,11 @@ class Status extends ImmutablePureComponent {
|
|||
}
|
||||
|
||||
if (pictureInPicture.get('inUse')) {
|
||||
media = <PictureInPicturePlaceholder />;
|
||||
media = <PictureInPicturePlaceholder aspectRatio={this.getAttachmentAspectRatio()} />;
|
||||
} else if (status.get('media_attachments').size > 0) {
|
||||
const language = status.getIn(['translation', 'language']) || status.get('language');
|
||||
|
||||
if (this.props.muted) {
|
||||
media = (
|
||||
<AttachmentList
|
||||
compact
|
||||
media={status.get('media_attachments')}
|
||||
/>
|
||||
);
|
||||
} else if (status.getIn(['media_attachments', 0, 'type']) === 'audio') {
|
||||
if (status.getIn(['media_attachments', 0, 'type']) === 'audio') {
|
||||
const attachment = status.getIn(['media_attachments', 0]);
|
||||
const description = attachment.getIn(['translation', 'description']) || attachment.get('description');
|
||||
|
||||
|
@ -475,11 +485,11 @@ class Status extends ImmutablePureComponent {
|
|||
<Component
|
||||
preview={attachment.get('preview_url')}
|
||||
frameRate={attachment.getIn(['meta', 'original', 'frame_rate'])}
|
||||
aspectRatio={`${attachment.getIn(['meta', 'original', 'width'])} / ${attachment.getIn(['meta', 'original', 'height'])}`}
|
||||
blurhash={attachment.get('blurhash')}
|
||||
src={attachment.get('url')}
|
||||
alt={description}
|
||||
lang={language}
|
||||
inline
|
||||
sensitive={status.get('sensitive')}
|
||||
onOpenVideo={this.handleOpenVideo}
|
||||
deployPictureInPicture={pictureInPicture.get('available') ? this.handleDeployPictureInPicture : undefined}
|
||||
|
@ -508,7 +518,7 @@ class Status extends ImmutablePureComponent {
|
|||
</Bundle>
|
||||
);
|
||||
}
|
||||
} else if (status.get('spoiler_text').length === 0 && status.get('card') && !this.props.muted) {
|
||||
} else if (status.get('spoiler_text').length === 0 && status.get('card')) {
|
||||
media = (
|
||||
<Card
|
||||
onOpenMedia={this.handleOpenMedia}
|
||||
|
|
|
@ -470,6 +470,7 @@ class Audio extends PureComponent {
|
|||
const progress = Math.min((currentTime / duration) * 100, 100);
|
||||
|
||||
let warning;
|
||||
|
||||
if (sensitive) {
|
||||
warning = <FormattedMessage id='status.sensitive_warning' defaultMessage='Sensitive content' />;
|
||||
} else {
|
||||
|
@ -515,7 +516,10 @@ class Audio extends PureComponent {
|
|||
|
||||
<div className={classNames('spoiler-button', { 'spoiler-button--hidden': revealed || editable })}>
|
||||
<button type='button' className='spoiler-button__overlay' onClick={this.toggleReveal}>
|
||||
<span className='spoiler-button__overlay__label'>{warning}</span>
|
||||
<span className='spoiler-button__overlay__label'>
|
||||
{warning}
|
||||
<span className='spoiler-button__overlay__action'><FormattedMessage id='status.media.show' defaultMessage='Click to show' /></span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -86,7 +86,6 @@ class Bookmarks extends ImmutablePureComponent {
|
|||
onClick={this.handleHeaderClick}
|
||||
pinned={pinned}
|
||||
multiColumn={multiColumn}
|
||||
showBackButton
|
||||
/>
|
||||
|
||||
<StatusList
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import { PureComponent } from 'react';
|
||||
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { Blurhash } from 'mastodon/components/blurhash';
|
||||
import { accountsCountRenderer } from 'mastodon/components/hashtag';
|
||||
import { RelativeTimestamp } from 'mastodon/components/relative_timestamp';
|
||||
import { ShortNumber } from 'mastodon/components/short_number';
|
||||
import { Skeleton } from 'mastodon/components/skeleton';
|
||||
|
||||
|
@ -13,10 +16,14 @@ export default class Story extends PureComponent {
|
|||
static propTypes = {
|
||||
url: PropTypes.string,
|
||||
title: PropTypes.string,
|
||||
lang: PropTypes.string,
|
||||
publisher: PropTypes.string,
|
||||
publishedAt: PropTypes.string,
|
||||
author: PropTypes.string,
|
||||
sharedTimes: PropTypes.number,
|
||||
thumbnail: PropTypes.string,
|
||||
blurhash: PropTypes.string,
|
||||
expanded: PropTypes.bool,
|
||||
};
|
||||
|
||||
state = {
|
||||
|
@ -26,16 +33,16 @@ export default class Story extends PureComponent {
|
|||
handleImageLoad = () => this.setState({ thumbnailLoaded: true });
|
||||
|
||||
render () {
|
||||
const { url, title, publisher, sharedTimes, thumbnail, blurhash } = this.props;
|
||||
const { expanded, url, title, lang, publisher, author, publishedAt, sharedTimes, thumbnail, blurhash } = this.props;
|
||||
|
||||
const { thumbnailLoaded } = this.state;
|
||||
|
||||
return (
|
||||
<a className='story' href={url} target='blank' rel='noopener'>
|
||||
<a className={classNames('story', { expanded })} href={url} target='blank' rel='noopener'>
|
||||
<div className='story__details'>
|
||||
<div className='story__details__publisher'>{publisher ? publisher : <Skeleton width={50} />}</div>
|
||||
<div className='story__details__title'>{title ? title : <Skeleton />}</div>
|
||||
<div className='story__details__shared'>{typeof sharedTimes === 'number' ? <ShortNumber value={sharedTimes} renderer={accountsCountRenderer} /> : <Skeleton width={100} />}</div>
|
||||
<div className='story__details__publisher'>{publisher ? <span lang={lang}>{publisher}</span> : <Skeleton width={50} />}{publishedAt && <> · <RelativeTimestamp timestamp={publishedAt} /></>}</div>
|
||||
<div className='story__details__title' lang={lang}>{title ? title : <Skeleton />}</div>
|
||||
<div className='story__details__shared'>{author && <><FormattedMessage id='link_preview.author' defaultMessage='By {name}' values={{ name: <strong>{author}</strong> }} /> · </>}{typeof sharedTimes === 'number' ? <ShortNumber value={sharedTimes} renderer={accountsCountRenderer} /> : <Skeleton width={100} />}</div>
|
||||
</div>
|
||||
|
||||
<div className='story__thumbnail'>
|
||||
|
|
|
@ -55,12 +55,16 @@ class Links extends PureComponent {
|
|||
<div className='explore__links'>
|
||||
{banner}
|
||||
|
||||
{isLoading ? (<LoadingIndicator />) : links.map(link => (
|
||||
{isLoading ? (<LoadingIndicator />) : links.map((link, i) => (
|
||||
<Story
|
||||
key={link.get('id')}
|
||||
expanded={i === 0}
|
||||
lang={link.get('language')}
|
||||
url={link.get('url')}
|
||||
title={link.get('title')}
|
||||
publisher={link.get('provider_name')}
|
||||
publishedAt={link.get('published_at')}
|
||||
author={link.get('author_name')}
|
||||
sharedTimes={link.getIn(['history', 0, 'accounts']) * 1 + link.getIn(['history', 1, 'accounts']) * 1}
|
||||
thumbnail={link.get('image')}
|
||||
blurhash={link.get('blurhash')}
|
||||
|
|
|
@ -86,7 +86,6 @@ class Favourites extends ImmutablePureComponent {
|
|||
onClick={this.handleHeaderClick}
|
||||
pinned={pinned}
|
||||
multiColumn={multiColumn}
|
||||
showBackButton
|
||||
/>
|
||||
|
||||
<StatusList
|
||||
|
|
|
@ -65,7 +65,7 @@ class Lists extends ImmutablePureComponent {
|
|||
|
||||
return (
|
||||
<Column bindToDocument={!multiColumn} label={intl.formatMessage(messages.heading)}>
|
||||
<ColumnHeader title={intl.formatMessage(messages.heading)} icon='list-ul' multiColumn={multiColumn} showBackButton />
|
||||
<ColumnHeader title={intl.formatMessage(messages.heading)} icon='list-ul' multiColumn={multiColumn} />
|
||||
|
||||
<NewListForm />
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
|
|||
|
||||
import { Blurhash } from 'mastodon/components/blurhash';
|
||||
import { Icon } from 'mastodon/components/icon';
|
||||
import { RelativeTimestamp } from 'mastodon/components/relative_timestamp';
|
||||
import { useBlurhash } from 'mastodon/initial_state';
|
||||
|
||||
const IDNA_PREFIX = 'xn--';
|
||||
|
@ -57,14 +58,9 @@ export default class Card extends PureComponent {
|
|||
static propTypes = {
|
||||
card: ImmutablePropTypes.map,
|
||||
onOpenMedia: PropTypes.func.isRequired,
|
||||
compact: PropTypes.bool,
|
||||
sensitive: PropTypes.bool,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
compact: false,
|
||||
};
|
||||
|
||||
state = {
|
||||
previewLoaded: false,
|
||||
embedded: false,
|
||||
|
@ -148,7 +144,7 @@ export default class Card extends PureComponent {
|
|||
}
|
||||
|
||||
render () {
|
||||
const { card, compact } = this.props;
|
||||
const { card } = this.props;
|
||||
const { embedded, revealed } = this.state;
|
||||
|
||||
if (card === null) {
|
||||
|
@ -156,29 +152,27 @@ export default class Card extends PureComponent {
|
|||
}
|
||||
|
||||
const provider = card.get('provider_name').length === 0 ? decodeIDNA(getHostname(card.get('url'))) : card.get('provider_name');
|
||||
const horizontal = (!compact && card.get('width') > card.get('height')) || card.get('type') !== 'link' || embedded;
|
||||
const interactive = card.get('type') !== 'link';
|
||||
const className = classnames('status-card', { horizontal, compact, interactive });
|
||||
const title = interactive ? <a className='status-card__title' href={card.get('url')} title={card.get('title')} rel='noopener noreferrer' target='_blank'><strong>{card.get('title')}</strong></a> : <strong className='status-card__title' title={card.get('title')}>{card.get('title')}</strong>;
|
||||
const language = card.get('language') || '';
|
||||
|
||||
const description = (
|
||||
<div className='status-card__content' lang={language}>
|
||||
{title}
|
||||
{!(horizontal || compact) && <p className='status-card__description' title={card.get('description')}>{card.get('description')}</p>}
|
||||
<span className='status-card__host'>{provider}</span>
|
||||
<div className='status-card__content'>
|
||||
<span className='status-card__host'>
|
||||
<span lang={language}>{provider}</span>
|
||||
{card.get('published_at') && <> · <RelativeTimestamp timestamp={card.get('published_at')} /></>}
|
||||
</span>
|
||||
<strong className='status-card__title' title={card.get('title')} lang={language}>{card.get('title')}</strong>
|
||||
{card.get('author_name').length > 0 && <span className='status-card__author'><FormattedMessage id='link_preview.author' defaultMessage='By {name}' values={{ name: <strong>{card.get('author_name')}</strong> }} /></span>}
|
||||
</div>
|
||||
);
|
||||
|
||||
const thumbnailStyle = {
|
||||
visibility: revealed? null : 'hidden',
|
||||
visibility: revealed ? null : 'hidden',
|
||||
aspectRatio: `${card.get('width')} / ${card.get('height')}`
|
||||
};
|
||||
|
||||
if (horizontal) {
|
||||
thumbnailStyle.aspectRatio = (compact && !embedded) ? '16 / 9' : `${card.get('width')} / ${card.get('height')}`;
|
||||
}
|
||||
let embed;
|
||||
|
||||
let embed = '';
|
||||
let canvas = (
|
||||
<Blurhash
|
||||
className={classnames('status-card__image-preview', {
|
||||
|
@ -188,12 +182,18 @@ export default class Card extends PureComponent {
|
|||
dummy={!useBlurhash}
|
||||
/>
|
||||
);
|
||||
|
||||
let thumbnail = <img src={card.get('image')} alt='' style={thumbnailStyle} onLoad={this.handleImageLoad} className='status-card__image-image' />;
|
||||
|
||||
let spoilerButton = (
|
||||
<button type='button' onClick={this.handleReveal} className='spoiler-button__overlay'>
|
||||
<span className='spoiler-button__overlay__label'><FormattedMessage id='status.sensitive_warning' defaultMessage='Sensitive content' /></span>
|
||||
<span className='spoiler-button__overlay__label'>
|
||||
<FormattedMessage id='status.sensitive_warning' defaultMessage='Sensitive content' />
|
||||
<span className='spoiler-button__overlay__action'><FormattedMessage id='status.media.show' defaultMessage='Click to show' /></span>
|
||||
</span>
|
||||
</button>
|
||||
);
|
||||
|
||||
spoilerButton = (
|
||||
<div className={classnames('spoiler-button', { 'spoiler-button--minified': revealed })}>
|
||||
{spoilerButton}
|
||||
|
@ -219,19 +219,20 @@ export default class Card extends PureComponent {
|
|||
<div className='status-card__actions'>
|
||||
<div>
|
||||
<button type='button' onClick={this.handleEmbedClick}><Icon id={iconVariant} /></button>
|
||||
{horizontal && <a href={card.get('url')} target='_blank' rel='noopener noreferrer'><Icon id='external-link' /></a>}
|
||||
<a href={card.get('url')} target='_blank' rel='noopener noreferrer'><Icon id='external-link' /></a>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!revealed && spoilerButton}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={className} ref={this.setRef} onClick={revealed ? null : this.handleReveal} role={revealed ? 'button' : null}>
|
||||
<div className='status-card' ref={this.setRef} onClick={revealed ? null : this.handleReveal} role={revealed ? 'button' : null}>
|
||||
{embed}
|
||||
{!compact && description}
|
||||
<a href={card.get('url')} target='_blank' rel='noopener noreferrer'>{description}</a>
|
||||
</div>
|
||||
);
|
||||
} else if (card.get('image')) {
|
||||
|
@ -243,14 +244,14 @@ export default class Card extends PureComponent {
|
|||
);
|
||||
} else {
|
||||
embed = (
|
||||
<div className='status-card__image'>
|
||||
<div className='status-card__image' style={{ aspectRatio: '1.9 / 1' }}>
|
||||
<Icon id='file-text' />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<a href={card.get('url')} className={className} target='_blank' rel='noopener noreferrer' ref={this.setRef}>
|
||||
<a href={card.get('url')} className='status-card' target='_blank' rel='noopener noreferrer' ref={this.setRef}>
|
||||
{embed}
|
||||
{description}
|
||||
</a>
|
||||
|
|
|
@ -113,8 +113,30 @@ class DetailedStatus extends ImmutablePureComponent {
|
|||
onTranslate(status);
|
||||
};
|
||||
|
||||
_properStatus () {
|
||||
const { status } = this.props;
|
||||
|
||||
if (status.get('reblog', null) !== null && typeof status.get('reblog') === 'object') {
|
||||
return status.get('reblog');
|
||||
} else {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
getAttachmentAspectRatio () {
|
||||
const attachments = this._properStatus().get('media_attachments');
|
||||
|
||||
if (attachments.getIn([0, 'type']) === 'video') {
|
||||
return `${attachments.getIn([0, 'meta', 'original', 'width'])} / ${attachments.getIn([0, 'meta', 'original', 'height'])}`;
|
||||
} else if (attachments.getIn([0, 'type']) === 'audio') {
|
||||
return '16 / 9';
|
||||
} else {
|
||||
return (attachments.size === 1 && attachments.getIn([0, 'meta', 'small', 'aspect'])) ? attachments.getIn([0, 'meta', 'small', 'aspect']) : '3 / 2'
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
const status = (this.props.status && this.props.status.get('reblog')) ? this.props.status.get('reblog') : this.props.status;
|
||||
const status = this._properStatus();
|
||||
const outerStyle = { boxSizing: 'border-box' };
|
||||
const { intl, compact, pictureInPicture } = this.props;
|
||||
|
||||
|
@ -136,7 +158,7 @@ class DetailedStatus extends ImmutablePureComponent {
|
|||
const language = status.getIn(['translation', 'language']) || status.get('language');
|
||||
|
||||
if (pictureInPicture.get('inUse')) {
|
||||
media = <PictureInPicturePlaceholder />;
|
||||
media = <PictureInPicturePlaceholder aspectRatio={this.getAttachmentAspectRatio()} />;
|
||||
} else if (status.get('media_attachments').size > 0) {
|
||||
if (status.getIn(['media_attachments', 0, 'type']) === 'audio') {
|
||||
const attachment = status.getIn(['media_attachments', 0]);
|
||||
|
@ -167,13 +189,13 @@ class DetailedStatus extends ImmutablePureComponent {
|
|||
<Video
|
||||
preview={attachment.get('preview_url')}
|
||||
frameRate={attachment.getIn(['meta', 'original', 'frame_rate'])}
|
||||
aspectRatio={`${attachment.getIn(['meta', 'original', 'width'])} / ${attachment.getIn(['meta', 'original', 'height'])}`}
|
||||
blurhash={attachment.get('blurhash')}
|
||||
src={attachment.get('url')}
|
||||
alt={description}
|
||||
lang={language}
|
||||
width={300}
|
||||
height={150}
|
||||
inline
|
||||
onOpenVideo={this.handleOpenVideo}
|
||||
sensitive={status.get('sensitive')}
|
||||
visible={this.props.showMedia}
|
||||
|
|
|
@ -172,6 +172,7 @@ class MediaModal extends ImmutablePureComponent {
|
|||
width={image.get('width')}
|
||||
height={image.get('height')}
|
||||
frameRate={image.getIn(['meta', 'original', 'frame_rate'])}
|
||||
aspectRatio={`${image.getIn(['meta', 'original', 'width'])} / ${image.getIn(['meta', 'original', 'height'])}`}
|
||||
currentTime={currentTime || 0}
|
||||
autoPlay={autoPlay || false}
|
||||
volume={volume || 1}
|
||||
|
|
|
@ -49,6 +49,7 @@ class VideoModal extends ImmutablePureComponent {
|
|||
<Video
|
||||
preview={media.get('preview_url')}
|
||||
frameRate={media.getIn(['meta', 'original', 'frame_rate'])}
|
||||
aspectRatio={`${media.getIn(['meta', 'original', 'width'])} / ${media.getIn(['meta', 'original', 'height'])}`}
|
||||
blurhash={media.get('blurhash')}
|
||||
src={media.get('url')}
|
||||
currentTime={options.startTime}
|
||||
|
|
|
@ -105,6 +105,7 @@ class Video extends PureComponent {
|
|||
static propTypes = {
|
||||
preview: PropTypes.string,
|
||||
frameRate: PropTypes.string,
|
||||
aspectRatio: PropTypes.string,
|
||||
src: PropTypes.string.isRequired,
|
||||
alt: PropTypes.string,
|
||||
lang: PropTypes.string,
|
||||
|
@ -113,7 +114,6 @@ class Video extends PureComponent {
|
|||
onOpenVideo: PropTypes.func,
|
||||
onCloseVideo: PropTypes.func,
|
||||
detailed: PropTypes.bool,
|
||||
inline: PropTypes.bool,
|
||||
editable: PropTypes.bool,
|
||||
alwaysVisible: PropTypes.bool,
|
||||
visible: PropTypes.bool,
|
||||
|
@ -500,14 +500,9 @@ class Video extends PureComponent {
|
|||
}
|
||||
|
||||
render () {
|
||||
const { preview, src, inline, onOpenVideo, onCloseVideo, intl, alt, lang, detailed, sensitive, editable, blurhash, autoFocus } = this.props;
|
||||
const { preview, src, aspectRatio, onOpenVideo, onCloseVideo, intl, alt, lang, detailed, sensitive, editable, blurhash, autoFocus } = this.props;
|
||||
const { currentTime, duration, volume, buffer, dragging, paused, fullscreen, hovered, muted, revealed } = this.state;
|
||||
const progress = Math.min((currentTime / duration) * 100, 100);
|
||||
const playerStyle = {};
|
||||
|
||||
if (inline) {
|
||||
playerStyle.aspectRatio = '16 / 9';
|
||||
}
|
||||
|
||||
let preload;
|
||||
|
||||
|
@ -527,95 +522,101 @@ class Video extends PureComponent {
|
|||
warning = <FormattedMessage id='status.media_hidden' defaultMessage='Media hidden' />;
|
||||
}
|
||||
|
||||
// The outer wrapper is necessary to avoid reflowing the layout when going into full screen
|
||||
return (
|
||||
<div
|
||||
role='menuitem'
|
||||
className={classNames('video-player', { inactive: !revealed, detailed, inline: inline && !fullscreen, fullscreen, editable })}
|
||||
style={playerStyle}
|
||||
ref={this.setPlayerRef}
|
||||
onMouseEnter={this.handleMouseEnter}
|
||||
onMouseLeave={this.handleMouseLeave}
|
||||
onClick={this.handleClickRoot}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
tabIndex={0}
|
||||
>
|
||||
<Blurhash
|
||||
hash={blurhash}
|
||||
className={classNames('media-gallery__preview', {
|
||||
'media-gallery__preview--hidden': revealed,
|
||||
})}
|
||||
dummy={!useBlurhash}
|
||||
/>
|
||||
|
||||
{(revealed || editable) && <video
|
||||
ref={this.setVideoRef}
|
||||
src={src}
|
||||
poster={preview}
|
||||
preload={preload}
|
||||
role='button'
|
||||
<div style={{ aspectRatio }}>
|
||||
<div
|
||||
role='menuitem'
|
||||
className={classNames('video-player', { inactive: !revealed, detailed, fullscreen, editable })}
|
||||
style={{ aspectRatio }}
|
||||
ref={this.setPlayerRef}
|
||||
onMouseEnter={this.handleMouseEnter}
|
||||
onMouseLeave={this.handleMouseLeave}
|
||||
onClick={this.handleClickRoot}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
tabIndex={0}
|
||||
aria-label={alt}
|
||||
title={alt}
|
||||
lang={lang}
|
||||
volume={volume}
|
||||
onClick={this.togglePlay}
|
||||
onKeyDown={this.handleVideoKeyDown}
|
||||
onPlay={this.handlePlay}
|
||||
onPause={this.handlePause}
|
||||
onLoadedData={this.handleLoadedData}
|
||||
onProgress={this.handleProgress}
|
||||
onVolumeChange={this.handleVolumeChange}
|
||||
style={{ ...playerStyle, width: '100%' }}
|
||||
/>}
|
||||
>
|
||||
<Blurhash
|
||||
hash={blurhash}
|
||||
className={classNames('media-gallery__preview', {
|
||||
'media-gallery__preview--hidden': revealed,
|
||||
})}
|
||||
dummy={!useBlurhash}
|
||||
/>
|
||||
|
||||
<div className={classNames('spoiler-button', { 'spoiler-button--hidden': revealed || editable })}>
|
||||
<button type='button' className='spoiler-button__overlay' onClick={this.toggleReveal}>
|
||||
<span className='spoiler-button__overlay__label'>{warning}</span>
|
||||
</button>
|
||||
</div>
|
||||
{(revealed || editable) && <video
|
||||
ref={this.setVideoRef}
|
||||
src={src}
|
||||
poster={preview}
|
||||
preload={preload}
|
||||
role='button'
|
||||
tabIndex={0}
|
||||
aria-label={alt}
|
||||
title={alt}
|
||||
lang={lang}
|
||||
volume={volume}
|
||||
onClick={this.togglePlay}
|
||||
onKeyDown={this.handleVideoKeyDown}
|
||||
onPlay={this.handlePlay}
|
||||
onPause={this.handlePause}
|
||||
onLoadedData={this.handleLoadedData}
|
||||
onProgress={this.handleProgress}
|
||||
onVolumeChange={this.handleVolumeChange}
|
||||
style={{ width: '100%' }}
|
||||
/>}
|
||||
|
||||
<div className={classNames('video-player__controls', { active: paused || hovered })}>
|
||||
<div className='video-player__seek' onMouseDown={this.handleMouseDown} ref={this.setSeekRef}>
|
||||
<div className='video-player__seek__buffer' style={{ width: `${buffer}%` }} />
|
||||
<div className='video-player__seek__progress' style={{ width: `${progress}%` }} />
|
||||
|
||||
<span
|
||||
className={classNames('video-player__seek__handle', { active: dragging })}
|
||||
tabIndex={0}
|
||||
style={{ left: `${progress}%` }}
|
||||
onKeyDown={this.handleVideoKeyDown}
|
||||
/>
|
||||
<div className={classNames('spoiler-button', { 'spoiler-button--hidden': revealed || editable })}>
|
||||
<button type='button' className='spoiler-button__overlay' onClick={this.toggleReveal}>
|
||||
<span className='spoiler-button__overlay__label'>
|
||||
{warning}
|
||||
<span className='spoiler-button__overlay__action'><FormattedMessage id='status.media.show' defaultMessage='Click to show' /></span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className='video-player__buttons-bar'>
|
||||
<div className='video-player__buttons left'>
|
||||
<button type='button' title={intl.formatMessage(paused ? messages.play : messages.pause)} aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} className='player-button' onClick={this.togglePlay} autoFocus={autoFocus}><Icon id={paused ? 'play' : 'pause'} fixedWidth /></button>
|
||||
<button type='button' title={intl.formatMessage(muted ? messages.unmute : messages.mute)} aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} className='player-button' onClick={this.toggleMute}><Icon id={muted ? 'volume-off' : 'volume-up'} fixedWidth /></button>
|
||||
<div className={classNames('video-player__controls', { active: paused || hovered })}>
|
||||
<div className='video-player__seek' onMouseDown={this.handleMouseDown} ref={this.setSeekRef}>
|
||||
<div className='video-player__seek__buffer' style={{ width: `${buffer}%` }} />
|
||||
<div className='video-player__seek__progress' style={{ width: `${progress}%` }} />
|
||||
|
||||
<div className={classNames('video-player__volume', { active: this.state.hovered })} onMouseDown={this.handleVolumeMouseDown} ref={this.setVolumeRef}>
|
||||
<div className='video-player__volume__current' style={{ width: `${volume * 100}%` }} />
|
||||
|
||||
<span
|
||||
className={classNames('video-player__volume__handle')}
|
||||
tabIndex={0}
|
||||
style={{ left: `${volume * 100}%` }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{(detailed || fullscreen) && (
|
||||
<span className='video-player__time'>
|
||||
<span className='video-player__time-current'>{formatTime(Math.floor(currentTime))}</span>
|
||||
<span className='video-player__time-sep'>/</span>
|
||||
<span className='video-player__time-total'>{formatTime(Math.floor(duration))}</span>
|
||||
</span>
|
||||
)}
|
||||
<span
|
||||
className={classNames('video-player__seek__handle', { active: dragging })}
|
||||
tabIndex={0}
|
||||
style={{ left: `${progress}%` }}
|
||||
onKeyDown={this.handleVideoKeyDown}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='video-player__buttons right'>
|
||||
{(!onCloseVideo && !editable && !fullscreen && !this.props.alwaysVisible) && <button type='button' title={intl.formatMessage(messages.hide)} aria-label={intl.formatMessage(messages.hide)} className='player-button' onClick={this.toggleReveal}><Icon id='eye-slash' fixedWidth /></button>}
|
||||
{(!fullscreen && onOpenVideo) && <button type='button' title={intl.formatMessage(messages.expand)} aria-label={intl.formatMessage(messages.expand)} className='player-button' onClick={this.handleOpenVideo}><Icon id='expand' fixedWidth /></button>}
|
||||
{onCloseVideo && <button type='button' title={intl.formatMessage(messages.close)} aria-label={intl.formatMessage(messages.close)} className='player-button' onClick={this.handleCloseVideo}><Icon id='compress' fixedWidth /></button>}
|
||||
<button type='button' title={intl.formatMessage(fullscreen ? messages.exit_fullscreen : messages.fullscreen)} aria-label={intl.formatMessage(fullscreen ? messages.exit_fullscreen : messages.fullscreen)} className='player-button' onClick={this.toggleFullscreen}><Icon id={fullscreen ? 'compress' : 'arrows-alt'} fixedWidth /></button>
|
||||
<div className='video-player__buttons-bar'>
|
||||
<div className='video-player__buttons left'>
|
||||
<button type='button' title={intl.formatMessage(paused ? messages.play : messages.pause)} aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} className='player-button' onClick={this.togglePlay} autoFocus={autoFocus}><Icon id={paused ? 'play' : 'pause'} fixedWidth /></button>
|
||||
<button type='button' title={intl.formatMessage(muted ? messages.unmute : messages.mute)} aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} className='player-button' onClick={this.toggleMute}><Icon id={muted ? 'volume-off' : 'volume-up'} fixedWidth /></button>
|
||||
|
||||
<div className={classNames('video-player__volume', { active: this.state.hovered })} onMouseDown={this.handleVolumeMouseDown} ref={this.setVolumeRef}>
|
||||
<div className='video-player__volume__current' style={{ width: `${volume * 100}%` }} />
|
||||
|
||||
<span
|
||||
className={classNames('video-player__volume__handle')}
|
||||
tabIndex={0}
|
||||
style={{ left: `${volume * 100}%` }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{(detailed || fullscreen) && (
|
||||
<span className='video-player__time'>
|
||||
<span className='video-player__time-current'>{formatTime(Math.floor(currentTime))}</span>
|
||||
<span className='video-player__time-sep'>/</span>
|
||||
<span className='video-player__time-total'>{formatTime(Math.floor(duration))}</span>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className='video-player__buttons right'>
|
||||
{(!onCloseVideo && !editable && !fullscreen && !this.props.alwaysVisible) && <button type='button' title={intl.formatMessage(messages.hide)} aria-label={intl.formatMessage(messages.hide)} className='player-button' onClick={this.toggleReveal}><Icon id='eye-slash' fixedWidth /></button>}
|
||||
{(!fullscreen && onOpenVideo) && <button type='button' title={intl.formatMessage(messages.expand)} aria-label={intl.formatMessage(messages.expand)} className='player-button' onClick={this.handleOpenVideo}><Icon id='expand' fixedWidth /></button>}
|
||||
{onCloseVideo && <button type='button' title={intl.formatMessage(messages.close)} aria-label={intl.formatMessage(messages.close)} className='player-button' onClick={this.handleCloseVideo}><Icon id='compress' fixedWidth /></button>}
|
||||
<button type='button' title={intl.formatMessage(fullscreen ? messages.exit_fullscreen : messages.fullscreen)} aria-label={intl.formatMessage(fullscreen ? messages.exit_fullscreen : messages.fullscreen)} className='player-button' onClick={this.toggleFullscreen}><Icon id={fullscreen ? 'compress' : 'arrows-alt'} fixedWidth /></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -51,7 +51,6 @@
|
|||
* @property {boolean} activity_api_enabled
|
||||
* @property {string} admin
|
||||
* @property {boolean=} boost_modal
|
||||
* @property {boolean} crop_images
|
||||
* @property {boolean=} delete_modal
|
||||
* @property {boolean=} disable_swiping
|
||||
* @property {string=} disabled_account_id
|
||||
|
@ -112,7 +111,6 @@ const getMeta = (prop) => initialState?.meta && initialState.meta[prop];
|
|||
export const activityApiEnabled = getMeta('activity_api_enabled');
|
||||
export const autoPlayGif = getMeta('auto_play_gif');
|
||||
export const boostModal = getMeta('boost_modal');
|
||||
export const cropImages = getMeta('crop_images');
|
||||
export const deleteModal = getMeta('delete_modal');
|
||||
export const disableSwiping = getMeta('disable_swiping');
|
||||
export const disabledAccountId = getMeta('disabled_account_id');
|
||||
|
|
|
@ -363,6 +363,7 @@
|
|||
"lightbox.previous": "Previous",
|
||||
"limited_account_hint.action": "Show profile anyway",
|
||||
"limited_account_hint.title": "This profile has been hidden by the moderators of {domain}.",
|
||||
"link_preview.author": "By {name}",
|
||||
"lists.account.add": "Add to list",
|
||||
"lists.account.remove": "Remove from list",
|
||||
"lists.delete": "Delete list",
|
||||
|
|
|
@ -24,13 +24,16 @@ html {
|
|||
.column > .scrollable,
|
||||
.getting-started,
|
||||
.column-inline-form,
|
||||
.error-column,
|
||||
.regeneration-indicator {
|
||||
background: $white;
|
||||
border: 1px solid lighten($ui-base-color, 8%);
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
.error-column {
|
||||
border: 1px solid lighten($ui-base-color, 8%);
|
||||
}
|
||||
|
||||
.column > .scrollable.about {
|
||||
border-top: 1px solid lighten($ui-base-color, 8%);
|
||||
}
|
||||
|
@ -77,6 +80,10 @@ html {
|
|||
background: $white;
|
||||
}
|
||||
|
||||
.column-header {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.column-header__button.active {
|
||||
color: $ui-highlight-color;
|
||||
|
||||
|
@ -414,7 +421,7 @@ html {
|
|||
.column-header__collapsible-inner {
|
||||
background: darken($ui-base-color, 4%);
|
||||
border: 1px solid lighten($ui-base-color, 8%);
|
||||
border-top: 0;
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.dashboard__quick-access,
|
||||
|
|
|
@ -5,7 +5,7 @@ $white: #ffffff;
|
|||
$classic-base-color: #282c37;
|
||||
$classic-primary-color: #9baec8;
|
||||
$classic-secondary-color: #d9e1e8;
|
||||
$classic-highlight-color: #6364ff;
|
||||
$classic-highlight-color: #858afa;
|
||||
|
||||
$blurple-600: #563acc; // Iris
|
||||
$blurple-500: #6364ff; // Brand purple
|
||||
|
|
|
@ -175,6 +175,10 @@ a {
|
|||
button {
|
||||
font-family: inherit;
|
||||
cursor: pointer;
|
||||
|
||||
&:focus:not(:focus-visible) {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
.app-holder {
|
||||
|
|
|
@ -252,13 +252,14 @@
|
|||
|
||||
&.overlayed {
|
||||
box-sizing: content-box;
|
||||
background: rgba($base-overlay-background, 0.6);
|
||||
color: rgba($primary-text-color, 0.7);
|
||||
background: rgba($black, 0.65);
|
||||
backdrop-filter: blur(10px) saturate(180%) contrast(75%) brightness(70%);
|
||||
color: rgba($white, 0.7);
|
||||
border-radius: 4px;
|
||||
padding: 2px;
|
||||
|
||||
&:hover {
|
||||
background: rgba($base-overlay-background, 0.9);
|
||||
background: rgba($black, 0.9);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1352,6 +1353,10 @@ body > [data-popper-placement] {
|
|||
}
|
||||
}
|
||||
|
||||
.scrollable > div:first-child .detailed-status {
|
||||
border-top: 0;
|
||||
}
|
||||
|
||||
.detailed-status__meta {
|
||||
margin-top: 16px;
|
||||
color: $dark-text-color;
|
||||
|
@ -3504,12 +3509,10 @@ button.icon-button.active i.fa-retweet {
|
|||
}
|
||||
|
||||
.status-card {
|
||||
display: block;
|
||||
position: relative;
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
border: 1px solid lighten($ui-base-color, 8%);
|
||||
border-radius: 4px;
|
||||
color: $dark-text-color;
|
||||
color: $darker-text-color;
|
||||
margin-top: 14px;
|
||||
text-decoration: none;
|
||||
overflow: hidden;
|
||||
|
@ -3563,8 +3566,29 @@ button.icon-button.active i.fa-retweet {
|
|||
a.status-card {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background: lighten($ui-base-color, 8%);
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
.status-card__title,
|
||||
.status-card__host,
|
||||
.status-card__author {
|
||||
color: $highlight-text-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.status-card a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
.status-card__title,
|
||||
.status-card__host,
|
||||
.status-card__author {
|
||||
color: $highlight-text-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3590,42 +3614,42 @@ a.status-card {
|
|||
|
||||
.status-card__title {
|
||||
display: block;
|
||||
font-weight: 500;
|
||||
margin-bottom: 5px;
|
||||
color: $darker-text-color;
|
||||
font-weight: 700;
|
||||
font-size: 19px;
|
||||
line-height: 24px;
|
||||
color: $primary-text-color;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.status-card__content {
|
||||
flex: 1 1 auto;
|
||||
overflow: hidden;
|
||||
padding: 14px 14px 14px 8px;
|
||||
}
|
||||
|
||||
.status-card__description {
|
||||
color: $darker-text-color;
|
||||
overflow: hidden;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
padding: 15px 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.status-card__host {
|
||||
display: block;
|
||||
margin-top: 5px;
|
||||
font-size: 13px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 14px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.status-card__author {
|
||||
display: block;
|
||||
margin-top: 8px;
|
||||
font-size: 14px;
|
||||
color: $primary-text-color;
|
||||
|
||||
strong {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.status-card__image {
|
||||
flex: 0 0 100px;
|
||||
width: 100%;
|
||||
background: lighten($ui-base-color, 8%);
|
||||
position: relative;
|
||||
border-radius: 8px;
|
||||
|
||||
& > .fa {
|
||||
font-size: 21px;
|
||||
|
@ -3637,50 +3661,8 @@ a.status-card {
|
|||
}
|
||||
}
|
||||
|
||||
.status-card.horizontal {
|
||||
display: block;
|
||||
|
||||
.status-card__image {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.status-card__image-image,
|
||||
.status-card__image-preview {
|
||||
border-radius: 4px 4px 0 0;
|
||||
}
|
||||
|
||||
.status-card__title {
|
||||
white-space: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.status-card.compact {
|
||||
border-color: lighten($ui-base-color, 4%);
|
||||
|
||||
&.interactive {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.status-card__content {
|
||||
padding: 8px;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.status-card__title {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.status-card__image {
|
||||
flex: 0 0 60px;
|
||||
}
|
||||
}
|
||||
|
||||
a.status-card.compact:hover {
|
||||
background-color: lighten($ui-base-color, 4%);
|
||||
}
|
||||
|
||||
.status-card__image-image {
|
||||
border-radius: 4px 0 0 4px;
|
||||
border-radius: 8px;
|
||||
display: block;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
|
@ -3691,7 +3673,7 @@ a.status-card.compact:hover {
|
|||
}
|
||||
|
||||
.status-card__image-preview {
|
||||
border-radius: 4px 0 0 4px;
|
||||
border-radius: 8px;
|
||||
display: block;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
|
@ -4204,6 +4186,7 @@ a.status-card.compact:hover {
|
|||
margin: 0;
|
||||
border: 0;
|
||||
border-radius: 4px;
|
||||
color: $white;
|
||||
|
||||
&__label {
|
||||
display: flex;
|
||||
|
@ -4211,7 +4194,6 @@ a.status-card.compact:hover {
|
|||
justify-content: center;
|
||||
gap: 8px;
|
||||
flex-direction: column;
|
||||
color: $primary-text-color;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
@ -5033,7 +5015,6 @@ a.status-card.compact:hover {
|
|||
position: absolute;
|
||||
top: 16px;
|
||||
inset-inline-end: 10px;
|
||||
z-index: 2;
|
||||
display: inline-block;
|
||||
opacity: 0;
|
||||
transition: all 100ms linear;
|
||||
|
@ -5172,9 +5153,9 @@ a.status-card.compact:hover {
|
|||
display: flex;
|
||||
}
|
||||
|
||||
.video-modal__container {
|
||||
.video-modal .video-player {
|
||||
max-height: 80vh;
|
||||
max-width: 100vw;
|
||||
max-height: 100vh;
|
||||
}
|
||||
|
||||
.audio-modal__container {
|
||||
|
@ -6192,7 +6173,7 @@ a.status-card.compact:hover {
|
|||
box-sizing: border-box;
|
||||
margin-top: 8px;
|
||||
overflow: hidden;
|
||||
border-radius: 4px;
|
||||
border-radius: 8px;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
min-height: 64px;
|
||||
|
@ -6207,7 +6188,7 @@ a.status-card.compact:hover {
|
|||
box-sizing: border-box;
|
||||
display: block;
|
||||
position: relative;
|
||||
border-radius: 4px;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
|
||||
&--tall {
|
||||
|
@ -6293,7 +6274,7 @@ a.status-card.compact:hover {
|
|||
box-sizing: border-box;
|
||||
position: relative;
|
||||
background: darken($ui-base-color, 8%);
|
||||
border-radius: 4px;
|
||||
border-radius: 8px;
|
||||
padding-bottom: 44px;
|
||||
width: 100%;
|
||||
|
||||
|
@ -6360,7 +6341,7 @@ a.status-card.compact:hover {
|
|||
position: relative;
|
||||
background: $base-shadow-color;
|
||||
max-width: 100%;
|
||||
border-radius: 4px;
|
||||
border-radius: 8px;
|
||||
box-sizing: border-box;
|
||||
color: $white;
|
||||
display: flex;
|
||||
|
@ -6377,8 +6358,6 @@ a.status-card.compact:hover {
|
|||
|
||||
video {
|
||||
display: block;
|
||||
max-width: 100vw;
|
||||
max-height: 80vh;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
|
@ -6386,22 +6365,15 @@ a.status-card.compact:hover {
|
|||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
margin: 0;
|
||||
aspect-ratio: auto !important;
|
||||
|
||||
video {
|
||||
max-width: 100% !important;
|
||||
max-height: 100% !important;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
outline: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.inline {
|
||||
video {
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
&__controls {
|
||||
position: absolute;
|
||||
direction: ltr;
|
||||
|
@ -8163,6 +8135,7 @@ noscript {
|
|||
.search__input {
|
||||
border: 1px solid lighten($ui-base-color, 8%);
|
||||
padding: 10px;
|
||||
padding-inline-end: 28px;
|
||||
}
|
||||
|
||||
.search__popout {
|
||||
|
@ -8191,8 +8164,9 @@ noscript {
|
|||
align-items: center;
|
||||
color: $primary-text-color;
|
||||
text-decoration: none;
|
||||
padding: 15px 0;
|
||||
padding: 15px;
|
||||
border-bottom: 1px solid lighten($ui-base-color, 8%);
|
||||
gap: 15px;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: 0;
|
||||
|
@ -8201,33 +8175,40 @@ noscript {
|
|||
&:hover,
|
||||
&:active,
|
||||
&:focus {
|
||||
background-color: lighten($ui-base-color, 4%);
|
||||
color: $highlight-text-color;
|
||||
|
||||
.story__details__publisher,
|
||||
.story__details__shared {
|
||||
color: $highlight-text-color;
|
||||
}
|
||||
}
|
||||
|
||||
&__details {
|
||||
padding: 0 15px;
|
||||
flex: 1 1 auto;
|
||||
|
||||
&__publisher {
|
||||
color: $darker-text-color;
|
||||
margin-bottom: 4px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: 19px;
|
||||
line-height: 24px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 4px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
&__shared {
|
||||
color: $darker-text-color;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
&__thumbnail {
|
||||
flex: 0 0 auto;
|
||||
margin: 0 15px;
|
||||
position: relative;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
|
@ -8238,7 +8219,7 @@ noscript {
|
|||
}
|
||||
|
||||
img {
|
||||
border-radius: 4px;
|
||||
border-radius: 8px;
|
||||
display: block;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
|
@ -8247,7 +8228,7 @@ noscript {
|
|||
}
|
||||
|
||||
&__preview {
|
||||
border-radius: 4px;
|
||||
border-radius: 8px;
|
||||
display: block;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
|
@ -8263,6 +8244,23 @@ noscript {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.expanded {
|
||||
flex-direction: column;
|
||||
|
||||
.story__thumbnail {
|
||||
order: 1;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
aspect-ratio: 1.91 / 1;
|
||||
}
|
||||
|
||||
.story__details {
|
||||
order: 2;
|
||||
width: 100%;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.server-banner {
|
||||
|
|
|
@ -121,11 +121,6 @@
|
|||
border-radius: 4px;
|
||||
}
|
||||
|
||||
&.active {
|
||||
border-color: $valid-value-color;
|
||||
background: $valid-value-color;
|
||||
}
|
||||
|
||||
&:active,
|
||||
&:focus,
|
||||
&:hover {
|
||||
|
@ -133,6 +128,11 @@
|
|||
border-width: 4px;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: $valid-value-color;
|
||||
border-color: $valid-value-color;
|
||||
}
|
||||
|
||||
&::-moz-focus-inner {
|
||||
outline: 0 !important;
|
||||
border: 0;
|
||||
|
@ -216,6 +216,14 @@
|
|||
padding: 10px;
|
||||
}
|
||||
|
||||
.poll__input {
|
||||
&:active,
|
||||
&:focus,
|
||||
&:hover {
|
||||
border-color: $ui-button-focus-background-color;
|
||||
}
|
||||
}
|
||||
|
||||
.poll__footer {
|
||||
border-top: 1px solid darken($simple-background-color, 8%);
|
||||
padding: 10px;
|
||||
|
@ -241,6 +249,14 @@
|
|||
color: $action-button-color;
|
||||
border-color: $action-button-color;
|
||||
margin-inline-end: 5px;
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&.active {
|
||||
border-color: $action-button-color;
|
||||
background-color: $action-button-color;
|
||||
color: $ui-button-color;
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
|
|
|
@ -124,6 +124,7 @@ class LinkDetailsExtractor
|
|||
author_url: author_url || '',
|
||||
embed_url: embed_url || '',
|
||||
language: language,
|
||||
published_at: published_at.presence,
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -159,6 +160,10 @@ class LinkDetailsExtractor
|
|||
html_entities.decode(structured_data&.description || opengraph_tag('og:description') || meta_tag('description'))
|
||||
end
|
||||
|
||||
def published_at
|
||||
structured_data&.date_published || opengraph_tag('article:published_time')
|
||||
end
|
||||
|
||||
def image
|
||||
valid_url_or_nil(opengraph_tag('og:image'))
|
||||
end
|
||||
|
|
|
@ -103,10 +103,6 @@ module HasUserSettings
|
|||
settings['web.trends']
|
||||
end
|
||||
|
||||
def setting_crop_images
|
||||
settings['web.crop_images']
|
||||
end
|
||||
|
||||
def setting_disable_swiping
|
||||
settings['web.disable_swiping']
|
||||
end
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
# max_score_at :datetime
|
||||
# trendable :boolean
|
||||
# link_type :integer
|
||||
# published_at :datetime
|
||||
#
|
||||
|
||||
class PreviewCard < ApplicationRecord
|
||||
|
|
|
@ -58,7 +58,8 @@ class Report < ApplicationRecord
|
|||
|
||||
before_validation :set_uri, only: :create
|
||||
|
||||
after_create_commit :trigger_webhooks
|
||||
after_create_commit :trigger_create_webhooks
|
||||
after_update_commit :trigger_update_webhooks
|
||||
|
||||
def object_type
|
||||
:flag
|
||||
|
@ -155,7 +156,11 @@ class Report < ApplicationRecord
|
|||
errors.add(:rule_ids, I18n.t('reports.errors.invalid_rules')) unless rules.size == rule_ids&.size
|
||||
end
|
||||
|
||||
def trigger_webhooks
|
||||
def trigger_create_webhooks
|
||||
TriggerWebhookWorker.perform_async('report.created', 'Report', id)
|
||||
end
|
||||
|
||||
def trigger_update_webhooks
|
||||
TriggerWebhookWorker.perform_async('report.updated', 'Report', id)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,7 +20,6 @@ class UserSettings
|
|||
setting :hide_followers_count, default: false
|
||||
|
||||
namespace :web do
|
||||
setting :crop_images, default: true
|
||||
setting :advanced_layout, default: false
|
||||
setting :trends, default: true
|
||||
setting :use_blurhash, default: true
|
||||
|
|
|
@ -20,6 +20,7 @@ class Webhook < ApplicationRecord
|
|||
account.created
|
||||
account.updated
|
||||
report.created
|
||||
report.updated
|
||||
status.created
|
||||
status.updated
|
||||
).freeze
|
||||
|
@ -59,7 +60,7 @@ class Webhook < ApplicationRecord
|
|||
case event
|
||||
when 'account.approved', 'account.created', 'account.updated'
|
||||
:manage_users
|
||||
when 'report.created'
|
||||
when 'report.created', 'report.updated'
|
||||
:manage_reports
|
||||
when 'status.created', 'status.updated'
|
||||
:view_devops
|
||||
|
|
|
@ -65,13 +65,11 @@ class InitialStateSerializer < ActiveModel::Serializer
|
|||
store[:default_content_type] = object.current_account.user.setting_default_content_type
|
||||
store[:system_emoji_font] = object.current_account.user.setting_system_emoji_font
|
||||
store[:show_trends] = Setting.trends && object.current_account.user.setting_trends
|
||||
store[:crop_images] = object.current_account.user.setting_crop_images
|
||||
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[:crop_images] = Setting.crop_images
|
||||
end
|
||||
|
||||
store[:disabled_account_id] = object.disabled_account.id.to_s if object.disabled_account
|
||||
|
|
|
@ -6,7 +6,7 @@ class REST::PreviewCardSerializer < ActiveModel::Serializer
|
|||
attributes :url, :title, :description, :language, :type,
|
||||
:author_name, :author_url, :provider_name,
|
||||
:provider_url, :html, :width, :height,
|
||||
:image, :embed_url, :blurhash
|
||||
:image, :embed_url, :blurhash, :published_at
|
||||
|
||||
def image
|
||||
object.image? ? full_asset_url(object.image.url(:original)) : nil
|
||||
|
|
|
@ -37,11 +37,6 @@
|
|||
= ff.input :'web.use_system_font', wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_system_font_ui')
|
||||
= ff.input :'web.use_system_emoji_font', wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_system_emoji_font'), glitch_only: true
|
||||
|
||||
%h4= t 'appearance.toot_layout'
|
||||
|
||||
.fields-group
|
||||
= ff.input :'web.crop_images', wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_crop_images')
|
||||
|
||||
%h4= t 'appearance.discovery'
|
||||
|
||||
.fields-group
|
||||
|
|
|
@ -923,7 +923,6 @@ an:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: Totz pueden contribuyir.
|
||||
sensitive_content: Conteniu sensible
|
||||
toot_layout: Disenyo d'as publicacions
|
||||
application_mailer:
|
||||
notification_preferences: Cambiar preferencias de correu electronico
|
||||
salutation: "%{name}:"
|
||||
|
|
|
@ -982,7 +982,6 @@ ar:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: يمكن للجميع المساهمة.
|
||||
sensitive_content: المحتوى الحساس
|
||||
toot_layout: شكل المنشور
|
||||
application_mailer:
|
||||
notification_preferences: تعديل تفضيلات البريد الإلكتروني
|
||||
salutation: "%{name}،"
|
||||
|
|
|
@ -439,7 +439,6 @@ ast:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: tol mundu pue collaborar.
|
||||
sensitive_content: Conteníu sensible
|
||||
toot_layout: Distribución de los artículos
|
||||
application_mailer:
|
||||
notification_preferences: Camudar les preferencies de los mensaxes de corréu electrónicu
|
||||
applications:
|
||||
|
|
|
@ -1009,7 +1009,6 @@ be:
|
|||
guide_link: https://be.crowdin.com/project/mastodon/be
|
||||
guide_link_text: Кожны можа зрабіць унёсак.
|
||||
sensitive_content: Далікатны змест
|
||||
toot_layout: Макет допісу
|
||||
application_mailer:
|
||||
notification_preferences: Змяніць налады эл. пошты
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -973,7 +973,6 @@ bg:
|
|||
guide_link: https://ru.crowdin.com/project/mastodon
|
||||
guide_link_text: Всеки може да участва.
|
||||
sensitive_content: Деликатно съдържание
|
||||
toot_layout: Оформление на публикацията
|
||||
application_mailer:
|
||||
notification_preferences: Промяна на предпочитанията за имейл
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -973,7 +973,6 @@ ca:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: Tothom hi pot contribuir.
|
||||
sensitive_content: Contingut sensible
|
||||
toot_layout: Disseny dels tuts
|
||||
application_mailer:
|
||||
notification_preferences: Canvia les preferències de correu
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -571,7 +571,6 @@ ckb:
|
|||
body: ماستۆدۆن لەلایەن خۆبەخشەوە وەردەگێڕێت.
|
||||
guide_link_text: هەموو کەسێک دەتوانێت بەشداری بکات.
|
||||
sensitive_content: ناوەڕۆکی هەستیار
|
||||
toot_layout: لۆی توت
|
||||
application_mailer:
|
||||
notification_preferences: گۆڕینی پەسەندکراوەکانی ئیمەیڵ
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -537,7 +537,6 @@ co:
|
|||
guide_link: https://fr.crowdin.com/project/mastodon
|
||||
guide_link_text: Tuttu u mondu pò participà.
|
||||
sensitive_content: Cuntinutu sensibile
|
||||
toot_layout: Urganizazione
|
||||
application_mailer:
|
||||
notification_preferences: Cambià e priferenze e-mail
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -997,7 +997,6 @@ cs:
|
|||
guide_link: https://cs.crowdin.com/project/mastodon
|
||||
guide_link_text: Zapojit se může každý.
|
||||
sensitive_content: Citlivý obsah
|
||||
toot_layout: Rozložení příspěvků
|
||||
application_mailer:
|
||||
notification_preferences: Změnit předvolby e-mailů
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -1045,7 +1045,6 @@ cy:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: Gall pawb gyfrannu.
|
||||
sensitive_content: Cynnwys sensitif
|
||||
toot_layout: Cynllun postiad
|
||||
application_mailer:
|
||||
notification_preferences: Newid gosodiadau e-bost
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -973,7 +973,6 @@ da:
|
|||
guide_link: https://da.crowdin.com/project/mastodon
|
||||
guide_link_text: Alle kan bidrage.
|
||||
sensitive_content: Sensitivt indhold
|
||||
toot_layout: Indlægslayout
|
||||
application_mailer:
|
||||
notification_preferences: Skift e-mailpræferencer
|
||||
salutation: "%{name}"
|
||||
|
|
|
@ -973,7 +973,6 @@ de:
|
|||
guide_link: https://de.crowdin.com/project/mastodon/de
|
||||
guide_link_text: Alle können mitmachen und etwas dazu beitragen.
|
||||
sensitive_content: Inhaltswarnung
|
||||
toot_layout: Timeline-Layout
|
||||
application_mailer:
|
||||
notification_preferences: E-Mail-Einstellungen ändern
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -961,7 +961,6 @@ el:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: Μπορεί να συνεισφέρει ο οποιοσδήποτε.
|
||||
sensitive_content: Ευαίσθητο περιεχόμενο
|
||||
toot_layout: Διαρρύθμιση αναρτήσεων
|
||||
application_mailer:
|
||||
notification_preferences: Αλλαγή προτιμήσεων email
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -973,7 +973,6 @@ en-GB:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: Everyone can contribute.
|
||||
sensitive_content: Sensitive content
|
||||
toot_layout: Post layout
|
||||
application_mailer:
|
||||
notification_preferences: Change e-mail preferences
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -973,7 +973,6 @@ en:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: Everyone can contribute.
|
||||
sensitive_content: Sensitive content
|
||||
toot_layout: Post layout
|
||||
application_mailer:
|
||||
notification_preferences: Change e-mail preferences
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -973,7 +973,6 @@ eo:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: Ĉiu povas kontribui.
|
||||
sensitive_content: Tikla enhavo
|
||||
toot_layout: Mesaĝo aranĝo
|
||||
application_mailer:
|
||||
notification_preferences: Ŝanĝi retmesaĝajn preferojn
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -973,7 +973,6 @@ es-AR:
|
|||
guide_link: https://es.crowdin.com/project/mastodon
|
||||
guide_link_text: Todos pueden contribuir.
|
||||
sensitive_content: Contenido sensible
|
||||
toot_layout: Diseño del mensaje
|
||||
application_mailer:
|
||||
notification_preferences: Cambiar configuración de correo electrónico
|
||||
salutation: "%{name}:"
|
||||
|
|
|
@ -973,7 +973,6 @@ es-MX:
|
|||
guide_link: https://es.crowdin.com/project/mastodon
|
||||
guide_link_text: Todos pueden contribuir.
|
||||
sensitive_content: Contenido sensible
|
||||
toot_layout: Diseño de los toots
|
||||
application_mailer:
|
||||
notification_preferences: Cambiar preferencias de correo electrónico
|
||||
salutation: "%{name}:"
|
||||
|
|
|
@ -973,7 +973,6 @@ es:
|
|||
guide_link: https://es.crowdin.com/project/mastodon
|
||||
guide_link_text: Todos pueden contribuir.
|
||||
sensitive_content: Contenido sensible
|
||||
toot_layout: Diseño de las publicaciones
|
||||
application_mailer:
|
||||
notification_preferences: Cambiar preferencias de correo electrónico
|
||||
salutation: "%{name}:"
|
||||
|
|
|
@ -973,7 +973,6 @@ et:
|
|||
guide_link: https://crowdin.com/project/mastodon/et
|
||||
guide_link_text: Panustada võib igaüks!
|
||||
sensitive_content: Tundlik sisu
|
||||
toot_layout: Postituse väljanägemine
|
||||
application_mailer:
|
||||
notification_preferences: Muuda e-kirjade eelistusi
|
||||
salutation: "%{name}!"
|
||||
|
|
|
@ -972,7 +972,6 @@ eu:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: Edonork lagundu dezake.
|
||||
sensitive_content: Eduki hunkigarria
|
||||
toot_layout: Bidalketen diseinua
|
||||
application_mailer:
|
||||
notification_preferences: Aldatu e-mail hobespenak
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -821,7 +821,6 @@ fa:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: همه میتوانند کمک کنند.
|
||||
sensitive_content: محتوای حساس
|
||||
toot_layout: آرایش فرسته
|
||||
application_mailer:
|
||||
notification_preferences: تغییر ترجیحات ایمیل
|
||||
salutation: "%{name}،"
|
||||
|
|
|
@ -973,7 +973,6 @@ fi:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: Kaikki voivat osallistua.
|
||||
sensitive_content: Arkaluonteinen sisältö
|
||||
toot_layout: Viestin asettelu
|
||||
application_mailer:
|
||||
notification_preferences: Muuta sähköpostiasetuksia
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -973,7 +973,6 @@ fo:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: Øll kunnu geva íkast.
|
||||
sensitive_content: Viðkvæmt innihald
|
||||
toot_layout: Uppseting av postum
|
||||
application_mailer:
|
||||
notification_preferences: Broyt teldupostastillingar
|
||||
salutation: "%{name}"
|
||||
|
|
|
@ -973,7 +973,6 @@ fr-QC:
|
|||
guide_link: https://fr.crowdin.com/project/mastodon
|
||||
guide_link_text: Tout le monde peut y contribuer.
|
||||
sensitive_content: Contenu sensible
|
||||
toot_layout: Agencement des messages
|
||||
application_mailer:
|
||||
notification_preferences: Modifier les préférences de courriel
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -973,7 +973,6 @@ fr:
|
|||
guide_link: https://fr.crowdin.com/project/mastodon
|
||||
guide_link_text: Tout le monde peut y contribuer.
|
||||
sensitive_content: Contenu sensible
|
||||
toot_layout: Agencement des messages
|
||||
application_mailer:
|
||||
notification_preferences: Modifier les préférences de courriel
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -973,7 +973,6 @@ fy:
|
|||
guide_link: https://crowdin.com/project/mastodon/fy
|
||||
guide_link_text: Elkenien kin bydrage.
|
||||
sensitive_content: Gefoelige ynhâld
|
||||
toot_layout: Lay-out fan berjochten
|
||||
application_mailer:
|
||||
notification_preferences: E-mailynstellingen wizigje
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -1009,7 +1009,6 @@ gd:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: "’S urrainn do neach sam bith cuideachadh."
|
||||
sensitive_content: Susbaint fhrionasach
|
||||
toot_layout: Co-dhealbhachd nam postaichean
|
||||
application_mailer:
|
||||
notification_preferences: Atharraich roghainnean a’ phuist-d
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -973,7 +973,6 @@ gl:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: Todas podemos contribuír.
|
||||
sensitive_content: Contido sensible
|
||||
toot_layout: Disposición da publicación
|
||||
application_mailer:
|
||||
notification_preferences: Cambiar os axustes de email
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -1009,7 +1009,6 @@ he:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: כולם יכולים לתרום.
|
||||
sensitive_content: תוכן רגיש
|
||||
toot_layout: פריסת הודעה
|
||||
application_mailer:
|
||||
notification_preferences: שינוי העדפות דוא"ל
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -973,7 +973,6 @@ hu:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: Bárki közreműködhet.
|
||||
sensitive_content: Kényes tartalom
|
||||
toot_layout: Bejegyzések elrendezése
|
||||
application_mailer:
|
||||
notification_preferences: E-mail beállítások módosítása
|
||||
salutation: "%{name}!"
|
||||
|
|
|
@ -901,7 +901,6 @@ id:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: Siapa saja bisa berkontribusi.
|
||||
sensitive_content: Konten sensitif
|
||||
toot_layout: Tata letak kiriman
|
||||
application_mailer:
|
||||
notification_preferences: Ubah pilihan email
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -880,7 +880,6 @@ io:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: Omnu povas kontributar.
|
||||
sensitive_content: Sentoza kontenajo
|
||||
toot_layout: Postostrukturo
|
||||
application_mailer:
|
||||
notification_preferences: Chanjez retpostopreferaji
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -975,7 +975,6 @@ is:
|
|||
guide_link: https://crowdin.com/project/mastodon/is
|
||||
guide_link_text: Allir geta tekið þátt.
|
||||
sensitive_content: Viðkvæmt efni
|
||||
toot_layout: Framsetning færslu
|
||||
application_mailer:
|
||||
notification_preferences: Breyta kjörstillingum tölvupósts
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -975,7 +975,6 @@ it:
|
|||
guide_link: https://it.crowdin.com/project/mastodon
|
||||
guide_link_text: Tutti possono contribuire.
|
||||
sensitive_content: Contenuto sensibile
|
||||
toot_layout: Layout dei toot
|
||||
application_mailer:
|
||||
notification_preferences: Cambia preferenze email
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -955,7 +955,6 @@ ja:
|
|||
guide_link: https://ja.crowdin.com/project/mastodon
|
||||
guide_link_text: 誰でも参加することができます。
|
||||
sensitive_content: 閲覧注意コンテンツ
|
||||
toot_layout: 投稿のレイアウト
|
||||
application_mailer:
|
||||
notification_preferences: メール設定の変更
|
||||
salutation: "%{name}さん"
|
||||
|
|
|
@ -320,7 +320,6 @@ kk:
|
|||
confirmation_dialogs: Пікірталас диалогтары
|
||||
discovery: Пікірталас
|
||||
sensitive_content: Нәзік контент
|
||||
toot_layout: Жазба формасы
|
||||
application_mailer:
|
||||
notification_preferences: Change e-mail prеferences
|
||||
settings: 'Change e-mail preferеnces: %{link}'
|
||||
|
|
|
@ -957,7 +957,6 @@ ko:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: 누구나 기여할 수 있습니다.
|
||||
sensitive_content: 민감한 내용
|
||||
toot_layout: 게시물 레이아웃
|
||||
application_mailer:
|
||||
notification_preferences: 메일 설정 변경
|
||||
salutation: "%{name} 님,"
|
||||
|
|
|
@ -920,7 +920,6 @@ ku:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: Herkes dikare beşdar bibe.
|
||||
sensitive_content: Naveroka hestiyarî
|
||||
toot_layout: Xêzkirina şandîya
|
||||
application_mailer:
|
||||
notification_preferences: Sazkariyên e-nameyê biguherîne
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -979,7 +979,6 @@ lv:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: Ikviens var piedalīties.
|
||||
sensitive_content: Sensitīvs saturs
|
||||
toot_layout: Ziņas izskats
|
||||
application_mailer:
|
||||
notification_preferences: Mainīt e-pasta uztādījumus
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -955,7 +955,6 @@ my:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: လူတိုင်းပါဝင်ကူညီနိုင်ပါတယ်။
|
||||
sensitive_content: သတိထားရသော အကြောင်းအရာ
|
||||
toot_layout: ပို့စ်အပြင်အဆင်
|
||||
application_mailer:
|
||||
notification_preferences: အီးမေးလ် သတ်မှတ်ချက်များကို ပြောင်းပါ
|
||||
salutation: "%{name}"
|
||||
|
|
|
@ -973,7 +973,6 @@ nl:
|
|||
guide_link: https://crowdin.com/project/mastodon/nl
|
||||
guide_link_text: Iedereen kan bijdragen.
|
||||
sensitive_content: Gevoelige inhoud
|
||||
toot_layout: Lay-out van berichten
|
||||
application_mailer:
|
||||
notification_preferences: E-mailvoorkeuren wijzigen
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -965,7 +965,6 @@ nn:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: Alle kan bidra.
|
||||
sensitive_content: Ømtolig innhald
|
||||
toot_layout: Tutoppsett
|
||||
application_mailer:
|
||||
notification_preferences: Endr e-post-innstillingane
|
||||
salutation: Hei %{name},
|
||||
|
|
|
@ -914,7 +914,6 @@
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: Alle kan bidra.
|
||||
sensitive_content: Følsomt innhold
|
||||
toot_layout: Innleggsoppsett
|
||||
application_mailer:
|
||||
notification_preferences: Endre E-postinnstillingene
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -459,7 +459,6 @@ oc:
|
|||
body: Mastodon es traduch per de benevòls.
|
||||
guide_link_text: Tot lo monde pòt contribuïr.
|
||||
sensitive_content: Contengut sensible
|
||||
toot_layout: Disposicion del tut
|
||||
application_mailer:
|
||||
notification_preferences: Cambiar las preferéncias de corrièl
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -1009,7 +1009,6 @@ pl:
|
|||
guide_link: https://pl.crowdin.com/project/mastodon
|
||||
guide_link_text: Każdy może wnieść swój wkład.
|
||||
sensitive_content: Wrażliwa zawartość
|
||||
toot_layout: Wygląd wpisów
|
||||
application_mailer:
|
||||
notification_preferences: Zmień ustawienia e-maili
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -973,7 +973,6 @@ pt-BR:
|
|||
guide_link: https://br.crowdin.com/project/mastodon
|
||||
guide_link_text: Todos podem contribuir.
|
||||
sensitive_content: Conteúdo sensível
|
||||
toot_layout: Formato da publicação
|
||||
application_mailer:
|
||||
notification_preferences: Alterar preferências de e-mail
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -973,7 +973,6 @@ pt-PT:
|
|||
guide_link: https://pt.crowdin.com/project/mastodon/
|
||||
guide_link_text: Todos podem contribuir.
|
||||
sensitive_content: Conteúdo problemático
|
||||
toot_layout: Disposição da publicação
|
||||
application_mailer:
|
||||
notification_preferences: Alterar preferências de e-mail
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -408,7 +408,6 @@ ro:
|
|||
localization:
|
||||
guide_link_text: Toată lumea poate contribui.
|
||||
sensitive_content: Conținut sensibil
|
||||
toot_layout: Aspect postare
|
||||
application_mailer:
|
||||
notification_preferences: Modifică preferințe e-mail
|
||||
settings: 'Modifică preferințe e-mail: %{link}'
|
||||
|
|
|
@ -1009,7 +1009,6 @@ ru:
|
|||
guide_link: https://ru.crowdin.com/project/mastodon
|
||||
guide_link_text: Каждый может внести свой вклад.
|
||||
sensitive_content: Содержимое деликатного характера
|
||||
toot_layout: Структура постов
|
||||
application_mailer:
|
||||
notification_preferences: Настроить уведомления можно здесь
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -491,7 +491,6 @@ sc:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: Chie si siat podet contribuire.
|
||||
sensitive_content: Cuntenutu sensìbile
|
||||
toot_layout: Dispositzione de is tuts
|
||||
application_mailer:
|
||||
notification_preferences: Muda is preferèntzias de posta
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -913,7 +913,6 @@ sco:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: Awbody kin contribute.
|
||||
sensitive_content: Sensitive content
|
||||
toot_layout: Post leyoot
|
||||
application_mailer:
|
||||
notification_preferences: Chynge email preferences
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -757,7 +757,6 @@ si:
|
|||
guide_link: https://crowdin.com/project/mastodon
|
||||
guide_link_text: සෑම කෙනෙකුටම දායක විය හැකිය.
|
||||
sensitive_content: සංවේදී අන්තර්ගතය
|
||||
toot_layout: පෝස්ට් පිරිසැලසුම
|
||||
application_mailer:
|
||||
notification_preferences: ඊමේල් මනාප වෙනස් කරන්න
|
||||
salutation: "%{name},"
|
||||
|
|
|
@ -192,7 +192,6 @@ an:
|
|||
setting_always_send_emails: Ninviar siempre notificacions per correu
|
||||
setting_auto_play_gif: Reproducir automaticament los GIFs animaus
|
||||
setting_boost_modal: Amostrar finestra de confirmación antes de retutar
|
||||
setting_crop_images: Retallar a 16x9 las imachens d'as publicacions no expandidas
|
||||
setting_default_language: Idioma de publicación
|
||||
setting_default_privacy: Privacidat de publicacions
|
||||
setting_default_sensitive: Marcar siempre imachens como sensibles
|
||||
|
|
|
@ -200,7 +200,6 @@ ar:
|
|||
setting_always_send_emails: ارسل إشعارات البريد الإلكتروني دائماً
|
||||
setting_auto_play_gif: تشغيل تلقائي لِوَسائط جيف المتحركة
|
||||
setting_boost_modal: إظهار مربع حوار التأكيد قبل إعادة مشاركة أي منشور
|
||||
setting_crop_images: قص الصور في المنشورات غير الموسعة إلى 16x9
|
||||
setting_default_language: لغة النشر
|
||||
setting_default_privacy: خصوصية المنشور
|
||||
setting_default_sensitive: اعتبر الوسائط دائما كمحتوى حساس
|
||||
|
|
|
@ -111,7 +111,6 @@ ast:
|
|||
setting_always_send_emails: Unviar siempres los avisos per corréu electrónicu
|
||||
setting_auto_play_gif: Reproducir automáticamente los GIFs
|
||||
setting_boost_modal: Amosar el diálogu de confirmación enantes de compartir un artículu
|
||||
setting_crop_images: Recortar les imáxenes de los artículos ensin espander a la proporción 16:9
|
||||
setting_default_language: Llingua de los artículos
|
||||
setting_default_privacy: Privacidá de los artículos
|
||||
setting_default_sensitive: Marcar siempres tol conteníu como sensible
|
||||
|
|
|
@ -200,7 +200,6 @@ be:
|
|||
setting_always_send_emails: Заўжды дасылаць для апавяшчэнні эл. пошты
|
||||
setting_auto_play_gif: Аўтапрайграванне анімаваных GIF
|
||||
setting_boost_modal: Паказваць акно пацвярджэння перад пашырэннем
|
||||
setting_crop_images: У неразгорнутых допісах абразаць відарысы да 16:9
|
||||
setting_default_language: Мова допісаў
|
||||
setting_default_privacy: Прыватнасць допісаў
|
||||
setting_default_sensitive: Заўсёды пазначаць кантэнт як далікатны
|
||||
|
|
|
@ -200,7 +200,6 @@ bg:
|
|||
setting_always_send_emails: Все да се пращат известия по имейла
|
||||
setting_auto_play_gif: Самопускащи се анимирани гифчета
|
||||
setting_boost_modal: Показване на прозорец за потвърждение преди подсилване
|
||||
setting_crop_images: Изрязване на образи в неразгънати публикации до 16x9
|
||||
setting_default_language: Език на публикуване
|
||||
setting_default_privacy: Поверителност на публикуване
|
||||
setting_default_sensitive: Все да се бележи мултимедията като деликатна
|
||||
|
|
|
@ -200,7 +200,6 @@ ca:
|
|||
setting_always_send_emails: Envia'm sempre notificacions per correu electrònic
|
||||
setting_auto_play_gif: Reprodueix automàticament els GIF animats
|
||||
setting_boost_modal: Mostra la finestra de confirmació abans d'impulsar
|
||||
setting_crop_images: Retalla les imatges en tuts no ampliats a 16x9
|
||||
setting_default_language: Llengua dels tuts
|
||||
setting_default_privacy: Privacitat dels tuts
|
||||
setting_default_sensitive: Marcar sempre el contingut gràfic com a sensible
|
||||
|
|
|
@ -136,7 +136,6 @@ ckb:
|
|||
setting_aggregate_reblogs: گرووپی توتەکان یەکبخە
|
||||
setting_auto_play_gif: خۆکاربەخشکردنی GIFــەکان
|
||||
setting_boost_modal: پیشاندانی دیالۆگی دووپاتکردنەوە پێش دوبارە توتاندن
|
||||
setting_crop_images: لە تووتی نەکراوە،وینەکان لە ئەندازی ۱٦×۹ ببڕە
|
||||
setting_default_language: زمانی نووسراوەکانتان
|
||||
setting_default_privacy: چوارچێوەی تایبەتێتی ئێوە
|
||||
setting_default_sensitive: هەمیشە نیشانکردنی میدیا وەک هەستیار
|
||||
|
|
|
@ -137,7 +137,6 @@ co:
|
|||
setting_aggregate_reblogs: Gruppà e spartere indè e linee
|
||||
setting_auto_play_gif: Lettura autumatica di i GIF animati
|
||||
setting_boost_modal: Mustrà una cunfirmazione per sparte un statutu
|
||||
setting_crop_images: Riquatrà i ritratti in 16x9 indè i statuti micca selezziunati
|
||||
setting_default_language: Lingua di pubblicazione
|
||||
setting_default_privacy: Cunfidenzialità di i statuti
|
||||
setting_default_sensitive: Sempre cunsiderà media cum’è sensibili
|
||||
|
|
|
@ -195,7 +195,6 @@ cs:
|
|||
setting_always_send_emails: Vždy posílat e-mailová oznámení
|
||||
setting_auto_play_gif: Automaticky přehrávat animace GIF
|
||||
setting_boost_modal: Před boostnutím zobrazovat potvrzovací okno
|
||||
setting_crop_images: Ořezávat obrázky v nerozbalených příspěvcích na 16x9
|
||||
setting_default_language: Jazyk příspěvků
|
||||
setting_default_privacy: Soukromí příspěvků
|
||||
setting_default_sensitive: Vždy označovat média jako citlivá
|
||||
|
|
|
@ -200,7 +200,6 @@ cy:
|
|||
setting_always_send_emails: Anfonwch hysbysiadau e-bost bob amser
|
||||
setting_auto_play_gif: Chwarae GIFs wedi'u hanimeiddio yn awtomatig
|
||||
setting_boost_modal: Dangos deialog cadarnhau cyn rhoi hwb
|
||||
setting_crop_images: Tocio delweddau o fewn postiadau nad ydynt wedi'u hehangu i 16x9
|
||||
setting_default_language: Iaith postio
|
||||
setting_default_privacy: Preifatrwydd cyhoeddi
|
||||
setting_default_sensitive: Marcio cyfryngau fel eu bod yn sensitif bob tro
|
||||
|
|
|
@ -200,7 +200,6 @@ da:
|
|||
setting_always_send_emails: Send altid en e-mailnotifikationer
|
||||
setting_auto_play_gif: Autoafspil animerede GIF'er
|
||||
setting_boost_modal: Vis bekræftelsesdialog inden boosting
|
||||
setting_crop_images: Beskær billeder i ikke-ekspanderede indlæg til 16x9
|
||||
setting_default_language: Sprog for indlæg
|
||||
setting_default_privacy: Fortrolighed for indlæg
|
||||
setting_default_sensitive: Markér altid medier som sensitive
|
||||
|
|
|
@ -200,7 +200,6 @@ de:
|
|||
setting_always_send_emails: Benachrichtigungen immer senden
|
||||
setting_auto_play_gif: Animierte GIFs automatisch abspielen
|
||||
setting_boost_modal: Bestätigungsdialog beim Teilen eines Beitrags anzeigen
|
||||
setting_crop_images: Bilder in nicht ausgeklappten Beiträgen auf 16:9 zuschneiden
|
||||
setting_default_language: Beitragssprache
|
||||
setting_default_privacy: Beitragssichtbarkeit
|
||||
setting_default_sensitive: Eigene Medien immer mit einer Inhaltswarnung versehen
|
||||
|
|
|
@ -195,7 +195,6 @@ el:
|
|||
setting_always_send_emails: Πάντα να αποστέλλονται ειδοποίησεις μέσω email
|
||||
setting_auto_play_gif: Αυτόματη αναπαραγωγή των GIF
|
||||
setting_boost_modal: Επιβεβαίωση πριν την προώθηση
|
||||
setting_crop_images: Περιορισμός των εικόνων σε μη-ανεπτυγμένα τουτ σε αναλογία 16x9
|
||||
setting_default_language: Γλώσσα δημοσιεύσεων
|
||||
setting_default_privacy: Ιδιωτικότητα δημοσιεύσεων
|
||||
setting_default_sensitive: Σημείωση όλων των πολυμέσων ως ευαίσθητου περιεχομένου
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue