Merge commit '24319836de6046fb2985ec1a24c30ad7d47584d7' into glitch-soc/merge-upstream

Conflicts:
- `config/routes/api.rb`:
  glitch-soc has an extra `:destroy` action on notifications for historical reasons.
  Kept it for now, while otherwise updating as upstream did.
This commit is contained in:
Claire 2024-03-11 17:29:07 +01:00
commit a5127d0ef8
232 changed files with 6162 additions and 2199 deletions

View file

@ -123,7 +123,7 @@ module.exports = defineConfig({
'react/react-in-jsx-scope': 'off', // not needed with new JSX transform 'react/react-in-jsx-scope': 'off', // not needed with new JSX transform
'react/self-closing-comp': 'error', 'react/self-closing-comp': 'error',
// recommended values found in https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/src/index.js // recommended values found in https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/v6.8.0/src/index.js#L46
'jsx-a11y/accessible-emoji': 'warn', 'jsx-a11y/accessible-emoji': 'warn',
'jsx-a11y/click-events-have-key-events': 'off', 'jsx-a11y/click-events-have-key-events': 'off',
'jsx-a11y/label-has-associated-control': 'off', 'jsx-a11y/label-has-associated-control': 'off',
@ -176,7 +176,7 @@ module.exports = defineConfig({
}, },
], ],
// See https://github.com/import-js/eslint-plugin-import/blob/main/config/recommended.js // See https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/config/recommended.js
'import/extensions': [ 'import/extensions': [
'error', 'error',
'always', 'always',

View file

@ -29,7 +29,7 @@ ARG MASTODON_VERSION_METADATA=""
# See: https://docs.joinmastodon.org/admin/config/#rails_serve_static_files # See: https://docs.joinmastodon.org/admin/config/#rails_serve_static_files
ARG RAILS_SERVE_STATIC_FILES="true" ARG RAILS_SERVE_STATIC_FILES="true"
# Allow to use YJIT compiler # Allow to use YJIT compiler
# See: https://github.com/ruby/ruby/blob/master/doc/yjit/yjit.md # See: https://github.com/ruby/ruby/blob/v3_2_3/doc/yjit/yjit.md
ARG RUBY_YJIT_ENABLE="1" ARG RUBY_YJIT_ENABLE="1"
# Timezone used by the Docker container and runtime, change with [--build-arg TZ=Europe/Berlin] # Timezone used by the Docker container and runtime, change with [--build-arg TZ=Europe/Berlin]
ARG TZ="Etc/UTC" ARG TZ="Etc/UTC"

View file

@ -465,11 +465,11 @@ GEM
statsd-ruby (~> 1.4, >= 1.4.0) statsd-ruby (~> 1.4, >= 1.4.0)
oj (3.16.3) oj (3.16.3)
bigdecimal (>= 3.0) bigdecimal (>= 3.0)
omniauth (2.1.1) omniauth (2.1.2)
hashie (>= 3.4.6) hashie (>= 3.4.6)
rack (>= 2.2.3) rack (>= 2.2.3)
rack-protection rack-protection
omniauth-cas (3.0.0.beta.1) omniauth-cas (3.0.0)
addressable (~> 2.8) addressable (~> 2.8)
nokogiri (~> 1.12) nokogiri (~> 1.12)
omniauth (~> 2.1) omniauth (~> 2.1)
@ -505,7 +505,7 @@ GEM
parslet (2.0.0) parslet (2.0.0)
pastel (0.8.0) pastel (0.8.0)
tty-color (~> 0.5) tty-color (~> 0.5)
pg (1.5.5) pg (1.5.6)
pghero (3.4.1) pghero (3.4.1)
activerecord (>= 6) activerecord (>= 6)
posix-spawn (0.3.15) posix-spawn (0.3.15)
@ -543,8 +543,9 @@ GEM
httpclient httpclient
json-jwt (>= 1.11.0) json-jwt (>= 1.11.0)
rack (>= 2.1.0) rack (>= 2.1.0)
rack-protection (3.0.5) rack-protection (3.2.0)
rack base64 (>= 0.1.0)
rack (~> 2.2, >= 2.2.4)
rack-proxy (0.7.6) rack-proxy (0.7.6)
rack rack
rack-session (1.0.2) rack-session (1.0.2)
@ -743,7 +744,7 @@ GEM
unicode-display_width (>= 1.1.1, < 3) unicode-display_width (>= 1.1.1, < 3)
terrapin (1.0.1) terrapin (1.0.1)
climate_control climate_control
test-prof (1.3.1) test-prof (1.3.2)
thor (1.3.1) thor (1.3.1)
tilt (2.3.0) tilt (2.3.0)
timeout (0.4.1) timeout (0.4.1)

View file

@ -53,7 +53,7 @@ module Admin
end end
def resource_params def resource_params
params.require(:rule).permit(:text, :priority) params.require(:rule).permit(:text, :hint, :priority)
end end
end end
end end

View file

@ -0,0 +1,37 @@
# frozen_string_literal: true
class Api::V1::Notifications::PoliciesController < Api::BaseController
before_action -> { doorkeeper_authorize! :read, :'read:notifications' }, only: :show
before_action -> { doorkeeper_authorize! :write, :'write:notifications' }, only: :update
before_action :require_user!
before_action :set_policy
def show
render json: @policy, serializer: REST::NotificationPolicySerializer
end
def update
@policy.update!(resource_params)
render json: @policy, serializer: REST::NotificationPolicySerializer
end
private
def set_policy
@policy = NotificationPolicy.find_or_initialize_by(account: current_account)
with_read_replica do
@policy.summarize!
end
end
def resource_params
params.permit(
:filter_not_following,
:filter_not_followers,
:filter_new_accounts,
:filter_private_mentions
)
end
end

View file

@ -0,0 +1,79 @@
# frozen_string_literal: true
class Api::V1::Notifications::RequestsController < Api::BaseController
before_action -> { doorkeeper_authorize! :read, :'read:notifications' }, only: :index
before_action -> { doorkeeper_authorize! :write, :'write:notifications' }, except: :index
before_action :require_user!
before_action :set_request, except: :index
after_action :insert_pagination_headers, only: :index
def index
with_read_replica do
@requests = load_requests
@relationships = relationships
end
render json: @requests, each_serializer: REST::NotificationRequestSerializer, relationships: @relationships
end
def show
render json: @request, serializer: REST::NotificationRequestSerializer
end
def accept
AcceptNotificationRequestService.new.call(@request)
render_empty
end
def dismiss
@request.update!(dismissed: true)
render_empty
end
private
def load_requests
requests = NotificationRequest.where(account: current_account).where(dismissed: truthy_param?(:dismissed) || false).includes(:last_status, from_account: [:account_stat, :user]).to_a_paginated_by_id(
limit_param(DEFAULT_ACCOUNTS_LIMIT),
params_slice(:max_id, :since_id, :min_id)
)
NotificationRequest.preload_cache_collection(requests) do |statuses|
cache_collection(statuses, Status)
end
end
def relationships
StatusRelationshipsPresenter.new(@requests.map(&:last_status), current_user&.account_id)
end
def set_request
@request = NotificationRequest.where(account: current_account).find(params[:id])
end
def insert_pagination_headers
set_pagination_headers(next_path, prev_path)
end
def next_path
api_v1_notifications_requests_url pagination_params(max_id: pagination_max_id) unless @requests.empty?
end
def prev_path
api_v1_notifications_requests_url pagination_params(min_id: pagination_since_id) unless @requests.empty?
end
def pagination_max_id
@requests.last.id
end
def pagination_since_id
@requests.first.id
end
def pagination_params(core_params)
params.slice(:dismissed).permit(:dismissed).merge(core_params)
end
end

View file

@ -58,7 +58,8 @@ class Api::V1::NotificationsController < Api::BaseController
current_account.notifications.without_suspended.browserable( current_account.notifications.without_suspended.browserable(
types: Array(browserable_params[:types]), types: Array(browserable_params[:types]),
exclude_types: Array(browserable_params[:exclude_types]), exclude_types: Array(browserable_params[:exclude_types]),
from_account_id: browserable_params[:account_id] from_account_id: browserable_params[:account_id],
include_filtered: truthy_param?(:include_filtered)
) )
end end
@ -87,10 +88,10 @@ class Api::V1::NotificationsController < Api::BaseController
end end
def browserable_params def browserable_params
params.permit(:account_id, types: [], exclude_types: []) params.permit(:account_id, :include_filtered, types: [], exclude_types: [])
end end
def pagination_params(core_params) def pagination_params(core_params)
params.slice(:limit, :account_id, :types, :exclude_types).permit(:limit, :account_id, types: [], exclude_types: []).merge(core_params) params.slice(:limit, :account_id, :types, :exclude_types, :include_filtered).permit(:limit, :account_id, :include_filtered, types: [], exclude_types: []).merge(core_params)
end end
end end

View file

@ -198,6 +198,7 @@ module LanguagesHelper
ldn: ['Láadan', 'Láadan'].freeze, ldn: ['Láadan', 'Láadan'].freeze,
lfn: ['Lingua Franca Nova', 'lingua franca nova'].freeze, lfn: ['Lingua Franca Nova', 'lingua franca nova'].freeze,
moh: ['Mohawk', 'Kanienʼkéha'].freeze, moh: ['Mohawk', 'Kanienʼkéha'].freeze,
nds: ['Low German', 'Plattdüütsch'].freeze,
pdc: ['Pennsylvania Dutch', 'Pennsilfaani-Deitsch'].freeze, pdc: ['Pennsylvania Dutch', 'Pennsilfaani-Deitsch'].freeze,
sco: ['Scots', 'Scots'].freeze, sco: ['Scots', 'Scots'].freeze,
sma: ['Southern Sami', 'Åarjelsaemien Gïele'].freeze, sma: ['Southern Sami', 'Åarjelsaemien Gïele'].freeze,

View file

@ -788,11 +788,12 @@ export function addPollOption(title) {
}; };
} }
export function changePollOption(index, title) { export function changePollOption(index, title, maxOptions) {
return { return {
type: COMPOSE_POLL_OPTION_CHANGE, type: COMPOSE_POLL_OPTION_CHANGE,
index, index,
title, title,
maxOptions,
}; };
} }

View file

@ -44,6 +44,38 @@ export const NOTIFICATIONS_MARK_AS_READ = 'NOTIFICATIONS_MARK_AS_READ';
export const NOTIFICATIONS_SET_BROWSER_SUPPORT = 'NOTIFICATIONS_SET_BROWSER_SUPPORT'; export const NOTIFICATIONS_SET_BROWSER_SUPPORT = 'NOTIFICATIONS_SET_BROWSER_SUPPORT';
export const NOTIFICATIONS_SET_BROWSER_PERMISSION = 'NOTIFICATIONS_SET_BROWSER_PERMISSION'; export const NOTIFICATIONS_SET_BROWSER_PERMISSION = 'NOTIFICATIONS_SET_BROWSER_PERMISSION';
export const NOTIFICATION_POLICY_FETCH_REQUEST = 'NOTIFICATION_POLICY_FETCH_REQUEST';
export const NOTIFICATION_POLICY_FETCH_SUCCESS = 'NOTIFICATION_POLICY_FETCH_SUCCESS';
export const NOTIFICATION_POLICY_FETCH_FAIL = 'NOTIFICATION_POLICY_FETCH_FAIL';
export const NOTIFICATION_REQUESTS_FETCH_REQUEST = 'NOTIFICATION_REQUESTS_FETCH_REQUEST';
export const NOTIFICATION_REQUESTS_FETCH_SUCCESS = 'NOTIFICATION_REQUESTS_FETCH_SUCCESS';
export const NOTIFICATION_REQUESTS_FETCH_FAIL = 'NOTIFICATION_REQUESTS_FETCH_FAIL';
export const NOTIFICATION_REQUESTS_EXPAND_REQUEST = 'NOTIFICATION_REQUESTS_EXPAND_REQUEST';
export const NOTIFICATION_REQUESTS_EXPAND_SUCCESS = 'NOTIFICATION_REQUESTS_EXPAND_SUCCESS';
export const NOTIFICATION_REQUESTS_EXPAND_FAIL = 'NOTIFICATION_REQUESTS_EXPAND_FAIL';
export const NOTIFICATION_REQUEST_FETCH_REQUEST = 'NOTIFICATION_REQUEST_FETCH_REQUEST';
export const NOTIFICATION_REQUEST_FETCH_SUCCESS = 'NOTIFICATION_REQUEST_FETCH_SUCCESS';
export const NOTIFICATION_REQUEST_FETCH_FAIL = 'NOTIFICATION_REQUEST_FETCH_FAIL';
export const NOTIFICATION_REQUEST_ACCEPT_REQUEST = 'NOTIFICATION_REQUEST_ACCEPT_REQUEST';
export const NOTIFICATION_REQUEST_ACCEPT_SUCCESS = 'NOTIFICATION_REQUEST_ACCEPT_SUCCESS';
export const NOTIFICATION_REQUEST_ACCEPT_FAIL = 'NOTIFICATION_REQUEST_ACCEPT_FAIL';
export const NOTIFICATION_REQUEST_DISMISS_REQUEST = 'NOTIFICATION_REQUEST_DISMISS_REQUEST';
export const NOTIFICATION_REQUEST_DISMISS_SUCCESS = 'NOTIFICATION_REQUEST_DISMISS_SUCCESS';
export const NOTIFICATION_REQUEST_DISMISS_FAIL = 'NOTIFICATION_REQUEST_DISMISS_FAIL';
export const NOTIFICATIONS_FOR_REQUEST_FETCH_REQUEST = 'NOTIFICATIONS_FOR_REQUEST_FETCH_REQUEST';
export const NOTIFICATIONS_FOR_REQUEST_FETCH_SUCCESS = 'NOTIFICATIONS_FOR_REQUEST_FETCH_SUCCESS';
export const NOTIFICATIONS_FOR_REQUEST_FETCH_FAIL = 'NOTIFICATIONS_FOR_REQUEST_FETCH_FAIL';
export const NOTIFICATIONS_FOR_REQUEST_EXPAND_REQUEST = 'NOTIFICATIONS_FOR_REQUEST_EXPAND_REQUEST';
export const NOTIFICATIONS_FOR_REQUEST_EXPAND_SUCCESS = 'NOTIFICATIONS_FOR_REQUEST_EXPAND_SUCCESS';
export const NOTIFICATIONS_FOR_REQUEST_EXPAND_FAIL = 'NOTIFICATIONS_FOR_REQUEST_EXPAND_FAIL';
defineMessages({ defineMessages({
mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' }, mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' },
group: { id: 'notifications.group', defaultMessage: '{count} notifications' }, group: { id: 'notifications.group', defaultMessage: '{count} notifications' },
@ -313,3 +345,264 @@ export function setBrowserPermission (value) {
value, value,
}; };
} }
export const fetchNotificationPolicy = () => (dispatch, getState) => {
dispatch(fetchNotificationPolicyRequest());
api(getState).get('/api/v1/notifications/policy').then(({ data }) => {
dispatch(fetchNotificationPolicySuccess(data));
}).catch(err => {
dispatch(fetchNotificationPolicyFail(err));
});
};
export const fetchNotificationPolicyRequest = () => ({
type: NOTIFICATION_POLICY_FETCH_REQUEST,
});
export const fetchNotificationPolicySuccess = policy => ({
type: NOTIFICATION_POLICY_FETCH_SUCCESS,
policy,
});
export const fetchNotificationPolicyFail = error => ({
type: NOTIFICATION_POLICY_FETCH_FAIL,
error,
});
export const updateNotificationsPolicy = params => (dispatch, getState) => {
dispatch(fetchNotificationPolicyRequest());
api(getState).put('/api/v1/notifications/policy', params).then(({ data }) => {
dispatch(fetchNotificationPolicySuccess(data));
}).catch(err => {
dispatch(fetchNotificationPolicyFail(err));
});
};
export const fetchNotificationRequests = () => (dispatch, getState) => {
const params = {};
if (getState().getIn(['notificationRequests', 'isLoading'])) {
return;
}
if (getState().getIn(['notificationRequests', 'items'])?.size > 0) {
params.since_id = getState().getIn(['notificationRequests', 'items', 0, 'id']);
}
dispatch(fetchNotificationRequestsRequest());
api(getState).get('/api/v1/notifications/requests', { params }).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data.map(x => x.account)));
dispatch(fetchNotificationRequestsSuccess(response.data, next ? next.uri : null));
}).catch(err => {
dispatch(fetchNotificationRequestsFail(err));
});
};
export const fetchNotificationRequestsRequest = () => ({
type: NOTIFICATION_REQUESTS_FETCH_REQUEST,
});
export const fetchNotificationRequestsSuccess = (requests, next) => ({
type: NOTIFICATION_REQUESTS_FETCH_SUCCESS,
requests,
next,
});
export const fetchNotificationRequestsFail = error => ({
type: NOTIFICATION_REQUESTS_FETCH_FAIL,
error,
});
export const expandNotificationRequests = () => (dispatch, getState) => {
const url = getState().getIn(['notificationRequests', 'next']);
if (!url || getState().getIn(['notificationRequests', 'isLoading'])) {
return;
}
dispatch(expandNotificationRequestsRequest());
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data.map(x => x.account)));
dispatch(expandNotificationRequestsSuccess(response.data, next?.uri));
}).catch(err => {
dispatch(expandNotificationRequestsFail(err));
});
};
export const expandNotificationRequestsRequest = () => ({
type: NOTIFICATION_REQUESTS_EXPAND_REQUEST,
});
export const expandNotificationRequestsSuccess = (requests, next) => ({
type: NOTIFICATION_REQUESTS_EXPAND_SUCCESS,
requests,
next,
});
export const expandNotificationRequestsFail = error => ({
type: NOTIFICATION_REQUESTS_EXPAND_FAIL,
error,
});
export const fetchNotificationRequest = id => (dispatch, getState) => {
const current = getState().getIn(['notificationRequests', 'current']);
if (current.getIn(['item', 'id']) === id || current.get('isLoading')) {
return;
}
dispatch(fetchNotificationRequestRequest(id));
api(getState).get(`/api/v1/notifications/requests/${id}`).then(({ data }) => {
dispatch(fetchNotificationRequestSuccess(data));
}).catch(err => {
dispatch(fetchNotificationRequestFail(id, err));
});
};
export const fetchNotificationRequestRequest = id => ({
type: NOTIFICATION_REQUEST_FETCH_REQUEST,
id,
});
export const fetchNotificationRequestSuccess = request => ({
type: NOTIFICATION_REQUEST_FETCH_SUCCESS,
request,
});
export const fetchNotificationRequestFail = (id, error) => ({
type: NOTIFICATION_REQUEST_FETCH_FAIL,
id,
error,
});
export const acceptNotificationRequest = id => (dispatch, getState) => {
dispatch(acceptNotificationRequestRequest(id));
api(getState).post(`/api/v1/notifications/requests/${id}/accept`).then(() => {
dispatch(acceptNotificationRequestSuccess(id));
}).catch(err => {
dispatch(acceptNotificationRequestFail(id, err));
});
};
export const acceptNotificationRequestRequest = id => ({
type: NOTIFICATION_REQUEST_ACCEPT_REQUEST,
id,
});
export const acceptNotificationRequestSuccess = id => ({
type: NOTIFICATION_REQUEST_ACCEPT_SUCCESS,
id,
});
export const acceptNotificationRequestFail = (id, error) => ({
type: NOTIFICATION_REQUEST_ACCEPT_FAIL,
id,
error,
});
export const dismissNotificationRequest = id => (dispatch, getState) => {
dispatch(dismissNotificationRequestRequest(id));
api(getState).post(`/api/v1/notifications/requests/${id}/dismiss`).then(() =>{
dispatch(dismissNotificationRequestSuccess(id));
}).catch(err => {
dispatch(dismissNotificationRequestFail(id, err));
});
};
export const dismissNotificationRequestRequest = id => ({
type: NOTIFICATION_REQUEST_DISMISS_REQUEST,
id,
});
export const dismissNotificationRequestSuccess = id => ({
type: NOTIFICATION_REQUEST_DISMISS_SUCCESS,
id,
});
export const dismissNotificationRequestFail = (id, error) => ({
type: NOTIFICATION_REQUEST_DISMISS_FAIL,
id,
error,
});
export const fetchNotificationsForRequest = accountId => (dispatch, getState) => {
const current = getState().getIn(['notificationRequests', 'current']);
const params = { account_id: accountId };
if (current.getIn(['item', 'account']) === accountId) {
if (current.getIn(['notifications', 'isLoading'])) {
return;
}
if (current.getIn(['notifications', 'items'])?.size > 0) {
params.since_id = current.getIn(['notifications', 'items', 0, 'id']);
}
}
dispatch(fetchNotificationsForRequestRequest());
api(getState).get('/api/v1/notifications', { params }).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedStatuses(response.data.map(item => item.status).filter(status => !!status)));
dispatch(fetchNotificationsForRequestSuccess(response.data, next?.uri));
}).catch(err => {
dispatch(fetchNotificationsForRequestFail(err));
});
};
export const fetchNotificationsForRequestRequest = () => ({
type: NOTIFICATIONS_FOR_REQUEST_FETCH_REQUEST,
});
export const fetchNotificationsForRequestSuccess = (notifications, next) => ({
type: NOTIFICATIONS_FOR_REQUEST_FETCH_SUCCESS,
notifications,
next,
});
export const fetchNotificationsForRequestFail = (error) => ({
type: NOTIFICATIONS_FOR_REQUEST_FETCH_FAIL,
error,
});
export const expandNotificationsForRequest = () => (dispatch, getState) => {
const url = getState().getIn(['notificationRequests', 'current', 'notifications', 'next']);
if (!url || getState().getIn(['notificationRequests', 'current', 'notifications', 'isLoading'])) {
return;
}
dispatch(expandNotificationsForRequestRequest());
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedStatuses(response.data.map(item => item.status).filter(status => !!status)));
dispatch(expandNotificationsForRequestSuccess(response.data, next?.uri));
}).catch(err => {
dispatch(expandNotificationsForRequestFail(err));
});
};
export const expandNotificationsForRequestRequest = () => ({
type: NOTIFICATIONS_FOR_REQUEST_EXPAND_REQUEST,
});
export const expandNotificationsForRequestSuccess = (notifications, next) => ({
type: NOTIFICATIONS_FOR_REQUEST_EXPAND_SUCCESS,
notifications,
next,
});
export const expandNotificationsForRequestFail = (error) => ({
type: NOTIFICATIONS_FOR_REQUEST_EXPAND_FAIL,
error,
});

View file

@ -1,7 +1,7 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { PureComponent, useCallback } from 'react'; import { PureComponent, useCallback } from 'react';
import { FormattedMessage, injectIntl, defineMessages } from 'react-intl'; import { FormattedMessage, injectIntl, defineMessages, useIntl } from 'react-intl';
import classNames from 'classnames'; import classNames from 'classnames';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
@ -11,7 +11,7 @@ import ArrowBackIcon from '@/material-icons/400-24px/arrow_back.svg?react';
import ChevronLeftIcon from '@/material-icons/400-24px/chevron_left.svg?react'; import ChevronLeftIcon from '@/material-icons/400-24px/chevron_left.svg?react';
import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react'; import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react';
import CloseIcon from '@/material-icons/400-24px/close.svg?react'; import CloseIcon from '@/material-icons/400-24px/close.svg?react';
import TuneIcon from '@/material-icons/400-24px/tune.svg?react'; import SettingsIcon from '@/material-icons/400-24px/settings.svg?react';
import { Icon } from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import { ButtonInTabsBar, useColumnsContext } from 'mastodon/features/ui/util/columns_context'; import { ButtonInTabsBar, useColumnsContext } from 'mastodon/features/ui/util/columns_context';
import { WithRouterPropTypes } from 'mastodon/utils/react_router'; import { WithRouterPropTypes } from 'mastodon/utils/react_router';
@ -23,10 +23,12 @@ const messages = defineMessages({
hide: { id: 'column_header.hide_settings', defaultMessage: 'Hide settings' }, hide: { id: 'column_header.hide_settings', defaultMessage: 'Hide settings' },
moveLeft: { id: 'column_header.moveLeft_settings', defaultMessage: 'Move column to the left' }, moveLeft: { id: 'column_header.moveLeft_settings', defaultMessage: 'Move column to the left' },
moveRight: { id: 'column_header.moveRight_settings', defaultMessage: 'Move column to the right' }, moveRight: { id: 'column_header.moveRight_settings', defaultMessage: 'Move column to the right' },
back: { id: 'column_back_button.label', defaultMessage: 'Back' },
}); });
const BackButton = ({ pinned, show }) => { const BackButton = ({ pinned, show, onlyIcon }) => {
const history = useAppHistory(); const history = useAppHistory();
const intl = useIntl();
const { multiColumn } = useColumnsContext(); const { multiColumn } = useColumnsContext();
const handleBackClick = useCallback(() => { const handleBackClick = useCallback(() => {
@ -39,18 +41,20 @@ const BackButton = ({ pinned, show }) => {
const showButton = history && !pinned && ((multiColumn && history.location?.state?.fromMastodon) || show); const showButton = history && !pinned && ((multiColumn && history.location?.state?.fromMastodon) || show);
if(!showButton) return null; if (!showButton) return null;
return (<button onClick={handleBackClick} className='column-header__back-button'>
<Icon id='chevron-left' icon={ArrowBackIcon} className='column-back-button__icon' />
<FormattedMessage id='column_back_button.label' defaultMessage='Back' />
</button>);
return (
<button onClick={handleBackClick} className={classNames('column-header__back-button', { 'compact': onlyIcon })} aria-label={intl.formatMessage(messages.back)}>
<Icon id='chevron-left' icon={ArrowBackIcon} className='column-back-button__icon' />
{!onlyIcon && <FormattedMessage id='column_back_button.label' defaultMessage='Back' />}
</button>
);
}; };
BackButton.propTypes = { BackButton.propTypes = {
pinned: PropTypes.bool, pinned: PropTypes.bool,
show: PropTypes.bool, show: PropTypes.bool,
onlyIcon: PropTypes.bool,
}; };
class ColumnHeader extends PureComponent { class ColumnHeader extends PureComponent {
@ -145,27 +149,31 @@ class ColumnHeader extends PureComponent {
} }
if (multiColumn && pinned) { if (multiColumn && pinned) {
pinButton = <button key='pin-button' className='text-btn column-header__setting-btn' onClick={this.handlePin}><Icon id='times' icon={CloseIcon} /> <FormattedMessage id='column_header.unpin' defaultMessage='Unpin' /></button>; pinButton = <button className='text-btn column-header__setting-btn' onClick={this.handlePin}><Icon id='times' icon={CloseIcon} /> <FormattedMessage id='column_header.unpin' defaultMessage='Unpin' /></button>;
moveButtons = ( moveButtons = (
<div key='move-buttons' className='column-header__setting-arrows'> <div className='column-header__setting-arrows'>
<button title={formatMessage(messages.moveLeft)} aria-label={formatMessage(messages.moveLeft)} className='icon-button column-header__setting-btn' onClick={this.handleMoveLeft}><Icon id='chevron-left' icon={ChevronLeftIcon} /></button> <button title={formatMessage(messages.moveLeft)} aria-label={formatMessage(messages.moveLeft)} className='icon-button column-header__setting-btn' onClick={this.handleMoveLeft}><Icon id='chevron-left' icon={ChevronLeftIcon} /></button>
<button title={formatMessage(messages.moveRight)} aria-label={formatMessage(messages.moveRight)} className='icon-button column-header__setting-btn' onClick={this.handleMoveRight}><Icon id='chevron-right' icon={ChevronRightIcon} /></button> <button title={formatMessage(messages.moveRight)} aria-label={formatMessage(messages.moveRight)} className='icon-button column-header__setting-btn' onClick={this.handleMoveRight}><Icon id='chevron-right' icon={ChevronRightIcon} /></button>
</div> </div>
); );
} else if (multiColumn && this.props.onPin) { } else if (multiColumn && this.props.onPin) {
pinButton = <button key='pin-button' className='text-btn column-header__setting-btn' onClick={this.handlePin}><Icon id='plus' icon={AddIcon} /> <FormattedMessage id='column_header.pin' defaultMessage='Pin' /></button>; pinButton = <button className='text-btn column-header__setting-btn' onClick={this.handlePin}><Icon id='plus' icon={AddIcon} /> <FormattedMessage id='column_header.pin' defaultMessage='Pin' /></button>;
} }
backButton = <BackButton pinned={pinned} show={showBackButton} />; backButton = <BackButton pinned={pinned} show={showBackButton} onlyIcon={!!title} />;
const collapsedContent = [ const collapsedContent = [
extraContent, extraContent,
]; ];
if (multiColumn) { if (multiColumn) {
collapsedContent.push(pinButton); collapsedContent.push(
collapsedContent.push(moveButtons); <div key='buttons' className='column-header__advanced-buttons'>
{pinButton}
{moveButtons}
</div>
);
} }
if (this.context.identity.signedIn && (children || (multiColumn && this.props.onPin))) { if (this.context.identity.signedIn && (children || (multiColumn && this.props.onPin))) {
@ -177,7 +185,7 @@ class ColumnHeader extends PureComponent {
onClick={this.handleToggleClick} onClick={this.handleToggleClick}
> >
<i className='icon-with-badge'> <i className='icon-with-badge'>
<Icon id='sliders' icon={TuneIcon} /> <Icon id='sliders' icon={SettingsIcon} />
{collapseIssues && <i className='icon-with-badge__issue-badge' />} {collapseIssues && <i className='icon-with-badge__issue-badge' />}
</i> </i>
</button> </button>
@ -190,16 +198,19 @@ class ColumnHeader extends PureComponent {
<div className={wrapperClassName}> <div className={wrapperClassName}>
<h1 className={buttonClassName}> <h1 className={buttonClassName}>
{hasTitle && ( {hasTitle && (
<button onClick={this.handleTitleClick}> <>
<Icon id={icon} icon={iconComponent} className='column-header__icon' /> {backButton}
{title}
</button> <button onClick={this.handleTitleClick} className='column-header__title'>
{!showBackButton && <Icon id={icon} icon={iconComponent} className='column-header__icon' />}
{title}
</button>
</>
)} )}
{!hasTitle && backButton} {!hasTitle && backButton}
<div className='column-header__buttons'> <div className='column-header__buttons'>
{hasTitle && backButton}
{extraButton} {extraButton}
{collapseButton} {collapseButton}
</div> </div>

View file

@ -9,7 +9,6 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import { supportsPassiveEvents } from 'detect-passive-events'; import { supportsPassiveEvents } from 'detect-passive-events';
import Overlay from 'react-overlays/Overlay'; import Overlay from 'react-overlays/Overlay';
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
import { CircularProgress } from 'mastodon/components/circular_progress'; import { CircularProgress } from 'mastodon/components/circular_progress';
import { WithRouterPropTypes } from 'mastodon/utils/react_router'; import { WithRouterPropTypes } from 'mastodon/utils/react_router';
@ -298,7 +297,7 @@ class Dropdown extends PureComponent {
}) : ( }) : (
<IconButton <IconButton
icon={!open ? icon : 'close'} icon={!open ? icon : 'close'}
iconComponent={!open ? iconComponent : CloseIcon} iconComponent={iconComponent}
title={title} title={title}
active={open} active={open}
disabled={disabled} disabled={disabled}

View file

@ -170,7 +170,8 @@ class About extends PureComponent {
<ol className='rules-list'> <ol className='rules-list'>
{server.get('rules').map(rule => ( {server.get('rules').map(rule => (
<li key={rule.get('id')}> <li key={rule.get('id')}>
<span className='rules-list__text'>{rule.get('text')}</span> <div className='rules-list__text'>{rule.get('text')}</div>
{rule.get('hint').length > 0 && (<div className='rules-list__hint'>{rule.get('hint')}</div>)}
</li> </li>
))} ))}
</ol> </ol>

View file

@ -22,6 +22,7 @@ import { CopyIconButton } from 'mastodon/components/copy_icon_button';
import { FollowersCounter, FollowingCounter, StatusesCounter } from 'mastodon/components/counters'; import { FollowersCounter, FollowingCounter, StatusesCounter } from 'mastodon/components/counters';
import { Icon } from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import { IconButton } from 'mastodon/components/icon_button'; import { IconButton } from 'mastodon/components/icon_button';
import { LoadingIndicator } from 'mastodon/components/loading_indicator';
import { ShortNumber } from 'mastodon/components/short_number'; import { ShortNumber } from 'mastodon/components/short_number';
import DropdownMenuContainer from 'mastodon/containers/dropdown_menu_container'; import DropdownMenuContainer from 'mastodon/containers/dropdown_menu_container';
import { autoPlayGif, me, domain } from 'mastodon/initial_state'; import { autoPlayGif, me, domain } from 'mastodon/initial_state';
@ -289,7 +290,7 @@ class Header extends ImmutablePureComponent {
if (me !== account.get('id')) { if (me !== account.get('id')) {
if (signedIn && !account.get('relationship')) { // Wait until the relationship is loaded if (signedIn && !account.get('relationship')) { // Wait until the relationship is loaded
actionBtn = ''; actionBtn = <Button disabled><LoadingIndicator /></Button>;
} else if (account.getIn(['relationship', 'requested'])) { } else if (account.getIn(['relationship', 'requested'])) {
actionBtn = <Button text={intl.formatMessage(messages.cancel_follow_request)} title={intl.formatMessage(messages.requested)} onClick={this.props.onFollow} />; actionBtn = <Button text={intl.formatMessage(messages.cancel_follow_request)} title={intl.formatMessage(messages.requested)} onClick={this.props.onFollow} />;
} else if (!account.getIn(['relationship', 'blocking'])) { } else if (!account.getIn(['relationship', 'blocking'])) {
@ -426,15 +427,10 @@ class Header extends ImmutablePureComponent {
</a> </a>
<div className='account__header__tabs__buttons'> <div className='account__header__tabs__buttons'>
{!hidden && ( {!hidden && bellBtn}
<> {!hidden && shareBtn}
{actionBtn}
{bellBtn}
{shareBtn}
</>
)}
<DropdownMenuContainer disabled={menu.length === 0} items={menu} icon='ellipsis-v' iconComponent={MoreHorizIcon} size={24} direction='right' /> <DropdownMenuContainer disabled={menu.length === 0} items={menu} icon='ellipsis-v' iconComponent={MoreHorizIcon} size={24} direction='right' />
{!hidden && actionBtn}
</div> </div>
</div> </div>

View file

@ -20,7 +20,7 @@ class ColumnSettings extends PureComponent {
const { settings, onChange } = this.props; const { settings, onChange } = this.props;
return ( return (
<div> <div className='column-settings'>
<div className='column-settings__row'> <div className='column-settings__row'>
<SettingToggle settings={settings} settingPath={['other', 'onlyMedia']} onChange={onChange} label={<FormattedMessage id='community.column_settings.media_only' defaultMessage='Media only' />} /> <SettingToggle settings={settings} settingPath={['other', 'onlyMedia']} onChange={onChange} label={<FormattedMessage id='community.column_settings.media_only' defaultMessage='Media only' />} />
</div> </div>

View file

@ -58,10 +58,11 @@ const Option = ({ multipleChoice, index, title, autoFocus }) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const suggestions = useSelector(state => state.getIn(['compose', 'suggestions'])); const suggestions = useSelector(state => state.getIn(['compose', 'suggestions']));
const lang = useSelector(state => state.getIn(['compose', 'language'])); const lang = useSelector(state => state.getIn(['compose', 'language']));
const maxOptions = useSelector(state => state.getIn(['server', 'server', 'configuration', 'polls', 'max_options']));
const handleChange = useCallback(({ target: { value } }) => { const handleChange = useCallback(({ target: { value } }) => {
dispatch(changePollOption(index, value)); dispatch(changePollOption(index, value, maxOptions));
}, [dispatch, index]); }, [dispatch, index, maxOptions]);
const handleSuggestionsFetchRequested = useCallback(token => { const handleSuggestionsFetchRequested = useCallback(token => {
dispatch(fetchComposeSuggestions(token)); dispatch(fetchComposeSuggestions(token));

View file

@ -42,15 +42,17 @@ const ColumnSettings = () => {
); );
return ( return (
<div> <div className='column-settings'>
<div className='column-settings__row'> <section>
<SettingToggle <div className='column-settings__row'>
settings={settings} <SettingToggle
settingPath={['onlyMedia']} settings={settings}
onChange={onChange} settingPath={['onlyMedia']}
label={<FormattedMessage id='community.column_settings.media_only' defaultMessage='Media only' />} onChange={onChange}
/> label={<FormattedMessage id='community.column_settings.media_only' defaultMessage='Media only' />}
</div> />
</div>
</section>
</div> </div>
); );
}; };

View file

@ -107,28 +107,28 @@ class ColumnSettings extends PureComponent {
const { settings, onChange } = this.props; const { settings, onChange } = this.props;
return ( return (
<div> <div className='column-settings'>
<div className='column-settings__row'> <section>
<div className='setting-toggle'> <div className='column-settings__row'>
<Toggle id='hashtag.column_settings.tag_toggle' onChange={this.onToggle} checked={this.state.open} /> <SettingToggle settings={settings} settingPath={['local']} onChange={onChange} label={<FormattedMessage id='community.column_settings.local_only' defaultMessage='Local only' />} />
<span className='setting-toggle__label'> <div className='setting-toggle'>
<FormattedMessage id='hashtag.column_settings.tag_toggle' defaultMessage='Include additional tags in this column' /> <Toggle id='hashtag.column_settings.tag_toggle' onChange={this.onToggle} checked={this.state.open} />
</span>
<span className='setting-toggle__label'>
<FormattedMessage id='hashtag.column_settings.tag_toggle' defaultMessage='Include additional tags in this column' />
</span>
</div>
</div> </div>
</div>
{this.state.open && ( {this.state.open && (
<div className='column-settings__hashtags'> <div className='column-settings__hashtags'>
{this.modeSelect('any')} {this.modeSelect('any')}
{this.modeSelect('all')} {this.modeSelect('all')}
{this.modeSelect('none')} {this.modeSelect('none')}
</div> </div>
)} )}
</section>
<div className='column-settings__row'>
<SettingToggle settings={settings} settingPath={['local']} onChange={onChange} label={<FormattedMessage id='community.column_settings.local_only' defaultMessage='Local only' />} />
</div>
</div> </div>
); );
} }

View file

@ -24,43 +24,36 @@ export const ColumnSettings: React.FC = () => {
); );
return ( return (
<div> <div className='column-settings'>
<span className='column-settings__section'> <section>
<FormattedMessage <div className='column-settings__row'>
id='home.column_settings.basic' <SettingToggle
defaultMessage='Basic' prefix='home_timeline'
/> settings={settings}
</span> settingPath={['shows', 'reblog']}
onChange={onChange}
label={
<FormattedMessage
id='home.column_settings.show_reblogs'
defaultMessage='Show boosts'
/>
}
/>
<div className='column-settings__row'> <SettingToggle
<SettingToggle prefix='home_timeline'
prefix='home_timeline' settings={settings}
settings={settings} settingPath={['shows', 'reply']}
settingPath={['shows', 'reblog']} onChange={onChange}
onChange={onChange} label={
label={ <FormattedMessage
<FormattedMessage id='home.column_settings.show_replies'
id='home.column_settings.show_reblogs' defaultMessage='Show replies'
defaultMessage='Show boosts' />
/> }
} />
/> </div>
</div> </section>
<div className='column-settings__row'>
<SettingToggle
prefix='home_timeline'
settings={settings}
settingPath={['shows', 'reply']}
onChange={onChange}
label={
<FormattedMessage
id='home.column_settings.show_replies'
defaultMessage='Show replies'
/>
}
/>
</div>
</div> </div>
); );
}; };

View file

@ -193,35 +193,38 @@ class ListTimeline extends PureComponent {
pinned={pinned} pinned={pinned}
multiColumn={multiColumn} multiColumn={multiColumn}
> >
<div className='column-settings__row column-header__links'> <div className='column-settings'>
<button type='button' className='text-btn column-header__setting-btn' tabIndex={0} onClick={this.handleEditClick}> <section className='column-header__links'>
<Icon id='pencil' icon={EditIcon} /> <FormattedMessage id='lists.edit' defaultMessage='Edit list' /> <button type='button' className='text-btn column-header__setting-btn' tabIndex={0} onClick={this.handleEditClick}>
</button> <Icon id='pencil' icon={EditIcon} /> <FormattedMessage id='lists.edit' defaultMessage='Edit list' />
</button>
<button type='button' className='text-btn column-header__setting-btn' tabIndex={0} onClick={this.handleDeleteClick}> <button type='button' className='text-btn column-header__setting-btn' tabIndex={0} onClick={this.handleDeleteClick}>
<Icon id='trash' icon={DeleteIcon} /> <FormattedMessage id='lists.delete' defaultMessage='Delete list' /> <Icon id='trash' icon={DeleteIcon} /> <FormattedMessage id='lists.delete' defaultMessage='Delete list' />
</button> </button>
</div> </section>
<div className='setting-toggle'> <section>
<Toggle id={`list-${id}-exclusive`} checked={isExclusive} onChange={this.onExclusiveToggle} /> <div className='setting-toggle'>
<label htmlFor={`list-${id}-exclusive`} className='setting-toggle__label'> <Toggle id={`list-${id}-exclusive`} checked={isExclusive} onChange={this.onExclusiveToggle} />
<FormattedMessage id='lists.exclusive' defaultMessage='Hide these posts from home' /> <label htmlFor={`list-${id}-exclusive`} className='setting-toggle__label'>
</label> <FormattedMessage id='lists.exclusive' defaultMessage='Hide these posts from home' />
</div> </label>
{ replies_policy !== undefined && (
<div role='group' aria-labelledby={`list-${id}-replies-policy`}>
<span id={`list-${id}-replies-policy`} className='column-settings__section'>
<FormattedMessage id='lists.replies_policy.title' defaultMessage='Show replies to:' />
</span>
<div className='column-settings__row'>
{ ['none', 'list', 'followed'].map(policy => (
<RadioButton name='order' key={policy} value={policy} label={intl.formatMessage(messages[policy])} checked={replies_policy === policy} onChange={this.handleRepliesPolicyChange} />
))}
</div> </div>
</div> </section>
)}
{replies_policy !== undefined && (
<section aria-labelledby={`list-${id}-replies-policy`}>
<h3 id={`list-${id}-replies-policy`}><FormattedMessage id='lists.replies_policy.title' defaultMessage='Show replies to:' /></h3>
<div className='column-settings__row'>
{ ['none', 'list', 'followed'].map(policy => (
<RadioButton name='order' key={policy} value={policy} label={intl.formatMessage(messages[policy])} checked={replies_policy === policy} onChange={this.handleRepliesPolicyChange} />
))}
</div>
</section>
)}
</div>
</ColumnHeader> </ColumnHeader>
<StatusListContainer <StatusListContainer

View file

@ -0,0 +1,31 @@
import PropTypes from 'prop-types';
import { useCallback } from 'react';
import Toggle from 'react-toggle';
export const CheckboxWithLabel = ({ checked, disabled, children, onChange }) => {
const handleChange = useCallback(({ target }) => {
onChange(target.checked);
}, [onChange]);
return (
<label className='app-form__toggle'>
<div className='app-form__toggle__label'>
{children}
</div>
<div className='app-form__toggle__toggle'>
<div>
<Toggle checked={checked} onChange={handleChange} disabled={disabled} />
</div>
</div>
</label>
);
};
CheckboxWithLabel.propTypes = {
checked: PropTypes.bool,
disabled: PropTypes.bool,
children: PropTypes.children,
onChange: PropTypes.func,
};

View file

@ -7,6 +7,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_REPORTS } from 'mastodon/permissions'; import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_REPORTS } from 'mastodon/permissions';
import { CheckboxWithLabel } from './checkbox_with_label';
import ClearColumnButton from './clear_column_button'; import ClearColumnButton from './clear_column_button';
import GrantPermissionButton from './grant_permission_button'; import GrantPermissionButton from './grant_permission_button';
import SettingToggle from './setting_toggle'; import SettingToggle from './setting_toggle';
@ -26,18 +27,34 @@ export default class ColumnSettings extends PureComponent {
alertsEnabled: PropTypes.bool, alertsEnabled: PropTypes.bool,
browserSupport: PropTypes.bool, browserSupport: PropTypes.bool,
browserPermission: PropTypes.string, browserPermission: PropTypes.string,
notificationPolicy: ImmutablePropTypes.map,
onChangePolicy: PropTypes.func.isRequired,
}; };
onPushChange = (path, checked) => { onPushChange = (path, checked) => {
this.props.onChange(['push', ...path], checked); this.props.onChange(['push', ...path], checked);
}; };
handleFilterNotFollowing = checked => {
this.props.onChangePolicy('filter_not_following', checked);
};
handleFilterNotFollowers = checked => {
this.props.onChangePolicy('filter_not_followers', checked);
};
handleFilterNewAccounts = checked => {
this.props.onChangePolicy('filter_new_accounts', checked);
};
handleFilterPrivateMentions = checked => {
this.props.onChangePolicy('filter_private_mentions', checked);
};
render () { render () {
const { settings, pushSettings, onChange, onClear, alertsEnabled, browserSupport, browserPermission, onRequestNotificationPermission } = this.props; const { settings, pushSettings, onChange, onClear, alertsEnabled, browserSupport, browserPermission, onRequestNotificationPermission, notificationPolicy } = this.props;
const unreadMarkersShowStr = <FormattedMessage id='notifications.column_settings.unread_notifications.highlight' defaultMessage='Highlight unread notifications' />; const unreadMarkersShowStr = <FormattedMessage id='notifications.column_settings.unread_notifications.highlight' defaultMessage='Highlight unread notifications' />;
const filterBarShowStr = <FormattedMessage id='notifications.column_settings.filter_bar.show_bar' defaultMessage='Show filter bar' />;
const filterAdvancedStr = <FormattedMessage id='notifications.column_settings.filter_bar.advanced' defaultMessage='Display all categories' />;
const alertStr = <FormattedMessage id='notifications.column_settings.alert' defaultMessage='Desktop notifications' />; const alertStr = <FormattedMessage id='notifications.column_settings.alert' defaultMessage='Desktop notifications' />;
const showStr = <FormattedMessage id='notifications.column_settings.show' defaultMessage='Show in column' />; const showStr = <FormattedMessage id='notifications.column_settings.show' defaultMessage='Show in column' />;
const soundStr = <FormattedMessage id='notifications.column_settings.sound' defaultMessage='Play sound' />; const soundStr = <FormattedMessage id='notifications.column_settings.sound' defaultMessage='Play sound' />;
@ -46,48 +63,59 @@ export default class ColumnSettings extends PureComponent {
const pushStr = showPushSettings && <FormattedMessage id='notifications.column_settings.push' defaultMessage='Push notifications' />; const pushStr = showPushSettings && <FormattedMessage id='notifications.column_settings.push' defaultMessage='Push notifications' />;
return ( return (
<div> <div className='column-settings'>
{alertsEnabled && browserSupport && browserPermission === 'denied' && ( {alertsEnabled && browserSupport && browserPermission === 'denied' && (
<div className='column-settings__row column-settings__row--with-margin'> <span className='warning-hint'><FormattedMessage id='notifications.permission_denied' defaultMessage='Desktop notifications are unavailable due to previously denied browser permissions request' /></span>
<span className='warning-hint'><FormattedMessage id='notifications.permission_denied' defaultMessage='Desktop notifications are unavailable due to previously denied browser permissions request' /></span>
</div>
)} )}
{alertsEnabled && browserSupport && browserPermission === 'default' && ( {alertsEnabled && browserSupport && browserPermission === 'default' && (
<div className='column-settings__row column-settings__row--with-margin'> <span className='warning-hint'>
<span className='warning-hint'> <FormattedMessage id='notifications.permission_required' defaultMessage='Desktop notifications are unavailable because the required permission has not been granted.' /> <GrantPermissionButton onClick={onRequestNotificationPermission} />
<FormattedMessage id='notifications.permission_required' defaultMessage='Desktop notifications are unavailable because the required permission has not been granted.' /> <GrantPermissionButton onClick={onRequestNotificationPermission} /> </span>
</span>
</div>
)} )}
<div className='column-settings__row'> <section>
<ClearColumnButton onClick={onClear} /> <ClearColumnButton onClick={onClear} />
</div> </section>
<div role='group' aria-labelledby='notifications-unread-markers'> <section>
<span id='notifications-unread-markers' className='column-settings__section'> <h3><FormattedMessage id='notifications.policy.title' defaultMessage='Filter out notifications from…' /></h3>
<div className='column-settings__row'>
<CheckboxWithLabel checked={notificationPolicy.get('filter_not_following')} onChange={this.handleFilterNotFollowing}>
<strong><FormattedMessage id='notifications.policy.filter_not_following_title' defaultMessage="People you don't follow" /></strong>
<span className='hint'><FormattedMessage id='notifications.policy.filter_not_following_hint' defaultMessage='Until you manually approve them' /></span>
</CheckboxWithLabel>
<CheckboxWithLabel checked={notificationPolicy.get('filter_not_followers')} onChange={this.handleFilterNotFollowers}>
<strong><FormattedMessage id='notifications.policy.filter_not_followers_title' defaultMessage='People not following you' /></strong>
<span className='hint'><FormattedMessage id='notifications.policy.filter_not_followers_hint' defaultMessage='Including people who have been following you fewer than {days, plural, one {one day} other {# days}}' values={{ days: 3 }} /></span>
</CheckboxWithLabel>
<CheckboxWithLabel checked={notificationPolicy.get('filter_new_accounts')} onChange={this.handleFilterNewAccounts}>
<strong><FormattedMessage id='notifications.policy.filter_new_accounts_title' defaultMessage='New accounts' /></strong>
<span className='hint'><FormattedMessage id='notifications.policy.filter_new_accounts.hint' defaultMessage='Created within the past {days, plural, one {one day} other {# days}}' values={{ days: 30 }} /></span>
</CheckboxWithLabel>
<CheckboxWithLabel checked={notificationPolicy.get('filter_private_mentions')} onChange={this.handleFilterPrivateMentions}>
<strong><FormattedMessage id='notifications.policy.filter_private_mentions_title' defaultMessage='Unsolicited private mentions' /></strong>
<span className='hint'><FormattedMessage id='notifications.policy.filter_private_mentions_hint' defaultMessage="Filtered unless it's in reply to your own mention or if you follow the sender" /></span>
</CheckboxWithLabel>
</div>
</section>
<section role='group' aria-labelledby='notifications-unread-markers'>
<h3 id='notifications-unread-markers'>
<FormattedMessage id='notifications.column_settings.unread_notifications.category' defaultMessage='Unread notifications' /> <FormattedMessage id='notifications.column_settings.unread_notifications.category' defaultMessage='Unread notifications' />
</span> </h3>
<div className='column-settings__row'> <div className='column-settings__row'>
<SettingToggle id='unread-notification-markers' prefix='notifications' settings={settings} settingPath={['showUnread']} onChange={onChange} label={unreadMarkersShowStr} /> <SettingToggle id='unread-notification-markers' prefix='notifications' settings={settings} settingPath={['showUnread']} onChange={onChange} label={unreadMarkersShowStr} />
</div> </div>
</div> </section>
<div role='group' aria-labelledby='notifications-filter-bar'> <section role='group' aria-labelledby='notifications-follow'>
<span id='notifications-filter-bar' className='column-settings__section'> <h3 id='notifications-follow'><FormattedMessage id='notifications.column_settings.follow' defaultMessage='New followers:' /></h3>
<FormattedMessage id='notifications.column_settings.filter_bar.category' defaultMessage='Quick filter bar' />
</span>
<div className='column-settings__row'>
<SettingToggle id='show-filter-bar' prefix='notifications' settings={settings} settingPath={['quickFilter', 'show']} onChange={onChange} label={filterBarShowStr} />
<SettingToggle id='show-filter-bar' prefix='notifications' settings={settings} settingPath={['quickFilter', 'advanced']} onChange={onChange} label={filterAdvancedStr} />
</div>
</div>
<div role='group' aria-labelledby='notifications-follow'>
<span id='notifications-follow' className='column-settings__section'><FormattedMessage id='notifications.column_settings.follow' defaultMessage='New followers:' /></span>
<div className='column-settings__row'> <div className='column-settings__row'>
<SettingToggle disabled={browserPermission === 'denied'} prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'follow']} onChange={onChange} label={alertStr} /> <SettingToggle disabled={browserPermission === 'denied'} prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'follow']} onChange={onChange} label={alertStr} />
@ -95,10 +123,10 @@ export default class ColumnSettings extends PureComponent {
<SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'follow']} onChange={onChange} label={showStr} /> <SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'follow']} onChange={onChange} label={showStr} />
<SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'follow']} onChange={onChange} label={soundStr} /> <SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'follow']} onChange={onChange} label={soundStr} />
</div> </div>
</div> </section>
<div role='group' aria-labelledby='notifications-follow-request'> <section role='group' aria-labelledby='notifications-follow-request'>
<span id='notifications-follow-request' className='column-settings__section'><FormattedMessage id='notifications.column_settings.follow_request' defaultMessage='New follow requests:' /></span> <h3 id='notifications-follow-request'><FormattedMessage id='notifications.column_settings.follow_request' defaultMessage='New follow requests:' /></h3>
<div className='column-settings__row'> <div className='column-settings__row'>
<SettingToggle disabled={browserPermission === 'denied'} prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'follow_request']} onChange={onChange} label={alertStr} /> <SettingToggle disabled={browserPermission === 'denied'} prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'follow_request']} onChange={onChange} label={alertStr} />
@ -106,10 +134,10 @@ export default class ColumnSettings extends PureComponent {
<SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'follow_request']} onChange={onChange} label={showStr} /> <SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'follow_request']} onChange={onChange} label={showStr} />
<SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'follow_request']} onChange={onChange} label={soundStr} /> <SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'follow_request']} onChange={onChange} label={soundStr} />
</div> </div>
</div> </section>
<div role='group' aria-labelledby='notifications-favourite'> <section role='group' aria-labelledby='notifications-favourite'>
<span id='notifications-favourite' className='column-settings__section'><FormattedMessage id='notifications.column_settings.favourite' defaultMessage='Favorites:' /></span> <h3 id='notifications-favourite'><FormattedMessage id='notifications.column_settings.favourite' defaultMessage='Favorites:' /></h3>
<div className='column-settings__row'> <div className='column-settings__row'>
<SettingToggle disabled={browserPermission === 'denied'} prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'favourite']} onChange={onChange} label={alertStr} /> <SettingToggle disabled={browserPermission === 'denied'} prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'favourite']} onChange={onChange} label={alertStr} />
@ -117,10 +145,10 @@ export default class ColumnSettings extends PureComponent {
<SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'favourite']} onChange={onChange} label={showStr} /> <SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'favourite']} onChange={onChange} label={showStr} />
<SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'favourite']} onChange={onChange} label={soundStr} /> <SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'favourite']} onChange={onChange} label={soundStr} />
</div> </div>
</div> </section>
<div role='group' aria-labelledby='notifications-mention'> <section role='group' aria-labelledby='notifications-mention'>
<span id='notifications-mention' className='column-settings__section'><FormattedMessage id='notifications.column_settings.mention' defaultMessage='Mentions:' /></span> <h3 id='notifications-mention'><FormattedMessage id='notifications.column_settings.mention' defaultMessage='Mentions:' /></h3>
<div className='column-settings__row'> <div className='column-settings__row'>
<SettingToggle disabled={browserPermission === 'denied'} prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'mention']} onChange={onChange} label={alertStr} /> <SettingToggle disabled={browserPermission === 'denied'} prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'mention']} onChange={onChange} label={alertStr} />
@ -128,10 +156,10 @@ export default class ColumnSettings extends PureComponent {
<SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'mention']} onChange={onChange} label={showStr} /> <SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'mention']} onChange={onChange} label={showStr} />
<SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'mention']} onChange={onChange} label={soundStr} /> <SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'mention']} onChange={onChange} label={soundStr} />
</div> </div>
</div> </section>
<div role='group' aria-labelledby='notifications-reblog'> <section role='group' aria-labelledby='notifications-reblog'>
<span id='notifications-reblog' className='column-settings__section'><FormattedMessage id='notifications.column_settings.reblog' defaultMessage='Boosts:' /></span> <h3 id='notifications-reblog'><FormattedMessage id='notifications.column_settings.reblog' defaultMessage='Boosts:' /></h3>
<div className='column-settings__row'> <div className='column-settings__row'>
<SettingToggle disabled={browserPermission === 'denied'} prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'reblog']} onChange={onChange} label={alertStr} /> <SettingToggle disabled={browserPermission === 'denied'} prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'reblog']} onChange={onChange} label={alertStr} />
@ -139,10 +167,10 @@ export default class ColumnSettings extends PureComponent {
<SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'reblog']} onChange={onChange} label={showStr} /> <SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'reblog']} onChange={onChange} label={showStr} />
<SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'reblog']} onChange={onChange} label={soundStr} /> <SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'reblog']} onChange={onChange} label={soundStr} />
</div> </div>
</div> </section>
<div role='group' aria-labelledby='notifications-poll'> <section role='group' aria-labelledby='notifications-poll'>
<span id='notifications-poll' className='column-settings__section'><FormattedMessage id='notifications.column_settings.poll' defaultMessage='Poll results:' /></span> <h3 id='notifications-poll'><FormattedMessage id='notifications.column_settings.poll' defaultMessage='Poll results:' /></h3>
<div className='column-settings__row'> <div className='column-settings__row'>
<SettingToggle disabled={browserPermission === 'denied'} prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'poll']} onChange={onChange} label={alertStr} /> <SettingToggle disabled={browserPermission === 'denied'} prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'poll']} onChange={onChange} label={alertStr} />
@ -150,10 +178,10 @@ export default class ColumnSettings extends PureComponent {
<SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'poll']} onChange={onChange} label={showStr} /> <SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'poll']} onChange={onChange} label={showStr} />
<SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'poll']} onChange={onChange} label={soundStr} /> <SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'poll']} onChange={onChange} label={soundStr} />
</div> </div>
</div> </section>
<div role='group' aria-labelledby='notifications-status'> <section role='group' aria-labelledby='notifications-status'>
<span id='notifications-status' className='column-settings__section'><FormattedMessage id='notifications.column_settings.status' defaultMessage='New posts:' /></span> <h3 id='notifications-status'><FormattedMessage id='notifications.column_settings.status' defaultMessage='New posts:' /></h3>
<div className='column-settings__row'> <div className='column-settings__row'>
<SettingToggle disabled={browserPermission === 'denied'} prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'status']} onChange={onChange} label={alertStr} /> <SettingToggle disabled={browserPermission === 'denied'} prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'status']} onChange={onChange} label={alertStr} />
@ -161,10 +189,10 @@ export default class ColumnSettings extends PureComponent {
<SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'status']} onChange={onChange} label={showStr} /> <SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'status']} onChange={onChange} label={showStr} />
<SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'status']} onChange={onChange} label={soundStr} /> <SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'status']} onChange={onChange} label={soundStr} />
</div> </div>
</div> </section>
<div role='group' aria-labelledby='notifications-update'> <section role='group' aria-labelledby='notifications-update'>
<span id='notifications-update' className='column-settings__section'><FormattedMessage id='notifications.column_settings.update' defaultMessage='Edits:' /></span> <h3 id='notifications-update'><FormattedMessage id='notifications.column_settings.update' defaultMessage='Edits:' /></h3>
<div className='column-settings__row'> <div className='column-settings__row'>
<SettingToggle disabled={browserPermission === 'denied'} prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'update']} onChange={onChange} label={alertStr} /> <SettingToggle disabled={browserPermission === 'denied'} prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'update']} onChange={onChange} label={alertStr} />
@ -172,11 +200,11 @@ export default class ColumnSettings extends PureComponent {
<SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'update']} onChange={onChange} label={showStr} /> <SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'update']} onChange={onChange} label={showStr} />
<SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'update']} onChange={onChange} label={soundStr} /> <SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'update']} onChange={onChange} label={soundStr} />
</div> </div>
</div> </section>
{((this.context.identity.permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) && ( {((this.context.identity.permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) && (
<div role='group' aria-labelledby='notifications-admin-sign-up'> <section role='group' aria-labelledby='notifications-admin-sign-up'>
<span id='notifications-status' className='column-settings__section'><FormattedMessage id='notifications.column_settings.admin.sign_up' defaultMessage='New sign-ups:' /></span> <h3 id='notifications-status'><FormattedMessage id='notifications.column_settings.admin.sign_up' defaultMessage='New sign-ups:' /></h3>
<div className='column-settings__row'> <div className='column-settings__row'>
<SettingToggle disabled={browserPermission === 'denied'} prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'admin.sign_up']} onChange={onChange} label={alertStr} /> <SettingToggle disabled={browserPermission === 'denied'} prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'admin.sign_up']} onChange={onChange} label={alertStr} />
@ -184,12 +212,12 @@ export default class ColumnSettings extends PureComponent {
<SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'admin.sign_up']} onChange={onChange} label={showStr} /> <SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'admin.sign_up']} onChange={onChange} label={showStr} />
<SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'admin.sign_up']} onChange={onChange} label={soundStr} /> <SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'admin.sign_up']} onChange={onChange} label={soundStr} />
</div> </div>
</div> </section>
)} )}
{((this.context.identity.permissions & PERMISSION_MANAGE_REPORTS) === PERMISSION_MANAGE_REPORTS) && ( {((this.context.identity.permissions & PERMISSION_MANAGE_REPORTS) === PERMISSION_MANAGE_REPORTS) && (
<div role='group' aria-labelledby='notifications-admin-report'> <section role='group' aria-labelledby='notifications-admin-report'>
<span id='notifications-status' className='column-settings__section'><FormattedMessage id='notifications.column_settings.admin.report' defaultMessage='New reports:' /></span> <h3 id='notifications-status'><FormattedMessage id='notifications.column_settings.admin.report' defaultMessage='New reports:' /></h3>
<div className='column-settings__row'> <div className='column-settings__row'>
<SettingToggle disabled={browserPermission === 'denied'} prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'admin.report']} onChange={onChange} label={alertStr} /> <SettingToggle disabled={browserPermission === 'denied'} prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'admin.report']} onChange={onChange} label={alertStr} />
@ -197,7 +225,7 @@ export default class ColumnSettings extends PureComponent {
<SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'admin.report']} onChange={onChange} label={showStr} /> <SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'admin.report']} onChange={onChange} label={showStr} />
<SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'admin.report']} onChange={onChange} label={soundStr} /> <SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'admin.report']} onChange={onChange} label={soundStr} />
</div> </div>
</div> </section>
)} )}
</div> </div>
); );

View file

@ -0,0 +1,49 @@
import { useEffect } from 'react';
import { FormattedMessage } from 'react-intl';
import { Link } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import ArchiveIcon from '@/material-icons/400-24px/archive.svg?react';
import { fetchNotificationPolicy } from 'mastodon/actions/notifications';
import { Icon } from 'mastodon/components/icon';
import { toCappedNumber } from 'mastodon/utils/numbers';
export const FilteredNotificationsBanner = () => {
const dispatch = useDispatch();
const policy = useSelector(state => state.get('notificationPolicy'));
useEffect(() => {
dispatch(fetchNotificationPolicy());
const interval = setInterval(() => {
dispatch(fetchNotificationPolicy());
}, 120000);
return () => {
clearInterval(interval);
};
}, [dispatch]);
if (policy === null || policy.getIn(['summary', 'pending_notifications_count']) * 1 === 0) {
return null;
}
return (
<Link className='filtered-notifications-banner' to='/notifications/requests'>
<Icon icon={ArchiveIcon} />
<div className='filtered-notifications-banner__text'>
<strong><FormattedMessage id='filtered_notifications_banner.title' defaultMessage='Filtered notifications' /></strong>
<span><FormattedMessage id='filtered_notifications_banner.pending_requests' defaultMessage='Notifications from {count, plural, =0 {no} one {one person} other {# people}} you may know' values={{ count: policy.getIn(['summary', 'pending_requests_count']) }} /></span>
</div>
<div className='filtered-notifications-banner__badge'>
{toCappedNumber(policy.getIn(['summary', 'pending_notifications_count']))}
</div>
</Link>
);
};

View file

@ -0,0 +1,65 @@
import PropTypes from 'prop-types';
import { useCallback } from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { Link } from 'react-router-dom';
import { useSelector, useDispatch } from 'react-redux';
import DoneIcon from '@/material-icons/400-24px/done.svg?react';
import VolumeOffIcon from '@/material-icons/400-24px/volume_off.svg?react';
import { acceptNotificationRequest, dismissNotificationRequest } from 'mastodon/actions/notifications';
import { Avatar } from 'mastodon/components/avatar';
import { IconButton } from 'mastodon/components/icon_button';
import { makeGetAccount } from 'mastodon/selectors';
import { toCappedNumber } from 'mastodon/utils/numbers';
const getAccount = makeGetAccount();
const messages = defineMessages({
accept: { id: 'notification_requests.accept', defaultMessage: 'Accept' },
dismiss: { id: 'notification_requests.dismiss', defaultMessage: 'Dismiss' },
});
export const NotificationRequest = ({ id, accountId, notificationsCount }) => {
const dispatch = useDispatch();
const account = useSelector(state => getAccount(state, accountId));
const intl = useIntl();
const handleDismiss = useCallback(() => {
dispatch(dismissNotificationRequest(id));
}, [dispatch, id]);
const handleAccept = useCallback(() => {
dispatch(acceptNotificationRequest(id));
}, [dispatch, id]);
return (
<div className='notification-request'>
<Link to={`/notifications/requests/${id}`} className='notification-request__link'>
<Avatar account={account} size={36} />
<div className='notification-request__name'>
<div className='notification-request__name__display-name'>
<bdi><strong dangerouslySetInnerHTML={{ __html: account?.get('display_name_html') }} /></bdi>
<span className='filtered-notifications-banner__badge'>{toCappedNumber(notificationsCount)}</span>
</div>
<span>@{account?.get('acct')}</span>
</div>
</Link>
<div className='notification-request__actions'>
<IconButton iconComponent={VolumeOffIcon} onClick={handleDismiss} title={intl.formatMessage(messages.dismiss)} />
<IconButton iconComponent={DoneIcon} onClick={handleAccept} title={intl.formatMessage(messages.accept)} />
</div>
</div>
);
};
NotificationRequest.propTypes = {
id: PropTypes.string.isRequired,
accountId: PropTypes.string.isRequired,
notificationsCount: PropTypes.string.isRequired,
};

View file

@ -4,7 +4,7 @@ import { connect } from 'react-redux';
import { showAlert } from '../../../actions/alerts'; import { showAlert } from '../../../actions/alerts';
import { openModal } from '../../../actions/modal'; import { openModal } from '../../../actions/modal';
import { setFilter, clearNotifications, requestBrowserPermission } from '../../../actions/notifications'; import { setFilter, clearNotifications, requestBrowserPermission, updateNotificationsPolicy } from '../../../actions/notifications';
import { changeAlerts as changePushNotifications } from '../../../actions/push_notifications'; import { changeAlerts as changePushNotifications } from '../../../actions/push_notifications';
import { changeSetting } from '../../../actions/settings'; import { changeSetting } from '../../../actions/settings';
import ColumnSettings from '../components/column_settings'; import ColumnSettings from '../components/column_settings';
@ -21,6 +21,7 @@ const mapStateToProps = state => ({
alertsEnabled: state.getIn(['settings', 'notifications', 'alerts']).includes(true), alertsEnabled: state.getIn(['settings', 'notifications', 'alerts']).includes(true),
browserSupport: state.getIn(['notifications', 'browserSupport']), browserSupport: state.getIn(['notifications', 'browserSupport']),
browserPermission: state.getIn(['notifications', 'browserPermission']), browserPermission: state.getIn(['notifications', 'browserPermission']),
notificationPolicy: state.get('notificationPolicy'),
}); });
const mapDispatchToProps = (dispatch, { intl }) => ({ const mapDispatchToProps = (dispatch, { intl }) => ({
@ -73,6 +74,12 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
dispatch(requestBrowserPermission()); dispatch(requestBrowserPermission());
}, },
onChangePolicy (param, checked) {
dispatch(updateNotificationsPolicy({
[param]: checked,
}));
},
}); });
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ColumnSettings)); export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ColumnSettings));

View file

@ -5,7 +5,7 @@ import FilterBar from '../components/filter_bar';
const makeMapStateToProps = state => ({ const makeMapStateToProps = state => ({
selectedFilter: state.getIn(['settings', 'notifications', 'quickFilter', 'active']), selectedFilter: state.getIn(['settings', 'notifications', 'quickFilter', 'active']),
advancedMode: state.getIn(['settings', 'notifications', 'quickFilter', 'advanced']), advancedMode: false,
}); });
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({

View file

@ -33,6 +33,7 @@ import ColumnHeader from '../../components/column_header';
import { LoadGap } from '../../components/load_gap'; import { LoadGap } from '../../components/load_gap';
import ScrollableList from '../../components/scrollable_list'; import ScrollableList from '../../components/scrollable_list';
import { FilteredNotificationsBanner } from './components/filtered_notifications_banner';
import NotificationsPermissionBanner from './components/notifications_permission_banner'; import NotificationsPermissionBanner from './components/notifications_permission_banner';
import ColumnSettingsContainer from './containers/column_settings_container'; import ColumnSettingsContainer from './containers/column_settings_container';
import FilterBarContainer from './containers/filter_bar_container'; import FilterBarContainer from './containers/filter_bar_container';
@ -65,7 +66,6 @@ const getNotifications = createSelector([
}); });
const mapStateToProps = state => ({ const mapStateToProps = state => ({
showFilterBar: state.getIn(['settings', 'notifications', 'quickFilter', 'show']),
notifications: getNotifications(state), notifications: getNotifications(state),
isLoading: state.getIn(['notifications', 'isLoading'], 0) > 0, isLoading: state.getIn(['notifications', 'isLoading'], 0) > 0,
isUnread: state.getIn(['notifications', 'unread']) > 0 || state.getIn(['notifications', 'pendingItems']).size > 0, isUnread: state.getIn(['notifications', 'unread']) > 0 || state.getIn(['notifications', 'pendingItems']).size > 0,
@ -85,7 +85,6 @@ class Notifications extends PureComponent {
static propTypes = { static propTypes = {
columnId: PropTypes.string, columnId: PropTypes.string,
notifications: ImmutablePropTypes.list.isRequired, notifications: ImmutablePropTypes.list.isRequired,
showFilterBar: PropTypes.bool.isRequired,
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
isLoading: PropTypes.bool, isLoading: PropTypes.bool,
@ -188,14 +187,14 @@ class Notifications extends PureComponent {
}; };
render () { render () {
const { intl, notifications, isLoading, isUnread, columnId, multiColumn, hasMore, numPending, showFilterBar, lastReadId, canMarkAsRead, needsNotificationPermission } = this.props; const { intl, notifications, isLoading, isUnread, columnId, multiColumn, hasMore, numPending, lastReadId, canMarkAsRead, needsNotificationPermission } = this.props;
const pinned = !!columnId; const pinned = !!columnId;
const emptyMessage = <FormattedMessage id='empty_column.notifications' defaultMessage="You don't have any notifications yet. When other people interact with you, you will see it here." />; const emptyMessage = <FormattedMessage id='empty_column.notifications' defaultMessage="You don't have any notifications yet. When other people interact with you, you will see it here." />;
const { signedIn } = this.context.identity; const { signedIn } = this.context.identity;
let scrollableContent = null; let scrollableContent = null;
const filterBarContainer = (signedIn && showFilterBar) const filterBarContainer = signedIn
? (<FilterBarContainer />) ? (<FilterBarContainer />)
: null; : null;
@ -285,6 +284,9 @@ class Notifications extends PureComponent {
</ColumnHeader> </ColumnHeader>
{filterBarContainer} {filterBarContainer}
<FilteredNotificationsBanner />
{scrollContainer} {scrollContainer}
<Helmet> <Helmet>

View file

@ -0,0 +1,144 @@
import PropTypes from 'prop-types';
import { useRef, useCallback, useEffect } from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { Helmet } from 'react-helmet';
import { useSelector, useDispatch } from 'react-redux';
import ArchiveIcon from '@/material-icons/400-24px/archive.svg?react';
import DoneIcon from '@/material-icons/400-24px/done.svg?react';
import VolumeOffIcon from '@/material-icons/400-24px/volume_off.svg?react';
import { fetchNotificationRequest, fetchNotificationsForRequest, expandNotificationsForRequest, acceptNotificationRequest, dismissNotificationRequest } from 'mastodon/actions/notifications';
import Column from 'mastodon/components/column';
import ColumnHeader from 'mastodon/components/column_header';
import { IconButton } from 'mastodon/components/icon_button';
import ScrollableList from 'mastodon/components/scrollable_list';
import NotificationContainer from './containers/notification_container';
const messages = defineMessages({
title: { id: 'notification_requests.notifications_from', defaultMessage: 'Notifications from {name}' },
accept: { id: 'notification_requests.accept', defaultMessage: 'Accept' },
dismiss: { id: 'notification_requests.dismiss', defaultMessage: 'Dismiss' },
});
const selectChild = (ref, index, alignTop) => {
const container = ref.current.node;
const element = container.querySelector(`article:nth-of-type(${index + 1}) .focusable`);
if (element) {
if (alignTop && container.scrollTop > element.offsetTop) {
element.scrollIntoView(true);
} else if (!alignTop && container.scrollTop + container.clientHeight < element.offsetTop + element.offsetHeight) {
element.scrollIntoView(false);
}
element.focus();
}
};
export const NotificationRequest = ({ multiColumn, params: { id } }) => {
const columnRef = useRef();
const intl = useIntl();
const dispatch = useDispatch();
const notificationRequest = useSelector(state => state.getIn(['notificationRequests', 'current', 'item', 'id']) === id ? state.getIn(['notificationRequests', 'current', 'item']) : null);
const accountId = notificationRequest?.get('account');
const account = useSelector(state => state.getIn(['accounts', accountId]));
const notifications = useSelector(state => state.getIn(['notificationRequests', 'current', 'notifications', 'items']));
const isLoading = useSelector(state => state.getIn(['notificationRequests', 'current', 'notifications', 'isLoading']));
const hasMore = useSelector(state => !!state.getIn(['notificationRequests', 'current', 'notifications', 'next']));
const removed = useSelector(state => state.getIn(['notificationRequests', 'current', 'removed']));
const handleHeaderClick = useCallback(() => {
columnRef.current?.scrollTop();
}, [columnRef]);
const handleLoadMore = useCallback(() => {
dispatch(expandNotificationsForRequest());
}, [dispatch]);
const handleDismiss = useCallback(() => {
dispatch(dismissNotificationRequest(id));
}, [dispatch, id]);
const handleAccept = useCallback(() => {
dispatch(acceptNotificationRequest(id));
}, [dispatch, id]);
const handleMoveUp = useCallback(id => {
const elementIndex = notifications.findIndex(item => item !== null && item.get('id') === id) - 1;
selectChild(columnRef, elementIndex, true);
}, [columnRef, notifications]);
const handleMoveDown = useCallback(id => {
const elementIndex = notifications.findIndex(item => item !== null && item.get('id') === id) + 1;
selectChild(columnRef, elementIndex, false);
}, [columnRef, notifications]);
useEffect(() => {
dispatch(fetchNotificationRequest(id));
}, [dispatch, id]);
useEffect(() => {
if (accountId) {
dispatch(fetchNotificationsForRequest(accountId));
}
}, [dispatch, accountId]);
const columnTitle = intl.formatMessage(messages.title, { name: account?.get('display_name') });
return (
<Column bindToDocument={!multiColumn} ref={columnRef} label={columnTitle}>
<ColumnHeader
icon='archive'
iconComponent={ArchiveIcon}
title={columnTitle}
onClick={handleHeaderClick}
multiColumn={multiColumn}
showBackButton
extraButton={!removed && (
<>
<IconButton className='column-header__button' iconComponent={VolumeOffIcon} onClick={handleDismiss} title={intl.formatMessage(messages.dismiss)} />
<IconButton className='column-header__button' iconComponent={DoneIcon} onClick={handleAccept} title={intl.formatMessage(messages.accept)} />
</>
)}
/>
<ScrollableList
scrollKey={`notification_requests/${id}`}
trackScroll={!multiColumn}
bindToDocument={!multiColumn}
isLoading={isLoading}
showLoading={isLoading && notifications.size === 0}
hasMore={hasMore}
onLoadMore={handleLoadMore}
>
{notifications.map(item => (
item && <NotificationContainer
key={item.get('id')}
notification={item}
accountId={item.get('account')}
onMoveUp={handleMoveUp}
onMoveDown={handleMoveDown}
/>
))}
</ScrollableList>
<Helmet>
<title>{columnTitle}</title>
<meta name='robots' content='noindex' />
</Helmet>
</Column>
);
};
NotificationRequest.propTypes = {
multiColumn: PropTypes.bool,
params: PropTypes.shape({
id: PropTypes.string.isRequired,
}),
};
export default NotificationRequest;

View file

@ -0,0 +1,85 @@
import PropTypes from 'prop-types';
import { useRef, useCallback, useEffect } from 'react';
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
import { Helmet } from 'react-helmet';
import { useSelector, useDispatch } from 'react-redux';
import ArchiveIcon from '@/material-icons/400-24px/archive.svg?react';
import { fetchNotificationRequests, expandNotificationRequests } from 'mastodon/actions/notifications';
import Column from 'mastodon/components/column';
import ColumnHeader from 'mastodon/components/column_header';
import ScrollableList from 'mastodon/components/scrollable_list';
import { NotificationRequest } from './components/notification_request';
const messages = defineMessages({
title: { id: 'notification_requests.title', defaultMessage: 'Filtered notifications' },
});
export const NotificationRequests = ({ multiColumn }) => {
const columnRef = useRef();
const intl = useIntl();
const dispatch = useDispatch();
const isLoading = useSelector(state => state.getIn(['notificationRequests', 'isLoading']));
const notificationRequests = useSelector(state => state.getIn(['notificationRequests', 'items']));
const hasMore = useSelector(state => !!state.getIn(['notificationRequests', 'next']));
const handleHeaderClick = useCallback(() => {
columnRef.current?.scrollTop();
}, [columnRef]);
const handleLoadMore = useCallback(() => {
dispatch(expandNotificationRequests());
}, [dispatch]);
useEffect(() => {
dispatch(fetchNotificationRequests());
}, [dispatch]);
return (
<Column bindToDocument={!multiColumn} ref={columnRef} label={intl.formatMessage(messages.title)}>
<ColumnHeader
icon='archive'
iconComponent={ArchiveIcon}
title={intl.formatMessage(messages.title)}
onClick={handleHeaderClick}
multiColumn={multiColumn}
showBackButton
/>
<ScrollableList
scrollKey='notification_requests'
trackScroll={!multiColumn}
bindToDocument={!multiColumn}
isLoading={isLoading}
showLoading={isLoading && notificationRequests.size === 0}
hasMore={hasMore}
onLoadMore={handleLoadMore}
emptyMessage={<FormattedMessage id='empty_column.notification_requests' defaultMessage='All clear! There is nothing here. When you receive new notifications, they will appear here according to your settings.' />}
>
{notificationRequests.map(request => (
<NotificationRequest
key={request.get('id')}
id={request.get('id')}
accountId={request.get('account')}
notificationsCount={request.get('notifications_count')}
/>
))}
</ScrollableList>
<Helmet>
<title>{intl.formatMessage(messages.title)}</title>
<meta name='robots' content='noindex' />
</Helmet>
</Column>
);
};
NotificationRequests.propTypes = {
multiColumn: PropTypes.bool,
};
export default NotificationRequests;

View file

@ -20,11 +20,13 @@ class ColumnSettings extends PureComponent {
const { settings, onChange } = this.props; const { settings, onChange } = this.props;
return ( return (
<div> <div className='column-settings'>
<div className='column-settings__row'> <section>
<SettingToggle settings={settings} settingPath={['other', 'onlyMedia']} onChange={onChange} label={<FormattedMessage id='community.column_settings.media_only' defaultMessage='Media only' />} /> <div className='column-settings__row'>
<SettingToggle settings={settings} settingPath={['other', 'onlyRemote']} onChange={onChange} label={<FormattedMessage id='community.column_settings.remote_only' defaultMessage='Remote only' />} /> <SettingToggle settings={settings} settingPath={['other', 'onlyMedia']} onChange={onChange} label={<FormattedMessage id='community.column_settings.media_only' defaultMessage='Media only' />} />
</div> <SettingToggle settings={settings} settingPath={['other', 'onlyRemote']} onChange={onChange} label={<FormattedMessage id='community.column_settings.remote_only' defaultMessage='Remote only' />} />
</div>
</section>
</div> </div>
); );
} }

View file

@ -1,27 +1,30 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classNames from 'classnames'; import classNames from 'classnames';
import { NavLink } from 'react-router-dom'; import { useRouteMatch, NavLink } from 'react-router-dom';
import { Icon } from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
const ColumnLink = ({ icon, iconComponent, text, to, href, method, badge, transparent, ...other }) => { const ColumnLink = ({ icon, activeIcon, iconComponent, activeIconComponent, text, to, href, method, badge, transparent, ...other }) => {
const match = useRouteMatch(to);
const className = classNames('column-link', { 'column-link--transparent': transparent }); const className = classNames('column-link', { 'column-link--transparent': transparent });
const badgeElement = typeof badge !== 'undefined' ? <span className='column-link__badge'>{badge}</span> : null; const badgeElement = typeof badge !== 'undefined' ? <span className='column-link__badge'>{badge}</span> : null;
const iconElement = (typeof icon === 'string' || iconComponent) ? <Icon id={icon} icon={iconComponent} className='column-link__icon' /> : icon; const iconElement = (typeof icon === 'string' || iconComponent) ? <Icon id={icon} icon={iconComponent} className='column-link__icon' /> : icon;
const activeIconElement = activeIcon ?? (activeIconComponent ? <Icon id={icon} icon={activeIconComponent} className='column-link__icon' /> : iconElement);
const active = match?.isExact;
if (href) { if (href) {
return ( return (
<a href={href} className={className} data-method={method} title={text} {...other}> <a href={href} className={className} data-method={method} title={text} {...other}>
{iconElement} {active ? activeIconElement : iconElement}
<span>{text}</span> <span>{text}</span>
{badgeElement} {badgeElement}
</a> </a>
); );
} else { } else {
return ( return (
<NavLink to={to} className={className} title={text} {...other}> <NavLink to={to} className={className} title={text} exact {...other}>
{iconElement} {active ? activeIconElement : iconElement}
<span>{text}</span> <span>{text}</span>
{badgeElement} {badgeElement}
</NavLink> </NavLink>
@ -32,6 +35,8 @@ const ColumnLink = ({ icon, iconComponent, text, to, href, method, badge, transp
ColumnLink.propTypes = { ColumnLink.propTypes = {
icon: PropTypes.oneOfType([PropTypes.string, PropTypes.node]).isRequired, icon: PropTypes.oneOfType([PropTypes.string, PropTypes.node]).isRequired,
iconComponent: PropTypes.func, iconComponent: PropTypes.func,
activeIcon: PropTypes.node,
activeIconComponent: PropTypes.func,
text: PropTypes.string.isRequired, text: PropTypes.string.isRequired,
to: PropTypes.string, to: PropTypes.string,
href: PropTypes.string, href: PropTypes.string,

View file

@ -1,55 +0,0 @@
import PropTypes from 'prop-types';
import { Component } from 'react';
import { injectIntl, defineMessages } from 'react-intl';
import { List as ImmutableList } from 'immutable';
import { connect } from 'react-redux';
import PersonAddIcon from '@/material-icons/400-24px/person_add.svg?react';
import { fetchFollowRequests } from 'mastodon/actions/accounts';
import { IconWithBadge } from 'mastodon/components/icon_with_badge';
import ColumnLink from 'mastodon/features/ui/components/column_link';
const messages = defineMessages({
text: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' },
});
const mapStateToProps = state => ({
count: state.getIn(['user_lists', 'follow_requests', 'items'], ImmutableList()).size,
});
class FollowRequestsColumnLink extends Component {
static propTypes = {
dispatch: PropTypes.func.isRequired,
count: PropTypes.number.isRequired,
intl: PropTypes.object.isRequired,
};
componentDidMount () {
const { dispatch } = this.props;
dispatch(fetchFollowRequests());
}
render () {
const { count, intl } = this.props;
if (count === 0) {
return null;
}
return (
<ColumnLink
transparent
to='/follow_requests'
icon={<IconWithBadge className='column-link__icon' id='user-plus' icon={PersonAddIcon} count={count} />}
text={intl.formatMessage(messages.text)}
/>
);
}
}
export default injectIntl(connect(mapStateToProps)(FollowRequestsColumnLink));

View file

@ -1,10 +1,9 @@
import PropTypes from 'prop-types'; import { useEffect } from 'react';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import ImmutablePropTypes from 'react-immutable-proptypes'; import { useDispatch, useSelector } from 'react-redux';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { connect } from 'react-redux';
import ListAltActiveIcon from '@/material-icons/400-24px/list_alt-fill.svg?react';
import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react'; import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react';
import { fetchLists } from 'mastodon/actions/lists'; import { fetchLists } from 'mastodon/actions/lists';
@ -18,40 +17,25 @@ const getOrderedLists = createSelector([state => state.get('lists')], lists => {
return lists.toList().filter(item => !!item).sort((a, b) => a.get('title').localeCompare(b.get('title'))).take(4); return lists.toList().filter(item => !!item).sort((a, b) => a.get('title').localeCompare(b.get('title'))).take(4);
}); });
const mapStateToProps = state => ({ export const ListPanel = () => {
lists: getOrderedLists(state), const dispatch = useDispatch();
}); const lists = useSelector(state => getOrderedLists(state));
class ListPanel extends ImmutablePureComponent { useEffect(() => {
static propTypes = {
dispatch: PropTypes.func.isRequired,
lists: ImmutablePropTypes.list,
};
componentDidMount () {
const { dispatch } = this.props;
dispatch(fetchLists()); dispatch(fetchLists());
}, [dispatch]);
if (!lists || lists.isEmpty()) {
return null;
} }
render () { return (
const { lists } = this.props; <div className='list-panel'>
<hr />
if (!lists || lists.isEmpty()) { {lists.map(list => (
return null; <ColumnLink icon='list-ul' key={list.get('id')} iconComponent={ListAltIcon} activeIconComponent={ListAltActiveIcon} text={list.get('title')} to={`/lists/${list.get('id')}`} transparent />
} ))}
</div>
return ( );
<div className='list-panel'> };
<hr />
{lists.map(list => (
<ColumnLink icon='list-ul' iconComponent={ListAltIcon} key={list.get('id')} strict text={list.get('title')} to={`/lists/${list.get('id')}`} transparent />
))}
</div>
);
}
}
export default connect(mapStateToProps)(ListPanel);

View file

@ -1,20 +1,33 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Component } from 'react'; import { Component, useEffect } from 'react';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl, useIntl } from 'react-intl';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { useSelector, useDispatch } from 'react-redux';
import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react'; import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react';
import BookmarksIcon from '@/material-icons/400-24px/bookmarks-fill.svg?react'; import BookmarksActiveIcon from '@/material-icons/400-24px/bookmarks-fill.svg?react';
import BookmarksIcon from '@/material-icons/400-24px/bookmarks.svg?react';
import ExploreIcon from '@/material-icons/400-24px/explore.svg?react'; import ExploreIcon from '@/material-icons/400-24px/explore.svg?react';
import HomeIcon from '@/material-icons/400-24px/home-fill.svg?react'; import HomeActiveIcon from '@/material-icons/400-24px/home-fill.svg?react';
import HomeIcon from '@/material-icons/400-24px/home.svg?react';
import ListAltActiveIcon from '@/material-icons/400-24px/list_alt-fill.svg?react';
import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react'; import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react';
import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react'; import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react';
import NotificationsActiveIcon from '@/material-icons/400-24px/notifications-fill.svg?react';
import NotificationsIcon from '@/material-icons/400-24px/notifications.svg?react';
import PersonAddActiveIcon from '@/material-icons/400-24px/person_add-fill.svg?react';
import PersonAddIcon from '@/material-icons/400-24px/person_add.svg?react';
import PublicIcon from '@/material-icons/400-24px/public.svg?react'; import PublicIcon from '@/material-icons/400-24px/public.svg?react';
import SearchIcon from '@/material-icons/400-24px/search.svg?react'; import SearchIcon from '@/material-icons/400-24px/search.svg?react';
import SettingsIcon from '@/material-icons/400-24px/settings-fill.svg?react'; import SettingsIcon from '@/material-icons/400-24px/settings.svg?react';
import StarIcon from '@/material-icons/400-24px/star-fill.svg?react'; import StarActiveIcon from '@/material-icons/400-24px/star-fill.svg?react';
import StarIcon from '@/material-icons/400-24px/star.svg?react';
import { fetchFollowRequests } from 'mastodon/actions/accounts';
import { IconWithBadge } from 'mastodon/components/icon_with_badge';
import { WordmarkLogo } from 'mastodon/components/logo'; import { WordmarkLogo } from 'mastodon/components/logo';
import { NavigationPortal } from 'mastodon/components/navigation_portal'; import { NavigationPortal } from 'mastodon/components/navigation_portal';
import { timelinePreview, trendsEnabled } from 'mastodon/initial_state'; import { timelinePreview, trendsEnabled } from 'mastodon/initial_state';
@ -22,9 +35,7 @@ import { transientSingleColumn } from 'mastodon/is_mobile';
import ColumnLink from './column_link'; import ColumnLink from './column_link';
import DisabledAccountBanner from './disabled_account_banner'; import DisabledAccountBanner from './disabled_account_banner';
import FollowRequestsColumnLink from './follow_requests_column_link'; import { ListPanel } from './list_panel';
import ListPanel from './list_panel';
import NotificationsCounterIcon from './notifications_counter_icon';
import SignInBanner from './sign_in_banner'; import SignInBanner from './sign_in_banner';
const messages = defineMessages({ const messages = defineMessages({
@ -42,8 +53,48 @@ const messages = defineMessages({
search: { id: 'navigation_bar.search', defaultMessage: 'Search' }, search: { id: 'navigation_bar.search', defaultMessage: 'Search' },
advancedInterface: { id: 'navigation_bar.advanced_interface', defaultMessage: 'Open in advanced web interface' }, advancedInterface: { id: 'navigation_bar.advanced_interface', defaultMessage: 'Open in advanced web interface' },
openedInClassicInterface: { id: 'navigation_bar.opened_in_classic_interface', defaultMessage: 'Posts, accounts, and other specific pages are opened by default in the classic web interface.' }, openedInClassicInterface: { id: 'navigation_bar.opened_in_classic_interface', defaultMessage: 'Posts, accounts, and other specific pages are opened by default in the classic web interface.' },
followRequests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' },
}); });
const NotificationsLink = () => {
const count = useSelector(state => state.getIn(['notifications', 'unread']));
const intl = useIntl();
return (
<ColumnLink
transparent
to='/notifications'
icon={<IconWithBadge icon={NotificationsIcon} count={count} className='column-link__icon' />}
activeIcon={<IconWithBadge icon={NotificationsActiveIcon} count={count} className='column-link__icon' />}
text={intl.formatMessage(messages.notifications)}
/>
);
};
const FollowRequestsLink = () => {
const count = useSelector(state => state.getIn(['user_lists', 'follow_requests', 'items'])?.size ?? 0);
const intl = useIntl();
const dispatch = useDispatch();
useEffect(() => {
dispatch(fetchFollowRequests());
}, [dispatch]);
if (count === 0) {
return null;
}
return (
<ColumnLink
transparent
to='/follow_requests'
icon={<IconWithBadge icon={PersonAddIcon} count={count} className='column-link__icon' />}
activeIcon={<IconWithBadge icon={PersonAddActiveIcon} count={count} className='column-link__icon' />}
text={intl.formatMessage(messages.followRequests)}
/>
);
};
class NavigationPanel extends Component { class NavigationPanel extends Component {
static contextTypes = { static contextTypes = {
@ -87,9 +138,9 @@ class NavigationPanel extends Component {
{signedIn && ( {signedIn && (
<> <>
<ColumnLink transparent to='/home' icon='home' iconComponent={HomeIcon} text={intl.formatMessage(messages.home)} /> <ColumnLink transparent to='/home' icon='home' iconComponent={HomeIcon} activeIconComponent={HomeActiveIcon} text={intl.formatMessage(messages.home)} />
<ColumnLink transparent to='/notifications' icon={<NotificationsCounterIcon className='column-link__icon' />} text={intl.formatMessage(messages.notifications)} /> <NotificationsLink />
<FollowRequestsColumnLink /> <FollowRequestsLink />
</> </>
)} )}
@ -113,9 +164,9 @@ class NavigationPanel extends Component {
{signedIn && ( {signedIn && (
<> <>
<ColumnLink transparent to='/conversations' icon='at' iconComponent={AlternateEmailIcon} text={intl.formatMessage(messages.direct)} /> <ColumnLink transparent to='/conversations' icon='at' iconComponent={AlternateEmailIcon} text={intl.formatMessage(messages.direct)} />
<ColumnLink transparent to='/bookmarks' icon='bookmarks' iconComponent={BookmarksIcon} text={intl.formatMessage(messages.bookmarks)} /> <ColumnLink transparent to='/bookmarks' icon='bookmarks' iconComponent={BookmarksIcon} activeIconComponent={BookmarksActiveIcon} text={intl.formatMessage(messages.bookmarks)} />
<ColumnLink transparent to='/favourites' icon='star' iconComponent={StarIcon} text={intl.formatMessage(messages.favourites)} /> <ColumnLink transparent to='/favourites' icon='star' iconComponent={StarIcon} activeIconComponent={StarActiveIcon} text={intl.formatMessage(messages.favourites)} />
<ColumnLink transparent to='/lists' icon='list-ul' iconComponent={ListAltIcon} text={intl.formatMessage(messages.lists)} /> <ColumnLink transparent to='/lists' icon='list-ul' iconComponent={ListAltIcon} activeIconComponent={ListAltActiveIcon} text={intl.formatMessage(messages.lists)} />
<ListPanel /> <ListPanel />

View file

@ -1,13 +0,0 @@
import { connect } from 'react-redux';
import NotificationsIcon from '@/material-icons/400-24px/notifications-fill.svg?react';
import { IconWithBadge } from 'mastodon/components/icon_with_badge';
const mapStateToProps = state => ({
count: state.getIn(['notifications', 'unread']),
id: 'bell',
icon: NotificationsIcon,
});
export default connect(mapStateToProps)(IconWithBadge);

View file

@ -48,6 +48,8 @@ import {
DirectTimeline, DirectTimeline,
HashtagTimeline, HashtagTimeline,
Notifications, Notifications,
NotificationRequests,
NotificationRequest,
FollowRequests, FollowRequests,
FavouritedStatuses, FavouritedStatuses,
BookmarkedStatuses, BookmarkedStatuses,
@ -80,7 +82,6 @@ const mapStateToProps = state => ({
hasComposingText: state.getIn(['compose', 'text']).trim().length !== 0, hasComposingText: state.getIn(['compose', 'text']).trim().length !== 0,
hasMediaAttachments: state.getIn(['compose', 'media_attachments']).size > 0, hasMediaAttachments: state.getIn(['compose', 'media_attachments']).size > 0,
canUploadMore: !state.getIn(['compose', 'media_attachments']).some(x => ['audio', 'video'].includes(x.get('type'))) && state.getIn(['compose', 'media_attachments']).size < 4, canUploadMore: !state.getIn(['compose', 'media_attachments']).some(x => ['audio', 'video'].includes(x.get('type'))) && state.getIn(['compose', 'media_attachments']).size < 4,
dropdownMenuIsOpen: state.dropdownMenu.openId !== null,
firstLaunch: state.getIn(['settings', 'introductionVersion'], 0) < INTRODUCTION_VERSION, firstLaunch: state.getIn(['settings', 'introductionVersion'], 0) < INTRODUCTION_VERSION,
username: state.getIn(['accounts', me, 'username']), username: state.getIn(['accounts', me, 'username']),
}); });
@ -204,7 +205,9 @@ class SwitchingColumnsArea extends PureComponent {
<WrappedRoute path={['/conversations', '/timelines/direct']} component={DirectTimeline} content={children} /> <WrappedRoute path={['/conversations', '/timelines/direct']} component={DirectTimeline} content={children} />
<WrappedRoute path='/tags/:id' component={HashtagTimeline} content={children} /> <WrappedRoute path='/tags/:id' component={HashtagTimeline} content={children} />
<WrappedRoute path='/lists/:id' component={ListTimeline} content={children} /> <WrappedRoute path='/lists/:id' component={ListTimeline} content={children} />
<WrappedRoute path='/notifications' component={Notifications} content={children} /> <WrappedRoute path='/notifications' component={Notifications} content={children} exact />
<WrappedRoute path='/notifications/requests' component={NotificationRequests} content={children} exact />
<WrappedRoute path='/notifications/requests/:id' component={NotificationRequest} content={children} exact />
<WrappedRoute path='/favourites' component={FavouritedStatuses} content={children} /> <WrappedRoute path='/favourites' component={FavouritedStatuses} content={children} />
<WrappedRoute path='/bookmarks' component={BookmarkedStatuses} content={children} /> <WrappedRoute path='/bookmarks' component={BookmarkedStatuses} content={children} />
@ -262,7 +265,6 @@ class UI extends PureComponent {
hasMediaAttachments: PropTypes.bool, hasMediaAttachments: PropTypes.bool,
canUploadMore: PropTypes.bool, canUploadMore: PropTypes.bool,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
dropdownMenuIsOpen: PropTypes.bool,
layout: PropTypes.string.isRequired, layout: PropTypes.string.isRequired,
firstLaunch: PropTypes.bool, firstLaunch: PropTypes.bool,
username: PropTypes.string, username: PropTypes.string,
@ -555,7 +557,7 @@ class UI extends PureComponent {
render () { render () {
const { draggingOver } = this.state; const { draggingOver } = this.state;
const { children, isComposing, location, dropdownMenuIsOpen, layout } = this.props; const { children, isComposing, location, layout } = this.props;
const handlers = { const handlers = {
help: this.handleHotkeyToggleHelp, help: this.handleHotkeyToggleHelp,
@ -581,7 +583,7 @@ class UI extends PureComponent {
return ( return (
<HotKeys keyMap={keyMap} handlers={handlers} ref={this.setHotkeysRef} attach={window} focused> <HotKeys keyMap={keyMap} handlers={handlers} ref={this.setHotkeysRef} attach={window} focused>
<div className={classNames('ui', { 'is-composing': isComposing })} ref={this.setRef} style={{ pointerEvents: dropdownMenuIsOpen ? 'none' : null }}> <div className={classNames('ui', { 'is-composing': isComposing })} ref={this.setRef}>
<Header /> <Header />
<SwitchingColumnsArea location={location} singleColumn={layout === 'mobile' || layout === 'single-column'}> <SwitchingColumnsArea location={location} singleColumn={layout === 'mobile' || layout === 'single-column'}>

View file

@ -189,3 +189,11 @@ export function About () {
export function PrivacyPolicy () { export function PrivacyPolicy () {
return import(/*webpackChunkName: "features/privacy_policy" */'../../privacy_policy'); return import(/*webpackChunkName: "features/privacy_policy" */'../../privacy_policy');
} }
export function NotificationRequests () {
return import(/*webpackChunkName: "features/notifications/requests" */'../../notifications/requests');
}
export function NotificationRequest () {
return import(/*webpackChunkName: "features/notifications/request" */'../../notifications/request');
}

View file

@ -277,7 +277,13 @@
"follow_request.authorize": "ترخيص", "follow_request.authorize": "ترخيص",
"follow_request.reject": "رفض", "follow_request.reject": "رفض",
"follow_requests.unlocked_explanation": "حتى وإن كان حسابك غير مقفل، يعتقد فريق {domain} أنك قد ترغب في مراجعة طلبات المتابعة من هذه الحسابات يدوياً.", "follow_requests.unlocked_explanation": "حتى وإن كان حسابك غير مقفل، يعتقد فريق {domain} أنك قد ترغب في مراجعة طلبات المتابعة من هذه الحسابات يدوياً.",
"follow_suggestions.curated_suggestion": "اختيار الموظفين",
"follow_suggestions.dismiss": "لا تُظهرها مجدّدًا", "follow_suggestions.dismiss": "لا تُظهرها مجدّدًا",
"follow_suggestions.hints.featured": "تم اختيار هذا الملف الشخصي يدوياً من قبل فريق {domain}.",
"follow_suggestions.hints.friends_of_friends": "هذا الملف الشخصي مشهور بين الأشخاص الذين تتابعهم.",
"follow_suggestions.hints.most_followed": "هذا الملف الشخصي هو واحد من الأكثر متابعة على {domain}.",
"follow_suggestions.hints.most_interactions": "هذا الملف الشخصي قد حصل مؤخرا على الكثير من الاهتمام على {domain}.",
"follow_suggestions.hints.similar_to_recently_followed": "هذا الملف الشخصي مشابه للملفات الشخصية التي تابعتها مؤخرا.",
"follow_suggestions.personalized_suggestion": "توصية مخصصة", "follow_suggestions.personalized_suggestion": "توصية مخصصة",
"follow_suggestions.popular_suggestion": "توصية رائجة", "follow_suggestions.popular_suggestion": "توصية رائجة",
"follow_suggestions.view_all": "عرض الكل", "follow_suggestions.view_all": "عرض الكل",

View file

@ -480,7 +480,7 @@
"onboarding.action.back": "Върнете ме обратно", "onboarding.action.back": "Върнете ме обратно",
"onboarding.actions.back": "Върнете ме обратно", "onboarding.actions.back": "Върнете ме обратно",
"onboarding.actions.go_to_explore": "Виж тенденции", "onboarding.actions.go_to_explore": "Виж тенденции",
"onboarding.actions.go_to_home": "Към началния ви инфоканал", "onboarding.actions.go_to_home": "Към началния ми инфоканал",
"onboarding.compose.template": "Здравейте, #Mastodon!", "onboarding.compose.template": "Здравейте, #Mastodon!",
"onboarding.follows.empty": "За съжаление, в момента не могат да бъдат показани резултати. Може да опитате да търсите или да разгледате, за да намерите кого да последвате, или опитайте отново по-късно.", "onboarding.follows.empty": "За съжаление, в момента не могат да бъдат показани резултати. Може да опитате да търсите или да разгледате, за да намерите кого да последвате, или опитайте отново по-късно.",
"onboarding.follows.lead": "Може да бъдете куратор на началния си инфоканал. Последвайки повече хора, по-деен и по-интересен ще става. Тези профили може да са добра начална точка, от която винаги по-късно да спрете да следвате!", "onboarding.follows.lead": "Може да бъдете куратор на началния си инфоканал. Последвайки повече хора, по-деен и по-интересен ще става. Тези профили може да са добра начална точка, от която винаги по-късно да спрете да следвате!",
@ -504,7 +504,7 @@
"onboarding.start.skip": "Желаете ли да прескочите?", "onboarding.start.skip": "Желаете ли да прескочите?",
"onboarding.start.title": "Успяхте!", "onboarding.start.title": "Успяхте!",
"onboarding.steps.follow_people.body": "Може да бъдете куратор на инфоканала си. Хайде да го запълним с интересни хора.", "onboarding.steps.follow_people.body": "Може да бъдете куратор на инфоканала си. Хайде да го запълним с интересни хора.",
"onboarding.steps.follow_people.title": оследвайте {count, plural, one {един човек} other {# души}}", "onboarding.steps.follow_people.title": ерсонализиране на началния ви инфоканал",
"onboarding.steps.publish_status.body": "Поздравете целия свят.", "onboarding.steps.publish_status.body": "Поздравете целия свят.",
"onboarding.steps.publish_status.title": "Направете първата си публикация", "onboarding.steps.publish_status.title": "Направете първата си публикация",
"onboarding.steps.setup_profile.body": "Други са по-вероятно да взаимодействат с вас с попълнения профил.", "onboarding.steps.setup_profile.body": "Други са по-вероятно да взаимодействат с вас с попълнения профил.",

View file

@ -113,6 +113,7 @@
"column.directory": "Mont a-dreuz ar profiloù", "column.directory": "Mont a-dreuz ar profiloù",
"column.domain_blocks": "Domani berzet", "column.domain_blocks": "Domani berzet",
"column.favourites": "Muiañ-karet", "column.favourites": "Muiañ-karet",
"column.firehose": "Redoù war-eeun",
"column.follow_requests": "Rekedoù heuliañ", "column.follow_requests": "Rekedoù heuliañ",
"column.home": "Degemer", "column.home": "Degemer",
"column.lists": "Listennoù", "column.lists": "Listennoù",
@ -143,6 +144,8 @@
"compose_form.lock_disclaimer.lock": "prennet", "compose_form.lock_disclaimer.lock": "prennet",
"compose_form.placeholder": "Petra emaoc'h o soñjal e-barzh ?", "compose_form.placeholder": "Petra emaoc'h o soñjal e-barzh ?",
"compose_form.poll.duration": "Pad ar sontadeg", "compose_form.poll.duration": "Pad ar sontadeg",
"compose_form.poll.multiple": "Meur a choaz",
"compose_form.poll.option_placeholder": "Choaz {number}",
"compose_form.poll.single": "Dibabit unan", "compose_form.poll.single": "Dibabit unan",
"compose_form.poll.switch_to_multiple": "Kemmañ ar sontadeg evit aotren meur a zibab", "compose_form.poll.switch_to_multiple": "Kemmañ ar sontadeg evit aotren meur a zibab",
"compose_form.poll.switch_to_single": "Kemmañ ar sontadeg evit aotren un dibab hepken", "compose_form.poll.switch_to_single": "Kemmañ ar sontadeg evit aotren un dibab hepken",
@ -441,7 +444,7 @@
"onboarding.action.back": "Distreiñ", "onboarding.action.back": "Distreiñ",
"onboarding.actions.back": "Distreiñ", "onboarding.actions.back": "Distreiñ",
"onboarding.actions.go_to_explore": "See what's trending", "onboarding.actions.go_to_explore": "See what's trending",
"onboarding.actions.go_to_home": "Go to your home feed", "onboarding.actions.go_to_home": "Mont d'ho red degemer",
"onboarding.compose.template": "Salud #Mastodon!", "onboarding.compose.template": "Salud #Mastodon!",
"onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!", "onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!",
"onboarding.follows.title": "Popular on Mastodon", "onboarding.follows.title": "Popular on Mastodon",

View file

@ -151,7 +151,7 @@
"compose_form.poll.single": "Einfachauswahl", "compose_form.poll.single": "Einfachauswahl",
"compose_form.poll.switch_to_multiple": "Mehrfachauswahl erlauben", "compose_form.poll.switch_to_multiple": "Mehrfachauswahl erlauben",
"compose_form.poll.switch_to_single": "Nur Einfachauswahl erlauben", "compose_form.poll.switch_to_single": "Nur Einfachauswahl erlauben",
"compose_form.poll.type": "Stil", "compose_form.poll.type": "Art",
"compose_form.publish": "Veröffentlichen", "compose_form.publish": "Veröffentlichen",
"compose_form.publish_form": "Neuer Beitrag", "compose_form.publish_form": "Neuer Beitrag",
"compose_form.reply": "Antworten", "compose_form.reply": "Antworten",
@ -277,7 +277,7 @@
"follow_request.authorize": "Genehmigen", "follow_request.authorize": "Genehmigen",
"follow_request.reject": "Ablehnen", "follow_request.reject": "Ablehnen",
"follow_requests.unlocked_explanation": "Auch wenn dein Konto öffentlich bzw. nicht geschützt ist, haben die Moderator*innen von {domain} gedacht, dass du diesen Follower lieber manuell bestätigen solltest.", "follow_requests.unlocked_explanation": "Auch wenn dein Konto öffentlich bzw. nicht geschützt ist, haben die Moderator*innen von {domain} gedacht, dass du diesen Follower lieber manuell bestätigen solltest.",
"follow_suggestions.curated_suggestion": "Vom Server empfohlen", "follow_suggestions.curated_suggestion": "Vom Server-Team empfohlen",
"follow_suggestions.dismiss": "Nicht mehr anzeigen", "follow_suggestions.dismiss": "Nicht mehr anzeigen",
"follow_suggestions.hints.featured": "Dieses Profil wurde vom {domain}-Team ausgewählt.", "follow_suggestions.hints.featured": "Dieses Profil wurde vom {domain}-Team ausgewählt.",
"follow_suggestions.hints.friends_of_friends": "Dieses Profil ist bei deinen Followern beliebt.", "follow_suggestions.hints.friends_of_friends": "Dieses Profil ist bei deinen Followern beliebt.",

View file

@ -241,6 +241,7 @@
"empty_column.list": "There is nothing in this list yet. When members of this list publish new posts, they will appear here.", "empty_column.list": "There is nothing in this list yet. When members of this list publish new posts, they will appear here.",
"empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.", "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.",
"empty_column.mutes": "You haven't muted any users yet.", "empty_column.mutes": "You haven't muted any users yet.",
"empty_column.notification_requests": "All clear! There is nothing here. When you receive new notifications, they will appear here according to your settings.",
"empty_column.notifications": "You don't have any notifications yet. When other people interact with you, you will see it here.", "empty_column.notifications": "You don't have any notifications yet. When other people interact with you, you will see it here.",
"empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up", "empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up",
"error.unexpected_crash.explanation": "Due to a bug in our code or a browser compatibility issue, this page could not be displayed correctly.", "error.unexpected_crash.explanation": "Due to a bug in our code or a browser compatibility issue, this page could not be displayed correctly.",
@ -271,6 +272,8 @@
"filter_modal.select_filter.subtitle": "Use an existing category or create a new one", "filter_modal.select_filter.subtitle": "Use an existing category or create a new one",
"filter_modal.select_filter.title": "Filter this post", "filter_modal.select_filter.title": "Filter this post",
"filter_modal.title.status": "Filter a post", "filter_modal.title.status": "Filter a post",
"filtered_notifications_banner.pending_requests": "Notifications from {count, plural, =0 {no} one {one person} other {# people}} you may know",
"filtered_notifications_banner.title": "Filtered notifications",
"firehose.all": "All", "firehose.all": "All",
"firehose.local": "This server", "firehose.local": "This server",
"firehose.remote": "Other servers", "firehose.remote": "Other servers",
@ -314,7 +317,6 @@
"hashtag.follow": "Follow hashtag", "hashtag.follow": "Follow hashtag",
"hashtag.unfollow": "Unfollow hashtag", "hashtag.unfollow": "Unfollow hashtag",
"hashtags.and_other": "…and {count, plural, other {# more}}", "hashtags.and_other": "…and {count, plural, other {# more}}",
"home.column_settings.basic": "Basic",
"home.column_settings.show_reblogs": "Show boosts", "home.column_settings.show_reblogs": "Show boosts",
"home.column_settings.show_replies": "Show replies", "home.column_settings.show_replies": "Show replies",
"home.hide_announcements": "Hide announcements", "home.hide_announcements": "Hide announcements",
@ -440,15 +442,16 @@
"notification.reblog": "{name} boosted your post", "notification.reblog": "{name} boosted your post",
"notification.status": "{name} just posted", "notification.status": "{name} just posted",
"notification.update": "{name} edited a post", "notification.update": "{name} edited a post",
"notification_requests.accept": "Accept",
"notification_requests.dismiss": "Dismiss",
"notification_requests.notifications_from": "Notifications from {name}",
"notification_requests.title": "Filtered notifications",
"notifications.clear": "Clear notifications", "notifications.clear": "Clear notifications",
"notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?", "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
"notifications.column_settings.admin.report": "New reports:", "notifications.column_settings.admin.report": "New reports:",
"notifications.column_settings.admin.sign_up": "New sign-ups:", "notifications.column_settings.admin.sign_up": "New sign-ups:",
"notifications.column_settings.alert": "Desktop notifications", "notifications.column_settings.alert": "Desktop notifications",
"notifications.column_settings.favourite": "Favorites:", "notifications.column_settings.favourite": "Favorites:",
"notifications.column_settings.filter_bar.advanced": "Display all categories",
"notifications.column_settings.filter_bar.category": "Quick filter bar",
"notifications.column_settings.filter_bar.show_bar": "Show filter bar",
"notifications.column_settings.follow": "New followers:", "notifications.column_settings.follow": "New followers:",
"notifications.column_settings.follow_request": "New follow requests:", "notifications.column_settings.follow_request": "New follow requests:",
"notifications.column_settings.mention": "Mentions:", "notifications.column_settings.mention": "Mentions:",
@ -474,6 +477,15 @@
"notifications.permission_denied": "Desktop notifications are unavailable due to previously denied browser permissions request", "notifications.permission_denied": "Desktop notifications are unavailable due to previously denied browser permissions request",
"notifications.permission_denied_alert": "Desktop notifications can't be enabled, as browser permission has been denied before", "notifications.permission_denied_alert": "Desktop notifications can't be enabled, as browser permission has been denied before",
"notifications.permission_required": "Desktop notifications are unavailable because the required permission has not been granted.", "notifications.permission_required": "Desktop notifications are unavailable because the required permission has not been granted.",
"notifications.policy.filter_new_accounts.hint": "Created within the past {days, plural, one {one day} other {# days}}",
"notifications.policy.filter_new_accounts_title": "New accounts",
"notifications.policy.filter_not_followers_hint": "Including people who have been following you fewer than {days, plural, one {one day} other {# days}}",
"notifications.policy.filter_not_followers_title": "People not following you",
"notifications.policy.filter_not_following_hint": "Until you manually approve them",
"notifications.policy.filter_not_following_title": "People you don't follow",
"notifications.policy.filter_private_mentions_hint": "Filtered unless it's in reply to your own mention or if you follow the sender",
"notifications.policy.filter_private_mentions_title": "Unsolicited private mentions",
"notifications.policy.title": "Filter out notifications from…",
"notifications_permission_banner.enable": "Enable desktop notifications", "notifications_permission_banner.enable": "Enable desktop notifications",
"notifications_permission_banner.how_to_control": "To receive notifications when Mastodon isn't open, enable desktop notifications. You can control precisely which types of interactions generate desktop notifications through the {icon} button above once they're enabled.", "notifications_permission_banner.how_to_control": "To receive notifications when Mastodon isn't open, enable desktop notifications. You can control precisely which types of interactions generate desktop notifications through the {icon} button above once they're enabled.",
"notifications_permission_banner.title": "Never miss a thing", "notifications_permission_banner.title": "Never miss a thing",

View file

@ -271,7 +271,7 @@
"filter_modal.select_filter.subtitle": "Usar una categoría existente o crear una nueva", "filter_modal.select_filter.subtitle": "Usar una categoría existente o crear una nueva",
"filter_modal.select_filter.title": "Filtrar este mensaje", "filter_modal.select_filter.title": "Filtrar este mensaje",
"filter_modal.title.status": "Filtrar un mensaje", "filter_modal.title.status": "Filtrar un mensaje",
"firehose.all": "Todas", "firehose.all": "Todos",
"firehose.local": "Este servidor", "firehose.local": "Este servidor",
"firehose.remote": "Otros servidores", "firehose.remote": "Otros servidores",
"follow_request.authorize": "Autorizar", "follow_request.authorize": "Autorizar",

View file

@ -279,15 +279,15 @@
"follow_requests.unlocked_explanation": "A pesar de que tu cuenta no es privada, el personal de {domain} ha pensado que quizás deberías revisar manualmente las solicitudes de seguimiento de estas cuentas.", "follow_requests.unlocked_explanation": "A pesar de que tu cuenta no es privada, el personal de {domain} ha pensado que quizás deberías revisar manualmente las solicitudes de seguimiento de estas cuentas.",
"follow_suggestions.curated_suggestion": "Recomendaciones del equipo", "follow_suggestions.curated_suggestion": "Recomendaciones del equipo",
"follow_suggestions.dismiss": "No mostrar de nuevo", "follow_suggestions.dismiss": "No mostrar de nuevo",
"follow_suggestions.hints.featured": "Este perfil ha sido elegido a mano por el equipo de {domain}.", "follow_suggestions.hints.featured": "Este perfil ha sido seleccionado a mano por el equipo de {domain}.",
"follow_suggestions.hints.friends_of_friends": "Este perfil es popular entre las personas que sigues.", "follow_suggestions.hints.friends_of_friends": "Este perfil es popular entre las personas que sigues.",
"follow_suggestions.hints.most_followed": "Este perfil es uno de los más seguidos en {domain}.", "follow_suggestions.hints.most_followed": "Este perfil es uno de los más seguidos en {domain}.",
"follow_suggestions.hints.most_interactions": "Este perfil ha estado recibiendo recientemente mucha atención en {domain}.", "follow_suggestions.hints.most_interactions": "Este perfil ha estado recibiendo mucha atención en {domain}.",
"follow_suggestions.hints.similar_to_recently_followed": "Este perfil es similar a los perfiles que has seguido recientemente.", "follow_suggestions.hints.similar_to_recently_followed": "Este perfil es similar a los perfiles que has seguido recientemente.",
"follow_suggestions.personalized_suggestion": "Sugerencia personalizada", "follow_suggestions.personalized_suggestion": "Sugerencia personalizada",
"follow_suggestions.popular_suggestion": "Sugerencia popular", "follow_suggestions.popular_suggestion": "Sugerencia popular",
"follow_suggestions.view_all": "Ver todo", "follow_suggestions.view_all": "Ver todo",
"follow_suggestions.who_to_follow": "A quién seguir", "follow_suggestions.who_to_follow": "Recomendamos seguir",
"followed_tags": "Hashtags seguidos", "followed_tags": "Hashtags seguidos",
"footer.about": "Acerca de", "footer.about": "Acerca de",
"footer.directory": "Directorio de perfiles", "footer.directory": "Directorio de perfiles",

View file

@ -529,15 +529,15 @@
"poll_button.add_poll": "Añadir una encuesta", "poll_button.add_poll": "Añadir una encuesta",
"poll_button.remove_poll": "Eliminar encuesta", "poll_button.remove_poll": "Eliminar encuesta",
"privacy.change": "Ajustar privacidad", "privacy.change": "Ajustar privacidad",
"privacy.direct.long": "Todos los mencionados en el post", "privacy.direct.long": "Visible únicamente por los mencionados en la publicación",
"privacy.direct.short": "Personas específicas", "privacy.direct.short": "Personas específicas",
"privacy.private.long": "Solo tus seguidores", "privacy.private.long": "Visible únicamente por tus seguidores",
"privacy.private.short": "Seguidores", "privacy.private.short": "Seguidores",
"privacy.public.long": "Cualquiera dentro y fuera de Mastodon", "privacy.public.long": "Visible por todo el mundo, dentro y fuera de Mastodon",
"privacy.public.short": "Público", "privacy.public.short": "Pública",
"privacy.unlisted.additional": "Esto se comporta exactamente igual que el público, excepto que la publicación no aparecerá en la cronología en directo o en las etiquetas, la exploración o búsqueda de Mastodon, incluso si está optado por activar la cuenta de usuario.", "privacy.unlisted.additional": "Se comporta exactamente igual que la visibilidad pública, excepto que la publicación no aparecerá en las cronologías públicas o en las etiquetas, la sección de Explorar o la búsqueda de Mastodon, incluso si has habilitado la opción de búsqueda en tu perfil.",
"privacy.unlisted.long": "Menos fanfares algorítmicos", "privacy.unlisted.long": "Sin algoritmos de descubrimiento",
"privacy.unlisted.short": "Público tranquilo", "privacy.unlisted.short": "Pública silenciosa",
"privacy_policy.last_updated": "Actualizado por última vez {date}", "privacy_policy.last_updated": "Actualizado por última vez {date}",
"privacy_policy.title": "Política de Privacidad", "privacy_policy.title": "Política de Privacidad",
"recommended": "Recomendado", "recommended": "Recomendado",

View file

@ -21,7 +21,7 @@
"account.blocked": "Blokeeritud", "account.blocked": "Blokeeritud",
"account.browse_more_on_origin_server": "Vaata rohkem algsel profiilil", "account.browse_more_on_origin_server": "Vaata rohkem algsel profiilil",
"account.cancel_follow_request": "Võta jälgimistaotlus tagasi", "account.cancel_follow_request": "Võta jälgimistaotlus tagasi",
"account.copy": "Kopeeri link profiili", "account.copy": "Kopeeri profiili link",
"account.direct": "Maini privaatselt @{name}", "account.direct": "Maini privaatselt @{name}",
"account.disable_notifications": "Peata teavitused @{name} postitustest", "account.disable_notifications": "Peata teavitused @{name} postitustest",
"account.domain_blocked": "Domeen peidetud", "account.domain_blocked": "Domeen peidetud",
@ -277,6 +277,17 @@
"follow_request.authorize": "Autoriseeri", "follow_request.authorize": "Autoriseeri",
"follow_request.reject": "Hülga", "follow_request.reject": "Hülga",
"follow_requests.unlocked_explanation": "Kuigi su konto pole lukustatud, soovitab {domain} personal siiski nende kontode jälgimistaotlused käsitsi üle vaadata.", "follow_requests.unlocked_explanation": "Kuigi su konto pole lukustatud, soovitab {domain} personal siiski nende kontode jälgimistaotlused käsitsi üle vaadata.",
"follow_suggestions.curated_suggestion": "Teiste valitud",
"follow_suggestions.dismiss": "Ära enam näita",
"follow_suggestions.hints.featured": "Selle kasutajaprofiili on soovitanud {domain} kasutajad.",
"follow_suggestions.hints.friends_of_friends": "See kasutajaprofiil on jälgitavate seas populaarne.",
"follow_suggestions.hints.most_followed": "See on {domain} enim jälgitud kasutajaprofiil.",
"follow_suggestions.hints.most_interactions": "See on {domain} viimasel ajal enim tähelepanu saanud kasutajaprofiil.",
"follow_suggestions.hints.similar_to_recently_followed": "See kasutajaprofiil sarnaneb neile, mida oled hiljuti jälgima asunud.",
"follow_suggestions.personalized_suggestion": "Isikupärastatud soovitus",
"follow_suggestions.popular_suggestion": "Popuplaarne soovitus",
"follow_suggestions.view_all": "Vaata kõiki",
"follow_suggestions.who_to_follow": "Keda jälgida",
"followed_tags": "Jälgitavad märksõnad", "followed_tags": "Jälgitavad märksõnad",
"footer.about": "Teave", "footer.about": "Teave",
"footer.directory": "Profiilikataloog", "footer.directory": "Profiilikataloog",
@ -473,7 +484,7 @@
"onboarding.compose.template": "Tere, #Mastodon!", "onboarding.compose.template": "Tere, #Mastodon!",
"onboarding.follows.empty": "Kahjuks ei saa hetkel tulemusi näidata. Proovi kasutada otsingut või lehitse uurimise lehte, et leida inimesi, keda jälgida, või proovi hiljem uuesti.", "onboarding.follows.empty": "Kahjuks ei saa hetkel tulemusi näidata. Proovi kasutada otsingut või lehitse uurimise lehte, et leida inimesi, keda jälgida, või proovi hiljem uuesti.",
"onboarding.follows.lead": "Haldad ise oma koduvoogu. Mida rohkemaid inimesi jälgid, seda aktiivsem ja huvitavam see on. Need profiilid võiksid olla head alustamiskohad — saad nende jälgimise alati lõpetada!", "onboarding.follows.lead": "Haldad ise oma koduvoogu. Mida rohkemaid inimesi jälgid, seda aktiivsem ja huvitavam see on. Need profiilid võiksid olla head alustamiskohad — saad nende jälgimise alati lõpetada!",
"onboarding.follows.title": "Populaarne Mastodonis", "onboarding.follows.title": "Isikupärasta oma koduvoogu",
"onboarding.profile.discoverable": "Muuda mu profiil avastatavaks", "onboarding.profile.discoverable": "Muuda mu profiil avastatavaks",
"onboarding.profile.discoverable_hint": "Kui nõustud enda avastamisega Mastodonis, võivad sinu postitused ilmuda otsingutulemustes ja trendides ning sinu profiili võidakse soovitada sinuga sarnaste huvidega inimestele.", "onboarding.profile.discoverable_hint": "Kui nõustud enda avastamisega Mastodonis, võivad sinu postitused ilmuda otsingutulemustes ja trendides ning sinu profiili võidakse soovitada sinuga sarnaste huvidega inimestele.",
"onboarding.profile.display_name": "Näidatav nimi", "onboarding.profile.display_name": "Näidatav nimi",
@ -493,11 +504,11 @@
"onboarding.start.skip": "Soovid kohe edasi hüpata?", "onboarding.start.skip": "Soovid kohe edasi hüpata?",
"onboarding.start.title": "Said valmis!", "onboarding.start.title": "Said valmis!",
"onboarding.steps.follow_people.body": "Haldad oma koduvoogu. Täida see huvitavate inimestega.", "onboarding.steps.follow_people.body": "Haldad oma koduvoogu. Täida see huvitavate inimestega.",
"onboarding.steps.follow_people.title": "Jälgi {count, plural, one {üht inimest} other {# inimest}}", "onboarding.steps.follow_people.title": "Isikupärasta oma koduvoogu",
"onboarding.steps.publish_status.body": "Ütle maailmale tere.", "onboarding.steps.publish_status.body": "Ütle maailmale tere.",
"onboarding.steps.publish_status.title": "Tee oma esimene postitus", "onboarding.steps.publish_status.title": "Tee oma esimene postitus",
"onboarding.steps.setup_profile.body": "Täidetud profiili korral suhtlevad teised sinuga tõenäolisemalt.", "onboarding.steps.setup_profile.body": "Täidetud profiili korral suhtlevad teised sinuga tõenäolisemalt.",
"onboarding.steps.setup_profile.title": "Kohanda oma profiili", "onboarding.steps.setup_profile.title": "Isikupärasta oma profiili",
"onboarding.steps.share_profile.body": "Anna sõpradele teada, kuidas sind Mastodonist leida!", "onboarding.steps.share_profile.body": "Anna sõpradele teada, kuidas sind Mastodonist leida!",
"onboarding.steps.share_profile.title": "Jaga oma profiili", "onboarding.steps.share_profile.title": "Jaga oma profiili",
"onboarding.tips.2fa": "<strong>Kas sa teadsid?</strong> Saad oma kontot muuta turvalisemaks valides konto seadetes kaheastmelise autoriseerimise. See töötab mistahes sinu valitud TOTP-äpiga, telefoninumbrit pole vaja!", "onboarding.tips.2fa": "<strong>Kas sa teadsid?</strong> Saad oma kontot muuta turvalisemaks valides konto seadetes kaheastmelise autoriseerimise. See töötab mistahes sinu valitud TOTP-äpiga, telefoninumbrit pole vaja!",
@ -524,6 +535,7 @@
"privacy.private.short": "Jälgijad", "privacy.private.short": "Jälgijad",
"privacy.public.long": "Nii kasutajad kui mittekasutajad", "privacy.public.long": "Nii kasutajad kui mittekasutajad",
"privacy.public.short": "Avalik", "privacy.public.short": "Avalik",
"privacy.unlisted.additional": "See on olemuselt küll avalik, aga postitus ei ilmu voogudes ega märksõnades, lehitsedes ega Mastodoni otsingus, isegi kui konto on seadistustes avalik.",
"privacy.unlisted.long": "Vähem algoritmilisi teavitusi", "privacy.unlisted.long": "Vähem algoritmilisi teavitusi",
"privacy.unlisted.short": "Vaikselt avalik", "privacy.unlisted.short": "Vaikselt avalik",
"privacy_policy.last_updated": "Viimati uuendatud {date}", "privacy_policy.last_updated": "Viimati uuendatud {date}",

View file

@ -201,9 +201,9 @@
"disabled_account_banner.text": "Tilisi {disabledAccount} on tällä hetkellä poissa käytöstä.", "disabled_account_banner.text": "Tilisi {disabledAccount} on tällä hetkellä poissa käytöstä.",
"dismissable_banner.community_timeline": "Nämä ovat tuoreimpia julkaisuja käyttäjiltä, joiden tili on palvelimella {domain}.", "dismissable_banner.community_timeline": "Nämä ovat tuoreimpia julkaisuja käyttäjiltä, joiden tili on palvelimella {domain}.",
"dismissable_banner.dismiss": "Hylkää", "dismissable_banner.dismiss": "Hylkää",
"dismissable_banner.explore_links": "Näitä uutisia jaetaan tänään sosiaalisessa verkossa eniten. Uusimmat ja eri käyttäjien eniten lähettämät uutiset nousevat listauksessa korkeimmalle.", "dismissable_banner.explore_links": "Näitä uutisia jaetaan tänään sosiaalisessa verkossa eniten. Uusimmat ja eri käyttäjien eniten lähettämät uutiset nousevat listauksessa korkeammalle.",
"dismissable_banner.explore_statuses": "Tänään nämä sosiaalisen verkon julkaisut keräävät eniten huomiota. Uusimmat, tehostetuimmat ja suosikeiksi lisätyimmät julkaisut nousevat listauksessa korkeammalle.", "dismissable_banner.explore_statuses": "Nämä sosiaalisen verkon julkaisut keräävät tänään eniten huomiota. Uusimmat, tehostetuimmat ja suosikeiksi lisätyimmät julkaisut nousevat listauksessa korkeammalle.",
"dismissable_banner.explore_tags": "Nämä sosiaalisen verkon aihetunnisteet keräävät tänään eniten huomiota. Useimman käyttäjän käyttämät aihetunnisteet nousevat listauksessa korkeimmalle.", "dismissable_banner.explore_tags": "Nämä sosiaalisen verkon aihetunnisteet keräävät tänään eniten huomiota. Useimman käyttäjän käyttämät aihetunnisteet nousevat listauksessa korkeammalle.",
"dismissable_banner.public_timeline": "Nämä ovat viimeisimpiä julkaisuja sosiaalisen verkon käyttäjiltä, joita seurataan palvelimella {domain}.", "dismissable_banner.public_timeline": "Nämä ovat viimeisimpiä julkaisuja sosiaalisen verkon käyttäjiltä, joita seurataan palvelimella {domain}.",
"embed.instructions": "Upota julkaisu verkkosivullesi kopioimalla alla oleva koodi.", "embed.instructions": "Upota julkaisu verkkosivullesi kopioimalla alla oleva koodi.",
"embed.preview": "Tältä se näyttää:", "embed.preview": "Tältä se näyttää:",
@ -284,7 +284,7 @@
"follow_suggestions.hints.most_followed": "Tämä profiili on yksi seuratuimmista palvelimella {domain}.", "follow_suggestions.hints.most_followed": "Tämä profiili on yksi seuratuimmista palvelimella {domain}.",
"follow_suggestions.hints.most_interactions": "Tämä profiili on viime aikoina saanut paljon huomiota palvelimella {domain}.", "follow_suggestions.hints.most_interactions": "Tämä profiili on viime aikoina saanut paljon huomiota palvelimella {domain}.",
"follow_suggestions.hints.similar_to_recently_followed": "Tämä profiili on samankaltainen kuin profiilit, joita olet viimeksi seurannut.", "follow_suggestions.hints.similar_to_recently_followed": "Tämä profiili on samankaltainen kuin profiilit, joita olet viimeksi seurannut.",
"follow_suggestions.personalized_suggestion": "Personoitu ehdotus", "follow_suggestions.personalized_suggestion": "Mukautettu ehdotus",
"follow_suggestions.popular_suggestion": "Suosittu ehdotus", "follow_suggestions.popular_suggestion": "Suosittu ehdotus",
"follow_suggestions.view_all": "Näytä kaikki", "follow_suggestions.view_all": "Näytä kaikki",
"follow_suggestions.who_to_follow": "Ehdotuksia seurattavaksi", "follow_suggestions.who_to_follow": "Ehdotuksia seurattavaksi",
@ -504,7 +504,7 @@
"onboarding.start.skip": "Haluatko hypätä suoraan eteenpäin ilman alkuunpääsyohjeistuksia?", "onboarding.start.skip": "Haluatko hypätä suoraan eteenpäin ilman alkuunpääsyohjeistuksia?",
"onboarding.start.title": "Olet tehnyt sen!", "onboarding.start.title": "Olet tehnyt sen!",
"onboarding.steps.follow_people.body": "Mastodon perustuu sinua kiinnostavien henkilöjen julkaisujen seuraamiseen.", "onboarding.steps.follow_people.body": "Mastodon perustuu sinua kiinnostavien henkilöjen julkaisujen seuraamiseen.",
"onboarding.steps.follow_people.title": "Mukauta kotisyötteesi", "onboarding.steps.follow_people.title": "Mukauta kotisyötettäsi",
"onboarding.steps.publish_status.body": "Tervehdi maailmaa sanoin, kuvin tai äänestyksin {emoji}", "onboarding.steps.publish_status.body": "Tervehdi maailmaa sanoin, kuvin tai äänestyksin {emoji}",
"onboarding.steps.publish_status.title": "Laadi ensimmäinen julkaisusi", "onboarding.steps.publish_status.title": "Laadi ensimmäinen julkaisusi",
"onboarding.steps.setup_profile.body": "Täydentämällä profiilisi tietoja tehostat vuorovaikutteisuutta.", "onboarding.steps.setup_profile.body": "Täydentämällä profiilisi tietoja tehostat vuorovaikutteisuutta.",
@ -657,7 +657,7 @@
"status.filter": "Suodata tämä julkaisu", "status.filter": "Suodata tämä julkaisu",
"status.filtered": "Suodatettu", "status.filtered": "Suodatettu",
"status.hide": "Piilota julkaisu", "status.hide": "Piilota julkaisu",
"status.history.created": "{name} luotu {date}", "status.history.created": "{name} loi {date}",
"status.history.edited": "{name} muokkasi {date}", "status.history.edited": "{name} muokkasi {date}",
"status.load_more": "Lataa lisää", "status.load_more": "Lataa lisää",
"status.media.open": "Avaa napsauttamalla", "status.media.open": "Avaa napsauttamalla",

View file

@ -145,10 +145,10 @@
"compose_form.lock_disclaimer": "Chan eil an cunntas agad {locked}. S urrainn do dhuine sam bith gad leantainn is na postaichean agad a tha ag amas air an luchd-leantainn agad a-mhàin a shealltainn.", "compose_form.lock_disclaimer": "Chan eil an cunntas agad {locked}. S urrainn do dhuine sam bith gad leantainn is na postaichean agad a tha ag amas air an luchd-leantainn agad a-mhàin a shealltainn.",
"compose_form.lock_disclaimer.lock": "glaiste", "compose_form.lock_disclaimer.lock": "glaiste",
"compose_form.placeholder": "Dè tha air d aire?", "compose_form.placeholder": "Dè tha air d aire?",
"compose_form.poll.duration": "Faide a chunntais-bheachd", "compose_form.poll.duration": "Faide a chunntais",
"compose_form.poll.multiple": "Iomadh roghainn", "compose_form.poll.multiple": "Iomadh-roghainn",
"compose_form.poll.option_placeholder": "Roghainn {number}", "compose_form.poll.option_placeholder": "Roghainn {number}",
"compose_form.poll.single": "Tagh aonan", "compose_form.poll.single": "Aonan",
"compose_form.poll.switch_to_multiple": "Atharraich an cunntas-bheachd ach an gabh iomadh roghainn a thaghadh", "compose_form.poll.switch_to_multiple": "Atharraich an cunntas-bheachd ach an gabh iomadh roghainn a thaghadh",
"compose_form.poll.switch_to_single": "Atharraich an cunntas-bheachd gus nach gabh ach aon roghainn a thaghadh", "compose_form.poll.switch_to_single": "Atharraich an cunntas-bheachd gus nach gabh ach aon roghainn a thaghadh",
"compose_form.poll.type": "Stoidhle", "compose_form.poll.type": "Stoidhle",
@ -277,7 +277,13 @@
"follow_request.authorize": "Ùghdarraich", "follow_request.authorize": "Ùghdarraich",
"follow_request.reject": "Diùlt", "follow_request.reject": "Diùlt",
"follow_requests.unlocked_explanation": "Ged nach eil an cunntas agad glaiste, tha sgioba {domain} dhen bheachd gum b fheàirrde thu lèirmheas a dhèanamh air na h-iarrtasan leantainn o na cunntasan seo a làimh.", "follow_requests.unlocked_explanation": "Ged nach eil an cunntas agad glaiste, tha sgioba {domain} dhen bheachd gum b fheàirrde thu lèirmheas a dhèanamh air na h-iarrtasan leantainn o na cunntasan seo a làimh.",
"follow_suggestions.curated_suggestion": "Roghainn an sgioba",
"follow_suggestions.dismiss": "Na seall seo a-rithist", "follow_suggestions.dismiss": "Na seall seo a-rithist",
"follow_suggestions.hints.featured": "Chaidh a phròifil seo a thaghadh le sgioba {domain} a làimh.",
"follow_suggestions.hints.friends_of_friends": "Tha fèill mhòr air a phròifil seo am measg nan daoine a leanas tu.",
"follow_suggestions.hints.most_followed": "Tha a phròifil seo am measg an fheadhainn a leanar as trice air {domain}.",
"follow_suggestions.hints.most_interactions": "Chaidh mòran aire a thoirt air a phròifil seo air {domain} o chionn goirid.",
"follow_suggestions.hints.similar_to_recently_followed": "Tha a phròifil seo coltach ris na pròifilean air an lean thu o chionn goirid.",
"follow_suggestions.personalized_suggestion": "Moladh pearsanaichte", "follow_suggestions.personalized_suggestion": "Moladh pearsanaichte",
"follow_suggestions.popular_suggestion": "Moladh air a bheil fèill mhòr", "follow_suggestions.popular_suggestion": "Moladh air a bheil fèill mhòr",
"follow_suggestions.view_all": "Seall na h-uile", "follow_suggestions.view_all": "Seall na h-uile",
@ -479,9 +485,11 @@
"onboarding.follows.empty": "Gu mì-fhortanach, chan urrainn dhuinn toradh a shealltainn an-dràsta. Feuch gleus an luirg no duilleag an rùrachaidh airson daoine ri leantainn a lorg no feuch ris a-rithist an ceann tamaill.", "onboarding.follows.empty": "Gu mì-fhortanach, chan urrainn dhuinn toradh a shealltainn an-dràsta. Feuch gleus an luirg no duilleag an rùrachaidh airson daoine ri leantainn a lorg no feuch ris a-rithist an ceann tamaill.",
"onboarding.follows.lead": "S e do prìomh-doras do Mhastodon a th ann san dachaigh. Mar as motha an t-uiread de dhaoine a leanas tu s ann nas beòthaile inntinniche a bhios i. Seo moladh no dhà dhut airson tòiseachadh:", "onboarding.follows.lead": "S e do prìomh-doras do Mhastodon a th ann san dachaigh. Mar as motha an t-uiread de dhaoine a leanas tu s ann nas beòthaile inntinniche a bhios i. Seo moladh no dhà dhut airson tòiseachadh:",
"onboarding.follows.title": "Cuir dreach pearsanta air do dhachaigh", "onboarding.follows.title": "Cuir dreach pearsanta air do dhachaigh",
"onboarding.profile.discoverable": "Bu mhath leam gun gabh a phròifil agam a lorg", "onboarding.profile.discoverable": "Bu mhath leam gun gabh a phròifil agam a rùrachadh",
"onboarding.profile.discoverable_hint": "Ma chuir thu romhad gun gabh a phròifil agad a rùrachadh air Mastodon, faodaidh na postaichean agad nochdadh ann an toraidhean luirg agus treandaichean agus dhfhaoidte gun dèid a phròifil agad a mholadh dhan fheadhainn aig a bheil ùidhean coltach ri d ùidhean-sa.",
"onboarding.profile.display_name": "Ainm-taisbeanaidh", "onboarding.profile.display_name": "Ainm-taisbeanaidh",
"onboarding.profile.display_name_hint": "D ainm slàn no spòrsail…", "onboarding.profile.display_name_hint": "D ainm slàn no spòrsail…",
"onboarding.profile.lead": "S urrainn dhut seo a choileanadh uair sam bith eile sna roghainnean far am bi roghainnean gnàthachaidh eile ri làimh dhut cuideachd.",
"onboarding.profile.note": "Cunntas-beatha", "onboarding.profile.note": "Cunntas-beatha",
"onboarding.profile.note_hint": "S urrainn dhut @iomradh a thoirt air càch no air #tagaicheanHais…", "onboarding.profile.note_hint": "S urrainn dhut @iomradh a thoirt air càch no air #tagaicheanHais…",
"onboarding.profile.save_and_continue": "Sàbhail s lean air adhart", "onboarding.profile.save_and_continue": "Sàbhail s lean air adhart",
@ -527,6 +535,8 @@
"privacy.private.short": "Luchd-leantainn", "privacy.private.short": "Luchd-leantainn",
"privacy.public.long": "Duine sam bith taobh a-staigh no a-muigh Mhastodon", "privacy.public.long": "Duine sam bith taobh a-staigh no a-muigh Mhastodon",
"privacy.public.short": "Poblach", "privacy.public.short": "Poblach",
"privacy.unlisted.additional": "Tha seo coltach ris an fhaicsinneachd phoblach ach cha nochd am post air loidhnichean-ama an t-saoghail phoblaich, nan tagaichean hais no an rùrachaidh no ann an toraidhean luirg Mhastodon fiù s ma thug thu ro-aonta airson sin seachad.",
"privacy.unlisted.long": "Ìre bheag an algairim",
"privacy.unlisted.short": "Poblach ach sàmhach", "privacy.unlisted.short": "Poblach ach sàmhach",
"privacy_policy.last_updated": "An t-ùrachadh mu dheireadh {date}", "privacy_policy.last_updated": "An t-ùrachadh mu dheireadh {date}",
"privacy_policy.title": "Poileasaidh prìobhaideachd", "privacy_policy.title": "Poileasaidh prìobhaideachd",

View file

@ -197,6 +197,7 @@
"firehose.all": "Toto", "firehose.all": "Toto",
"firehose.local": "Iste servitor", "firehose.local": "Iste servitor",
"firehose.remote": "Altere servitores", "firehose.remote": "Altere servitores",
"follow_request.reject": "Rejectar",
"follow_suggestions.dismiss": "Non monstrar novemente", "follow_suggestions.dismiss": "Non monstrar novemente",
"follow_suggestions.personalized_suggestion": "Suggestion personalisate", "follow_suggestions.personalized_suggestion": "Suggestion personalisate",
"follow_suggestions.popular_suggestion": "Suggestion personalisate", "follow_suggestions.popular_suggestion": "Suggestion personalisate",
@ -204,6 +205,7 @@
"footer.about": "A proposito de", "footer.about": "A proposito de",
"footer.directory": "Directorio de profilos", "footer.directory": "Directorio de profilos",
"footer.get_app": "Obtene le application", "footer.get_app": "Obtene le application",
"footer.invite": "Invitar personas",
"footer.keyboard_shortcuts": "Accessos directe de claviero", "footer.keyboard_shortcuts": "Accessos directe de claviero",
"footer.privacy_policy": "Politica de confidentialitate", "footer.privacy_policy": "Politica de confidentialitate",
"footer.source_code": "Vider le codice fonte", "footer.source_code": "Vider le codice fonte",
@ -244,6 +246,7 @@
"keyboard_shortcuts.muted": "Aperir lista de usatores silentiate", "keyboard_shortcuts.muted": "Aperir lista de usatores silentiate",
"keyboard_shortcuts.my_profile": "Aperir tu profilo", "keyboard_shortcuts.my_profile": "Aperir tu profilo",
"keyboard_shortcuts.notifications": "Aperir columna de notificationes", "keyboard_shortcuts.notifications": "Aperir columna de notificationes",
"keyboard_shortcuts.open_media": "Aperir medio",
"keyboard_shortcuts.profile": "Aperir le profilo del autor", "keyboard_shortcuts.profile": "Aperir le profilo del autor",
"keyboard_shortcuts.reply": "Responder al message", "keyboard_shortcuts.reply": "Responder al message",
"keyboard_shortcuts.spoilers": "Monstrar/celar le campo CW", "keyboard_shortcuts.spoilers": "Monstrar/celar le campo CW",
@ -273,9 +276,11 @@
"navigation_bar.blocks": "Usatores blocate", "navigation_bar.blocks": "Usatores blocate",
"navigation_bar.bookmarks": "Marcapaginas", "navigation_bar.bookmarks": "Marcapaginas",
"navigation_bar.community_timeline": "Chronologia local", "navigation_bar.community_timeline": "Chronologia local",
"navigation_bar.compose": "Componer un nove message",
"navigation_bar.direct": "Mentiones private", "navigation_bar.direct": "Mentiones private",
"navigation_bar.discover": "Discoperir", "navigation_bar.discover": "Discoperir",
"navigation_bar.domain_blocks": "Dominios blocate", "navigation_bar.domain_blocks": "Dominios blocate",
"navigation_bar.explore": "Explorar",
"navigation_bar.favourites": "Favoritos", "navigation_bar.favourites": "Favoritos",
"navigation_bar.filters": "Parolas silentiate", "navigation_bar.filters": "Parolas silentiate",
"navigation_bar.lists": "Listas", "navigation_bar.lists": "Listas",

View file

@ -1,5 +1,8 @@
{ {
"about.contact": "Anermis:", "about.contact": "Anermis:",
"about.disclaimer": "Mastodon d aseɣẓan ilelli, d aseɣẓan n uɣbalu yeldin, d tnezzut n Mastodon gGmbH.",
"about.not_available": "Talɣut-a ur tettwabder ara deg uqeddac-a.",
"about.powered_by": "Azeṭṭa inmetti yettwasɣelsen sɣur {mastodon}",
"about.rules": "Ilugan n uqeddac", "about.rules": "Ilugan n uqeddac",
"account.account_note_header": "Tazmilt", "account.account_note_header": "Tazmilt",
"account.add_or_remove_from_list": "Rnu neɣ kkes seg tebdarin", "account.add_or_remove_from_list": "Rnu neɣ kkes seg tebdarin",
@ -10,13 +13,15 @@
"account.block_short": "Sewḥel", "account.block_short": "Sewḥel",
"account.blocked": "Yettusewḥel", "account.blocked": "Yettusewḥel",
"account.browse_more_on_origin_server": "Snirem ugar deg umeɣnu aneẓli", "account.browse_more_on_origin_server": "Snirem ugar deg umeɣnu aneẓli",
"account.cancel_follow_request": "Withdraw follow request", "account.cancel_follow_request": "Sefsex taḍfart",
"account.copy": "Nɣel assaɣ ɣer umaɣnu", "account.copy": "Nɣel assaɣ ɣer umaɣnu",
"account.direct": "Bder-d @{name} weḥd-s",
"account.disable_notifications": "Ḥbes ur iyi-d-ttazen ara ilɣa mi ara d-isuffeɣ @{name}", "account.disable_notifications": "Ḥbes ur iyi-d-ttazen ara ilɣa mi ara d-isuffeɣ @{name}",
"account.domain_blocked": "Taɣult yeffren", "account.domain_blocked": "Taɣult yeffren",
"account.edit_profile": "Ẓreg amaɣnu", "account.edit_profile": "Ẓreg amaɣnu",
"account.enable_notifications": "Azen-iyi-d ilɣa mi ara d-isuffeɣ @{name}", "account.enable_notifications": "Azen-iyi-d ilɣa mi ara d-isuffeɣ @{name}",
"account.endorse": "Welleh fell-as deg umaɣnu-inek", "account.endorse": "Welleh fell-as deg umaɣnu-inek",
"account.featured_tags.last_status_at": "Tasuffeɣt taneggarut ass n {date}",
"account.featured_tags.last_status_never": "Ulac tisuffaɣ", "account.featured_tags.last_status_never": "Ulac tisuffaɣ",
"account.follow": "Ḍfer", "account.follow": "Ḍfer",
"account.followers": "Imeḍfaren", "account.followers": "Imeḍfaren",
@ -27,14 +32,17 @@
"account.follows.empty": "Ar tura, amseqdac-agi ur yeṭṭafaṛ yiwen.", "account.follows.empty": "Ar tura, amseqdac-agi ur yeṭṭafaṛ yiwen.",
"account.go_to_profile": "Ddu ɣer umaɣnu", "account.go_to_profile": "Ddu ɣer umaɣnu",
"account.hide_reblogs": "Ffer ayen i ibeṭṭu @{name}", "account.hide_reblogs": "Ffer ayen i ibeṭṭu @{name}",
"account.joined_short": "Izeddi da", "account.joined_short": "Izeddi da seg ass n",
"account.link_verified_on": "Taɣara n useɣwen-a tettwasenqed ass n {date}", "account.link_verified_on": "Taɣara n useɣwen-a tettwasenqed ass n {date}",
"account.locked_info": "Amiḍan-agi uslig isekweṛ. D bab-is kan i izemren ad yeǧǧ, s ufus-is, win ara t-iḍefṛen.", "account.locked_info": "Amiḍan-agi uslig isekweṛ. D bab-is kan i izemren ad yeǧǧ, s ufus-is, win ara t-iḍefṛen.",
"account.media": "Timidyatin", "account.media": "Timidyatin",
"account.mention": "Bder-d @{name}", "account.mention": "Bder-d @{name}",
"account.moved_to": "{name} yenna-d dakken amiḍan-is amaynut yuɣal :",
"account.mute": "Sgugem @{name}", "account.mute": "Sgugem @{name}",
"account.mute_notifications_short": "Susem ilɣa",
"account.mute_short": "Sgugem", "account.mute_short": "Sgugem",
"account.muted": "Yettwasgugem", "account.muted": "Yettwasgugem",
"account.no_bio": "Ulac aglam i d-yettunefken.",
"account.open_original_page": "Ldi asebter anasli", "account.open_original_page": "Ldi asebter anasli",
"account.posts": "Tisuffaɣ", "account.posts": "Tisuffaɣ",
"account.posts_with_replies": "Tisuffaɣ d tririyin", "account.posts_with_replies": "Tisuffaɣ d tririyin",
@ -69,6 +77,7 @@
"bundle_modal_error.close": "Mdel", "bundle_modal_error.close": "Mdel",
"bundle_modal_error.message": "Tella-d kra n tuccḍa mi d-yettali ugbur-agi.", "bundle_modal_error.message": "Tella-d kra n tuccḍa mi d-yettali ugbur-agi.",
"bundle_modal_error.retry": "Ɛreḍ tikelt-nniḍen", "bundle_modal_error.retry": "Ɛreḍ tikelt-nniḍen",
"closed_registrations_modal.description": "Asnulfu n umiḍan deg {domain} mačči d ayen izemren ad yili, maca ttxil-k·m, err deg lbal-ik·im belli ur teḥwaǧeḍ ara amiḍan s wudem ibanen ɣef {domain} akken ad tesqedceḍ Mastodon.",
"closed_registrations_modal.find_another_server": "Aff-d aqeddac nniḍen", "closed_registrations_modal.find_another_server": "Aff-d aqeddac nniḍen",
"closed_registrations_modal.title": "Ajerred deg Masṭudun", "closed_registrations_modal.title": "Ajerred deg Masṭudun",
"column.about": "Ɣef", "column.about": "Ɣef",
@ -99,6 +108,7 @@
"community.column_settings.remote_only": "Anmeggag kan", "community.column_settings.remote_only": "Anmeggag kan",
"compose.language.change": "Beddel tutlayt", "compose.language.change": "Beddel tutlayt",
"compose.language.search": "Nadi tutlayin …", "compose.language.search": "Nadi tutlayin …",
"compose.published.body": "Yeffeɣ-d yizen-nni.",
"compose.published.open": "Ldi", "compose.published.open": "Ldi",
"compose.saved.body": "Tettwasekles tsuffeɣt.", "compose.saved.body": "Tettwasekles tsuffeɣt.",
"compose_form.direct_message_warning_learn_more": "Issin ugar", "compose_form.direct_message_warning_learn_more": "Issin ugar",
@ -111,6 +121,7 @@
"compose_form.poll.multiple": "Aṭas n ufran", "compose_form.poll.multiple": "Aṭas n ufran",
"compose_form.poll.option_placeholder": "Taxtiṛt {number}", "compose_form.poll.option_placeholder": "Taxtiṛt {number}",
"compose_form.poll.single": "Fren yiwen", "compose_form.poll.single": "Fren yiwen",
"compose_form.poll.type": "Aɣanib",
"compose_form.publish": "Suffeɣ", "compose_form.publish": "Suffeɣ",
"compose_form.publish_form": "Tasuffeɣt tamaynut", "compose_form.publish_form": "Tasuffeɣt tamaynut",
"compose_form.reply": "Err", "compose_form.reply": "Err",
@ -128,6 +139,7 @@
"confirmations.discard_edit_media.confirm": "Sefsex", "confirmations.discard_edit_media.confirm": "Sefsex",
"confirmations.domain_block.confirm": "Ffer taɣult meṛṛa", "confirmations.domain_block.confirm": "Ffer taɣult meṛṛa",
"confirmations.edit.confirm": "Ẓreg", "confirmations.edit.confirm": "Ẓreg",
"confirmations.edit.message": "Abeddel tura ad d-yaru izen-nni i d-tegreḍ akka tura. Tetḥeqqeḍ tebɣiḍ ad tkemmleḍ?",
"confirmations.logout.confirm": "Ffeɣ", "confirmations.logout.confirm": "Ffeɣ",
"confirmations.logout.message": "D tidet tebɣiḍ ad teffɣeḍ?", "confirmations.logout.message": "D tidet tebɣiḍ ad teffɣeḍ?",
"confirmations.mute.confirm": "Sgugem", "confirmations.mute.confirm": "Sgugem",
@ -142,14 +154,18 @@
"conversation.mark_as_read": "Creḍ yettwaɣṛa", "conversation.mark_as_read": "Creḍ yettwaɣṛa",
"conversation.open": "Ssken adiwenni", "conversation.open": "Ssken adiwenni",
"conversation.with": "Akked {names}", "conversation.with": "Akked {names}",
"copy_icon_button.copied": "Yettwanɣel ɣer ufus",
"copypaste.copied": "Yettwanɣel", "copypaste.copied": "Yettwanɣel",
"copypaste.copy_to_clipboard": "Nɣel ɣer afus",
"directory.federated": "Deg fedivers yettwasnen", "directory.federated": "Deg fedivers yettwasnen",
"directory.local": "Seg {domain} kan", "directory.local": "Seg {domain} kan",
"directory.new_arrivals": "Imaynuten id yewḍen", "directory.new_arrivals": "Imaynuten id yewḍen",
"directory.recently_active": "Yermed xas melmi kan", "directory.recently_active": "Yermed xas melmi kan",
"disabled_account_banner.account_settings": "Iɣewwaṛen n umiḍan", "disabled_account_banner.account_settings": "Iɣewwaṛen n umiḍan",
"dismissable_banner.explore_links": "These news stories are being talked about by people on this and other servers of the decentralized network right now.", "dismissable_banner.dismiss": "Agi",
"dismissable_banner.explore_tags": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.", "dismissable_banner.explore_links": "D tiqsiḍin n yisallen i yettwabḍan ass-a deg web inmetti. Tiqsiḍin n yisallen timaynutin i d-yettwassufɣen s wugar n medden yemgaraden, d tid i d-yufraren ugar.",
"dismissable_banner.explore_statuses": "Ti d tisufaɣ seg uzeṭṭa anmetti i d-yettawin tamyigawt ass-a. Tisufaɣ timaynutin yesεan aṭas n lǧehd d tid iḥemmlen s waṭas, ttwaεlayit d timezwura.",
"dismissable_banner.explore_tags": "D wiyi i d ihacṭagen i d-yettawin tamyigawt deg web anmetti ass-a. Ihacṭagen i sseqdacen ugar n medden, εlayit d imezwura.",
"embed.instructions": "Ẓẓu addad-agi deg usmel-inek s wenγal n tangalt yellan sdaw-agi.", "embed.instructions": "Ẓẓu addad-agi deg usmel-inek s wenγal n tangalt yellan sdaw-agi.",
"embed.preview": "Akka ara d-iban:", "embed.preview": "Akka ara d-iban:",
"emoji_button.activity": "Aqeddic", "emoji_button.activity": "Aqeddic",
@ -221,19 +237,28 @@
"hashtag.column_settings.tag_mode.any": "Yiwen seg-sen", "hashtag.column_settings.tag_mode.any": "Yiwen seg-sen",
"hashtag.column_settings.tag_mode.none": "Yiwen ala seg-sen", "hashtag.column_settings.tag_mode.none": "Yiwen ala seg-sen",
"hashtag.column_settings.tag_toggle": "Glu-d s yihacṭagen imerna i ujgu-agi", "hashtag.column_settings.tag_toggle": "Glu-d s yihacṭagen imerna i ujgu-agi",
"hashtag.counter_by_accounts": "{count, plural, one {{counter} imtekki} other {{counter} n imtekkiyen}}",
"hashtag.counter_by_uses": "{count, plural, one {{counter} n tsuffeɣt} other {{counter} n tsuffaɣ}}", "hashtag.counter_by_uses": "{count, plural, one {{counter} n tsuffeɣt} other {{counter} n tsuffaɣ}}",
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} n tsuffeɣt} other {{counter} n tsuffaɣ}} assa", "hashtag.counter_by_uses_today": "{count, plural, one {{counter} n tsuffeɣt} other {{counter} n tsuffaɣ}} assa",
"hashtag.follow": "Ḍfeṛ ahacṭag", "hashtag.follow": "Ḍfeṛ ahacṭag",
"hashtags.and_other": "…d {count, plural, one {}other {# nniḍen}}",
"home.column_settings.basic": "Igejdanen", "home.column_settings.basic": "Igejdanen",
"home.column_settings.show_reblogs": "Ssken-d beṭṭu", "home.column_settings.show_reblogs": "Ssken-d beṭṭu",
"home.column_settings.show_replies": "Ssken-d tiririyin", "home.column_settings.show_replies": "Ssken-d tiririyin",
"home.hide_announcements": "Ffer ulɣuyen", "home.hide_announcements": "Ffer ulɣuyen",
"home.pending_critical_update.body": "Ma ulac aɣilif, leqqem aqeddac-ik Mastodon akken kan tzemreḍ !", "home.pending_critical_update.body": "Ma ulac aɣilif, leqqem aqeddac-ik Mastodon akken kan tzemreḍ !",
"home.show_announcements": "Ssken-d ulɣuyen", "home.show_announcements": "Ssken-d ulɣuyen",
"interaction_modal.description.favourite": "S umiḍan ɣef Mastodon, tzemreḍ ad tesmenyifeḍ tasuffeɣt-a akken ad teǧǧeḍ amaru ad iẓer belli tḥemmleḍ-tt u ad tt-id-tsellkeḍ i ticki.",
"interaction_modal.description.follow": "S umiḍan deg Mastodon, tzemreḍ ad tḍefreḍ {name} akken ad d-teṭṭfeḍ iznan-is deg lxiḍ-ik·im agejdan.",
"interaction_modal.description.reblog": "S umiḍan deg Mastodon, tzemreḍ ad tesnerniḍ tasuffeɣt-a akken ad tt-tebḍuḍ d yineḍfaren-ik·im.",
"interaction_modal.description.reply": "S umiḍan deg Mastodon, tzemreḍ ad d-terreḍ ɣef tsuffeɣt-a.",
"interaction_modal.login.action": "Awi-yi ɣer uqeddac-iw",
"interaction_modal.login.prompt": "Taɣult n uqeddac-ik·im agejdan, amedya mastodon.social",
"interaction_modal.no_account_yet": "Ulac-ik·ikem deg Maṣṭudun?", "interaction_modal.no_account_yet": "Ulac-ik·ikem deg Maṣṭudun?",
"interaction_modal.on_another_server": "Deg uqeddac nniḍen", "interaction_modal.on_another_server": "Deg uqeddac nniḍen",
"interaction_modal.on_this_server": "Deg uqeddac-ayi", "interaction_modal.on_this_server": "Deg uqeddac-ayi",
"interaction_modal.sign_in": "Ur tekcimeḍ ara ɣer uqeddac-a. Anda yella umiḍan-ik·im ?", "interaction_modal.sign_in": "Ur tekcimeḍ ara ɣer uqeddac-a. Anda yella umiḍan-ik·im ?",
"interaction_modal.sign_in_hint": "Ihi : Wa d asmel ideg tjerdeḍ. Ma ur tecfiḍ ara, nadi imayl n ummager deg tenkult-ik·im. Tzemreḍ daɣen ad d-tefkeḍ isem-ik·im n useqdac ummid ! (amedya @Mastodon@mastodon.social)",
"interaction_modal.title.follow": "Ḍfer {name}", "interaction_modal.title.follow": "Ḍfer {name}",
"intervals.full.days": "{number, plural, one {# n wass} other {# n wussan}}", "intervals.full.days": "{number, plural, one {# n wass} other {# n wussan}}",
"intervals.full.hours": "{number, plural, one {# n usarag} other {# n yesragen}}", "intervals.full.hours": "{number, plural, one {# n usarag} other {# n yesragen}}",
@ -311,6 +336,7 @@
"navigation_bar.lists": "Tibdarin", "navigation_bar.lists": "Tibdarin",
"navigation_bar.logout": "Ffeɣ", "navigation_bar.logout": "Ffeɣ",
"navigation_bar.mutes": "Iseqdacen yettwasusmen", "navigation_bar.mutes": "Iseqdacen yettwasusmen",
"navigation_bar.opened_in_classic_interface": "Tisuffaɣ, imiḍanen akked isebtar-nniḍen igejdanen ldin-d s wudem amezwer deg ugrudem web aklasiki.",
"navigation_bar.personal": "Udmawan", "navigation_bar.personal": "Udmawan",
"navigation_bar.pins": "Tisuffaɣ yettwasenṭḍen", "navigation_bar.pins": "Tisuffaɣ yettwasenṭḍen",
"navigation_bar.preferences": "Imenyafen", "navigation_bar.preferences": "Imenyafen",
@ -361,12 +387,18 @@
"onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!", "onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!",
"onboarding.follows.title": "Popular on Mastodon", "onboarding.follows.title": "Popular on Mastodon",
"onboarding.profile.display_name": "Isem ara d-yettwaskanen", "onboarding.profile.display_name": "Isem ara d-yettwaskanen",
"onboarding.profile.note_hint": "Tzemreḍ ad d-@tbedreḍ imdanen niḍen neɣ #ihacṭagen …",
"onboarding.profile.save_and_continue": "Sekles, tkemmleḍ",
"onboarding.profile.title": "Asbadu n umaɣnu",
"onboarding.profile.upload_avatar": "Sali tugna n umaɣnu",
"onboarding.profile.upload_header": "Sali tacacit n umaɣnu",
"onboarding.share.lead": "Ini-asen i medden amek ara k·m-id-afen deg Mastodon!",
"onboarding.share.message": "Nekk d {username} deg #Mastodon! Ḍfer iyi-d sya {url}", "onboarding.share.message": "Nekk d {username} deg #Mastodon! Ḍfer iyi-d sya {url}",
"onboarding.share.title": "Bḍu amaɣnu-inek·inem", "onboarding.share.title": "Bḍu amaɣnu-inek·inem",
"onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:", "onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:",
"onboarding.start.skip": "Want to skip right ahead?", "onboarding.start.skip": "Want to skip right ahead?",
"onboarding.start.title": "Tseggmeḍ-tt !", "onboarding.start.title": "Tseggmeḍ-tt !",
"onboarding.steps.follow_people.body": "You curate your own feed. Lets fill it with interesting people.", "onboarding.steps.follow_people.body": "Aḍfer n medden yelhan, d tikti n Mastodon.",
"onboarding.steps.follow_people.title": "Follow {count, plural, one {one person} other {# people}}", "onboarding.steps.follow_people.title": "Follow {count, plural, one {one person} other {# people}}",
"onboarding.steps.publish_status.body": "Say hello to the world.", "onboarding.steps.publish_status.body": "Say hello to the world.",
"onboarding.steps.publish_status.title": "Aru tasuffeɣt-inek·inem tamezwarutt", "onboarding.steps.publish_status.title": "Aru tasuffeɣt-inek·inem tamezwarutt",
@ -377,6 +409,7 @@
"picture_in_picture.restore": "Err-it amkan-is", "picture_in_picture.restore": "Err-it amkan-is",
"poll.closed": "Tfukk", "poll.closed": "Tfukk",
"poll.refresh": "Smiren", "poll.refresh": "Smiren",
"poll.reveal": "Wali igmaḍ",
"poll.total_people": "{count, plural, one {# n wemdan} other {# n yemdanen}}", "poll.total_people": "{count, plural, one {# n wemdan} other {# n yemdanen}}",
"poll.total_votes": "{count, plural, one {# n udɣaṛ} other {# n yedɣaṛen}}", "poll.total_votes": "{count, plural, one {# n udɣaṛ} other {# n yedɣaṛen}}",
"poll.vote": "Dɣeṛ", "poll.vote": "Dɣeṛ",
@ -385,10 +418,13 @@
"poll_button.remove_poll": "Kkes asenqed", "poll_button.remove_poll": "Kkes asenqed",
"privacy.change": "Seggem tabaḍnit n yizen", "privacy.change": "Seggem tabaḍnit n yizen",
"privacy.direct.long": "Wid akk i d-yettwabdaren deg tuffeɣt", "privacy.direct.long": "Wid akk i d-yettwabdaren deg tuffeɣt",
"privacy.direct.short": "Imdanen ulmisen",
"privacy.private.long": "Ala wid i k-yeṭṭafaṛen", "privacy.private.long": "Ala wid i k-yeṭṭafaṛen",
"privacy.private.short": "Imeḍfaren", "privacy.private.short": "Imeḍfaren",
"privacy.public.long": "Kra n win yellan deg Masṭudun neɣ berra-s", "privacy.public.long": "Kra n win yellan deg Masṭudun neɣ berra-s",
"privacy.public.short": "Azayez", "privacy.public.short": "Azayez",
"privacy.unlisted.long": "Kra kan n ilguritmen",
"privacy_policy.last_updated": "Aleqqem aneggaru {date}",
"privacy_policy.title": "Tasertit tabaḍnit", "privacy_policy.title": "Tasertit tabaḍnit",
"refresh": "Smiren", "refresh": "Smiren",
"regeneration_indicator.label": "Yessalay-d…", "regeneration_indicator.label": "Yessalay-d…",
@ -412,9 +448,11 @@
"report.next": "Uḍfiṛ", "report.next": "Uḍfiṛ",
"report.placeholder": "Iwenniten-nniḍen", "report.placeholder": "Iwenniten-nniḍen",
"report.reasons.dislike": "Ur t-ḥemmleɣ ara", "report.reasons.dislike": "Ur t-ḥemmleɣ ara",
"report.reasons.other": "D ayen nniḍen",
"report.reasons.spam": "D aspam", "report.reasons.spam": "D aspam",
"report.submit": "Azen", "report.submit": "Azen",
"report.target": "Mmel {target}", "report.target": "Mmel {target}",
"report.thanks.title": "Ur tebɣiḍ ara ad twaliḍ aya?",
"report.unfollow": "Seḥbes aḍfar n @{name}", "report.unfollow": "Seḥbes aḍfar n @{name}",
"report_notification.attached_statuses": "{count, plural, one {# post} other {# posts}} attached", "report_notification.attached_statuses": "{count, plural, one {# post} other {# posts}} attached",
"report_notification.categories.other": "Ayen nniḍen", "report_notification.categories.other": "Ayen nniḍen",
@ -422,7 +460,13 @@
"report_notification.open": "Ldi aneqqis", "report_notification.open": "Ldi aneqqis",
"search.no_recent_searches": "Ulac inadiyen ineggura", "search.no_recent_searches": "Ulac inadiyen ineggura",
"search.placeholder": "Nadi", "search.placeholder": "Nadi",
"search.quick_action.account_search": "Imaɣnuten mṣadan d {x}",
"search.quick_action.go_to_account": "Ddu ɣer umaɣnu {x}",
"search.quick_action.go_to_hashtag": "Ddu ɣer uhacṭag {x}",
"search.quick_action.open_url": "Ldi tansa URL deg Mastodon",
"search.quick_action.status_search": "Tisuffaɣ mṣadan d {x}",
"search.search_or_paste": "Nadi neɣ senṭeḍ URL", "search.search_or_paste": "Nadi neɣ senṭeḍ URL",
"search_popout.full_text_search_disabled_message": "Ur yelli ara deg {domain}.",
"search_popout.language_code": "Tangalt ISO n tutlayt", "search_popout.language_code": "Tangalt ISO n tutlayt",
"search_popout.options": "Iwellihen n unadi", "search_popout.options": "Iwellihen n unadi",
"search_popout.recent": "Inadiyen ineggura", "search_popout.recent": "Inadiyen ineggura",
@ -471,6 +515,7 @@
"status.report": "Cetki ɣef @{name}", "status.report": "Cetki ɣef @{name}",
"status.sensitive_warning": "Agbur amḥulfu", "status.sensitive_warning": "Agbur amḥulfu",
"status.share": "Bḍu", "status.share": "Bḍu",
"status.show_filter_reason": "Ssken-d akken yebɣu yili",
"status.show_less": "Ssken-d drus", "status.show_less": "Ssken-d drus",
"status.show_less_all": "Semẓi akk tisuffɣin", "status.show_less_all": "Semẓi akk tisuffɣin",
"status.show_more": "Ssken-d ugar", "status.show_more": "Ssken-d ugar",
@ -516,6 +561,7 @@
"upload_modal.preparing_ocr": "Aheyyi n OCR…", "upload_modal.preparing_ocr": "Aheyyi n OCR…",
"upload_modal.preview_label": "Taskant ({ratio})", "upload_modal.preview_label": "Taskant ({ratio})",
"upload_progress.label": "Asali iteddu...", "upload_progress.label": "Asali iteddu...",
"username.taken": "Yettwaṭṭef yisem-a n useqdac. Ɛreḍ wayeḍ",
"video.close": "Mdel tabidyutt", "video.close": "Mdel tabidyutt",
"video.download": "Sidered afaylu", "video.download": "Sidered afaylu",
"video.exit_fullscreen": "Ffeɣ seg ugdil ačuran", "video.exit_fullscreen": "Ffeɣ seg ugdil ačuran",

View file

@ -27,8 +27,8 @@
"account.domain_blocked": "Užblokuotas domenas", "account.domain_blocked": "Užblokuotas domenas",
"account.edit_profile": "Redaguoti profilį", "account.edit_profile": "Redaguoti profilį",
"account.enable_notifications": "Pranešti man, kai @{name} paskelbia", "account.enable_notifications": "Pranešti man, kai @{name} paskelbia",
"account.endorse": "Rekomenduoti profilyje", "account.endorse": "Rodyti profilyje",
"account.featured_tags.last_status_at": "Paskutinį kartą paskelbta {date}", "account.featured_tags.last_status_at": "Paskutinis įrašas {date}",
"account.featured_tags.last_status_never": "Nėra įrašų", "account.featured_tags.last_status_never": "Nėra įrašų",
"account.featured_tags.title": "{name} rekomenduojami saitažodžiai", "account.featured_tags.title": "{name} rekomenduojami saitažodžiai",
"account.follow": "Sekti", "account.follow": "Sekti",
@ -53,7 +53,7 @@
"account.mute_notifications_short": "Nutildyti pranešimus", "account.mute_notifications_short": "Nutildyti pranešimus",
"account.mute_short": "Nutildyti", "account.mute_short": "Nutildyti",
"account.muted": "Nutildytas", "account.muted": "Nutildytas",
"account.mutual": "Abipusis", "account.mutual": "Bendri",
"account.no_bio": "Nėra pateikto aprašymo.", "account.no_bio": "Nėra pateikto aprašymo.",
"account.open_original_page": "Atidaryti originalinį puslapį", "account.open_original_page": "Atidaryti originalinį puslapį",
"account.posts": "Įrašai", "account.posts": "Įrašai",
@ -72,7 +72,7 @@
"account.unmute": "Atšaukti nutildymą @{name}", "account.unmute": "Atšaukti nutildymą @{name}",
"account.unmute_notifications_short": "Atšaukti nutildymą pranešimams", "account.unmute_notifications_short": "Atšaukti nutildymą pranešimams",
"account.unmute_short": "Atšaukti nutildymą", "account.unmute_short": "Atšaukti nutildymą",
"account_note.placeholder": "Spustelėk norėdamas (-a) pridėti pastabą", "account_note.placeholder": "Spustelėk norint pridėti pastabą.",
"admin.dashboard.daily_retention": "Naudotojų pasilikimo rodiklis pagal dieną po registracijos", "admin.dashboard.daily_retention": "Naudotojų pasilikimo rodiklis pagal dieną po registracijos",
"admin.dashboard.monthly_retention": "Naudotojų pasilikimo rodiklis pagal mėnesį po registracijos", "admin.dashboard.monthly_retention": "Naudotojų pasilikimo rodiklis pagal mėnesį po registracijos",
"admin.dashboard.retention.average": "Vidurkis", "admin.dashboard.retention.average": "Vidurkis",
@ -89,21 +89,21 @@
"announcement.announcement": "Skelbimas", "announcement.announcement": "Skelbimas",
"attachments_list.unprocessed": "(neapdorotas)", "attachments_list.unprocessed": "(neapdorotas)",
"audio.hide": "Slėpti garsą", "audio.hide": "Slėpti garsą",
"boost_modal.combo": "Gali paspausti {combo}, kad praleisti kitą kartą", "boost_modal.combo": "Galima paspausti {combo}, kad praleisti kitą kartą.",
"bundle_column_error.copy_stacktrace": "Kopijuoti klaidos ataskaitą", "bundle_column_error.copy_stacktrace": "Kopijuoti klaidos ataskaitą",
"bundle_column_error.error.body": "Užklausos puslapio nepavyko atvaizduoti. Tai gali būti dėl mūsų kodo klaidos arba naršyklės suderinamumo problemos.", "bundle_column_error.error.body": "Paprašytos puslapio nepavyko atvaizduoti. Tai gali būti dėl mūsų kodo klaidos arba naršyklės suderinamumo problemos.",
"bundle_column_error.error.title": "O, ne!", "bundle_column_error.error.title": "O, ne!",
"bundle_column_error.network.body": "Bandant užkrauti šį puslapį įvyko klaida. Tai galėjo atsitikti dėl laikinos tavo interneto ryšio arba šio serverio problemos.", "bundle_column_error.network.body": "Bandant užkrauti šį puslapį įvyko klaida. Tai galėjo atsitikti dėl laikinos tavo interneto ryšio arba šio serverio problemos.",
"bundle_column_error.network.title": "Tinklo klaida", "bundle_column_error.network.title": "Tinklo klaida",
"bundle_column_error.retry": "Bandyti dar kartą", "bundle_column_error.retry": "Bandyti dar kartą",
"bundle_column_error.return": "Grįžti į pradžią", "bundle_column_error.return": "Grįžti į pagrindinį",
"bundle_column_error.routing.body": "Prašyto puslapio nepavyko rasti. Ar esi tikras (-a), kad adreso juostoje nurodytas URL adresas yra teisingas?", "bundle_column_error.routing.body": "Prašyto puslapio nepavyko rasti. Ar esi tikras (-a), kad adreso juostoje nurodytas URL adresas yra teisingas?",
"bundle_column_error.routing.title": "404", "bundle_column_error.routing.title": "404",
"bundle_modal_error.close": "Uždaryti", "bundle_modal_error.close": "Uždaryti",
"bundle_modal_error.message": "Kraunant šį komponentą kažkas nepavyko.", "bundle_modal_error.message": "Kraunant šį komponentą kažkas nepavyko.",
"bundle_modal_error.retry": "Bandyti dar kartą", "bundle_modal_error.retry": "Bandyti dar kartą",
"closed_registrations.other_server_instructions": "Kadangi Mastodon yra decentralizuotas, gali susikurti paskyrą kitame serveryje ir vis tiek bendrauti su šiuo serveriu.", "closed_registrations.other_server_instructions": "Kadangi Mastodon yra decentralizuotas, gali susikurti paskyrą kitame serveryje ir vis tiek bendrauti su šiuo serveriu.",
"closed_registrations_modal.description": "Sukurti paskyrą {domain} šiuo metu neįmanoma, tačiau nepamiršk, kad norint naudotis Mastodon nebūtina turėti paskyrą domene {domain}.", "closed_registrations_modal.description": "Sukurti paskyrą {domain} šiuo metu neįmanoma, bet nepamiršk, kad norint naudotis Mastodon nebūtina turėti paskyrą domene {domain}.",
"closed_registrations_modal.find_another_server": "Rasti kitą serverį", "closed_registrations_modal.find_another_server": "Rasti kitą serverį",
"closed_registrations_modal.preamble": "Mastodon yra decentralizuotas, todėl nesvarbu, kur susikursi paskyrą, galėsi sekti ir bendrauti su bet kuriuo šiame serveryje esančiu asmeniu. Jį gali net savarankiškai talpinti!", "closed_registrations_modal.preamble": "Mastodon yra decentralizuotas, todėl nesvarbu, kur susikursi paskyrą, galėsi sekti ir bendrauti su bet kuriuo šiame serveryje esančiu asmeniu. Jį gali net savarankiškai talpinti!",
"closed_registrations_modal.title": "Užsiregistruoti Mastodon", "closed_registrations_modal.title": "Užsiregistruoti Mastodon",
@ -116,7 +116,7 @@
"column.domain_blocks": "Užblokuoti domenai", "column.domain_blocks": "Užblokuoti domenai",
"column.favourites": "Mėgstamiausi", "column.favourites": "Mėgstamiausi",
"column.firehose": "Tiesioginiai srautai", "column.firehose": "Tiesioginiai srautai",
"column.follow_requests": "Sekimo prašymus", "column.follow_requests": "Sekimo prašymai",
"column.home": "Pagrindinis", "column.home": "Pagrindinis",
"column.lists": "Sąrašai", "column.lists": "Sąrašai",
"column.mutes": "Nutildyti naudotojai", "column.mutes": "Nutildyti naudotojai",
@ -131,7 +131,7 @@
"column_header.show_settings": "Rodyti nustatymus", "column_header.show_settings": "Rodyti nustatymus",
"column_header.unpin": "Atsegti", "column_header.unpin": "Atsegti",
"column_subheading.settings": "Nustatymai", "column_subheading.settings": "Nustatymai",
"community.column_settings.local_only": "Tik vietinis", "community.column_settings.local_only": "Tik vietinė",
"community.column_settings.media_only": "Tik medija", "community.column_settings.media_only": "Tik medija",
"community.column_settings.remote_only": "Tik nuotolinis", "community.column_settings.remote_only": "Tik nuotolinis",
"compose.language.change": "Keisti kalbą", "compose.language.change": "Keisti kalbą",
@ -140,17 +140,17 @@
"compose.published.open": "Atidaryti", "compose.published.open": "Atidaryti",
"compose.saved.body": "Įrašas išsaugotas.", "compose.saved.body": "Įrašas išsaugotas.",
"compose_form.direct_message_warning_learn_more": "Sužinoti daugiau", "compose_form.direct_message_warning_learn_more": "Sužinoti daugiau",
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.", "compose_form.encryption_warning": "Mastodon įrašai nėra šifruojami nuo galo iki galo. Per Mastodon nesidalyk jokia slapta informacija.",
"compose_form.hashtag_warning": "Šis įrašas nebus įtraukta į jokį saitažodį, nes ji nėra vieša. Tik viešų įrašų galima ieškoti pagal saitažodį.", "compose_form.hashtag_warning": "Šis įrašas nebus įtraukta į jokį saitažodį, nes ji nėra vieša. Tik viešų įrašų galima ieškoti pagal saitažodį.",
"compose_form.lock_disclaimer": "Tavo paskyra nėra {locked}. Bet kas gali sekti tave ir peržiūrėti tik sekėjams skirtus įrašus.", "compose_form.lock_disclaimer": "Tavo paskyra nėra {locked}. Bet kas gali sekti tave ir peržiūrėti tik sekėjams skirtus įrašus.",
"compose_form.lock_disclaimer.lock": "užrakinta", "compose_form.lock_disclaimer.lock": "užrakinta",
"compose_form.placeholder": "Kas tavo mintyse?", "compose_form.placeholder": "Kas tavo mintyse?",
"compose_form.poll.duration": "Apklausos trukmė", "compose_form.poll.duration": "Apklausos trukmė",
"compose_form.poll.multiple": "Keli pasirinkimai", "compose_form.poll.multiple": "Keli pasirinkimai",
"compose_form.poll.option_placeholder": "{number} pasirinkimas", "compose_form.poll.option_placeholder": "{number} parinktis",
"compose_form.poll.single": "Pasirinkti vieną", "compose_form.poll.single": "Pasirinkti vieną",
"compose_form.poll.switch_to_multiple": "Keisti apklausą, kad būtų galima pasirinkti kelis pasirinkimus", "compose_form.poll.switch_to_multiple": "Keisti apklausą, kad būtų galima pasirinkti kelis pasirinkimus.",
"compose_form.poll.switch_to_single": "Pakeisti apklausą, kad būtų galima pasirinkti vieną variantą", "compose_form.poll.switch_to_single": "Keisti apklausą, kad būtų galima pasirinkti vieną pasirinkimą",
"compose_form.poll.type": "Stilius", "compose_form.poll.type": "Stilius",
"compose_form.publish": "Skelbti", "compose_form.publish": "Skelbti",
"compose_form.publish_form": "Naujas įrašas", "compose_form.publish_form": "Naujas įrašas",
@ -166,24 +166,26 @@
"confirmations.cancel_follow_request.confirm": "Atšaukti prašymą", "confirmations.cancel_follow_request.confirm": "Atšaukti prašymą",
"confirmations.cancel_follow_request.message": "Ar tikrai nori atšaukti savo prašymą sekti {name}?", "confirmations.cancel_follow_request.message": "Ar tikrai nori atšaukti savo prašymą sekti {name}?",
"confirmations.delete.confirm": "Ištrinti", "confirmations.delete.confirm": "Ištrinti",
"confirmations.delete.message": "Are you sure you want to delete this status?", "confirmations.delete.message": "Ar tikrai nori ištrinti šį įrašą?",
"confirmations.delete_list.confirm": "Ištrinti", "confirmations.delete_list.confirm": "Ištrinti",
"confirmations.delete_list.message": "Ar tikrai nori visam laikui ištrinti šį sąrašą?", "confirmations.delete_list.message": "Ar tikrai nori visam laikui ištrinti šį sąrašą?",
"confirmations.discard_edit_media.confirm": "Atmesti", "confirmations.discard_edit_media.confirm": "Atmesti",
"confirmations.discard_edit_media.message": "Turi neišsaugotų medijos aprašymo ar peržiūros pakeitimų, vis tiek juos atmesti?", "confirmations.discard_edit_media.message": "Turi neišsaugotų medijos aprašymo ar peržiūros pakeitimų, vis tiek juos atmesti?",
"confirmations.domain_block.confirm": "Hide entire domain", "confirmations.domain_block.confirm": "Blokuoti visą domeną",
"confirmations.domain_block.message": "Ar tikrai, tikrai nori užblokuoti visą {domain}? Daugeliu atvejų užtenka kelių tikslinių blokavimų arba nutildymų. Šio domeno turinio nematysi jokiose viešose laiko skalėse ar pranešimuose. Tavo sekėjai iš to domeno bus pašalinti.",
"confirmations.edit.confirm": "Redaguoti", "confirmations.edit.confirm": "Redaguoti",
"confirmations.edit.message": "Redaguojant dabar, bus perrašyta šiuo metu kuriama žinutė. Ar tikrai nori tęsti?", "confirmations.edit.message": "Redaguojant dabar, bus perrašyta šiuo metu kuriama žinutė. Ar tikrai nori tęsti?",
"confirmations.logout.confirm": "Atsijungti", "confirmations.logout.confirm": "Atsijungti",
"confirmations.logout.message": "Ar tikrai nori atsijungti?", "confirmations.logout.message": "Ar tikrai nori atsijungti?",
"confirmations.mute.confirm": "Nutildyti", "confirmations.mute.confirm": "Nutildyti",
"confirmations.mute.explanation": "Tai paslėps jų įrašus ir įrašus, kuriuose jie menėmi, tačiau jie vis tiek galės matyti tavo įrašus ir sekti.", "confirmations.mute.explanation": "Tai paslėps jų įrašus ir įrašus, kuriuose jie menėmi, bet jie vis tiek galės matyti tavo įrašus ir sekti.",
"confirmations.mute.message": "Ar tikrai norite nutildyti {name}?", "confirmations.mute.message": "Ar tikrai nori nutildyti {name}?",
"confirmations.redraft.confirm": "Ištrinti ir perrašyti", "confirmations.redraft.confirm": "Ištrinti ir parengti iš naujo",
"confirmations.redraft.message": "Ar tikrai nori ištrinti šį įrašą ir parengti jį iš naujo kaip juodraštį? Bus prarastos mėgstamiausios ir pakėlimai, o atsakymai į originalinį įrašą taps liekamojais.",
"confirmations.reply.confirm": "Atsakyti", "confirmations.reply.confirm": "Atsakyti",
"confirmations.reply.message": "Atsakant dabar, bus perrašyta metu kuriama žinutė. Ar tikrai nori tęsti?", "confirmations.reply.message": "Atsakant dabar, bus perrašyta metu kuriama žinutė. Ar tikrai nori tęsti?",
"confirmations.unfollow.confirm": "Nebesekti", "confirmations.unfollow.confirm": "Nebesekti",
"confirmations.unfollow.message": "Ar tikrai norite atsisakyti sekimo {name}?", "confirmations.unfollow.message": "Ar tikrai nori nebesekti {name}?",
"conversation.delete": "Ištrinti pokalbį", "conversation.delete": "Ištrinti pokalbį",
"conversation.mark_as_read": "Žymėti kaip skaitytą", "conversation.mark_as_read": "Žymėti kaip skaitytą",
"conversation.open": "Peržiūrėti pokalbį", "conversation.open": "Peržiūrėti pokalbį",
@ -191,87 +193,94 @@
"copy_icon_button.copied": "Nukopijuota į iškarpinę", "copy_icon_button.copied": "Nukopijuota į iškarpinę",
"copypaste.copied": "Nukopijuota", "copypaste.copied": "Nukopijuota",
"copypaste.copy_to_clipboard": "Kopijuoti į iškarpinę", "copypaste.copy_to_clipboard": "Kopijuoti į iškarpinę",
"directory.local": "Iš {domain} tik", "directory.federated": "Iš žinomų fediversų",
"directory.new_arrivals": "Naujos prekės", "directory.local": "Tik iš {domain}",
"directory.recently_active": "Neseniai aktyvus", "directory.new_arrivals": "Nauji atvykėliai",
"directory.recently_active": "Neseniai aktyvus (-i)",
"disabled_account_banner.account_settings": "Paskyros nustatymai", "disabled_account_banner.account_settings": "Paskyros nustatymai",
"disabled_account_banner.text": "Jūsų paskyra {disabledAccount} šiuo metu yra išjungta.", "disabled_account_banner.text": "Tavo paskyra {disabledAccount} šiuo metu išjungta.",
"dismissable_banner.community_timeline": "Tai naujausi vieši įrašai, kuriuos paskelbė žmonės, kurių paskyros talpinamos {domain}.",
"dismissable_banner.dismiss": "Atmesti", "dismissable_banner.dismiss": "Atmesti",
"dismissable_banner.explore_links": "These news stories are being talked about by people on this and other servers of the decentralized network right now.", "dismissable_banner.explore_links": "Tai naujienos, kuriomis šiandien daugiausiai bendrinamasi socialiniame žiniatinklyje. Naujesnės naujienų istorijos, kurias paskelbė daugiau skirtingų žmonių, vertinamos aukščiau.",
"dismissable_banner.explore_statuses": "Tai įrašai iš viso socialinio tinklo, kurie šiandien sulaukia vis daugiau dėmesio. Naujesni įrašai, turintys daugiau boosts ir mėgstamiausių įrašų, yra vertinami aukščiau.", "dismissable_banner.explore_statuses": "Tai įrašai iš viso socialinio žiniatinklio, kurie šiandien sulaukia daug dėmesio. Naujesni įrašai, turintys daugiau pakėlimų ir mėgstamų, vertinami aukščiau.",
"dismissable_banner.explore_tags": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.", "dismissable_banner.explore_tags": "Tai saitažodžiai, kurie šiandien sulaukia daug dėmesio socialiniame žiniatinklyje. Saitažodžiai, kuriuos naudoja daugiau skirtingų žmonių, vertinami aukščiau.",
"embed.instructions": "Embed this status on your website by copying the code below.", "dismissable_banner.public_timeline": "Tai naujausi vieši įrašai, kuriuos socialiniame žiniatinklyje paskelbė žmonės, sekantys {domain}.",
"embed.preview": "Štai kaip tai atrodys:", "embed.instructions": "Įterpk šį įrašą į savo svetainę nukopijavus (-usi) toliau pateiktą kodą.",
"embed.preview": "Štai, kaip tai atrodys:",
"emoji_button.activity": "Veikla", "emoji_button.activity": "Veikla",
"emoji_button.clear": "Išvalyti", "emoji_button.clear": "Išvalyti",
"emoji_button.custom": "Pasirinktinis", "emoji_button.custom": "Pasirinktinis",
"emoji_button.flags": "Vėliavos", "emoji_button.flags": "Vėliavos",
"emoji_button.food": "Maistas ir Gėrimai", "emoji_button.food": "Maistas ir gėrimai",
"emoji_button.label": "Įterpti veidelius", "emoji_button.label": "Įterpti veidelius",
"emoji_button.nature": "Gamta", "emoji_button.nature": "Gamta",
"emoji_button.not_found": "Nerasta jokių tinkamų jaustukų", "emoji_button.not_found": "Nerasta jokių tinkamų jaustukų.",
"emoji_button.objects": "Objektai", "emoji_button.objects": "Objektai",
"emoji_button.people": "Žmonės", "emoji_button.people": "Žmonės",
"emoji_button.recent": "Dažniausiai naudojama", "emoji_button.recent": "Dažniausiai naudojami",
"emoji_button.search": "Paieška...", "emoji_button.search": "Ieškoti...",
"emoji_button.search_results": "Paieškos rezultatai", "emoji_button.search_results": "Paieškos rezultatai",
"emoji_button.symbols": "Simboliai", "emoji_button.symbols": "Simboliai",
"emoji_button.travel": "Kelionės ir Vietos", "emoji_button.travel": "Kelionės ir vietos",
"empty_column.account_hides_collections": "Šis naudotojas (-a) pasirinko nepadaryti šią informaciją prieinamą", "empty_column.account_hides_collections": "Šis (-i) naudotojas (-a) pasirinko nepadaryti šią informaciją prieinamą.",
"empty_column.account_suspended": "Paskyra sustabdyta", "empty_column.account_suspended": "Paskyra sustabdyta.",
"empty_column.account_timeline": "No toots here!", "empty_column.account_timeline": "Nėra įrašų čia.",
"empty_column.account_unavailable": "Profilis neprieinamas", "empty_column.account_unavailable": "Profilis neprieinamas.",
"empty_column.blocks": "Dar neužblokavote nė vieno naudotojo.", "empty_column.blocks": "Dar neužblokavai nė vieno naudotojo.",
"empty_column.bookmarked_statuses": "You don't have any bookmarked toots yet. When you bookmark one, it will show up here.", "empty_column.bookmarked_statuses": "Dar neturi nė vienos įrašo žymės. Kai vieną iš jų pridėsi į žymes, jis bus rodomas čia.",
"empty_column.community": "Vietinė laiko juosta yra tuščia. Parašykite ką nors viešai, kad pradėtumėte veikti!", "empty_column.community": "Vietinė laiko skalė tuščia. Parašyk ką nors viešai, kad pradėtum bendrauti!",
"empty_column.direct": "Dar neturite jokių privačių paminėjimų. Kai išsiųsite arba gausite tokį pranešimą, jis bus rodomas čia.", "empty_column.direct": "Dar neturi jokių privačių paminėjimų. Kai išsiųsi arba gausi vieną iš jų, jis bus rodomas čia.",
"empty_column.domain_blocks": "There are no hidden domains yet.", "empty_column.domain_blocks": "Dar nėra užblokuotų domenų.",
"empty_column.favourited_statuses": "Dar neturite mėgstamiausių įrašų. Kai vieną iš jų pamėgsite, jis bus rodomas čia.", "empty_column.explore_statuses": "Šiuo metu niekas nėra tendencinga. Patikrink vėliau.",
"empty_column.follow_requests": "Dar neturite jokių sekimo užklausų. Kai gausite tokį prašymą, jis bus rodomas čia.", "empty_column.favourited_statuses": "Dar neturi mėgstamų įrašų. Kai vieną iš jų pamėgsi, jis bus rodomas čia.",
"empty_column.followed_tags": "Dar nesekėte jokių grotažymių. Kai tai padarysite, jie bus rodomi čia.", "empty_column.favourites": "Šio įrašo dar niekas nepamėgo. Kai kas nors tai padarys, jie bus rodomi čia.",
"empty_column.follow_requests": "Dar neturi jokių sekimo prašymų. Kai gausi tokį prašymą, jis bus rodomas čia.",
"empty_column.followed_tags": "Dar neseki jokių saitažodžių. Kai tai padarysi, jie bus rodomi čia.",
"empty_column.hashtag": "Nėra nieko šiame saitažodyje kol kas.", "empty_column.hashtag": "Nėra nieko šiame saitažodyje kol kas.",
"empty_column.home": "Your home timeline is empty! Follow more people to fill it up. {suggestions}", "empty_column.home": "Tavo pagrindinio laiko skalė tuščia! Sek daugiau žmonių, kad ją užpildytum.",
"empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.", "empty_column.list": "Nėra nieko šiame sąraše kol kas. Kai šio sąrašo nariai paskelbs naujų įrašų, jie bus rodomi čia.",
"empty_column.lists": "Dar neturite jokių sąrašų. Kai jį sukursite, jis bus rodomas čia.", "empty_column.lists": "Dar neturi jokių sąrašų. Kai jį sukursi, jis bus rodomas čia.",
"empty_column.mutes": "Dar nesate nutildę nė vieno naudotojo.", "empty_column.mutes": "Dar nesi nutildęs (-usi) nė vieno naudotojo.",
"empty_column.notifications": "Dar neturite jokių pranešimų. Kai kiti žmonės su jumis bendraus, matysite tai čia.", "empty_column.notifications": "Dar neturi jokių pranešimų. Kai kiti žmonės su tavimi bendraus, matysi tai čia.",
"empty_column.public": "Čia nieko nėra! Parašykite ką nors viešai arba rankiniu būdu sekite naudotojus iš kitų serverių, kad jį užpildytumėte", "empty_column.public": "Čia nieko nėra! Parašyk ką nors viešai arba rankiniu būdu sek naudotojus iš kitų serverių, kad jį užpildytum.",
"error.unexpected_crash.explanation": "Dėl mūsų kodo klaidos arba naršyklės suderinamumo problemos šis puslapis negalėjo būti rodomas teisingai.", "error.unexpected_crash.explanation": "Dėl mūsų kodo riktos arba naršyklės suderinamumo problemos šis puslapis negalėjo būti rodomas teisingai.",
"error.unexpected_crash.explanation_addons": "Šį puslapį nepavyko teisingai parodyti. Šią klaidą greičiausiai sukėlė naršyklės priedas arba automatinio vertimo įrankiai.", "error.unexpected_crash.explanation_addons": "Šį puslapį nepavyko parodyti teisingai. Šią klaidą greičiausiai sukėlė naršyklės priedas arba automatinio vertimo įrankiai.",
"error.unexpected_crash.next_steps": "Pabandykite atnaujinti puslapį. Jei tai nepadeda, galbūt vis dar galėsite naudotis \"Mastodon\" naudodami kitą naršyklę arba vietinę programėlę.", "error.unexpected_crash.next_steps": "Pabandyk atnaujinti puslapį. Jei tai nepadeda, galbūt vis dar galėsi naudotis Mastodon per kitą naršyklę arba savąją programėlę.",
"error.unexpected_crash.next_steps_addons": "Pabandykite juos išjungti ir atnaujinti puslapį. Jei tai nepadeda, galbūt vis dar galėsite naudotis \"Mastodon\" naudodami kitą naršyklę arba vietinę programėlę.", "error.unexpected_crash.next_steps_addons": "Pabandyk juos išjungti ir atnaujinti puslapį. Jei tai nepadeda, galbūt vis dar galėsi naudotis Mastodon per kitą naršyklę arba savąją programėlę.",
"errors.unexpected_crash.report_issue": "Pranešti apie triktį", "errors.unexpected_crash.copy_stacktrace": "Kopijuoti dėklo eigą į iškarpinę",
"errors.unexpected_crash.report_issue": "Pranešti apie problemą",
"explore.search_results": "Paieškos rezultatai", "explore.search_results": "Paieškos rezultatai",
"explore.suggested_follows": "Žmonės", "explore.suggested_follows": "Žmonės",
"explore.title": "Naršyti", "explore.title": "Naršyti",
"explore.trending_links": "Naujienos", "explore.trending_links": "Naujienos",
"explore.trending_statuses": "Įrašai", "explore.trending_statuses": "Įrašai",
"explore.trending_tags": "Saitažodžiai", "explore.trending_tags": "Saitažodžiai",
"filter_modal.added.context_mismatch_explanation": "Ši filtro kategorija netaikoma kontekste, kuriame peržiūrėjote šį pranešimą. Jei norite, kad pranešimas būtų filtruojamas ir šiame kontekste, turėsite redaguoti filtrą.", "filter_modal.added.context_mismatch_explanation": "Ši filtro kategorija netaikoma kontekstui, kuriame peržiūrėjai šį įrašą. Jei nori, kad įrašas būtų filtruojamas ir šiame kontekste, turėsi redaguoti filtrą.",
"filter_modal.added.context_mismatch_title": "Konteksto neatitikimas!", "filter_modal.added.context_mismatch_title": "Konteksto neatitikimas.",
"filter_modal.added.expired_explanation": "Ši filtro kategorija nustojo galioti, kad ji būtų taikoma, turėsite pakeisti galiojimo datą.", "filter_modal.added.expired_explanation": "Ši filtro kategorija nustojo galioti. Kad ji būtų taikoma, turėsi pakeisti galiojimo datą.",
"filter_modal.added.expired_title": "Pasibaigė filtro galiojimo laikas!", "filter_modal.added.expired_title": "Baigėsi filtro galiojimas.",
"filter_modal.added.review_and_configure": "Norėdami peržiūrėti ir toliau konfigūruoti šią filtro kategoriją, eikite į {settings_link}.", "filter_modal.added.review_and_configure": "Norint peržiūrėti ir toliau konfigūruoti šią filtro kategoriją, eik į nuorodą {settings_link}.",
"filter_modal.added.review_and_configure_title": "Filtro nuostatos", "filter_modal.added.review_and_configure_title": "Filtro nustatymai",
"filter_modal.added.settings_link": "nustatymų puslapis", "filter_modal.added.settings_link": "nustatymų puslapis",
"filter_modal.added.short_explanation": "Šis pranešimas buvo įtrauktas į šią filtro kategoriją: {title}.", "filter_modal.added.short_explanation": "Šis įrašas buvo pridėtas į šią filtro kategoriją: {title}.",
"filter_modal.added.title": "Pridėtas filtras!", "filter_modal.added.title": "Pridėtas filtras.",
"filter_modal.select_filter.context_mismatch": "netaikoma šiame kontekste", "filter_modal.select_filter.context_mismatch": "netaikoma šiame kontekste.",
"filter_modal.select_filter.expired": "nebegalioja", "filter_modal.select_filter.expired": "nebegalioja.",
"filter_modal.select_filter.prompt_new": "Nauja kategorija: {name}", "filter_modal.select_filter.prompt_new": "Nauja kategorija: {name}",
"filter_modal.select_filter.search": "Ieškoti arba sukurti", "filter_modal.select_filter.search": "Ieškoti arba sukurti",
"filter_modal.select_filter.subtitle": "Naudoti esamą kategoriją arba sukurti naują", "filter_modal.select_filter.subtitle": "Naudok esamą kategoriją arba sukurk naują.",
"filter_modal.select_filter.title": "Filtruoti šį įrašą", "filter_modal.select_filter.title": "Filtruoti šį įrašą",
"filter_modal.title.status": "Filtruoti šį įrašą", "filter_modal.title.status": "Filtruoti įrašą",
"firehose.all": "Visi", "firehose.all": "Visi",
"firehose.local": "Šis serveris", "firehose.local": "Šis serveris",
"firehose.remote": "Kiti serveriai", "firehose.remote": "Kiti serveriai",
"follow_request.authorize": "Autorizuoti", "follow_request.authorize": "Leisti",
"follow_request.reject": "Atmesti", "follow_request.reject": "Atmesti",
"follow_requests.unlocked_explanation": "Nors tavo paskyra neužrakinta, {domain} personalas mano, kad galbūt norėsi rankiniu būdu patikrinti šių paskyrų sekimo užklausas.", "follow_requests.unlocked_explanation": "Nors tavo paskyra neužrakinta, {domain} personalas mano, kad galbūt norėsi rankiniu būdu patikrinti šių paskyrų sekimo prašymus.",
"follow_suggestions.curated_suggestion": "Personalo pasirinkimai", "follow_suggestions.curated_suggestion": "Personalo pasirinkimai",
"follow_suggestions.dismiss": "Daugiau nerodyti", "follow_suggestions.dismiss": "Daugiau nerodyti",
"follow_suggestions.hints.friends_of_friends": "Šis profilis yra populiarus tarp žmonių, kuriuos sekei.", "follow_suggestions.hints.featured": "Šį profilį atrinko {domain} komanda.",
"follow_suggestions.hints.friends_of_friends": "Šis profilis yra populiarus tarp žmonių, kuriuos seki.",
"follow_suggestions.hints.most_followed": "Šis profilis yra vienas iš labiausiai sekamų {domain}.", "follow_suggestions.hints.most_followed": "Šis profilis yra vienas iš labiausiai sekamų {domain}.",
"follow_suggestions.hints.most_interactions": "Pastaruoju metu šis profilis sulaukia daug dėmesio šiame {domain}.", "follow_suggestions.hints.most_interactions": "Pastaruoju metu šis profilis sulaukia daug dėmesio šiame {domain}.",
"follow_suggestions.hints.similar_to_recently_followed": "Šis profilis panašus į profilius, kuriuos neseniai sekei.", "follow_suggestions.hints.similar_to_recently_followed": "Šis profilis panašus į profilius, kuriuos neseniai sekei.",
@ -279,7 +288,7 @@
"follow_suggestions.popular_suggestion": "Populiarus pasiūlymas", "follow_suggestions.popular_suggestion": "Populiarus pasiūlymas",
"follow_suggestions.view_all": "Peržiūrėti viską", "follow_suggestions.view_all": "Peržiūrėti viską",
"follow_suggestions.who_to_follow": "Ką sekti", "follow_suggestions.who_to_follow": "Ką sekti",
"followed_tags": "Sekamos saitažodžiai", "followed_tags": "Sekami saitažodžiai",
"footer.about": "Apie", "footer.about": "Apie",
"footer.directory": "Profilių katalogas", "footer.directory": "Profilių katalogas",
"footer.get_app": "Gauti programėlę", "footer.get_app": "Gauti programėlę",
@ -289,214 +298,243 @@
"footer.source_code": "Peržiūrėti šaltinio kodą", "footer.source_code": "Peržiūrėti šaltinio kodą",
"footer.status": "Būsena", "footer.status": "Būsena",
"generic.saved": "Išsaugoti", "generic.saved": "Išsaugoti",
"getting_started.heading": "Pradedant", "getting_started.heading": "Kaip pradėti",
"hashtag.column_header.tag_mode.all": "ir {additional}", "hashtag.column_header.tag_mode.all": "ir {additional}",
"hashtag.column_header.tag_mode.any": "ar {additional}", "hashtag.column_header.tag_mode.any": "ar {additional}",
"hashtag.column_header.tag_mode.none": "be {additional}", "hashtag.column_header.tag_mode.none": "be {additional}",
"hashtag.column_settings.select.no_options_message": "Pasiūlymų nerasta", "hashtag.column_settings.select.no_options_message": "Pasiūlymų nerasta.",
"hashtag.column_settings.select.placeholder": "Įvesti grotažymes…", "hashtag.column_settings.select.placeholder": "Įvesti saitažodžius…",
"hashtag.column_settings.tag_mode.all": "Visi šie", "hashtag.column_settings.tag_mode.all": "Visi šie",
"hashtag.column_settings.tag_mode.any": "Bet kuris šių", "hashtag.column_settings.tag_mode.any": "Bet kuris šių",
"hashtag.column_settings.tag_mode.none": "Nė vienas iš šių", "hashtag.column_settings.tag_mode.none": "Nė vienas iš šių",
"hashtag.column_settings.tag_toggle": "Include additional tags in this column", "hashtag.column_settings.tag_toggle": "Įtraukti papildomas šio stulpelio žymes",
"hashtag.counter_by_accounts": "{count, plural,one {{counter} dalyvis}other {{counter} dalyviai}}", "hashtag.counter_by_accounts": "{count, plural, one {{counter} dalyvis} few {{counter} dalyviai} many {{counter} dalyvio} other {{counter} dalyvių}}",
"hashtag.counter_by_uses": "{count, plural, one {{counter} įrašas} other {{counter} įrašų}}", "hashtag.counter_by_uses": "{count, plural, one {{counter} įrašas} few {{counter} įrašai} many {{counter} įrašo} other {{counter} įrašų}}",
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} įrašas} other {{counter} įrašų}} šiandien", "hashtag.counter_by_uses_today": "{count, plural, one {{counter} įrašas} few {{counter} įrašai} many {{counter} įrašo} other {{counter} įrašų}} šiandien",
"hashtag.follow": "Sekti grotažymę", "hashtag.follow": "Sekti saitažodį",
"hashtag.unfollow": "Nesekti grotažymės", "hashtag.unfollow": "Nebesekti saitažodį",
"hashtags.and_other": "…ir{count, plural,other {#daugiau}}", "hashtags.and_other": "…ir {count, plural, one {# daugiau} few {# daugiau} many {# daugiau}other {# daugiau}}",
"home.column_settings.basic": "Pagrindinis", "home.column_settings.basic": "Paprastas",
"home.column_settings.show_reblogs": "Rodyti \"boosts\"", "home.column_settings.show_reblogs": "Rodyti pakėlimus",
"home.column_settings.show_replies": "Rodyti atsakymus", "home.column_settings.show_replies": "Rodyti atsakymus",
"home.hide_announcements": "Slėpti skelbimus", "home.hide_announcements": "Slėpti skelbimus",
"home.pending_critical_update.link": "Žiūrėti atnaujinimus", "home.pending_critical_update.body": "Kuo greičiau atnaujink savo Mastodon serverį!",
"home.pending_critical_update.title": "Galimas kritinis saugumo atnaujinimas!", "home.pending_critical_update.link": "Žiūrėti naujinimus",
"home.pending_critical_update.title": "Galimas kritinis saugumo naujinimas.",
"home.show_announcements": "Rodyti skelbimus",
"interaction_modal.description.favourite": "Su Mastodon paskyra gali pamėgti šį įrašą, kad autorius (-ė) žinotų, jog vertinti tai ir išsaugoti jį vėliau.",
"interaction_modal.description.follow": "Su Mastodon paskyra gali sekti {name}, kad gautum jų įrašus į pagrindinį srautą.",
"interaction_modal.description.reblog": "Su Mastodon paskyra gali pakelti šią įrašą ir pasidalyti juo su savo sekėjais.",
"interaction_modal.description.reply": "Su Mastodon paskyra gali atsakyti į šį įrašą.",
"interaction_modal.login.action": "Į pagrindinį puslapį",
"interaction_modal.login.prompt": "Tavo pagrindinio serverio domenas, pvz., mastodon.social.",
"interaction_modal.no_account_yet": "Nesi Mastodon?", "interaction_modal.no_account_yet": "Nesi Mastodon?",
"interaction_modal.on_another_server": "Kitame serveryje", "interaction_modal.on_another_server": "Kitame serveryje",
"interaction_modal.on_this_server": "Šiame serveryje", "interaction_modal.on_this_server": "Šiame serveryje",
"interaction_modal.sign_in": "Nesi prisijungęs (-usi) prie šio serverio. Kur yra laikoma tavo paskyra?", "interaction_modal.sign_in": "Nesi prisijungęs (-usi) prie šio serverio. Kur yra talpinama tavo paskyra?",
"interaction_modal.sign_in_hint": "Patarimas: tai svetainė, kurioje užsiregistravai. Jei neprisimeni, ieškok sveikinimo el. laiško savo pašto dėžutėje. Taip pat gali įvesti visą savo naudotojo vardą (pvz., @Mastodon@mastodon.social).", "interaction_modal.sign_in_hint": "Patarimas: tai svetainė, kurioje užsiregistravai. Jei neprisimeni, ieškok sveikinimo el. laiško savo pašto dėžutėje. Taip pat gali įvesti visą savo naudotojo vardą (pvz., @Mastodon@mastodon.social).",
"interaction_modal.title.favourite": "Mėgstamiausias {name} įrašas", "interaction_modal.title.favourite": "Pamėgti {name} įrašą",
"interaction_modal.title.follow": "Sekti {name}", "interaction_modal.title.follow": "Sekti {name}",
"keyboard_shortcuts.back": "to navigate back", "interaction_modal.title.reblog": "Pakelti {name} įrašą",
"keyboard_shortcuts.blocked": "to open blocked users list", "interaction_modal.title.reply": "Atsakyti į {name} įrašą",
"keyboard_shortcuts.boost": "to boost", "intervals.full.days": "{number, plural, one {# diena} few {# dienos} many {# dienos} other {# dienų}}",
"keyboard_shortcuts.column": "to focus a status in one of the columns", "intervals.full.hours": "{number, plural, one {# valanda} few {# valandos} many {# valandos} other {# valandų}}",
"keyboard_shortcuts.compose": "to focus the compose textarea", "intervals.full.minutes": "{number, plural, one {# minutė} few {# minutes} many {# minutės} other {# minučių}}",
"keyboard_shortcuts.direct": "to open direct messages column", "keyboard_shortcuts.back": "Naršyti atgal",
"keyboard_shortcuts.down": "to move down in the list", "keyboard_shortcuts.blocked": "Atidaryti užblokuotų naudotojų sąrašą",
"keyboard_shortcuts.enter": "to open status", "keyboard_shortcuts.boost": "Pakelti įrašą",
"keyboard_shortcuts.federated": "to open federated timeline", "keyboard_shortcuts.column": "Fokusuoti stulpelį",
"keyboard_shortcuts.heading": "Keyboard Shortcuts", "keyboard_shortcuts.compose": "Fokusuoti rengykles teksto sritį",
"keyboard_shortcuts.home": "to open home timeline", "keyboard_shortcuts.description": "Aprašymas",
"keyboard_shortcuts.direct": "atidaryti privačių paminėjimų stulpelį",
"keyboard_shortcuts.down": "Perkelti žemyn sąraše",
"keyboard_shortcuts.enter": "Atidaryti įrašą",
"keyboard_shortcuts.favourite": "Pamėgti įrašą",
"keyboard_shortcuts.favourites": "Atidaryti mėgstamųjų sąrašą",
"keyboard_shortcuts.federated": "Atidaryti federacinę laiko skalę",
"keyboard_shortcuts.heading": "Spartieji klavišai",
"keyboard_shortcuts.home": "Atidaryti pagrindinį laiko skalę",
"keyboard_shortcuts.hotkey": "Spartusis klavišas", "keyboard_shortcuts.hotkey": "Spartusis klavišas",
"keyboard_shortcuts.legend": "to display this legend", "keyboard_shortcuts.legend": "Rodyti šią legendą",
"keyboard_shortcuts.local": "to open local timeline", "keyboard_shortcuts.local": "Atidaryti vietinę laiko skalę",
"keyboard_shortcuts.mention": "to mention author", "keyboard_shortcuts.mention": "Paminėti autorių (-ę)",
"keyboard_shortcuts.muted": "to open muted users list", "keyboard_shortcuts.muted": "Atidaryti nutildytų naudotojų sąrašą",
"keyboard_shortcuts.my_profile": "to open your profile", "keyboard_shortcuts.my_profile": "Atidaryti savo profilį",
"keyboard_shortcuts.notifications": "to open notifications column", "keyboard_shortcuts.notifications": "Atidaryti pranešimų stulpelį",
"keyboard_shortcuts.open_media": "Atidaryti mediją", "keyboard_shortcuts.open_media": "Atidaryti mediją",
"keyboard_shortcuts.pinned": "to open pinned toots list", "keyboard_shortcuts.pinned": "Atidaryti prisegtų įrašų sąrašą",
"keyboard_shortcuts.profile": "to open author's profile", "keyboard_shortcuts.profile": "Atidaryti autoriaus (-ės) profilį",
"keyboard_shortcuts.reply": "to reply", "keyboard_shortcuts.reply": "Atsakyti į įrašą",
"keyboard_shortcuts.requests": "to open follow requests list", "keyboard_shortcuts.requests": "Atidaryti sekimo prašymų sąrašą",
"keyboard_shortcuts.search": "to focus search", "keyboard_shortcuts.search": "Fokusuoti paieškos juostą",
"keyboard_shortcuts.spoilers": "to show/hide CW field", "keyboard_shortcuts.spoilers": "Rodyti / slėpti TĮ lauką",
"keyboard_shortcuts.start": "to open \"get started\" column", "keyboard_shortcuts.start": "Atidarykite stulpelį Kaip pradėti",
"keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW", "keyboard_shortcuts.toggle_hidden": "Rodyti / slėpti tekstą po TĮ",
"keyboard_shortcuts.toggle_sensitivity": "Rodyti / slėpti mediją", "keyboard_shortcuts.toggle_sensitivity": "Rodyti / slėpti mediją",
"keyboard_shortcuts.toot": "to start a brand new toot", "keyboard_shortcuts.toot": "Pradėti naują įrašą",
"keyboard_shortcuts.unfocus": "to un-focus compose textarea/search", "keyboard_shortcuts.unfocus": "Nebefokusuoti rengykles teksto sritį / paiešką",
"keyboard_shortcuts.up": "to move up in the list", "keyboard_shortcuts.up": "Perkelti į viršų sąraše",
"lightbox.close": "Uždaryti", "lightbox.close": "Uždaryti",
"lightbox.compress": "Suspausti vaizdo peržiūros langelį",
"lightbox.expand": "Išplėsti vaizdo peržiūros langelį",
"lightbox.next": "Kitas", "lightbox.next": "Kitas",
"lightbox.previous": "Ankstesnis", "lightbox.previous": "Ankstesnis",
"limited_account_hint.action": "Vis tiek rodyti profilį", "limited_account_hint.action": "Vis tiek rodyti profilį",
"limited_account_hint.title": "Šį profilį paslėpė {domain} moderatoriai.", "limited_account_hint.title": "Šį profilį paslėpė {domain} prižiūrėtojai.",
"link_preview.author": "Sukūrė {name}", "link_preview.author": "Sukūrė {name}",
"lists.account.add": "Pridėti į sąrašą", "lists.account.add": "Pridėti į sąrašą",
"lists.account.remove": "Pašalinti iš sąrašo", "lists.account.remove": "Pašalinti iš sąrašo",
"lists.delete": "Ištrinti sąrašą", "lists.delete": "Ištrinti sąrašą",
"lists.edit": "Redaguoti sąrašą", "lists.edit": "Redaguoti sąrašą",
"lists.edit.submit": "Prierašo pakeitimas", "lists.edit.submit": "Keisti pavadinimą",
"lists.exclusive": "Slėpti šiuos įrašus iš pagrindinio",
"lists.new.create": "Pridėti sąrašą", "lists.new.create": "Pridėti sąrašą",
"lists.new.title_placeholder": "Naujas sąrašo pavadinimas", "lists.new.title_placeholder": "Naujas sąrašo pavadinimas",
"lists.replies_policy.followed": "Bet kuris sekamas naudotojas", "lists.replies_policy.followed": "Bet kuriam sekamam naudotojui",
"lists.replies_policy.list": "Sąrašo nariai", "lists.replies_policy.list": "Sąrašo nariams",
"lists.replies_policy.none": "Nei vienas", "lists.replies_policy.none": "Nei vienam",
"lists.replies_policy.title": "Rodyti atsakymus:", "lists.replies_policy.title": "Rodyti atsakymus:",
"lists.search": "Ieškoti tarp sekamų žmonių", "lists.search": "Ieškoti tarp sekamų žmonių",
"lists.subheading": "Jūsų sąrašai", "lists.subheading": "Tavo sąrašai",
"load_pending": "{count, plural, one {# naujas elementas} few {# nauji elementai} many {# naujo elemento} other {# naujų elementų}}",
"loading_indicator.label": "Kraunama…", "loading_indicator.label": "Kraunama…",
"media_gallery.toggle_visible": "{number, plural, one {Slėpti vaizdą} few {Slėpti vaizdus} many {Slėpti vaizdo} other {Slėpti vaizdų}}", "media_gallery.toggle_visible": "{number, plural, one {Slėpti vaizdą} few {Slėpti vaizdus} many {Slėpti vaizdo} other {Slėpti vaizdų}}",
"moved_to_account_banner.text": "Tavo paskyra {disabledAccount} šiuo metu yra išjungta, nes persikėlei į {movedToAccount}.", "moved_to_account_banner.text": "Tavo paskyra {disabledAccount} šiuo metu išjungta, nes persikėlei į {movedToAccount}.",
"mute_modal.duration": "Trukmė", "mute_modal.duration": "Trukmė",
"mute_modal.hide_notifications": "Slėpti šio naudotojo pranešimus?", "mute_modal.hide_notifications": "Slėpti šio naudotojo pranešimus?",
"mute_modal.indefinite": "Neribotas", "mute_modal.indefinite": "Neribota",
"navigation_bar.about": "Apie", "navigation_bar.about": "Apie",
"navigation_bar.advanced_interface": "Atidarykite išplėstinę žiniatinklio sąsają", "navigation_bar.advanced_interface": "Atidaryti išplėstinę žiniatinklio sąsają",
"navigation_bar.blocks": "Užblokuoti naudotojai", "navigation_bar.blocks": "Užblokuoti naudotojai",
"navigation_bar.bookmarks": "Žymės", "navigation_bar.bookmarks": "Žymės",
"navigation_bar.compose": "Compose new toot", "navigation_bar.community_timeline": "Vietinė laiko skalė",
"navigation_bar.compose": "Sukurti naują įrašą",
"navigation_bar.direct": "Privatūs paminėjimai", "navigation_bar.direct": "Privatūs paminėjimai",
"navigation_bar.discover": "Atrasti", "navigation_bar.discover": "Atrasti",
"navigation_bar.domain_blocks": "Hidden domains", "navigation_bar.domain_blocks": "Užblokuoti domenai",
"navigation_bar.explore": "Naršyti", "navigation_bar.explore": "Naršyti",
"navigation_bar.favourites": "Mėgstamiausi", "navigation_bar.favourites": "Mėgstami",
"navigation_bar.filters": "Nutyti žodžiai", "navigation_bar.filters": "Nutildyti žodžiai",
"navigation_bar.follow_requests": "Sekti prašymus", "navigation_bar.follow_requests": "Sekimo prašymai",
"navigation_bar.followed_tags": "Sekti grotažymę", "navigation_bar.followed_tags": "Sekami saitažodžiai",
"navigation_bar.follows_and_followers": "Sekimai ir sekėjai", "navigation_bar.follows_and_followers": "Sekimai ir sekėjai",
"navigation_bar.lists": "Sąrašai", "navigation_bar.lists": "Sąrašai",
"navigation_bar.logout": "Atsijungti", "navigation_bar.logout": "Atsijungti",
"navigation_bar.mutes": "tildyti naudotojai", "navigation_bar.mutes": "Nutildyti naudotojai",
"navigation_bar.opened_in_classic_interface": "Įrašai, paskyros ir kiti konkretūs puslapiai pagal numatytuosius nustatymus atidaromi klasikinėje žiniatinklio sąsajoje.", "navigation_bar.opened_in_classic_interface": "Įrašai, paskyros ir kiti konkretūs puslapiai pagal numatytuosius nustatymus atidaromi klasikinėje žiniatinklio sąsajoje.",
"navigation_bar.personal": "Asmeninis", "navigation_bar.personal": "Asmeninis",
"navigation_bar.pins": "Pinned toots", "navigation_bar.pins": "Prisegti įrašai",
"navigation_bar.preferences": "Nuostatos", "navigation_bar.preferences": "Nuostatos",
"navigation_bar.public_timeline": "Federuota laiko juosta", "navigation_bar.public_timeline": "Federacinė laiko skalė",
"navigation_bar.search": "Ieškoti", "navigation_bar.search": "Ieškoti",
"navigation_bar.security": "Apsauga", "navigation_bar.security": "Apsauga",
"not_signed_in_indicator.not_signed_in": "You need to sign in to access this resource.", "not_signed_in_indicator.not_signed_in": "Norint pasiekti šį išteklį, reikia prisijungti.",
"notification.admin.report": "{name} pranešė.{target}", "notification.admin.report": "{name} pranešė {target}",
"notification.admin.sign_up": "{name} užsiregistravo", "notification.admin.sign_up": "{name} užsiregistravo",
"notification.favourite": "{name} pamėgo jūsų įrašą", "notification.favourite": "{name} pamėgo tavo įrašą",
"notification.follow": "{name} pradėjo jus sekti", "notification.follow": "{name} seka tave",
"notification.follow_request": "{name} nori tapti jūsų sekėju", "notification.follow_request": "{name} paprašė tave sekti",
"notification.mention": "{name} paminėjo jus", "notification.mention": "{name} paminėjo tave",
"notification.own_poll": "Tavo apklausa baigėsi", "notification.own_poll": "Tavo apklausa baigėsi",
"notification.poll": "Apklausa, kurioje balsavai, pasibaigė", "notification.poll": "Apklausa, kurioje balsavai, pasibaigė",
"notification.reblog": "{name} boosted your status", "notification.reblog": "{name} pakėlė tavo įrašą",
"notification.status": "{name} ką tik paskelbė", "notification.status": "{name} ką tik paskelbė",
"notification.update": "{name} redagavo įrašą", "notification.update": "{name} redagavo įrašą",
"notifications.clear": "Išvalyti pranešimus", "notifications.clear": "Išvalyti pranešimus",
"notifications.clear_confirmation": "Ar tikrai nori visam laikui išvalyti visus pranešimus?", "notifications.clear_confirmation": "Ar tikrai nori visam laikui išvalyti visus pranešimus?",
"notifications.column_settings.admin.report": "Nauji ataskaitos:", "notifications.column_settings.admin.report": "Naujos ataskaitos:",
"notifications.column_settings.admin.sign_up": "Nauji prisiregistravimai:", "notifications.column_settings.admin.sign_up": "Naujos registracijos:",
"notifications.column_settings.alert": "Darbalaukio pranešimai", "notifications.column_settings.alert": "Darbalaukio pranešimai",
"notifications.column_settings.favourite": "Mėgstamiausi:", "notifications.column_settings.favourite": "Mėgstami:",
"notifications.column_settings.filter_bar.advanced": "Rodyti visas kategorijas", "notifications.column_settings.filter_bar.advanced": "Rodyti visas kategorijas",
"notifications.column_settings.filter_bar.category": "Greito filtro juosta", "notifications.column_settings.filter_bar.category": "Spartaus filtro juosta",
"notifications.column_settings.filter_bar.show_bar": "Rodyti filtro juostą", "notifications.column_settings.filter_bar.show_bar": "Rodyti filtro juostą",
"notifications.column_settings.follow": "Nauji sekėjai:", "notifications.column_settings.follow": "Nauji sekėjai:",
"notifications.column_settings.follow_request": "Nauji prašymai sekti:", "notifications.column_settings.follow_request": "Nauji sekimo prašymai:",
"notifications.column_settings.mention": "Paminėjimai:", "notifications.column_settings.mention": "Paminėjimai:",
"notifications.column_settings.poll": "Balsavimo rezultatai:", "notifications.column_settings.poll": "Balsavimo rezultatai:",
"notifications.column_settings.push": "\"Push\" pranešimai", "notifications.column_settings.push": "Stumdomieji pranešimai",
"notifications.column_settings.reblog": "Pakėlimai:", "notifications.column_settings.reblog": "Pakėlimai:",
"notifications.column_settings.show": "Rodyti stulpelyje", "notifications.column_settings.show": "Rodyti stulpelyje",
"notifications.column_settings.sound": "Paleisti garsą", "notifications.column_settings.sound": "Paleisti garsą",
"notifications.column_settings.status": "New toots:", "notifications.column_settings.status": "Nauji įrašai:",
"notifications.column_settings.unread_notifications.category": "Neperskaityti pranešimai", "notifications.column_settings.unread_notifications.category": "Neperskaityti pranešimai",
"notifications.column_settings.unread_notifications.highlight": "Paryškinti neperskaitytus pranešimus", "notifications.column_settings.unread_notifications.highlight": "Paryškinti neperskaitytus pranešimus",
"notifications.column_settings.update": "Redagavimai:", "notifications.column_settings.update": "Redagavimai:",
"notifications.filter.all": "Visi", "notifications.filter.all": "Visi",
"notifications.filter.boosts": "\"Boost\" kiekis", "notifications.filter.boosts": "Pakėlimai",
"notifications.filter.favourites": "Mėgstamiausi", "notifications.filter.favourites": "Mėgstami",
"notifications.filter.follows": "Sekimai", "notifications.filter.follows": "Sekimai",
"notifications.filter.mentions": "Paminėjimai", "notifications.filter.mentions": "Paminėjimai",
"notifications.filter.polls": "Balsavimo rezultatai", "notifications.filter.polls": "Balsavimo rezultatai",
"notifications.filter.statuses": "Atnaujinimai iš žmonių kuriuos sekate", "notifications.filter.statuses": "Naujinimai iš žmonių, kuriuos seki",
"notifications.grant_permission": "Suteikti leidimą.", "notifications.grant_permission": "Suteikti leidimą.",
"notifications.group": "{count} pranešimai", "notifications.group": "{count} pranešimai",
"notifications.mark_as_read": "Pažymėti kiekvieną pranešimą kaip perskaitytą", "notifications.mark_as_read": "Pažymėti kiekvieną pranešimą kaip perskaitytą",
"notifications.permission_denied": "Darbalaukio pranešimai nepasiekiami dėl anksčiau atmestos naršyklės leidimų užklausos", "notifications.permission_denied": "Darbalaukio pranešimai nepasiekiami dėl anksčiau atmestos naršyklės leidimų užklausos.",
"notifications.permission_denied_alert": "Negalima įjungti darbalaukio pranešimų, nes prieš tai naršyklės leidimas buvo atmestas", "notifications.permission_denied_alert": "Negalima įjungti darbalaukio pranešimų, nes prieš tai naršyklės leidimas buvo atmestas.",
"notifications.permission_required": "Darbalaukio pranešimai nepasiekiami, nes nesuteiktas reikiamas leidimas.", "notifications.permission_required": "Darbalaukio pranešimai nepasiekiami, nes nebuvo suteiktas reikiamas leidimas.",
"notifications_permission_banner.enable": "Įjungti darbalaukio pranešimus", "notifications_permission_banner.enable": "Įjungti darbalaukio pranešimus",
"notifications_permission_banner.how_to_control": "Jei norite gauti pranešimus, kai \"Mastodon\" nėra atidarytas, įjunkite darbalaukio pranešimus. Įjungę darbalaukio pranešimus, galite tiksliai valdyti, kokių tipų sąveikos generuoja darbalaukio pranešimus, naudodamiesi pirmiau esančiu mygtuku {icon}.", "notifications_permission_banner.how_to_control": "Jei nori gauti pranešimus, kai Mastodon nėra atidarytas, įjunk darbalaukio pranešimus. Įjungęs (-usi) darbalaukio pranešimus, gali tiksliai valdyti, kokių tipų sąveikos generuoja darbalaukio pranešimus, naudojant pirmiau esančiu mygtuku {icon}.",
"notifications_permission_banner.title": "Niekada nieko nepraleiskite", "notifications_permission_banner.title": "Niekada nieko nepraleisk",
"onboarding.action.back": "Gražinkite mane atgal", "onboarding.action.back": "Grąžinti mane atgal",
"onboarding.actions.back": "Gražinkite mane atgal", "onboarding.actions.back": "Grąžinti mane atgal",
"onboarding.actions.go_to_explore": "See what's trending", "onboarding.actions.go_to_explore": "Į tendencijų puslapį",
"onboarding.actions.go_to_home": "Go to your home feed", "onboarding.actions.go_to_home": "Į mano pagrindinį srautų puslapį",
"onboarding.compose.template": "Sveiki #Mastodon!", "onboarding.compose.template": "Sveiki #Mastodon!",
"onboarding.follows.empty": "Deja, šiuo metu jokių rezultatų parodyti negalima. Galite pabandyti naudoti paiešką arba naršyti atradimo puslapyje, kad surastumėte žmonių, kuriuos norite sekti, arba pabandyti vėliau.", "onboarding.follows.empty": "Deja, šiuo metu jokių rezultatų parodyti negalima. Gali pabandyti naudoti paiešką arba naršyti atradimo puslapį, kad surastum žmonių, kuriuos nori sekti, arba bandyti vėliau.",
"onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!", "onboarding.follows.lead": "Tavo pagrindinis srautas pagrindinis būdas patirti Mastodon. Kuo daugiau žmonių seksi, tuo jis bus aktyvesnis ir įdomesnis. Norint pradėti, pateikiame keletą pasiūlymų:",
"onboarding.follows.title": "Popular on Mastodon", "onboarding.follows.title": "Suasmenink savo pagrindinį srautą",
"onboarding.profile.discoverable": "Padaryti mano profilį atrandamą", "onboarding.profile.discoverable": "Padaryti mano profilį atrandamą",
"onboarding.profile.discoverable_hint": "Kai pasirenki Mastodon atrandamumą, tavo įrašai gali būti rodomi paieškos rezultatuose ir trendose, o profilis gali būti siūlomas panašių interesų turintiems žmonėms.", "onboarding.profile.discoverable_hint": "Kai pasirenki Mastodon atrandamumą, tavo įrašai gali būti rodomi paieškos rezultatuose ir tendencijose, o profilis gali būti siūlomas panašių pomėgių turintiems žmonėms.",
"onboarding.profile.display_name": "Rodomas vardas", "onboarding.profile.display_name": "Rodomas vardas",
"onboarding.profile.display_name_hint": "Tavo pilnas vardas arba linksmas vardas…", "onboarding.profile.display_name_hint": "Tavo pilnas vardas arba linksmas vardas…",
"onboarding.profile.lead": "Gali visada tai užbaigti vėliau nustatymuose, kur yra dar daugiau pritaikymo parinkčių.", "onboarding.profile.lead": "Gali visada tai užbaigti vėliau nustatymuose, kur yra dar daugiau pritaikymo parinkčių.",
"onboarding.profile.note": "Biografija", "onboarding.profile.note": "Biografija",
"onboarding.profile.note_hint": "Gali @paminėti kitus žmones arba #saitažodžius…", "onboarding.profile.note_hint": "Gali @paminėti kitus žmones arba #saitažodžius…",
"onboarding.profile.save_and_continue": "Išsaugoti ir tęsti", "onboarding.profile.save_and_continue": "Išsaugoti ir tęsti",
"onboarding.profile.title": "Profilio konfigūravimas", "onboarding.profile.title": "Profilio sąranka",
"onboarding.profile.upload_avatar": "Įkelti profilio nuotrauką", "onboarding.profile.upload_avatar": "Įkelti profilio nuotrauką",
"onboarding.profile.upload_header": "Įkelti profilio antraštę", "onboarding.profile.upload_header": "Įkelti profilio antraštę",
"onboarding.share.lead": "Praneškite žmonėms, kaip jus rasti \"Mastodon\"!", "onboarding.share.lead": "Leisk žmonėms sužinoti, kaip tave rasti Mastodon!",
"onboarding.share.message": "Aš {username} #Mastodon! Ateik sekti manęs adresu {url}", "onboarding.share.message": "Aš {username}, esant #Mastodon! Ateik sekti manęs adresu {url}.",
"onboarding.share.next_steps": "Galimi kiti žingsniai:", "onboarding.share.next_steps": "Galimi kiti žingsniai:",
"onboarding.share.title": "Bendrinkite savo profilį", "onboarding.share.title": "Bendrink savo profilį",
"onboarding.start.lead": "Dabar esi Mastodon dalis unikalios decentralizuotos socialinės žiniasklaidos platformos, kurioje tu, o ne algoritmas, pats nustatai savo patirtį. Pradėkime tavo kelionę šioje naujoje socialinėje erdvėje:", "onboarding.start.lead": "Dabar esi Mastodon dalis unikalios decentralizuotos socialinės medijos platformos, kurioje tu, o ne algoritmas, pats nustatai savo patirtį. Pradėkime tavo kelionę šioje naujoje socialinėje erdvėje:",
"onboarding.start.skip": "Want to skip right ahead?", "onboarding.start.skip": "Nereikia pagalbos pradėti?",
"onboarding.start.title": "Jums pavyko!", "onboarding.start.title": "Tau pavyko!",
"onboarding.steps.follow_people.body": "You curate your own feed. Lets fill it with interesting people.", "onboarding.steps.follow_people.body": "Sekti įdomius žmones tai, kas yra Mastodon.",
"onboarding.steps.follow_people.title": "Follow {count, plural, one {one person} other {# people}}", "onboarding.steps.follow_people.title": "Suasmenink savo pagrindinį srautą",
"onboarding.steps.publish_status.body": "Say hello to the world.", "onboarding.steps.publish_status.body": "Sakyk labas pasauliui tekstu, nuotraukomis, vaizdo įrašais arba apklausomis {emoji}.",
"onboarding.steps.publish_status.title": "Susikūrk savo pirmąjį įrašą", "onboarding.steps.publish_status.title": "Sukūrk savo pirmąjį įrašą",
"onboarding.steps.setup_profile.body": "Others are more likely to interact with you with a filled out profile.", "onboarding.steps.setup_profile.body": "Padidink savo sąveiką turint išsamų profilį.",
"onboarding.steps.setup_profile.title": "Customize your profile", "onboarding.steps.setup_profile.title": "Suasmenink savo profilį",
"onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!", "onboarding.steps.share_profile.body": "Leisk draugams sužinoti, kaip tave rasti Mastodon.",
"onboarding.steps.share_profile.title": "Share your profile", "onboarding.steps.share_profile.title": "Bendrink savo Mastodon profilį",
"picture_in_picture.restore": "Padėkite jį atgal", "onboarding.tips.2fa": "<strong>Ar žinojai?</strong> Savo paskyrą gali apsaugoti nustatęs (-usi) dviejų veiksnių tapatybės nustatymą paskyros nustatymuose. Jis veikia su bet kuria pasirinkta TOTP programėle, telefono numeris nebūtinas.",
"poll.closed": "Uždaryti", "onboarding.tips.accounts_from_other_servers": "<strong>Ar žinojai?</strong> Kadangi Mastodon decentralizuotas, kai kurie profiliai, su kuriais susidursi, bus talpinami ne tavo, o kituose serveriuose. Ir vis tiek galėsi su jais sklandžiai bendrauti! Jų serveris yra antroje naudotojo vardo pusėje.",
"onboarding.tips.migration": "<strong>Ar žinojai?</strong> Jei manai, kad {domain} serveris ateityje tau netiks, gali persikelti į kitą Mastodon serverį neprarandant savo sekėjų. Gali net talpinti savo paties serverį.",
"onboarding.tips.verification": "<strong>Ar žinojai?</strong> Savo paskyrą gali patvirtinti pateikęs (-usi) nuorodą į Mastodon profilį savo interneto svetainėje ir pridėjęs (-usi) svetainę prie savo profilio. Nereikia jokių mokesčių ar dokumentų.",
"password_confirmation.exceeds_maxlength": "Slaptažodžio patvirtinimas viršija maksimalų slaptažodžio ilgį.",
"password_confirmation.mismatching": "Slaptažodžio patvirtinimas nesutampa.",
"picture_in_picture.restore": "Padėti jį atgal",
"poll.closed": "Uždaryta",
"poll.refresh": "Atnaujinti", "poll.refresh": "Atnaujinti",
"poll.reveal": "Peržiūrėti rezultatus", "poll.reveal": "Peržiūrėti rezultatus",
"poll.total_people": "{count, plural, one {# žmogus} few {# žmonės} many {# žmogus} other {# žmonių}}",
"poll.total_votes": "{count, plural, one {# balsas} few {# balsai} many {# balso} other {# balsų}}",
"poll.vote": "Balsuoti", "poll.vote": "Balsuoti",
"poll.voted": "Tu balsavai už šį atsakymą", "poll.voted": "Tu balsavai už šį atsakymą",
"poll.votes": "{votes, plural, one {# balsas} few {# balsai} many {# balso} other {# balsų}}", "poll.votes": "{votes, plural, one {# balsas} few {# balsai} many {# balso} other {# balsų}}",
"poll_button.add_poll": "Pridėti apklausą", "poll_button.add_poll": "Pridėti apklausą",
"poll_button.remove_poll": "Šalinti apklausą", "poll_button.remove_poll": "Pašalinti apklausą",
"privacy.change": "Adjust status privacy", "privacy.change": "Keisti įrašo privatumą",
"privacy.direct.long": "Visus, paminėtus įraše", "privacy.direct.long": "Visus, paminėtus įraše",
"privacy.direct.short": "Konkretūs žmonės", "privacy.direct.short": "Konkretūs žmonės",
"privacy.private.long": "Tik sekėjams", "privacy.private.long": "Tik sekėjams",
"privacy.private.short": "Sekėjai", "privacy.private.short": "Sekėjai",
"privacy.public.long": "Bet kas iš Mastodon ir ne Mastodon", "privacy.public.long": "Bet kas iš Mastodon ir ne Mastodon",
"privacy.public.short": "Viešas", "privacy.public.short": "Vieša",
"privacy.unlisted.additional": "Tai veikia lygiai taip pat, kaip ir vieša, tik įrašas nebus rodomas tiesioginiuose srautuose, saitažodžiose, naršyme ar Mastodon paieškoje, net jei esi įtraukęs (-usi) visą paskyrą.", "privacy.unlisted.additional": "Tai veikia lygiai taip pat, kaip ir vieša, tik įrašas nebus rodomas tiesioginiuose srautuose, saitažodžiose, naršyme ar Mastodon paieškoje, net jei esi įtraukęs (-usi) visą paskyrą.",
"privacy.unlisted.long": "Mažiau algoritminių fanfarų", "privacy.unlisted.long": "Mažiau algoritminių fanfarų",
"privacy.unlisted.short": "Tyliai vieša", "privacy.unlisted.short": "Tyliai vieša",
@ -504,8 +542,14 @@
"privacy_policy.title": "Privatumo politika", "privacy_policy.title": "Privatumo politika",
"recommended": "Rekomenduojama", "recommended": "Rekomenduojama",
"refresh": "Atnaujinti", "refresh": "Atnaujinti",
"regeneration_indicator.label": "Kraunasi…", "regeneration_indicator.label": "Kraunama…",
"regeneration_indicator.sublabel": "Ruošiamas tavo pagrindinis srautas!",
"relative_time.days": "{number} d.",
"relative_time.full.days": "prieš {number, plural, one {# dieną} few {# dienas} many {# dienos} other {# dienų}}",
"relative_time.full.hours": "prieš {number, plural, one {# valandą} few {# valandas} many {# valandos} other {# valandų}}",
"relative_time.full.just_now": "ką tik", "relative_time.full.just_now": "ką tik",
"relative_time.full.minutes": "prieš {number, plural, one {# minutę} few {# minutes} many {# minutės} other {# minučių}}",
"relative_time.full.seconds": "prieš {number, plural, one {# sekundę} few {# sekundes} many {# sekundės} other {# sekundžių}}",
"relative_time.hours": "{number} val.", "relative_time.hours": "{number} val.",
"relative_time.just_now": "dabar", "relative_time.just_now": "dabar",
"relative_time.minutes": "{number} min.", "relative_time.minutes": "{number} min.",
@ -515,15 +559,20 @@
"reply_indicator.cancel": "Atšaukti", "reply_indicator.cancel": "Atšaukti",
"reply_indicator.poll": "Apklausa", "reply_indicator.poll": "Apklausa",
"report.block": "Blokuoti", "report.block": "Blokuoti",
"report.categories.legal": "Legalus", "report.block_explanation": "Jų įrašų nematysi. Jie negalės matyti tavo įrašų ar sekti tavęs. Jie galės pamatyti, kad yra užblokuoti.",
"report.categories.legal": "Teisinės",
"report.categories.other": "Kita", "report.categories.other": "Kita",
"report.categories.spam": "Šlamštas", "report.categories.spam": "Šlamštas",
"report.categories.violation": "Turinys pažeidžia vieną ar daugiau serverio taisyklių", "report.categories.violation": "Turinys pažeidžia vieną ar daugiau serverio taisyklių",
"report.category.subtitle": "Pasirinkite tinkamiausią variantą", "report.category.subtitle": "Pasirink geriausią atitikmenį.",
"report.category.title": "Papasakok mums, kas vyksta su šiuo {type}",
"report.category.title_account": "profilis", "report.category.title_account": "profilis",
"report.category.title_status": "įrašas", "report.category.title_status": "įrašas",
"report.close": "Atlikta", "report.close": "Atlikta",
"report.comment.title": "Ar yra dar kas nors, ką, jūsų manymu, turėtume žinoti?", "report.comment.title": "Ar yra dar kas nors, ką, tavo manymu, turėtume žinoti?",
"report.forward": "Persiųsti į {target}",
"report.forward_hint": "Paskyra yra iš kito serverio. Siųsti anoniminę šios ataskaitos kopiją ir ten?",
"report.mute": "Nutildyti",
"report.mute_explanation": "Jų įrašų nematysi. Jie vis tiek gali tave sekti ir matyti įrašus, bet nežinos, kad jie nutildyti.", "report.mute_explanation": "Jų įrašų nematysi. Jie vis tiek gali tave sekti ir matyti įrašus, bet nežinos, kad jie nutildyti.",
"report.next": "Tęsti", "report.next": "Tęsti",
"report.placeholder": "Papildomi komentarai", "report.placeholder": "Papildomi komentarai",
@ -532,41 +581,42 @@
"report.reasons.legal": "Tai nelegalu", "report.reasons.legal": "Tai nelegalu",
"report.reasons.legal_description": "Manai, kad tai pažeidžia tavo arba serverio šalies įstatymus", "report.reasons.legal_description": "Manai, kad tai pažeidžia tavo arba serverio šalies įstatymus",
"report.reasons.other": "Tai kažkas kita", "report.reasons.other": "Tai kažkas kita",
"report.reasons.other_description": "Šis klausimas neatitinka kitų kategorijų", "report.reasons.other_description": "Problema netinka kitoms kategorijoms",
"report.reasons.spam": "Tai šlamštas", "report.reasons.spam": "Tai šlamštas",
"report.reasons.spam_description": "Kenkėjiškos nuorodos, netikras įsitraukimas arba pasikartojantys atsakymai", "report.reasons.spam_description": "Kenkėjiškos nuorodos, netikras įsitraukimas arba pasikartojantys atsakymai",
"report.reasons.violation": "Tai pažeidžia serverio taisykles", "report.reasons.violation": "Tai pažeidžia serverio taisykles",
"report.reasons.violation_description": "Žinai, kad tai pažeidžia konkrečias taisykles", "report.reasons.violation_description": "Žinai, kad tai pažeidžia konkrečias taisykles",
"report.rules.subtitle": "Pasirink viską, kas tinka", "report.rules.subtitle": "Pasirink viską, kas tinka.",
"report.rules.title": "Kokios taisyklės pažeidžiamos?", "report.rules.title": "Kokios taisyklės pažeidžiamos?",
"report.statuses.subtitle": "Pasirinkti viską, kas tinka", "report.statuses.subtitle": "Pasirink viską, kas tinka.",
"report.statuses.title": "Ar yra kokių nors įrašų, patvirtinančių šį pranešimą?", "report.statuses.title": "Ar yra kokių nors įrašų, patvirtinančių šį ataskaitą?",
"report.submit": "Pateikti", "report.submit": "Pateikti",
"report.target": "Report {target}", "report.target": "Pranešama apie {target}",
"report.thanks.take_action": "Čia pateikiamos galimybės kontroliuoti, ką matote \"Mastodon\":", "report.thanks.take_action": "Štai parinktys, kaip kontroliuoti, ką matai Mastodon:",
"report.thanks.take_action_actionable": "Kol tai peržiūrėsime, galite imtis veiksmų prieš @{name}:", "report.thanks.take_action_actionable": "Kol peržiūrėsime, gali imtis veiksmų prieš {name}:",
"report.thanks.title": "Nenorite to matyti?", "report.thanks.title": "Nenori to matyti?",
"report.thanks.title_actionable": "Ačiū, kad pranešėte, mes tai išnagrinėsime.", "report.thanks.title_actionable": "Ačiū, kad pranešei, mes tai išnagrinėsime.",
"report.unfollow": "Nebesekti @{name}", "report.unfollow": "Nebesekti @{name}",
"report.unfollow_explanation": "Jūs sekate šią paskyrą. Norėdami nebematyti jų įrašų savo pagrindiniame kanale, panaikinkite jų sekimą.", "report.unfollow_explanation": "Tu seki šią paskyrą. Jei nori nebematyti jų įrašų savo pagrindiniame sraute, nebesek jų.",
"report_notification.attached_statuses": "{count, plural, one {# post} other {# posts}} attached", "report_notification.attached_statuses": "Pridėti {count, plural, one {{count} įrašas} few {{count} įrašai} many {{count} įrašo} other {{count} įrašų}}",
"report_notification.categories.legal": "Legalus", "report_notification.categories.legal": "Teisinės",
"report_notification.categories.other": "Kita", "report_notification.categories.other": "Kita",
"report_notification.categories.spam": "Šlamštas", "report_notification.categories.spam": "Šlamštas",
"report_notification.categories.violation": "Taisyklės pažeidimas", "report_notification.categories.violation": "Taisyklės pažeidimas",
"search.no_recent_searches": "Paieškos įrašų nėra", "report_notification.open": "Atidaryti ataskaitą",
"search.no_recent_searches": "Nėra naujausių paieškų.",
"search.placeholder": "Paieška", "search.placeholder": "Paieška",
"search.quick_action.account_search": "Profiliai, atitinkantys {x}", "search.quick_action.account_search": "Profiliai, atitinkantys {x}",
"search.quick_action.go_to_account": "Eiti į profilį {x}", "search.quick_action.go_to_account": "Eiti į profilį {x}",
"search.quick_action.go_to_hashtag": "Eiti į hashtag {x}", "search.quick_action.go_to_hashtag": "Eiti į saitažodį {x}",
"search.quick_action.open_url": "Atidaryti URL adresą Mastodon", "search.quick_action.open_url": "Atidaryti URL adresą Mastodon",
"search.quick_action.status_search": "Pranešimai, atitinkantys {x}", "search.quick_action.status_search": "Pranešimai, atitinkantys {x}",
"search.search_or_paste": "Ieškok arba įklijuok URL", "search.search_or_paste": "Ieškoti arba įklijuoti URL",
"search_popout.full_text_search_disabled_message": "Nepasiekima {domain}.", "search_popout.full_text_search_disabled_message": "Nepasiekima {domain}.",
"search_popout.full_text_search_logged_out_message": "Pasiekiama tik prisijungus.", "search_popout.full_text_search_logged_out_message": "Pasiekiama tik prisijungus.",
"search_popout.language_code": "ISO kalbos kodas", "search_popout.language_code": "ISO kalbos kodas",
"search_popout.options": "Paieškos nustatymai", "search_popout.options": "Paieškos nustatymai",
"search_popout.quick_actions": "Greiti veiksmai", "search_popout.quick_actions": "Spartūs veiksmai",
"search_popout.recent": "Naujausios paieškos", "search_popout.recent": "Naujausios paieškos",
"search_popout.specific_date": "konkreti data", "search_popout.specific_date": "konkreti data",
"search_popout.user": "naudotojas", "search_popout.user": "naudotojas",
@ -575,23 +625,25 @@
"search_results.hashtags": "Saitažodžiai", "search_results.hashtags": "Saitažodžiai",
"search_results.nothing_found": "Nepavyko rasti nieko pagal šiuos paieškos terminus.", "search_results.nothing_found": "Nepavyko rasti nieko pagal šiuos paieškos terminus.",
"search_results.see_all": "Žiūrėti viską", "search_results.see_all": "Žiūrėti viską",
"search_results.statuses": "Toots", "search_results.statuses": "Įrašai",
"search_results.title": "Ieškoti {q}", "search_results.title": "Ieškoti {q}",
"server_banner.about_active_users": "Žmonės, kurie naudojosi šiuo serveriu per pastarąsias 30 dienų (mėnesio aktyvūs naudotojai)", "server_banner.about_active_users": "Žmonės, kurie naudojosi šiuo serveriu per pastarąsias 30 dienų (mėnesio aktyvūs naudotojai)",
"server_banner.active_users": "aktyvūs naudotojai", "server_banner.active_users": "aktyvūs naudotojai",
"server_banner.administered_by": "Administruoja:", "server_banner.administered_by": "Administruoja:",
"server_banner.introduction": "{domain} yra decentralizuoto socialinio tinklo, kurį valdo {mastodon}, dalis.", "server_banner.introduction": "{domain} decentralizuoto socialinio tinklo dalis, kurį palaiko {mastodon}.",
"server_banner.learn_more": "Sužinoti daugiau", "server_banner.learn_more": "Sužinoti daugiau",
"server_banner.server_stats": "Serverio statistika:", "server_banner.server_stats": "Serverio statistika:",
"sign_in_banner.create_account": "Sukurti paskyrą", "sign_in_banner.create_account": "Sukurti paskyrą",
"sign_in_banner.sign_in": "Prisijungimas", "sign_in_banner.sign_in": "Prisijungimas",
"sign_in_banner.sso_redirect": "Prisijungti arba Registruotis", "sign_in_banner.sso_redirect": "Prisijungti arba užsiregistruoti",
"sign_in_banner.text": "Prisijunk, kad galėtum sekti profilius arba saitažodžius, mėgsti, bendrinti ir atsakyti į įrašus. Taip pat gali bendrauti iš savo paskyros kitame serveryje.", "sign_in_banner.text": "Prisijunk, kad galėtum sekti profilius arba saitažodžius, mėgsti, bendrinti ir atsakyti į įrašus. Taip pat gali bendrauti iš savo paskyros kitame serveryje.",
"status.admin_account": "Atvira moderavimo sąsaja @{name}", "status.admin_account": "Atidaryti prižiūrėjimo sąsają @{name}",
"status.admin_domain": "Atvira moderavimo sąsaja {domain}", "status.admin_domain": "Atidaryti prižiūrėjimo sąsają {domain}",
"status.admin_status": "Open this status in the moderation interface", "status.admin_status": "Atidaryti šį įrašą prižiūrėjimo sąsajoje",
"status.block": "Blokuoti @{name}", "status.block": "Blokuoti @{name}",
"status.bookmark": "Žymė", "status.bookmark": "Pridėti į žymės",
"status.cancel_reblog_private": "Nebepakelti",
"status.cannot_reblog": "Šis įrašas negali būti pakeltas.",
"status.copy": "Kopijuoti nuorodą į įrašą", "status.copy": "Kopijuoti nuorodą į įrašą",
"status.delete": "Ištrinti", "status.delete": "Ištrinti",
"status.detailed_status": "Išsami pokalbio peržiūra", "status.detailed_status": "Išsami pokalbio peržiūra",
@ -599,15 +651,15 @@
"status.direct_indicator": "Privatus paminėjimas", "status.direct_indicator": "Privatus paminėjimas",
"status.edit": "Redaguoti", "status.edit": "Redaguoti",
"status.edited": "Redaguota {date}", "status.edited": "Redaguota {date}",
"status.edited_x_times": "Edited {count, plural, one {# time} other {# times}}", "status.edited_x_times": "Redaguota {count, plural, one {{count} kartą} few {{count} kartus} many {{count} karto} other {{count} kartų}}",
"status.embed": "Įterptas", "status.embed": "Įterpti",
"status.favourite": "Mėgstamiausias", "status.favourite": "Pamėgti",
"status.filter": "Filtruoti šį įrašą", "status.filter": "Filtruoti šį įrašą",
"status.filtered": "Filtruota", "status.filtered": "Filtruota",
"status.hide": "Slėpti įrašą", "status.hide": "Slėpti įrašą",
"status.history.created": "{name} sukurtas {date}", "status.history.created": "{name} sukurta {date}",
"status.history.edited": "{name} redaguotas {date}", "status.history.edited": "{name} redaguota {date}",
"status.load_more": "Pakrauti daugiau", "status.load_more": "Krauti daugiau",
"status.media.open": "Spausk, kad atidaryti", "status.media.open": "Spausk, kad atidaryti",
"status.media.show": "Spausk, kad matyti", "status.media.show": "Spausk, kad matyti",
"status.media_hidden": "Paslėpta medija", "status.media_hidden": "Paslėpta medija",
@ -615,15 +667,20 @@
"status.more": "Daugiau", "status.more": "Daugiau",
"status.mute": "Nutildyti @{name}", "status.mute": "Nutildyti @{name}",
"status.mute_conversation": "Nutildyti pokalbį", "status.mute_conversation": "Nutildyti pokalbį",
"status.open": "Expand this status", "status.open": "Išplėsti šį įrašą",
"status.pin": "Prisegti prie profilio", "status.pin": "Prisegti prie profilio",
"status.pinned": "Prisegtas įrašas", "status.pinned": "Prisegtas įrašas",
"status.read_more": "Skaityti daugiau", "status.read_more": "Skaityti daugiau",
"status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.", "status.reblog": "Pakelti",
"status.redraft": "Ištrinti ir iš naujo parengti juodraštį", "status.reblog_private": "Pakelti su originaliu matomumu",
"status.reblogged_by": "{name} pakėlė",
"status.reblogs.empty": "Šio įrašo dar niekas nepakėlė. Kai kas nors tai padarys, jie bus rodomi čia.",
"status.redraft": "Ištrinti ir parengti iš naujo",
"status.remove_bookmark": "Pašalinti žymę",
"status.replied_to": "Atsakyta į {name}",
"status.reply": "Atsakyti", "status.reply": "Atsakyti",
"status.replyAll": "Atsakyti į giją", "status.replyAll": "Atsakyti į giją",
"status.report": "Pranešti @{name}", "status.report": "Pranešti apie @{name}",
"status.sensitive_warning": "Jautrus turinys", "status.sensitive_warning": "Jautrus turinys",
"status.share": "Bendrinti", "status.share": "Bendrinti",
"status.show_filter_reason": "Rodyti vis tiek", "status.show_filter_reason": "Rodyti vis tiek",
@ -632,37 +689,62 @@
"status.show_more": "Rodyti daugiau", "status.show_more": "Rodyti daugiau",
"status.show_more_all": "Rodyti daugiau visiems", "status.show_more_all": "Rodyti daugiau visiems",
"status.show_original": "Rodyti originalą", "status.show_original": "Rodyti originalą",
"status.title.with_attachments": "{user}{attachmentCount, plural, one {priedas} few {{attachmentCount} priedai} many {{attachmentCount} priedo} other {{attachmentCount} priedų}}", "status.title.with_attachments": "{user} paskelbė {attachmentCount, plural, one {priedą} few {{attachmentCount} priedus} many {{attachmentCount} priedo} other {{attachmentCount} priedų}}",
"status.translate": "Versti", "status.translate": "Versti",
"status.translated_from_with": "Išversta iš {lang} naudojant {provider}", "status.translated_from_with": "Išversta iš {lang} naudojant {provider}.",
"status.uncached_media_warning": "Peržiūra nepasiekiama", "status.uncached_media_warning": "Peržiūra nepasiekiama.",
"subscribed_languages.lead": "Po pakeitimo tavo pagrindinėje ir sąrašo laiko juostose bus rodomi tik įrašai pasirinktomis kalbomis. Jei nori gauti įrašus visomis kalbomis, pasirink nė vieno.", "status.unmute_conversation": "Atšaukti pokalbio nutildymą",
"tabs_bar.home": "Pradžia", "status.unpin": "Atsegti iš profilio",
"subscribed_languages.lead": "Po pakeitimo tavo pagrindinėje ir sąrašo laiko skalėje bus rodomi tik įrašai pasirinktomis kalbomis. Jei nori gauti įrašus visomis kalbomis, pasirink nė vieno.",
"subscribed_languages.save": "Išsaugoti pakeitimus",
"subscribed_languages.target": "Keisti prenumeruojamas kalbas {target}",
"tabs_bar.home": "Pagrindinis",
"tabs_bar.notifications": "Pranešimai", "tabs_bar.notifications": "Pranešimai",
"time_remaining.days": "Liko {number, plural, one {# diena} few {# dienos} many {# dieno} other {# dienų}}", "time_remaining.days": "liko {number, plural, one {# diena} few {# dienos} many {# dienos} other {# dienų}}",
"timeline_hint.remote_resource_not_displayed": "{resource} iš kitų serverių nerodomas.", "time_remaining.hours": "liko {number, plural, one {# valanda} few {# valandos} many {# valandos} other {# valandų}}",
"time_remaining.minutes": "liko {number, plural, one {# minutė} few {# minutės} many {# minutės} other {# minučių}}",
"time_remaining.moments": "liko akimirkos",
"time_remaining.seconds": "liko {number, plural, one {# sekundė} few {# sekundės} many {# sekundės} other {# sekundžių}}",
"timeline_hint.remote_resource_not_displayed": "{resource} iš kitų serverių nerodomi.",
"timeline_hint.resources.followers": "Sekėjai", "timeline_hint.resources.followers": "Sekėjai",
"timeline_hint.resources.follows": "Seka", "timeline_hint.resources.follows": "Seka",
"timeline_hint.resources.statuses": "Senesni įrašai", "timeline_hint.resources.statuses": "Senesni įrašai",
"trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} in the past {days, plural, one {day} other {# days}}", "trends.counter_by_accounts": "{count, plural, one {{counter} žmogus} few {{counter} žmonės} many {{counter} žmogus} other {{counter} žmonių}} per {days, plural, one {dieną} few {{days} dienas} many {{days} dienas} other {{days} dienų}}",
"trends.trending_now": "Tendencinga dabar",
"ui.beforeunload": "Jei paliksi Mastodon, tavo juodraštis bus prarastas.", "ui.beforeunload": "Jei paliksi Mastodon, tavo juodraštis bus prarastas.",
"units.short.billion": "{count} mlrd.",
"units.short.million": "{count} mln.",
"units.short.thousand": "{count} tūkst.", "units.short.thousand": "{count} tūkst.",
"upload_form.audio_description": "Describe for people with hearing loss", "upload_area.title": "Nuvilk, kad įkeltum",
"upload_form.description": "Describe for the visually impaired", "upload_button.label": "Pridėti vaizdų, vaizdo įrašą arba garso failą",
"upload_error.limit": "Viršyta failo įkėlimo riba.",
"upload_error.poll": "Failų įkėlimas neleidžiamas su apklausomis.",
"upload_form.audio_description": "Aprašyk žmonėms, kurie yra kurtieji ar neprigirdintys.",
"upload_form.description": "Aprašyk žmonėms, kurie yra aklieji arba silpnaregiai.",
"upload_form.edit": "Redaguoti", "upload_form.edit": "Redaguoti",
"upload_form.video_description": "Describe for people with hearing loss or visual impairment", "upload_form.thumbnail": "Keisti miniatiūrą",
"upload_form.video_description": "Aprašyk žmonėms, kurie yra kurtieji, neprigirdintys, aklieji ar silpnaregiai.",
"upload_modal.analyzing_picture": "Analizuojamas vaizdas…",
"upload_modal.apply": "Taikyti",
"upload_modal.applying": "Pritaikoma…",
"upload_modal.choose_image": "Pasirinkti vaizdą", "upload_modal.choose_image": "Pasirinkti vaizdą",
"upload_modal.description_placeholder": "Greita rudoji lapė peršoka tinginį šunį", "upload_modal.description_placeholder": "Greita rudoji lapė peršoka tinginį šunį",
"upload_modal.detect_text": "Aptikti tekstą iš nuotraukos",
"upload_modal.edit_media": "Redaguoti mediją", "upload_modal.edit_media": "Redaguoti mediją",
"upload_modal.hint": "Spustelėk arba nuvilk apskritimą peržiūroje, kad pasirinktum centrinį tašką, kuris visada bus matomas visose miniatiūrose.",
"upload_modal.preparing_ocr": "Rengimas OCR…",
"upload_modal.preview_label": "Peržiūra ({ratio})",
"upload_progress.label": "Įkeliama...", "upload_progress.label": "Įkeliama...",
"upload_progress.processing": "Apdorojama…", "upload_progress.processing": "Apdorojama…",
"username.taken": "Šis naudotojo vardas užimtas. Pabandyk kitą.", "username.taken": "Šis naudotojo vardas užimtas. Pabandyk kitą.",
"video.close": "Uždaryti vaizdo įrašą", "video.close": "Uždaryti vaizdo įrašą",
"video.download": "Atsisiųsti failą", "video.download": "Atsisiųsti failą",
"video.exit_fullscreen": "Išeiti iš viso ekrano", "video.exit_fullscreen": "Išeiti iš viso ekrano",
"video.expand": "Išplėsti vaizdo įrašą",
"video.fullscreen": "Visas ekranas", "video.fullscreen": "Visas ekranas",
"video.hide": "Slėpti vaizdo įrašą", "video.hide": "Slėpti vaizdo įrašą",
"video.mute": "Nutildyti garsą", "video.mute": "Išjungti garsą",
"video.pause": "Pristabdyti",
"video.play": "Leisti", "video.play": "Leisti",
"video.unmute": "Atitildyti garsą" "video.unmute": "Įjungti garsą"
} }

View file

@ -21,24 +21,26 @@
"account.blocked": "Bloķēts", "account.blocked": "Bloķēts",
"account.browse_more_on_origin_server": "Pārlūkot vairāk sākotnējā profilā", "account.browse_more_on_origin_server": "Pārlūkot vairāk sākotnējā profilā",
"account.cancel_follow_request": "Atsaukt sekošanas pieprasījumu", "account.cancel_follow_request": "Atsaukt sekošanas pieprasījumu",
"account.copy": "Ievietot saiti uz profilu starpliktuvē",
"account.direct": "Pieminēt @{name} privāti", "account.direct": "Pieminēt @{name} privāti",
"account.disable_notifications": "Pārtraukt man paziņot, kad @{name} publicē ierakstu", "account.disable_notifications": "Pārtraukt man paziņot, kad @{name} publicē ierakstu",
"account.domain_blocked": "Domēns ir bloķēts", "account.domain_blocked": "Domēns ir bloķēts",
"account.edit_profile": "Rediģēt profilu", "account.edit_profile": "Labot profilu",
"account.enable_notifications": "Paziņot man, kad @{name} publicē ierakstu", "account.enable_notifications": "Paziņot man, kad @{name} publicē ierakstu",
"account.endorse": "Izcelts profilā", "account.endorse": "Izcelts profilā",
"account.featured_tags.last_status_at": "Beidzamā ziņa {date}", "account.featured_tags.last_status_at": "Beidzamā ziņa {date}",
"account.featured_tags.last_status_never": "Ierakstu nav", "account.featured_tags.last_status_never": "Ierakstu nav",
"account.featured_tags.title": "{name} izceltie tēmturi", "account.featured_tags.title": "{name} izceltie tēmturi",
"account.follow": "Sekot", "account.follow": "Sekot",
"account.follow_back": "Sekot atpakaļ",
"account.followers": "Sekotāji", "account.followers": "Sekotāji",
"account.followers.empty": "Šim lietotājam vēl nav sekotāju.", "account.followers.empty": "Šim lietotājam vēl nav sekotāju.",
"account.followers_counter": "{count, plural, one {{counter} Sekotājs} other {{counter} Sekotāji}}", "account.followers_counter": "{count, plural, zero {{counter} sekotāju} one {{counter} sekotājs} other {{counter} sekotāji}}",
"account.following": "Seko", "account.following": "Seko",
"account.following_counter": "{count, plural, one {{counter} sekojamais} other {{counter} sekojamie}}", "account.following_counter": "{count, plural, zero{{counter} sekojamo} one {{counter} sekojamais} other {{counter} sekojamie}}",
"account.follows.empty": "Šis lietotājs pagaidām nevienam neseko.", "account.follows.empty": "Šis lietotājs pagaidām nevienam neseko.",
"account.go_to_profile": "Doties uz profilu", "account.go_to_profile": "Doties uz profilu",
"account.hide_reblogs": "Slēpt @{name} izceltas ziņas", "account.hide_reblogs": "Paslēpt @{name} pastiprinātos ierakstus",
"account.in_memoriam": "Piemiņai.", "account.in_memoriam": "Piemiņai.",
"account.joined_short": "Pievienojās", "account.joined_short": "Pievienojās",
"account.languages": "Mainīt abonētās valodas", "account.languages": "Mainīt abonētās valodas",
@ -51,13 +53,14 @@
"account.mute_notifications_short": "Izslēgt paziņojumu skaņu", "account.mute_notifications_short": "Izslēgt paziņojumu skaņu",
"account.mute_short": "Apklusināt", "account.mute_short": "Apklusināt",
"account.muted": "Apklusināts", "account.muted": "Apklusināts",
"account.mutual": "Savstarpējs",
"account.no_bio": "Apraksts nav sniegts.", "account.no_bio": "Apraksts nav sniegts.",
"account.open_original_page": "Atvērt oriģinālo lapu", "account.open_original_page": "Atvērt oriģinālo lapu",
"account.posts": "Ieraksti", "account.posts": "Ieraksti",
"account.posts_with_replies": "Ieraksti un atbildes", "account.posts_with_replies": "Ieraksti un atbildes",
"account.report": "Sūdzēties par @{name}", "account.report": "Sūdzēties par @{name}",
"account.requested": "Gaida apstiprinājumu. Nospied, lai atceltu sekošanas pieparasījumu", "account.requested": "Gaida apstiprinājumu. Nospied, lai atceltu sekošanas pieparasījumu",
"account.requested_follow": "{name} nosūtīja tev sekošanas pieprasījumu", "account.requested_follow": "{name} nosūtīja Tev sekošanas pieprasījumu",
"account.share": "Dalīties ar @{name} profilu", "account.share": "Dalīties ar @{name} profilu",
"account.show_reblogs": "Parādīt @{name} pastiprinātos ierakstus", "account.show_reblogs": "Parādīt @{name} pastiprinātos ierakstus",
"account.statuses_counter": "{count, plural, zero {{counter} ierakstu} one {{counter} ieraksts} other {{counter} ieraksti}}", "account.statuses_counter": "{count, plural, zero {{counter} ierakstu} one {{counter} ieraksts} other {{counter} ieraksti}}",
@ -97,18 +100,18 @@
"bundle_column_error.routing.body": "Pieprasīto lapu nevarēja atrast. Vai esi pārliecināts, ka URL adreses joslā ir pareizs?", "bundle_column_error.routing.body": "Pieprasīto lapu nevarēja atrast. Vai esi pārliecināts, ka URL adreses joslā ir pareizs?",
"bundle_column_error.routing.title": "404", "bundle_column_error.routing.title": "404",
"bundle_modal_error.close": "Aizvērt", "bundle_modal_error.close": "Aizvērt",
"bundle_modal_error.message": "Kaut kas nogāja greizi, ielādējot šo komponenti.", "bundle_modal_error.message": "Kaut kas nogāja greizi šīs sastāvdaļas ielādēšanas laikā.",
"bundle_modal_error.retry": "Mēģināt vēlreiz", "bundle_modal_error.retry": "Mēģināt vēlreiz",
"closed_registrations.other_server_instructions": "Tā kā Mastodon ir decentralizēts, tu vari izveidot kontu citā serverī un joprojām mijiedarboties ar šo.", "closed_registrations.other_server_instructions": "Tā kā Mastodon ir decentralizēts, tu vari izveidot kontu citā serverī un joprojām mijiedarboties ar šo.",
"closed_registrations_modal.description": "Pašlaik nav iespējams izveidot kontu domēnā {domain}, taču ņem vērā, ka tev nav nepieciešams konts tieši {domain}, lai lietotu Mastodon.", "closed_registrations_modal.description": "Pašlaik nav iespējams izveidot kontu {domain}, bet, lūdzu, ņem vērā, ka Tev nav nepieciešams tieši {domain} konts, lai lietotu Mastodon!",
"closed_registrations_modal.find_another_server": "Atrast citu serveri", "closed_registrations_modal.find_another_server": "Atrast citu serveri",
"closed_registrations_modal.preamble": "Mastodon ir decentralizēts, tāpēc neatkarīgi no tā, kur tu izveido savu kontu, varēsi sekot līdzi un sazināties ar ikvienu šajā serverī. Tu pat vari vadīt to pats!", "closed_registrations_modal.preamble": "Mastodon ir decentralizēts, tāpēc neatkarīgi no tā, kur Tu izveido savu kontu, varēsi sekot un mijiedarboties ar ikvienu šajā serverī. Tu pat vari to pašizvietot!",
"closed_registrations_modal.title": "Reģistrēšanās Mastodon", "closed_registrations_modal.title": "Reģistrēšanās Mastodon",
"column.about": "Par", "column.about": "Par",
"column.blocks": "Bloķētie lietotāji", "column.blocks": "Bloķētie lietotāji",
"column.bookmarks": "Grāmatzīmes", "column.bookmarks": "Grāmatzīmes",
"column.community": "Vietējā laika līnija", "column.community": "Vietējā laika līnija",
"column.direct": "Privāti pieminēti", "column.direct": "Privātas pieminēšanas",
"column.directory": "Pārlūkot profilus", "column.directory": "Pārlūkot profilus",
"column.domain_blocks": "Bloķētie domēni", "column.domain_blocks": "Bloķētie domēni",
"column.favourites": "Iecienītie", "column.favourites": "Iecienītie",
@ -133,21 +136,28 @@
"community.column_settings.remote_only": "Tikai attālinātie", "community.column_settings.remote_only": "Tikai attālinātie",
"compose.language.change": "Mainīt valodu", "compose.language.change": "Mainīt valodu",
"compose.language.search": "Meklēt valodas...", "compose.language.search": "Meklēt valodas...",
"compose.published.body": "Ziņa publicēta.", "compose.published.body": "Ieraksts publicēta.",
"compose.published.open": "Atvērt", "compose.published.open": "Atvērt",
"compose.saved.body": "Ziņa saglabāta.", "compose.saved.body": "Ziņa saglabāta.",
"compose_form.direct_message_warning_learn_more": "Uzzināt vairāk", "compose_form.direct_message_warning_learn_more": "Uzzināt vairāk",
"compose_form.encryption_warning": "Ziņas vietnē Mastodon nav pilnībā šifrētas. Nedalies ar sensitīvu informāciju caur Mastodon.", "compose_form.encryption_warning": "Mastodon ieraksti nav pilnībā šifrēti. Nedalies ar jebkādu jutīgu informāciju caur Mastodon!",
"compose_form.hashtag_warning": "Šī ziņa netiks norādīta zem nevienas atsauces, jo tā nav publiska. Tikai publiskās ziņās var meklēt pēc atsauces.", "compose_form.hashtag_warning": "Šī ziņa netiks norādīta zem nevienas atsauces, jo tā nav publiska. Tikai publiskās ziņās var meklēt pēc atsauces.",
"compose_form.lock_disclaimer": "Tavs konts nav {locked}. Ikviens var tev piesekot un redzēt tikai sekotājiem paredzētos ziņojumus.", "compose_form.lock_disclaimer": "Tavs konts nav {locked}. Ikviens var Tev sekot, lai redzētu tikai sekotājiem paredzētos ierakstus.",
"compose_form.lock_disclaimer.lock": "slēgts", "compose_form.lock_disclaimer.lock": "slēgts",
"compose_form.placeholder": "Kas tev padomā?", "compose_form.placeholder": "Kas Tev padomā?",
"compose_form.poll.duration": "Aptaujas ilgums", "compose_form.poll.duration": "Aptaujas ilgums",
"compose_form.poll.multiple": "Vairākas izvēles iespējas",
"compose_form.poll.option_placeholder": "Izvēle {number}",
"compose_form.poll.single": "Jāizvēlas viens",
"compose_form.poll.switch_to_multiple": "Mainīt aptaujas veidu, lai atļautu vairākas izvēles", "compose_form.poll.switch_to_multiple": "Mainīt aptaujas veidu, lai atļautu vairākas izvēles",
"compose_form.poll.switch_to_single": "Mainīt aptaujas veidu, lai atļautu vienu izvēli", "compose_form.poll.switch_to_single": "Mainīt aptaujas veidu, lai atļautu vienu izvēli",
"compose_form.publish": "Iesūtīt",
"compose_form.publish_form": "Jauns ieraksts", "compose_form.publish_form": "Jauns ieraksts",
"compose_form.reply": "Atbildēt",
"compose_form.save_changes": "Atjaunināt",
"compose_form.spoiler.marked": "Noņemt satura brīdinājumu", "compose_form.spoiler.marked": "Noņemt satura brīdinājumu",
"compose_form.spoiler.unmarked": "Pievienot satura brīdinājumu", "compose_form.spoiler.unmarked": "Pievienot satura brīdinājumu",
"compose_form.spoiler_placeholder": "Satura brīdinājums (pēc izvēles)",
"confirmation_modal.cancel": "Atcelt", "confirmation_modal.cancel": "Atcelt",
"confirmations.block.block_and_report": "Bloķēt un ziņot", "confirmations.block.block_and_report": "Bloķēt un ziņot",
"confirmations.block.confirm": "Bloķēt", "confirmations.block.confirm": "Bloķēt",
@ -157,28 +167,29 @@
"confirmations.delete.confirm": "Dzēst", "confirmations.delete.confirm": "Dzēst",
"confirmations.delete.message": "Vai tiešām vēlies dzēst šo ierakstu?", "confirmations.delete.message": "Vai tiešām vēlies dzēst šo ierakstu?",
"confirmations.delete_list.confirm": "Dzēst", "confirmations.delete_list.confirm": "Dzēst",
"confirmations.delete_list.message": "Vai tiešam vēlies neatgriezeniski dzēst šo sarakstu?", "confirmations.delete_list.message": "Vai tiešām neatgriezeniski izdzēst šo sarakstu?",
"confirmations.discard_edit_media.confirm": "Atmest", "confirmations.discard_edit_media.confirm": "Atmest",
"confirmations.discard_edit_media.message": "Tev ir nesaglabātas izmaiņas multivides aprakstā vai priekšskatījumā. Vēlies tās atmest?", "confirmations.discard_edit_media.message": "Ir nesaglabātas izmaiņas informācijas nesēja aprakstā vai priekšskatījumā. Vēlies tās atmest tik un tā?",
"confirmations.domain_block.confirm": "Bloķēt visu domēnu", "confirmations.domain_block.confirm": "Bloķēt visu domēnu",
"confirmations.domain_block.message": "Vai tu tiešām vēlies bloķēt visu domēnu {domain}? Parasti pietiek, ja nobloķē vai apklusini kādu. Tu neredzēsi saturu vai paziņojumus no šī domēna nevienā laika līnijā. Tavi sekotāji no šī domēna tiks noņemti.", "confirmations.domain_block.message": "Vai tu tiešām vēlies bloķēt visu domēnu {domain}? Parasti pietiek, ja nobloķē vai apklusini kādu. Tu neredzēsi saturu vai paziņojumus no šī domēna nevienā laika līnijā. Tavi sekotāji no šī domēna tiks noņemti.",
"confirmations.edit.confirm": "Rediģēt", "confirmations.edit.confirm": "Labot",
"confirmations.edit.message": "Rediģējot, tiks pārrakstīts ziņojums, kuru tu šobrīd raksti. Vai tiešām vēlies turpināt?", "confirmations.edit.message": "Rediģējot, tiks pārrakstīts ziņojums, kuru tu šobrīd raksti. Vai tiešām vēlies turpināt?",
"confirmations.logout.confirm": "Iziet", "confirmations.logout.confirm": "Iziet",
"confirmations.logout.message": "Vai tiešām vēlies izrakstīties?", "confirmations.logout.message": "Vai tiešām vēlies izrakstīties?",
"confirmations.mute.confirm": "Apklusināt", "confirmations.mute.confirm": "Apklusināt",
"confirmations.mute.explanation": "Šādi no viņiem tiks slēptas ziņas un ziņas, kurās viņi tiek pieminēti, taču viņi joprojām varēs redzēt tavas ziņas un sekot tev.", "confirmations.mute.explanation": "Šādi tiks slēpti ieraksti no viņiem un ieraksti, kuros viņi tiek pieminēti, taču viņi joprojām varēs redzēt Tavus ierakstus un sekot Tev.",
"confirmations.mute.message": "Vai tiešām vēlies apklusināt {name}?", "confirmations.mute.message": "Vai tiešām vēlies apklusināt {name}?",
"confirmations.redraft.confirm": "Dzēst un pārrakstīt", "confirmations.redraft.confirm": "Dzēst un pārrakstīt",
"confirmations.redraft.message": "Vai tiešām vēlies dzēst šo ziņu un no jauna noformēt to? Izlase un pastiprinājumi tiks zaudēti, un atbildes uz sākotnējo ziņu tiks atstātas bez autoratlīdzības.", "confirmations.redraft.message": "Vai tiešām vēlies dzēst šo ziņu un no jauna noformēt to? Izlase un pastiprinājumi tiks zaudēti, un atbildes uz sākotnējo ziņu tiks atstātas bez autoratlīdzības.",
"confirmations.reply.confirm": "Atbildēt", "confirmations.reply.confirm": "Atbildēt",
"confirmations.reply.message": "Ja tagad atbildēsi, tavs ziņas uzmetums tiks dzēsts. Vai tiešām vēlies turpināt?", "confirmations.reply.message": "Tūlītēja atbildēšana pārrakstīs pašlaik sastādīto ziņu. Vai tiešām turpināt?",
"confirmations.unfollow.confirm": "Pārstāt sekot", "confirmations.unfollow.confirm": "Pārstāt sekot",
"confirmations.unfollow.message": "Vai tiešam vairs nevēlies sekot lietotājam {name}?", "confirmations.unfollow.message": "Vai tiešam vairs nevēlies sekot lietotājam {name}?",
"conversation.delete": "Dzēst sarunu", "conversation.delete": "Dzēst sarunu",
"conversation.mark_as_read": "Atzīmēt kā izlasītu", "conversation.mark_as_read": "Atzīmēt kā izlasītu",
"conversation.open": "Skatīt sarunu", "conversation.open": "Skatīt sarunu",
"conversation.with": "Ar {names}", "conversation.with": "Ar {names}",
"copy_icon_button.copied": "Ievietots starpliktuvē",
"copypaste.copied": "Nokopēts", "copypaste.copied": "Nokopēts",
"copypaste.copy_to_clipboard": "Kopēt uz starpliktuvi", "copypaste.copy_to_clipboard": "Kopēt uz starpliktuvi",
"directory.federated": "No pazīstamas federācijas", "directory.federated": "No pazīstamas federācijas",
@ -187,12 +198,12 @@
"directory.recently_active": "Nesen aktīvie", "directory.recently_active": "Nesen aktīvie",
"disabled_account_banner.account_settings": "Konta iestatījumi", "disabled_account_banner.account_settings": "Konta iestatījumi",
"disabled_account_banner.text": "Tavs konts {disabledAccount} pašlaik ir atspējots.", "disabled_account_banner.text": "Tavs konts {disabledAccount} pašlaik ir atspējots.",
"dismissable_banner.community_timeline": īs ir jaunākās publiskās ziņas no personām, kuru kontus mitina {domain}.", "dismissable_banner.community_timeline": ie ir jaunākie publiskie ieraksti no cilvēkiem, kuru konti ir mitināti {domain}.",
"dismissable_banner.dismiss": "Atcelt", "dismissable_banner.dismiss": "Atcelt",
"dismissable_banner.explore_links": "Par šiem jaunumiem šobrīd runā cilvēki šajā un citos decentralizētā tīkla serveros.", "dismissable_banner.explore_links": "Par šiem jaunumiem šobrīd runā cilvēki šajā un citos decentralizētā tīkla serveros.",
"dismissable_banner.explore_statuses": "Ieraksti, kas šobrīd gūst arvien lielāku ievērību visā sociālajā tīklā. Augstāk tiek kārtoti neseni ieraksti, kas pastiprināti un pievienoti izlasēm.", "dismissable_banner.explore_statuses": "Šie ir ieraksti, kas šodien gūst arvien lielāku ievērību visā sociālajā tīklā. Augstāk tiek kārtoti jaunāki ieraksti, kuri tiek vairāk pastiprināti un ievietoti izlasēs.",
"dismissable_banner.explore_tags": "Šie tēmturi šobrīd kļūst arvien populārāki cilvēku vidū šajā un citos decentralizētā tīkla serveros.", "dismissable_banner.explore_tags": "Šie tēmturi šobrīd kļūst arvien populārāki cilvēku vidū šajā un citos decentralizētā tīkla serveros.",
"dismissable_banner.public_timeline": īs ir jaunākās publiskās ziņas no lietotājiem sociālajā tīmeklī, kurām seko lietotāji domēnā {domain}.", "dismissable_banner.public_timeline": ie ir jaunākie publiskie ieraksti no lietotājiem sociālajā tīmeklī, kuriem {domain} seko cilvēki.",
"embed.instructions": "Iestrādā šo ziņu savā mājaslapā, kopējot zemāk redzamo kodu.", "embed.instructions": "Iestrādā šo ziņu savā mājaslapā, kopējot zemāk redzamo kodu.",
"embed.preview": "Tas izskatīsies šādi:", "embed.preview": "Tas izskatīsies šādi:",
"emoji_button.activity": "Aktivitāte", "emoji_button.activity": "Aktivitāte",
@ -215,22 +226,22 @@
"empty_column.account_timeline": "Šeit ziņojumu nav!", "empty_column.account_timeline": "Šeit ziņojumu nav!",
"empty_column.account_unavailable": "Profils nav pieejams", "empty_column.account_unavailable": "Profils nav pieejams",
"empty_column.blocks": "Pašreiz tu neesi nevienu bloķējis.", "empty_column.blocks": "Pašreiz tu neesi nevienu bloķējis.",
"empty_column.bookmarked_statuses": "Pašreiz tev nav neviena grāmatzīmēm pievienota ieraksta. Kad tādu pievienosi, tas parādīsies šeit.", "empty_column.bookmarked_statuses": "Pašlaik Tev nav neviena grāmatzīmēs pievienota ieraksta. Kad tādu pievienosi, tas parādīsies šeit.",
"empty_column.community": "Vietējā laika līnija ir tukša. Uzraksti kaut ko publiski, lai viss notiktu!", "empty_column.community": "Vietējā laika līnija ir tukša. Uzraksti kaut ko publiski, lai viss notiktu!",
"empty_column.direct": "Jums vēl nav nevienas privātas pieminēšanas. Nosūtot vai saņemot to, tas tiks parādīts šeit.", "empty_column.direct": "Tev vēl nav privātu pieminēšanu. Kad Tu nosūtīsi vai saņemsi kādu, tā pārādīsies šeit.",
"empty_column.domain_blocks": "Vēl nav neviena bloķēta domēna.", "empty_column.domain_blocks": "Vēl nav neviena bloķēta domēna.",
"empty_column.explore_statuses": "Pašlaik nekā aktuāla nav. Pārbaudi vēlāk!", "empty_column.explore_statuses": "Pašlaik nav nekā aktuāla. Ieskaties šeit vēlāk!",
"empty_column.favourited_statuses": "Tev vēl nav nevienas iecienītākās ziņas. Kad iecienīsi kādu, tas tiks parādīts šeit.", "empty_column.favourited_statuses": "Tev vēl nav iecienītāko ierakstu. Kad pievienosi kādu izlasei, tas tiks parādīts šeit.",
"empty_column.favourites": "Šo ziņu neviens vēl nav pievienojis izlasei. Kad kāds to izdarīs, tas parādīsies šeit.", "empty_column.favourites": "Šo ziņu neviens vēl nav pievienojis izlasei. Kad kāds to izdarīs, tas parādīsies šeit.",
"empty_column.follow_requests": "Šobrīd tev nav sekošanas pieprasījumu. Kad kāds pieteiksies tev sekot, pieprasījums parādīsies šeit.", "empty_column.follow_requests": "Šobrīd Tev nav sekošanas pieprasījumu. Kad saņemsi kādu, tas parādīsies šeit.",
"empty_column.followed_tags": "Tu vēl neesi sekojis nevienam tēmturim. Kad to izdarīsi, tie tiks parādīti šeit.", "empty_column.followed_tags": "Tu vēl neesi sekojis nevienam tēmturim. Kad to izdarīsi, tie tiks parādīti šeit.",
"empty_column.hashtag": "Ar šo tēmturi nekas nav atrodams.", "empty_column.hashtag": "Ar šo tēmturi nekas nav atrodams.",
"empty_column.home": "Tava mājas laikrinda ir tukša! Lai to aizpildītu, pieseko vairāk cilvēkiem.", "empty_column.home": "Tava mājas laikjosla ir tukša. Seko vairāk cilvēkiem, lai to piepildītu!",
"empty_column.list": "Šis saraksts pašreiz ir tukšs. Kad šī saraksta dalībnieki publicēs jaunas ziņas, tās parādīsies šeit.", "empty_column.list": "Pagaidām šajā sarakstā nekā nav. Kad šī saraksta dalībnieki ievietos jaunus ierakstus, tie parādīsies šeit.",
"empty_column.lists": "Pašreiz tev nav neviena saraksta. Kad tādu izveidosi, tas parādīsies šeit.", "empty_column.lists": "Pašlaik Tev nav neviena saraksta. Kad tādu izveidosi, tas parādīsies šeit.",
"empty_column.mutes": "Neviens lietotājs vēl nav apklusināts.", "empty_column.mutes": "Neviens lietotājs vēl nav apklusināts.",
"empty_column.notifications": "Tev vēl nav paziņojumu. Kad citi cilvēki ar tevi mijiedarbosies, tu to redzēsi šeit.", "empty_column.notifications": "Tev vēl nav paziņojumu. Kad citi cilvēki ar Tevi mijiedarbosies, Tu to redzēsi šeit.",
"empty_column.public": "Šeit vēl nekā nav! Ieraksti ko publiski vai pieseko lietotājiem no citiem serveriem", "empty_column.public": "Šeit nekā nav! Ieraksti kaut ko publiski vai seko lietotājiem no citiem serveriem, lai iegūtu saturu",
"error.unexpected_crash.explanation": "Koda kļūdas vai pārlūkprogrammas saderības problēmas dēļ šo lapu nevarēja parādīt pareizi.", "error.unexpected_crash.explanation": "Koda kļūdas vai pārlūkprogrammas saderības problēmas dēļ šo lapu nevarēja parādīt pareizi.",
"error.unexpected_crash.explanation_addons": "Šo lapu nevarēja parādīt pareizi. Šo kļūdu, iespējams, izraisīja pārlūkprogrammas papildinājums vai automātiskās tulkošanas rīki.", "error.unexpected_crash.explanation_addons": "Šo lapu nevarēja parādīt pareizi. Šo kļūdu, iespējams, izraisīja pārlūkprogrammas papildinājums vai automātiskās tulkošanas rīki.",
"error.unexpected_crash.next_steps": "Mēģini atsvaidzināt lapu. Ja tas nepalīdz, iespējams, varēsi lietot Mastodon, izmantojot citu pārlūkprogrammu vai lietotni.", "error.unexpected_crash.next_steps": "Mēģini atsvaidzināt lapu. Ja tas nepalīdz, iespējams, varēsi lietot Mastodon, izmantojot citu pārlūkprogrammu vai lietotni.",
@ -239,13 +250,13 @@
"errors.unexpected_crash.report_issue": "Ziņot par problēmu", "errors.unexpected_crash.report_issue": "Ziņot par problēmu",
"explore.search_results": "Meklēšanas rezultāti", "explore.search_results": "Meklēšanas rezultāti",
"explore.suggested_follows": "Cilvēki", "explore.suggested_follows": "Cilvēki",
"explore.title": "Pārlūkot", "explore.title": "Izpētīt",
"explore.trending_links": "Jaunumi", "explore.trending_links": "Jaunumi",
"explore.trending_statuses": "Ziņas", "explore.trending_statuses": "Ieraksti",
"explore.trending_tags": "Tēmturi", "explore.trending_tags": "Tēmturi",
"filter_modal.added.context_mismatch_explanation": "Šī filtra kategorija neattiecas uz kontekstu, kurā esi piekļuvis šai ziņai. Ja vēlies, lai ziņa tiktu filtrēta arī šajā kontekstā, tev būs jārediģē filtrs.", "filter_modal.added.context_mismatch_explanation": "Šī atlases kategorija neattiecas uz kontekstu, kurā esi piekļuvis šim ierakstam. Ja vēlies, lai ieraksts tiktu atlasīts arī šajā kontekstā, Tev būs jālabo atlase.",
"filter_modal.added.context_mismatch_title": "Konteksta neatbilstība!", "filter_modal.added.context_mismatch_title": "Konteksta neatbilstība!",
"filter_modal.added.expired_explanation": "Šai filtra kategorijai ir beidzies derīguma termiņš. Lai to lietotu, tev būs jāmaina derīguma termiņš.", "filter_modal.added.expired_explanation": "Šai atlases kategorijai ir beidzies derīguma termiņš. Lai to lietotu, Tev būs jāmaina derīguma termiņš.",
"filter_modal.added.expired_title": "Filtra termiņš beidzies!", "filter_modal.added.expired_title": "Filtra termiņš beidzies!",
"filter_modal.added.review_and_configure": "Lai pārskatītu un tālāk konfigurētu šo filtru kategoriju, dodies uz {settings_link}.", "filter_modal.added.review_and_configure": "Lai pārskatītu un tālāk konfigurētu šo filtru kategoriju, dodies uz {settings_link}.",
"filter_modal.added.review_and_configure_title": "Filtra iestatījumi", "filter_modal.added.review_and_configure_title": "Filtra iestatījumi",
@ -255,7 +266,7 @@
"filter_modal.select_filter.context_mismatch": "neattiecas uz šo kontekstu", "filter_modal.select_filter.context_mismatch": "neattiecas uz šo kontekstu",
"filter_modal.select_filter.expired": "beidzies", "filter_modal.select_filter.expired": "beidzies",
"filter_modal.select_filter.prompt_new": "Jauna kategorija: {name}", "filter_modal.select_filter.prompt_new": "Jauna kategorija: {name}",
"filter_modal.select_filter.search": "Meklē vai izveido", "filter_modal.select_filter.search": "Meklēt vai izveidot",
"filter_modal.select_filter.subtitle": "Izmanto esošu kategoriju vai izveido jaunu", "filter_modal.select_filter.subtitle": "Izmanto esošu kategoriju vai izveido jaunu",
"filter_modal.select_filter.title": "Filtrēt šo ziņu", "filter_modal.select_filter.title": "Filtrēt šo ziņu",
"filter_modal.title.status": "Filtrēt ziņu", "filter_modal.title.status": "Filtrēt ziņu",
@ -264,7 +275,11 @@
"firehose.remote": "Citi serveri", "firehose.remote": "Citi serveri",
"follow_request.authorize": "Autorizēt", "follow_request.authorize": "Autorizēt",
"follow_request.reject": "Noraidīt", "follow_request.reject": "Noraidīt",
"follow_requests.unlocked_explanation": "Lai gan tavs konts nav bloķēts, {domain} darbinieki iedomājās, ka, iespējams, vēlēsies pārskatīt pieprasījumus no šiem kontiem.", "follow_requests.unlocked_explanation": "Lai gan Tavs konts nav slēgts, {domain} darbinieki iedomājās, ka Tu varētu vēlēties pašrocīgi pārskatīt sekošanas pieprasījumus no šiem kontiem.",
"follow_suggestions.curated_suggestion": "Darbinieku izvēle",
"follow_suggestions.dismiss": "Vairs nerādīt",
"follow_suggestions.view_all": "Skatīt visu",
"follow_suggestions.who_to_follow": "Kam sekot",
"followed_tags": "Sekojamie tēmturi", "followed_tags": "Sekojamie tēmturi",
"footer.about": "Par", "footer.about": "Par",
"footer.directory": "Profilu direktorija", "footer.directory": "Profilu direktorija",
@ -286,8 +301,8 @@
"hashtag.column_settings.tag_mode.none": "Neviens no šiem", "hashtag.column_settings.tag_mode.none": "Neviens no šiem",
"hashtag.column_settings.tag_toggle": "Pievienot kolonnai papildu tēmturus", "hashtag.column_settings.tag_toggle": "Pievienot kolonnai papildu tēmturus",
"hashtag.counter_by_accounts": "{count, plural, one {{counter} dalībnieks} other {{counter} dalībnieki}}", "hashtag.counter_by_accounts": "{count, plural, one {{counter} dalībnieks} other {{counter} dalībnieki}}",
"hashtag.counter_by_uses": "{count, plural, zero {{counter} ziņa} one {{counter} ieraksts} other {{counter} ziņas}}", "hashtag.counter_by_uses": "{count, plural, zero {{counter} ierakstu} one {{counter} ieraksts} other {{counter} ieraksti}}",
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} ziņa} other {{counter} ziņas}} šodien", "hashtag.counter_by_uses_today": "{count, plural, zero {{counter} ierakstu} one {{counter} ieraksts} other {{counter} ieraksti}} šodien",
"hashtag.follow": "Sekot tēmturim", "hashtag.follow": "Sekot tēmturim",
"hashtag.unfollow": "Pārstāt sekot tēmturim", "hashtag.unfollow": "Pārstāt sekot tēmturim",
"hashtags.and_other": "..un {count, plural, other {# vairāk}}", "hashtags.and_other": "..un {count, plural, other {# vairāk}}",
@ -300,16 +315,16 @@
"home.pending_critical_update.title": "Pieejams kritisks drošības jauninājums!", "home.pending_critical_update.title": "Pieejams kritisks drošības jauninājums!",
"home.show_announcements": "Rādīt paziņojumus", "home.show_announcements": "Rādīt paziņojumus",
"interaction_modal.description.favourite": "Ar Mastodon kontu tu vari pievienot šo ziņu izlasei, lai informētu autoru, ka to novērtē, un saglabātu to vēlākai lasīšanai.", "interaction_modal.description.favourite": "Ar Mastodon kontu tu vari pievienot šo ziņu izlasei, lai informētu autoru, ka to novērtē, un saglabātu to vēlākai lasīšanai.",
"interaction_modal.description.follow": "Ar Mastodon kontu tu vari sekot {name}, lai saņemtu viņu ziņas savā mājas plūsmā.", "interaction_modal.description.follow": "Ar Mastodon kontu Tu vari sekot {name}, lai saņemtu lietotāja ierakstus savā mājas plūsmā.",
"interaction_modal.description.reblog": "Izmantojot kontu Mastodon, tu vari izcelt šo ziņu, lai kopīgotu to ar saviem sekotājiem.", "interaction_modal.description.reblog": "Ar Mastodon kontu Tu vari izvirzīt šo ierakstu, lai kopīgotu to ar saviem sekotājiem.",
"interaction_modal.description.reply": "Ar Mastodon kontu tu vari atbildēt uz šo ziņu.", "interaction_modal.description.reply": "Ar Mastodon kontu tu vari atbildēt uz šo ziņu.",
"interaction_modal.login.action": "Nogādā mani mājās", "interaction_modal.login.action": "Nogādāt mani mājās",
"interaction_modal.login.prompt": "Tavas mājvietas servera domēns, piem., mastodon.social", "interaction_modal.login.prompt": "Tavas mājvietas servera domēns, piem., mastodon.social",
"interaction_modal.no_account_yet": "Neesi Mastodon?", "interaction_modal.no_account_yet": "Neesi Mastodon?",
"interaction_modal.on_another_server": "Citā serverī", "interaction_modal.on_another_server": "Citā serverī",
"interaction_modal.on_this_server": "Šajā serverī", "interaction_modal.on_this_server": "Šajā serverī",
"interaction_modal.sign_in": "Tu neesi pieteicies šajā serverī. Kur tiek mitināts tavs konts?", "interaction_modal.sign_in": "Tu neesi pieteicies šajā serverī. Kur tiek mitināts Tavs konts?",
"interaction_modal.sign_in_hint": "Padoms: Šī ir vietne, kurā tu piereģistrējies. Ja neatceries, meklē sveiciena e-pastu savā iesūtnē. Vari arī ievadīt pilnu lietotājvārdu! (piem., @Mastodon@mastodon.social)", "interaction_modal.sign_in_hint": "Padoms: tā ir tīmekļvietne, kurā Tu reģistrējies. Ja neatceries, jāmeklē sveiciena e-pasts savā iesūtnē. Vari arī ievadīt pilnu lietotājvārdu (piem., @Mastodon@mastodon.social).",
"interaction_modal.title.favourite": "Pievienot {name} ziņu izlasei", "interaction_modal.title.favourite": "Pievienot {name} ziņu izlasei",
"interaction_modal.title.follow": "Sekot {name}", "interaction_modal.title.follow": "Sekot {name}",
"interaction_modal.title.reblog": "Pastiprināt {name} ierakstu", "interaction_modal.title.reblog": "Pastiprināt {name} ierakstu",
@ -361,12 +376,12 @@
"link_preview.author": "Pēc {name}", "link_preview.author": "Pēc {name}",
"lists.account.add": "Pievienot sarakstam", "lists.account.add": "Pievienot sarakstam",
"lists.account.remove": "Noņemt no saraksta", "lists.account.remove": "Noņemt no saraksta",
"lists.delete": "Dzēst sarakstu", "lists.delete": "Izdzēst sarakstu",
"lists.edit": "Rediģēt sarakstu", "lists.edit": "Labot sarakstu",
"lists.edit.submit": "Mainīt virsrakstu", "lists.edit.submit": "Mainīt virsrakstu",
"lists.exclusive": "Paslēpt šīs ziņas no mājvietas", "lists.exclusive": "Nerādīt šos ierakstus sākumā",
"lists.new.create": "Pievienot sarakstu", "lists.new.create": "Pievienot sarakstu",
"lists.new.title_placeholder": "Jaunais saraksta nosaukums", "lists.new.title_placeholder": "Jaunā saraksta nosaukums",
"lists.replies_policy.followed": "Jebkuram sekotajam lietotājam", "lists.replies_policy.followed": "Jebkuram sekotajam lietotājam",
"lists.replies_policy.list": "Saraksta dalībniekiem", "lists.replies_policy.list": "Saraksta dalībniekiem",
"lists.replies_policy.none": "Nevienam", "lists.replies_policy.none": "Nevienam",
@ -374,8 +389,9 @@
"lists.search": "Meklēt starp cilvēkiem, kuriem tu seko", "lists.search": "Meklēt starp cilvēkiem, kuriem tu seko",
"lists.subheading": "Tavi saraksti", "lists.subheading": "Tavi saraksti",
"load_pending": "{count, plural, one {# jauna lieta} other {# jaunas lietas}}", "load_pending": "{count, plural, one {# jauna lieta} other {# jaunas lietas}}",
"loading_indicator.label": "Ielādē…",
"media_gallery.toggle_visible": "{number, plural, one {Slēpt attēlu} other {Slēpt attēlus}}", "media_gallery.toggle_visible": "{number, plural, one {Slēpt attēlu} other {Slēpt attēlus}}",
"moved_to_account_banner.text": "Tavs konts {disabledAccount} pašlaik ir atspējots, jo pārcēlies uz kontu {movedToAccount}.", "moved_to_account_banner.text": "Tavs konts {disabledAccount} pašlaik ir atspējots, jo Tu pārcēlies uz kontu {movedToAccount}.",
"mute_modal.duration": "Ilgums", "mute_modal.duration": "Ilgums",
"mute_modal.hide_notifications": "Slēpt paziņojumus no šī lietotāja?", "mute_modal.hide_notifications": "Slēpt paziņojumus no šī lietotāja?",
"mute_modal.indefinite": "Beztermiņa", "mute_modal.indefinite": "Beztermiņa",
@ -385,10 +401,10 @@
"navigation_bar.bookmarks": "Grāmatzīmes", "navigation_bar.bookmarks": "Grāmatzīmes",
"navigation_bar.community_timeline": "Vietējā laika līnija", "navigation_bar.community_timeline": "Vietējā laika līnija",
"navigation_bar.compose": "Veidot jaunu ziņu", "navigation_bar.compose": "Veidot jaunu ziņu",
"navigation_bar.direct": "Privāti pieminēti", "navigation_bar.direct": "Privātas pieminēšanas",
"navigation_bar.discover": "Atklāt", "navigation_bar.discover": "Atklāt",
"navigation_bar.domain_blocks": "Bloķētie domēni", "navigation_bar.domain_blocks": "Bloķētie domēni",
"navigation_bar.explore": "Pārlūkot", "navigation_bar.explore": "Izpētīt",
"navigation_bar.favourites": "Izlase", "navigation_bar.favourites": "Izlase",
"navigation_bar.filters": "Apklusinātie vārdi", "navigation_bar.filters": "Apklusinātie vārdi",
"navigation_bar.follow_requests": "Sekošanas pieprasījumi", "navigation_bar.follow_requests": "Sekošanas pieprasījumi",
@ -397,23 +413,23 @@
"navigation_bar.lists": "Saraksti", "navigation_bar.lists": "Saraksti",
"navigation_bar.logout": "Iziet", "navigation_bar.logout": "Iziet",
"navigation_bar.mutes": "Apklusinātie lietotāji", "navigation_bar.mutes": "Apklusinātie lietotāji",
"navigation_bar.opened_in_classic_interface": "Ziņas, konti un citas noteiktas lapas pēc noklusējuma tiek atvērtas klasiskajā tīmekļa saskarnē.", "navigation_bar.opened_in_classic_interface": "Ieraksti, konti un citas noteiktas lapas pēc noklusējuma tiek atvērtas klasiskajā tīmekļa saskarnē.",
"navigation_bar.personal": "Personīgie", "navigation_bar.personal": "Personīgie",
"navigation_bar.pins": "Piespraustās ziņas", "navigation_bar.pins": "Piespraustās ziņas",
"navigation_bar.preferences": "Iestatījumi", "navigation_bar.preferences": "Iestatījumi",
"navigation_bar.public_timeline": "Apvienotā laika līnija", "navigation_bar.public_timeline": "Apvienotā laika līnija",
"navigation_bar.search": "Meklēt", "navigation_bar.search": "Meklēt",
"navigation_bar.security": "Drošība", "navigation_bar.security": "Drošība",
"not_signed_in_indicator.not_signed_in": "Lai piekļūtu šim resursam, tev ir jāpierakstās.", "not_signed_in_indicator.not_signed_in": "Ir jāpiesakās, lai piekļūtu šim resursam.",
"notification.admin.report": "{name} ziņoja par {target}", "notification.admin.report": "{name} ziņoja par {target}",
"notification.admin.sign_up": "{name} ir pierakstījies", "notification.admin.sign_up": "{name} ir pierakstījies",
"notification.favourite": "{name} pievienoja tavu ziņu izlasei", "notification.favourite": "{name} pievienoja tavu ziņu izlasei",
"notification.follow": "{name} uzsāka tev sekot", "notification.follow": "{name} uzsāka Tev sekot",
"notification.follow_request": "{name} nosūtīja tev sekošanas pieprasījumu", "notification.follow_request": "{name} nosūtīja Tev sekošanas pieprasījumu",
"notification.mention": "{name} pieminēja tevi", "notification.mention": "{name} pieminēja Tevi",
"notification.own_poll": "Tava aptauja ir noslēgusies", "notification.own_poll": "Tava aptauja ir noslēgusies",
"notification.poll": "Aptauja, kurā tu piedalījies, ir noslēgusies", "notification.poll": "Aptauja, kurā tu piedalījies, ir noslēgusies",
"notification.reblog": "{name} pastiprināja tavu ierakstu", "notification.reblog": "{name} pastiprināja Tavu ierakstu",
"notification.status": "{name} tikko publicēja", "notification.status": "{name} tikko publicēja",
"notification.update": "{name} rediģēja ierakstu", "notification.update": "{name} rediģēja ierakstu",
"notifications.clear": "Notīrīt paziņojumus", "notifications.clear": "Notīrīt paziņojumus",
@ -427,7 +443,7 @@
"notifications.column_settings.filter_bar.show_bar": "Rādīt filtru joslu", "notifications.column_settings.filter_bar.show_bar": "Rādīt filtru joslu",
"notifications.column_settings.follow": "Jauni sekotāji:", "notifications.column_settings.follow": "Jauni sekotāji:",
"notifications.column_settings.follow_request": "Jauni sekošanas pieprasījumi:", "notifications.column_settings.follow_request": "Jauni sekošanas pieprasījumi:",
"notifications.column_settings.mention": "Pieminējumi:", "notifications.column_settings.mention": "Pieminēšanas:",
"notifications.column_settings.poll": "Aptaujas rezultāti:", "notifications.column_settings.poll": "Aptaujas rezultāti:",
"notifications.column_settings.push": "Uznirstošie paziņojumi", "notifications.column_settings.push": "Uznirstošie paziņojumi",
"notifications.column_settings.reblog": "Pastiprinātie ieraksti:", "notifications.column_settings.reblog": "Pastiprinātie ieraksti:",
@ -441,7 +457,7 @@
"notifications.filter.boosts": "Pastiprinātie ieraksti", "notifications.filter.boosts": "Pastiprinātie ieraksti",
"notifications.filter.favourites": "Izlases", "notifications.filter.favourites": "Izlases",
"notifications.filter.follows": "Seko", "notifications.filter.follows": "Seko",
"notifications.filter.mentions": "Pieminējumi", "notifications.filter.mentions": "Pieminēšanas",
"notifications.filter.polls": "Aptaujas rezultāti", "notifications.filter.polls": "Aptaujas rezultāti",
"notifications.filter.statuses": "Jaunumi no cilvēkiem, kuriem tu seko", "notifications.filter.statuses": "Jaunumi no cilvēkiem, kuriem tu seko",
"notifications.grant_permission": "Piešķirt atļauju.", "notifications.grant_permission": "Piešķirt atļauju.",
@ -458,27 +474,36 @@
"onboarding.actions.go_to_explore": "Skatīt tendences", "onboarding.actions.go_to_explore": "Skatīt tendences",
"onboarding.actions.go_to_home": "Dodieties uz manu mājas plūsmu", "onboarding.actions.go_to_home": "Dodieties uz manu mājas plūsmu",
"onboarding.compose.template": "Sveiki, #Mastodon!", "onboarding.compose.template": "Sveiki, #Mastodon!",
"onboarding.follows.empty": "Diemžēl pašlaik nevar parādīt rezultātus. Vari mēģināt izmantot meklēšanu vai pārlūkot izpētes lapu, lai atrastu personas, kurām sekot, vai mēģināt vēlreiz vēlāk.", "onboarding.follows.empty": "Diemžēl pašlaik nevar parādīt rezultātus. Vari mēģināt izmantot meklēšanu vai pārlūkot izpētes lapu, lai atrastu cilvēkus, kuriem sekot, vai vēlāk mēģināt vēlreiz.",
"onboarding.follows.lead": "Tava mājas plūsma ir galvenais veids, kā izbaudīt Mastodon. Jo vairāk cilvēku sekosi, jo aktīvāk un interesantāk tas būs. Lai sāktu, šeit ir daži ieteikumi:", "onboarding.follows.lead": "Tava mājas plūsma ir galvenais veids, kā izbaudīt Mastodon. Jo vairāk cilvēku sekosi, jo aktīvāk un interesantāk tas būs. Lai sāktu, šeit ir daži ieteikumi:",
"onboarding.follows.title": "Populārs Mastodon", "onboarding.follows.title": "Populārs Mastodon",
"onboarding.share.lead": "Paziņo citiem, kā viņi tevi var atrast Mastodon!", "onboarding.profile.discoverable": "Padarīt manu profilu atklājamu",
"onboarding.profile.display_name": "Attēlojamais vārds",
"onboarding.profile.display_name_hint": "Tavs pilnais vārds vai Tavs joku vārds…",
"onboarding.profile.note": "Apraksts",
"onboarding.profile.note_hint": "Tu vari @pieminēt citus cilvēkus vai #tēmturus…",
"onboarding.profile.save_and_continue": "Saglabāt un turpināt",
"onboarding.profile.title": "Profila iestatīšana",
"onboarding.profile.upload_avatar": "Augšupielādēt profila attēlu",
"onboarding.profile.upload_header": "Augšupielādēt profila galveni",
"onboarding.share.lead": "Dari cilvēkiem zināmu, ka viņi var Tevi atrast Mastodon!",
"onboarding.share.message": "Es esmu {username} #Mastodon! Nāc sekot man uz {url}", "onboarding.share.message": "Es esmu {username} #Mastodon! Nāc sekot man uz {url}",
"onboarding.share.next_steps": "Iespējamie nākamie soļi:", "onboarding.share.next_steps": "Iespējamie nākamie soļi:",
"onboarding.share.title": "Kopīgo savu profilu", "onboarding.share.title": "Kopīgo savu profilu",
"onboarding.start.lead": "Tagad tu esat daļa no Mastodon — unikālas, decentralizētas sociālo mediju platformas, kurā tu, nevis algoritms, veido savu pieredzi. Sāksim darbu šajā jaunajā sociālajā jomā:", "onboarding.start.lead": "Tagad Tu esi daļa no Mastodon — vienreizējas, decentralizētas sociālās mediju platformas, kurā Tu, nevis algoritms, veido Tavu pieredzi. Sāksim darbu šajā jaunajā sociālajā jomā:",
"onboarding.start.skip": "Nav nepieciešama palīdzība darba sākšanai?", "onboarding.start.skip": "Nav nepieciešama palīdzība darba sākšanai?",
"onboarding.start.title": "Tev tas izdevās!", "onboarding.start.title": "Tev tas izdevās!",
"onboarding.steps.follow_people.body": "Tu pats veido savu plūsmu. Piepildīsim to ar interesantiem cilvēkiem.", "onboarding.steps.follow_people.body": "Tu pats veido savu plūsmu. Piepildīsim to ar interesantiem cilvēkiem.",
"onboarding.steps.follow_people.title": "Sekot {count, plural, one {one person} other {# cilvēkiem}}", "onboarding.steps.follow_people.title": "Sekot {count, plural, one {one person} other {# cilvēkiem}}",
"onboarding.steps.publish_status.body": "Sveicini pasauli ar tekstu, fotoattēliem, video, vai aptaujām {emoji}", "onboarding.steps.publish_status.body": "Sveicini pasauli ar tekstu, fotoattēliem, video, vai aptaujām {emoji}",
"onboarding.steps.publish_status.title": "Izveido savu pirmo ziņu", "onboarding.steps.publish_status.title": "Izveido savu pirmo ziņu",
"onboarding.steps.setup_profile.body": "Citi, visticamāk, sazināsies ar tevi, izmantojot aizpildītu profilu.", "onboarding.steps.setup_profile.body": "Palielini mijiedarbību ar aptverošu profilu!",
"onboarding.steps.setup_profile.title": "Pielāgo savu profilu", "onboarding.steps.setup_profile.title": "Pielāgo savu profilu",
"onboarding.steps.share_profile.body": "Paziņo saviem draugiem, kā tevi atrast Mastodon!", "onboarding.steps.share_profile.body": "Dari saviem draugiem zināmu, kā Tevi atrast Mastodon!",
"onboarding.steps.share_profile.title": "Kopīgo savu Mastodon profilu", "onboarding.steps.share_profile.title": "Kopīgo savu Mastodon profilu",
"onboarding.tips.2fa": "<strong>Vai zināji?</strong> Tu vari aizsargāt savu kontu, konta iestatījumos iestatot divu faktoru autentifikāciju. Tas darbojas ar jebkuru tevis izvēlētu TOTP lietotni, nav nepieciešams tālruņa numurs!", "onboarding.tips.2fa": "<strong>Vai zināji?</strong> Tu vari aizsargāt savu kontu, konta iestatījumos iestatot divpakāpju autentifikāciju. Tas darbojas ar jebkuru Tevis izvēlētu TOTP lietotni, nav nepieciešams tālruņa numurs!",
"onboarding.tips.accounts_from_other_servers": "<strong>Vai zināji?</strong> Tā kā Mastodon ir decentralizēts, daži profili, ar kuriem saskaraties, tiks mitināti citos, nevis tavos serveros. Un tomēr tu varat sazināties ar viņiem nevainojami! Viņu serveris atrodas viņu lietotājvārda otrajā pusē!", "onboarding.tips.accounts_from_other_servers": "<strong>Vai zināji?</strong> Tā kā Mastodon ir decentralizēts, daži profili, ar kuriem saskaraties, tiks mitināti citos, nevis tavos serveros. Un tomēr tu varat sazināties ar viņiem nevainojami! Viņu serveris atrodas viņu lietotājvārda otrajā pusē!",
"onboarding.tips.migration": "<strong>Vai zināji?</strong> Ja uzskati, ka {domain} nākotnē nav lieliska servera izvēle, vari pāriet uz citu Mastodon serveri, nezaudējot savus sekotājus. Tu pat vari mitināt savu personīgo serveri!", "onboarding.tips.migration": "<strong>Vai zināji?</strong> Ja uzskati, ka {domain} nākotnē nav lieliska servera izvēle, vari pāriet uz citu Mastodon serveri, nezaudējot savus sekotājus. Tu pat vari mitināt savu serveri!",
"onboarding.tips.verification": "<strong>Vai zināji?</strong> Tu vari verificēt savu kontu, ievietojot saiti uz savu Mastodon profilu savā vietnē un pievienojot vietni savam profilam. Nav nepieciešami nekādi maksājumi vai dokumenti!", "onboarding.tips.verification": "<strong>Vai zināji?</strong> Tu vari verificēt savu kontu, ievietojot saiti uz savu Mastodon profilu savā vietnē un pievienojot vietni savam profilam. Nav nepieciešami nekādi maksājumi vai dokumenti!",
"password_confirmation.exceeds_maxlength": "Paroles apstiprināšana pārsniedz maksimālo paroles garumu", "password_confirmation.exceeds_maxlength": "Paroles apstiprināšana pārsniedz maksimālo paroles garumu",
"password_confirmation.mismatching": "Paroles apstiprinājums neatbilst", "password_confirmation.mismatching": "Paroles apstiprinājums neatbilst",
@ -494,9 +519,14 @@
"poll_button.add_poll": "Pievienot aptauju", "poll_button.add_poll": "Pievienot aptauju",
"poll_button.remove_poll": "Noņemt aptauju", "poll_button.remove_poll": "Noņemt aptauju",
"privacy.change": "Mainīt ieraksta privātumu", "privacy.change": "Mainīt ieraksta privātumu",
"privacy.direct.long": "Visi ierakstā pieminētie",
"privacy.direct.short": "Noteikti cilvēki",
"privacy.private.long": "Tikai Tavi sekotāji",
"privacy.private.short": "Sekotāji",
"privacy.public.short": "Publiska", "privacy.public.short": "Publiska",
"privacy_policy.last_updated": "Pēdējo reizi atjaunināta {date}", "privacy_policy.last_updated": "Pēdējo reizi atjaunināta {date}",
"privacy_policy.title": "Privātuma politika", "privacy_policy.title": "Privātuma politika",
"recommended": "Ieteicams",
"refresh": "Atsvaidzināt", "refresh": "Atsvaidzināt",
"regeneration_indicator.label": "Ielādē…", "regeneration_indicator.label": "Ielādē…",
"regeneration_indicator.sublabel": "Tiek gatavota tava plūsma!", "regeneration_indicator.sublabel": "Tiek gatavota tava plūsma!",
@ -512,8 +542,9 @@
"relative_time.seconds": "{number}s", "relative_time.seconds": "{number}s",
"relative_time.today": "šodien", "relative_time.today": "šodien",
"reply_indicator.cancel": "Atcelt", "reply_indicator.cancel": "Atcelt",
"reply_indicator.poll": "Aptauja",
"report.block": "Bloķēt", "report.block": "Bloķēt",
"report.block_explanation": "Tu neredzēsi viņu ziņas. Viņi nevarēs redzēt tavas ziņas vai sekot tev. Viņi varēs saprast, ka ir bloķēti.", "report.block_explanation": "Tu neredzēsi viņu ierakstus. Viņi nevarēs redzēt Tavus ierakstus vai sekot tev. Viņi varēs saprast, ka ir bloķēti.",
"report.categories.legal": "Tiesisks", "report.categories.legal": "Tiesisks",
"report.categories.other": "Citi", "report.categories.other": "Citi",
"report.categories.spam": "Spams", "report.categories.spam": "Spams",
@ -527,7 +558,7 @@
"report.forward": "Pārsūtīt {target}", "report.forward": "Pārsūtīt {target}",
"report.forward_hint": "Konts ir no cita servera. Vai nosūtīt anonimizētu sūdzības kopiju arī tam?", "report.forward_hint": "Konts ir no cita servera. Vai nosūtīt anonimizētu sūdzības kopiju arī tam?",
"report.mute": "Apklusināt", "report.mute": "Apklusināt",
"report.mute_explanation": "Tu neredzēsi viņu ziņas. Viņi joprojām var tev sekot un redzēt tavas ziņas un nezinās, ka viņi ir apklusināti.", "report.mute_explanation": "Tu neredzēsi viņu ierakstus. Viņi joprojām var Tev sekot un redzēt Tavus ierakstus un nezinās, ka viņi ir apklusināti.",
"report.next": "Tālāk", "report.next": "Tālāk",
"report.placeholder": "Papildu komentāri", "report.placeholder": "Papildu komentāri",
"report.reasons.dislike": "Man tas nepatīk", "report.reasons.dislike": "Man tas nepatīk",
@ -543,15 +574,15 @@
"report.rules.subtitle": "Atlasi visus atbilstošos", "report.rules.subtitle": "Atlasi visus atbilstošos",
"report.rules.title": "Kuri noteikumi tiek pārkāpti?", "report.rules.title": "Kuri noteikumi tiek pārkāpti?",
"report.statuses.subtitle": "Atlasi visus atbilstošos", "report.statuses.subtitle": "Atlasi visus atbilstošos",
"report.statuses.title": "Vai ir kādi ieraksti, kas atbalsta šo sūdzību?", "report.statuses.title": "Vai ir kādi ieraksti, kas apstiprina šo ziņojumu?",
"report.submit": "Iesniegt", "report.submit": "Iesniegt",
"report.target": "Ziņošana par: {target}", "report.target": "Ziņošana par: {target}",
"report.thanks.take_action": "Tālāk ir norādītas iespējas, kā kontrolēt Mastodon redzamo saturu:", "report.thanks.take_action": "Šeit ir iespējas, lai pārvaldītu Mastodon redzamo saturu:",
"report.thanks.take_action_actionable": "Kamēr mēs to izskatām, tu vari veikt darbības pret @{name}:", "report.thanks.take_action_actionable": "Kamēr mēs to izskatām, tu vari veikt darbības pret @{name}:",
"report.thanks.title": "Vai nevēlies to redzēt?", "report.thanks.title": "Vai nevēlies to redzēt?",
"report.thanks.title_actionable": "Paldies, ka ziņoji, mēs to izskatīsim.", "report.thanks.title_actionable": "Paldies, ka ziņoji, mēs to izskatīsim.",
"report.unfollow": "Pārtraukt sekot @{name}", "report.unfollow": "Pārtraukt sekot @{name}",
"report.unfollow_explanation": "Tu seko šim kontam. Lai vairs neredzētu viņu ziņas savā mājas plūsmā, pārtrauc viņiem sekot.", "report.unfollow_explanation": "Tu seko šim kontam. Lai vairs neredzētu tā ierakstus savā mājas plūsmā, pārtrauc sekot tam!",
"report_notification.attached_statuses": "Pievienoti {count, plural,one {{count} sūtījums} other {{count} sūtījumi}}", "report_notification.attached_statuses": "Pievienoti {count, plural,one {{count} sūtījums} other {{count} sūtījumi}}",
"report_notification.categories.legal": "Tiesisks", "report_notification.categories.legal": "Tiesisks",
"report_notification.categories.other": "Cita", "report_notification.categories.other": "Cita",
@ -564,19 +595,20 @@
"search.quick_action.go_to_account": "Doties uz profilu {x}", "search.quick_action.go_to_account": "Doties uz profilu {x}",
"search.quick_action.go_to_hashtag": "Doties uz tēmturi {x}", "search.quick_action.go_to_hashtag": "Doties uz tēmturi {x}",
"search.quick_action.open_url": "Atvērt URL Mastodonā", "search.quick_action.open_url": "Atvērt URL Mastodonā",
"search.quick_action.status_search": "Ziņas atbilst {x}", "search.quick_action.status_search": "Ieraksti, kas atbilst {x}",
"search.search_or_paste": "Meklē vai iekopē URL", "search.search_or_paste": "Meklēt vai ielīmēt URL",
"search_popout.full_text_search_disabled_message": "Nav pieejams {domain}.", "search_popout.full_text_search_disabled_message": "Nav pieejams {domain}.",
"search_popout.full_text_search_logged_out_message": "Pieejams tikai pēc pieteikšanās.",
"search_popout.language_code": "ISO valodas kods", "search_popout.language_code": "ISO valodas kods",
"search_popout.options": "Meklēšanas iespējas", "search_popout.options": "Meklēšanas iespējas",
"search_popout.quick_actions": "Ātrās darbības", "search_popout.quick_actions": "Ātrās darbības",
"search_popout.recent": "Nesen meklētais", "search_popout.recent": "Nesen meklētais",
"search_popout.specific_date": "konkts datums", "search_popout.specific_date": "noteikts datums",
"search_popout.user": "lietotājs", "search_popout.user": "lietotājs",
"search_results.accounts": "Profili", "search_results.accounts": "Profili",
"search_results.all": "Visi", "search_results.all": "Visi",
"search_results.hashtags": "Tēmturi", "search_results.hashtags": "Tēmturi",
"search_results.nothing_found": "Nevarēja atrast neko šiem meklēšanas vienumiem", "search_results.nothing_found": "Nevarēja atrast neko, kas atbilstu šim meklēšanas vaicājumam",
"search_results.see_all": "Skatīt visus", "search_results.see_all": "Skatīt visus",
"search_results.statuses": "Ieraksti", "search_results.statuses": "Ieraksti",
"search_results.title": "Meklēt {q}", "search_results.title": "Meklēt {q}",
@ -587,9 +619,9 @@
"server_banner.learn_more": "Uzzināt vairāk", "server_banner.learn_more": "Uzzināt vairāk",
"server_banner.server_stats": "Servera statistika:", "server_banner.server_stats": "Servera statistika:",
"sign_in_banner.create_account": "Izveidot kontu", "sign_in_banner.create_account": "Izveidot kontu",
"sign_in_banner.sign_in": "Pierakstīties", "sign_in_banner.sign_in": "Pieteikties",
"sign_in_banner.sso_redirect": "Piesakies vai Reģistrējies", "sign_in_banner.sso_redirect": "Piesakies vai Reģistrējies",
"sign_in_banner.text": "Pieraksties, lai sekotu profiliem vai atsaucēm, pievienotu izlasei, kopīgotu ziņas un atbildētu uz tām. Vari arī mijiedarboties no sava konta citā serverī.", "sign_in_banner.text": "Jāpiesakās, lai sekotu profiliem vai tēmturiem, pievienotu izlasei, kopīgotu ierakstus un atbildētu uz tiem. Vari arī mijiedarboties ar savu kontu citā serverī.",
"status.admin_account": "Atvērt @{name} moderēšanas saskarni", "status.admin_account": "Atvērt @{name} moderēšanas saskarni",
"status.admin_domain": "Atvērt {domain} moderēšanas saskarni", "status.admin_domain": "Atvērt {domain} moderēšanas saskarni",
"status.admin_status": "Atvērt šo ziņu moderācijas saskarnē", "status.admin_status": "Atvērt šo ziņu moderācijas saskarnē",
@ -602,16 +634,16 @@
"status.detailed_status": "Detalizēts sarunas skats", "status.detailed_status": "Detalizēts sarunas skats",
"status.direct": "Pieminēt @{name} privāti", "status.direct": "Pieminēt @{name} privāti",
"status.direct_indicator": "Pieminēts privāti", "status.direct_indicator": "Pieminēts privāti",
"status.edit": "Rediģēt", "status.edit": "Labot",
"status.edited": "Rediģēts {date}", "status.edited": "Labots {date}",
"status.edited_x_times": "Rediģēts {count, plural, one {{count} reize} other {{count} reizes}}", "status.edited_x_times": "Labots {count, plural, one {{count} reizi} other {{count} reizes}}",
"status.embed": "Iestrādāt", "status.embed": "Iestrādāt",
"status.favourite": "Iecienīts", "status.favourite": "Iecienīts",
"status.filter": "Filtrē šo ziņu", "status.filter": "Filtrē šo ziņu",
"status.filtered": "Filtrēts", "status.filtered": "Filtrēts",
"status.hide": "Slēpt ierakstu", "status.hide": "Slēpt ierakstu",
"status.history.created": "{name} izveidoja {date}", "status.history.created": "{name} izveidoja {date}",
"status.history.edited": "{name} rediģēja {date}", "status.history.edited": "{name} laboja {date}",
"status.load_more": "Ielādēt vairāk", "status.load_more": "Ielādēt vairāk",
"status.media.open": "Noklikšķini, lai atvērtu", "status.media.open": "Noklikšķini, lai atvērtu",
"status.media.show": "Noklikšķini, lai parādītu", "status.media.show": "Noklikšķini, lai parādītu",
@ -648,7 +680,7 @@
"status.uncached_media_warning": "Priekšskatījums nav pieejams", "status.uncached_media_warning": "Priekšskatījums nav pieejams",
"status.unmute_conversation": "Noņemt sarunas apklusinājumu", "status.unmute_conversation": "Noņemt sarunas apklusinājumu",
"status.unpin": "Noņemt profila piespraudumu", "status.unpin": "Noņemt profila piespraudumu",
"subscribed_languages.lead": "Pēc izmaiņu veikšanas tavā mājas un sarakstu laika līnijā tiks rādītas tikai ziņas atlasītajās valodās. Neatlasi nevienu, lai saņemtu ziņas visās valodās.", "subscribed_languages.lead": "Pēc izmaiņu veikšanas Tavā mājas un sarakstu laika līnijā tiks rādīti tikai tie ieraksti atlasītajās valodās. Neatlasīt nevienu, lai saņemtu ierakstus visās valodās.",
"subscribed_languages.save": "Saglabāt izmaiņas", "subscribed_languages.save": "Saglabāt izmaiņas",
"subscribed_languages.target": "Mainīt abonētās valodas priekš {target}", "subscribed_languages.target": "Mainīt abonētās valodas priekš {target}",
"tabs_bar.home": "Sākums", "tabs_bar.home": "Sākums",
@ -662,8 +694,8 @@
"timeline_hint.resources.followers": "Sekotāji", "timeline_hint.resources.followers": "Sekotāji",
"timeline_hint.resources.follows": "Seko", "timeline_hint.resources.follows": "Seko",
"timeline_hint.resources.statuses": "Vecāki ieraksti", "timeline_hint.resources.statuses": "Vecāki ieraksti",
"trends.counter_by_accounts": "{count, plural, one {{counter} persona} other {{counter} cilvēki}} par {days, plural, one {# dienu} other {{days} dienām}}", "trends.counter_by_accounts": "{count, plural, zero {{counter} cilvēku} one {{counter} cilvēks} other {{counter} cilvēki}} {days, plural, one {{day} dienā} other {{days} dienās}}",
"trends.trending_now": "Aktuālās tendences", "trends.trending_now": "Pašlaik populāri",
"ui.beforeunload": "Ja pametīsit Mastodonu, jūsu melnraksts tiks zaudēts.", "ui.beforeunload": "Ja pametīsit Mastodonu, jūsu melnraksts tiks zaudēts.",
"units.short.billion": "{count}Mjd", "units.short.billion": "{count}Mjd",
"units.short.million": "{count}M", "units.short.million": "{count}M",
@ -674,7 +706,7 @@
"upload_error.poll": "Datņu augšupielādes aptaujās nav atļautas.", "upload_error.poll": "Datņu augšupielādes aptaujās nav atļautas.",
"upload_form.audio_description": "Pievieno aprakstu cilvēkiem ar dzirdes zudumu", "upload_form.audio_description": "Pievieno aprakstu cilvēkiem ar dzirdes zudumu",
"upload_form.description": "Pievieno aprakstu vājredzīgajiem", "upload_form.description": "Pievieno aprakstu vājredzīgajiem",
"upload_form.edit": "Rediģēt", "upload_form.edit": "Labot",
"upload_form.thumbnail": "Nomainīt sīktēlu", "upload_form.thumbnail": "Nomainīt sīktēlu",
"upload_form.video_description": "Pievieno aprakstu cilvēkiem ar dzirdes vai redzes traucējumiem", "upload_form.video_description": "Pievieno aprakstu cilvēkiem ar dzirdes vai redzes traucējumiem",
"upload_modal.analyzing_picture": "Analizē attēlu…", "upload_modal.analyzing_picture": "Analizē attēlu…",
@ -683,7 +715,7 @@
"upload_modal.choose_image": "Izvēlēties attēlu", "upload_modal.choose_image": "Izvēlēties attēlu",
"upload_modal.description_placeholder": "Raibais runcis rīgā ratu rumbā rūc", "upload_modal.description_placeholder": "Raibais runcis rīgā ratu rumbā rūc",
"upload_modal.detect_text": "Noteikt tekstu no attēla", "upload_modal.detect_text": "Noteikt tekstu no attēla",
"upload_modal.edit_media": "Rediģēt multividi", "upload_modal.edit_media": "Labot informācijas nesēju",
"upload_modal.hint": "Noklikšķini vai velc apli priekšskatījumā, lai izvēlētos fokusa punktu, kas vienmēr būs redzams visos sīktēlos.", "upload_modal.hint": "Noklikšķini vai velc apli priekšskatījumā, lai izvēlētos fokusa punktu, kas vienmēr būs redzams visos sīktēlos.",
"upload_modal.preparing_ocr": "Sagatavo OCR…", "upload_modal.preparing_ocr": "Sagatavo OCR…",
"upload_modal.preview_label": "Priekšskatīt ({ratio})", "upload_modal.preview_label": "Priekšskatīt ({ratio})",

View file

@ -530,7 +530,7 @@
"poll_button.remove_poll": "Peiling verwijderen", "poll_button.remove_poll": "Peiling verwijderen",
"privacy.change": "Zichtbaarheid van bericht aanpassen", "privacy.change": "Zichtbaarheid van bericht aanpassen",
"privacy.direct.long": "Alleen voor mensen die specifiek in het bericht worden vermeld", "privacy.direct.long": "Alleen voor mensen die specifiek in het bericht worden vermeld",
"privacy.direct.short": "Specifieke mensen", "privacy.direct.short": "Privébericht",
"privacy.private.long": "Alleen jouw volgers", "privacy.private.long": "Alleen jouw volgers",
"privacy.private.short": "Volgers", "privacy.private.short": "Volgers",
"privacy.public.long": "Iedereen op Mastodon en daarbuiten", "privacy.public.long": "Iedereen op Mastodon en daarbuiten",
@ -666,7 +666,7 @@
"status.mention": "@{name} vermelden", "status.mention": "@{name} vermelden",
"status.more": "Meer", "status.more": "Meer",
"status.mute": "@{name} negeren", "status.mute": "@{name} negeren",
"status.mute_conversation": "Negeer gesprek", "status.mute_conversation": "Gesprek negeren",
"status.open": "Volledig bericht tonen", "status.open": "Volledig bericht tonen",
"status.pin": "Aan profielpagina vastmaken", "status.pin": "Aan profielpagina vastmaken",
"status.pinned": "Vastgemaakt bericht", "status.pinned": "Vastgemaakt bericht",

View file

@ -277,6 +277,7 @@
"follow_request.authorize": "Autoriser", "follow_request.authorize": "Autoriser",
"follow_request.reject": "Avvis", "follow_request.reject": "Avvis",
"follow_requests.unlocked_explanation": "Selv om kontoen din ikke er låst, tror {domain} ansatte at du kanskje vil gjennomgå forespørsler fra disse kontoene manuelt.", "follow_requests.unlocked_explanation": "Selv om kontoen din ikke er låst, tror {domain} ansatte at du kanskje vil gjennomgå forespørsler fra disse kontoene manuelt.",
"follow_suggestions.view_all": "Vis alle",
"followed_tags": "Fulgte emneknagger", "followed_tags": "Fulgte emneknagger",
"footer.about": "Om", "footer.about": "Om",
"footer.directory": "Profilkatalog", "footer.directory": "Profilkatalog",

View file

@ -375,7 +375,7 @@
"lightbox.previous": "Назад", "lightbox.previous": "Назад",
"limited_account_hint.action": "Все равно показать профиль", "limited_account_hint.action": "Все равно показать профиль",
"limited_account_hint.title": "Этот профиль был скрыт модераторами {domain}.", "limited_account_hint.title": "Этот профиль был скрыт модераторами {domain}.",
"link_preview.author": "По алфавиту", "link_preview.author": "Автор: {name}",
"lists.account.add": "Добавить в список", "lists.account.add": "Добавить в список",
"lists.account.remove": "Убрать из списка", "lists.account.remove": "Убрать из списка",
"lists.delete": "Удалить список", "lists.delete": "Удалить список",

View file

@ -1 +1,19 @@
{} {
"about.blocks": "Модеровані серверы",
"about.contact": "Контакт:",
"about.disclaimer": "Mastodon є задарьнов проґрамов из удпертым кодом тай торговов значков Mastodon gGmbH.",
"about.domain_blocks.no_reason_available": "Причины не ясні",
"about.domain_blocks.silenced.title": "Обмежено",
"about.domain_blocks.suspended.explanation": "Ниякі податкы из сього сервера не будут уброблені, усокочені ци поміняні, што чинит невозможнов хоть-яку інтеракцію ци зязок из хосновачами из сього сервера.",
"about.domain_blocks.suspended.title": "Заблоковано",
"about.rules": "Правила сервера",
"account.account_note_header": "Примітка",
"account.add_or_remove_from_list": "Дати авадь забрати из исписа",
"account.badges.bot": "Автоматічно",
"account.badges.group": "Ґрупа",
"account.block": "Заблоковати @{name}",
"account.block_domain": "Заблоковати домен {domain}",
"account.block_short": "Заблоковати",
"account.blocked": "Заблоковано",
"account.browse_more_on_origin_server": "Позирайте бульше на ориґіналнум профілю"
}

File diff suppressed because it is too large Load diff

View file

@ -277,7 +277,13 @@
"follow_request.authorize": "Odobri", "follow_request.authorize": "Odobri",
"follow_request.reject": "Odbij", "follow_request.reject": "Odbij",
"follow_requests.unlocked_explanation": "Iako vaš nalog nije zaključan, osoblje {domain} smatra da biste možda želeli da ručno pregledate zahteve za praćenje sa ovih naloga.", "follow_requests.unlocked_explanation": "Iako vaš nalog nije zaključan, osoblje {domain} smatra da biste možda želeli da ručno pregledate zahteve za praćenje sa ovih naloga.",
"follow_suggestions.curated_suggestion": "Izbor osoblja",
"follow_suggestions.dismiss": "Ne prikazuj ponovo", "follow_suggestions.dismiss": "Ne prikazuj ponovo",
"follow_suggestions.hints.featured": "Ovaj profil je ručno izabrao tim {domain}.",
"follow_suggestions.hints.friends_of_friends": "Ovaj profil je popularan među ljudima koje pratite.",
"follow_suggestions.hints.most_followed": "Ovaj profil je jedan od najpraćenijih na {domain}.",
"follow_suggestions.hints.most_interactions": "Ovaj profil je nedavno dobio veliku pažnju na {domain}.",
"follow_suggestions.hints.similar_to_recently_followed": "Ovaj profil je sličan profilima koje ste nedavno zapratili.",
"follow_suggestions.personalized_suggestion": "Personalizovani predlog", "follow_suggestions.personalized_suggestion": "Personalizovani predlog",
"follow_suggestions.popular_suggestion": "Popularni predlog", "follow_suggestions.popular_suggestion": "Popularni predlog",
"follow_suggestions.view_all": "Prikaži sve", "follow_suggestions.view_all": "Prikaži sve",

View file

@ -277,6 +277,7 @@
"follow_request.authorize": "Одобри", "follow_request.authorize": "Одобри",
"follow_request.reject": "Одбиј", "follow_request.reject": "Одбиј",
"follow_requests.unlocked_explanation": "Иако ваш налог није закључан, особље {domain} сматра да бисте можда желели да ручно прегледате захтеве за праћење са ових налога.", "follow_requests.unlocked_explanation": "Иако ваш налог није закључан, особље {domain} сматра да бисте можда желели да ручно прегледате захтеве за праћење са ових налога.",
"follow_suggestions.curated_suggestion": "Избор особља",
"follow_suggestions.dismiss": "Не приказуј поново", "follow_suggestions.dismiss": "Не приказуј поново",
"follow_suggestions.hints.featured": "Овај профил је ручно изабрао тим {domain}.", "follow_suggestions.hints.featured": "Овај профил је ручно изабрао тим {domain}.",
"follow_suggestions.hints.friends_of_friends": "Овај профил је популаран међу људима које пратите.", "follow_suggestions.hints.friends_of_friends": "Овај профил је популаран међу људима које пратите.",
@ -507,7 +508,7 @@
"onboarding.steps.publish_status.body": "Поздравите свет текстом, сликама, видео снимцима или анкетама {emoji}", "onboarding.steps.publish_status.body": "Поздравите свет текстом, сликама, видео снимцима или анкетама {emoji}",
"onboarding.steps.publish_status.title": "Напишите своју прву објаву", "onboarding.steps.publish_status.title": "Напишите своју прву објаву",
"onboarding.steps.setup_profile.body": "Појачајте своје интеракције тако што ћете имати свеобухватан профил.", "onboarding.steps.setup_profile.body": "Појачајте своје интеракције тако што ћете имати свеобухватан профил.",
"onboarding.steps.setup_profile.title": "Персонализујтее свој профил", "onboarding.steps.setup_profile.title": "Персонализујте свој профил",
"onboarding.steps.share_profile.body": "Нека ваши пријатељи знају како да вас пронађу на Mastodon-у!", "onboarding.steps.share_profile.body": "Нека ваши пријатељи знају како да вас пронађу на Mastodon-у!",
"onboarding.steps.share_profile.title": "Поделите свој Mastodon профил", "onboarding.steps.share_profile.title": "Поделите свој Mastodon профил",
"onboarding.tips.2fa": "<strong>Да ли сте знали?</strong> Можете да заштитите свој налог подешавањем двоструке потврде идентитета у подешавањима налога. Ради са било којом TOTP апликацијом по вашем избору, није потребан број телефона!", "onboarding.tips.2fa": "<strong>Да ли сте знали?</strong> Можете да заштитите свој налог подешавањем двоструке потврде идентитета у подешавањима налога. Ради са било којом TOTP апликацијом по вашем избору, није потребан број телефона!",

View file

@ -119,6 +119,7 @@
"compose_form.save_changes": "o sin e ni", "compose_form.save_changes": "o sin e ni",
"compose_form.spoiler.marked": "o weka e toki pi ijo ike ken", "compose_form.spoiler.marked": "o weka e toki pi ijo ike ken",
"confirmation_modal.cancel": "o pini", "confirmation_modal.cancel": "o pini",
"confirmations.block.block_and_report": "o weka e jan o toki e jan tawa lawa",
"confirmations.block.confirm": "o weka", "confirmations.block.confirm": "o weka",
"confirmations.block.message": "sina o wile ala wile weka e jan {name}?", "confirmations.block.message": "sina o wile ala wile weka e jan {name}?",
"confirmations.cancel_follow_request.confirm": "o weka e wile sina", "confirmations.cancel_follow_request.confirm": "o weka e wile sina",
@ -132,20 +133,24 @@
"confirmations.domain_block.confirm": "o weka.", "confirmations.domain_block.confirm": "o weka.",
"confirmations.domain_block.message": "sina wile ala a wile a len e ma {domain} ꞏ ken suli la len jan taso li pona ꞏ len pi ma ni la sina ken ala lukin e ijo pi ma ni lon lipu toki ale anu lukin toki ꞏ len ni la jan kute sina pi ma ni li weka", "confirmations.domain_block.message": "sina wile ala a wile a len e ma {domain} ꞏ ken suli la len jan taso li pona ꞏ len pi ma ni la sina ken ala lukin e ijo pi ma ni lon lipu toki ale anu lukin toki ꞏ len ni la jan kute sina pi ma ni li weka",
"confirmations.edit.confirm": "o ante", "confirmations.edit.confirm": "o ante",
"confirmations.edit.message": "sina ante e toki sina la toki pali sina li weka. sina wile ala wile e ni?",
"confirmations.logout.confirm": "o weka", "confirmations.logout.confirm": "o weka",
"confirmations.logout.message": "sina wile ala wile weka", "confirmations.logout.message": "sina wile ala wile weka",
"confirmations.mute.confirm": "o len", "confirmations.mute.confirm": "o len",
"confirmations.mute.explanation": "ni la sina lukin ala e toki ona e toki kepeken nimi ona. taso la ona li ken lukin e toki sina li ken kute e ona.",
"confirmations.mute.message": "sina awen ala awen wile kute ala e {name}?", "confirmations.mute.message": "sina awen ala awen wile kute ala e {name}?",
"confirmations.redraft.confirm": "o weka o pali sin e toki", "confirmations.redraft.confirm": "o weka o pali sin e toki",
"confirmations.redraft.message": "pali sin e toki ni la sina wile ala wile weka e ona? sina ni la suli pi toki ni en wawa pi toki ni li weka. kin la toki lon toki ni li jo e mama ala.", "confirmations.redraft.message": "pali sin e toki ni la sina wile ala wile weka e ona? sina ni la suli pi toki ni en wawa pi toki ni li weka. kin la toki lon toki ni li jo e mama ala.",
"confirmations.reply.confirm": "toki lon toki ni", "confirmations.reply.confirm": "toki lon toki ni",
"confirmations.reply.message": "toki tawa ona li weka e toki pali sina ꞏ sina wile ala wile ni", "confirmations.reply.message": "sina toki lon toki ni la toki pali sina li weka. sina wile ala wile e ni?",
"confirmations.unfollow.confirm": "o pini kute", "confirmations.unfollow.confirm": "o pini kute",
"confirmations.unfollow.message": "sina o wile ala wile pini kute e jan {name}?", "confirmations.unfollow.message": "sina o wile ala wile pini kute e jan {name}?",
"conversation.delete": "o weka e toki ni", "conversation.delete": "o weka e toki ni",
"conversation.mark_as_read": "ni o sin ala", "conversation.mark_as_read": "ni o sin ala",
"conversation.open": "o lukin e toki", "conversation.open": "o lukin e toki",
"conversation.with": "lon {names}", "conversation.with": "lon {names}",
"copy_icon_button.copied": "toki li awen lon ilo sina",
"copypaste.copy_to_clipboard": "o awen lon ilo sina",
"directory.local": "tan {domain} taso", "directory.local": "tan {domain} taso",
"directory.new_arrivals": "jan pi kama sin", "directory.new_arrivals": "jan pi kama sin",
"directory.recently_active": "jan lon tenpo poka", "directory.recently_active": "jan lon tenpo poka",
@ -154,6 +159,9 @@
"dismissable_banner.community_timeline": "ni li toki pi tenpo poka tawa ale tan jan lon ma lawa pi nimi {domain}.", "dismissable_banner.community_timeline": "ni li toki pi tenpo poka tawa ale tan jan lon ma lawa pi nimi {domain}.",
"dismissable_banner.dismiss": "o weka", "dismissable_banner.dismiss": "o weka",
"dismissable_banner.explore_links": "ni li toki pi ijo sin ꞏ jan mute li pana e ni lon tenpo suno ni ꞏ sin la jan mute li pana la ni li kama suli", "dismissable_banner.explore_links": "ni li toki pi ijo sin ꞏ jan mute li pana e ni lon tenpo suno ni ꞏ sin la jan mute li pana la ni li kama suli",
"dismissable_banner.explore_statuses": "suni ni la jan mute li lukin e toki ni. jan mute li wawa e toki li suli e toki la toki ni li lon sewi. toki li sin la toki ni li lon sewi.",
"dismissable_banner.explore_tags": "suni ni la jan mute li lukin e toki pi toki ni. jan mute li kepeken toki la toki ni li lon sewi.",
"dismissable_banner.public_timeline": "toki ni li sin. jan li pali e toki ni la jan ante mute pi ma {domain} li kute e jan ni.",
"embed.preview": "ni li jo e sitelen ni:", "embed.preview": "ni li jo e sitelen ni:",
"emoji_button.activity": "musi", "emoji_button.activity": "musi",
"emoji_button.flags": "len ma", "emoji_button.flags": "len ma",
@ -171,15 +179,25 @@
"empty_column.account_timeline": "toki ala li lon!", "empty_column.account_timeline": "toki ala li lon!",
"empty_column.account_unavailable": "ken ala lukin e lipu jan", "empty_column.account_unavailable": "ken ala lukin e lipu jan",
"empty_column.blocks": "jan ala li weka tawa sina.", "empty_column.blocks": "jan ala li weka tawa sina.",
"empty_column.direct": "jan ala li toki len e sina. jan li toki len e sina la sina ken lukin e ni lon ni.",
"empty_column.domain_blocks": "ma ala li weka tawa sina.",
"empty_column.favourited_statuses": "sina suli ala e toki. sina suli e toki la sina ken lukin e toki ni lon ni.",
"empty_column.favourites": "jan ala li suli e toki ni. jan li suli e toki ni la sina ken lukin e ona lon ni.",
"empty_column.follow_requests": "jan ala li toki pi wile kute tawa sina. jan li toki pi wile kute tawa sina la sina ken lukin e toki ni lon ni.",
"empty_column.followed_tags": "sina alasa ala e toki ꞏ sina alasa e toki la toki li lon ni", "empty_column.followed_tags": "sina alasa ala e toki ꞏ sina alasa e toki la toki li lon ni",
"empty_column.hashtag": "ala li lon toki ni", "empty_column.hashtag": "ala li lon toki ni",
"empty_column.home": "ala a li lon lipu open sina! sina wile lon e ijo lon ni la o kute e jan pi toki suli.",
"empty_column.list": "ala li lon kulupu lipu ni. jan pi kulupu lipu ni li toki sin la toki ni li lon ni.",
"empty_column.lists": "sina jo ala e kulupu lipu. sina pali sin e kulupu lipu la ona li lon ni.",
"empty_column.mutes": "jan ala li len tawa sina.", "empty_column.mutes": "jan ala li len tawa sina.",
"error.unexpected_crash.explanation": "ilo li ken ala pana e lipu ni. ni li ken tan pakala mi tan pakala pi ilo sina.",
"errors.unexpected_crash.report_issue": "o toki e pakala tawa lawa", "errors.unexpected_crash.report_issue": "o toki e pakala tawa lawa",
"explore.search_results": "ijo pi alasa ni", "explore.search_results": "ijo pi alasa ni",
"explore.suggested_follows": "jan", "explore.suggested_follows": "jan",
"explore.title": "o alasa", "explore.title": "o alasa",
"explore.trending_links": "sin", "explore.trending_links": "sin",
"explore.trending_statuses": "toki", "explore.trending_statuses": "toki",
"filter_modal.added.settings_link": "lipu lawa",
"filter_modal.select_filter.expired": "tenpo pini", "filter_modal.select_filter.expired": "tenpo pini",
"filter_modal.select_filter.search": "o alasa anu pali", "filter_modal.select_filter.search": "o alasa anu pali",
"firehose.all": "ale", "firehose.all": "ale",
@ -187,6 +205,10 @@
"firehose.remote": "kulupu ante", "firehose.remote": "kulupu ante",
"follow_request.authorize": "o ken", "follow_request.authorize": "o ken",
"follow_request.reject": "o ala", "follow_request.reject": "o ala",
"follow_suggestions.hints.friends_of_friends": "jan kute sina li lukin mute e toki pi jan ni.",
"follow_suggestions.hints.most_followed": "jan mute lon ma {domain} li kute e jan ni.",
"follow_suggestions.hints.most_interactions": "tenpo poka la jan mute pi ma {domain} li lukin mute e toki pi jan ni.",
"follow_suggestions.hints.similar_to_recently_followed": "sina kute e jan lon tenpo poka la jan ni li sama ona.",
"follow_suggestions.view_all": "o lukin e ale", "follow_suggestions.view_all": "o lukin e ale",
"follow_suggestions.who_to_follow": "sina o kute e ni", "follow_suggestions.who_to_follow": "sina o kute e ni",
"footer.about": "sona", "footer.about": "sona",
@ -203,11 +225,14 @@
"hashtag.column_settings.tag_mode.any": "wan ni", "hashtag.column_settings.tag_mode.any": "wan ni",
"hashtag.column_settings.tag_mode.none": "ala ni", "hashtag.column_settings.tag_mode.none": "ala ni",
"home.pending_critical_update.link": "o lukin e ijo ilo sin", "home.pending_critical_update.link": "o lukin e ijo ilo sin",
"interaction_modal.login.action": "o lon tomo",
"interaction_modal.on_another_server": "lon ma ante", "interaction_modal.on_another_server": "lon ma ante",
"interaction_modal.on_this_server": "lon ma ni", "interaction_modal.on_this_server": "lon ma ni",
"interaction_modal.title.favourite": "o suli e toki {name}", "interaction_modal.title.favourite": "o suli e toki {name}",
"interaction_modal.title.follow": "o kute e {name}", "interaction_modal.title.follow": "o kute e {name}",
"interaction_modal.title.reblog": "o wawa e toki {name}", "interaction_modal.title.reblog": "o wawa e toki {name}",
"interaction_modal.title.reply": "o toki lon toki pi jan {name}",
"intervals.full.days": "{number, plural, other {suni #}}",
"keyboard_shortcuts.blocked": "o lukin e lipu sina pi jan weka", "keyboard_shortcuts.blocked": "o lukin e lipu sina pi jan weka",
"keyboard_shortcuts.boost": "o pana sin e toki", "keyboard_shortcuts.boost": "o pana sin e toki",
"keyboard_shortcuts.down": "o tawa anpa lon lipu", "keyboard_shortcuts.down": "o tawa anpa lon lipu",
@ -253,25 +278,42 @@
"navigation_bar.pins": "toki sewi", "navigation_bar.pins": "toki sewi",
"navigation_bar.preferences": "wile sina", "navigation_bar.preferences": "wile sina",
"navigation_bar.search": "o alasa", "navigation_bar.search": "o alasa",
"notification.admin.report": "jan {name} li toki e jan {target} tawa lawa",
"notification.admin.sign_up": "{name} li kama", "notification.admin.sign_up": "{name} li kama",
"notification.favourite": "{name} li suli e toki sina", "notification.favourite": "{name} li suli e toki sina",
"notification.follow": " {name} li kute e sina", "notification.follow": " {name} li kute e sina",
"notification.follow_request": "{name} li wile kute e sina", "notification.follow_request": "{name} li wile kute e sina",
"notification.mention": "jan {name} li toki e sina", "notification.mention": "jan {name} li toki e sina",
"notification.poll": "sina pana lon pana la pana ni li pini",
"notification.reblog": "{name} li wawa e toki sina", "notification.reblog": "{name} li wawa e toki sina",
"notification.status": "{name} li toki", "notification.status": "{name} li toki",
"notification.update": "{name} li ante e toki", "notification.update": "{name} li ante e toki",
"notifications.column_settings.follow": "jan kute sin", "notifications.column_settings.follow": "jan kute sin",
"notifications.column_settings.poll": "pana lon pana ni:",
"notifications.column_settings.reblog": "wawa:",
"notifications.column_settings.update": "ante toki:",
"notifications.filter.all": "ale", "notifications.filter.all": "ale",
"notifications.filter.polls": "pana lon pana ni",
"onboarding.compose.template": "toki a, #Mastodon o!", "onboarding.compose.template": "toki a, #Mastodon o!",
"onboarding.profile.display_name": "nimi tawa jan ante",
"onboarding.share.lead": "o toki lon nasin Masoton pi alasa sina tawa jan",
"onboarding.share.message": "ilo #Mastodon la mi jan {username} a! o kute e mi lon ni: {url}",
"onboarding.start.title": "sina o kama pona a!", "onboarding.start.title": "sina o kama pona a!",
"onboarding.tips.migration": "<strong>sina sona ala sona e ni?</strong> tenpo kama la sina pilin ike tawa ma {domain} la, sina ken tawa ma ante lon ilo Masoton. jan li kute e sina la jan ni li awen kute e sina. kin la sina ken lawa e ma pi sina taso a!",
"poll.total_people": "{count, plural, other {jan #}}", "poll.total_people": "{count, plural, other {jan #}}",
"poll.total_votes": "{count, plural, other {pana #}}",
"poll.vote": "o pana",
"poll.voted": "sina pana e ni",
"poll.votes": "{votes, plural, other {pana #}}",
"privacy.direct.long": "jan ale lon toki",
"privacy.public.short": "tawa ale", "privacy.public.short": "tawa ale",
"relative_time.full.just_now": "tenpo ni", "relative_time.full.just_now": "tenpo ni",
"relative_time.just_now": "tenpo ni", "relative_time.just_now": "tenpo ni",
"relative_time.today": "tenpo suno ni", "relative_time.today": "tenpo suno ni",
"report.block": "o weka e jan", "report.block": "o weka e jan",
"report.block_explanation": "sina kama lukin ala e toki ona. ona li kama ala ken lukin e toki sina li kama ala ken kute e sina. ona li ken sona e kama ni.", "report.block_explanation": "sina kama lukin ala e toki ona. ona li kama ala ken lukin e toki sina li kama ala ken kute e sina. ona li ken sona e kama ni.",
"report.categories.other": "ante",
"report.categories.spam": "ike tan toki mute",
"report.category.title": "ike seme li lon {type} ni", "report.category.title": "ike seme li lon {type} ni",
"report.category.title_account": "lipu", "report.category.title_account": "lipu",
"report.category.title_status": "toki", "report.category.title_status": "toki",

View file

@ -6,7 +6,7 @@
"about.domain_blocks.preamble": "Mastodon 基本上允許您瀏覽聯邦宇宙中任何伺服器的內容並與使用者互動。以下是在本伺服器上設定的例外。", "about.domain_blocks.preamble": "Mastodon 基本上允許您瀏覽聯邦宇宙中任何伺服器的內容並與使用者互動。以下是在本伺服器上設定的例外。",
"about.domain_blocks.silenced.explanation": "一般來說您不會看到來自這個伺服器的個人檔案和內容,除非您明確搜尋或主動跟隨對方。", "about.domain_blocks.silenced.explanation": "一般來說您不會看到來自這個伺服器的個人檔案和內容,除非您明確搜尋或主動跟隨對方。",
"about.domain_blocks.silenced.title": "已受限", "about.domain_blocks.silenced.title": "已受限",
"about.domain_blocks.suspended.explanation": "來自此伺服器的資料都不會被處理、儲存或交換,也無法與此伺服器上的使用者互動或交流。", "about.domain_blocks.suspended.explanation": "來自此伺服器的資料都不會被處理、儲存或交換,也無法和此伺服器上的使用者互動與交流。",
"about.domain_blocks.suspended.title": "已停權", "about.domain_blocks.suspended.title": "已停權",
"about.not_available": "無法於本伺服器上使用此資訊。", "about.not_available": "無法於本伺服器上使用此資訊。",
"about.powered_by": "由 {mastodon} 提供的去中心化社群媒體", "about.powered_by": "由 {mastodon} 提供的去中心化社群媒體",
@ -212,7 +212,7 @@
"emoji_button.custom": "自訂", "emoji_button.custom": "自訂",
"emoji_button.flags": "旗幟", "emoji_button.flags": "旗幟",
"emoji_button.food": "食物 & 飲料", "emoji_button.food": "食物 & 飲料",
"emoji_button.label": "插入表情符號", "emoji_button.label": "插入 emoji 表情符號",
"emoji_button.nature": "自然", "emoji_button.nature": "自然",
"emoji_button.not_found": "啊就沒這表情符號吼!! (╯°□°)╯︵ ┻━┻", "emoji_button.not_found": "啊就沒這表情符號吼!! (╯°□°)╯︵ ┻━┻",
"emoji_button.objects": "物件", "emoji_button.objects": "物件",
@ -227,7 +227,7 @@
"empty_column.account_timeline": "這裡還沒有嘟文!", "empty_column.account_timeline": "這裡還沒有嘟文!",
"empty_column.account_unavailable": "無法取得個人檔案", "empty_column.account_unavailable": "無法取得個人檔案",
"empty_column.blocks": "您還沒有封鎖任何使用者。", "empty_column.blocks": "您還沒有封鎖任何使用者。",
"empty_column.bookmarked_statuses": "您還沒有建立任何書籤。當您建立書籤時,它將於此顯示。", "empty_column.bookmarked_statuses": "您還沒有新增任何書籤。當您新增書籤時,它將於此顯示。",
"empty_column.community": "本站時間軸是空的。快公開嘟些文搶頭香啊!", "empty_column.community": "本站時間軸是空的。快公開嘟些文搶頭香啊!",
"empty_column.direct": "您還沒有收到任何私訊。當您私訊別人或收到私訊時,它將於此顯示。", "empty_column.direct": "您還沒有收到任何私訊。當您私訊別人或收到私訊時,它將於此顯示。",
"empty_column.domain_blocks": "尚未封鎖任何網域。", "empty_column.domain_blocks": "尚未封鎖任何網域。",
@ -239,7 +239,7 @@
"empty_column.hashtag": "這個主題標籤下什麼也沒有。", "empty_column.hashtag": "這個主題標籤下什麼也沒有。",
"empty_column.home": "您的首頁時間軸是空的!跟隨更多人來將它填滿吧!", "empty_column.home": "您的首頁時間軸是空的!跟隨更多人來將它填滿吧!",
"empty_column.list": "這份列表下什麼也沒有。當此列表的成員嘟出新的嘟文時,它們將顯示於此。", "empty_column.list": "這份列表下什麼也沒有。當此列表的成員嘟出新的嘟文時,它們將顯示於此。",
"empty_column.lists": "您還沒有建立任何列表。當您建立列表時,它將於此顯示。", "empty_column.lists": "您還沒有新增任何列表。當您新增列表時,它將於此顯示。",
"empty_column.mutes": "您尚未靜音任何使用者。", "empty_column.mutes": "您尚未靜音任何使用者。",
"empty_column.notifications": "您還沒有收到任何通知,當您與別人開始互動時,它將於此顯示。", "empty_column.notifications": "您還沒有收到任何通知,當您與別人開始互動時,它將於此顯示。",
"empty_column.public": "這裡什麼都沒有!嘗試寫些公開的嘟文,或者跟隨其他伺服器的使用者後,就會有嘟文出現了", "empty_column.public": "這裡什麼都沒有!嘗試寫些公開的嘟文,或者跟隨其他伺服器的使用者後,就會有嘟文出現了",
@ -322,10 +322,10 @@
"home.pending_critical_update.link": "檢視更新內容", "home.pending_critical_update.link": "檢視更新內容",
"home.pending_critical_update.title": "有可取得的重要安全性更新!", "home.pending_critical_update.title": "有可取得的重要安全性更新!",
"home.show_announcements": "顯示公告", "home.show_announcements": "顯示公告",
"interaction_modal.description.favourite": "在 Mastodon 上有個帳號的話,您可以將此嘟文加入最愛以讓作者知道您欣賞它且將它儲存下來。", "interaction_modal.description.favourite": "若於 Mastodon 上有個帳號,您可以將此嘟文加入最愛使作者知道您欣賞它且將它儲存下來。",
"interaction_modal.description.follow": "在 Mastodon 上有個帳號的話,您可以跟隨 {name} 以於首頁時間軸接收他們的嘟文。", "interaction_modal.description.follow": "若於 Mastodon 上有個帳號,您可以跟隨 {name} 以於首頁時間軸接收他們的嘟文。",
"interaction_modal.description.reblog": "在 Mastodon 上有個帳號的話,您可以轉嘟此嘟文以分享給您的跟隨者們。", "interaction_modal.description.reblog": "若於 Mastodon 上有個帳號,您可以轉嘟此嘟文以分享給您的跟隨者們。",
"interaction_modal.description.reply": "在 Mastodon 上有個帳號的話,您可以回覆此嘟文。", "interaction_modal.description.reply": "若於 Mastodon 上有個帳號,您可以回覆此嘟文。",
"interaction_modal.login.action": "返回首頁", "interaction_modal.login.action": "返回首頁",
"interaction_modal.login.prompt": "您帳號所屬伺服器之網域例如mastodon.social", "interaction_modal.login.prompt": "您帳號所屬伺服器之網域例如mastodon.social",
"interaction_modal.no_account_yet": "還沒有 Mastodon 帳號嗎?", "interaction_modal.no_account_yet": "還沒有 Mastodon 帳號嗎?",
@ -347,7 +347,7 @@
"keyboard_shortcuts.compose": "將游標移至文字撰寫區塊", "keyboard_shortcuts.compose": "將游標移至文字撰寫區塊",
"keyboard_shortcuts.description": "說明", "keyboard_shortcuts.description": "說明",
"keyboard_shortcuts.direct": "開啟私訊對話欄", "keyboard_shortcuts.direct": "開啟私訊對話欄",
"keyboard_shortcuts.down": "下移動", "keyboard_shortcuts.down": "下移動",
"keyboard_shortcuts.enter": "檢視嘟文", "keyboard_shortcuts.enter": "檢視嘟文",
"keyboard_shortcuts.favourite": "加到最愛", "keyboard_shortcuts.favourite": "加到最愛",
"keyboard_shortcuts.favourites": "開啟最愛列表", "keyboard_shortcuts.favourites": "開啟最愛列表",
@ -373,7 +373,7 @@
"keyboard_shortcuts.toggle_sensitivity": "顯示或隱藏媒體", "keyboard_shortcuts.toggle_sensitivity": "顯示或隱藏媒體",
"keyboard_shortcuts.toot": "發個新嘟文", "keyboard_shortcuts.toot": "發個新嘟文",
"keyboard_shortcuts.unfocus": "跳離文字撰寫區塊或搜尋框", "keyboard_shortcuts.unfocus": "跳離文字撰寫區塊或搜尋框",
"keyboard_shortcuts.up": "上移動", "keyboard_shortcuts.up": "上移動",
"lightbox.close": "關閉", "lightbox.close": "關閉",
"lightbox.compress": "折疊圖片檢視框", "lightbox.compress": "折疊圖片檢視框",
"lightbox.expand": "展開圖片檢視框", "lightbox.expand": "展開圖片檢視框",
@ -483,7 +483,7 @@
"onboarding.actions.go_to_home": "前往您的首頁時間軸", "onboarding.actions.go_to_home": "前往您的首頁時間軸",
"onboarding.compose.template": "哈囉 #Mastodon", "onboarding.compose.template": "哈囉 #Mastodon",
"onboarding.follows.empty": "很遺憾,目前未能顯示任何結果。您可以嘗試使用搜尋、瀏覽探索頁面以找尋人們跟隨、或稍候再試。", "onboarding.follows.empty": "很遺憾,目前未能顯示任何結果。您可以嘗試使用搜尋、瀏覽探索頁面以找尋人們跟隨、或稍候再試。",
"onboarding.follows.lead": "您的首頁時間軸是 Mastodon 的核心體驗。若您跟隨更多人的話,它將會變得更活躍有趣。這些個人檔案也許是個好起點,您可以隨時取消跟隨他們!", "onboarding.follows.lead": "您的首頁時間軸是 Mastodon 的核心體驗。若您跟隨更多人,它將會變得更活躍有趣。這些個人檔案也許是個好起點,您可以隨時取消跟隨他們!",
"onboarding.follows.title": "客製化您的首頁時間軸", "onboarding.follows.title": "客製化您的首頁時間軸",
"onboarding.profile.discoverable": "使我的個人檔案可以被找到", "onboarding.profile.discoverable": "使我的個人檔案可以被找到",
"onboarding.profile.discoverable_hint": "當您於 Mastodon 上選擇加入可發現性時,您的嘟文可能會出現於搜尋結果與趨勢中。您的個人檔案可能會被推薦給與您志趣相投的人。", "onboarding.profile.discoverable_hint": "當您於 Mastodon 上選擇加入可發現性時,您的嘟文可能會出現於搜尋結果與趨勢中。您的個人檔案可能會被推薦給與您志趣相投的人。",
@ -505,7 +505,7 @@
"onboarding.start.title": "噹噹!完成啦!", "onboarding.start.title": "噹噹!完成啦!",
"onboarding.steps.follow_people.body": "Mastodon 的趣味就是跟隨些有趣的人們!", "onboarding.steps.follow_people.body": "Mastodon 的趣味就是跟隨些有趣的人們!",
"onboarding.steps.follow_people.title": "客製化您的首頁時間軸", "onboarding.steps.follow_people.title": "客製化您的首頁時間軸",
"onboarding.steps.publish_status.body": "向新世界打聲招呼吧。", "onboarding.steps.publish_status.body": "透過文字、照片、影片或投票 {emoji} 向新世界打聲招呼吧。",
"onboarding.steps.publish_status.title": "撰寫您第一則嘟文", "onboarding.steps.publish_status.title": "撰寫您第一則嘟文",
"onboarding.steps.setup_profile.body": "若您完整填寫個人檔案,其他人比較願意與您互動。", "onboarding.steps.setup_profile.body": "若您完整填寫個人檔案,其他人比較願意與您互動。",
"onboarding.steps.setup_profile.title": "客製化您的個人檔案", "onboarding.steps.setup_profile.title": "客製化您的個人檔案",
@ -526,7 +526,7 @@
"poll.vote": "投票", "poll.vote": "投票",
"poll.voted": "您已對此問題投票", "poll.voted": "您已對此問題投票",
"poll.votes": "{votes, plural, one {# 張票} other {# 張票}}", "poll.votes": "{votes, plural, one {# 張票} other {# 張票}}",
"poll_button.add_poll": "建立投票", "poll_button.add_poll": "新增投票",
"poll_button.remove_poll": "移除投票", "poll_button.remove_poll": "移除投票",
"privacy.change": "調整嘟文隱私狀態", "privacy.change": "調整嘟文隱私狀態",
"privacy.direct.long": "此嘟文提及之所有人", "privacy.direct.long": "此嘟文提及之所有人",
@ -716,7 +716,7 @@
"units.short.million": "{count}M", "units.short.million": "{count}M",
"units.short.thousand": "{count}K", "units.short.thousand": "{count}K",
"upload_area.title": "拖放來上傳", "upload_area.title": "拖放來上傳",
"upload_button.label": "上傳圖片、影片、或者音檔案", "upload_button.label": "上傳圖片、影片、或者音檔案",
"upload_error.limit": "已達到檔案上傳限制。", "upload_error.limit": "已達到檔案上傳限制。",
"upload_error.poll": "不允許於投票時上傳檔案。", "upload_error.poll": "不允許於投票時上傳檔案。",
"upload_form.audio_description": "為聽障人士增加文字說明", "upload_form.audio_description": "為聽障人士增加文字說明",

View file

@ -280,12 +280,12 @@ const updateSuggestionTags = (state, token) => {
}); });
}; };
const updatePoll = (state, index, value) => state.updateIn(['poll', 'options'], options => { const updatePoll = (state, index, value, maxOptions) => state.updateIn(['poll', 'options'], options => {
const tmp = options.set(index, value).filterNot(x => x.trim().length === 0); const tmp = options.set(index, value).filterNot(x => x.trim().length === 0);
if (tmp.size === 0) { if (tmp.size === 0) {
return tmp.push('').push(''); return tmp.push('').push('');
} else if (tmp.size < 4) { } else if (tmp.size < maxOptions) {
return tmp.push(''); return tmp.push('');
} }
@ -529,7 +529,7 @@ export default function compose(state = initialState, action) {
case COMPOSE_POLL_REMOVE: case COMPOSE_POLL_REMOVE:
return state.set('poll', null); return state.set('poll', null);
case COMPOSE_POLL_OPTION_CHANGE: case COMPOSE_POLL_OPTION_CHANGE:
return updatePoll(state, action.index, action.title); return updatePoll(state, action.index, action.title, action.maxOptions);
case COMPOSE_POLL_SETTINGS_CHANGE: case COMPOSE_POLL_SETTINGS_CHANGE:
return state.update('poll', poll => poll.set('expires_in', action.expiresIn).set('multiple', action.isMultiple)); return state.update('poll', poll => poll.set('expires_in', action.expiresIn).set('multiple', action.isMultiple));
case COMPOSE_LANGUAGE_CHANGE: case COMPOSE_LANGUAGE_CHANGE:

View file

@ -27,6 +27,8 @@ import media_attachments from './media_attachments';
import meta from './meta'; import meta from './meta';
import { modalReducer } from './modal'; import { modalReducer } from './modal';
import mutes from './mutes'; import mutes from './mutes';
import { notificationPolicyReducer } from './notification_policy';
import { notificationRequestsReducer } from './notification_requests';
import notifications from './notifications'; import notifications from './notifications';
import picture_in_picture from './picture_in_picture'; import picture_in_picture from './picture_in_picture';
import polls from './polls'; import polls from './polls';
@ -84,6 +86,8 @@ const reducers = {
history, history,
tags, tags,
followed_tags, followed_tags,
notificationPolicy: notificationPolicyReducer,
notificationRequests: notificationRequestsReducer,
}; };
// We want the root state to be an ImmutableRecord, which is an object with a defined list of keys, // We want the root state to be an ImmutableRecord, which is an object with a defined list of keys,

View file

@ -0,0 +1,12 @@
import { fromJS } from 'immutable';
import { NOTIFICATION_POLICY_FETCH_SUCCESS } from 'mastodon/actions/notifications';
export const notificationPolicyReducer = (state = null, action) => {
switch(action.type) {
case NOTIFICATION_POLICY_FETCH_SUCCESS:
return fromJS(action.policy);
default:
return state;
}
};

View file

@ -0,0 +1,96 @@
import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';
import {
NOTIFICATION_REQUESTS_EXPAND_REQUEST,
NOTIFICATION_REQUESTS_EXPAND_SUCCESS,
NOTIFICATION_REQUESTS_EXPAND_FAIL,
NOTIFICATION_REQUESTS_FETCH_REQUEST,
NOTIFICATION_REQUESTS_FETCH_SUCCESS,
NOTIFICATION_REQUESTS_FETCH_FAIL,
NOTIFICATION_REQUEST_FETCH_REQUEST,
NOTIFICATION_REQUEST_FETCH_SUCCESS,
NOTIFICATION_REQUEST_FETCH_FAIL,
NOTIFICATION_REQUEST_ACCEPT_REQUEST,
NOTIFICATION_REQUEST_DISMISS_REQUEST,
NOTIFICATIONS_FOR_REQUEST_FETCH_REQUEST,
NOTIFICATIONS_FOR_REQUEST_FETCH_SUCCESS,
NOTIFICATIONS_FOR_REQUEST_FETCH_FAIL,
NOTIFICATIONS_FOR_REQUEST_EXPAND_REQUEST,
NOTIFICATIONS_FOR_REQUEST_EXPAND_SUCCESS,
NOTIFICATIONS_FOR_REQUEST_EXPAND_FAIL,
} from 'mastodon/actions/notifications';
import { notificationToMap } from './notifications';
const initialState = ImmutableMap({
items: ImmutableList(),
isLoading: false,
next: null,
current: ImmutableMap({
isLoading: false,
item: null,
removed: false,
notifications: ImmutableMap({
items: ImmutableList(),
isLoading: false,
next: null,
}),
}),
});
const normalizeRequest = request => fromJS({
...request,
account: request.account.id,
});
const removeRequest = (state, id) => {
if (state.getIn(['current', 'item', 'id']) === id) {
state = state.setIn(['current', 'removed'], true);
}
return state.update('items', list => list.filterNot(item => item.get('id') === id));
};
export const notificationRequestsReducer = (state = initialState, action) => {
switch(action.type) {
case NOTIFICATION_REQUESTS_FETCH_SUCCESS:
return state.withMutations(map => {
map.update('items', list => ImmutableList(action.requests.map(normalizeRequest)).concat(list));
map.set('isLoading', false);
map.update('next', next => next ?? action.next);
});
case NOTIFICATION_REQUESTS_EXPAND_SUCCESS:
return state.withMutations(map => {
map.update('items', list => list.concat(ImmutableList(action.requests.map(normalizeRequest))));
map.set('isLoading', false);
map.set('next', action.next);
});
case NOTIFICATION_REQUESTS_EXPAND_REQUEST:
case NOTIFICATION_REQUESTS_FETCH_REQUEST:
return state.set('isLoading', true);
case NOTIFICATION_REQUESTS_EXPAND_FAIL:
case NOTIFICATION_REQUESTS_FETCH_FAIL:
return state.set('isLoading', false);
case NOTIFICATION_REQUEST_ACCEPT_REQUEST:
case NOTIFICATION_REQUEST_DISMISS_REQUEST:
return removeRequest(state, action.id);
case NOTIFICATION_REQUEST_FETCH_REQUEST:
return state.set('current', initialState.get('current').set('isLoading', true));
case NOTIFICATION_REQUEST_FETCH_SUCCESS:
return state.update('current', map => map.set('isLoading', false).set('item', normalizeRequest(action.request)));
case NOTIFICATION_REQUEST_FETCH_FAIL:
return state.update('current', map => map.set('isLoading', false));
case NOTIFICATIONS_FOR_REQUEST_FETCH_REQUEST:
case NOTIFICATIONS_FOR_REQUEST_EXPAND_REQUEST:
return state.setIn(['current', 'notifications', 'isLoading'], true);
case NOTIFICATIONS_FOR_REQUEST_FETCH_SUCCESS:
return state.updateIn(['current', 'notifications'], map => map.set('isLoading', false).update('items', list => ImmutableList(action.notifications.map(notificationToMap)).concat(list)).update('next', next => next ?? action.next));
case NOTIFICATIONS_FOR_REQUEST_EXPAND_SUCCESS:
return state.updateIn(['current', 'notifications'], map => map.set('isLoading', false).update('items', list => list.concat(ImmutableList(action.notifications.map(notificationToMap)))).set('next', action.next));
case NOTIFICATIONS_FOR_REQUEST_FETCH_FAIL:
case NOTIFICATIONS_FOR_REQUEST_EXPAND_FAIL:
return state.setIn(['current', 'notifications', 'isLoading'], false);
default:
return state;
}
};

View file

@ -48,7 +48,7 @@ const initialState = ImmutableMap({
browserPermission: 'default', browserPermission: 'default',
}); });
const notificationToMap = notification => ImmutableMap({ export const notificationToMap = notification => ImmutableMap({
id: notification.id, id: notification.id,
type: notification.type, type: notification.type,
account: notification.account.id, account: notification.account.id,

View file

@ -69,3 +69,11 @@ export function pluralReady(
export function roundTo10(num: number): number { export function roundTo10(num: number): number {
return Math.round(num * 0.1) / 0.1; return Math.round(num * 0.1) / 0.1;
} }
export function toCappedNumber(num: string): string {
if (parseInt(num) > 99) {
return '99+';
} else {
return num;
}
}

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="m480-240 160-160-56-56-64 64v-168h-80v168l-64-64-56 56 160 160ZM200-120q-33 0-56.5-23.5T120-200v-499q0-14 4.5-27t13.5-24l50-61q11-14 27.5-21.5T250-840h460q18 0 34.5 7.5T772-811l50 61q9 11 13.5 24t4.5 27v499q0 33-23.5 56.5T760-120H200Zm16-600h528l-34-40H250l-34 40Z"/></svg>

After

Width:  |  Height:  |  Size: 370 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="m480-240 160-160-56-56-64 64v-168h-80v168l-64-64-56 56 160 160ZM200-640v440h560v-440H200Zm0 520q-33 0-56.5-23.5T120-200v-499q0-14 4.5-27t13.5-24l50-61q11-14 27.5-21.5T250-840h460q18 0 34.5 7.5T772-811l50 61q9 11 13.5 24t4.5 27v499q0 33-23.5 56.5T760-120H200Zm16-600h528l-34-40H250l-34 40Zm264 300Z"/></svg>

After

Width:  |  Height:  |  Size: 403 B

View file

@ -53,4 +53,10 @@ $fluid-breakpoint: $maximum-width + 20px;
border-bottom: 0; border-bottom: 0;
} }
} }
&__hint {
font-size: 14px;
font-weight: 400;
color: $darker-text-color;
}
} }

View file

@ -3289,12 +3289,13 @@ $ui-header-height: 55px;
border: 0; border: 0;
border-bottom: 1px solid lighten($ui-base-color, 8%); border-bottom: 1px solid lighten($ui-base-color, 8%);
text-align: unset; text-align: unset;
padding: 15px; padding: 13px;
margin: 0; margin: 0;
z-index: 3; z-index: 3;
outline: 0; outline: 0;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 5px;
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
@ -3304,6 +3305,7 @@ $ui-header-height: 55px;
.column-header__back-button { .column-header__back-button {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 5px;
background: $ui-base-color; background: $ui-base-color;
border: 0; border: 0;
font-family: inherit; font-family: inherit;
@ -3311,23 +3313,19 @@ $ui-header-height: 55px;
cursor: pointer; cursor: pointer;
white-space: nowrap; white-space: nowrap;
font-size: 16px; font-size: 16px;
padding: 0 5px 0 0; padding: 13px;
z-index: 3; z-index: 3;
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
} }
&:last-child { &.compact {
padding: 0 15px 0 0; padding-inline-end: 5px;
flex: 0 0 auto;
} }
} }
.column-back-button__icon {
display: inline-block;
margin-inline-end: 5px;
}
.react-toggle { .react-toggle {
display: inline-block; display: inline-block;
position: relative; position: relative;
@ -4013,7 +4011,7 @@ a.status-card {
z-index: 2; z-index: 2;
outline: 0; outline: 0;
& > button { &__title {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 5px; gap: 5px;
@ -4035,8 +4033,18 @@ a.status-card {
} }
} }
& > .column-header__back-button { .column-header__back-button + &__title {
padding-inline-start: 0;
}
.column-header__back-button {
flex: 1;
color: $highlight-text-color; color: $highlight-text-color;
&.compact {
flex: 0 0 auto;
color: $primary-text-color;
}
} }
&.active { &.active {
@ -4050,6 +4058,18 @@ a.status-card {
&:active { &:active {
outline: 0; outline: 0;
} }
&__advanced-buttons {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px;
padding-top: 0;
&:first-child {
padding-top: 16px;
}
}
} }
.column-header__buttons { .column-header__buttons {
@ -4136,7 +4156,6 @@ a.status-card {
.column-header__collapsible-inner { .column-header__collapsible-inner {
background: $ui-base-color; background: $ui-base-color;
padding: 15px;
} }
.column-header__setting-btn { .column-header__setting-btn {
@ -4158,20 +4177,8 @@ a.status-card {
} }
.column-header__setting-arrows { .column-header__setting-arrows {
float: right; display: flex;
align-items: center;
.column-header__setting-btn {
padding: 5px;
&:first-child {
padding-inline-end: 7px;
}
&:last-child {
padding-inline-start: 7px;
margin-inline-start: 5px;
}
}
} }
.text-btn { .text-btn {
@ -4408,24 +4415,56 @@ a.status-card {
text-align: center; text-align: center;
} }
.column-settings__outer { .column-settings {
background: lighten($ui-base-color, 8%); display: flex;
padding: 15px; flex-direction: column;
}
.column-settings__section { &__section {
color: $darker-text-color; // FIXME: Legacy
cursor: default; color: $darker-text-color;
display: block; cursor: default;
font-weight: 500; display: block;
margin-bottom: 10px; font-weight: 500;
} }
.column-settings__row--with-margin { .column-header__links {
margin-bottom: 15px; margin: 0;
}
section {
padding: 16px;
border-bottom: 1px solid lighten($ui-base-color, 8%);
&:last-child {
border-bottom: 0;
}
}
h3 {
font-size: 16px;
line-height: 24px;
letter-spacing: 0.5px;
font-weight: 500;
color: $primary-text-color;
margin-bottom: 16px;
}
&__row {
display: flex;
flex-direction: column;
gap: 12px;
}
.app-form__toggle {
&__toggle > div {
border: 0;
}
}
} }
.column-settings__hashtags { .column-settings__hashtags {
margin-top: 15px;
.column-settings__row { .column-settings__row {
margin-bottom: 15px; margin-bottom: 15px;
} }
@ -4549,16 +4588,13 @@ a.status-card {
} }
.setting-toggle { .setting-toggle {
display: block; display: flex;
line-height: 24px; align-items: center;
gap: 8px;
} }
.setting-toggle__label { .setting-toggle__label {
color: $darker-text-color; color: $darker-text-color;
display: inline-block;
margin-bottom: 14px;
margin-inline-start: 8px;
vertical-align: middle;
} }
.limited-account-hint { .limited-account-hint {
@ -6949,29 +6985,33 @@ a.status-card {
background: $ui-base-color; background: $ui-base-color;
&__column { &__column {
padding: 10px 15px; display: flex;
padding-bottom: 0; flex-direction: column;
gap: 15px;
padding: 15px;
} }
.radio-button { .radio-button {
display: block; display: flex;
} }
} }
.column-settings__row .radio-button { .column-settings__row .radio-button {
display: block; display: flex;
} }
.radio-button { .radio-button {
font-size: 14px; font-size: 14px;
position: relative; position: relative;
display: inline-block; display: inline-flex;
padding: 6px 0; align-items: center;
line-height: 18px; line-height: 18px;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
cursor: pointer; cursor: pointer;
gap: 10px;
color: $secondary-text-color;
input[type='radio'], input[type='radio'],
input[type='checkbox'] { input[type='checkbox'] {
@ -6979,21 +7019,29 @@ a.status-card {
} }
&__input { &__input {
display: inline-block; display: block;
position: relative; position: relative;
border: 1px solid $ui-primary-color; border: 2px solid $secondary-text-color;
box-sizing: border-box; box-sizing: border-box;
width: 18px; width: 18px;
height: 18px; height: 18px;
flex: 0 0 auto; flex: 0 0 auto;
margin-inline-end: 10px;
top: -1px;
border-radius: 50%; border-radius: 50%;
vertical-align: middle;
&.checked { &.checked {
border-color: lighten($ui-highlight-color, 4%); border-color: $secondary-text-color;
background: lighten($ui-highlight-color, 4%);
&::before {
position: absolute;
left: 2px;
top: 2px;
content: '';
display: block;
border-radius: 50%;
width: 10px;
height: 10px;
background: $secondary-text-color;
}
} }
} }
} }
@ -7455,10 +7503,7 @@ noscript {
.button { .button {
flex-shrink: 1; flex-shrink: 1;
white-space: nowrap; white-space: nowrap;
min-width: 80px;
@media screen and (max-width: $no-gap-breakpoint) {
min-width: 0;
}
} }
.icon-button { .icon-button {
@ -9591,3 +9636,110 @@ noscript {
} }
} }
} }
.filtered-notifications-banner {
display: flex;
align-items: center;
background: $ui-base-color;
border-bottom: 1px solid lighten($ui-base-color, 8%);
padding: 15px;
gap: 15px;
color: $darker-text-color;
text-decoration: none;
&:hover,
&:active,
&:focus {
color: $secondary-text-color;
.filtered-notifications-banner__badge {
background: $secondary-text-color;
}
}
.icon {
width: 24px;
height: 24px;
}
&__text {
flex: 1 1 auto;
font-style: 14px;
line-height: 20px;
strong {
font-size: 16px;
line-height: 24px;
display: block;
}
}
&__badge {
background: $darker-text-color;
color: $ui-base-color;
border-radius: 100px;
padding: 2px 8px;
font-weight: 500;
font-size: 11px;
line-height: 16px;
}
}
.notification-request {
display: flex;
align-items: center;
gap: 16px;
padding: 15px;
border-bottom: 1px solid lighten($ui-base-color, 8%);
&__link {
display: flex;
align-items: center;
gap: 12px;
flex: 1 1 auto;
text-decoration: none;
color: inherit;
overflow: hidden;
.account__avatar {
flex-shrink: 0;
}
}
&__name {
flex: 1 1 auto;
color: $darker-text-color;
font-style: 14px;
line-height: 20px;
overflow: hidden;
text-overflow: ellipsis;
&__display-name {
display: flex;
align-items: center;
gap: 6px;
font-size: 16px;
letter-spacing: 0.5px;
line-height: 24px;
color: $secondary-text-color;
}
.filtered-notifications-banner__badge {
background-color: $highlight-text-color;
border-radius: 4px;
padding: 1px 6px;
}
}
&__actions {
display: flex;
align-items: center;
gap: 8px;
.icon-button {
border-radius: 4px;
border: 1px solid lighten($ui-base-color, 8%);
padding: 5px;
}
}
}

View file

@ -1313,6 +1313,12 @@ code {
font-weight: 600; font-weight: 600;
} }
.hint {
display: block;
font-size: 14px;
color: $darker-text-color;
}
.recommended { .recommended {
position: absolute; position: absolute;
margin: 0 4px; margin: 0 4px;

View file

@ -2,15 +2,15 @@
class Admin::Metrics::Dimension class Admin::Metrics::Dimension
DIMENSIONS = { DIMENSIONS = {
languages: Admin::Metrics::Dimension::LanguagesDimension, languages: LanguagesDimension,
sources: Admin::Metrics::Dimension::SourcesDimension, sources: SourcesDimension,
servers: Admin::Metrics::Dimension::ServersDimension, servers: ServersDimension,
space_usage: Admin::Metrics::Dimension::SpaceUsageDimension, space_usage: SpaceUsageDimension,
software_versions: Admin::Metrics::Dimension::SoftwareVersionsDimension, software_versions: SoftwareVersionsDimension,
tag_servers: Admin::Metrics::Dimension::TagServersDimension, tag_servers: TagServersDimension,
tag_languages: Admin::Metrics::Dimension::TagLanguagesDimension, tag_languages: TagLanguagesDimension,
instance_accounts: Admin::Metrics::Dimension::InstanceAccountsDimension, instance_accounts: InstanceAccountsDimension,
instance_languages: Admin::Metrics::Dimension::InstanceLanguagesDimension, instance_languages: InstanceLanguagesDimension,
}.freeze }.freeze
def self.retrieve(dimension_keys, start_at, end_at, limit, params) def self.retrieve(dimension_keys, start_at, end_at, limit, params)

View file

@ -2,20 +2,20 @@
class Admin::Metrics::Measure class Admin::Metrics::Measure
MEASURES = { MEASURES = {
active_users: Admin::Metrics::Measure::ActiveUsersMeasure, active_users: ActiveUsersMeasure,
new_users: Admin::Metrics::Measure::NewUsersMeasure, new_users: NewUsersMeasure,
interactions: Admin::Metrics::Measure::InteractionsMeasure, interactions: InteractionsMeasure,
opened_reports: Admin::Metrics::Measure::OpenedReportsMeasure, opened_reports: OpenedReportsMeasure,
resolved_reports: Admin::Metrics::Measure::ResolvedReportsMeasure, resolved_reports: ResolvedReportsMeasure,
tag_accounts: Admin::Metrics::Measure::TagAccountsMeasure, tag_accounts: TagAccountsMeasure,
tag_uses: Admin::Metrics::Measure::TagUsesMeasure, tag_uses: TagUsesMeasure,
tag_servers: Admin::Metrics::Measure::TagServersMeasure, tag_servers: TagServersMeasure,
instance_accounts: Admin::Metrics::Measure::InstanceAccountsMeasure, instance_accounts: InstanceAccountsMeasure,
instance_media_attachments: Admin::Metrics::Measure::InstanceMediaAttachmentsMeasure, instance_media_attachments: InstanceMediaAttachmentsMeasure,
instance_reports: Admin::Metrics::Measure::InstanceReportsMeasure, instance_reports: InstanceReportsMeasure,
instance_statuses: Admin::Metrics::Measure::InstanceStatusesMeasure, instance_statuses: InstanceStatusesMeasure,
instance_follows: Admin::Metrics::Measure::InstanceFollowsMeasure, instance_follows: InstanceFollowsMeasure,
instance_followers: Admin::Metrics::Measure::InstanceFollowersMeasure, instance_followers: InstanceFollowersMeasure,
}.freeze }.freeze
def self.retrieve(measure_keys, start_at, end_at, params) def self.retrieve(measure_keys, start_at, end_at, params)

View file

@ -15,10 +15,15 @@ module Account::Associations
has_many :favourites, inverse_of: :account, dependent: :destroy has_many :favourites, inverse_of: :account, dependent: :destroy
has_many :bookmarks, inverse_of: :account, dependent: :destroy has_many :bookmarks, inverse_of: :account, dependent: :destroy
has_many :mentions, inverse_of: :account, dependent: :destroy has_many :mentions, inverse_of: :account, dependent: :destroy
has_many :notifications, inverse_of: :account, dependent: :destroy
has_many :conversations, class_name: 'AccountConversation', dependent: :destroy, inverse_of: :account has_many :conversations, class_name: 'AccountConversation', dependent: :destroy, inverse_of: :account
has_many :scheduled_statuses, inverse_of: :account, dependent: :destroy has_many :scheduled_statuses, inverse_of: :account, dependent: :destroy
# Notifications
has_many :notifications, inverse_of: :account, dependent: :destroy
has_one :notification_policy, inverse_of: :account, dependent: :destroy
has_many :notification_permissions, inverse_of: :account, dependent: :destroy
has_many :notification_requests, inverse_of: :account, dependent: :destroy
# Pinned statuses # Pinned statuses
has_many :status_pins, inverse_of: :account, dependent: :destroy has_many :status_pins, inverse_of: :account, dependent: :destroy
has_many :pinned_statuses, -> { reorder('status_pins.created_at DESC') }, through: :status_pins, class_name: 'Status', source: :status has_many :pinned_statuses, -> { reorder('status_pins.created_at DESC') }, through: :status_pins, class_name: 'Status', source: :status

View file

@ -178,7 +178,7 @@ module Account::Interactions
end end
def unblock_domain!(other_domain) def unblock_domain!(other_domain)
block = domain_blocks.find_by(domain: other_domain) block = domain_blocks.find_by(domain: normalized_domain(other_domain))
block&.destroy block&.destroy
end end
@ -300,4 +300,8 @@ module Account::Interactions
domain_blocking_by_domain: Account.domain_blocking_map_by_domain(domains, id), domain_blocking_by_domain: Account.domain_blocking_map_by_domain(domains, id),
}) })
end end
def normalized_domain(domain)
TagManager.instance.normalize_domain(domain)
end
end end

View file

@ -12,6 +12,7 @@
# account_id :bigint(8) not null # account_id :bigint(8) not null
# from_account_id :bigint(8) not null # from_account_id :bigint(8) not null
# type :string # type :string
# filtered :boolean default(FALSE), not null
# #
class Notification < ApplicationRecord class Notification < ApplicationRecord
@ -89,7 +90,7 @@ class Notification < ApplicationRecord
end end
class << self class << self
def browserable(types: [], exclude_types: [], from_account_id: nil) def browserable(types: [], exclude_types: [], from_account_id: nil, include_filtered: false)
requested_types = if types.empty? requested_types = if types.empty?
TYPES TYPES
else else
@ -99,6 +100,7 @@ class Notification < ApplicationRecord
requested_types -= exclude_types.map(&:to_sym) requested_types -= exclude_types.map(&:to_sym)
all.tap do |scope| all.tap do |scope|
scope.merge!(where(filtered: false)) unless include_filtered || from_account_id.present?
scope.merge!(where(from_account_id: from_account_id)) if from_account_id.present? scope.merge!(where(from_account_id: from_account_id)) if from_account_id.present?
scope.merge!(where(type: requested_types)) unless requested_types.size == TYPES.size scope.merge!(where(type: requested_types)) unless requested_types.size == TYPES.size
end end
@ -144,6 +146,8 @@ class Notification < ApplicationRecord
after_initialize :set_from_account after_initialize :set_from_account
before_validation :set_from_account before_validation :set_from_account
after_destroy :remove_from_notification_request
private private
def set_from_account def set_from_account
@ -158,4 +162,9 @@ class Notification < ApplicationRecord
self.from_account_id = activity&.id self.from_account_id = activity&.id
end end
end end
def remove_from_notification_request
notification_request = NotificationRequest.find_by(account_id: account_id, from_account_id: from_account_id)
notification_request&.reconsider_existence!
end
end end

View file

@ -0,0 +1,16 @@
# frozen_string_literal: true
# == Schema Information
#
# Table name: notification_permissions
#
# id :bigint(8) not null, primary key
# account_id :bigint(8) not null
# from_account_id :bigint(8) not null
# created_at :datetime not null
# updated_at :datetime not null
#
class NotificationPermission < ApplicationRecord
belongs_to :account
belongs_to :from_account, class_name: 'Account'
end

View file

@ -0,0 +1,36 @@
# frozen_string_literal: true
# == Schema Information
#
# Table name: notification_policies
#
# id :bigint(8) not null, primary key
# account_id :bigint(8) not null
# filter_not_following :boolean default(FALSE), not null
# filter_not_followers :boolean default(FALSE), not null
# filter_new_accounts :boolean default(FALSE), not null
# filter_private_mentions :boolean default(TRUE), not null
# created_at :datetime not null
# updated_at :datetime not null
#
class NotificationPolicy < ApplicationRecord
belongs_to :account
has_many :notification_requests, primary_key: :account_id, foreign_key: :account_id, dependent: nil, inverse_of: false
attr_reader :pending_requests_count, :pending_notifications_count
MAX_MEANINGFUL_COUNT = 100
def summarize!
@pending_requests_count = pending_notification_requests.first
@pending_notifications_count = pending_notification_requests.last
end
private
def pending_notification_requests
@pending_notification_requests ||= notification_requests.where(dismissed: false).limit(MAX_MEANINGFUL_COUNT).pick(Arel.sql('count(*), coalesce(sum(notifications_count), 0)::bigint'))
end
end

View file

@ -0,0 +1,53 @@
# frozen_string_literal: true
# == Schema Information
#
# Table name: notification_requests
#
# id :bigint(8) not null, primary key
# account_id :bigint(8) not null
# from_account_id :bigint(8) not null
# last_status_id :bigint(8) not null
# notifications_count :bigint(8) default(0), not null
# dismissed :boolean default(FALSE), not null
# created_at :datetime not null
# updated_at :datetime not null
#
class NotificationRequest < ApplicationRecord
include Paginable
MAX_MEANINGFUL_COUNT = 100
belongs_to :account
belongs_to :from_account, class_name: 'Account'
belongs_to :last_status, class_name: 'Status'
before_save :prepare_notifications_count
def self.preload_cache_collection(requests)
cached_statuses_by_id = yield(requests.filter_map(&:last_status)).index_by(&:id) # Call cache_collection in block
requests.each do |request|
request.last_status = cached_statuses_by_id[request.last_status_id] unless request.last_status_id.nil?
end
end
def reconsider_existence!
return if dismissed?
prepare_notifications_count
if notifications_count.positive?
save
else
destroy
end
end
private
def prepare_notifications_count
self.notifications_count = Notification.where(account: account, from_account: from_account, filtered: true).limit(MAX_MEANINGFUL_COUNT).count
end
end

View file

@ -10,6 +10,7 @@
# text :text default(""), not null # text :text default(""), not null
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null
# hint :text default(""), not null
# #
class Rule < ApplicationRecord class Rule < ApplicationRecord
include Discard::Model include Discard::Model

View file

@ -0,0 +1,16 @@
# frozen_string_literal: true
class REST::NotificationPolicySerializer < ActiveModel::Serializer
attributes :filter_not_following,
:filter_not_followers,
:filter_new_accounts,
:filter_private_mentions,
:summary
def summary
{
pending_requests_count: object.pending_requests_count.to_s,
pending_notifications_count: object.pending_notifications_count.to_s,
}
end
end

View file

@ -0,0 +1,16 @@
# frozen_string_literal: true
class REST::NotificationRequestSerializer < ActiveModel::Serializer
attributes :id, :created_at, :updated_at, :notifications_count
belongs_to :from_account, key: :account, serializer: REST::AccountSerializer
belongs_to :last_status, serializer: REST::StatusSerializer
def id
object.id.to_s
end
def notifications_count
object.notifications_count.to_s
end
end

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
class REST::RuleSerializer < ActiveModel::Serializer class REST::RuleSerializer < ActiveModel::Serializer
attributes :id, :text attributes :id, :text, :hint
def id def id
object.id.to_s object.id.to_s

View file

@ -0,0 +1,8 @@
# frozen_string_literal: true
class AcceptNotificationRequestService < BaseService
def call(request)
NotificationPermission.create!(account: request.account, from_account: request.from_account)
UnfilterNotificationsWorker.perform_async(request.id)
end
end

View file

@ -11,126 +11,195 @@ class NotifyService < BaseService
status status
).freeze ).freeze
class DismissCondition
def initialize(notification)
@recipient = notification.account
@sender = notification.from_account
@notification = notification
end
def dismiss?
blocked = @recipient.unavailable?
blocked ||= from_self? && @notification.type != :poll
return blocked if message? && from_staff?
blocked ||= domain_blocking?
blocked ||= @recipient.blocking?(@sender)
blocked ||= @recipient.muting_notifications?(@sender)
blocked ||= conversation_muted?
blocked ||= blocked_mention? if message?
blocked
end
private
def blocked_mention?
FeedManager.instance.filter?(:mentions, @notification.target_status, @recipient)
end
def message?
@notification.type == :mention
end
def from_staff?
@sender.local? && @sender.user.present? && @sender.user_role&.overrides?(@recipient.user_role)
end
def from_self?
@recipient.id == @sender.id
end
def domain_blocking?
@recipient.domain_blocking?(@sender.domain) && !following_sender?
end
def conversation_muted?
@notification.target_status && @recipient.muting_conversation?(@notification.target_status.conversation)
end
def following_sender?
@recipient.following?(@sender)
end
end
class FilterCondition
NEW_ACCOUNT_THRESHOLD = 30.days.freeze
NEW_FOLLOWER_THRESHOLD = 3.days.freeze
def initialize(notification)
@notification = notification
@recipient = notification.account
@sender = notification.from_account
@policy = NotificationPolicy.find_or_initialize_by(account: @recipient)
end
def filter?
return false if override_for_sender?
from_limited? ||
filtered_by_not_following_policy? ||
filtered_by_not_followers_policy? ||
filtered_by_new_accounts_policy? ||
filtered_by_private_mentions_policy?
end
private
def filtered_by_not_following_policy?
@policy.filter_not_following? && not_following?
end
def filtered_by_not_followers_policy?
@policy.filter_not_followers? && not_follower?
end
def filtered_by_new_accounts_policy?
@policy.filter_new_accounts? && new_account?
end
def filtered_by_private_mentions_policy?
@policy.filter_private_mentions? && not_following? && private_mention_not_in_response?
end
def not_following?
!@recipient.following?(@sender)
end
def not_follower?
follow = Follow.find_by(account: @sender, target_account: @recipient)
follow.nil? || follow.created_at > NEW_FOLLOWER_THRESHOLD.ago
end
def new_account?
@sender.created_at > NEW_ACCOUNT_THRESHOLD.ago
end
def override_for_sender?
NotificationPermission.exists?(account: @recipient, from_account: @sender)
end
def from_limited?
@sender.silenced? && not_following?
end
def private_mention_not_in_response?
@notification.type == :mention && @notification.target_status.direct_visibility? && !response_to_recipient?
end
def response_to_recipient?
return false if @notification.target_status.in_reply_to_id.nil?
statuses_that_mention_sender.positive?
end
def statuses_that_mention_sender
Status.count_by_sql([<<-SQL.squish, id: @notification.target_status.in_reply_to_id, recipient_id: @recipient.id, sender_id: @sender.id, depth_limit: 100])
WITH RECURSIVE ancestors(id, in_reply_to_id, mention_id, path, depth) AS (
SELECT s.id, s.in_reply_to_id, m.id, ARRAY[s.id], 0
FROM statuses s
LEFT JOIN mentions m ON m.silent = FALSE AND m.account_id = :sender_id AND m.status_id = s.id
WHERE s.id = :id
UNION ALL
SELECT s.id, s.in_reply_to_id, m.id, st.path || s.id, st.depth + 1
FROM ancestors st
JOIN statuses s ON s.id = st.in_reply_to_id
LEFT JOIN mentions m ON m.silent = FALSE AND m.account_id = :sender_id AND m.status_id = s.id
WHERE st.mention_id IS NULL AND NOT s.id = ANY(path) AND st.depth < :depth_limit
)
SELECT COUNT(*)
FROM ancestors st
JOIN statuses s ON s.id = st.id
WHERE st.mention_id IS NOT NULL AND s.visibility = 3
SQL
end
end
def call(recipient, type, activity) def call(recipient, type, activity)
return if recipient.user.nil?
@recipient = recipient @recipient = recipient
@activity = activity @activity = activity
@notification = Notification.new(account: @recipient, type: type, activity: @activity) @notification = Notification.new(account: @recipient, type: type, activity: @activity)
return if recipient.user.nil? || blocked? # For certain conditions we don't need to create a notification at all
return if dismiss?
@notification.filtered = filter?
@notification.save! @notification.save!
# It's possible the underlying activity has been deleted # It's possible the underlying activity has been deleted
# between the save call and now # between the save call and now
return if @notification.activity.nil? return if @notification.activity.nil?
push_notification! if @notification.filtered?
push_to_conversation! if direct_message? update_notification_request!
send_email! if email_needed? else
push_notification!
push_to_conversation! if direct_message?
send_email! if email_needed?
end
rescue ActiveRecord::RecordInvalid rescue ActiveRecord::RecordInvalid
nil nil
end end
private private
def blocked_mention? def dismiss?
FeedManager.instance.filter?(:mentions, @notification.mention.status, @recipient) DismissCondition.new(@notification).dismiss?
end end
def following_sender? def filter?
return @following_sender if defined?(@following_sender) FilterCondition.new(@notification).filter?
@following_sender = @recipient.following?(@notification.from_account) || @recipient.requested?(@notification.from_account)
end end
def optional_non_follower? def update_notification_request!
@recipient.user.settings['interactions.must_be_follower'] && !@notification.from_account.following?(@recipient) return unless @notification.type == :mention
end
def optional_non_following? notification_request = NotificationRequest.find_or_initialize_by(account_id: @recipient.id, from_account_id: @notification.from_account_id)
@recipient.user.settings['interactions.must_be_following'] && !following_sender? notification_request.last_status_id = @notification.target_status.id
end notification_request.save
def message?
@notification.type == :mention
end
def direct_message?
message? && @notification.target_status.direct_visibility?
end
# Returns true if the sender has been mentioned by the recipient up the thread
def response_to_recipient?
return false if @notification.target_status.in_reply_to_id.nil?
# Using an SQL CTE to avoid unneeded back-and-forth with SQL server in case of long threads
!Status.count_by_sql([<<-SQL.squish, id: @notification.target_status.in_reply_to_id, recipient_id: @recipient.id, sender_id: @notification.from_account.id, depth_limit: 100]).zero?
WITH RECURSIVE ancestors(id, in_reply_to_id, mention_id, path, depth) AS (
SELECT s.id, s.in_reply_to_id, m.id, ARRAY[s.id], 0
FROM statuses s
LEFT JOIN mentions m ON m.silent = FALSE AND m.account_id = :sender_id AND m.status_id = s.id
WHERE s.id = :id
UNION ALL
SELECT s.id, s.in_reply_to_id, m.id, st.path || s.id, st.depth + 1
FROM ancestors st
JOIN statuses s ON s.id = st.in_reply_to_id
LEFT JOIN mentions m ON m.silent = FALSE AND m.account_id = :sender_id AND m.status_id = s.id
WHERE st.mention_id IS NULL AND NOT s.id = ANY(path) AND st.depth < :depth_limit
)
SELECT COUNT(*)
FROM ancestors st
JOIN statuses s ON s.id = st.id
WHERE st.mention_id IS NOT NULL AND s.visibility = 3
SQL
end
def from_staff?
@notification.from_account.local? && @notification.from_account.user.present? && @notification.from_account.user_role&.overrides?(@recipient.user_role)
end
def optional_non_following_and_direct?
direct_message? &&
@recipient.user.settings['interactions.must_be_following_dm'] &&
!following_sender? &&
!response_to_recipient?
end
def hellbanned?
@notification.from_account.silenced? && !following_sender?
end
def from_self?
@recipient.id == @notification.from_account.id
end
def domain_blocking?
@recipient.domain_blocking?(@notification.from_account.domain) && !following_sender?
end
def blocked?
blocked = @recipient.unavailable?
blocked ||= from_self? && @notification.type != :poll
return blocked if message? && from_staff?
blocked ||= domain_blocking?
blocked ||= @recipient.blocking?(@notification.from_account)
blocked ||= @recipient.muting_notifications?(@notification.from_account)
blocked ||= hellbanned?
blocked ||= optional_non_follower?
blocked ||= optional_non_following?
blocked ||= optional_non_following_and_direct?
blocked ||= conversation_muted?
blocked ||= blocked_mention? if @notification.type == :mention
blocked
end
def conversation_muted?
if @notification.target_status
@recipient.muting_conversation?(@notification.target_status.conversation)
else
false
end
end end
def push_notification! def push_notification!
@ -150,6 +219,10 @@ class NotifyService < BaseService
AccountConversation.add_status(@recipient, @notification.target_status) AccountConversation.add_status(@recipient, @notification.target_status)
end end
def direct_message?
@notification.type == :mention && @notification.target_status.direct_visibility?
end
def push_to_web_push_subscriptions! def push_to_web_push_subscriptions!
::Web::PushNotificationWorker.push_bulk(web_push_subscriptions.select { |subscription| subscription.pushable?(@notification) }) { |subscription| [subscription.id, @notification.id] } ::Web::PushNotificationWorker.push_bulk(web_push_subscriptions.select { |subscription| subscription.pushable?(@notification) }) { |subscription| [subscription.id, @notification.id] }
end end

View file

@ -7,5 +7,8 @@
.fields-group .fields-group
= f.input :text, wrapper: :with_block_label = f.input :text, wrapper: :with_block_label
.fields-group
= f.input :hint, wrapper: :with_block_label
.actions .actions
= f.button :button, t('generic.save_changes'), type: :submit = f.button :button, t('generic.save_changes'), type: :submit

View file

@ -12,6 +12,9 @@
.fields-group .fields-group
= f.input :text, wrapper: :with_block_label = f.input :text, wrapper: :with_block_label
.fields-group
= f.input :hint, wrapper: :with_block_label
.actions .actions
= f.button :button, t('admin.rules.add_new'), type: :submit = f.button :button, t('admin.rules.add_new'), type: :submit

View file

@ -20,6 +20,7 @@
- @rules.each do |rule| - @rules.each do |rule|
%li %li
.rules-list__text= rule.text .rules-list__text= rule.text
.rules-list__hint= rule.hint
.stacked-actions .stacked-actions
- accept_path = @invite_code.present? ? public_invite_url(invite_code: @invite_code, accept: @accept_token) : new_user_registration_path(accept: @accept_token) - accept_path = @invite_code.present? ? public_invite_url(invite_code: @invite_code, accept: @accept_token) : new_user_registration_path(accept: @accept_token)

View file

@ -42,11 +42,3 @@
label_method: ->(setting) { I18n.t("simple_form.labels.notification_emails.software_updates.#{setting}") }, label_method: ->(setting) { I18n.t("simple_form.labels.notification_emails.software_updates.#{setting}") },
label: I18n.t('simple_form.labels.notification_emails.software_updates.label'), label: I18n.t('simple_form.labels.notification_emails.software_updates.label'),
wrapper: :with_label wrapper: :with_label
%h4= t 'notifications.other_settings'
.fields-group
= f.simple_fields_for :settings, current_user.settings do |ff|
= ff.input :'interactions.must_be_follower', wrapper: :with_label, label: I18n.t('simple_form.labels.interactions.must_be_follower')
= ff.input :'interactions.must_be_following', wrapper: :with_label, label: I18n.t('simple_form.labels.interactions.must_be_following')
= ff.input :'interactions.must_be_following_dm', wrapper: :with_label, label: I18n.t('simple_form.labels.interactions.must_be_following_dm')

View file

@ -0,0 +1,37 @@
# frozen_string_literal: true
class UnfilterNotificationsWorker
include Sidekiq::Worker
def perform(notification_request_id)
@notification_request = NotificationRequest.find(notification_request_id)
push_to_conversations!
unfilter_notifications!
remove_request!
rescue ActiveRecord::RecordNotFound
true
end
private
def push_to_conversations!
notifications_with_private_mentions.find_each { |notification| AccountConversation.add_status(@notification_request.account, notification.target_status) }
end
def unfilter_notifications!
filtered_notifications.in_batches.update_all(filtered: false)
end
def remove_request!
@notification_request.destroy!
end
def filtered_notifications
Notification.where(account: @notification_request.account, from_account: @notification_request.from_account, filtered: true)
end
def notifications_with_private_mentions
filtered_notifications.joins(mention: :status).merge(Status.where(visibility: :direct)).includes(mention: :status)
end
end

View file

@ -1,10 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
# TODO # TODO: Starting with Rails 7.0, the framework default is true for this setting.
# Starting with Rails 7.0, the framework default here is to set this true. # This location in devise redirects and we can't hook in or override:
# However, we have a location in devise that redirects where we don't have an # https://github.com/heartcombo/devise/blob/v4.9.3/app/controllers/devise/confirmations_controller.rb#L28
# easy ability to override the method or set a config option, and where the # When solution is found, this setting can go back to default.
# redirect does not supply this option itself.
# https://github.com/heartcombo/devise/blob/v4.9.2/app/controllers/devise/confirmations_controller.rb#L28
# Once a solution is found, this line can be removed.
Rails.application.config.action_controller.raise_on_open_redirects = false Rails.application.config.action_controller.raise_on_open_redirects = false

View file

@ -19,7 +19,7 @@ kab:
account: account:
attributes: attributes:
username: username:
invalid: isekkilen, uṭṭunen d yijerriden n wadda kan invalid: ilaq ad ilin isekkilen, uṭṭunen d yijerriden n wadda kan
reserved: yettwaṭṭef reserved: yettwaṭṭef
status: status:
attributes: attributes:

View file

@ -7,11 +7,11 @@ sk:
options: Voľby options: Voľby
user: user:
agreement: Dohoda o poskytovaní služieb agreement: Dohoda o poskytovaní služieb
email: Emailová adresa email: E-mailová adresa
locale: Jazyk locale: Jazyk
password: Heslo password: Heslo
user/account: user/account:
username: Meno používateľa username: Používateľské meno
user/invite_request: user/invite_request:
text: Dôvod text: Dôvod
errors: errors:
@ -41,9 +41,9 @@ sk:
attributes: attributes:
email: email:
blocked: používa nepovoleného poskytovateľa e-mailu blocked: používa nepovoleného poskytovateľa e-mailu
unreachable: zdá sa, že neexistuje unreachable: vyzerá, že neexistuje
role_id: role_id:
elevated: nemôže byť vyššia ako vaša súčasná rola elevated: nemôže byť viac ako vaša súčasná rola
user_role: user_role:
attributes: attributes:
permissions_as_keys: permissions_as_keys:
@ -51,9 +51,9 @@ sk:
elevated: nemôže obsahovať povolenia, ktoré vaša aktuálna rola nemá elevated: nemôže obsahovať povolenia, ktoré vaša aktuálna rola nemá
own_role: nie je možné zmeniť s vašou aktuálnou rolou own_role: nie je možné zmeniť s vašou aktuálnou rolou
position: position:
elevated: nemôže byť vyššia ako vaša súčasná rola elevated: nemôže byť viac ako vaša súčasná rola
own_role: nie je možné zmeniť s vašou aktuálnou rolou own_role: nie je možné zmeniť s vašou aktuálnou rolou
webhook: webhook:
attributes: attributes:
events: events:
invalid_permissions: nemožno zahrnúť udalosti, ku ktorým nemáte práva invalid_permissions: nemôže zahrnúť udalosti, ku ktorým nemáte práva

View file

@ -173,5 +173,3 @@ af:
warning: warning:
title: title:
silence: Rekening beperk silence: Rekening beperk
welcome:
edit_profile_action: Stel profiel op

View file

@ -1288,7 +1288,6 @@ an:
notifications: notifications:
email_events: Eventos pa notificacions per correu electronico email_events: Eventos pa notificacions per correu electronico
email_events_hint: 'Tría los eventos pa los quals deseyas recibir notificacions:' email_events_hint: 'Tría los eventos pa los quals deseyas recibir notificacions:'
other_settings: Atros achustes de notificacions
number: number:
human: human:
decimal_units: decimal_units:
@ -1597,8 +1596,6 @@ an:
silence: Cuenta limitada silence: Cuenta limitada
suspend: Cuenta suspendida suspend: Cuenta suspendida
welcome: welcome:
edit_profile_action: Configurar lo perfil
edit_profile_step: Puetz personalizar lo tuyo perfil puyando una foto de perfil, cambiando lo tuyo nombre d'usuario y muito mas. Puetz optar per revisar a los nuevos seguidores antes que puedan seguir-te.
explanation: Aquí i hai qualques consellos pa empecipiar explanation: Aquí i hai qualques consellos pa empecipiar
subject: Bienveniu a Mastodon subject: Bienveniu a Mastodon
title: Te damos la bienvenida a bordo, %{name}! title: Te damos la bienvenida a bordo, %{name}!

View file

@ -1594,7 +1594,6 @@ ar:
administration_emails: إشعارات البريد الإلكتروني الإدارية administration_emails: إشعارات البريد الإلكتروني الإدارية
email_events: الأحداث للإشعارات عبر البريد الإلكتروني email_events: الأحداث للإشعارات عبر البريد الإلكتروني
email_events_hint: 'اختر الأحداث التي تريد أن تصِلَك اشعارات عنها:' email_events_hint: 'اختر الأحداث التي تريد أن تصِلَك اشعارات عنها:'
other_settings: إعدادات أخرى للإشعارات
number: number:
human: human:
decimal_units: decimal_units:
@ -1966,8 +1965,6 @@ ar:
silence: الحساب محدود silence: الحساب محدود
suspend: الحساب مُعلَّق suspend: الحساب مُعلَّق
welcome: welcome:
edit_profile_action: تهيئة الملف التعريفي
edit_profile_step: يمكنك تخصيص ملفك الشخصي عن طريق رفع صورة ملفك الشخصي, تغيير اسم العرض الخاص بك والمزيد. يمكنك اختيار مراجعة المتابعين الجدد قبل السماح لهم بمتابعتك.
explanation: ها هي بعض النصائح قبل بداية الاستخدام explanation: ها هي بعض النصائح قبل بداية الاستخدام
subject: أهلًا بك على ماستدون subject: أهلًا بك على ماستدون
title: أهلاً بك، %{name}! title: أهلاً بك، %{name}!

View file

@ -695,7 +695,6 @@ ast:
notifications: notifications:
email_events: Unviu d'avisos per corréu electrónicu email_events: Unviu d'avisos per corréu electrónicu
email_events_hint: 'Seleiciona los eventos de los que quies recibir avisos:' email_events_hint: 'Seleiciona los eventos de los que quies recibir avisos:'
other_settings: Configuración d'otros avisos
number: number:
human: human:
decimal_units: decimal_units:
@ -900,8 +899,6 @@ ast:
none: Alvertencia none: Alvertencia
suspend: Cuenta suspendida suspend: Cuenta suspendida
welcome: welcome:
edit_profile_action: Configurar el perfil
edit_profile_step: Pues personalizar el perfil pente la xuba d'una semeya, el cambéu del nome visible ya muncho más. Tamién, si lo prefieres, pues revisar los perfiles nuevos enantes de que puedan siguite.
explanation: Equí tienes dalgunos conseyos pa que comiences explanation: Equí tienes dalgunos conseyos pa que comiences
subject: Afáyate en Mastodon subject: Afáyate en Mastodon
title: "¡Afáyate, %{name}!" title: "¡Afáyate, %{name}!"

View file

@ -1547,7 +1547,6 @@ be:
administration_emails: Апавяшчэнні эл. пошты для адміністратара administration_emails: Апавяшчэнні эл. пошты для адміністратара
email_events: Падзеі для апавяшчэнняў эл. пошты email_events: Падзеі для апавяшчэнняў эл. пошты
email_events_hint: 'Выберыце падзеі, аб якіх вы хочаце атрымліваць апавяшчэнні:' email_events_hint: 'Выберыце падзеі, аб якіх вы хочаце атрымліваць апавяшчэнні:'
other_settings: Іншыя налады апавяшчэнняў
number: number:
human: human:
decimal_units: decimal_units:
@ -1907,9 +1906,42 @@ be:
silence: Уліковы запіс абмежаваны silence: Уліковы запіс абмежаваны
suspend: Уліковы запіс выключаны suspend: Уліковы запіс выключаны
welcome: welcome:
edit_profile_action: Наладзіць профіль apps_android_action: Спампаваць з Google Play
edit_profile_step: Вы можаце наладзіць свой профіль, запампаваўшы выяву профілю, змяніўшы адлюстраванае імя і іншае. Вы можаце праглядаць новых падпісчыкаў, перш чым ім будзе дазволена падпісацца на вас. apps_ios_action: Спампваваць з App Store
apps_step: Спампуйце нашыя афіцыйныя праграмы.
apps_title: Кліенты Mastodon
checklist_subtitle: 'Давайце паспрабуем разабрацца ў гэтай новай сацыяльнай сетцы:'
checklist_title: З чаго пачаць
edit_profile_action: Персаналізаваць
edit_profile_step: Узмацніце ўзаемадзеянне, запоўніўшы поўны профіль.
edit_profile_title: Наладзьце свой профіль
explanation: Вось некаторыя парады каб пачаць explanation: Вось некаторыя парады каб пачаць
feature_action: Даведацца больш
feature_audience: Mastodon дае ўнікальную магчымасць кіраваць сваёй аўдыторыяй без пасрэднікаў. Маючы сервер Mastodon, разгорнуты на ўласнай інфраструктуры, яго карыстальнікі могуць узаемадзейнічаць з любым іншым серверам Mastodon, не аддаючы кантроль у чужыя рукі.
feature_audience_title: Фармуйце сваю аўдыторыю з упэўненасцю
feature_control: Толькі вы дакладна ведаеце, што хочаце бачыць на сваім серверы. Ніякіх алгарытмаў або рэкламы, якія марнуюць ваш час. Сачыце за любым серверам Mastodon з аднаго ўліковага запісу і атрымлівайце паведамленні ў храналагічным парадку, каб ваш куток Інтэрнэту быў крыху падобны на вас.
feature_control_title: Кіруйце сваёй стужкай
feature_creativity: Mastodon падтрымлівае публікацыі з аўдыя, відэа і малюнкамі, апісаннем даступнасці, апытаннямі, папярэджаннямі аб змесце, аніміраванымі аватарамі, карыстальніцкімі эмодзі, мініяцюрамі, элементамі кіравання абрэзкай мініяцюр і іншым. Незалежна ад таго, дзеліцеся вы сваім мастацтвам, музыкай або падкастам, Mastodon тут для вас.
feature_creativity_title: Неабмежаваны творчы патэнцыял
feature_moderation: Mastodon вяртае прыняцце рашэнняў у вашыя рукі. У адрозненне ад сацыяльных сетак, якія належаць карпарацыям, якія спускаюць свае правілы зверху, кожны сервер Mastodon усталёўвае свае правілы і нормы, якія выконваюцца на мясцовым узроўні, што робіць іх найболей гнуткімі ў задавальненні запатрабаванняў розных груп людзей. Далучайцеся да сервера з правіламі, з якімі вы згодны, ці стварыце свой уласны.
feature_moderation_title: Мадэрацыя, якой яна павінна быць
follow_action: Падпісацца
follow_step: Падпіска на цікавых людзей - гэта галоўнае ў Mastodon.
follow_title: Наладзьце сваю хатнюю стужку
follows_subtitle: Падпішыцеся на папулярных карыстальнікаў
follows_title: На каго падпісацца
follows_view_more: Прагледзець больш людзей, на якіх варта падпісацца
hashtags_recent_count: "%{people} людзей за апошнія %{days} дні"
hashtags_subtitle: Даведайцеся што было папулярна ў апошнія 2 дні
hashtags_title: Папулярныя хэштэгі
hashtags_view_more: Прагледзець іншыя папулярныя хэштэгі
post_action: Стварыць
post_step: Скажыце ўсім прывітанне з дапамогай тэксту, фатаграфій, відэа і апытанняў.
post_title: Стварыце свой першы допіс
share_action: Абагуліць
share_step: Няхай вашыя сябры ведаюць, як знайсці вас у Mastodon.
share_title: Абагульце ваш профіль у Mastodon
sign_in_action: Увайсці
subject: Вітаем у Mastodon subject: Вітаем у Mastodon
title: Рады вітаць вас, %{name}! title: Рады вітаць вас, %{name}!
users: users:

View file

@ -767,6 +767,7 @@ bg:
disabled: До никого disabled: До никого
users: До влезнали локални потребители users: До влезнали локални потребители
registrations: registrations:
moderation_recommandation: Уверете се, че имате адекватен и реактивен модераторски екип преди да отворите регистриранията за всеки!
preamble: Управлява кой може да създава акаунт на сървъра ви. preamble: Управлява кой може да създава акаунт на сървъра ви.
title: Регистрации title: Регистрации
registrations_mode: registrations_mode:
@ -774,6 +775,7 @@ bg:
approved: Изисква се одобрение за регистриране approved: Изисква се одобрение за регистриране
none: Никой не може да се регистрира none: Никой не може да се регистрира
open: Всеки може да се регистрира open: Всеки може да се регистрира
warning_hint: Препоръчваме употребата на „Изисква се одобрение за регистриране“, освен ако сте уверени, че екипът ви за модериране може да се справи със спама и зловредните регистрирания своевременно.
security: security:
authorized_fetch: Изисква се удостоверяване от федеративни сървъри authorized_fetch: Изисква се удостоверяване от федеративни сървъри
authorized_fetch_hint: Изискването удостоверяване от феративните сървъри позволява по-строго прилагане на блокирания както на ниво потребител, така и на ниво сървър. Това обаче снижава производителността, намалява обхвата на вашите отговори и може да възникнат проблеми със съвместимостта с някои федеративни услуги. Освен това, то не пречи на посветени участници да извличат вашите обществени публикации и акаунти. authorized_fetch_hint: Изискването удостоверяване от феративните сървъри позволява по-строго прилагане на блокирания както на ниво потребител, така и на ниво сървър. Това обаче снижава производителността, намалява обхвата на вашите отговори и може да възникнат проблеми със съвместимостта с някои федеративни услуги. Освен това, то не пречи на посветени участници да извличат вашите обществени публикации и акаунти.
@ -966,6 +968,9 @@ bg:
title: Уебкуки title: Уебкуки
webhook: Уебкука webhook: Уебкука
admin_mailer: admin_mailer:
auto_close_registrations:
body: Поради липса на скорошна дейност по модериране, регистрациите на %{instance} бяха самодейно превключени в режим, изискващ ръчна проверка, за да се предотврати употребата на %{instance} като платформа за потенциални зложелатели. Може да превключите обратно в режим „отворено регистриране“ по всяко време.
subject: Регистриранията за %{instance} са самодейно превключени към изискване на одобрение
new_appeal: new_appeal:
actions: actions:
delete_statuses: за изтриване на публикациите им delete_statuses: за изтриване на публикациите им
@ -1009,7 +1014,7 @@ bg:
remove: Разкачвне на псевдонима remove: Разкачвне на псевдонима
appearance: appearance:
advanced_web_interface: Разширен уеб интерфейс advanced_web_interface: Разширен уеб интерфейс
advanced_web_interface_hint: 'Ако желаете да се възползвате от цялата ширина на своя екран, разширеният уеб интерфейс ще ви позволи да настроите няколко различни колони, за да виждате едновременно различна информация: Начало, известия, федерирана хронология, множество списъци и хаштагове.' advanced_web_interface_hint: 'Ако искате да употребявате цялата ширина на екрана си, разширеният уеб интерфейс ви позволява да настроите най-различни колони, за да виждате едновременно множество сведения, колкото искате: Начало, известия, федеративен инфоканал, произволен брой списъци и хаштагове.'
animations_and_accessibility: Анимация и достъпност animations_and_accessibility: Анимация и достъпност
confirmation_dialogs: Диалогов прозорец за потвърждение confirmation_dialogs: Диалогов прозорец за потвърждение
discovery: Откриване discovery: Откриване
@ -1490,7 +1495,6 @@ bg:
administration_emails: Администраторски известия по имейла administration_emails: Администраторски известия по имейла
email_events: Събития за известия по имейл email_events: Събития за известия по имейл
email_events_hint: 'Изберете събития, за които искате да получавате известия:' email_events_hint: 'Изберете събития, за които искате да получавате известия:'
other_settings: Настройки за други известия
number: number:
human: human:
decimal_units: decimal_units:
@ -1838,9 +1842,42 @@ bg:
silence: Акаунтът има ограничение silence: Акаунтът има ограничение
suspend: Акаунтът е спрян suspend: Акаунтът е спрян
welcome: welcome:
edit_profile_action: Настройване на профила apps_android_action: Вземане от Google Play
edit_profile_step: Може да настроите профила си, качвайки снимката на профила, променяйки показваното си име и други неща. Може да се включите за преглед на нови последователи преди да бъдат позволени да ви последват. apps_ios_action: Изтегляне в App Store
apps_step: Изтегляне на служебните ни приложения.
apps_title: Приложения на Mastodon
checklist_subtitle: 'Нека започнем приключение в тази нова социална граница:'
checklist_title: Добре дошли при контролния списък
edit_profile_action: Персонализиране
edit_profile_step: Подсилете взаимодействията си, изграждайки цялостен профил.
edit_profile_title: Пригодете профила си
explanation: Ето няколко стъпки за начало explanation: Ето няколко стъпки за начало
feature_action: Научете повече
feature_audience: Mastodon ви осигурява с неповторимата възможност на управление на публиката ви без посредници. Mastodon се разгръща на ваша собствена инфраструктура, позволяваща ви да следвате и да бъдете последвани от всеки друг сървър на Mastodon в мрежата и не е под ничий контрол освен ваш.
feature_audience_title: Изградете публиката си с увереност
feature_control: Вие знаете най-добре какво искате да виждате на началния си инфоканал. Няма алгоритми или реклами, за да ви губят времето. Последвате всекиго през всеки сървър на Mastodon от един акаунт и получавате публикациите им в хронологичен ред, а и правете свое кътче в интернет малко по-подобно на вас.
feature_control_title: Поддържайте управлението на часовата си ос
feature_creativity: Mastodon поддържа публикации със звук, картина и видео, описания на достъпността, анкети, предупреждения за съдържание, анимирани аватари, потребителски емоджита, контрол на изрязване на миниобрази и още, за да ви помогнат да се изразите в мрежата. Независимо дали публикувате свое изкуство, музика или свой подкаст, то Mastodon е там за вас.
feature_creativity_title: Несравнимо творчество
feature_moderation: Mastodon връща вземането на решения в ръцете ви. Всеки сървър сътворява свои правила и регулации, прилагащи се локално, а не отгоре надолу като корпоративна социална медия, което го прави най-гъвкав в отговор на нуждите на различни групи хора. Присъединете се към сървър, с който сте съгласни, или пък си хоствайте свой.
feature_moderation_title: Модерирайте начина, по който трябва да е
follow_action: Последване
follow_step: Последването на интересни хора е основната цел на Mastodon.
follow_title: Персонализиране на началния ви инфоканал
follows_subtitle: Следвайте добре известни акаунти
follows_title: Кого да се последва
follows_view_more: Преглед на още хора за последване
hashtags_recent_count: "%{people} души за последните %{days} дни"
hashtags_subtitle: Проучете какво изгрява от последните 2 дни
hashtags_title: Изгряващи хаштагове
hashtags_view_more: Преглед на още изгряващи хаштагове
post_action: Съставяне
post_step: Поздравете света с текст, снимки, видео или анкети.
post_title: Направете първата си публикация
share_action: Споделяне
share_step: Позволете на приятелите си да знаят как да ви намират в Mastodon.
share_title: Споделете профила си в Mastodon
sign_in_action: Вход
subject: Добре дошли в Mastodon subject: Добре дошли в Mastodon
title: Добре дошли на борда, %{name}! title: Добре дошли на борда, %{name}!
users: users:

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