Merge branch 'master' into skylight

This commit is contained in:
Eugen Rochko 2017-04-13 21:55:13 +02:00
commit 17c2ba7366
121 changed files with 3031 additions and 572 deletions

View file

@ -1,6 +1,8 @@
engines:
duplication:
enabled: true
exclude_paths:
- app/assets/javascripts/components/locales/
config:
languages:
- ruby

View file

@ -35,6 +35,7 @@ SMTP_PORT=587
SMTP_LOGIN=
SMTP_PASSWORD=
SMTP_FROM_ADDRESS=notifications@example.com
#SMTP_DELIVERY_METHOD=smtp # delivery method can also be sendmail
#SMTP_AUTH_METHOD=plain
#SMTP_OPENSSL_VERIFY_MODE=peer
#SMTP_ENABLE_STARTTLS_AUTO=true

4
.gitignore vendored
View file

@ -32,3 +32,7 @@ config/deploy/*
# Ignore IDE files
.vscode/
# Ignore postgres + redis volume optionally created by docker-compose
postgres
redis

View file

@ -2,6 +2,8 @@ import api from '../api';
import { updateTimeline } from './timelines';
import * as emojione from 'emojione';
export const COMPOSE_CHANGE = 'COMPOSE_CHANGE';
export const COMPOSE_SUBMIT_REQUEST = 'COMPOSE_SUBMIT_REQUEST';
export const COMPOSE_SUBMIT_SUCCESS = 'COMPOSE_SUBMIT_SUCCESS';
@ -72,9 +74,8 @@ export function mentionCompose(account, router) {
export function submitCompose() {
return function (dispatch, getState) {
dispatch(submitComposeRequest());
api(getState).post('/api/v1/statuses', {
status: getState().getIn(['compose', 'text'], ''),
status: emojione.shortnameToUnicode(getState().getIn(['compose', 'text'], '')),
in_reply_to_id: getState().getIn(['compose', 'in_reply_to'], null),
media_ids: getState().getIn(['compose', 'media_attachments']).map(item => item.get('id')),
sensitive: getState().getIn(['compose', 'sensitive']),

View file

@ -7,7 +7,8 @@ export const REPORT_SUBMIT_REQUEST = 'REPORT_SUBMIT_REQUEST';
export const REPORT_SUBMIT_SUCCESS = 'REPORT_SUBMIT_SUCCESS';
export const REPORT_SUBMIT_FAIL = 'REPORT_SUBMIT_FAIL';
export const REPORT_STATUS_TOGGLE = 'REPORT_STATUS_TOGGLE';
export const REPORT_STATUS_TOGGLE = 'REPORT_STATUS_TOGGLE';
export const REPORT_COMMENT_CHANGE = 'REPORT_COMMENT_CHANGE';
export function initReport(account, status) {
return {
@ -62,3 +63,10 @@ export function submitReportFail(error) {
error
};
};
export function changeReportComment(comment) {
return {
type: REPORT_COMMENT_CHANGE,
comment
};
};

View file

@ -3,15 +3,43 @@ import PureRenderMixin from 'react-addons-pure-render-mixin';
const ExtendedVideoPlayer = React.createClass({
propTypes: {
src: React.PropTypes.string.isRequired
src: React.PropTypes.string.isRequired,
time: React.PropTypes.number,
controls: React.PropTypes.bool.isRequired,
muted: React.PropTypes.bool.isRequired
},
mixins: [PureRenderMixin],
handleLoadedData () {
if (this.props.time) {
this.video.currentTime = this.props.time;
}
},
componentDidMount () {
this.video.addEventListener('loadeddata', this.handleLoadedData);
},
componentWillUnmount () {
this.video.removeEventListener('loadeddata', this.handleLoadedData);
},
setRef (c) {
this.video = c;
},
render () {
return (
<div>
<video src={this.props.src} autoPlay muted loop />
<div className='extended-video-player'>
<video
ref={this.setRef}
src={this.props.src}
autoPlay
muted={this.props.muted}
controls={this.props.controls}
loop={!this.props.controls}
/>
</div>
);
},

View file

@ -13,7 +13,8 @@ const IconButton = React.createClass({
activeStyle: React.PropTypes.object,
disabled: React.PropTypes.bool,
inverted: React.PropTypes.bool,
animate: React.PropTypes.bool
animate: React.PropTypes.bool,
overlay: React.PropTypes.bool
},
getDefaultProps () {
@ -21,7 +22,8 @@ const IconButton = React.createClass({
size: 18,
active: false,
disabled: false,
animate: false
animate: false,
overlay: false
};
},
@ -39,7 +41,7 @@ const IconButton = React.createClass({
let style = {
fontSize: `${this.props.size}px`,
width: `${this.props.size * 1.28571429}px`,
height: `${this.props.size}px`,
height: `${this.props.size * 1.28571429}px`,
lineHeight: `${this.props.size}px`,
...this.props.style
};
@ -48,13 +50,31 @@ const IconButton = React.createClass({
style = { ...style, ...this.props.activeStyle };
}
const classes = ['icon-button'];
if (this.props.active) {
classes.push('active');
}
if (this.props.disabled) {
classes.push('disabled');
}
if (this.props.inverted) {
classes.push('inverted');
}
if (this.props.overlay) {
classes.push('overlayed');
}
return (
<Motion defaultStyle={{ rotate: this.props.active ? -360 : 0 }} style={{ rotate: this.props.animate ? spring(this.props.active ? -360 : 0, { stiffness: 120, damping: 7 }) : 0 }}>
{({ rotate }) =>
<button
aria-label={this.props.title}
title={this.props.title}
className={`icon-button ${this.props.active ? 'active' : ''} ${this.props.disabled ? 'disabled' : ''} ${this.props.inverted ? 'inverted' : ''}`}
className={classes.join(' ')}
onClick={this.handleClick}
style={style}>
<i style={{ transform: `rotate(${rotate}deg)` }} className={`fa fa-fw fa-${this.props.icon}`} aria-hidden='true' />

View file

@ -39,8 +39,8 @@ const spoilerSubSpanStyle = {
const spoilerButtonStyle = {
position: 'absolute',
top: '6px',
left: '8px',
top: '4px',
left: '4px',
zIndex: '100'
};
@ -232,8 +232,8 @@ const MediaGallery = React.createClass({
return (
<div style={{ ...outerStyle, height: `${this.props.height}px` }}>
<div style={spoilerButtonStyle}>
<IconButton title={intl.formatMessage(messages.toggle_visible)} icon={this.state.visible ? 'eye' : 'eye-slash'} onClick={this.handleOpen} />
<div style={{ ...spoilerButtonStyle, display: !this.state.visible ? 'none' : 'block' }}>
<IconButton title={intl.formatMessage(messages.toggle_visible)} icon={this.state.visible ? 'eye' : 'eye-slash'} overlay onClick={this.handleOpen} />
</div>
{children}

View file

@ -25,6 +25,7 @@ const Status = React.createClass({
onReblog: React.PropTypes.func,
onDelete: React.PropTypes.func,
onOpenMedia: React.PropTypes.func,
onOpenVideo: React.PropTypes.func,
onBlock: React.PropTypes.func,
me: React.PropTypes.number,
boostModal: React.PropTypes.bool,
@ -76,7 +77,7 @@ const Status = React.createClass({
if (status.get('media_attachments').size > 0 && !this.props.muted) {
if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
media = <VideoPlayer media={status.getIn(['media_attachments', 0])} sensitive={status.get('sensitive')} />;
media = <VideoPlayer media={status.getIn(['media_attachments', 0])} sensitive={status.get('sensitive')} onOpenVideo={this.props.onOpenVideo} />;
} else {
media = <MediaGallery media={status.get('media_attachments')} sensitive={status.get('sensitive')} height={110} onOpenMedia={this.props.onOpenMedia} />;
}

View file

@ -92,7 +92,7 @@ const StatusContent = React.createClass({
const { status } = this.props;
const { hidden } = this.state;
const content = { __html: emojify(status.get('content')).replace(/\n/g, '') };
const content = { __html: emojify(status.get('content')) };
const spoilerContent = { __html: emojify(escapeTextContentForBrowser(status.get('spoiler_text', ''))) };
const directionStyle = { direction: 'ltr' };

View file

@ -6,7 +6,8 @@ import { isIOS } from '../is_mobile';
const messages = defineMessages({
toggle_sound: { id: 'video_player.toggle_sound', defaultMessage: 'Toggle sound' },
toggle_visible: { id: 'video_player.toggle_visible', defaultMessage: 'Toggle visibility' }
toggle_visible: { id: 'video_player.toggle_visible', defaultMessage: 'Toggle visibility' },
expand_video: { id: 'video_player.expand', defaultMessage: 'Expand video' }
});
const videoStyle = {
@ -21,8 +22,8 @@ const videoStyle = {
const muteStyle = {
position: 'absolute',
top: '10px',
right: '10px',
top: '4px',
right: '4px',
color: 'white',
textShadow: "0px 1px 1px black, 1px 0px 1px black",
opacity: '0.8',
@ -54,8 +55,17 @@ const spoilerSubSpanStyle = {
const spoilerButtonStyle = {
position: 'absolute',
top: '6px',
left: '8px',
top: '4px',
left: '4px',
color: 'white',
textShadow: "0px 1px 1px black, 1px 0px 1px black",
zIndex: '100'
};
const expandButtonStyle = {
position: 'absolute',
bottom: '4px',
right: '4px',
color: 'white',
textShadow: "0px 1px 1px black, 1px 0px 1px black",
zIndex: '100'
@ -68,7 +78,8 @@ const VideoPlayer = React.createClass({
height: React.PropTypes.number,
sensitive: React.PropTypes.bool,
intl: React.PropTypes.object.isRequired,
autoplay: React.PropTypes.bool
autoplay: React.PropTypes.bool,
onOpenVideo: React.PropTypes.func.isRequired
},
getDefaultProps () {
@ -116,6 +127,11 @@ const VideoPlayer = React.createClass({
});
},
handleExpand () {
this.video.pause();
this.props.onOpenVideo(this.props.media, this.video.currentTime);
},
setRef (c) {
this.video = c;
},
@ -154,8 +170,14 @@ const VideoPlayer = React.createClass({
const { media, intl, width, height, sensitive, autoplay } = this.props;
let spoilerButton = (
<div style={spoilerButtonStyle} >
<IconButton title={intl.formatMessage(messages.toggle_visible)} icon={this.state.visible ? 'eye' : 'eye-slash'} onClick={this.handleVisibility} />
<div style={{...spoilerButtonStyle, display: !this.state.visible ? 'none' : 'block'}} >
<IconButton overlay title={intl.formatMessage(messages.toggle_visible)} icon={this.state.visible ? 'eye' : 'eye-slash'} onClick={this.handleVisibility} />
</div>
);
let expandButton = (
<div style={expandButtonStyle} >
<IconButton overlay title={intl.formatMessage(messages.expand_video)} icon='expand' onClick={this.handleExpand} />
</div>
);
@ -164,7 +186,7 @@ const VideoPlayer = React.createClass({
if (this.state.hasAudio) {
muteButton = (
<div style={muteStyle}>
<IconButton title={intl.formatMessage(messages.toggle_sound)} icon={this.state.muted ? 'volume-off' : 'volume-up'} onClick={this.handleClick} />
<IconButton overlay title={intl.formatMessage(messages.toggle_sound)} icon={this.state.muted ? 'volume-off' : 'volume-up'} onClick={this.handleClick} />
</div>
);
}
@ -202,6 +224,7 @@ const VideoPlayer = React.createClass({
<div style={{ cursor: 'default', marginTop: '8px', overflow: 'hidden', width: `${width}px`, height: `${height}px`, boxSizing: 'border-box', background: '#000', position: 'relative' }}>
{spoilerButton}
{muteButton}
{expandButton}
<video ref={this.setRef} src={media.get('url')} autoPlay={!isIOS()} loop={true} muted={this.state.muted} style={videoStyle} onClick={this.handleVideoClick} />
</div>
);

View file

@ -48,12 +48,13 @@ import fr from 'react-intl/locale-data/fr';
import hu from 'react-intl/locale-data/hu';
import ja from 'react-intl/locale-data/ja';
import pt from 'react-intl/locale-data/pt';
import nl from 'react-intl/locale-data/nl';
import no from 'react-intl/locale-data/no';
import ru from 'react-intl/locale-data/ru';
import uk from 'react-intl/locale-data/uk';
import zh from 'react-intl/locale-data/zh';
import bg from 'react-intl/locale-data/bg';
import { localeData as zh_hk } from '../locales/zh-hk';
import getMessagesForLocale from '../locales';
import { hydrateStore } from '../actions/store';
import createStream from '../stream';
@ -66,7 +67,6 @@ const browserHistory = useRouterHistory(createBrowserHistory)({
basename: '/web'
});
addLocaleData([
...en,
...de,
@ -77,14 +77,15 @@ addLocaleData([
...hu,
...ja,
...pt,
...nl,
...no,
...ru,
...uk,
...zh,
...zh_hk,
...bg,
]);
const Mastodon = React.createClass({
propTypes: {

View file

@ -47,7 +47,7 @@ const mapDispatchToProps = (dispatch) => ({
if (status.get('reblogged')) {
dispatch(unreblog(status));
} else {
if (e.altKey || !this.boostModal) {
if (e.shiftKey || !this.boostModal) {
this.onModalReblog(status);
} else {
dispatch(openModal('BOOST', { status, onReblog: this.onModalReblog }));
@ -75,6 +75,10 @@ const mapDispatchToProps = (dispatch) => ({
dispatch(openModal('MEDIA', { media, index }));
},
onOpenVideo (media, time) {
dispatch(openModal('VIDEO', { media, time }));
},
onBlock (account) {
dispatch(blockAccount(account.get('id')));
},

View file

@ -14,7 +14,7 @@ import ColumnBackButtonSlim from '../../components/column_back_button_slim';
import createStream from '../../stream';
const messages = defineMessages({
title: { id: 'column.community', defaultMessage: 'Local' }
title: { id: 'column.community', defaultMessage: 'Local timeline' }
});
const mapStateToProps = state => ({

View file

@ -19,7 +19,7 @@ import TextIconButton from './text_icon_button';
const messages = defineMessages({
placeholder: { id: 'compose_form.placeholder', defaultMessage: 'What is on your mind?' },
spoiler_placeholder: { id: 'compose_form.spoiler_placeholder', defaultMessage: 'Content warning' },
publish: { id: 'compose_form.publish', defaultMessage: 'Publish' }
publish: { id: 'compose_form.publish', defaultMessage: 'Toot' }
});
const ComposeForm = React.createClass({

View file

@ -12,7 +12,7 @@ import SearchResultsContainer from './containers/search_results_container';
const messages = defineMessages({
start: { id: 'getting_started.heading', defaultMessage: 'Getting started' },
public: { id: 'navigation_bar.public_timeline', defaultMessage: 'Whole Known Network' },
public: { id: 'navigation_bar.public_timeline', defaultMessage: 'Federated timeline' },
community: { id: 'navigation_bar.community_timeline', defaultMessage: 'Local timeline' },
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' }

View file

@ -7,11 +7,11 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
const messages = defineMessages({
heading: { id: 'getting_started.heading', defaultMessage: 'Getting started' },
public_timeline: { id: 'navigation_bar.public_timeline', defaultMessage: 'Whole Known Network' },
public_timeline: { id: 'navigation_bar.public_timeline', defaultMessage: 'Federated timeline' },
community_timeline: { id: 'navigation_bar.community_timeline', defaultMessage: 'Local timeline' },
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' },
sign_out: { id: 'navigation_bar.logout', defaultMessage: 'Sign out' },
sign_out: { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favourites' },
blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
info: { id: 'navigation_bar.info', defaultMessage: 'Extended information' }

View file

@ -27,8 +27,9 @@ const ColumnSettings = React.createClass({
propTypes: {
settings: ImmutablePropTypes.map.isRequired,
intl: React.PropTypes.object.isRequired,
onChange: React.PropTypes.func.isRequired,
onSave: React.PropTypes.func.isRequired
onSave: React.PropTypes.func.isRequired,
},
mixins: [PureRenderMixin],

View file

@ -14,7 +14,7 @@ import ColumnBackButtonSlim from '../../components/column_back_button_slim';
import createStream from '../../stream';
const messages = defineMessages({
title: { id: 'column.public', defaultMessage: 'Whole Known Network' }
title: { id: 'column.public', defaultMessage: 'Federated timeline' }
});
const mapStateToProps = state => ({

View file

@ -47,7 +47,7 @@ const Report = React.createClass({
propTypes: {
isSubmitting: React.PropTypes.bool,
account: ImmutablePropTypes.map,
statusIds: ImmutablePropTypes.list.isRequired,
statusIds: ImmutablePropTypes.orderedSet.isRequired,
comment: React.PropTypes.string.isRequired,
dispatch: React.PropTypes.func.isRequired,
intl: React.PropTypes.object.isRequired
@ -94,7 +94,8 @@ const Report = React.createClass({
return (
<Column heading={intl.formatMessage(messages.heading)} icon='flag'>
<ColumnBackButtonSlim />
<div className='report' style={{ display: 'flex', flexDirection: 'column', maxHeight: '100%', boxSizing: 'border-box' }}>
<div className='report scrollable' style={{ display: 'flex', flexDirection: 'column', maxHeight: '100%', boxSizing: 'border-box' }}>
<div className='report__target' style={{ flex: '0 0 auto', padding: '10px' }}>
<FormattedMessage id='report.target' defaultMessage='Reporting' />
<strong>{account.get('acct')}</strong>
@ -106,7 +107,7 @@ const Report = React.createClass({
</div>
</div>
<div style={{ flex: '0 0 160px', padding: '10px' }}>
<div style={{ flex: '0 0 100px', padding: '10px' }}>
<textarea
className='report__textarea'
placeholder={intl.formatMessage(messages.placeholder)}

View file

@ -17,7 +17,8 @@ const DetailedStatus = React.createClass({
propTypes: {
status: ImmutablePropTypes.map.isRequired,
onOpenMedia: React.PropTypes.func.isRequired
onOpenMedia: React.PropTypes.func.isRequired,
onOpenVideo: React.PropTypes.func.isRequired,
},
mixins: [PureRenderMixin],
@ -39,7 +40,7 @@ const DetailedStatus = React.createClass({
if (status.get('media_attachments').size > 0) {
if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
media = <VideoPlayer sensitive={status.get('sensitive')} media={status.getIn(['media_attachments', 0])} width={300} height={150} autoplay />;
media = <VideoPlayer sensitive={status.get('sensitive')} media={status.getIn(['media_attachments', 0])} width={300} height={150} onOpenVideo={this.props.onOpenVideo} autoplay />;
} else {
media = <MediaGallery sensitive={status.get('sensitive')} media={status.get('media_attachments')} height={300} onOpenMedia={this.props.onOpenMedia} />;
}

View file

@ -92,7 +92,7 @@ const Status = React.createClass({
if (status.get('reblogged')) {
this.props.dispatch(unreblog(status));
} else {
if (e.altKey || !this.props.boostModal) {
if (e.shiftKey || !this.props.boostModal) {
this.handleModalReblog(status);
} else {
this.props.dispatch(openModal('BOOST', { status, onReblog: this.handleModalReblog }));
@ -112,6 +112,10 @@ const Status = React.createClass({
this.props.dispatch(openModal('MEDIA', { media, index }));
},
handleOpenVideo (media, time) {
this.props.dispatch(openModal('VIDEO', { media, time }));
},
handleReport (status) {
this.props.dispatch(initReport(status.get('account'), status));
},
@ -151,7 +155,7 @@ const Status = React.createClass({
<div className='scrollable'>
{ancestors}
<DetailedStatus status={status} me={me} onOpenMedia={this.handleOpenMedia} />
<DetailedStatus status={status} me={me} onOpenVideo={this.handleOpenVideo} onOpenMedia={this.handleOpenMedia} />
<ActionBar status={status} me={me} onReply={this.handleReplyClick} onFavourite={this.handleFavouriteClick} onReblog={this.handleReblogClick} onDelete={this.handleDeleteClick} onMention={this.handleMentionClick} onReport={this.handleReport} />
{descendants}

View file

@ -65,7 +65,7 @@ const BoostModal = React.createClass({
</div>
<div className='boost-modal__action-bar'>
<div><FormattedMessage id='boost_modal.combo' defaultMessage='You can press {combo} to skip this next time' values={{ combo: <span>Alt + <i className='fa fa-retweet' /></span> }} /></div>
<div><FormattedMessage id='boost_modal.combo' defaultMessage='You can press {combo} to skip this next time' values={{ combo: <span>Shift + <i className='fa fa-retweet' /></span> }} /></div>
<Button text={intl.formatMessage(messages.reblog)} onClick={this.handleReblog} />
</div>
</div>

View file

@ -111,7 +111,7 @@ const MediaModal = React.createClass({
if (attachment.get('type') === 'image') {
content = <ImageLoader src={url} imgProps={{ style: { display: 'block' } }} />;
} else if (attachment.get('type') === 'gifv') {
content = <ExtendedVideoPlayer src={url} />;
content = <ExtendedVideoPlayer src={url} muted={true} controls={false} />;
}
return (

View file

@ -1,10 +1,12 @@
import PureRenderMixin from 'react-addons-pure-render-mixin';
import MediaModal from './media_modal';
import VideoModal from './video_modal';
import BoostModal from './boost_modal';
import { TransitionMotion, spring } from 'react-motion';
const MODAL_COMPONENTS = {
'MEDIA': MediaModal,
'VIDEO': VideoModal,
'BOOST': BoostModal
};

View file

@ -0,0 +1,47 @@
import LoadingIndicator from '../../../components/loading_indicator';
import PureRenderMixin from 'react-addons-pure-render-mixin';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ExtendedVideoPlayer from '../../../components/extended_video_player';
import { defineMessages, injectIntl } from 'react-intl';
import IconButton from '../../../components/icon_button';
const messages = defineMessages({
close: { id: 'lightbox.close', defaultMessage: 'Close' }
});
const closeStyle = {
position: 'absolute',
zIndex: '100',
top: '4px',
right: '4px'
};
const VideoModal = React.createClass({
propTypes: {
media: ImmutablePropTypes.map.isRequired,
time: React.PropTypes.number,
onClose: React.PropTypes.func.isRequired,
intl: React.PropTypes.object.isRequired
},
mixins: [PureRenderMixin],
render () {
const { media, intl, time, onClose } = this.props;
const url = media.get('url');
return (
<div className='modal-root__modal media-modal'>
<div>
<div style={closeStyle}><IconButton title={intl.formatMessage(messages.close)} icon='times' overlay onClick={onClose} /></div>
<ExtendedVideoPlayer src={url} muted={false} controls={true} time={time} />
</div>
</div>
);
}
});
export default injectIntl(VideoModal);

View file

@ -0,0 +1,68 @@
const bg = {
"column_back_button.label": "Назад",
"lightbox.close": "Затвори",
"loading_indicator.label": "Зареждане...",
"status.mention": "Споменаване",
"status.delete": "Изтриване",
"status.reply": "Отговор",
"status.reblog": "Споделяне",
"status.favourite": "Предпочитани",
"status.reblogged_by": "{name} сподели",
"status.sensitive_warning": "Деликатно съдържание",
"status.sensitive_toggle": "Покажи",
"video_player.toggle_sound": "Звук",
"account.mention": "Споменаване",
"account.edit_profile": "Редактирай профила си",
"account.unblock": "Не блокирай",
"account.unfollow": "Не следвай",
"account.block": "Блокирай",
"account.follow": "Последвай",
"account.posts": "Публикации",
"account.follows": "Следвам",
"account.followers": "Последователи",
"account.follows_you": "Твой последовател",
"account.requested": "В очакване на одобрение",
"getting_started.heading": "Първи стъпки",
"getting_started.about_addressing": "Можеш да последваш потребител, ако знаеш потребителското му име и домейна, на който се намира, като в полето за търсене ги въведеш по този начин: име@домейн",
"getting_started.about_shortcuts": "Ако с търсения потребител се намирате на един и същ домейн, достатъчно е да въведеш само името. Същото важи и за споменаване на хора в публикации.",
"getting_started.about_developer": "Можеш да потърсиш разработчика на този проект като: Gargron@mastodon.social",
"getting_started.open_source_notice": "Mastodon е софтуер с отворен код. Можеш да помогнеш или да докладваш за проблеми в Github: {github}.",
"column.home": "Начало",
"column.mentions": "Споменавания",
"column.public": "Публичен канал",
"column.notifications": "Известия",
"tabs_bar.compose": "Съставяне",
"tabs_bar.home": "Начало",
"tabs_bar.mentions": "Споменавания",
"tabs_bar.public": "Публичен канал",
"tabs_bar.notifications": "Известия",
"compose_form.placeholder": "Какво си мислиш?",
"compose_form.publish": "Раздумай",
"compose_form.sensitive": "Отбележи съдържанието като деликатно",
"compose_form.spoiler": "Скрий текста зад предупреждение",
"compose_form.private": "Отбележи като поверително",
"compose_form.privacy_disclaimer": "Поверителни публикации ще бъдат изпратени до споменатите потребители на {domains}. Доверяваш ли се на {domainsCount, plural, one {that server} other {those servers}}, че няма да издаде твоята публикация?",
"compose_form.unlisted": "Не показвай в публичния канал",
"navigation_bar.edit_profile": "Редактирай профил",
"navigation_bar.preferences": "Предпочитания",
"navigation_bar.public_timeline": "Публичен канал",
"navigation_bar.logout": "Излизане",
"reply_indicator.cancel": "Отказ",
"search.placeholder": "Търсене",
"search.account": "Акаунт",
"search.hashtag": "Хаштаг",
"upload_button.label": "Добави медия",
"upload_form.undo": "Отмяна",
"notification.follow": "{name} те последва",
"notification.favourite": "{name} хареса твоята публикация",
"notification.reblog": "{name} сподели твоята публикация",
"notification.mention": "{name} те спомена",
"notifications.column_settings.alert": "Десктоп известия",
"notifications.column_settings.show": "Покажи в колона",
"notifications.column_settings.follow": "Нови последователи:",
"notifications.column_settings.favourite": "Предпочитани:",
"notifications.column_settings.mention": "Споменавания:",
"notifications.column_settings.reblog": "Споделяния:",
};
export default bg;

View file

@ -1,4 +1,4 @@
const en = {
const de = {
"column_back_button.label": "Zurück",
"lightbox.close": "Schließen",
"loading_indicator.label": "Lade…",
@ -74,4 +74,4 @@ const en = {
"missing_indicator.label": "Nicht gefunden"
};
export default en;
export default de;

View file

@ -1,72 +1,131 @@
/**
* Note for Contributors:
* This file (en.jsx) serve as a template for other languages.
* To make other contributors' life easier, please REMEMBER:
* 1. to add your new string here; and
* 2. to remove old strings that are no longer needed; and
* 3. to sort the strings by the key.
* 4. To rename the `en` const name and export default name to match your locale.
* Thanks!
*/
const en = {
"column_back_button.label": "Back",
"lightbox.close": "Close",
"loading_indicator.label": "Loading...",
"status.mention": "Mention @{name}",
"status.delete": "Delete",
"status.reply": "Reply",
"status.reblog": "Boost",
"status.favourite": "Favourite",
"status.reblogged_by": "{name} boosted",
"status.sensitive_warning": "Sensitive content",
"status.sensitive_toggle": "Click to view",
"status.show_more": "Show more",
"status.show_less": "Show less",
"status.open": "Expand this status",
"status.report": "Report @{name}",
"video_player.toggle_sound": "Toggle sound",
"account.mention": "Mention @{name}",
"account.edit_profile": "Edit profile",
"account.unblock": "Unblock @{name}",
"account.unfollow": "Unfollow",
"account.block": "Block @{name}",
"account.disclaimer": "This user is from another instance. This number may be larger.",
"account.edit_profile": "Edit profile",
"account.follow": "Follow",
"account.posts": "Posts",
"account.follows": "Follows",
"account.followers": "Followers",
"account.follows_you": "Follows you",
"account.follows": "Follows",
"account.mention": "Mention @{name}",
"account.mute": "Mute @{name}",
"account.posts": "Posts",
"account.report": "Report @{name}",
"account.requested": "Awaiting approval",
"getting_started.heading": "Getting started",
"getting_started.about_addressing": "You can follow people if you know their username and the domain they are on by entering an e-mail-esque address into the search form.",
"getting_started.about_shortcuts": "If the target user is on the same domain as you, just the username will work. The same rule applies to mentioning people in statuses.",
"getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}. {apps}.",
"column.home": "Home",
"account.unblock": "Unblock @{name}",
"account.unfollow": "Unfollow",
"account.unmute": "Unmute @{name}",
"boost_modal.combo": "You can press {combo} to skip this next time",
"column_back_button.label": "Back",
"column.blocks": "Blocked users",
"column.community": "Local timeline",
"column.public": "Federated timeline",
"column.favourites": "Favourites",
"column.follow_requests": "Follow requests",
"column.home": "Home",
"column.notifications": "Notifications",
"tabs_bar.compose": "Compose",
"tabs_bar.home": "Home",
"tabs_bar.mentions": "Mentions",
"tabs_bar.public": "Federated timeline",
"tabs_bar.notifications": "Notifications",
"column.public": "Federated timeline",
"compose_form.placeholder": "What is on your mind?",
"compose_form.privacy_disclaimer": "Your private status will be delivered to mentioned users on {domains}. Do you trust {domainsCount, plural, one {that server} other {those servers}}? Post privacy only works on Mastodon instances. If {domains} {domainsCount, plural, one {is not a Mastodon instance} other {are not Mastodon instances}}, there will be no indication that your post is private, and it may be boosted or otherwise made visible to unintended recipients.",
"compose_form.publish": "Toot",
"compose_form.sensitive": "Mark media as sensitive",
"compose_form.spoiler_placeholder": "Content warning",
"compose_form.spoiler": "Hide text behind warning",
"compose_form.private": "Mark as private",
"compose_form.privacy_disclaimer": "Your private status will be delivered to mentioned users on {domains}. Do you trust {domainsCount, plural, one {that server} other {those servers}}? Post privacy only works on Mastodon instances. If {domains} {domainsCount, plural, one {is not a Mastodon instance} other {are not Mastodon instances}}, there will be no indication that your post is private, and it may be boosted or otherwise made visible to unintended recipients.",
"compose_form.unlisted": "Do not display on public timelines",
"navigation_bar.edit_profile": "Edit profile",
"navigation_bar.preferences": "Preferences",
"emoji_button.label": "Insert emoji",
"empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
"empty_column.hashtag": "There is nothing in this hashtag yet.",
"empty_column.home.public_timeline": "the public timeline",
"empty_column.home": "You aren't following anyone yet. Visit {public} or use search to get started and meet other users.",
"empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.",
"empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up",
"follow_request.authorize": "Authorize",
"follow_request.reject": "Reject",
"getting_started.apps": "Various apps are available",
"getting_started.heading": "Getting started",
"getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}. {apps}.",
"home.column_settings.advanced": "Advanced",
"home.column_settings.basic": "Basic",
"home.column_settings.filter_regex": "Filter out by regular expressions",
"home.column_settings.show_reblogs": "Show boosts",
"home.column_settings.show_replies": "Show replies",
"home.settings": "Column settings",
"lightbox.close": "Close",
"loading_indicator.label": "Loading...",
"media_gallery.toggle_visible": "Toggle visibility",
"missing_indicator.label": "Not found",
"navigation_bar.blocks": "Blocked users",
"navigation_bar.community_timeline": "Local timeline",
"navigation_bar.public_timeline": "Federated timeline",
"navigation_bar.edit_profile": "Edit profile",
"navigation_bar.favourites": "Favourites",
"navigation_bar.follow_requests": "Follow requests",
"navigation_bar.info": "Extended information",
"navigation_bar.logout": "Logout",
"reply_indicator.cancel": "Cancel",
"search.placeholder": "Search",
"search.account": "Account",
"search.hashtag": "Hashtag",
"upload_button.label": "Add media",
"upload_form.undo": "Undo",
"notification.follow": "{name} followed you",
"navigation_bar.preferences": "Preferences",
"navigation_bar.public_timeline": "Federated timeline",
"notification.favourite": "{name} favourited your status",
"notification.follow": "{name} followed you",
"notification.reblog": "{name} boosted your status",
"notification.mention": "{name} mentioned you",
"notifications.clear_confirmation": "Are you sure you want to clear all your notifications?",
"notifications.clear": "Clear notifications",
"notifications.column_settings.alert": "Desktop notifications",
"notifications.column_settings.show": "Show in column",
"notifications.column_settings.follow": "New followers:",
"notifications.column_settings.favourite": "Favourites:",
"notifications.column_settings.follow": "New followers:",
"notifications.column_settings.mention": "Mentions:",
"notifications.column_settings.reblog": "Boosts:",
"notifications.column_settings.show": "Show in column",
"notifications.column_settings.sound": "Play sound",
"notifications.settings": "Column settings",
"privacy.change": "Adjust status privacy",
"privacy.direct.long": "Post to mentioned users only",
"privacy.direct.short": "Direct",
"privacy.private.long": "Post to followers only",
"privacy.private.short": "Private",
"privacy.public.long": "Post to public timelines",
"privacy.public.short": "Public",
"privacy.unlisted.long": "Do not show in public timelines",
"privacy.unlisted.short": "Unlisted",
"reply_indicator.cancel": "Cancel",
"report.heading": "New report",
"report.placeholder": "Additional comments",
"report.submit": "Submit",
"report.target": "Reporting",
"search_results.total": "{count} {count, plural, one {result} other {results}}",
"search.placeholder": "Search",
"search.status_by": "Status by {name}",
"status.delete": "Delete",
"status.favourite": "Favourite",
"status.load_more": "Load more",
"status.media_hidden": "Media hidden",
"status.mention": "Mention @{name}",
"status.open": "Expand this status",
"status.reblog": "Boost",
"status.reblogged_by": "{name} boosted",
"status.reply": "Reply",
"status.report": "Report @{name}",
"status.sensitive_toggle": "Click to view",
"status.sensitive_warning": "Sensitive content",
"status.show_less": "Show less",
"status.show_more": "Show more",
"tabs_bar.compose": "Compose",
"tabs_bar.federated_timeline": "Federated",
"tabs_bar.home": "Home",
"tabs_bar.local_timeline": "Local",
"tabs_bar.notifications": "Notifications",
"upload_area.title": "Drag & drop to upload",
"upload_button.label": "Add media",
"upload_form.undo": "Undo",
"upload_progress.label": "Uploading...",
"video_player.toggle_sound": "Toggle sound",
"video_player.toggle_visible": "Toggle visibility",
"video_player.expand": "Expand video",
};
export default en;

