mirror of
https://github.com/mastodon/mastodon.git
synced 2025-09-05 17:31:12 +00:00
Merge branch 'main' into feature/require-mfa-by-admin
This commit is contained in:
commit
6a40447759
|
@ -6,7 +6,7 @@ module Admin
|
|||
|
||||
def index
|
||||
authorize :audit_log, :index?
|
||||
@auditable_accounts = Account.auditable.select(:id, :username)
|
||||
@auditable_accounts = Account.auditable.select(:id, :username).order(username: :asc)
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -18,7 +18,7 @@ class Admin::Disputes::AppealsController < Admin::BaseController
|
|||
end
|
||||
|
||||
def reject
|
||||
authorize @appeal, :approve?
|
||||
authorize @appeal, :reject?
|
||||
log_action :reject, @appeal
|
||||
@appeal.reject!(current_account)
|
||||
UserMailer.appeal_rejected(@appeal.account.user, @appeal).deliver_later
|
||||
|
|
|
@ -36,7 +36,7 @@ module Admin
|
|||
end
|
||||
|
||||
def edit
|
||||
authorize :domain_block, :create?
|
||||
authorize :domain_block, :update?
|
||||
end
|
||||
|
||||
def create
|
||||
|
@ -129,7 +129,7 @@ module Admin
|
|||
end
|
||||
|
||||
def requires_confirmation?
|
||||
@domain_block.valid? && (@domain_block.new_record? || @domain_block.severity_changed?) && @domain_block.severity.to_s == 'suspend' && !params[:confirm]
|
||||
@domain_block.valid? && (@domain_block.new_record? || @domain_block.severity_changed?) && @domain_block.suspend? && !params[:confirm]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,6 +11,7 @@ class StatusesController < ApplicationController
|
|||
before_action :require_account_signature!, only: [:show, :activity], if: -> { request.format == :json && authorized_fetch_mode? }
|
||||
before_action :set_status
|
||||
before_action :redirect_to_original, only: :show
|
||||
before_action :verify_embed_allowed, only: :embed
|
||||
|
||||
after_action :set_link_headers
|
||||
|
||||
|
@ -40,8 +41,6 @@ class StatusesController < ApplicationController
|
|||
end
|
||||
|
||||
def embed
|
||||
return not_found if @status.hidden? || @status.reblog?
|
||||
|
||||
expires_in 180, public: true
|
||||
response.headers.delete('X-Frame-Options')
|
||||
|
||||
|
@ -50,6 +49,10 @@ class StatusesController < ApplicationController
|
|||
|
||||
private
|
||||
|
||||
def verify_embed_allowed
|
||||
not_found if @status.hidden? || @status.reblog?
|
||||
end
|
||||
|
||||
def set_link_headers
|
||||
response.headers['Link'] = LinkHeader.new(
|
||||
[[ActivityPub::TagManager.instance.uri_for(@status), [%w(rel alternate), %w(type application/activity+json)]]]
|
||||
|
|
63
app/javascript/mastodon/components/learn_more_link.tsx
Normal file
63
app/javascript/mastodon/components/learn_more_link.tsx
Normal file
|
@ -0,0 +1,63 @@
|
|||
import { useState, useRef, useCallback, useId } from 'react';
|
||||
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import Overlay from 'react-overlays/Overlay';
|
||||
|
||||
export const LearnMoreLink: React.FC<{ children: React.ReactNode }> = ({
|
||||
children,
|
||||
}) => {
|
||||
const accessibilityId = useId();
|
||||
const [open, setOpen] = useState(false);
|
||||
const triggerRef = useRef(null);
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
setOpen(!open);
|
||||
}, [open, setOpen]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
className='link-button'
|
||||
ref={triggerRef}
|
||||
onClick={handleClick}
|
||||
aria-expanded={open}
|
||||
aria-controls={accessibilityId}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='learn_more_link.learn_more'
|
||||
defaultMessage='Learn more'
|
||||
/>
|
||||
</button>
|
||||
|
||||
<Overlay
|
||||
show={open}
|
||||
rootClose
|
||||
onHide={handleClick}
|
||||
offset={[5, 5]}
|
||||
placement='bottom-end'
|
||||
target={triggerRef}
|
||||
>
|
||||
{({ props }) => (
|
||||
<div
|
||||
{...props}
|
||||
role='region'
|
||||
id={accessibilityId}
|
||||
className='account__domain-pill__popout learn-more__popout dropdown-animation'
|
||||
>
|
||||
<div className='learn-more__popout__content'>{children}</div>
|
||||
|
||||
<div>
|
||||
<button className='link-button' onClick={handleClick}>
|
||||
<FormattedMessage
|
||||
id='learn_more_link.got_it'
|
||||
defaultMessage='Got it'
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Overlay>
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -138,6 +138,16 @@ class StatusContent extends PureComponent {
|
|||
|
||||
onCollapsedToggle(collapsed);
|
||||
}
|
||||
|
||||
// Remove quote fallback link from the DOM so it doesn't
|
||||
// mess with paragraph margins
|
||||
if (!!status.get('quote')) {
|
||||
const inlineQuote = node.querySelector('.quote-inline');
|
||||
|
||||
if (inlineQuote) {
|
||||
inlineQuote.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleMouseEnter = ({ currentTarget }) => {
|
||||
|
|
|
@ -3,19 +3,15 @@ import { useEffect, useMemo } from 'react';
|
|||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import classNames from 'classnames';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import type { Map as ImmutableMap } from 'immutable';
|
||||
|
||||
import ArticleIcon from '@/material-icons/400-24px/article.svg?react';
|
||||
import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react';
|
||||
import { Icon } from 'mastodon/components/icon';
|
||||
import { LearnMoreLink } from 'mastodon/components/learn_more_link';
|
||||
import StatusContainer from 'mastodon/containers/status_container';
|
||||
import type { Status } from 'mastodon/models/status';
|
||||
import type { RootState } from 'mastodon/store';
|
||||
import { useAppDispatch, useAppSelector } from 'mastodon/store';
|
||||
|
||||
import QuoteIcon from '../../images/quote.svg?react';
|
||||
import { fetchStatus } from '../actions/statuses';
|
||||
import { makeGetStatus } from '../selectors';
|
||||
|
||||
|
@ -31,7 +27,6 @@ const QuoteWrapper: React.FC<{
|
|||
'status__quote--error': isError,
|
||||
})}
|
||||
>
|
||||
<Icon id='quote' icon={QuoteIcon} className='status__quote-icon' />
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
@ -45,27 +40,20 @@ const NestedQuoteLink: React.FC<{
|
|||
accountId ? state.accounts.get(accountId) : undefined,
|
||||
);
|
||||
|
||||
const quoteAuthorName = account?.display_name_html;
|
||||
const quoteAuthorName = account?.acct;
|
||||
|
||||
if (!quoteAuthorName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const quoteAuthorElement = (
|
||||
<span dangerouslySetInnerHTML={{ __html: quoteAuthorName }} />
|
||||
);
|
||||
const quoteUrl = `/@${account.get('acct')}/${status.get('id') as string}`;
|
||||
|
||||
return (
|
||||
<Link to={quoteUrl} className='status__quote-author-button'>
|
||||
<div className='status__quote-author-button'>
|
||||
<FormattedMessage
|
||||
id='status.quote_post_author'
|
||||
defaultMessage='Post by {name}'
|
||||
values={{ name: quoteAuthorElement }}
|
||||
defaultMessage='Quoted a post by @{name}'
|
||||
values={{ name: quoteAuthorName }}
|
||||
/>
|
||||
<Icon id='chevron_right' icon={ChevronRightIcon} />
|
||||
<Icon id='article' icon={ArticleIcon} />
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -112,39 +100,42 @@ export const QuotedStatus: React.FC<{
|
|||
defaultMessage='Hidden due to one of your filters'
|
||||
/>
|
||||
);
|
||||
} else if (quoteState === 'deleted') {
|
||||
quoteError = (
|
||||
<FormattedMessage
|
||||
id='status.quote_error.removed'
|
||||
defaultMessage='This post was removed by its author.'
|
||||
/>
|
||||
);
|
||||
} else if (quoteState === 'unauthorized') {
|
||||
quoteError = (
|
||||
<FormattedMessage
|
||||
id='status.quote_error.unauthorized'
|
||||
defaultMessage='This post cannot be displayed as you are not authorized to view it.'
|
||||
/>
|
||||
);
|
||||
} else if (quoteState === 'pending') {
|
||||
quoteError = (
|
||||
<FormattedMessage
|
||||
id='status.quote_error.pending_approval'
|
||||
defaultMessage='This post is pending approval from the original author.'
|
||||
/>
|
||||
<>
|
||||
<FormattedMessage
|
||||
id='status.quote_error.pending_approval'
|
||||
defaultMessage='Post pending'
|
||||
/>
|
||||
|
||||
<LearnMoreLink>
|
||||
<h6>
|
||||
<FormattedMessage
|
||||
id='status.quote_error.pending_approval_popout.title'
|
||||
defaultMessage='Pending quote? Remain calm'
|
||||
/>
|
||||
</h6>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id='status.quote_error.pending_approval_popout.body'
|
||||
defaultMessage='Quotes shared across the Fediverse may take time to display, as different servers have different protocols.'
|
||||
/>
|
||||
</p>
|
||||
</LearnMoreLink>
|
||||
</>
|
||||
);
|
||||
} else if (quoteState === 'rejected' || quoteState === 'revoked') {
|
||||
} else if (
|
||||
!status ||
|
||||
!quotedStatusId ||
|
||||
quoteState === 'deleted' ||
|
||||
quoteState === 'rejected' ||
|
||||
quoteState === 'revoked' ||
|
||||
quoteState === 'unauthorized'
|
||||
) {
|
||||
quoteError = (
|
||||
<FormattedMessage
|
||||
id='status.quote_error.rejected'
|
||||
defaultMessage='This post cannot be displayed as the original author does not allow it to be quoted.'
|
||||
/>
|
||||
);
|
||||
} else if (!status || !quotedStatusId) {
|
||||
quoteError = (
|
||||
<FormattedMessage
|
||||
id='status.quote_error.not_found'
|
||||
defaultMessage='This post cannot be displayed.'
|
||||
id='status.quote_error.not_available'
|
||||
defaultMessage='Post unavailable'
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -168,7 +159,7 @@ export const QuotedStatus: React.FC<{
|
|||
isQuotedPost
|
||||
id={quotedStatusId}
|
||||
contextType={contextType}
|
||||
avatarSize={40}
|
||||
avatarSize={32}
|
||||
>
|
||||
{canRenderChildQuote && (
|
||||
<QuotedStatus
|
||||
|
|
|
@ -24,6 +24,11 @@ export const RefreshController: React.FC<{
|
|||
const refresh = useAppSelector(
|
||||
(state) => state.contexts.refreshing[statusId],
|
||||
);
|
||||
const autoRefresh = useAppSelector(
|
||||
(state) =>
|
||||
!state.contexts.replies[statusId] ||
|
||||
state.contexts.replies[statusId].length === 0,
|
||||
);
|
||||
const dispatch = useAppDispatch();
|
||||
const intl = useIntl();
|
||||
const [ready, setReady] = useState(false);
|
||||
|
@ -39,6 +44,11 @@ export const RefreshController: React.FC<{
|
|||
dispatch(completeContextRefresh({ statusId }));
|
||||
|
||||
if (result.async_refresh.result_count > 0) {
|
||||
if (autoRefresh) {
|
||||
void dispatch(fetchContext({ statusId }));
|
||||
return '';
|
||||
}
|
||||
|
||||
setReady(true);
|
||||
}
|
||||
} else {
|
||||
|
@ -57,7 +67,7 @@ export const RefreshController: React.FC<{
|
|||
return () => {
|
||||
clearTimeout(timeoutId);
|
||||
};
|
||||
}, [dispatch, setReady, statusId, refresh]);
|
||||
}, [dispatch, setReady, statusId, refresh, autoRefresh]);
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
setLoading(true);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"about.blocks": "Moderated servers",
|
||||
"about.contact": "Contact:",
|
||||
"about.default_locale": "Varsayılan",
|
||||
"about.default_locale": "Default",
|
||||
"about.disclaimer": "Mastodon is free, open-source software, and a trademark of Mastodon gGmbH.",
|
||||
"about.domain_blocks.no_reason_available": "Reason not available",
|
||||
"about.domain_blocks.preamble": "Mastodon generally allows you to view content from and interact with users from any other server in the Fediverse. These are the exceptions that have been made on this particular server.",
|
||||
|
@ -9,11 +9,11 @@
|
|||
"about.domain_blocks.silenced.title": "Limited",
|
||||
"about.domain_blocks.suspended.explanation": "No data from this server will be processed, stored or exchanged, making any interaction or communication with users from this server impossible.",
|
||||
"about.domain_blocks.suspended.title": "Suspended",
|
||||
"about.language_label": "Dil",
|
||||
"about.language_label": "Language",
|
||||
"about.not_available": "This information has not been made available on this server.",
|
||||
"about.powered_by": "Decentralised social media powered by {mastodon}",
|
||||
"about.rules": "Server rules",
|
||||
"account.account_note_header": "Kişisel not",
|
||||
"account.account_note_header": "Personal note",
|
||||
"account.add_or_remove_from_list": "Add or Remove from lists",
|
||||
"account.badges.bot": "Automated",
|
||||
"account.badges.group": "Group",
|
||||
|
@ -845,8 +845,6 @@
|
|||
"status.bookmark": "Bookmark",
|
||||
"status.cancel_reblog_private": "Unboost",
|
||||
"status.cannot_reblog": "This post cannot be boosted",
|
||||
"status.context.load_new_replies": "Yeni yanıtlar geldi.",
|
||||
"status.context.loading": "Daha fazla yanıt kontrol ediliyor",
|
||||
"status.continued_thread": "Continued thread",
|
||||
"status.copy": "Copy link to status",
|
||||
"status.delete": "Delete",
|
||||
|
|
|
@ -498,6 +498,8 @@
|
|||
"keyboard_shortcuts.translate": "to translate a post",
|
||||
"keyboard_shortcuts.unfocus": "Unfocus compose textarea/search",
|
||||
"keyboard_shortcuts.up": "Move up in the list",
|
||||
"learn_more_link.got_it": "Got it",
|
||||
"learn_more_link.learn_more": "Learn more",
|
||||
"lightbox.close": "Close",
|
||||
"lightbox.next": "Next",
|
||||
"lightbox.previous": "Previous",
|
||||
|
@ -873,12 +875,11 @@
|
|||
"status.open": "Expand this post",
|
||||
"status.pin": "Pin on profile",
|
||||
"status.quote_error.filtered": "Hidden due to one of your filters",
|
||||
"status.quote_error.not_found": "This post cannot be displayed.",
|
||||
"status.quote_error.pending_approval": "This post is pending approval from the original author.",
|
||||
"status.quote_error.rejected": "This post cannot be displayed as the original author does not allow it to be quoted.",
|
||||
"status.quote_error.removed": "This post was removed by its author.",
|
||||
"status.quote_error.unauthorized": "This post cannot be displayed as you are not authorized to view it.",
|
||||
"status.quote_post_author": "Post by {name}",
|
||||
"status.quote_error.not_available": "Post unavailable",
|
||||
"status.quote_error.pending_approval": "Post pending",
|
||||
"status.quote_error.pending_approval_popout.body": "Quotes shared across the Fediverse may take time to display, as different servers have different protocols.",
|
||||
"status.quote_error.pending_approval_popout.title": "Pending quote? Remain calm",
|
||||
"status.quote_post_author": "Quoted a post by @{name}",
|
||||
"status.read_more": "Read more",
|
||||
"status.reblog": "Boost",
|
||||
"status.reblog_private": "Boost with original visibility",
|
||||
|
|
|
@ -845,6 +845,8 @@
|
|||
"status.bookmark": "Järjehoidja",
|
||||
"status.cancel_reblog_private": "Lõpeta jagamine",
|
||||
"status.cannot_reblog": "Seda postitust ei saa jagada",
|
||||
"status.context.load_new_replies": "Leidub uusi vastuseid",
|
||||
"status.context.loading": "Kontrollin täiendavate vastuste olemasolu",
|
||||
"status.continued_thread": "Jätkatud lõim",
|
||||
"status.copy": "Kopeeri postituse link",
|
||||
"status.delete": "Kustuta",
|
||||
|
|
|
@ -845,6 +845,8 @@
|
|||
"status.bookmark": "Blêdwizer tafoegje",
|
||||
"status.cancel_reblog_private": "Net langer booste",
|
||||
"status.cannot_reblog": "Dit berjocht kin net boost wurde",
|
||||
"status.context.load_new_replies": "Nije reaksjes beskikber",
|
||||
"status.context.loading": "Op nije reaksjes oan it kontrolearjen",
|
||||
"status.continued_thread": "Ferfolgje it petear",
|
||||
"status.copy": "Copy link to status",
|
||||
"status.delete": "Fuortsmite",
|
||||
|
|
|
@ -346,7 +346,7 @@
|
|||
"featured_carousel.post": "הודעה",
|
||||
"featured_carousel.previous": "הקודם",
|
||||
"featured_carousel.slide": "{index} מתוך {total}",
|
||||
"filter_modal.added.context_mismatch_explanation": "קטגוריית המסנן הזאת לא חלה על ההקשר שממנו הגעת אל ההודעה הזו. אם תרצה/י שההודעה תסונן גם בהקשר זה, תצטרך/י לערוך את הסנן.",
|
||||
"filter_modal.added.context_mismatch_explanation": "קטגוריית הסנן הזאת לא חלה על ההקשר שממנו הגעת אל ההודעה הזו. אם תרצה/י שההודעה תסונן גם בהקשר זה, תצטרך/י לערוך את הסנן.",
|
||||
"filter_modal.added.context_mismatch_title": "אין התאמה להקשר!",
|
||||
"filter_modal.added.expired_explanation": "פג תוקפה של קטגוריית הסינון הזו, יש צורך לשנות את תאריך התפוגה כדי שהסינון יוחל.",
|
||||
"filter_modal.added.expired_title": "פג תוקף המסנן!",
|
||||
|
|
|
@ -513,7 +513,7 @@
|
|||
"lists.add_to_lists": "리스트에 {name} 추가",
|
||||
"lists.create": "생성",
|
||||
"lists.create_a_list_to_organize": "새 리스트를 만들어 홈 피드를 정리하세요",
|
||||
"lists.create_list": "리스트 생성",
|
||||
"lists.create_list": "리스트 만들기",
|
||||
"lists.delete": "리스트 삭제",
|
||||
"lists.done": "완료",
|
||||
"lists.edit": "리스트 편집",
|
||||
|
|
|
@ -12,6 +12,8 @@ body {
|
|||
--background-color: #fff;
|
||||
--background-color-tint: rgba(255, 255, 255, 80%);
|
||||
--background-filter: blur(10px);
|
||||
--surface-variant-background-color: #f1ebfb;
|
||||
--surface-border-color: #cac4d0;
|
||||
--on-surface-color: #{color.adjust($ui-base-color, $alpha: -0.65)};
|
||||
--rich-text-container-color: rgba(255, 216, 231, 100%);
|
||||
--rich-text-text-color: rgba(114, 47, 83, 100%);
|
||||
|
|
|
@ -1433,10 +1433,6 @@ body > [data-popper-placement] {
|
|||
}
|
||||
}
|
||||
|
||||
.status--has-quote .quote-inline {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.status {
|
||||
padding: 16px;
|
||||
min-height: 54px;
|
||||
|
@ -1470,10 +1466,6 @@ body > [data-popper-placement] {
|
|||
margin-top: 16px;
|
||||
}
|
||||
|
||||
&--is-quote {
|
||||
border: none;
|
||||
}
|
||||
|
||||
&--in-thread {
|
||||
--thread-margin: calc(46px + 8px);
|
||||
|
||||
|
@ -1860,79 +1852,99 @@ body > [data-popper-placement] {
|
|||
// --status-gutter-width is currently only set inside of
|
||||
// .notification-ungrouped, so everywhere else this will fall back
|
||||
// to the pixel values
|
||||
--quote-margin: var(--status-gutter-width, 36px);
|
||||
--quote-margin: var(--status-gutter-width);
|
||||
|
||||
position: relative;
|
||||
margin-block-start: 16px;
|
||||
margin-inline-start: calc(var(--quote-margin) + var(--thread-margin, 0px));
|
||||
border-radius: 8px;
|
||||
border-radius: 12px;
|
||||
color: var(--nested-card-text);
|
||||
background: var(--nested-card-background);
|
||||
border: var(--nested-card-border);
|
||||
|
||||
@container (width > 460px) {
|
||||
--quote-margin: var(--status-gutter-width, 56px);
|
||||
}
|
||||
border: 1px solid var(--surface-border-color);
|
||||
}
|
||||
|
||||
.status__quote--error {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
padding: 12px;
|
||||
font-size: 15px;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
letter-spacing: 0.25px;
|
||||
min-height: 56px;
|
||||
|
||||
.link-button {
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
letter-spacing: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.status__quote-author-button {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
display: inline-flex;
|
||||
width: auto;
|
||||
margin-block-start: 10px;
|
||||
padding: 5px 12px;
|
||||
display: flex;
|
||||
margin-top: 8px;
|
||||
padding: 8px 12px;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-family: inherit;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
letter-spacing: 0;
|
||||
text-decoration: none;
|
||||
color: $highlight-text-color;
|
||||
background: var(--nested-card-background);
|
||||
border: var(--nested-card-border);
|
||||
border-radius: 4px;
|
||||
|
||||
&:active,
|
||||
&:focus,
|
||||
&:hover {
|
||||
border-color: lighten($highlight-text-color, 4%);
|
||||
color: lighten($highlight-text-color, 4%);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: $ui-button-icon-focus-outline;
|
||||
}
|
||||
font-weight: 400;
|
||||
line-height: 20px;
|
||||
letter-spacing: 0.25px;
|
||||
color: $darker-text-color;
|
||||
background: var(--surface-variant-background-color);
|
||||
border-radius: 8px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.status__quote-icon {
|
||||
position: absolute;
|
||||
inset-block-start: 18px;
|
||||
inset-inline-start: -40px;
|
||||
display: block;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
padding: 5px;
|
||||
color: #6a49ba;
|
||||
z-index: 10;
|
||||
.status--is-quote {
|
||||
border: none;
|
||||
padding: 12px;
|
||||
|
||||
.status__quote--error & {
|
||||
inset-block-start: 50%;
|
||||
transform: translateY(-50%);
|
||||
.status__info {
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
@container (width > 460px) {
|
||||
inset-inline-start: -50px;
|
||||
.display-name,
|
||||
.status__relative-time {
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
letter-spacing: 0.1px;
|
||||
}
|
||||
|
||||
.display-name__account {
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.status__content {
|
||||
display: -webkit-box;
|
||||
font-size: 14px;
|
||||
letter-spacing: 0.25px;
|
||||
line-height: 20px;
|
||||
-webkit-line-clamp: 4;
|
||||
line-clamp: 4;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
|
||||
p {
|
||||
margin-bottom: 20px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.media-gallery,
|
||||
.video-player,
|
||||
.audio-player,
|
||||
.attachment-list,
|
||||
.poll {
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2152,6 +2164,27 @@ body > [data-popper-placement] {
|
|||
}
|
||||
}
|
||||
|
||||
.learn-more__popout {
|
||||
gap: 8px;
|
||||
|
||||
&__content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: inherit;
|
||||
font-weight: 500;
|
||||
line-height: inherit;
|
||||
letter-spacing: 0.1px;
|
||||
}
|
||||
|
||||
.link-button {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.account__wrapper {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
--surface-background-color: #{darken($ui-base-color, 4%)};
|
||||
--surface-variant-background-color: #{$ui-base-color};
|
||||
--surface-variant-active-background-color: #{lighten($ui-base-color, 4%)};
|
||||
--surface-border-color: #{lighten($ui-base-color, 8%)};
|
||||
--on-surface-color: #{color.adjust($ui-base-color, $alpha: -0.5)};
|
||||
--avatar-border-radius: 8px;
|
||||
--media-outline-color: #{rgba(#fcf8ff, 0.15)};
|
||||
|
|
|
@ -206,8 +206,8 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
|||
@quote.save
|
||||
|
||||
embedded_quote = safe_prefetched_embed(@account, @status_parser.quoted_object, @json['context'])
|
||||
ActivityPub::VerifyQuoteService.new.call(@quote, fetchable_quoted_uri: @quote_uri, prefetched_quoted_object: embedded_quote, request_id: @options[:request_id])
|
||||
rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS
|
||||
ActivityPub::VerifyQuoteService.new.call(@quote, fetchable_quoted_uri: @quote_uri, prefetched_quoted_object: embedded_quote, request_id: @options[:request_id], depth: @options[:depth])
|
||||
rescue Mastodon::RecursionLimitExceededError, Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS
|
||||
ActivityPub::RefetchAndVerifyQuoteWorker.perform_in(rand(30..600).seconds, @quote.id, @quote_uri, { 'request_id' => @options[:request_id] })
|
||||
end
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ class Admin::Metrics::Dimension::SpaceUsageDimension < Admin::Metrics::Dimension
|
|||
|
||||
def media_size
|
||||
value = [
|
||||
MediaAttachment.sum(Arel.sql('COALESCE(file_file_size, 0) + COALESCE(thumbnail_file_size, 0)')),
|
||||
MediaAttachment.sum(MediaAttachment.combined_media_file_size),
|
||||
CustomEmoji.sum(:image_file_size),
|
||||
PreviewCard.sum(:image_file_size),
|
||||
Account.sum(Arel.sql('COALESCE(avatar_file_size, 0) + COALESCE(header_file_size, 0)')),
|
||||
|
|
|
@ -29,7 +29,7 @@ class Admin::Metrics::Measure::InstanceMediaAttachmentsMeasure < Admin::Metrics:
|
|||
def perform_total_query
|
||||
domain = params[:domain]
|
||||
domain = Instance.by_domain_and_subdomains(params[:domain]).select(:domain) if params[:include_subdomains]
|
||||
MediaAttachment.joins(:account).merge(Account.where(domain: domain)).sum('COALESCE(file_file_size, 0) + COALESCE(thumbnail_file_size, 0)')
|
||||
MediaAttachment.joins(:account).merge(Account.where(domain: domain)).sum(MediaAttachment.combined_media_file_size)
|
||||
end
|
||||
|
||||
def perform_previous_total_query
|
||||
|
@ -44,7 +44,7 @@ class Admin::Metrics::Measure::InstanceMediaAttachmentsMeasure < Admin::Metrics:
|
|||
<<~SQL.squish
|
||||
SELECT axis.*, (
|
||||
WITH new_media_attachments AS (
|
||||
SELECT COALESCE(media_attachments.file_file_size, 0) + COALESCE(media_attachments.thumbnail_file_size, 0) AS size
|
||||
SELECT #{media_size_total} AS size
|
||||
FROM media_attachments
|
||||
INNER JOIN accounts ON accounts.id = media_attachments.account_id
|
||||
WHERE date_trunc('day', media_attachments.created_at)::date = axis.period
|
||||
|
@ -58,6 +58,10 @@ class Admin::Metrics::Measure::InstanceMediaAttachmentsMeasure < Admin::Metrics:
|
|||
SQL
|
||||
end
|
||||
|
||||
def media_size_total
|
||||
MediaAttachment.combined_media_file_size.to_sql
|
||||
end
|
||||
|
||||
def params
|
||||
@params.permit(:domain, :include_subdomains)
|
||||
end
|
||||
|
|
|
@ -30,8 +30,10 @@ class StatusReachFinder
|
|||
[
|
||||
replied_to_account_id,
|
||||
reblog_of_account_id,
|
||||
quote_of_account_id,
|
||||
mentioned_account_ids,
|
||||
reblogs_account_ids,
|
||||
quotes_account_ids,
|
||||
favourites_account_ids,
|
||||
replies_account_ids,
|
||||
].tap do |arr|
|
||||
|
@ -46,6 +48,10 @@ class StatusReachFinder
|
|||
@status.in_reply_to_account_id if distributable?
|
||||
end
|
||||
|
||||
def quote_of_account_id
|
||||
@status.quote&.quoted_account_id
|
||||
end
|
||||
|
||||
def reblog_of_account_id
|
||||
@status.reblog.account_id if @status.reblog?
|
||||
end
|
||||
|
@ -54,6 +60,11 @@ class StatusReachFinder
|
|||
@status.mentions.pluck(:account_id)
|
||||
end
|
||||
|
||||
# Beware: Quotes can be created without the author having had access to the status
|
||||
def quotes_account_ids
|
||||
@status.quotes.pluck(:account_id) if distributable? || unsafe?
|
||||
end
|
||||
|
||||
# Beware: Reblogs can be created without the author having had access to the status
|
||||
def reblogs_account_ids
|
||||
@status.reblogs.rewhere(deleted_at: [nil, @status.deleted_at]).pluck(:account_id) if distributable? || unsafe?
|
||||
|
|
|
@ -26,6 +26,7 @@ class AccountSuggestions::FriendsOfFriendsSource < AccountSuggestions::Source
|
|||
AND NOT EXISTS (SELECT 1 FROM mutes m WHERE m.target_account_id = follows.target_account_id AND m.account_id = :id)
|
||||
AND (accounts.domain IS NULL OR NOT EXISTS (SELECT 1 FROM account_domain_blocks b WHERE b.account_id = :id AND b.domain = accounts.domain))
|
||||
AND NOT EXISTS (SELECT 1 FROM follows f WHERE f.target_account_id = follows.target_account_id AND f.account_id = :id)
|
||||
AND NOT EXISTS (SELECT 1 FROM follow_requests f WHERE f.target_account_id = follows.target_account_id AND f.account_id = :id)
|
||||
AND follows.target_account_id <> :id
|
||||
AND accounts.discoverable
|
||||
AND accounts.suspended_at IS NULL
|
||||
|
|
28
app/models/concerns/user/activity.rb
Normal file
28
app/models/concerns/user/activity.rb
Normal file
|
@ -0,0 +1,28 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module User::Activity
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
# The home and list feeds will be stored for this amount of time, and status
|
||||
# fan-out to followers will include only people active within this time frame.
|
||||
#
|
||||
# Lowering the duration may improve performance if many people sign up, but
|
||||
# most will not check their feed every day. Raising the duration reduces the
|
||||
# amount of background processing that happens when people become active.
|
||||
ACTIVE_DURATION = ENV.fetch('USER_ACTIVE_DAYS', 7).to_i.days
|
||||
|
||||
included do
|
||||
scope :signed_in_recently, -> { where(current_sign_in_at: ACTIVE_DURATION.ago..) }
|
||||
scope :not_signed_in_recently, -> { where(current_sign_in_at: ...ACTIVE_DURATION.ago) }
|
||||
end
|
||||
|
||||
def signed_in_recently?
|
||||
current_sign_in_at.present? && current_sign_in_at >= ACTIVE_DURATION.ago
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def inactive_since_duration?
|
||||
last_sign_in_at < ACTIVE_DURATION.ago
|
||||
end
|
||||
end
|
22
app/models/concerns/user/confirmation.rb
Normal file
22
app/models/concerns/user/confirmation.rb
Normal file
|
@ -0,0 +1,22 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module User::Confirmation
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
scope :confirmed, -> { where.not(confirmed_at: nil) }
|
||||
scope :unconfirmed, -> { where(confirmed_at: nil) }
|
||||
|
||||
def confirm
|
||||
wrap_email_confirmation { super }
|
||||
end
|
||||
end
|
||||
|
||||
def confirmed?
|
||||
confirmed_at.present?
|
||||
end
|
||||
|
||||
def unconfirmed?
|
||||
!confirmed?
|
||||
end
|
||||
end
|
|
@ -298,6 +298,10 @@ class MediaAttachment < ApplicationRecord
|
|||
IMAGE_FILE_EXTENSIONS + VIDEO_FILE_EXTENSIONS + AUDIO_FILE_EXTENSIONS
|
||||
end
|
||||
|
||||
def combined_media_file_size
|
||||
arel_table.coalesce(arel_table[:file_file_size], 0) + arel_table.coalesce(arel_table[:thumbnail_file_size], 0)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def file_styles(attachment)
|
||||
|
|
|
@ -78,6 +78,7 @@ class Status < ApplicationRecord
|
|||
has_many :mentions, dependent: :destroy, inverse_of: :status
|
||||
has_many :mentioned_accounts, through: :mentions, source: :account, class_name: 'Account'
|
||||
has_many :media_attachments, dependent: :nullify
|
||||
has_many :quotes, foreign_key: 'quoted_status_id', inverse_of: :quoted_status, dependent: :nullify
|
||||
|
||||
# The `dependent` option is enabled by the initial `mentions` association declaration
|
||||
has_many :active_mentions, -> { active }, class_name: 'Mention', inverse_of: :status # rubocop:disable Rails/HasManyOrHasOneDependent
|
||||
|
|
|
@ -58,20 +58,13 @@ class User < ApplicationRecord
|
|||
|
||||
include LanguagesHelper
|
||||
include Redisable
|
||||
include User::Activity
|
||||
include User::Confirmation
|
||||
include User::HasSettings
|
||||
include User::LdapAuthenticable
|
||||
include User::Omniauthable
|
||||
include User::PamAuthenticable
|
||||
|
||||
# The home and list feeds will be stored in Redis for this amount
|
||||
# of time, and status fan-out to followers will include only people
|
||||
# within this time frame. Lowering the duration may improve performance
|
||||
# if lots of people sign up, but not a lot of them check their feed
|
||||
# every day. Raising the duration reduces the amount of expensive
|
||||
# RegenerationWorker jobs that need to be run when those people come
|
||||
# to check their feed
|
||||
ACTIVE_DURATION = ENV.fetch('USER_ACTIVE_DAYS', 7).to_i.days.freeze
|
||||
|
||||
devise :two_factor_authenticatable,
|
||||
otp_secret_length: 32
|
||||
|
||||
|
@ -118,13 +111,9 @@ class User < ApplicationRecord
|
|||
scope :recent, -> { order(id: :desc) }
|
||||
scope :pending, -> { where(approved: false) }
|
||||
scope :approved, -> { where(approved: true) }
|
||||
scope :confirmed, -> { where.not(confirmed_at: nil) }
|
||||
scope :unconfirmed, -> { where(confirmed_at: nil) }
|
||||
scope :enabled, -> { where(disabled: false) }
|
||||
scope :disabled, -> { where(disabled: true) }
|
||||
scope :active, -> { confirmed.signed_in_recently.account_not_suspended }
|
||||
scope :signed_in_recently, -> { where(current_sign_in_at: ACTIVE_DURATION.ago..) }
|
||||
scope :not_signed_in_recently, -> { where(current_sign_in_at: ...ACTIVE_DURATION.ago) }
|
||||
scope :matches_email, ->(value) { where(arel_table[:email].matches("#{value}%")) }
|
||||
scope :matches_ip, ->(value) { left_joins(:ips).merge(IpBlock.contained_by(value)).group(users: [:id]) }
|
||||
|
||||
|
@ -143,7 +132,10 @@ class User < ApplicationRecord
|
|||
delegate :can?, to: :role
|
||||
|
||||
attr_reader :invite_code, :date_of_birth
|
||||
attr_writer :external, :bypass_registration_checks, :current_account
|
||||
attr_writer :current_account
|
||||
|
||||
attribute :external, :boolean, default: false
|
||||
attribute :bypass_registration_checks, :boolean, default: false
|
||||
|
||||
def self.those_who_can(*any_of_privileges)
|
||||
matching_role_ids = UserRole.that_can(*any_of_privileges).map(&:id)
|
||||
|
@ -178,14 +170,6 @@ class User < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
def signed_in_recently?
|
||||
current_sign_in_at.present? && current_sign_in_at >= ACTIVE_DURATION.ago
|
||||
end
|
||||
|
||||
def confirmed?
|
||||
confirmed_at.present?
|
||||
end
|
||||
|
||||
def invited?
|
||||
invite_id.present?
|
||||
end
|
||||
|
@ -210,12 +194,6 @@ class User < ApplicationRecord
|
|||
account_id
|
||||
end
|
||||
|
||||
def confirm
|
||||
wrap_email_confirmation do
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
# Mark current email as confirmed, bypassing Devise
|
||||
def mark_email_as_confirmed!
|
||||
wrap_email_confirmation do
|
||||
|
@ -231,16 +209,11 @@ class User < ApplicationRecord
|
|||
end
|
||||
|
||||
def update_sign_in!(new_sign_in: false)
|
||||
old_current = current_sign_in_at
|
||||
new_current = Time.now.utc
|
||||
|
||||
self.last_sign_in_at = old_current || new_current
|
||||
self.last_sign_in_at = current_sign_in_at || new_current
|
||||
self.current_sign_in_at = new_current
|
||||
|
||||
if new_sign_in
|
||||
self.sign_in_count ||= 0
|
||||
self.sign_in_count += 1
|
||||
end
|
||||
increment(:sign_in_count) if new_sign_in
|
||||
|
||||
save(validate: false) unless new_record?
|
||||
prepare_returning_user!
|
||||
|
@ -262,10 +235,6 @@ class User < ApplicationRecord
|
|||
confirmed? && approved? && !disabled? && !account.unavailable? && !account.memorial?
|
||||
end
|
||||
|
||||
def unconfirmed?
|
||||
!confirmed?
|
||||
end
|
||||
|
||||
def unconfirmed_or_pending?
|
||||
unconfirmed? || pending?
|
||||
end
|
||||
|
@ -507,14 +476,6 @@ class User < ApplicationRecord
|
|||
Setting.registrations_mode == 'open'
|
||||
end
|
||||
|
||||
def external?
|
||||
!!@external
|
||||
end
|
||||
|
||||
def bypass_registration_checks?
|
||||
@bypass_registration_checks
|
||||
end
|
||||
|
||||
def sanitize_role
|
||||
self.role = nil if role.present? && role.everyone?
|
||||
end
|
||||
|
@ -531,7 +492,7 @@ class User < ApplicationRecord
|
|||
return unless confirmed?
|
||||
|
||||
ActivityTracker.record('activity:logins', id)
|
||||
regenerate_feed! if needs_feed_update?
|
||||
regenerate_feed! if inactive_since_duration?
|
||||
end
|
||||
|
||||
def notify_staff_about_pending_account!
|
||||
|
@ -550,10 +511,6 @@ class User < ApplicationRecord
|
|||
RegenerationWorker.perform_async(account_id)
|
||||
end
|
||||
|
||||
def needs_feed_update?
|
||||
last_sign_in_at < ACTIVE_DURATION.ago
|
||||
end
|
||||
|
||||
def validate_email_dns?
|
||||
email_changed? && !external? && !self.class.skip_mx_check?
|
||||
end
|
||||
|
|
|
@ -8,9 +8,10 @@ class ActivityPub::FetchRemoteStatusService < BaseService
|
|||
DISCOVERIES_PER_REQUEST = 1000
|
||||
|
||||
# Should be called when uri has already been checked for locality
|
||||
def call(uri, prefetched_body: nil, on_behalf_of: nil, expected_actor_uri: nil, request_id: nil)
|
||||
def call(uri, prefetched_body: nil, on_behalf_of: nil, expected_actor_uri: nil, request_id: nil, depth: nil)
|
||||
return if domain_not_allowed?(uri)
|
||||
|
||||
@depth = depth || 0
|
||||
@request_id = request_id || "#{Time.now.utc.to_i}-status-#{uri}"
|
||||
@json = if prefetched_body.nil?
|
||||
fetch_status(uri, true, on_behalf_of)
|
||||
|
@ -52,7 +53,7 @@ class ActivityPub::FetchRemoteStatusService < BaseService
|
|||
return nil if discoveries > DISCOVERIES_PER_REQUEST
|
||||
end
|
||||
|
||||
ActivityPub::Activity.factory(activity_json, actor, request_id: @request_id).perform
|
||||
ActivityPub::Activity.factory(activity_json, actor, request_id: @request_id, depth: @depth).perform
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -3,9 +3,12 @@
|
|||
class ActivityPub::VerifyQuoteService < BaseService
|
||||
include JsonLdHelper
|
||||
|
||||
MAX_SYNCHRONOUS_DEPTH = 2
|
||||
|
||||
# Optionally fetch quoted post, and verify the quote is authorized
|
||||
def call(quote, fetchable_quoted_uri: nil, prefetched_quoted_object: nil, prefetched_approval: nil, request_id: nil)
|
||||
def call(quote, fetchable_quoted_uri: nil, prefetched_quoted_object: nil, prefetched_approval: nil, request_id: nil, depth: nil)
|
||||
@request_id = request_id
|
||||
@depth = depth || 0
|
||||
@quote = quote
|
||||
@fetching_error = nil
|
||||
|
||||
|
@ -72,10 +75,12 @@ class ActivityPub::VerifyQuoteService < BaseService
|
|||
return if uri.nil? || @quote.quoted_status.present?
|
||||
|
||||
status = ActivityPub::TagManager.instance.uri_to_resource(uri, Status)
|
||||
status ||= ActivityPub::FetchRemoteStatusService.new.call(uri, on_behalf_of: @quote.account.followers.local.first, prefetched_body:, request_id: @request_id)
|
||||
raise Mastodon::RecursionLimitExceededError if @depth > MAX_SYNCHRONOUS_DEPTH && status.nil?
|
||||
|
||||
status ||= ActivityPub::FetchRemoteStatusService.new.call(uri, on_behalf_of: @quote.account.followers.local.first, prefetched_body:, request_id: @request_id, depth: @depth + 1)
|
||||
|
||||
@quote.update(quoted_status: status) if status.present?
|
||||
rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS => e
|
||||
rescue Mastodon::RecursionLimitExceededError, Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS => e
|
||||
@fetching_error = e
|
||||
end
|
||||
|
||||
|
@ -90,7 +95,7 @@ class ActivityPub::VerifyQuoteService < BaseService
|
|||
# It's not safe to fetch if the inlined object is cross-origin or doesn't match expectations
|
||||
return if object['id'] != uri || non_matching_uri_hosts?(@quote.approval_uri, object['id'])
|
||||
|
||||
status = ActivityPub::FetchRemoteStatusService.new.call(object['id'], prefetched_body: object, on_behalf_of: @quote.account.followers.local.first, request_id: @request_id)
|
||||
status = ActivityPub::FetchRemoteStatusService.new.call(object['id'], prefetched_body: object, on_behalf_of: @quote.account.followers.local.first, request_id: @request_id, depth: @depth)
|
||||
|
||||
if status.present?
|
||||
@quote.update(quoted_status: status)
|
||||
|
|
|
@ -86,9 +86,7 @@ class ActivityPub::FetchAllRepliesWorker
|
|||
|
||||
return if root_status_body.nil?
|
||||
|
||||
@batch.within do
|
||||
FetchReplyWorker.perform_async(root_status_uri, { **options.deep_stringify_keys, 'prefetched_body' => root_status_body })
|
||||
end
|
||||
FetchReplyWorker.perform_async(root_status_uri, { **options.deep_stringify_keys.except('batch_id'), 'prefetched_body' => root_status_body })
|
||||
|
||||
get_replies(root_status_body, MAX_PAGES, options)
|
||||
end
|
||||
|
|
|
@ -190,6 +190,7 @@ da:
|
|||
create_relay: Opret Videresendelse
|
||||
create_unavailable_domain: Opret Utilgængeligt Domæne
|
||||
create_user_role: Opret rolle
|
||||
create_username_block: Opret brugernavn-regel
|
||||
demote_user: Degradér bruger
|
||||
destroy_announcement: Slet bekendtgørelse
|
||||
destroy_canonical_email_block: Slet e-mailblokering
|
||||
|
@ -203,6 +204,7 @@ da:
|
|||
destroy_status: Slet indlæg
|
||||
destroy_unavailable_domain: Slet Utilgængeligt Domæne
|
||||
destroy_user_role: Ødelæg rolle
|
||||
destroy_username_block: Slet brugernavn-regel
|
||||
disable_2fa_user: Deaktivér 2FA
|
||||
disable_custom_emoji: Deaktivér tilpasset emoji
|
||||
disable_relay: Deaktivér Videresendelse
|
||||
|
@ -237,6 +239,7 @@ da:
|
|||
update_report: Opdatér anmeldelse
|
||||
update_status: Opdatér indlæg
|
||||
update_user_role: Opdatér rolle
|
||||
update_username_block: Opdatér brugernavn-regel
|
||||
actions:
|
||||
approve_appeal_html: "%{name} godkendte moderationsafgørelsesappellen fra %{target}"
|
||||
approve_user_html: "%{name} godkendte tilmeldingen fra %{target}"
|
||||
|
@ -255,6 +258,7 @@ da:
|
|||
create_relay_html: "%{name} oprettede videresendelsen %{target}"
|
||||
create_unavailable_domain_html: "%{name} stoppede levering til domænet %{target}"
|
||||
create_user_role_html: "%{name} oprettede %{target}-rolle"
|
||||
create_username_block_html: "%{name} tilføjede regel for brugernavne indeholdende %{target}"
|
||||
demote_user_html: "%{name} degraderede brugeren %{target}"
|
||||
destroy_announcement_html: "%{name} slettede bekendtgørelsen %{target}"
|
||||
destroy_canonical_email_block_html: "%{name} afblokerede e-mailen med hash'et %{target}"
|
||||
|
@ -268,6 +272,7 @@ da:
|
|||
destroy_status_html: "%{name} fjernede indlægget fra %{target}"
|
||||
destroy_unavailable_domain_html: "%{name} genoptog levering til domænet %{target}"
|
||||
destroy_user_role_html: "%{name} slettede %{target}-rolle"
|
||||
destroy_username_block_html: "%{name} fjernede regel for brugernavne indeholdende %{target}"
|
||||
disable_2fa_user_html: "%{name} deaktiverede tofaktorkravet for brugeren %{target}"
|
||||
disable_custom_emoji_html: "%{name} deaktiverede emojien %{target}"
|
||||
disable_relay_html: "%{name} deaktiverede videresendelsen %{target}"
|
||||
|
@ -302,6 +307,7 @@ da:
|
|||
update_report_html: "%{name} opdaterede rapporten %{target}"
|
||||
update_status_html: "%{name} opdaterede indlægget fra %{target}"
|
||||
update_user_role_html: "%{name} ændrede %{target}-rolle"
|
||||
update_username_block_html: "%{name} opdaterede regel for brugernavne indeholdende %{target}"
|
||||
deleted_account: slettet konto
|
||||
empty: Ingen logger fundet.
|
||||
filter_by_action: Filtrér efter handling
|
||||
|
@ -1085,6 +1091,25 @@ da:
|
|||
other: Brugt af %{count} personer den seneste uge
|
||||
title: Anbefalinger og trends
|
||||
trending: Trender
|
||||
username_blocks:
|
||||
add_new: Tilføj ny
|
||||
block_registrations: Blokér registreringer
|
||||
comparison:
|
||||
contains: Indeholder
|
||||
equals: Er lig
|
||||
contains_html: Indeholder %{string}
|
||||
created_msg: Brugernavn-regel er hermed oprettet
|
||||
delete: Slet
|
||||
edit:
|
||||
title: Redigér brugernavn-regel
|
||||
matches_exactly_html: Er lig med %{string}
|
||||
new:
|
||||
create: Opret regel
|
||||
title: Opret ny brugernavn-regel
|
||||
no_username_block_selected: Ingen brugernavn-regler ændret (ingen var valgt)
|
||||
not_permitted: Ikke tilladt
|
||||
title: Brugernavn-regler
|
||||
updated_msg: Brugernavn-regel opdateret
|
||||
warning_presets:
|
||||
add_new: Tilføj ny
|
||||
delete: Slet
|
||||
|
|
|
@ -190,6 +190,7 @@ de:
|
|||
create_relay: Relay erstellen
|
||||
create_unavailable_domain: Nicht verfügbare Domain erstellen
|
||||
create_user_role: Rolle erstellen
|
||||
create_username_block: Regel für Profilnamen erstellen
|
||||
demote_user: Benutzer*in herabstufen
|
||||
destroy_announcement: Ankündigung löschen
|
||||
destroy_canonical_email_block: E-Mail-Sperre entfernen
|
||||
|
@ -203,6 +204,7 @@ de:
|
|||
destroy_status: Beitrag entfernen
|
||||
destroy_unavailable_domain: Nicht-verfügbare Domain entfernen
|
||||
destroy_user_role: Rolle entfernen
|
||||
destroy_username_block: Regel für Profilnamen löschen
|
||||
disable_2fa_user: 2FA deaktivieren
|
||||
disable_custom_emoji: Eigenes Emoji deaktivieren
|
||||
disable_relay: Relay deaktivieren
|
||||
|
@ -237,6 +239,7 @@ de:
|
|||
update_report: Meldung aktualisieren
|
||||
update_status: Beitrag aktualisieren
|
||||
update_user_role: Rolle bearbeiten
|
||||
update_username_block: Regel für Profilnamen aktualisieren
|
||||
actions:
|
||||
approve_appeal_html: "%{name} hat den Einspruch gegen eine Moderationsentscheidung von %{target} genehmigt"
|
||||
approve_user_html: "%{name} genehmigte die Registrierung von %{target}"
|
||||
|
@ -255,6 +258,7 @@ de:
|
|||
create_relay_html: "%{name} erstellte ein Relay %{target}"
|
||||
create_unavailable_domain_html: "%{name} beendete die Zustellung an die Domain %{target}"
|
||||
create_user_role_html: "%{name} erstellte die Rolle %{target}"
|
||||
create_username_block_html: "%{name} erstellte eine Regel für Profilnamen mit %{target}"
|
||||
demote_user_html: "%{name} stufte %{target} herunter"
|
||||
destroy_announcement_html: "%{name} löschte die Ankündigung %{target}"
|
||||
destroy_canonical_email_block_html: "%{name} entsperrte die E-Mail mit dem Hash %{target}"
|
||||
|
@ -268,6 +272,7 @@ de:
|
|||
destroy_status_html: "%{name} entfernte einen Beitrag von %{target}"
|
||||
destroy_unavailable_domain_html: "%{name} nahm die Zustellung an die Domain %{target} wieder auf"
|
||||
destroy_user_role_html: "%{name} löschte die Rolle %{target}"
|
||||
destroy_username_block_html: "%{name} entfernte eine Regel für Profilnamen mit %{target}"
|
||||
disable_2fa_user_html: "%{name} deaktivierte die Zwei-Faktor-Authentisierung für %{target}"
|
||||
disable_custom_emoji_html: "%{name} deaktivierte das Emoji %{target}"
|
||||
disable_relay_html: "%{name} deaktivierte das Relay %{target}"
|
||||
|
@ -302,6 +307,7 @@ de:
|
|||
update_report_html: "%{name} überarbeitete die Meldung %{target}"
|
||||
update_status_html: "%{name} überarbeitete einen Beitrag von %{target}"
|
||||
update_user_role_html: "%{name} änderte die Rolle von %{target}"
|
||||
update_username_block_html: "%{name} aktualisierte eine Regel für Profilnamen mit %{target}"
|
||||
deleted_account: gelöschtes Konto
|
||||
empty: Protokolle nicht gefunden.
|
||||
filter_by_action: Nach Aktion filtern
|
||||
|
@ -1085,6 +1091,25 @@ de:
|
|||
other: In den vergangenen 7 Tagen von %{count} Profilen verwendet
|
||||
title: Empfehlungen & Trends
|
||||
trending: Angesagt
|
||||
username_blocks:
|
||||
add_new: Neue Regel
|
||||
block_registrations: Registrierungen sperren
|
||||
comparison:
|
||||
contains: Enthält
|
||||
equals: Entspricht
|
||||
contains_html: Enthält %{string}
|
||||
created_msg: Regel für Profilnamen erfolgreich erstellt
|
||||
delete: Löschen
|
||||
edit:
|
||||
title: Regel für Profilnamen bearbeiten
|
||||
matches_exactly_html: Entspricht %{string}
|
||||
new:
|
||||
create: Regel erstellen
|
||||
title: Neue Regel für Profilnamen erstellen
|
||||
no_username_block_selected: Keine Regeln für Profilnamen wurden geändert, weil keine ausgewählt wurde(n)
|
||||
not_permitted: Nicht gestattet
|
||||
title: Regeln für Profilnamen
|
||||
updated_msg: Regel für Profilnamen erfolgreich aktualisiert
|
||||
warning_presets:
|
||||
add_new: Neu hinzufügen
|
||||
delete: Löschen
|
||||
|
|
|
@ -190,6 +190,7 @@ es-AR:
|
|||
create_relay: Crear relé
|
||||
create_unavailable_domain: Crear dominio no disponible
|
||||
create_user_role: Crear rol
|
||||
create_username_block: Crear regla de nombre de usuario
|
||||
demote_user: Descender usuario
|
||||
destroy_announcement: Eliminar anuncio
|
||||
destroy_canonical_email_block: Eliminar bloqueo de correo electrónico
|
||||
|
@ -203,6 +204,7 @@ es-AR:
|
|||
destroy_status: Eliminar mensaje
|
||||
destroy_unavailable_domain: Eliminar dominio no disponible
|
||||
destroy_user_role: Destruir rol
|
||||
destroy_username_block: Eliminar regla de nombre de usuario
|
||||
disable_2fa_user: Deshabilitar 2FA
|
||||
disable_custom_emoji: Deshabilitar emoji personalizado
|
||||
disable_relay: Deshabilitar relé
|
||||
|
@ -237,6 +239,7 @@ es-AR:
|
|||
update_report: Actualizar denuncia
|
||||
update_status: Actualizar mensaje
|
||||
update_user_role: Actualizar rol
|
||||
update_username_block: Actualizar regla de nombre de usuario
|
||||
actions:
|
||||
approve_appeal_html: "%{name} aprobó la solicitud de moderación de %{target}"
|
||||
approve_user_html: "%{name} aprobó el registro de %{target}"
|
||||
|
@ -255,6 +258,7 @@ es-AR:
|
|||
create_relay_html: "%{name} creó el relé %{target}"
|
||||
create_unavailable_domain_html: "%{name} detuvo la entrega al dominio %{target}"
|
||||
create_user_role_html: "%{name} creó el rol %{target}"
|
||||
create_username_block_html: "%{name} agregó una regla para los nombres de usuario que contienen %{target}"
|
||||
demote_user_html: "%{name} bajó de nivel al usuario %{target}"
|
||||
destroy_announcement_html: "%{name} eliminó el anuncio %{target}"
|
||||
destroy_canonical_email_block_html: "%{name} desbloqueó el correo electrónico con el hash %{target}"
|
||||
|
@ -268,6 +272,7 @@ es-AR:
|
|||
destroy_status_html: "%{name} eliminó el mensaje de %{target}"
|
||||
destroy_unavailable_domain_html: "%{name} reanudó la entrega al dominio %{target}"
|
||||
destroy_user_role_html: "%{name} eliminó el rol %{target}"
|
||||
destroy_username_block_html: "%{name} eliminó una regla para los nombres de usuario que contienen %{target}"
|
||||
disable_2fa_user_html: "%{name} deshabilitó el requerimiento de dos factores para el usuario %{target}"
|
||||
disable_custom_emoji_html: "%{name} deshabilitó el emoji %{target}"
|
||||
disable_relay_html: "%{name} deshabilitó el relé %{target}"
|
||||
|
@ -302,6 +307,7 @@ es-AR:
|
|||
update_report_html: "%{name} actualizó la denuncia %{target}"
|
||||
update_status_html: "%{name} actualizó el mensaje de %{target}"
|
||||
update_user_role_html: "%{name} cambió el rol %{target}"
|
||||
update_username_block_html: "%{name} actualizó una regla para los nombres de usuario que contienen %{target}"
|
||||
deleted_account: cuenta eliminada
|
||||
empty: No se encontraron registros.
|
||||
filter_by_action: Filtrar por acción
|
||||
|
@ -1085,6 +1091,25 @@ es-AR:
|
|||
other: Usada por %{count} personas durante la última semana
|
||||
title: Recomendaciones y tendencias
|
||||
trending: En tendencia
|
||||
username_blocks:
|
||||
add_new: Agregar nueva
|
||||
block_registrations: Bloquear registros
|
||||
comparison:
|
||||
contains: Contiene
|
||||
equals: Es igual a
|
||||
contains_html: Contiene %{string}
|
||||
created_msg: Regla de nombre de usuario creada exitosamente
|
||||
delete: Eliminar
|
||||
edit:
|
||||
title: Editar regla de nombre de usuario
|
||||
matches_exactly_html: Es igual a %{string}
|
||||
new:
|
||||
create: Crear regla
|
||||
title: Crear nueva regla de nombre de usuario
|
||||
no_username_block_selected: No se cambiaron las reglas de nombre de usuario, ya que no se seleccionó ninguna
|
||||
not_permitted: No permitido
|
||||
title: Reglas de nombre de usuario
|
||||
updated_msg: Regla de nombre de usuario actualizada exitosamente
|
||||
warning_presets:
|
||||
add_new: Agregar nuevo
|
||||
delete: Eliminar
|
||||
|
|
|
@ -190,6 +190,7 @@ es-MX:
|
|||
create_relay: Crear Relé
|
||||
create_unavailable_domain: Crear Dominio No Disponible
|
||||
create_user_role: Crear rol
|
||||
create_username_block: Crear regla de nombre de usuario
|
||||
demote_user: Degradar Usuario
|
||||
destroy_announcement: Eliminar Anuncio
|
||||
destroy_canonical_email_block: Eliminar bloqueo de correo electrónico
|
||||
|
@ -203,6 +204,7 @@ es-MX:
|
|||
destroy_status: Eliminar Publicación
|
||||
destroy_unavailable_domain: Eliminar Dominio No Disponible
|
||||
destroy_user_role: Destruir Rol
|
||||
destroy_username_block: Eliminar regla de nombre de usuario
|
||||
disable_2fa_user: Deshabilitar 2FA
|
||||
disable_custom_emoji: Deshabilitar Emoji Personalizado
|
||||
disable_relay: Desactivar Relé
|
||||
|
@ -237,6 +239,7 @@ es-MX:
|
|||
update_report: Actualizar informe
|
||||
update_status: Actualizar Publicación
|
||||
update_user_role: Actualizar Rol
|
||||
update_username_block: Actualizar regla de nombre de usuario
|
||||
actions:
|
||||
approve_appeal_html: "%{name} aprobó la solicitud de moderación de %{target}"
|
||||
approve_user_html: "%{name} aprobó el registro de %{target}"
|
||||
|
@ -255,6 +258,7 @@ es-MX:
|
|||
create_relay_html: "%{name} creó un relé %{target}"
|
||||
create_unavailable_domain_html: "%{name} detuvo las entregas al dominio %{target}"
|
||||
create_user_role_html: "%{name} creó el rol %{target}"
|
||||
create_username_block_html: "%{name} añadió regla para nombres de usuario que contienen %{target}"
|
||||
demote_user_html: "%{name} degradó al usuario %{target}"
|
||||
destroy_announcement_html: "%{name} eliminó el anuncio %{target}"
|
||||
destroy_canonical_email_block_html: "%{name} ha desbloqueado el correo electrónico con el hash %{target}"
|
||||
|
@ -268,6 +272,7 @@ es-MX:
|
|||
destroy_status_html: "%{name} eliminó la publicación por %{target}"
|
||||
destroy_unavailable_domain_html: "%{name} reanudó las entregas al dominio %{target}"
|
||||
destroy_user_role_html: "%{name} eliminó el rol %{target}"
|
||||
destroy_username_block_html: "%{name} eliminó la regla para los nombres de usuario que contienen %{target}"
|
||||
disable_2fa_user_html: "%{name} desactivó el requisito de dos factores para el usuario %{target}"
|
||||
disable_custom_emoji_html: "%{name} desactivó el emoji %{target}"
|
||||
disable_relay_html: "%{name} desactivó el relé %{target}"
|
||||
|
@ -302,6 +307,7 @@ es-MX:
|
|||
update_report_html: "%{name} actualizó el informe %{target}"
|
||||
update_status_html: "%{name} actualizó la publicación de %{target}"
|
||||
update_user_role_html: "%{name} cambió el rol %{target}"
|
||||
update_username_block_html: "%{name} actualizó una regla para los nombres de usuario que contienen %{target}"
|
||||
deleted_account: cuenta eliminada
|
||||
empty: No se encontraron registros.
|
||||
filter_by_action: Filtrar por acción
|
||||
|
@ -1085,6 +1091,25 @@ es-MX:
|
|||
other: Usada por %{count} personas durante la última semana
|
||||
title: Recomendaciones y Tendencias
|
||||
trending: En tendencia
|
||||
username_blocks:
|
||||
add_new: Añadir nuevo
|
||||
block_registrations: Bloquear registros
|
||||
comparison:
|
||||
contains: Contiene
|
||||
equals: Igual
|
||||
contains_html: Contiene %{string}
|
||||
created_msg: Regla de nombre de usuario creada correctamente
|
||||
delete: Eliminar
|
||||
edit:
|
||||
title: Editar regla de nombre de usuario
|
||||
matches_exactly_html: Es igual a %{string}
|
||||
new:
|
||||
create: Crear regla
|
||||
title: Crear nueva regla de nombre de usuario
|
||||
no_username_block_selected: No se modificaron las reglas de nombre de usuario, ya que no se seleccionó ninguna
|
||||
not_permitted: No permitido
|
||||
title: Reglas para el nombre de usuario
|
||||
updated_msg: Regla de nombre de usuario actualizada correctamente
|
||||
warning_presets:
|
||||
add_new: Añadir nuevo
|
||||
delete: Borrar
|
||||
|
|
|
@ -190,6 +190,7 @@ es:
|
|||
create_relay: Crear Relé
|
||||
create_unavailable_domain: Crear Dominio No Disponible
|
||||
create_user_role: Crear Rol
|
||||
create_username_block: Crear regla de nombre de usuario
|
||||
demote_user: Degradar Usuario
|
||||
destroy_announcement: Eliminar Anuncio
|
||||
destroy_canonical_email_block: Eliminar Bloqueo de Correo Electrónico
|
||||
|
@ -203,6 +204,7 @@ es:
|
|||
destroy_status: Eliminar Publicación
|
||||
destroy_unavailable_domain: Eliminar Dominio No Disponible
|
||||
destroy_user_role: Destruir Rol
|
||||
destroy_username_block: Eliminar regla de nombre de usuario
|
||||
disable_2fa_user: Deshabilitar 2FA
|
||||
disable_custom_emoji: Deshabilitar Emoji Personalizado
|
||||
disable_relay: Desactivar Relé
|
||||
|
@ -237,6 +239,7 @@ es:
|
|||
update_report: Actualizar informe
|
||||
update_status: Actualizar Publicación
|
||||
update_user_role: Actualizar Rol
|
||||
update_username_block: Actualizar regla de nombre de usuario
|
||||
actions:
|
||||
approve_appeal_html: "%{name} aprobó la solicitud de moderación de %{target}"
|
||||
approve_user_html: "%{name} aprobó el registro de %{target}"
|
||||
|
@ -255,6 +258,7 @@ es:
|
|||
create_relay_html: "%{name} creó un relé %{target}"
|
||||
create_unavailable_domain_html: "%{name} detuvo las entregas al dominio %{target}"
|
||||
create_user_role_html: "%{name} creó el rol %{target}"
|
||||
create_username_block_html: "%{name} agregó una regla para los nombres de usuario que contienen %{target}"
|
||||
demote_user_html: "%{name} degradó al usuario %{target}"
|
||||
destroy_announcement_html: "%{name} eliminó el anuncio %{target}"
|
||||
destroy_canonical_email_block_html: "%{name} desbloqueó el correo electrónico con el hash %{target}"
|
||||
|
@ -268,6 +272,7 @@ es:
|
|||
destroy_status_html: "%{name} eliminó la publicación de %{target}"
|
||||
destroy_unavailable_domain_html: "%{name} reanudó las entregas al dominio %{target}"
|
||||
destroy_user_role_html: "%{name} eliminó el rol %{target}"
|
||||
destroy_username_block_html: "%{name} eliminó una regla para los nombres de usuario que contienen %{target}"
|
||||
disable_2fa_user_html: "%{name} desactivó el requisito de dos factores para el usuario %{target}"
|
||||
disable_custom_emoji_html: "%{name} desactivó el emoji %{target}"
|
||||
disable_relay_html: "%{name} desactivó el relé %{target}"
|
||||
|
@ -302,6 +307,7 @@ es:
|
|||
update_report_html: "%{name} actualizó el informe %{target}"
|
||||
update_status_html: "%{name} actualizó la publicación de %{target}"
|
||||
update_user_role_html: "%{name} cambió el rol %{target}"
|
||||
update_username_block_html: "%{name} actualizó una regla para los nombres de usuario que contienen %{target}"
|
||||
deleted_account: cuenta eliminada
|
||||
empty: No se encontraron registros.
|
||||
filter_by_action: Filtrar por acción
|
||||
|
@ -1085,6 +1091,25 @@ es:
|
|||
other: Usada por %{count} personas durante la última semana
|
||||
title: Recomendaciones y Tendencias
|
||||
trending: En tendencia
|
||||
username_blocks:
|
||||
add_new: Añadir nueva
|
||||
block_registrations: Bloquear registros
|
||||
comparison:
|
||||
contains: Contiene
|
||||
equals: Es igual a
|
||||
contains_html: Contiene %{string}
|
||||
created_msg: Regla de nombre de usuario creada correctamente
|
||||
delete: Eliminar
|
||||
edit:
|
||||
title: Editar regla de nombre de usuario
|
||||
matches_exactly_html: Es igual a %{string}
|
||||
new:
|
||||
create: Crear regla
|
||||
title: Crear nueva regla de nombre de usuario
|
||||
no_username_block_selected: No se cambiaron las reglas de nombre de usuario, ya que no se seleccionó ninguno
|
||||
not_permitted: No permitido
|
||||
title: Reglas de nombre de usuario
|
||||
updated_msg: Regla de nombre de usuario actualizada correctamente
|
||||
warning_presets:
|
||||
add_new: Añadir nuevo
|
||||
delete: Borrar
|
||||
|
@ -1872,7 +1897,7 @@ es:
|
|||
edited_at_html: Editado %{date}
|
||||
errors:
|
||||
in_reply_not_found: La publicación a la que intentas responder no existe.
|
||||
quoted_status_not_found: La publicación que estás intentando citar no existe.
|
||||
quoted_status_not_found: La publicación que estás intentando citar no parece existir.
|
||||
over_character_limit: Límite de caracteres de %{max} superado
|
||||
pin_errors:
|
||||
direct: Las publicaciones que son visibles solo para los usuarios mencionados no pueden fijarse
|
||||
|
|
|
@ -190,6 +190,7 @@ et:
|
|||
create_relay: Loo sõnumivahendusserver
|
||||
create_unavailable_domain: Kättesaamatu domeeni lisamine
|
||||
create_user_role: Loo roll
|
||||
create_username_block: Lisa kasutajanime reegel
|
||||
demote_user: Alandas kasutaja
|
||||
destroy_announcement: Eemaldas teadaande
|
||||
destroy_canonical_email_block: Kustuta e-posti blokeering
|
||||
|
@ -203,6 +204,7 @@ et:
|
|||
destroy_status: Kustuta postitus
|
||||
destroy_unavailable_domain: Kättesaamatu domeeni kustutamine
|
||||
destroy_user_role: Rolli kustutamine
|
||||
destroy_username_block: Kustuta kasutajanime reegel
|
||||
disable_2fa_user: Keela 2FA
|
||||
disable_custom_emoji: Keelas kohandatud emotikoni
|
||||
disable_relay: Lülita sõnumivahendusserver välja
|
||||
|
@ -237,6 +239,7 @@ et:
|
|||
update_report: Uuendamise raport
|
||||
update_status: Uuenda postitust
|
||||
update_user_role: Uuenda rolli
|
||||
update_username_block: Uuenda kasutajanime reeglit
|
||||
actions:
|
||||
approve_appeal_html: "%{name} kiitis heaks modereerimise otsuse vaidlustuse %{target} poolt"
|
||||
approve_user_html: "%{name} kiitis heaks registreerimise %{target} poolt"
|
||||
|
@ -255,6 +258,7 @@ et:
|
|||
create_relay_html: "%{name} lõi sõnumivahendusserveri: %{target}"
|
||||
create_unavailable_domain_html: "%{name} lõpetas edastamise domeeni %{target}"
|
||||
create_user_role_html: "%{name} lõi rolli %{target}"
|
||||
create_username_block_html: "%{name} lisas kasutajanime reegli, milles sisaldub %{target}"
|
||||
demote_user_html: "%{name} alandas kasutajat %{target}"
|
||||
destroy_announcement_html: "%{name} kustutas teadaande %{target}"
|
||||
destroy_canonical_email_block_html: "%{name} eemaldas blokeeringu e-postilt räsiga %{target}"
|
||||
|
@ -268,6 +272,7 @@ et:
|
|||
destroy_status_html: "%{name} kustutas %{target} postituse"
|
||||
destroy_unavailable_domain_html: "%{name} taastas edastamise domeeni %{target}"
|
||||
destroy_user_role_html: "%{name} kustutas %{target} rolli"
|
||||
destroy_username_block_html: "%{name} eemaldas kasutajanime reegli, milles sisaldub %{target}"
|
||||
disable_2fa_user_html: "%{name} eemaldas kasutaja %{target} kahe etapise nõude"
|
||||
disable_custom_emoji_html: "%{name} keelas emotikooni %{target}"
|
||||
disable_relay_html: "%{name} eemaldas sõnumivahendusserveri kasutuselt: %{target}"
|
||||
|
@ -302,6 +307,7 @@ et:
|
|||
update_report_html: "%{name} uuendas raportit %{target}"
|
||||
update_status_html: "%{name} muutis %{target} postitust"
|
||||
update_user_role_html: "%{name} muutis %{target} rolli"
|
||||
update_username_block_html: "%{name} uuendas kasutajanime reeglit, milles sisaldub %{target}"
|
||||
deleted_account: kustutatud konto
|
||||
empty: Logisi ei leitud.
|
||||
filter_by_action: Filtreeri tegevuse järgi
|
||||
|
@ -806,6 +812,8 @@ et:
|
|||
preamble: Täpsem kirjeldus, kuidas serverit käitatakse, modereeritakse ja rahastatakse.
|
||||
rules_hint: Reeglitele, millega kasutajad peavad nõustuma, on vastav piirkond.
|
||||
title: Teave
|
||||
allow_referrer_origin:
|
||||
title: Luba välistel serveritel näha Mastodoni teenust linkide viitajana
|
||||
appearance:
|
||||
preamble: Kohanda Mastodoni veebiliidest.
|
||||
title: Välimus
|
||||
|
@ -993,6 +1001,7 @@ et:
|
|||
other: Saada %{display_count} e-kirja
|
||||
publish: Postita
|
||||
published_on_html: Postitatud %{date}
|
||||
save_draft: Salvesta kavandina
|
||||
title: Kasutustingimused
|
||||
title: Administreerimine
|
||||
trends:
|
||||
|
@ -1069,6 +1078,25 @@ et:
|
|||
other: Kasutatud %{count} kasutaja poolt viimase nädala jooksul
|
||||
title: Soovitused ja trendid
|
||||
trending: Trendid
|
||||
username_blocks:
|
||||
add_new: Lisa uus
|
||||
block_registrations: Blokeeri registreerimisi
|
||||
comparison:
|
||||
contains: Sisaldab
|
||||
equals: Võrdub
|
||||
contains_html: 'Sisaldab: %{string}'
|
||||
created_msg: Kasutajanime reegli lisamine õnnestus
|
||||
delete: Kustuta
|
||||
edit:
|
||||
title: Muuda kasutajanime reeglit
|
||||
matches_exactly_html: 'Võrdub: %{string}'
|
||||
new:
|
||||
create: Lisa reegel
|
||||
title: Lisa uus kasutajanime reegel
|
||||
no_username_block_selected: Ühtegi kasutajanimereeglit ei muudetud, kuna midagi polnud valitud
|
||||
not_permitted: Ei ole lubatud
|
||||
title: Kasutajanime reeglid
|
||||
updated_msg: Kasutajanime reegli uuendamine õnnestus
|
||||
warning_presets:
|
||||
add_new: Lisa uus
|
||||
delete: Kustuta
|
||||
|
@ -1331,6 +1359,10 @@ et:
|
|||
basic_information: Põhiinfo
|
||||
hint_html: "<strong>Kohanda, mida inimesed näevad su avalikul profiilil ja postituste kõrval.</strong> Inimesed alustavad tõenäolisemalt sinu jälgimist ja interakteeruvad sinuga, kui sul on täidetud profiil ja profiilipilt."
|
||||
other: Muu
|
||||
emoji_styles:
|
||||
auto: Automaatne
|
||||
native: Rakenduseomane
|
||||
twemoji: Twemoji
|
||||
errors:
|
||||
'400': Esitatud päring oli vigane või valesti vormindatud.
|
||||
'403': Sul puudub õigus seda lehte vaadata.
|
||||
|
@ -1850,6 +1882,7 @@ et:
|
|||
edited_at_html: Muudetud %{date}
|
||||
errors:
|
||||
in_reply_not_found: Postitus, millele üritad vastata, ei näi enam eksisteerivat.
|
||||
quoted_status_not_found: Postitus, mida üritad tsiteerida, ei näi enam eksisteerivat.
|
||||
over_character_limit: tähtmärkide limiit %{max} ületatud
|
||||
pin_errors:
|
||||
direct: Ei saa kinnitada postitusi, mis on nähtavad vaid mainitud kasutajatele
|
||||
|
|
|
@ -190,6 +190,7 @@ fo:
|
|||
create_relay: Stovna reiðlag
|
||||
create_unavailable_domain: Stovna navnaøki, sum ikki er tøkt
|
||||
create_user_role: Stovna leiklut
|
||||
create_username_block: Stovna brúkaranavnsreglu
|
||||
demote_user: Lækka brúkara í tign
|
||||
destroy_announcement: Strika kunngerð
|
||||
destroy_canonical_email_block: Strika t-postablokk
|
||||
|
@ -203,6 +204,7 @@ fo:
|
|||
destroy_status: Strika post
|
||||
destroy_unavailable_domain: Strika navnaøki, sum ikki er tøkt
|
||||
destroy_user_role: Bein burtur leiklut
|
||||
destroy_username_block: Strika brúkaranavnsreglu
|
||||
disable_2fa_user: Ger 2FA óvirkið
|
||||
disable_custom_emoji: Ger serligt kenslutekn óvirkið
|
||||
disable_relay: Ger reiðlag óvirkið
|
||||
|
@ -237,6 +239,7 @@ fo:
|
|||
update_report: Dagfør frágreiðing
|
||||
update_status: Dagfør Uppslag
|
||||
update_user_role: Dagfør Leiklut
|
||||
update_username_block: Dagfør brúkaranavnsreglu
|
||||
actions:
|
||||
approve_appeal_html: "%{name} góðkendi umsjónaráheitan frá %{target}"
|
||||
approve_user_html: "%{name} góðtók umsókn frá %{target}"
|
||||
|
@ -255,6 +258,7 @@ fo:
|
|||
create_relay_html: "%{name} gjørdi eitt reiðlag %{target}"
|
||||
create_unavailable_domain_html: "%{name} steðgaði veiting til navnaøkið %{target}"
|
||||
create_user_role_html: "%{name} stovnaði %{target} leiklutin"
|
||||
create_username_block_html: "%{name} legði reglu afturat fyri brúkaranøvn, sum innihalda %{target}"
|
||||
demote_user_html: "%{name} lækkaði tignina hjá brúkaranum %{target}"
|
||||
destroy_announcement_html: "%{name} strikaðar fráboðanir %{target}"
|
||||
destroy_canonical_email_block_html: "%{name} strikaði blokeringina av teldupostin við hashkodu %{target}"
|
||||
|
@ -268,6 +272,7 @@ fo:
|
|||
destroy_status_html: "%{name} slettaði upplegg hjá %{target}"
|
||||
destroy_unavailable_domain_html: "%{name} tók upp aftir veiting til navnaøkið %{target}"
|
||||
destroy_user_role_html: "%{name} slettaði leiklutin hjá %{target}"
|
||||
destroy_username_block_html: "%{name} strikaði reglu fyri brúkaranøvn, sum innihalda %{target}"
|
||||
disable_2fa_user_html: "%{name} slepti kravið um váttan í tveimum stigum fyri brúkaran %{target}"
|
||||
disable_custom_emoji_html: "%{name} gjørdi kensluteknið %{target} óvirkið"
|
||||
disable_relay_html: "%{name} gjørdi reiðlagið %{target} óvirkið"
|
||||
|
@ -302,6 +307,7 @@ fo:
|
|||
update_report_html: "%{name} dagførdi meldingina %{target}"
|
||||
update_status_html: "%{name} dagførdi postin hjá %{target}"
|
||||
update_user_role_html: "%{name} broyttir %{target} leiklutir"
|
||||
update_username_block_html: "%{name} dagførdi reglu fyri brúkaranøvn, sum innihalda %{target}"
|
||||
deleted_account: strikað konta
|
||||
empty: Eingir loggar funnir.
|
||||
filter_by_action: Filtrera eftir atgerð
|
||||
|
@ -1085,6 +1091,25 @@ fo:
|
|||
other: Brúkt av %{count} brúkarum seinastu vikuna
|
||||
title: Tilmæli & rák
|
||||
trending: Vælumtókt
|
||||
username_blocks:
|
||||
add_new: Legg afturat
|
||||
block_registrations: Blokera skrásetingar
|
||||
comparison:
|
||||
contains: Inniheldur
|
||||
equals: Er tað sama sum
|
||||
contains_html: Inniheldur %{string}
|
||||
created_msg: Eydnaðist at leggja brúkaranavnsreglu afturat
|
||||
delete: Strika
|
||||
edit:
|
||||
title: Broyt brúkaranavnsreglu
|
||||
matches_exactly_html: Tað sama sum %{string}
|
||||
new:
|
||||
create: Stovna reglu
|
||||
title: Stovna brúkaranavnsreglu
|
||||
no_username_block_selected: Ongar brúkaranavnsreglur vóru broyttar, tí ongar vóru valdar
|
||||
not_permitted: Ikki loyvt
|
||||
title: Brúkaranavnsreglur
|
||||
updated_msg: Eydnaðist at dagføra brúkaranavnsreglu
|
||||
warning_presets:
|
||||
add_new: Legg afturat
|
||||
delete: Strika
|
||||
|
|
|
@ -190,6 +190,7 @@ fy:
|
|||
create_relay: Relay oanmeitsje
|
||||
create_unavailable_domain: Net beskikber domein oanmeitsje
|
||||
create_user_role: Rol oanmeitsje
|
||||
create_username_block: Brûkersnammeregel oanmeitsje
|
||||
demote_user: Brûker degradearje
|
||||
destroy_announcement: Meidieling fuortsmite
|
||||
destroy_canonical_email_block: E-mailblokkade fuortsmite
|
||||
|
@ -203,6 +204,7 @@ fy:
|
|||
destroy_status: Toot fuortsmite
|
||||
destroy_unavailable_domain: Net beskikber domein fuortsmite
|
||||
destroy_user_role: Rol permanint fuortsmite
|
||||
destroy_username_block: Brûkersnammeregel fuortsmite
|
||||
disable_2fa_user: Twa-stapsferifikaasje útskeakelje
|
||||
disable_custom_emoji: Lokale emoji útskeakelje
|
||||
disable_relay: Relay útskeakelje
|
||||
|
@ -237,6 +239,7 @@ fy:
|
|||
update_report: Rapportaazje bywurkje
|
||||
update_status: Berjocht bywurkje
|
||||
update_user_role: Rol bywurkje
|
||||
update_username_block: Brûkersnammeregel bywurkje
|
||||
actions:
|
||||
approve_appeal_html: "%{name} hat it beswier tsjin de moderaasjemaatregel fan %{target} goedkard"
|
||||
approve_user_html: "%{name} hat de registraasje fan %{target} goedkard"
|
||||
|
@ -255,6 +258,7 @@ fy:
|
|||
create_relay_html: "%{name} hat in relay oanmakke %{target}"
|
||||
create_unavailable_domain_html: "%{name} hat de besoarging foar domein %{target} beëinige"
|
||||
create_user_role_html: "%{name} hat de rol %{target} oanmakke"
|
||||
create_username_block_html: "%{name} hat in brûkersnammeregel mei %{target} tafoege"
|
||||
demote_user_html: Brûker %{target} is troch %{name} degradearre
|
||||
destroy_announcement_html: "%{name} hat de meidieling %{target} fuortsmiten"
|
||||
destroy_canonical_email_block_html: "%{name} hat it e-mailberjocht mei de hash %{target} deblokkearre"
|
||||
|
@ -268,6 +272,7 @@ fy:
|
|||
destroy_status_html: Berjocht fan %{target} is troch %{name} fuortsmiten
|
||||
destroy_unavailable_domain_html: "%{name} hat de besoarging foar domein %{target} opnij starte"
|
||||
destroy_user_role_html: "%{name} hat de rol %{target} fuortsmiten"
|
||||
destroy_username_block_html: "%{name} hat in brûkersnammeregel mei %{target} fuortsmiten"
|
||||
disable_2fa_user_html: De fereaske twa-stapsferifikaasje foar %{target} is troch %{name} útskeakele
|
||||
disable_custom_emoji_html: Emoji %{target} is troch %{name} útskeakele
|
||||
disable_relay_html: "%{name} hat de relay %{target} útskeakele"
|
||||
|
@ -302,6 +307,7 @@ fy:
|
|||
update_report_html: Rapportaazje %{target} is troch %{name} bywurke
|
||||
update_status_html: "%{name} hat de berjochten %{target} bywurke"
|
||||
update_user_role_html: "%{name} hat de rol %{target} wizige"
|
||||
update_username_block_html: "%{name} hat in brûkersnammeregel mei %{target} bywurke"
|
||||
deleted_account: fuortsmiten account
|
||||
empty: Gjin lochboeken fûn.
|
||||
filter_by_action: Op aksje filterje
|
||||
|
@ -1085,6 +1091,25 @@ fy:
|
|||
other: Dizze wike troch %{count} persoanen brûkt
|
||||
title: Oanrekommandaasjes & trends
|
||||
trending: Trending
|
||||
username_blocks:
|
||||
add_new: Nije tafoegje
|
||||
block_registrations: Registraasjes blokkearje
|
||||
comparison:
|
||||
contains: Befettet
|
||||
equals: Is lyk oan
|
||||
contains_html: Befettet %{string}
|
||||
created_msg: Brûkersnammeregel mei sukses oanmakke
|
||||
delete: Fuortsmite
|
||||
edit:
|
||||
title: Brûkersnammeregel bywurkje
|
||||
matches_exactly_html: Is lyk oan %{string}
|
||||
new:
|
||||
create: Regel oanmeitsje
|
||||
title: Brûkersnammeregel oanmeitsje
|
||||
no_username_block_selected: Der binne gjin brûkersnammeregels wizige, omdat der gjin ien selektearre waard
|
||||
not_permitted: Net tastien
|
||||
title: Brûkersnammeregels
|
||||
updated_msg: Brûkersnammeregel mei sukses bywurke
|
||||
warning_presets:
|
||||
add_new: Nije tafoegje
|
||||
delete: Fuortsmite
|
||||
|
@ -1872,6 +1897,7 @@ fy:
|
|||
edited_at_html: Bewurke op %{date}
|
||||
errors:
|
||||
in_reply_not_found: It berjocht wêrop jo probearje te reagearjen liket net te bestean.
|
||||
quoted_status_not_found: It berjocht dy’t jo probearje te sitearjen liket net te bestean.
|
||||
over_character_limit: Oer de limyt fan %{max} tekens
|
||||
pin_errors:
|
||||
direct: Berjochten dy’t allinnich sichtber binne foar fermelde brûkers kinne net fêstset wurde
|
||||
|
|
|
@ -190,6 +190,7 @@ gl:
|
|||
create_relay: Crear Repetidor
|
||||
create_unavailable_domain: Crear dominio Non dispoñible
|
||||
create_user_role: Crear Rol
|
||||
create_username_block: Crear regra para Identificadores
|
||||
demote_user: Degradar usuaria
|
||||
destroy_announcement: Eliminar anuncio
|
||||
destroy_canonical_email_block: Eliminar bloqueo do correo
|
||||
|
@ -203,6 +204,7 @@ gl:
|
|||
destroy_status: Eliminar publicación
|
||||
destroy_unavailable_domain: Eliminar dominio Non dispoñible
|
||||
destroy_user_role: Eliminar Rol
|
||||
destroy_username_block: Eliminar regra para Identificadores
|
||||
disable_2fa_user: Desactivar 2FA
|
||||
disable_custom_emoji: Desactivar emoticona personalizada
|
||||
disable_relay: Desactivar Repetidor
|
||||
|
@ -237,6 +239,7 @@ gl:
|
|||
update_report: Actualización da denuncia
|
||||
update_status: Actualizar publicación
|
||||
update_user_role: Actualizar Rol
|
||||
update_username_block: Actualizar regra para Identificadores
|
||||
actions:
|
||||
approve_appeal_html: "%{name} aprobou a apelación da decisión da moderación de %{target}"
|
||||
approve_user_html: "%{name} aprobou o rexistro de %{target}"
|
||||
|
@ -255,6 +258,7 @@ gl:
|
|||
create_relay_html: "%{name} creou un repetidor en %{target}"
|
||||
create_unavailable_domain_html: "%{name} deixou de interactuar co dominio %{target}"
|
||||
create_user_role_html: "%{name} creou o rol %{target}"
|
||||
create_username_block_html: "%{name} engadiu unha regra para identificadores que contén %{target}"
|
||||
demote_user_html: "%{name} degradou a usuaria %{target}"
|
||||
destroy_announcement_html: "%{name} eliminou o anuncio %{target}"
|
||||
destroy_canonical_email_block_html: "%{name} desbloqueou o correo con suma de comprobación %{target}"
|
||||
|
@ -268,6 +272,7 @@ gl:
|
|||
destroy_status_html: "%{name} eliminou a publicación de %{target}"
|
||||
destroy_unavailable_domain_html: "%{name} retomou a interacción co dominio %{target}"
|
||||
destroy_user_role_html: "%{name} eliminou o rol %{target}"
|
||||
destroy_username_block_html: "%{name} retirou unha regra para identificadores que contén %{target}"
|
||||
disable_2fa_user_html: "%{name} desactivou o requerimento do segundo factor para a usuaria %{target}"
|
||||
disable_custom_emoji_html: "%{name} desactivou o emoji %{target}"
|
||||
disable_relay_html: "%{name} desactivou o repetidor %{target}"
|
||||
|
@ -302,6 +307,7 @@ gl:
|
|||
update_report_html: "%{name} actualizou a denuncia %{target}"
|
||||
update_status_html: "%{name} actualizou a publicación de %{target}"
|
||||
update_user_role_html: "%{name} cambiou o rol %{target}"
|
||||
update_username_block_html: "%{name} actualizou a regra para identificadores que contén %{target}"
|
||||
deleted_account: conta eliminada
|
||||
empty: Non se atoparon rexistros.
|
||||
filter_by_action: Filtrar por acción
|
||||
|
@ -1085,6 +1091,25 @@ gl:
|
|||
other: Utilizado por %{count} persoas na última semana
|
||||
title: Recomendacións e Suxestións
|
||||
trending: Popularidade
|
||||
username_blocks:
|
||||
add_new: Engadir nova
|
||||
block_registrations: Bloqueo dos rexistros
|
||||
comparison:
|
||||
contains: Contén
|
||||
equals: É igual a
|
||||
contains_html: Contén %{string}
|
||||
created_msg: Creouse correctamente a regra para identificadores
|
||||
delete: Eliminar
|
||||
edit:
|
||||
title: Editar regra para identificadores
|
||||
matches_exactly_html: É igual a %{string}
|
||||
new:
|
||||
create: Crear regra
|
||||
title: Crear nova regra para identificadores
|
||||
no_username_block_selected: Non se cambiou ningunha regra porque non se seleccionou ningunha
|
||||
not_permitted: Non permitido
|
||||
title: Regras para identificadores
|
||||
updated_msg: Actualizouse correctamente a regra
|
||||
warning_presets:
|
||||
add_new: Engadir novo
|
||||
delete: Eliminar
|
||||
|
|
|
@ -196,6 +196,7 @@ he:
|
|||
create_relay: יצירת ממסר
|
||||
create_unavailable_domain: יצירת דומיין בלתי זמין
|
||||
create_user_role: יצירת תפקיד
|
||||
create_username_block: יצירת חוק שמות משתמש
|
||||
demote_user: הורדת משתמש בדרגה
|
||||
destroy_announcement: מחיקת הכרזה
|
||||
destroy_canonical_email_block: מחיקת חסימת דואל
|
||||
|
@ -209,6 +210,7 @@ he:
|
|||
destroy_status: מחיקת הודעה
|
||||
destroy_unavailable_domain: מחיקת דומיין בלתי זמין
|
||||
destroy_user_role: מחיקת תפקיד
|
||||
destroy_username_block: מחיקת חוק שמות משתמש
|
||||
disable_2fa_user: השעיית זיהוי דו-גורמי
|
||||
disable_custom_emoji: השעיית אמוג'י מיוחד
|
||||
disable_relay: השבתת ממסר
|
||||
|
@ -243,6 +245,7 @@ he:
|
|||
update_report: עדכון דו"ח עבירה
|
||||
update_status: סטטוס עדכון
|
||||
update_user_role: עדכון תפקיד
|
||||
update_username_block: עדכון חוק שמות משתמש
|
||||
actions:
|
||||
approve_appeal_html: "%{name} אישר/ה ערעור על החלטת מנהלי הקהילה מ-%{target}"
|
||||
approve_user_html: "%{name} אישר/ה הרשמה מ-%{target}"
|
||||
|
@ -261,6 +264,7 @@ he:
|
|||
create_relay_html: "%{name} יצרו את הממסר %{target}"
|
||||
create_unavailable_domain_html: "%{name} הפסיק/ה משלוח לדומיין %{target}"
|
||||
create_user_role_html: "%{name} יצר את התפקיד של %{target}"
|
||||
create_username_block_html: "%{name} הוסיפו חוק לשמות משתמש המכילים %{target}"
|
||||
demote_user_html: "%{name} הוריד/ה בדרגה את המשתמש %{target}"
|
||||
destroy_announcement_html: "%{name} מחק/ה את ההכרזה %{target}"
|
||||
destroy_canonical_email_block_html: "%{name} הסירו חסימה מדואל %{target}"
|
||||
|
@ -274,6 +278,7 @@ he:
|
|||
destroy_status_html: ההודעה של %{target} הוסרה ע"י %{name}
|
||||
destroy_unavailable_domain_html: "%{name} התחיל/ה מחדש משלוח לדומיין %{target}"
|
||||
destroy_user_role_html: "%{name} ביטל את התפקיד של %{target}"
|
||||
destroy_username_block_html: "%{name} הסירו חוק לשמות משתמש המכילים %{target}"
|
||||
disable_2fa_user_html: "%{name} ביטל/ה את הדרישה לאימות דו-גורמי למשתמש %{target}"
|
||||
disable_custom_emoji_html: "%{name} השבית/ה את האמוג'י %{target}"
|
||||
disable_relay_html: "%{name} השביתו את הממסר %{target}"
|
||||
|
@ -308,6 +313,7 @@ he:
|
|||
update_report_html: '%{name} עדכן/ה דו"ח %{target}'
|
||||
update_status_html: "%{name} עדכן/ה הודעה של %{target}"
|
||||
update_user_role_html: "%{name} שינה את התפקיד של %{target}"
|
||||
update_username_block_html: "%{name} עידכנו חוק לשמות משתמש המכילים %{target}"
|
||||
deleted_account: חשבון מחוק
|
||||
empty: לא נמצאו יומנים.
|
||||
filter_by_action: סינון לפי פעולה
|
||||
|
@ -1121,6 +1127,25 @@ he:
|
|||
two: הוצגה על ידי %{count} משתמשים במשך השבוע שעבר
|
||||
title: המלצות ונושאים חמים
|
||||
trending: נושאים חמים
|
||||
username_blocks:
|
||||
add_new: הוספת חדש
|
||||
block_registrations: חסימת הרשמות
|
||||
comparison:
|
||||
contains: מכיל
|
||||
equals: שווה
|
||||
contains_html: מכיל %{string}
|
||||
created_msg: חוק שמות משתמשים נוצר בהצלחה
|
||||
delete: מחיקה
|
||||
edit:
|
||||
title: עריכת חוק שמות משתמש
|
||||
matches_exactly_html: מתאים ל־%{string}
|
||||
new:
|
||||
create: יצירת כלל
|
||||
title: יצירת חוק חדש לשמות משתמש
|
||||
no_username_block_selected: לא בוצעו שינויים בחוקי בחירת שמות שכן לא נבחרו כאלו
|
||||
not_permitted: שמות אסורים
|
||||
title: חוקי שמות
|
||||
updated_msg: חוק שמות משתמשים עודכן בהצלחה
|
||||
warning_presets:
|
||||
add_new: הוספת חדש
|
||||
delete: למחוק
|
||||
|
|
|
@ -190,6 +190,7 @@ is:
|
|||
create_relay: Búa til endurvarpa
|
||||
create_unavailable_domain: Útbúa lén sem ekki er tiltækt
|
||||
create_user_role: Útbúa hlutverk
|
||||
create_username_block: Búa til notandanafnsreglu
|
||||
demote_user: Lækka notanda í tign
|
||||
destroy_announcement: Eyða tilkynningu
|
||||
destroy_canonical_email_block: Eyða útilokunarblokk tölvupósts
|
||||
|
@ -203,6 +204,7 @@ is:
|
|||
destroy_status: Eyða færslu
|
||||
destroy_unavailable_domain: Eyða léni sem ekki er tiltækt
|
||||
destroy_user_role: Eyða hlutverki
|
||||
destroy_username_block: Eyða notandanafnsreglu
|
||||
disable_2fa_user: Gera tveggja-þátta auðkenningu óvirka
|
||||
disable_custom_emoji: Gera sérsniðið tjáningartákn óvirkt
|
||||
disable_relay: Gera endurvarpa óvirkan
|
||||
|
@ -237,6 +239,7 @@ is:
|
|||
update_report: Uppfæra kæru
|
||||
update_status: Uppfæra færslu
|
||||
update_user_role: Uppfæra hlutverk
|
||||
update_username_block: Uppfæra notandanafnsreglu
|
||||
actions:
|
||||
approve_appeal_html: "%{name} samþykkti áfrýjun á ákvörðun umsjónarmanns frá %{target}"
|
||||
approve_user_html: "%{name} samþykkti nýskráningu frá %{target}"
|
||||
|
@ -255,6 +258,7 @@ is:
|
|||
create_relay_html: "%{name} bjó til endurvarpa %{target}"
|
||||
create_unavailable_domain_html: "%{name} stöðvaði afhendingu til lénsins %{target}"
|
||||
create_user_role_html: "%{name} útbjó %{target} hlutverk"
|
||||
create_username_block_html: "%{name} bætti við reglu varðandi notendanöfn sem innihalda %{target}"
|
||||
demote_user_html: "%{name} lækkaði notandann %{target} í tign"
|
||||
destroy_announcement_html: "%{name} eyddi tilkynninguni %{target}"
|
||||
destroy_canonical_email_block_html: "%{name} tók af útilokun á tölvupósti með tætigildið %{target}"
|
||||
|
@ -268,6 +272,7 @@ is:
|
|||
destroy_status_html: "%{name} fjarlægði færslu frá %{target}"
|
||||
destroy_unavailable_domain_html: "%{name} hóf aftur afhendingu til lénsins %{target}"
|
||||
destroy_user_role_html: "%{name} eyddi hlutverki %{target}"
|
||||
destroy_username_block_html: "%{name} fjarlægði reglu varðandi notendanöfn sem innihalda %{target}"
|
||||
disable_2fa_user_html: "%{name} gerði kröfu um tveggja-þátta innskráningu óvirka fyrir notandann %{target}"
|
||||
disable_custom_emoji_html: "%{name} gerði tjáningartáknið %{target} óvirkt"
|
||||
disable_relay_html: "%{name} gerði endurvarpann %{target} óvirkan"
|
||||
|
@ -302,6 +307,7 @@ is:
|
|||
update_report_html: "%{name} uppfærði kæru %{target}"
|
||||
update_status_html: "%{name} uppfærði færslu frá %{target}"
|
||||
update_user_role_html: "%{name} breytti hlutverki %{target}"
|
||||
update_username_block_html: "%{name} uppfærði reglu varðandi notendanöfn sem innihalda %{target}"
|
||||
deleted_account: eyddur notandaaðgangur
|
||||
empty: Engar atvikaskrár fundust.
|
||||
filter_by_action: Sía eftir aðgerð
|
||||
|
@ -1087,6 +1093,25 @@ is:
|
|||
other: Notað af %{count} aðilum síðustu vikuna
|
||||
title: Meðmæli og vinsælt
|
||||
trending: Vinsælt
|
||||
username_blocks:
|
||||
add_new: Bæta við nýju
|
||||
block_registrations: Loka á nýskráningar
|
||||
comparison:
|
||||
contains: Inniheldur
|
||||
equals: Er jafnt og
|
||||
contains_html: Inniheldur %{string}
|
||||
created_msg: Tókst að útbúa notandanafnsreglu
|
||||
delete: Eyða
|
||||
edit:
|
||||
title: Breyta notandanafnsreglu
|
||||
matches_exactly_html: Er jafnt og %{string}
|
||||
new:
|
||||
create: Búa til reglu
|
||||
title: Búa til nýja notandanafnsreglu
|
||||
no_username_block_selected: Engum notandanafnsreglum var breytt þar sem engar voru valdar
|
||||
not_permitted: Ekki leyft
|
||||
title: Notendanafnareglur
|
||||
updated_msg: Tókst að uppfæra notandanafnsreglu
|
||||
warning_presets:
|
||||
add_new: Bæta við nýju
|
||||
delete: Eyða
|
||||
|
|
|
@ -181,7 +181,7 @@ ko:
|
|||
create_canonical_email_block: 이메일 차단 생성
|
||||
create_custom_emoji: 커스텀 에모지 생성
|
||||
create_domain_allow: 도메인 허용 생성
|
||||
create_domain_block: 도메인 차단 추가
|
||||
create_domain_block: 도메인 차단 만들기
|
||||
create_email_domain_block: 이메일 도메인 차단 생성
|
||||
create_ip_block: IP 규칙 만들기
|
||||
create_relay: 릴레이 생성
|
||||
|
@ -1069,6 +1069,12 @@ ko:
|
|||
other: 지난 주 동안 %{count} 명의 사람들이 사용했습니다
|
||||
title: 추천과 유행
|
||||
trending: 유행 중
|
||||
username_blocks:
|
||||
add_new: 새로 추가
|
||||
new:
|
||||
create: 규칙 만들기
|
||||
title: 새 유저네임 규칙 만들기
|
||||
not_permitted: 허용하지 않음
|
||||
warning_presets:
|
||||
add_new: 새로 추가
|
||||
delete: 삭제
|
||||
|
|
|
@ -160,6 +160,10 @@ da:
|
|||
name: Offentligt rollennavn, hvis rollen er opsat til fremstå som et badge
|
||||
permissions_as_keys: Brugere med denne rolle vil kunne tilgå...
|
||||
position: Højere rolle bestemmer konfliktløsning i visse situationer. Visse handlinger kan kun udføres på roller med lavere prioritet
|
||||
username_block:
|
||||
allow_with_approval: I stedet for at forhindre tilmelding helt, vil matchende tilmeldinger kræve din godkendelse
|
||||
comparison: Vær opmærksom på Scunthorpe-problemet ved blokering af delvise match
|
||||
username: Matches uanset minuskel/majuskel-brug og alm. homoglyffer, såsom "4" for "a" eller "3" for "e"
|
||||
webhook:
|
||||
events: Vælg begivenheder at sende
|
||||
template: Skriv din egen JSON nyttelast ved hjælp af variabel interpolation. Lad feltet stå tomt for standard JSON.
|
||||
|
@ -371,6 +375,10 @@ da:
|
|||
name: Navn
|
||||
permissions_as_keys: Tilladelser
|
||||
position: Prioritet
|
||||
username_block:
|
||||
allow_with_approval: Tillad registreringer med godkendelse
|
||||
comparison: Sammenligningsmetode
|
||||
username: Ord, som skal matches
|
||||
webhook:
|
||||
events: Aktive begivenheder
|
||||
template: Payload skabelon
|
||||
|
|
|
@ -160,6 +160,10 @@ de:
|
|||
name: Name der Rolle, der auch öffentlich als Badge angezeigt wird, sofern dies unten aktiviert ist
|
||||
permissions_as_keys: Benutzer*innen mit dieser Rolle haben Zugriff auf...
|
||||
position: Höhere Rollen entscheiden über Konfliktlösungen zu gewissen Situationen. Bestimmte Aktionen können nur mit geringfügigeren Rollen durchgeführt werden
|
||||
username_block:
|
||||
allow_with_approval: Anstatt Registrierungen komplett zu verhindern, benötigen übereinstimmende Treffer eine Genehmigung
|
||||
comparison: Bitte beachte das Scunthorpe-Problem, wenn teilweise übereinstimmende Treffer gesperrt werden
|
||||
username: Abgleich erfolgt unabhängig der Groß- und Kleinschreibung sowie gängiger Homoglyphen („4“ für „a“ oder „3“ für „e“)
|
||||
webhook:
|
||||
events: Zu sendende Ereignisse auswählen
|
||||
template: Erstelle deine eigenen JSON-Nutzdaten mit Hilfe von Variablen-Interpolation. Leer lassen für Standard-JSON.
|
||||
|
@ -371,6 +375,10 @@ de:
|
|||
name: Name
|
||||
permissions_as_keys: Berechtigungen
|
||||
position: Priorität
|
||||
username_block:
|
||||
allow_with_approval: Registrierungen mit Genehmigung zulassen
|
||||
comparison: Vergleichsmethode
|
||||
username: Übereinstimmendes Wort
|
||||
webhook:
|
||||
events: Aktivierte Ereignisse
|
||||
template: Nutzdaten-Vorlage
|
||||
|
|
|
@ -160,6 +160,10 @@ es-AR:
|
|||
name: Nombre público del rol, si el rol se establece para que se muestre como una insignia
|
||||
permissions_as_keys: Los usuarios con este rol tendrán acceso a…
|
||||
position: Un rol más alto decide la resolución de conflictos en ciertas situaciones. Ciertas acciones sólo pueden llevarse a cabo en roles con prioridad inferior
|
||||
username_block:
|
||||
allow_with_approval: En lugar de impedir el registro total, los registros coincidentes requerirán tu aprobación
|
||||
comparison: Por favor, tené en cuenta el Problema de Scunthorpe al bloquear coincidencias parciales
|
||||
username: Coincidirá sin importar la capitalización de letras y los homoglifos comunes como «4» para «a», o «3» para «e»
|
||||
webhook:
|
||||
events: Seleccionar eventos para enviar
|
||||
template: Creá tu propio archivo JSON usando interpolación variable. Dejalo en blanco para usar el archivo JSON predeterminado.
|
||||
|
@ -371,6 +375,10 @@ es-AR:
|
|||
name: Nombre
|
||||
permissions_as_keys: Permisos
|
||||
position: Prioridad
|
||||
username_block:
|
||||
allow_with_approval: Permitir registros con aprobación
|
||||
comparison: Método de comparación
|
||||
username: Palabra a coincidir
|
||||
webhook:
|
||||
events: Eventos habilitados
|
||||
template: Plantilla de carga
|
||||
|
|
|
@ -160,6 +160,10 @@ es-MX:
|
|||
name: Nombre público del rol, si el rol se establece para que se muestre como una insignia
|
||||
permissions_as_keys: Los usuarios con este rol tendrán acceso a...
|
||||
position: Un rol superior decide la resolución de conflictos en ciertas situaciones. Ciertas acciones sólo pueden llevarse a cabo en roles con menor prioridad
|
||||
username_block:
|
||||
allow_with_approval: En lugar de impedir directamente el registro, los registros coincidentes requerirán tu aprobación
|
||||
comparison: Por favor ten en cuenta el problema de Scunthorpe al bloquear coincidencias parciales
|
||||
username: Se emparejará independientemente de las mayúsculas y minúsculas y de los homógrafos comunes como «4» por «a» o «3» por «e»
|
||||
webhook:
|
||||
events: Seleccionar eventos para enviar
|
||||
template: Crea tu propio JSON usando interpolación variable. Déjalo en blanco para el JSON predeterminado.
|
||||
|
@ -371,6 +375,10 @@ es-MX:
|
|||
name: Nombre
|
||||
permissions_as_keys: Permisos
|
||||
position: Prioridad
|
||||
username_block:
|
||||
allow_with_approval: Permitir registros con aprobación previa
|
||||
comparison: Método de comparación
|
||||
username: Palabra a coincidir
|
||||
webhook:
|
||||
events: Eventos habilitados
|
||||
template: Plantilla de carga
|
||||
|
|
|
@ -160,6 +160,10 @@ es:
|
|||
name: Nombre público del rol, si el rol se establece para que se muestre como una insignia
|
||||
permissions_as_keys: Los usuarios con este rol tendrán acceso a...
|
||||
position: Un rol superior decide la resolución de conflictos en ciertas situaciones. Ciertas acciones sólo pueden llevarse a cabo en roles con menor prioridad
|
||||
username_block:
|
||||
allow_with_approval: En lugar de impedir directamente el registro, los registros coincidentes requerirán tu aprobación
|
||||
comparison: Por favor, ten en cuenta el problema de Scunthorpe al bloquear coincidencias parciales
|
||||
username: Se emparejará independientemente de la mayúscula o minúscula y de homógrafos comunes como «4» por «a» o «3» por «e»
|
||||
webhook:
|
||||
events: Seleccionar eventos para enviar
|
||||
template: Crea tu propio JSON usando interpolación variable. Déjalo en blanco para el JSON predeterminado.
|
||||
|
@ -371,6 +375,10 @@ es:
|
|||
name: Nombre
|
||||
permissions_as_keys: Permisos
|
||||
position: Prioridad
|
||||
username_block:
|
||||
allow_with_approval: Permitir registros con aprobación
|
||||
comparison: Método de comparación
|
||||
username: Palabra a coincidir
|
||||
webhook:
|
||||
events: Eventos habilitados
|
||||
template: Plantilla de carga
|
||||
|
|
|
@ -10,6 +10,7 @@ et:
|
|||
indexable: Sinu avalikud postitused võivad ilmuda Mastodoni otsingutulemustes. Inimesed, kes on sinu postitustele reageerinud, saavad neid otsida nii või naa.
|
||||
note: 'Saad @mainida teisi inimesi või #silte.'
|
||||
show_collections: Inimesed saavad sirvida su jälgijaid ja jälgitavaid. Inimesed, keda sa jälgid, näevad seda sõltumata häälestuse valikust.
|
||||
unlocked: Teised kasutajad saavad sind jälgima hakata nõusolekut küsimata. Eemalda märge, kui soovid jälgimistaotlusi üle vaadata ja valida, kas nõustuda või keelduda uute jälgijatega.
|
||||
account_alias:
|
||||
acct: Sisesta konto kasutajanimi@domeen, mille soovid siia ümber kolida
|
||||
account_migration:
|
||||
|
@ -59,6 +60,7 @@ et:
|
|||
setting_display_media_default: Peida tundlikuks märgitud meedia
|
||||
setting_display_media_hide_all: Alati peida kõik meedia
|
||||
setting_display_media_show_all: Alati näita tundlikuks märgistatud meedia
|
||||
setting_system_scrollbars_ui: Kehtib vaid Safaril ja Chrome'il põhinevatel tavaarvuti veebibrauserite puhul
|
||||
setting_use_blurhash: Värvid põhinevad peidetud visuaalidel, kuid hägustavad igasuguseid detaile
|
||||
setting_use_pending_items: Voo automaatse kerimise asemel peida ajajoone uuendused kliki taha
|
||||
username: Võid kasutada ladina tähti, numbreid ja allkriipsu
|
||||
|
|
|
@ -160,6 +160,10 @@ fo:
|
|||
name: Almenna navnið á leiklutinum, um leikluturin er settur at verða vístur sum eitt tignarmerki
|
||||
permissions_as_keys: Brúkarar við hesum leiklutinum fara at fáa atgongd til...
|
||||
position: Hægri leiklutur er avgerandi fyri loysn av ósemjum í ávísum støðum. Ávísar atgerðir kunnu einans verða gjørdar móti leiklutum, sum hava eina lægri raðfesting
|
||||
username_block:
|
||||
allow_with_approval: Í staðin fyri at forða heilt fyri skráseting, fara samsvarandi skrásetingar at krevja, at tú góðkennir tær
|
||||
comparison: Vinarliga gev Scunthorpe-trupulleikanum gætur, tá tú blokerar lutvís samsvar
|
||||
username: Samsvar vera funnin óansæð stórar og smáar bókstavir og vanligar homoglyffir, sosum "4" fyri "a" og "3" fyri "e"
|
||||
webhook:
|
||||
events: Vel hendingar at senda
|
||||
template: Samanset títt egna JSON farm við at brúka variabul-interpolasjón. Lat vera blankt fyri sjálvgaldandi JSON.
|
||||
|
@ -371,6 +375,10 @@ fo:
|
|||
name: Navn
|
||||
permissions_as_keys: Loyvi
|
||||
position: Raðfesting
|
||||
username_block:
|
||||
allow_with_approval: Loyv skrásetingum við góðkenning
|
||||
comparison: Samanberingarmetoda
|
||||
username: Orð, sum skal samsvara
|
||||
webhook:
|
||||
events: Virknar hendingar
|
||||
template: Farmaformur
|
||||
|
|
|
@ -160,6 +160,10 @@ gl:
|
|||
name: Nome público do rol, se o rol se mostra como unha insignia
|
||||
permissions_as_keys: As usuarias con este rol terán acceso a...
|
||||
position: O rol superior decide nos conflitos en certas situacións. Algunhas accións só poden aplicarse sobre roles cunha prioridade menor
|
||||
username_block:
|
||||
allow_with_approval: No lugar de evitar a cración directa de contas, as contas mediante regras van precisar a túa aprobación
|
||||
comparison: Ten en conta o Sunthorpe Problem cando se bloquean coincidencias parciais
|
||||
username: Vai crear unha coincidencia sen importar se son maiúsculas ou minúsculas e homoglifos como «4» por «a» ou «3» por «e».
|
||||
webhook:
|
||||
events: Escoller eventos a enviar
|
||||
template: Crea o teu propio JSON interpolando variables. Déixao en branco para usar o JSON predeterminado.
|
||||
|
@ -371,6 +375,10 @@ gl:
|
|||
name: Nome
|
||||
permissions_as_keys: Permisos
|
||||
position: Prioridade
|
||||
username_block:
|
||||
allow_with_approval: Permitir crear contas con aprobación
|
||||
comparison: Método de comparación
|
||||
username: Palabra a comparar
|
||||
webhook:
|
||||
events: Eventos activados
|
||||
template: Modelo de carga
|
||||
|
|
|
@ -162,6 +162,10 @@ he:
|
|||
name: שם ציבורי של התפקיד, במידה והתפקיד מוגדר ככזה שמופיע כתג
|
||||
permissions_as_keys: למשתמשים בתפקיד זה תהיה גישה ל...
|
||||
position: תפקיד גבוה יותר מכריע בחילוקי דעות במצבים מסוימים. פעולות מסוימות יכולות להתבצע רק על תפקידים בדרגה נמוכה יותר
|
||||
username_block:
|
||||
allow_with_approval: במקום למנוע הרשמה לחלוטין, הרשמות חדשות יצטרכו לחכות לאישורך
|
||||
comparison: יש להזהר מחסימת חלקי שמות קצרים מדי כדי להמנע מהתופעה הידועה בשם Scunthorpe problem
|
||||
username: ההתאמה תתבצע ללא קשר לגודל אותיות או להומוגליפים נפוצים כגון "4" במקום "a" או "3" במקום "e"
|
||||
webhook:
|
||||
events: בחר אירועים לשליחה
|
||||
template: ניתן להרכיב מטען JSON משלך בשימוש בשילוב משתנים. יש להשאיר ריק בשביל JSON ברירת המחדל.
|
||||
|
@ -373,6 +377,10 @@ he:
|
|||
name: שם
|
||||
permissions_as_keys: הרשאות
|
||||
position: עדיפות
|
||||
username_block:
|
||||
allow_with_approval: הרשאת הרשמה לאחר אישור
|
||||
comparison: שיטת השוואה
|
||||
username: מילה להתאמה
|
||||
webhook:
|
||||
events: אירועים מאופשרים
|
||||
template: תבנית מטען
|
||||
|
|
|
@ -160,6 +160,10 @@ is:
|
|||
name: Opinbert heiti hlutverks, ef birta á hlutverk sem merki
|
||||
permissions_as_keys: Notendur með þetta hlutverk munu hafa aðgang að...
|
||||
position: Rétthærra hlutverk ákvarðar lausn árekstra í ákveðnum tilfellum. Sumar aðgerðir er aðeins hægt að framkvæma á hlutverk með lægri forgangi
|
||||
username_block:
|
||||
allow_with_approval: Í stað þess að loka alfarið á nýskráningar, munu samsvarandi nýskráningar þurfa samþykki þitt
|
||||
comparison: Hafðu í huga Scunthorpe-vandamálið (Scunthorpe inniheldur orð sem ýmsar síur reyna að banna) þegar þú útilokar samsvarandi orðhluta
|
||||
username: Mun samsvara án tillits til stafstöðu eða algengra táknlíkinga á borð við "4" í stað "a" eða "3" í stað "e"
|
||||
webhook:
|
||||
events: Veldu atburði sem á að senda
|
||||
template: Sníddu eigin JSON með breytilegri brúun. Skiljið eftir autt fyrir sjálfgefið JSON.
|
||||
|
@ -371,6 +375,10 @@ is:
|
|||
name: Nafn
|
||||
permissions_as_keys: Heimildir
|
||||
position: Forgangur
|
||||
username_block:
|
||||
allow_with_approval: Leyfa skráningar með samþykki
|
||||
comparison: Aðferð við samanburð
|
||||
username: Orð sem samsvara
|
||||
webhook:
|
||||
events: Virkjaðir atburðir
|
||||
template: Sniðmát gagna
|
||||
|
|
|
@ -159,6 +159,10 @@ vi:
|
|||
name: Tên công khai của vai trò, nếu vai trò được đặt để hiển thị dưới dạng huy hiệu
|
||||
permissions_as_keys: Người có vai trò này sẽ có quyền truy cập vào...
|
||||
position: Vai trò cao hơn sẽ có quyền quyết định xung đột trong các tình huống. Các vai trò có mức độ ưu tiên thấp hơn chỉ có thể thực hiện một số hành động nhất định
|
||||
username_block:
|
||||
allow_with_approval: Thay vì cấm đăng ký ngay lập tức, bạn sẽ duyệt phù hợp trước khi đăng ký
|
||||
comparison: Xin hãy lưu ý đến Vấn đề Scunthorpe khi chặn các từ trùng khớp một phần
|
||||
username: Sẽ được khớp bất kể chữ hoa và chữ tượng hình phổ biến như "4" cho "a" hoặc "3" cho "e"
|
||||
webhook:
|
||||
events: Chọn sự kiện để gửi
|
||||
template: Soạn JSON payload của riêng bạn bằng phép nội suy biến. Để trống để dùng JSON mặc định.
|
||||
|
@ -370,6 +374,10 @@ vi:
|
|||
name: Tên
|
||||
permissions_as_keys: Quyền
|
||||
position: Mức độ ưu tiên
|
||||
username_block:
|
||||
allow_with_approval: Cho đăng ký nhưng duyệt thủ công
|
||||
comparison: Phương pháp so sánh
|
||||
username: Khớp từ
|
||||
webhook:
|
||||
events: Những sự kiện đã bật
|
||||
template: Mẫu payload
|
||||
|
|
|
@ -159,6 +159,10 @@ zh-TW:
|
|||
name: 角色的公開名稱,如果角色設定為顯示為徽章
|
||||
permissions_as_keys: 有此角色的使用者將有權存取...
|
||||
position: 某些情況下,衝突的解決方式由更高階的角色決定。某些動作只能由優先程度較低的角色執行
|
||||
username_block:
|
||||
allow_with_approval: 不直接禁止註冊,符合規則之註冊將需要您的審核
|
||||
comparison: 當您封鎖部分匹配時,請留心 Scunthorpe 問題
|
||||
username: 將匹配不限大小寫與常見同形異義字,如以「4」代替「A」或以「3」代替「E」
|
||||
webhook:
|
||||
events: 請選擇要傳送的事件
|
||||
template: 使用變數代換組合您自己的 JSON payload。留白以使用預設 JSON 。
|
||||
|
@ -370,6 +374,10 @@ zh-TW:
|
|||
name: 名稱
|
||||
permissions_as_keys: 權限
|
||||
position: 優先權
|
||||
username_block:
|
||||
allow_with_approval: 經審核後可註冊
|
||||
comparison: 比較方式
|
||||
username: 字詞匹配
|
||||
webhook:
|
||||
events: 已啟用的事件
|
||||
template: Payload 樣板
|
||||
|
|
|
@ -1072,6 +1072,11 @@ uk:
|
|||
other: Використали %{count} людей за минулий тиждень
|
||||
title: Рекомендації та тренди
|
||||
trending: Популярне
|
||||
username_blocks:
|
||||
comparison:
|
||||
contains: Містить
|
||||
equals: Дорівнює
|
||||
delete: Видалити
|
||||
warning_presets:
|
||||
add_new: Додати новий
|
||||
delete: Видалити
|
||||
|
|
|
@ -187,6 +187,7 @@ vi:
|
|||
create_relay: Tạo relay
|
||||
create_unavailable_domain: Bỏ liên hợp
|
||||
create_user_role: Tạo vai trò
|
||||
create_username_block: Tạo quy tắc tên người dùng
|
||||
demote_user: Hạ vai trò
|
||||
destroy_announcement: Xóa thông báo
|
||||
destroy_canonical_email_block: Bỏ chặn địa chỉ email biến thể
|
||||
|
@ -200,6 +201,7 @@ vi:
|
|||
destroy_status: Xóa tút
|
||||
destroy_unavailable_domain: Cho phép liên hợp
|
||||
destroy_user_role: Xóa vai trò
|
||||
destroy_username_block: Xóa quy tắc tên người dùng
|
||||
disable_2fa_user: Vô hiệu hóa 2FA
|
||||
disable_custom_emoji: Vô hiệu hóa emoji
|
||||
disable_relay: Tắt relay
|
||||
|
@ -234,6 +236,7 @@ vi:
|
|||
update_report: Cập nhật báo cáo
|
||||
update_status: Cập nhật tút
|
||||
update_user_role: Cập nhật vai trò
|
||||
update_username_block: Cập nhật quy tắc tên người dùng
|
||||
actions:
|
||||
approve_appeal_html: "%{name} đã chấp nhận khiếu nại từ %{target}"
|
||||
approve_user_html: "%{name} đã chấp nhận đăng ký từ %{target}"
|
||||
|
@ -252,6 +255,7 @@ vi:
|
|||
create_relay_html: "%{name} đã tạo relay %{target}"
|
||||
create_unavailable_domain_html: "%{name} đã bỏ liên hợp với máy chủ %{target}"
|
||||
create_user_role_html: "%{name} đã tạo vai trò %{target}"
|
||||
create_username_block_html: "%{name} thêm quy tắc cho tên người dùng chứa %{target}"
|
||||
demote_user_html: "%{name} đã hạ vai trò của %{target}"
|
||||
destroy_announcement_html: "%{name} đã xóa thông báo %{target}"
|
||||
destroy_canonical_email_block_html: "%{name} đã bỏ chặn địa chỉ email biến thể %{target}"
|
||||
|
@ -265,6 +269,7 @@ vi:
|
|||
destroy_status_html: "%{name} đã xóa tút của %{target}"
|
||||
destroy_unavailable_domain_html: "%{name} tiếp tục liên hợp với máy chủ %{target}"
|
||||
destroy_user_role_html: "%{name} đã xóa vai trò %{target}"
|
||||
destroy_username_block_html: "%{name} xóa quy tắc cho tên người dùng chứa %{target}"
|
||||
disable_2fa_user_html: "%{name} đã vô hiệu hóa xác thực 2 bước của %{target}"
|
||||
disable_custom_emoji_html: "%{name} đã ẩn emoji %{target}"
|
||||
disable_relay_html: "%{name} đã tắt relay %{target}"
|
||||
|
@ -299,6 +304,7 @@ vi:
|
|||
update_report_html: "%{name} đã cập nhật báo cáo %{target}"
|
||||
update_status_html: "%{name} đã cập nhật tút của %{target}"
|
||||
update_user_role_html: "%{name} đã cập nhật vai trò %{target}"
|
||||
update_username_block_html: "%{name} đã cập nhật quy tắc cho tên người dùng chứa %{target}"
|
||||
deleted_account: tài khoản đã xóa
|
||||
empty: Không tìm thấy bản ghi.
|
||||
filter_by_action: Theo hành động
|
||||
|
@ -1067,6 +1073,25 @@ vi:
|
|||
other: "%{count} người dùng tuần rồi"
|
||||
title: Đề xuất & Xu hướng
|
||||
trending: Xu hướng
|
||||
username_blocks:
|
||||
add_new: Thêm mới
|
||||
block_registrations: Cấm đăng ký
|
||||
comparison:
|
||||
contains: Có chứa
|
||||
equals: Tương tự
|
||||
contains_html: Có chứa %{string}
|
||||
created_msg: Đã tạo quy tắc tên người dùng thành công
|
||||
delete: Xóa
|
||||
edit:
|
||||
title: Sửa quy tắc tên người dùng
|
||||
matches_exactly_html: Có chứa %{string}
|
||||
new:
|
||||
create: Tạo quy tắc
|
||||
title: Tạo quy tắc tên người dùng mới
|
||||
no_username_block_selected: Chưa chọn quy tắc tên người dùng nào
|
||||
not_permitted: Cấm
|
||||
title: Quy tắc tên người dùng
|
||||
updated_msg: Đã cập nhật quy tắc tên người dùng thành công
|
||||
warning_presets:
|
||||
add_new: Thêm mới
|
||||
delete: Xóa bỏ
|
||||
|
|
|
@ -187,6 +187,7 @@ zh-TW:
|
|||
create_relay: 新增中繼
|
||||
create_unavailable_domain: 新增無法存取的網域
|
||||
create_user_role: 新增角色
|
||||
create_username_block: 新增使用者名稱規則
|
||||
demote_user: 將用戶降級
|
||||
destroy_announcement: 刪除公告
|
||||
destroy_canonical_email_block: 刪除電子郵件封鎖
|
||||
|
@ -200,6 +201,7 @@ zh-TW:
|
|||
destroy_status: 刪除狀態
|
||||
destroy_unavailable_domain: 刪除無法存取的網域
|
||||
destroy_user_role: 移除角色
|
||||
destroy_username_block: 刪除使用者名稱規則
|
||||
disable_2fa_user: 停用兩階段驗證
|
||||
disable_custom_emoji: 停用自訂 emoji 表情符號
|
||||
disable_relay: 停用中繼
|
||||
|
@ -234,6 +236,7 @@ zh-TW:
|
|||
update_report: 更新檢舉報告
|
||||
update_status: 更新狀態
|
||||
update_user_role: 更新角色
|
||||
update_username_block: 變更使用者名稱規則
|
||||
actions:
|
||||
approve_appeal_html: "%{name} 已批准來自 %{target} 的審核決定申訴"
|
||||
approve_user_html: "%{name} 已批准自 %{target} 而來的註冊"
|
||||
|
@ -252,6 +255,7 @@ zh-TW:
|
|||
create_relay_html: "%{name} 已新增中繼 %{target}"
|
||||
create_unavailable_domain_html: "%{name} 停止發送至網域 %{target}"
|
||||
create_user_role_html: "%{name} 已新增 %{target} 角色"
|
||||
create_username_block_html: "%{name} 已新增使用者名稱包含 %{target} 之規則"
|
||||
demote_user_html: "%{name} 將使用者 %{target} 降級"
|
||||
destroy_announcement_html: "%{name} 已刪除公告 %{target}"
|
||||
destroy_canonical_email_block_html: "%{name} 已解除封鎖 hash 為 %{target} 之電子郵件"
|
||||
|
@ -265,6 +269,7 @@ zh-TW:
|
|||
destroy_status_html: "%{name} 已刪除 %{target} 的嘟文"
|
||||
destroy_unavailable_domain_html: "%{name} 已恢復對網域 %{target} 的發送"
|
||||
destroy_user_role_html: "%{name} 已刪除 %{target} 角色"
|
||||
destroy_username_block_html: "%{name} 已移除使用者名稱包含 %{target} 之規則"
|
||||
disable_2fa_user_html: "%{name} 已停用使用者 %{target} 的兩階段驗證 (2FA) "
|
||||
disable_custom_emoji_html: "%{name} 已停用自訂 emoji 表情符號 %{target}"
|
||||
disable_relay_html: "%{name} 已停用中繼 %{target}"
|
||||
|
@ -299,6 +304,7 @@ zh-TW:
|
|||
update_report_html: "%{name} 已更新 %{target} 的檢舉"
|
||||
update_status_html: "%{name} 已更新 %{target} 的嘟文"
|
||||
update_user_role_html: "%{name} 已變更 %{target} 角色"
|
||||
update_username_block_html: "%{name} 已變更使用者名稱包含 %{target} 之規則"
|
||||
deleted_account: 已刪除帳號
|
||||
empty: 找不到 log
|
||||
filter_by_action: 按動作過濾
|
||||
|
@ -1069,6 +1075,25 @@ zh-TW:
|
|||
other: 上週被 %{count} 個人使用
|
||||
title: 推薦內容與熱門趨勢
|
||||
trending: 熱門
|
||||
username_blocks:
|
||||
add_new: 新增
|
||||
block_registrations: 禁止註冊
|
||||
comparison:
|
||||
contains: 包含
|
||||
equals: 等於
|
||||
contains_html: 包含 %{string}
|
||||
created_msg: 已成功新增使用者名稱規則
|
||||
delete: 刪除
|
||||
edit:
|
||||
title: 編輯使用者名稱規則
|
||||
matches_exactly_html: 等於 %{string}
|
||||
new:
|
||||
create: 新增規則
|
||||
title: 新增使用者名稱規則
|
||||
no_username_block_selected: 因未選取任何使用者名稱規則,所以什麼事都沒發生
|
||||
not_permitted: 不允許
|
||||
title: 使用者名稱規則
|
||||
updated_msg: 已成功變更使用者名稱規則
|
||||
warning_presets:
|
||||
add_new: 新增
|
||||
delete: 刪除
|
||||
|
|
|
@ -14,6 +14,7 @@ module Mastodon
|
|||
class InvalidParameterError < Error; end
|
||||
class SignatureVerificationError < Error; end
|
||||
class MalformedHeaderError < Error; end
|
||||
class RecursionLimitExceededError < Error; end
|
||||
|
||||
class UnexpectedResponseError < Error
|
||||
attr_reader :response
|
||||
|
|
|
@ -313,9 +313,7 @@ module Mastodon::CLI
|
|||
end
|
||||
|
||||
def combined_media_sum
|
||||
Arel.sql(<<~SQL.squish)
|
||||
COALESCE(file_file_size, 0) + COALESCE(thumbnail_file_size, 0)
|
||||
SQL
|
||||
MediaAttachment.combined_media_file_size
|
||||
end
|
||||
|
||||
def preload_records_from_mixed_objects(objects)
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
"cocoon-js-vanilla": "^1.5.1",
|
||||
"color-blend": "^4.0.0",
|
||||
"core-js": "^3.30.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"cross-env": "^10.0.0",
|
||||
"detect-passive-events": "^2.0.3",
|
||||
"emoji-mart": "npm:emoji-mart-lazyload@latest",
|
||||
"emojibase": "^16.0.0",
|
||||
|
@ -168,7 +168,7 @@
|
|||
"eslint-import-resolver-typescript": "^4.2.5",
|
||||
"eslint-plugin-formatjs": "^5.3.1",
|
||||
"eslint-plugin-import": "~2.31.0",
|
||||
"eslint-plugin-jsdoc": "^51.0.0",
|
||||
"eslint-plugin-jsdoc": "^52.0.0",
|
||||
"eslint-plugin-jsx-a11y": "~6.10.2",
|
||||
"eslint-plugin-promise": "~7.2.1",
|
||||
"eslint-plugin-react": "^7.37.4",
|
||||
|
|
|
@ -16,10 +16,12 @@ RSpec.describe AccountSuggestions::FriendsOfFriendsSource do
|
|||
let!(:jerk) { Fabricate(:account, discoverable: true, hide_collections: false) }
|
||||
let!(:larry) { Fabricate(:account, discoverable: true, hide_collections: false) }
|
||||
let!(:morty) { Fabricate(:account, discoverable: true, hide_collections: false, memorial: true) }
|
||||
let!(:joyce) { Fabricate(:account, discoverable: true, hide_collections: false) }
|
||||
|
||||
context 'with follows and blocks' do
|
||||
before do
|
||||
bob.block!(jerk)
|
||||
bob.request_follow!(joyce)
|
||||
FollowRecommendationMute.create!(account: bob, target_account: neil)
|
||||
|
||||
# bob follows eugen, alice and larry
|
||||
|
@ -28,8 +30,8 @@ RSpec.describe AccountSuggestions::FriendsOfFriendsSource do
|
|||
# alice follows eve and mallory
|
||||
[john, mallory].each { |account| alice.follow!(account) }
|
||||
|
||||
# eugen follows eve, john, jerk, larry, neil and morty
|
||||
[eve, mallory, jerk, larry, neil, morty].each { |account| eugen.follow!(account) }
|
||||
# eugen follows eve, john, jerk, larry, neil, morty and joyce
|
||||
[eve, mallory, jerk, larry, neil, morty, joyce].each { |account| eugen.follow!(account) }
|
||||
end
|
||||
|
||||
it 'returns eligible accounts', :aggregate_failures do
|
||||
|
@ -55,6 +57,9 @@ RSpec.describe AccountSuggestions::FriendsOfFriendsSource do
|
|||
|
||||
# morty is not included because his account is in memoriam
|
||||
expect(results).to_not include([morty.id, :friends_of_friends])
|
||||
|
||||
# joyce is not included because there is already a pending follow request
|
||||
expect(results).to_not include([joyce.id, :friends_of_friends])
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -313,6 +313,12 @@ RSpec.describe MediaAttachment, :attachment_processing do
|
|||
end
|
||||
end
|
||||
|
||||
describe '.combined_media_file_size' do
|
||||
subject { described_class.combined_media_file_size }
|
||||
|
||||
it { is_expected.to be_an(Arel::Nodes::Grouping) }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def media_metadata
|
||||
|
|
|
@ -10,6 +10,8 @@ RSpec.describe User do
|
|||
let(:account) { Fabricate(:account, username: 'alice') }
|
||||
|
||||
it_behaves_like 'two_factor_backupable'
|
||||
it_behaves_like 'User::Activity'
|
||||
it_behaves_like 'User::Confirmation'
|
||||
|
||||
describe 'otp_secret' do
|
||||
it 'encrypts the saved value' do
|
||||
|
@ -65,34 +67,6 @@ RSpec.describe User do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'confirmed' do
|
||||
it 'returns an array of users who are confirmed' do
|
||||
Fabricate(:user, confirmed_at: nil)
|
||||
confirmed_user = Fabricate(:user, confirmed_at: Time.zone.now)
|
||||
expect(described_class.confirmed).to contain_exactly(confirmed_user)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'signed_in_recently' do
|
||||
it 'returns a relation of users who have signed in during the recent period' do
|
||||
recent_sign_in_user = Fabricate(:user, current_sign_in_at: within_duration_window_days.ago)
|
||||
Fabricate(:user, current_sign_in_at: exceed_duration_window_days.ago)
|
||||
|
||||
expect(described_class.signed_in_recently)
|
||||
.to contain_exactly(recent_sign_in_user)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'not_signed_in_recently' do
|
||||
it 'returns a relation of users who have not signed in during the recent period' do
|
||||
no_recent_sign_in_user = Fabricate(:user, current_sign_in_at: exceed_duration_window_days.ago)
|
||||
Fabricate(:user, current_sign_in_at: within_duration_window_days.ago)
|
||||
|
||||
expect(described_class.not_signed_in_recently)
|
||||
.to contain_exactly(no_recent_sign_in_user)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'account_not_suspended' do
|
||||
it 'returns with linked accounts that are not suspended' do
|
||||
suspended_account = Fabricate(:account, suspended_at: 10.days.ago)
|
||||
|
@ -127,14 +101,6 @@ RSpec.describe User do
|
|||
expect(described_class.matches_ip('2160:2160::/32')).to contain_exactly(user1)
|
||||
end
|
||||
end
|
||||
|
||||
def exceed_duration_window_days
|
||||
described_class::ACTIVE_DURATION + 2.days
|
||||
end
|
||||
|
||||
def within_duration_window_days
|
||||
described_class::ACTIVE_DURATION - 2.days
|
||||
end
|
||||
end
|
||||
|
||||
describe 'email domains denylist integration' do
|
||||
|
@ -197,12 +163,13 @@ RSpec.describe User do
|
|||
|
||||
describe '#update_sign_in!' do
|
||||
context 'with an existing user' do
|
||||
let!(:user) { Fabricate :user, last_sign_in_at: 10.days.ago, current_sign_in_at: 1.hour.ago, sign_in_count: 123 }
|
||||
let!(:user) { Fabricate :user, last_sign_in_at: 10.days.ago, current_sign_in_at:, sign_in_count: 123 }
|
||||
let(:current_sign_in_at) { 1.hour.ago }
|
||||
|
||||
context 'with new sign in false' do
|
||||
it 'updates timestamps but not counts' do
|
||||
expect { user.update_sign_in!(new_sign_in: false) }
|
||||
.to change(user, :last_sign_in_at)
|
||||
.to change(user, :last_sign_in_at).to(current_sign_in_at)
|
||||
.and change(user, :current_sign_in_at)
|
||||
.and not_change(user, :sign_in_count)
|
||||
end
|
||||
|
@ -211,11 +178,22 @@ RSpec.describe User do
|
|||
context 'with new sign in true' do
|
||||
it 'updates timestamps and counts' do
|
||||
expect { user.update_sign_in!(new_sign_in: true) }
|
||||
.to change(user, :last_sign_in_at)
|
||||
.to change(user, :last_sign_in_at).to(current_sign_in_at)
|
||||
.and change(user, :current_sign_in_at)
|
||||
.and change(user, :sign_in_count).by(1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user does not have a current_sign_in_at value' do
|
||||
let(:current_sign_in_at) { nil }
|
||||
|
||||
before { travel_to(1.minute.ago) }
|
||||
|
||||
it 'updates last sign in to now' do
|
||||
expect { user.update_sign_in! }
|
||||
.to change(user, :last_sign_in_at).to(Time.now.utc)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a new user' do
|
||||
|
@ -228,79 +206,6 @@ RSpec.describe User do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#confirmed?' do
|
||||
it 'returns true when a confirmed_at is set' do
|
||||
user = Fabricate.build(:user, confirmed_at: Time.now.utc)
|
||||
expect(user.confirmed?).to be true
|
||||
end
|
||||
|
||||
it 'returns false if a confirmed_at is nil' do
|
||||
user = Fabricate.build(:user, confirmed_at: nil)
|
||||
expect(user.confirmed?).to be false
|
||||
end
|
||||
end
|
||||
|
||||
describe '#confirm' do
|
||||
subject { user.confirm }
|
||||
|
||||
let(:new_email) { 'new-email@example.com' }
|
||||
|
||||
before do
|
||||
allow(TriggerWebhookWorker).to receive(:perform_async)
|
||||
end
|
||||
|
||||
context 'when the user is already confirmed' do
|
||||
let!(:user) { Fabricate(:user, confirmed_at: Time.now.utc, approved: true, unconfirmed_email: new_email) }
|
||||
|
||||
it 'sets email to unconfirmed_email and does not trigger web hook' do
|
||||
expect { subject }.to change { user.reload.email }.to(new_email)
|
||||
|
||||
expect(TriggerWebhookWorker).to_not have_received(:perform_async).with('account.approved', 'Account', user.account_id)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user is a new user' do
|
||||
let(:user) { Fabricate(:user, confirmed_at: nil, unconfirmed_email: new_email) }
|
||||
|
||||
context 'when the user is already approved' do
|
||||
before do
|
||||
Setting.registrations_mode = 'approved'
|
||||
user.approve!
|
||||
end
|
||||
|
||||
it 'sets email to unconfirmed_email and triggers `account.approved` web hook' do
|
||||
expect { subject }.to change { user.reload.email }.to(new_email)
|
||||
|
||||
expect(TriggerWebhookWorker).to have_received(:perform_async).with('account.approved', 'Account', user.account_id).once
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user does not require explicit approval' do
|
||||
before do
|
||||
Setting.registrations_mode = 'open'
|
||||
end
|
||||
|
||||
it 'sets email to unconfirmed_email and triggers `account.approved` web hook' do
|
||||
expect { subject }.to change { user.reload.email }.to(new_email)
|
||||
|
||||
expect(TriggerWebhookWorker).to have_received(:perform_async).with('account.approved', 'Account', user.account_id).once
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user requires explicit approval but is not approved' do
|
||||
before do
|
||||
Setting.registrations_mode = 'approved'
|
||||
end
|
||||
|
||||
it 'sets email to unconfirmed_email and does not trigger web hook' do
|
||||
expect { subject }.to change { user.reload.email }.to(new_email)
|
||||
|
||||
expect(TriggerWebhookWorker).to_not have_received(:perform_async).with('account.approved', 'Account', user.account_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#approve!' do
|
||||
subject { user.approve! }
|
||||
|
||||
|
|
48
spec/support/examples/models/concerns/user/activity.rb
Normal file
48
spec/support/examples/models/concerns/user/activity.rb
Normal file
|
@ -0,0 +1,48 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.shared_examples 'User::Activity' do
|
||||
before { stub_const 'User::ACTIVE_DURATION', 7.days }
|
||||
|
||||
describe 'Scopes' do
|
||||
let!(:recent_sign_in_user) { Fabricate(:user, current_sign_in_at: 2.days.ago) }
|
||||
let!(:no_recent_sign_in_user) { Fabricate(:user, current_sign_in_at: 10.days.ago) }
|
||||
|
||||
describe '.signed_in_recently' do
|
||||
it 'returns users who have signed in during the recent period' do
|
||||
expect(described_class.signed_in_recently)
|
||||
.to contain_exactly(recent_sign_in_user)
|
||||
end
|
||||
end
|
||||
|
||||
describe '.not_signed_in_recently' do
|
||||
it 'returns users who have not signed in during the recent period' do
|
||||
expect(described_class.not_signed_in_recently)
|
||||
.to contain_exactly(no_recent_sign_in_user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#signed_in_recently?' do
|
||||
subject { Fabricate.build :user, current_sign_in_at: }
|
||||
|
||||
context 'when current_sign_in_at is nil' do
|
||||
let(:current_sign_in_at) { nil }
|
||||
|
||||
it { is_expected.to_not be_signed_in_recently }
|
||||
end
|
||||
|
||||
context 'when current_sign_in_at is before the threshold' do
|
||||
let(:current_sign_in_at) { 10.days.ago }
|
||||
|
||||
it { is_expected.to_not be_signed_in_recently }
|
||||
end
|
||||
|
||||
context 'when current_sign_in_at is after the threshold' do
|
||||
let(:current_sign_in_at) { 2.days.ago }
|
||||
|
||||
it { is_expected.to be_signed_in_recently }
|
||||
end
|
||||
end
|
||||
end
|
114
spec/support/examples/models/concerns/user/confirmation.rb
Normal file
114
spec/support/examples/models/concerns/user/confirmation.rb
Normal file
|
@ -0,0 +1,114 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.shared_examples 'User::Confirmation' do
|
||||
describe 'Scopes' do
|
||||
let!(:unconfirmed_user) { Fabricate :user, confirmed_at: nil }
|
||||
let!(:confirmed_user) { Fabricate :user, confirmed_at: Time.now.utc }
|
||||
|
||||
describe '.confirmed' do
|
||||
it 'returns users who are confirmed' do
|
||||
expect(described_class.confirmed)
|
||||
.to contain_exactly(confirmed_user)
|
||||
end
|
||||
end
|
||||
|
||||
describe '.unconfirmed' do
|
||||
it 'returns users who are not confirmed' do
|
||||
expect(described_class.unconfirmed)
|
||||
.to contain_exactly(unconfirmed_user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#confirmed?' do
|
||||
subject { Fabricate.build(:user, confirmed_at:) }
|
||||
|
||||
context 'when confirmed_at is set' do
|
||||
let(:confirmed_at) { Time.now.utc }
|
||||
|
||||
it { is_expected.to be_confirmed }
|
||||
end
|
||||
|
||||
context 'when confirmed_at is not set' do
|
||||
let(:confirmed_at) { nil }
|
||||
|
||||
it { is_expected.to_not be_confirmed }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#unconfirmed?' do
|
||||
subject { Fabricate.build(:user, confirmed_at:) }
|
||||
|
||||
context 'when confirmed_at is set' do
|
||||
let(:confirmed_at) { Time.now.utc }
|
||||
|
||||
it { is_expected.to_not be_unconfirmed }
|
||||
end
|
||||
|
||||
context 'when confirmed_at is not set' do
|
||||
let(:confirmed_at) { nil }
|
||||
|
||||
it { is_expected.to be_unconfirmed }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#confirm' do
|
||||
subject { user.confirm }
|
||||
|
||||
let(:new_email) { 'new-email@host.example' }
|
||||
|
||||
before { allow(TriggerWebhookWorker).to receive(:perform_async) }
|
||||
|
||||
context 'when the user is already confirmed' do
|
||||
let!(:user) { Fabricate(:user, confirmed_at: Time.now.utc, approved: true, unconfirmed_email: new_email) }
|
||||
|
||||
it 'sets email to unconfirmed_email and does not trigger web hook' do
|
||||
expect { subject }
|
||||
.to change { user.reload.email }.to(new_email)
|
||||
expect(TriggerWebhookWorker)
|
||||
.to_not have_received(:perform_async).with('account.approved', 'Account', user.account_id)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user is a new user' do
|
||||
let(:user) { Fabricate(:user, confirmed_at: nil, unconfirmed_email: new_email) }
|
||||
|
||||
context 'when the user does not require explicit approval' do
|
||||
before { Setting.registrations_mode = 'open' }
|
||||
|
||||
it 'sets email to unconfirmed_email and triggers `account.approved` web hook' do
|
||||
expect { subject }
|
||||
.to change { user.reload.email }.to(new_email)
|
||||
expect(TriggerWebhookWorker)
|
||||
.to have_received(:perform_async).with('account.approved', 'Account', user.account_id).once
|
||||
end
|
||||
end
|
||||
|
||||
context 'when registrations mode is approved' do
|
||||
before { Setting.registrations_mode = 'approved' }
|
||||
|
||||
context 'when the user is already approved' do
|
||||
before { user.approve! }
|
||||
|
||||
it 'sets email to unconfirmed_email and triggers `account.approved` web hook' do
|
||||
expect { subject }
|
||||
.to change { user.reload.email }.to(new_email)
|
||||
expect(TriggerWebhookWorker)
|
||||
.to have_received(:perform_async).with('account.approved', 'Account', user.account_id).once
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user is not approved' do
|
||||
it 'sets email to unconfirmed_email and does not trigger web hook' do
|
||||
expect { subject }
|
||||
.to change { user.reload.email }.to(new_email)
|
||||
expect(TriggerWebhookWorker)
|
||||
.to_not have_received(:perform_async).with('account.approved', 'Account', user.account_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -57,6 +57,30 @@ RSpec.describe 'blocking domains through the moderation interface' do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when suspending an already suspended domain and using a lower severity' do
|
||||
before { Fabricate :domain_block, domain: 'example.com', severity: 'silence' }
|
||||
|
||||
it 'warns about downgrade and does not update' do
|
||||
visit new_admin_domain_block_path
|
||||
|
||||
submit_domain_block('example.com', 'noop')
|
||||
|
||||
expect(page)
|
||||
.to have_content(/You have already imposed stricter limits on example.com/)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when failing to provide a domain value' do
|
||||
it 'provides an error about the missing value' do
|
||||
visit new_admin_domain_block_path
|
||||
|
||||
submit_domain_block('', 'noop')
|
||||
|
||||
expect(page)
|
||||
.to have_content(/review the error below/)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when suspending a subdomain of an already-silenced domain' do
|
||||
it 'presents a confirmation screen before suspending the domain' do
|
||||
domain_block = Fabricate(:domain_block, domain: 'example.com', severity: 'silence')
|
||||
|
|
36
yarn.lock
36
yarn.lock
|
@ -1939,6 +1939,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@epic-web/invariant@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "@epic-web/invariant@npm:1.0.0"
|
||||
checksum: 10c0/72dbeb026e4e4eb3bc9c65739b91408ca77ab7d603a2494fa2eff3790ec22892c4caba751cffdf30f5ccf0e7ba79c1e9c96cf0a357404b9432bf1365baac23ca
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@es-joy/jsdoccomment@npm:~0.52.0":
|
||||
version: 0.52.0
|
||||
resolution: "@es-joy/jsdoccomment@npm:0.52.0"
|
||||
|
@ -2665,7 +2672,7 @@ __metadata:
|
|||
cocoon-js-vanilla: "npm:^1.5.1"
|
||||
color-blend: "npm:^4.0.0"
|
||||
core-js: "npm:^3.30.2"
|
||||
cross-env: "npm:^7.0.3"
|
||||
cross-env: "npm:^10.0.0"
|
||||
detect-passive-events: "npm:^2.0.3"
|
||||
emoji-mart: "npm:emoji-mart-lazyload@latest"
|
||||
emojibase: "npm:^16.0.0"
|
||||
|
@ -2676,7 +2683,7 @@ __metadata:
|
|||
eslint-import-resolver-typescript: "npm:^4.2.5"
|
||||
eslint-plugin-formatjs: "npm:^5.3.1"
|
||||
eslint-plugin-import: "npm:~2.31.0"
|
||||
eslint-plugin-jsdoc: "npm:^51.0.0"
|
||||
eslint-plugin-jsdoc: "npm:^52.0.0"
|
||||
eslint-plugin-jsx-a11y: "npm:~6.10.2"
|
||||
eslint-plugin-promise: "npm:~7.2.1"
|
||||
eslint-plugin-react: "npm:^7.37.4"
|
||||
|
@ -6104,19 +6111,20 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cross-env@npm:^7.0.3":
|
||||
version: 7.0.3
|
||||
resolution: "cross-env@npm:7.0.3"
|
||||
"cross-env@npm:^10.0.0":
|
||||
version: 10.0.0
|
||||
resolution: "cross-env@npm:10.0.0"
|
||||
dependencies:
|
||||
cross-spawn: "npm:^7.0.1"
|
||||
"@epic-web/invariant": "npm:^1.0.0"
|
||||
cross-spawn: "npm:^7.0.6"
|
||||
bin:
|
||||
cross-env: src/bin/cross-env.js
|
||||
cross-env-shell: src/bin/cross-env-shell.js
|
||||
checksum: 10c0/f3765c25746c69fcca369655c442c6c886e54ccf3ab8c16847d5ad0e91e2f337d36eedc6599c1227904bf2a228d721e690324446876115bc8e7b32a866735ecf
|
||||
cross-env: dist/bin/cross-env.js
|
||||
cross-env-shell: dist/bin/cross-env-shell.js
|
||||
checksum: 10c0/d16ffc3734106577d57b6253d81ab50294623bd59f96e161033eaf99c1c308ffbaba8463c23a6c0f72e841eff467cb7007a0a551f27554fcf2bbf6598cd828f9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.1, cross-spawn@npm:^7.0.6":
|
||||
"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.6":
|
||||
version: 7.0.6
|
||||
resolution: "cross-spawn@npm:7.0.6"
|
||||
dependencies:
|
||||
|
@ -7040,9 +7048,9 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"eslint-plugin-jsdoc@npm:^51.0.0":
|
||||
version: 51.3.4
|
||||
resolution: "eslint-plugin-jsdoc@npm:51.3.4"
|
||||
"eslint-plugin-jsdoc@npm:^52.0.0":
|
||||
version: 52.0.1
|
||||
resolution: "eslint-plugin-jsdoc@npm:52.0.1"
|
||||
dependencies:
|
||||
"@es-joy/jsdoccomment": "npm:~0.52.0"
|
||||
are-docs-informative: "npm:^0.0.2"
|
||||
|
@ -7056,7 +7064,7 @@ __metadata:
|
|||
spdx-expression-parse: "npm:^4.0.0"
|
||||
peerDependencies:
|
||||
eslint: ^7.0.0 || ^8.0.0 || ^9.0.0
|
||||
checksum: 10c0/59e5aa972bdd1bd4e2ca2796ed4455dff1069044abc028621e107aa4b0cbb62ce09554c8e7c2ff3a44a1cbd551e54b6970adc420ba3a89adc6236b94310a81ff
|
||||
checksum: 10c0/0dac74a5ea1db8d15eea5a29a6dadd1361029230f414794abfd143b8cd0129d1cd862481d31eb0374b215d0841f41209fb8b4e36ac69b758094d7c77052432c0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user