Merge branch 'master' into glitch-soc/merge-upstream

No conflicts.
This commit is contained in:
Thibaut Girka
2019-01-19 18:28:37 +01:00
57 changed files with 1103 additions and 444 deletions

View File

@ -4,5 +4,9 @@ export function start() {
require('font-awesome/css/font-awesome.css');
require.context('../images/', true);
Rails.start();
try {
Rails.start();
} catch (e) {
// If called twice
}
};

View File

@ -1,15 +1,17 @@
import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types';
export default class DisplayName extends React.PureComponent {
static propTypes = {
account: ImmutablePropTypes.map.isRequired,
others: ImmutablePropTypes.list,
localDomain: PropTypes.string,
};
render () {
const { account, others } = this.props;
const { account, others, localDomain } = this.props;
const displayNameHtml = { __html: account.get('display_name_html') };
let suffix;
@ -17,7 +19,13 @@ export default class DisplayName extends React.PureComponent {
if (others && others.size > 1) {
suffix = `+${others.size}`;
} else {
suffix = <span className='display-name__account'>@{account.get('acct')}</span>;
let acct = account.get('acct');
if (acct.indexOf('@') === -1 && localDomain) {
acct = `${acct}@${localDomain}`;
}
suffix = <span className='display-name__account'>@{acct}</span>;
}
return (

View File

@ -77,7 +77,7 @@ class Status extends ImmutablePureComponent {
'account',
'muted',
'hidden',
]
];
handleClick = () => {
if (this.props.onClick) {

View File

@ -1,28 +1,32 @@
import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import StatusListContainer from '../../ui/containers/status_list_container';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { expandHashtagTimeline } from '../../../actions/timelines';
import Column from '../../../components/column';
import ColumnHeader from '../../../components/column_header';
import { connectHashtagStream } from '../../../actions/streaming';
import Masonry from 'react-masonry-infinite';
import { List as ImmutableList } from 'immutable';
import DetailedStatusContainer from '../../status/containers/detailed_status_container';
import { debounce } from 'lodash';
import LoadingIndicator from '../../../components/loading_indicator';
export default @connect()
const mapStateToProps = (state, { hashtag }) => ({
statusIds: state.getIn(['timelines', `hashtag:${hashtag}`, 'items'], ImmutableList()),
isLoading: state.getIn(['timelines', `hashtag:${hashtag}`, 'isLoading'], false),
hasMore: state.getIn(['timelines', `hashtag:${hashtag}`, 'hasMore'], false),
});
export default @connect(mapStateToProps)
class HashtagTimeline extends React.PureComponent {
static propTypes = {
dispatch: PropTypes.func.isRequired,
statusIds: ImmutablePropTypes.list.isRequired,
isLoading: PropTypes.bool.isRequired,
hasMore: PropTypes.bool.isRequired,
hashtag: PropTypes.string.isRequired,
};
handleHeaderClick = () => {
this.column.scrollTop();
}
setRef = c => {
this.column = c;
}
componentDidMount () {
const { dispatch, hashtag } = this.props;
@ -37,28 +41,52 @@ class HashtagTimeline extends React.PureComponent {
}
}
handleLoadMore = maxId => {
this.props.dispatch(expandHashtagTimeline(this.props.hashtag, { maxId }));
handleLoadMore = () => {
const maxId = this.props.statusIds.last();
if (maxId) {
this.props.dispatch(expandHashtagTimeline(this.props.hashtag, { maxId }));
}
}
setRef = c => {
this.masonry = c;
}
handleHeightChange = debounce(() => {
if (!this.masonry) {
return;
}
this.masonry.forcePack();
}, 50)
render () {
const { hashtag } = this.props;
const { statusIds, hasMore, isLoading } = this.props;
const sizes = [
{ columns: 1, gutter: 0 },
{ mq: '415px', columns: 1, gutter: 10 },
{ mq: '640px', columns: 2, gutter: 10 },
{ mq: '960px', columns: 3, gutter: 10 },
{ mq: '1255px', columns: 3, gutter: 10 },
];
const loader = (isLoading && statusIds.isEmpty()) ? <LoadingIndicator key={0} /> : undefined;
return (
<Column ref={this.setRef}>
<ColumnHeader
icon='hashtag'
title={hashtag}
onClick={this.handleHeaderClick}
/>
<StatusListContainer
trackScroll={false}
scrollKey='standalone_hashtag_timeline'
timelineId={`hashtag:${hashtag}`}
onLoadMore={this.handleLoadMore}
/>
</Column>
<Masonry ref={this.setRef} className='statuses-grid' hasMore={hasMore} loadMore={this.handleLoadMore} sizes={sizes} loader={loader}>
{statusIds.map(statusId => (
<div className='statuses-grid__item' key={statusId}>
<DetailedStatusContainer
id={statusId}
compact
measureHeight
onHeightChange={this.handleHeightChange}
/>
</div>
)).toArray()}
</Masonry>
);
}

View File

@ -11,6 +11,8 @@ import { FormattedDate, FormattedNumber } from 'react-intl';
import Card from './card';
import ImmutablePureComponent from 'react-immutable-pure-component';
import Video from '../../video';
import scheduleIdleTask from '../../ui/util/schedule_idle_task';
import classNames from 'classnames';
export default class DetailedStatus extends ImmutablePureComponent {
@ -23,10 +25,18 @@ export default class DetailedStatus extends ImmutablePureComponent {
onOpenMedia: PropTypes.func.isRequired,
onOpenVideo: PropTypes.func.isRequired,
onToggleHidden: PropTypes.func.isRequired,
measureHeight: PropTypes.bool,
onHeightChange: PropTypes.func,
domain: PropTypes.string.isRequired,
compact: PropTypes.bool,
};
state = {
height: null,
};
handleAccountClick = (e) => {
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
if (e.button === 0 && !(e.ctrlKey || e.metaKey) && this.context.router) {
e.preventDefault();
this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`);
}
@ -42,13 +52,57 @@ export default class DetailedStatus extends ImmutablePureComponent {
this.props.onToggleHidden(this.props.status);
}
_measureHeight (heightJustChanged) {
if (this.props.measureHeight && this.node) {
scheduleIdleTask(() => this.node && this.setState({ height: Math.ceil(this.node.scrollHeight) + 1 }));
if (this.props.onHeightChange && heightJustChanged) {
this.props.onHeightChange();
}
}
}
setRef = c => {
this.node = c;
this._measureHeight();
}
componentDidUpdate (prevProps, prevState) {
this._measureHeight(prevState.height !== this.state.height);
}
handleModalLink = e => {
e.preventDefault();
let href;
if (e.target.nodeName !== 'A') {
href = e.target.parentNode.href;
} else {
href = e.target.href;
}
window.open(href, 'mastodon-intent', 'width=445,height=600,resizable=no,menubar=no,status=no,scrollbars=yes');
}
render () {
const status = this.props.status.get('reblog') ? this.props.status.get('reblog') : this.props.status;
const outerStyle = { boxSizing: 'border-box' };
const { compact } = this.props;
if (!status) {
return null;
}
let media = '';
let applicationLink = '';
let reblogLink = '';
let reblogIcon = 'retweet';
let favouriteLink = '';
if (this.props.measureHeight) {
outerStyle.height = `${this.state.height}px`;
}
if (status.get('media_attachments').size > 0) {
if (status.get('media_attachments').some(item => item.get('type') === 'unknown')) {
@ -95,35 +149,63 @@ export default class DetailedStatus extends ImmutablePureComponent {
if (status.get('visibility') === 'private') {
reblogLink = <i className={`fa fa-${reblogIcon}`} />;
} else if (this.context.router) {
reblogLink = (
<Link to={`/statuses/${status.get('id')}/reblogs`} className='detailed-status__link'>
<i className={`fa fa-${reblogIcon}`} />
<span className='detailed-status__reblogs'>
<FormattedNumber value={status.get('reblogs_count')} />
</span>
</Link>
);
} else {
reblogLink = (<Link to={`/statuses/${status.get('id')}/reblogs`} className='detailed-status__link'>
<i className={`fa fa-${reblogIcon}`} />
<span className='detailed-status__reblogs'>
<FormattedNumber value={status.get('reblogs_count')} />
</span>
</Link>);
reblogLink = (
<a href={`/interact/${status.get('id')}?type=reblog`} className='detailed-status__link' onClick={this.handleModalLink}>
<i className={`fa fa-${reblogIcon}`} />
<span className='detailed-status__reblogs'>
<FormattedNumber value={status.get('reblogs_count')} />
</span>
</a>
);
}
if (this.context.router) {
favouriteLink = (
<Link to={`/statuses/${status.get('id')}/favourites`} className='detailed-status__link'>
<i className='fa fa-star' />
<span className='detailed-status__favorites'>
<FormattedNumber value={status.get('favourites_count')} />
</span>
</Link>
);
} else {
favouriteLink = (
<a href={`/interact/${status.get('id')}?type=favourite`} className='detailed-status__link' onClick={this.handleModalLink}>
<i className='fa fa-star' />
<span className='detailed-status__favorites'>
<FormattedNumber value={status.get('favourites_count')} />
</span>
</a>
);
}
return (
<div className='detailed-status'>
<a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='detailed-status__display-name'>
<div className='detailed-status__display-avatar'><Avatar account={status.get('account')} size={48} /></div>
<DisplayName account={status.get('account')} />
</a>
<div style={outerStyle}>
<div ref={this.setRef} className={classNames('detailed-status', { compact })}>
<a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='detailed-status__display-name'>
<div className='detailed-status__display-avatar'><Avatar account={status.get('account')} size={48} /></div>
<DisplayName account={status.get('account')} localDomain={this.props.domain} />
</a>
<StatusContent status={status} expanded={!status.get('hidden')} onExpandedToggle={this.handleExpandedToggle} />
<StatusContent status={status} expanded={!status.get('hidden')} onExpandedToggle={this.handleExpandedToggle} />
{media}
{media}
<div className='detailed-status__meta'>
<a className='detailed-status__datetime' href={status.get('url')} target='_blank' rel='noopener'>
<FormattedDate value={new Date(status.get('created_at'))} hour12={false} year='numeric' month='short' day='2-digit' hour='2-digit' minute='2-digit' />
</a>{applicationLink} · {reblogLink} · <Link to={`/statuses/${status.get('id')}/favourites`} className='detailed-status__link'>
<i className='fa fa-star' />
<span className='detailed-status__favorites'>
<FormattedNumber value={status.get('favourites_count')} />
</span>
</Link>
<div className='detailed-status__meta'>
<a className='detailed-status__datetime' href={status.get('url')} target='_blank' rel='noopener'>
<FormattedDate value={new Date(status.get('created_at'))} hour12={false} year='numeric' month='short' day='2-digit' hour='2-digit' minute='2-digit' />
</a>{applicationLink} · {reblogLink} · {favouriteLink}
</div>
</div>
</div>
);

View File

@ -0,0 +1,172 @@
import React from 'react';
import { connect } from 'react-redux';
import DetailedStatus from '../components/detailed_status';
import { makeGetStatus } from '../../../selectors';
import {
replyCompose,
mentionCompose,
directCompose,
} from '../../../actions/compose';
import {
reblog,
favourite,
unreblog,
unfavourite,
pin,
unpin,
} from '../../../actions/interactions';
import { blockAccount } from '../../../actions/accounts';
import {
muteStatus,
unmuteStatus,
deleteStatus,
hideStatus,
revealStatus,
} from '../../../actions/statuses';
import { initMuteModal } from '../../../actions/mutes';
import { initReport } from '../../../actions/reports';
import { openModal } from '../../../actions/modal';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { boostModal, deleteModal } from '../../../initial_state';
import { showAlertForError } from '../../../actions/alerts';
const messages = defineMessages({
deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
deleteMessage: { id: 'confirmations.delete.message', defaultMessage: 'Are you sure you want to delete this status?' },
redraftConfirm: { id: 'confirmations.redraft.confirm', defaultMessage: 'Delete & redraft' },
redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.' },
blockConfirm: { id: 'confirmations.block.confirm', defaultMessage: 'Block' },
replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' },
replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
});
const makeMapStateToProps = () => {
const getStatus = makeGetStatus();
const mapStateToProps = (state, props) => ({
status: getStatus(state, props),
domain: state.getIn(['meta', 'domain']),
});
return mapStateToProps;
};
const mapDispatchToProps = (dispatch, { intl }) => ({
onReply (status, router) {
dispatch((_, getState) => {
let state = getState();
if (state.getIn(['compose', 'text']).trim().length !== 0) {
dispatch(openModal('CONFIRM', {
message: intl.formatMessage(messages.replyMessage),
confirm: intl.formatMessage(messages.replyConfirm),
onConfirm: () => dispatch(replyCompose(status, router)),
}));
} else {
dispatch(replyCompose(status, router));
}
});
},
onModalReblog (status) {
dispatch(reblog(status));
},
onReblog (status, e) {
if (status.get('reblogged')) {
dispatch(unreblog(status));
} else {
if (e.shiftKey || !boostModal) {
this.onModalReblog(status);
} else {
dispatch(openModal('BOOST', { status, onReblog: this.onModalReblog }));
}
}
},
onFavourite (status) {
if (status.get('favourited')) {
dispatch(unfavourite(status));
} else {
dispatch(favourite(status));
}
},
onPin (status) {
if (status.get('pinned')) {
dispatch(unpin(status));
} else {
dispatch(pin(status));
}
},
onEmbed (status) {
dispatch(openModal('EMBED', {
url: status.get('url'),
onError: error => dispatch(showAlertForError(error)),
}));
},
onDelete (status, history, withRedraft = false) {
if (!deleteModal) {
dispatch(deleteStatus(status.get('id'), history, withRedraft));
} else {
dispatch(openModal('CONFIRM', {
message: intl.formatMessage(withRedraft ? messages.redraftMessage : messages.deleteMessage),
confirm: intl.formatMessage(withRedraft ? messages.redraftConfirm : messages.deleteConfirm),
onConfirm: () => dispatch(deleteStatus(status.get('id'), history, withRedraft)),
}));
}
},
onDirect (account, router) {
dispatch(directCompose(account, router));
},
onMention (account, router) {
dispatch(mentionCompose(account, router));
},
onOpenMedia (media, index) {
dispatch(openModal('MEDIA', { media, index }));
},
onOpenVideo (media, time) {
dispatch(openModal('VIDEO', { media, time }));
},
onBlock (account) {
dispatch(openModal('CONFIRM', {
message: <FormattedMessage id='confirmations.block.message' defaultMessage='Are you sure you want to block {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
confirm: intl.formatMessage(messages.blockConfirm),
onConfirm: () => dispatch(blockAccount(account.get('id'))),
}));
},
onReport (status) {
dispatch(initReport(status.get('account'), status));
},
onMute (account) {
dispatch(initMuteModal(account));
},
onMuteConversation (status) {
if (status.get('muted')) {
dispatch(unmuteStatus(status.get('id')));
} else {
dispatch(muteStatus(status.get('id')));
}
},
onToggleHidden (status) {
if (status.get('hidden')) {
dispatch(revealStatus(status.get('id')));
} else {
dispatch(hideStatus(status.get('id')));
}
},
});
export default injectIntl(connect(makeMapStateToProps, mapDispatchToProps)(DetailedStatus));

View File

@ -101,6 +101,7 @@ const makeMapStateToProps = () => {
ancestorsIds,
descendantsIds,
askReplyConfirmation: state.getIn(['compose', 'text']).trim().length !== 0,
domain: state.getIn(['meta', 'domain']),
};
};
@ -123,6 +124,7 @@ class Status extends ImmutablePureComponent {
descendantsIds: ImmutablePropTypes.list,
intl: PropTypes.object.isRequired,
askReplyConfirmation: PropTypes.bool,
domain: PropTypes.string.isRequired,
};
state = {
@ -387,7 +389,7 @@ class Status extends ImmutablePureComponent {
render () {
let ancestors, descendants;
const { shouldUpdateScroll, status, ancestorsIds, descendantsIds, intl } = this.props;
const { shouldUpdateScroll, status, ancestorsIds, descendantsIds, intl, domain } = this.props;
const { fullscreen } = this.state;
if (status === null) {
@ -438,6 +440,7 @@ class Status extends ImmutablePureComponent {
onOpenVideo={this.handleOpenVideo}
onOpenMedia={this.handleOpenMedia}
onToggleHidden={this.handleToggleHidden}
domain={domain}
/>
<ActionBar

View File

@ -33,7 +33,7 @@ const messages = defineMessages({
publish: { id: 'compose_form.publish', defaultMessage: 'Toot' },
});
const shouldHideFAB = path => path.match(/^\/statuses\//);
const shouldHideFAB = path => path.match(/^\/statuses\/|^\/search|^\/getting-started/);
export default @(component => injectIntl(component, { withRef: true }))
class ColumnsArea extends ImmutablePureComponent {

View File

@ -243,6 +243,7 @@ class UI extends React.PureComponent {
}
handleDragOver = (e) => {
if (this.dataTransferIsText(e.dataTransfer)) return false;
e.preventDefault();
e.stopPropagation();
@ -256,6 +257,7 @@ class UI extends React.PureComponent {
}
handleDrop = (e) => {
if (this.dataTransferIsText(e.dataTransfer)) return;
e.preventDefault();
this.setState({ draggingOver: false });
@ -279,6 +281,10 @@ class UI extends React.PureComponent {
this.setState({ draggingOver: false });
}
dataTransferIsText = (dataTransfer) => {
return (dataTransfer && Array.from(dataTransfer.types).includes('text/plain') && dataTransfer.items.length === 1);
}
closeUploadModal = () => {
this.setState({ draggingOver: false });
}

View File

@ -8,7 +8,7 @@
"account.disclaimer_full": "La informació següent pot reflectir incompleta el perfil de l'usuari.",
"account.domain_blocked": "Domini ocult",
"account.edit_profile": "Editar el perfil",
"account.endorse": "Característica del perfil",
"account.endorse": "Recomanar en el teu perfil",
"account.follow": "Segueix",
"account.followers": "Seguidors",
"account.followers.empty": "Encara ningú no segueix aquest usuari.",

View File

@ -84,7 +84,7 @@
"confirmations.block.confirm": "Blocio",
"confirmations.block.message": "Ydych chi'n sicr eich bod eisiau blocio {name}?",
"confirmations.delete.confirm": "Dileu",
"confirmations.delete.message": "Ydych chi'n sicr eich bod eisiau dileu y statws hwn?",
"confirmations.delete.message": "Ydych chi'n sicr eich bod eisiau dileu y tŵt hwn?",
"confirmations.delete_list.confirm": "Dileu",
"confirmations.delete_list.message": "Ydych chi'n sicr eich bod eisiau dileu y rhestr hwn am byth?",
"confirmations.domain_block.confirm": "Cuddio parth cyfan",
@ -92,12 +92,12 @@
"confirmations.mute.confirm": "Tawelu",
"confirmations.mute.message": "Ydych chi'n sicr eich bod am ddistewi {name}?",
"confirmations.redraft.confirm": "Dileu & ailddrafftio",
"confirmations.redraft.message": "Ydych chi'n siwr eich bod eisiau dileu y statws hwn a'i ailddrafftio? Bydd ffefrynnau a bwstiau'n cael ei colli, a bydd ymatebion i'r statws gwreiddiol yn cael eu hamddifadu.",
"confirmations.redraft.message": "Ydych chi'n siwr eich bod eisiau dileu y tŵt hwn a'i ailddrafftio? Bydd ffefrynnau a bwstiau'n cael ei colli, a bydd ymatebion i'r tŵt gwreiddiol yn cael eu hamddifadu.",
"confirmations.reply.confirm": "Ateb",
"confirmations.reply.message": "Bydd ateb nawr yn cymryd lle y neges yr ydych yn cyfansoddi ar hyn o bryd. Ydych chi'n sicr yr ydych am barhau?",
"confirmations.unfollow.confirm": "Dad-ddilynwch",
"confirmations.unfollow.message": "Ydych chi'n sicr eich bod am ddad-ddilyn {name}?",
"embed.instructions": "Mewnblannwch y statws hwn ar eich gwefan drwy gopïo'r côd isod.",
"embed.instructions": "Mewnblannwch y tŵt hwn ar eich gwefan drwy gopïo'r côd isod.",
"embed.preview": "Dyma sut olwg fydd arno:",
"emoji_button.activity": "Gweithgarwch",
"emoji_button.custom": "Unigryw",
@ -169,12 +169,12 @@
"keyboard_shortcuts.back": "i lywio nôl",
"keyboard_shortcuts.blocked": "i agor rhestr defnyddwyr a flociwyd",
"keyboard_shortcuts.boost": "i fŵstio",
"keyboard_shortcuts.column": "i ffocysu statws yn un o'r colofnau",
"keyboard_shortcuts.column": "i ffocysu tŵt yn un o'r colofnau",
"keyboard_shortcuts.compose": "i ffocysu yr ardal cyfansoddi testun",
"keyboard_shortcuts.description": "Disgrifiad",
"keyboard_shortcuts.direct": "i agor colofn negeseuon preifat",
"keyboard_shortcuts.down": "i symud lawr yn y rhestr",
"keyboard_shortcuts.enter": "i agor statws",
"keyboard_shortcuts.enter": "i agor tŵt",
"keyboard_shortcuts.favourite": "i hoffi",
"keyboard_shortcuts.favourites": "i agor rhestr hoffi",
"keyboard_shortcuts.federated": "i agor ffrwd y ffederasiwn",
@ -234,10 +234,10 @@
"navigation_bar.preferences": "Dewisiadau",
"navigation_bar.public_timeline": "Ffrwd y ffederasiwn",
"navigation_bar.security": "Diogelwch",
"notification.favourite": "hoffodd {name} eich statws",
"notification.favourite": "hoffodd {name} eich tŵt",
"notification.follow": "dilynodd {name} chi",
"notification.mention": "Soniodd {name} amdanoch chi",
"notification.reblog": "{name} boosted your status",
"notification.reblog": "Hysbysebodd {name} eich tŵt",
"notifications.clear": "Clirio hysbysiadau",
"notifications.clear_confirmation": "Ydych chi'n sicr eich bod am glirio'ch holl hysbysiadau am byth?",
"notifications.column_settings.alert": "Hysbysiadau bwrdd gwaith",
@ -257,7 +257,7 @@
"notifications.filter.follows": "Yn dilyn",
"notifications.filter.mentions": "Mentions",
"notifications.group": "{count} o hysbysiadau",
"privacy.change": "Addasu preifatrwdd y statws",
"privacy.change": "Addasu preifatrwdd y tŵt",
"privacy.direct.long": "Cyhoeddi i'r defnyddwyr sy'n cael eu crybwyll yn unig",
"privacy.direct.short": "Uniongyrchol",
"privacy.private.long": "Cyhoeddi i ddilynwyr yn unig",
@ -284,7 +284,7 @@
"search_popout.search_format": "Fformat chwilio uwch",
"search_popout.tips.full_text": "Mae testun syml yn dychwelyd tŵtiau yr ydych wedi ysgrifennu, hoffi, wedi'u bŵstio, neu wedi'ch crybwyll ynddynt, ynghyd a chyfateb a enwau defnyddwyr, enwau arddangos ac hashnodau.",
"search_popout.tips.hashtag": "hashnod",
"search_popout.tips.status": "statws",
"search_popout.tips.status": "tŵt",
"search_popout.tips.text": "Mae testun syml yn dychwelyd enwau arddangos, enwau defnyddwyr a hashnodau sy'n cyfateb",
"search_popout.tips.user": "defnyddiwr",
"search_results.accounts": "Pobl",
@ -293,7 +293,7 @@
"search_results.total": "{count, number} {count, plural, one {result} other {results}}",
"standalone.public_title": "Golwg tu fewn...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.admin_status": "Open this tŵt in the moderation interface",
"status.block": "Blocio @{name}",
"status.cancel_reblog_private": "Dadfŵstio",
"status.cannot_reblog": "Ni ellir sbarduno'r tŵt hwn",
@ -309,7 +309,7 @@
"status.more": "Mwy",
"status.mute": "Tawelu @{name}",
"status.mute_conversation": "Tawelu sgwrs",
"status.open": "Ehangu'r statws hwn",
"status.open": "Ehangu'r tŵt hwn",
"status.pin": "Pinio ar y proffil",
"status.pinned": "Pinio tŵt",
"status.read_more": "Darllen mwy",

View File

@ -1950,6 +1950,43 @@
],
"path": "app/javascript/mastodon/features/status/components/action_bar.json"
},
{
"descriptors": [
{
"defaultMessage": "Delete",
"id": "confirmations.delete.confirm"
},
{
"defaultMessage": "Are you sure you want to delete this status?",
"id": "confirmations.delete.message"
},
{
"defaultMessage": "Delete & redraft",
"id": "confirmations.redraft.confirm"
},
{
"defaultMessage": "Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.",
"id": "confirmations.redraft.message"
},
{
"defaultMessage": "Block",
"id": "confirmations.block.confirm"
},
{
"defaultMessage": "Reply",
"id": "confirmations.reply.confirm"
},
{
"defaultMessage": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
"id": "confirmations.reply.message"
},
{
"defaultMessage": "Are you sure you want to block {name}?",
"id": "confirmations.block.message"
}
],
"path": "app/javascript/mastodon/features/status/containers/detailed_status_container.json"
},
{
"descriptors": [
{

View File

@ -132,7 +132,7 @@
"follow_request.authorize": "Autorizează",
"follow_request.reject": "Respinge",
"getting_started.developers": "Dezvoltatori",
"getting_started.directory": "Directorul profilului",
"getting_started.directory": "Explorează",
"getting_started.documentation": "Documentație",
"getting_started.heading": "Începe",
"getting_started.invite": "Invită prieteni",

View File

@ -70,7 +70,7 @@
"compose_form.direct_message_warning": "Tento príspevok bude videný výhradne iba spomenutými užívateľmi. Ber ale na vedomie že správci tvojej a všetkých iných zahrnutých instancií majú možnosť skontrolovať túto správu.",
"compose_form.direct_message_warning_learn_more": "Zistiť viac",
"compose_form.hashtag_warning": "Tento toot nebude zobrazený pod žiadným haštagom lebo nieje listovaný. Iba verejné tooty môžu byť nájdené podľa haštagu.",
"compose_form.lock_disclaimer": "Váš účet nie je zamknutý. Ktokoľvek ťa môže nasledovať a vidieť tvoje správy pre sledujúcich.",
"compose_form.lock_disclaimer": "Váš účet nie je {locked}. Ktokoľvek ťa môže nasledovať a vidieť tvoje správy pre sledujúcich.",
"compose_form.lock_disclaimer.lock": "zamknutý",
"compose_form.placeholder": "Čo máš na mysli?",
"compose_form.publish": "Pošli",