Merge remote-tracking branch 'upstream/main'
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone Build is passing

This commit is contained in:
Dalite 2024-03-15 11:06:28 +01:00
commit ffae506e12
197 changed files with 1054 additions and 754 deletions

View file

@ -8,6 +8,7 @@ class Api::BaseController < ApplicationController
include Api::AccessTokenTrackingConcern
include Api::CachingConcern
include Api::ContentSecurityPolicy
include Api::ErrorHandling
skip_before_action :require_functional!, unless: :limited_federation_mode?
@ -18,51 +19,6 @@ class Api::BaseController < ApplicationController
protect_from_forgery with: :null_session
rescue_from ActiveRecord::RecordInvalid, Mastodon::ValidationError do |e|
render json: { error: e.to_s }, status: 422
end
rescue_from ActiveRecord::RecordNotUnique do
render json: { error: 'Duplicate record' }, status: 422
end
rescue_from Date::Error do
render json: { error: 'Invalid date supplied' }, status: 422
end
rescue_from ActiveRecord::RecordNotFound do
render json: { error: 'Record not found' }, status: 404
end
rescue_from HTTP::Error, Mastodon::UnexpectedResponseError do
render json: { error: 'Remote data could not be fetched' }, status: 503
end
rescue_from OpenSSL::SSL::SSLError do
render json: { error: 'Remote SSL certificate could not be verified' }, status: 503
end
rescue_from Mastodon::NotPermittedError do
render json: { error: 'This action is not allowed' }, status: 403
end
rescue_from Seahorse::Client::NetworkingError do |e|
Rails.logger.warn "Storage server error: #{e}"
render json: { error: 'There was a temporary problem serving your request, please try again' }, status: 503
end
rescue_from Mastodon::RaceConditionError, Stoplight::Error::RedLight do
render json: { error: 'There was a temporary problem serving your request, please try again' }, status: 503
end
rescue_from Mastodon::RateLimitExceededError do
render json: { error: I18n.t('errors.429') }, status: 429
end
rescue_from ActionController::ParameterMissing, Mastodon::InvalidParameterError do |e|
render json: { error: e.to_s }, status: 400
end
def doorkeeper_unauthorized_render_options(error: nil)
{ json: { error: error.try(:description) || 'Not authorized' } }
end
@ -73,6 +29,14 @@ class Api::BaseController < ApplicationController
protected
def pagination_max_id
pagination_collection.last.id
end
def pagination_since_id
pagination_collection.first.id
end
def set_pagination_headers(next_path = nil, prev_path = nil)
links = []
links << [next_path, [%w(rel next)]] if next_path

View file

@ -51,11 +51,7 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
@statuses.size == limit_param(DEFAULT_STATUSES_LIMIT)
end
def pagination_max_id
@statuses.last.id
end
def pagination_since_id
@statuses.first.id
def pagination_collection
@statuses
end
end

View file

@ -137,12 +137,8 @@ class Api::V1::Admin::AccountsController < Api::BaseController
api_v1_admin_accounts_url(pagination_params(min_id: pagination_since_id)) unless @accounts.empty?
end
def pagination_max_id
@accounts.last.id
end
def pagination_since_id
@accounts.first.id
def pagination_collection
@accounts
end
def records_continue?

View file

@ -77,12 +77,8 @@ class Api::V1::Admin::CanonicalEmailBlocksController < Api::BaseController
api_v1_admin_canonical_email_blocks_url(pagination_params(min_id: pagination_since_id)) unless @canonical_email_blocks.empty?
end
def pagination_max_id
@canonical_email_blocks.last.id
end
def pagination_since_id
@canonical_email_blocks.first.id
def pagination_collection
@canonical_email_blocks
end
def records_continue?

View file

@ -73,12 +73,8 @@ class Api::V1::Admin::DomainAllowsController < Api::BaseController
api_v1_admin_domain_allows_url(pagination_params(min_id: pagination_since_id)) unless @domain_allows.empty?
end
def pagination_max_id
@domain_allows.last.id
end
def pagination_since_id
@domain_allows.first.id
def pagination_collection
@domain_allows
end
def records_continue?

View file

@ -84,12 +84,8 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController
api_v1_admin_domain_blocks_url(pagination_params(min_id: pagination_since_id)) unless @domain_blocks.empty?
end
def pagination_max_id
@domain_blocks.last.id
end
def pagination_since_id
@domain_blocks.first.id
def pagination_collection
@domain_blocks
end
def records_continue?

View file

@ -70,12 +70,8 @@ class Api::V1::Admin::EmailDomainBlocksController < Api::BaseController
api_v1_admin_email_domain_blocks_url(pagination_params(min_id: pagination_since_id)) unless @email_domain_blocks.empty?
end
def pagination_max_id
@email_domain_blocks.last.id
end
def pagination_since_id
@email_domain_blocks.first.id
def pagination_collection
@email_domain_blocks
end
def records_continue?

View file

@ -75,12 +75,8 @@ class Api::V1::Admin::IpBlocksController < Api::BaseController
api_v1_admin_ip_blocks_url(pagination_params(min_id: pagination_since_id)) unless @ip_blocks.empty?
end
def pagination_max_id
@ip_blocks.last.id
end
def pagination_since_id
@ip_blocks.first.id
def pagination_collection
@ip_blocks
end
def records_continue?

View file

@ -101,12 +101,8 @@ class Api::V1::Admin::ReportsController < Api::BaseController
api_v1_admin_reports_url(pagination_params(min_id: pagination_since_id)) unless @reports.empty?
end
def pagination_max_id
@reports.last.id
end
def pagination_since_id
@reports.first.id
def pagination_collection
@reports
end
def records_continue?

View file

@ -56,12 +56,8 @@ class Api::V1::Admin::TagsController < Api::BaseController
api_v1_admin_tags_url(pagination_params(min_id: pagination_since_id)) unless @tags.empty?
end
def pagination_max_id
@tags.last.id
end
def pagination_since_id
@tags.first.id
def pagination_collection
@tags
end
def records_continue?

View file

@ -54,12 +54,8 @@ class Api::V1::Admin::Trends::Links::PreviewCardProvidersController < Api::BaseC
api_v1_admin_trends_links_preview_card_providers_url(pagination_params(min_id: pagination_since_id)) unless @providers.empty?
end
def pagination_max_id
@providers.last.id
end
def pagination_since_id
@providers.first.id
def pagination_collection
@providers
end
def records_continue?

View file

@ -40,12 +40,8 @@ class Api::V1::BlocksController < Api::BaseController
api_v1_blocks_url pagination_params(since_id: pagination_since_id) unless paginated_blocks.empty?
end
def pagination_max_id
paginated_blocks.last.id
end
def pagination_since_id
paginated_blocks.first.id
def pagination_collection
paginated_blocks
end
def records_continue?

View file

@ -43,12 +43,8 @@ class Api::V1::BookmarksController < Api::BaseController
api_v1_bookmarks_url pagination_params(min_id: pagination_since_id) unless results.empty?
end
def pagination_max_id
results.last.id
end
def pagination_since_id
results.first.id
def pagination_collection
results
end
def records_continue?

View file

@ -41,12 +41,8 @@ class Api::V1::Crypto::EncryptedMessagesController < Api::BaseController
api_v1_crypto_encrypted_messages_url pagination_params(min_id: pagination_since_id) unless @encrypted_messages.empty?
end
def pagination_max_id
@encrypted_messages.last.id
end
def pagination_since_id
@encrypted_messages.first.id
def pagination_collection
@encrypted_messages
end
def records_continue?

View file

@ -50,12 +50,8 @@ class Api::V1::DomainBlocksController < Api::BaseController
api_v1_domain_blocks_url pagination_params(since_id: pagination_since_id) unless @blocks.empty?
end
def pagination_max_id
@blocks.last.id
end
def pagination_since_id
@blocks.first.id
def pagination_collection
@blocks
end
def records_continue?

View file

@ -44,12 +44,8 @@ class Api::V1::EndorsementsController < Api::BaseController
api_v1_endorsements_url pagination_params(since_id: pagination_since_id) unless @accounts.empty?
end
def pagination_max_id
@accounts.last.id
end
def pagination_since_id
@accounts.first.id
def pagination_collection
@accounts
end
def records_continue?

View file

@ -43,12 +43,8 @@ class Api::V1::FavouritesController < Api::BaseController
api_v1_favourites_url pagination_params(min_id: pagination_since_id) unless results.empty?
end
def pagination_max_id
results.last.id
end
def pagination_since_id
results.first.id
def pagination_collection
results
end
def records_continue?

View file

@ -34,12 +34,8 @@ class Api::V1::FollowedTagsController < Api::BaseController
api_v1_followed_tags_url pagination_params(since_id: pagination_since_id) unless @results.empty?
end
def pagination_max_id
@results.last.id
end
def pagination_since_id
@results.first.id
def pagination_collection
@results
end
def records_continue?

View file

@ -71,12 +71,8 @@ class Api::V1::Lists::AccountsController < Api::BaseController
api_v1_list_accounts_url pagination_params(since_id: pagination_since_id) unless @accounts.empty?
end
def pagination_max_id
@accounts.last.id
end
def pagination_since_id
@accounts.first.id
def pagination_collection
@accounts
end
def records_continue?

View file

@ -40,12 +40,8 @@ class Api::V1::MutesController < Api::BaseController
api_v1_mutes_url pagination_params(since_id: pagination_since_id) unless paginated_mutes.empty?
end
def pagination_max_id
paginated_mutes.last.id
end
def pagination_since_id
paginated_mutes.first.id
def pagination_collection
paginated_mutes
end
def records_continue?

View file

@ -70,12 +70,8 @@ class Api::V1::NotificationsController < Api::BaseController
api_v1_notifications_url pagination_params(min_id: pagination_since_id) unless @notifications.empty?
end
def pagination_max_id
@notifications.last.id
end
def pagination_since_id
@notifications.first.id
def pagination_collection
@notifications
end
def browserable_params

View file

@ -63,11 +63,7 @@ class Api::V1::ScheduledStatusesController < Api::BaseController
@statuses.size == limit_param(DEFAULT_STATUSES_LIMIT)
end
def pagination_max_id
@statuses.last.id
end
def pagination_since_id
@statuses.first.id
def pagination_collection
@statuses
end
end

View file

@ -9,12 +9,8 @@ class Api::V1::Timelines::BaseController < Api::BaseController
set_pagination_headers(next_path, prev_path)
end
def pagination_max_id
@statuses.last.id
end
def pagination_since_id
@statuses.first.id
def pagination_collection
@statuses
end
def next_path_params

View file

@ -129,7 +129,7 @@ class ApplicationController < ActionController::Base
end
def single_user_mode?
@single_user_mode ||= Rails.configuration.x.single_user_mode && Account.where('id > 0').exists?
@single_user_mode ||= Rails.configuration.x.single_user_mode && Account.without_internal.exists?
end
def use_seamless_external_login?

View file

@ -0,0 +1,52 @@
# frozen_string_literal: true
module Api::ErrorHandling
extend ActiveSupport::Concern
included do
rescue_from ActiveRecord::RecordInvalid, Mastodon::ValidationError do |e|
render json: { error: e.to_s }, status: 422
end
rescue_from ActiveRecord::RecordNotUnique do
render json: { error: 'Duplicate record' }, status: 422
end
rescue_from Date::Error do
render json: { error: 'Invalid date supplied' }, status: 422
end
rescue_from ActiveRecord::RecordNotFound do
render json: { error: 'Record not found' }, status: 404
end
rescue_from HTTP::Error, Mastodon::UnexpectedResponseError do
render json: { error: 'Remote data could not be fetched' }, status: 503
end
rescue_from OpenSSL::SSL::SSLError do
render json: { error: 'Remote SSL certificate could not be verified' }, status: 503
end
rescue_from Mastodon::NotPermittedError do
render json: { error: 'This action is not allowed' }, status: 403
end
rescue_from Seahorse::Client::NetworkingError do |e|
Rails.logger.warn "Storage server error: #{e}"
render json: { error: 'There was a temporary problem serving your request, please try again' }, status: 503
end
rescue_from Mastodon::RaceConditionError, Stoplight::Error::RedLight do
render json: { error: 'There was a temporary problem serving your request, please try again' }, status: 503
end
rescue_from Mastodon::RateLimitExceededError do
render json: { error: I18n.t('errors.429') }, status: 429
end
rescue_from ActionController::ParameterMissing, Mastodon::InvalidParameterError do |e|
render json: { error: e.to_s }, status: 400
end
end
end

View file

@ -213,7 +213,7 @@ module ApplicationHelper
state_params[:moved_to_account] = current_account.moved_to_account
end
state_params[:owner] = Account.local.without_suspended.where('id > 0').first if single_user_mode?
state_params[:owner] = Account.local.without_suspended.without_internal.first if single_user_mode?
json = ActiveModelSerializers::SerializableResource.new(InitialStatePresenter.new(state_params), serializer: InitialStateSerializer).to_json
# rubocop:disable Rails/OutputSafety

View file

