diff options
Diffstat (limited to 'app/javascript')
15 files changed, 159 insertions, 104 deletions
diff --git a/app/javascript/flavours/glitch/actions/notifications.js b/app/javascript/flavours/glitch/actions/notifications.js index ddf14f78f..0184d9c80 100644 --- a/app/javascript/flavours/glitch/actions/notifications.js +++ b/app/javascript/flavours/glitch/actions/notifications.js @@ -102,7 +102,7 @@ export function expandNotifications({ maxId } = {}, done = noOp) { }; if (!maxId && notifications.get('items').size > 0) { - params.since_id = notifications.getIn(['items', 0]); + params.since_id = notifications.getIn(['items', 0, 'id']); } dispatch(expandNotificationsRequest(isLoadingMore)); diff --git a/app/javascript/flavours/glitch/actions/timelines.js b/app/javascript/flavours/glitch/actions/timelines.js index 27ca66e51..ffd259d5f 100644 --- a/app/javascript/flavours/glitch/actions/timelines.js +++ b/app/javascript/flavours/glitch/actions/timelines.js @@ -12,34 +12,13 @@ export const TIMELINE_SCROLL_TOP = 'TIMELINE_SCROLL_TOP'; export const TIMELINE_DISCONNECT = 'TIMELINE_DISCONNECT'; -export const TIMELINE_CONTEXT_UPDATE = 'CONTEXT_UPDATE'; - export function updateTimeline(timeline, status) { return (dispatch, getState) => { - const parents = []; - - if (status.in_reply_to_id) { - let parent = getState().getIn(['statuses', status.in_reply_to_id]); - - while (parent && parent.get('in_reply_to_id')) { - parents.push(parent.get('id')); - parent = getState().getIn(['statuses', parent.get('in_reply_to_id')]); - } - } - dispatch({ type: TIMELINE_UPDATE, timeline, status, }); - - if (parents.length > 0) { - dispatch({ - type: TIMELINE_CONTEXT_UPDATE, - status, - references: parents, - }); - } }; }; diff --git a/app/javascript/flavours/glitch/features/status/index.js b/app/javascript/flavours/glitch/features/status/index.js index 61de148e1..d2d5a05c8 100644 --- a/app/javascript/flavours/glitch/features/status/index.js +++ b/app/javascript/flavours/glitch/features/status/index.js @@ -1,3 +1,4 @@ +import Immutable from 'immutable'; import React from 'react'; import { connect } from 'react-redux'; import PropTypes from 'prop-types'; @@ -57,13 +58,49 @@ const messages = defineMessages({ const makeMapStateToProps = () => { const getStatus = makeGetStatus(); - const mapStateToProps = (state, props) => ({ - status: getStatus(state, { id: props.params.statusId }), - settings: state.get('local_settings'), - ancestorsIds: state.getIn(['contexts', 'ancestors', props.params.statusId]), - descendantsIds: state.getIn(['contexts', 'descendants', props.params.statusId]), - askReplyConfirmation: state.getIn(['compose', 'text']).trim().length !== 0, - }); + const mapStateToProps = (state, props) => { + const status = getStatus(state, { id: props.params.statusId }); + let ancestorsIds = Immutable.List(); + let descendantsIds = Immutable.List(); + + if (status) { + ancestorsIds = ancestorsIds.withMutations(mutable => { + let id = status.get('in_reply_to_id'); + + while (id) { + mutable.unshift(id); + id = state.getIn(['contexts', 'inReplyTos', id]); + } + }); + + descendantsIds = descendantsIds.withMutations(mutable => { + const ids = [status.get('id')]; + + while (ids.length > 0) { + let id = ids.shift(); + const replies = state.getIn(['contexts', 'replies', id]); + + if (status.get('id') !== id) { + mutable.push(id); + } + + if (replies) { + replies.reverse().forEach(reply => { + ids.unshift(reply); + }); + } + } + }); + } + + return { + status, + ancestorsIds, + descendantsIds, + settings: state.get('local_settings'), + askReplyConfirmation: state.getIn(['compose', 'text']).trim().length !== 0, + }; + }; return mapStateToProps; }; @@ -97,6 +134,16 @@ export default class Status extends ImmutablePureComponent { componentDidMount () { attachFullscreenListener(this.onFullScreenChange); this.props.dispatch(fetchStatus(this.props.params.statusId)); + + const { status, ancestorsIds } = this.props; + + if (status && ancestorsIds && ancestorsIds.size > 0) { + const element = this.node.querySelectorAll('.focusable')[ancestorsIds.size - 1]; + + window.requestAnimationFrame(() => { + element.scrollIntoView(true); + }); + } } static getDerivedStateFromProps(props, state) { @@ -339,7 +386,7 @@ export default class Status extends ImmutablePureComponent { } componentDidUpdate (prevProps) { - if (this.props.params.statusId !== prevProps.params.statusId && this.props.params.statusId) { + if (this.props.params.statusId && (this.props.params.statusId !== prevProps.params.statusId || prevProps.ancestorsIds.size < this.props.ancestorsIds.size)) { const { status, ancestorsIds } = this.props; if (status && ancestorsIds && ancestorsIds.size > 0) { diff --git a/app/javascript/flavours/glitch/reducers/contexts.js b/app/javascript/flavours/glitch/reducers/contexts.js index effd70756..73b25fe3f 100644 --- a/app/javascript/flavours/glitch/reducers/contexts.js +++ b/app/javascript/flavours/glitch/reducers/contexts.js @@ -3,38 +3,63 @@ import { ACCOUNT_MUTE_SUCCESS, } from 'flavours/glitch/actions/accounts'; import { CONTEXT_FETCH_SUCCESS } from 'flavours/glitch/actions/statuses'; -import { TIMELINE_DELETE, TIMELINE_CONTEXT_UPDATE } from 'flavours/glitch/actions/timelines'; +import { TIMELINE_DELETE, TIMELINE_UPDATE } from 'flavours/glitch/actions/timelines'; import { Map as ImmutableMap, List as ImmutableList } from 'immutable'; +import compareId from 'flavours/glitch/util/compare_id'; const initialState = ImmutableMap({ - ancestors: ImmutableMap(), - descendants: ImmutableMap(), + inReplyTos: ImmutableMap(), + replies: ImmutableMap(), }); -const normalizeContext = (state, id, ancestors, descendants) => { - const ancestorsIds = ImmutableList(ancestors.map(ancestor => ancestor.id)); - const descendantsIds = ImmutableList(descendants.map(descendant => descendant.id)); +const normalizeContext = (immutableState, id, ancestors, descendants) => immutableState.withMutations(state => { + state.update('inReplyTos', immutableAncestors => immutableAncestors.withMutations(inReplyTos => { + state.update('replies', immutableDescendants => immutableDescendants.withMutations(replies => { + function addReply({ id, in_reply_to_id }) { + if (in_reply_to_id && !inReplyTos.has(id)) { - return state.withMutations(map => { - map.setIn(['ancestors', id], ancestorsIds); - map.setIn(['descendants', id], descendantsIds); - }); -}; + replies.update(in_reply_to_id, ImmutableList(), siblings => { + const index = siblings.findLastIndex(sibling => compareId(sibling, id) < 0); + return siblings.insert(index + 1, id); + }); + + inReplyTos.set(id, in_reply_to_id); + } + } + + // We know in_reply_to_id of statuses but `id` itself. + // So we assume that the status of the id replies to last ancestors. + + ancestors.forEach(addReply); + + if (ancestors[0]) { + addReply({ id, in_reply_to_id: ancestors[ancestors.length - 1].id }); + } + + descendants.forEach(addReply); + })); + })); +}); const deleteFromContexts = (immutableState, ids) => immutableState.withMutations(state => { - state.update('ancestors', immutableAncestors => immutableAncestors.withMutations(ancestors => { - state.update('descendants', immutableDescendants => immutableDescendants.withMutations(descendants => { + state.update('inReplyTos', immutableAncestors => immutableAncestors.withMutations(inReplyTos => { + state.update('replies', immutableDescendants => immutableDescendants.withMutations(replies => { ids.forEach(id => { - descendants.get(id, ImmutableList()).forEach(descendantId => { - ancestors.update(descendantId, ImmutableList(), list => list.filterNot(itemId => itemId === id)); - }); + const inReplyToIdOfId = inReplyTos.get(id); + const repliesOfId = replies.get(id); + const siblings = replies.get(inReplyToIdOfId); + + if (siblings) { + replies.set(inReplyToIdOfId, siblings.filterNot(sibling => sibling === id)); + } - ancestors.get(id, ImmutableList()).forEach(ancestorId => { - descendants.update(ancestorId, ImmutableList(), list => list.filterNot(itemId => itemId === id)); - }); - descendants.delete(id); - ancestors.delete(id); + if (repliesOfId) { + repliesOfId.forEach(reply => inReplyTos.delete(reply)); + } + + inReplyTos.delete(id); + replies.delete(id); }); })); })); @@ -47,23 +72,23 @@ const filterContexts = (state, relationship, statuses) => { return deleteFromContexts(state, ownedStatusIds); }; -const updateContext = (state, status, references) => { - return state.update('descendants', map => { - references.forEach(parentId => { - map = map.update(parentId, ImmutableList(), list => { - if (list.includes(status.id)) { - return list; - } +const updateContext = (state, status) => { + if (status.in_reply_to_id) { + return state.withMutations(mutable => { + const replies = mutable.getIn(['replies', status.in_reply_to_id], ImmutableList()); - return list.push(status.id); - }); + mutable.setIn(['inReplyTos', status.id], status.in_reply_to_id); + + if (!replies.includes(status.id)) { + mutable.setIn(['replies', status.in_reply_to_id], replies.push(status.id)); + } }); + } - return map; - }); + return state; }; -export default function contexts(state = initialState, action) { +export default function replies(state = initialState, action) { switch(action.type) { case ACCOUNT_BLOCK_SUCCESS: case ACCOUNT_MUTE_SUCCESS: @@ -72,8 +97,8 @@ export default function contexts(state = initialState, action) { return normalizeContext(state, action.id, action.ancestors, action.descendants); case TIMELINE_DELETE: return deleteFromContexts(state, [action.id]); - case TIMELINE_CONTEXT_UPDATE: - return updateContext(state, action.status, action.references); + case TIMELINE_UPDATE: + return updateContext(state, action.status); default: return state; } diff --git a/app/javascript/locales/locale-data/oc.js b/app/javascript/locales/locale-data/oc.js index c4b56350b..d4adc42eb 100644 --- a/app/javascript/locales/locale-data/oc.js +++ b/app/javascript/locales/locale-data/oc.js @@ -17,8 +17,8 @@ export default [{ }, relativeTime: { future: { - one: "dins {0} an", - other: "dins {0} ans", + one: "d’aquí {0} an", + other: "d’aquí {0} ans", }, past: { one: "fa {0} an", @@ -35,8 +35,8 @@ export default [{ }, relativeTime: { future: { - one: "dins {0} mes", - other: "dins {0} meses", + one: "d’aquí {0} mes", + other: "d’aquí {0} meses", }, past: { one: "fa {0} mes", @@ -53,8 +53,8 @@ export default [{ }, relativeTime: { future: { - one: "dins {0} jorn", - other: "dins {0} jorns", + one: "d’aquí {0} jorn", + other: "d’aquí {0} jorns", }, past: { one: "fa {0} jorn", @@ -66,8 +66,8 @@ export default [{ displayName: "ora", relativeTime: { future: { - one: "dins {0} ora", - other: "dins {0} oras", + one: "d’aquí {0} ora", + other: "d’aquí {0} oras", }, past: { one: "fa {0} ora", @@ -79,8 +79,8 @@ export default [{ displayName: "minuta", relativeTime: { future: { - one: "dins {0} minuta", - other: "dins {0} minutas", + one: "d’aquí {0} minuta", + other: "d’aquí {0} minutas", }, past: { one: "fa {0} minuta", @@ -95,8 +95,8 @@ export default [{ }, relativeTime: { future: { - one: "dins {0} segonda", - other: "dins {0} segondas", + one: "d’aquí {0} segonda", + other: "d’aquí {0} segondas", }, past: { one: "fa {0} segonda", diff --git a/app/javascript/mastodon/actions/conversations.js b/app/javascript/mastodon/actions/conversations.js index aefd2fef7..3c2ea9680 100644 --- a/app/javascript/mastodon/actions/conversations.js +++ b/app/javascript/mastodon/actions/conversations.js @@ -38,7 +38,7 @@ export const expandConversations = ({ maxId } = {}) => (dispatch, getState) => { const params = { max_id: maxId }; if (!maxId) { - params.since_id = getState().getIn(['conversations', 0, 'last_status']); + params.since_id = getState().getIn(['conversations', 'items', 0, 'last_status']); } api(getState).get('/api/v1/conversations', { params }) diff --git a/app/javascript/mastodon/actions/notifications.js b/app/javascript/mastodon/actions/notifications.js index 92c70e155..d24f39ad2 100644 --- a/app/javascript/mastodon/actions/notifications.js +++ b/app/javascript/mastodon/actions/notifications.js @@ -106,7 +106,7 @@ export function expandNotifications({ maxId } = {}, done = noOp) { }; if (!maxId && notifications.get('items').size > 0) { - params.since_id = notifications.getIn(['items', 0]); + params.since_id = notifications.getIn(['items', 0, 'id']); } dispatch(expandNotificationsRequest(isLoadingMore)); diff --git a/app/javascript/mastodon/actions/timelines.js b/app/javascript/mastodon/actions/timelines.js index 81c4c8425..215adc4ea 100644 --- a/app/javascript/mastodon/actions/timelines.js +++ b/app/javascript/mastodon/actions/timelines.js @@ -15,7 +15,7 @@ export const TIMELINE_SCROLL_TOP = 'TIMELINE_SCROLL_TOP'; export const TIMELINE_DISCONNECT = 'TIMELINE_DISCONNECT'; export function updateTimeline(timeline, status, accept) { - return (dispatch, getState) => { + return dispatch => { if (typeof accept === 'function' && !accept(status)) { return; } diff --git a/app/javascript/mastodon/features/account/components/header.js b/app/javascript/mastodon/features/account/components/header.js index 11ae58905..8604e7167 100644 --- a/app/javascript/mastodon/features/account/components/header.js +++ b/app/javascript/mastodon/features/account/components/header.js @@ -16,6 +16,7 @@ const messages = defineMessages({ unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' }, edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' }, linkVerifiedOn: { id: 'account.link_verified_on', defaultMessage: 'Ownership of this link was checked on {date}' }, + account_locked: { id: 'account.locked_info', defaultMessage: 'This account privacy status is set to locked. The owner manually reviews who can follow them.' }, }); const dateFormatOptions = { @@ -148,7 +149,7 @@ class Header extends ImmutablePureComponent { } if (account.get('locked')) { - lockedIcon = <i className='fa fa-lock' />; + lockedIcon = <i className='fa fa-lock' title={intl.formatMessage(messages.account_locked)} />; } const content = { __html: account.get('note_emojified') }; diff --git a/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js b/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js index 82936c838..9c9f62d82 100644 --- a/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js +++ b/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js @@ -5,8 +5,8 @@ import { injectIntl, FormattedMessage } from 'react-intl'; import Toggle from 'react-toggle'; import AsyncSelect from 'react-select/lib/Async'; -@injectIntl -export default class ColumnSettings extends React.PureComponent { +export default @injectIntl +class ColumnSettings extends React.PureComponent { static propTypes = { settings: ImmutablePropTypes.map.isRequired, diff --git a/app/javascript/mastodon/features/hashtag_timeline/index.js b/app/javascript/mastodon/features/hashtag_timeline/index.js index d7722dcce..c2e026d13 100644 --- a/app/javascript/mastodon/features/hashtag_timeline/index.js +++ b/app/javascript/mastodon/features/hashtag_timeline/index.js @@ -42,13 +42,13 @@ class HashtagTimeline extends React.PureComponent { title = () => { let title = [this.props.params.id]; if (this.additionalFor('any')) { - title.push(<FormattedMessage id='hashtag.column_header.tag_mode.any' values={{ additional: this.additionalFor('any') }} defaultMessage=' or {additional}' />); + title.push(' ', <FormattedMessage id='hashtag.column_header.tag_mode.any' values={{ additional: this.additionalFor('any') }} defaultMessage='or {additional}' />); } if (this.additionalFor('all')) { - title.push(<FormattedMessage id='hashtag.column_header.tag_mode.all' values={{ additional: this.additionalFor('all') }} defaultMessage=' and {additional}' />); + title.push(' ', <FormattedMessage id='hashtag.column_header.tag_mode.all' values={{ additional: this.additionalFor('all') }} defaultMessage='and {additional}' />); } if (this.additionalFor('none')) { - title.push(<FormattedMessage id='hashtag.column_header.tag_mode.none' values={{ additional: this.additionalFor('none') }} defaultMessage=' without {additional}' />); + title.push(' ', <FormattedMessage id='hashtag.column_header.tag_mode.none' values={{ additional: this.additionalFor('none') }} defaultMessage='without {additional}' />); } return title; } diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 16f680fa3..ca5abcb05 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -17,6 +17,7 @@ "account.follows_you": "Follows you", "account.hide_reblogs": "Hide boosts from @{name}", "account.link_verified_on": "Ownership of this link was checked on {date}", + "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.", "account.media": "Media", "account.mention": "Mention @{name}", "account.moved_to": "{name} has moved to:", @@ -142,9 +143,9 @@ "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.", "getting_started.security": "Security", "getting_started.terms": "Terms of service", - "hashtag.column_header.tag_mode.all": "{tag} and {additional}", - "hashtag.column_header.tag_mode.any": "{tag} or {additional}", - "hashtag.column_header.tag_mode.none": "{tag} without {additional}", + "hashtag.column_header.tag_mode.all": "and {additional}", + "hashtag.column_header.tag_mode.any": "or {additional}", + "hashtag.column_header.tag_mode.none": "without {additional}", "hashtag.column_settings.tag_mode.all": "All of these", "hashtag.column_settings.tag_mode.any": "Any of these", "hashtag.column_settings.tag_mode.none": "None of these", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index e774bb70b..06fe71e6b 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -142,9 +142,9 @@ "getting_started.open_source_notice": "Mastodonはオープンソースソフトウェアです。誰でもGitHub({github})から開発に参加したり、問題を報告したりできます。", "getting_started.security": "セキュリティ", "getting_started.terms": "プライバシーポリシー", - "hashtag.column_header.tag_mode.all": " と {additional}", - "hashtag.column_header.tag_mode.any": " か {additional}", - "hashtag.column_header.tag_mode.none": " ({additional} を除く)", + "hashtag.column_header.tag_mode.all": "と {additional}", + "hashtag.column_header.tag_mode.any": "か {additional}", + "hashtag.column_header.tag_mode.none": "({additional} を除く)", "hashtag.column_settings.tag_mode.all": "すべてを含む", "hashtag.column_settings.tag_mode.any": "いずれかを含む", "hashtag.column_settings.tag_mode.none": "これらを除く", diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json index ec0507e15..a94e0336d 100644 --- a/app/javascript/mastodon/locales/oc.json +++ b/app/javascript/mastodon/locales/oc.json @@ -1,5 +1,5 @@ { - "account.add_or_remove_from_list": "Add or Remove from lists", + "account.add_or_remove_from_list": "Ajustar o tirar de las listas", "account.badges.bot": "Robòt", "account.block": "Blocar @{name}", "account.block_domain": "Tot amagar del domeni {domain}", @@ -17,6 +17,7 @@ "account.follows_you": "Vos sèc", "account.hide_reblogs": "Rescondre los partatges de @{name}", "account.link_verified_on": "La proprietat d’aqueste ligam foguèt verificada lo {date}", + "account.locked_info": "L’estatut de privacitat del compte es configurat sus clavat. Lo proprietari causís qual pòt sègre son compte.", "account.media": "Mèdias", "account.mention": "Mencionar @{name}", "account.moved_to": "{name} a mudat los catons a :", @@ -68,7 +69,7 @@ "community.column_settings.media_only": "Solament los mèdias", "compose_form.direct_message_warning": "Sols los mencionats poiràn veire aqueste tut.", "compose_form.direct_message_warning_learn_more": "Ne saber mai", - "compose_form.hashtag_warning": "Aqueste tut serà pas ligat a cap d’etiqueta estant qu’es pas listat. Òm pas cercar que los tuts publics per etiqueta.", + "compose_form.hashtag_warning": "Aqueste tut serà pas ligat a cap d’etiqueta estant qu’es pas listat. Òm pòt pas cercar que los tuts publics per etiqueta.", "compose_form.lock_disclaimer": "Vòstre compte es pas {locked}. Tot lo monde pòt vos sègre e veire los estatuts reservats als seguidors.", "compose_form.lock_disclaimer.lock": "clavat", "compose_form.placeholder": "A de qué pensatz ?", @@ -112,7 +113,7 @@ "emoji_button.search_results": "Resultats de recèrca", "emoji_button.symbols": "Simbòls", "emoji_button.travel": "Viatges & lòcs", - "empty_column.account_timeline": "No toots here!", + "empty_column.account_timeline": "Cap de tuts aquí !", "empty_column.blocks": "Avètz pas blocat degun pel moment.", "empty_column.community": "Lo flux public local es void. Escrivètz quicòm per lo garnir !", "empty_column.direct": "Avètz pas encara cap de messatges. Quand ne mandatz un o que ne recebètz un, serà mostrat aquí.", @@ -138,13 +139,13 @@ "getting_started.open_source_notice": "Mastodon es un logicial liure. Podètz contribuir e mandar vòstres comentaris e rapòrt de bug via {github} sus GitHub.", "getting_started.security": "Seguretat", "getting_started.terms": "Condicions d’utilizacion", - "hashtag.column_header.tag_mode.all": "and {additional}", - "hashtag.column_header.tag_mode.any": "or {additional}", - "hashtag.column_header.tag_mode.none": "without {additional}", - "hashtag.column_settings.tag_mode.all": "All of these", - "hashtag.column_settings.tag_mode.any": "Any of these", - "hashtag.column_settings.tag_mode.none": "None of these", - "hashtag.column_settings.tag_toggle": "Include additional tags in this column", + "hashtag.column_header.tag_mode.all": "e {additional}", + "hashtag.column_header.tag_mode.any": "o {additional}", + "hashtag.column_header.tag_mode.none": "sens {additional}", + "hashtag.column_settings.tag_mode.all": "Totes aquestes", + "hashtag.column_settings.tag_mode.any": "Un d’aquestes", + "hashtag.column_settings.tag_mode.none": "Cap d’aquestesNone of these", + "hashtag.column_settings.tag_toggle": "Inclure las etiquetas suplementàrias dins aquesta colomna", "home.column_settings.basic": "Basic", "home.column_settings.show_reblogs": "Mostrar los partatges", "home.column_settings.show_replies": "Mostrar las responsas", @@ -174,7 +175,7 @@ "keyboard_shortcuts.reply": "respondre", "keyboard_shortcuts.requests": "per dorbir la lista de demanda d’abonament", "keyboard_shortcuts.search": "anar a la recèrca", - "keyboard_shortcuts.start": "per dobrir la columna «Per començar»", + "keyboard_shortcuts.start": "per dobrir la colomna «Per començar»", "keyboard_shortcuts.toggle_hidden": "mostrar/amagar lo tèxte dels avertiments", "keyboard_shortcuts.toot": "començar un estatut tot novèl", "keyboard_shortcuts.unfocus": "quitar lo camp tèxte/de recèrca", @@ -321,7 +322,7 @@ "status.show_less_all": "Los tornar plegar totes", "status.show_more": "Desplegar", "status.show_more_all": "Los desplegar totes", - "status.show_thread": "Show thread", + "status.show_thread": "Mostrar lo fil", "status.unmute_conversation": "Tornar mostrar la conversacion", "status.unpin": "Tirar del perfil", "suggestions.dismiss": "Regetar la suggestion", diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json index 1fb8df0ad..237ffd33a 100644 --- a/app/javascript/mastodon/locales/pl.json +++ b/app/javascript/mastodon/locales/pl.json @@ -17,6 +17,7 @@ "account.follows_you": "Śledzi Cię", "account.hide_reblogs": "Ukryj podbicia od @{name}", "account.link_verified_on": "Własność tego odnośnika została potwierdzona {date}", + "account.locked_info": "To konto jest prywatne. Właściciel ręcznie wybiera kto może go śledzić.", "account.media": "Zawartość multimedialna", "account.mention": "Wspomnij o @{name}", "account.moved_to": "{name} przeniósł(-osła) się do:", |