View file

@ -3,6 +3,7 @@ import de from './de';
import es from './es';
import hu from './hu';
import fr from './fr';
import nl from './nl';
import no from './no';
import pt from './pt';
import uk from './uk';
@ -11,7 +12,7 @@ import eo from './eo';
import ru from './ru';
import ja from './ja';
import zh_hk from './zh-hk';
import bg from './bg';
const locales = {
en,
@ -19,6 +20,7 @@ const locales = {
es,
hu,
fr,
nl,
no,
pt,
uk,
@ -27,6 +29,7 @@ const locales = {
ru,
ja,
'zh-HK': zh_hk,
bg,
};
export default function getMessagesForLocale (locale) {

View file

@ -11,9 +11,11 @@ const ja = {
"status.sensitive_warning": "不適切なコンテンツ",
"status.sensitive_toggle": "クリックして表示",
"status.show_more": "もっと見る",
"status.load_more": "もっと見る",
"status.show_less": "隠す",
"status.open": "Expand this status",
"status.report": "@{name} さんを報告",
"status.report": "@{name} さんを通報",
"status.media_hidden": "非表示のメデイア",
"video_player.toggle_sound": "音の切り替え",
"account.mention": "@{name} さんに返信",
"account.edit_profile": "プロフィールを編集",
@ -23,11 +25,14 @@ const ja = {
"account.mute": "ミュート",
"account.unmute": "ミュート解除",
"account.follow": "フォロー",
"account.report": "@{name}を通報する",
"account.posts": "投稿",
"account.follows": "フォロー",
"account.followers": "フォロワー",
"account.follows_you": "フォローされています",
"account.requested": "承認待ち",
"follow_request.authorize": "許可",
"follow_request.reject": "拒否",
"getting_started.heading": "スタート",
"getting_started.about_addressing": "ドメインとユーザー名を知っているなら検索フォームに入力すればフォローできます。",
"getting_started.about_shortcuts": "対象のアカウントがあなたと同じドメインのユーザーならばユーザー名のみで検索できます。これは返信のときも一緒です。",
@ -36,19 +41,34 @@ const ja = {
"column.community": "ローカルタイムライン",
"column.public": "連合タイムライン",
"column.notifications": "通知",
"column.favourites": "お気に入り",
"tabs_bar.compose": "投稿",
"tabs_bar.home": "ホーム",
"tabs_bar.mentions": "返信",
"tabs_bar.local_timeline": "ローカルTL",
"tabs_bar.federated_timeline": "連合TL",
"tabs_bar.local_timeline": "ローカル",
"tabs_bar.federated_timeline": "連合",
"tabs_bar.notifications": "通知",
"compose_form.placeholder": "今なにしてる?",
"compose_form.publish": "トゥート",
"compose_form.sensitive": "メディアを不適切なコンテンツとしてマークする",
"compose_form.spoiler": "テキストを隠す",
"compose_form.spoiler_placeholder": "内容注意メッセージ",
"compose_form.private": "非公開にする",
"compose_form.privacy_disclaimer": "あなたの非公開トゥートは返信先のユーザーat {domains})に公開されます。{domainsCount, plural, one {that server} other {those servers}}を信頼しますか投稿のプライバシー保護はMastodonサーバー内でのみ有効です。 もし{domains} {domainsCount, plural, one {is not a Mastodon instance} other {are not Mastodon instances}}ならばあなたの投稿のプライバシーは保護されず、ブーストされたり予期しないユーザーに見られる可能性があります。",
"compose_form.unlisted": "公開タイムラインに表示しない",
"privacy.public.short": "公開",
"privacy.public.long": "公開TLに投稿する",
"privacy.unlisted.short": "未収載",
"privacy.unlisted.long": "公開TLで表示しない",
"privacy.private.short": "非公開",
"privacy.private.long": "フォロワーだけに公開",
"privacy.direct.short": "ダイレクト",
"privacy.direct.long": "含んだユーザーだけに公開",
"privacy.change": "投稿のプライバシーを変更2",
"report.heading": "新規通報",
"report.placeholder": "コメント",
"report.target": "問題のユーザー",
"report.submit": "通報する",
"navigation_bar.edit_profile": "プロフィールを編集",
"navigation_bar.preferences": "ユーザー設定",
"navigation_bar.community_timeline": "ローカルタイムライン",
@ -61,12 +81,16 @@ const ja = {
"search.placeholder": "検索",
"search.account": "アカウント",
"search.hashtag": "ハッシュタグ",
"search.status_by": "{uuuname}からの投稿",
"upload_area.title": "ファイルをこちらにドラッグしてください",
"upload_button.label": "メディアを追加",
"upload_form.undo": "やり直す",
"notification.follow": "{name} さんにフォローされました",
"notification.favourite": "{name} さんがあなたのトゥートをお気に入りに登録しました",
"notification.reblog": "{name} さんがあなたのトゥートをブーストしました",
"notification.mention": "{name} さんがあなたに返信しました",
"notifications.clear": "通知を片付ける",
"notifications.clear_confirmation": "通知を全部片付けます。大丈夫ですか?",
"notifications.column_settings.alert": "デスクトップ通知",
"notifications.column_settings.show": "カラムに表示",
"notifications.column_settings.follow": "新しいフォロワー",
@ -78,6 +102,18 @@ const ja = {
"empty_column.home.public_timeline": "連合タイムライン",
"empty_column.notifications": "まだ通知がありません。他の人とふれ合って会話を始めましょう。",
"empty_column.public": "ここにはまだ何もありません!公開で何かを投稿したり、他のインスタンスのユーザーをフォローしたりしていっぱいにしましょう!",
"empty_column.hashtag": "このハッシュタグはまだ使っていません。",
"upload_progress.label": "アップロード中…",
"emoji_button.label": "絵文字を追加",
"home.column_settings.basic": "シンプル",
"home.column_settings.advanced": "エキスパート",
"home.column_settings.show_reblogs": "ブースト表示",
"home.column_settings.show_replies": "返信表示",
"home.column_settings.filter_regex": "正規表現でフィルター",
"home.settings": "カラム設定",
"notification.settings": "カラム設定",
"missing_indicator.label": "見つかりません",
"boost_modal.combo": "次は{combo}を押せば、これをスキップできます。"
};
export default ja;

View file

@ -0,0 +1,68 @@
const nl = {
"column_back_button.label": "terug",
"lightbox.close": "Sluiten",
"loading_indicator.label": "Laden...",
"status.mention": "Vermeld @{name}",
"status.delete": "Verwijder",
"status.reply": "Reageer",
"status.reblog": "Boost",
"status.favourite": "Favoriet",
"status.reblogged_by": "{name} boostte",
"status.sensitive_warning": "Gevoelige inhoud",
"status.sensitive_toggle": "Klik om te zien",
"video_player.toggle_sound": "Geluid omschakelen",
"account.mention": "Vermeld @{name}",
"account.edit_profile": "Bewerk profiel",
"account.unblock": "Deblokkeer @{name}",
"account.unfollow": "Ontvolg",
"account.block": "Blokkeer @{name}",
"account.follow": "Volg",
"account.posts": "Berichten",
"account.follows": "Volgt",
"account.followers": "Volgers",
"account.follows_you": "Volgt jou",
"account.requested": "Wacht op goedkeuring",
"getting_started.heading": "Beginnen",
"getting_started.about_addressing": "Je kunt mensen volgen als je hun gebruikersnaam en het domein van hun server kent, door het e-mailachtige adres in het zoekscherm in te voeren.",
"getting_started.about_shortcuts": "Als de gezochte gebruiker op hetzelfde domein zit als jijzelf, is invoeren van de gebruikersnaam genoeg. Dat geldt ook als je mensen in de statussen wilt vermelden.",
"getting_started.open_source_notice": "Mastodon is open source software. Je kunt bijdragen of problemen melden op GitHub via {github}. {apps}.",
"column.home": "Thuis",
"column.community": "Lokale tijdlijn",
"column.public": "Federatietijdlijn",
"column.notifications": "Meldingen",
"tabs_bar.compose": "Schrijven",
"tabs_bar.home": "Thuis",
"tabs_bar.mentions": "Vermeldingen",
"tabs_bar.public": "Federatietijdlijn",
"tabs_bar.notifications": "Meldingen",
"compose_form.placeholder": "Waar ben je mee bezig?",
"compose_form.publish": "Toot",
"compose_form.sensitive": "Markeer media als gevoelig",
"compose_form.spoiler": "Verberg tekst achter waarschuwing",
"compose_form.private": "Mark als privé",
"compose_form.privacy_disclaimer": "Je besloten status wordt afgeleverd aan vermelde gebruikers op {domains}. Vertrouw je {domainsCount, plural, one {that server} andere {those servers}}? Privé plaatsen werkt alleen op Mastodon servers. Als {domains} {domainsCount, plural, een {is not a Mastodon instance} andere {are not Mastodon instances}}, dan wordt er geen indicatie gegeven dat he bericht besloten is, waardoor het kan worden geboost of op andere manier zichtbaar worden voor niet bedoelde lezers.",
"compose_form.unlisted": "Niet tonen op openbare tijdlijnen",
"navigation_bar.edit_profile": "Bewerk profiel",
"navigation_bar.preferences": "Voorkeuren",
"navigation_bar.community_timeline": "Lokale tijdlijn",
"navigation_bar.public_timeline": "Federatietijdlijn",
"navigation_bar.logout": "Uitloggen",
"reply_indicator.cancel": "Annuleren",
"search.placeholder": "Zoeken",
"search.account": "Account",
"search.hashtag": "Hashtag",
"upload_button.label": "Toevoegen media",
"upload_form.undo": "Ongedaan maken",
"notification.follow": "{name} volgde jou",
"notification.favourite": "{name} markeerde je status als favoriet",
"notification.reblog": "{name} boostte je status",
"notification.mention": "{name} vermeldde jou",
"notifications.column_settings.alert": "Desktopmeldingen",
"notifications.column_settings.show": "Tonen in kolom",
"notifications.column_settings.follow": "Nieuwe volgers:",
"notifications.column_settings.favourite": "Favoriten:",
"notifications.column_settings.mention": "Vermeldingen:",
"notifications.column_settings.reblog": "Boosts:",
};
export default nl;

View file

@ -6,7 +6,7 @@ const no = {
"status.delete": "Slett",
"status.reply": "Svar",
"status.reblog": "Reblogg",
"status.favourite": "Favoritt",
"status.favourite": "Lik",
"status.reblogged_by": "{name} reblogget",
"status.sensitive_warning": "Sensitivt innhold",
"status.sensitive_toggle": "Klikk for å vise",
@ -32,12 +32,14 @@ const no = {
"getting_started.open_source_notice": "Mastodon er programvare med fri kildekode. Du kan bidra eller rapportere problemer på GitHub på {github}. {apps}.",
"column.home": "Hjem",
"column.community": "Lokal tidslinje",
"column.public": "Føderert tidslinje",
"column.public": "Forent tidslinje",
"column.notifications": "Varslinger",
"column.blocks": "Blokkerte brukere",
"column.favourites": "Likt",
"tabs_bar.compose": "Komponer",
"tabs_bar.home": "Hjem",
"tabs_bar.mentions": "Nevninger",
"tabs_bar.public": "Føderert tidslinje",
"tabs_bar.public": "Forent tidslinje",
"tabs_bar.notifications": "Varslinger",
"compose_form.placeholder": "Hva har du på hjertet?",
"compose_form.publish": "Tut",
@ -49,8 +51,11 @@ const no = {
"navigation_bar.edit_profile": "Rediger profil",
"navigation_bar.preferences": "Preferanser",
"navigation_bar.community_timeline": "Lokal tidslinje",
"navigation_bar.public_timeline": "Føderert tidslinje",
"navigation_bar.public_timeline": "Forent tidslinje",
"navigation_bar.logout": "Logg ut",
"navigation_bar.blocks": "Blokkerte brukere",
"navigation_bar.info": "Utvidet informasjon",
"navigation_bar.favourites": "Likt",
"reply_indicator.cancel": "Avbryt",
"search.placeholder": "Søk",
"search.account": "Konto",
@ -64,7 +69,7 @@ const no = {
"notifications.column_settings.alert": "Skrivebordsvarslinger",
"notifications.column_settings.show": "Vis i kolonne",
"notifications.column_settings.follow": "Nye følgere:",
"notifications.column_settings.favourite": "Favouritter:",
"notifications.column_settings.favourite": "Likt:",
"notifications.column_settings.mention": "Nevninger:",
"notifications.column_settings.reblog": "Reblogginger:",
};

View file

@ -14,59 +14,115 @@ const pt = {
"status.show_less": "Mostrar menos",
"status.open": "Expandir",
"status.report": "Reportar @{name}",
"status.load_more": "Carregar mais",
"status.media_hidden": "Media escondida",
"video_player.toggle_sound": "Ligar/Desligar som",
"video_player.toggle_visible": "Ligar/Desligar vídeo",
"account.mention": "Mencionar @{name}",
"account.edit_profile": "Editar perfil",
"account.unblock": "Não bloquear @{name}",
"account.unfollow": "Não seguir",
"account.block": "Bloquear @{name}",
"account.mute": "Mute",
"account.unmute": "Remover Mute",
"account.follow": "Seguir",
"account.posts": "Posts",
"account.follows": "Segue",
"account.followers": "Seguidores",
"account.follows_you": "É teu seguidor",
"account.requested": "A aguardar aprovação",
"account.report": "Denunciar",
"account.disclaimer": "Essa conta está localizado em outra instância. Os nomes podem ser maiores.",
"getting_started.heading": "Primeiros passos",
"getting_started.about_addressing": "Podes seguir pessoas se sabes o nome de usuário deles e o domínio em que estão colocando um endereço similar a e-mail no campo no topo da barra lateral.",
"getting_started.about_shortcuts": "Se o usuário alvo está no mesmo domínio, só o nome funcionará. A mesma regra se aplica a mencionar pessoas nas postagens.",
"getting_started.about_developer": "Pode seguir o developer deste projecto em Gargron@mastodon.social",
"getting_started.open_source_notice": "Mastodon é software de fonte aberta. Podes contribuir ou repostar problemas no GitHub do projecto: {github}. {apps}.",
"column.home": "Home",
"column.community": "Local",
"column.public": "Público",
"column.public": "Global",
"column.notifications": "Notificações",
"column.blocks": "Utilizadores Bloqueados",
"column.favourites": "Favoritos",
"column.follow_requests": "Seguidores Pendentes",
"empty_column.notifications": "Não tens notificações. Interage com outros utilizadores para iniciar uma conversa.",
"empty_column.public": "Não há nada aqui! Escreve algo publicamente ou segue outros utilizadores para ver aqui os conteúdos públicos.",
"empty_column.home": "Ainda não segues qualquer utilizador. Visita {public} ou utiliza a pesquisa para procurar outros utilizadores.",
"empty_column.home.public_timeline": "global",
"empty_column.community": "Ainda não existem conteúdo local para mostrar!",
"empty_column.hashtag": "Não existe qualquer conteúdo com essa hashtag",
"tabs_bar.compose": "Criar",
"tabs_bar.home": "Home",
"tabs_bar.mentions": "Menções",
"tabs_bar.public": "Público",
"tabs_bar.notifications": "Notificações",
"tabs_bar.local_timeline": "Local",
"tabs_bar.federated_timeline": "Global",
"compose_form.placeholder": "Em que estás a pensar?",
"compose_form.publish": "Publicar",
"compose_form.sensitive": "Media com conteúdo sensível",
"compose_form.sensitive": "Marcar media como conteúdo sensível",
"compose_form.spoiler": "Esconder texto com aviso",
"compose_form.spoiler_placeholder": "Aviso",
"compose_form.private": "Tornar privado",
"compose_form.privacy_disclaimer": "O teu conteúdo privado vai ser partilhado com os utilizadores do {domains}. Confias {domainsCount, plural, one {neste servidor} other {nestes servidores}}? A privacidade só funciona em instâncias do Mastodon. Se {domains} {domainsCount, plural, one {não é uma instância} other {não são instâncias}}, não existem indicadores da privacidade da tua partilha, e podem ser partilhados com outros.",
"compose_form.unlisted": "Não mostrar na listagem pública",
"emoji_button.label": "Inserir Emoji",
"navigation_bar.edit_profile": "Editar perfil",
"navigation_bar.preferences": "Preferências",
"navigation_bar.community_timeline": "Local",
"navigation_bar.public_timeline": "Público",
"navigation_bar.public_timeline": "Global",
"navigation_bar.blocks": "Utilizadores bloqueados",
"navigation_bar.favourites": "Favoritos",
"navigation_bar.info": "Mais informações",
"navigation_bar.logout": "Sair",
"navigation_bar.follow_requests": "Seguidores pendentes",
"reply_indicator.cancel": "Cancelar",
"search.placeholder": "Pesquisar",
"search.account": "Conta",
"search.hashtag": "Hashtag",
"search_results.total": "{count} {count, plural, one {resultado} other {resultados}}",
"search.status_by": "Post de {name}",
"upload_button.label": "Adicionar media",
"upload_form.undo": "Anular",
"upload_progress.label": "A gravar…",
"upload_area.title": "Arraste e solte para enviar",
"notification.follow": "{name} seguiu-te",
"notification.favourite": "{name} adicionou o teu post aos favoritos",
"notification.reblog": "{name} partilhou o teu post",
"notification.mention": "{name} mencionou-te",
"notifications.column_settings.alert": "Notificações no computador",
"notifications.column_settings.show": "Mostrar nas colunas",
"notifications.column_settings.sound": "Reproduzir som",
"notifications.column_settings.follow": "Novos seguidores:",
"notifications.column_settings.favourite": "Favoritos:",
"notifications.column_settings.mention": "Menções:",
"notifications.column_settings.reblog": "Partilhas:",
"notifications.clear": "Limpar notificações",
"notifications.clear_confirmation": "Queres mesmo limpar todas as notificações?",
"notifications.settings": "Parâmetros da lista de Notificações",
"privacy.public.short": "Público",
"privacy.public.long": "Publicar em todos os feeds",
"privacy.unlisted.short": "Não listar",
"privacy.unlisted.long": "Não publicar nos feeds públicos",
"privacy.private.short": "Privado",
"privacy.private.long": "Apenas para os seguidores",
"privacy.direct.short": "Directo",
"privacy.direct.long": "Apenas para utilizadores mencionados",
"privacy.change": "Ajustar a privacidade da mensagem",
"media_gallery.toggle_visible": "Modificar a visibilidade",
"missing_indicator.label": "Não encontrado",
"follow_request.authorize": "Autorizar",
"follow_request.reject": "Rejeitar",
"home.settings": "Parâmetros da coluna Home",
"home.column_settings.basic": "Básico",
"home.column_settings.show_reblogs": "Mostrar as partilhas",
"home.column_settings.show_replies": "Mostrar as respostas",
"home.column_settings.advanced": "Avançadas",
"home.column_settings.filter_regex": "Filtrar com uma expressão regular",
"report.heading": "Nova denuncia",
"report.placeholder": "Comentários adicionais",
"report.submit": "Enviar",
"report.target": "Denunciar"
};
export default pt;

View file

@ -10,22 +10,29 @@ const ru = {
"status.reblogged_by": "{name} продвинул(а)",
"status.sensitive_warning": "Чувствительный контент",
"status.sensitive_toggle": "Нажмите для просмотра",
"status.show_more": "Развернуть",
"status.show_less": "Свернуть",
"status.open": "Развернуть статус",
"status.report": "Пожаловаться",
"status.load_more": "Показать еще",
"video_player.toggle_sound": "Вкл./выкл. звук",
"account.mention": "Упомянуть @{name}",
"account.mention": "Упомянуть",
"account.edit_profile": "Изменить профиль",
"account.unblock": "Разблокировать @{name}",
"account.unblock": "Разблокировать",
"account.unfollow": "Отписаться",
"account.block": "Блокировать @{name}",
"account.block": "Блокировать",
"account.mute": "Заглушить",
"account.follow": "Подписаться",
"account.posts": "Посты",
"account.follows": "Подписки",
"account.followers": "Подписчики",
"account.followers": "Подписаны",
"account.follows_you": "Подписан(а) на Вас",
"account.requested": "Ожидает подтверждения",
"getting_started.heading": "Добро пожаловать",
"getting_started.about_addressing": "Вы можете подписаться на человека, зная имя пользователя и домен, на котором он находится, введя e-mail-подобный адрес в форму поиска.",
"getting_started.about_shortcuts": "Если пользователь находится на одном с Вами домене, можно использовать только имя. То же правило применимо к упоминанию пользователей в статусах.",
"getting_started.open_source_notice": "Mastodon - программа с открытым исходным кодом. Вы можете помочь проекту или сообщить о проблемах на GitHub по адресу {github}. {apps}.",
"getting_started.apps": "Доступны различные приложения.",
"column.home": "Главная",
"column.community": "Локальная лента",
"column.public": "Глобальная лента",
@ -36,7 +43,7 @@ const ru = {
"tabs_bar.public": "Глобальная лента",
"tabs_bar.notifications": "Уведомления",
"compose_form.placeholder": "О чем Вы думаете?",
"compose_form.publish": "Протрубить",
"compose_form.publish": "Трубить",
"compose_form.sensitive": "Отметить как чувствительный контент",
"compose_form.spoiler": "Скрыть текст за предупреждением",
"compose_form.private": "Отметить как приватное",
@ -47,6 +54,9 @@ const ru = {
"navigation_bar.community_timeline": "Локальная лента",
"navigation_bar.public_timeline": "Глобальная лента",
"navigation_bar.logout": "Выйти",
"navigation_bar.info": "Об узле",
"navigation_bar.favourites": "Понравившееся",
"navigation_bar.blocks": "Список блокировки",
"reply_indicator.cancel": "Отмена",
"search.placeholder": "Поиск",
"search.account": "Аккаунт",
@ -57,12 +67,35 @@ const ru = {
"notification.favourite": "{name} понравился Ваш статус",
"notification.reblog": "{name} продвинул(а) Ваш статус",
"notification.mention": "{name} упомянул(а) Вас",
"home.settings": "Настройки колонки",
"home.column_settings.basic": "Основные",
"home.column_settings.advanced": "Дополнительные",
"home.column_settings.filter_regex": "Отфильтровать регулярным выражением",
"home.column_settings.show_replies": "Показывать продвижения",
"home.column_settings.show_replies": "Показывать ответы",
"notifications.clear": "Очистить уведомления",
"notifications.settings": "Настройки колонки",
"notifications.column_settings.alert": "Десктопные уведомления",
"notifications.column_settings.show": "Показывать в колонке",
"notifications.column_settings.follow": "Новые подписчики:",
"notifications.column_settings.favourite": "Нравится:",
"notifications.column_settings.mention": "Упоминания:",
"notifications.column_settings.reblog": "Продвижения:",
"notifications.column_settings.sound": "Проигрывать звук",
"empty_column.notifications": "У Вас еще нет уведомлений. Заведите знакомство с другими пользователями, чтобы начать разговор.",
"empty_column.hashtag": "Статусов с таким хэштегом еще не существует.",
"empty_column.community": "Локальная лента пуста. Напишите что-нибудь, чтобы разогреть народ!",
"empty_column.public": "Здесь ничего нет! Опубликуйте что-нибудь или подпишитесь на пользователей с других узлов, чтобы заполнить ленту.",
"empty_column.home": "Пока Вы ни на кого не подписаны. Полистайте {public} или используйте поиск, чтобы освоиться и завести новые знакомства.",
"empty_column.home.public_timeline": "публичные ленты",
"privacy.public.short": "Публичный",
"privacy.public.long": "Показать в публичных лентах",
"privacy.unlisted.short": "Скрытый",
"privacy.unlisted.long": "Не показывать в лентах",
"privacy.private.short": "Приватный",
"privacy.private.long": "Показать только подписчикам",
"privacy.direct.short": "Направленный",
"privacy.direct.long": "Показать только упомянутым",
};
export default ru;

View file

@ -67,6 +67,7 @@ function clearAll(state) {
map.set('is_submitting', false);
map.set('in_reply_to', null);
map.set('privacy', state.get('default_privacy'));
map.set('sensitive', false);
map.update('media_attachments', list => list.clear());
});
};
@ -157,6 +158,9 @@ export default function compose(state = initialState, action) {
if (action.status.get('spoiler_text').length > 0) {
map.set('spoiler', true);
map.set('spoiler_text', action.status.get('spoiler_text'));
} else {
map.set('spoiler', false);
map.set('spoiler_text', '');
}
});
case COMPOSE_REPLY_CANCEL:

View file

@ -4,7 +4,8 @@ import {
REPORT_SUBMIT_SUCCESS,
REPORT_SUBMIT_FAIL,
REPORT_CANCEL,
REPORT_STATUS_TOGGLE
REPORT_STATUS_TOGGLE,
REPORT_COMMENT_CHANGE
} from '../actions/reports';
import Immutable from 'immutable';
@ -39,6 +40,8 @@ export default function reports(state = initialState, action) {
return set.remove(action.statusId);
});
case REPORT_COMMENT_CHANGE:
return state.setIn(['new', 'comment'], action.comment);
case REPORT_SUBMIT_REQUEST:
return state.setIn(['new', 'isSubmitting'], true);
case REPORT_SUBMIT_FAIL:

View file

@ -1,6 +1,7 @@
@import 'variables';
.app-body{
-webkit-overflow-scrolling: touch;
-ms-overflow-style: -ms-autohiding-scrollbar;
}
@ -111,6 +112,18 @@
color: $color3;
}
}
&.overlayed {
box-sizing: content-box;
background: rgba($color8, 0.6);
color: rgba($color5, 0.7);
border-radius: 4px;
padding: 2px;
&:hover {
background: rgba($color8, 0.9);
}
}
}
.text-icon-button {

View file

@ -88,7 +88,7 @@ code {
}
}
input[type=text], input[type=email], input[type=password], textarea {
input[type=text], input[type=number], input[type=email], input[type=password], textarea {
background: transparent;
box-sizing: border-box;
border: 0;

View file

@ -218,6 +218,7 @@
margin-top: 8px;
height: 300px;
overflow: hidden;
position: relative;
video {
position: relative;

View file

@ -2,49 +2,29 @@
module Admin
class AccountsController < BaseController
before_action :set_account, except: :index
def index
@accounts = Account.alphabetic.page(params[:page])
@accounts = @accounts.local if params[:local].present?
@accounts = @accounts.remote if params[:remote].present?
@accounts = @accounts.where(domain: params[:by_domain]) if params[:by_domain].present?
@accounts = @accounts.silenced if params[:silenced].present?
@accounts = @accounts.recent if params[:recent].present?
@accounts = @accounts.suspended if params[:suspended].present?
@accounts = filtered_accounts.page(params[:page])
end
def show; end
def suspend
Admin::SuspensionWorker.perform_async(@account.id)
redirect_to admin_accounts_path
end
def unsuspend
@account.update(suspended: false)
redirect_to admin_accounts_path
end
def silence
@account.update(silenced: true)
redirect_to admin_accounts_path
end
def unsilence
@account.update(silenced: false)
redirect_to admin_accounts_path
def show
@account = Account.find(params[:id])
end
private
def set_account
@account = Account.find(params[:id])
def filtered_accounts
AccountFilter.new(filter_params).results
end
def account_params
params.require(:account).permit(:silenced, :suspended)
def filter_params
params.permit(
:local,
:remote,
:by_domain,
:silenced,
:recent,
:suspended
)
end
end
end

View file

@ -0,0 +1,23 @@
# frozen_string_literal: true
module Admin
class SilencesController < BaseController
before_action :set_account
def create
@account.update(silenced: true)
redirect_to admin_accounts_path
end
def destroy
@account.update(silenced: false)
redirect_to admin_accounts_path
end
private
def set_account
@account = Account.find(params[:account_id])
end
end
end

View file

@ -0,0 +1,23 @@
# frozen_string_literal: true
module Admin
class SuspensionsController < BaseController
before_action :set_account
def create
Admin::SuspensionWorker.perform_async(@account.id)
redirect_to admin_accounts_path
end
def destroy
@account.update(suspended: false)
redirect_to admin_accounts_path
end
private
def set_account
@account = Account.find(params[:account_id])
end
end
end

View file

@ -6,7 +6,7 @@ module Settings
before_action :authenticate_user!
def index
export_data = Export.new(export_accounts).to_csv
@export = Export.new(current_account)
respond_to do |format|
format.csv { send_data export_data, filename: export_filename }

View file

@ -5,8 +5,8 @@ module Settings
class BlockedAccountsController < BaseController
private
def export_accounts
current_account.blocking
def export_data
@export.to_blocked_accounts_csv
end
end
end

View file

@ -5,8 +5,8 @@ module Settings
class FollowingAccountsController < BaseController
private
def export_accounts
current_account.following
def export_data
@export.to_following_accounts_csv
end
end
end

View file

@ -5,8 +5,8 @@ module Settings
class MutedAccountsController < BaseController
private
def export_accounts
current_account.muting
def export_data
@export.to_muted_accounts_csv
end
end
end

View file

@ -6,9 +6,6 @@ class Settings::ExportsController < ApplicationController
before_action :authenticate_user!
def show
@total_storage = current_account.media_attachments.sum(:file_file_size)
@total_follows = current_account.following.count
@total_blocks = current_account.blocking.count
@total_mutes = current_account.muting.count
@export = Export.new(current_account)
end
end

View file

@ -0,0 +1,13 @@
# frozen_string_literal: true
module WellKnown
class HostMetaController < ApplicationController
def show
@webfinger_template = "#{webfinger_url}?resource={uri}"
respond_to do |format|
format.xml { render content_type: 'application/xrd+xml' }
end
end
end
end

View file

@ -0,0 +1,43 @@
# frozen_string_literal: true
module WellKnown
class WebfingerController < ApplicationController
def show
@account = Account.find_local!(username_from_resource)
@canonical_account_uri = @account.to_webfinger_s
@magic_key = pem_to_magic_key(@account.keypair.public_key)
respond_to do |format|
format.xml { render content_type: 'application/xrd+xml' }
format.json { render content_type: 'application/jrd+json' }
end
rescue ActiveRecord::RecordNotFound
head 404
end
private
def username_from_resource
WebfingerResource.new(resource_param).username
end
def pem_to_magic_key(public_key)
modulus, exponent = [public_key.n, public_key.e].map do |component|
result = []
until component.zero?
result << [component % 256].pack('C')
component >>= 8
end
result.reverse.join
end
(['RSA'] + [modulus, exponent].map { |n| Base64.urlsafe_encode64(n) }).join('.')
end
def resource_param
params.require(:resource)
end
end
end

View file

@ -1,55 +0,0 @@
# frozen_string_literal: true
class XrdController < ApplicationController
before_action :set_default_format_xml, only: :host_meta
def host_meta
@webfinger_template = "#{webfinger_url}?resource={uri}"
respond_to do |format|
format.xml { render content_type: 'application/xrd+xml' }
end
end
def webfinger
@account = Account.find_local!(username_from_resource)
@canonical_account_uri = @account.to_webfinger_s
@magic_key = pem_to_magic_key(@account.keypair.public_key)
respond_to do |format|
format.xml { render content_type: 'application/xrd+xml' }
format.json { render content_type: 'application/jrd+json' }
end
rescue ActiveRecord::RecordNotFound
head 404
end
private
def set_default_format_xml
request.format = 'xml' if request.headers['HTTP_ACCEPT'].nil? && params[:format].nil?
end
def username_from_resource
WebfingerResource.new(resource_param).username
end
def pem_to_magic_key(public_key)
modulus, exponent = [public_key.n, public_key.e].map do |component|
result = []
until component.zero?
result << [component % 256].pack('C')
component >>= 8
end
result.reverse.join
end
(['RSA'] + [modulus, exponent].map { |n| Base64.urlsafe_encode64(n) }).join('.')
end
def resource_param
params.require(:resource)
end
end

View file

@ -8,6 +8,7 @@ module SettingsHelper
eo: 'Esperanto',
fr: 'Français',
hu: 'Magyar',
nl: 'Nederlands',
no: 'Norsk',
pt: 'Português',
fi: 'Suomi',
@ -16,6 +17,7 @@ module SettingsHelper
ja: '日本語',
'zh-CN': '简体中文',
'zh-HK': '繁體中文(香港)',
bg: 'Български',
}.freeze
def human_locale(locale)

View file

@ -15,6 +15,7 @@ class Formatter
html = status.text
html = encode(html)
html = simple_format(html, {}, sanitize: false)
html = html.gsub(/\n/, '')
html = link_urls(html)
html = link_mentions(html, status.mentions)
html = link_hashtags(html)
@ -95,6 +96,6 @@ class Formatter
end
def mention_html(match, account)
"#{match.split('@').first}<span class=\"h-card\"><a href=\"#{TagManager.instance.url_for(account)}\" class=\"u-url mention\">@#{account.username}</a></span>"
"#{match.split('@').first}<span class=\"h-card\"><a href=\"#{TagManager.instance.url_for(account)}\" class=\"u-url mention\">@<span>#{account.username}</span></a></span>"
end
end

View file

@ -0,0 +1,36 @@
# frozen_string_literal: true
class AccountFilter
attr_reader :params
def initialize(params)
@params = params
end
def results
scope = Account.alphabetic
params.each do |key, value|
scope = scope.merge scope_for(key, value)
end
scope
end
def scope_for(key, value)
case key
when /local/
Account.local
when /remote/
Account.remote
when /by_domain/
Account.where(domain: value)
when /silenced/
Account.silenced
when /recent/
Account.recent
when /suspended/
Account.suspended
else
raise "Unknown filter: #{key}"
end
end
end

View file

@ -2,13 +2,43 @@
require 'csv'
class Export
attr_reader :accounts
attr_reader :account
def initialize(accounts)
@accounts = accounts
def initialize(account)
@account = account
end
def to_csv
def to_blocked_accounts_csv
to_csv account.blocking
end
def to_muted_accounts_csv
to_csv account.muting
end
def to_following_accounts_csv
to_csv account.following
end
def total_storage
account.media_attachments.sum(:file_file_size)
end
def total_follows
account.following.count
end
def total_blocks
account.blocking.count
end
def total_mutes
account.muting.count
end
private
def to_csv(accounts)
CSV.generate do |csv|
accounts.each do |account|
csv << [(account.local? ? account.local_username_and_domain : account.acct)]

View file

@ -51,7 +51,7 @@
%h3#coppa Children's Online Privacy Protection Act Compliance
%p
Our site, products and services are all directed to people who are at least 13 years old or older. If this server is in the USA, and you are under the age of 13, per the requirements of COPPA
Our site, products and services are all directed to people who are at least 13 years old. If this server is in the USA, and you are under the age of 13, per the requirements of COPPA
= surround '(', '),' do
= link_to 'Children\'s Online Privacy Protection Act', 'https://en.wikipedia.org/wiki/Children%27s_Online_Privacy_Protection_Act'
do not use this site.

View file

@ -1,30 +1,30 @@
- content_for :page_title do
Accounts
= t('admin.accounts.title')
.filters
.filter-subset
%strong Location
%strong= t('admin.accounts.location.title')
%ul
%li= filter_link_to 'All', local: nil, remote: nil
%li= filter_link_to 'Local', local: '1', remote: nil
%li= filter_link_to 'Remote', remote: '1', local: nil
%li= filter_link_to t('admin.accounts.location.all'), local: nil, remote: nil
%li= filter_link_to t('admin.accounts.location.local'), local: '1', remote: nil
%li= filter_link_to t('admin.accounts.location.remote'), remote: '1', local: nil
.filter-subset
%strong Moderation
%strong= t('admin.accounts.moderation.title')
%ul
%li= filter_link_to 'All', silenced: nil, suspended: nil
%li= filter_link_to 'Silenced', silenced: '1'
%li= filter_link_to 'Suspended', suspended: '1'
%li= filter_link_to t('admin.accounts.moderation.all'), silenced: nil, suspended: nil
%li= filter_link_to t('admin.accounts.moderation.silenced'), silenced: '1'
%li= filter_link_to t('admin.accounts.moderation.suspended'), suspended: '1'
.filter-subset
%strong Order
%strong= t('admin.accounts.order.title')
%ul
%li= filter_link_to 'Alphabetic', recent: nil
%li= filter_link_to 'Most recent', recent: '1'
%li= filter_link_to t('admin.accounts.order.alphabetic'), recent: nil
%li= filter_link_to t('admin.accounts.order.most_recent'), recent: '1'
%table.table
%thead
%tr
%th Username
%th Domain
%th= t('admin.accounts.username')
%th= t('admin.accounts.domain')
%th= fa_icon 'paper-plane-o'
%th
%tbody
@ -36,14 +36,14 @@
= link_to account.domain, admin_accounts_path(by_domain: account.domain)
%td
- if account.local?
Local
= t('admin.accounts.location.local')
- elsif account.subscribed?
%i.fa.fa-check
- else
%i.fa.fa-times
%td
= table_link_to 'circle', 'Web', web_path("accounts/#{account.id}")
= table_link_to 'globe', 'Public', TagManager.instance.url_for(account)
= table_link_to 'pencil', 'Edit', admin_account_path(account.id)
= table_link_to 'circle', t('admin.accounts.web'), web_path("accounts/#{account.id}")
= table_link_to 'globe', t('admin.accounts.public'), TagManager.instance.url_for(account)
= table_link_to 'pencil', t('admin.accounts.edit'), admin_account_path(account.id)
= paginate @accounts

View file

@ -4,24 +4,24 @@
%table.table
%tbody
%tr
%th Username
%th= t('admin.accounts.username')
%td= @account.username
%tr
%th Domain
%th= t('admin.accounts.domain')
%td= @account.domain
%tr
%th Display name
%th= t('admin.accounts.display_name')
%td= @account.display_name
- if @account.local?
%tr
%th E-mail
%th= t('admin.accounts.email')
%td= @account.user.email
%tr
%th Most recent IP
%th= t('admin.accounts.most_recent_ip')
%td= @account.user.current_sign_in_ip
%tr
%th Most recent activity
%th= t('admin.accounts.most_recent_activity')
%td
- if @account.user.current_sign_in_at
= l @account.user.current_sign_in_at
@ -29,44 +29,44 @@
Never
- else
%tr
%th Profile URL
%th= t('admin.accounts.profile_url')
%td= link_to @account.url
%tr
%th Feed URL
%th= t('admin.accounts.feed_url')
%td= link_to @account.remote_url
%tr
%th PuSH subscription expires
%th= t('admin.accounts.push_subscription_expires')
%td
- if @account.subscribed?
= l @account.subscription_expires_at
- else
Not subscribed
= t('admin.accounts.not_subscribed')
%tr
%th Salmon URL
%th= t('admin.accounts.salmon_url')
%td= link_to @account.salmon_url
%tr
%th Follows
%th= t('admin.accounts.follows')
%td= @account.following_count
%tr
%th Followers
%th= t('admin.accounts.followers')
%td= @account.followers_count
%tr
%th Statuses
%th= t('admin.accounts.statuses')
%td= @account.statuses_count
%tr
%th Media attachments
%th= t('admin.accounts.media_attachments')
%td
= @account.media_attachments.count
= surround '(', ')' do
= number_to_human_size @account.media_attachments.sum('file_file_size')
- if @account.silenced?
= link_to 'Undo silence', unsilence_admin_account_path(@account.id), method: :post, class: 'button'
= link_to t('admin.accounts.undo_silenced'), admin_account_silence_path(@account.id), method: :delete, class: 'button'
- else
= link_to 'Silence', silence_admin_account_path(@account.id), method: :post, class: 'button'
= link_to t('admin.accounts.silence'), admin_account_silence_path(@account.id), method: :post, class: 'button'
- if @account.suspended?
= link_to 'Undo suspension', unsuspend_admin_account_path(@account.id), method: :post, class: 'button'
= link_to t('admin.accounts.undo_suspension'), admin_account_suspension_path(@account.id), method: :delete, class: 'button'
- else
= link_to 'Perform full suspension', suspend_admin_account_path(@account.id), method: :post, data: { confirm: 'Are you sure?' }, class: 'button'
= link_to t('admin.accounts.perform_full_suspension'), admin_account_suspension_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button'

View file

@ -1,11 +1,11 @@
- content_for :page_title do
Domain Blocks
= t('admin.domain_block.title')
%table.table
%thead
%tr
%th Domain
%th Severity
%th= t('admin.domain_block.domain')
%th= t('admin.domain_block.severity')
%tbody
- @blocks.each do |block|
%tr
@ -14,4 +14,4 @@
%td= block.severity
= paginate @blocks
= link_to 'Add new', new_admin_domain_block_path, class: 'button'
= link_to t('admin.domain_block.add_new'), new_admin_domain_block_path, class: 'button'

View file

@ -1,18 +1,14 @@
- content_for :page_title do
New domain block
= t('admin.domain_block.new.title')
= simple_form_for @domain_block, url: admin_domain_blocks_path do |f|
= render 'shared/error_messages', object: @domain_block
%p.hint The domain block will not prevent creation of account entries in the database, but will retroactively and automatically apply specific moderation methods on those accounts.
%p.hint= t('admin.domain_block.new.hint')
= f.input :domain, placeholder: 'Domain'
= f.input :severity, collection: DomainBlock.severities.keys, wrapper: :with_label, include_blank: false
= f.input :domain, placeholder: t('admin.domain_block.domain')
= f.input :severity, collection: DomainBlock.severities.keys, wrapper: :with_label, include_blank: false, label_method: lambda { |type| I18n.t("admin.domain_block.new.severity.#{type}") }
%p.hint
%strong Silence
will make the account's posts invisible to anyone who isn't following them.
%strong Suspend
will remove all of the account's content, media, and profile data.
%p.hint= t('admin.domain_block.new.severity.desc_html')
.actions
= f.button :button, 'Create block', type: :submit
= f.button :button, t('admin.domain_block.new.create'), type: :submit

View file

@ -1,14 +1,14 @@
- content_for :page_title do
PubSubHubbub
= t('admin.pubsubhubbub.title')
%table.table
%thead
%tr
%th Topic
%th Callback URL
%th Confirmed
%th Expires in
%th Last delivery
%th= t('admin.pubsubhubbub.topic')
%th= t('admin.pubsubhubbub.callback_url')
%th= t('admin.pubsubhubbub.confirmed')
%th= t('admin.pubsubhubbub.expires_in')
%th= t('admin.pubsubhubbub.last_delivery')
%tbody
- @subscriptions.each do |subscription|
%tr

View file

@ -1,12 +1,12 @@
- content_for :page_title do
= t('reports.reports')
= t('admin.reports.title')
.filters
.filter-subset
%strong= t('reports.status')
%strong= t('admin.reports.status')
%ul
%li= filter_link_to t('reports.unresolved'), action_taken: nil
%li= filter_link_to t('reports.resolved'), action_taken: '1'
%li= filter_link_to t('admin.reports.unresolved'), action_taken: nil
%li= filter_link_to t('admin.reports.resolved'), action_taken: '1'
= form_tag do
@ -14,10 +14,10 @@
%thead
%tr
%th
%th= t('reports.id')
%th= t('reports.target')
%th= t('reports.reported_by')
%th= t('reports.comment.label')
%th= t('admin.reports.id')
%th= t('admin.reports.target')
%th= t('admin.reports.reported_by')
%th= t('admin.reports.comment.label')
%th
%tbody
- @reports.each do |report|
@ -27,6 +27,6 @@
%td= link_to report.target_account.acct, admin_account_path(report.target_account.id)
%td= link_to report.account.acct, admin_account_path(report.account.id)
%td= truncate(report.comment, length: 30, separator: ' ')
%td= table_link_to 'circle', t('reports.view'), admin_report_path(report)
%td= table_link_to 'circle', t('admin.reports.view'), admin_report_path(report)
= paginate @reports

View file

@ -1,16 +1,16 @@
- content_for :page_title do
= t('reports.report', id: @report.id)
= t('admin.reports.report', id: @report.id)
.report-accounts
.report-accounts__item
%strong= t('reports.reported_account')
%strong= t('admin.reports.reported_account')
= render partial: 'authorize_follow/card', locals: { account: @report.target_account }
.report-accounts__item
%strong= t('reports.reported_by')
%strong= t('admin.reports.reported_by')
= render partial: 'authorize_follow/card', locals: { account: @report.account }
%p
%strong= t('reports.comment.label')
%strong= t('admin.reports.comment.label')
\:
= @report.comment.presence || t('reports.comment.none')
@ -22,7 +22,7 @@
.activity-stream.activity-stream-headless
.entry= render partial: 'stream_entries/simple_status', locals: { status: status }
.report-status__actions
= link_to remove_admin_report_path(@report, status_id: status.id), method: :post, class: 'icon-button', style: 'font-size: 24px; width: 24px; height: 24px', title: t('reports.delete') do
= link_to remove_admin_report_path(@report, status_id: status.id), method: :post, class: 'icon-button', style: 'font-size: 24px; width: 24px; height: 24px', title: t('admin.reports.delete') do
= fa_icon 'trash'
- if !@report.action_taken?
@ -30,10 +30,10 @@
%div{ style: 'overflow: hidden' }
%div{ style: 'float: right' }
= link_to t('reports.silence_account'), silence_admin_report_path(@report), method: :post, class: 'button'
= link_to t('reports.suspend_account'), suspend_admin_report_path(@report), method: :post, class: 'button'
= link_to t('admin.reports.silence_account'), silence_admin_report_path(@report), method: :post, class: 'button'
= link_to t('admin.reports.suspend_account'), suspend_admin_report_path(@report), method: :post, class: 'button'
%div{ style: 'float: left' }
= link_to t('reports.mark_as_resolved'), resolve_admin_report_path(@report), method: :post, class: 'button'
= link_to t('admin.reports.mark_as_resolved'), resolve_admin_report_path(@report), method: :post, class: 'button'
- elsif !@report.action_taken_by_account.nil?
%hr/

View file

@ -2,7 +2,7 @@
= t('auth.login')
= simple_form_for(resource, as: resource_name, url: session_path(resource_name), method: :post) do |f|
= f.input :otp_attempt, placeholder: t('simple_form.labels.defaults.otp_attempt'), input_html: { 'aria-label' => t('simple_form.labels.defaults.otp_attempt') }, required: true, autofocus: true, autocomplete: 'off'
= f.input :otp_attempt, type: :number, placeholder: t('simple_form.labels.defaults.otp_attempt'), input_html: { 'aria-label' => t('simple_form.labels.defaults.otp_attempt') }, required: true, autofocus: true, autocomplete: 'off'
.actions
= f.button :button, t('auth.login'), type: :submit

View file

@ -5,17 +5,17 @@
%tbody
%tr
%th= t('exports.storage')
%td= number_to_human_size @total_storage
%td= number_to_human_size @export.total_storage
%td
%tr
%th= t('exports.follows')
%td= @total_follows
%td= @export.total_follows
%td= table_link_to 'download', t('exports.csv'), settings_exports_follows_path(format: :csv)
%tr
%th= t('exports.blocks')
%td= @total_blocks
%td= @export.total_blocks
%td= table_link_to 'download', t('exports.csv'), settings_exports_blocks_path(format: :csv)
%tr
%th= t('exports.mutes')
%td= @total_mutes
%td= @export.total_mutes
%td= table_link_to 'download', t('exports.csv'), settings_exports_mutes_path(format: :csv)

View file

@ -11,7 +11,7 @@
- else
%meta{ property: 'og:description', content: @stream_entry.activity.content }/
- if @stream_entry.activity.is_a?(Status) && @stream_entry.activity.media_attachments.size > 0
- if @stream_entry.activity.is_a?(Status) && !@stream_entry.activity.sensitive? && @stream_entry.activity.media_attachments.size > 0
%meta{ property: 'og:image', content: full_asset_url(@stream_entry.activity.media_attachments.first.file.url(:small)) }/
- else
%meta{ property: 'og:image', content: full_asset_url(@account.avatar.url(:original)) }/

View file

@ -24,9 +24,9 @@ module Mastodon
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
config.i18n.available_locales = [
:en,
:bg,
:de,
:eo,
:es,
@ -34,6 +34,7 @@ module Mastodon
:fr,
:hu,
:ja,
:nl,
:no,
:pt,
:ru,

View file

@ -104,7 +104,8 @@ Rails.application.configure do
:enable_starttls_auto => ENV['SMTP_ENABLE_STARTTLS_AUTO'] || true,
}
config.action_mailer.delivery_method = :smtp
config.action_mailer.delivery_method = ENV.fetch('SMTP_DELIVERY_METHOD', 'smtp').to_sym
config.react.variant = :production

View file

@ -4,7 +4,7 @@ Paperclip.options[:read_timeout] = 60
Paperclip.interpolates :filename do |attachment, style|
return attachment.original_filename if style == :original
[basename(attachment, style), extension(attachment, style)].delete_if(&:empty?).join('.')
[basename(attachment, style), content_type_extension(attachment, style)].delete_if(&:empty?).join('.')
end
if ENV['S3_ENABLED'] == 'true'

169
config/locales/bg.yml Normal file
View file

@ -0,0 +1,169 @@
---
bg:
about:
about_mastodon: Mastodon е <em>безплатен</em> сървър с <em>отворен код</em> за социални мрежи. Като <em>децентрализирана</em> алтернатива на комерсиалните платформи, той позволява избягването на риска от монополизация на твоята комуникация от единични компании. Изберете си сървър, на който се доверявате, и ще можете да контактувате с всички останали. Всеки може да пусне Mastodon и лесно да вземе участие в <em>социалната мрежа</em>.
about_this: За тази инстанция
apps: Приложения
business_email: 'Служебен e-mail:'
closed_registrations: В момента регистрациите за тази инстанция са затворени.
contact: За контакти
description_headline: Какво е %{domain}?
domain_count_after: други инстанции
domain_count_before: Свързани към
features:
api: Отворено API за приложения и услуги
blocks: Богат на инструменти за блокиране и заглушаване
characters: Публикации от 500 символа
chronology: Публикациите се показват хронологично
ethics: 'Етичен дизайн: без реклами и проследяване'
gifv: GIFV комплекти и кратки видео клипове
privacy: Настройване на поверителността за всяка публикация
public: Публични канали
features_headline: Какво откроява Mastodon
get_started: Първи стъпки
links: Връзки
other_instances: Други инстанции
source_code: Програмен код
status_count_after: публикации
status_count_before: Написали
terms: Условия
user_count_after: потребители
user_count_before: Дом на
accounts:
follow: Последвай
followers: Последователи
following: Следва
nothing_here: Тук няма никого!
people_followed_by: Хора, които %{name} следва
people_who_follow: Хора, които следват %{name}
posts: Публикации
remote_follow: Последвай
unfollow: Не следвай
application_mailer:
settings: 'Промяна на предпочитанията за e-mail: %{link}'
signature: Mastodon известия от %{instance}
view: 'Преглед:'
applications:
invalid_url: Предоставеният URL е невалиден
auth:
change_password: Идентификационни данни
didnt_get_confirmation: Не получих инструкции за потвърждение
forgot_password: Забравих си паролата
login: Влизане
logout: Излизане
register: Регистрация
resend_confirmation: Изпрати отново инструкции за потвърждение
reset_password: Подновяване на паролата
set_new_password: Задай нова парола
authorize_follow:
error: Възникна грешка в откриването на потребителя
follow: Последвай
prompt_html: "(<strong>%{self}</strong>), молбата ти беше изпратена до:"
title: Последвай %{acct}
datetime:
distance_in_words:
about_x_hours: "%{count} ч."
about_x_months: "%{count} м."
about_x_years: "%{count} г."
almost_x_years: "%{count} г."
half_a_minute: Току-що
less_than_x_minutes: "%{count} мин."
less_than_x_seconds: Току-що
over_x_years: "%{count} г."
x_days: "%{count} дни"
x_minutes: "%{count} мин."
x_months: "%{count} м."
x_seconds: "%{count} сек."
exports:
blocks: Вашите блокирания
csv: CSV
follows: Вашите следвания
storage: Съхранение на мултимедия
generic:
changes_saved_msg: Успешно запазване на промените!
powered_by: поддържано от %{link}
save_changes: Запази промените
validation_errors:
one: Нещо все още не е наред! Моля, прегледай грешката по-долу
other: Нещо все още не е наред! Моля, прегледай грешките по-долу
imports:
preface: Можеш да импортираш някои данни, като например всички хора, които следваш или блокираш в акаунта си на тази инстанция, от файлове, създадени чрез експорт в друга инстанция.
success: Твоите данни бяха успешно качени и ще бъдат обработени впоследствие.
types:
blocking: Списък на блокираните
following: Списък на последователите
upload: Качване
landing_strip_html: <strong>%{name}</strong> е потребител от <strong>%{domain}</strong>. Можеш да ги следваш, или да контактуваш с тях, ако имаш акаунт където и да е из федерираната вселена на Mastodon. Ако нямаш акаунт, можеш да си <a href="%{sign_up_path}">създадеш ето тук</a>.
media_attachments:
validations:
images_and_video: Не мога да прикача видеоклип към публикация, която вече съдържа изображения
too_many: Не мога да прикача повече от 4 файла
notification_mailer:
digest:
body: 'Ето кратко резюме на нещата, които се случиха от последното ти посещение в %{instance} на %{since}:'
mention: "%{name} те спомена в:"
new_followers_summary:
one: Имаш един нов последовател! Ура!
other: Имаш %{count} нови последователи! Изумително!
subject:
one: "1 ново известие от последното ти посещение \U0001F418"
other: "%{count} нови известия от последното ти посещение \U0001F418"
favourite:
body: 'Публикацията ти беше харесана от %{name}:'
subject: "%{name} хареса твоята публикация"
follow:
body: "%{name} те последва!"
subject: "%{name} те последва"
follow_request:
body: "%{name} помоли за разрешение да те последва"
subject: 'Чакащ последовател: %{name}'
mention:
body: "%{name} те спомена в:"
subject: "%{name} те спомена"
reblog:
body: 'Твоята публикация беше споделена от %{name}:'
subject: "%{name} сподели публикацията ти"
pagination:
next: Напред
prev: Назад
remote_follow:
acct: Въведи потребителско_име@домейн, от които искаш да следваш
missing_resource: Неуспешно търсене на нужния URL за пренасочване за твоя акаунт
proceed: Започни следване
prompt: 'Ще последваш:'
settings:
authorized_apps: Упълномощени приложения
back: Обратно към Mastodon
edit_profile: Редактирай профила си
export: Експортиране на данни
import: Импортиране
preferences: Предпочитания
settings: Настройки
two_factor_auth: Двустепенно удостоверяване
statuses:
open_in_web: Отвори в уеб
over_character_limit: прехвърлен лимит от %{max} символа
show_more: Покажи повече
visibilities:
private: Покажи само на последователите си
public: Публично
unlisted: Публично, но не показвай в публичния канал
stream_entries:
click_to_show: Покажи
reblogged: споделено
sensitive_content: Деликатно съдържание
time:
formats:
default: "%d %b, %Y, %H:%M"
two_factor_auth:
description_html: При активация на <strong>двустепенно удостоверяване</strong>, за да влезеш в приложението, ще трябва да използваш телефона си. През него ще се генерира код, който да въвеждаш при влизане.
disable: Деактивирай
enable: Активирай
instructions_html: "<strong>Сканирай този QR код с Google Authenticator или подобно приложение от своя телефон</strong>. Oтсега нататък, това приложение ще генерира код, който ще трябва да въвеждаш при всяко влизане."
plaintext_secret_html: 'Тайна в обикновен текст: <samp>%{secret}</samp>'
warning: Ако не можеш да настроиш приложението за удостверяване сега, избери "Деактивирай". В противен случай, няма да можеш да влезеш в акаунта си.
users:
invalid_email: E-mail адресът е невалиден
invalid_otp_token: Невалиден код
will_paginate:
page_gap: "&hellip;"

View file

@ -0,0 +1,61 @@
---
bg:
devise:
confirmations:
confirmed: Твоят профил беше успешно потвърден. Влизането в профила е успешно.
send_instructions: Ще получиш писмо с инструкции как да потвърдиш своя профил до няколко минути.
send_paranoid_instructions: Ако твоят имейл адрес съществува в базата ни, ще получиш там инструкции как да потвърдиш своя профил.
failure:
already_authenticated: Вече си вътре в профила си.
inactive: Профилът ти все още не е активиран.
invalid: Невалиден имейл адрес или парола.
last_attempt: Разполагаш с още един опит преди профилът ти да бъде заключен.
locked: Профилът ти е заключен.
not_found_in_database: "Невалидни стойности за %{authentication_keys} или парола."
timeout: Сесията ти изтече, моля влез отново, за да продължиш.
unauthenticated: Преди да продължиш, трябва да влезеш в профила си или да се регистрираш.
unconfirmed: Преди да продължиш, трябва да потвърдиш регистрацията си.
mailer:
confirmation_instructions:
subject: 'Mastodon: Инструкции за потвърждаване'
password_change:
subject: 'Mastodon: Паролата е променена'
reset_password_instructions:
subject: 'Инструкции за смяна на паролата'
unlock_instructions:
subject: 'Инструкции за отключване'
omniauth_callbacks:
failure: "Не успяхме да те упълномощим чрез %{kind}, защото \"%{reason}\"."
success: "Успешно упълномощаване чрез %{kind} профил."
passwords:
no_token: Може да достъпваш тази страница само от имейл за промяна на паролата. Ако тази страница е отворена от такъв имейл, увери се, че използваш целия URL-адрес, който сме ти изпратили.
send_instructions: Ще получиш писмо с инструкции как да промениш паролата си до няколко минути.
send_paranoid_instructions: Ако твоят имейл адрес съществува в базата ни, ще получиш там инструкции за промяна на своята парола.
updated: Паролата ти беше променена успешно. Влизането в профила е успешно.
updated_not_active: Паролата ти беше променена успешно.
registrations:
destroyed: Довиждане! Твоят профил беше успешно изтрит. Надяваме се скоро да те видим отново.
signed_up: Привет! Регистрирацията ти е успешна.
signed_up_but_inactive: Регистрирацията ти е успешна. Въпреки това, не можеш да влезеш в профила си, защото той все още не е потвърден.
signed_up_but_locked: Регистрирацията ти е успешна. Въпреки това, не можеш да влезеш в профила си, защото той е заключен.
signed_up_but_unconfirmed: Писмо с връзка за потвърждаване на профила ти беше изпратено на твоя имейл адрес. Моля, отвори връзката, за да активираш своя профил.
update_needs_confirmation: Профилът ти е успешно променен, но ние трябва да проверим твоя нов имейл адрес. Моля, провери пощата си и отвори връзката за потвърждаване на новия адрес.
updated: Профилът ти е успешно променен.
sessions:
already_signed_out: Успешно излизане от профила.
signed_in: Успешно влизане.
signed_out: Успешно излизане.
unlocks:
send_instructions: Ще получиш писмо с инструкции как да отключиш профила си до няколко минути.
send_paranoid_instructions: Ако твоят профил съществува в базата ни, на своя имейл адрес ще получиш инструкции за отключването му до няколко минути.
unlocked: Твоят профил беше отключен успешно. За да продължиш, влез в него.
errors:
messages:
already_confirmed: е вече потвърден, моля опитай да влезеш в профила си с него
confirmation_period_expired: "трябва да се потвърди в рамките на %{period}, моля направи нова заявка за потвърждение"
expired: е изтекъл, моля заяви нов
not_found: не е намерен
not_locked: не бе заключен
not_saved:
one: "Една грешка попречи този %{resource} да бъде записан:"
other: "%{count} грешки попречиха този %{resource} да бъде записан:"

View file

@ -0,0 +1,60 @@
---
hr:
devise:
confirmations:
already_authenticated: Već si prijavljen.
confirmed: Tvoja email adresa je uspješno potvrđena.
inactive: Tvoj račun još nije aktiviran.
invalid: Nevaljan %{authentication_keys} ili lozinka.
last_attempt: Imaš još jedan pokušaj prije no što ti se račun zaključa.
locked: Tvoj račun je zaključan.
not_found_in_database: Nevaljani %{authentication_keys} ili lozinka.
send_instructions: Primit ćeš email sa uputama kako potvrditi svoju email adresu za nekoliko minuta.
send_paranoid_instructions: Ako tvoja email adresa postoji u našoj bazi podataka, primit ćeš email sa uputama kako ju potvrditi za nekoliko minuta.
timeout: Tvoja sesija je istekla. Molimo te, prijavi se ponovo kako bi nastavio.
unauthenticated: Moraš se registrirati ili prijaviti prije no što nastaviš.
unconfirmed: Moraš potvrditi svoju email adresu prije no što nastaviš.
mailer:
confirmation_instructions:
subject: 'Mastodon: Upute za potvrđivanje'
password_change:
subject: 'Mastodon: Lozinka je promijenjena'
reset_password_instructions:
subject: 'Mastodon: Upute za resetiranje lozinke'
unlock_instructions:
subject: 'Mastodon: Upute za otključavanje'
omniauth_callbacks:
failure: Ne možemo te autentificirati sa %{kind} zbog "%{reason}".
success: Uspješno autentificiran sa %{kind} računa.
passwords:
no_token: Ne možeš pristupiti ovoj stranici bez dolaženja sa emaila za resetiranje lozinke. Ako dolaziš sa tog emaila, pazi da koristiš potpuni link koji ti je dan.
send_instructions: Primit ćeš email sa uputama kako resetirati svoju lozinku za nekoliko minuta.
send_paranoid_instructions: Ako tvoja email adresa postoji u našoj bazi podataka, primit ćeš link za povrat lozinke na svoju email adresu za nekoliko minuta.
updated: Tvoja lozinka je uspješno izmijenjena. Sada si prijavljen.
updated_not_active: Toja lozinka je uspješno izmijenjena.
registrations:
destroyed: Zbogom! Tvoj račun je uspješno otkazan. Nadamo se da ćemo te vidjeti ponovo.
signed_up: Dobro došao! Uspješno si se prijavio.
signed_up_but_inactive: Uspješno si se registrirao. No, ne možeš se prijaviti, jer ti račun još nije aktiviran.
signed_up_but_locked: Uspješno si se registrirao. No, ne možeš se prijaviti jer je tvoj račun zaključan.
signed_up_but_unconfirmed: Poruka sa linkom za potvrđivanje je poslana na tvoju email adresu. Molimo, slijedi link kako bi tvoj račun bio aktiviran.
update_needs_confirmation: Tvoj račun je uspješno ažuriran, ali trebamo provjeriti tvoju novu email adresu. Molimo, provjeri svoj email i slijedi link za potvrđivanje kako bi tvoja nova email adresa bila potvrđena.
updated: Tvoj račun je uspješno ažuriran.
sessions:
already_signed_out: Uspješno si odjavljen.
signed_in: Uspješno si prijavljen.
signed_out: Uspješno si odjavljen.
unlocks:
send_instructions: Primit ćeš email sa uputama kako otključati svoj račun za nekoliko minuta.
send_paranoid_instructions: Ako tvoj račun postoji, primit ćeš email sa uputama kako ga otključati za nekoliko minuta.
unlocked: Tvoj račun je uspješno otključan. Prijavi se kako bi nastavio.
errors:
messages:
already_confirmed: je već potvrđen, pokušaj se prijaviti
confirmation_period_expired: mora biti potvrđen u roku od %{period}, molimo zatraži novi
expired: je istekao, zatraži novu
not_found: nije nađen
not_locked: nije zaključan
not_saved:
one: '1 greška je zabranila da ovaj %{resource} bude sačuvan:'
other: "%{count} greške su zabranile da ovaj %{resource} bude sačuvan:"

View file

@ -0,0 +1,59 @@
---
nl:
devise:
confirmations:
confirmed: Je account is bevestigd.
send_instructions: Je ontvangt via e-mail instructies hoe je je account kan bevestigen.
send_paranoid_instructions: Als je e-mailadres bestaat in de database, ontvang je via e-mail instructies hoe je je account kan bevestigen.
failure:
already_authenticated: Je bent al ingelogd.
inactive: Je account is nog niet geactiveerd.
invalid: Ongeldig e-mail of wachtwoord.
invalid_token: Invalide authenticiteit token.
last_attempt: Je hebt nog een poging over voordat je account wordt geblokkeerd.
locked: Je account is gelocked.
not_found_in_database: Ongeldig e-mail of wachtwoord.
timeout: Je sessie is verlopen, log a.u.b. opnieuw in.
unauthenticated: Je dient in te loggen of je in te schrijven.
unconfirmed: Je dient eerst je account te bevestigen.
mailer:
confirmation_instructions:
subject: Bevestiging mailadres
reset_password_instructions:
subject: Wachtwoord resetten
unlock_instructions:
subject: Unlock instructies
omniauth_callbacks:
failure: Kon je niet aanmelden met je %{kind} account, omdat "%{reason}".
success: Successvol aangemeld met je %{kind} account.
passwords:
no_token: Je kan deze pagina niet benaderen zonder een "wachtwoord reset e-mail"
send_instructions: Je ontvangt via e-mail instructies hoe je je wachtwoord moet resetten.
send_paranoid_instructions: Als je e-mailadres bestaat in de database, ontvang je via e-mail instructies hoe je je wachtwoord moet resetten.
updated: Je wachtwoord is gewijzigd. Je bent nu ingelogd.
updated_not_active: Je wachtwoord is gewijzigd.
registrations:
destroyed: Je account is verwijderd, wellicht tot ziens!
signed_up: Je bent ingeschreven.
signed_up_but_inactive: Je bent ingeschreven. Je kon alleen niet automatisch ingelogd worden omdat je account nog niet geactiveerd is.
signed_up_but_locked: Je bent ingeschreven. Je kon alleen niet automatisch ingelogd worden omdat je account geblokkeerd is.
signed_up_but_unconfirmed: Je ontvangt via e-mail instructies hoe je je account kunt activeren.
update_needs_confirmation: Je hebt je e-mailadres succesvol gewijzigd, maar we moeten je nieuwe mailadres nog verifiëren. Controleer je e-mail en klik op de link in de mail om je mailadres te verifiëren.
updated: Je account gegevens zijn opgeslagen.
sessions:
signed_in: Je bent succesvol ingelogd.
signed_out: Je bent succesvol uitgelogd.
unlocks:
send_instructions: Je ontvangt via e-mail instructies hoe je je account kan unlocken.
send_paranoid_instructions: Als je e-mailadres bestaat in de database, ontvang je via e-mail instructies hoe je je account kan unlocken.
unlocked: Je account is ge-unlocked. Je kan nu weer inloggen.
errors:
messages:
already_confirmed: is reeds bevestigd
confirmation_period_expired: moet worden bevestigd binnen %{period}, probeer het a.u.b. nog een keer
expired: is verlopen, vraag een nieuwe aan
not_found: niet gevonden
not_locked: is niet gesloten
not_saved:
one: '1 fout blokkeerde het opslaan van deze %{resource}:'
other: "%{count} fouten blokkeerden het opslaan van deze %{resource}:"

View file

@ -0,0 +1,113 @@
---
bg:
activerecord:
attributes:
doorkeeper/application:
name: Име
redirect_uri: URI за пренасочване
errors:
models:
doorkeeper/application:
attributes:
redirect_uri:
fragment_present: не може да съдържа фрагмент.
invalid_uri: трябва да е валидно URI.
relative_uri: трябва да е абсолютно URI.
secured_uri: трябва да е HTTPS/SSL URI.
doorkeeper:
applications:
buttons:
authorize: Упълномощаване
cancel: Отказ
destroy: Унищожаване
edit: Редакция
submit: Изпращане
confirmations:
destroy: Потвърждаваш ли изтриването?
edit:
title: Редактиране на приложението
form:
error: О, не! Провери формата за възможни грешки
help:
native_redirect_uri: Изполвай %{native_redirect_uri} за локални тестове
redirect_uri: Използвай един ред за всяко URI
scopes: Разделяй диапазоните с интервал. Остави празно, за да използваш диапазона по подразбиране.
index:
callback_url: URL за обратно повикване
name: Име
new: Ново приложение
title: Твоите приложения
new:
title: Ново приложение
show:
actions: Действия
application_id: Идентификатор на приложението
callback_urls: URL-и за обратно повикване
scopes: Диапазони
secret: Тайна
title: 'Приложение: %{name}'
authorizations:
buttons:
authorize: Упълномощаване
deny: Отказ
error:
title: Възникна грешка
new:
able_to: Ще е възможно
prompt: Приложението %{client_name} заявява достъп до твоя акаунт
title: Изисква се упълномощаване
show:
title: Код за упълномощаване
authorized_applications:
buttons:
revoke: Отмяна
confirmations:
revoke: Потвърждаваш ли отмяната?
index:
application: Приложение
created_at: Създадено на
date_format: "%Y-%m-%d %H:%M:%S"
scopes: Диапазони
title: Твоите упълномощени приложения
errors:
messages:
access_denied: Заявката беше отказана от собственика на ресурса или от сървъра за упълномощаване.
credential_flow_not_configured: Resource Owner Password Credentials предизвика грешка, заради това, че настройките за Doorkeeper.configure.resource_owner_from_credentials липсват.
invalid_client: Удостоверяването на клиента предизвика грешка, поради непознат клиент, липсващо клиентско удостоверяване, или заради това, че методът на удостоверяване не се поддържа.
invalid_grant: Предоставеното удостоверение за достъп е невалидно, изтекло, отхвърлено, не съвпада с пренасочващото URI, използвано в заявката за удостоверение, или е бил издадено от друг клиент.
invalid_redirect_uri: Наличното пренасочващо URI е невалидно.
invalid_request: Заявката е с липсващ задължителен параметър, включва стойност на параметъра, която не се поддържа, или е изкривена по друг начин.
invalid_resource_owner: Предоставените идентификационни данни на притежателя на ресурса са невалидни, или притежателят не може да бъде намерен.
invalid_scope: Заявеният диапазон е невалиден, неизвестен или изкривен.
invalid_token:
expired: Маркерът за достъп изтече
revoked: Маркерът за достъп беше отхвърлен
unknown: Маркерът за достъп е невалиден
resource_owner_authenticator_not_configured: Намирането на Resource Owner се провали поради липса на конфигурация на Doorkeeper.configure.resource_owner_authenticator.
server_error: Сървърът за удостоверяване попадна на неочаквано условие, което предотврати изпълнението на заявката.
temporarily_unavailable: Сървърът за удостоверяване не може да се справи със заявката в момента поради временно претоварване или профилактика на сървъра.
unauthorized_client: Клиентът не е удостоверен да изпълни заявката по този начин.
unsupported_grant_type: Типът на удостоврението за достъп не се поддържа от сървъра за удостоверяване.
unsupported_response_type: Удостоверяващият сървър не поддържа този тип отговор.
flash:
applications:
create:
notice: Приложението е създадено.
destroy:
notice: Приложението е изтрито.
update:
notice: Приложението е обновено.
authorized_applications:
destroy:
notice: Приложението е отказано.
layouts:
admin:
nav:
applications: Приложения
oauth2_provider: OAuth2 доставчик
application:
title: Нужно е упълномощаване по OAuth
scopes:
follow: следването, блокирането, деблокирането и отмяната на следването на акаунтите
read: четенето на данните от твоя акаунт
write: публикуването от твое име

View file

@ -13,7 +13,16 @@ fr:
name: Nom
redirect_uri: L'URL de redirection
errors:
messages:
record_invalid: Données invalides
models:
account:
attributes:
note:
too_long: Description trop longue
username:
blank: Identifiant vide
taken: Identifiant déjà pris
doorkeeper/application:
attributes:
redirect_uri:
@ -21,23 +30,17 @@ fr:
invalid_uri: doit être une URL valide.
relative_uri: doit être une URL absolue.
secured_uri: doit être une URL HTTP/SSL.
account:
attributes:
username:
blank: Identifiant vide
user:
attributes:
email:
taken: Email pris
invalid: Email invalide
blank: Email vide
invalid: Email invalide
taken: Email pris
password:
blank: Mot de passe vide
too_short: Mot de passe trop court
password_confirmation:
confirmation: Le mot de passe ne correspond pas
messages:
record_invalid: Données invalides
doorkeeper:
applications:
buttons:

View file

@ -0,0 +1,113 @@
---
hr:
activerecord:
attributes:
doorkeeper/application:
name: Ime
redirect_uri: Redirect URI
errors:
models:
doorkeeper/application:
attributes:
redirect_uri:
fragment_present: ne može sadržavati fragment.
invalid_uri: mora biti valjan URI.
relative_uri: mora biti apsolutan URI.
secured_uri: mora biti HTTPS/SSL URI.
doorkeeper:
applications:
buttons:
authorize: Odobri
cancel: Otkaži
destroy: Uništi
edit: Uredi
submit: Pošalji
confirmations:
destroy: Jesi li siguran?
edit:
title: Uredi aplikaciju
form:
error: Ups! Provjeri svoju formu za moguće greške
help:
native_redirect_uri: Koristi %{native_redirect_uri} za lokalne testove
redirect_uri: Koristi jednu liniju po URI
scopes: Odvoji scopes sa razmacima. Ostavi prazninu kako bi koristio zadane scopes.
index:
callback_url: Callback URL
name: Ime
new: Nova Aplikacija
title: Tvoje aplikacije
new:
title: Nova Aplikacija
show:
actions: Akcije
application_id: Id Aplikacije
callback_urls: Callback urls
scopes: Scopes
secret: Tajna
title: 'Aplikacija: %{name}'
authorizations:
buttons:
authorize: Odobri
deny: Odbij
error:
title: Došlo je do greške
new:
able_to: Moći će
prompt: Aplikacija %{client_name} je zatražila pristup tvom računu
title: Traži se autorizacija
show:
title: Autorizacijski kod
authorized_applications:
buttons:
revoke: Odbij
confirmations:
revoke: Jesi li siguran?
index:
application: Aplikacija
created_at: Ovlašeno
date_format: "%Y-%m-%d %H:%M:%S"
scopes: Scopes
title: Tvoje autorizirane aplikacije
errors:
messages:
access_denied: Vlasnik resursa / autorizacijski server je odbio zahtjev.
credential_flow_not_configured: Resource Owner Password Credentials flow failed due to Doorkeeper.configure.resource_owner_from_credentials being unconfigured.
invalid_client: Autentifikacija klijenta nije uspjela zbog nepoznatog klijenta, neuključene autentifikacije od strane klijenta, ili nepodržane metode autentifikacije.
invalid_grant: The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.
invalid_redirect_uri: The redirect uri included nije valjan.
invalid_request: Zahtjevu nedostaje traženi parametar, uključuje nepodržanu vrijednost parametra, ili je na neki drugi način neispravno formiran.
invalid_resource_owner: The provided resource owner credentials nisu valjani, ili vlasnik resursa ne može biti nađen
invalid_scope: Traženi scope nije valjan, znan, ili je neispravno oblikovan.
invalid_token:
expired: Pristupni token je istekao
revoked: Pristupni token je odbijen
unknown: Pristupni token nije valjan
resource_owner_authenticator_not_configured: Resource Owner find failed due to Doorkeeper.configure.resource_owner_authenticator being unconfiged.
server_error: Autorizacijski server naišao je na neočekivani uvjet, što ga je onemogućilo da ispuni zahtjev.
temporarily_unavailable: Autorizacijski server trenutno nije u mogućnosti izvesti zahtjev zbog privremenog preopterećenja ili održavanja servera.
unauthorized_client: Klijent nije ovlašten izvesti zahtjev koristeći ovu metodu.
unsupported_grant_type: The authorization grant tip nije podržan od autorizacijskog servera.
unsupported_response_type: Autorizacijski server ne podržava ovaj tip odgovora.
flash:
applications:
create:
notice: Aplikacija je stvorena.
destroy:
notice: Aplikacija je obrisana.
update:
notice: Aplikacija je ažurirana.
authorized_applications:
destroy:
notice: Aplikacija je odbijena.
layouts:
admin:
nav:
applications: Aplikacije
oauth2_provider: OAuth2 Provider
application:
title: Traži se OAuth autorizacija
scopes:
follow: slijediti, blokirati, deblokirati i prestati slijediti račune
read: čitati podatke tvog računa
write: slati poruke u tvoje ime

View file

@ -25,7 +25,7 @@ ja:
confirmations:
destroy: 本当に削除しますか?
edit:
title: アプリケーションの編集
title: アプリの編集
form:
error: フォームにエラーが無いか確認してください。
help:
@ -35,17 +35,17 @@ ja:
index:
callback_url: コールバックURL
name: 名前
new: 新規アプリケーション
title: あなたのアプリケーション
new: 新規アプリ
title: アプリ
new:
title: 新規アプリケーション
title: 新規アプリ
show:
actions: アクション
application_id: アクションId
callback_urls: コールバックurl
scopes: アクセス権
secret: 非公開
title: 'アプリケーション: %{name}'
title: 'アプリ: %{name}'
authorizations:
buttons:
authorize: 承認
@ -53,8 +53,8 @@ ja:
error:
title: エラーが発生しました。
new:
able_to: このアプリケーションは以下のことができます
prompt: アプリケーション %{client_name} があなたのアカウントへのアクセスを要求しています。
able_to: このアプリは以下のことができます
prompt: アプリ %{client_name} があなたのアカウントへのアクセスを要求しています。
title: 認証が必要です。
show:
title: 認証コード
@ -68,7 +68,7 @@ ja:
created_at: 許可した日時
date_format: "%Y年%m月%d日 %H時%M分%S秒"
scopes: アクセス権
title: 認証済みアプリケーション
title: 認証済みアプリ
errors:
messages:
access_denied: リソースの所有者または認証サーバーが要求を拒否しました。
@ -92,22 +92,22 @@ ja:
flash:
applications:
create:
notice: アプリケーションが作成されました。
notice: アプリが作成されました。
destroy:
notice: アプリケーションが削除されました。
notice: アプリが削除されました。
update:
notice: アプリケーションが更新されました。
notice: アプリが更新されました。
authorized_applications:
destroy:
notice: アプリケーションが取り消されました。
notice: アプリが取り消されました。
layouts:
admin:
nav:
applications: アプリケーション
applications: アプリ
oauth2_provider: OAuth2プロバイダー
application:
title: OAuth認証が必要です。
title: OAuth認証
scopes:
follow: アカウントのフォロー, ブロック, ブロック解除, フォロー解除
read: アカウントのデータの読み取り
write: アカウントからの投稿の書き込み
read: アカウントからのデータの読み取り
write: アカウントへのデータの書き込み

View file

@ -0,0 +1,114 @@
---
nl:
activerecord:
attributes:
doorkeeper/application:
name: Naam
redirect_uri: Redirect URI
scopes: Scopes
errors:
models:
doorkeeper/application:
attributes:
redirect_uri:
fragment_present: kan geen fragment bevatten.
invalid_uri: moet een geldige URI zijn.
relative_uri: moet een absolute URI zijn.
secured_uri: moet een HTTPS/SSL URI zijn.
doorkeeper:
applications:
buttons:
authorize: Autoriseren
cancel: Annuleren
destroy: Verwijderen
edit: Bewerken
submit: Opslaan
confirmations:
destroy: Weet je het zeker?
edit:
title: Bewerk applicatie
form:
error: Oops! Controleer het formulier op fouten
help:
native_redirect_uri: Gebruik %{native_redirect_uri} voor lokale tests
redirect_uri: 'Gebruik één regel per URI. '
scopes: Scheid scopes met spaties. Laat leeg om de standaard scopes te gebruiken.
index:
callback_url: Callback URL
name: Naam
new: Nieuwe applicatie
title: Jouw applicaties
new:
title: Nieuwe applicatie
show:
actions: Acties
application_id: Applicatie Id
callback_urls: Callback urls
scopes: Scopes
secret: Secret
title: 'Applicatie: %{name}'
authorizations:
buttons:
authorize: Autoriseren
deny: Weigeren
error:
title: Er is een fout opgetreden
new:
able_to: Deze applicatie zal in staat zijn om
prompt: "%{client_name} autoriseren om uw account te gebruiken?"
title: Autorisatie vereist
show:
title: Autorisatie code
authorized_applications:
buttons:
revoke: Intrekken
confirmations:
revoke: Weet je het zeker?
index:
application: Applicatie
created_at: Aangemaakt op
date_format: "%d-%m-%Y %H:%M:%S"
title: Jouw geautoriseerde applicaties
errors:
messages:
access_denied: De resource eigenaar of autorisatie-server weigerde het verzoek.
credential_flow_not_configured: Resource Owner Password Credentials flow failed due to Doorkeeper.configure.resource_owner_from_credentials being unconfigured.
invalid_client: Client verificatie is mislukt door onbekende klant, geen client authenticatie opgegeven, of een niet-ondersteunde authenticatie methode.
invalid_grant: De verstrekte autorisatie is ongeldig, verlopen, ingetrokken, komt niet overeen met de redirect uri die is opgegeven, of werd uitgegeven aan een andere klant.
invalid_redirect_uri: De opgegeven redirect uri is niet geldig.
invalid_request: Het verzoek mist een vereiste parameter, bevat een niet-ondersteunde parameter waarde of is anderszins onjuist.
invalid_resource_owner: De verstrekte resource eigenaar gegevens zijn niet geldig of de resource eigenaar kan niet worden gevonden
invalid_scope: De opgevraagde scope is niet geldig, onbekend of onjuist.
invalid_token:
expired: Het toegangstoken is verlopen
revoked: Het toegangstoken is geweigerd
unknown: Het toegangstoken is ongeldig
resource_owner_authenticator_not_configured: Resource Owner find failed due to Doorkeeper.configure.resource_owner_authenticator being unconfiged.
server_error: De autorisatieserver is een onverwachte voorwaarde tegengekomen die het verzoek verhinderd.
temporarily_unavailable: De autorisatieserver is momenteel niet in staat het verzoek te behandelen als gevolg van een tijdelijke overbelasting of onderhoud aan de server.
unauthorized_client: De client is niet bevoegd om dit verzoek met deze methode uit te voeren.
unsupported_grant_type: Het type autorisatie is niet ondersteund door de autorisatieserver
unsupported_response_type: De autorisatieserver ondersteund dit response type niet
flash:
applications:
create:
notice: Applicatie aangemaakt.
destroy:
notice: Applicatie verwijderd.
update:
notice: Applicatie bewerkt.
authorized_applications:
destroy:
notice: Applicatie ingetrokken.
layouts:
admin:
nav:
applications: Applicaties
home: Home
oauth2_provider: OAuth2 Provider
application:
title: OAuth autorisatie vereist
scopes:
follow: volg, blokkeer, deblokkeer en stop volgen accounts
read: lees je accountgegevens
write: plaatsen namens jou

View file

@ -39,6 +39,108 @@ en:
posts: Posts
remote_follow: Remote follow
unfollow: Unfollow
admin:
accounts:
are_you_sure: Are you sure?
display_name: Display name
domain: Domain
edit: Edit
email: E-mail
feed_url: Feed URL
followers: Followers
follows: Follows
location:
all: All
local: Local
remote: Remote
title: Location
media_attachments: Media attachments
moderation:
all: All
silenced: Silenced
suspended: Suspended
title: Moderation
most_recent_activity: Most recent activity
most_recent_ip: Most recent IP
not_subscribed: Not subscribed
order:
alphabetic: Alphabetic
most_recent: Most recent
title: Order
perform_full_suspension: Perform full suspension
profile_url: Profile URL
public: Public
push_subscription_expires: PuSH subscription expires
salmon_url: Salmon URL
silence: Silence
statuses: Statuses
title: Accounts
undo_silenced: Undo silence
undo_suspension: Undo suspension
username: Username
web: Web
domain_block:
add_new: Add new
domain: Domain
new:
create: Create block
hint: The domain block will not prevent creation of account entries in the database, but will retroactively and automatically apply specific moderation methods on those accounts.
severity:
desc_html: "<strong>Silence</strong> will make the account's posts invisible to anyone who isn't following them. <strong>Suspend</strong> will remove all of the account's content, media, and profile data."
silence: Silence
suspend: Suspend
title: New domain block
severity: Severity
title: Domain Blocks
pubsubhubbub:
callback_url: Callback URL
confirmed: Confirmed
expires_in: Expires in
last_delivery: Last delivery
title: PubSubHubbub
topic: Topic
reports:
comment:
label: Comment
none: None
delete: Delete
id: ID
mark_as_resolved: Mark as resolved
report: 'Report #%{id}'
reported_account: Reported account
reported_by: Reported by
resolved: Resolved
silence_account: Silence account
status: Status
suspend_account: Suspend account
target: Target
title: Reports
unresolved: Unresolved
view: View
settings:
click_to_edit: Click to edit
contact_information:
email: Enter a public e-mail address
label: Contact information
username: Enter a username
registrations:
closed_message:
desc_html: Displayed on frontpage when registrations are closed<br>You can use HTML tags
title: Closed registration message
open:
disabled: Disabled
enabled: Enabled
title: Open registration
setting: Setting
site_description:
desc_html: Displayed as a paragraph on the frontpage and used as a meta tag.<br>You can use HTML tags, in particular <code>&lt;a&gt;</code> and <code>&lt;em&gt;</code>.
title: Site description
site_description_extended:
desc_html: Displayed on extended information page<br>You can use HTML tags
title: Extended site description
site_title: Site title
title: Site Settings
title: Administration
application_mailer:
settings: 'Change e-mail preferences: %{link}'
signature: Mastodon notifications from %{instance}
@ -74,11 +176,17 @@ en:
x_minutes: "%{count}m"
x_months: "%{count}mo"
x_seconds: "%{count}s"
errors:
'404': The page you were looking for doesn't exist.
'410': The page you were looking for doesn't exist anymore.
'422':
content: Security verification failed. Are you blocking cookies?
title: Security verification failed
exports:
blocks: You block
mutes: You mute
csv: CSV
follows: You follow
mutes: You mute
storage: Media storage
generic:
changes_saved_msg: Changes successfully saved!
@ -134,6 +242,24 @@ en:
missing_resource: Could not find the required redirect URL for your account
proceed: Proceed to follow
prompt: 'You are going to follow:'
reports:
comment:
label: Comment
none: None
delete: Delete
id: ID
mark_as_resolved: Mark as resolved
report: 'Report #%{id}'
reported_account: Reported account
reported_by: Reported by
reports: Reports
resolved: Resolved
silence_account: Silence account
status: Status
suspend_account: Suspend account
target: Target
unresolved: Unresolved
view: View
settings:
authorized_apps: Authorized apps
back: Back to Mastodon
@ -174,52 +300,3 @@ en:
invalid_otp_token: Invalid two-factor code
will_paginate:
page_gap: "&hellip;"
errors:
404: The page you were looking for doesn't exist.
410: The page you were looking for doesn't exist anymore.
422:
title: Security verification failed
content: Security verification failed. Are you blocking cookies?
reports:
reports: Reports
status: Status
unresolved: Unresolved
resolved: Resolved
id: ID
target: Target
reported_by: Reported by
comment:
label: Comment
none: None
view: View
report: "Report #%{id}"
delete: Delete
reported_account: Reported account
reported_by: Signalé par
silence_account: Silence account
suspend_account: Suspend account
mark_as_resolved: Mark as resolved
admin:
settings:
title: Site Settings
setting: Setting
click_to_edit: Click to edit
contact_information:
label: Contact information
username: Enter a username
email: Enter a public e-mail address
site_title: Site title
site_description:
title: Site description
desc_html: "Displayed as a paragraph on the frontpage and used as a meta tag.<br>You can use HTML tags, in particular <code>&lt;a&gt;</code> and <code>&lt;em&gt;</code>."
site_description_extended:
title: Extended site description
desc_html: "Displayed on extended information page<br>You can use HTML tags"
registrations:
open:
title: Open registration
enabled: Enabled
disabled: Disabled
closed_message:
title: Closed registration message
desc_html: "Displayed on frontpage when registrations are closed<br>You can use HTML tags"

View file

@ -7,14 +7,14 @@ es:
business_email: 'Correo de negocios:'
closed_registrations: Los registros están actualmente cerrados en esta instancia.
contact: Contacto
description_headline: ¿Qué es %{domain}?
description_headline: "¿Qué es %{domain}?"
domain_count_after: otras instancias
domain_count_before: Conectado a
domain_count_before: Conectado a
features:
api: API pública para aplicaciones y servicios
blocks: Moderación de contenido
characters: 500 caracteres por publicación
chronology: Las historias son cronológicas
chronology: Las historias son cronológicas
ethics: 'Diseño etico: sin anuncios, sin rastreos'
gifv: Videos cortos y GIFV
privacy: Configuraciones de privacidad ajustables
@ -33,7 +33,7 @@ es:
follow: Seguir
followers: Seguidores
following: Siguiendo
nothing_here: ¡No hay nada aquí!
nothing_here: "¡No hay nada aquí!"
people_followed_by: Usuarios a quien %{name} sigue
people_who_follow: Usuarios que siguen a %{name}
posts: Toots
@ -47,8 +47,8 @@ es:
invalid_url: La URL proporcionada es incorrecta
auth:
change_password: Cambiar contraseña
didnt_get_confirmation: ¿No recibió el correo de confirmación?
forgot_password: ¿Olvidaste tu contraseña?
didnt_get_confirmation: "¿No recibió el correo de confirmación?"
forgot_password: "¿Olvidaste tu contraseña?"
login: Iniciar sesión
logout: Cerrar sesión
register: Registrarse
@ -80,12 +80,12 @@ es:
follows: Personas que sigues
storage: Almacenamiento
generic:
changes_saved_msg: ¡Cambios guardados con éxito!
changes_saved_msg: "¡Cambios guardados con éxito!"
powered_by: powered by %{link}
save_changes: Guardar cambios
validation_errors:
one: ¡Algo no está bien! Por favor, revisa el error
other: ¡Algo no está bien! Por favor, revise %{count} errores más abajo
one: "¡Algo no está bien! Por favor, revisa el error"
other: "¡Algo no está bien! Por favor, revise %{count} errores más abajo"
imports:
preface: Puedes importar ciertos datos, como todas las personas que estás siguiendo o bloqueando en tu cuenta en esta instancia, desde archivos exportados de otra instancia.
success: Sus datos se han cargado correctamente y serán procesados en brevedad
@ -94,13 +94,17 @@ es:
following: Lista de seguidos
upload: Cargar
landing_strip_html: <strong>%{name}</strong> es un usuario en <strong>%{domain}</strong>. Puedes seguirlo(a) o interactuar con el o ella si tienes una cuenta en cualquier parte del fediverse. Si no tienes una, puedes <a href="%{sign_up_path}">registrar aquí</a>.
media_attachments:
validations:
images_and_video: No se puede adjuntar un video a un estado que ya contenga imágenes
too_many: No se pueden adjuntar más de 4 archivos
notification_mailer:
digest:
body: 'Un resumen de lo que te perdiste en %{instance} desde tu última visita el %{since}:'
mention: "%{name} te ha mencionado en:"
new_followers_summary:
one: ¡Hurra!. Alguien más te ha comenzado a seguir
other: ¡Genial!. Te han seguido %{count} nuevas personas
one: "¡Hurra!. Alguien más te ha comenzado a seguir"
other: "¡Genial!. Te han seguido %{count} nuevas personas"
subject:
one: "1 nueva notificación desde tu última visita \U0001F418"
other: "%{count} nuevas notificaciones desde tu última visita \U0001F418"
@ -117,7 +121,7 @@ es:
body: 'Fuiste mencionado por %{name} en:'
subject: Fuiste mencionado por %{name}
reblog:
body: '%{name} ha retooteado tu estado'
body: "%{name} ha retooteado tu estado"
subject: "%{name} ha retooteado tu estado"
pagination:
next: Próximo
@ -161,7 +165,3 @@ es:
users:
invalid_email: La dirección de correo es incorrecta
invalid_otp_token: Código de dos factores incorrecto
media_attachments:
validations:
too_many: No se pueden adjuntar más de 4 archivos
images_and_video: No se puede adjuntar un video a un estado que ya contenga imágenes

View file

@ -15,7 +15,7 @@ fr:
blocks: Outils complets de bloquage et masquage
characters: 500 caractères par post
chronology: Fil chronologique
ethics: 'Pas de pubs, pas de pistage'
ethics: Pas de pubs, pas de pistage
gifv: Partage de vidéos et de GIFs
privacy: Réglages de confidentialité au niveau des posts
public: Fils publics
@ -39,6 +39,108 @@ fr:
posts: Statuts
remote_follow: Suivre à distance
unfollow: Ne plus suivre
admin:
accounts:
are_you_sure: Êtes-vous certain ?
display_name: Nom affiché
domain: Domaine
edit: Éditer
email: Courriel
feed_url: URL du flux
followers: Abonné⋅es
follows: Abonnements
location:
all: Tous
local: Local
remote: Distant
title: Situation
media_attachments: Fichiers médias
moderation:
all: Tous
silenced: Muets
suspended: Suspendus
title: Modération
most_recent_activity: Dernière activité
most_recent_ip: Adresse IP la plus récente
not_subscribed: Non abonné
order:
alphabetic: Alphabétique
most_recent: Plus récent
title: Tri
perform_full_suspension: Effectuer une suspension complète
profile_url: URL du profil
public: Public
push_subscription_expires: Expiration de l'abonnement PuSH
salmon_url: URL Salmon
silence: Rendre muet
statuses: Statuts
title: Comptes
undo_silenced: Annuler la mu
undo_suspension: Annuler la suspension
username: Nom d'utilisateur
web: Web
domain_block:
add_new: Ajouter
domain: Domaine
new:
create: Créer le blocage
hint: Le blocage de domaine n'empêchera pas la création de comptes dans la base de données, mais il appliquera automatiquement et rétrospectivement des méthodes de modération spécifiques sur ces comptes.
severity:
desc_html: "<strong>Silence</strong> rendra les messages des comptes concernés invisibles à ceux qui ne les suivent pas. <strong>Suspend</strong> supprimera tout le contenu des comptes concernés, les médias, et les données du profil."
silence: Muet
suspend: Suspendre
title: Nouveau blocage de domaine
severity: Séverité
title: Blocage de domaines
pubsubhubbub:
callback_url: URL de rappel
confirmed: Confirmé
expires_in: Expire dans
last_delivery: Dernière livraison
title: PubSubHubbub
topic: Sujet
reports:
comment:
label: Commentaire
none: Aucun
delete: Supprimer
id: ID
mark_as_resolved: Marqué comme résolu
report: 'Signalement #%{id}'
reported_account: Compte signalé
reported_by: Signalé par
resolved: Résolus
silence_account: Rendre le compte muet
status: Statut
suspend_account: Suspendre le compte
target: Cible
title: Signalements
unresolved: Non résolus
view: Voir
settings:
click_to_edit: Cliquez pour éditer
contact_information:
email: Entrez une adresse courriel publique
label: Informations de contact
username: Entrez un nom d'utilisateur
registrations:
closed_message:
desc_html: Affiché sur la page d'accueil lorsque les inscriptions sont fermées<br>Vous pouvez utiliser des balises HTML
title: Message de fermeture des inscriptions
open:
disabled: Désactivées
enabled: Activées
title: Inscriptions
setting: Paramètre
site_description:
desc_html: Affichée sous la forme d'un paragraphe sur la page d'accueil et utilisée comme balise meta.<br>Vous pouvez utiliser des balises HTML, en particulier <code>&lt;a&gt;</code> et <code>&lt;em&gt;</code>.
title: Description du site
site_description_extended:
desc_html: Affichée sur la page d'informations complémentaires du site<br>Vous pouvez utiliser des balises HTML
title: Description étendue du site
site_title: Titre du site
title: Paramètres du site
title: Administration
application_mailer:
settings: 'Changer les préférences courriel : %{link}'
signature: Notifications de Mastodon depuis %{instance}
@ -80,6 +182,12 @@ fr:
x_minutes: "%{count}min"
x_months: "%{count}mois"
x_seconds: "%{count}s"
errors:
'404': La page que vous recherchez n'existe pas.
'410': La page que vous recherchez n'existe plus.
'422':
content: Vérification de sécurité échouée. Bloquez-vous les cookies ?
title: Vérification de sécurité échouée
exports:
blocks: Vous bloquez
csv: CSV
@ -103,7 +211,7 @@ fr:
notification_mailer:
digest:
body: 'Voici ce que vous avez raté sur ${instance} depuis votre dernière visite (%{}) :'
mention: '%{name} vous a mentionné⋅e'
mention: "%{name} vous a mentionné⋅e"
new_followers_summary:
one: Vous avez un⋅e nouvel⋅le abonné⋅e ! Youpi !
other: Vous avez %{count} nouveaux abonné⋅es ! Incroyable !
@ -133,6 +241,24 @@ fr:
missing_resource: L'URL de redirection n'a pas pu être trouvée
proceed: Continuez pour suivre
prompt: 'Vous allez suivre :'
reports:
comment:
label: Commentaire
none: Aucun
delete: Supprimer
id: ID
mark_as_resolved: Marqué comme résolu
report: 'Signalement #%{id}'
reported_account: Compte signalé
reported_by: Signalé par
reports: Signalements
resolved: Résolus
silence_account: Rendre le compte muet
status: Statut
suspend_account: Suspendre le compte
target: Cible
unresolved: Non résolus
view: Voir
settings:
authorized_apps: Applications autorisées
back: Retour vers Mastodon
@ -156,7 +282,7 @@ fr:
sensitive_content: Contenu sensible
time:
formats:
default: '%d %b %Y, %H:%M'
default: "%d %b %Y, %H:%M"
two_factor_auth:
description_html: Si vous activez <strong>l'identification à deux facteurs</strong>, vous devrez être en possession de votre téléphone afin de générer un code de connexion.
disable: Désactiver
@ -169,52 +295,3 @@ fr:
invalid_otp_token: Le code d'authentification à deux facteurs est invalide
will_paginate:
page_gap: "&hellip;"
errors:
404: La page que vous recherchez n'existe pas.
410: La page que vous recherchez n'existe plus.
422:
title: Vérification de sécurité échouée
content: Vérification de sécurité échouée. Bloquez-vous les cookies ?
reports:
reports: Signalements
status: Statut
unresolved: Non résolus
resolved: Résolus
id: ID
target: Cible
reported_by: Signalé par
comment:
label: Commentaire
none: Aucun
view: Voir
report: "Signalement #%{id}"
delete: Supprimer
reported_account: Compte signalé
reported_by: Signalé par
silence_account: Rendre le compte muet
suspend_account: Suspendre le compte
mark_as_resolved: Marqué comme résolu
admin:
settings:
title: Paramètres du site
setting: Paramètre
click_to_edit: Cliquez pour éditer
contact_information:
label: Informations de contact
username: Entrez un nom d'utilisateur
email: Entrez une adresse courriel publique
site_title: Titre du site
site_description:
title: Description du site
desc_html: "Affichée sous la forme d'un paragraphe sur la page d'accueil et utilisée comme balise meta.<br>Vous pouvez utiliser des balises HTML, en particulier <code>&lt;a&gt;</code> et <code>&lt;em&gt;</code>."
site_description_extended:
title: Description étendue du site
desc_html: "Affichée sur la page d'informations complémentaires du site<br>Vous pouvez utiliser des balises HTML"
registrations:
open:
title: Inscriptions
enabled: Activées
disabled: Désactivées
closed_message:
title: Message de fermeture des inscriptions
desc_html: "Affiché sur la page d'accueil lorsque les inscriptions sont fermées<br>Vous pouvez utiliser des balises HTML"

165
config/locales/hr.yml Normal file
View file

@ -0,0 +1,165 @@
---
hr:
about:
about_mastodon: Mastodon je <em>besplatna, open-source</em> socijalna mreža. <em>Decentralizirana</em> alternativa komercijalnim platformama, izbjegava rizik toga da jedna tvrtka monopolizira vašu komunikaciju. Izaberite server kojem ćete vjerovati &mdash; koji god odabrali, moći ćete komunicirati sa svima ostalima. Bilo tko može imati svoju vlastitu Mastodon instancu i sudjelovati u <em>socijalnoj mreži</em> bez problema.
about_this: O ovoj instanci
apps: Aplikacije
business_email: 'Poslovni e-mail:'
closed_registrations: Registracije na ovoj instanci su trenutno zatvorene.
contact: Kontakt
description_headline: Što je %{domain}?
domain_count_after: druge instance
domain_count_before: Spojen na
features:
api: Otvoren API za aplikacije i servise
blocks: Bogati alati za blokiranje i ušutkivanje
characters: 500 znakova po postu
chronology: Timelines su kronološke
ethics: 'Etički dizajn: bez oglasa, bez praćenja'
gifv: GIFV setovi i kratki videi
privacy: Granularne postavke privatnosti, po postu
public: Javne timelines
features_headline: Po čemu se Mastodon razlikuje
get_started: Započni
links: Linkovi
other_instances: Druge instance
source_code: Izvorni kod
status_count_after: statusi
status_count_before: Tko je autor
terms: Uvjeti
user_count_after: korisnici
user_count_before: Home to
accounts:
follow: Slijedi
followers: Sljedbenici
following: Slijedim
nothing_here: Ovdje nema ničeg!
people_followed_by: Ljudi koje %{name} slijedi
people_who_follow: Ljudi koji slijede %{name}
posts: Postovi
remote_follow: Remote follow
unfollow: Prestani slijediti
application_mailer:
settings: 'Promijeni e-mail postavke: %{link}'
signature: Mastodon notifikacije sa %{instance}
view: 'View:'
applications:
invalid_url: Uneseni link nije valjan
auth:
change_password: Vjerodajnice
didnt_get_confirmation: Niste primili instrukcije za potvrđivanje?
forgot_password: Zaboravljena lozinka?
login: Prijavi se
logout: Odjavi se
register: Registriraj se
resend_confirmation: Ponovo pošalji instrukcije za potvrđivanje
reset_password: Resetiraj lozinku
set_new_password: Postavi novu lozinku
authorize_follow:
error: Nažalost, došlo je do greške looking up the remote račun
follow: Slijedi
prompt_html: 'Ti si (<strong>%{self}</strong>) poslao zahtjev za sljeđenje:'
title: Slijedi %{acct}
datetime:
distance_in_words:
about_x_hours: "%{count}s"
about_x_months: "%{count}mj"
about_x_years: "%{count}g"
almost_x_years: "%{count}g"
half_a_minute: upravo
less_than_x_minutes: "%{count}m"
less_than_x_seconds: upravo
over_x_years: "%{count}g"
x_days: "%{count}d"
x_minutes: "%{count}m"
x_months: "%{count}mj"
x_seconds: "%{count}sek"
exports:
blocks: Blokirao si
csv: CSV
follows: Slijediš
storage: Pohrana media zapisa
generic:
changes_saved_msg: Izmjene su uspješno sačuvane!
powered_by: omogućuje %{link}
save_changes: Sačuvaj izmjene
validation_errors:
one: Nešto ne štima! Vidi grešku ispod
other: Nešto još uvijek ne štima! Vidi %{count} greške ispod
imports:
preface: Možeš uvesti određene podatke kao što su svi ljudi koje slijediš ili blokiraš u svoj račun na ovoj instanci, sa fajlova kreiranih izvozom sa druge instance.
success: Tvoji podaci su uspješno uploadani i bit će obrađeni u dogledno vrijeme
types:
blocking: Lista blokiranih
following: Lista onih koje slijedim
upload: Upload
landing_strip_html: <strong>%{name}</strong> je korisnik na <strong>%{domain}</strong>. Možeš ih slijediti ili komunicirati s njima ako imaš račun igdje u fediversu. Ako nemaš, možeš se <a href="%{sign_up_path}">registrirati ovdje</a>.
notification_mailer:
digest:
body: 'Ovo je kratak sažetak propuštenog %{instance} od tvog prošlog posjeta %{since}:'
mention: "%{name} te je spomenuo:"
new_followers_summary:
one: Imaš novog sljedbenika! Yay!
other: Imaš %{count} novih sljedbenika! Prekrašno!
subject:
one: "1 nova notifikacija od tvog prošlog posjeta \U0001F418"
other: "%{count} novih notifikacija od tvog prošlog posjeta \U0001F418"
favourite:
body: 'Tvoj status je %{name} označio kao omiljen:'
subject: "%{name} je označio kao omiljen tvoj status"
follow:
body: "%{name} te sada slijedi!"
subject: "%{name} te sada slijedi"
follow_request:
body: "%{name} je zatražio da te slijedi"
subject: 'Sljedbenik na čekanju: %{name}'
mention:
body: 'Spomenuo te je %{name} in:'
subject: Spomenuo te je %{name}
reblog:
body: 'Tvoj status je potaknut od %{name}:'
subject: "%{name} je potakao tvoj status"
pagination:
next: Sljedeći
prev: Prošli
remote_follow:
acct: Unesi svoje username@domain sa koje želiš slijediti
missing_resource: Could not find the required redirect URL za tvoj račun
proceed: Nastavi slijediti
prompt: 'Slijediti ćeš:'
settings:
authorized_apps: Autorizirane aplikacije
back: Natrag na Mastodon
edit_profile: Uredi profil
export: Izvoz podataka
import: Uvezi
preferences: Postavke
settings: Podešenja
two_factor_auth: Dvo-faktorska Autentifikacija
statuses:
open_in_web: Otvori na webu
over_character_limit: prijeđen je limit od %{max} znakova
show_more: Prikaži više
visibilities:
private: Pokaži samo sljedbenicima
public: Javno
unlisted: Javno, no nemoj prikazati na javnom timelineu
stream_entries:
click_to_show: Klikni da bi prikazao
reblogged: potaknut
sensitive_content: Osjetljivi sadržaj
time:
formats:
default: "%b %d, %Y, %H:%M"
two_factor_auth:
description_html: Ako omogućiš <strong>two-factor autentifikaciju</strong>, prijavljivanje će zahtjevati da kod sebe imaš svoj mobitel, koji će generirati tokene koje ćeš unijeti.
disable: Onemogući
enable: Omogući
instructions_html: "<strong>Skeniraj ovaj QR kod into Google Authenticator or a similiar app on your phone</strong>. Od sada, ta aplikacija će generirati tokene koje ćeš unijeti pri prijavljivanju."
plaintext_secret_html: 'Plain-text secret: <samp>%{secret}</samp>'
warning: Ako trenuno ne možeš konfigurirati authenticator app, trebaš kliknuti "onemogući" ili se nećeš moći prijaviti.
users:
invalid_email: E-mail adresa nije valjana
invalid_otp_token: Nevaljani dvo-faktorski kod
will_paginate:
page_gap: "&hellip;"

View file

@ -7,7 +7,7 @@ ja:
business_email: 'ビジネスメールアドレス:'
closed_registrations: 現在このインスタンスでの新規登録は受け付けていません。
contact: 連絡先
description_headline: '%{domain} とは?'
description_headline: "%{domain} とは?"
domain_count_after: 個のインスタンス
domain_count_before: 接続中
features:
@ -34,19 +34,40 @@ ja:
followers: フォロワー
following: フォロー中
nothing_here: 何もありません
people_followed_by: '%{name} さんをフォロー中のアカウント'
people_who_follow: '%{name} さんがフォロー中のアカウント'
people_followed_by: "%{name} さんをフォロー中のアカウント"
people_who_follow: "%{name} さんがフォロー中のアカウント"
posts: 投稿
remote_follow: リモートフォロー
unfollow: フォロー解除
admin:
settings:
click_to_edit: クリックして編集
contact_information:
email: 公開するメールアドレスを入力
label: 連絡先情報
username: ユーザー名を入力
registrations:
open:
disabled: 無効
enabled: 有効
title: 新規登録を受け付ける
setting: 設定
site_description:
desc_html: トップページへの表示と meta タグに使用されます。<br>HTMLタグ、特に<code>&lt;a&gt;</code> and <code>&lt;em&gt;</code>が利用可能です。
title: サイトの説明文
site_description_extended:
desc_html: インスタンスについてのページに表示されます。<br>HTMLタグが利用可能です。
title: サイトの詳細な説明
site_title: サイトのタイトル
title: サイト設定
application_mailer:
settings: 'メール設定の変更: %{link}'
signature: 'Mastodon %{instance} インスタンスからの通知'
signature: Mastodon %{instance} インスタンスからの通知
view: 'View:'
applications:
invalid_url: URLが無効です
auth:
change_password: 資格情報
change_password: ログイン情報
didnt_get_confirmation: 確認メールを受信できませんか?
forgot_password: パスワードをお忘れですか?
login: ログイン
@ -59,7 +80,7 @@ ja:
error: 残念ながら、リモートアカウントにエラーが発生しました。
follow: フォロー
prompt_html: 'あなた(<strong>%{self}</strong>)は以下のアカウントのフォローをリクエストしました:'
title: '%{acct} をフォロー'
title: "%{acct} をフォロー"
datetime:
distance_in_words:
about_x_hours: "%{count}時間"
@ -74,10 +95,17 @@ ja:
x_minutes: "%{count}分"
x_months: "%{count}月"
x_seconds: "%{count}秒"
errors:
'404': お探しのページは見つかりませんでした。
'410': お探しのページはもう存在しません。
'422':
content: セキュリティ認証に失敗しました。Cookieをブロックしていませんか
title: セキュリティ認証に失敗
exports:
blocks: ブロック
csv: CSV
follows: フォロー
mutes: ミュート
storage: メディア
generic:
changes_saved_msg: 正常に変更されました
@ -90,8 +118,9 @@ ja:
preface: 他のインスタンスでエクスポートされたファイルから、フォロー/ブロックした情報をこのインスタンス上のアカウントにインポートできます。
success: ファイルは正常にアップロードされ、現在処理中です。しばらくしてから確認してください
types:
blocking: ブロック中のアカウントリスト
blocking: ブロックしたアカウントリスト
following: フォロー中のアカウントリスト
muting: ミュートしたアカウントリスト
upload: アップロード
landing_strip_html: <strong>%{name}</strong> さんはインスタンス <strong>%{domain}</strong> のユーザーです。アカウントさえ持っていればフォローしたり会話したりできます。もしお持ちでないなら <a href="%{sign_up_path}">こちら</a> からサインアップできます。
media_attachments:
@ -100,11 +129,11 @@ ja:
too_many: 追加できるファイルは4つまでです。
notification_mailer:
digest:
body: '%{instance} での最後のログインからの出来事:'
body: "%{instance} での最後のログインからの出来事:"
mention: "%{name} さんがあなたに返信しました:"
new_followers_summary:
one: 新たなフォロワーを獲得しました!
other: '%{count} 人の新たなフォロワーを獲得しました!'
other: "%{count} 人の新たなフォロワーを獲得しました!"
subject:
one: "新しい1件の通知 \U0001F418"
other: "新しい%{count}件の通知 \U0001F418"
@ -116,21 +145,40 @@ ja:
subject: "%{name} さんにフォローされています"
follow_request:
body: "%{name} さんがあなたにフォローをリクエストしました。"
subject: '%{name} さんからのフォローリクエスト'
subject: "%{name} さんからのフォローリクエスト"
mention:
body: '%{name} さんから返信がありました:'
subject: '%{name} さんに返信されました'
body: "%{name} さんから返信がありました:"
subject: "%{name} さんに返信されました"
reblog:
body: 'あなたのトゥートが %{name} さんにブーストされました:'
subject: "あなたのトゥートが %{name} さんにブーストされました"
subject: あなたのトゥートが %{name} さんにブーストされました
pagination:
next:
prev:
truncate: "&hellip;"
remote_follow:
acct: フォローしたい人の ユーザー名@ドメイン を入力してください
missing_resource: リダイレクト先が見つかりませんでした
proceed: フォローする
prompt: 'フォローしようとしています:'
reports:
comment:
label: コメント
none: なし
delete: 削除
id: ID
mark_as_resolved: 解決する
report: '通報 #%{id}'
reported_account: 通報されているユーザー
reported_by: 通報者
reports: 通報
resolved: 解決済み
silence_account: ユーザーをサイレンスする
status: 現状
suspend_account: ユーザーを停止する
target: 通報されているユーザー
unresolved: 未決
view: 見る
settings:
authorized_apps: 認証済みアプリ
back: 戻る
@ -142,7 +190,7 @@ ja:
two_factor_auth: 二段階認証
statuses:
open_in_web: Webで開く
over_character_limit: '上限は %{max}文字までです'
over_character_limit: 上限は %{max}文字までです
show_more: もっと見る
visibilities:
private: Private - フォロワーだけに見せる
@ -157,7 +205,7 @@ ja:
default: "%Y年%m月%d日 %H:%M"
two_factor_auth:
code_hint: 確認するには認証アプリで表示されたコードを入力してください
description_html: <strong>二段階認証</strong>を有効にするとログイン時、電話でコードを受け取る必要があります。
description_html: "<strong>二段階認証</strong>を有効にするとログイン時、電話でコードを受け取る必要があります。"
disable: 無効
enable: 有効
enabled_success: 二段階認証が有効になりました
@ -171,31 +219,3 @@ ja:
invalid_otp_token: 二段階認証コードが間違っています
will_paginate:
page_gap: "&hellip;"
errors:
404: お探しのページは見つかりませんでした。
410: お探しのページはもう存在しません。
422:
title: セキュリティ認証に失敗
content: セキュリティ認証に失敗しました。Cookieをブロックしていませんか
admin:
settings:
title: サイト設定
setting: 設定
click_to_edit: クリックして編集
contact_information:
label: 連絡先情報
username: ユーザー名を入力
email: 公開するメールアドレスを入力
site_title: サイトのタイトル
site_description:
title: サイトの説明文
desc_html: "トップページへの表示と meta タグに使用されます。<br>HTMLタグ、特に<code>&lt;a&gt;</code> and <code>&lt;em&gt;</code>が利用可能です。"
site_description_extended:
title: サイトの詳細な説明
desc_html: "インスタンスについてのページに表示されます。<br>HTMLタグが利用可能です。"
registrations:
open:
title: 新規登録を受け付ける
enabled: 有効
disabled: 無効

165
config/locales/nl.yml Normal file
View file

@ -0,0 +1,165 @@
---
nl:
about:
about_mastodon: Mastodon is een <em>vrije, gratis, open-source</em> sociaal netwerk. E <em>gedecentraliseerd</em> alternatief voor commerciële platforms, het voorkomt de risico's van een enkel bedrijf dat jouw communicatie monopoliseert. Kies een server die je vertrouwt &mdash; welke je ook kiest, je kunt met iedere ander communiceren. Iedereen kan een eigen Mastodon server draaien en naadloos deelnemen in het <em>sociale netwerk</em>.
about_this: Over deze server
apps: Apps
business_email: 'Zakelijke e-mailadres:'
closed_registrations: Registrateren op deze server is momenteel uitgeschakeld.
contact: Contact
description_headline: Wat is %{domain}?
domain_count_after: andere servers
domain_count_before: Verbonden met
features:
api: Open API voor apps en services
blocks: Rijke blokkeer- en dempingshulpmiddelen
characters: 500 tekens per bericht
chronology: Tijdlijnen zijn chronologisch
ethics: 'Ethisch design: geen ads, geen spionage'
gifv: GIFV sets en korte video's
privacy: Granulaire, privacy instellingen per bericht
public: Openbare tijdlijnen
features_headline: Wat maak Mastodon anders
get_started: Beginnen
links: Links
other_instances: Andere servers
source_code: Source code
status_count_after: statussen
status_count_before: Wie schreef
terms: Voorw
user_count_after: gebruikers
user_count_before: Thuis naar
accounts:
follow: Volg
followers: Volgens
following: Volgend
nothing_here: Hier is niets!
people_followed_by: Mensen die %{name} volgt
people_who_follow: Mensen die %{name} volgen
posts: Berichten
remote_follow: Externe volg
unfollow: Ontvolgen
application_mailer:
settings: 'Wijzigen e-mailvoorkeuren: %{link}'
signature: Mastodon meldingen van %{instance}
view: 'Bekijk:'
applications:
invalid_url: De opgegevens URL is ongeldig
auth:
change_password: Inloggegevens
didnt_get_confirmation: Ontving je geen bevestigingsinstructies?
forgot_password: Wachtwoord vergeten?
login: Inloggen
logout: Uitloggen
register: Registreren
resend_confirmation: Herstuur de bevestigingsinstructies
reset_password: Herstel wachtwoord
set_new_password: Instellen nieuw wachtwoord
authorize_follow:
error: Helaas, er was een fout bij het opzoeken van het externe account
follow: Volgen
prompt_html: 'Je (<strong>%{self}</strong>) hebt volgen aangevraagd:'
title: Volg %{acct}
datetime:
distance_in_words:
about_x_hours: "%{count}u"
about_x_months: "%{count}ma"
about_x_years: "%{count}j"
almost_x_years: "%{count}j"
half_a_minute: Net
less_than_x_minutes: "%{count}m"
less_than_x_seconds: Net
over_x_years: "%{count}j"
x_days: "%{count}d"
x_minutes: "%{count}m"
x_months: "%{count}ma"
x_seconds: "%{count}s"
exports:
blocks: Je blokkeert
csv: CSV
follows: Je volgt
storage: Media-opslag
generic:
changes_saved_msg: Wijzigingen succesvol opgeslagen!
powered_by: powered by %{link}
save_changes: Wijziginen opslaan
validation_errors:
one: Er is iets niet helemaal goed! Bekijk onderstaande fout
other: Er is iets niet helemaal goed! Bekijk onderstaande %{count} fouten
imports:
preface: Je kunt bepaalde gegevens, zoals de mensen die je volgt of blokkeert, importeren voor je account op deze server, als ze zijn geëxporteerd op een andere server.
success: Je gegevens zijn succesvol ge-upload en wordt binnenkort verwerkt
types:
blocking: Blokkadelijst
following: Volglijst
upload: Uploaden
landing_strip_html: <strong>%{name}</strong> is een gebruiker op <strong>%{domain}</strong>. Je kunt deze volgen of ermee interacteren als je ergens in deze fediverse een account hebt. Als he dat niet hebt, kun je je <a href="%{sign_up_path}">hier aanmelden</a>.
notification_mailer:
digest:
body: 'Hier is een korte samenvatting van wat je hebt gemist op %{instance} sinds je laatste bezoek op %{since}:'
mention: "%{name} vermeldde je in:"
new_followers_summary:
one: Je hebt een nieuwe volger! Hoera!
other: Je hebt %{count} nieuwe volgers! Prachtig!
subject:
one: "1 nieuwe melding sinds je laatste bezoek \U0001F418"
other: "%{count} nieuwe meldingen sinds je laatste bezoek \U0001F418"
favourite:
body: 'Je status werd als favoriet gemarkeerd door %{name}:'
subject: "%{name} markeerde je status als favouriet"
follow:
body: "%{name} volgt je nu!"
subject: "%{name} volgt je nu"
follow_request:
body: "%{name} wil je graag volgend"
subject: 'Volgen in afwachting: %{name}'
mention:
body: 'Je werd door %{name} vermeld in:'
subject: Je werd vermeld door %{name}
reblog:
body: 'Je status werd geboost door %{name}:'
subject: "%{name} booste je status"
pagination:
next: Volgende
prev: Vorige
remote_follow:
acct: Geef je gebruikersnaam@domein op waarvandaan je wilt volgen
missing_resource: Kon geen de vereiste doorverwijszings-URL voor je account niet vinden
proceed: Ga door om te volgen
prompt: 'Je gaat volgen:'
settings:
authorized_apps: Geautoriseerde
back: Terug naar Mastodon
edit_profile: Bewerk profiel
export: Gegevensexport
import: Import
preferences: Voorkeuren
settings: Instellingen
two_factor_auth: Twe-factor authenticatie
statuses:
open_in_web: Openen in web
over_character_limit: Tekenlimiet van %{max} overschreden
show_more: Toon meer
visibilities:
private: Toon alleen aan volgers
public: Openbaar
unlisted: Openbaar, maar niet tonen op openbare tijdlijn
stream_entries:
click_to_show: Klik om te tonen
reblogged: boostte
sensitive_content: Gevoelige inhoud
time:
formats:
default: "%b %d, %J, %U:%M"
two_factor_auth:
description_html: Als je <strong>twee-factor authenticatie</strong> instelt, kun je alleen inloggen als je je mobiele telefoon bij je hebt, waarmee je de in te voeren tokens genereert.
disable: Uitschakelen
enable: Inschakelen
instructions_html: "<strong>Scan deze QR-code in Google Authenticator of een soortgelijke app op je mobiele telefoon</strong>. Van nu af aan creëert deze app tokens die je bij inloggen moet invoeren."
plaintext_secret_html: 'Gewone-tekst geheim: <samp>%{secret}</samp>'
warning: Als je nu geen authenticator app kunt installeren, moet je "Uitschakelen" kiezen of je kunt niet meer inloggen.
users:
invalid_email: Het e-mailadres is ongeldig
invalid_otp_token: Ongeldige twe-factor code
will_paginate:
page_gap: "&hellip;"

View file

@ -1,7 +1,7 @@
---
'no':
about:
about_mastodon: Mastodon er et <em>gratis, åpen kildekode</em> sosialt nettverk. Et <em>desentralisert</em> alternativ til kommersielle plattformer. Slik kan det unngå risikoene ved å ha et enkelt selskap med monopol på din kommunikasjon. Velg en tjener du stoler på &mdash; uansett hvilken du velger så kan du interagere med alle andre. Alle kan kjøre sin egen Mastodon og delta sømløst i det sosiale nettverket.
about_mastodon: Mastodon er et sosialt nettverk laget med <em>fri programvare</em>. Et <em>desentralisert</em> alternativ til kommersielle plattformer. Slik kan det unngå risikoene ved å ha et enkelt selskap som monopoliserer din kommunikasjon. Velg en tjener du stoler på &mdash; uansett hvilken du velger så kan du kommunisere med alle andre. Alle kan kjøre sin egen Mastodon og delta sømløst i det sosiale nettverket.
about_this: Om denne instansen
apps: Applikasjoner
business_email: 'Bedriftsepost:'
@ -10,24 +10,24 @@
domain_count_after: andre instanser
domain_count_before: Koblet til
features:
api: Åpent api for applikasjoner og tjenester
blocks: Rikholdige blokkerings verktøy
characters: 500 tegn per post
api: Åpent API for applikasjoner og tjenester
blocks: Rikholdige blokkeringsverktøy
characters: 500 tegn per status
chronology: Tidslinjer er kronologiske
ethics: 'Etisk design: Ingen reklame, ingen sporing'
gifv: GIFV sett og korte videoer
privacy: Finmaskete personvernsinnstillinger
public: Offentlige tidslinjer
gifv: Støtte for GIFV og korte videoer
privacy: Finmaskede personvernsinnstillinger
public: Forente tidslinjer
features_headline: Hva skiller Mastodon fra andre sosiale nettverk
get_started: Kom i gang
links: Lenker
other_instances: Andre instanser
source_code: Kildekode
status_count_after: statuser
status_count_before: Hvem skrev
status_count_before: Som skrev
terms: Betingelser
user_count_after: brukere
user_count_before: Hjem til
user_count_before: Her bor
accounts:
follow: Følg
followers: Følgere
@ -116,8 +116,8 @@
body: 'Du ble nevnt av %{name} i:'
subject: Du ble nevnt av %{name}
reblog:
body: 'Din status fikk en boost av %{name}:'
subject: "%{name} ga din status en boost"
body: 'Din status ble reblogget av %{name}:'
subject: "%{name} reblogget din status"
pagination:
next: Neste
prev: Forrige
@ -142,10 +142,10 @@
visibilities:
private: Vis kun til følgere
public: Offentlig
unlisted: Offentlig, men vis ikke på offentlig tidslinje
unlisted: Offentlig, men vis ikke på forent tidslinje
stream_entries:
click_to_show: Klikk for å vise
reblogged: boostet
reblogged: reblogget
sensitive_content: Sensitivt innhold
time:
formats:

View file

@ -9,7 +9,7 @@ ru:
contact: Связаться
description_headline: Что такое %{domain}?
domain_count_after: другими узлами
domain_count_before: Связывается с
domain_count_before: Связан с
features:
api: Открытый API для приложений и сервисов
blocks: Продвинутые инструменты блокирования и глушения
@ -25,7 +25,7 @@ ru:
other_instances: Другие узлы
source_code: Исходный код
status_count_after: статусов
status_count_before: Автор
status_count_before: Опубликовано
terms: Условия
user_count_after: пользователей
user_count_before: Здесь живет
@ -42,7 +42,7 @@ ru:
application_mailer:
settings: 'Изменить настройки e-mail: %{link}'
signature: Уведомления Mastodon от %{instance}
view: 'View:'
view: 'Просмотр:'
applications:
invalid_url: Введенный URL неверен
auth:
@ -112,7 +112,7 @@ ru:
subject: "%{name} теперь подписан(а) на Вас"
follow_request:
body: "%{name} запросил Вас о подписке"
subject: '%{name} хочет подписаться на Вас'
subject: "%{name} хочет подписаться на Вас"
mention:
body: 'Вас упомянул(а) %{name} в:'
subject: Вы были упомянуты %{name}
@ -126,7 +126,7 @@ ru:
acct: Введите username@domain, откуда Вы хотите подписаться
missing_resource: Поиск требуемого перенаправления URL для Вашего аккаунта завершился неудачей
proceed: Продолжить подписку
prompt: 'Вы ходите подписаться на:'
prompt: 'Вы хотите подписаться на:'
settings:
authorized_apps: Авторизованные приложения
back: Назад в Mastodon
@ -142,8 +142,8 @@ ru:
show_more: Подробнее
visibilities:
private: Показывать только подписчикам
public: Публичный
unlisted: Публичный, но без отображения в публичных лентах
public: Показывать всем
unlisted: Показывать всем, но не отображать в публичных лентах
stream_entries:
click_to_show: Показать
reblogged: продвинул(а)
@ -152,12 +152,17 @@ ru:
formats:
default: "%b %d, %Y, %H:%M"
two_factor_auth:
code_hint: Для подтверждения введите код, сгенерированный приложением аутентификатора
description_html: При включении <strong>двухфакторной аутентификации</strong>, вход потребует от Вас использования Вашего телефона, который сгенерирует входные токены.
disable: Отключить
enable: Включить
instructions_html: "<strong>Отсканируйте этот QR-код с помощью Google Authenticator или другого подобного приложения на Вашем телефоне</strong>. С этого момента приложение будет генерировать токены, которые будет необходимо ввести для входа."
manual_instructions: 'Если Вы не можете отсканировать QR-код и хотите ввести его вручную, секрет представлен здесь открытым текстом:'
plaintext_secret_html: 'Секрет открытым текстом: <samp>%{secret}</samp>'
setup: Настроить
warning: Если сейчас у Вас не получается настроить аутентификатор, нажмите "отключить", иначе Вы не сможете войти!
users:
invalid_email: Введенный e-mail неверен
invalid_otp_token: Введен неверный код
will_paginate:
page_gap: "&hellip;"

View file

@ -0,0 +1,46 @@
---
hr:
simple_form:
hints:
defaults:
avatar: PNG, GIF ili JPG. Najviše 2MB. Bit će smanjen na 120x120px
display_name: Najviše 30 znakova
header: PNG, GIF ili JPG. Najviše 2MB. Bit će smanjen na 700x335px
locked: traži te da ručno odobriš sljedbenike i postavlja privatnost postova na dostupnu samo sljedbenicima
note: Najviše 160 znakova
imports:
data: CSV fajl izvezen iz druge Mastodon instance
labels:
defaults:
avatar: Avatar
confirm_new_password: Potvrdi novu lozinku
confirm_password: Potvrdi lozinku
current_password: Trenutna lozinka
data: Podaci
display_name: Ime koje ću prikazati
email: E-mail adresa
header: Header
locale: Jezik
locked: Učini račun privatnim
new_password: Nova lozinka
note: Bio
otp_attempt: Dvo-faktorski kod
password: Lozinka
setting_default_privacy: Privatnost posta
type: Tip uvoženja
username: Korisničko ime
interactions:
must_be_follower: Blokiraj notifikacije onih koji me ne slijede
must_be_following: Blokiraj notifikacije ljudi koje ne slijedim
notification_emails:
digest: Šalji mi e-mailove s notifikacijama
favourite: Pošalji mi e-mail kad netko lajka moj status
follow: Pošalji mi e-mail kad me netko počne slijediti
follow_request: Pošalji mi e-mail kad mi netko pošalje zahtjev da me želi slijediti
mention: Pošalji mi e-mail kad me netko spomene
reblog: Pošalji mi e-mail kad netko rebloga moj status
'no': 'Ne'
required:
mark: "*"
text: traženo
'yes': 'Da'

View file

@ -0,0 +1,46 @@
---
bg:
simple_form:
hints:
defaults:
avatar: PNG, GIF или JPG. До 2MB. Ще бъде смалена до 120x120 пиксела
display_name: До 30 символа
header: PNG, GIF или JPG. До 2MB. Ще бъде смалена до 700x335 пиксела
locked: Изисква ръчно одобрение на последователите. По подразбиране, публикациите са достъпни само до последователи.
note: До 160 символа
imports:
data: CSV файл, експортиран от друга инстанция на Mastodon
labels:
defaults:
avatar: Аватар
confirm_new_password: Потвърди новата парола
confirm_password: Потвърди паролата
current_password: Текуща парола
data: Данни
display_name: Показвано име
email: E-mail адрес
header: Заглавен ред
locale: Език
locked: Направи акаунта поверителен
new_password: Нова парола
note: Био
otp_attempt: Двустепенен код
password: Парола
setting_default_privacy: Поверителност на публикациите
type: Тип на импортиране
username: Потребителско име
interactions:
must_be_follower: Блокирай известия от не-последователи
must_be_following: Блокирай известия от хора, които не следваш
notification_emails:
digest: Изпращай извлечения на съобщенията
favourite: Изпращай e-mail, когато някой хареса твоя публикация
follow: Изпращай e-mail, когато някой те последва
follow_request: Изпращай e-mail, когато някой пожелае да те последва
mention: Изпращай e-mail, когато някой те спомене
reblog: Изпращай e-mail, когато някой сподели твоя публикация
'no': 'Не'
required:
mark: "*"
text: задължително
'yes': 'Да'

View file

@ -26,10 +26,11 @@ en:
note: Bio
otp_attempt: Two-factor code
password: Password
setting_boost_modal: Show confirmation dialog before boosting
setting_default_privacy: Post privacy
severity: Severity
type: Import type
username: Username
setting_boost_modal: Show confirmation dialog before boosting
interactions:
must_be_follower: Block notifications from non-followers
must_be_following: Block notifications from people you don't follow

View file

@ -26,7 +26,9 @@ fr:
note: Présentation
otp_attempt: Code d'identification à deux facteurs
password: Mot de passe
setting_boost_modal: Afficher un dialogue de confirmation avant de partager
setting_default_privacy: Confidentialité des statuts
severity: Séverité
type: Type d'import
username: Identifiant
interactions:

View file

@ -26,10 +26,10 @@ ja:
note: プロフィール
otp_attempt: 二段階認証コード
password: パスワード
setting_boost_modal: ブーストする前に確認ダイアログを表示する
setting_default_privacy: 投稿の公開範囲
type: インポートする項目
username: ユーザー名
setting_boost_modal: ブーストする前に確認ダイアログを表示する
interactions:
must_be_follower: フォロワー以外からの通知をブロック
must_be_following: フォローしていないユーザーからの通知をブロック
@ -40,8 +40,8 @@ ja:
follow_request: フォローリクエストを受けた時にメールで通知する
mention: 返信が来た時にメールで通知する
reblog: トゥートがブーストされた時にメールで通知する
'no': 'いいえ'
'no': いいえ
required:
mark: "*"
text: 必須
'yes': 'はい'
'yes': はい

View file

@ -0,0 +1,46 @@
---
nl:
simple_form:
hints:
defaults:
avatar: PNG, GIF of JPG. Maximaal 2MB. Wordt teruggeschaald naar 120x120px
display_name: Maximaal 30 tekens
header: PNG, GIF of JPG. Maximaal 2MB. Wordt teruggeschaald naar 700x335px
locked: Vereist dat je handmatig volgers accepteert en stelt standaard plaatsen berichten privacy in op alleen-volgers
note: Maximaal 160 characters
imports:
data: CSV file geëxporteerd van een andere Mastodon server
labels:
defaults:
avatar: Avatar
confirm_new_password: Bevestig nieuw wachtwoord
confirm_password: Bevestig wachtwoord
current_password: Huidige wachtwoord
data: Gegevens
display_name: Weergavenaam
email: E-mailadres
header: Kop
locale: Taal
locked: Maak account besloten
new_password: Nieuwe wachtwoord
note: Bio
otp_attempt: Twee-factor code
password: Wachtwoord
setting_default_privacy: Berichten privacy
type: Import type
username: gebruikersnaam
interactions:
must_be_follower: Blokkeermeldingen van niet-volgers
must_be_following: Blokkeer meldingen van mensen die je niet volgt
notification_emails:
digest: Verstuur samenvattingse-mails
favourite: Verstuur een e-mail wanneer iemand je status als favoriet markeert
follow: Verstuur een e-mail wanneer iemand je volgt
follow_request: Verstuur een e-mail wanneer iemand je wil volgen
mention: Verstuur een e-mail wanneer iemand je vermeld
reblog: Verstuur een e-mail wanneer iemand je status boost
'no': 'Nee'
required:
mark: "*"
text: vereist
'yes': 'Ja'

View file

@ -26,21 +26,22 @@
note: Biografi
otp_attempt: To-faktor kode
password: Passord
setting_boost_modal: Vis bekreftelsesdialog før reblogging
setting_default_privacy: Leserettigheter for poster
type: Importeringstype
username: Brukernavn
interactions:
must_be_follower: Blokker meldinger fra ikke-følgere
must_be_following: Blokker meldinger fra folk du ikke følger
must_be_follower: Blokker varslinger fra ikke-følgere
must_be_following: Blokker varslinger fra folk du ikke følger
notification_emails:
digest: Send oppsummerings eposter
digest: Send oppsummeringseposter
favourite: Send e-post når noen liker din status
follow: Send e-post når noen følger deg
follow_request: Send e-post når noen spør om å få følge deg
follow_request: Send e-post når noen ber om å få følge deg
mention: Send e-post når noen nevner deg
reblog: Send e-post når noen reblogger din status
'no': 'Nei'
'no': Nei
required:
mark: "*"
text: påkrevd
'yes': 'Ja'
'yes': Ja

View file

@ -26,7 +26,7 @@ ru:
note: О Вас
otp_attempt: Двухфакторный код
password: Пароль
setting_default_privacy: Приватность постов
setting_default_privacy: Видимость постов
type: Тип импорта
username: Имя пользователя
interactions:

Some files were not shown because too many files have changed in this diff Show more