@ -552,7 +552,10 @@ export const fetchNotificationsForRequest = accountId => (dispatch, getState) =>
api(getState).get('/api/v1/notifications', { params }).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data.map(item => item.account)));
dispatch(importFetchedStatuses(response.data.map(item => item.status).filter(status => !!status)));
dispatch(importFetchedAccounts(response.data.filter(item => item.report).map(item => item.report.target_account)));
dispatch(fetchNotificationsForRequestSuccess(response.data, next?.uri));
}).catch(err => {
dispatch(fetchNotificationsForRequestFail(err));
@ -585,7 +588,10 @@ export const expandNotificationsForRequest = () => (dispatch, getState) => {
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data.map(item => item.account)));
dispatch(importFetchedStatuses(response.data.map(item => item.status).filter(status => !!status)));
dispatch(importFetchedAccounts(response.data.filter(item => item.report).map(item => item.report.target_account)));
dispatch(expandNotificationsForRequestSuccess(response.data, next?.uri));
}).catch(err => {
dispatch(expandNotificationsForRequestFail(err));

View file

@ -199,7 +199,7 @@ class ColumnHeader extends PureComponent {
<h1 className={buttonClassName}>
{hasTitle && (
<>
{backButton}
{showBackButton && backButton}
<button onClick={this.handleTitleClick} className='column-header__title'>
{!showBackButton && <Icon id={icon} icon={iconComponent} className='column-header__icon' />}
@ -208,7 +208,7 @@ class ColumnHeader extends PureComponent {
</>
)}
{!hasTitle && backButton}
{!hasTitle && showBackButton && backButton}
<div className='column-header__buttons'>
{extraButton}

View file

@ -5,9 +5,7 @@ import { FormattedMessage, injectIntl } from 'react-intl';
import { connect } from 'react-redux';
import ArrowDropDownIcon from '@/material-icons/400-24px/arrow_drop_down.svg?react';
import { openModal } from 'mastodon/actions/modal';
import { Icon } from 'mastodon/components/icon';
import InlineAccount from 'mastodon/components/inline_account';
import { RelativeTimestamp } from 'mastodon/components/relative_timestamp';
@ -67,7 +65,7 @@ class EditedTimestamp extends PureComponent {
return (
<DropdownMenu statusId={statusId} renderItem={this.renderItem} scrollable renderHeader={this.renderHeader} onItemClick={this.handleItemClick}>
<button className='dropdown-menu__text-button'>
<FormattedMessage id='status.edited' defaultMessage='Edited {date}' values={{ date: intl.formatDate(timestamp, { month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' }) }} /> <Icon id='caret-down' icon={ArrowDropDownIcon} />
<FormattedMessage id='status.edited' defaultMessage='Edited {date}' values={{ date: <span className='animated-number'>{intl.formatDate(timestamp, { month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' })}</span> }} />
</button>
</DropdownMenu>
);

View file

@ -22,6 +22,7 @@ import Card from '../features/status/components/card';
// to use the progress bar to show download progress
import Bundle from '../features/ui/components/bundle';
import { MediaGallery, Video, Audio } from '../features/ui/util/async-components';
import { SensitiveMediaContext } from '../features/ui/util/sensitive_media_context';
import { displayMedia } from '../initial_state';
import { Avatar } from './avatar';
@ -78,6 +79,8 @@ const messages = defineMessages({
class Status extends ImmutablePureComponent {
static contextType = SensitiveMediaContext;
static propTypes = {
status: ImmutablePropTypes.map,
account: ImmutablePropTypes.record,
@ -133,19 +136,21 @@ class Status extends ImmutablePureComponent {
];
state = {
showMedia: defaultMediaVisibility(this.props.status),
statusId: undefined,
showMedia: defaultMediaVisibility(this.props.status) && !(this.context?.hideMediaByDefault),
forceFilter: undefined,
};
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.status && nextProps.status.get('id') !== prevState.statusId) {
return {
showMedia: defaultMediaVisibility(nextProps.status),
statusId: nextProps.status.get('id'),
};
} else {
return null;
componentDidUpdate (prevProps) {
// This will potentially cause a wasteful redraw, but in most cases `Status` components are used
// with a `key` directly depending on their `id`, preventing re-use of the component across
// different IDs.
// But just in case this does change, reset the state on status change.
if (this.props.status?.get('id') !== prevProps.status?.get('id')) {
this.setState({
showMedia: defaultMediaVisibility(this.props.status) && !(this.context?.hideMediaByDefault),
forceFilter: undefined,
});
}
}

View file

@ -7,7 +7,6 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
import FindInPageIcon from '@/material-icons/400-24px/find_in_page.svg?react';
import PeopleIcon from '@/material-icons/400-24px/group.svg?react';
import SearchIcon from '@/material-icons/400-24px/search.svg?react';
import TagIcon from '@/material-icons/400-24px/tag.svg?react';
import { Icon } from 'mastodon/components/icon';
import { LoadMore } from 'mastodon/components/load_more';
@ -76,11 +75,6 @@ class SearchResults extends ImmutablePureComponent {
return (
<div className='search-results'>
<div className='search-results__header'>
<Icon id='search' icon={SearchIcon} />
<FormattedMessage id='explore.search_results' defaultMessage='Search results' />
</div>
{accounts}
{hashtags}
{statuses}

View file

@ -15,6 +15,7 @@ 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 { SensitiveMediaContextProvider } from 'mastodon/features/ui/util/sensitive_media_context';
import NotificationContainer from './containers/notification_container';
@ -87,7 +88,7 @@ export const NotificationRequest = ({ multiColumn, params: { id } }) => {
}
}, [dispatch, accountId]);
const columnTitle = intl.formatMessage(messages.title, { name: account?.get('display_name') });
const columnTitle = intl.formatMessage(messages.title, { name: account?.get('display_name') || account?.get('username') });
return (
<Column bindToDocument={!multiColumn} ref={columnRef} label={columnTitle}>
@ -106,25 +107,27 @@ export const NotificationRequest = ({ multiColumn, params: { id } }) => {
)}
/>
<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>
<SensitiveMediaContextProvider hideMediaByDefault>
<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>
</SensitiveMediaContextProvider>
<Helmet>
<title>{columnTitle}</title>

View file

@ -9,8 +9,6 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react';
import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react';
import StarIcon from '@/material-icons/400-24px/star-fill.svg?react';
import { AnimatedNumber } from 'mastodon/components/animated_number';
import EditedTimestamp from 'mastodon/components/edited_timestamp';
import { getHashtagBarForStatus } from 'mastodon/components/hashtag_bar';
@ -143,10 +141,7 @@ class DetailedStatus extends ImmutablePureComponent {
let media = '';
let applicationLink = '';
let reblogLink = '';
const reblogIcon = 'retweet';
const reblogIconComponent = RepeatIcon;
let favouriteLink = '';
let edited = '';
if (this.props.measureHeight) {
outerStyle.height = `${this.state.height}px`;
@ -218,68 +213,53 @@ class DetailedStatus extends ImmutablePureComponent {
}
if (status.get('application')) {
applicationLink = <> · <a className='detailed-status__application' href={status.getIn(['application', 'website'])} target='_blank' rel='noopener noreferrer'>{status.getIn(['application', 'name'])}</a></>;
applicationLink = <>·<a className='detailed-status__application' href={status.getIn(['application', 'website'])} target='_blank' rel='noopener noreferrer'>{status.getIn(['application', 'name'])}</a></>;
}
const visibilityLink = <> · <VisibilityIcon visibility={status.get('visibility')} /></>;
const visibilityLink = <>·<VisibilityIcon visibility={status.get('visibility')} /></>;
if (['private', 'direct'].includes(status.get('visibility'))) {
reblogLink = '';
} else if (this.props.history) {
reblogLink = (
<>
{' · '}
<Link to={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}/reblogs`} className='detailed-status__link'>
<Icon id={reblogIcon} icon={reblogIconComponent} />
<span className='detailed-status__reblogs'>
<AnimatedNumber value={status.get('reblogs_count')} />
</span>
</Link>
</>
<Link to={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}/reblogs`} className='detailed-status__link'>
<span className='detailed-status__reblogs'>
<AnimatedNumber value={status.get('reblogs_count')} />
</span>
<FormattedMessage id='status.reblogs' defaultMessage='{count, plural, one {boost} other {boosts}}' values={{ count: status.get('reblogs_count') }} />
</Link>
);
} else {
reblogLink = (
<>
{' · '}
<a href={`/interact/${status.get('id')}?type=reblog`} className='detailed-status__link' onClick={this.handleModalLink}>
<Icon id={reblogIcon} icon={reblogIconComponent} />
<span className='detailed-status__reblogs'>
<AnimatedNumber value={status.get('reblogs_count')} />
</span>
</a>
</>
<a href={`/interact/${status.get('id')}?type=reblog`} className='detailed-status__link' onClick={this.handleModalLink}>
<span className='detailed-status__reblogs'>
<AnimatedNumber value={status.get('reblogs_count')} />
</span>
<FormattedMessage id='status.reblogs' defaultMessage='{count, plural, one {boost} other {boosts}}' values={{ count: status.get('reblogs_count') }} />
</a>
);
}
if (this.props.history) {
favouriteLink = (
<Link to={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}/favourites`} className='detailed-status__link'>
<Icon id='star' icon={StarIcon} />
<span className='detailed-status__favorites'>
<AnimatedNumber value={status.get('favourites_count')} />
</span>
<FormattedMessage id='status.favourites' defaultMessage='{count, plural, one {favorite} other {favorites}}' values={{ count: status.get('favourites_count') }} />
</Link>
);
} else {
favouriteLink = (
<a href={`/interact/${status.get('id')}?type=favourite`} className='detailed-status__link' onClick={this.handleModalLink}>
<Icon id='star' icon={StarIcon} />
<span className='detailed-status__favorites'>
<AnimatedNumber value={status.get('favourites_count')} />
</span>
<FormattedMessage id='status.favourites' defaultMessage='{count, plural, one {favorite} other {favorites}}' values={{ count: status.get('favourites_count') }} />
</a>
);
}
if (status.get('edited_at')) {
edited = (
<>
{' · '}
<EditedTimestamp statusId={status.get('id')} timestamp={status.get('edited_at')} />
</>
);
}
const {statusContentProps, hashtagBar} = getHashtagBarForStatus(status);
const expanded = !status.get('hidden') || status.get('spoiler_text').length === 0;
@ -310,9 +290,23 @@ class DetailedStatus extends ImmutablePureComponent {
{expanded && hashtagBar}
<div className='detailed-status__meta'>
<a className='detailed-status__datetime' href={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`} target='_blank' rel='noopener noreferrer'>
<FormattedDate value={new Date(status.get('created_at'))} year='numeric' month='short' day='2-digit' hour='2-digit' minute='2-digit' />
</a>{edited}{visibilityLink}{applicationLink}{reblogLink} · {favouriteLink}
<div className='detailed-status__meta__line'>
<a className='detailed-status__datetime' href={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`} target='_blank' rel='noopener noreferrer'>
<FormattedDate value={new Date(status.get('created_at'))} year='numeric' month='short' day='2-digit' hour='2-digit' minute='2-digit' />
</a>
{visibilityLink}
{applicationLink}
</div>
{status.get('edited_at') && <div className='detailed-status__meta__line'><EditedTimestamp statusId={status.get('id')} timestamp={status.get('edited_at')} /></div>}
<div className='detailed-status__meta__line'>
{reblogLink}
·
{favouriteLink}
</div>
</div>
</div>
</div>

View file

@ -66,8 +66,8 @@ const NotificationsLink = () => {
<ColumnLink
transparent
to='/notifications'
icon={<IconWithBadge icon={NotificationsIcon} count={count} className='column-link__icon' />}
activeIcon={<IconWithBadge icon={NotificationsActiveIcon} count={count} className='column-link__icon' />}
icon={<IconWithBadge id='bell' icon={NotificationsIcon} count={count} className='column-link__icon' />}
activeIcon={<IconWithBadge id='bell' icon={NotificationsActiveIcon} count={count} className='column-link__icon' />}
text={intl.formatMessage(messages.notifications)}
/>
);
@ -90,8 +90,8 @@ const FollowRequestsLink = () => {
<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' />}
icon={<IconWithBadge id='user-plus' icon={PersonAddIcon} count={count} className='column-link__icon' />}
activeIcon={<IconWithBadge id='user-plus' icon={PersonAddActiveIcon} count={count} className='column-link__icon' />}
text={intl.formatMessage(messages.followRequests)}
/>
);

View file

@ -0,0 +1,28 @@
import { createContext, useContext, useMemo } from 'react';
export const SensitiveMediaContext = createContext<{
hideMediaByDefault: boolean;
}>({
hideMediaByDefault: false,
});
export function useSensitiveMediaContext() {
return useContext(SensitiveMediaContext);
}
type ContextValue = React.ContextType<typeof SensitiveMediaContext>;
export const SensitiveMediaContextProvider: React.FC<
React.PropsWithChildren<{ hideMediaByDefault: boolean }>
> = ({ hideMediaByDefault, children }) => {
const contextValue = useMemo<ContextValue>(
() => ({ hideMediaByDefault }),
[hideMediaByDefault],
);
return (
<SensitiveMediaContext.Provider value={contextValue}>
{children}
</SensitiveMediaContext.Provider>
);
};

View file

@ -241,6 +241,7 @@
"empty_column.list": "У гэтым спісе пакуль што нічога няма. Калі члены лісту апублікуюць новыя запісы, яны з'явяцца тут.",
"empty_column.lists": "Як толькі вы створыце новы спіс ён будзе захоўвацца тут, але пакуль што тут пуста.",
"empty_column.mutes": "Вы яшчэ нікога не ігнаруеце.",
"empty_column.notification_requests": "Чысціня! Тут нічога няма. Калі вы будзеце атрымліваць новыя апавяшчэння, яны будуць з'яўляцца тут у адпаведнасці з вашымі наладамі.",
"empty_column.notifications": "У вас няма ніякіх апавяшчэнняў. Калі іншыя людзі ўзаемадзейнічаюць з вамі, вы ўбачыце гэта тут.",
"empty_column.public": "Тут нічога няма! Апублікуйце што-небудзь, або падпішыцеся на карыстальнікаў з другіх сервераў",
"error.unexpected_crash.explanation": "Гэта старонка не можа быць адлюстравана карэктна з-за памылкі ў нашым кодзе, або праблемы з сумяшчальнасцю браўзера.",
@ -271,6 +272,8 @@
"filter_modal.select_filter.subtitle": "Скарыстайцеся існуючай катэгорыяй або стварыце новую",
"filter_modal.select_filter.title": "Фільтраваць гэты допіс",
"filter_modal.title.status": "Фільтраваць допіс",
"filtered_notifications_banner.pending_requests": "Апавяшчэнні ад {count, plural, =0 {# людзей якіх} one {# чалавека якіх} few {# чалавек якіх} many {# людзей якіх} other {# чалавека якіх}} вы магчыма ведаеце",
"filtered_notifications_banner.title": "Адфільтраваныя апавяшчэнні",
"firehose.all": "Усе",
"firehose.local": "Гэты сервер",
"firehose.remote": "Іншыя серверы",
@ -439,6 +442,10 @@
"notification.reblog": "{name} пашырыў ваш допіс",
"notification.status": "Новы допіс ад {name}",
"notification.update": "Допіс {name} адрэдагаваны",
"notification_requests.accept": "Прыняць",
"notification_requests.dismiss": "Адхіліць",
"notification_requests.notifications_from": "Апавяшчэнні ад {name}",
"notification_requests.title": "Адфільтраваныя апавяшчэнні",
"notifications.clear": "Ачысціць апавяшчэнні",
"notifications.clear_confirmation": "Вы ўпэўнены, што жадаеце назаўсёды сцерці ўсё паведамленні?",
"notifications.column_settings.admin.report": "Новыя скаргі:",
@ -470,6 +477,15 @@
"notifications.permission_denied": "Апавяшчэнні на працоўным стале недаступныя з-за папярэдне адхіленага запыта праў браўзера",
"notifications.permission_denied_alert": "Апавяшчэнні на працоўным стале не могуць быць уключаныя, з-за таго што запыт браўзера быў адхілены",
"notifications.permission_required": "Апавяшчэнні на працоўным стале недаступныя, з-за таго што неабходны дазвол не быў дадзены.",
"notifications.policy.filter_new_accounts.hint": "Створаныя на працягу {days, plural, one {апошняга # дня} few {апошніх # дзён} many {апошніх # дзён} other {апошняй # дня}}",
"notifications.policy.filter_new_accounts_title": "Новыя ўліковыя запісы",
"notifications.policy.filter_not_followers_hint": "Уключаючы людзей, якія падпісаны на вас менш, чым {days, plural, one {# дзень} few {# дні} many {# дзён} other {# дня}}",
"notifications.policy.filter_not_followers_title": "Людзі, якія не падпісаны на вас",
"notifications.policy.filter_not_following_hint": "Пакуль вы не пацвердзіце іх уручную",
"notifications.policy.filter_not_following_title": "Людзі, на якіх вы не падпісаны",
"notifications.policy.filter_private_mentions_hint": "Фільтруецца за выключэннем адказу на вашае згадванне ці калі вы падпісаны на адпраўніка",
"notifications.policy.filter_private_mentions_title": "Непажаданыя асаблівыя згадванні",
"notifications.policy.title": "Адфільтроўваць апавяшчэнні ад…",
"notifications_permission_banner.enable": "Уключыць апавяшчэнні на працоўным стале",
"notifications_permission_banner.how_to_control": "Каб атрымліваць апавяшчэнні, калі Mastodon не адкрыты, уключыце апавяшчэнні працоўнага стала. Вы зможаце дакладна кантраляваць, якія падзеі будуць ствараць апавяшчэнні з дапамогай {icon} кнопкі, як толькі яны будуць уключаны.",
"notifications_permission_banner.title": "Не прапусціце нічога",

View file

@ -272,7 +272,7 @@
"filter_modal.select_filter.subtitle": "Usa una categoria existent o crea'n una de nova",
"filter_modal.select_filter.title": "Filtra aquest tut",
"filter_modal.title.status": "Filtra un tut",
"filtered_notifications_banner.pending_requests": "Notificacions de {count, plural, =0 {no} one {una persona} other {# persones}} que potser coneixeu",
"filtered_notifications_banner.pending_requests": "Notificacions {count, plural, =0 {de ningú} one {d'una persona} other {de # persones}} que potser coneixes",
"filtered_notifications_banner.title": "Notificacions filtrades",
"firehose.all": "Tots",
"firehose.local": "Aquest servidor",
@ -477,13 +477,13 @@
"notifications.permission_denied": "Les notificacions descriptori no estan disponibles perquè prèviament sha denegat el permís al navegador",
"notifications.permission_denied_alert": "No es poden activar les notificacions de l'escriptori perquè abans s'ha denegat el permís del navegador",
"notifications.permission_required": "Les notificacions d'escriptori no estan disponibles perquè el permís requerit no ha estat concedit.",
"notifications.policy.filter_new_accounts.hint": "Creat durant els passats {days, plural, one {un dia} other {# dies}}",
"notifications.policy.filter_new_accounts.hint": "Creat {days, plural, one {ahir} other {durant els # dies passats}}",
"notifications.policy.filter_new_accounts_title": "Comptes nous",
"notifications.policy.filter_not_followers_hint": "Incloent les persones que us segueixen fa menys de {days, plural, one {un dia} other {# dies}}",
"notifications.policy.filter_not_followers_hint": "Incloent les persones que us segueixen fa menys {days, plural, one {d'un dia} other {de # dies}}",
"notifications.policy.filter_not_followers_title": "Persones que no us segueixen",
"notifications.policy.filter_not_following_hint": "Fins que no ho aproveu de forma manual",
"notifications.policy.filter_not_following_title": "Persones que no seguiu",
"notifications.policy.filter_private_mentions_hint": "Filtra-ho excepte si és en resposta a una menció vostra o si seguiu el remitent",
"notifications.policy.filter_private_mentions_hint": "Filtrat si no és que és en resposta a una menció vostra o si seguiu el remitent",
"notifications.policy.filter_private_mentions_title": "Mencions privades no sol·licitades",
"notifications.policy.title": "Filtra les notificacions de…",
"notifications_permission_banner.enable": "Activa les notificacions descriptori",

View file

@ -241,6 +241,7 @@
"empty_column.list": "Does dim yn y rhestr yma eto. Pan fydd aelodau'r rhestr yn cyhoeddi postiad newydd, mi fydd yn ymddangos yma.",
"empty_column.lists": "Nid oes gennych unrhyw restrau eto. Pan fyddwch yn creu un, mi fydd yn ymddangos yma.",
"empty_column.mutes": "Nid ydych wedi tewi unrhyw ddefnyddwyr eto.",
"empty_column.notification_requests": "Dim i boeni amdano! Does dim byd yma. Pan fyddwch yn derbyn hysbysiadau newydd, byddan nhw'n ymddangos yma yn ôl eich gosodiadau.",
"empty_column.notifications": "Nid oes gennych unrhyw hysbysiadau eto. Rhyngweithiwch ag eraill i ddechrau'r sgwrs.",
"empty_column.public": "Does dim byd yma! Ysgrifennwch rywbeth cyhoeddus, neu dilynwch ddefnyddwyr o weinyddion eraill i'w lanw",
"error.unexpected_crash.explanation": "Oherwydd gwall yn ein cod neu oherwydd problem cysondeb porwr, nid oedd y dudalen hon gallu cael ei dangos yn gywir.",
@ -271,6 +272,7 @@
"filter_modal.select_filter.subtitle": "Defnyddiwch gategori sy'n bodoli eisoes neu crëu un newydd",
"filter_modal.select_filter.title": "Hidlo'r postiad hwn",
"filter_modal.title.status": "Hidlo postiad",
"filtered_notifications_banner.title": "Hysbysiadau wedi'u hidlo",
"firehose.all": "Popeth",
"firehose.local": "Gweinydd hwn",
"firehose.remote": "Gweinyddion eraill",
@ -439,6 +441,10 @@
"notification.reblog": "Hybodd {name} eich post",
"notification.status": "{name} newydd ei bostio",
"notification.update": "Golygodd {name} bostiad",
"notification_requests.accept": "Derbyn",
"notification_requests.dismiss": "Cau",
"notification_requests.notifications_from": "Hysbysiadau gan {name}",
"notification_requests.title": "Hysbysiadau wedi'u hidlo",
"notifications.clear": "Clirio hysbysiadau",
"notifications.clear_confirmation": "Ydych chi'n siŵr eich bod am glirio'ch holl hysbysiadau am byth?",
"notifications.column_settings.admin.report": "Adroddiadau newydd:",
@ -470,6 +476,15 @@
"notifications.permission_denied": "Nid oes hysbysiadau bwrdd gwaith ar gael oherwydd cais am ganiatâd porwr a wrthodwyd yn flaenorol",
"notifications.permission_denied_alert": "Nid oes modd galluogi hysbysiadau bwrdd gwaith, gan fod caniatâd porwr wedi'i wrthod o'r blaen",
"notifications.permission_required": "Nid oes hysbysiadau bwrdd gwaith ar gael oherwydd na roddwyd y caniatâd gofynnol.",
"notifications.policy.filter_new_accounts.hint": "Crëwyd o fewn {days, lluosog, un {yr un diwrnod} arall {y # diwrnod}} diwethaf",
"notifications.policy.filter_new_accounts_title": "Cyfrifon newydd",
"notifications.policy.filter_not_followers_hint": "Gan gynnwys pobl sydd wedi bod yn eich dilyn am llai {days, plural, un {nag un diwrnod} arall {na # diwrnod}}",
"notifications.policy.filter_not_followers_title": "Pobl sydd ddim yn eich dilyn",
"notifications.policy.filter_not_following_hint": "Hyd nes i chi eu cymeradwyo â llaw",
"notifications.policy.filter_not_following_title": "Pobl nad ydych yn eu dilyn",
"notifications.policy.filter_private_mentions_hint": "Wedi'i hidlo oni bai ei fod mewn ymateb i'ch crybwylliad eich hun neu os ydych yn dilyn yr anfonwr",
"notifications.policy.filter_private_mentions_title": "Crybwylliadau preifat digymell",
"notifications.policy.title": "Hidlo hysbysiadau gan…",
"notifications_permission_banner.enable": "Galluogi hysbysiadau bwrdd gwaith",
"notifications_permission_banner.how_to_control": "I dderbyn hysbysiadau pan nad yw Mastodon ar agor, galluogwch hysbysiadau bwrdd gwaith. Gallwch reoli'n union pa fathau o ryngweithiadau sy'n cynhyrchu hysbysiadau bwrdd gwaith trwy'r botwm {icon} uchod unwaith y byddan nhw wedi'u galluogi.",
"notifications_permission_banner.title": "Peidiwch â cholli dim",

View file

@ -272,6 +272,7 @@
"filter_modal.select_filter.subtitle": "Vælg en eksisterende kategori eller opret en ny",
"filter_modal.select_filter.title": "Filtrér dette indlæg",
"filter_modal.title.status": "Filtrér et indlæg",
"filtered_notifications_banner.pending_requests": "Notifikationer fra {count, plural, =0 {ingen} one {én person} other {# personer}} du måske kender",
"filtered_notifications_banner.title": "Filtrerede notifikationer",
"firehose.all": "Alle",
"firehose.local": "Denne server",

View file

@ -662,10 +662,11 @@
"status.direct": "Privately mention @{name}",
"status.direct_indicator": "Private mention",
"status.edit": "Edit",
"status.edited": "Edited {date}",
"status.edited": "Last edited {date}",
"status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}",
"status.embed": "Embed",
"status.favourite": "Favorite",
"status.favourites": "{count, plural, one {favorite} other {favorites}}",
"status.filter": "Filter this post",
"status.filtered": "Filtered",
"status.hide": "Hide post",
@ -686,6 +687,7 @@
"status.reblog": "Boost",
"status.reblog_private": "Boost with original visibility",
"status.reblogged_by": "{name} boosted",
"status.reblogs": "{count, plural, one {boost} other {boosts}}",
"status.reblogs.empty": "No one has boosted this post yet. When someone does, they will show up here.",
"status.redraft": "Delete & re-draft",
"status.remove_bookmark": "Remove bookmark",

View file

@ -272,7 +272,7 @@
"filter_modal.select_filter.subtitle": "Usar una categoría existente o crear una nueva",
"filter_modal.select_filter.title": "Filtrar este mensaje",
"filter_modal.title.status": "Filtrar un mensaje",
"filtered_notifications_banner.pending_requests": "Notificaciones de {count, plural, =0 {ninguna cuenta} one {una cuenta} other {# cuentas}} que podrías conocer",
"filtered_notifications_banner.pending_requests": "Notificaciones de {count, plural, =0 {nadie} one {una persona} other {# personas}} que podrías conocer",
"filtered_notifications_banner.title": "Notificaciones filtradas",
"firehose.all": "Todos",
"firehose.local": "Este servidor",

View file

@ -271,6 +271,7 @@
"filter_modal.select_filter.subtitle": "Kasuta olemasolevat kategooriat või loo uus",
"filter_modal.select_filter.title": "Filtreeri seda postitust",
"filter_modal.title.status": "Postituse filtreerimine",
"filtered_notifications_banner.pending_requests": "Teateid {count, plural, =0 {mitte üheltki} one {ühelt} other {#}} inimeselt, keda võid teada",
"firehose.all": "Kõik",
"firehose.local": "See server",
"firehose.remote": "Teised serverid",

View file

@ -325,8 +325,8 @@
"interaction_modal.description.follow": "با حسابی روی ماستودون می‌توانید {name} را برای دریافت فرسته‌هایش در خوراک خانگیتان دنبال کنید.",
"interaction_modal.description.reblog": "با حسابی روی ماستودون می‌توانید این فرسته را با پی‌گیران خودتان هم‌رسانی کنید.",
"interaction_modal.description.reply": "با حسابی روی ماستودون می‌توانید به این فرسته پاسخ دهید.",
"interaction_modal.login.action": "من رو ببر خونه",
"interaction_modal.login.prompt": "دامنه سرور شخصی شما، به عنوان مثال. mastodon.social",
"interaction_modal.login.action": "رفتن به خانه",
"interaction_modal.login.prompt": "دامنهٔ کارساز شخصیتان چون mastodon.social",
"interaction_modal.no_account_yet": "در ماستودون نیست؟",
"interaction_modal.on_another_server": "روی کارسازی دیگر",
"interaction_modal.on_this_server": "روی این کارساز",

View file

@ -241,6 +241,7 @@
"empty_column.list": "Tällä listalla ei ole vielä mitään. Kun tämän listan jäsenet lähettävät uusia julkaisuja, ne näkyvät tässä.",
"empty_column.lists": "Sinulla ei ole vielä yhtään listaa. Kun luot sellaisen, näkyy se tässä.",
"empty_column.mutes": "Et ole mykistänyt vielä yhtään käyttäjää.",
"empty_column.notification_requests": "Kaikki kunnossa! Täällä ei ole mitään. Kun saat uusia ilmoituksia, ne näkyvät täällä asetustesi mukaisesti.",
"empty_column.notifications": "Sinulla ei ole vielä ilmoituksia. Kun keskustelet muille, näet sen täällä.",
"empty_column.public": "Täällä ei ole mitään! Kirjoita jotain julkisesti. Voit myös seurata muiden palvelimien käyttäjiä",
"error.unexpected_crash.explanation": "Sivua ei voida näyttää oikein ohjelmointivirheen tai selaimen yhteensopivuusvajeen vuoksi.",
@ -271,6 +272,8 @@
"filter_modal.select_filter.subtitle": "Käytä olemassa olevaa luokkaa tai luo uusi",
"filter_modal.select_filter.title": "Suodata tämä julkaisu",
"filter_modal.title.status": "Suodata julkaisu",
"filtered_notifications_banner.pending_requests": "Ilmoitukset, {count, plural, =0 {ei tänään} one {1 henkilö} other {# henkilöä}}",
"filtered_notifications_banner.title": "Suodatetut ilmoitukset",
"firehose.all": "Kaikki",
"firehose.local": "Tämä palvelin",
"firehose.remote": "Muut palvelimet",
@ -439,6 +442,10 @@
"notification.reblog": "{name} tehosti julkaisuasi",
"notification.status": "{name} julkaisi juuri",
"notification.update": "{name} muokkasi julkaisua",
"notification_requests.accept": "Hyväksy",
"notification_requests.dismiss": "Hylkää",
"notification_requests.notifications_from": "Ilmoitukset käyttäjältä {name}",
"notification_requests.title": "Suodatetut ilmoitukset",
"notifications.clear": "Tyhjennä ilmoitukset",
"notifications.clear_confirmation": "Haluatko varmasti poistaa kaikki ilmoitukset pysyvästi?",
"notifications.column_settings.admin.report": "Uudet ilmoitukset:",
@ -470,6 +477,15 @@
"notifications.permission_denied": "Työpöytäilmoitukset eivät ole käytettävissä, koska selaimen käyttöoikeuspyyntö on aiemmin evätty",
"notifications.permission_denied_alert": "Työpöytäilmoituksia ei voi ottaa käyttöön, koska selaimen käyttöoikeus on aiemmin estetty",
"notifications.permission_required": "Työpöytäilmoitukset eivät ole käytettävissä, koska siihen tarvittavaa lupaa ei ole myönnetty.",
"notifications.policy.filter_new_accounts.hint": "Luotu {days, plural, one {viime päivänä} other {viimeisenä # päivänä}}",
"notifications.policy.filter_new_accounts_title": "Uudet tilit",
"notifications.policy.filter_not_followers_hint": "Mukaan lukien ne, jotka ovat seuranneet sinua vähemmän kuin {days, plural, one {päivän} other {# päivää}}",
"notifications.policy.filter_not_followers_title": "Henkilöt, jotka eivät seuraa sinua",
"notifications.policy.filter_not_following_hint": "Kunnes hyväksyt ne manuaalisesti",
"notifications.policy.filter_not_following_title": "Henkilöt, joita et seuraa",
"notifications.policy.filter_private_mentions_hint": "Suodatetaan, ellei se vastaa omaan mainintaan tai jos seuraat lähettäjää",
"notifications.policy.filter_private_mentions_title": "Ei-toivotut yksityismaininnat",
"notifications.policy.title": "Suodata ilmoitukset pois kohteesta…",
"notifications_permission_banner.enable": "Ota työpöytäilmoitukset käyttöön",
"notifications_permission_banner.how_to_control": "Saadaksesi ilmoituksia, kun Mastodon ei ole auki, ota työpöytäilmoitukset käyttöön. Voit hallita tarkasti, mistä saat työpöytäilmoituksia kun ilmoitukset on otettu käyttöön yllä olevan {icon}-painikkeen kautta.",
"notifications_permission_banner.title": "Älä anna minkään mennä ohi",

View file

@ -169,6 +169,7 @@
"empty_column.list": "Wala pang laman ang listahang ito. Kapag naglathala ng mga bagong post ang mga miyembro ng listahang ito, makikita iyon dito.",
"empty_column.lists": "Wala ka pang mga listahan. Kapag gumawa ka ng isa, makikita yun dito.",
"explore.search_results": "Mga resulta ng paghahanap",
"filter_modal.select_filter.search": "Hanapin o gumawa",
"firehose.all": "Lahat",
"firehose.local": "Itong serbiro",
"firehose.remote": "Ibang mga serbiro",

View file

@ -272,7 +272,7 @@
"filter_modal.select_filter.subtitle": "Brúka ein verandi bólk ella skapa ein nýggjan",
"filter_modal.select_filter.title": "Filtrera hendan postin",
"filter_modal.title.status": "Filtrera ein post",
"filtered_notifications_banner.pending_requests": "Fráboðanir frá {count, plural, =0 {ongum} one {einum persóni} other {# persónum}}, sum tú møguliga kennir",
"filtered_notifications_banner.pending_requests": "Fráboðanir frá {count, plural, =0 {ongum} one {einum persóni} other {# persónum}}, sum tú kanska kennir",
"filtered_notifications_banner.title": "Sáldaðar fráboðanir",
"firehose.all": "Allar",
"firehose.local": "Hesin ambætarin",

View file

@ -241,6 +241,7 @@
"empty_column.list": "Aínda non hai nada nesta listaxe. Cando as usuarias incluídas na listaxe publiquen mensaxes, amosaranse aquí.",
"empty_column.lists": "Aínda non tes listaxes. Cando crees unha, amosarase aquí.",
"empty_column.mutes": "Aínda non silenciaches a ningúnha usuaria.",
"empty_column.notification_requests": "Todo ben! Nada por aquí. Cando recibas novas notificación aparecerán aquí seguindo o criterio dos teus axustes.",
"empty_column.notifications": "Aínda non tes notificacións. Aparecerán cando outras persoas interactúen contigo.",
"empty_column.public": "Nada por aquí! Escribe algo de xeito público, ou segue de xeito manual usuarias doutros servidores para ir enchéndoo",
"error.unexpected_crash.explanation": "Debido a un erro no noso código ou a unha compatilidade co teu navegador, esta páxina non pode ser amosada correctamente.",
@ -271,6 +272,8 @@
"filter_modal.select_filter.subtitle": "Usar unha categoría existente ou crear unha nova",
"filter_modal.select_filter.title": "Filtrar esta publicación",
"filter_modal.title.status": "Filtrar unha publicación",
"filtered_notifications_banner.pending_requests": "Notificacións de {count, plural, =0 {ninguén} one {unha persoa} other {# persoas}} que poderías coñecer",
"filtered_notifications_banner.title": "Notificacións filtradas",
"firehose.all": "Todo",
"firehose.local": "Este servidor",
"firehose.remote": "Outros servidores",
@ -439,6 +442,10 @@
"notification.reblog": "{name} compartiu a túa publicación",
"notification.status": "{name} publicou",
"notification.update": "{name} editou unha publicación",
"notification_requests.accept": "Aceptar",
"notification_requests.dismiss": "Desbotar",
"notification_requests.notifications_from": "Notificacións de {name}",
"notification_requests.title": "Notificacións filtradas",
"notifications.clear": "Limpar notificacións",
"notifications.clear_confirmation": "Tes a certeza de querer limpar de xeito permanente todas as túas notificacións?",
"notifications.column_settings.admin.report": "Novas denuncias:",
@ -470,6 +477,15 @@
"notifications.permission_denied": "Non se activaron as notificacións de escritorio porque se denegou o permiso",
"notifications.permission_denied_alert": "Non se poden activar as notificacións de escritorio, xa que o permiso para o navegador foi denegado previamente",
"notifications.permission_required": "As notificacións de escritorio non están dispoñibles porque non se concedeu o permiso necesario.",
"notifications.policy.filter_new_accounts.hint": "Creadas desde {days, plural, one {onte} other {fai # días}}",
"notifications.policy.filter_new_accounts_title": "Novas contas",
"notifications.policy.filter_not_followers_hint": "Inclúe a persoas que te seguen desde fai menos de {days, plural, one {1 día} other {# días}}",
"notifications.policy.filter_not_followers_title": "Persoas que non te seguen",
"notifications.policy.filter_not_following_hint": "Ata que as autorices",
"notifications.policy.filter_not_following_title": "Persoas que ti non segues",
"notifications.policy.filter_private_mentions_hint": "Filtradas a non ser que sexa unha resposta á túa propia mención ou se ti segues á remitente",
"notifications.policy.filter_private_mentions_title": "Mencións privadas non solicitadas",
"notifications.policy.title": "Desbotar notificacións de…",
"notifications_permission_banner.enable": "Activar notificacións de escritorio",
"notifications_permission_banner.how_to_control": "Activa as notificacións de escritorio para recibir notificacións mentras Mastodon non está aberto. Podes controlar de xeito preciso o tipo de interaccións que crean as notificacións de escritorio a través da {icon} superior unha vez están activadas.",
"notifications_permission_banner.title": "Non perder nada",

View file

@ -272,7 +272,7 @@
"filter_modal.select_filter.subtitle": "שימוש בקטגורייה קיימת או יצירת אחת חדשה",
"filter_modal.select_filter.title": "סינון ההודעה הזו",
"filter_modal.title.status": "סנן הודעה",
"filtered_notifications_banner.pending_requests": "{count, plural,=0 {אין התראות ממשתמשים ה}one {התראה אחת ממישהו/מישהי ה}other {יש # התראות ממשתמשים }}מוכרים לך",
"filtered_notifications_banner.pending_requests": "{count, plural,=0 {אין התראות ממשתמשים ה}one {התראה אחת ממישהו/מישהי ה}two {יש התראותיים ממשתמשים }other {יש # התראות ממשתמשים }}מוכרים לך",
"filtered_notifications_banner.title": "התראות מסוננות",
"firehose.all": "הכל",
"firehose.local": "שרת זה",

View file

@ -272,7 +272,7 @@
"filter_modal.select_filter.subtitle": "Válassz egy meglévő kategóriát, vagy hozz létre egy újat",
"filter_modal.select_filter.title": "E bejegyzés szűrése",
"filter_modal.title.status": "Egy bejegyzés szűrése",
"filtered_notifications_banner.pending_requests": "Értesítések {count, plural, =0 {0 személytől} one {egy feltehetőleg ismert személytől} other {# feltehetőleg ismert személytől}}",
"filtered_notifications_banner.pending_requests": "Értesítések {count, plural, =0 {nincsenek} one {egy valósztínűleg ismerős személytől} other {# valószínűleg ismerős személytől}}",
"filtered_notifications_banner.title": "Szűrt értesítések",
"firehose.all": "Összes",
"firehose.local": "Ez a kiszolgáló",

View file

@ -272,7 +272,7 @@
"filter_modal.select_filter.subtitle": "Usa una categoria esistente o creane una nuova",
"filter_modal.select_filter.title": "Filtra questo post",
"filter_modal.title.status": "Filtra un post",
"filtered_notifications_banner.pending_requests": "Notifiche da {count, plural, =0 {nessuna persona} one {una persona} other {# persone}} che potresti conoscere",
"filtered_notifications_banner.pending_requests": "Notifiche da {count, plural, =0 {nessuno} one {una persona} other {# persone}} che potresti conoscere",
"filtered_notifications_banner.title": "Notifiche filtrate",
"firehose.all": "Tutto",
"firehose.local": "Questo server",

View file

@ -320,7 +320,7 @@
"mute_modal.hide_notifications": "Tebɣiḍ ad teffreḍ talɣutin n umseqdac-a?",
"mute_modal.indefinite": "Ur yettwasbadu ara",
"navigation_bar.about": "Ɣef",
"navigation_bar.blocks": "Imseqdacen yettusḥebsen",
"navigation_bar.blocks": "Iseqdacen yettusḥebsen",
"navigation_bar.bookmarks": "Ticraḍ",
"navigation_bar.community_timeline": "Tasuddemt tadigant",
"navigation_bar.compose": "Aru tajewwiqt tamaynut",

View file

@ -271,7 +271,7 @@
"filter_modal.select_filter.subtitle": "기존의 카테고리를 사용하거나 새로 하나를 만듧니다",
"filter_modal.select_filter.title": "이 게시물을 필터",
"filter_modal.title.status": "게시물 필터",
"filtered_notifications_banner.pending_requests": "알 수도 있는 {count, plural, =0 {0명} one {한 명} other {# 명}}의 사람들로부터의 알림",
"filtered_notifications_banner.pending_requests": "알 수도 있는 {count, plural, =0 {0 명} one {한 명} other {# 명}}의 사람들로부터의 알림",
"filtered_notifications_banner.title": "걸러진 알림",
"firehose.all": "모두",
"firehose.local": "이 서버",
@ -478,6 +478,7 @@
"notifications.permission_required": "필요한 권한이 승인되지 않아 데스크탑 알림을 사용할 수 없습니다.",
"notifications.policy.filter_new_accounts.hint": "{days, plural, one {하루} other {#일}} 안에 만들어진",
"notifications.policy.filter_new_accounts_title": "새 계정",
"notifications.policy.filter_not_followers_hint": "나를 팔로우 한 지 {days, plural, other {# 일}}이 되지 않은 사람들을 포함",
"notifications.policy.filter_not_followers_title": "나를 팔로우하지 않는 사람들",
"notifications.policy.filter_not_following_hint": "내가 수동으로 승인하기 전까지",
"notifications.policy.filter_not_following_title": "내가 팔로우하지 않는 사람들",

View file

@ -271,6 +271,7 @@
"filter_modal.select_filter.subtitle": "Kulanea una kategoria egzistente o kriya mueva",
"filter_modal.select_filter.title": "Filtra esta publikasyon",
"filter_modal.title.status": "Filtra una publikasyon",
"filtered_notifications_banner.pending_requests": "Avizos de {count, plural, =0 {dingun} one {una persona} other {# personas}} ke puedes koneser",
"filtered_notifications_banner.title": "Avizos filtrados",
"firehose.all": "Todo",
"firehose.local": "Este sirvidor",
@ -442,6 +443,7 @@
"notification.update": "{name} edito una publikasyon",
"notification_requests.accept": "Acheta",
"notification_requests.dismiss": "Kita",
"notification_requests.notifications_from": "Avizos de {name}",
"notification_requests.title": "Avizos filtrados",
"notifications.clear": "Efasa avizos",
"notifications.clear_confirmation": "Estas siguro ke keres permanentemente efasar todos tus avizos?",
@ -474,7 +476,13 @@
"notifications.permission_denied": "Avizos de ensimameza no estan desponivles porke ya se tiene refuzado el permiso",
"notifications.permission_denied_alert": "\"No se pueden kapasitar los avizos de ensimameza, porke ya se tiene refuzado el permiso de navigador",
"notifications.permission_required": "Avizos de ensimameza no estan desponivles porke los nesesarios permisos no tienen sido risividos.",
"notifications.policy.filter_new_accounts.hint": "Kriyadas durante {days, plural, one {el ultimo diya} other {los ultimos # diyas}}",
"notifications.policy.filter_new_accounts_title": "Muevos kuentos",
"notifications.policy.filter_not_followers_title": "Personas ke te no sigen",
"notifications.policy.filter_not_following_hint": "Asta ke las aproves manualmente",
"notifications.policy.filter_not_following_title": "Personas ke no siges",
"notifications.policy.filter_private_mentions_title": "Enmentaduras privadas no solisitadas",
"notifications.policy.title": "Filtra avizos de…",
"notifications_permission_banner.enable": "Kapasita avizos de ensimameza",
"notifications_permission_banner.how_to_control": "Para risivir avizos kuando Mastodon no esta avierto, kapasita avizos de ensimameza. Puedes kontrolar presizamente kualos tipos de enteraksiones djeneren avizos de ensimameza kon el boton {icon} arriva kuando esten kapasitadas.",
"notifications_permission_banner.title": "Nunkua te piedres niente",

View file

@ -439,6 +439,10 @@
"notification.reblog": "{name} pakėlė tavo įrašą",
"notification.status": "{name} ką tik paskelbė",
"notification.update": "{name} redagavo įrašą",
"notification_requests.accept": "Priimti",
"notification_requests.dismiss": "Atmesti",
"notification_requests.notifications_from": "Pranešimai iš {name}",
"notification_requests.title": "Filtruojami pranešimai",
"notifications.clear": "Išvalyti pranešimus",
"notifications.clear_confirmation": "Ar tikrai nori visam laikui išvalyti visus pranešimus?",
"notifications.column_settings.admin.report": "Naujos ataskaitos:",
@ -470,6 +474,12 @@
"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_required": "Darbalaukio pranešimai nepasiekiami, nes nebuvo suteiktas reikiamas leidimas.",
"notifications.policy.filter_new_accounts.hint": "Sukurta per {days, plural, one {vieną dieną} few {# dienas} many {# dienos} other {# dienų}}",
"notifications.policy.filter_new_accounts_title": "Naujos paskyros",
"notifications.policy.filter_not_following_hint": "Kol jų nepatvirtinsi rankiniu būdu",
"notifications.policy.filter_not_following_title": "Žmonių, kuriuos neseki",
"notifications.policy.filter_private_mentions_title": "Nepageidaujami privatūs paminėjimai",
"notifications.policy.title": "Filtruoti pranešimus iš…",
"notifications_permission_banner.enable": "Įjungti darbalaukio pranešimus",
"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 nepraleisk",

View file

@ -272,7 +272,7 @@
"filter_modal.select_filter.subtitle": "Een bestaande categorie gebruiken of een nieuwe aanmaken",
"filter_modal.select_filter.title": "Dit bericht filteren",
"filter_modal.title.status": "Een bericht filteren",
"filtered_notifications_banner.pending_requests": "Meldingen van {count, plural, =0 {no} one {één persoon} other {# mensen}} die je misschien kent",
"filtered_notifications_banner.pending_requests": "Meldingen van {count, plural, =0 {niemand} one {één persoon} other {# mensen}} die je misschien kent",
"filtered_notifications_banner.title": "Gefilterde meldingen",
"firehose.all": "Alles",
"firehose.local": "Deze server",

View file

@ -241,6 +241,7 @@
"empty_column.list": "Det er ingenting i denne lista enno. Når medlemer av denne lista legg ut nye statusar, så dukkar dei opp her.",
"empty_column.lists": "Du har ingen lister enno. Når du lagar ei, så dukkar ho opp her.",
"empty_column.mutes": "Du har ikkje målbunde nokon enno.",
"empty_column.notification_requests": "Ferdig! Her er det ingenting. Når du får nye varsel, kjem dei opp her slik du har valt.",
"empty_column.notifications": "Du har ingen varsel enno. Kommuniser med andre for å starte samtalen.",
"empty_column.public": "Det er ingenting her! Skriv noko offentleg, eller følg brukarar frå andre tenarar manuelt for å fylle det opp",
"error.unexpected_crash.explanation": "På grunn av eit nettlesarkompatibilitetsproblem eller ein feil i koden vår, kunne ikkje denne sida bli vist slik den skal.",
@ -271,6 +272,8 @@
"filter_modal.select_filter.subtitle": "Bruk ein eksisterande kategori eller opprett ein ny",
"filter_modal.select_filter.title": "Filtrer dette innlegget",
"filter_modal.title.status": "Filtrer eit innlegg",
"filtered_notifications_banner.pending_requests": "Varsel frå {count, plural, =0 {ingen} one {ein person} other {# folk}} du kanskje kjenner",
"filtered_notifications_banner.title": "Filtrerte varslingar",
"firehose.all": "Alle",
"firehose.local": "Denne tenaren",
"firehose.remote": "Andre tenarar",
@ -439,6 +442,10 @@
"notification.reblog": "{name} framheva innlegget ditt",
"notification.status": "{name} la nettopp ut",
"notification.update": "{name} redigerte eit innlegg",
"notification_requests.accept": "Godkjenn",
"notification_requests.dismiss": "Avvis",
"notification_requests.notifications_from": "Varslingar frå {name}",
"notification_requests.title": "Filtrerte varslingar",
"notifications.clear": "Tøm varsel",
"notifications.clear_confirmation": "Er du sikker på at du vil fjerna alle varsla dine for alltid?",
"notifications.column_settings.admin.report": "Nye rapportar:",
@ -470,6 +477,15 @@
"notifications.permission_denied": "Skrivebordsvarsel er ikkje tilgjengelege på grunn av at nettlesaren tidlegare ikkje har fått naudsynte rettar til å vise dei",
"notifications.permission_denied_alert": "Sidan nettlesaren tidlegare har blitt nekta naudsynte rettar, kan ikkje skrivebordsvarsel aktiverast",
"notifications.permission_required": "Skrivebordsvarsel er utilgjengelege fordi naudsynte rettar ikkje er gitt.",
"notifications.policy.filter_new_accounts.hint": "Skrive siste {days, plural, one {dag} other {# dagar}}",
"notifications.policy.filter_new_accounts_title": "Nye brukarkontoar",
"notifications.policy.filter_not_followers_hint": "Inkludert folk som har fylgt deg mindre enn {days, plural, one {ein dag} other {# dagar}}",
"notifications.policy.filter_not_followers_title": "Folk som ikkje fylgjer deg",
"notifications.policy.filter_not_following_hint": "Til du godkjenner dei manuelt",
"notifications.policy.filter_not_following_title": "Folk du ikkje fylgjer",
"notifications.policy.filter_private_mentions_hint": "Filtrert viss det ikkje er eit svar på dine eigne nemningar eller viss du fylgjer avsendaren",
"notifications.policy.filter_private_mentions_title": "Masseutsende private nemningar",
"notifications.policy.title": "Filtrer ut varslingar frå…",
"notifications_permission_banner.enable": "Skru på skrivebordsvarsel",
"notifications_permission_banner.how_to_control": "Aktiver skrivebordsvarsel for å få varsel når Mastodon ikkje er open. Du kan nøye bestemme kva samhandlingar som skal føre til skrivebordsvarsel gjennom {icon}-knappen ovanfor etter at varsel er aktivert.",
"notifications_permission_banner.title": "Gå aldri glipp av noko",

View file

@ -272,6 +272,7 @@
"filter_modal.select_filter.subtitle": "Utilize uma categoria existente ou crie uma nova",
"filter_modal.select_filter.title": "Filtrar esta publicação",
"filter_modal.title.status": "Filtrar uma publicação",
"filtered_notifications_banner.pending_requests": "Notificações de {count, plural, =0 {ninguém} one {uma pessoa} other {# pessoas}} que talvez conheça",
"filtered_notifications_banner.title": "Notificações filtradas",
"firehose.all": "Todas",
"firehose.local": "Este servidor",
@ -476,7 +477,9 @@
"notifications.permission_denied": "Notificações no ambiente de trabalho não estão disponíveis porque a permissão, solicitada pelo navegador, foi recusada anteriormente",
"notifications.permission_denied_alert": "Notificações no ambiente de trabalho não podem ser ativadas, pois a permissão do navegador foi recusada anteriormente",
"notifications.permission_required": "Notificações no ambiente de trabalho não estão disponíveis porque a permissão necessária não foi concedida.",
"notifications.policy.filter_new_accounts.hint": "Criada nos últimos {days, plural, one {um dia} other {# dias}}",
"notifications.policy.filter_new_accounts_title": "Novas contas",
"notifications.policy.filter_not_followers_hint": "Incluindo pessoas que o seguem há menos de {days, plural, one {um dia} other {# dias}}",
"notifications.policy.filter_not_followers_title": "Pessoas não te seguem",
"notifications.policy.filter_not_following_hint": "Até que você os aprove manualmente",
"notifications.policy.filter_not_following_title": "Pessoas que você não segue",

View file

@ -271,6 +271,7 @@
"filter_modal.select_filter.subtitle": "Použite existujúcu kategóriu alebo vytvorte novú",
"filter_modal.select_filter.title": "Filtrovanie tohto príspevku",
"filter_modal.title.status": "Filtrovanie príspevku",
"filtered_notifications_banner.pending_requests": "Oboznámenia od {count, plural, =0 {nikoho} one {jedného človeka} other {# ľudí}} čo môžeš poznať",
"firehose.all": "Všetko",
"firehose.local": "Tento server",
"firehose.remote": "Ostatné servery",
@ -439,6 +440,9 @@
"notification.reblog": "{name} zdieľa váš príspevok",
"notification.status": "{name} uverejňuje niečo nové",
"notification.update": "{name} upravuje príspevok",
"notification_requests.accept": "Prijať",
"notification_requests.notifications_from": "Oboznámenia od {name}",
"notification_requests.title": "Filtrované oboznámenia",
"notifications.clear": "Vyčistiť upozornenia",
"notifications.clear_confirmation": "Určite chcete nenávratne odstrániť všetky svoje upozornenia?",
"notifications.column_settings.admin.report": "Nové hlásenia:",
@ -470,6 +474,9 @@
"notifications.permission_denied": "Upozornenia na ploche sú nedostupné pre už skôr zamietnutú požiadavku prehliadača",
"notifications.permission_denied_alert": "Upozornenia na ploche nemôžu byť zapnuté, pretože požiadavka prehliadača bola už skôr zamietnutá",
"notifications.permission_required": "Upozornenia na ploche sú nedostupné, pretože neboli udelené potrebné povolenia.",
"notifications.policy.filter_new_accounts_title": "Nové účty",
"notifications.policy.filter_not_followers_title": "Ľudia, ktorí ťa nenasledujú",
"notifications.policy.filter_not_following_title": "Ľudia, ktorých nenasleduješ",
"notifications_permission_banner.enable": "Povoliť upozornenia na ploche",
"notifications_permission_banner.how_to_control": "Ak chcete dostávať upozornenia, keď Mastodon nie je otvorený, povoľte upozornenia na ploche. Po ich zapnutí môžete presne kontrolovať, ktoré typy interakcií generujú upozornenia na ploche, a to prostredníctvom tlačidla {icon} vyššie.",
"notifications_permission_banner.title": "Nenechajte si nič ujsť",

View file

@ -272,6 +272,7 @@
"filter_modal.select_filter.subtitle": "Uporabite obstoječo kategorijo ali ustvarite novo",
"filter_modal.select_filter.title": "Filtriraj to objavo",
"filter_modal.title.status": "Filtrirajte objavo",
"filtered_notifications_banner.pending_requests": "Obvestila od {count, plural, =0 {nikogar, ki bi ga} one {# človeka, ki bi ga} two {# ljudi, ki bi ju} few {# ljudi, ki bi jih} other {# ljudi, ki bi jih}} lahko poznali",
"filtered_notifications_banner.title": "Filtrirana obvestila",
"firehose.all": "Vse",
"firehose.local": "Ta strežnik",
@ -476,7 +477,9 @@
"notifications.permission_denied": "Namizna obvestila niso na voljo zaradi poprej zavrnjene zahteve dovoljenja brskalnika.",
"notifications.permission_denied_alert": "Namiznih obvestil ni mogoče omogočiti, ker je bilo dovoljenje brskalnika že prej zavrnjeno",
"notifications.permission_required": "Namizna obvestila niso na voljo, ker zahtevano dovoljenje ni bilo podeljeno.",
"notifications.policy.filter_new_accounts.hint": "Ustvarjen v {days, plural, one {zadnjem # dnevu} two {zadnjih # dnevih} few {zadnjih # dnevih} other {zadnjih # dnevih}}",
"notifications.policy.filter_new_accounts_title": "Novi računi",
"notifications.policy.filter_not_followers_hint": "Vključujoč ljudi, ki vam sledijo manj kot {days, plural, one {# dan} two {# dneva} few {# dni} other {# dni}}",
"notifications.policy.filter_not_followers_title": "Ljudje, ki vam ne sledijo",
"notifications.policy.filter_not_following_hint": "Dokler jih ročno ne odobrite",
"notifications.policy.filter_not_following_title": "Ljudje, ki jim ne sledite",

View file

@ -241,6 +241,7 @@
"empty_column.list": "Në këtë listë ende ska gjë. Kur anëtarë të kësaj liste postojnë gjendje të reja, ato do të shfaqen këtu.",
"empty_column.lists": "Ende skeni ndonjë listë. Kur të krijoni një të tillë, do të duket këtu.",
"empty_column.mutes": "Skeni heshtuar ende ndonjë përdorues.",
"empty_column.notification_requests": "Gjithçka si duhet! Ska çbëhet këtu. Kur merrni njoftime të reja, do të shfaqen këtu, në përputhje me rregullimet tuaja.",
"empty_column.notifications": "Ende skeni ndonjë njoftim. Ndërveproni me të tjerët që të nisë biseda.",
"empty_column.public": "Ska gjë këtu! Shkruani diçka publikisht, ose ndiqni dorazi përdorues prej instancash të tjera, që kjo të mbushet",
"error.unexpected_crash.explanation": "Për shkak të një të mete në kodin tonë ose të një problemi përputhshmërie të shfletuesit, kjo faqe smund të shfaqet saktë.",
@ -271,6 +272,7 @@
"filter_modal.select_filter.subtitle": "Përdorni një kategori ekzistuese, ose krijoni një të re",
"filter_modal.select_filter.title": "Filtroje këtë postim",
"filter_modal.title.status": "Filtroni një postim",
"filtered_notifications_banner.title": "Njoftime të filtruar",
"firehose.all": "Krejt",
"firehose.local": "Këtë shërbyes",
"firehose.remote": "Shërbyes të tjerë",
@ -439,6 +441,10 @@
"notification.reblog": "{name} përforcoi mesazhin tuaj",
"notification.status": "{name} sapo postoi",
"notification.update": "{name} përpunoi një postim",
"notification_requests.accept": "Pranoje",
"notification_requests.dismiss": "Hidhe tej",
"notification_requests.notifications_from": "Njoftime prej {name}",
"notification_requests.title": "Njoftime të filtruar",
"notifications.clear": "Spastroji njoftimet",
"notifications.clear_confirmation": "Jeni i sigurt se doni të spastrohen përgjithmonë krejt njoftimet tuaja?",
"notifications.column_settings.admin.report": "Raportime të reja:",
@ -470,6 +476,13 @@
"notifications.permission_denied": "Smerren dot njoftime në desktop, ngaqë më herët shfletuesit i janë mohuar lejet për këtë",
"notifications.permission_denied_alert": "Smund të aktivizohen njoftimet në desktop, ngaqë lejet e shfletuesit për këtë janë mohuar më herët",
"notifications.permission_required": "Smerren dot njoftime desktop, ngaqë sështë akorduar leja përkatëse.",
"notifications.policy.filter_new_accounts_title": "Llogari të reja",
"notifications.policy.filter_not_followers_title": "Persona që sju ndjekin",
"notifications.policy.filter_not_following_hint": "Deri sa ti miratoni dorazi",
"notifications.policy.filter_not_following_title": "Persona që si ndiqni",
"notifications.policy.filter_private_mentions_hint": "Filtruar, hiq rastin nëse gjendet te përgjigje ndaj përmendjes tuaj, ose nëse dërguesin e ndiqni",
"notifications.policy.filter_private_mentions_title": "Përmendje private të pakërkuara",
"notifications.policy.title": "Filtroni njoftime nga…",
"notifications_permission_banner.enable": "Aktivizo njoftime në desktop",
"notifications_permission_banner.how_to_control": "Për të marrë njoftime, kur Mastodon-i sështë i hapur, aktivizoni njoftime në desktop. Përmes butoni {icon} më sipër, mund të kontrolloni me përpikëri cilat lloje ndërveprimesh prodhojnë njoftime në desktop, pasi të jenë aktivizuar.",
"notifications_permission_banner.title": "Mos tju shpëtojë gjë",

View file

@ -241,6 +241,7 @@
"empty_column.list": "U ovoj listi još nema ničega. Kada članovi ove liste objave nešto novo, pojaviće se ovde.",
"empty_column.lists": "Još uvek nemate nijednu listu. Kada napravite jednu, ona će se pojaviti ovde.",
"empty_column.mutes": "Još uvek ne ignorišete nijednog korisnika.",
"empty_column.notification_requests": "Sve je čisto! Ovde nema ničega. Kada dobijete nova obaveštenja, ona će se pojaviti ovde u skladu sa vašim podešavanjima.",
"empty_column.notifications": "Još uvek nemate nikakva obaveštenja. Kada drugi ljudi budu u interakciji sa vama, videćete to ovde.",
"empty_column.public": "Ovde nema ničega! Napišite nešto javno ili ručno pratite korisnike sa drugih servera da biste ovo popunili",
"error.unexpected_crash.explanation": "Zbog greške u našem kodu ili problema sa kompatibilnošću pregledača, ova stranica se nije mogla pravilno prikazati.",
@ -271,6 +272,8 @@
"filter_modal.select_filter.subtitle": "Koristite postojeću kategoriju ili kreirajte novu",
"filter_modal.select_filter.title": "Filtriraj ovu objavu",
"filter_modal.title.status": "Filtriraj objavu",
"filtered_notifications_banner.pending_requests": "Obaveštenja od {count, plural, =0 {nikoga koga možda poznajete} one {# osobe koju možda poznajete} few {# osobe koje možda poznajete} other {# osoba koje možda poznajete}}",
"filtered_notifications_banner.title": "Filtrirana obaveštenja",
"firehose.all": "Sve",
"firehose.local": "Ovaj server",
"firehose.remote": "Ostali serveri",
@ -439,6 +442,10 @@
"notification.reblog": "{name} je podržao vašu objavu",
"notification.status": "{name} je upravo objavio",
"notification.update": "{name} je uredio objavu",
"notification_requests.accept": "Prihvati",
"notification_requests.dismiss": "Odbaci",
"notification_requests.notifications_from": "Obaveštenja od {name}",
"notification_requests.title": "Filtrirana obaveštenja",
"notifications.clear": "Obriši obaveštenja",
"notifications.clear_confirmation": "Da li ste sigurni da želite trajno da obrišete sva vaša obaveštenja?",
"notifications.column_settings.admin.report": "Nove prijave:",
@ -470,6 +477,15 @@
"notifications.permission_denied": "Obaveštenja na radnoj površini nisu dostupna zbog prethodno odbijenog zahteva za dozvolu pregledača",
"notifications.permission_denied_alert": "Obaveštenja na radnoj površini ne mogu biti omogućena, jer je dozvola pregledača ranije bila odbijena",
"notifications.permission_required": "Obaveštenja na radnoj površini nisu dostupna jer potrebna dozvola nije dodeljena.",
"notifications.policy.filter_new_accounts.hint": "Kreirano {days, plural, one {u poslednjeg # dana} few {u poslednja # dana} other {u poslednjih # dana}}",
"notifications.policy.filter_new_accounts_title": "Novi nalozi",
"notifications.policy.filter_not_followers_hint": "Uključujući ljude koji su vas pratili manje od {days, plural, one {# dana} few {# dana} other {# dana}}",
"notifications.policy.filter_not_followers_title": "Ljudi koji vas ne prate",
"notifications.policy.filter_not_following_hint": "Dok ih ručno ne odobrite",
"notifications.policy.filter_not_following_title": "Ljudi koje ne pratite",
"notifications.policy.filter_private_mentions_hint": "Filtrirano osim ako je odgovor na vaše pominjanje ili ako pratite pošiljaoca",
"notifications.policy.filter_private_mentions_title": "Neželjena privatna pominjanja",
"notifications.policy.title": "Filtriraj obaveštenja od…",
"notifications_permission_banner.enable": "Omogućiti obaveštenja na radnoj površini",
"notifications_permission_banner.how_to_control": "Da biste primali obaveštenja kada Mastodon nije otvoren, omogućite obaveštenja na radnoj površini. Kada su obaveštenja na radnoj površini omogućena vrste interakcija koje ona generišu mogu se podešavati pomoću dugmeta {icon}.",
"notifications_permission_banner.title": "Nikada ništa ne propustite",

View file

@ -241,6 +241,7 @@
"empty_column.list": "У овој листи још нема ничега. Када чланови ове листе објаве нешто ново, појавиће се овде.",
"empty_column.lists": "Још увек немате ниједну листу. Када направите једну, она ће се појавити овде.",
"empty_column.mutes": "Још увек не игноришете ниједног корисника.",
"empty_column.notification_requests": "Све је чисто! Овде нема ничега. Када добијете нова обавештења, она ће се појавити овде у складу са вашим подешавањима.",
"empty_column.notifications": "Још увек немате никаква обавештења. Када други људи буду у интеракцији са вама, видећете то овде.",
"empty_column.public": "Овде нема ничега! Напишите нешто јавно или ручно пратите кориснике са других сервера да бисте ово попунили",
"error.unexpected_crash.explanation": "Због грешке у нашем коду или проблема са компатибилношћу прегледача, ова страница се није могла правилно приказати.",
@ -271,6 +272,8 @@
"filter_modal.select_filter.subtitle": "Користите постојећу категорију или креирајте нову",
"filter_modal.select_filter.title": "Филтрирај ову објаву",
"filter_modal.title.status": "Филтрирај објаву",
"filtered_notifications_banner.pending_requests": "Обавештења од {count, plural, =0 {никога кога можда познајете} one {# особе коју можда познајете} few {# особе које можда познајете} other {# особа које можда познајете}}",
"filtered_notifications_banner.title": "Филтрирана обавештења",
"firehose.all": "Све",
"firehose.local": "Овај сервер",
"firehose.remote": "Остали сервери",
@ -439,6 +442,10 @@
"notification.reblog": "{name} је подржао вашу објаву",
"notification.status": "{name} је управо објавио",
"notification.update": "{name} је уредио објаву",
"notification_requests.accept": "Прихвати",
"notification_requests.dismiss": "Одбаци",
"notification_requests.notifications_from": "Обавештења од {name}",
"notification_requests.title": "Филтрирана обавештења",
"notifications.clear": "Обриши обавештења",
"notifications.clear_confirmation": "Да ли сте сигурни да желите трајно да обришете сва ваша обавештења?",
"notifications.column_settings.admin.report": "Нове пријаве:",
@ -470,6 +477,15 @@
"notifications.permission_denied": "Обавештења на радној површини нису доступна због претходно одбијеног захтева за дозволу прегледача",
"notifications.permission_denied_alert": "Обавештења на радној површини не могу бити омогућена, јер је дозвола прегледача раније била одбијена",
"notifications.permission_required": "Обавештења на радној површини нису доступна јер потребна дозвола није додељена.",
"notifications.policy.filter_new_accounts.hint": "Креирано {days, plural, one {у последњег # дана} few {у последња # дана} other {у последњих # дана}}",
"notifications.policy.filter_new_accounts_title": "Нови налози",
"notifications.policy.filter_not_followers_hint": "Укључујући људе који су вас пратили мање од {days, plural, one {# дана} few {# дана} other {# дана}}",
"notifications.policy.filter_not_followers_title": "Људи који вас не прате",
"notifications.policy.filter_not_following_hint": "Док их ручно не одобрите",
"notifications.policy.filter_not_following_title": "Људи које не пратите",
"notifications.policy.filter_private_mentions_hint": "Филтрирано осим ако је одговор на ваше помињање или ако пратите пошиљаоца",
"notifications.policy.filter_private_mentions_title": "Нежељена приватна помињања",
"notifications.policy.title": "Филтрирај обавештења од…",
"notifications_permission_banner.enable": "Омогућити обавештења на радној површини",
"notifications_permission_banner.how_to_control": "Да бисте примали обавештења када Mastodon није отворен, омогућите обавештења на радној површини. Kада су обавештења на радној површини омогућена врсте интеракција које она генеришу могу се подешавати помоћу дугмета {icon}.",
"notifications_permission_banner.title": "Никада ништа не пропустите",

View file

@ -241,6 +241,7 @@
"empty_column.list": "ยังไม่มีสิ่งใดในรายการนี้ เมื่อสมาชิกของรายการนี้โพสต์โพสต์ใหม่ โพสต์จะปรากฏที่นี่",
"empty_column.lists": "คุณยังไม่มีรายการใด ๆ เมื่อคุณสร้างรายการ รายการจะปรากฏที่นี่",
"empty_column.mutes": "คุณยังไม่ได้ซ่อนผู้ใช้ใด ๆ",
"empty_column.notification_requests": "โล่งทั้งหมด! ไม่มีสิ่งใดที่นี่ เมื่อคุณได้รับการแจ้งเตือนใหม่ การแจ้งเตือนจะปรากฏที่นี่ตามการตั้งค่าของคุณ",
"empty_column.notifications": "คุณยังไม่มีการแจ้งเตือนใด ๆ เมื่อผู้คนอื่น ๆ โต้ตอบกับคุณ คุณจะเห็นการแจ้งเตือนที่นี่",
"empty_column.public": "ไม่มีสิ่งใดที่นี่! เขียนบางอย่างเป็นสาธารณะ หรือติดตามผู้ใช้จากเซิร์ฟเวอร์อื่น ๆ ด้วยตนเองเพื่อเติมเส้นเวลาให้เต็ม",
"error.unexpected_crash.explanation": "เนื่องจากข้อบกพร่องในโค้ดของเราหรือปัญหาความเข้ากันได้ของเบราว์เซอร์ จึงไม่สามารถแสดงหน้านี้ได้อย่างถูกต้อง",
@ -271,6 +272,7 @@
"filter_modal.select_filter.subtitle": "ใช้หมวดหมู่ที่มีอยู่หรือสร้างหมวดหมู่ใหม่",
"filter_modal.select_filter.title": "กรองโพสต์นี้",
"filter_modal.title.status": "กรองโพสต์",
"filtered_notifications_banner.pending_requests": "การแจ้งเตือนจาก {count, plural, =0 {ไม่มีใคร} other {# คน}} ที่คุณอาจรู้จัก",
"filtered_notifications_banner.title": "การแจ้งเตือนที่กรองอยู่",
"firehose.all": "ทั้งหมด",
"firehose.local": "เซิร์ฟเวอร์นี้",

View file

@ -241,6 +241,7 @@
"empty_column.list": "Henüz bu listede bir şey yok. Bu listenin üyeleri bir şey paylaşığında burada gözükecek.",
"empty_column.lists": "Henüz listen yok. Liste oluşturduğunda burada görünür.",
"empty_column.mutes": "Henüz bir kullanıcıyı sessize almadınız.",
"empty_column.notification_requests": "Hepsi tamam! Burada yeni bir şey yok. Yeni bildirim aldığınızda, ayarlarınıza göre burada görüntülenecekler.",
"empty_column.notifications": "Henüz bildiriminiz yok. Sohbete başlamak için başkalarıyla etkileşim kurun.",
"empty_column.public": "Burada hiçbir şey yok! Herkese açık bir şeyler yazın veya burayı doldurmak için diğer sunuculardaki kullanıcıları takip edin",
"error.unexpected_crash.explanation": "Bizim kodumuzdaki bir hatadan ya da tarayıcı uyumluluk sorunundan dolayı, bu sayfa düzgün görüntülenemedi.",
@ -271,6 +272,8 @@
"filter_modal.select_filter.subtitle": "Mevcut bir kategoriyi kullan veya yeni bir tane oluştur",
"filter_modal.select_filter.title": "Bu gönderiyi süzgeçle",
"filter_modal.title.status": "Bir gönderi süzgeçle",
"filtered_notifications_banner.pending_requests": "Bildiğiniz {count, plural, =0 {hiç kimseden} one {bir kişiden} other {# kişiden}} bildirim",
"filtered_notifications_banner.title": "Filtrelenmiş bildirimler",
"firehose.all": "Tümü",
"firehose.local": "Bu sunucu",
"firehose.remote": "Diğer sunucular",
@ -356,7 +359,7 @@
"keyboard_shortcuts.hotkey": "Kısayol tuşu",
"keyboard_shortcuts.legend": "Bu efsaneyi görüntülemek için",
"keyboard_shortcuts.local": "Yerel akışı aç",
"keyboard_shortcuts.mention": "Yazandan bahsetmek için",
"keyboard_shortcuts.mention": "Yazana değinmek için",
"keyboard_shortcuts.muted": "Sessize alınmış kullanıcı listesini açmak için",
"keyboard_shortcuts.my_profile": "Profilinizi açmak için",
"keyboard_shortcuts.notifications": "Bildirimler sütununu açmak için",
@ -433,12 +436,16 @@
"notification.favourite": "{name} gönderinizi beğendi",
"notification.follow": "{name} seni takip etti",
"notification.follow_request": "{name} size takip isteği gönderdi",
"notification.mention": "{name} senden bahsetti",
"notification.mention": "{name} sana değindi",
"notification.own_poll": "Anketiniz sona erdi",
"notification.poll": "Oy verdiğiniz bir anket sona erdi",
"notification.reblog": "{name} gönderini yeniden paylaştı",
"notification.status": "{name} az önce gönderdi",
"notification.update": "{name} bir gönderiyi düzenledi",
"notification_requests.accept": "Onayla",
"notification_requests.dismiss": "Yoksay",
"notification_requests.notifications_from": "{name} bildirimleri",
"notification_requests.title": "Filtrelenmiş bildirimler",
"notifications.clear": "Bildirimleri temizle",
"notifications.clear_confirmation": "Tüm bildirimlerinizi kalıcı olarak temizlemek ister misiniz?",
"notifications.column_settings.admin.report": "Yeni bildirimler:",
@ -470,6 +477,15 @@
"notifications.permission_denied": "Daha önce reddedilen tarayıcı izinleri isteği nedeniyle masaüstü bildirimleri kullanılamıyor",
"notifications.permission_denied_alert": "Tarayıcı izni daha önce reddedildiğinden, masaüstü bildirimleri etkinleştirilemez",
"notifications.permission_required": "Masaüstü bildirimleri, gereksinim duyulan izin verilmediği için mevcut değil.",
"notifications.policy.filter_new_accounts.hint": "Son {days, plural, one {bir gün} other {# gün}}de oluşturuldu",
"notifications.policy.filter_new_accounts_title": "Yeni hesaplar",
"notifications.policy.filter_not_followers_hint": "Sizi {days, plural, one {bir gün} other {# gün}}den azdır takip eden kişileri de içeriyor",
"notifications.policy.filter_not_followers_title": "Seni takip etmeyen kullanıcılar",
"notifications.policy.filter_not_following_hint": "Onları manuel olarak onaylayana kadar",
"notifications.policy.filter_not_following_title": "Takip etmediğin kullanıcılar",
"notifications.policy.filter_private_mentions_hint": "Kendi değinmenize yanıt veya takip ettiğiniz kullanıcıdan değilse filtrelenir",
"notifications.policy.filter_private_mentions_title": "İstenmeyen özel değinmeler",
"notifications.policy.title": "Şundan bildirimleri filtrele…",
"notifications_permission_banner.enable": "Masaüstü bildirimlerini etkinleştir",
"notifications_permission_banner.how_to_control": "Mastodon açık olmadığında bildirim almak için masaüstü bildirimlerini etkinleştirin. Etkinleştirildikten sonra yukarıdaki {icon} düğmesini kullanarak hangi etkileşim türlerinin masaüstü bildirimleri oluşturduğunu tam olarak kontrol edebilirsiniz.",
"notifications_permission_banner.title": "Hiçbir şeyi kaçırmayın",

View file

@ -241,6 +241,7 @@
"empty_column.list": "Chưa có tút. Khi những người trong danh sách này đăng tút mới, chúng sẽ xuất hiện ở đây.",
"empty_column.lists": "Bạn chưa tạo danh sách nào.",
"empty_column.mutes": "Bạn chưa ẩn bất kỳ ai.",
"empty_column.notification_requests": "Sạch sẽ! Không còn gì ở đây. Khi bạn nhận được thông báo mới, chúng sẽ xuất hiện ở đây theo cài đặt của bạn.",
"empty_column.notifications": "Bạn chưa có thông báo nào. Hãy thử theo dõi hoặc nhắn riêng cho ai đó.",
"empty_column.public": "Trống trơn! Bạn hãy viết gì đó hoặc bắt đầu theo dõi những người khác",
"error.unexpected_crash.explanation": "Trang này có thể không hiển thị chính xác do lỗi lập trình Mastodon hoặc vấn đề tương thích trình duyệt.",
@ -271,6 +272,8 @@
"filter_modal.select_filter.subtitle": "Sử dụng một danh mục hiện có hoặc tạo một danh mục mới",
"filter_modal.select_filter.title": "Lọc tút này",
"filter_modal.title.status": "Lọc một tút",
"filtered_notifications_banner.pending_requests": "Thông báo từ {count, plural, =0 {không ai} other {# người}} bạn có thể biết",
"filtered_notifications_banner.title": "Thông báo đã lọc",
"firehose.all": "Toàn bộ",
"firehose.local": "Máy chủ này",
"firehose.remote": "Máy chủ khác",
@ -361,7 +364,7 @@
"keyboard_shortcuts.my_profile": "mở hồ sơ của bạn",
"keyboard_shortcuts.notifications": "mở thông báo",
"keyboard_shortcuts.open_media": "mở ảnh hoặc video",
"keyboard_shortcuts.pinned": "Open pinned posts list",
"keyboard_shortcuts.pinned": "mở những tút đã ghim",
"keyboard_shortcuts.profile": "mở trang của người đăng tút",
"keyboard_shortcuts.reply": "trả lời",
"keyboard_shortcuts.requests": "mở danh sách yêu cầu theo dõi",
@ -439,6 +442,10 @@
"notification.reblog": "{name} đăng lại tút của bạn",
"notification.status": "{name} đăng tút mới",
"notification.update": "{name} đã sửa tút",
"notification_requests.accept": "Chấp nhận",
"notification_requests.dismiss": "Bỏ qua",
"notification_requests.notifications_from": "Thông báo từ {name}",
"notification_requests.title": "Thông báo đã lọc",
"notifications.clear": "Xóa hết thông báo",
"notifications.clear_confirmation": "Bạn thật sự muốn xóa vĩnh viễn tất cả thông báo của mình?",
"notifications.column_settings.admin.report": "Báo cáo mới:",
@ -470,6 +477,15 @@
"notifications.permission_denied": "Trình duyệt không cho phép hiển thị thông báo trên màn hình.",
"notifications.permission_denied_alert": "Không thể bật thông báo trên màn hình bởi vì trình duyệt đã cấm trước đó",
"notifications.permission_required": "Không hiện thông báo trên màn hình bởi vì chưa cho phép.",
"notifications.policy.filter_new_accounts.hint": "Đã tạo trong vòng {days, plural, other {# ngày}}",
"notifications.policy.filter_new_accounts_title": "Tài khoản mới",
"notifications.policy.filter_not_followers_hint": "Bao gồm những người đã theo dõi bạn ít hơn {days, plural, other {# ngày}}",
"notifications.policy.filter_not_followers_title": "Những người không theo dõi bạn",
"notifications.policy.filter_not_following_hint": "Cho tới khi bạn duyệt họ",
"notifications.policy.filter_not_following_title": "Những người bạn không theo dõi",
"notifications.policy.filter_private_mentions_hint": "Được lọc trừ khi nó trả lời lượt nhắc từ bạn hoặc nếu bạn theo dõi người gửi",
"notifications.policy.filter_private_mentions_title": "Lượt nhắc riêng tư không được yêu cầu",
"notifications.policy.title": "Lọc ra thông báo từ…",
"notifications_permission_banner.enable": "Cho phép thông báo trên màn hình",
"notifications_permission_banner.how_to_control": "Hãy bật thông báo trên màn hình để không bỏ lỡ những thông báo từ Mastodon. Một khi đã bật, bạn có thể lựa chọn từng loại thông báo khác nhau thông qua {icon} nút bên dưới.",
"notifications_permission_banner.title": "Không bỏ lỡ điều thú vị nào",

View file

@ -1,5 +1,3 @@
import Rails from '@rails/ujs';
export const logOut = () => {
const form = document.createElement('form');
@ -9,13 +7,18 @@ export const logOut = () => {
methodInput.setAttribute('type', 'hidden');
form.appendChild(methodInput);
const csrfToken = Rails.csrfToken();
const csrfParam = Rails.csrfParam();
const csrfToken = document.querySelector<HTMLMetaElement>(
'meta[name=csrf-token]',
);
const csrfParam = document.querySelector<HTMLMetaElement>(
'meta[name=csrf-param]',
);
if (csrfParam && csrfToken) {
const csrfInput = document.createElement('input');
csrfInput.setAttribute('name', csrfParam);
csrfInput.setAttribute('value', csrfToken);
csrfInput.setAttribute('name', csrfParam.content);
csrfInput.setAttribute('value', csrfToken.content);
csrfInput.setAttribute('type', 'hidden');
form.appendChild(csrfInput);
}

View file

@ -263,11 +263,11 @@ html {
}
.react-toggle-track {
background: $ui-secondary-color;
background: $ui-primary-color;
}
.react-toggle:hover:not(.react-toggle--disabled) .react-toggle-track {
background: darken($ui-secondary-color, 10%);
background: lighten($ui-primary-color, 10%);
}
.react-toggle.react-toggle--checked:hover:not(.react-toggle--disabled)

View file

@ -1659,15 +1659,35 @@ body > [data-popper-placement] {
}
.detailed-status__meta {
margin-top: 16px;
margin-top: 24px;
color: $dark-text-color;
font-size: 14px;
line-height: 18px;
&__line {
border-bottom: 1px solid var(--background-border-color);
padding: 8px 0;
display: flex;
align-items: center;
gap: 8px;
&:first-child {
padding-top: 0;
}
&:last-child {
padding-bottom: 0;
border-bottom: 0;
}
}
.icon {
width: 15px;
height: 15px;
vertical-align: middle;
width: 18px;
height: 18px;
}
.animated-number {
color: $secondary-text-color;
}
}
@ -1711,19 +1731,6 @@ body > [data-popper-placement] {
color: inherit;
text-decoration: none;
gap: 6px;
position: relative;
top: 0.145em;
.icon {
top: 0;
}
}
.detailed-status__favorites,
.detailed-status__reblogs {
font-weight: 500;
font-size: 12px;
line-height: 18px;
}
.domain {
@ -2292,6 +2299,10 @@ a.account__display-name {
outline: 1px dotted;
}
&:hover {
text-decoration: underline;
}
.icon {
width: 15px;
height: 15px;
@ -3369,7 +3380,7 @@ $ui-header-height: 55px;
height: 20px;
padding: 0;
border-radius: 10px;
background-color: #626982;
background-color: $ui-primary-color;
}
.react-toggle--focus {
@ -3392,7 +3403,7 @@ $ui-header-height: 55px;
width: 16px;
height: 16px;
border-radius: 50%;
background-color: $primary-text-color;
background-color: $ui-button-color;
box-sizing: border-box;
transition: all 0.25s ease;
transition-property: border-color, left;
@ -3403,6 +3414,15 @@ $ui-header-height: 55px;
border-color: $ui-highlight-color;
}
.react-toggle:hover:not(.react-toggle--disabled) .react-toggle-track {
background: darken($ui-primary-color, 5%);
}
.react-toggle.react-toggle--checked:hover:not(.react-toggle--disabled)
.react-toggle-track {
background: lighten($ui-highlight-color, 5%);
}
.switch-to-advanced {
color: $light-text-color;
background-color: $ui-base-color;
@ -3476,7 +3496,7 @@ $ui-header-height: 55px;
}
.column-subheading {
background: darken($ui-base-color, 4%);
background: var(--surface-background-color);
color: $darker-text-color;
padding: 8px 20px;
font-size: 12px;
@ -4628,7 +4648,7 @@ a.status-card {
}
.follow_requests-unlocked_explanation {
background: darken($ui-base-color, 4%);
background: var(--surface-background-color);
border-bottom: 1px solid var(--background-border-color);
contain: initial;
flex-grow: 0;
@ -5260,18 +5280,6 @@ a.status-card {
}
}
.search-results__header {
color: $dark-text-color;
background: lighten($ui-base-color, 2%);
padding: 15px;
font-weight: 500;
font-size: 16px;
cursor: default;
display: flex;
align-items: center;
gap: 5px;
}
.search-results__section {
border-bottom: 1px solid var(--background-border-color);
@ -5280,8 +5288,8 @@ a.status-card {
}
&__header {
background: darken($ui-base-color, 4%);
border-bottom: 1px solid var(--background-border-color);
background: var(--surface-background-color);
padding: 15px;
font-weight: 500;
font-size: 14px;
@ -7150,7 +7158,7 @@ noscript {
.follow-request-banner,
.account-memorial-banner {
padding: 20px;
background: lighten($ui-base-color, 4%);
background: var(--surface-background-color);
display: flex;
align-items: center;
flex-direction: column;
@ -8317,7 +8325,8 @@ noscript {
flex: 1 1 auto;
display: flex;
flex-direction: column;
background: $ui-base-color;
border: 1px solid var(--background-border-color);
border-top: 0;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
}

View file

@ -104,4 +104,5 @@ $font-monospace: 'mastodon-font-monospace' !default;
--background-filter: blur(10px) saturate(180%) contrast(75%) brightness(70%);
--background-color: #{darken($ui-base-color, 8%)};
--background-color-tint: #{rgba(darken($ui-base-color, 8%), 0.9)};
--surface-background-color: #{darken($ui-base-color, 4%)};
}

View file

@ -24,7 +24,7 @@ class ActivityTracker
end
def get(start_at, end_at = Time.now.utc)
(start_at.to_date...end_at.to_date).map do |date|
(start_at.to_date..end_at.to_date).map do |date|
key = key_at(date.to_time(:utc))
value = case @type

View file

@ -37,11 +37,11 @@ class Admin::Metrics::Dimension::InstanceLanguagesDimension < Admin::Metrics::Di
end
def earliest_status_id
Mastodon::Snowflake.id_at(@start_at, with_random: false)
Mastodon::Snowflake.id_at(@start_at.beginning_of_day, with_random: false)
end
def latest_status_id
Mastodon::Snowflake.id_at(@end_at, with_random: false)
Mastodon::Snowflake.id_at(@end_at.end_of_day, with_random: false)
end
def params

View file

@ -30,10 +30,10 @@ class Admin::Metrics::Dimension::ServersDimension < Admin::Metrics::Dimension::B
end
def earliest_status_id
Mastodon::Snowflake.id_at(@start_at)
Mastodon::Snowflake.id_at(@start_at.beginning_of_day, with_random: false)
end
def latest_status_id
Mastodon::Snowflake.id_at(@end_at)
Mastodon::Snowflake.id_at(@end_at.end_of_day, with_random: false)
end
end

View file

@ -40,11 +40,11 @@ class Admin::Metrics::Dimension::TagLanguagesDimension < Admin::Metrics::Dimensi
end
def earliest_status_id
Mastodon::Snowflake.id_at(@start_at, with_random: false)
Mastodon::Snowflake.id_at(@start_at.beginning_of_day, with_random: false)
end
def latest_status_id
Mastodon::Snowflake.id_at(@end_at, with_random: false)
Mastodon::Snowflake.id_at(@end_at.end_of_day, with_random: false)
end
def params

View file

@ -40,11 +40,11 @@ class Admin::Metrics::Dimension::TagServersDimension < Admin::Metrics::Dimension
end
def earliest_status_id
Mastodon::Snowflake.id_at(@start_at, with_random: false)
Mastodon::Snowflake.id_at(@start_at.beginning_of_day, with_random: false)
end
def latest_status_id
Mastodon::Snowflake.id_at(@end_at, with_random: false)
Mastodon::Snowflake.id_at(@end_at.end_of_day, with_random: false)
end
def params

View file

@ -51,11 +51,11 @@ class Admin::Metrics::Measure::InstanceStatusesMeasure < Admin::Metrics::Measure
end
def earliest_status_id
Mastodon::Snowflake.id_at(@start_at, with_random: false)
Mastodon::Snowflake.id_at(@start_at.beginning_of_day, with_random: false)
end
def latest_status_id
Mastodon::Snowflake.id_at(@end_at, with_random: false)
Mastodon::Snowflake.id_at(@end_at.end_of_day, with_random: false)
end
def time_period

View file

@ -50,6 +50,7 @@ class TextFormatter
class << self
include ERB::Util
include ActionView::Helpers::TagHelper
def shortened_link(url, rel_me: false)
url = Addressable::URI.parse(url).to_s
@ -60,9 +61,11 @@ class TextFormatter
suffix = url[prefix.length + 30..]
cutoff = url[prefix.length..].length > 30
<<~HTML.squish.html_safe # rubocop:disable Rails/OutputSafety
<a href="#{h(url)}" target="_blank" rel="#{rel.join(' ')}" translate="no"><span class="invisible">#{h(prefix)}</span><span class="#{cutoff ? 'ellipsis' : ''}">#{h(display_url)}</span><span class="invisible">#{h(suffix)}</span></a>
HTML
tag.a href: url, target: '_blank', rel: rel.join(' '), translate: 'no' do
tag.span(prefix, class: 'invisible') +
tag.span(display_url, class: (cutoff ? 'ellipsis' : '')) +
tag.span(suffix, class: 'invisible')
end
rescue Addressable::URI::InvalidURIError, IDN::Idna::IdnaError
h(url)
end

View file

@ -111,6 +111,7 @@ class Account < ApplicationRecord
normalizes :username, with: ->(username) { username.squish }
scope :without_internal, -> { where(id: 1...) }
scope :remote, -> { where.not(domain: nil) }
scope :local, -> { where(domain: nil) }
scope :partitioned, -> { order(Arel.sql('row_number() over (partition by domain)')) }
@ -441,7 +442,7 @@ class Account < ApplicationRecord
end
def inboxes
urls = reorder(nil).where(protocol: :activitypub).group(:preferred_inbox_url).pluck(Arel.sql("coalesce(nullif(accounts.shared_inbox_url, ''), accounts.inbox_url) AS preferred_inbox_url"))
urls = reorder(nil).activitypub.group(:preferred_inbox_url).pluck(Arel.sql("coalesce(nullif(accounts.shared_inbox_url, ''), accounts.inbox_url) AS preferred_inbox_url"))
DeliveryFailureTracker.without_unavailable(urls)
end

View file

@ -242,10 +242,6 @@ module Account::Interactions
status_pins.exists?(status: status)
end
def endorsed?(account)
account_pins.exists?(target_account: account)
end
def status_matches_filters(status)
active_filters = CustomFilter.cached_filters_for(id)
CustomFilter.apply_cached_filters(active_filters, status)

View file

@ -31,7 +31,7 @@ module Account::StatusesSearch
def add_to_public_statuses_index!
return unless Chewy.enabled?
statuses.without_reblogs.where(visibility: :public).reorder(nil).find_in_batches do |batch|
statuses.without_reblogs.public_visibility.reorder(nil).find_in_batches do |batch|
PublicStatusesIndex.import(batch)
end
end

View file

@ -5,6 +5,18 @@ module DomainNormalizable
included do
before_validation :normalize_domain
scope :by_domain_length, -> { order(domain_char_length.desc) }
end
class_methods do
def domain_char_length
Arel.sql(
<<~SQL.squish
CHAR_LENGTH(domain)
SQL
)
end
end
private

View file

@ -4,7 +4,7 @@ module Status::SearchConcern
extend ActiveSupport::Concern
included do
scope :indexable, -> { without_reblogs.where(visibility: :public).joins(:account).where(account: { indexable: true }) }
scope :indexable, -> { without_reblogs.public_visibility.joins(:account).where(account: { indexable: true }) }
end
def searchable_by

View file

@ -41,7 +41,7 @@ class CustomFilter < ApplicationRecord
validates :title, :context, presence: true
validate :context_must_be_valid
before_validation :clean_up_contexts
normalizes :context, with: ->(context) { context.map(&:strip).filter_map(&:presence) }
before_save :prepare_cache_invalidation!
before_destroy :prepare_cache_invalidation!
@ -114,10 +114,6 @@ class CustomFilter < ApplicationRecord
private
def clean_up_contexts
self.context = Array(context).map(&:strip).filter_map(&:presence)
end
def context_must_be_valid
errors.add(:context, I18n.t('filters.errors.invalid_context')) if invalid_context_value?
end

View file

@ -70,7 +70,7 @@ class DomainBlock < ApplicationRecord
segments = uri.normalized_host.split('.')
variants = segments.map.with_index { |_, i| segments[i..].join('.') }
where(domain: variants).order(Arel.sql('char_length(domain) desc')).first
where(domain: variants).by_domain_length.first
rescue Addressable::URI::InvalidURIError, IDN::Idna::IdnaError
nil
end

View file

@ -56,7 +56,7 @@ class EmailDomainBlock < ApplicationRecord
end
def blocking?(allow_with_approval: false)
blocks = EmailDomainBlock.where(domain: domains_with_variants, allow_with_approval: allow_with_approval).order(Arel.sql('char_length(domain) desc'))
blocks = EmailDomainBlock.where(domain: domains_with_variants, allow_with_approval: allow_with_approval).by_domain_length
blocks.each { |block| block.history.add(@attempt_ip) } if @attempt_ip.present?
blocks.any?
end

View file

@ -23,7 +23,7 @@ class IpBlock < ApplicationRecord
sign_up_requires_approval: 5000,
sign_up_block: 5500,
no_access: 9999,
}
}, prefix: true
validates :ip, :severity, presence: true
validates :ip, uniqueness: true

View file

@ -29,18 +29,40 @@ class Notification < ApplicationRecord
'Poll' => :poll,
}.freeze
TYPES = %i(
mention
status
reblog
follow
follow_request
favourite
poll
update
admin.sign_up
admin.report
).freeze
PROPERTIES = {
mention: {
filterable: true,
}.freeze,
status: {
filterable: false,
}.freeze,
reblog: {
filterable: true,
}.freeze,
follow: {
filterable: true,
}.freeze,
follow_request: {
filterable: true,
}.freeze,
favourite: {
filterable: true,
}.freeze,
poll: {
filterable: false,
}.freeze,
update: {
filterable: false,
}.freeze,
'admin.sign_up': {
filterable: false,
}.freeze,
'admin.report': {
filterable: false,
}.freeze,
}.freeze
TYPES = PROPERTIES.keys.freeze
TARGET_STATUS_INCLUDES_BY_TYPE = {
status: :status,

View file

@ -54,6 +54,6 @@ class PreviewCardProvider < ApplicationRecord
def self.matching_domain(domain)
segments = domain.split('.')
where(domain: segments.map.with_index { |_, i| segments[i..].join('.') }).order(Arel.sql('char_length(domain) desc')).first
where(domain: segments.map.with_index { |_, i| segments[i..].join('.') }).by_domain_length.first
end
end

View file

@ -61,7 +61,7 @@ class PublicFeed
end
def public_scope
Status.with_public_visibility.joins(:account).merge(Account.without_suspended.without_silenced)
Status.public_visibility.joins(:account).merge(Account.without_suspended.without_silenced)
end
def local_only_scope

View file

@ -108,7 +108,6 @@ class Status < ApplicationRecord
scope :with_accounts, ->(ids) { where(id: ids).includes(:account) }
scope :without_replies, -> { where('statuses.reply = FALSE OR statuses.in_reply_to_account_id = statuses.account_id') }
scope :without_reblogs, -> { where(statuses: { reblog_of_id: nil }) }
scope :with_public_visibility, -> { where(visibility: :public) }
scope :tagged_with, ->(tag_ids) { joins(:statuses_tags).where(statuses_tags: { tag_id: tag_ids }) }
scope :not_excluded_by_account, ->(account) { where.not(account_id: account.excluded_from_timeline_account_ids) }
scope :not_domain_blocked_by_account, ->(account) { account.excluded_from_timeline_domains.blank? ? left_outer_joins(:account) : left_outer_joins(:account).where('accounts.domain IS NULL OR accounts.domain NOT IN (?)', account.excluded_from_timeline_domains) }
@ -443,7 +442,6 @@ class Status < ApplicationRecord
def set_visibility
self.visibility = reblog.visibility if reblog? && visibility.nil?
self.visibility = (account.locked? ? :private : :public) if visibility.nil?
self.sensitive = false if sensitive.nil?
end
def set_conversation

View file

@ -446,7 +446,7 @@ class User < ApplicationRecord
end
def sign_up_from_ip_requires_approval?
sign_up_ip.present? && IpBlock.sign_up_requires_approval.exists?(['ip >>= ?', sign_up_ip.to_s])
sign_up_ip.present? && IpBlock.severity_sign_up_requires_approval.exists?(['ip >>= ?', sign_up_ip.to_s])
end
def sign_up_email_requires_approval?

View file

@ -68,6 +68,13 @@ class NotifyService < BaseService
NEW_FOLLOWER_THRESHOLD = 3.days.freeze
NON_FILTERABLE_TYPES = %i(
admin.sign_up
admin.report
poll
update
).freeze
def initialize(notification)
@notification = notification
@recipient = notification.account
@ -76,6 +83,7 @@ class NotifyService < BaseService
end
def filter?
return false unless Notification::PROPERTIES[@notification.type][:filterable]
return false if override_for_sender?
from_limited? ||

View file

@ -508,7 +508,7 @@ fa:
private_comment: یادداشت خصوصی
public_comment: یادداشت عمومی
purge: پاکسازی
title: ارتباط میان‌سروری
title: ارتباط همگانی
total_blocked_by_us: مسدودشده از طرف ما
total_followed_by_them: ما را پی می‌گیرند
total_followed_by_us: ما پیگیرشان هستیم
@ -673,7 +673,7 @@ fa:
follow_recommendations: پیروی از پیشنهادها
profile_directory: شاخهٔ نمایه
public_timelines: خط زمانی‌های عمومی
publish_discovered_servers: انتشار سرورهای یافته‌شده
publish_discovered_servers: انتشار کارسازهای کشف شده
publish_statistics: انتشار آمار
title: کشف
trends: پرطرفدارها
@ -898,7 +898,7 @@ fa:
description:
prefix_invited_by_user: "@%{name} شما را به عضویت در این کارساز ماستودون دعوت کرده است!"
prefix_sign_up: همین امروز عضو ماستودون شوید!
suffix: با داشتن حساب می‌توانید دیگران را پی بگیرید، نوشته‌های تازه منتشر کنید، و با کاربران دیگر از هر سرور ماستودون دیگری و حتی سرورهای دیگر در ارتباط باشید!
suffix: با داشتن حساب می‌توانید دیگران را پی گرفته، نوشته‌هایی منتشر کرده و با کاربرانی از هر کارساز ماستودن دیگری در ارتباط باشید!
didnt_get_confirmation: یک پیوند تأیید را دریافت نکردید؟
dont_have_your_security_key: کلید امنیتیتان را ندارید؟
forgot_password: گذرواژه خود را فراموش کرده‌اید؟
@ -921,7 +921,7 @@ fa:
cas: CAS
saml: SAML
register: عضو شوید
registration_closed: سرور %{instance} عضو تازه‌ای نمی‌پذیرد
registration_closed: کارساز %{instance} عضو تازه‌ای نمی‌پذیرد
resend_confirmation: ارسال مجدد پیوند تایید
reset_password: بازنشانی گذرواژه
rules:

View file

@ -1551,7 +1551,7 @@ fi:
limit_reached: Erilaisten reaktioiden raja saavutettu
unrecognized_emoji: ei ole tunnistettu emoji
redirects:
prompt: Mikäli luotat linkkiin, jatka napsauttaen sitä.
prompt: Jos luotat linkkiin, jatka napsauttamalla sitä.
title: Olet poistumassa palvelimelta %{instance}.
relationships:
activity: Tilin aktiivisuus
@ -1802,7 +1802,7 @@ fi:
explanation: Joku on yrittänyt kirjautua tilillesi antaen väärän toisen todennustunnisteen.
further_actions_html: Jos se et ollut sinä, suosittelemme, että %{action} välittömästi, sillä se on saattanut vaarantua.
subject: Kaksivaiheisen todennuksen virhe
title: Kaksivaihekirjautumisen toinen vaihe epäonnistui
title: Kaksivaiheisen kirjautumisen toinen vaihe epäonnistui
suspicious_sign_in:
change_password: vaihda salasanasi
details: 'Tässä on tiedot kirjautumisesta:'
@ -1846,7 +1846,10 @@ fi:
apps_ios_action: Lataa App Storesta
apps_step: Lataa viralliset sovelluksemme.
apps_title: Mastodon-sovellukset
checklist_subtitle: 'Aloitetaan, sinä aloitat uudella sosiaalisella seudulla:'
checklist_title: Tervetuloa tarkistuslista
edit_profile_action: Mukauta
edit_profile_step: Täydentämällä profiilisi tietoja tehostat vaikutemaa.
edit_profile_title: Mukauta profiiliasi
explanation: Näillä vinkeillä pääset alkuun
feature_action: Lue lisää

View file

@ -705,6 +705,7 @@ kab:
moved: Igujj
primary: Agejdan
relationship: Assaɣ
remove_selected_follows: Ur ṭṭafar ara iseqdacen yettwafernen
status: Addad n umiḍan
sessions:
activity: Armud aneggaru
@ -729,6 +730,7 @@ kab:
current_session: Tiɣimit tamirant
date: Azemz
description: "%{browser} s %{platform}"
explanation: Ha-t-en yiminigen web ikecmen akka tura ɣer umiḍan-ik·im Mastodon.
ip: IP
platforms:
adobe_air: Adobe Air

View file

@ -1846,15 +1846,25 @@ lad:
apps_ios_action: Abasha en App Store
apps_step: Abasha muestras aplikasyones ofisyalas.
apps_title: Aplikasyones de Mastodon
checklist_title: Lista de bienvenida
edit_profile_action: Personaliza
edit_profile_step: Kompleta tu profil para aumentar tus enteraksyones.
edit_profile_title: Personaliza tu profil
explanation: Aki ay algunos konsejos para ampesar
feature_action: Ambezate mas
feature_audience_title: Konstruye tu audyensya kon konfyansa
feature_control_title: Manten kontrol de tu linya de tyempo
feature_creativity_title: Kreativita sin paralelas
feature_moderation_title: La moderasyon komo deveria ser
follow_action: Sige
follow_title: Personaliza tu linya prinsipala
follows_subtitle: Sige kuentos konesidos
follows_title: A ken segir
follows_view_more: Ve mas personas para segir
hashtags_recent_count: "%{people} personas en los ultimos %{days} diyas"
hashtags_subtitle: Eksplora los trendes de los ultimos 2 diyas
hashtags_title: Etiketas en trend
hashtags_view_more: Ve mas etiketas en trend
post_action: Eskrive
post_step: Puedes introdusirte al mundo kon teksto, fotos, videos o anketas.
post_title: Eskrive tu primera publikasyon

View file

@ -116,6 +116,7 @@ be:
sign_up_requires_approval: Новыя рэгістрацыі запатрабуюць вашага ўзгаднення
severity: Абярыце, што будзе адбывацца з запытамі з гэтага IP
rule:
hint: Неабавязкова. Пазначце дадатковыя звесткі аб правіле
text: Апішыце правіла ці патрабаванне для карыстальнікаў на гэтым серверы. Імкніцеся зрабіць яго простым ды кароткім
sessions:
otp: 'Увядзіце код двухфактарнай аўтэнтыфікацыі з вашага тэлефона або адзін з кодаў аднаўлення:'
@ -299,6 +300,7 @@ be:
patch: Апавяшчаць аб абнаўленнях з выпраўленнем памылак
trending_tag: Новы трэнд патрабуе разгляду
rule:
hint: Дадатковая інфармацыя
text: Правіла
settings:
indexable: Індэксаваць профіль у пошукавых сістэмах

View file

@ -116,7 +116,7 @@ ca:
sign_up_requires_approval: Els nous registres requeriran la teva aprovació
severity: Tria què passarà amb les sol·licituds des daquesta IP
rule:
hint: Opcional. Proporciona més detalls de la regla
hint: Opcional. Proporcioneu més detalls de la regla
text: Descriu una norma o requeriment pels usuaris d'aquest servidor. Intenta fer-la curta i senzilla
sessions:
otp: 'Introdueix el codi de dos factors generat per el teu telèfon o utilitza un dels teus codis de recuperació:'

View file

@ -62,7 +62,7 @@ fa:
username: تنها می‌توانید از حروف، اعداد، و زیرخط استفاده کنید
whole_word: اگر کلیدواژه فقط دارای حروف و اعداد باشد، تنها وقتی پیدا می‌شود که با کل یک واژه در متن منطبق باشد، نه با بخشی از یک واژه
domain_allow:
domain: این دامین خواهد توانست داده‌ها از این سرور را دریافت کند و داده‌های از این دامین در این‌جا پردازش و ذخیره خواهند شد
domain: این دامنه خواهد توانست داده‌ها را از این کارساز واکشی کرده و داده‌های ورودی از آن پردازش و ذخیره خواهند شد
email_domain_block:
domain: این می‌تواند نام دامنه‌ای باشد که در نشانی رایانامه یا رکورد MX استفاده می‌شود. پس از ثبت نام بررسی خواهند شد.
with_dns_records: تلاشی برای resolve کردن رکوردهای ساناد دامنهٔ داده‌شده انجام شده و نتیجه نیز مسدود خواهد شد

View file

@ -116,6 +116,7 @@ fi:
sign_up_requires_approval: Uudet rekisteröitymiset edellyttävät hyväksyntääsi
severity: Valitse, mitä tapahtuu tämän IP-osoitteen pyynnöille
rule:
hint: Valinnainen. Anna lisätietoja säännöstä
text: Kuvaile sääntöä tai edellytystä palvelimesi käyttäjille. Suosi tiivistä, yksinkertaista ilmaisua
sessions:
otp: 'Näppäile mobiilisovelluksessa näkyvä kaksivaiheisen todennuksen tunnusluku, tai käytä tarvittaessa palautuskoodia:'
@ -299,6 +300,7 @@ fi:
patch: Ilmoita virhekorjauspäivityksistä
trending_tag: Uusi trendi vaatii tarkistusta
rule:
hint: Lisätietoja
text: Sääntö
settings:
indexable: Sisällytä profiilisivu hakukoneisiin

View file

@ -116,6 +116,7 @@ ja:
sign_up_requires_approval: 承認するまで新規登録が完了しなくなります
severity: このIPに対する措置を選択してください
rule:
hint: ルールについての具体的な説明を追加できます (任意)
text: ユーザーのためのルールや要件を記述してください。短くシンプルにしてください。
sessions:
otp: '携帯電話のアプリで生成された二要素認証コードを入力するか、リカバリーコードを使用してください:'
@ -299,6 +300,7 @@ ja:
patch: 緊急のアップデートとバグ修正アップデートを通知する
trending_tag: 新しいトレンドのレビューをする必要がある時
rule:
hint: ルールの補足説明
text: ルール
settings:
indexable: 検索エンジンからアクセスできるようにする

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