forked from treehouse/mastodon
Merge pull request #332 from glitch-soc/merge-upstream
Merge in home feed regeneration changes from upstreamrebase/4.0.0rc2
commit
26ecee79bf
|
@ -9,7 +9,11 @@ class Api::V1::Timelines::HomeController < Api::BaseController
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@statuses = load_statuses
|
@statuses = load_statuses
|
||||||
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id)
|
|
||||||
|
render json: @statuses,
|
||||||
|
each_serializer: REST::StatusSerializer,
|
||||||
|
relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id),
|
||||||
|
status: regeneration_in_progress? ? 206 : 200
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -57,4 +61,8 @@ class Api::V1::Timelines::HomeController < Api::BaseController
|
||||||
def pagination_since_id
|
def pagination_since_id
|
||||||
@statuses.first.id
|
@statuses.first.id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def regeneration_in_progress?
|
||||||
|
Redis.current.exists("account:#{current_account.id}:regeneration")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,13 +19,14 @@ export const TIMELINE_DISCONNECT = 'TIMELINE_DISCONNECT';
|
||||||
|
|
||||||
export const TIMELINE_CONTEXT_UPDATE = 'CONTEXT_UPDATE';
|
export const TIMELINE_CONTEXT_UPDATE = 'CONTEXT_UPDATE';
|
||||||
|
|
||||||
export function refreshTimelineSuccess(timeline, statuses, skipLoading, next) {
|
export function refreshTimelineSuccess(timeline, statuses, skipLoading, next, partial) {
|
||||||
return {
|
return {
|
||||||
type: TIMELINE_REFRESH_SUCCESS,
|
type: TIMELINE_REFRESH_SUCCESS,
|
||||||
timeline,
|
timeline,
|
||||||
statuses,
|
statuses,
|
||||||
skipLoading,
|
skipLoading,
|
||||||
next,
|
next,
|
||||||
|
partial,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -88,7 +89,7 @@ export function refreshTimeline(timelineId, path, params = {}) {
|
||||||
return function (dispatch, getState) {
|
return function (dispatch, getState) {
|
||||||
const timeline = getState().getIn(['timelines', timelineId], ImmutableMap());
|
const timeline = getState().getIn(['timelines', timelineId], ImmutableMap());
|
||||||
|
|
||||||
if (timeline.get('isLoading') || timeline.get('online')) {
|
if (timeline.get('isLoading') || (timeline.get('online') && !timeline.get('isPartial'))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,8 +105,12 @@ export function refreshTimeline(timelineId, path, params = {}) {
|
||||||
dispatch(refreshTimelineRequest(timelineId, skipLoading));
|
dispatch(refreshTimelineRequest(timelineId, skipLoading));
|
||||||
|
|
||||||
api(getState).get(path, { params }).then(response => {
|
api(getState).get(path, { params }).then(response => {
|
||||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
if (response.status === 206) {
|
||||||
dispatch(refreshTimelineSuccess(timelineId, response.data, skipLoading, next ? next.uri : null));
|
dispatch(refreshTimelineSuccess(timelineId, [], skipLoading, null, true));
|
||||||
|
} else {
|
||||||
|
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||||
|
dispatch(refreshTimelineSuccess(timelineId, response.data, skipLoading, next ? next.uri : null, false));
|
||||||
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
dispatch(refreshTimelineFail(timelineId, error, skipLoading));
|
dispatch(refreshTimelineFail(timelineId, error, skipLoading));
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,9 +2,14 @@ import React from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
const MissingIndicator = () => (
|
const MissingIndicator = () => (
|
||||||
<div className='missing-indicator'>
|
<div className='regeneration-indicator missing-indicator'>
|
||||||
<div>
|
<div>
|
||||||
<FormattedMessage id='missing_indicator.label' defaultMessage='Not found' />
|
<div className='regeneration-indicator__figure' />
|
||||||
|
|
||||||
|
<div className='regeneration-indicator__label'>
|
||||||
|
<FormattedMessage id='missing_indicator.label' tagName='strong' defaultMessage='Not found' />
|
||||||
|
<FormattedMessage id='missing_indicator.sublabel' defaultMessage='This resource could not be found' />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
|
||||||
import StatusContainer from 'flavours/glitch/containers/status_container';
|
import StatusContainer from 'flavours/glitch/containers/status_container';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import ScrollableList from './scrollable_list';
|
import ScrollableList from './scrollable_list';
|
||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
export default class StatusList extends ImmutablePureComponent {
|
export default class StatusList extends ImmutablePureComponent {
|
||||||
|
|
||||||
|
@ -16,6 +17,7 @@ export default class StatusList extends ImmutablePureComponent {
|
||||||
trackScroll: PropTypes.bool,
|
trackScroll: PropTypes.bool,
|
||||||
shouldUpdateScroll: PropTypes.func,
|
shouldUpdateScroll: PropTypes.func,
|
||||||
isLoading: PropTypes.bool,
|
isLoading: PropTypes.bool,
|
||||||
|
isPartial: PropTypes.bool,
|
||||||
hasMore: PropTypes.bool,
|
hasMore: PropTypes.bool,
|
||||||
prepend: PropTypes.node,
|
prepend: PropTypes.node,
|
||||||
emptyMessage: PropTypes.node,
|
emptyMessage: PropTypes.node,
|
||||||
|
@ -48,8 +50,23 @@ export default class StatusList extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { statusIds, ...other } = this.props;
|
const { statusIds, ...other } = this.props;
|
||||||
const { isLoading } = other;
|
const { isLoading, isPartial } = other;
|
||||||
|
|
||||||
|
if (isPartial) {
|
||||||
|
return (
|
||||||
|
<div className='regeneration-indicator'>
|
||||||
|
<div>
|
||||||
|
<div className='regeneration-indicator__figure' />
|
||||||
|
|
||||||
|
<div className='regeneration-indicator__label'>
|
||||||
|
<FormattedMessage id='regeneration_indicator.label' tagName='strong' defaultMessage='Loading…' />
|
||||||
|
<FormattedMessage id='regeneration_indicator.sublabel' defaultMessage='Your home feed is being prepared!' />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const scrollableContent = (isLoading || statusIds.size > 0) ? (
|
const scrollableContent = (isLoading || statusIds.size > 0) ? (
|
||||||
statusIds.map((statusId) => (
|
statusIds.map((statusId) => (
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { expandHomeTimeline } from 'flavours/glitch/actions/timelines';
|
import { expandHomeTimeline, refreshHomeTimeline } from 'flavours/glitch/actions/timelines';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import StatusListContainer from 'flavours/glitch/features/ui/containers/status_list_container';
|
import StatusListContainer from 'flavours/glitch/features/ui/containers/status_list_container';
|
||||||
import Column from 'flavours/glitch/components/column';
|
import Column from 'flavours/glitch/components/column';
|
||||||
|
@ -16,6 +16,7 @@ const messages = defineMessages({
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
hasUnread: state.getIn(['timelines', 'home', 'unread']) > 0,
|
hasUnread: state.getIn(['timelines', 'home', 'unread']) > 0,
|
||||||
|
isPartial: state.getIn(['timelines', 'home', 'isPartial'], false),
|
||||||
});
|
});
|
||||||
|
|
||||||
@connect(mapStateToProps)
|
@connect(mapStateToProps)
|
||||||
|
@ -26,6 +27,7 @@ export default class HomeTimeline extends React.PureComponent {
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
hasUnread: PropTypes.bool,
|
hasUnread: PropTypes.bool,
|
||||||
|
isPartial: PropTypes.bool,
|
||||||
columnId: PropTypes.string,
|
columnId: PropTypes.string,
|
||||||
multiColumn: PropTypes.bool,
|
multiColumn: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
@ -57,6 +59,39 @@ export default class HomeTimeline extends React.PureComponent {
|
||||||
this.props.dispatch(expandHomeTimeline());
|
this.props.dispatch(expandHomeTimeline());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount () {
|
||||||
|
this._checkIfReloadNeeded(false, this.props.isPartial);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate (prevProps) {
|
||||||
|
this._checkIfReloadNeeded(prevProps.isPartial, this.props.isPartial);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount () {
|
||||||
|
this._stopPolling();
|
||||||
|
}
|
||||||
|
|
||||||
|
_checkIfReloadNeeded (wasPartial, isPartial) {
|
||||||
|
const { dispatch } = this.props;
|
||||||
|
|
||||||
|
if (wasPartial === isPartial) {
|
||||||
|
return;
|
||||||
|
} else if (!wasPartial && isPartial) {
|
||||||
|
this.polling = setInterval(() => {
|
||||||
|
dispatch(refreshHomeTimeline());
|
||||||
|
}, 3000);
|
||||||
|
} else if (wasPartial && !isPartial) {
|
||||||
|
this._stopPolling();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_stopPolling () {
|
||||||
|
if (this.polling) {
|
||||||
|
clearInterval(this.polling);
|
||||||
|
this.polling = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, hasUnread, columnId, multiColumn } = this.props;
|
const { intl, hasUnread, columnId, multiColumn } = this.props;
|
||||||
const pinned = !!columnId;
|
const pinned = !!columnId;
|
||||||
|
|
|
@ -120,13 +120,17 @@ export default class ListTimeline extends React.PureComponent {
|
||||||
if (typeof list === 'undefined') {
|
if (typeof list === 'undefined') {
|
||||||
return (
|
return (
|
||||||
<Column>
|
<Column>
|
||||||
<LoadingIndicator />
|
<div className='scrollable'>
|
||||||
|
<LoadingIndicator />
|
||||||
|
</div>
|
||||||
</Column>
|
</Column>
|
||||||
);
|
);
|
||||||
} else if (list === false) {
|
} else if (list === false) {
|
||||||
return (
|
return (
|
||||||
<Column>
|
<Column>
|
||||||
<MissingIndicator />
|
<div className='scrollable'>
|
||||||
|
<MissingIndicator />
|
||||||
|
</div>
|
||||||
</Column>
|
</Column>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ const makeMapStateToProps = () => {
|
||||||
const mapStateToProps = (state, { timelineId }) => ({
|
const mapStateToProps = (state, { timelineId }) => ({
|
||||||
statusIds: getStatusIds(state, { type: timelineId }),
|
statusIds: getStatusIds(state, { type: timelineId }),
|
||||||
isLoading: state.getIn(['timelines', timelineId, 'isLoading'], true),
|
isLoading: state.getIn(['timelines', timelineId, 'isLoading'], true),
|
||||||
|
isPartial: state.getIn(['timelines', timelineId, 'isPartial'], false),
|
||||||
hasMore: !!state.getIn(['timelines', timelineId, 'next']),
|
hasMore: !!state.getIn(['timelines', timelineId, 'next']),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 11 KiB |
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 8.3 KiB |
|
@ -30,7 +30,7 @@ const initialTimeline = ImmutableMap({
|
||||||
items: ImmutableList(),
|
items: ImmutableList(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const normalizeTimeline = (state, timeline, statuses, next) => {
|
const normalizeTimeline = (state, timeline, statuses, next, isPartial) => {
|
||||||
const oldIds = state.getIn([timeline, 'items'], ImmutableList());
|
const oldIds = state.getIn([timeline, 'items'], ImmutableList());
|
||||||
const ids = ImmutableList(statuses.map(status => status.get('id'))).filter(newId => !oldIds.includes(newId));
|
const ids = ImmutableList(statuses.map(status => status.get('id'))).filter(newId => !oldIds.includes(newId));
|
||||||
const wasLoaded = state.getIn([timeline, 'loaded']);
|
const wasLoaded = state.getIn([timeline, 'loaded']);
|
||||||
|
@ -41,6 +41,7 @@ const normalizeTimeline = (state, timeline, statuses, next) => {
|
||||||
mMap.set('isLoading', false);
|
mMap.set('isLoading', false);
|
||||||
if (!hadNext) mMap.set('next', next);
|
if (!hadNext) mMap.set('next', next);
|
||||||
mMap.set('items', wasLoaded ? ids.concat(oldIds) : ids);
|
mMap.set('items', wasLoaded ? ids.concat(oldIds) : ids);
|
||||||
|
mMap.set('isPartial', isPartial);
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -125,7 +126,7 @@ export default function timelines(state = initialState, action) {
|
||||||
case TIMELINE_EXPAND_FAIL:
|
case TIMELINE_EXPAND_FAIL:
|
||||||
return state.update(action.timeline, initialTimeline, map => map.set('isLoading', false));
|
return state.update(action.timeline, initialTimeline, map => map.set('isLoading', false));
|
||||||
case TIMELINE_REFRESH_SUCCESS:
|
case TIMELINE_REFRESH_SUCCESS:
|
||||||
return normalizeTimeline(state, action.timeline, fromJS(action.statuses), action.next);
|
return normalizeTimeline(state, action.timeline, fromJS(action.statuses), action.next, action.partial);
|
||||||
case TIMELINE_EXPAND_SUCCESS:
|
case TIMELINE_EXPAND_SUCCESS:
|
||||||
return appendNormalizedTimeline(state, action.timeline, fromJS(action.statuses), action.next);
|
return appendNormalizedTimeline(state, action.timeline, fromJS(action.statuses), action.next);
|
||||||
case TIMELINE_UPDATE:
|
case TIMELINE_UPDATE:
|
||||||
|
|
|
@ -838,21 +838,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.missing-indicator {
|
.missing-indicator {
|
||||||
text-align: center;
|
padding-top: 20px + 48px;
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: lighten($ui-base-color, 16%);
|
|
||||||
background: $ui-base-color;
|
|
||||||
cursor: default;
|
|
||||||
display: flex;
|
|
||||||
flex: 1 1 auto;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
& > div {
|
.regeneration-indicator__figure {
|
||||||
background: url('~images/mastodon-not-found.png') no-repeat center -50px;
|
background-image: url('~flavours/glitch/images/elephant_ui_disappointed.svg');
|
||||||
padding-top: 210px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1162,6 +1151,7 @@ noscript {
|
||||||
@import 'metadata';
|
@import 'metadata';
|
||||||
@import 'composer';
|
@import 'composer';
|
||||||
@import 'columns';
|
@import 'columns';
|
||||||
|
@import 'regeneration_indicator';
|
||||||
@import 'search';
|
@import 'search';
|
||||||
@import 'emoji';
|
@import 'emoji';
|
||||||
@import 'doodle';
|
@import 'doodle';
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
.regeneration-indicator {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: lighten($ui-base-color, 16%);
|
||||||
|
background: $ui-base-color;
|
||||||
|
cursor: default;
|
||||||
|
display: flex;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 20px;
|
||||||
|
|
||||||
|
& > div {
|
||||||
|
width: 100%;
|
||||||
|
background: transparent;
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__figure {
|
||||||
|
background: url('~flavours/glitch/images/elephant_ui_working.svg') no-repeat center 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 160px;
|
||||||
|
background-size: contain;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.missing-indicator {
|
||||||
|
padding-top: 20px + 48px;
|
||||||
|
|
||||||
|
.regeneration-indicator__figure {
|
||||||
|
background-image: url('~flavours/glitch/images/elephant_ui_disappointed.svg');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__label {
|
||||||
|
margin-top: 200px;
|
||||||
|
|
||||||
|
strong {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
color: lighten($ui-base-color, 34%);
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
Before Width: | Height: | Size: 24 KiB |
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 11 KiB |
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 8.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 19 KiB |
|
@ -19,13 +19,14 @@ export const TIMELINE_DISCONNECT = 'TIMELINE_DISCONNECT';
|
||||||
|
|
||||||
export const TIMELINE_CONTEXT_UPDATE = 'CONTEXT_UPDATE';
|
export const TIMELINE_CONTEXT_UPDATE = 'CONTEXT_UPDATE';
|
||||||
|
|
||||||
export function refreshTimelineSuccess(timeline, statuses, skipLoading, next) {
|
export function refreshTimelineSuccess(timeline, statuses, skipLoading, next, partial) {
|
||||||
return {
|
return {
|
||||||
type: TIMELINE_REFRESH_SUCCESS,
|
type: TIMELINE_REFRESH_SUCCESS,
|
||||||
timeline,
|
timeline,
|
||||||
statuses,
|
statuses,
|
||||||
skipLoading,
|
skipLoading,
|
||||||
next,
|
next,
|
||||||
|
partial,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -88,7 +89,7 @@ export function refreshTimeline(timelineId, path, params = {}) {
|
||||||
return function (dispatch, getState) {
|
return function (dispatch, getState) {
|
||||||
const timeline = getState().getIn(['timelines', timelineId], ImmutableMap());
|
const timeline = getState().getIn(['timelines', timelineId], ImmutableMap());
|
||||||
|
|
||||||
if (timeline.get('isLoading') || timeline.get('online')) {
|
if (timeline.get('isLoading') || (timeline.get('online') && !timeline.get('isPartial'))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,8 +105,12 @@ export function refreshTimeline(timelineId, path, params = {}) {
|
||||||
dispatch(refreshTimelineRequest(timelineId, skipLoading));
|
dispatch(refreshTimelineRequest(timelineId, skipLoading));
|
||||||
|
|
||||||
api(getState).get(path, { params }).then(response => {
|
api(getState).get(path, { params }).then(response => {
|
||||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
if (response.status === 206) {
|
||||||
dispatch(refreshTimelineSuccess(timelineId, response.data, skipLoading, next ? next.uri : null));
|
dispatch(refreshTimelineSuccess(timelineId, [], skipLoading, null, true));
|
||||||
|
} else {
|
||||||
|
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||||
|
dispatch(refreshTimelineSuccess(timelineId, response.data, skipLoading, next ? next.uri : null, false));
|
||||||
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
dispatch(refreshTimelineFail(timelineId, error, skipLoading));
|
dispatch(refreshTimelineFail(timelineId, error, skipLoading));
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,9 +2,14 @@ import React from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
const MissingIndicator = () => (
|
const MissingIndicator = () => (
|
||||||
<div className='missing-indicator'>
|
<div className='regeneration-indicator missing-indicator'>
|
||||||
<div>
|
<div>
|
||||||
<FormattedMessage id='missing_indicator.label' defaultMessage='Not found' />
|
<div className='regeneration-indicator__figure' />
|
||||||
|
|
||||||
|
<div className='regeneration-indicator__label'>
|
||||||
|
<FormattedMessage id='missing_indicator.label' tagName='strong' defaultMessage='Not found' />
|
||||||
|
<FormattedMessage id='missing_indicator.sublabel' defaultMessage='This resource could not be found' />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
|
||||||
import StatusContainer from '../containers/status_container';
|
import StatusContainer from '../containers/status_container';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import ScrollableList from './scrollable_list';
|
import ScrollableList from './scrollable_list';
|
||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
export default class StatusList extends ImmutablePureComponent {
|
export default class StatusList extends ImmutablePureComponent {
|
||||||
|
|
||||||
|
@ -16,6 +17,7 @@ export default class StatusList extends ImmutablePureComponent {
|
||||||
trackScroll: PropTypes.bool,
|
trackScroll: PropTypes.bool,
|
||||||
shouldUpdateScroll: PropTypes.func,
|
shouldUpdateScroll: PropTypes.func,
|
||||||
isLoading: PropTypes.bool,
|
isLoading: PropTypes.bool,
|
||||||
|
isPartial: PropTypes.bool,
|
||||||
hasMore: PropTypes.bool,
|
hasMore: PropTypes.bool,
|
||||||
prepend: PropTypes.node,
|
prepend: PropTypes.node,
|
||||||
emptyMessage: PropTypes.node,
|
emptyMessage: PropTypes.node,
|
||||||
|
@ -48,8 +50,23 @@ export default class StatusList extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { statusIds, ...other } = this.props;
|
const { statusIds, ...other } = this.props;
|
||||||
const { isLoading } = other;
|
const { isLoading, isPartial } = other;
|
||||||
|
|
||||||
|
if (isPartial) {
|
||||||
|
return (
|
||||||
|
<div className='regeneration-indicator'>
|
||||||
|
<div>
|
||||||
|
<div className='regeneration-indicator__figure' />
|
||||||
|
|
||||||
|
<div className='regeneration-indicator__label'>
|
||||||
|
<FormattedMessage id='regeneration_indicator.label' tagName='strong' defaultMessage='Loading…' />
|
||||||
|
<FormattedMessage id='regeneration_indicator.sublabel' defaultMessage='Your home feed is being prepared!' />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const scrollableContent = (isLoading || statusIds.size > 0) ? (
|
const scrollableContent = (isLoading || statusIds.size > 0) ? (
|
||||||
statusIds.map((statusId) => (
|
statusIds.map((statusId) => (
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { expandHomeTimeline } from '../../actions/timelines';
|
import { expandHomeTimeline, refreshHomeTimeline } from '../../actions/timelines';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import StatusListContainer from '../ui/containers/status_list_container';
|
import StatusListContainer from '../ui/containers/status_list_container';
|
||||||
import Column from '../../components/column';
|
import Column from '../../components/column';
|
||||||
|
@ -16,6 +16,7 @@ const messages = defineMessages({
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
hasUnread: state.getIn(['timelines', 'home', 'unread']) > 0,
|
hasUnread: state.getIn(['timelines', 'home', 'unread']) > 0,
|
||||||
|
isPartial: state.getIn(['timelines', 'home', 'isPartial'], false),
|
||||||
});
|
});
|
||||||
|
|
||||||
@connect(mapStateToProps)
|
@connect(mapStateToProps)
|
||||||
|
@ -26,6 +27,7 @@ export default class HomeTimeline extends React.PureComponent {
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
hasUnread: PropTypes.bool,
|
hasUnread: PropTypes.bool,
|
||||||
|
isPartial: PropTypes.bool,
|
||||||
columnId: PropTypes.string,
|
columnId: PropTypes.string,
|
||||||
multiColumn: PropTypes.bool,
|
multiColumn: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
@ -57,6 +59,39 @@ export default class HomeTimeline extends React.PureComponent {
|
||||||
this.props.dispatch(expandHomeTimeline());
|
this.props.dispatch(expandHomeTimeline());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount () {
|
||||||
|
this._checkIfReloadNeeded(false, this.props.isPartial);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate (prevProps) {
|
||||||
|
this._checkIfReloadNeeded(prevProps.isPartial, this.props.isPartial);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount () {
|
||||||
|
this._stopPolling();
|
||||||
|
}
|
||||||
|
|
||||||
|
_checkIfReloadNeeded (wasPartial, isPartial) {
|
||||||
|
const { dispatch } = this.props;
|
||||||
|
|
||||||
|
if (wasPartial === isPartial) {
|
||||||
|
return;
|
||||||
|
} else if (!wasPartial && isPartial) {
|
||||||
|
this.polling = setInterval(() => {
|
||||||
|
dispatch(refreshHomeTimeline());
|
||||||
|
}, 3000);
|
||||||
|
} else if (wasPartial && !isPartial) {
|
||||||
|
this._stopPolling();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_stopPolling () {
|
||||||
|
if (this.polling) {
|
||||||
|
clearInterval(this.polling);
|
||||||
|
this.polling = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, hasUnread, columnId, multiColumn } = this.props;
|
const { intl, hasUnread, columnId, multiColumn } = this.props;
|
||||||
const pinned = !!columnId;
|
const pinned = !!columnId;
|
||||||
|
|
|
@ -120,13 +120,17 @@ export default class ListTimeline extends React.PureComponent {
|
||||||
if (typeof list === 'undefined') {
|
if (typeof list === 'undefined') {
|
||||||
return (
|
return (
|
||||||
<Column>
|
<Column>
|
||||||
<LoadingIndicator />
|
<div className='scrollable'>
|
||||||
|
<LoadingIndicator />
|
||||||
|
</div>
|
||||||
</Column>
|
</Column>
|
||||||
);
|
);
|
||||||
} else if (list === false) {
|
} else if (list === false) {
|
||||||
return (
|
return (
|
||||||
<Column>
|
<Column>
|
||||||
<MissingIndicator />
|
<div className='scrollable'>
|
||||||
|
<MissingIndicator />
|
||||||
|
</div>
|
||||||
</Column>
|
</Column>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ const makeMapStateToProps = () => {
|
||||||
const mapStateToProps = (state, { timelineId }) => ({
|
const mapStateToProps = (state, { timelineId }) => ({
|
||||||
statusIds: getStatusIds(state, { type: timelineId }),
|
statusIds: getStatusIds(state, { type: timelineId }),
|
||||||
isLoading: state.getIn(['timelines', timelineId, 'isLoading'], true),
|
isLoading: state.getIn(['timelines', timelineId, 'isLoading'], true),
|
||||||
|
isPartial: state.getIn(['timelines', timelineId, 'isPartial'], false),
|
||||||
hasMore: !!state.getIn(['timelines', timelineId, 'next']),
|
hasMore: !!state.getIn(['timelines', timelineId, 'next']),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
"column_header.unpin": "Desafixar",
|
"column_header.unpin": "Desafixar",
|
||||||
"column_subheading.navigation": "Navegação",
|
"column_subheading.navigation": "Navegação",
|
||||||
"column_subheading.settings": "Configurações",
|
"column_subheading.settings": "Configurações",
|
||||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
"compose_form.hashtag_warning": "Esse toot não será listado em nenhuma hashtag por ser não listado. Somente toots públicos podem ser pesquisados por hashtag.",
|
||||||
"compose_form.lock_disclaimer": "A sua conta não está {locked}. Qualquer pessoa pode te seguir e visualizar postagens direcionadas a apenas seguidores.",
|
"compose_form.lock_disclaimer": "A sua conta não está {locked}. Qualquer pessoa pode te seguir e visualizar postagens direcionadas a apenas seguidores.",
|
||||||
"compose_form.lock_disclaimer.lock": "trancada",
|
"compose_form.lock_disclaimer.lock": "trancada",
|
||||||
"compose_form.placeholder": "No que você está pensando?",
|
"compose_form.placeholder": "No que você está pensando?",
|
||||||
|
@ -223,7 +223,7 @@
|
||||||
"status.media_hidden": "Mídia escondida",
|
"status.media_hidden": "Mídia escondida",
|
||||||
"status.mention": "Mencionar @{name}",
|
"status.mention": "Mencionar @{name}",
|
||||||
"status.more": "Mais",
|
"status.more": "Mais",
|
||||||
"status.mute": "Mute @{name}",
|
"status.mute": "Silenciar @{name}",
|
||||||
"status.mute_conversation": "Silenciar conversa",
|
"status.mute_conversation": "Silenciar conversa",
|
||||||
"status.open": "Expandir",
|
"status.open": "Expandir",
|
||||||
"status.pin": "Fixar no perfil",
|
"status.pin": "Fixar no perfil",
|
||||||
|
|
|
@ -195,8 +195,8 @@
|
||||||
"privacy.private.short": "Iba sledujúci",
|
"privacy.private.short": "Iba sledujúci",
|
||||||
"privacy.public.long": "Pošli všetkým",
|
"privacy.public.long": "Pošli všetkým",
|
||||||
"privacy.public.short": "Verejne",
|
"privacy.public.short": "Verejne",
|
||||||
"privacy.unlisted.long": "Neposielať verejne",
|
"privacy.unlisted.long": "Neposielať do verejných časových osí",
|
||||||
"privacy.unlisted.short": "Nie je v zozname",
|
"privacy.unlisted.short": "Verejne mimo osí",
|
||||||
"relative_time.days": "{number}d",
|
"relative_time.days": "{number}d",
|
||||||
"relative_time.hours": "{number}h",
|
"relative_time.hours": "{number}h",
|
||||||
"relative_time.just_now": "now",
|
"relative_time.just_now": "now",
|
||||||
|
|
|
@ -30,7 +30,7 @@ const initialTimeline = ImmutableMap({
|
||||||
items: ImmutableList(),
|
items: ImmutableList(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const normalizeTimeline = (state, timeline, statuses, next) => {
|
const normalizeTimeline = (state, timeline, statuses, next, isPartial) => {
|
||||||
const oldIds = state.getIn([timeline, 'items'], ImmutableList());
|
const oldIds = state.getIn([timeline, 'items'], ImmutableList());
|
||||||
const ids = ImmutableList(statuses.map(status => status.get('id'))).filter(newId => !oldIds.includes(newId));
|
const ids = ImmutableList(statuses.map(status => status.get('id'))).filter(newId => !oldIds.includes(newId));
|
||||||
const wasLoaded = state.getIn([timeline, 'loaded']);
|
const wasLoaded = state.getIn([timeline, 'loaded']);
|
||||||
|
@ -41,6 +41,7 @@ const normalizeTimeline = (state, timeline, statuses, next) => {
|
||||||
mMap.set('isLoading', false);
|
mMap.set('isLoading', false);
|
||||||
if (!hadNext) mMap.set('next', next);
|
if (!hadNext) mMap.set('next', next);
|
||||||
mMap.set('items', wasLoaded ? ids.concat(oldIds) : ids);
|
mMap.set('items', wasLoaded ? ids.concat(oldIds) : ids);
|
||||||
|
mMap.set('isPartial', isPartial);
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -124,7 +125,7 @@ export default function timelines(state = initialState, action) {
|
||||||
case TIMELINE_EXPAND_FAIL:
|
case TIMELINE_EXPAND_FAIL:
|
||||||
return state.update(action.timeline, initialTimeline, map => map.set('isLoading', false));
|
return state.update(action.timeline, initialTimeline, map => map.set('isLoading', false));
|
||||||
case TIMELINE_REFRESH_SUCCESS:
|
case TIMELINE_REFRESH_SUCCESS:
|
||||||
return normalizeTimeline(state, action.timeline, fromJS(action.statuses), action.next);
|
return normalizeTimeline(state, action.timeline, fromJS(action.statuses), action.next, action.partial);
|
||||||
case TIMELINE_EXPAND_SUCCESS:
|
case TIMELINE_EXPAND_SUCCESS:
|
||||||
return appendNormalizedTimeline(state, action.timeline, fromJS(action.statuses), action.next);
|
return appendNormalizedTimeline(state, action.timeline, fromJS(action.statuses), action.next);
|
||||||
case TIMELINE_UPDATE:
|
case TIMELINE_UPDATE:
|
||||||
|
|
|
@ -2303,7 +2303,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.missing-indicator {
|
.regeneration-indicator {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
@ -2314,11 +2314,46 @@
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
padding: 20px;
|
||||||
|
|
||||||
& > div {
|
& > div {
|
||||||
background: url('~images/mastodon-not-found.png') no-repeat center -50px;
|
|
||||||
padding-top: 210px;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
background: transparent;
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__figure {
|
||||||
|
background: url('~images/elephant_ui_working.svg') no-repeat center 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 160px;
|
||||||
|
background-size: contain;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.missing-indicator {
|
||||||
|
padding-top: 20px + 48px;
|
||||||
|
|
||||||
|
.regeneration-indicator__figure {
|
||||||
|
background-image: url('~images/elephant_ui_disappointed.svg');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__label {
|
||||||
|
margin-top: 200px;
|
||||||
|
|
||||||
|
strong {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
color: lighten($ui-base-color, 34%);
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2749,7 +2784,6 @@
|
||||||
@keyframes heartbeat {
|
@keyframes heartbeat {
|
||||||
from {
|
from {
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
transform-origin: center center;
|
|
||||||
animation-timing-function: ease-out;
|
animation-timing-function: ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2775,6 +2809,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.pulse-loading {
|
.pulse-loading {
|
||||||
|
transform-origin: center center;
|
||||||
animation: heartbeat 1.5s ease-in-out infinite both;
|
animation: heartbeat 1.5s ease-in-out infinite both;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ class NotifyService < BaseService
|
||||||
end
|
end
|
||||||
|
|
||||||
def response_to_recipient?
|
def response_to_recipient?
|
||||||
@notification.target_status.in_reply_to_account_id == @recipient.id
|
@notification.target_status.in_reply_to_account_id == @recipient.id && @notification.target_status.thread&.direct_visibility?
|
||||||
end
|
end
|
||||||
|
|
||||||
def optional_non_following_and_direct?
|
def optional_non_following_and_direct?
|
||||||
|
|
|
@ -3,5 +3,6 @@
|
||||||
class PrecomputeFeedService < BaseService
|
class PrecomputeFeedService < BaseService
|
||||||
def call(account)
|
def call(account)
|
||||||
FeedManager.instance.populate_feed(account)
|
FeedManager.instance.populate_feed(account)
|
||||||
|
Redis.current.del("account:#{account.id}:regeneration")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
class RegenerationWorker
|
class RegenerationWorker
|
||||||
include Sidekiq::Worker
|
include Sidekiq::Worker
|
||||||
|
|
||||||
sidekiq_options queue: 'pull', backtrace: true, unique: :until_executed
|
sidekiq_options unique: :until_executed
|
||||||
|
|
||||||
def perform(account_id, _ = :home)
|
def perform(account_id, _ = :home)
|
||||||
account = Account.find(account_id)
|
account = Account.find(account_id)
|
||||||
|
|
|
@ -265,12 +265,18 @@ ca:
|
||||||
unresolved: No resolt
|
unresolved: No resolt
|
||||||
view: Visualització
|
view: Visualització
|
||||||
settings:
|
settings:
|
||||||
|
activity_api_enabled:
|
||||||
|
desc_html: Compte d'estatus publicats localment, usuaris actius i registres nous en cubs setmanals
|
||||||
|
title: Publica estadístiques agregades sobre l'activitat de l'usuari
|
||||||
bootstrap_timeline_accounts:
|
bootstrap_timeline_accounts:
|
||||||
desc_html: Separa diversos noms d'usuari amb comes. Només funcionaran els comptes locals i desbloquejats. El valor predeterminat quan està buit és tots els administradors locals..
|
desc_html: Separa diversos noms d'usuari amb comes. Només funcionaran els comptes locals i desbloquejats. El valor predeterminat quan està buit és tots els administradors locals..
|
||||||
title: El seguiment per defecte per als nous usuaris
|
title: El seguiment per defecte per als nous usuaris
|
||||||
contact_information:
|
contact_information:
|
||||||
email: Introdueix una adreça de correu electrònic pùblica
|
email: Introdueix una adreça de correu electrònic pùblica
|
||||||
username: Introdueix un nom d'usuari
|
username: Introdueix un nom d'usuari
|
||||||
|
peers_api_enabled:
|
||||||
|
desc_html: Els noms de domini que ha trobat aquesta instància al fediverse
|
||||||
|
title: Publica la llista d'instàncies descobertes
|
||||||
registrations:
|
registrations:
|
||||||
closed_message:
|
closed_message:
|
||||||
desc_html: Apareix en la primera pàgina quan es tanquen els registres<br>Pots utilitzar etiquetes HTML
|
desc_html: Apareix en la primera pàgina quan es tanquen els registres<br>Pots utilitzar etiquetes HTML
|
||||||
|
@ -345,7 +351,7 @@ ca:
|
||||||
warning: Aneu amb compte amb aquestes dades. No ho compartiu mai amb ningú!
|
warning: Aneu amb compte amb aquestes dades. No ho compartiu mai amb ningú!
|
||||||
your_token: El token d'accés
|
your_token: El token d'accés
|
||||||
auth:
|
auth:
|
||||||
agreement_html: En inscriure't, acceptes <a href="%{rules_path}">els nostres termes del servei</a> i <a href="%{terms_path}">la nostra política de privadesa</a>.
|
agreement_html: En inscriure't, acceptes seguir <a href="%{rules_path}">els nostres termes del servei</a> i <a href="%{terms_path}">la nostra política de privadesa</a>.
|
||||||
change_password: Canvia la contrasenya
|
change_password: Canvia la contrasenya
|
||||||
delete_account: Esborra el compte
|
delete_account: Esborra el compte
|
||||||
delete_account_html: Si vols esborrar el teu compte pots <a href="%{path}">fer-ho aquí</a>. Se't demanarà confirmació.
|
delete_account_html: Si vols esborrar el teu compte pots <a href="%{path}">fer-ho aquí</a>. Se't demanarà confirmació.
|
||||||
|
@ -546,12 +552,14 @@ ca:
|
||||||
blackberry: Blackberry
|
blackberry: Blackberry
|
||||||
chrome: Chrome
|
chrome: Chrome
|
||||||
edge: Microsoft Edge
|
edge: Microsoft Edge
|
||||||
|
electron: Electron
|
||||||
firefox: Firefox
|
firefox: Firefox
|
||||||
generic: Navegador desconegut
|
generic: Navegador desconegut
|
||||||
ie: Internet Explorer
|
ie: Internet Explorer
|
||||||
micro_messenger: MicroMessenger
|
micro_messenger: MicroMessenger
|
||||||
nokia: Nokia S40 Ovi Browser
|
nokia: Nokia S40 Ovi Browser
|
||||||
opera: Opera
|
opera: Opera
|
||||||
|
otter: Altre
|
||||||
phantom_js: PhantomJS
|
phantom_js: PhantomJS
|
||||||
qq: QQ Browser
|
qq: QQ Browser
|
||||||
safari: Safari
|
safari: Safari
|
||||||
|
@ -596,7 +604,7 @@ ca:
|
||||||
open_in_web: Obre en la web
|
open_in_web: Obre en la web
|
||||||
over_character_limit: Límit de caràcters de %{max} superat
|
over_character_limit: Límit de caràcters de %{max} superat
|
||||||
pin_errors:
|
pin_errors:
|
||||||
limit: S'han fixat massa toots
|
limit: Ja has fixat el màxim nombre de toots
|
||||||
ownership: El toot d'algú altre no es pot fixar
|
ownership: El toot d'algú altre no es pot fixar
|
||||||
private: No es pot fixar el toot no públic
|
private: No es pot fixar el toot no públic
|
||||||
reblog: No es pot fixar un impuls
|
reblog: No es pot fixar un impuls
|
||||||
|
|
|
@ -17,11 +17,32 @@ ca:
|
||||||
unconfirmed: Has de confirmar l'adreça de correu electrònic abans de continuar.
|
unconfirmed: Has de confirmar l'adreça de correu electrònic abans de continuar.
|
||||||
mailer:
|
mailer:
|
||||||
confirmation_instructions:
|
confirmation_instructions:
|
||||||
|
action: Verificar l'adreça de correu
|
||||||
|
explanation: Has creat un compte a %{host} amb aquesta adreça de correu electrònic. Estàs a un sol clic de l'activació. Si no fos així, ignora aquest correu electrònic.
|
||||||
|
extra_html: Si us plau consulta també <a href="%{terms_path}"> les regles de la instància</a> i <a href="%{policy_path}"> les nostres condicions de servei</a>.
|
||||||
subject: 'Mastodon: Instruccions de confirmació'
|
subject: 'Mastodon: Instruccions de confirmació'
|
||||||
|
title: Verifica l'adreça de correu
|
||||||
|
email_changed:
|
||||||
|
explanation: 'L''adreça de correu del teu compte s''està canviant a:'
|
||||||
|
extra: Si no has canviat el teu correu electrònic, és probable que algú hagi accedit al teu compte. Si us plau, canvia la contrasenya immediatament o posa't en contacte amb l'administrador de l'instància si no pots accedir al teu compte.
|
||||||
|
subject: 'Mastodon: s''ha canviat l''adreça electrònica'
|
||||||
|
title: Nova adreça de correu electrònic
|
||||||
password_change:
|
password_change:
|
||||||
|
explanation: S'ha canviat la contrasenya del teu compte.
|
||||||
|
extra: Si no has canviat el teu correu electrònic, és probable que algú hagi accedit al teu compte. Si us plau, canvia la contrasenya immediatament o posa't en contacte amb l'administrador de l'instància si no pots accedir al teu compte.
|
||||||
subject: 'Mastodon: Contrasenya canviada'
|
subject: 'Mastodon: Contrasenya canviada'
|
||||||
|
title: Contrasenya canviada
|
||||||
|
reconfirmation_instructions:
|
||||||
|
explanation: Confirma la nova adreça per canviar el teu correu electrònic.
|
||||||
|
extra: Si no has iniciat aquest canvi, ignora aquest correu electrònic. L'adreça electrònica del compte de Mastodon no canviarà fins que accedeixis a l'enllaç de dalt.
|
||||||
|
subject: 'Mastodon: Confirma el correu electrònic per a %{instance}'
|
||||||
|
title: Verifica l'adreça de correu electrònic
|
||||||
reset_password_instructions:
|
reset_password_instructions:
|
||||||
|
action: Canviar contrasenya
|
||||||
|
explanation: Has sol·licitat una contrasenya nova per al teu compte.
|
||||||
|
extra: Si no ho has sol·licitat, ignora aquest correu electrònic. La teva contrasenya no canviarà fins que accedeixis a l'enllaç de dalt i creis un de nou.
|
||||||
subject: 'Mastodon: Instruccions per a reiniciar contrassenya'
|
subject: 'Mastodon: Instruccions per a reiniciar contrassenya'
|
||||||
|
title: Contrasenya restablerta
|
||||||
unlock_instructions:
|
unlock_instructions:
|
||||||
subject: 'Mastodon: Instruccions per a desblocar'
|
subject: 'Mastodon: Instruccions per a desblocar'
|
||||||
omniauth_callbacks:
|
omniauth_callbacks:
|
||||||
|
|
|
@ -18,8 +18,12 @@ gl:
|
||||||
mailer:
|
mailer:
|
||||||
confirmation_instructions:
|
confirmation_instructions:
|
||||||
subject: 'Mastodon: Instruccións de confirmación para %{instance}'
|
subject: 'Mastodon: Instruccións de confirmación para %{instance}'
|
||||||
|
email_changed:
|
||||||
|
subject: 'Mastodon: email cambiado'
|
||||||
password_change:
|
password_change:
|
||||||
subject: 'Mastodon: contrasinal cambiado'
|
subject: 'Mastodon: contrasinal cambiado'
|
||||||
|
reconfirmation_instructions:
|
||||||
|
subject: 'Mastodon: Confirme email para %{instance}'
|
||||||
reset_password_instructions:
|
reset_password_instructions:
|
||||||
subject: 'Mastodon: Instruccións para restablecer o contrasinal'
|
subject: 'Mastodon: Instruccións para restablecer o contrasinal'
|
||||||
unlock_instructions:
|
unlock_instructions:
|
||||||
|
|
|
@ -17,15 +17,32 @@ ja:
|
||||||
unconfirmed: 続行するにはメールアドレスを確認する必要があります。
|
unconfirmed: 続行するにはメールアドレスを確認する必要があります。
|
||||||
mailer:
|
mailer:
|
||||||
confirmation_instructions:
|
confirmation_instructions:
|
||||||
|
action: メールアドレスの確認
|
||||||
|
explanation: このメールアドレスで%{host}にアカウントを作成しました。有効にするまであと一歩です。もし心当たりがない場合、申し訳ありませんがこのメールを無視してください。
|
||||||
|
extra_html: また <a href="%{terms_path}">インスタンスのルール</a> と <a href="%{policy_path}">利用規約</a> もお読みください。
|
||||||
subject: 'Mastodon: メールアドレスの確認'
|
subject: 'Mastodon: メールアドレスの確認'
|
||||||
|
title: メールアドレスの確認
|
||||||
email_changed:
|
email_changed:
|
||||||
|
explanation: 'アカウントのメールアドレスは以下のように変更されます:'
|
||||||
|
extra: メールアドレスの変更を行っていない場合、他の誰かがあなたのアカウントにアクセスした可能性があります。すぐにパスワードを変更するか、アカウントがロックされている場合はインスタンス管理者に連絡してください。
|
||||||
subject: 'Mastodon: メールアドレスの変更'
|
subject: 'Mastodon: メールアドレスの変更'
|
||||||
|
title: 新しいメールアドレス
|
||||||
password_change:
|
password_change:
|
||||||
|
explanation: パスワードが変更されました。
|
||||||
|
extra: パスワードの変更を行っていない場合、他の誰かがあなたのアカウントにアクセスした可能性があります。すぐにパスワードを変更するか、アカウントがロックされている場合はインスタンス管理者に連絡してください。
|
||||||
subject: 'Mastodon: パスワードが変更されました'
|
subject: 'Mastodon: パスワードが変更されました'
|
||||||
|
title: パスワードの変更
|
||||||
reconfirmation_instructions:
|
reconfirmation_instructions:
|
||||||
|
explanation: メールアドレスを変更するため新しいアドレスを確認してください。
|
||||||
|
extra: この変更に心当たりがない場合、このメールを無視してください。上記リンク先にアクセスするまでアカウントのメールアドレスは変更されません。
|
||||||
subject: 'Mastodon: %{instance}のメールを確認する'
|
subject: 'Mastodon: %{instance}のメールを確認する'
|
||||||
|
title: メールアドレスの確認
|
||||||
reset_password_instructions:
|
reset_password_instructions:
|
||||||
|
action: パスワードの変更
|
||||||
|
explanation: あなたのアカウントに対しパスワードの再発行が要求されました。
|
||||||
|
extra: この要求に心当たりがない場合、このメールを無視してください。上記リンク先にアクセスし新しいものを作成するまでパスワードは変更されません。
|
||||||
subject: 'Mastodon: パスワード再発行'
|
subject: 'Mastodon: パスワード再発行'
|
||||||
|
title: パスワード再発行
|
||||||
unlock_instructions:
|
unlock_instructions:
|
||||||
subject: 'Mastodon: アカウントのロックの解除'
|
subject: 'Mastodon: アカウントのロックの解除'
|
||||||
omniauth_callbacks:
|
omniauth_callbacks:
|
||||||
|
|
|
@ -19,8 +19,12 @@ nl:
|
||||||
mailer:
|
mailer:
|
||||||
confirmation_instructions:
|
confirmation_instructions:
|
||||||
subject: 'Mastodon: E-mail bevestigen voor %{instance}'
|
subject: 'Mastodon: E-mail bevestigen voor %{instance}'
|
||||||
|
email_changed:
|
||||||
|
subject: 'Mastodon: E-mailadres is veranderd'
|
||||||
password_change:
|
password_change:
|
||||||
subject: 'Mastodon: Wachtwoord veranderd'
|
subject: 'Mastodon: Wachtwoord veranderd'
|
||||||
|
reconfirmation_instructions:
|
||||||
|
subject: 'Mastodon: Bevestig het e-mailadres voor %{instance}'
|
||||||
reset_password_instructions:
|
reset_password_instructions:
|
||||||
subject: 'Mastodon: Wachtwoord opnieuw instellen'
|
subject: 'Mastodon: Wachtwoord opnieuw instellen'
|
||||||
unlock_instructions:
|
unlock_instructions:
|
||||||
|
|
|
@ -17,15 +17,32 @@ pl:
|
||||||
unconfirmed: Zweryfikuj adres e-mail, aby kontynuować.
|
unconfirmed: Zweryfikuj adres e-mail, aby kontynuować.
|
||||||
mailer:
|
mailer:
|
||||||
confirmation_instructions:
|
confirmation_instructions:
|
||||||
|
action: Zweryfikuj adres e-mail
|
||||||
|
explanation: Utworzyłeś konto na %{host} podając ten adres e-mail. Jedno kliknięcie dzieli Cię od aktywacji tego konta. Jeżeli to nie Ty, zignoruj ten e-mail.
|
||||||
|
extra_html: Przeczytaj też <a href="%{terms_path}">regulamin instancji</a> i <a href="%{policy_path}">nasze zasady użytkowania</a>.
|
||||||
subject: 'Mastodon: Instrukcje weryfikacji adresu e-mail'
|
subject: 'Mastodon: Instrukcje weryfikacji adresu e-mail'
|
||||||
|
title: Zweryfikuj adres e-mail
|
||||||
email_changed:
|
email_changed:
|
||||||
|
explanation: 'Adres e-mail dla Twojego konta zostanie zmieniony na:'
|
||||||
|
extra: Jeżeli nie próbowałeś zmienić adresu e-mail, prawdopodobnie ktoś uzyskał dostęp do Twojego konta. Zmień natychmiastowo hasło lub skontaktuj się z administratorem isntancji, jeżeli nie masz dostępu do konta.
|
||||||
subject: 'Mastodon: Zmieniono adres e-mail'
|
subject: 'Mastodon: Zmieniono adres e-mail'
|
||||||
|
title: Nowy adres e-mail
|
||||||
password_change:
|
password_change:
|
||||||
|
explanation: Hasło do Twojego konta zostało zmienione.
|
||||||
|
extra: Jeżeli nie zmieniałeś hasła, prawdopodobnie ktoś uzyskał dostęp do Twojego konta. Zmień hasło natychmiastowo lub skontaktuj się z administratorem instancji, jeżeli nie masz dostępu do konta.
|
||||||
subject: 'Mastodon: Zmieniono hasło'
|
subject: 'Mastodon: Zmieniono hasło'
|
||||||
|
title: Zmieniono hasło
|
||||||
reconfirmation_instructions:
|
reconfirmation_instructions:
|
||||||
|
explanation: Potwierdź nowy adres aby zmienić e-mail.
|
||||||
|
extra: Jeżeli nie próbowałeś zmienić e-maila, zignoruj tą wiadomość. Adres e-mail przypisany do konta Mastodona nie ulegnie zmianie, jeżeli nie użyjesz powyższego odnośniku.
|
||||||
subject: 'Mastodon: Potwierdź adres e-mail na &{instance}'
|
subject: 'Mastodon: Potwierdź adres e-mail na &{instance}'
|
||||||
|
title: Zweryfikuj adres e-mail
|
||||||
reset_password_instructions:
|
reset_password_instructions:
|
||||||
|
action: Zmień hasło
|
||||||
|
explanation: Próbowałeś uzyskać nowe hasło do swojego konta.
|
||||||
|
extra: Jeżeli to nie Ty, zignoruj tą wiadomość. Twoje hasło nie ulegnie zmianie, jeżeli nie wykorzystasz powyższego odnośnika i nie utworzysz nowego hasła.
|
||||||
subject: 'Mastodon: Instrukcje ustawienia nowego hasła'
|
subject: 'Mastodon: Instrukcje ustawienia nowego hasła'
|
||||||
|
title: Przywracanie hasła
|
||||||
unlock_instructions:
|
unlock_instructions:
|
||||||
subject: 'Mastodon: Instrukcje odblokowania konta'
|
subject: 'Mastodon: Instrukcje odblokowania konta'
|
||||||
omniauth_callbacks:
|
omniauth_callbacks:
|
||||||
|
@ -38,7 +55,7 @@ pl:
|
||||||
updated: Twoje hasło zostało zmienione. Jesteś zalogowany/a.
|
updated: Twoje hasło zostało zmienione. Jesteś zalogowany/a.
|
||||||
updated_not_active: Twoje hasło zostało zmienione.
|
updated_not_active: Twoje hasło zostało zmienione.
|
||||||
registrations:
|
registrations:
|
||||||
destroyed: Twoje konto zostało anulowane. Mamy jednak nadzieję, że do nas wrócisz. Do zobaczenia!
|
destroyed: Twoje konto zostało zawieszone. Mamy jednak nadzieję, że do nas wrócisz. Do zobaczenia!
|
||||||
signed_up: Twoje konto zostało utworzone. Witamy!
|
signed_up: Twoje konto zostało utworzone. Witamy!
|
||||||
signed_up_but_inactive: Twoje konto zostało utworzone. Nie mogliśmy Cię jednak zalogować, ponieważ konto nie zostało jeszcze aktywowane.
|
signed_up_but_inactive: Twoje konto zostało utworzone. Nie mogliśmy Cię jednak zalogować, ponieważ konto nie zostało jeszcze aktywowane.
|
||||||
signed_up_but_locked: Twoje konto zostało utworzone. Nie mogliśmy Cię jednak zalogować, ponieważ konto jest zablokowane.
|
signed_up_but_locked: Twoje konto zostało utworzone. Nie mogliśmy Cię jednak zalogować, ponieważ konto jest zablokowane.
|
||||||
|
|
|
@ -18,8 +18,12 @@ pt-BR:
|
||||||
mailer:
|
mailer:
|
||||||
confirmation_instructions:
|
confirmation_instructions:
|
||||||
subject: 'Mastodon: Instruções de confirmação'
|
subject: 'Mastodon: Instruções de confirmação'
|
||||||
|
email_changed:
|
||||||
|
subject: 'Mastodon: Email alterado'
|
||||||
password_change:
|
password_change:
|
||||||
subject: 'Mastodon: Senha modificada'
|
subject: 'Mastodon: Senha modificada'
|
||||||
|
reconfirmation_instructions:
|
||||||
|
subject: 'Mastodon: Confirmar emai para %{instance}'
|
||||||
reset_password_instructions:
|
reset_password_instructions:
|
||||||
subject: 'Mastodon: Instruções para mudança de senha'
|
subject: 'Mastodon: Instruções para mudança de senha'
|
||||||
unlock_instructions:
|
unlock_instructions:
|
||||||
|
|
|
@ -83,7 +83,7 @@ pl:
|
||||||
invalid_grant: Grant uwierzytelnienia jest niepoprawny, przeterminowany, unieważniony, nie pasuje do URI przekierowwania użytego w żądaniu uwierzytelnienia, lub został wystawiony przez innego klienta.
|
invalid_grant: Grant uwierzytelnienia jest niepoprawny, przeterminowany, unieważniony, nie pasuje do URI przekierowwania użytego w żądaniu uwierzytelnienia, lub został wystawiony przez innego klienta.
|
||||||
invalid_redirect_uri: URI przekierowania jest nieprawidłowy.
|
invalid_redirect_uri: URI przekierowania jest nieprawidłowy.
|
||||||
invalid_request: 'Żądanie jest nieprawidłowe: brakujący parametr, niewspierana wartość parametru, lub inny błąd.'
|
invalid_request: 'Żądanie jest nieprawidłowe: brakujący parametr, niewspierana wartość parametru, lub inny błąd.'
|
||||||
invalid_resource_owner: Dostarczone dane uwierzytelniające właściciela zasobu są niepoprawne, lub właściciel zasobu nie może zostać znaleziony.
|
invalid_resource_owner: Dostarczone dane uwierzytelniające właściciela zasobu są niepoprawne, lub właściciel zasobu nie może zostać znaleziony
|
||||||
invalid_scope: Zakres żądania jest niepoprawny, nieznany, lub błędnie zbudowany.
|
invalid_scope: Zakres żądania jest niepoprawny, nieznany, lub błędnie zbudowany.
|
||||||
invalid_token:
|
invalid_token:
|
||||||
expired: Token dostępowy wygasł
|
expired: Token dostępowy wygasł
|
||||||
|
|
|
@ -265,12 +265,18 @@ gl:
|
||||||
unresolved: Non resolto
|
unresolved: Non resolto
|
||||||
view: Vista
|
view: Vista
|
||||||
settings:
|
settings:
|
||||||
|
activity_api_enabled:
|
||||||
|
desc_html: Conta de estados publicados localmente, usuarias activas, e novos rexistros por semana
|
||||||
|
title: Publicar estatísticas agregadas sobre a actividade da usuaria
|
||||||
bootstrap_timeline_accounts:
|
bootstrap_timeline_accounts:
|
||||||
desc_html: Separar múltiples nomes de usuaria con vírgulas. Só funcionarán as contas locais non bloqueadas. Si baldeiro, por omisión son todos os local admin.
|
desc_html: Separar múltiples nomes de usuaria con vírgulas. Só funcionarán as contas locais non bloqueadas. Si baldeiro, por omisión son todos os local admin.
|
||||||
title: Seguimentos por omisión para novas usuarias
|
title: Seguimentos por omisión para novas usuarias
|
||||||
contact_information:
|
contact_information:
|
||||||
email: e-mail de traballo
|
email: e-mail de traballo
|
||||||
username: Nome de usuaria de contacto
|
username: Nome de usuaria de contacto
|
||||||
|
peers_api_enabled:
|
||||||
|
desc_html: Nome de dominio que esta instancia atopou no fediverso
|
||||||
|
title: Publicar lista de instancias descubertas
|
||||||
registrations:
|
registrations:
|
||||||
closed_message:
|
closed_message:
|
||||||
desc_html: Mostrado na páxina de portada cando o rexistro está pechado. Pode utilizar etiquetas HTML
|
desc_html: Mostrado na páxina de portada cando o rexistro está pechado. Pode utilizar etiquetas HTML
|
||||||
|
@ -509,6 +515,7 @@ gl:
|
||||||
quadrillion: Q
|
quadrillion: Q
|
||||||
thousand: K
|
thousand: K
|
||||||
trillion: T
|
trillion: T
|
||||||
|
unit: " "
|
||||||
pagination:
|
pagination:
|
||||||
next: Seguinte
|
next: Seguinte
|
||||||
prev: Previo
|
prev: Previo
|
||||||
|
|
|
@ -338,10 +338,13 @@ ja:
|
||||||
body: "%{reporter} が %{target} を通報しました"
|
body: "%{reporter} が %{target} を通報しました"
|
||||||
subject: "%{instance} の新しい通報 (#%{id})"
|
subject: "%{instance} の新しい通報 (#%{id})"
|
||||||
application_mailer:
|
application_mailer:
|
||||||
|
notification_preferences: メール設定の変更
|
||||||
salutation: "%{name} さん"
|
salutation: "%{name} さん"
|
||||||
settings: 'メール設定の変更: %{link}'
|
settings: 'メール設定の変更: %{link}'
|
||||||
signature: Mastodon %{instance} インスタンスからの通知
|
signature: Mastodon %{instance} インスタンスからの通知
|
||||||
view: 'リンク:'
|
view: 'リンク:'
|
||||||
|
view_profile: プロフィールを表示
|
||||||
|
view_status: トゥートを表示
|
||||||
applications:
|
applications:
|
||||||
created: アプリが作成されました
|
created: アプリが作成されました
|
||||||
destroyed: アプリが削除されました
|
destroyed: アプリが削除されました
|
||||||
|
@ -491,29 +494,38 @@ ja:
|
||||||
title: モデレーション
|
title: モデレーション
|
||||||
notification_mailer:
|
notification_mailer:
|
||||||
digest:
|
digest:
|
||||||
|
action: 全ての通知を表示
|
||||||
body: "%{instance} での最後のログインからの出来事:"
|
body: "%{instance} での最後のログインからの出来事:"
|
||||||
mention: "%{name} さんがあなたに返信しました:"
|
mention: "%{name} さんがあなたに返信しました:"
|
||||||
new_followers_summary:
|
new_followers_summary:
|
||||||
one: 新たなフォロワーを獲得しました!
|
one: また、離れている間に新たなフォロワーを獲得しました!
|
||||||
other: "%{count} 人の新たなフォロワーを獲得しました!"
|
other: また、離れている間に%{count} 人の新たなフォロワーを獲得しました!
|
||||||
subject:
|
subject:
|
||||||
one: "新しい1件の通知 \U0001F418"
|
one: "新しい1件の通知 \U0001F418"
|
||||||
other: "新しい%{count}件の通知 \U0001F418"
|
other: "新しい%{count}件の通知 \U0001F418"
|
||||||
|
title: 不在の間に…
|
||||||
favourite:
|
favourite:
|
||||||
body: "%{name} さんにお気に入り登録された、あなたのトゥートがあります:"
|
body: "%{name} さんにお気に入り登録された、あなたのトゥートがあります:"
|
||||||
subject: "%{name} さんにお気に入りに登録されました"
|
subject: "%{name} さんにお気に入りに登録されました"
|
||||||
|
title: 新たなお気に入り登録
|
||||||
follow:
|
follow:
|
||||||
body: "%{name} さんにフォローされています!"
|
body: "%{name} さんにフォローされています!"
|
||||||
subject: "%{name} さんにフォローされています"
|
subject: "%{name} さんにフォローされています"
|
||||||
|
title: 新たなフォロワー
|
||||||
follow_request:
|
follow_request:
|
||||||
|
action: フォローリクエストの管理
|
||||||
body: "%{name} さんがあなたにフォローをリクエストしました"
|
body: "%{name} さんがあなたにフォローをリクエストしました"
|
||||||
subject: "%{name} さんからのフォローリクエスト"
|
subject: "%{name} さんからのフォローリクエスト"
|
||||||
|
title: 新たなフォローリクエスト
|
||||||
mention:
|
mention:
|
||||||
|
action: 返信
|
||||||
body: "%{name} さんから返信がありました:"
|
body: "%{name} さんから返信がありました:"
|
||||||
subject: "%{name} さんに返信されました"
|
subject: "%{name} さんに返信されました"
|
||||||
|
title: 新たな返信
|
||||||
reblog:
|
reblog:
|
||||||
body: "%{name} さんにブーストされた、あなたのトゥートがあります:"
|
body: "%{name} さんにブーストされた、あなたのトゥートがあります:"
|
||||||
subject: "%{name} さんにブーストされました"
|
subject: "%{name} さんにブーストされました"
|
||||||
|
title: 新たなブースト
|
||||||
number:
|
number:
|
||||||
human:
|
human:
|
||||||
decimal_units:
|
decimal_units:
|
||||||
|
|
|
@ -265,12 +265,18 @@ nl:
|
||||||
unresolved: Onopgelost
|
unresolved: Onopgelost
|
||||||
view: Weergeven
|
view: Weergeven
|
||||||
settings:
|
settings:
|
||||||
|
activity_api_enabled:
|
||||||
|
desc_html: Wekelijks overzicht van de hoeveelheid lokale toots, actieve gebruikers en nieuwe registraties
|
||||||
|
title: Statistieken over gebruikersactiviteit publiceren
|
||||||
bootstrap_timeline_accounts:
|
bootstrap_timeline_accounts:
|
||||||
desc_html: Meerdere gebruikersnamen met komma's scheiden. Alleen lokale en niet opgeschorte accounts werken. Laat leeg voor alle lokale beheerders.
|
desc_html: Meerdere gebruikersnamen met komma's scheiden. Alleen lokale en niet opgeschorte accounts werken. Laat leeg voor alle lokale beheerders.
|
||||||
title: Standaard te volgen accounts voor nieuwe gebruikers
|
title: Standaard te volgen accounts voor nieuwe gebruikers
|
||||||
contact_information:
|
contact_information:
|
||||||
email: Vul een openbaar gebruikt e-mailadres in
|
email: Vul een openbaar gebruikt e-mailadres in
|
||||||
username: Vul een gebruikersnaam in
|
username: Vul een gebruikersnaam in
|
||||||
|
peers_api_enabled:
|
||||||
|
desc_html: Domeinnamen die deze server in de fediverse is tegengekomen
|
||||||
|
title: Lijst van bekende servers publiceren
|
||||||
registrations:
|
registrations:
|
||||||
closed_message:
|
closed_message:
|
||||||
desc_html: Wordt op de voorpagina weergegeven wanneer registratie van nieuwe accounts is uitgeschakeld<br>En ook hier kan je HTML gebruiken
|
desc_html: Wordt op de voorpagina weergegeven wanneer registratie van nieuwe accounts is uitgeschakeld<br>En ook hier kan je HTML gebruiken
|
||||||
|
@ -476,11 +482,11 @@ nl:
|
||||||
title: Moderatie
|
title: Moderatie
|
||||||
notification_mailer:
|
notification_mailer:
|
||||||
digest:
|
digest:
|
||||||
body: 'Hier is een korte samenvatting van wat je hebt gemist op %{instance} sinds jouw laatste bezoek op %{since}:'
|
body: Hier is een korte samenvatting van de berichten die je sinds jouw laatste bezoek op %{since} hebt gemist
|
||||||
mention: "%{name} vermeldde jou in:"
|
mention: "%{name} vermeldde jou in:"
|
||||||
new_followers_summary:
|
new_followers_summary:
|
||||||
one: Jij hebt een nieuwe volger! Hoera!
|
one: Je hebt trouwens sinds je weg was er ook een nieuwe volger bijgekregen! Hoera!
|
||||||
other: Jij hebt %{count} nieuwe volgers! Prachtig!
|
other: Je hebt trouwens sinds je weg was er ook %{count} nieuwe volgers bijgekregen! Fantastisch!
|
||||||
subject:
|
subject:
|
||||||
one: "1 nieuwe melding sinds jouw laatste bezoek \U0001F418"
|
one: "1 nieuwe melding sinds jouw laatste bezoek \U0001F418"
|
||||||
other: "%{count} nieuwe meldingen sinds jouw laatste bezoek \U0001F418"
|
other: "%{count} nieuwe meldingen sinds jouw laatste bezoek \U0001F418"
|
||||||
|
|
|
@ -46,7 +46,7 @@ pl:
|
||||||
posts: Wpisy
|
posts: Wpisy
|
||||||
posts_with_replies: Wpisy z odpowiedziami
|
posts_with_replies: Wpisy z odpowiedziami
|
||||||
remote_follow: Śledź zdalnie
|
remote_follow: Śledź zdalnie
|
||||||
reserved_username: Ta nazwa użytkownika jest zarezerwowana.
|
reserved_username: Ta nazwa użytkownika jest zarezerwowana
|
||||||
roles:
|
roles:
|
||||||
admin: Administrator
|
admin: Administrator
|
||||||
moderator: Moderator
|
moderator: Moderator
|
||||||
|
@ -183,7 +183,7 @@ pl:
|
||||||
title: Niestandardowe emoji
|
title: Niestandardowe emoji
|
||||||
unlisted: Niewidoczne
|
unlisted: Niewidoczne
|
||||||
update_failed_msg: Nie udało się zaktualizować emoji
|
update_failed_msg: Nie udało się zaktualizować emoji
|
||||||
updated_msg: Pomyślnie zaktualizowano emoji
|
updated_msg: Pomyślnie zaktualizowano emoji!
|
||||||
upload: Dodaj
|
upload: Dodaj
|
||||||
domain_blocks:
|
domain_blocks:
|
||||||
add_new: Dodaj nową
|
add_new: Dodaj nową
|
||||||
|
@ -194,7 +194,7 @@ pl:
|
||||||
create: Utwórz blokadę
|
create: Utwórz blokadę
|
||||||
hint: Blokada domen nie zabroni tworzenia wpisów kont w bazie danych, ale pozwoli na automatyczną moderację kont do nich należących.
|
hint: Blokada domen nie zabroni tworzenia wpisów kont w bazie danych, ale pozwoli na automatyczną moderację kont do nich należących.
|
||||||
severity:
|
severity:
|
||||||
desc_html: "<strong>Wyciszenie</strong> uczyni wpisy użytkownika widoczne tylko dla osób, które go śledzą. <strong>Zawieszenie</strong> spowoduje usunięcie całej zawartości dodanej przez użytkownika."
|
desc_html: "<strong>Wyciszenie</strong> uczyni wpisy użytkownika widoczne tylko dla osób, które go śledzą. <strong>Zawieszenie</strong> spowoduje usunięcie całej zawartości dodanej przez użytkownika. Użyj <strong>Żadne</strong>, jeżeli chcesz jedynie odrzucać zawartość multimedialną."
|
||||||
noop: Nic nie rób
|
noop: Nic nie rób
|
||||||
silence: Wycisz
|
silence: Wycisz
|
||||||
suspend: Zawieś
|
suspend: Zawieś
|
||||||
|
@ -305,7 +305,7 @@ pl:
|
||||||
title: Niestandardowe zasady użytkowania
|
title: Niestandardowe zasady użytkowania
|
||||||
site_title: Nazwa instancji
|
site_title: Nazwa instancji
|
||||||
thumbnail:
|
thumbnail:
|
||||||
desc_html: 'Używana w podglądzie przez OpenGraph i API. Zalecany rozmiar: 1200x630 pikseli.'
|
desc_html: 'Używana w podglądzie przez OpenGraph i API. Zalecany rozmiar: 1200x630 pikseli'
|
||||||
title: Miniatura instancji
|
title: Miniatura instancji
|
||||||
timeline_preview:
|
timeline_preview:
|
||||||
desc_html: Wyświetlaj publiczną oś czasu na stronie widocznej dla niezalogowanych
|
desc_html: Wyświetlaj publiczną oś czasu na stronie widocznej dla niezalogowanych
|
||||||
|
@ -339,10 +339,12 @@ pl:
|
||||||
body: Użytkownik %{reporter} zgłosił %{target}
|
body: Użytkownik %{reporter} zgłosił %{target}
|
||||||
subject: Nowe zgłoszenie na %{instance} (#%{id})
|
subject: Nowe zgłoszenie na %{instance} (#%{id})
|
||||||
application_mailer:
|
application_mailer:
|
||||||
|
notification_preferences: Zmień ustawienia e-maili
|
||||||
salutation: "%{name},"
|
salutation: "%{name},"
|
||||||
settings: 'Zmień ustawienia powiadamiania: %{link}'
|
settings: 'Zmień ustawienia powiadamiania: %{link}'
|
||||||
signature: Powiadomienie Mastodona z instancji %{instance}
|
signature: Powiadomienie Mastodona z instancji %{instance}
|
||||||
view: 'Zobacz:'
|
view: 'Zobacz:'
|
||||||
|
view_status: Wyświetl wpis
|
||||||
applications:
|
applications:
|
||||||
created: Pomyślnie utworzono aplikację
|
created: Pomyślnie utworzono aplikację
|
||||||
destroyed: Pomyślnie usunięto aplikację
|
destroyed: Pomyślnie usunięto aplikację
|
||||||
|
@ -494,33 +496,42 @@ pl:
|
||||||
title: Moderacja
|
title: Moderacja
|
||||||
notification_mailer:
|
notification_mailer:
|
||||||
digest:
|
digest:
|
||||||
body: 'Oto krótkie podsumowanie co Cię ominęło na %{instance} od Twojej ostatniej wizyty (%{since}):'
|
action: Wyświetl wszystkie powiadomienia
|
||||||
|
body: Oto krótkie podsumowanie wiadomości, które ominęły Cię od Twojej ostatniej wizyty (%{since})
|
||||||
mention: "%{name} wspomniał o Tobie w:"
|
mention: "%{name} wspomniał o Tobie w:"
|
||||||
new_followers_summary:
|
new_followers_summary:
|
||||||
few: "(%{count}) nowe osoby śledzą Cię!"
|
few: "(%{count}) nowe osoby śledzą Cię!"
|
||||||
many: "(%{count}) nowych osób Cię śledzi! Wspaniale!"
|
many: "(%{count}) nowych osób Cię śledzi! Wspaniale!"
|
||||||
one: Śledzi Cię nowa osoba! Gratulacje!
|
one: Dodatkowo, w czasie nieobecności zaczęła śledzić Cię jedna osoba Gratulacje!
|
||||||
other: "(%{count}) nowych osób Cię śledzi! Wspaniale!"
|
other: Dodatkowo, zaczęło Cię śledzić %{count} nowych osób! Wspaniale!
|
||||||
subject:
|
subject:
|
||||||
few: "%{count} nowe powiadomienia od Twojej ostatniej wizyty \U0001F418"
|
few: "%{count} nowe powiadomienia od Twojej ostatniej wizyty \U0001F418"
|
||||||
many: "%{count} nowych powiadomień od Twojej ostatniej wizyty \U0001F418"
|
many: "%{count} nowych powiadomień od Twojej ostatniej wizyty \U0001F418"
|
||||||
one: "1 nowe powiadomienie od Twojej ostatniej wizyty \U0001F418"
|
one: "1 nowe powiadomienie od Twojej ostatniej wizyty \U0001F418"
|
||||||
other: "%{count} nowych powiadomień od Twojej ostatniej wizyty \U0001F418"
|
other: "%{count} nowych powiadomień od Twojej ostatniej wizyty \U0001F418"
|
||||||
|
title: W trakcie Twojej nieobecności…
|
||||||
favourite:
|
favourite:
|
||||||
body: 'Twój wpis został polubiony przez %{name}:'
|
body: 'Twój wpis został polubiony przez %{name}:'
|
||||||
subject: "%{name} lubi Twój wpis"
|
subject: "%{name} lubi Twój wpis"
|
||||||
|
title: Nowe polubienie
|
||||||
follow:
|
follow:
|
||||||
body: "%{name} Cię śledzi!"
|
body: "%{name} Cię śledzi!"
|
||||||
subject: "%{name} Cię śledzi"
|
subject: "%{name} Cię śledzi"
|
||||||
|
title: Nowy śledzący
|
||||||
follow_request:
|
follow_request:
|
||||||
|
action: Zarządzaj prośbami o możliwość śledzenia
|
||||||
body: "%{name} poprosił o możliwość śledzenia Cię"
|
body: "%{name} poprosił o możliwość śledzenia Cię"
|
||||||
subject: 'Prośba o możliwość śledzenia: %{name}'
|
subject: 'Prośba o możliwość śledzenia: %{name}'
|
||||||
|
title: Nowa prośba o możliwość śledzenia
|
||||||
mention:
|
mention:
|
||||||
|
action: Odpowiedz
|
||||||
body: "%{name} wspomniał o Tobie w:"
|
body: "%{name} wspomniał o Tobie w:"
|
||||||
subject: "%{name} wspomniał o Tobie"
|
subject: "%{name} wspomniał o Tobie"
|
||||||
|
title: Nowe wspomnienie o Tobie
|
||||||
reblog:
|
reblog:
|
||||||
body: 'Twój wpis został podbity przez %{name}:'
|
body: 'Twój wpis został podbity przez %{name}:'
|
||||||
subject: Twój wpis został podbity przez %{name}
|
subject: Twój wpis został podbity przez %{name}
|
||||||
|
title: Nowe podbicie
|
||||||
number:
|
number:
|
||||||
human:
|
human:
|
||||||
decimal_units:
|
decimal_units:
|
||||||
|
@ -568,12 +579,14 @@ pl:
|
||||||
blackberry: Blackberry
|
blackberry: Blackberry
|
||||||
chrome: Chrome
|
chrome: Chrome
|
||||||
edge: Microsoft Edge
|
edge: Microsoft Edge
|
||||||
|
electron: Electron
|
||||||
firefox: Firefox
|
firefox: Firefox
|
||||||
generic: nieznana przeglądarka
|
generic: nieznana przeglądarka
|
||||||
ie: Internet Explorer
|
ie: Internet Explorer
|
||||||
micro_messenger: MicroMessenger
|
micro_messenger: MicroMessenger
|
||||||
nokia: Nokia S40 Ovi Browser
|
nokia: Nokia S40 Ovi Browser
|
||||||
opera: Opera
|
opera: Opera
|
||||||
|
otter: Przeglądarka Otter
|
||||||
phantom_js: PhantomJS
|
phantom_js: PhantomJS
|
||||||
qq: QQ Browser
|
qq: QQ Browser
|
||||||
safari: Safari
|
safari: Safari
|
||||||
|
|
|
@ -265,12 +265,18 @@ pt-BR:
|
||||||
unresolved: Não resolvido
|
unresolved: Não resolvido
|
||||||
view: Visualizar
|
view: Visualizar
|
||||||
settings:
|
settings:
|
||||||
|
activity_api_enabled:
|
||||||
|
desc_html: Contagem de status postados localmente, usuários ativos e novos cadastros filtrados semanalmente
|
||||||
|
title: Publicar estatísticas agregadas sobre atividade de usuários
|
||||||
bootstrap_timeline_accounts:
|
bootstrap_timeline_accounts:
|
||||||
desc_html: Separe nomes de usuário através de vírgulas. Funciona apenas com contas locais e destrancadas. O padrão quando vazio são todos os administradores locais.
|
desc_html: Separe nomes de usuário através de vírgulas. Funciona apenas com contas locais e destrancadas. O padrão quando vazio são todos os administradores locais.
|
||||||
title: Usuários a serem seguidos por padrão por novas contas
|
title: Usuários a serem seguidos por padrão por novas contas
|
||||||
contact_information:
|
contact_information:
|
||||||
email: E-mail
|
email: E-mail
|
||||||
username: Contate usuário
|
username: Contate usuário
|
||||||
|
peers_api_enabled:
|
||||||
|
desc_html: Nomes de domínio que essa instância encontrou no fediverso
|
||||||
|
title: Publicar lista de instâncias descobertas
|
||||||
registrations:
|
registrations:
|
||||||
closed_message:
|
closed_message:
|
||||||
desc_html: Exibido na página inicial quando cadastros estão fechados. Você pode usar tags HTML
|
desc_html: Exibido na página inicial quando cadastros estão fechados. Você pode usar tags HTML
|
||||||
|
@ -285,7 +291,7 @@ pt-BR:
|
||||||
desc_html: Permitir que qualquer um crie uma conta
|
desc_html: Permitir que qualquer um crie uma conta
|
||||||
title: Cadastro aberto
|
title: Cadastro aberto
|
||||||
show_staff_badge:
|
show_staff_badge:
|
||||||
desc_html: Mostrar uma insígnia de equipe na página de usuário
|
desc_html: Mostrar uma insígnia de Equipe na página de usuário
|
||||||
title: Mostrar insígnia de equipe
|
title: Mostrar insígnia de equipe
|
||||||
site_description:
|
site_description:
|
||||||
desc_html: Parágrafo introdutório na página inicial e em meta tags. Você pode usar tags HTML, em especial <code><a></code> e <code><em></code>.
|
desc_html: Parágrafo introdutório na página inicial e em meta tags. Você pode usar tags HTML, em especial <code><a></code> e <code><em></code>.
|
||||||
|
@ -345,7 +351,7 @@ pt-BR:
|
||||||
warning: Tenha cuidado com estes dados. Nunca compartilhe com alguém!
|
warning: Tenha cuidado com estes dados. Nunca compartilhe com alguém!
|
||||||
your_token: Seu token de acesso
|
your_token: Seu token de acesso
|
||||||
auth:
|
auth:
|
||||||
agreement_html: Cadastrando-se você concorda em seguir <a href="%{rules_path}">as regras da instância</a> e <a href="%{terms_path}">os nossos termos de serviço</a>.
|
agreement_html: Ao se cadastrar você concorda em seguir <a href="%{rules_path}">as regras da instância</a> e <a href="%{terms_path}">os nossos termos de serviço</a>.
|
||||||
change_password: Segurança
|
change_password: Segurança
|
||||||
delete_account: Excluir conta
|
delete_account: Excluir conta
|
||||||
delete_account_html: Se você deseja excluir a sua conta, você pode <a href="%{path}">prosseguir para cá</a>. Uma confirmação será requisitada.
|
delete_account_html: Se você deseja excluir a sua conta, você pode <a href="%{path}">prosseguir para cá</a>. Uma confirmação será requisitada.
|
||||||
|
@ -596,7 +602,7 @@ pt-BR:
|
||||||
open_in_web: Abrir na web
|
open_in_web: Abrir na web
|
||||||
over_character_limit: limite de caracteres de %{max} excedido
|
over_character_limit: limite de caracteres de %{max} excedido
|
||||||
pin_errors:
|
pin_errors:
|
||||||
limit: Você já fixou o máximo de toots possíveis
|
limit: Você já fixou a quantidade máxima de toots
|
||||||
ownership: Toots de outras pessoas não podem ser fixados
|
ownership: Toots de outras pessoas não podem ser fixados
|
||||||
private: Toot não-público não pode ser fixado
|
private: Toot não-público não pode ser fixado
|
||||||
reblog: Um compartilhamento não pode ser fixado
|
reblog: Um compartilhamento não pode ser fixado
|
||||||
|
|
|
@ -49,6 +49,7 @@ ru:
|
||||||
reserved_username: Имя пользователя зарезервировано
|
reserved_username: Имя пользователя зарезервировано
|
||||||
roles:
|
roles:
|
||||||
admin: Администратор
|
admin: Администратор
|
||||||
|
moderator: Мод
|
||||||
unfollow: Отписаться
|
unfollow: Отписаться
|
||||||
admin:
|
admin:
|
||||||
account_moderation_notes:
|
account_moderation_notes:
|
||||||
|
@ -71,6 +72,8 @@ ru:
|
||||||
domain: Домен
|
domain: Домен
|
||||||
edit: Изменить
|
edit: Изменить
|
||||||
email: E-mail
|
email: E-mail
|
||||||
|
enable: Включить
|
||||||
|
enabled: Включен
|
||||||
feed_url: URL фида
|
feed_url: URL фида
|
||||||
followers: Подписчики
|
followers: Подписчики
|
||||||
followers_url: URL подписчиков
|
followers_url: URL подписчиков
|
||||||
|
@ -336,10 +339,12 @@ ru:
|
||||||
body: "%{reporter} подал(а) жалобу на %{target}"
|
body: "%{reporter} подал(а) жалобу на %{target}"
|
||||||
subject: Новая жалоба, узел %{instance} (#%{id})
|
subject: Новая жалоба, узел %{instance} (#%{id})
|
||||||
application_mailer:
|
application_mailer:
|
||||||
|
notification_preferences: Изменить настройки e-mail
|
||||||
salutation: "%{name},"
|
salutation: "%{name},"
|
||||||
settings: 'Изменить настройки e-mail: %{link}'
|
settings: 'Изменить настройки e-mail: %{link}'
|
||||||
signature: Уведомления Mastodon от %{instance}
|
signature: Уведомления Mastodon от %{instance}
|
||||||
view: 'Просмотр:'
|
view: 'Просмотр:'
|
||||||
|
view_status: Просмотреть статус
|
||||||
applications:
|
applications:
|
||||||
created: Приложение успешно создано
|
created: Приложение успешно создано
|
||||||
destroyed: Приложение успешно удалено
|
destroyed: Приложение успешно удалено
|
||||||
|
@ -349,7 +354,7 @@ ru:
|
||||||
warning: Будьте очень внимательны с этими данными. Не делитесь ими ни с кем!
|
warning: Будьте очень внимательны с этими данными. Не делитесь ими ни с кем!
|
||||||
your_token: Ваш токен доступа
|
your_token: Ваш токен доступа
|
||||||
auth:
|
auth:
|
||||||
agreement_html: Создавая аккаунт, вы соглашаетесь с <a href="%{rules_path}">нашими правилами поведения</a> и <a href="%{terms_path}">политикой конфиденциальности</a>.
|
agreement_html: Создавая аккаунт, вы соглашаетесь с <a href="%{rules_path}">правилами узла</a> и <a href="%{terms_path}">нашими условиями обслуживания</a>.
|
||||||
change_password: Изменить пароль
|
change_password: Изменить пароль
|
||||||
delete_account: Удалить аккаунт
|
delete_account: Удалить аккаунт
|
||||||
delete_account_html: Если Вы хотите удалить свой аккаунт, вы можете <a href="%{path}">перейти сюда</a>. У Вас будет запрошено подтверждение.
|
delete_account_html: Если Вы хотите удалить свой аккаунт, вы можете <a href="%{path}">перейти сюда</a>. У Вас будет запрошено подтверждение.
|
||||||
|
@ -554,6 +559,7 @@ ru:
|
||||||
blackberry: Blackberry
|
blackberry: Blackberry
|
||||||
chrome: Chrome
|
chrome: Chrome
|
||||||
edge: Microsoft Edge
|
edge: Microsoft Edge
|
||||||
|
electron: Electron
|
||||||
firefox: Firefox
|
firefox: Firefox
|
||||||
generic: Неизвестный браузер
|
generic: Неизвестный браузер
|
||||||
ie: Internet Explorer
|
ie: Internet Explorer
|
||||||
|
|
|
@ -4,7 +4,7 @@ ca:
|
||||||
hints:
|
hints:
|
||||||
defaults:
|
defaults:
|
||||||
avatar: PNG, GIF o JPG. Màxim 2MB. Serà escalat a 120x120px
|
avatar: PNG, GIF o JPG. Màxim 2MB. Serà escalat a 120x120px
|
||||||
digest: S'envia després d'un llarg període d'inactivitat amb un resum de les mencions que has rebut en la teva absència
|
digest: Només s'envia després d'un llarg període d'inactivitat amb un resum de les mencions que has rebut en la teva absència
|
||||||
display_name:
|
display_name:
|
||||||
one: <span class="name-counter">1</span> càracter
|
one: <span class="name-counter">1</span> càracter
|
||||||
other: <span class="name-counter">%{count}</span> càracters
|
other: <span class="name-counter">%{count}</span> càracters
|
||||||
|
|
|
@ -4,7 +4,7 @@ fr:
|
||||||
hints:
|
hints:
|
||||||
defaults:
|
defaults:
|
||||||
avatar: Au format PNG, GIF ou JPG. 2 Mo maximum. Sera réduit à 120x120px
|
avatar: Au format PNG, GIF ou JPG. 2 Mo maximum. Sera réduit à 120x120px
|
||||||
digest: Envoyé après une longue période d’inactivité et contient un résumé des notifications que vous avez reçues pendant votre absence
|
digest: Uniquement envoyé après une longue période d’inactivité et uniquement si vous avez reçu des messages personnels pendant votre absence
|
||||||
display_name:
|
display_name:
|
||||||
one: <span class="name-counter">1</span> caractère restant
|
one: <span class="name-counter">1</span> caractère restant
|
||||||
other: <span class="name-counter">%{count}</span> caractères restants
|
other: <span class="name-counter">%{count}</span> caractères restants
|
||||||
|
|
|
@ -4,7 +4,7 @@ ja:
|
||||||
hints:
|
hints:
|
||||||
defaults:
|
defaults:
|
||||||
avatar: 2MBまでのPNGやGIF、JPGが利用可能です。120x120pxまで縮小されます
|
avatar: 2MBまでのPNGやGIF、JPGが利用可能です。120x120pxまで縮小されます
|
||||||
digest: 長期間ログインしなかった際、その期間に受け取った返信の要約を受け取ることができます
|
digest: 長期間使用していない場合と不在時に返信を受けた場合のみ送信されます
|
||||||
display_name: あと<span class="name-counter">%{count}</span>文字入力できます。
|
display_name: あと<span class="name-counter">%{count}</span>文字入力できます。
|
||||||
header: 2MBまでのPNGやGIF、JPGが利用可能です。 700x335pxまで縮小されます
|
header: 2MBまでのPNGやGIF、JPGが利用可能です。 700x335pxまで縮小されます
|
||||||
locked: フォロワーを手動で承認する必要があります
|
locked: フォロワーを手動で承認する必要があります
|
||||||
|
|
|
@ -4,27 +4,27 @@ pl:
|
||||||
hints:
|
hints:
|
||||||
defaults:
|
defaults:
|
||||||
avatar: PNG, GIF lub JPG. Maksymalnie 2MB. Zostanie zmniejszony do 120x120px
|
avatar: PNG, GIF lub JPG. Maksymalnie 2MB. Zostanie zmniejszony do 120x120px
|
||||||
digest: Wysyłane po długiej nieaktywności, zawiera podsumowanie wspomnień o Twoich profilu
|
digest: Wysyłane tylko po długiej nieaktywności, jeżeli w tym czasie otrzymaleś jakąś wiadomość bezpośrednią
|
||||||
display_name:
|
display_name:
|
||||||
few: Pozostały <span class="name-counter">%{count}</span> znaki.
|
few: Pozostały <span class="name-counter">%{count}</span> znaki.
|
||||||
many: Pozostało <span class="name-counter">%{count}</span> znaków
|
many: Pozostało <span class="name-counter">%{count}</span> znaków
|
||||||
one: Pozostał <span class="name-counter">1</span> znak.
|
one: Pozostał <span class="name-counter">1</span> znak
|
||||||
other: Pozostało <span class="name-counter">%{count}</span> znaków
|
other: Pozostało <span class="name-counter">%{count}</span> znaków
|
||||||
header: PNG, GIF lub JPG. Maksymalnie 2MB. Zostanie zmniejszony do 700x335px
|
header: PNG, GIF lub JPG. Maksymalnie 2MB. Zostanie zmniejszony do 700x335px
|
||||||
locked: Musisz akceptować prośby o śledzenie
|
locked: Musisz akceptować prośby o śledzenie
|
||||||
note:
|
note:
|
||||||
few: Pozostały <span class="name-counter">%{count}</span> znaki.
|
few: Pozostały <span class="name-counter">%{count}</span> znaki.
|
||||||
many: Pozostało <span class="name-counter">%{count}</span> znaków
|
many: Pozostało <span class="name-counter">%{count}</span> znaków
|
||||||
one: Pozostał <span class="name-counter">1</span> znak.
|
one: Pozostał <span class="name-counter">1</span> znak
|
||||||
other: Pozostało <span class="name-counter">%{count}</span> znaków
|
other: Pozostało <span class="name-counter">%{count}</span> znaków
|
||||||
setting_noindex: Wpływa na widoczność strony profilu i Twoich wpisów
|
setting_noindex: Wpływa na widoczność strony profilu i Twoich wpisów
|
||||||
setting_skin: Zmienia wygląd używanej odmiany Mastodona
|
setting_skin: Zmienia wygląd używanej odmiany Mastodona
|
||||||
imports:
|
imports:
|
||||||
data: Plik CSV wyeksportowany z innej instancji Mastodona
|
data: Plik CSV wyeksportowany z innej instancji Mastodona
|
||||||
sessions:
|
sessions:
|
||||||
otp: Wprowadź kod weryfikacji dwuetapowej z telefonu lub wykorzystaj jeden z kodów zapasowych
|
otp: Wprowadź kod weryfikacji dwuetapowej z telefonu lub wykorzystaj jeden z kodów zapasowych.
|
||||||
user:
|
user:
|
||||||
filtered_languages: Wpisy w wybranych językach nie będą wyświetlać się na publicznych osiach czasu.
|
filtered_languages: Wpisy w wybranych językach nie będą wyświetlać się na publicznych osiach czasu
|
||||||
labels:
|
labels:
|
||||||
defaults:
|
defaults:
|
||||||
avatar: Awatar
|
avatar: Awatar
|
||||||
|
|
|
@ -30,10 +30,12 @@ sk:
|
||||||
data: Dáta
|
data: Dáta
|
||||||
display_name: Meno
|
display_name: Meno
|
||||||
email: Emailová adresa
|
email: Emailová adresa
|
||||||
|
expires_in: Expirovať po
|
||||||
filtered_languages: Filtrované jazyky
|
filtered_languages: Filtrované jazyky
|
||||||
header: Obrázok v hlavičke
|
header: Obrázok v hlavičke
|
||||||
locale: Jazyk
|
locale: Jazyk
|
||||||
locked: Zamknúť účet
|
locked: Zamknúť účet
|
||||||
|
max_uses: Maximálny počet použití
|
||||||
new_password: Nové heslo
|
new_password: Nové heslo
|
||||||
note: O vás
|
note: O vás
|
||||||
otp_attempt: Dvoj-faktorový (2FA) kód
|
otp_attempt: Dvoj-faktorový (2FA) kód
|
||||||
|
@ -44,6 +46,7 @@ sk:
|
||||||
setting_default_sensitive: Označiť každý obrázok/video/súbor ako chúlostivý
|
setting_default_sensitive: Označiť každý obrázok/video/súbor ako chúlostivý
|
||||||
setting_delete_modal: Zobrazovať potvrdzovacie okno pred zmazaním toot-u
|
setting_delete_modal: Zobrazovať potvrdzovacie okno pred zmazaním toot-u
|
||||||
setting_noindex: Nezaradzovať vaše príspevky do indexácie pre vyhľadávanie
|
setting_noindex: Nezaradzovať vaše príspevky do indexácie pre vyhľadávanie
|
||||||
|
setting_reduce_motion: Redukovať pohyb v animáciách
|
||||||
setting_system_font_ui: Použiť štandardný systémový font
|
setting_system_font_ui: Použiť štandardný systémový font
|
||||||
setting_theme: Vzhľad
|
setting_theme: Vzhľad
|
||||||
setting_unfollow_modal: Zobrazovať potvrdzovacie okno pred skončením sledovania iného používateľa
|
setting_unfollow_modal: Zobrazovať potvrdzovacie okno pred skončením sledovania iného používateľa
|
||||||
|
@ -53,6 +56,7 @@ sk:
|
||||||
interactions:
|
interactions:
|
||||||
must_be_follower: Blokovať notifikácie pod používateľov, ktorí vás nesledujú
|
must_be_follower: Blokovať notifikácie pod používateľov, ktorí vás nesledujú
|
||||||
must_be_following: Blokovať notifikácie od ľudí ktorý vás nesledujú
|
must_be_following: Blokovať notifikácie od ľudí ktorý vás nesledujú
|
||||||
|
must_be_following_dm: Blokovať priame správy od ľudí ktorých nesleduješ
|
||||||
notification_emails:
|
notification_emails:
|
||||||
digest: Posielať súhrnné emaily
|
digest: Posielať súhrnné emaily
|
||||||
favourite: Poslať email ak niekto označí váš príspevok ako obľúbený
|
favourite: Poslať email ak niekto označí váš príspevok ako obľúbený
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
---
|
---
|
||||||
sk:
|
sk:
|
||||||
about:
|
about:
|
||||||
|
about_hashtag_html: Toto sú verejné tooty otagované <strong>#%{tagom}</strong>. Ak máš účet niekde vo fediverse, môžeš ich používať.
|
||||||
about_mastodon_html: Mastodon je sociálna sieť založená na otvorených webových protokoloch. Jej zrojový kód je otvorený a je decentralizovaná podobne ako email.
|
about_mastodon_html: Mastodon je sociálna sieť založená na otvorených webových protokoloch. Jej zrojový kód je otvorený a je decentralizovaná podobne ako email.
|
||||||
about_this: Info
|
about_this: Info
|
||||||
closed_registrations: Registrácie sú momentálne uzatvorené. Avšak, existujú ďalšie Mastodon inštancie kde si môžete založiť účet a získať prístup do tejto siete od nich.
|
closed_registrations: Registrácie sú momentálne uzatvorené. Avšak, existujú ďalšie Mastodon inštancie kde si môžete založiť účet a získať prístup do tejto siete od nich.
|
||||||
|
@ -38,6 +39,7 @@ sk:
|
||||||
followers: Sledujúci
|
followers: Sledujúci
|
||||||
following: Sleduje
|
following: Sleduje
|
||||||
media: Médiá
|
media: Médiá
|
||||||
|
moved_html: "%{name} účet bol presunutý na %{new_profile_link}:"
|
||||||
nothing_here: Nič tu nie je!
|
nothing_here: Nič tu nie je!
|
||||||
people_followed_by: Ľudia, ktorých %{name} sleduje
|
people_followed_by: Ľudia, ktorých %{name} sleduje
|
||||||
people_who_follow: Ľudia sledujúci %{name}
|
people_who_follow: Ľudia sledujúci %{name}
|
||||||
|
@ -47,17 +49,31 @@ sk:
|
||||||
reserved_username: Prihlasovacie meno je rezervované
|
reserved_username: Prihlasovacie meno je rezervované
|
||||||
roles:
|
roles:
|
||||||
admin: Admin
|
admin: Admin
|
||||||
|
moderator: Mod
|
||||||
unfollow: Prestať sledovať
|
unfollow: Prestať sledovať
|
||||||
admin:
|
admin:
|
||||||
|
account_moderation_notes:
|
||||||
|
account: Moderátor
|
||||||
|
create: Vytvoriť
|
||||||
|
created_at: Dátum
|
||||||
|
created_msg: Poznámka moderátora bola úspešne vytvorená!
|
||||||
|
delete: Zmazať
|
||||||
|
destroyed_msg: Poznámka moderátora bola úspešne zmazaná!
|
||||||
accounts:
|
accounts:
|
||||||
are_you_sure: Ste si istý?
|
are_you_sure: Ste si istý?
|
||||||
|
by_domain: Doména
|
||||||
confirm: Potvrdiť
|
confirm: Potvrdiť
|
||||||
confirmed: Potvrdený
|
confirmed: Potvrdený
|
||||||
|
demote: Degradovať
|
||||||
|
disable: Zablokovať
|
||||||
disable_two_factor_authentication: Zakázať 2FA
|
disable_two_factor_authentication: Zakázať 2FA
|
||||||
|
disabled: Blokovaný
|
||||||
display_name: Zobraziť meno
|
display_name: Zobraziť meno
|
||||||
domain: Doména
|
domain: Doména
|
||||||
edit: Upraviť
|
edit: Upraviť
|
||||||
email: Email
|
email: Email
|
||||||
|
enable: Povoliť
|
||||||
|
enabled: Povolený
|
||||||
feed_url: URL časovej osi
|
feed_url: URL časovej osi
|
||||||
followers: Sledujúci
|
followers: Sledujúci
|
||||||
followers_url: URL sledujúcich
|
followers_url: URL sledujúcich
|
||||||
|
@ -69,12 +85,15 @@ sk:
|
||||||
local: Lokálne
|
local: Lokálne
|
||||||
remote: Federované
|
remote: Federované
|
||||||
title: Lokácia
|
title: Lokácia
|
||||||
|
login_status: Status prihlásenia
|
||||||
media_attachments: Prílohy
|
media_attachments: Prílohy
|
||||||
|
memorialize: Zmeniť na "Navždy budeme spomínať"
|
||||||
moderation:
|
moderation:
|
||||||
all: Všetko
|
all: Všetko
|
||||||
silenced: Umlčané
|
silenced: Umlčané
|
||||||
suspended: Suspendované
|
suspended: Suspendované
|
||||||
title: Moderácia
|
title: Moderácia
|
||||||
|
moderation_notes: Moderátorské poznámky
|
||||||
most_recent_activity: Posledná aktivita
|
most_recent_activity: Posledná aktivita
|
||||||
most_recent_ip: Posledná IP
|
most_recent_ip: Posledná IP
|
||||||
not_subscribed: Nezaregistrované
|
not_subscribed: Nezaregistrované
|
||||||
|
@ -85,6 +104,7 @@ sk:
|
||||||
outbox_url: URL poslaných
|
outbox_url: URL poslaných
|
||||||
perform_full_suspension: Suspendovať
|
perform_full_suspension: Suspendovať
|
||||||
profile_url: URL profilu
|
profile_url: URL profilu
|
||||||
|
promote: Povýšiť
|
||||||
protocol: Protokol
|
protocol: Protokol
|
||||||
public: Verejná os
|
public: Verejná os
|
||||||
push_subscription_expires: PuSH odoberanie expiruje
|
push_subscription_expires: PuSH odoberanie expiruje
|
||||||
|
@ -92,6 +112,12 @@ sk:
|
||||||
reset: Reset
|
reset: Reset
|
||||||
reset_password: Obnoviť heslo
|
reset_password: Obnoviť heslo
|
||||||
resubscribe: Znovu odoberať
|
resubscribe: Znovu odoberať
|
||||||
|
role: Oprávnenia
|
||||||
|
roles:
|
||||||
|
admin: Administrátor
|
||||||
|
moderator: Moderátor
|
||||||
|
staff: Člen
|
||||||
|
user: Používateľ
|
||||||
salmon_url: Salmon URL
|
salmon_url: Salmon URL
|
||||||
search: Hľadať
|
search: Hľadať
|
||||||
shared_inbox_url: URL zdieľanej schránky
|
shared_inbox_url: URL zdieľanej schránky
|
||||||
|
@ -108,17 +134,56 @@ sk:
|
||||||
unsubscribe: Prestať odoberať
|
unsubscribe: Prestať odoberať
|
||||||
username: Používateľske meno
|
username: Používateľske meno
|
||||||
web: Web
|
web: Web
|
||||||
|
action_logs:
|
||||||
|
actions:
|
||||||
|
confirm_user: "%{name} potvrdil e-mailovú adresu používateľa %{target}"
|
||||||
|
create_custom_emoji: "%{name} nahral nový emoji %{target}"
|
||||||
|
create_domain_block: "%{name} zablokoval doménu %{target}"
|
||||||
|
create_email_domain_block: "%{name} pridal e-mailovú doménu %{target} na zoznam zakázaných"
|
||||||
|
demote_user: "%{name} degradoval používateľa %{target}"
|
||||||
|
destroy_domain_block: "%{name} povolil doménu %{target}"
|
||||||
|
destroy_email_domain_block: "%{name} pridal e-mailovú doménu %{target} na zoznam povolených"
|
||||||
|
destroy_status: "%{name} zmazal status %{target}"
|
||||||
|
disable_2fa_user: "%{name} zakázal 2FA pre používateľa %{target}"
|
||||||
|
disable_custom_emoji: "%{name} zakázal emoji %{target}"
|
||||||
|
disable_user: "%{name} zakázal prihlásenie pre používateľa %{target}"
|
||||||
|
enable_custom_emoji: "%{name} povolil emoji %{target}"
|
||||||
|
enable_user: "%{name} povolil prihlásenie pre používateľa %{target}"
|
||||||
|
memorialize_account: '%{name} zmenil účet %{target} na stránku "Navždy budeme spomínať"'
|
||||||
|
promote_user: "%{name} povýšil používateľa %{target}"
|
||||||
|
reset_password_user: "%{name} resetoval heslo pre používateľa %{target}"
|
||||||
|
resolve_report: "%{name} zamietol nahlásenie %{target}"
|
||||||
|
silence_account: "%{name} stíšil účet %{target}"
|
||||||
|
suspend_account: "%{name} suspendoval účet používateľa %{target}"
|
||||||
|
unsilence_account: "%{name} zrušil stíšenie účtu používateľa %{target}"
|
||||||
|
unsuspend_account: "%{name} zrušil suspendáciu účtu používateľa %{target}"
|
||||||
|
update_custom_emoji: "%{name} aktualizoval emoji %{target}"
|
||||||
|
update_status: "%{name} aktualizoval status %{target}"
|
||||||
|
title: Audit log
|
||||||
custom_emojis:
|
custom_emojis:
|
||||||
|
by_domain: Doména
|
||||||
|
copied_msg: Lokálna kópia emoji úspešne vytvorená
|
||||||
|
copy: Kopírovať
|
||||||
|
copy_failed_msg: Nebolo možné vytvoriť lokálnu kópiu tohto emoji
|
||||||
created_msg: Emoji úspešne vytvorené!
|
created_msg: Emoji úspešne vytvorené!
|
||||||
delete: Zmazať
|
delete: Zmazať
|
||||||
destroyed_msg: Emojo úspešne zničený!
|
destroyed_msg: Emojo úspešne zničený!
|
||||||
|
disable: Zakázať
|
||||||
|
disabled_msg: Emoji bolo úspešne zakázané
|
||||||
emoji: Emoji
|
emoji: Emoji
|
||||||
|
enable: Povoliť
|
||||||
|
enabled_msg: Emoji bolo úspešne povolené
|
||||||
image_hint: PNG do 50KB
|
image_hint: PNG do 50KB
|
||||||
|
listed: V zozname
|
||||||
new:
|
new:
|
||||||
title: Pridať vlastný emoji
|
title: Pridať nový vlastný emoji
|
||||||
|
overwrite: Prepísať
|
||||||
shortcode: Skratka
|
shortcode: Skratka
|
||||||
shortcode_hint: Aspoň 2 znaky, povolené sú alfanumerické alebo podčiarkovník
|
shortcode_hint: Aspoň 2 znaky, povolené sú alfanumerické alebo podčiarkovník
|
||||||
title: Vlastné emoji
|
title: Vlastné emoji
|
||||||
|
unlisted: Nie je na zozname
|
||||||
|
update_failed_msg: Nebolo možné aktualizovať toto emoji
|
||||||
|
updated_msg: Emoji bolo úspešne aktualizované!
|
||||||
upload: Nahrať
|
upload: Nahrať
|
||||||
domain_blocks:
|
domain_blocks:
|
||||||
add_new: Pridať nový
|
add_new: Pridať nový
|
||||||
|
@ -129,16 +194,43 @@ sk:
|
||||||
create: Blokovať doménu
|
create: Blokovať doménu
|
||||||
hint: Blokovanie domény stále dovolí vytvárať nové účty v databáze, ale tieto budú automaticky moderované.
|
hint: Blokovanie domény stále dovolí vytvárať nové účty v databáze, ale tieto budú automaticky moderované.
|
||||||
severity:
|
severity:
|
||||||
|
desc_html: "<strong>Stíšenie</strong> urobí všetky príspevky účtu neviditeľné pre všetkých ktorý nesledujú tento účet. <strong>Suspendácia</strong> zmaže všetky príspevky, médiá a profilové informácie. Použi <strong>Nič</strong> ak chceš iba neprijímať súbory médií."
|
||||||
noop: Nič
|
noop: Nič
|
||||||
silence: Stíšiť
|
silence: Stíšiť
|
||||||
suspend: Suspendovať
|
suspend: Suspendovať
|
||||||
title: Nové blokovanie domény
|
title: Nové blokovanie domény
|
||||||
reject_media: Odmietať súbory s obrázkami alebo videami
|
reject_media: Odmietať súbory s obrázkami alebo videami
|
||||||
|
reject_media_hint: Zmaže lokálne uložené súbory médií a odmietne ich sťahovanie v budúcnosti. Irelevantné pre suspendáciu
|
||||||
severities:
|
severities:
|
||||||
noop: Nič
|
noop: Nič
|
||||||
silence: Stíšiť
|
silence: Stíšiť
|
||||||
suspend: Suspendovať
|
suspend: Suspendovať
|
||||||
severity: Závažnosť
|
severity: Závažnosť
|
||||||
|
show:
|
||||||
|
affected_accounts:
|
||||||
|
one: Jeden účet v databáze ovplyvnený
|
||||||
|
other: "%{count} účtov v databáze ovplyvnených"
|
||||||
|
retroactive:
|
||||||
|
silence: Zrušiť stíšenie všetkých existujúcich účtov z tejto domény
|
||||||
|
suspend: Zrušiť suspendáciu všetkých existujúcich účtov z tejto domény
|
||||||
|
title: Zrušiť blokovanie domény pre %{domain}
|
||||||
|
undo: Vrátiť späť
|
||||||
|
title: Blokovanie domén
|
||||||
|
undo: Späť
|
||||||
|
email_domain_blocks:
|
||||||
|
add_new: Pridať nový
|
||||||
|
created_msg: Emailová doména bola úspešne pridaná do zoznamu zakázaných
|
||||||
|
delete: Zmazať
|
||||||
|
destroyed_msg: Emailová doména bola úspešne vymazaná zo zoznamu zakázaných
|
||||||
|
domain: Doména
|
||||||
|
new:
|
||||||
|
create: Pridať doménu
|
||||||
|
auth:
|
||||||
|
login: Prihlásenie
|
||||||
settings:
|
settings:
|
||||||
authorized_apps: Autorizované aplikácie
|
authorized_apps: Autorizované aplikácie
|
||||||
back: Naspäť na stránku
|
back: Naspäť na stránku
|
||||||
|
users:
|
||||||
|
invalid_email: Emailová adresa je neplatná
|
||||||
|
invalid_otp_token: Neplatný 2FA kód
|
||||||
|
signed_in_as: 'Prihlásený ako:'
|
||||||
|
|
|
@ -43,15 +43,39 @@ describe ApplicationController, type: :controller do
|
||||||
expect_updated_sign_in_at(user)
|
expect_updated_sign_in_at(user)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'regenerates feed when sign in is older than two weeks' do
|
describe 'feed regeneration' do
|
||||||
allow(RegenerationWorker).to receive(:perform_async)
|
before do
|
||||||
user.update(current_sign_in_at: 3.weeks.ago)
|
alice = Fabricate(:account)
|
||||||
sign_in user, scope: :user
|
bob = Fabricate(:account)
|
||||||
get :show
|
|
||||||
|
|
||||||
expect_updated_sign_in_at(user)
|
user.account.follow!(alice)
|
||||||
expect(Redis.current.get("account:#{user.account_id}:regeneration")).to eq 'true'
|
user.account.follow!(bob)
|
||||||
expect(RegenerationWorker).to have_received(:perform_async)
|
|
||||||
|
Fabricate(:status, account: alice, text: 'hello world')
|
||||||
|
Fabricate(:status, account: bob, text: 'yes hello')
|
||||||
|
Fabricate(:status, account: user.account, text: 'test')
|
||||||
|
|
||||||
|
user.update(last_sign_in_at: 'Tue, 04 Jul 2017 14:45:56 UTC +00:00', current_sign_in_at: 'Wed, 05 Jul 2017 22:10:52 UTC +00:00')
|
||||||
|
|
||||||
|
sign_in user, scope: :user
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sets a regeneration marker while regenerating' do
|
||||||
|
allow(RegenerationWorker).to receive(:perform_async)
|
||||||
|
get :show
|
||||||
|
|
||||||
|
expect_updated_sign_in_at(user)
|
||||||
|
expect(Redis.current.get("account:#{user.account_id}:regeneration")).to eq 'true'
|
||||||
|
expect(RegenerationWorker).to have_received(:perform_async)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'regenerates feed when sign in is older than two weeks' do
|
||||||
|
get :show
|
||||||
|
|
||||||
|
expect_updated_sign_in_at(user)
|
||||||
|
expect(Redis.current.zcard(FeedManager.instance.key(:home, user.account_id))).to eq 3
|
||||||
|
expect(Redis.current.get("account:#{user.account_id}:regeneration")).to be_nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def expect_updated_sign_in_at(user)
|
def expect_updated_sign_in_at(user)
|
||||||
|
|
|
@ -82,10 +82,19 @@ RSpec.describe NotifyService do
|
||||||
is_expected.to_not change(Notification, :count)
|
is_expected.to_not change(Notification, :count)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'if the message chain initiated by recipient' do
|
context 'if the message chain initiated by recipient, but is not direct message' do
|
||||||
let(:reply_to) { Fabricate(:status, account: recipient) }
|
let(:reply_to) { Fabricate(:status, account: recipient) }
|
||||||
let(:activity) { Fabricate(:mention, account: recipient, status: Fabricate(:status, account: sender, visibility: :direct, thread: reply_to)) }
|
let(:activity) { Fabricate(:mention, account: recipient, status: Fabricate(:status, account: sender, visibility: :direct, thread: reply_to)) }
|
||||||
|
|
||||||
|
it 'does not notify' do
|
||||||
|
is_expected.to_not change(Notification, :count)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'if the message chain initiated by recipient and is direct message' do
|
||||||
|
let(:reply_to) { Fabricate(:status, account: recipient, visibility: :direct) }
|
||||||
|
let(:activity) { Fabricate(:mention, account: recipient, status: Fabricate(:status, account: sender, visibility: :direct, thread: reply_to)) }
|
||||||
|
|
||||||
it 'does notify' do
|
it 'does notify' do
|
||||||
is_expected.to change(Notification, :count)
|
is_expected.to change(Notification, :count)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue