);
diff --git a/app/javascript/flavours/glitch/components/status_list.js b/app/javascript/flavours/glitch/components/status_list.js
index f190ba6ab61..f253f0fdc12 100644
--- a/app/javascript/flavours/glitch/components/status_list.js
+++ b/app/javascript/flavours/glitch/components/status_list.js
@@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
import StatusContainer from 'flavours/glitch/containers/status_container';
import ImmutablePureComponent from 'react-immutable-pure-component';
import ScrollableList from './scrollable_list';
+import { FormattedMessage } from 'react-intl';
export default class StatusList extends ImmutablePureComponent {
@@ -16,6 +17,7 @@ export default class StatusList extends ImmutablePureComponent {
trackScroll: PropTypes.bool,
shouldUpdateScroll: PropTypes.func,
isLoading: PropTypes.bool,
+ isPartial: PropTypes.bool,
hasMore: PropTypes.bool,
prepend: PropTypes.node,
emptyMessage: PropTypes.node,
@@ -48,8 +50,23 @@ export default class StatusList extends ImmutablePureComponent {
}
render () {
- const { statusIds, ...other } = this.props;
- const { isLoading } = other;
+ const { statusIds, ...other } = this.props;
+ const { isLoading, isPartial } = other;
+
+ if (isPartial) {
+ return (
+
+ );
+ }
const scrollableContent = (isLoading || statusIds.size > 0) ? (
statusIds.map((statusId) => (
diff --git a/app/javascript/flavours/glitch/features/home_timeline/index.js b/app/javascript/flavours/glitch/features/home_timeline/index.js
index 2dfec6bbed3..c20c0244a68 100644
--- a/app/javascript/flavours/glitch/features/home_timeline/index.js
+++ b/app/javascript/flavours/glitch/features/home_timeline/index.js
@@ -1,6 +1,6 @@
import React from 'react';
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 StatusListContainer from 'flavours/glitch/features/ui/containers/status_list_container';
import Column from 'flavours/glitch/components/column';
@@ -16,6 +16,7 @@ const messages = defineMessages({
const mapStateToProps = state => ({
hasUnread: state.getIn(['timelines', 'home', 'unread']) > 0,
+ isPartial: state.getIn(['timelines', 'home', 'isPartial'], false),
});
@connect(mapStateToProps)
@@ -26,6 +27,7 @@ export default class HomeTimeline extends React.PureComponent {
dispatch: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
hasUnread: PropTypes.bool,
+ isPartial: PropTypes.bool,
columnId: PropTypes.string,
multiColumn: PropTypes.bool,
};
@@ -57,6 +59,39 @@ export default class HomeTimeline extends React.PureComponent {
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 () {
const { intl, hasUnread, columnId, multiColumn } = this.props;
const pinned = !!columnId;
diff --git a/app/javascript/flavours/glitch/features/list_timeline/index.js b/app/javascript/flavours/glitch/features/list_timeline/index.js
index c6a89a92022..f9476d92d54 100644
--- a/app/javascript/flavours/glitch/features/list_timeline/index.js
+++ b/app/javascript/flavours/glitch/features/list_timeline/index.js
@@ -120,13 +120,17 @@ export default class ListTimeline extends React.PureComponent {
if (typeof list === 'undefined') {
return (
);
}
diff --git a/app/javascript/flavours/glitch/features/ui/containers/status_list_container.js b/app/javascript/flavours/glitch/features/ui/containers/status_list_container.js
index eca85b8e636..f85a2eeb8aa 100644
--- a/app/javascript/flavours/glitch/features/ui/containers/status_list_container.js
+++ b/app/javascript/flavours/glitch/features/ui/containers/status_list_container.js
@@ -51,6 +51,7 @@ const makeMapStateToProps = () => {
const mapStateToProps = (state, { timelineId }) => ({
statusIds: getStatusIds(state, { type: timelineId }),
isLoading: state.getIn(['timelines', timelineId, 'isLoading'], true),
+ isPartial: state.getIn(['timelines', timelineId, 'isPartial'], false),
hasMore: !!state.getIn(['timelines', timelineId, 'next']),
});
diff --git a/app/javascript/flavours/glitch/images/elephant_ui_disappointed.svg b/app/javascript/flavours/glitch/images/elephant_ui_disappointed.svg
new file mode 100644
index 00000000000..580c15a1388
--- /dev/null
+++ b/app/javascript/flavours/glitch/images/elephant_ui_disappointed.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/javascript/flavours/glitch/images/elephant_ui_working.svg b/app/javascript/flavours/glitch/images/elephant_ui_working.svg
new file mode 100644
index 00000000000..8ba475db0a0
--- /dev/null
+++ b/app/javascript/flavours/glitch/images/elephant_ui_working.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/javascript/flavours/glitch/reducers/timelines.js b/app/javascript/flavours/glitch/reducers/timelines.js
index 679e1601eb2..4c62d8df39b 100644
--- a/app/javascript/flavours/glitch/reducers/timelines.js
+++ b/app/javascript/flavours/glitch/reducers/timelines.js
@@ -30,7 +30,7 @@ const initialTimeline = ImmutableMap({
items: ImmutableList(),
});
-const normalizeTimeline = (state, timeline, statuses, next) => {
+const normalizeTimeline = (state, timeline, statuses, next, isPartial) => {
const oldIds = state.getIn([timeline, 'items'], ImmutableList());
const ids = ImmutableList(statuses.map(status => status.get('id'))).filter(newId => !oldIds.includes(newId));
const wasLoaded = state.getIn([timeline, 'loaded']);
@@ -41,6 +41,7 @@ const normalizeTimeline = (state, timeline, statuses, next) => {
mMap.set('isLoading', false);
if (!hadNext) mMap.set('next', next);
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:
return state.update(action.timeline, initialTimeline, map => map.set('isLoading', false));
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:
return appendNormalizedTimeline(state, action.timeline, fromJS(action.statuses), action.next);
case TIMELINE_UPDATE:
diff --git a/app/javascript/flavours/glitch/styles/components/index.scss b/app/javascript/flavours/glitch/styles/components/index.scss
index 8f051f7a054..8f06209c618 100644
--- a/app/javascript/flavours/glitch/styles/components/index.scss
+++ b/app/javascript/flavours/glitch/styles/components/index.scss
@@ -838,21 +838,10 @@
}
.missing-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-top: 20px + 48px;
- & > div {
- background: url('~images/mastodon-not-found.png') no-repeat center -50px;
- padding-top: 210px;
- width: 100%;
+ .regeneration-indicator__figure {
+ background-image: url('~flavours/glitch/images/elephant_ui_disappointed.svg');
}
}
@@ -1162,6 +1151,7 @@ noscript {
@import 'metadata';
@import 'composer';
@import 'columns';
+@import 'regeneration_indicator';
@import 'search';
@import 'emoji';
@import 'doodle';
diff --git a/app/javascript/flavours/glitch/styles/components/regeneration_indicator.scss b/app/javascript/flavours/glitch/styles/components/regeneration_indicator.scss
new file mode 100644
index 00000000000..9c1873cdffc
--- /dev/null
+++ b/app/javascript/flavours/glitch/styles/components/regeneration_indicator.scss
@@ -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;
+ }
+ }
+}
diff --git a/app/javascript/images/elephant-friend.png b/app/javascript/images/elephant-friend.png
deleted file mode 100644
index 3c5145ba987..00000000000
Binary files a/app/javascript/images/elephant-friend.png and /dev/null differ
diff --git a/app/javascript/images/elephant_ui_disappointed.svg b/app/javascript/images/elephant_ui_disappointed.svg
new file mode 100644
index 00000000000..580c15a1388
--- /dev/null
+++ b/app/javascript/images/elephant_ui_disappointed.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/javascript/images/elephant_ui_working.svg b/app/javascript/images/elephant_ui_working.svg
new file mode 100644
index 00000000000..8ba475db0a0
--- /dev/null
+++ b/app/javascript/images/elephant_ui_working.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/javascript/images/mastodon-not-found.png b/app/javascript/images/mastodon-not-found.png
deleted file mode 100644
index 76108d41f69..00000000000
Binary files a/app/javascript/images/mastodon-not-found.png and /dev/null differ
diff --git a/app/javascript/mastodon/actions/timelines.js b/app/javascript/mastodon/actions/timelines.js
index f8843d1d902..df6a3637955 100644
--- a/app/javascript/mastodon/actions/timelines.js
+++ b/app/javascript/mastodon/actions/timelines.js
@@ -19,13 +19,14 @@ export const TIMELINE_DISCONNECT = 'TIMELINE_DISCONNECT';
export const TIMELINE_CONTEXT_UPDATE = 'CONTEXT_UPDATE';
-export function refreshTimelineSuccess(timeline, statuses, skipLoading, next) {
+export function refreshTimelineSuccess(timeline, statuses, skipLoading, next, partial) {
return {
type: TIMELINE_REFRESH_SUCCESS,
timeline,
statuses,
skipLoading,
next,
+ partial,
};
};
@@ -88,7 +89,7 @@ export function refreshTimeline(timelineId, path, params = {}) {
return function (dispatch, getState) {
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;
}
@@ -104,8 +105,12 @@ export function refreshTimeline(timelineId, path, params = {}) {
dispatch(refreshTimelineRequest(timelineId, skipLoading));
api(getState).get(path, { params }).then(response => {
- const next = getLinks(response).refs.find(link => link.rel === 'next');
- dispatch(refreshTimelineSuccess(timelineId, response.data, skipLoading, next ? next.uri : null));
+ if (response.status === 206) {
+ 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 => {
dispatch(refreshTimelineFail(timelineId, error, skipLoading));
});
diff --git a/app/javascript/mastodon/components/missing_indicator.js b/app/javascript/mastodon/components/missing_indicator.js
index 87df7f61ce3..70d8c3b9841 100644
--- a/app/javascript/mastodon/components/missing_indicator.js
+++ b/app/javascript/mastodon/components/missing_indicator.js
@@ -2,9 +2,14 @@ import React from 'react';
import { FormattedMessage } from 'react-intl';
const MissingIndicator = () => (
-
+
);
diff --git a/app/javascript/mastodon/components/status_list.js b/app/javascript/mastodon/components/status_list.js
index 58a7b228a94..5acaf714ec6 100644
--- a/app/javascript/mastodon/components/status_list.js
+++ b/app/javascript/mastodon/components/status_list.js
@@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
import StatusContainer from '../containers/status_container';
import ImmutablePureComponent from 'react-immutable-pure-component';
import ScrollableList from './scrollable_list';
+import { FormattedMessage } from 'react-intl';
export default class StatusList extends ImmutablePureComponent {
@@ -16,6 +17,7 @@ export default class StatusList extends ImmutablePureComponent {
trackScroll: PropTypes.bool,
shouldUpdateScroll: PropTypes.func,
isLoading: PropTypes.bool,
+ isPartial: PropTypes.bool,
hasMore: PropTypes.bool,
prepend: PropTypes.node,
emptyMessage: PropTypes.node,
@@ -48,8 +50,23 @@ export default class StatusList extends ImmutablePureComponent {
}
render () {
- const { statusIds, ...other } = this.props;
- const { isLoading } = other;
+ const { statusIds, ...other } = this.props;
+ const { isLoading, isPartial } = other;
+
+ if (isPartial) {
+ return (
+
+ );
+ }
const scrollableContent = (isLoading || statusIds.size > 0) ? (
statusIds.map((statusId) => (
diff --git a/app/javascript/mastodon/features/home_timeline/index.js b/app/javascript/mastodon/features/home_timeline/index.js
index a4bc60facee..31f5a3c8b2b 100644
--- a/app/javascript/mastodon/features/home_timeline/index.js
+++ b/app/javascript/mastodon/features/home_timeline/index.js
@@ -1,6 +1,6 @@
import React from 'react';
import { connect } from 'react-redux';
-import { expandHomeTimeline } from '../../actions/timelines';
+import { expandHomeTimeline, refreshHomeTimeline } from '../../actions/timelines';
import PropTypes from 'prop-types';
import StatusListContainer from '../ui/containers/status_list_container';
import Column from '../../components/column';
@@ -16,6 +16,7 @@ const messages = defineMessages({
const mapStateToProps = state => ({
hasUnread: state.getIn(['timelines', 'home', 'unread']) > 0,
+ isPartial: state.getIn(['timelines', 'home', 'isPartial'], false),
});
@connect(mapStateToProps)
@@ -26,6 +27,7 @@ export default class HomeTimeline extends React.PureComponent {
dispatch: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
hasUnread: PropTypes.bool,
+ isPartial: PropTypes.bool,
columnId: PropTypes.string,
multiColumn: PropTypes.bool,
};
@@ -57,6 +59,39 @@ export default class HomeTimeline extends React.PureComponent {
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 () {
const { intl, hasUnread, columnId, multiColumn } = this.props;
const pinned = !!columnId;
diff --git a/app/javascript/mastodon/features/list_timeline/index.js b/app/javascript/mastodon/features/list_timeline/index.js
index ae136e48f9b..3b97ac62a2f 100644
--- a/app/javascript/mastodon/features/list_timeline/index.js
+++ b/app/javascript/mastodon/features/list_timeline/index.js
@@ -120,13 +120,17 @@ export default class ListTimeline extends React.PureComponent {
if (typeof list === 'undefined') {
return (
-
+
+
+
);
} else if (list === false) {
return (
-
+
+
+
);
}
diff --git a/app/javascript/mastodon/features/ui/containers/status_list_container.js b/app/javascript/mastodon/features/ui/containers/status_list_container.js
index a0aec440326..59b53d8235d 100644
--- a/app/javascript/mastodon/features/ui/containers/status_list_container.js
+++ b/app/javascript/mastodon/features/ui/containers/status_list_container.js
@@ -47,6 +47,7 @@ const makeMapStateToProps = () => {
const mapStateToProps = (state, { timelineId }) => ({
statusIds: getStatusIds(state, { type: timelineId }),
isLoading: state.getIn(['timelines', timelineId, 'isLoading'], true),
+ isPartial: state.getIn(['timelines', timelineId, 'isPartial'], false),
hasMore: !!state.getIn(['timelines', timelineId, 'next']),
});
diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json
index 947c6fb2b91..381b80639b5 100644
--- a/app/javascript/mastodon/locales/pt-BR.json
+++ b/app/javascript/mastodon/locales/pt-BR.json
@@ -50,7 +50,7 @@
"column_header.unpin": "Desafixar",
"column_subheading.navigation": "Navegação",
"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.lock": "trancada",
"compose_form.placeholder": "No que você está pensando?",
@@ -223,7 +223,7 @@
"status.media_hidden": "Mídia escondida",
"status.mention": "Mencionar @{name}",
"status.more": "Mais",
- "status.mute": "Mute @{name}",
+ "status.mute": "Silenciar @{name}",
"status.mute_conversation": "Silenciar conversa",
"status.open": "Expandir",
"status.pin": "Fixar no perfil",
diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json
index 41ebfbd0e04..c38bfd3c6fc 100644
--- a/app/javascript/mastodon/locales/sk.json
+++ b/app/javascript/mastodon/locales/sk.json
@@ -195,8 +195,8 @@
"privacy.private.short": "Iba sledujúci",
"privacy.public.long": "Pošli všetkým",
"privacy.public.short": "Verejne",
- "privacy.unlisted.long": "Neposielať verejne",
- "privacy.unlisted.short": "Nie je v zozname",
+ "privacy.unlisted.long": "Neposielať do verejných časových osí",
+ "privacy.unlisted.short": "Verejne mimo osí",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
diff --git a/app/javascript/mastodon/reducers/timelines.js b/app/javascript/mastodon/reducers/timelines.js
index 9984c3b5d6a..7b7b5470fc0 100644
--- a/app/javascript/mastodon/reducers/timelines.js
+++ b/app/javascript/mastodon/reducers/timelines.js
@@ -30,7 +30,7 @@ const initialTimeline = ImmutableMap({
items: ImmutableList(),
});
-const normalizeTimeline = (state, timeline, statuses, next) => {
+const normalizeTimeline = (state, timeline, statuses, next, isPartial) => {
const oldIds = state.getIn([timeline, 'items'], ImmutableList());
const ids = ImmutableList(statuses.map(status => status.get('id'))).filter(newId => !oldIds.includes(newId));
const wasLoaded = state.getIn([timeline, 'loaded']);
@@ -41,6 +41,7 @@ const normalizeTimeline = (state, timeline, statuses, next) => {
mMap.set('isLoading', false);
if (!hadNext) mMap.set('next', next);
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:
return state.update(action.timeline, initialTimeline, map => map.set('isLoading', false));
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:
return appendNormalizedTimeline(state, action.timeline, fromJS(action.statuses), action.next);
case TIMELINE_UPDATE:
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index 71bffdaa682..d13a18ad7e9 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -2303,7 +2303,7 @@
}
}
-.missing-indicator {
+.regeneration-indicator {
text-align: center;
font-size: 16px;
font-weight: 500;
@@ -2314,11 +2314,46 @@
flex: 1 1 auto;
align-items: center;
justify-content: center;
+ padding: 20px;
& > div {
- background: url('~images/mastodon-not-found.png') no-repeat center -50px;
- padding-top: 210px;
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 {
from {
transform: scale(1);
- transform-origin: center center;
animation-timing-function: ease-out;
}
@@ -2775,6 +2809,7 @@
}
.pulse-loading {
+ transform-origin: center center;
animation: heartbeat 1.5s ease-in-out infinite both;
}
diff --git a/app/services/notify_service.rb b/app/services/notify_service.rb
index d5960c3adc6..ba086449cc1 100644
--- a/app/services/notify_service.rb
+++ b/app/services/notify_service.rb
@@ -54,7 +54,7 @@ class NotifyService < BaseService
end
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
def optional_non_following_and_direct?
diff --git a/app/services/precompute_feed_service.rb b/app/services/precompute_feed_service.rb
index 36aabaa001b..4f771ff7233 100644
--- a/app/services/precompute_feed_service.rb
+++ b/app/services/precompute_feed_service.rb
@@ -3,5 +3,6 @@
class PrecomputeFeedService < BaseService
def call(account)
FeedManager.instance.populate_feed(account)
+ Redis.current.del("account:#{account.id}:regeneration")
end
end
diff --git a/app/workers/regeneration_worker.rb b/app/workers/regeneration_worker.rb
index 8cee21ae1fb..5c6a040bd58 100644
--- a/app/workers/regeneration_worker.rb
+++ b/app/workers/regeneration_worker.rb
@@ -3,7 +3,7 @@
class RegenerationWorker
include Sidekiq::Worker
- sidekiq_options queue: 'pull', backtrace: true, unique: :until_executed
+ sidekiq_options unique: :until_executed
def perform(account_id, _ = :home)
account = Account.find(account_id)
diff --git a/config/locales/ca.yml b/config/locales/ca.yml
index 5fd5b3f6dcc..5e30abaf578 100644
--- a/config/locales/ca.yml
+++ b/config/locales/ca.yml
@@ -265,12 +265,18 @@ ca:
unresolved: No resolt
view: Visualització
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:
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
contact_information:
email: Introdueix una adreça de correu electrònic pùblica
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:
closed_message:
desc_html: Apareix en la primera pàgina quan es tanquen els registres
Pots utilitzar etiquetes HTML
@@ -345,7 +351,7 @@ ca:
warning: Aneu amb compte amb aquestes dades. No ho compartiu mai amb ningú!
your_token: El token d'accés
auth:
- agreement_html: En inscriure't, acceptes
els nostres termes del servei i
la nostra política de privadesa.
+ agreement_html: En inscriure't, acceptes seguir
els nostres termes del servei i
la nostra política de privadesa.
change_password: Canvia la contrasenya
delete_account: Esborra el compte
delete_account_html: Si vols esborrar el teu compte pots
fer-ho aquí. Se't demanarà confirmació.
@@ -546,12 +552,14 @@ ca:
blackberry: Blackberry
chrome: Chrome
edge: Microsoft Edge
+ electron: Electron
firefox: Firefox
generic: Navegador desconegut
ie: Internet Explorer
micro_messenger: MicroMessenger
nokia: Nokia S40 Ovi Browser
opera: Opera
+ otter: Altre
phantom_js: PhantomJS
qq: QQ Browser
safari: Safari
@@ -596,7 +604,7 @@ ca:
open_in_web: Obre en la web
over_character_limit: Límit de caràcters de %{max} superat
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
private: No es pot fixar el toot no públic
reblog: No es pot fixar un impuls
diff --git a/config/locales/devise.ca.yml b/config/locales/devise.ca.yml
index fe95c402d61..d88db17cac1 100644
--- a/config/locales/devise.ca.yml
+++ b/config/locales/devise.ca.yml
@@ -17,11 +17,32 @@ ca:
unconfirmed: Has de confirmar l'adreça de correu electrònic abans de continuar.
mailer:
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é
les regles de la instància i
les nostres condicions de servei.
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:
+ 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'
+ 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:
+ 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'
+ title: Contrasenya restablerta
unlock_instructions:
subject: 'Mastodon: Instruccions per a desblocar'
omniauth_callbacks:
diff --git a/config/locales/devise.gl.yml b/config/locales/devise.gl.yml
index 8a2b5d5638c..c0fc53834a7 100644
--- a/config/locales/devise.gl.yml
+++ b/config/locales/devise.gl.yml
@@ -18,8 +18,12 @@ gl:
mailer:
confirmation_instructions:
subject: 'Mastodon: Instruccións de confirmación para %{instance}'
+ email_changed:
+ subject: 'Mastodon: email cambiado'
password_change:
subject: 'Mastodon: contrasinal cambiado'
+ reconfirmation_instructions:
+ subject: 'Mastodon: Confirme email para %{instance}'
reset_password_instructions:
subject: 'Mastodon: Instruccións para restablecer o contrasinal'
unlock_instructions:
diff --git a/config/locales/devise.ja.yml b/config/locales/devise.ja.yml
index 118186877be..1f6395479ac 100644
--- a/config/locales/devise.ja.yml
+++ b/config/locales/devise.ja.yml
@@ -17,15 +17,32 @@ ja:
unconfirmed: 続行するにはメールアドレスを確認する必要があります。
mailer:
confirmation_instructions:
+ action: メールアドレスの確認
+ explanation: このメールアドレスで%{host}にアカウントを作成しました。有効にするまであと一歩です。もし心当たりがない場合、申し訳ありませんがこのメールを無視してください。
+ extra_html: また
インスタンスのルール と
利用規約 もお読みください。
subject: 'Mastodon: メールアドレスの確認'
+ title: メールアドレスの確認
email_changed:
+ explanation: 'アカウントのメールアドレスは以下のように変更されます:'
+ extra: メールアドレスの変更を行っていない場合、他の誰かがあなたのアカウントにアクセスした可能性があります。すぐにパスワードを変更するか、アカウントがロックされている場合はインスタンス管理者に連絡してください。
subject: 'Mastodon: メールアドレスの変更'
+ title: 新しいメールアドレス
password_change:
+ explanation: パスワードが変更されました。
+ extra: パスワードの変更を行っていない場合、他の誰かがあなたのアカウントにアクセスした可能性があります。すぐにパスワードを変更するか、アカウントがロックされている場合はインスタンス管理者に連絡してください。
subject: 'Mastodon: パスワードが変更されました'
+ title: パスワードの変更
reconfirmation_instructions:
+ explanation: メールアドレスを変更するため新しいアドレスを確認してください。
+ extra: この変更に心当たりがない場合、このメールを無視してください。上記リンク先にアクセスするまでアカウントのメールアドレスは変更されません。
subject: 'Mastodon: %{instance}のメールを確認する'
+ title: メールアドレスの確認
reset_password_instructions:
+ action: パスワードの変更
+ explanation: あなたのアカウントに対しパスワードの再発行が要求されました。
+ extra: この要求に心当たりがない場合、このメールを無視してください。上記リンク先にアクセスし新しいものを作成するまでパスワードは変更されません。
subject: 'Mastodon: パスワード再発行'
+ title: パスワード再発行
unlock_instructions:
subject: 'Mastodon: アカウントのロックの解除'
omniauth_callbacks:
diff --git a/config/locales/devise.nl.yml b/config/locales/devise.nl.yml
index 8c2c7b6a110..57e85a7b5d5 100644
--- a/config/locales/devise.nl.yml
+++ b/config/locales/devise.nl.yml
@@ -19,8 +19,12 @@ nl:
mailer:
confirmation_instructions:
subject: 'Mastodon: E-mail bevestigen voor %{instance}'
+ email_changed:
+ subject: 'Mastodon: E-mailadres is veranderd'
password_change:
subject: 'Mastodon: Wachtwoord veranderd'
+ reconfirmation_instructions:
+ subject: 'Mastodon: Bevestig het e-mailadres voor %{instance}'
reset_password_instructions:
subject: 'Mastodon: Wachtwoord opnieuw instellen'
unlock_instructions:
diff --git a/config/locales/devise.pl.yml b/config/locales/devise.pl.yml
index 6a296046304..53a4f4552ed 100644
--- a/config/locales/devise.pl.yml
+++ b/config/locales/devise.pl.yml
@@ -17,15 +17,32 @@ pl:
unconfirmed: Zweryfikuj adres e-mail, aby kontynuować.
mailer:
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ż
regulamin instancji i
nasze zasady użytkowania.
subject: 'Mastodon: Instrukcje weryfikacji adresu e-mail'
+ title: Zweryfikuj adres e-mail
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'
+ title: Nowy adres e-mail
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'
+ title: Zmieniono hasło
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}'
+ title: Zweryfikuj adres e-mail
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'
+ title: Przywracanie hasła
unlock_instructions:
subject: 'Mastodon: Instrukcje odblokowania konta'
omniauth_callbacks:
@@ -38,7 +55,7 @@ pl:
updated: Twoje hasło zostało zmienione. Jesteś zalogowany/a.
updated_not_active: Twoje hasło zostało zmienione.
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_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.
diff --git a/config/locales/devise.pt-BR.yml b/config/locales/devise.pt-BR.yml
index 13736b3a350..eab86c80290 100644
--- a/config/locales/devise.pt-BR.yml
+++ b/config/locales/devise.pt-BR.yml
@@ -18,8 +18,12 @@ pt-BR:
mailer:
confirmation_instructions:
subject: 'Mastodon: Instruções de confirmação'
+ email_changed:
+ subject: 'Mastodon: Email alterado'
password_change:
subject: 'Mastodon: Senha modificada'
+ reconfirmation_instructions:
+ subject: 'Mastodon: Confirmar emai para %{instance}'
reset_password_instructions:
subject: 'Mastodon: Instruções para mudança de senha'
unlock_instructions:
diff --git a/config/locales/doorkeeper.pl.yml b/config/locales/doorkeeper.pl.yml
index 33f133c06fd..6c127b73be6 100644
--- a/config/locales/doorkeeper.pl.yml
+++ b/config/locales/doorkeeper.pl.yml
@@ -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_redirect_uri: URI przekierowania jest nieprawidłowy.
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_token:
expired: Token dostępowy wygasł
diff --git a/config/locales/gl.yml b/config/locales/gl.yml
index ca72bf18346..55f71724966 100644
--- a/config/locales/gl.yml
+++ b/config/locales/gl.yml
@@ -265,12 +265,18 @@ gl:
unresolved: Non resolto
view: Vista
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:
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
contact_information:
email: e-mail de traballo
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:
closed_message:
desc_html: Mostrado na páxina de portada cando o rexistro está pechado. Pode utilizar etiquetas HTML
@@ -509,6 +515,7 @@ gl:
quadrillion: Q
thousand: K
trillion: T
+ unit: " "
pagination:
next: Seguinte
prev: Previo
diff --git a/config/locales/ja.yml b/config/locales/ja.yml
index 44b89e859cd..8b7b678c6ab 100644
--- a/config/locales/ja.yml
+++ b/config/locales/ja.yml
@@ -338,10 +338,13 @@ ja:
body: "%{reporter} が %{target} を通報しました"
subject: "%{instance} の新しい通報 (#%{id})"
application_mailer:
+ notification_preferences: メール設定の変更
salutation: "%{name} さん"
settings: 'メール設定の変更: %{link}'
signature: Mastodon %{instance} インスタンスからの通知
view: 'リンク:'
+ view_profile: プロフィールを表示
+ view_status: トゥートを表示
applications:
created: アプリが作成されました
destroyed: アプリが削除されました
@@ -491,29 +494,38 @@ ja:
title: モデレーション
notification_mailer:
digest:
+ action: 全ての通知を表示
body: "%{instance} での最後のログインからの出来事:"
mention: "%{name} さんがあなたに返信しました:"
new_followers_summary:
- one: 新たなフォロワーを獲得しました!
- other: "%{count} 人の新たなフォロワーを獲得しました!"
+ one: また、離れている間に新たなフォロワーを獲得しました!
+ other: また、離れている間に%{count} 人の新たなフォロワーを獲得しました!
subject:
one: "新しい1件の通知 \U0001F418"
other: "新しい%{count}件の通知 \U0001F418"
+ title: 不在の間に…
favourite:
body: "%{name} さんにお気に入り登録された、あなたのトゥートがあります:"
subject: "%{name} さんにお気に入りに登録されました"
+ title: 新たなお気に入り登録
follow:
body: "%{name} さんにフォローされています!"
subject: "%{name} さんにフォローされています"
+ title: 新たなフォロワー
follow_request:
+ action: フォローリクエストの管理
body: "%{name} さんがあなたにフォローをリクエストしました"
subject: "%{name} さんからのフォローリクエスト"
+ title: 新たなフォローリクエスト
mention:
+ action: 返信
body: "%{name} さんから返信がありました:"
subject: "%{name} さんに返信されました"
+ title: 新たな返信
reblog:
body: "%{name} さんにブーストされた、あなたのトゥートがあります:"
subject: "%{name} さんにブーストされました"
+ title: 新たなブースト
number:
human:
decimal_units:
diff --git a/config/locales/nl.yml b/config/locales/nl.yml
index a0add9bfac2..600d5225dac 100644
--- a/config/locales/nl.yml
+++ b/config/locales/nl.yml
@@ -265,12 +265,18 @@ nl:
unresolved: Onopgelost
view: Weergeven
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:
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
contact_information:
email: Vul een openbaar gebruikt e-mailadres 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:
closed_message:
desc_html: Wordt op de voorpagina weergegeven wanneer registratie van nieuwe accounts is uitgeschakeld
En ook hier kan je HTML gebruiken
@@ -476,11 +482,11 @@ nl:
title: Moderatie
notification_mailer:
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:"
new_followers_summary:
- one: Jij hebt een nieuwe volger! Hoera!
- other: Jij hebt %{count} nieuwe volgers! Prachtig!
+ one: Je hebt trouwens sinds je weg was er ook een nieuwe volger bijgekregen! Hoera!
+ other: Je hebt trouwens sinds je weg was er ook %{count} nieuwe volgers bijgekregen! Fantastisch!
subject:
one: "1 nieuwe melding sinds jouw laatste bezoek \U0001F418"
other: "%{count} nieuwe meldingen sinds jouw laatste bezoek \U0001F418"
diff --git a/config/locales/pl.yml b/config/locales/pl.yml
index 8aa6d27315d..efb955b37cf 100644
--- a/config/locales/pl.yml
+++ b/config/locales/pl.yml
@@ -46,7 +46,7 @@ pl:
posts: Wpisy
posts_with_replies: Wpisy z odpowiedziami
remote_follow: Śledź zdalnie
- reserved_username: Ta nazwa użytkownika jest zarezerwowana.
+ reserved_username: Ta nazwa użytkownika jest zarezerwowana
roles:
admin: Administrator
moderator: Moderator
@@ -183,7 +183,7 @@ pl:
title: Niestandardowe emoji
unlisted: Niewidoczne
update_failed_msg: Nie udało się zaktualizować emoji
- updated_msg: Pomyślnie zaktualizowano emoji
+ updated_msg: Pomyślnie zaktualizowano emoji!
upload: Dodaj
domain_blocks:
add_new: Dodaj nową
@@ -194,7 +194,7 @@ pl:
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.
severity:
- desc_html: "
Wyciszenie uczyni wpisy użytkownika widoczne tylko dla osób, które go śledzą.
Zawieszenie spowoduje usunięcie całej zawartości dodanej przez użytkownika."
+ desc_html: "
Wyciszenie uczyni wpisy użytkownika widoczne tylko dla osób, które go śledzą.
Zawieszenie spowoduje usunięcie całej zawartości dodanej przez użytkownika. Użyj
Żadne, jeżeli chcesz jedynie odrzucać zawartość multimedialną."
noop: Nic nie rób
silence: Wycisz
suspend: Zawieś
@@ -305,7 +305,7 @@ pl:
title: Niestandardowe zasady użytkowania
site_title: Nazwa instancji
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
timeline_preview:
desc_html: Wyświetlaj publiczną oś czasu na stronie widocznej dla niezalogowanych
@@ -339,10 +339,12 @@ pl:
body: Użytkownik %{reporter} zgłosił %{target}
subject: Nowe zgłoszenie na %{instance} (#%{id})
application_mailer:
+ notification_preferences: Zmień ustawienia e-maili
salutation: "%{name},"
settings: 'Zmień ustawienia powiadamiania: %{link}'
signature: Powiadomienie Mastodona z instancji %{instance}
view: 'Zobacz:'
+ view_status: Wyświetl wpis
applications:
created: Pomyślnie utworzono aplikację
destroyed: Pomyślnie usunięto aplikację
@@ -494,33 +496,42 @@ pl:
title: Moderacja
notification_mailer:
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:"
new_followers_summary:
few: "(%{count}) nowe osoby śledzą Cię!"
many: "(%{count}) nowych osób Cię śledzi! Wspaniale!"
- one: Śledzi Cię nowa osoba! Gratulacje!
- other: "(%{count}) nowych osób Cię śledzi! Wspaniale!"
+ one: Dodatkowo, w czasie nieobecności zaczęła śledzić Cię jedna osoba Gratulacje!
+ other: Dodatkowo, zaczęło Cię śledzić %{count} nowych osób! Wspaniale!
subject:
few: "%{count} nowe powiadomienia od Twojej ostatniej wizyty \U0001F418"
many: "%{count} nowych powiadomień od Twojej ostatniej wizyty \U0001F418"
one: "1 nowe powiadomienie od Twojej ostatniej wizyty \U0001F418"
other: "%{count} nowych powiadomień od Twojej ostatniej wizyty \U0001F418"
+ title: W trakcie Twojej nieobecności…
favourite:
body: 'Twój wpis został polubiony przez %{name}:'
subject: "%{name} lubi Twój wpis"
+ title: Nowe polubienie
follow:
body: "%{name} Cię śledzi!"
subject: "%{name} Cię śledzi"
+ title: Nowy śledzący
follow_request:
+ action: Zarządzaj prośbami o możliwość śledzenia
body: "%{name} poprosił o możliwość śledzenia Cię"
subject: 'Prośba o możliwość śledzenia: %{name}'
+ title: Nowa prośba o możliwość śledzenia
mention:
+ action: Odpowiedz
body: "%{name} wspomniał o Tobie w:"
subject: "%{name} wspomniał o Tobie"
+ title: Nowe wspomnienie o Tobie
reblog:
body: 'Twój wpis został podbity przez %{name}:'
subject: Twój wpis został podbity przez %{name}
+ title: Nowe podbicie
number:
human:
decimal_units:
@@ -568,12 +579,14 @@ pl:
blackberry: Blackberry
chrome: Chrome
edge: Microsoft Edge
+ electron: Electron
firefox: Firefox
generic: nieznana przeglądarka
ie: Internet Explorer
micro_messenger: MicroMessenger
nokia: Nokia S40 Ovi Browser
opera: Opera
+ otter: Przeglądarka Otter
phantom_js: PhantomJS
qq: QQ Browser
safari: Safari
diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml
index d4bf72da3ce..39683bd8850 100644
--- a/config/locales/pt-BR.yml
+++ b/config/locales/pt-BR.yml
@@ -265,12 +265,18 @@ pt-BR:
unresolved: Não resolvido
view: Visualizar
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:
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
contact_information:
email: E-mail
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:
closed_message:
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
title: Cadastro aberto
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
site_description:
desc_html: Parágrafo introdutório na página inicial e em meta tags. Você pode usar tags HTML, em especial
<a>
e
<em>
.
@@ -345,7 +351,7 @@ pt-BR:
warning: Tenha cuidado com estes dados. Nunca compartilhe com alguém!
your_token: Seu token de acesso
auth:
- agreement_html: Cadastrando-se você concorda em seguir
as regras da instância e
os nossos termos de serviço.
+ agreement_html: Ao se cadastrar você concorda em seguir
as regras da instância e
os nossos termos de serviço.
change_password: Segurança
delete_account: Excluir conta
delete_account_html: Se você deseja excluir a sua conta, você pode
prosseguir para cá. Uma confirmação será requisitada.
@@ -596,7 +602,7 @@ pt-BR:
open_in_web: Abrir na web
over_character_limit: limite de caracteres de %{max} excedido
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
private: Toot não-público não pode ser fixado
reblog: Um compartilhamento não pode ser fixado
diff --git a/config/locales/ru.yml b/config/locales/ru.yml
index 697a1aa27ce..6e63aaddacc 100644
--- a/config/locales/ru.yml
+++ b/config/locales/ru.yml
@@ -49,6 +49,7 @@ ru:
reserved_username: Имя пользователя зарезервировано
roles:
admin: Администратор
+ moderator: Мод
unfollow: Отписаться
admin:
account_moderation_notes:
@@ -71,6 +72,8 @@ ru:
domain: Домен
edit: Изменить
email: E-mail
+ enable: Включить
+ enabled: Включен
feed_url: URL фида
followers: Подписчики
followers_url: URL подписчиков
@@ -336,10 +339,12 @@ ru:
body: "%{reporter} подал(а) жалобу на %{target}"
subject: Новая жалоба, узел %{instance} (#%{id})
application_mailer:
+ notification_preferences: Изменить настройки e-mail
salutation: "%{name},"
settings: 'Изменить настройки e-mail: %{link}'
signature: Уведомления Mastodon от %{instance}
view: 'Просмотр:'
+ view_status: Просмотреть статус
applications:
created: Приложение успешно создано
destroyed: Приложение успешно удалено
@@ -349,7 +354,7 @@ ru:
warning: Будьте очень внимательны с этими данными. Не делитесь ими ни с кем!
your_token: Ваш токен доступа
auth:
- agreement_html: Создавая аккаунт, вы соглашаетесь с
нашими правилами поведения и
политикой конфиденциальности.
+ agreement_html: Создавая аккаунт, вы соглашаетесь с
правилами узла и
нашими условиями обслуживания.
change_password: Изменить пароль
delete_account: Удалить аккаунт
delete_account_html: Если Вы хотите удалить свой аккаунт, вы можете
перейти сюда. У Вас будет запрошено подтверждение.
@@ -554,6 +559,7 @@ ru:
blackberry: Blackberry
chrome: Chrome
edge: Microsoft Edge
+ electron: Electron
firefox: Firefox
generic: Неизвестный браузер
ie: Internet Explorer
diff --git a/config/locales/simple_form.ca.yml b/config/locales/simple_form.ca.yml
index 2ff3348f30d..3d210b73cc9 100644
--- a/config/locales/simple_form.ca.yml
+++ b/config/locales/simple_form.ca.yml
@@ -4,7 +4,7 @@ ca:
hints:
defaults:
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:
one:
1 càracter
other:
%{count} càracters
diff --git a/config/locales/simple_form.fr.yml b/config/locales/simple_form.fr.yml
index 2397e5161c6..017aa4021c6 100644
--- a/config/locales/simple_form.fr.yml
+++ b/config/locales/simple_form.fr.yml
@@ -4,7 +4,7 @@ fr:
hints:
defaults:
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:
one:
1 caractère restant
other:
%{count} caractères restants
diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml
index 361a5ada657..33b75e74ad7 100644
--- a/config/locales/simple_form.ja.yml
+++ b/config/locales/simple_form.ja.yml
@@ -4,7 +4,7 @@ ja:
hints:
defaults:
avatar: 2MBまでのPNGやGIF、JPGが利用可能です。120x120pxまで縮小されます
- digest: 長期間ログインしなかった際、その期間に受け取った返信の要約を受け取ることができます
+ digest: 長期間使用していない場合と不在時に返信を受けた場合のみ送信されます
display_name: あと
%{count}文字入力できます。
header: 2MBまでのPNGやGIF、JPGが利用可能です。 700x335pxまで縮小されます
locked: フォロワーを手動で承認する必要があります
diff --git a/config/locales/simple_form.pl.yml b/config/locales/simple_form.pl.yml
index a9723966926..dd987aab12d 100644
--- a/config/locales/simple_form.pl.yml
+++ b/config/locales/simple_form.pl.yml
@@ -4,27 +4,27 @@ pl:
hints:
defaults:
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:
few: Pozostały
%{count} znaki.
many: Pozostało
%{count} znaków
- one: Pozostał
1 znak.
+ one: Pozostał
1 znak
other: Pozostało
%{count} znaków
header: PNG, GIF lub JPG. Maksymalnie 2MB. Zostanie zmniejszony do 700x335px
locked: Musisz akceptować prośby o śledzenie
note:
few: Pozostały
%{count} znaki.
many: Pozostało
%{count} znaków
- one: Pozostał
1 znak.
+ one: Pozostał
1 znak
other: Pozostało
%{count} znaków
setting_noindex: Wpływa na widoczność strony profilu i Twoich wpisów
setting_skin: Zmienia wygląd używanej odmiany Mastodona
imports:
data: Plik CSV wyeksportowany z innej instancji Mastodona
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:
- 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:
defaults:
avatar: Awatar
diff --git a/config/locales/simple_form.sk.yml b/config/locales/simple_form.sk.yml
index 25265c73a6c..45e4c295402 100644
--- a/config/locales/simple_form.sk.yml
+++ b/config/locales/simple_form.sk.yml
@@ -30,10 +30,12 @@ sk:
data: Dáta
display_name: Meno
email: Emailová adresa
+ expires_in: Expirovať po
filtered_languages: Filtrované jazyky
header: Obrázok v hlavičke
locale: Jazyk
locked: Zamknúť účet
+ max_uses: Maximálny počet použití
new_password: Nové heslo
note: O vás
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_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_reduce_motion: Redukovať pohyb v animáciách
setting_system_font_ui: Použiť štandardný systémový font
setting_theme: Vzhľad
setting_unfollow_modal: Zobrazovať potvrdzovacie okno pred skončením sledovania iného používateľa
@@ -53,6 +56,7 @@ sk:
interactions:
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_dm: Blokovať priame správy od ľudí ktorých nesleduješ
notification_emails:
digest: Posielať súhrnné emaily
favourite: Poslať email ak niekto označí váš príspevok ako obľúbený
diff --git a/config/locales/sk.yml b/config/locales/sk.yml
index d3ae96dcd3e..4cf7d6f3098 100644
--- a/config/locales/sk.yml
+++ b/config/locales/sk.yml
@@ -1,6 +1,7 @@
---
sk:
about:
+ about_hashtag_html: Toto sú verejné tooty otagované
#%{tagom}. 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_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.
@@ -38,6 +39,7 @@ sk:
followers: Sledujúci
following: Sleduje
media: Médiá
+ moved_html: "%{name} účet bol presunutý na %{new_profile_link}:"
nothing_here: Nič tu nie je!
people_followed_by: Ľudia, ktorých %{name} sleduje
people_who_follow: Ľudia sledujúci %{name}
@@ -47,17 +49,31 @@ sk:
reserved_username: Prihlasovacie meno je rezervované
roles:
admin: Admin
+ moderator: Mod
unfollow: Prestať sledovať
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:
are_you_sure: Ste si istý?
+ by_domain: Doména
confirm: Potvrdiť
confirmed: Potvrdený
+ demote: Degradovať
+ disable: Zablokovať
disable_two_factor_authentication: Zakázať 2FA
+ disabled: Blokovaný
display_name: Zobraziť meno
domain: Doména
edit: Upraviť
email: Email
+ enable: Povoliť
+ enabled: Povolený
feed_url: URL časovej osi
followers: Sledujúci
followers_url: URL sledujúcich
@@ -69,12 +85,15 @@ sk:
local: Lokálne
remote: Federované
title: Lokácia
+ login_status: Status prihlásenia
media_attachments: Prílohy
+ memorialize: Zmeniť na "Navždy budeme spomínať"
moderation:
all: Všetko
silenced: Umlčané
suspended: Suspendované
title: Moderácia
+ moderation_notes: Moderátorské poznámky
most_recent_activity: Posledná aktivita
most_recent_ip: Posledná IP
not_subscribed: Nezaregistrované
@@ -85,6 +104,7 @@ sk:
outbox_url: URL poslaných
perform_full_suspension: Suspendovať
profile_url: URL profilu
+ promote: Povýšiť
protocol: Protokol
public: Verejná os
push_subscription_expires: PuSH odoberanie expiruje
@@ -92,6 +112,12 @@ sk:
reset: Reset
reset_password: Obnoviť heslo
resubscribe: Znovu odoberať
+ role: Oprávnenia
+ roles:
+ admin: Administrátor
+ moderator: Moderátor
+ staff: Člen
+ user: Používateľ
salmon_url: Salmon URL
search: Hľadať
shared_inbox_url: URL zdieľanej schránky
@@ -108,17 +134,56 @@ sk:
unsubscribe: Prestať odoberať
username: Používateľske meno
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:
+ 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é!
delete: Zmazať
destroyed_msg: Emojo úspešne zničený!
+ disable: Zakázať
+ disabled_msg: Emoji bolo úspešne zakázané
emoji: Emoji
+ enable: Povoliť
+ enabled_msg: Emoji bolo úspešne povolené
image_hint: PNG do 50KB
+ listed: V zozname
new:
- title: Pridať vlastný emoji
+ title: Pridať nový vlastný emoji
+ overwrite: Prepísať
shortcode: Skratka
shortcode_hint: Aspoň 2 znaky, povolené sú alfanumerické alebo podčiarkovník
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ť
domain_blocks:
add_new: Pridať nový
@@ -129,16 +194,43 @@ sk:
create: Blokovať doménu
hint: Blokovanie domény stále dovolí vytvárať nové účty v databáze, ale tieto budú automaticky moderované.
severity:
+ desc_html: "
Stíšenie urobí všetky príspevky účtu neviditeľné pre všetkých ktorý nesledujú tento účet.
Suspendácia zmaže všetky príspevky, médiá a profilové informácie. Použi
Nič ak chceš iba neprijímať súbory médií."
noop: Nič
silence: Stíšiť
suspend: Suspendovať
title: Nové blokovanie domény
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:
noop: Nič
silence: Stíšiť
suspend: Suspendovať
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:
authorized_apps: Autorizované aplikácie
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:'
diff --git a/spec/controllers/concerns/user_tracking_concern_spec.rb b/spec/controllers/concerns/user_tracking_concern_spec.rb
index 168d44ba6d9..d08095ef827 100644
--- a/spec/controllers/concerns/user_tracking_concern_spec.rb
+++ b/spec/controllers/concerns/user_tracking_concern_spec.rb
@@ -43,15 +43,39 @@ describe ApplicationController, type: :controller do
expect_updated_sign_in_at(user)
end
- it 'regenerates feed when sign in is older than two weeks' do
- allow(RegenerationWorker).to receive(:perform_async)
- user.update(current_sign_in_at: 3.weeks.ago)
- sign_in user, scope: :user
- get :show
+ describe 'feed regeneration' do
+ before do
+ alice = Fabricate(:account)
+ bob = Fabricate(:account)
- 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)
+ user.account.follow!(alice)
+ user.account.follow!(bob)
+
+ 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
def expect_updated_sign_in_at(user)
diff --git a/spec/services/notify_service_spec.rb b/spec/services/notify_service_spec.rb
index bb7601e7643..1435ec917f4 100644
--- a/spec/services/notify_service_spec.rb
+++ b/spec/services/notify_service_spec.rb
@@ -82,10 +82,19 @@ RSpec.describe NotifyService do
is_expected.to_not change(Notification, :count)
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(: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
is_expected.to change(Notification, :count)
end