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
7b1f26eea2
|
@ -1 +1 @@
|
||||||
3.4.4
|
3.4.5
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { resolve } from 'node:path';
|
||||||
|
|
||||||
import type { StorybookConfig } from '@storybook/react-vite';
|
import type { StorybookConfig } from '@storybook/react-vite';
|
||||||
|
|
||||||
const config: StorybookConfig = {
|
const config: StorybookConfig = {
|
||||||
|
@ -26,6 +28,12 @@ const config: StorybookConfig = {
|
||||||
'oops.png',
|
'oops.png',
|
||||||
].map((path) => ({ from: `../public/${path}`, to: `/${path}` })),
|
].map((path) => ({ from: `../public/${path}`, to: `/${path}` })),
|
||||||
],
|
],
|
||||||
|
viteFinal(config) {
|
||||||
|
// For an unknown reason, Storybook does not use the root
|
||||||
|
// from the Vite config so we need to set it manually.
|
||||||
|
config.root = resolve(__dirname, '../app/javascript');
|
||||||
|
return config;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default config;
|
export default config;
|
||||||
|
|
|
@ -13,7 +13,7 @@ ARG BASE_REGISTRY="docker.io"
|
||||||
|
|
||||||
# Ruby image to use for base image, change with [--build-arg RUBY_VERSION="3.4.x"]
|
# Ruby image to use for base image, change with [--build-arg RUBY_VERSION="3.4.x"]
|
||||||
# renovate: datasource=docker depName=docker.io/ruby
|
# renovate: datasource=docker depName=docker.io/ruby
|
||||||
ARG RUBY_VERSION="3.4.4"
|
ARG RUBY_VERSION="3.4.5"
|
||||||
# # Node.js version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"]
|
# # Node.js version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"]
|
||||||
# renovate: datasource=node-version depName=node
|
# renovate: datasource=node-version depName=node
|
||||||
ARG NODE_MAJOR_VERSION="22"
|
ARG NODE_MAJOR_VERSION="22"
|
||||||
|
|
11
Gemfile.lock
11
Gemfile.lock
|
@ -224,7 +224,7 @@ GEM
|
||||||
mail (~> 2.7)
|
mail (~> 2.7)
|
||||||
email_validator (2.2.4)
|
email_validator (2.2.4)
|
||||||
activemodel
|
activemodel
|
||||||
erb (5.0.1)
|
erb (5.0.2)
|
||||||
erubi (1.13.1)
|
erubi (1.13.1)
|
||||||
et-orbi (1.2.11)
|
et-orbi (1.2.11)
|
||||||
tzinfo
|
tzinfo
|
||||||
|
@ -315,7 +315,7 @@ GEM
|
||||||
http_accept_language (2.1.1)
|
http_accept_language (2.1.1)
|
||||||
httpclient (2.9.0)
|
httpclient (2.9.0)
|
||||||
mutex_m
|
mutex_m
|
||||||
httplog (1.7.0)
|
httplog (1.7.1)
|
||||||
rack (>= 2.0)
|
rack (>= 2.0)
|
||||||
rainbow (>= 2.0.0)
|
rainbow (>= 2.0.0)
|
||||||
i18n (1.14.7)
|
i18n (1.14.7)
|
||||||
|
@ -335,7 +335,7 @@ GEM
|
||||||
inline_svg (1.10.0)
|
inline_svg (1.10.0)
|
||||||
activesupport (>= 3.0)
|
activesupport (>= 3.0)
|
||||||
nokogiri (>= 1.6)
|
nokogiri (>= 1.6)
|
||||||
io-console (0.8.0)
|
io-console (0.8.1)
|
||||||
irb (1.15.2)
|
irb (1.15.2)
|
||||||
pp (>= 0.6.0)
|
pp (>= 0.6.0)
|
||||||
rdoc (>= 4.0.0)
|
rdoc (>= 4.0.0)
|
||||||
|
@ -627,11 +627,10 @@ GEM
|
||||||
prism (1.4.0)
|
prism (1.4.0)
|
||||||
prometheus_exporter (2.2.0)
|
prometheus_exporter (2.2.0)
|
||||||
webrick
|
webrick
|
||||||
propshaft (1.1.0)
|
propshaft (1.2.0)
|
||||||
actionpack (>= 7.0.0)
|
actionpack (>= 7.0.0)
|
||||||
activesupport (>= 7.0.0)
|
activesupport (>= 7.0.0)
|
||||||
rack
|
rack
|
||||||
railties (>= 7.0.0)
|
|
||||||
psych (5.2.6)
|
psych (5.2.6)
|
||||||
date
|
date
|
||||||
stringio
|
stringio
|
||||||
|
@ -708,7 +707,7 @@ GEM
|
||||||
link_header (~> 0.0, >= 0.0.8)
|
link_header (~> 0.0, >= 0.0.8)
|
||||||
rdf-normalize (0.7.0)
|
rdf-normalize (0.7.0)
|
||||||
rdf (~> 3.3)
|
rdf (~> 3.3)
|
||||||
rdoc (6.14.1)
|
rdoc (6.14.2)
|
||||||
erb
|
erb
|
||||||
psych (>= 4.0.0)
|
psych (>= 4.0.0)
|
||||||
redcarpet (3.6.1)
|
redcarpet (3.6.1)
|
||||||
|
|
|
@ -261,7 +261,9 @@ export const AltTextModal = forwardRef<ModalRef, Props & Partial<RestoreProps>>(
|
||||||
);
|
);
|
||||||
const lang = useAppSelector(
|
const lang = useAppSelector(
|
||||||
(state) =>
|
(state) =>
|
||||||
(state.compose as ImmutableMap<string, unknown>).get('lang') as string,
|
(state.compose as ImmutableMap<string, unknown>).get(
|
||||||
|
'language',
|
||||||
|
) as string,
|
||||||
);
|
);
|
||||||
const focusX =
|
const focusX =
|
||||||
(media?.getIn(['meta', 'focus', 'x'], 0) as number | undefined) ?? 0;
|
(media?.getIn(['meta', 'focus', 'x'], 0) as number | undefined) ?? 0;
|
||||||
|
|
|
@ -431,6 +431,7 @@ export const CollapsibleNavigationPanel: React.FC = () => {
|
||||||
filterTaps: true,
|
filterTaps: true,
|
||||||
bounds: isLtrDir ? { left: 0 } : { right: 0 },
|
bounds: isLtrDir ? { left: 0 } : { right: 0 },
|
||||||
rubberband: true,
|
rubberband: true,
|
||||||
|
enabled: openable,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -122,98 +122,93 @@ export const PolicyControls: React.FC = () => {
|
||||||
value={notificationPolicy.for_not_following}
|
value={notificationPolicy.for_not_following}
|
||||||
onChange={handleFilterNotFollowing}
|
onChange={handleFilterNotFollowing}
|
||||||
options={options}
|
options={options}
|
||||||
>
|
label={
|
||||||
<strong>
|
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='notifications.policy.filter_not_following_title'
|
id='notifications.policy.filter_not_following_title'
|
||||||
defaultMessage="People you don't follow"
|
defaultMessage="People you don't follow"
|
||||||
/>
|
/>
|
||||||
</strong>
|
}
|
||||||
<span className='hint'>
|
hint={
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='notifications.policy.filter_not_following_hint'
|
id='notifications.policy.filter_not_following_hint'
|
||||||
defaultMessage='Until you manually approve them'
|
defaultMessage='Until you manually approve them'
|
||||||
/>
|
/>
|
||||||
</span>
|
}
|
||||||
</SelectWithLabel>
|
/>
|
||||||
|
|
||||||
<SelectWithLabel
|
<SelectWithLabel
|
||||||
value={notificationPolicy.for_not_followers}
|
value={notificationPolicy.for_not_followers}
|
||||||
onChange={handleFilterNotFollowers}
|
onChange={handleFilterNotFollowers}
|
||||||
options={options}
|
options={options}
|
||||||
>
|
label={
|
||||||
<strong>
|
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='notifications.policy.filter_not_followers_title'
|
id='notifications.policy.filter_not_followers_title'
|
||||||
defaultMessage='People not following you'
|
defaultMessage='People not following you'
|
||||||
/>
|
/>
|
||||||
</strong>
|
}
|
||||||
<span className='hint'>
|
hint={
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='notifications.policy.filter_not_followers_hint'
|
id='notifications.policy.filter_not_followers_hint'
|
||||||
defaultMessage='Including people who have been following you fewer than {days, plural, one {one day} other {# days}}'
|
defaultMessage='Including people who have been following you fewer than {days, plural, one {one day} other {# days}}'
|
||||||
values={{ days: 3 }}
|
values={{ days: 3 }}
|
||||||
/>
|
/>
|
||||||
</span>
|
}
|
||||||
</SelectWithLabel>
|
/>
|
||||||
|
|
||||||
<SelectWithLabel
|
<SelectWithLabel
|
||||||
value={notificationPolicy.for_new_accounts}
|
value={notificationPolicy.for_new_accounts}
|
||||||
onChange={handleFilterNewAccounts}
|
onChange={handleFilterNewAccounts}
|
||||||
options={options}
|
options={options}
|
||||||
>
|
label={
|
||||||
<strong>
|
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='notifications.policy.filter_new_accounts_title'
|
id='notifications.policy.filter_new_accounts_title'
|
||||||
defaultMessage='New accounts'
|
defaultMessage='New accounts'
|
||||||
/>
|
/>
|
||||||
</strong>
|
}
|
||||||
<span className='hint'>
|
hint={
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='notifications.policy.filter_new_accounts.hint'
|
id='notifications.policy.filter_new_accounts.hint'
|
||||||
defaultMessage='Created within the past {days, plural, one {one day} other {# days}}'
|
defaultMessage='Created within the past {days, plural, one {one day} other {# days}}'
|
||||||
values={{ days: 30 }}
|
values={{ days: 30 }}
|
||||||
/>
|
/>
|
||||||
</span>
|
}
|
||||||
</SelectWithLabel>
|
/>
|
||||||
|
|
||||||
<SelectWithLabel
|
<SelectWithLabel
|
||||||
value={notificationPolicy.for_private_mentions}
|
value={notificationPolicy.for_private_mentions}
|
||||||
onChange={handleFilterPrivateMentions}
|
onChange={handleFilterPrivateMentions}
|
||||||
options={options}
|
options={options}
|
||||||
>
|
label={
|
||||||
<strong>
|
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='notifications.policy.filter_private_mentions_title'
|
id='notifications.policy.filter_private_mentions_title'
|
||||||
defaultMessage='Unsolicited private mentions'
|
defaultMessage='Unsolicited private mentions'
|
||||||
/>
|
/>
|
||||||
</strong>
|
}
|
||||||
<span className='hint'>
|
hint={
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='notifications.policy.filter_private_mentions_hint'
|
id='notifications.policy.filter_private_mentions_hint'
|
||||||
defaultMessage="Filtered unless it's in reply to your own mention or if you follow the sender"
|
defaultMessage="Filtered unless it's in reply to your own mention or if you follow the sender"
|
||||||
/>
|
/>
|
||||||
</span>
|
}
|
||||||
</SelectWithLabel>
|
/>
|
||||||
|
|
||||||
<SelectWithLabel
|
<SelectWithLabel
|
||||||
value={notificationPolicy.for_limited_accounts}
|
value={notificationPolicy.for_limited_accounts}
|
||||||
onChange={handleFilterLimitedAccounts}
|
onChange={handleFilterLimitedAccounts}
|
||||||
options={options}
|
options={options}
|
||||||
>
|
label={
|
||||||
<strong>
|
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='notifications.policy.filter_limited_accounts_title'
|
id='notifications.policy.filter_limited_accounts_title'
|
||||||
defaultMessage='Moderated accounts'
|
defaultMessage='Moderated accounts'
|
||||||
/>
|
/>
|
||||||
</strong>
|
}
|
||||||
<span className='hint'>
|
hint={
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='notifications.policy.filter_limited_accounts_hint'
|
id='notifications.policy.filter_limited_accounts_hint'
|
||||||
defaultMessage='Limited by server moderators'
|
defaultMessage='Limited by server moderators'
|
||||||
/>
|
/>
|
||||||
</span>
|
}
|
||||||
</SelectWithLabel>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import type { PropsWithChildren } from 'react';
|
import type { PropsWithChildren } from 'react';
|
||||||
import { useCallback, useState, useRef } from 'react';
|
import { useCallback, useState, useRef, useId } from 'react';
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@ interface DropdownProps {
|
||||||
options: SelectItem[];
|
options: SelectItem[];
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
onChange: (value: string) => void;
|
onChange: (value: string) => void;
|
||||||
|
'aria-labelledby': string;
|
||||||
|
'aria-describedby'?: string;
|
||||||
placement?: Placement;
|
placement?: Placement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,51 +26,33 @@ const Dropdown: React.FC<DropdownProps> = ({
|
||||||
options,
|
options,
|
||||||
disabled,
|
disabled,
|
||||||
onChange,
|
onChange,
|
||||||
|
'aria-labelledby': ariaLabelledBy,
|
||||||
|
'aria-describedby': ariaDescribedBy,
|
||||||
placement: initialPlacement = 'bottom-end',
|
placement: initialPlacement = 'bottom-end',
|
||||||
}) => {
|
}) => {
|
||||||
const activeElementRef = useRef<Element | null>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
const containerRef = useRef(null);
|
const buttonRef = useRef<HTMLButtonElement>(null);
|
||||||
const [isOpen, setOpen] = useState<boolean>(false);
|
const [isOpen, setOpen] = useState<boolean>(false);
|
||||||
const [placement, setPlacement] = useState<Placement>(initialPlacement);
|
const [placement, setPlacement] = useState<Placement>(initialPlacement);
|
||||||
|
const uniqueId = useId();
|
||||||
const handleToggle = useCallback(() => {
|
const menuId = `${uniqueId}-menu`;
|
||||||
if (
|
const buttonLabelId = `${uniqueId}-button`;
|
||||||
isOpen &&
|
|
||||||
activeElementRef.current &&
|
|
||||||
activeElementRef.current instanceof HTMLElement
|
|
||||||
) {
|
|
||||||
activeElementRef.current.focus({ preventScroll: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
setOpen(!isOpen);
|
|
||||||
}, [isOpen, setOpen]);
|
|
||||||
|
|
||||||
const handleMouseDown = useCallback(() => {
|
|
||||||
if (!isOpen) activeElementRef.current = document.activeElement;
|
|
||||||
}, [isOpen]);
|
|
||||||
|
|
||||||
const handleKeyDown = useCallback(
|
|
||||||
(e: React.KeyboardEvent) => {
|
|
||||||
switch (e.key) {
|
|
||||||
case ' ':
|
|
||||||
case 'Enter':
|
|
||||||
if (!isOpen) activeElementRef.current = document.activeElement;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[isOpen],
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleClose = useCallback(() => {
|
const handleClose = useCallback(() => {
|
||||||
if (
|
if (isOpen && buttonRef.current) {
|
||||||
isOpen &&
|
buttonRef.current.focus({ preventScroll: true });
|
||||||
activeElementRef.current &&
|
}
|
||||||
activeElementRef.current instanceof HTMLElement
|
|
||||||
)
|
|
||||||
activeElementRef.current.focus({ preventScroll: true });
|
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
}, [isOpen]);
|
}, [isOpen]);
|
||||||
|
|
||||||
|
const handleToggle = useCallback(() => {
|
||||||
|
if (isOpen) {
|
||||||
|
handleClose();
|
||||||
|
} else {
|
||||||
|
setOpen(true);
|
||||||
|
}
|
||||||
|
}, [isOpen, handleClose]);
|
||||||
|
|
||||||
const handleOverlayEnter = useCallback(
|
const handleOverlayEnter = useCallback(
|
||||||
(state: Partial<PopperState>) => {
|
(state: Partial<PopperState>) => {
|
||||||
if (state.placement) setPlacement(state.placement);
|
if (state.placement) setPlacement(state.placement);
|
||||||
|
@ -82,13 +66,18 @@ const Dropdown: React.FC<DropdownProps> = ({
|
||||||
<div ref={containerRef}>
|
<div ref={containerRef}>
|
||||||
<button
|
<button
|
||||||
type='button'
|
type='button'
|
||||||
|
ref={buttonRef}
|
||||||
onClick={handleToggle}
|
onClick={handleToggle}
|
||||||
onMouseDown={handleMouseDown}
|
|
||||||
onKeyDown={handleKeyDown}
|
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
aria-expanded={isOpen}
|
||||||
|
aria-controls={menuId}
|
||||||
|
aria-labelledby={`${ariaLabelledBy} ${buttonLabelId}`}
|
||||||
|
aria-describedby={ariaDescribedBy}
|
||||||
className={classNames('dropdown-button', { active: isOpen })}
|
className={classNames('dropdown-button', { active: isOpen })}
|
||||||
>
|
>
|
||||||
<span className='dropdown-button__label'>{valueOption?.text}</span>
|
<span id={buttonLabelId} className='dropdown-button__label'>
|
||||||
|
{valueOption?.text}
|
||||||
|
</span>
|
||||||
<Icon id='down' icon={ArrowDropDownIcon} />
|
<Icon id='down' icon={ArrowDropDownIcon} />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
@ -101,7 +90,7 @@ const Dropdown: React.FC<DropdownProps> = ({
|
||||||
popperConfig={{ strategy: 'fixed', onFirstUpdate: handleOverlayEnter }}
|
popperConfig={{ strategy: 'fixed', onFirstUpdate: handleOverlayEnter }}
|
||||||
>
|
>
|
||||||
{({ props, placement }) => (
|
{({ props, placement }) => (
|
||||||
<div {...props}>
|
<div {...props} id={menuId}>
|
||||||
<div
|
<div
|
||||||
className={`dropdown-animation privacy-dropdown__dropdown ${placement}`}
|
className={`dropdown-animation privacy-dropdown__dropdown ${placement}`}
|
||||||
>
|
>
|
||||||
|
@ -123,6 +112,8 @@ const Dropdown: React.FC<DropdownProps> = ({
|
||||||
interface Props {
|
interface Props {
|
||||||
value: string;
|
value: string;
|
||||||
options: SelectItem[];
|
options: SelectItem[];
|
||||||
|
label: string | React.ReactElement;
|
||||||
|
hint: string | React.ReactElement;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
onChange: (value: string) => void;
|
onChange: (value: string) => void;
|
||||||
}
|
}
|
||||||
|
@ -130,13 +121,26 @@ interface Props {
|
||||||
export const SelectWithLabel: React.FC<PropsWithChildren<Props>> = ({
|
export const SelectWithLabel: React.FC<PropsWithChildren<Props>> = ({
|
||||||
value,
|
value,
|
||||||
options,
|
options,
|
||||||
|
label,
|
||||||
|
hint,
|
||||||
disabled,
|
disabled,
|
||||||
children,
|
|
||||||
onChange,
|
onChange,
|
||||||
}) => {
|
}) => {
|
||||||
|
const uniqueId = useId();
|
||||||
|
const labelId = `${uniqueId}-label`;
|
||||||
|
const descId = `${uniqueId}-desc`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
// This label is only used for its click-forwarding behaviour,
|
||||||
|
// accessible names are assigned manually
|
||||||
|
// eslint-disable-next-line jsx-a11y/label-has-associated-control
|
||||||
<label className='app-form__toggle'>
|
<label className='app-form__toggle'>
|
||||||
<div className='app-form__toggle__label'>{children}</div>
|
<div className='app-form__toggle__label'>
|
||||||
|
<strong id={labelId}>{label}</strong>
|
||||||
|
<span className='hint' id={descId}>
|
||||||
|
{hint}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className='app-form__toggle__toggle'>
|
<div className='app-form__toggle__toggle'>
|
||||||
<div>
|
<div>
|
||||||
|
@ -144,6 +148,8 @@ export const SelectWithLabel: React.FC<PropsWithChildren<Props>> = ({
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
aria-labelledby={labelId}
|
||||||
|
aria-describedby={descId}
|
||||||
options={options}
|
options={options}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -617,7 +617,7 @@
|
||||||
"notification.reblog": "{name} продвинул(а) ваш пост",
|
"notification.reblog": "{name} продвинул(а) ваш пост",
|
||||||
"notification.reblog.name_and_others_with_link": "{name} и ещё <a>{count, plural, one {# пользователь} few {# пользователя} other {# пользователей}}</a> продвинули ваш пост",
|
"notification.reblog.name_and_others_with_link": "{name} и ещё <a>{count, plural, one {# пользователь} few {# пользователя} other {# пользователей}}</a> продвинули ваш пост",
|
||||||
"notification.relationships_severance_event": "Разорвана связь с {name}",
|
"notification.relationships_severance_event": "Разорвана связь с {name}",
|
||||||
"notification.relationships_severance_event.account_suspension": "Администратор сервера {from} заблокировал сервер {target}, поэтому вы больше не сможете получать обновления от людей с этого сервера или взаимодействовать с ними.",
|
"notification.relationships_severance_event.account_suspension": "Администратор сервера {from} заблокировал сервер {target}, поэтому вы больше не сможете получать обновления от людей с этого сервера и взаимодействовать с ними.",
|
||||||
"notification.relationships_severance_event.domain_block": "Администратор сервера {from} заблокировал сервер {target}, где размещены учётные записи {followersCount} ваших подписчиков и {followingCount, plural, one {# пользователя, на которого вы подписаны} other {# пользователей, на которых вы подписаны}}.",
|
"notification.relationships_severance_event.domain_block": "Администратор сервера {from} заблокировал сервер {target}, где размещены учётные записи {followersCount} ваших подписчиков и {followingCount, plural, one {# пользователя, на которого вы подписаны} other {# пользователей, на которых вы подписаны}}.",
|
||||||
"notification.relationships_severance_event.learn_more": "Узнать больше",
|
"notification.relationships_severance_event.learn_more": "Узнать больше",
|
||||||
"notification.relationships_severance_event.user_domain_block": "Вы заблокировали сервер {target}, где размещены учётные записи {followersCount} ваших подписчиков и {followingCount, plural, one {# пользователя, на которого вы подписаны} other {# пользователей, на которых вы подписаны}}.",
|
"notification.relationships_severance_event.user_domain_block": "Вы заблокировали сервер {target}, где размещены учётные записи {followersCount} ваших подписчиков и {followingCount, plural, one {# пользователя, на которого вы подписаны} other {# пользователей, на которых вы подписаны}}.",
|
||||||
|
@ -707,7 +707,7 @@
|
||||||
"onboarding.profile.display_name": "Отображаемое имя",
|
"onboarding.profile.display_name": "Отображаемое имя",
|
||||||
"onboarding.profile.display_name_hint": "Ваше полное имя или псевдоним…",
|
"onboarding.profile.display_name_hint": "Ваше полное имя или псевдоним…",
|
||||||
"onboarding.profile.note": "О себе",
|
"onboarding.profile.note": "О себе",
|
||||||
"onboarding.profile.note_hint": "Вы можете @упоминать других людей или использовать #хештеги…",
|
"onboarding.profile.note_hint": "Вы можете @упоминать других людей, а также использовать #хештеги…",
|
||||||
"onboarding.profile.save_and_continue": "Сохранить и продолжить",
|
"onboarding.profile.save_and_continue": "Сохранить и продолжить",
|
||||||
"onboarding.profile.title": "Создайте свой профиль",
|
"onboarding.profile.title": "Создайте свой профиль",
|
||||||
"onboarding.profile.upload_avatar": "Загрузить фото профиля",
|
"onboarding.profile.upload_avatar": "Загрузить фото профиля",
|
||||||
|
@ -741,16 +741,16 @@
|
||||||
"refresh": "Обновить",
|
"refresh": "Обновить",
|
||||||
"regeneration_indicator.please_stand_by": "Пожалуйста, подождите.",
|
"regeneration_indicator.please_stand_by": "Пожалуйста, подождите.",
|
||||||
"regeneration_indicator.preparing_your_home_feed": "Готовим вашу ленту…",
|
"regeneration_indicator.preparing_your_home_feed": "Готовим вашу ленту…",
|
||||||
"relative_time.days": "{number} д",
|
"relative_time.days": "{number} д.",
|
||||||
"relative_time.full.days": "{number, plural, one {# день} many {# дней} other {# дня}} назад",
|
"relative_time.full.days": "{number, plural, one {# день} many {# дней} other {# дня}} назад",
|
||||||
"relative_time.full.hours": "{number, plural, one {# час} many {# часов} other {# часа}} назад",
|
"relative_time.full.hours": "{number, plural, one {# час} many {# часов} other {# часа}} назад",
|
||||||
"relative_time.full.just_now": "только что",
|
"relative_time.full.just_now": "только что",
|
||||||
"relative_time.full.minutes": "{number, plural, one {# минуту} many {# минут} other {# минуты}} назад",
|
"relative_time.full.minutes": "{number, plural, one {# минуту} many {# минут} other {# минуты}} назад",
|
||||||
"relative_time.full.seconds": "{number, plural, one {# секунду} many {# секунд} other {# секунды}} назад",
|
"relative_time.full.seconds": "{number, plural, one {# секунду} many {# секунд} other {# секунды}} назад",
|
||||||
"relative_time.hours": "{number} ч",
|
"relative_time.hours": "{number} ч.",
|
||||||
"relative_time.just_now": "только что",
|
"relative_time.just_now": "только что",
|
||||||
"relative_time.minutes": "{number} мин",
|
"relative_time.minutes": "{number} мин.",
|
||||||
"relative_time.seconds": "{number} с",
|
"relative_time.seconds": "{number} с.",
|
||||||
"relative_time.today": "сегодня",
|
"relative_time.today": "сегодня",
|
||||||
"reply_indicator.attachments": "{count, plural, one {# вложение} few {# вложения} other {# вложений}}",
|
"reply_indicator.attachments": "{count, plural, one {# вложение} few {# вложения} other {# вложений}}",
|
||||||
"reply_indicator.cancel": "Отмена",
|
"reply_indicator.cancel": "Отмена",
|
||||||
|
@ -836,7 +836,7 @@
|
||||||
"server_banner.is_one_of_many": "{domain} — это один из многих независимых серверов Mastodon, которые вы можете использовать, чтобы присоединиться к сети Fediverse.",
|
"server_banner.is_one_of_many": "{domain} — это один из многих независимых серверов Mastodon, которые вы можете использовать, чтобы присоединиться к сети Fediverse.",
|
||||||
"server_banner.server_stats": "Статистика сервера:",
|
"server_banner.server_stats": "Статистика сервера:",
|
||||||
"sign_in_banner.create_account": "Зарегистрироваться",
|
"sign_in_banner.create_account": "Зарегистрироваться",
|
||||||
"sign_in_banner.follow_anyone": "Подписывайтесь на кого угодно в федивёрсе и читайте ленту в хронологическом порядке. Никаких алгоритмов, рекламы или кликбейта.",
|
"sign_in_banner.follow_anyone": "Подписывайтесь на кого угодно в федивёрсе и читайте ленту в хронологическом порядке. Никаких алгоритмов, рекламы и кликбейта.",
|
||||||
"sign_in_banner.mastodon_is": "Mastodon — лучший способ быть в курсе всего происходящего.",
|
"sign_in_banner.mastodon_is": "Mastodon — лучший способ быть в курсе всего происходящего.",
|
||||||
"sign_in_banner.sign_in": "Войти",
|
"sign_in_banner.sign_in": "Войти",
|
||||||
"sign_in_banner.sso_redirect": "Вход/Регистрация",
|
"sign_in_banner.sso_redirect": "Вход/Регистрация",
|
||||||
|
|
|
@ -1857,7 +1857,10 @@ body > [data-popper-placement] {
|
||||||
}
|
}
|
||||||
|
|
||||||
.status__quote {
|
.status__quote {
|
||||||
--quote-margin: 36px;
|
// --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);
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
margin-block-start: 16px;
|
margin-block-start: 16px;
|
||||||
|
@ -1868,7 +1871,7 @@ body > [data-popper-placement] {
|
||||||
border: var(--nested-card-border);
|
border: var(--nested-card-border);
|
||||||
|
|
||||||
@container (width > 460px) {
|
@container (width > 460px) {
|
||||||
--quote-margin: 56px;
|
--quote-margin: var(--status-gutter-width, 56px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10817,21 +10820,23 @@ noscript {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.status {
|
.status:not(.status--is-quote) {
|
||||||
border: 0;
|
border: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
||||||
&__avatar {
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.status__wrapper-direct {
|
.status__wrapper-direct {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
$icon-margin: 48px; // 40px avatar + 8px gap
|
.status {
|
||||||
|
// 40px avatar + 8px gap
|
||||||
|
--status-gutter-width: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status--is-quote {
|
||||||
|
--status-gutter-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.status__content,
|
.status__content,
|
||||||
.status__action-bar,
|
.status__action-bar,
|
||||||
|
@ -10845,16 +10850,16 @@ noscript {
|
||||||
.hashtag-bar,
|
.hashtag-bar,
|
||||||
.content-warning,
|
.content-warning,
|
||||||
.filter-warning {
|
.filter-warning {
|
||||||
margin-inline-start: $icon-margin;
|
margin-inline-start: var(--status-gutter-width);
|
||||||
width: calc(100% - $icon-margin);
|
width: calc(100% - var(--status-gutter-width));
|
||||||
}
|
}
|
||||||
|
|
||||||
.more-from-author {
|
.more-from-author {
|
||||||
width: calc(100% - $icon-margin + 2px);
|
width: calc(100% - var(--status-gutter-width) + 2px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.status__content__read-more-button {
|
.status__content__read-more-button {
|
||||||
margin-inline-start: $icon-margin;
|
margin-inline-start: var(--status-gutter-width);
|
||||||
}
|
}
|
||||||
|
|
||||||
.notification__report {
|
.notification__report {
|
||||||
|
|
|
@ -1349,6 +1349,8 @@ fa:
|
||||||
basic_information: اطلاعات پایه
|
basic_information: اطلاعات پایه
|
||||||
hint_html: "<strong>شخصیسازی آن چه مردم روی نمایهٔ عمومیتان و کنار فرستههایتان میبینند.</strong> هنگامی که نمایهای کامل و یک تصویر نمایه داشته باشید، احتمال پیگیری متقابل و تعامل با شما بیشتر است."
|
hint_html: "<strong>شخصیسازی آن چه مردم روی نمایهٔ عمومیتان و کنار فرستههایتان میبینند.</strong> هنگامی که نمایهای کامل و یک تصویر نمایه داشته باشید، احتمال پیگیری متقابل و تعامل با شما بیشتر است."
|
||||||
other: سایر
|
other: سایر
|
||||||
|
emoji_styles:
|
||||||
|
auto: خودکار
|
||||||
errors:
|
errors:
|
||||||
'400': درخواستی که فرستادید نامعتبر یا اشتباه بود.
|
'400': درخواستی که فرستادید نامعتبر یا اشتباه بود.
|
||||||
'403': شما اجازهٔ دیدن این صفحه را ندارید.
|
'403': شما اجازهٔ دیدن این صفحه را ندارید.
|
||||||
|
|
|
@ -354,7 +354,7 @@ ru:
|
||||||
enable: Включить
|
enable: Включить
|
||||||
enabled: Включён
|
enabled: Включён
|
||||||
enabled_msg: Эмодзи включён
|
enabled_msg: Эмодзи включён
|
||||||
image_hint: Поддерживаются файлы PNG или GIF размером не более %{size}
|
image_hint: Поддерживаются файлы PNG и GIF размером не более %{size}
|
||||||
list: В список
|
list: В список
|
||||||
listed: В списке
|
listed: В списке
|
||||||
new:
|
new:
|
||||||
|
@ -1280,7 +1280,7 @@ ru:
|
||||||
confirm: Продолжить
|
confirm: Продолжить
|
||||||
hint_html: "<strong>Подсказка:</strong> В течение часа вам не придётся снова вводить свой пароль."
|
hint_html: "<strong>Подсказка:</strong> В течение часа вам не придётся снова вводить свой пароль."
|
||||||
invalid_password: Неверный пароль
|
invalid_password: Неверный пароль
|
||||||
prompt: Введите пароль для продолжения
|
prompt: Введите пароль, чтобы продолжить
|
||||||
crypto:
|
crypto:
|
||||||
errors:
|
errors:
|
||||||
invalid_key: должен быть действительным Ed25519- или Curve25519-ключом
|
invalid_key: должен быть действительным Ed25519- или Curve25519-ключом
|
||||||
|
@ -1290,35 +1290,35 @@ ru:
|
||||||
with_month_name: "%d %B %Y"
|
with_month_name: "%d %B %Y"
|
||||||
datetime:
|
datetime:
|
||||||
distance_in_words:
|
distance_in_words:
|
||||||
about_x_hours: "%{count}ч"
|
about_x_hours: "%{count} ч."
|
||||||
about_x_months: "%{count}мес"
|
about_x_months: "%{count} мес."
|
||||||
about_x_years: "%{count}г"
|
about_x_years: "%{count} г."
|
||||||
almost_x_years: "%{count}г"
|
almost_x_years: "%{count} г."
|
||||||
half_a_minute: Только что
|
half_a_minute: Только что
|
||||||
less_than_x_minutes: "%{count}мин"
|
less_than_x_minutes: "%{count} мин."
|
||||||
less_than_x_seconds: Только что
|
less_than_x_seconds: Только что
|
||||||
over_x_years: "%{count}г"
|
over_x_years: "%{count} г."
|
||||||
x_days: "%{count}д"
|
x_days: "%{count} д."
|
||||||
x_minutes: "%{count}мин"
|
x_minutes: "%{count} мин."
|
||||||
x_months: "%{count}мес"
|
x_months: "%{count} мес."
|
||||||
x_seconds: "%{count}сек"
|
x_seconds: "%{count} с."
|
||||||
deletes:
|
deletes:
|
||||||
challenge_not_passed: Введённая вами информация некорректна
|
challenge_not_passed: Данные введены неверно
|
||||||
confirm_password: Введите свой пароль, чтобы подтвердить, что вы — это вы, и никто другой
|
confirm_password: Введите свой пароль, чтобы подтвердить, что это ваша учётная запись
|
||||||
confirm_username: Введите своё имя пользователя для подтверждения
|
confirm_username: Введите своё имя пользователя для подтверждения
|
||||||
proceed: Удалить учётную запись
|
proceed: Удалить учётную запись
|
||||||
success_msg: Ваша учётная запись была успешно удалена
|
success_msg: Ваша учётная запись удалена
|
||||||
warning:
|
warning:
|
||||||
before: 'Внимательно прочитайте следующую информацию перед началом:'
|
before: 'Внимательно ознакомьтесь со следующими замечаниями перед тем как продолжить:'
|
||||||
caches: Некоторые данные, обработанные другими узлами, однако, могут храниться ещё какое-то время
|
caches: На других серверах могут остаться сохранённые в кэше данные
|
||||||
data_removal: Все ваши золотые посты, шикарный профиль и прочие данные будут безвозвратно уничтожены
|
data_removal: Все ваши посты и другие ваши данные будут безвозвратно уничтожены
|
||||||
email_change_html: Вы можете <a href="%{path}">изменить свой адрес электронной почты</a>, не удаляя свою учетную запись
|
email_change_html: Вы можете <a href="%{path}">изменить свой адрес электронной почты</a>, не удаляя свою учетную запись
|
||||||
email_contact_html: Если оно все еще не пришло, вы можете обратиться за помощью по электронной почте <a href="mailto:%{email}">%{email}</a>
|
email_contact_html: Если оно все еще не пришло, вы можете обратиться за помощью по электронной почте <a href="mailto:%{email}">%{email}</a>
|
||||||
email_reconfirmation_html: Если вы не получили подтверждение по электронной почте, вы можете <a href="%{path}">запросить его снова</a>
|
email_reconfirmation_html: Если вы не получили подтверждение по электронной почте, вы можете <a href="%{path}">запросить его снова</a>
|
||||||
irreversible: После удаления восстановить или повторно активировать учётную запись не получится
|
irreversible: После удаления вы больше не сможете ни восстановить, ни повторно активировать свою учётную запись
|
||||||
more_details_html: За всеми подробностями, изучите <a href="%{terms_path}">политику конфиденциальности</a>.
|
more_details_html: За более подробной информацией вы можете обратиться к <a href="%{terms_path}">политике конфиденциальности</a>.
|
||||||
username_available: Ваше имя пользователя снова станет доступным
|
username_available: Ваше имя пользователя снова станет доступным
|
||||||
username_unavailable: Ваше имя пользователя останется недоступным для использования
|
username_unavailable: Зарегистрироваться с вашим именем пользователя будет невозможно
|
||||||
disputes:
|
disputes:
|
||||||
strikes:
|
strikes:
|
||||||
action_taken: Предпринятые меры
|
action_taken: Предпринятые меры
|
||||||
|
@ -1353,6 +1353,10 @@ ru:
|
||||||
basic_information: Основная информация
|
basic_information: Основная информация
|
||||||
hint_html: "<strong>Настройте то, что люди видят в вашем публичном профиле и рядом с вашими сообщениями.</strong> Другие люди с большей вероятностью подпишутся на Вас и будут взаимодействовать с вами, если у Вас заполнен профиль и добавлено изображение."
|
hint_html: "<strong>Настройте то, что люди видят в вашем публичном профиле и рядом с вашими сообщениями.</strong> Другие люди с большей вероятностью подпишутся на Вас и будут взаимодействовать с вами, если у Вас заполнен профиль и добавлено изображение."
|
||||||
other: Прочее
|
other: Прочее
|
||||||
|
emoji_styles:
|
||||||
|
auto: Автоматически
|
||||||
|
native: Как в системе
|
||||||
|
twemoji: Twemoji
|
||||||
errors:
|
errors:
|
||||||
'400': Ваш запрос был недействительным или неправильным.
|
'400': Ваш запрос был недействительным или неправильным.
|
||||||
'403': У Вас нет доступа к просмотру этой страницы.
|
'403': У Вас нет доступа к просмотру этой страницы.
|
||||||
|
@ -2136,17 +2140,17 @@ ru:
|
||||||
webauthn_credentials:
|
webauthn_credentials:
|
||||||
add: Добавить новый электронный ключ
|
add: Добавить новый электронный ключ
|
||||||
create:
|
create:
|
||||||
error: Возникла проблема с добавлением ключа безопасности. Пожалуйста, попробуйте еще раз.
|
error: При добавлении электронного ключа произошла ошибка. Попробуйте ещё раз.
|
||||||
success: Ваш электронный ключ добавлен.
|
success: Ваш электронный ключ добавлен.
|
||||||
delete: Удалить
|
delete: Удалить
|
||||||
delete_confirmation: Вы действительно хотите удалить этот электронный ключ?
|
delete_confirmation: Вы действительно хотите удалить этот электронный ключ?
|
||||||
description_html: Если вы включите <strong>аутентификацию по электронным ключам</strong>, для входа в учётную запись вам будет предложено использовать один из ваших ключей.
|
description_html: Если вы включите <strong>аутентификацию по электронным ключам</strong>, для входа в учётную запись вам будет предложено использовать один из ваших ключей.
|
||||||
destroy:
|
destroy:
|
||||||
error: Произошла ошибка при удалении ключа безопасности. Пожалуйста, попробуйте еще раз.
|
error: При удалении электронного ключа произошла ошибка. Попробуйте ещё раз.
|
||||||
success: Ваш электронный ключ удалён.
|
success: Ваш электронный ключ удалён.
|
||||||
invalid_credential: Неверный электронный ключ
|
invalid_credential: Неверный электронный ключ
|
||||||
nickname_hint: Введите название для нового электронного ключа
|
nickname_hint: Введите название для нового электронного ключа
|
||||||
not_enabled: Вы еще не включили WebAuthn
|
not_enabled: Вы еще не включили WebAuthn
|
||||||
not_supported: Этот браузер не поддерживает ключи безопасности
|
not_supported: В этом браузере отсутствует поддержка электронных ключей
|
||||||
otp_required: Чтобы использовать ключи безопасности, сначала включите двухфакторную аутентификацию.
|
otp_required: Чтобы использовать электронные ключи, сначала включите двухфакторную аутентификацию.
|
||||||
registered_on: Зарегистрирован %{date}
|
registered_on: Зарегистрирован %{date}
|
||||||
|
|
|
@ -149,6 +149,9 @@ ca:
|
||||||
min_age: No hauria de ser inferior a l'edat mínima exigida per la llei de la vostra jurisdicció.
|
min_age: No hauria de ser inferior a l'edat mínima exigida per la llei de la vostra jurisdicció.
|
||||||
user:
|
user:
|
||||||
chosen_languages: Quan estigui marcat, només es mostraran els tuts de les llengües seleccionades en les línies de temps públiques
|
chosen_languages: Quan estigui marcat, només es mostraran els tuts de les llengües seleccionades en les línies de temps públiques
|
||||||
|
date_of_birth:
|
||||||
|
one: Ens hem d'assegurar que teniu com a mínim %{count} any per a fer servir %{domain}. No ho desarem.
|
||||||
|
other: Ens hem d'assegurar que teniu com a mínim %{count} anys per a fer servir %{domain}. No ho desarem.
|
||||||
role: El rol controla quins permisos té l'usuari.
|
role: El rol controla quins permisos té l'usuari.
|
||||||
user_role:
|
user_role:
|
||||||
color: Color que s'usarà per al rol a tota la interfície d'usuari, com a RGB en format hexadecimal
|
color: Color que s'usarà per al rol a tota la interfície d'usuari, com a RGB en format hexadecimal
|
||||||
|
|
|
@ -150,6 +150,11 @@ cs:
|
||||||
min_age: Neměla by být pod minimálním věkem požadovaným zákony vaší jurisdikce.
|
min_age: Neměla by být pod minimálním věkem požadovaným zákony vaší jurisdikce.
|
||||||
user:
|
user:
|
||||||
chosen_languages: Po zaškrtnutí budou ve veřejných časových osách zobrazeny pouze příspěvky ve zvolených jazycích
|
chosen_languages: Po zaškrtnutí budou ve veřejných časových osách zobrazeny pouze příspěvky ve zvolených jazycích
|
||||||
|
date_of_birth:
|
||||||
|
few: Musíme se ujistit, že je Vám alespoň %{count}, abyste mohli používat %{domain}. Nebudeme to ukládat.
|
||||||
|
many: Musíme se ujistit, že je Vám alespoň %{count} let, abyste mohli používat %{domain}. Nebudeme to ukládat.
|
||||||
|
one: Musíme se ujistit, že je Vám alespoň %{count} rok, abyste mohli používat %{domain}. Nebudeme to ukládat.
|
||||||
|
other: Musíme se ujistit, že je Vám alespoň %{count}, abyste mohli používat %{domain}. Nebudeme to ukládat.
|
||||||
role: Role určuje, která oprávnění uživatel má.
|
role: Role určuje, která oprávnění uživatel má.
|
||||||
user_role:
|
user_role:
|
||||||
color: Barva, která má být použita pro roli v celém UI, jako RGB v hex formátu
|
color: Barva, která má být použita pro roli v celém UI, jako RGB v hex formátu
|
||||||
|
|
|
@ -151,8 +151,8 @@ da:
|
||||||
user:
|
user:
|
||||||
chosen_languages: Når markeret, vil kun indlæg på de valgte sprog fremgå på offentlige tidslinjer
|
chosen_languages: Når markeret, vil kun indlæg på de valgte sprog fremgå på offentlige tidslinjer
|
||||||
date_of_birth:
|
date_of_birth:
|
||||||
one: Vi skal sikre os, at du er mindst %{count} for at kunne bruge %{domain}. Vi gemmer ikke dette.
|
one: Vi skal sikre os, at du er mindst %{count} for at kunne bruge %{domain}. Informationen gemmes ikke.
|
||||||
other: Vi skal sikre os, at du er mindst %{count} for at kunne bruge %{domain}. Vi gemmer ikke dette.
|
other: Vi skal sikre os, at du er mindst %{count} for at kunne bruge %{domain}. Informationen gemmes ikke.
|
||||||
role: Rollen styrer, hvilke tilladelser brugeren er tildelt.
|
role: Rollen styrer, hvilke tilladelser brugeren er tildelt.
|
||||||
user_role:
|
user_role:
|
||||||
color: Farven, i RGB hex-format, der skal bruges til rollen i hele UI'en
|
color: Farven, i RGB hex-format, der skal bruges til rollen i hele UI'en
|
||||||
|
|
|
@ -150,6 +150,9 @@ fo:
|
||||||
min_age: Eigur ikki at vera undir lægsta aldri, sum lógirnar í tínum rættarøki krevja.
|
min_age: Eigur ikki at vera undir lægsta aldri, sum lógirnar í tínum rættarøki krevja.
|
||||||
user:
|
user:
|
||||||
chosen_languages: Tá hetta er valt, verða einans postar í valdum málum vístir á almennum tíðarlinjum
|
chosen_languages: Tá hetta er valt, verða einans postar í valdum málum vístir á almennum tíðarlinjum
|
||||||
|
date_of_birth:
|
||||||
|
one: Vit mugu tryggja okkum, at tú er í minsta lagi %{count} fyri at brúka %{domain}. Vit goyma ikki hesar upplýsingar.
|
||||||
|
other: Vit mugu tryggja okkum, at tú er í minsta lagi %{count} ár fyri at brúka %{domain}. Vit goyma ikki hesar upplýsingar.
|
||||||
role: Leikluturin stýrir hvørji rættindi, brúkarin hevur.
|
role: Leikluturin stýrir hvørji rættindi, brúkarin hevur.
|
||||||
user_role:
|
user_role:
|
||||||
color: Litur, sum leikluturin hevur í øllum brúkaramarkamótinum, sum RGB og upplýst sum sekstandatal
|
color: Litur, sum leikluturin hevur í øllum brúkaramarkamótinum, sum RGB og upplýst sum sekstandatal
|
||||||
|
|
|
@ -150,6 +150,9 @@ fy:
|
||||||
min_age: Mei net leger wêze as de minimale fereaske leeftiid neffens de wetten fan jo jurisdiksje.
|
min_age: Mei net leger wêze as de minimale fereaske leeftiid neffens de wetten fan jo jurisdiksje.
|
||||||
user:
|
user:
|
||||||
chosen_languages: Allinnich berjochten yn de selektearre talen wurde op de iepenbiere tiidline toand
|
chosen_languages: Allinnich berjochten yn de selektearre talen wurde op de iepenbiere tiidline toand
|
||||||
|
date_of_birth:
|
||||||
|
one: Wy moatte derfoar soargje dat jo op syn minst %{count} binne om %{domain} brûke te meien. Dit wurdt net bewarre.
|
||||||
|
other: Wy moatte derfoar soargje dat jo op syn minst %{count} binne om %{domain} brûke te meien. Dit wurdt net bewarre.
|
||||||
role: De rol bepaalt hokker rjochten in brûker hat.
|
role: De rol bepaalt hokker rjochten in brûker hat.
|
||||||
user_role:
|
user_role:
|
||||||
color: Kleur dy’t brûkt wurdt foar de rol yn de UI, as RGB yn heksadesimaal formaat
|
color: Kleur dy’t brûkt wurdt foar de rol yn de UI, as RGB yn heksadesimaal formaat
|
||||||
|
|
|
@ -150,6 +150,9 @@ gl:
|
||||||
min_age: Non debería ser inferior á idade mínima requerida polas leis da túa xurisdición.
|
min_age: Non debería ser inferior á idade mínima requerida polas leis da túa xurisdición.
|
||||||
user:
|
user:
|
||||||
chosen_languages: Se ten marca, só as publicacións nos idiomas seleccionados serán mostrados en cronoloxías públicas
|
chosen_languages: Se ten marca, só as publicacións nos idiomas seleccionados serán mostrados en cronoloxías públicas
|
||||||
|
date_of_birth:
|
||||||
|
one: Temos que confirmar que tes %{count} anos polo menos para usar %{domain}. Non gardamos este dato.
|
||||||
|
other: Temos que confirmar que tes %{count} anos polo menos para usar %{domain}. Non gardamos este dato.
|
||||||
role: Os roles establecen os permisos que ten a usuaria.
|
role: Os roles establecen os permisos que ten a usuaria.
|
||||||
user_role:
|
user_role:
|
||||||
color: Cor que se usará para o rol a través da IU, como RGB en formato hex
|
color: Cor que se usará para o rol a través da IU, como RGB en formato hex
|
||||||
|
|
|
@ -150,6 +150,9 @@ is:
|
||||||
min_age: Ætti ekki að vera lægri en sá lágmarksaldur sek kveðið er á um í lögum þíns lögsagnarumdæmis.
|
min_age: Ætti ekki að vera lægri en sá lágmarksaldur sek kveðið er á um í lögum þíns lögsagnarumdæmis.
|
||||||
user:
|
user:
|
||||||
chosen_languages: Þegar merkt er við þetta, birtast einungis færslur á völdum tungumálum á opinberum tímalínum
|
chosen_languages: Þegar merkt er við þetta, birtast einungis færslur á völdum tungumálum á opinberum tímalínum
|
||||||
|
date_of_birth:
|
||||||
|
one: Við verðum að ganga úr skugga um að þú hafir náð %{count} aldri til að nota %{domain}. Við munum ekki geyma þessar upplýsingar.
|
||||||
|
other: Við verðum að ganga úr skugga um að þú hafir náð %{count} aldri til að nota %{domain}. Við munum ekki geyma þessar upplýsingar.
|
||||||
role: Hlutverk stýrir hvaða heimildir notandinn hefur.
|
role: Hlutverk stýrir hvaða heimildir notandinn hefur.
|
||||||
user_role:
|
user_role:
|
||||||
color: Litur sem notaður er fyrir hlutverkið allsstaðar í viðmótinu, sem RGB-gildi á hex-sniði
|
color: Litur sem notaður er fyrir hlutverkið allsstaðar í viðmótinu, sem RGB-gildi á hex-sniði
|
||||||
|
|
|
@ -150,6 +150,9 @@ it:
|
||||||
min_age: Non si dovrebbe avere un'età inferiore a quella minima richiesta, dalle leggi della tua giurisdizione.
|
min_age: Non si dovrebbe avere un'età inferiore a quella minima richiesta, dalle leggi della tua giurisdizione.
|
||||||
user:
|
user:
|
||||||
chosen_languages: Quando una o più lingue sono contrassegnate, nelle timeline pubbliche vengono mostrati solo i toot nelle lingue selezionate
|
chosen_languages: Quando una o più lingue sono contrassegnate, nelle timeline pubbliche vengono mostrati solo i toot nelle lingue selezionate
|
||||||
|
date_of_birth:
|
||||||
|
one: Dobbiamo assicurarci che tu abbia almeno %{count} anni per utilizzare %{domain}. Non memorizzeremo questo dato.
|
||||||
|
other: Dobbiamo assicurarci che tu abbia almeno %{count} anni per utilizzare %{domain}. Non memorizzeremo questo dato.
|
||||||
role: Il ruolo controlla quali permessi ha l'utente.
|
role: Il ruolo controlla quali permessi ha l'utente.
|
||||||
user_role:
|
user_role:
|
||||||
color: Colore da usare per il ruolo in tutta l'UI, come RGB in formato esadecimale
|
color: Colore da usare per il ruolo in tutta l'UI, come RGB in formato esadecimale
|
||||||
|
|
|
@ -8,7 +8,7 @@ ru:
|
||||||
display_name: Ваше полное имя или псевдоним.
|
display_name: Ваше полное имя или псевдоним.
|
||||||
fields: Домашняя страница, местоимения, возраст — всё что угодно.
|
fields: Домашняя страница, местоимения, возраст — всё что угодно.
|
||||||
indexable: Отметьте флажок, чтобы ваши публичные посты могли быть найдены при помощи поиска в Mastodon. Люди, которые взаимодействовали с вашими постами, смогут их найти вне зависимости от этой настройки.
|
indexable: Отметьте флажок, чтобы ваши публичные посты могли быть найдены при помощи поиска в Mastodon. Люди, которые взаимодействовали с вашими постами, смогут их найти вне зависимости от этой настройки.
|
||||||
note: 'Вы можете @упоминать других людей или использовать #хештеги.'
|
note: 'Вы можете @упоминать других людей, а также использовать #хештеги.'
|
||||||
show_collections: Отметьте флажок, чтобы кто угодно мог просматривать списки ваших подписок и подписчиков. Люди, на которых вы подписаны, будут знать о том, что вы на них подписаны, вне зависимости от этой настройки.
|
show_collections: Отметьте флажок, чтобы кто угодно мог просматривать списки ваших подписок и подписчиков. Люди, на которых вы подписаны, будут знать о том, что вы на них подписаны, вне зависимости от этой настройки.
|
||||||
unlocked: 'Отметьте флажок, чтобы на вас можно было подписаться, не запрашивая подтверждения. Снимите флажок, чтобы вы могли просматривать запросы на подписку и выбирать: принять или отклонить новых подписчиков.'
|
unlocked: 'Отметьте флажок, чтобы на вас можно было подписаться, не запрашивая подтверждения. Снимите флажок, чтобы вы могли просматривать запросы на подписку и выбирать: принять или отклонить новых подписчиков.'
|
||||||
account_alias:
|
account_alias:
|
||||||
|
|
|
@ -22,7 +22,21 @@ export function MastodonThemes(): Plugin {
|
||||||
projectRoot = userConfig.envDir;
|
projectRoot = userConfig.envDir;
|
||||||
jsRoot = userConfig.root;
|
jsRoot = userConfig.root;
|
||||||
|
|
||||||
const entrypoints: Record<string, string> = {};
|
let entrypoints: Record<string, string> = {};
|
||||||
|
|
||||||
|
const existingInputs = userConfig.build?.rollupOptions?.input;
|
||||||
|
|
||||||
|
if (typeof existingInputs === 'string') {
|
||||||
|
entrypoints[path.basename(existingInputs)] = existingInputs;
|
||||||
|
} else if (Array.isArray(existingInputs)) {
|
||||||
|
for (const input of existingInputs) {
|
||||||
|
if (typeof input === 'string') {
|
||||||
|
entrypoints[path.basename(input)] = input;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (typeof existingInputs === 'object') {
|
||||||
|
entrypoints = existingInputs;
|
||||||
|
}
|
||||||
|
|
||||||
// Get all files mentioned in the themes.yml file.
|
// Get all files mentioned in the themes.yml file.
|
||||||
const themes = await loadThemesFromConfig(projectRoot);
|
const themes = await loadThemesFromConfig(projectRoot);
|
||||||
|
|
10
package.json
10
package.json
|
@ -30,7 +30,7 @@
|
||||||
"test:storybook": "vitest --project=storybook",
|
"test:storybook": "vitest --project=storybook",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
"storybook": "storybook dev -p 6006",
|
"storybook": "storybook dev -p 6006",
|
||||||
"build-storybook": "VITE_RUBY_PUBLIC_OUTPUT_DIR='.' VITE_RUBY_PUBLIC_DIR='./storybook-static' storybook build",
|
"build-storybook": "storybook build",
|
||||||
"chromatic": "npx chromatic -d storybook-static"
|
"chromatic": "npx chromatic -d storybook-static"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -69,6 +69,7 @@
|
||||||
"emojibase": "^16.0.0",
|
"emojibase": "^16.0.0",
|
||||||
"emojibase-data": "^16.0.3",
|
"emojibase-data": "^16.0.3",
|
||||||
"escape-html": "^1.0.3",
|
"escape-html": "^1.0.3",
|
||||||
|
"fast-glob": "^3.3.3",
|
||||||
"fuzzysort": "^3.0.0",
|
"fuzzysort": "^3.0.0",
|
||||||
"history": "^4.10.1",
|
"history": "^4.10.1",
|
||||||
"hoist-non-react-statics": "^3.3.2",
|
"hoist-non-react-statics": "^3.3.2",
|
||||||
|
@ -105,6 +106,7 @@
|
||||||
"redux-immutable": "^4.0.0",
|
"redux-immutable": "^4.0.0",
|
||||||
"regenerator-runtime": "^0.14.0",
|
"regenerator-runtime": "^0.14.0",
|
||||||
"requestidlecallback": "^0.3.0",
|
"requestidlecallback": "^0.3.0",
|
||||||
|
"rollup-plugin-gzip": "^4.1.1",
|
||||||
"rollup-plugin-visualizer": "^6.0.0",
|
"rollup-plugin-visualizer": "^6.0.0",
|
||||||
"sass": "^1.62.1",
|
"sass": "^1.62.1",
|
||||||
"stacktrace-js": "^2.0.2",
|
"stacktrace-js": "^2.0.2",
|
||||||
|
@ -115,9 +117,8 @@
|
||||||
"twitter-text": "3.1.0",
|
"twitter-text": "3.1.0",
|
||||||
"use-debounce": "^10.0.0",
|
"use-debounce": "^10.0.0",
|
||||||
"vite": "^6.3.5",
|
"vite": "^6.3.5",
|
||||||
|
"vite-plugin-manifest-sri": "^0.2.0",
|
||||||
"vite-plugin-pwa": "^1.0.0",
|
"vite-plugin-pwa": "^1.0.0",
|
||||||
"vite-plugin-rails": "^0.5.0",
|
|
||||||
"vite-plugin-ruby": "^5.1.1",
|
|
||||||
"vite-plugin-static-copy": "^3.1.0",
|
"vite-plugin-static-copy": "^3.1.0",
|
||||||
"vite-plugin-svgr": "^4.3.0",
|
"vite-plugin-svgr": "^4.3.0",
|
||||||
"vite-tsconfig-paths": "^5.1.4",
|
"vite-tsconfig-paths": "^5.1.4",
|
||||||
|
@ -187,15 +188,12 @@
|
||||||
"stylelint-config-standard-scss": "^15.0.1",
|
"stylelint-config-standard-scss": "^15.0.1",
|
||||||
"typescript": "~5.7.3",
|
"typescript": "~5.7.3",
|
||||||
"typescript-eslint": "^8.29.1",
|
"typescript-eslint": "^8.29.1",
|
||||||
"vite-plugin-rails": "^0.5.0",
|
|
||||||
"vite-plugin-svgr": "^4.2.0",
|
|
||||||
"vitest": "^3.2.1"
|
"vitest": "^3.2.1"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"@types/react": "^18.2.7",
|
"@types/react": "^18.2.7",
|
||||||
"@types/react-dom": "^18.2.4",
|
"@types/react-dom": "^18.2.4",
|
||||||
"kind-of": "^6.0.3",
|
"kind-of": "^6.0.3",
|
||||||
"vite-plugin-ruby": "^5.1.0",
|
|
||||||
"vite": "^6.3.5"
|
"vite": "^6.3.5"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
|
|
105
vite.config.mts
105
vite.config.mts
|
@ -1,19 +1,25 @@
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
|
import { readdir } from 'node:fs/promises';
|
||||||
|
|
||||||
import { optimizeLodashImports } from '@optimize-lodash/rollup-plugin';
|
import { optimizeLodashImports } from '@optimize-lodash/rollup-plugin';
|
||||||
import legacy from '@vitejs/plugin-legacy';
|
import legacy from '@vitejs/plugin-legacy';
|
||||||
import react from '@vitejs/plugin-react';
|
import react from '@vitejs/plugin-react';
|
||||||
import { PluginOption } from 'vite';
|
import glob from 'fast-glob';
|
||||||
|
import postcssPresetEnv from 'postcss-preset-env';
|
||||||
|
import Compress from 'rollup-plugin-gzip';
|
||||||
import { visualizer } from 'rollup-plugin-visualizer';
|
import { visualizer } from 'rollup-plugin-visualizer';
|
||||||
|
import {
|
||||||
|
PluginOption,
|
||||||
|
defineConfig,
|
||||||
|
UserConfigFnPromise,
|
||||||
|
UserConfig,
|
||||||
|
} from 'vite';
|
||||||
|
import manifestSRI from 'vite-plugin-manifest-sri';
|
||||||
import { VitePWA } from 'vite-plugin-pwa';
|
import { VitePWA } from 'vite-plugin-pwa';
|
||||||
import RailsPlugin from 'vite-plugin-rails';
|
|
||||||
import { viteStaticCopy } from 'vite-plugin-static-copy';
|
import { viteStaticCopy } from 'vite-plugin-static-copy';
|
||||||
import svgr from 'vite-plugin-svgr';
|
import svgr from 'vite-plugin-svgr';
|
||||||
import tsconfigPaths from 'vite-tsconfig-paths';
|
import tsconfigPaths from 'vite-tsconfig-paths';
|
||||||
|
|
||||||
import { defineConfig, UserConfigFnPromise, UserConfig } from 'vite';
|
|
||||||
import postcssPresetEnv from 'postcss-preset-env';
|
|
||||||
|
|
||||||
import { MastodonServiceWorkerLocales } from './config/vite/plugin-sw-locales';
|
import { MastodonServiceWorkerLocales } from './config/vite/plugin-sw-locales';
|
||||||
import { MastodonEmojiCompressed } from './config/vite/plugin-emoji-compressed';
|
import { MastodonEmojiCompressed } from './config/vite/plugin-emoji-compressed';
|
||||||
import { MastodonThemes } from './config/vite/plugin-mastodon-themes';
|
import { MastodonThemes } from './config/vite/plugin-mastodon-themes';
|
||||||
|
@ -22,8 +28,26 @@ import { MastodonNameLookup } from './config/vite/plugin-name-lookup';
|
||||||
const jsRoot = path.resolve(__dirname, 'app/javascript');
|
const jsRoot = path.resolve(__dirname, 'app/javascript');
|
||||||
|
|
||||||
export const config: UserConfigFnPromise = async ({ mode, command }) => {
|
export const config: UserConfigFnPromise = async ({ mode, command }) => {
|
||||||
|
const isProdBuild = mode === 'production' && command === 'build';
|
||||||
|
|
||||||
|
let outDirName = 'packs-dev';
|
||||||
|
if (mode === 'test') {
|
||||||
|
outDirName = 'packs-test';
|
||||||
|
} else if (mode === 'production') {
|
||||||
|
outDirName = 'packs';
|
||||||
|
}
|
||||||
|
const outDir = path.resolve('public', outDirName);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
root: jsRoot,
|
root: jsRoot,
|
||||||
|
base: `/${outDirName}/`,
|
||||||
|
envDir: __dirname,
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'~/': `${jsRoot}/`,
|
||||||
|
'@/': `${jsRoot}/`,
|
||||||
|
},
|
||||||
|
},
|
||||||
css: {
|
css: {
|
||||||
postcss: {
|
postcss: {
|
||||||
plugins: [
|
plugins: [
|
||||||
|
@ -41,12 +65,18 @@ export const config: UserConfigFnPromise = async ({ mode, command }) => {
|
||||||
// but it needs to be scoped to the whole domain
|
// but it needs to be scoped to the whole domain
|
||||||
'Service-Worker-Allowed': '/',
|
'Service-Worker-Allowed': '/',
|
||||||
},
|
},
|
||||||
|
port: 3036,
|
||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
commonjsOptions: { transformMixedEsModules: true },
|
commonjsOptions: { transformMixedEsModules: true },
|
||||||
chunkSizeWarningLimit: 1 * 1024 * 1024, // 1MB
|
chunkSizeWarningLimit: 1 * 1024 * 1024, // 1MB
|
||||||
sourcemap: true,
|
sourcemap: true,
|
||||||
|
emptyOutDir: mode !== 'production',
|
||||||
|
manifest: true,
|
||||||
|
outDir,
|
||||||
|
assetsDir: 'assets',
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
|
input: await findEntrypoints(),
|
||||||
output: {
|
output: {
|
||||||
chunkFileNames({ facadeModuleId, name }) {
|
chunkFileNames({ facadeModuleId, name }) {
|
||||||
if (!facadeModuleId) {
|
if (!facadeModuleId) {
|
||||||
|
@ -84,18 +114,12 @@ export const config: UserConfigFnPromise = async ({ mode, command }) => {
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
tsconfigPaths({ projects: [path.resolve(__dirname, 'tsconfig.json')] }),
|
tsconfigPaths({ projects: [path.resolve(__dirname, 'tsconfig.json')] }),
|
||||||
RailsPlugin({
|
|
||||||
compress: mode === 'production' && command === 'build',
|
|
||||||
sri: {
|
|
||||||
manifestPaths: ['.vite/manifest.json', '.vite/manifest-assets.json'],
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
MastodonThemes(),
|
|
||||||
react({
|
react({
|
||||||
babel: {
|
babel: {
|
||||||
plugins: ['formatjs', 'transform-react-remove-prop-types'],
|
plugins: ['formatjs', 'transform-react-remove-prop-types'],
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
MastodonThemes(),
|
||||||
viteStaticCopy({
|
viteStaticCopy({
|
||||||
targets: [
|
targets: [
|
||||||
{
|
{
|
||||||
|
@ -117,8 +141,13 @@ export const config: UserConfigFnPromise = async ({ mode, command }) => {
|
||||||
renderLegacyChunks: false,
|
renderLegacyChunks: false,
|
||||||
modernPolyfills: true,
|
modernPolyfills: true,
|
||||||
}),
|
}),
|
||||||
|
isProdBuild && (Compress() as PluginOption),
|
||||||
|
command === 'build' &&
|
||||||
|
manifestSRI({
|
||||||
|
manifestPaths: ['.vite/manifest.json', '.vite/manifest-assets.json'],
|
||||||
|
}),
|
||||||
VitePWA({
|
VitePWA({
|
||||||
srcDir: 'mastodon/service_worker',
|
srcDir: path.resolve(jsRoot, 'mastodon/service_worker'),
|
||||||
// We need to use injectManifest because we use our own service worker
|
// We need to use injectManifest because we use our own service worker
|
||||||
strategies: 'injectManifest',
|
strategies: 'injectManifest',
|
||||||
manifest: false,
|
manifest: false,
|
||||||
|
@ -150,4 +179,54 @@ export const config: UserConfigFnPromise = async ({ mode, command }) => {
|
||||||
} satisfies UserConfig;
|
} satisfies UserConfig;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
async function findEntrypoints() {
|
||||||
|
const entrypoints: Record<string, string> = {};
|
||||||
|
|
||||||
|
// First, JS entrypoints
|
||||||
|
const jsEntrypoints = await readdir(path.resolve(jsRoot, 'entrypoints'), {
|
||||||
|
withFileTypes: true,
|
||||||
|
});
|
||||||
|
const jsExtTest = /\.[jt]sx?$/;
|
||||||
|
for (const file of jsEntrypoints) {
|
||||||
|
if (file.isFile() && jsExtTest.test(file.name)) {
|
||||||
|
entrypoints[file.name.replace(jsExtTest, '')] = path.resolve(
|
||||||
|
file.parentPath,
|
||||||
|
file.name,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next, SCSS entrypoints
|
||||||
|
const scssEntrypoints = await readdir(
|
||||||
|
path.resolve(jsRoot, 'styles/entrypoints'),
|
||||||
|
{ withFileTypes: true },
|
||||||
|
);
|
||||||
|
const scssExtTest = /\.s?css$/;
|
||||||
|
for (const file of scssEntrypoints) {
|
||||||
|
if (file.isFile() && scssExtTest.test(file.name)) {
|
||||||
|
entrypoints[file.name.replace(scssExtTest, '')] = path.resolve(
|
||||||
|
file.parentPath,
|
||||||
|
file.name,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lastly other assets
|
||||||
|
const assetEntrypoints = await glob('{fonts,icons,images}/**/*', {
|
||||||
|
cwd: jsRoot,
|
||||||
|
absolute: true,
|
||||||
|
});
|
||||||
|
const excludeExts = ['', '.md'];
|
||||||
|
for (const file of assetEntrypoints) {
|
||||||
|
const ext = path.extname(file);
|
||||||
|
if (excludeExts.includes(ext)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const name = path.basename(file);
|
||||||
|
entrypoints[name] = path.resolve(jsRoot, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
return entrypoints;
|
||||||
|
}
|
||||||
|
|
||||||
export default defineConfig(config);
|
export default defineConfig(config);
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
import { resolve } from 'node:path';
|
import { resolve } from 'node:path';
|
||||||
|
|
||||||
import { storybookTest } from '@storybook/addon-vitest/vitest-plugin';
|
import { storybookTest } from '@storybook/addon-vitest/vitest-plugin';
|
||||||
import react from '@vitejs/plugin-react';
|
|
||||||
import svgr from 'vite-plugin-svgr';
|
|
||||||
import tsconfigPaths from 'vite-tsconfig-paths';
|
|
||||||
import {
|
import {
|
||||||
configDefaults,
|
configDefaults,
|
||||||
defineConfig,
|
defineConfig,
|
||||||
|
@ -13,15 +10,13 @@ import {
|
||||||
import { config as viteConfig } from './vite.config.mjs';
|
import { config as viteConfig } from './vite.config.mjs';
|
||||||
|
|
||||||
const storybookTests: TestProjectInlineConfiguration = {
|
const storybookTests: TestProjectInlineConfiguration = {
|
||||||
|
extends: true,
|
||||||
plugins: [
|
plugins: [
|
||||||
// See options at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon#storybooktest
|
// See options at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon#storybooktest
|
||||||
storybookTest({
|
storybookTest({
|
||||||
configDir: '.storybook',
|
configDir: '.storybook',
|
||||||
storybookScript: 'yarn run storybook',
|
storybookScript: 'yarn run storybook',
|
||||||
}),
|
}),
|
||||||
react(),
|
|
||||||
svgr(),
|
|
||||||
tsconfigPaths(),
|
|
||||||
],
|
],
|
||||||
test: {
|
test: {
|
||||||
name: 'storybook',
|
name: 'storybook',
|
||||||
|
|
113
yarn.lock
113
yarn.lock
|
@ -2680,6 +2680,7 @@ __metadata:
|
||||||
eslint-plugin-react: "npm:^7.37.4"
|
eslint-plugin-react: "npm:^7.37.4"
|
||||||
eslint-plugin-react-hooks: "npm:^5.2.0"
|
eslint-plugin-react-hooks: "npm:^5.2.0"
|
||||||
eslint-plugin-storybook: "npm:^9.0.4"
|
eslint-plugin-storybook: "npm:^9.0.4"
|
||||||
|
fast-glob: "npm:^3.3.3"
|
||||||
fuzzysort: "npm:^3.0.0"
|
fuzzysort: "npm:^3.0.0"
|
||||||
globals: "npm:^16.0.0"
|
globals: "npm:^16.0.0"
|
||||||
history: "npm:^4.10.1"
|
history: "npm:^4.10.1"
|
||||||
|
@ -2724,6 +2725,7 @@ __metadata:
|
||||||
redux-immutable: "npm:^4.0.0"
|
redux-immutable: "npm:^4.0.0"
|
||||||
regenerator-runtime: "npm:^0.14.0"
|
regenerator-runtime: "npm:^0.14.0"
|
||||||
requestidlecallback: "npm:^0.3.0"
|
requestidlecallback: "npm:^0.3.0"
|
||||||
|
rollup-plugin-gzip: "npm:^4.1.1"
|
||||||
rollup-plugin-visualizer: "npm:^6.0.0"
|
rollup-plugin-visualizer: "npm:^6.0.0"
|
||||||
sass: "npm:^1.62.1"
|
sass: "npm:^1.62.1"
|
||||||
stacktrace-js: "npm:^2.0.2"
|
stacktrace-js: "npm:^2.0.2"
|
||||||
|
@ -2740,11 +2742,10 @@ __metadata:
|
||||||
typescript-eslint: "npm:^8.29.1"
|
typescript-eslint: "npm:^8.29.1"
|
||||||
use-debounce: "npm:^10.0.0"
|
use-debounce: "npm:^10.0.0"
|
||||||
vite: "npm:^6.3.5"
|
vite: "npm:^6.3.5"
|
||||||
|
vite-plugin-manifest-sri: "npm:^0.2.0"
|
||||||
vite-plugin-pwa: "npm:^1.0.0"
|
vite-plugin-pwa: "npm:^1.0.0"
|
||||||
vite-plugin-rails: "npm:^0.5.0"
|
|
||||||
vite-plugin-ruby: "npm:^5.1.1"
|
|
||||||
vite-plugin-static-copy: "npm:^3.1.0"
|
vite-plugin-static-copy: "npm:^3.1.0"
|
||||||
vite-plugin-svgr: "npm:^4.2.0"
|
vite-plugin-svgr: "npm:^4.3.0"
|
||||||
vite-tsconfig-paths: "npm:^5.1.4"
|
vite-tsconfig-paths: "npm:^5.1.4"
|
||||||
vitest: "npm:^3.2.1"
|
vitest: "npm:^3.2.1"
|
||||||
wicg-inert: "npm:^3.1.2"
|
wicg-inert: "npm:^3.1.2"
|
||||||
|
@ -3298,7 +3299,7 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@rollup/pluginutils@npm:^5.0.1, @rollup/pluginutils@npm:^5.0.2, @rollup/pluginutils@npm:^5.0.5, @rollup/pluginutils@npm:^5.1.0":
|
"@rollup/pluginutils@npm:^5.0.1, @rollup/pluginutils@npm:^5.0.2, @rollup/pluginutils@npm:^5.1.0":
|
||||||
version: 5.1.4
|
version: 5.1.4
|
||||||
resolution: "@rollup/pluginutils@npm:5.1.4"
|
resolution: "@rollup/pluginutils@npm:5.1.4"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -3314,6 +3315,22 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@rollup/pluginutils@npm:^5.1.3":
|
||||||
|
version: 5.2.0
|
||||||
|
resolution: "@rollup/pluginutils@npm:5.2.0"
|
||||||
|
dependencies:
|
||||||
|
"@types/estree": "npm:^1.0.0"
|
||||||
|
estree-walker: "npm:^2.0.2"
|
||||||
|
picomatch: "npm:^4.0.2"
|
||||||
|
peerDependencies:
|
||||||
|
rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
rollup:
|
||||||
|
optional: true
|
||||||
|
checksum: 10c0/794890d512751451bcc06aa112366ef47ea8f9125dac49b1abf72ff8b079518b09359de9c60a013b33266541634e765ae61839c749fae0edb59a463418665c55
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@rollup/rollup-android-arm-eabi@npm:4.40.2":
|
"@rollup/rollup-android-arm-eabi@npm:4.40.2":
|
||||||
version: 4.40.2
|
version: 4.40.2
|
||||||
resolution: "@rollup/rollup-android-arm-eabi@npm:4.40.2"
|
resolution: "@rollup/rollup-android-arm-eabi@npm:4.40.2"
|
||||||
|
@ -6281,7 +6298,7 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.6, debug@npm:^4.3.7, debug@npm:^4.4.0, debug@npm:^4.4.1":
|
"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.6, debug@npm:^4.3.7, debug@npm:^4.4.0, debug@npm:^4.4.1":
|
||||||
version: 4.4.1
|
version: 4.4.1
|
||||||
resolution: "debug@npm:4.4.1"
|
resolution: "debug@npm:4.4.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -10223,7 +10240,7 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"picocolors@npm:^1.0.0, picocolors@npm:^1.1.1":
|
"picocolors@npm:^1.1.1":
|
||||||
version: 1.1.1
|
version: 1.1.1
|
||||||
resolution: "picocolors@npm:1.1.1"
|
resolution: "picocolors@npm:1.1.1"
|
||||||
checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58
|
checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58
|
||||||
|
@ -11800,12 +11817,12 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"rollup-plugin-gzip@npm:^3.1.0":
|
"rollup-plugin-gzip@npm:^4.1.1":
|
||||||
version: 3.1.2
|
version: 4.1.1
|
||||||
resolution: "rollup-plugin-gzip@npm:3.1.2"
|
resolution: "rollup-plugin-gzip@npm:4.1.1"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
rollup: ">=2.0.0"
|
rollup: ">=2.0.0"
|
||||||
checksum: 10c0/5129d3970cca37bfb5a2fdeddb863bc76be12489ec0a6fcb2be2764902aa2f8548eb8e6532c4e15912d95e8baaa7391a5ed6b58790ed2529c86a98fa75467edc
|
checksum: 10c0/0ad79a6eb84bb8d88db15a184ca661f44aa6fb3412c98d6a97f1dec365db37945a84c3a2d0bf709ae605ae305a40a0021b2e6d5494c537b029759f3695d9ac96
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -12536,13 +12553,6 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"stimulus-vite-helpers@npm:^3.0.0":
|
|
||||||
version: 3.1.0
|
|
||||||
resolution: "stimulus-vite-helpers@npm:3.1.0"
|
|
||||||
checksum: 10c0/828252f43b238191d71b7b4d2048b7df9845c789963a0a23ea0979941e55ad0e14d2b98646eba328e9f4432cf0c0c8340830c5cde1fc9046077c6f1109b4a671
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"storybook@npm:^9.0.4":
|
"storybook@npm:^9.0.4":
|
||||||
version: 9.0.4
|
version: 9.0.4
|
||||||
resolution: "storybook@npm:9.0.4"
|
resolution: "storybook@npm:9.0.4"
|
||||||
|
@ -13828,25 +13838,6 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"vite-plugin-environment@npm:^1.1.3":
|
|
||||||
version: 1.1.3
|
|
||||||
resolution: "vite-plugin-environment@npm:1.1.3"
|
|
||||||
peerDependencies:
|
|
||||||
vite: ">= 2.7"
|
|
||||||
checksum: 10c0/225986450220bdc6b109be4d05deeb94013d41cc235fe3064bd6c5a1b33c047ba59cac3a34aa240ae735fee6a77ab9ce033053c5ab7c152497bd7136bd3f3a6d
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"vite-plugin-full-reload@npm:^1.1.0":
|
|
||||||
version: 1.1.0
|
|
||||||
resolution: "vite-plugin-full-reload@npm:1.1.0"
|
|
||||||
dependencies:
|
|
||||||
picocolors: "npm:^1.0.0"
|
|
||||||
picomatch: "npm:^2.3.1"
|
|
||||||
checksum: 10c0/f33ccb4c58051e43b7d261d60f0078c0e28c49631dd86218cfa1902e0a61f038d1f6839f64a4fb95da0445720612d75656eb9b3d13c8b50d336e2548251c54b8
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"vite-plugin-manifest-sri@npm:^0.2.0":
|
"vite-plugin-manifest-sri@npm:^0.2.0":
|
||||||
version: 0.2.0
|
version: 0.2.0
|
||||||
resolution: "vite-plugin-manifest-sri@npm:0.2.0"
|
resolution: "vite-plugin-manifest-sri@npm:0.2.0"
|
||||||
|
@ -13875,34 +13866,6 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"vite-plugin-rails@npm:^0.5.0":
|
|
||||||
version: 0.5.0
|
|
||||||
resolution: "vite-plugin-rails@npm:0.5.0"
|
|
||||||
dependencies:
|
|
||||||
rollup-plugin-gzip: "npm:^3.1.0"
|
|
||||||
vite-plugin-environment: "npm:^1.1.3"
|
|
||||||
vite-plugin-full-reload: "npm:^1.1.0"
|
|
||||||
vite-plugin-manifest-sri: "npm:^0.2.0"
|
|
||||||
vite-plugin-ruby: "npm:^5.0.0"
|
|
||||||
vite-plugin-stimulus-hmr: "npm:^3.0.0"
|
|
||||||
peerDependencies:
|
|
||||||
vite: ">=5.0.0"
|
|
||||||
checksum: 10c0/c1648e87326527ed92339d10f46b7745849a4b1374ed3581410cbd43d9f3ab7aaf4a9285644d2c70a206d8b8330b5949ad69fbe2a2f616b8d8dbec447d75c366
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"vite-plugin-ruby@npm:^5.1.0":
|
|
||||||
version: 5.1.1
|
|
||||||
resolution: "vite-plugin-ruby@npm:5.1.1"
|
|
||||||
dependencies:
|
|
||||||
debug: "npm:^4.3.4"
|
|
||||||
fast-glob: "npm:^3.3.2"
|
|
||||||
peerDependencies:
|
|
||||||
vite: ">=5.0.0"
|
|
||||||
checksum: 10c0/c14230fef77eb8890897ac71dc56637d49dae8fe5bdb16dcb8fb0d7b7ca068ed30f61940b4ebb0906d03068555156237a84550ec227acde133573078114067ee
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"vite-plugin-static-copy@npm:^3.1.0":
|
"vite-plugin-static-copy@npm:^3.1.0":
|
||||||
version: 3.1.1
|
version: 3.1.1
|
||||||
resolution: "vite-plugin-static-copy@npm:3.1.1"
|
resolution: "vite-plugin-static-copy@npm:3.1.1"
|
||||||
|
@ -13918,26 +13881,16 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"vite-plugin-stimulus-hmr@npm:^3.0.0":
|
"vite-plugin-svgr@npm:^4.3.0":
|
||||||
version: 3.0.0
|
version: 4.3.0
|
||||||
resolution: "vite-plugin-stimulus-hmr@npm:3.0.0"
|
resolution: "vite-plugin-svgr@npm:4.3.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: "npm:^4.3"
|
"@rollup/pluginutils": "npm:^5.1.3"
|
||||||
stimulus-vite-helpers: "npm:^3.0.0"
|
|
||||||
checksum: 10c0/964e9713a7402cac0b8a868d7075a35a4a5502ffd11d227aa869da85ab07345af6fc725316bcaf241108076acc0151532f8b3fad6a32225bb279a99e383a2a0c
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"vite-plugin-svgr@npm:^4.2.0":
|
|
||||||
version: 4.2.0
|
|
||||||
resolution: "vite-plugin-svgr@npm:4.2.0"
|
|
||||||
dependencies:
|
|
||||||
"@rollup/pluginutils": "npm:^5.0.5"
|
|
||||||
"@svgr/core": "npm:^8.1.0"
|
"@svgr/core": "npm:^8.1.0"
|
||||||
"@svgr/plugin-jsx": "npm:^8.1.0"
|
"@svgr/plugin-jsx": "npm:^8.1.0"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
vite: ^2.6.0 || 3 || 4 || 5
|
vite: ">=2.6.0"
|
||||||
checksum: 10c0/0a6400f20905f53d08f1ce7d1f22d9a57db403e110e790f80c2e0411a0064a071a36b781f56f6823654f98052219171003f9ea023d4a31d930b4a4fc01776d1f
|
checksum: 10c0/a73f10d319f72cd8c16bf9701cf18170f2300f98c72c6bf939565de0b1e93916bd70c6f5a446dc034b4405c72d382655c7c16be4bd1cbf35bbcde5febf7aeffc
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user