mirror of
https://github.com/glitch-soc/mastodon
synced 2025-04-24 15:24:51 +00:00
Merge commit '5f87ae101c5e0e940e148d493eaac1ce31fe24c1' into glitch-soc/merge-upstream
This commit is contained in:
commit
99e3ea232f
60 changed files with 667 additions and 512 deletions
2
.github/renovate.json5
vendored
2
.github/renovate.json5
vendored
|
@ -15,6 +15,8 @@
|
|||
// to `null` after any other rule set it to something.
|
||||
dependencyDashboardHeader: 'This issue lists Renovate updates and detected dependencies. Read the [Dependency Dashboard](https://docs.renovatebot.com/key-concepts/dashboard/) docs to learn more. Before approving any upgrade: read the description and comments in the [`renovate.json5` file](https://github.com/mastodon/mastodon/blob/main/.github/renovate.json5).',
|
||||
postUpdateOptions: ['yarnDedupeHighest'],
|
||||
// The types are now included in recent versions,we ignore them here until we upgrade and remove the dependency
|
||||
ignoreDeps: ['@types/emoji-mart'],
|
||||
packageRules: [
|
||||
{
|
||||
// Require Dependency Dashboard Approval for major version bumps of these node packages
|
||||
|
|
30
Gemfile.lock
30
Gemfile.lock
|
@ -94,7 +94,7 @@ GEM
|
|||
ast (2.4.3)
|
||||
attr_required (1.0.2)
|
||||
aws-eventstream (1.3.2)
|
||||
aws-partitions (1.1066.0)
|
||||
aws-partitions (1.1080.0)
|
||||
aws-sdk-core (3.215.1)
|
||||
aws-eventstream (~> 1, >= 1.3.0)
|
||||
aws-partitions (~> 1, >= 1.992.0)
|
||||
|
@ -126,7 +126,7 @@ GEM
|
|||
blurhash (0.1.8)
|
||||
bootsnap (1.18.4)
|
||||
msgpack (~> 1.2)
|
||||
brakeman (7.0.0)
|
||||
brakeman (7.0.1)
|
||||
racc
|
||||
browser (6.2.0)
|
||||
brpoplpush-redis_script (0.1.3)
|
||||
|
@ -194,7 +194,7 @@ GEM
|
|||
devise_pam_authenticatable2 (9.2.0)
|
||||
devise (>= 4.0.0)
|
||||
rpam2 (~> 4.0)
|
||||
diff-lcs (1.6.0)
|
||||
diff-lcs (1.6.1)
|
||||
discard (1.4.0)
|
||||
activerecord (>= 4.2, < 9.0)
|
||||
docile (1.4.1)
|
||||
|
@ -266,10 +266,10 @@ GEM
|
|||
raabro (~> 1.4)
|
||||
globalid (1.2.1)
|
||||
activesupport (>= 6.1)
|
||||
google-protobuf (4.30.1)
|
||||
google-protobuf (4.30.2)
|
||||
bigdecimal
|
||||
rake (>= 13)
|
||||
googleapis-common-protos-types (1.18.0)
|
||||
googleapis-common-protos-types (1.19.0)
|
||||
google-protobuf (>= 3.18, < 5.a)
|
||||
haml (6.3.0)
|
||||
temple (>= 0.8.2)
|
||||
|
@ -328,7 +328,7 @@ GEM
|
|||
activesupport (>= 3.0)
|
||||
nokogiri (>= 1.6)
|
||||
io-console (0.8.0)
|
||||
irb (1.15.1)
|
||||
irb (1.15.2)
|
||||
pp (>= 0.6.0)
|
||||
rdoc (>= 4.0.0)
|
||||
reline (>= 0.4.2)
|
||||
|
@ -426,7 +426,7 @@ GEM
|
|||
mime-types (3.6.2)
|
||||
logger
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2025.0318)
|
||||
mime-types-data (3.2025.0402)
|
||||
mini_mime (1.1.5)
|
||||
mini_portile2 (2.8.8)
|
||||
minitest (5.25.5)
|
||||
|
@ -569,7 +569,7 @@ GEM
|
|||
opentelemetry-instrumentation-redis (0.26.1)
|
||||
opentelemetry-api (~> 1.0)
|
||||
opentelemetry-instrumentation-base (~> 0.23.0)
|
||||
opentelemetry-instrumentation-sidekiq (0.26.0)
|
||||
opentelemetry-instrumentation-sidekiq (0.26.1)
|
||||
opentelemetry-api (~> 1.0)
|
||||
opentelemetry-instrumentation-base (~> 0.23.0)
|
||||
opentelemetry-registry (0.4.0)
|
||||
|
@ -688,7 +688,7 @@ GEM
|
|||
link_header (~> 0.0, >= 0.0.8)
|
||||
rdf-normalize (0.7.0)
|
||||
rdf (~> 3.3)
|
||||
rdoc (6.12.0)
|
||||
rdoc (6.13.1)
|
||||
psych (>= 4.0.0)
|
||||
redcarpet (3.6.1)
|
||||
redis (4.8.1)
|
||||
|
@ -740,7 +740,7 @@ GEM
|
|||
rspec-mocks (~> 3.0)
|
||||
sidekiq (>= 5, < 9)
|
||||
rspec-support (3.13.2)
|
||||
rubocop (1.75.1)
|
||||
rubocop (1.75.2)
|
||||
json (~> 2.3)
|
||||
language_server-protocol (~> 3.17.0.2)
|
||||
lint_roller (~> 1.1.0)
|
||||
|
@ -748,10 +748,10 @@ GEM
|
|||
parser (>= 3.3.0.2)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
regexp_parser (>= 2.9.3, < 3.0)
|
||||
rubocop-ast (>= 1.43.0, < 2.0)
|
||||
rubocop-ast (>= 1.44.0, < 2.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 2.4.0, < 4.0)
|
||||
rubocop-ast (1.43.0)
|
||||
rubocop-ast (1.44.0)
|
||||
parser (>= 3.3.7.2)
|
||||
prism (~> 1.4)
|
||||
rubocop-capybara (2.22.1)
|
||||
|
@ -840,7 +840,7 @@ GEM
|
|||
stoplight (4.1.1)
|
||||
redlock (~> 1.0)
|
||||
stringio (3.1.6)
|
||||
strong_migrations (2.2.1)
|
||||
strong_migrations (2.3.0)
|
||||
activerecord (>= 7)
|
||||
swd (2.0.3)
|
||||
activesupport (>= 3)
|
||||
|
@ -851,7 +851,7 @@ GEM
|
|||
temple (0.10.3)
|
||||
terminal-table (4.0.0)
|
||||
unicode-display_width (>= 1.1.1, < 4)
|
||||
terrapin (1.0.1)
|
||||
terrapin (1.1.0)
|
||||
climate_control
|
||||
test-prof (1.4.4)
|
||||
thor (1.3.2)
|
||||
|
@ -1085,4 +1085,4 @@ RUBY VERSION
|
|||
ruby 3.4.1p0
|
||||
|
||||
BUNDLED WITH
|
||||
2.6.6
|
||||
2.6.7
|
||||
|
|
|
@ -10,8 +10,6 @@ module SignatureVerification
|
|||
EXPIRATION_WINDOW_LIMIT = 12.hours
|
||||
CLOCK_SKEW_MARGIN = 1.hour
|
||||
|
||||
class SignatureVerificationError < StandardError; end
|
||||
|
||||
def require_account_signature!
|
||||
render json: signature_verification_failure_reason, status: signature_verification_failure_code unless signed_request_account
|
||||
end
|
||||
|
@ -34,7 +32,7 @@ module SignatureVerification
|
|||
|
||||
def signature_key_id
|
||||
signature_params['keyId']
|
||||
rescue SignatureVerificationError
|
||||
rescue Mastodon::SignatureVerificationError
|
||||
nil
|
||||
end
|
||||
|
||||
|
@ -45,17 +43,17 @@ module SignatureVerification
|
|||
def signed_request_actor
|
||||
return @signed_request_actor if defined?(@signed_request_actor)
|
||||
|
||||
raise SignatureVerificationError, 'Request not signed' unless signed_request?
|
||||
raise SignatureVerificationError, 'Incompatible request signature. keyId and signature are required' if missing_required_signature_parameters?
|
||||
raise SignatureVerificationError, 'Unsupported signature algorithm (only rsa-sha256 and hs2019 are supported)' unless %w(rsa-sha256 hs2019).include?(signature_algorithm)
|
||||
raise SignatureVerificationError, 'Signed request date outside acceptable time window' unless matches_time_window?
|
||||
raise Mastodon::SignatureVerificationError, 'Request not signed' unless signed_request?
|
||||
raise Mastodon::SignatureVerificationError, 'Incompatible request signature. keyId and signature are required' if missing_required_signature_parameters?
|
||||
raise Mastodon::SignatureVerificationError, 'Unsupported signature algorithm (only rsa-sha256 and hs2019 are supported)' unless %w(rsa-sha256 hs2019).include?(signature_algorithm)
|
||||
raise Mastodon::SignatureVerificationError, 'Signed request date outside acceptable time window' unless matches_time_window?
|
||||
|
||||
verify_signature_strength!
|
||||
verify_body_digest!
|
||||
|
||||
actor = actor_from_key_id(signature_params['keyId'])
|
||||
|
||||
raise SignatureVerificationError, "Public key not found for key #{signature_params['keyId']}" if actor.nil?
|
||||
raise Mastodon::SignatureVerificationError, "Public key not found for key #{signature_params['keyId']}" if actor.nil?
|
||||
|
||||
signature = Base64.decode64(signature_params['signature'])
|
||||
compare_signed_string = build_signed_string(include_query_string: true)
|
||||
|
@ -68,7 +66,7 @@ module SignatureVerification
|
|||
|
||||
actor = stoplight_wrapper.run { actor_refresh_key!(actor) }
|
||||
|
||||
raise SignatureVerificationError, "Could not refresh public key #{signature_params['keyId']}" if actor.nil?
|
||||
raise Mastodon::SignatureVerificationError, "Could not refresh public key #{signature_params['keyId']}" if actor.nil?
|
||||
|
||||
compare_signed_string = build_signed_string(include_query_string: true)
|
||||
return actor unless verify_signature(actor, signature, compare_signed_string).nil?
|
||||
|
@ -78,7 +76,7 @@ module SignatureVerification
|
|||
return actor unless verify_signature(actor, signature, compare_signed_string).nil?
|
||||
|
||||
fail_with! "Verification failed for #{actor.to_log_human_identifier} #{actor.uri} using rsa-sha256 (RSASSA-PKCS1-v1_5 with SHA-256)", signed_string: compare_signed_string, signature: signature_params['signature']
|
||||
rescue SignatureVerificationError => e
|
||||
rescue Mastodon::SignatureVerificationError => e
|
||||
fail_with! e.message
|
||||
rescue *Mastodon::HTTP_CONNECTION_ERRORS => e
|
||||
fail_with! "Failed to fetch remote data: #{e.message}"
|
||||
|
@ -104,7 +102,7 @@ module SignatureVerification
|
|||
def signature_params
|
||||
@signature_params ||= SignatureParser.parse(request.headers['Signature'])
|
||||
rescue SignatureParser::ParsingError
|
||||
raise SignatureVerificationError, 'Error parsing signature parameters'
|
||||
raise Mastodon::SignatureVerificationError, 'Error parsing signature parameters'
|
||||
end
|
||||
|
||||
def signature_algorithm
|
||||
|
@ -116,31 +114,31 @@ module SignatureVerification
|
|||
end
|
||||
|
||||
def verify_signature_strength!
|
||||
raise SignatureVerificationError, 'Mastodon requires the Date header or (created) pseudo-header to be signed' unless signed_headers.include?('date') || signed_headers.include?('(created)')
|
||||
raise SignatureVerificationError, 'Mastodon requires the Digest header or (request-target) pseudo-header to be signed' unless signed_headers.include?(HttpSignatureDraft::REQUEST_TARGET) || signed_headers.include?('digest')
|
||||
raise SignatureVerificationError, 'Mastodon requires the Host header to be signed when doing a GET request' if request.get? && !signed_headers.include?('host')
|
||||
raise SignatureVerificationError, 'Mastodon requires the Digest header to be signed when doing a POST request' if request.post? && !signed_headers.include?('digest')
|
||||
raise Mastodon::SignatureVerificationError, 'Mastodon requires the Date header or (created) pseudo-header to be signed' unless signed_headers.include?('date') || signed_headers.include?('(created)')
|
||||
raise Mastodon::SignatureVerificationError, 'Mastodon requires the Digest header or (request-target) pseudo-header to be signed' unless signed_headers.include?(HttpSignatureDraft::REQUEST_TARGET) || signed_headers.include?('digest')
|
||||
raise Mastodon::SignatureVerificationError, 'Mastodon requires the Host header to be signed when doing a GET request' if request.get? && !signed_headers.include?('host')
|
||||
raise Mastodon::SignatureVerificationError, 'Mastodon requires the Digest header to be signed when doing a POST request' if request.post? && !signed_headers.include?('digest')
|
||||
end
|
||||
|
||||
def verify_body_digest!
|
||||
return unless signed_headers.include?('digest')
|
||||
raise SignatureVerificationError, 'Digest header missing' unless request.headers.key?('Digest')
|
||||
raise Mastodon::SignatureVerificationError, 'Digest header missing' unless request.headers.key?('Digest')
|
||||
|
||||
digests = request.headers['Digest'].split(',').map { |digest| digest.split('=', 2) }.map { |key, value| [key.downcase, value] }
|
||||
sha256 = digests.assoc('sha-256')
|
||||
raise SignatureVerificationError, "Mastodon only supports SHA-256 in Digest header. Offered algorithms: #{digests.map(&:first).join(', ')}" if sha256.nil?
|
||||
raise Mastodon::SignatureVerificationError, "Mastodon only supports SHA-256 in Digest header. Offered algorithms: #{digests.map(&:first).join(', ')}" if sha256.nil?
|
||||
|
||||
return if body_digest == sha256[1]
|
||||
|
||||
digest_size = begin
|
||||
Base64.strict_decode64(sha256[1].strip).length
|
||||
rescue ArgumentError
|
||||
raise SignatureVerificationError, "Invalid Digest value. The provided Digest value is not a valid base64 string. Given digest: #{sha256[1]}"
|
||||
raise Mastodon::SignatureVerificationError, "Invalid Digest value. The provided Digest value is not a valid base64 string. Given digest: #{sha256[1]}"
|
||||
end
|
||||
|
||||
raise SignatureVerificationError, "Invalid Digest value. The provided Digest value is not a SHA-256 digest. Given digest: #{sha256[1]}" if digest_size != 32
|
||||
raise Mastodon::SignatureVerificationError, "Invalid Digest value. The provided Digest value is not a SHA-256 digest. Given digest: #{sha256[1]}" if digest_size != 32
|
||||
|
||||
raise SignatureVerificationError, "Invalid Digest value. Computed SHA-256 digest: #{body_digest}; given: #{sha256[1]}"
|
||||
raise Mastodon::SignatureVerificationError, "Invalid Digest value. Computed SHA-256 digest: #{body_digest}; given: #{sha256[1]}"
|
||||
end
|
||||
|
||||
def verify_signature(actor, signature, compare_signed_string)
|
||||
|
@ -165,13 +163,13 @@ module SignatureVerification
|
|||
"#{HttpSignatureDraft::REQUEST_TARGET}: #{request.method.downcase} #{request.path}"
|
||||
end
|
||||
when '(created)'
|
||||
raise SignatureVerificationError, 'Invalid pseudo-header (created) for rsa-sha256' unless signature_algorithm == 'hs2019'
|
||||
raise SignatureVerificationError, 'Pseudo-header (created) used but corresponding argument missing' if signature_params['created'].blank?
|
||||
raise Mastodon::SignatureVerificationError, 'Invalid pseudo-header (created) for rsa-sha256' unless signature_algorithm == 'hs2019'
|
||||
raise Mastodon::SignatureVerificationError, 'Pseudo-header (created) used but corresponding argument missing' if signature_params['created'].blank?
|
||||
|
||||
"(created): #{signature_params['created']}"
|
||||
when '(expires)'
|
||||
raise SignatureVerificationError, 'Invalid pseudo-header (expires) for rsa-sha256' unless signature_algorithm == 'hs2019'
|
||||
raise SignatureVerificationError, 'Pseudo-header (expires) used but corresponding argument missing' if signature_params['expires'].blank?
|
||||
raise Mastodon::SignatureVerificationError, 'Invalid pseudo-header (expires) for rsa-sha256' unless signature_algorithm == 'hs2019'
|
||||
raise Mastodon::SignatureVerificationError, 'Pseudo-header (expires) used but corresponding argument missing' if signature_params['expires'].blank?
|
||||
|
||||
"(expires): #{signature_params['expires']}"
|
||||
else
|
||||
|
@ -193,7 +191,7 @@ module SignatureVerification
|
|||
|
||||
expires_time = Time.at(signature_params['expires'].to_i).utc if signature_params['expires'].present?
|
||||
rescue ArgumentError => e
|
||||
raise SignatureVerificationError, "Invalid Date header: #{e.message}"
|
||||
raise Mastodon::SignatureVerificationError, "Invalid Date header: #{e.message}"
|
||||
end
|
||||
|
||||
expires_time ||= created_time + 5.minutes unless created_time.nil?
|
||||
|
@ -233,9 +231,9 @@ module SignatureVerification
|
|||
account
|
||||
end
|
||||
rescue Mastodon::PrivateNetworkAddressError => e
|
||||
raise SignatureVerificationError, "Requests to private network addresses are disallowed (tried to query #{e.host})"
|
||||
raise Mastodon::SignatureVerificationError, "Requests to private network addresses are disallowed (tried to query #{e.host})"
|
||||
rescue Mastodon::HostValidationError, ActivityPub::FetchRemoteActorService::Error, ActivityPub::FetchRemoteKeyService::Error, Webfinger::Error => e
|
||||
raise SignatureVerificationError, e.message
|
||||
raise Mastodon::SignatureVerificationError, e.message
|
||||
end
|
||||
|
||||
def stoplight_wrapper
|
||||
|
@ -251,8 +249,8 @@ module SignatureVerification
|
|||
|
||||
ActivityPub::FetchRemoteActorService.new.call(actor.uri, only_key: true, suppress_errors: false)
|
||||
rescue Mastodon::PrivateNetworkAddressError => e
|
||||
raise SignatureVerificationError, "Requests to private network addresses are disallowed (tried to query #{e.host})"
|
||||
raise Mastodon::SignatureVerificationError, "Requests to private network addresses are disallowed (tried to query #{e.host})"
|
||||
rescue Mastodon::HostValidationError, ActivityPub::FetchRemoteActorService::Error, Webfinger::Error => e
|
||||
raise SignatureVerificationError, e.message
|
||||
raise Mastodon::SignatureVerificationError, e.message
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,14 +12,6 @@ export const DOMAIN_BLOCK_FAIL = 'DOMAIN_BLOCK_FAIL';
|
|||
export const DOMAIN_UNBLOCK_REQUEST = 'DOMAIN_UNBLOCK_REQUEST';
|
||||
export const DOMAIN_UNBLOCK_FAIL = 'DOMAIN_UNBLOCK_FAIL';
|
||||
|
||||
export const DOMAIN_BLOCKS_FETCH_REQUEST = 'DOMAIN_BLOCKS_FETCH_REQUEST';
|
||||
export const DOMAIN_BLOCKS_FETCH_SUCCESS = 'DOMAIN_BLOCKS_FETCH_SUCCESS';
|
||||
export const DOMAIN_BLOCKS_FETCH_FAIL = 'DOMAIN_BLOCKS_FETCH_FAIL';
|
||||
|
||||
export const DOMAIN_BLOCKS_EXPAND_REQUEST = 'DOMAIN_BLOCKS_EXPAND_REQUEST';
|
||||
export const DOMAIN_BLOCKS_EXPAND_SUCCESS = 'DOMAIN_BLOCKS_EXPAND_SUCCESS';
|
||||
export const DOMAIN_BLOCKS_EXPAND_FAIL = 'DOMAIN_BLOCKS_EXPAND_FAIL';
|
||||
|
||||
export function blockDomain(domain) {
|
||||
return (dispatch, getState) => {
|
||||
dispatch(blockDomainRequest(domain));
|
||||
|
@ -79,80 +71,6 @@ export function unblockDomainFail(domain, error) {
|
|||
};
|
||||
}
|
||||
|
||||
export function fetchDomainBlocks() {
|
||||
return (dispatch) => {
|
||||
dispatch(fetchDomainBlocksRequest());
|
||||
|
||||
api().get('/api/v1/domain_blocks').then(response => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||
dispatch(fetchDomainBlocksSuccess(response.data, next ? next.uri : null));
|
||||
}).catch(err => {
|
||||
dispatch(fetchDomainBlocksFail(err));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function fetchDomainBlocksRequest() {
|
||||
return {
|
||||
type: DOMAIN_BLOCKS_FETCH_REQUEST,
|
||||
};
|
||||
}
|
||||
|
||||
export function fetchDomainBlocksSuccess(domains, next) {
|
||||
return {
|
||||
type: DOMAIN_BLOCKS_FETCH_SUCCESS,
|
||||
domains,
|
||||
next,
|
||||
};
|
||||
}
|
||||
|
||||
export function fetchDomainBlocksFail(error) {
|
||||
return {
|
||||
type: DOMAIN_BLOCKS_FETCH_FAIL,
|
||||
error,
|
||||
};
|
||||
}
|
||||
|
||||
export function expandDomainBlocks() {
|
||||
return (dispatch, getState) => {
|
||||
const url = getState().getIn(['domain_lists', 'blocks', 'next']);
|
||||
|
||||
if (!url) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(expandDomainBlocksRequest());
|
||||
|
||||
api().get(url).then(response => {
|
||||
const next = getLinks(response).refs.find(link => link.rel === 'next');
|
||||
dispatch(expandDomainBlocksSuccess(response.data, next ? next.uri : null));
|
||||
}).catch(err => {
|
||||
dispatch(expandDomainBlocksFail(err));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function expandDomainBlocksRequest() {
|
||||
return {
|
||||
type: DOMAIN_BLOCKS_EXPAND_REQUEST,
|
||||
};
|
||||
}
|
||||
|
||||
export function expandDomainBlocksSuccess(domains, next) {
|
||||
return {
|
||||
type: DOMAIN_BLOCKS_EXPAND_SUCCESS,
|
||||
domains,
|
||||
next,
|
||||
};
|
||||
}
|
||||
|
||||
export function expandDomainBlocksFail(error) {
|
||||
return {
|
||||
type: DOMAIN_BLOCKS_EXPAND_FAIL,
|
||||
error,
|
||||
};
|
||||
}
|
||||
|
||||
export const initDomainBlockModal = account => dispatch => dispatch(openModal({
|
||||
modalType: 'DOMAIN_BLOCK',
|
||||
modalProps: {
|
||||
|
|
13
app/javascript/mastodon/api/domain_blocks.ts
Normal file
13
app/javascript/mastodon/api/domain_blocks.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
import api, { getLinks } from 'mastodon/api';
|
||||
|
||||
export const apiGetDomainBlocks = async (url?: string) => {
|
||||
const response = await api().request<string[]>({
|
||||
method: 'GET',
|
||||
url: url ?? '/api/v1/domain_blocks',
|
||||
});
|
||||
|
||||
return {
|
||||
domains: response.data,
|
||||
links: getLinks(response),
|
||||
};
|
||||
};
|
|
@ -1,29 +1,36 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import { useState, useCallback } from 'react';
|
||||
|
||||
import { defineMessages } from 'react-intl';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import ContentCopyIcon from '@/material-icons/400-24px/content_copy.svg?react';
|
||||
import { showAlert } from 'mastodon/actions/alerts';
|
||||
import { IconButton } from 'mastodon/components/icon_button';
|
||||
import { useAppDispatch } from 'mastodon/store';
|
||||
|
||||
const messages = defineMessages({
|
||||
copied: { id: 'copy_icon_button.copied', defaultMessage: 'Copied to clipboard' },
|
||||
copied: {
|
||||
id: 'copy_icon_button.copied',
|
||||
defaultMessage: 'Copied to clipboard',
|
||||
},
|
||||
});
|
||||
|
||||
export const CopyIconButton = ({ title, value, className }) => {
|
||||
export const CopyIconButton: React.FC<{
|
||||
title: string;
|
||||
value: string;
|
||||
className: string;
|
||||
}> = ({ title, value, className }) => {
|
||||
const [copied, setCopied] = useState(false);
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
navigator.clipboard.writeText(value);
|
||||
void navigator.clipboard.writeText(value);
|
||||
setCopied(true);
|
||||
dispatch(showAlert({ message: messages.copied }));
|
||||
setTimeout(() => setCopied(false), 700);
|
||||
setTimeout(() => {
|
||||
setCopied(false);
|
||||
}, 700);
|
||||
}, [setCopied, value, dispatch]);
|
||||
|
||||
return (
|
||||
|
@ -31,13 +38,8 @@ export const CopyIconButton = ({ title, value, className }) => {
|
|||
className={classNames(className, copied ? 'copied' : 'copyable')}
|
||||
title={title}
|
||||
onClick={handleClick}
|
||||
icon=''
|
||||
iconComponent={ContentCopyIcon}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
CopyIconButton.propTypes = {
|
||||
title: PropTypes.string,
|
||||
value: PropTypes.string,
|
||||
className: PropTypes.string,
|
||||
};
|
|
@ -1,24 +1,15 @@
|
|||
import { useCallback } from 'react';
|
||||
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import LockOpenIcon from '@/material-icons/400-24px/lock_open.svg?react';
|
||||
import { unblockDomain } from 'mastodon/actions/domain_blocks';
|
||||
import { useAppDispatch } from 'mastodon/store';
|
||||
|
||||
import { IconButton } from './icon_button';
|
||||
|
||||
const messages = defineMessages({
|
||||
unblockDomain: {
|
||||
id: 'account.unblock_domain',
|
||||
defaultMessage: 'Unblock domain {domain}',
|
||||
},
|
||||
});
|
||||
import { Button } from './button';
|
||||
|
||||
export const Domain: React.FC<{
|
||||
domain: string;
|
||||
}> = ({ domain }) => {
|
||||
const intl = useIntl();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const handleDomainUnblock = useCallback(() => {
|
||||
|
@ -27,20 +18,17 @@ export const Domain: React.FC<{
|
|||
|
||||
return (
|
||||
<div className='domain'>
|
||||
<div className='domain__wrapper'>
|
||||
<span className='domain__domain-name'>
|
||||
<strong>{domain}</strong>
|
||||
</span>
|
||||
<div className='domain__domain-name'>
|
||||
<strong>{domain}</strong>
|
||||
</div>
|
||||
|
||||
<div className='domain__buttons'>
|
||||
<IconButton
|
||||
active
|
||||
icon='unlock'
|
||||
iconComponent={LockOpenIcon}
|
||||
title={intl.formatMessage(messages.unblockDomain, { domain })}
|
||||
onClick={handleDomainUnblock}
|
||||
<div className='domain__buttons'>
|
||||
<Button onClick={handleDomainUnblock}>
|
||||
<FormattedMessage
|
||||
id='account.unblock_domain_short'
|
||||
defaultMessage='Unblock'
|
||||
/>
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
import PropTypes from 'prop-types';
|
||||
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||
|
||||
import { Helmet } from 'react-helmet';
|
||||
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { debounce } from 'lodash';
|
||||
|
||||
import BlockIcon from '@/material-icons/400-24px/block-fill.svg?react';
|
||||
import { Domain } from 'mastodon/components/domain';
|
||||
|
||||
import { fetchDomainBlocks, expandDomainBlocks } from '../../actions/domain_blocks';
|
||||
import { LoadingIndicator } from '../../components/loading_indicator';
|
||||
import ScrollableList from '../../components/scrollable_list';
|
||||
import Column from '../ui/components/column';
|
||||
|
||||
const messages = defineMessages({
|
||||
heading: { id: 'column.domain_blocks', defaultMessage: 'Blocked domains' },
|
||||
});
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
domains: state.getIn(['domain_lists', 'blocks', 'items']),
|
||||
hasMore: !!state.getIn(['domain_lists', 'blocks', 'next']),
|
||||
});
|
||||
|
||||
class Blocks extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
params: PropTypes.object.isRequired,
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
hasMore: PropTypes.bool,
|
||||
domains: ImmutablePropTypes.orderedSet,
|
||||
intl: PropTypes.object.isRequired,
|
||||
multiColumn: PropTypes.bool,
|
||||
};
|
||||
|
||||
UNSAFE_componentWillMount () {
|
||||
this.props.dispatch(fetchDomainBlocks());
|
||||
}
|
||||
|
||||
handleLoadMore = debounce(() => {
|
||||
this.props.dispatch(expandDomainBlocks());
|
||||
}, 300, { leading: true });
|
||||
|
||||
render () {
|
||||
const { intl, domains, hasMore, multiColumn } = this.props;
|
||||
|
||||
if (!domains) {
|
||||
return (
|
||||
<Column>
|
||||
<LoadingIndicator />
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
|
||||
const emptyMessage = <FormattedMessage id='empty_column.domain_blocks' defaultMessage='There are no blocked domains yet.' />;
|
||||
|
||||
return (
|
||||
<Column bindToDocument={!multiColumn} icon='ban' iconComponent={BlockIcon} heading={intl.formatMessage(messages.heading)} alwaysShowBackButton>
|
||||
<ScrollableList
|
||||
scrollKey='domain_blocks'
|
||||
onLoadMore={this.handleLoadMore}
|
||||
hasMore={hasMore}
|
||||
emptyMessage={emptyMessage}
|
||||
bindToDocument={!multiColumn}
|
||||
>
|
||||
{domains.map(domain =>
|
||||
<Domain key={domain} domain={domain} />,
|
||||
)}
|
||||
</ScrollableList>
|
||||
|
||||
<Helmet>
|
||||
<meta name='robots' content='noindex' />
|
||||
</Helmet>
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(injectIntl(Blocks));
|
113
app/javascript/mastodon/features/domain_blocks/index.tsx
Normal file
113
app/javascript/mastodon/features/domain_blocks/index.tsx
Normal file
|
@ -0,0 +1,113 @@
|
|||
import { useEffect, useRef, useCallback, useState } from 'react';
|
||||
|
||||
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
||||
|
||||
import { Helmet } from 'react-helmet';
|
||||
|
||||
import BlockIcon from '@/material-icons/400-24px/block-fill.svg?react';
|
||||
import { apiGetDomainBlocks } from 'mastodon/api/domain_blocks';
|
||||
import { Column } from 'mastodon/components/column';
|
||||
import type { ColumnRef } from 'mastodon/components/column';
|
||||
import { ColumnHeader } from 'mastodon/components/column_header';
|
||||
import { Domain } from 'mastodon/components/domain';
|
||||
import ScrollableList from 'mastodon/components/scrollable_list';
|
||||
|
||||
const messages = defineMessages({
|
||||
heading: { id: 'column.domain_blocks', defaultMessage: 'Blocked domains' },
|
||||
});
|
||||
|
||||
const Blocks: React.FC<{ multiColumn: boolean }> = ({ multiColumn }) => {
|
||||
const intl = useIntl();
|
||||
const [domains, setDomains] = useState<string[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [next, setNext] = useState<string | undefined>();
|
||||
const hasMore = !!next;
|
||||
const columnRef = useRef<ColumnRef>(null);
|
||||
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
|
||||
void apiGetDomainBlocks()
|
||||
.then(({ domains, links }) => {
|
||||
const next = links.refs.find((link) => link.rel === 'next');
|
||||
|
||||
setLoading(false);
|
||||
setDomains(domains);
|
||||
setNext(next?.uri);
|
||||
|
||||
return '';
|
||||
})
|
||||
.catch(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
}, [setLoading, setDomains, setNext]);
|
||||
|
||||
const handleLoadMore = useCallback(() => {
|
||||
setLoading(true);
|
||||
|
||||
void apiGetDomainBlocks(next)
|
||||
.then(({ domains, links }) => {
|
||||
const next = links.refs.find((link) => link.rel === 'next');
|
||||
|
||||
setLoading(false);
|
||||
setDomains((previousDomains) => [...previousDomains, ...domains]);
|
||||
setNext(next?.uri);
|
||||
|
||||
return '';
|
||||
})
|
||||
.catch(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
}, [setLoading, setDomains, setNext, next]);
|
||||
|
||||
const handleHeaderClick = useCallback(() => {
|
||||
columnRef.current?.scrollTop();
|
||||
}, []);
|
||||
|
||||
const emptyMessage = (
|
||||
<FormattedMessage
|
||||
id='empty_column.domain_blocks'
|
||||
defaultMessage='There are no blocked domains yet.'
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<Column
|
||||
bindToDocument={!multiColumn}
|
||||
ref={columnRef}
|
||||
label={intl.formatMessage(messages.heading)}
|
||||
>
|
||||
<ColumnHeader
|
||||
icon='ban'
|
||||
iconComponent={BlockIcon}
|
||||
title={intl.formatMessage(messages.heading)}
|
||||
onClick={handleHeaderClick}
|
||||
multiColumn={multiColumn}
|
||||
showBackButton
|
||||
/>
|
||||
|
||||
<ScrollableList
|
||||
scrollKey='domain_blocks'
|
||||
onLoadMore={handleLoadMore}
|
||||
hasMore={hasMore}
|
||||
isLoading={loading}
|
||||
showLoading={loading && domains.length === 0}
|
||||
emptyMessage={emptyMessage}
|
||||
trackScroll={!multiColumn}
|
||||
bindToDocument={!multiColumn}
|
||||
>
|
||||
{domains.map((domain) => (
|
||||
<Domain key={domain} domain={domain} />
|
||||
))}
|
||||
</ScrollableList>
|
||||
|
||||
<Helmet>
|
||||
<title>{intl.formatMessage(messages.heading)}</title>
|
||||
<meta name='robots' content='noindex' />
|
||||
</Helmet>
|
||||
</Column>
|
||||
);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default Blocks;
|
|
@ -65,6 +65,7 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} publicació} other {{counter} publicacions}}",
|
||||
"account.unblock": "Desbloca @{name}",
|
||||
"account.unblock_domain": "Desbloca el domini {domain}",
|
||||
"account.unblock_domain_short": "Desbloca",
|
||||
"account.unblock_short": "Desbloca",
|
||||
"account.unendorse": "No recomanis en el perfil",
|
||||
"account.unfollow": "Deixa de seguir",
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} příspěvek} few {{counter} příspěvky} many {{counter} příspěvků} other {{counter} příspěvků}}",
|
||||
"account.unblock": "Odblokovat @{name}",
|
||||
"account.unblock_domain": "Odblokovat doménu {domain}",
|
||||
"account.unblock_domain_short": "Odblokovat",
|
||||
"account.unblock_short": "Odblokovat",
|
||||
"account.unendorse": "Nezvýrazňovat na profilu",
|
||||
"account.unfollow": "Přestat sledovat",
|
||||
|
@ -79,7 +80,7 @@
|
|||
"admin.dashboard.retention.cohort_size": "Noví uživatelé",
|
||||
"admin.impact_report.instance_accounts": "Profily účtů, které by byli odstaněny",
|
||||
"admin.impact_report.instance_followers": "Sledující, o které by naši uživatelé přišli",
|
||||
"admin.impact_report.instance_follows": "Sledující, o které by naši uživatelé přišli",
|
||||
"admin.impact_report.instance_follows": "Sledující, o které by jejich uživatelé přišli",
|
||||
"admin.impact_report.title": "Shrnutí dopadu",
|
||||
"alert.rate_limited.message": "Zkuste to prosím znovu po {retry_time, time, medium}.",
|
||||
"alert.rate_limited.title": "Spojení omezena",
|
||||
|
@ -101,7 +102,7 @@
|
|||
"annual_report.summary.archetype.replier": "Sociální motýlek",
|
||||
"annual_report.summary.followers.followers": "sledujících",
|
||||
"annual_report.summary.followers.total": "{count} celkem",
|
||||
"annual_report.summary.here_it_is": "Zde je tvůj {year} v přehledu:",
|
||||
"annual_report.summary.here_it_is": "Zde je tvůj rok {year} v přehledu:",
|
||||
"annual_report.summary.highlighted_post.by_favourites": "nejvíce oblíbený příspěvek",
|
||||
"annual_report.summary.highlighted_post.by_reblogs": "nejvíce boostovaný příspěvek",
|
||||
"annual_report.summary.highlighted_post.by_replies": "příspěvek s nejvíce odpověďmi",
|
||||
|
@ -267,7 +268,7 @@
|
|||
"domain_pill.activitypub_like_language": "ActivityPub je jako jazyk, kterým Mastodon mluví s jinými sociálními sítěmi.",
|
||||
"domain_pill.server": "Server",
|
||||
"domain_pill.their_handle": "Handle:",
|
||||
"domain_pill.their_server": "Jejich digitální domov, kde žijí jejich všechny příspěvky.",
|
||||
"domain_pill.their_server": "Jejich digitální domov, kde žijí všechny jejich příspěvky.",
|
||||
"domain_pill.their_username": "Jejich jedinečný identifikátor na jejich serveru. Je možné, že na jiných serverech jsou uživatelé se stejným uživatelským jménem.",
|
||||
"domain_pill.username": "Uživatelské jméno",
|
||||
"domain_pill.whats_in_a_handle": "Co obsahuje handle?",
|
||||
|
@ -572,7 +573,7 @@
|
|||
"notification.label.private_reply": "Privátní odpověď",
|
||||
"notification.label.reply": "Odpověď",
|
||||
"notification.mention": "Zmínka",
|
||||
"notification.mentioned_you": "{name} vás zmínil",
|
||||
"notification.mentioned_you": "{name} vás zmínil*a",
|
||||
"notification.moderation-warning.learn_more": "Zjistit více",
|
||||
"notification.moderation_warning": "Obdrželi jste varování od moderátorů",
|
||||
"notification.moderation_warning.action_delete_statuses": "Některé z vašich příspěvků byly odstraněny.",
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} postiad} two {{counter} bostiad} few {{counter} phostiad} many {{counter} postiad} other {{counter} postiad}}",
|
||||
"account.unblock": "Dadrwystro @{name}",
|
||||
"account.unblock_domain": "Dadrwystro parth {domain}",
|
||||
"account.unblock_domain_short": "Dadrwystro",
|
||||
"account.unblock_short": "Dadrwystro",
|
||||
"account.unendorse": "Peidio a'i ddangos ar fy mhroffil",
|
||||
"account.unfollow": "Dad-ddilyn",
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} indlæg} other {{counter} indlæg}}",
|
||||
"account.unblock": "Fjern blokering af @{name}",
|
||||
"account.unblock_domain": "Fjern blokering af domænet {domain}",
|
||||
"account.unblock_domain_short": "Afblokér",
|
||||
"account.unblock_short": "Fjern blokering",
|
||||
"account.unendorse": "Fjern visning på din profil",
|
||||
"account.unfollow": "Følg ikke længere",
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} Beitrag} other {{counter} Beiträge}}",
|
||||
"account.unblock": "{name} nicht mehr blockieren",
|
||||
"account.unblock_domain": "Blockierung von {domain} aufheben",
|
||||
"account.unblock_domain_short": "Entsperren",
|
||||
"account.unblock_short": "Blockierung aufheben",
|
||||
"account.unendorse": "Im Profil nicht mehr empfehlen",
|
||||
"account.unfollow": "Entfolgen",
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} post} other {{counter} posts}}",
|
||||
"account.unblock": "Unblock @{name}",
|
||||
"account.unblock_domain": "Unblock domain {domain}",
|
||||
"account.unblock_domain_short": "Unblock",
|
||||
"account.unblock_short": "Unblock",
|
||||
"account.unendorse": "Don't feature on profile",
|
||||
"account.unfollow": "Unfollow",
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} mensaje} other {{counter} mensajes}}",
|
||||
"account.unblock": "Desbloquear a @{name}",
|
||||
"account.unblock_domain": "Desbloquear dominio {domain}",
|
||||
"account.unblock_domain_short": "Desbloquear",
|
||||
"account.unblock_short": "Desbloquear",
|
||||
"account.unendorse": "No destacar en el perfil",
|
||||
"account.unfollow": "Dejar de seguir",
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} publicación} other {{counter} publicaciones}}",
|
||||
"account.unblock": "Desbloquear a @{name}",
|
||||
"account.unblock_domain": "Mostrar a {domain}",
|
||||
"account.unblock_domain_short": "Desbloquear",
|
||||
"account.unblock_short": "Desbloquear",
|
||||
"account.unendorse": "No mostrar en el perfil",
|
||||
"account.unfollow": "Dejar de seguir",
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} publicación} other {{counter} publicaciones}}",
|
||||
"account.unblock": "Desbloquear a @{name}",
|
||||
"account.unblock_domain": "Desbloquear dominio {domain}",
|
||||
"account.unblock_domain_short": "Desbloquear",
|
||||
"account.unblock_short": "Desbloquear",
|
||||
"account.unendorse": "No mostrar en el perfil",
|
||||
"account.unfollow": "Dejar de seguir",
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} julkaisu} other {{counter} julkaisua}}",
|
||||
"account.unblock": "Kumoa käyttäjän @{name} esto",
|
||||
"account.unblock_domain": "Kumoa verkkotunnuksen {domain} esto",
|
||||
"account.unblock_domain_short": "Kumoa esto",
|
||||
"account.unblock_short": "Kumoa esto",
|
||||
"account.unendorse": "Kumoa suosittelu profiilissasi",
|
||||
"account.unfollow": "Älä seuraa",
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} postur} other {{counter} postar}}",
|
||||
"account.unblock": "Banna ikki @{name}",
|
||||
"account.unblock_domain": "Banna ikki økisnavnið {domain}",
|
||||
"account.unblock_domain_short": "Banna ikki",
|
||||
"account.unblock_short": "Banna ikki",
|
||||
"account.unendorse": "Vís ikki á vanga",
|
||||
"account.unfollow": "Fylg ikki",
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} publicación} other {{counter} publicacións}}",
|
||||
"account.unblock": "Desbloquear @{name}",
|
||||
"account.unblock_domain": "Amosar {domain}",
|
||||
"account.unblock_domain_short": "Desbloquear",
|
||||
"account.unblock_short": "Desbloquear",
|
||||
"account.unendorse": "Non amosar no perfil",
|
||||
"account.unfollow": "Deixar de seguir",
|
||||
|
|
|
@ -64,8 +64,9 @@
|
|||
"account.show_reblogs": "הצג הדהודים מאת @{name}",
|
||||
"account.statuses_counter": "{count, plural, one {הודעה אחת} two {הודעותיים} many {{counter} הודעות} other {{counter} הודעות}}",
|
||||
"account.unblock": "להסיר חסימה ל- @{name}",
|
||||
"account.unblock_domain": "הסירי את החסימה של קהילת {domain}",
|
||||
"account.unblock_short": "הסר חסימה",
|
||||
"account.unblock_domain": "הסרת החסימה של קהילת {domain}",
|
||||
"account.unblock_domain_short": "הסרת חסימה",
|
||||
"account.unblock_short": "הסרת חסימה",
|
||||
"account.unendorse": "אל תקדם בפרופיל",
|
||||
"account.unfollow": "הפסקת מעקב",
|
||||
"account.unmute": "הפסקת השתקת @{name}",
|
||||
|
@ -905,6 +906,12 @@
|
|||
"video.expand": "להרחיב וידאו",
|
||||
"video.fullscreen": "מסך מלא",
|
||||
"video.hide": "להסתיר וידאו",
|
||||
"video.mute": "השתקה",
|
||||
"video.pause": "השהיה",
|
||||
"video.play": "ניגון"
|
||||
"video.play": "ניגון",
|
||||
"video.skip_backward": "דילוג אחורה",
|
||||
"video.skip_forward": "דילוג קדימה",
|
||||
"video.unmute": "ביטול השתקה",
|
||||
"video.volume_down": "הנמכת עוצמת השמע",
|
||||
"video.volume_up": "הגברת עוצמת שמע"
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} bejegyzés} other {{counter} bejegyzés}}",
|
||||
"account.unblock": "@{name} letiltásának feloldása",
|
||||
"account.unblock_domain": "{domain} domain tiltásának feloldása",
|
||||
"account.unblock_domain_short": "Tiltás feloldása",
|
||||
"account.unblock_short": "Tiltás feloldása",
|
||||
"account.unendorse": "Ne jelenjen meg a profilodon",
|
||||
"account.unfollow": "Követés megszüntetése",
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} færsla} other {{counter} færslur}}",
|
||||
"account.unblock": "Aflétta útilokun af @{name}",
|
||||
"account.unblock_domain": "Aflétta útilokun lénsins {domain}",
|
||||
"account.unblock_domain_short": "Aflétta útilokun",
|
||||
"account.unblock_short": "Hætta að loka á",
|
||||
"account.unendorse": "Ekki birta á notandasniði",
|
||||
"account.unfollow": "Hætta að fylgja",
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
"account.unfollow": "Smetti di seguire",
|
||||
"account.unmute": "Riattiva @{name}",
|
||||
"account.unmute_notifications_short": "Riattiva notifiche",
|
||||
"account.unmute_short": "Riattiva",
|
||||
"account.unmute_short": "Attiva audio",
|
||||
"account_note.placeholder": "Clicca per aggiungere una nota",
|
||||
"admin.dashboard.daily_retention": "Tasso di ritenzione dell'utente per giorno, dopo la registrazione",
|
||||
"admin.dashboard.monthly_retention": "Tasso di ritenzione dell'utente per mese, dopo la registrazione",
|
||||
|
@ -905,6 +905,12 @@
|
|||
"video.expand": "Espandi il video",
|
||||
"video.fullscreen": "Schermo intero",
|
||||
"video.hide": "Nascondi il video",
|
||||
"video.mute": "Muta",
|
||||
"video.pause": "Pausa",
|
||||
"video.play": "Riproduci"
|
||||
"video.play": "Riproduci",
|
||||
"video.skip_backward": "Vai indietro",
|
||||
"video.skip_forward": "Vai avanti",
|
||||
"video.unmute": "Muta",
|
||||
"video.volume_down": "Abbassa volume",
|
||||
"video.volume_up": "Alza volume"
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} n tsuffeɣt} other {{counter} n tsuffaɣ}}",
|
||||
"account.unblock": "Serreḥ i @{name}",
|
||||
"account.unblock_domain": "Ssken-d {domain}",
|
||||
"account.unblock_domain_short": "Serreḥ",
|
||||
"account.unblock_short": "Serreḥ",
|
||||
"account.unendorse": "Ur ttwellih ara fell-as deg umaɣnu-inek",
|
||||
"account.unfollow": "Ur ṭṭafaṛ ara",
|
||||
|
@ -77,6 +78,7 @@
|
|||
"alt_text_modal.cancel": "Semmet",
|
||||
"alt_text_modal.done": "Immed",
|
||||
"announcement.announcement": "Ulɣu",
|
||||
"annual_report.summary.most_used_app.most_used_app": "asnas yettwasqedcen s waṭas",
|
||||
"annual_report.summary.most_used_hashtag.none": "Ula yiwen",
|
||||
"annual_report.summary.new_posts.new_posts": "tisuffaɣ timaynutin",
|
||||
"audio.hide": "Ffer amesli",
|
||||
|
@ -162,6 +164,7 @@
|
|||
"confirmations.discard_edit_media.confirm": "Sefsex",
|
||||
"confirmations.edit.confirm": "Ẓreg",
|
||||
"confirmations.edit.message": "Abeddel tura ad d-yaru izen-nni i d-tegreḍ akka tura. Tetḥeqqeḍ tebɣiḍ ad tkemmleḍ?",
|
||||
"confirmations.follow_to_list.confirm": "Ḍfeṛ-it sakin rnu-t ɣer tebdart",
|
||||
"confirmations.logout.confirm": "Ffeɣ",
|
||||
"confirmations.logout.message": "D tidet tebɣiḍ ad teffɣeḍ?",
|
||||
"confirmations.logout.title": "Tebɣiḍ ad teffɣeḍ ssya?",
|
||||
|
@ -245,6 +248,7 @@
|
|||
"filter_modal.select_filter.search": "Nadi neɣ snulfu-d",
|
||||
"filter_modal.select_filter.title": "Sizdeg tassufeɣt-a",
|
||||
"filter_modal.title.status": "Sizdeg tassufeɣt",
|
||||
"filtered_notifications_banner.title": "Ilɣa yettwasizdgen",
|
||||
"firehose.all": "Akk",
|
||||
"firehose.local": "Deg uqeddac-ayi",
|
||||
"firehose.remote": "Iqeddacen nniḍen",
|
||||
|
@ -350,9 +354,12 @@
|
|||
"lists.add_to_lists": "Rnu {name} ɣer tebdarin",
|
||||
"lists.create": "Snulfu-d",
|
||||
"lists.delete": "Kkes tabdart",
|
||||
"lists.done": "Immed",
|
||||
"lists.edit": "Ẓreg tabdart",
|
||||
"lists.list_name": "Isem n tebdart",
|
||||
"lists.new_list_name": "Isem n tebdart tamaynut",
|
||||
"lists.no_lists_yet": "Ulac tibdarin akka tura.",
|
||||
"lists.no_results_found": "Ulac igemmad.",
|
||||
"lists.remove_member": "Kkes",
|
||||
"lists.replies_policy.followed": "Kra n useqdac i yettwaḍefren",
|
||||
"lists.replies_policy.list": "Iɛeggalen n tebdart",
|
||||
|
@ -389,6 +396,7 @@
|
|||
"navigation_bar.follows_and_followers": "Imeḍfaṛen akked wid i teṭṭafaṛeḍ",
|
||||
"navigation_bar.lists": "Tibdarin",
|
||||
"navigation_bar.logout": "Ffeɣ",
|
||||
"navigation_bar.moderation": "Aseɣyed",
|
||||
"navigation_bar.mutes": "Iseqdacen yettwasusmen",
|
||||
"navigation_bar.opened_in_classic_interface": "Tisuffaɣ, imiḍanen akked isebtar-nniḍen igejdanen ldin-d s wudem amezwer deg ugrudem web aklasiki.",
|
||||
"navigation_bar.personal": "Udmawan",
|
||||
|
@ -419,6 +427,7 @@
|
|||
"notification_requests.edit_selection": "Ẓreg",
|
||||
"notification_requests.exit_selection": "Immed",
|
||||
"notification_requests.notifications_from": "Alɣuten sɣur {name}",
|
||||
"notification_requests.title": "Ilɣa yettwasizdgen",
|
||||
"notifications.clear": "Sfeḍ alɣuten",
|
||||
"notifications.clear_confirmation": "Tebɣiḍ s tidet ad tekkseḍ akk alɣuten-inek·em i lebda?",
|
||||
"notifications.column_settings.admin.report": "Ineqqisen imaynuten:",
|
||||
|
@ -463,6 +472,7 @@
|
|||
"onboarding.follows.back": "Uɣal",
|
||||
"onboarding.follows.done": "Immed",
|
||||
"onboarding.follows.search": "Nadi",
|
||||
"onboarding.follows.title": "Ḍfeṛ walbɛaḍ i wakken ad ttebdud",
|
||||
"onboarding.profile.display_name": "Isem ara d-yettwaskanen",
|
||||
"onboarding.profile.display_name_hint": "Isem-ik·im ummid neɣ isem-ik·im n uqeṣṣer…",
|
||||
"onboarding.profile.note": "Tameddurt",
|
||||
|
@ -484,15 +494,18 @@
|
|||
"poll_button.remove_poll": "Kkes asenqed",
|
||||
"privacy.change": "Seggem tabaḍnit n yizen",
|
||||
"privacy.direct.long": "Wid akk i d-yettwabdaren deg tsuffeɣt",
|
||||
"privacy.direct.short": "Abdar uslig",
|
||||
"privacy.private.long": "Ala wid i k·m-yeṭṭafaṛen",
|
||||
"privacy.private.short": "Imeḍfaren",
|
||||
"privacy.public.long": "Kra n win yellan deg Masṭudun neɣ berra-s",
|
||||
"privacy.public.short": "Azayez",
|
||||
"privacy.unlisted.long": "Kra kan yiwarzimen",
|
||||
"privacy.unlisted.short": "Azayez asusam",
|
||||
"privacy_policy.last_updated": "Aleqqem aneggaru {date}",
|
||||
"privacy_policy.title": "Tasertit tabaḍnit",
|
||||
"recommended": "Yettuwelleh",
|
||||
"refresh": "Smiren",
|
||||
"regeneration_indicator.please_stand_by": "Ttxil rǧu.",
|
||||
"relative_time.days": "{number}u",
|
||||
"relative_time.full.just_now": "tura kan",
|
||||
"relative_time.hours": "{number}isr",
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} bericht} other {{counter} berichten}}",
|
||||
"account.unblock": "@{name} deblokkeren",
|
||||
"account.unblock_domain": "{domain} niet langer blokkeren",
|
||||
"account.unblock_domain_short": "Deblokkeren",
|
||||
"account.unblock_short": "Deblokkeren",
|
||||
"account.unendorse": "Niet op profiel weergeven",
|
||||
"account.unfollow": "Ontvolgen",
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} publicação} other {{counter} publicações}}",
|
||||
"account.unblock": "Desbloquear @{name}",
|
||||
"account.unblock_domain": "Desbloquear o domínio {domain}",
|
||||
"account.unblock_domain_short": "Desbloquear",
|
||||
"account.unblock_short": "Desbloquear",
|
||||
"account.unendorse": "Não destacar no perfil",
|
||||
"account.unfollow": "Deixar de seguir",
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} postim} other {{counter} postime}}",
|
||||
"account.unblock": "Zhbllokoje @{name}",
|
||||
"account.unblock_domain": "Zhblloko përkatësinë {domain}",
|
||||
"account.unblock_domain_short": "Zhbllokoje",
|
||||
"account.unblock_short": "Zhbllokoje",
|
||||
"account.unendorse": "Mos e përfshi në profil",
|
||||
"account.unfollow": "Resht së ndjekuri",
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} gönderi} other {{counter} gönderi}}",
|
||||
"account.unblock": "@{name} adlı kişinin engelini kaldır",
|
||||
"account.unblock_domain": "{domain} alan adının engelini kaldır",
|
||||
"account.unblock_domain_short": "Engeli kaldır",
|
||||
"account.unblock_short": "Engeli kaldır",
|
||||
"account.unendorse": "Profilimde öne çıkarma",
|
||||
"account.unfollow": "Takibi bırak",
|
||||
|
@ -905,6 +906,12 @@
|
|||
"video.expand": "Videoyu genişlet",
|
||||
"video.fullscreen": "Tam ekran",
|
||||
"video.hide": "Videoyu gizle",
|
||||
"video.mute": "Sessiz",
|
||||
"video.pause": "Duraklat",
|
||||
"video.play": "Oynat"
|
||||
"video.play": "Oynat",
|
||||
"video.skip_backward": "Geriye atla",
|
||||
"video.skip_forward": "İleriye atla",
|
||||
"video.unmute": "Sesi aç",
|
||||
"video.volume_down": "Sesi kıs",
|
||||
"video.volume_up": "Sesi yükselt"
|
||||
}
|
||||
|
|
|
@ -1,21 +1,34 @@
|
|||
{
|
||||
"about.blocks": "ئوتتۇراھال مۇلازىمېتىر",
|
||||
"about.contact": "ئالاقىلاشقۇچى:",
|
||||
"account.badges.bot": "Bot",
|
||||
"account.cancel_follow_request": "Withdraw follow request",
|
||||
"account.posts": "Toots",
|
||||
"account.posts_with_replies": "Toots and replies",
|
||||
"about.blocks": "باشقۇرۇلىدىغان مۇلازىمېتىر",
|
||||
"about.contact": "ئالاقە:",
|
||||
"about.disclaimer": "Mastodon ھەقسىز، ئوچۇق كودلۇق يۇمشاق دېتال تاۋار ماركىسى Mastodon gGmbH غا تەۋە.",
|
||||
"about.domain_blocks.no_reason_available": "سەۋەبىنى ئىشلەتكىلى بولمايدۇ",
|
||||
"account.badges.bot": "ماشىنا ئادەم",
|
||||
"account.cancel_follow_request": "ئەگىشىش ئىلتىماسىدىن ۋاز كەچ",
|
||||
"account.posts": "يازما",
|
||||
"account.posts_with_replies": "يازما ۋە ئىنكاس",
|
||||
"account.report": "@{name} نى پاش قىل",
|
||||
"account.requested": "Awaiting approval",
|
||||
"account_note.placeholder": "Click to add a note",
|
||||
"column.pins": "Pinned toot",
|
||||
"community.column_settings.media_only": "Media only",
|
||||
"account_note.placeholder": "چېكىلسە ئىزاھات قوشىدۇ",
|
||||
"column.pins": "چوققىلانغان يازما",
|
||||
"community.column_settings.media_only": "ۋاسىتەلا",
|
||||
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
|
||||
"compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
|
||||
"compose_form.placeholder": "What is on your mind?",
|
||||
"compose_form.publish_form": "Publish",
|
||||
"compose_form.spoiler.marked": "Text is hidden behind warning",
|
||||
"compose_form.publish_form": "يېڭى يازما",
|
||||
"compose_form.reply": "جاۋاب",
|
||||
"compose_form.save_changes": "يېڭىلا",
|
||||
"compose_form.spoiler.marked": "مەزمۇن ئاگاھلاندۇرۇشىنى چىقىرىۋەت",
|
||||
"compose_form.spoiler.unmarked": "Text is not hidden",
|
||||
"confirmations.delete.message": "Are you sure you want to delete this status?",
|
||||
"compose_form.spoiler_placeholder": "مەزمۇن ئاگاھلاندۇرۇشى (تاللاشچان)",
|
||||
"confirmation_modal.cancel": "ۋاز كەچ",
|
||||
"confirmations.block.confirm": "توس",
|
||||
"confirmations.delete.message": "بۇ يازمىنى راستىنلا ئۆچۈرەمسىز؟",
|
||||
"confirmations.delete.title": "يازما ئۆچۈرەمدۇ؟",
|
||||
"confirmations.delete_list.confirm": "ئۆچۈر",
|
||||
"confirmations.delete_list.message": "بۇ تىزىمنى راستتىنلا مەڭگۈلۈك ئۆچۈرەمسىز؟",
|
||||
"confirmations.delete_list.title": "تىزىمنى ئۆچۈرەمدۇ؟",
|
||||
"confirmations.discard_edit_media.confirm": "تاشلىۋەت",
|
||||
"embed.instructions": "Embed this status on your website by copying the code below.",
|
||||
"empty_column.account_timeline": "No toots here!",
|
||||
"empty_column.bookmarked_statuses": "You don't have any bookmarked toots yet. When you bookmark one, it will show up here.",
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} допис} few {{counter} дописи} many {{counter} дописів} other {{counter} допис}}",
|
||||
"account.unblock": "Розблокувати @{name}",
|
||||
"account.unblock_domain": "Розблокувати {domain}",
|
||||
"account.unblock_domain_short": "Розблокувати",
|
||||
"account.unblock_short": "Розблокувати",
|
||||
"account.unendorse": "Не публікувати у профілі",
|
||||
"account.unfollow": "Відписатися",
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
"account.statuses_counter": "{count, plural, other {{counter} Tút}}",
|
||||
"account.unblock": "Bỏ chặn @{name}",
|
||||
"account.unblock_domain": "Bỏ ẩn {domain}",
|
||||
"account.unblock_domain_short": "Bỏ chặn",
|
||||
"account.unblock_short": "Bỏ chặn",
|
||||
"account.unendorse": "Ngưng tôn vinh người này",
|
||||
"account.unfollow": "Bỏ theo dõi",
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
"account.statuses_counter": "{count, plural, other {{count} 則嘟文}}",
|
||||
"account.unblock": "解除封鎖 @{name}",
|
||||
"account.unblock_domain": "解除封鎖網域 {domain}",
|
||||
"account.unblock_domain_short": "解除封鎖",
|
||||
"account.unblock_short": "解除封鎖",
|
||||
"account.unendorse": "取消於個人檔案推薦對方",
|
||||
"account.unfollow": "取消跟隨",
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
import { Map as ImmutableMap, OrderedSet as ImmutableOrderedSet } from 'immutable';
|
||||
|
||||
import {
|
||||
DOMAIN_BLOCKS_FETCH_SUCCESS,
|
||||
DOMAIN_BLOCKS_EXPAND_SUCCESS,
|
||||
unblockDomainSuccess
|
||||
} from '../actions/domain_blocks';
|
||||
|
||||
const initialState = ImmutableMap({
|
||||
blocks: ImmutableMap({
|
||||
items: ImmutableOrderedSet(),
|
||||
}),
|
||||
});
|
||||
|
||||
export default function domainLists(state = initialState, action) {
|
||||
switch(action.type) {
|
||||
case DOMAIN_BLOCKS_FETCH_SUCCESS:
|
||||
return state.setIn(['blocks', 'items'], ImmutableOrderedSet(action.domains)).setIn(['blocks', 'next'], action.next);
|
||||
case DOMAIN_BLOCKS_EXPAND_SUCCESS:
|
||||
return state.updateIn(['blocks', 'items'], set => set.union(action.domains)).setIn(['blocks', 'next'], action.next);
|
||||
case unblockDomainSuccess.type:
|
||||
return state.updateIn(['blocks', 'items'], set => set.delete(action.payload.domain));
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
|
@ -11,7 +11,6 @@ import { composeReducer } from './compose';
|
|||
import contexts from './contexts';
|
||||
import conversations from './conversations';
|
||||
import custom_emojis from './custom_emojis';
|
||||
import domain_lists from './domain_lists';
|
||||
import { dropdownMenuReducer } from './dropdown_menu';
|
||||
import filters from './filters';
|
||||
import followed_tags from './followed_tags';
|
||||
|
@ -49,7 +48,6 @@ const reducers = {
|
|||
loadingBar: loadingBarReducer,
|
||||
modal: modalReducer,
|
||||
user_lists,
|
||||
domain_lists,
|
||||
status_lists,
|
||||
accounts: accountsReducer,
|
||||
accounts_map,
|
||||
|
|
|
@ -1882,29 +1882,21 @@ body > [data-popper-placement] {
|
|||
}
|
||||
|
||||
.domain {
|
||||
padding: 10px;
|
||||
padding: 16px;
|
||||
border-bottom: 1px solid var(--background-border-color);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
.domain__domain-name {
|
||||
&__domain-name {
|
||||
flex: 1 1 auto;
|
||||
display: block;
|
||||
color: $primary-text-color;
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
font-size: 15px;
|
||||
line-height: 21px;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.domain__wrapper {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.domain_buttons {
|
||||
height: 18px;
|
||||
padding: 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.account {
|
||||
padding: 16px;
|
||||
border-bottom: 1px solid var(--background-border-color);
|
||||
|
|
|
@ -130,12 +130,7 @@ class ActivityPub::Activity
|
|||
|
||||
def first_mentioned_local_account
|
||||
audience = (as_array(@json['to']) + as_array(@json['cc'])).map { |x| value_or_id(x) }.uniq
|
||||
local_usernames = audience.select { |uri| ActivityPub::TagManager.instance.local_uri?(uri) }
|
||||
.map { |uri| ActivityPub::TagManager.instance.uri_to_local_id(uri, :username) }
|
||||
|
||||
return if local_usernames.empty?
|
||||
|
||||
Account.local.where(username: local_usernames).first
|
||||
ActivityPub::TagManager.instance.uris_to_local_accounts(audience).first
|
||||
end
|
||||
|
||||
def first_local_follower
|
||||
|
|
|
@ -412,11 +412,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
|||
def addresses_local_accounts?
|
||||
return true if @options[:delivered_to_account_id]
|
||||
|
||||
local_usernames = (audience_to + audience_cc).uniq.select { |uri| ActivityPub::TagManager.instance.local_uri?(uri) }.map { |uri| ActivityPub::TagManager.instance.uri_to_local_id(uri, :username) }
|
||||
|
||||
return false if local_usernames.empty?
|
||||
|
||||
Account.local.exists?(username: local_usernames)
|
||||
ActivityPub::TagManager.instance.uris_to_local_accounts((audience_to + audience_cc).uniq).exists?
|
||||
end
|
||||
|
||||
def tombstone_exists?
|
||||
|
|
|
@ -203,6 +203,19 @@ class ActivityPub::TagManager
|
|||
path_params[param]
|
||||
end
|
||||
|
||||
def uris_to_local_accounts(uris)
|
||||
usernames = []
|
||||
ids = []
|
||||
|
||||
uris.each do |uri|
|
||||
param, value = uri_to_local_account_params(uri)
|
||||
usernames << value.downcase if param == :username
|
||||
ids << value if param == :id
|
||||
end
|
||||
|
||||
Account.local.with_username(usernames).or(Account.local.where(id: ids))
|
||||
end
|
||||
|
||||
def uri_to_actor(uri)
|
||||
uri_to_resource(uri, Account)
|
||||
end
|
||||
|
@ -213,7 +226,7 @@ class ActivityPub::TagManager
|
|||
if local_uri?(uri)
|
||||
case klass.name
|
||||
when 'Account'
|
||||
klass.find_local(uri_to_local_id(uri, :username))
|
||||
uris_to_local_accounts([uri]).first
|
||||
else
|
||||
StatusFinder.new(uri).status
|
||||
end
|
||||
|
@ -225,4 +238,20 @@ class ActivityPub::TagManager
|
|||
rescue ActiveRecord::RecordNotFound
|
||||
nil
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def uri_to_local_account_params(uri)
|
||||
return unless local_uri?(uri)
|
||||
|
||||
path_params = Rails.application.routes.recognize_path(uri)
|
||||
|
||||
# TODO: handle numeric IDs
|
||||
case path_params[:controller]
|
||||
when 'accounts'
|
||||
[:username, path_params[:username]]
|
||||
when 'instance_actors'
|
||||
[:id, -99]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -53,11 +53,11 @@ class Fasp::Request
|
|||
|
||||
def validate!(response)
|
||||
content_digest_header = response.headers['content-digest']
|
||||
raise SignatureVerification::SignatureVerificationError, 'content-digest missing' if content_digest_header.blank?
|
||||
raise SignatureVerification::SignatureVerificationError, 'content-digest does not match' if content_digest_header != content_digest(response.body)
|
||||
raise Mastodon::SignatureVerificationError, 'content-digest missing' if content_digest_header.blank?
|
||||
raise Mastodon::SignatureVerificationError, 'content-digest does not match' if content_digest_header != content_digest(response.body)
|
||||
|
||||
signature_input = response.headers['signature-input']&.encode('UTF-8')
|
||||
raise SignatureVerification::SignatureVerificationError, 'signature-input is missing' if signature_input.blank?
|
||||
raise Mastodon::SignatureVerificationError, 'signature-input is missing' if signature_input.blank?
|
||||
|
||||
linzer_response = Linzer.new_response(
|
||||
response.body,
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
class Poll < ApplicationRecord
|
||||
include Expireable
|
||||
|
||||
MAKE_FETCH_HAPPEN = 1.minute
|
||||
|
||||
belongs_to :account
|
||||
belongs_to :status
|
||||
|
||||
|
@ -113,7 +115,7 @@ class Poll < ApplicationRecord
|
|||
end
|
||||
|
||||
def time_passed_since_last_fetch?
|
||||
last_fetched_at.nil? || last_fetched_at < 1.minute.ago
|
||||
last_fetched_at.nil? || last_fetched_at < MAKE_FETCH_HAPPEN.ago
|
||||
end
|
||||
|
||||
def show_totals_now?
|
||||
|
|
|
@ -30,10 +30,7 @@ class ActivityPub::SynchronizeFollowersService < BaseService
|
|||
# Account record, and should we not do that, we should have sent a Delete.
|
||||
# In any case there is not much we can do if that occurs.
|
||||
|
||||
# TODO: this will need changes when switching to numeric IDs
|
||||
|
||||
usernames = items.filter_map { |uri| ActivityPub::TagManager.instance.uri_to_local_id(uri, :username)&.downcase }
|
||||
Account.local.with_username(usernames)
|
||||
ActivityPub::TagManager.instance.uris_to_local_accounts(items)
|
||||
end
|
||||
|
||||
def remove_unexpected_local_followers!
|
||||
|
|
|
@ -79,6 +79,8 @@ br:
|
|||
public: Publik
|
||||
reject: Nac'hañ
|
||||
remove_header: Dilemel an talbenn
|
||||
resend_confirmation:
|
||||
send: Adkas al liamm-kadarnaat
|
||||
reset: Adderaouekaat
|
||||
reset_password: Adderaouekaat ar ger-tremen
|
||||
resubscribe: Adkoumanantiñ
|
||||
|
@ -99,6 +101,12 @@ br:
|
|||
web: Web
|
||||
action_logs:
|
||||
action_types:
|
||||
approve_user: Aprouiñ an implijer
|
||||
change_role_user: Kemmañ perzh an implijer
|
||||
confirm_user: Aprouiñ an implijer
|
||||
create_ip_block: Krouiñ ur reolenn IP
|
||||
create_user_role: Krouiñ ur perzh
|
||||
destroy_ip_block: Dilemel ar reolenn IP
|
||||
destroy_status: Dilemel ar c'hannad
|
||||
reset_password_user: Adderaouekaat ar ger-tremen
|
||||
update_status: Hizivaat ar c'hannad
|
||||
|
@ -141,12 +149,15 @@ br:
|
|||
export: Ezporzhiañ
|
||||
import: Enporzhiañ
|
||||
domain_blocks:
|
||||
confirm_suspension:
|
||||
cancel: Nullañ
|
||||
domain: Domani
|
||||
new:
|
||||
create: Sevel ur stanker
|
||||
severity:
|
||||
noop: Hini ebet
|
||||
suspend: Astalañ
|
||||
public_comment: Evezhiadenn foran
|
||||
email_domain_blocks:
|
||||
add_new: Ouzhpenniñ unan nevez
|
||||
delete: Dilemel
|
||||
|
@ -158,6 +169,18 @@ br:
|
|||
create: Ouzhpenniñ un domani
|
||||
export_domain_allows:
|
||||
no_file: Restr ebet diuzet
|
||||
fasp:
|
||||
debug:
|
||||
callbacks:
|
||||
delete: Dilemel
|
||||
ip: Chomlec'h IP
|
||||
providers:
|
||||
active: Oberiant
|
||||
delete: Dilemel
|
||||
name: Anv
|
||||
registrations:
|
||||
confirm: Kadarnaat
|
||||
status: Statud
|
||||
follow_recommendations:
|
||||
status: Statud
|
||||
suppressed: Dilamet
|
||||
|
@ -172,6 +195,7 @@ br:
|
|||
suspend: Astalañ
|
||||
policy: Reolennoù
|
||||
dashboard:
|
||||
instance_languages_dimension: Yezhoù pennañ
|
||||
instance_statuses_measure: toudoù stoket
|
||||
delivery:
|
||||
all: Pep tra
|
||||
|
@ -182,6 +206,9 @@ br:
|
|||
title: Habaskadur
|
||||
purge: Spurjañ
|
||||
title: Kevread
|
||||
total_blocked_by_us: Stanket ganeomp
|
||||
total_followed_by_them: Heuliet ganto
|
||||
total_followed_by_us: Heuliet ganeomp
|
||||
total_storage: Restroù media stag
|
||||
invites:
|
||||
filter:
|
||||
|
@ -191,6 +218,7 @@ br:
|
|||
title: Sil
|
||||
title: Pedadennoù
|
||||
ip_blocks:
|
||||
add_new: Krouiñ ur reolenn
|
||||
delete: Dilemel
|
||||
expires_in:
|
||||
'1209600': 2 sizhunvezh
|
||||
|
@ -198,6 +226,9 @@ br:
|
|||
'31556952': 1 bloavezh
|
||||
'86400': 1 devezh
|
||||
'94670856': 3 bloavezh
|
||||
new:
|
||||
title: Krouiñ ur reolenn IP nevez
|
||||
title: Reolennoù IP
|
||||
relays:
|
||||
delete: Dilemel
|
||||
disable: Diweredekaat
|
||||
|
@ -218,6 +249,7 @@ br:
|
|||
are_you_sure: Ha sur oc'h?
|
||||
comment:
|
||||
none: Hini ebet
|
||||
confirm: Kadarnaat
|
||||
delete_and_resolve: Dilemel ar c'hannadoù
|
||||
forwarded: Treuzkaset
|
||||
no_one_assigned: Den ebet
|
||||
|
|
|
@ -232,7 +232,7 @@ he:
|
|||
silence_account: הגבלת חשבון
|
||||
suspend_account: השעיית חשבון
|
||||
unassigned_report: ביטול הקצאת דו"ח
|
||||
unblock_email_account: ביטול חסימת כתובת דוא"ל
|
||||
unblock_email_account: הסרת חסימת כתובת דוא"ל
|
||||
unsensitive_account: ביטול Force-Sensitive לחשבון
|
||||
unsilence_account: ביטול השתקת חשבון
|
||||
unsuspend_account: ביטול השעיית חשבון
|
||||
|
@ -263,11 +263,11 @@ he:
|
|||
create_user_role_html: "%{name} יצר את התפקיד של %{target}"
|
||||
demote_user_html: "%{name} הוריד/ה בדרגה את המשתמש %{target}"
|
||||
destroy_announcement_html: "%{name} מחק/ה את ההכרזה %{target}"
|
||||
destroy_canonical_email_block_html: "%{name} הסיר/ה חסימה מדואל %{target}"
|
||||
destroy_canonical_email_block_html: "%{name} הסירו חסימה מדואל %{target}"
|
||||
destroy_custom_emoji_html: "%{name} מחק אמוג'י של %{target}"
|
||||
destroy_domain_allow_html: "%{name} לא התיר/ה פדרציה עם הדומיין %{target}"
|
||||
destroy_domain_block_html: "%{name} הסיר/ה חסימה מהדומיין %{target}"
|
||||
destroy_email_domain_block_html: '%{name} הסיר/ה חסימה מדומיין הדוא"ל %{target}'
|
||||
destroy_domain_block_html: החסימה על מתחם %{target} הוסרה ע"י %{name}
|
||||
destroy_email_domain_block_html: הוסרה חסימת מתחם דוא"ל %{target} בידי %{name}
|
||||
destroy_instance_html: "%{name} טיהר/ה את הדומיין %{target}"
|
||||
destroy_ip_block_html: "%{name} מחק/ה את הכלל עבור IP %{target}"
|
||||
destroy_relay_html: "%{name} מחקו את הממסר %{target}"
|
||||
|
@ -495,6 +495,36 @@ he:
|
|||
new:
|
||||
title: יבוא רשימת שרתים חסומים
|
||||
no_file: לא נבחר קובץ
|
||||
fasp:
|
||||
debug:
|
||||
callbacks:
|
||||
created_at: תאריך יצירה
|
||||
delete: מחיקה
|
||||
ip: כתובת IP
|
||||
request_body: גוף הבקשה
|
||||
title: ניפוי תקלות בקריאות חוזרות
|
||||
providers:
|
||||
active: פעילים
|
||||
base_url: קישור בסיס
|
||||
callback: קריאה חוזרת
|
||||
delete: מחיקה
|
||||
edit: עריכת ספק
|
||||
finish_registration: סיום הרשמה
|
||||
name: שם
|
||||
providers: ספקים
|
||||
public_key_fingerprint: טביעת האצבע של המפתח הציבורי
|
||||
registration_requested: נדרשת הרשמה
|
||||
registrations:
|
||||
confirm: אישור
|
||||
description: קיבלת הרשמה דרך FASP. יש לדחות אותה אם לא ביקשת את ההרשמה הזו מיוזמתך. אם זו בקשה מיוזמתך, יש להשוות בהקפדה אם השם וטביעת האצבע של המפתח הציבורי תואמים לפני אישור הרישום.
|
||||
reject: דחיה
|
||||
title: אישור הרשמת FASP
|
||||
save: שמירה
|
||||
select_capabilities: בחירת יכולות
|
||||
sign_in: כניסה
|
||||
status: מצב
|
||||
title: ספקי משנה לפדיוורס
|
||||
title: פרוטוקול FASP
|
||||
follow_recommendations:
|
||||
description_html: "<strong>עקבו אחר ההמלצות על מנת לעזור למשתמשים חדשים למצוא תוכן מעניין</strong>. במידה ומשתמש לא תקשר מספיק עם משתמשים אחרים כדי ליצור המלצות מעקב, חשבונות אלה יומלצו במקום. הם מחושבים מחדש על בסיסי יומיומי מתערובת של החשבונות הפעילים ביותר עם החשבונות הנעקבים ביותר עבור שפה נתונה."
|
||||
language: עבור שפה
|
||||
|
|
|
@ -479,6 +479,36 @@ it:
|
|||
new:
|
||||
title: Importare i blocchi di dominio
|
||||
no_file: Nessun file selezionato
|
||||
fasp:
|
||||
debug:
|
||||
callbacks:
|
||||
created_at: Creato il
|
||||
delete: Cancella
|
||||
ip: Indirizzo IP
|
||||
request_body: Request body
|
||||
title: Debug Callbacks
|
||||
providers:
|
||||
active: Attivo
|
||||
base_url: Url di base
|
||||
callback: Callback
|
||||
delete: Cancella
|
||||
edit: Modifica Provider
|
||||
finish_registration: Registrazione terminata
|
||||
name: Nome
|
||||
providers: Providers
|
||||
public_key_fingerprint: Chiave pubblica fingerprint
|
||||
registration_requested: Registrazione richiesta
|
||||
registrations:
|
||||
confirm: Conferma
|
||||
description: Hai ricevuto una registrazione da un FASP. Rifiutala se non l'hai avviata tu. Se l'hai avviata tu, confronta attentamente nome e impronta della chiave prima di confermare la registrazione.
|
||||
reject: Rifiuta
|
||||
title: Conferma registrazione FASP
|
||||
save: Salva
|
||||
select_capabilities: Seleziona Capacità
|
||||
sign_in: Connettiti
|
||||
status: Stato
|
||||
title: Fornitori di Servizi Ausiliari per il Fediverso
|
||||
title: FASP
|
||||
follow_recommendations:
|
||||
description_html: "<strong>I consigli su chi seguire aiutano i nuovi utenti a trovare rapidamente dei contenuti interessanti</strong>. Quando un utente non ha interagito abbastanza con altri per avere dei consigli personalizzati, vengono consigliati questi account. Sono ricalcolati ogni giorno da un misto di account con le più alte interazioni recenti e con il maggior numero di seguaci locali per una data lingua."
|
||||
language: Per lingua
|
||||
|
|
|
@ -268,6 +268,15 @@ kab:
|
|||
no_file: Ula d yiwen ufaylu ma yettwafran
|
||||
export_domain_blocks:
|
||||
no_file: Ulac afaylu yettwafernen
|
||||
fasp:
|
||||
debug:
|
||||
callbacks:
|
||||
delete: Kkes
|
||||
ip: Tansa IP
|
||||
providers:
|
||||
delete: Kkes
|
||||
save: Sekles
|
||||
title: FASP
|
||||
follow_recommendations:
|
||||
language: I tutlayt
|
||||
status: Addad
|
||||
|
@ -378,6 +387,7 @@ kab:
|
|||
everyone: Tisirag timezwura
|
||||
privileges:
|
||||
administrator: Anedbal
|
||||
view_dashboard: Timẓriwt n tfelwit
|
||||
rules:
|
||||
add_new: Rnu alugen
|
||||
delete: Kkes
|
||||
|
@ -391,6 +401,7 @@ kab:
|
|||
title: Udem
|
||||
discovery:
|
||||
profile_directory: Akaram n imaɣnuten
|
||||
title: Asnirem
|
||||
trends: Ayen mucaɛen
|
||||
domain_blocks:
|
||||
all: I medden akk
|
||||
|
@ -431,6 +442,9 @@ kab:
|
|||
software_version_patch_check:
|
||||
action: Wali ileqqman yellan
|
||||
tags:
|
||||
name: Isem
|
||||
newest: Amaynut
|
||||
oldest: Aqbur
|
||||
search: Anadi
|
||||
title: Ihacṭagen
|
||||
terms_of_service:
|
||||
|
@ -705,6 +719,7 @@ kab:
|
|||
units:
|
||||
billion: AṬ
|
||||
million: A
|
||||
thousand: GM
|
||||
trillion: Am
|
||||
otp_authentication:
|
||||
enable: Rmed
|
||||
|
@ -864,6 +879,7 @@ kab:
|
|||
warning:
|
||||
categories:
|
||||
spam: Aspam
|
||||
reason: 'Taɣẓint:'
|
||||
title:
|
||||
disable: Amiḍan i igersen
|
||||
none: Ɣur-wat
|
||||
|
|
|
@ -304,6 +304,7 @@ lv:
|
|||
title: Audita žurnāls
|
||||
unavailable_instance: "(domēna vārds nav pieejams)"
|
||||
announcements:
|
||||
back: Atgriezties pie paziņojumiem
|
||||
destroyed_msg: Paziņojums sekmīgi izdzēsts.
|
||||
edit:
|
||||
title: Labot paziņojumu
|
||||
|
@ -312,6 +313,9 @@ lv:
|
|||
new:
|
||||
create: Izveidot paziņojumu
|
||||
title: Jauns paziņojums
|
||||
preview:
|
||||
explanation_html: 'E-pasta ziņojums tiks nosūtīts <strong>%{display_count} lietotājiem</strong>. Šis teksts tiks iekļauts e-pasta ziņojumā:'
|
||||
title: Priekšskatīt paziņojumu
|
||||
publish: Publicēt
|
||||
published_msg: Paziņojums sekmīgi publicēts.
|
||||
scheduled_for: Plānots uz %{time}
|
||||
|
@ -455,7 +459,9 @@ lv:
|
|||
create: Pievienot domēnu
|
||||
resolve: Atrisināt domēnu
|
||||
title: Liegt jaunu e-pasta domēnu
|
||||
no_email_domain_block_selected: Neviens e-pasta domēna bloks netika mainīts, jo neviens netika atlasīts
|
||||
not_permitted: Nav atļauta
|
||||
resolved_dns_records_hint_html: Domēna vārds saistās ar zemāk norādītajiem MX domēniem, kuri beigās ir atbildīgi par e-pasta pieņemšana. MX domēna liegšana liegs reģistrēšanos no jebkuras e-pasta adreses, kas izmanto to pašu MX domēnu, pat ja redzamais domēna vārds ir atšķirīgs. <strong>Jāuzmanās, lai neliegtu galvenos e-pasta pakalpojuma sniedzējus.</strong>
|
||||
resolved_through_html: Atrisināts, izmantojot %{domain}
|
||||
title: Bloķētie e-pasta domēni
|
||||
export_domain_allows:
|
||||
|
@ -473,6 +479,13 @@ lv:
|
|||
new:
|
||||
title: Importēt bloķētos domēnus
|
||||
no_file: Nav atlasīts neviens fails
|
||||
fasp:
|
||||
debug:
|
||||
callbacks:
|
||||
created_at: Izveidots
|
||||
delete: Izdzēst
|
||||
ip: IP adrese
|
||||
request_body: Pieprasījuma saturs
|
||||
follow_recommendations:
|
||||
description_html: "<strong>Sekošanas ieteikumi palīdz jauniem lietotājiem ātri arast saistošu saturu</strong>. Kad lietotājs nav pietiekami mijiedarbojies ar citiem, lai veidotos pielāgoti sekošanas iteikumi, tiek ieteikti šie konti. Tie tiek pārskaitļoti ik dienas, izmantojot kontu, kuriem ir augstākās nesenās iesaistīšanās un lielākais vietējo sekotāju skaits norādītajā valodā."
|
||||
language: Valodai
|
||||
|
@ -934,6 +947,7 @@ lv:
|
|||
chance_to_review_html: "<strong>Izveidotie pakalpojuma izmantošanas noteikumi netiks laisti klajā automātiski.</strong> Būs iespēja izskatīt iznākumu. Lūgums norādīt nepieciešamo informāciju, lai turpinātu."
|
||||
explanation_html: Pakalpojuma izmantošanas noteikumu sagatave tiek piedāvāta tikai izzināšanas nolūkam, un to nevajadzētu izmantot kā juridisku padomu jebkurā jautājumā. Lūgums sazināties ar savu juridisko padomdevēju par saviem apstākļiem un noteiktiem juridiskiem jautājumiem.
|
||||
title: Pakalpojuma izmantošānas noteikumu uzstādīšana
|
||||
going_live_on_html: Darbībā, spēkā no %{date}
|
||||
history: Vēsture
|
||||
live: Darbībā
|
||||
no_history: Nav ierakstu par pakalpojuma izmantošanas noteikumu izmaiņām.
|
||||
|
@ -1060,6 +1074,7 @@ lv:
|
|||
admin_mailer:
|
||||
auto_close_registrations:
|
||||
body: Nesenu satura pārraudzības darbību trūkuma dēļ reģistrācija %{instance} ir automātiski pārslēgta nepieciešamība pēc pašrocīgas izskatīšanas, lai novērstu %{instance} izmantošana kā platformu iespējami sliktiem dalībniekiem. Jebkurā brīdī var ieslēgt atpakaļ atvērtu reģistrēšanos.
|
||||
subject: Reģistrēšanās %{instance} tika automātiski pārslēgta, lai pieprasītu apstiprināšanu
|
||||
new_appeal:
|
||||
actions:
|
||||
delete_statuses: lai izdzēstu viņu ierakstus
|
||||
|
@ -1186,6 +1201,7 @@ lv:
|
|||
set_new_password: Iestatīt jaunu paroli
|
||||
setup:
|
||||
email_below_hint_html: Jāpārbauda sava surogātpasta mape vai jāpieprasa vēl vienu! Savu e-pasta adresi var labot, ja tā ir nepareiza.
|
||||
email_settings_hint_html: Jāatver saite, kuru mēs nosūtījām uz %{email}, lai sāktu izmantot Mastodon. Mēs gaidīsim šeit pat.
|
||||
link_not_received: Vai nesaņēmi sati?
|
||||
new_confirmation_instructions_sent: Pēc dažām minūtēm saņemsi jaunu e-pasta ziņojumu ar apstiprinājuma saiti.
|
||||
title: Pārbaudi savu iesūtni
|
||||
|
@ -1194,21 +1210,27 @@ lv:
|
|||
title: Pieteikties %{domain}
|
||||
sign_up:
|
||||
manual_review: Reģistrāciju %{domain} pašrocīgi izskata mūsu satura pārraudzītāji. Lai palīdzētu mums apstrādāt Tavu reģistrāciju, uzraksti mazliet par sevi un to, kāpēc vēlies kontu %{domain}!
|
||||
preamble: Ar kontu šajā Mastodon serverī varēsi sekot jebkuram citam cilvēkam fediversā, neatkarīgi no tā, kur tiek mitināts viņu konts.
|
||||
title: Atļauj tevi iestatīt %{domain}.
|
||||
status:
|
||||
account_status: Konta statuss
|
||||
confirming: Gaida e-pasta adreses apstiprināšanas pabeigšanu.
|
||||
functional: Tavs konts ir pilnā darba kārtībā.
|
||||
pending: Tavs pieteikums ir rindā uz izskatīšanu, ko veic mūsu personāls. Tas var aizņemt kādu laiku. Tu saņemsi e-pasta ziņojumu, ja Tavs pieteikums tiks apstiprināts.
|
||||
redirecting_to: Tavs konts ir neaktīvs, jo pašlaik tas tiek novirzīts uz %{acct}.
|
||||
self_destruct: Tā kā %{domain} tiek slēgts, tu iegūsi tikai ierobežotu piekļuvi savam kontam.
|
||||
view_strikes: Skati iepriekšējos brīdinājumus par savu kontu
|
||||
too_fast: Veidlapa ir iesniegta pārāk ātri, mēģini vēlreiz.
|
||||
use_security_key: Lietot drošības atslēgu
|
||||
user_agreement_html: Es esmu izlasījis un piekrītu <a href="%{terms_of_service_path}" target="_blank">pakalpojuma izmantošanas noteikumiem</a> un <a href="%{privacy_policy_path}" target="_blank">privātuma nosacījumiem</a>
|
||||
user_privacy_agreement_html: Es izlasīju un piekrītu <a href="%{privacy_policy_path}" target="_blank">privātuma pamatnostādnēm</a>
|
||||
author_attribution:
|
||||
example_title: Parauga teksts
|
||||
hint_html: Vai Tu Raksti ziņu vai emuāra rakstus ārpus Mastodon? Pārraugi apliecinājumus, kad raksti tiek kopīgoti Mastodon.
|
||||
instructions: 'Jāpārliecinās, ka šis kods ir raksta HTML:'
|
||||
more_from_html: Vairāk no %{name}
|
||||
s_blog: "%{name} emuāri"
|
||||
then_instructions: Tad jāpievieno publicējuma domēna vārds zemāk esošajā laukā.
|
||||
title: Autora attiecinājums
|
||||
challenge:
|
||||
confirm: Turpināt
|
||||
|
@ -1413,6 +1435,48 @@ lv:
|
|||
merge_long: Saglabāt esošos ierakstus un pievienot jaunus
|
||||
overwrite: Pārrakstīt
|
||||
overwrite_long: Nomainīt pašreizējos ierakstus ar jauniem
|
||||
overwrite_preambles:
|
||||
blocking_html:
|
||||
one: Tu gatavojies <strong>aizstāt savu lieguma sarakstu</strong> ar līdz <strong>%{count} kontam</strong> no <strong>%{filename}</strong>.
|
||||
other: Tu gatavojies <strong>aizstāt savu lieguma sarakstu</strong> ar līdz <strong>%{count} kontiem</strong> no <strong>%{filename}</strong>.
|
||||
zero: Tu gatavojies <strong>aizstāt savu lieguma sarakstu</strong> ar līdz <strong>%{count} kontiem</strong> no <strong>%{filename}</strong>.
|
||||
bookmarks_html:
|
||||
one: Tu gatavojies <strong>aizstāt savas grāmatzīmes</strong> ar līdz <strong>%{count} ierakstam</strong> no <strong>%{filename}</strong>.
|
||||
other: Tu gatavojies <strong>aizstāt savas grāmatzīmes</strong> ar līdz <strong>%{count} ierakstiem</strong> no <strong>%{filename}</strong>.
|
||||
zero: Tu gatavojies <strong>aizstāt savas grāmatzīmes</strong> ar līdz <strong>%{count} ierakstiem</strong> no <strong>%{filename}</strong>.
|
||||
domain_blocking_html:
|
||||
one: Tu gatavojies <strong>aizstāt savu liegto domēnu sarakstu</strong> ar līdz <strong>%{count} domēnam</strong> no <strong>%{filename}</strong>.
|
||||
other: Tu gatavojies <strong>aizstāt savu liegto domēnu sarakstu</strong> ar līdz <strong>%{count} domēniem</strong> no <strong>%{filename}</strong>.
|
||||
zero: Tu gatavojies <strong>aizstāt savu liegto domēnu sarakstu</strong> ar līdz <strong>%{count} domēniem</strong> no <strong>%{filename}</strong>.
|
||||
following_html:
|
||||
one: Tu gatavojies <strong>sekot</strong> līdz <strong>%{count} kontam</strong> no <strong>%{filename}</strong> un <strong>pārtrauksi sekot citiem</strong>.
|
||||
other: Tu gatavojies <strong>sekot</strong> līdz <strong>%{count} kontiem</strong> no <strong>%{filename}</strong> un <strong>pārtrauksi sekot citiem</strong>.
|
||||
zero: Tu gatavojies <strong>sekot</strong> līdz <strong>%{count} kontiem</strong> no <strong>%{filename}</strong> un <strong>pārtrauksi sekot citiem</strong>.
|
||||
lists_html:
|
||||
one: Tu gatavojies <strong>aizstāt savus sarakstus</strong> ar <strong>%{filename}</strong> saturu. Līdz <strong>%{count} kontam</strong> tiks pievienoti jaunajos sarakstos.
|
||||
other: Tu gatavojies <strong>aizstāt savus sarakstus</strong> ar <strong>%{filename}</strong> saturu. Līdz <strong>%{count} kontiem</strong> tiks pievienoti jaunajos sarakstos.
|
||||
zero: Tu gatavojies <strong>aizstāt savus sarakstus</strong> ar <strong>%{filename}</strong> saturu. Līdz <strong>%{count} kontiem</strong> tiks pievienoti jaunajos sarakstos.
|
||||
muting_html:
|
||||
one: Tu gatavojies <strong>aizstāt savu apklusināto kontu sarakstu</strong> ar līdz <strong>%{count} kontam</strong> no <strong>%{filename}</strong>.
|
||||
other: Tu gatavojies <strong>aizstāt savu apklusināto kontu sarakstu</strong> ar līdz <strong>%{count} kontiem</strong> no <strong>%{filename}</strong>.
|
||||
zero: Tu gatavojies <strong>aizstāt savu apklusināto kontu sarakstu</strong> ar līdz <strong>%{count} kontiem</strong> no <strong>%{filename}</strong>.
|
||||
preambles:
|
||||
blocking_html:
|
||||
one: Tu gatavojies <strong>liegt</strong> līdz <strong>%{count} kontam</strong> no <strong>%{filename}</strong>.
|
||||
other: Tu gatavojies <strong>liegt</strong> līdz <strong>%{count} kontiem</strong> no <strong>%{filename}</strong>.
|
||||
zero: Tu gatavojies <strong>liegt</strong> līdz <strong>%{count} kontiem</strong> no <strong>%{filename}</strong>.
|
||||
bookmarks_html:
|
||||
one: Tu gatavojies pievienot līdz <strong>%{count} ierakstam</strong> no <strong>%{filename}</strong> savām <strong>grāmatzīmēm</strong>.
|
||||
other: Tu gatavojies pievienot līdz <strong>%{count} ierakstiem</strong> no <strong>%{filename}</strong> savām <strong>grāmatzīmēm</strong>.
|
||||
zero: Tu gatavojies pievienot līdz <strong>%{count} ierakstiem</strong> no <strong>%{filename}</strong> savām <strong>grāmatzīmēm</strong>.
|
||||
domain_blocking_html:
|
||||
one: Tu gatavojies <strong>liegt</strong> līdz <strong>%{count} domēnam</strong> no <strong>%{filename}</strong>.
|
||||
other: Tu gatavojies <strong>liegt</strong> līdz <strong>%{count} domēniem</strong> no <strong>%{filename}</strong>.
|
||||
zero: Tu gatavojies <strong>liegt</strong> līdz <strong>%{count} domēniem</strong> no <strong>%{filename}</strong>.
|
||||
following_html:
|
||||
one: Tu gatavojies <strong>sekot</strong> līdz <strong>%{count} kontam</strong> no <strong>%{filename}</strong>.
|
||||
other: Tu gatavojies <strong>sekot</strong> līdz <strong>%{count} kontiem</strong> no <strong>%{filename}</strong>.
|
||||
zero: Tu gatavojies <strong>sekot</strong> līdz <strong>%{count} kontiem</strong> no <strong>%{filename}</strong>.
|
||||
preface: Tu vari ievietot datus, kurus esi izguvis no cita servera, kā, piemēram, cilvēku sarakstu, kuriem Tu seko vai kurus bloķē.
|
||||
recent_imports: Nesen importēts
|
||||
states:
|
||||
|
|
|
@ -84,7 +84,7 @@ de:
|
|||
backups_retention_period: Nutzer*innen haben die Möglichkeit, Archive ihrer Beiträge zu erstellen, die sie später herunterladen können. Wenn ein positiver Wert gesetzt ist, werden diese Archive nach der festgelegten Anzahl von Tagen automatisch aus deinem Speicher gelöscht.
|
||||
bootstrap_timeline_accounts: Diese Konten werden bei den Follower-Empfehlungen für neu registrierte Nutzer*innen oben angeheftet.
|
||||
closed_registrations_message: Wird angezeigt, wenn Registrierungen deaktiviert sind
|
||||
content_cache_retention_period: Sämtliche Beiträge von anderen Servern (einschließlich geteilte Beiträge und Antworten) werden, unabhängig von der Interaktion der lokalen Nutzer*innen mit diesen Beiträgen, nach der festgelegten Anzahl von Tagen gelöscht. Das betrifft auch Beiträge, die von lokalen Nutzer*innen favorisiert oder als Lesezeichen gespeichert wurden. Private Erwähnungen zwischen Nutzer*innen von verschiedenen Servern werden ebenfalls verloren gehen und können nicht wiederhergestellt werden. Das Verwenden dieser Option richtet sich ausschließlich an Server für spezielle Zwecke und wird die allgemeine Nutzungserfahrung beeinträchtigen, wenn sie für den allgemeinen Gebrauch aktiviert ist.
|
||||
content_cache_retention_period: Sämtliche Beiträge von anderen Servern (einschließlich geteilte Beiträge und Antworten) werden, unabhängig von der Interaktion der lokalen Nutzer*innen mit diesen Beiträgen, nach der festgelegten Anzahl von Tagen gelöscht. Das betrifft auch Beiträge, die von lokalen Nutzer*innen favorisiert oder als Lesezeichen gespeichert wurden. Private Erwähnungen zwischen Nutzer*innen von verschiedenen Servern werden ebenfalls verloren gehen und können nicht wiederhergestellt werden. Diese Option richtet sich ausschließlich an Server mit speziellen Zwecken und wird die allgemeine Nutzungserfahrung beeinträchtigen, wenn sie für den allgemeinen Gebrauch aktiviert ist.
|
||||
custom_css: Du kannst benutzerdefinierte Stile auf die Web-Version von Mastodon anwenden.
|
||||
favicon: WEBP, PNG, GIF oder JPG. Überschreibt das Standard-Mastodon-Favicon mit einem eigenen Symbol.
|
||||
mascot: Überschreibt die Abbildung in der erweiterten Weboberfläche.
|
||||
|
|
|
@ -75,7 +75,7 @@ es-MX:
|
|||
filters:
|
||||
action: Elegir qué acción realizar cuando una publicación coincide con el filtro
|
||||
actions:
|
||||
blur: Ocultar contenido multimedia detrás de una advertencia, sin ocultar el texto en sí
|
||||
blur: Ocultar contenido multimedia detrás de una advertencia, sin ocultar el propio texto
|
||||
hide: Ocultar completamente el contenido filtrado, comportándose como si no existiera
|
||||
warn: Ocultar el contenido filtrado detrás de una advertencia mencionando el título del filtro
|
||||
form_admin_settings:
|
||||
|
@ -89,7 +89,7 @@ es-MX:
|
|||
favicon: WEBP, PNG, GIF o JPG. Reemplaza el icono predeterminado de Mastodon con un icono personalizado.
|
||||
mascot: Reemplaza la ilustración en la interfaz web avanzada.
|
||||
media_cache_retention_period: Los archivos multimedia de las publicaciones realizadas por usuarios remotos se almacenan en caché en su servidor. Si se establece en un valor positivo, los archivos multimedia se eliminarán tras el número de días especificado. Si los datos multimedia se solicitan después de haber sido eliminados, se volverán a descargar, si el contenido de origen sigue estando disponible. Debido a las restricciones sobre la frecuencia con la que las tarjetas de previsualización de enlaces sondean sitios de terceros, se recomienda establecer este valor en al menos 14 días, o las tarjetas de previsualización de enlaces no se actualizarán bajo demanda antes de ese tiempo.
|
||||
min_age: Se pedirá a los usuarios que confirmen su fecha de nacimiento durante el registro
|
||||
min_age: Se pedirá a los usuarios que confirmen su fecha de nacimiento al registrarse
|
||||
peers_api_enabled: Una lista de nombres de dominio que este servidor ha encontrado en el fediverso. Aquí no se incluye ningún dato sobre si usted federa con un servidor determinado, sólo que su servidor lo sabe. Esto es utilizado por los servicios que recopilan estadísticas sobre la federación en un sentido general.
|
||||
profile_directory: El directorio de perfiles lista a todos los usuarios que han optado por que su cuenta pueda ser descubierta.
|
||||
require_invite_text: Cuando los registros requieren aprobación manual, hace obligatoria la entrada de texto "¿Por qué quieres unirte?" en lugar de opcional
|
||||
|
@ -145,10 +145,10 @@ es-MX:
|
|||
dmca_email: Puede ser el mismo correo electrónico utilizado para "Dirección de correo electrónico para avisos legales" de arriba.
|
||||
domain: Identificación única del servicio en línea que presta.
|
||||
jurisdiction: Indique el país de residencia de quien paga las facturas. Si se trata de una empresa u otra entidad, indique el país en el que está constituida y la ciudad, región, territorio o estado, según proceda.
|
||||
min_age: No debería estar por debajo de la edad mínima requerida por las leyes de su jurisdicción.
|
||||
min_age: No debe ser menor de la edad mínima exigida por las leyes de su jurisdicción.
|
||||
user:
|
||||
chosen_languages: Cuando se marca, solo se mostrarán las publicaciones en los idiomas seleccionados en las líneas de tiempo públicas
|
||||
date_of_birth: Tenemos que asegurarnos de que al menos tienes %{age} años para usar Mastodon. No almacenaremos esta información.
|
||||
date_of_birth: Tenemos que asegurarnos de que tienes al menos %{age} para usar Mastodon. No almacenaremos esto.
|
||||
role: El rol controla qué permisos tiene el usuario.
|
||||
user_role:
|
||||
color: Color que se usará para el rol en toda la interfaz de usuario, como RGB en formato hexadecimal
|
||||
|
|
|
@ -480,6 +480,34 @@ tr:
|
|||
title: Domain bloklarını içe aktar
|
||||
no_file: Dosya seçilmedi
|
||||
fasp:
|
||||
debug:
|
||||
callbacks:
|
||||
created_at: Oluşturulma tarihi
|
||||
delete: Sil
|
||||
ip: IP adresi
|
||||
request_body: İstek gövdesi
|
||||
title: Hata ayıklama geri çağrıları
|
||||
providers:
|
||||
active: Etkin
|
||||
base_url: Temel URL
|
||||
callback: Geri çağırma
|
||||
delete: Sil
|
||||
edit: Sağlayıcıyı Düzenle
|
||||
finish_registration: Kaydı tamamla
|
||||
name: Ad
|
||||
providers: Sağlayıcılar
|
||||
public_key_fingerprint: Açık anahtar parmak izi
|
||||
registration_requested: Kayıt istendi
|
||||
registrations:
|
||||
confirm: Onayla
|
||||
description: FASP'tan bir kayıt aldınız. Eğer bunu siz başlatmadıysanız reddedin. Eğer siz başlattıysanız, kaydı onaylamadan önce ad ve anahtar parmak izini dikkatlice karşılaştırın.
|
||||
reject: Reddet
|
||||
title: FASP Kaydını Onayla
|
||||
save: Kaydet
|
||||
select_capabilities: Yetenekleri Seç
|
||||
sign_in: Oturum Aç
|
||||
status: Durum
|
||||
title: Fediverse Yardımcı Hizmet Sağlayıcıları (FASP)
|
||||
title: FASP
|
||||
follow_recommendations:
|
||||
description_html: "<strong>Takip önerileri yeni kullanıcıların hızlı bir şekilde ilginç içerik bulmalarını sağlar</strong>. Eğer bir kullanıcı, kişisel takip önerileri almaya yetecek kadar başkalarıyla etkileşime girmediğinde, onun yerine bu hesaplar önerilir. Bu öneriler, verili bir dil için en yüksek takipçi sayısına ve en yüksek güncel meşguliyete sahip hesapların bir karışımdan günlük olarak hesaplanıyorlar."
|
||||
|
|
|
@ -12,6 +12,7 @@ module Mastodon
|
|||
class RateLimitExceededError < Error; end
|
||||
class SyntaxError < Error; end
|
||||
class InvalidParameterError < Error; end
|
||||
class SignatureVerificationError < Error; end
|
||||
|
||||
class UnexpectedResponseError < Error
|
||||
attr_reader :response
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@mastodon/mastodon",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"packageManager": "yarn@4.7.0",
|
||||
"packageManager": "yarn@4.8.1",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
|
@ -151,7 +151,7 @@
|
|||
"@testing-library/jest-dom": "^6.0.0",
|
||||
"@testing-library/react": "^16.0.0",
|
||||
"@types/babel__core": "^7.20.1",
|
||||
"@types/emoji-mart": "^3.0.9",
|
||||
"@types/emoji-mart": "3.0.14",
|
||||
"@types/escape-html": "^1.0.2",
|
||||
"@types/hoist-non-react-statics": "^3.3.1",
|
||||
"@types/http-link-header": "^1.0.3",
|
||||
|
@ -197,7 +197,7 @@
|
|||
"stylelint": "^16.11.0",
|
||||
"stylelint-config-prettier-scss": "^1.0.0",
|
||||
"stylelint-config-standard-scss": "^14.0.0",
|
||||
"typescript": "^5.0.4",
|
||||
"typescript": "~5.7.3",
|
||||
"typescript-eslint": "^8.28.0",
|
||||
"webpack-dev-server": "^3.11.3"
|
||||
},
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Settings::PicturesController do
|
||||
render_views
|
||||
|
||||
let!(:user) { Fabricate(:user) }
|
||||
|
||||
before do
|
||||
sign_in user, scope: :user
|
||||
end
|
||||
|
||||
describe 'DELETE #destroy' do
|
||||
context 'with invalid picture id' do
|
||||
it 'returns http bad request' do
|
||||
delete :destroy, params: { id: 'invalid' }
|
||||
expect(response).to have_http_status(400)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with valid picture id' do
|
||||
context 'when account updates correctly' do
|
||||
let(:service) { instance_double(UpdateAccountService, call: true) }
|
||||
|
||||
before do
|
||||
allow(UpdateAccountService).to receive(:new).and_return(service)
|
||||
end
|
||||
|
||||
it 'updates the account' do
|
||||
delete :destroy, params: { id: 'avatar' }
|
||||
expect(response).to redirect_to(settings_profile_path)
|
||||
expect(response).to have_http_status(303)
|
||||
expect(service).to have_received(:call).with(user.account, { 'avatar' => nil, 'avatar_remote_url' => '' })
|
||||
end
|
||||
end
|
||||
|
||||
context 'when account cannot update' do
|
||||
let(:service) { instance_double(UpdateAccountService, call: false) }
|
||||
|
||||
before do
|
||||
allow(UpdateAccountService).to receive(:new).and_return(service)
|
||||
end
|
||||
|
||||
it 'redirects to profile' do
|
||||
delete :destroy, params: { id: 'avatar' }
|
||||
expect(response).to redirect_to(settings_profile_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -28,6 +28,19 @@ RSpec.describe Admin::Trends::StatusesHelper do
|
|||
end
|
||||
end
|
||||
|
||||
context 'with a remote status that has excessive attributes' do
|
||||
let(:attr_limit) { Nokogiri::Gumbo::DEFAULT_MAX_ATTRIBUTES * 2 }
|
||||
let(:html) { "<html><body #{(1..attr_limit).map { |x| "attr-#{x}" }.join(' ')}><p>text</p></body></html>" }
|
||||
|
||||
let(:status) { Fabricate.build(:status, uri: 'https://host.example', text: html) }
|
||||
|
||||
it 'renders a correct preview text' do
|
||||
result = helper.one_line_preview(status)
|
||||
|
||||
expect(result).to eq ''
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a status that has empty text' do
|
||||
let(:status) { Fabricate.build(:status, text: '') }
|
||||
|
||||
|
|
|
@ -187,6 +187,23 @@ RSpec.describe ActivityPub::TagManager do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#uris_to_local_accounts' do
|
||||
it 'returns the expected local accounts' do
|
||||
account = Fabricate(:account)
|
||||
expect(subject.uris_to_local_accounts([subject.uri_for(account), instance_actor_url])).to contain_exactly(account, Account.representative)
|
||||
end
|
||||
|
||||
it 'does not return remote accounts' do
|
||||
account = Fabricate(:account, uri: 'https://example.com/123', domain: 'example.com')
|
||||
expect(subject.uris_to_local_accounts([subject.uri_for(account)])).to be_empty
|
||||
end
|
||||
|
||||
it 'does not return an account for a local post' do
|
||||
status = Fabricate(:status)
|
||||
expect(subject.uris_to_local_accounts([subject.uri_for(status)])).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
describe '#uri_to_resource' do
|
||||
it 'returns the local account' do
|
||||
account = Fabricate(:account)
|
||||
|
|
|
@ -38,7 +38,7 @@ RSpec.describe Fasp::Request do
|
|||
it 'raises an error' do
|
||||
expect do
|
||||
subject.send(method, '/test_path')
|
||||
end.to raise_error(SignatureVerification::SignatureVerificationError)
|
||||
end.to raise_error(Mastodon::SignatureVerificationError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
55
spec/requests/settings/pictures_spec.rb
Normal file
55
spec/requests/settings/pictures_spec.rb
Normal file
|
@ -0,0 +1,55 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Settings Pictures' do
|
||||
let!(:user) { Fabricate(:user) }
|
||||
|
||||
before { sign_in user }
|
||||
|
||||
describe 'DELETE /settings/profile/pictures/:id' do
|
||||
context 'with invalid picture id' do
|
||||
it 'returns http bad request' do
|
||||
delete settings_profile_picture_path(id: 'invalid')
|
||||
|
||||
expect(response)
|
||||
.to have_http_status(400)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with valid picture id' do
|
||||
before { stub_service }
|
||||
|
||||
context 'when account updates correctly' do
|
||||
let(:service) { instance_double(UpdateAccountService, call: true) }
|
||||
|
||||
it 'updates the account' do
|
||||
delete settings_profile_picture_path(id: 'avatar')
|
||||
|
||||
expect(response)
|
||||
.to redirect_to(settings_profile_path)
|
||||
.and have_http_status(303)
|
||||
expect(service)
|
||||
.to have_received(:call).with(user.account, { 'avatar' => nil, 'avatar_remote_url' => '' })
|
||||
end
|
||||
end
|
||||
|
||||
context 'when account cannot update' do
|
||||
let(:service) { instance_double(UpdateAccountService, call: false) }
|
||||
|
||||
it 'redirects to profile' do
|
||||
delete settings_profile_picture_path(id: 'avatar')
|
||||
|
||||
expect(response)
|
||||
.to redirect_to(settings_profile_path)
|
||||
end
|
||||
end
|
||||
|
||||
def stub_service
|
||||
allow(UpdateAccountService)
|
||||
.to receive(:new)
|
||||
.and_return(service)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@mastodon/streaming",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"packageManager": "yarn@4.7.0",
|
||||
"packageManager": "yarn@4.8.1",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
|
@ -39,7 +39,7 @@
|
|||
"@types/ws": "^8.5.9",
|
||||
"globals": "^16.0.0",
|
||||
"pino-pretty": "^13.0.0",
|
||||
"typescript": "^5.0.4",
|
||||
"typescript": "~5.7.3",
|
||||
"typescript-eslint": "^8.28.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
|
|
147
yarn.lock
147
yarn.lock
|
@ -2190,14 +2190,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@eslint-community/regexpp@npm:^4.10.0":
|
||||
version: 4.10.0
|
||||
resolution: "@eslint-community/regexpp@npm:4.10.0"
|
||||
checksum: 10c0/c5f60ef1f1ea7649fa7af0e80a5a79f64b55a8a8fa5086de4727eb4c86c652aedee407a9c143b8995d2c0b2d75c1222bec9ba5d73dbfc1f314550554f0979ef4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@eslint-community/regexpp@npm:^4.12.1":
|
||||
"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.12.1":
|
||||
version: 4.12.1
|
||||
resolution: "@eslint-community/regexpp@npm:4.12.1"
|
||||
checksum: 10c0/a03d98c246bcb9109aec2c08e4d10c8d010256538dcb3f56610191607214523d4fb1b00aa81df830b6dffb74c5fa0be03642513a289c567949d3e550ca11cdf6
|
||||
|
@ -2848,7 +2841,7 @@ __metadata:
|
|||
"@testing-library/jest-dom": "npm:^6.0.0"
|
||||
"@testing-library/react": "npm:^16.0.0"
|
||||
"@types/babel__core": "npm:^7.20.1"
|
||||
"@types/emoji-mart": "npm:^3.0.9"
|
||||
"@types/emoji-mart": "npm:3.0.14"
|
||||
"@types/escape-html": "npm:^1.0.2"
|
||||
"@types/hoist-non-react-statics": "npm:^3.3.1"
|
||||
"@types/http-link-header": "npm:^1.0.3"
|
||||
|
@ -2970,7 +2963,7 @@ __metadata:
|
|||
tesseract.js: "npm:^6.0.0"
|
||||
tiny-queue: "npm:^0.2.1"
|
||||
twitter-text: "npm:3.1.0"
|
||||
typescript: "npm:^5.0.4"
|
||||
typescript: "npm:~5.7.3"
|
||||
typescript-eslint: "npm:^8.28.0"
|
||||
use-debounce: "npm:^10.0.0"
|
||||
webpack: "npm:^4.47.0"
|
||||
|
@ -3019,7 +3012,7 @@ __metadata:
|
|||
pino-http: "npm:^10.0.0"
|
||||
pino-pretty: "npm:^13.0.0"
|
||||
prom-client: "npm:^15.0.0"
|
||||
typescript: "npm:^5.0.4"
|
||||
typescript: "npm:~5.7.3"
|
||||
typescript-eslint: "npm:^8.28.0"
|
||||
utf-8-validate: "npm:^6.0.3"
|
||||
uuid: "npm:^11.0.0"
|
||||
|
@ -3822,7 +3815,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/emoji-mart@npm:^3.0.9":
|
||||
"@types/emoji-mart@npm:3.0.14":
|
||||
version: 3.0.14
|
||||
resolution: "@types/emoji-mart@npm:3.0.14"
|
||||
dependencies:
|
||||
|
@ -3848,10 +3841,10 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/estree@npm:*, @types/estree@npm:^1.0.0":
|
||||
version: 1.0.5
|
||||
resolution: "@types/estree@npm:1.0.5"
|
||||
checksum: 10c0/b3b0e334288ddb407c7b3357ca67dbee75ee22db242ca7c56fe27db4e1a31989cb8af48a84dd401deb787fe10cc6b2ab1ee82dc4783be87ededbe3d53c79c70d
|
||||
"@types/estree@npm:*, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.6":
|
||||
version: 1.0.7
|
||||
resolution: "@types/estree@npm:1.0.7"
|
||||
checksum: 10c0/be815254316882f7c40847336cd484c3bc1c3e34f710d197160d455dc9d6d050ffbf4c3bc76585dba86f737f020ab20bdb137ebe0e9116b0c86c7c0342221b8c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -3862,13 +3855,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/estree@npm:^1.0.6":
|
||||
version: 1.0.7
|
||||
resolution: "@types/estree@npm:1.0.7"
|
||||
checksum: 10c0/be815254316882f7c40847336cd484c3bc1c3e34f710d197160d455dc9d6d050ffbf4c3bc76585dba86f737f020ab20bdb137ebe0e9116b0c86c7c0342221b8c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/express-serve-static-core@npm:^4.17.33":
|
||||
version: 4.17.41
|
||||
resolution: "@types/express-serve-static-core@npm:4.17.41"
|
||||
|
@ -4054,16 +4040,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/node@npm:*":
|
||||
version: 22.8.6
|
||||
resolution: "@types/node@npm:22.8.6"
|
||||
dependencies:
|
||||
undici-types: "npm:~6.19.8"
|
||||
checksum: 10c0/d3a11f2549234a91a4c5d0ff35ab4bdcb7ba34db4d3f1d189be39b8bd41c19aac98d117150a95a9c5a9d45b1014135477ea240b2b8317c86ae3d3cf1c3b3f8f4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/node@npm:^22.0.0":
|
||||
"@types/node@npm:*, @types/node@npm:^22.0.0":
|
||||
version: 22.13.14
|
||||
resolution: "@types/node@npm:22.13.14"
|
||||
dependencies:
|
||||
|
@ -4908,16 +4885,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"acorn@npm:^8.0.4, acorn@npm:^8.1.0, acorn@npm:^8.12.0, acorn@npm:^8.8.1, acorn@npm:^8.8.2":
|
||||
version: 8.12.1
|
||||
resolution: "acorn@npm:8.12.1"
|
||||
bin:
|
||||
acorn: bin/acorn
|
||||
checksum: 10c0/51fb26cd678f914e13287e886da2d7021f8c2bc0ccc95e03d3e0447ee278dd3b40b9c57dc222acd5881adcf26f3edc40901a4953403232129e3876793cd17386
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"acorn@npm:^8.14.0":
|
||||
"acorn@npm:^8.0.4, acorn@npm:^8.1.0, acorn@npm:^8.14.0, acorn@npm:^8.8.1, acorn@npm:^8.8.2":
|
||||
version: 8.14.1
|
||||
resolution: "acorn@npm:8.14.1"
|
||||
bin:
|
||||
|
@ -6860,18 +6828,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.1, cross-spawn@npm:^7.0.3":
|
||||
version: 7.0.3
|
||||
resolution: "cross-spawn@npm:7.0.3"
|
||||
dependencies:
|
||||
path-key: "npm:^3.1.0"
|
||||
shebang-command: "npm:^2.0.0"
|
||||
which: "npm:^2.0.1"
|
||||
checksum: 10c0/5738c312387081c98d69c98e105b6327b069197f864a60593245d64c8089c8a0a744e16349281210d56835bb9274130d825a78b2ad6853ca13cfbeffc0c31750
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cross-spawn@npm:^7.0.6":
|
||||
"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.1, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6":
|
||||
version: 7.0.6
|
||||
resolution: "cross-spawn@npm:7.0.6"
|
||||
dependencies:
|
||||
|
@ -8384,7 +8341,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"eslint-visitor-keys@npm:^4.0.0, eslint-visitor-keys@npm:^4.2.0":
|
||||
"eslint-visitor-keys@npm:^4.2.0":
|
||||
version: 4.2.0
|
||||
resolution: "eslint-visitor-keys@npm:4.2.0"
|
||||
checksum: 10c0/2ed81c663b147ca6f578312919483eb040295bbab759e5a371953456c636c5b49a559883e2677112453728d66293c0a4c90ab11cab3428cf02a0236d2e738269
|
||||
|
@ -8441,7 +8398,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"espree@npm:^10.0.1, espree@npm:^10.3.0":
|
||||
"espree@npm:^10.0.1, espree@npm:^10.1.0, espree@npm:^10.3.0":
|
||||
version: 10.3.0
|
||||
resolution: "espree@npm:10.3.0"
|
||||
dependencies:
|
||||
|
@ -8452,17 +8409,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"espree@npm:^10.1.0":
|
||||
version: 10.1.0
|
||||
resolution: "espree@npm:10.1.0"
|
||||
dependencies:
|
||||
acorn: "npm:^8.12.0"
|
||||
acorn-jsx: "npm:^5.3.2"
|
||||
eslint-visitor-keys: "npm:^4.0.0"
|
||||
checksum: 10c0/52e6feaa77a31a6038f0c0e3fce93010a4625701925b0715cd54a2ae190b3275053a0717db698697b32653788ac04845e489d6773b508d6c2e8752f3c57470a0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"esprima@npm:^4.0.0, esprima@npm:^4.0.1":
|
||||
version: 4.0.1
|
||||
resolution: "esprima@npm:4.0.1"
|
||||
|
@ -15133,15 +15079,15 @@ __metadata:
|
|||
linkType: hard
|
||||
|
||||
"react-textarea-autosize@npm:^8.4.1":
|
||||
version: 8.5.8
|
||||
resolution: "react-textarea-autosize@npm:8.5.8"
|
||||
version: 8.5.9
|
||||
resolution: "react-textarea-autosize@npm:8.5.9"
|
||||
dependencies:
|
||||
"@babel/runtime": "npm:^7.20.13"
|
||||
use-composed-ref: "npm:^1.3.0"
|
||||
use-latest: "npm:^1.2.1"
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
checksum: 10c0/3d7add9773fd3dc189a6668efb82c1d2d5238ee5b7e933204f5f7da9df8daef81df50b36ca573a57beaa31b2727c6176ea806422790ad23be6cf7f5a5f71bbb9
|
||||
checksum: 10c0/3a924db59259a6e3b834dcddc12a8661b43dcdaa1b43c41c732e0548bb2761e9a53dbc6db4e0d9e237728b4869e42c25e5417408b0391aec290c90874733a09f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -15816,8 +15762,8 @@ __metadata:
|
|||
linkType: hard
|
||||
|
||||
"sass@npm:^1.62.1":
|
||||
version: 1.86.0
|
||||
resolution: "sass@npm:1.86.0"
|
||||
version: 1.86.3
|
||||
resolution: "sass@npm:1.86.3"
|
||||
dependencies:
|
||||
"@parcel/watcher": "npm:^2.4.1"
|
||||
chokidar: "npm:^4.0.0"
|
||||
|
@ -15828,7 +15774,7 @@ __metadata:
|
|||
optional: true
|
||||
bin:
|
||||
sass: sass.js
|
||||
checksum: 10c0/921caea1fd8a450d4a986e5570ce13c4ca7b2a57da390811add3d2087ad8f46f53b34652ddcb237d8bdaad49c560b8d6eee130c733c787d058bc5a71a914c139
|
||||
checksum: 10c0/ba819a0828f732adf7a94cd8ca017bce92bc299ffb878836ed1da80a30612bfbbf56a5e42d6dff3ad80d919c2025afb42948fc7b54a7bc61a9a2d58e1e0c558a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -15941,16 +15887,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.3":
|
||||
version: 7.6.3
|
||||
resolution: "semver@npm:7.6.3"
|
||||
bin:
|
||||
semver: bin/semver.js
|
||||
checksum: 10c0/88f33e148b210c153873cb08cfe1e281d518aaa9a666d4d148add6560db5cd3c582f3a08ccb91f38d5f379ead256da9931234ed122057f40bb5766e65e58adaf
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"semver@npm:^7.7.1":
|
||||
"semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.3, semver@npm:^7.7.1":
|
||||
version: 7.7.1
|
||||
resolution: "semver@npm:7.7.1"
|
||||
bin:
|
||||
|
@ -17604,14 +17541,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tslib@npm:^2.0.0, tslib@npm:^2.4.0, tslib@npm:^2.6.2":
|
||||
version: 2.8.0
|
||||
resolution: "tslib@npm:2.8.0"
|
||||
checksum: 10c0/31e4d14dc1355e9b89e4d3c893a18abb7f90b6886b089c2da91224d0a7752c79f3ddc41bc1aa0a588ac895bd97bb99c5bc2bfdb2f86de849f31caeb3ba79bbe5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tslib@npm:^2.8.0":
|
||||
"tslib@npm:^2.0.0, tslib@npm:^2.4.0, tslib@npm:^2.6.2, tslib@npm:^2.8.0":
|
||||
version: 2.8.1
|
||||
resolution: "tslib@npm:2.8.1"
|
||||
checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62
|
||||
|
@ -17751,16 +17681,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typescript@npm:^5.0.4":
|
||||
version: 5.7.3
|
||||
resolution: "typescript@npm:5.7.3"
|
||||
bin:
|
||||
tsc: bin/tsc
|
||||
tsserver: bin/tsserver
|
||||
checksum: 10c0/b7580d716cf1824736cc6e628ab4cd8b51877408ba2be0869d2866da35ef8366dd6ae9eb9d0851470a39be17cbd61df1126f9e211d8799d764ea7431d5435afa
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typescript@npm:^5.6.0":
|
||||
version: 5.8.2
|
||||
resolution: "typescript@npm:5.8.2"
|
||||
|
@ -17771,13 +17691,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typescript@patch:typescript@npm%3A^5.0.4#optional!builtin<compat/typescript>":
|
||||
"typescript@npm:~5.7.3":
|
||||
version: 5.7.3
|
||||
resolution: "typescript@patch:typescript@npm%3A5.7.3#optional!builtin<compat/typescript>::version=5.7.3&hash=5786d5"
|
||||
resolution: "typescript@npm:5.7.3"
|
||||
bin:
|
||||
tsc: bin/tsc
|
||||
tsserver: bin/tsserver
|
||||
checksum: 10c0/6fd7e0ed3bf23a81246878c613423730c40e8bdbfec4c6e4d7bf1b847cbb39076e56ad5f50aa9d7ebd89877999abaee216002d3f2818885e41c907caaa192cc4
|
||||
checksum: 10c0/b7580d716cf1824736cc6e628ab4cd8b51877408ba2be0869d2866da35ef8366dd6ae9eb9d0851470a39be17cbd61df1126f9e211d8799d764ea7431d5435afa
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -17791,6 +17711,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typescript@patch:typescript@npm%3A~5.7.3#optional!builtin<compat/typescript>":
|
||||
version: 5.7.3
|
||||
resolution: "typescript@patch:typescript@npm%3A5.7.3#optional!builtin<compat/typescript>::version=5.7.3&hash=5786d5"
|
||||
bin:
|
||||
tsc: bin/tsc
|
||||
tsserver: bin/tsserver
|
||||
checksum: 10c0/6fd7e0ed3bf23a81246878c613423730c40e8bdbfec4c6e4d7bf1b847cbb39076e56ad5f50aa9d7ebd89877999abaee216002d3f2818885e41c907caaa192cc4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"unbox-primitive@npm:^1.1.0":
|
||||
version: 1.1.0
|
||||
resolution: "unbox-primitive@npm:1.1.0"
|
||||
|
@ -17817,13 +17747,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"undici-types@npm:~6.19.8":
|
||||
version: 6.19.8
|
||||
resolution: "undici-types@npm:6.19.8"
|
||||
checksum: 10c0/078afa5990fba110f6824823ace86073b4638f1d5112ee26e790155f481f2a868cc3e0615505b6f4282bdf74a3d8caad715fd809e870c2bb0704e3ea6082f344
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"undici-types@npm:~6.20.0":
|
||||
version: 6.20.0
|
||||
resolution: "undici-types@npm:6.20.0"
|
||||
|
|
Loading…
Add table
Reference in a new issue