Merge commit '1b664cf20dbb696cf16a42efcf59ab186cb211eb' into glitch-soc/merge-upstream
This commit is contained in:
commit
6fc9febb47
@ -1,6 +1,6 @@
|
|||||||
# This configuration was generated by
|
# This configuration was generated by
|
||||||
# `rubocop --auto-gen-config --auto-gen-only-exclude --no-offense-counts --no-auto-gen-timestamp`
|
# `rubocop --auto-gen-config --auto-gen-only-exclude --no-offense-counts --no-auto-gen-timestamp`
|
||||||
# using RuboCop version 1.79.2.
|
# using RuboCop version 1.80.2.
|
||||||
# The point is for the user to remove these configuration records
|
# The point is for the user to remove these configuration records
|
||||||
# one by one as the offenses are removed from the code base.
|
# one by one as the offenses are removed from the code base.
|
||||||
# Note that changes in the inspected code, or installation of new
|
# Note that changes in the inspected code, or installation of new
|
||||||
|
|||||||
@ -12,13 +12,14 @@ import { initialize, mswLoader } from 'msw-storybook-addon';
|
|||||||
import { action } from 'storybook/actions';
|
import { action } from 'storybook/actions';
|
||||||
|
|
||||||
import type { LocaleData } from '@/mastodon/locales';
|
import type { LocaleData } from '@/mastodon/locales';
|
||||||
import { reducerWithInitialState, rootReducer } from '@/mastodon/reducers';
|
import { reducerWithInitialState } from '@/mastodon/reducers';
|
||||||
import { defaultMiddleware } from '@/mastodon/store/store';
|
import { defaultMiddleware } from '@/mastodon/store/store';
|
||||||
import { mockHandlers, unhandledRequestHandler } from '@/testing/api';
|
import { mockHandlers, unhandledRequestHandler } from '@/testing/api';
|
||||||
|
|
||||||
// If you want to run the dark theme during development,
|
// If you want to run the dark theme during development,
|
||||||
// you can change the below to `/application.scss`
|
// you can change the below to `/application.scss`
|
||||||
import '../app/javascript/styles/mastodon-light.scss';
|
import '../app/javascript/styles/mastodon-light.scss';
|
||||||
|
import './styles.css';
|
||||||
|
|
||||||
const localeFiles = import.meta.glob('@/mastodon/locales/*.json', {
|
const localeFiles = import.meta.glob('@/mastodon/locales/*.json', {
|
||||||
query: { as: 'json' },
|
query: { as: 'json' },
|
||||||
@ -49,12 +50,17 @@ const preview: Preview = {
|
|||||||
locale: 'en',
|
locale: 'en',
|
||||||
},
|
},
|
||||||
decorators: [
|
decorators: [
|
||||||
(Story, { parameters }) => {
|
(Story, { parameters, globals }) => {
|
||||||
|
const { locale } = globals as { locale: string };
|
||||||
const { state = {} } = parameters;
|
const { state = {} } = parameters;
|
||||||
let reducer = rootReducer;
|
const reducer = reducerWithInitialState(
|
||||||
if (typeof state === 'object' && state) {
|
{
|
||||||
reducer = reducerWithInitialState(state as Record<string, unknown>);
|
meta: {
|
||||||
}
|
locale,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
state as Record<string, unknown>,
|
||||||
|
);
|
||||||
const store = configureStore({
|
const store = configureStore({
|
||||||
reducer,
|
reducer,
|
||||||
middleware(getDefaultMiddleware) {
|
middleware(getDefaultMiddleware) {
|
||||||
|
|||||||
8
.storybook/styles.css
Normal file
8
.storybook/styles.css
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
@ -771,7 +771,7 @@ GEM
|
|||||||
rspec-mocks (~> 3.0)
|
rspec-mocks (~> 3.0)
|
||||||
sidekiq (>= 5, < 9)
|
sidekiq (>= 5, < 9)
|
||||||
rspec-support (3.13.4)
|
rspec-support (3.13.4)
|
||||||
rubocop (1.79.2)
|
rubocop (1.80.2)
|
||||||
json (~> 2.3)
|
json (~> 2.3)
|
||||||
language_server-protocol (~> 3.17.0.2)
|
language_server-protocol (~> 3.17.0.2)
|
||||||
lint_roller (~> 1.1.0)
|
lint_roller (~> 1.1.0)
|
||||||
@ -801,7 +801,7 @@ GEM
|
|||||||
rack (>= 1.1)
|
rack (>= 1.1)
|
||||||
rubocop (>= 1.75.0, < 2.0)
|
rubocop (>= 1.75.0, < 2.0)
|
||||||
rubocop-ast (>= 1.44.0, < 2.0)
|
rubocop-ast (>= 1.44.0, < 2.0)
|
||||||
rubocop-rspec (3.6.0)
|
rubocop-rspec (3.7.0)
|
||||||
lint_roller (~> 1.1)
|
lint_roller (~> 1.1)
|
||||||
rubocop (~> 1.72, >= 1.72.1)
|
rubocop (~> 1.72, >= 1.72.1)
|
||||||
rubocop-rspec_rails (2.31.0)
|
rubocop-rspec_rails (2.31.0)
|
||||||
@ -903,7 +903,7 @@ GEM
|
|||||||
unf (0.1.4)
|
unf (0.1.4)
|
||||||
unf_ext
|
unf_ext
|
||||||
unf_ext (0.0.9.1)
|
unf_ext (0.0.9.1)
|
||||||
unicode-display_width (3.1.4)
|
unicode-display_width (3.1.5)
|
||||||
unicode-emoji (~> 4.0, >= 4.0.4)
|
unicode-emoji (~> 4.0, >= 4.0.4)
|
||||||
unicode-emoji (4.0.4)
|
unicode-emoji (4.0.4)
|
||||||
uri (1.0.3)
|
uri (1.0.3)
|
||||||
|
|||||||
@ -49,8 +49,8 @@ module Admin
|
|||||||
|
|
||||||
def export_data
|
def export_data
|
||||||
CSV.generate(headers: export_headers, write_headers: true) do |content|
|
CSV.generate(headers: export_headers, write_headers: true) do |content|
|
||||||
DomainAllow.allowed_domains.each do |instance|
|
DomainAllow.allowed_domains.each do |domain|
|
||||||
content << [instance.domain]
|
content << [domain]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -13,9 +13,9 @@ import { useSelectableClick } from 'mastodon/hooks/useSelectableClick';
|
|||||||
const offset = [0, 4] as OffsetValue;
|
const offset = [0, 4] as OffsetValue;
|
||||||
const popperConfig = { strategy: 'fixed' } as UsePopperOptions;
|
const popperConfig = { strategy: 'fixed' } as UsePopperOptions;
|
||||||
|
|
||||||
export const AltTextBadge: React.FC<{
|
export const AltTextBadge: React.FC<{ description: string }> = ({
|
||||||
description: string;
|
description,
|
||||||
}> = ({ description }) => {
|
}) => {
|
||||||
const accessibilityId = useId();
|
const accessibilityId = useId();
|
||||||
const anchorRef = useRef<HTMLButtonElement>(null);
|
const anchorRef = useRef<HTMLButtonElement>(null);
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
@ -56,7 +56,7 @@ export const AltTextBadge: React.FC<{
|
|||||||
{({ props }) => (
|
{({ props }) => (
|
||||||
<div {...props} className='hover-card-controller'>
|
<div {...props} className='hover-card-controller'>
|
||||||
<div // eslint-disable-line jsx-a11y/no-noninteractive-element-interactions
|
<div // eslint-disable-line jsx-a11y/no-noninteractive-element-interactions
|
||||||
className='media-gallery__alt__popover dropdown-animation'
|
className='info-tooltip dropdown-animation'
|
||||||
role='region'
|
role='region'
|
||||||
id={accessibilityId}
|
id={accessibilityId}
|
||||||
onMouseDown={handleMouseDown}
|
onMouseDown={handleMouseDown}
|
||||||
|
|||||||
@ -8,6 +8,7 @@ const meta = {
|
|||||||
component: Button,
|
component: Button,
|
||||||
args: {
|
args: {
|
||||||
secondary: false,
|
secondary: false,
|
||||||
|
plain: false,
|
||||||
compact: false,
|
compact: false,
|
||||||
dangerous: false,
|
dangerous: false,
|
||||||
disabled: false,
|
disabled: false,
|
||||||
@ -57,6 +58,14 @@ export const Secondary: Story = {
|
|||||||
play: buttonTest,
|
play: buttonTest,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const Plain: Story = {
|
||||||
|
args: {
|
||||||
|
plain: true,
|
||||||
|
children: 'Plain button',
|
||||||
|
},
|
||||||
|
play: buttonTest,
|
||||||
|
};
|
||||||
|
|
||||||
export const Compact: Story = {
|
export const Compact: Story = {
|
||||||
args: {
|
args: {
|
||||||
compact: true,
|
compact: true,
|
||||||
@ -101,6 +110,14 @@ export const SecondaryDisabled: Story = {
|
|||||||
play: disabledButtonTest,
|
play: disabledButtonTest,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const PlainDisabled: Story = {
|
||||||
|
args: {
|
||||||
|
...Plain.args,
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
play: disabledButtonTest,
|
||||||
|
};
|
||||||
|
|
||||||
const loadingButtonTest: Story['play'] = async ({
|
const loadingButtonTest: Story['play'] = async ({
|
||||||
args,
|
args,
|
||||||
canvas,
|
canvas,
|
||||||
|
|||||||
@ -9,6 +9,7 @@ interface BaseProps
|
|||||||
extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {
|
extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {
|
||||||
block?: boolean;
|
block?: boolean;
|
||||||
secondary?: boolean;
|
secondary?: boolean;
|
||||||
|
plain?: boolean;
|
||||||
compact?: boolean;
|
compact?: boolean;
|
||||||
dangerous?: boolean;
|
dangerous?: boolean;
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
@ -35,6 +36,7 @@ export const Button: React.FC<Props> = ({
|
|||||||
disabled,
|
disabled,
|
||||||
block,
|
block,
|
||||||
secondary,
|
secondary,
|
||||||
|
plain,
|
||||||
compact,
|
compact,
|
||||||
dangerous,
|
dangerous,
|
||||||
loading,
|
loading,
|
||||||
@ -62,6 +64,7 @@ export const Button: React.FC<Props> = ({
|
|||||||
<button
|
<button
|
||||||
className={classNames('button', className, {
|
className={classNames('button', className, {
|
||||||
'button-secondary': secondary,
|
'button-secondary': secondary,
|
||||||
|
'button--plain': plain,
|
||||||
'button--compact': compact,
|
'button--compact': compact,
|
||||||
'button--block': block,
|
'button--block': block,
|
||||||
'button--dangerous': dangerous,
|
'button--dangerous': dangerous,
|
||||||
|
|||||||
@ -1,8 +1,3 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unsafe-call,
|
|
||||||
@typescript-eslint/no-unsafe-return,
|
|
||||||
@typescript-eslint/no-unsafe-assignment,
|
|
||||||
@typescript-eslint/no-unsafe-member-access
|
|
||||||
-- the settings store is not yet typed */
|
|
||||||
import type { PropsWithChildren } from 'react';
|
import type { PropsWithChildren } from 'react';
|
||||||
import { useCallback, useState, useEffect } from 'react';
|
import { useCallback, useState, useEffect } from 'react';
|
||||||
|
|
||||||
@ -23,31 +18,48 @@ interface Props {
|
|||||||
id: string;
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DismissableBanner: React.FC<PropsWithChildren<Props>> = ({
|
export function useDismissableBannerState({ id }: Props) {
|
||||||
id,
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
children,
|
const dismissed: boolean = useAppSelector((state) =>
|
||||||
}) => {
|
/* eslint-disable-next-line */
|
||||||
const dismissed = useAppSelector((state) =>
|
|
||||||
state.settings.getIn(['dismissed_banners', id], false),
|
state.settings.getIn(['dismissed_banners', id], false),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [isVisible, setIsVisible] = useState(
|
||||||
|
!bannerSettings.get(id) && !dismissed,
|
||||||
|
);
|
||||||
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const [visible, setVisible] = useState(!bannerSettings.get(id) && !dismissed);
|
const dismiss = useCallback(() => {
|
||||||
const intl = useIntl();
|
setIsVisible(false);
|
||||||
|
|
||||||
const handleDismiss = useCallback(() => {
|
|
||||||
setVisible(false);
|
|
||||||
bannerSettings.set(id, true);
|
bannerSettings.set(id, true);
|
||||||
dispatch(changeSetting(['dismissed_banners', id], true));
|
dispatch(changeSetting(['dismissed_banners', id], true));
|
||||||
}, [id, dispatch]);
|
}, [id, dispatch]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!visible && !dismissed) {
|
// Store legacy localStorage setting on server
|
||||||
|
if (!isVisible && !dismissed) {
|
||||||
dispatch(changeSetting(['dismissed_banners', id], true));
|
dispatch(changeSetting(['dismissed_banners', id], true));
|
||||||
}
|
}
|
||||||
}, [id, dispatch, visible, dismissed]);
|
}, [id, dispatch, isVisible, dismissed]);
|
||||||
|
|
||||||
if (!visible) {
|
return {
|
||||||
|
isVisible,
|
||||||
|
dismiss,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DismissableBanner: React.FC<PropsWithChildren<Props>> = ({
|
||||||
|
id,
|
||||||
|
children,
|
||||||
|
}) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
const { isVisible, dismiss } = useDismissableBannerState({
|
||||||
|
id,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!isVisible) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +70,7 @@ export const DismissableBanner: React.FC<PropsWithChildren<Props>> = ({
|
|||||||
icon='times'
|
icon='times'
|
||||||
iconComponent={CloseIcon}
|
iconComponent={CloseIcon}
|
||||||
title={intl.formatMessage(messages.dismiss)}
|
title={intl.formatMessage(messages.dismiss)}
|
||||||
onClick={handleDismiss}
|
onClick={dismiss}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,81 @@
|
|||||||
|
import type { ComponentProps } from 'react';
|
||||||
|
|
||||||
|
import type { Meta, StoryObj } from '@storybook/react-vite';
|
||||||
|
|
||||||
|
import { accountFactoryState } from '@/testing/factories';
|
||||||
|
|
||||||
|
import { DisplayName, LinkedDisplayName } from './index';
|
||||||
|
|
||||||
|
type PageProps = Omit<ComponentProps<typeof DisplayName>, 'account'> & {
|
||||||
|
name: string;
|
||||||
|
username: string;
|
||||||
|
loading: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const meta = {
|
||||||
|
title: 'Components/DisplayName',
|
||||||
|
args: {
|
||||||
|
username: 'mastodon@mastodon.social',
|
||||||
|
name: 'Test User 🧪',
|
||||||
|
loading: false,
|
||||||
|
simple: false,
|
||||||
|
noDomain: false,
|
||||||
|
localDomain: 'mastodon.social',
|
||||||
|
},
|
||||||
|
tags: [],
|
||||||
|
render({ name, username, loading, ...args }) {
|
||||||
|
const account = !loading
|
||||||
|
? accountFactoryState({
|
||||||
|
display_name: name,
|
||||||
|
acct: username,
|
||||||
|
})
|
||||||
|
: undefined;
|
||||||
|
return <DisplayName {...args} account={account} />;
|
||||||
|
},
|
||||||
|
} satisfies Meta<PageProps>;
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
|
||||||
|
type Story = StoryObj<typeof meta>;
|
||||||
|
|
||||||
|
export const Primary: Story = {
|
||||||
|
args: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Loading: Story = {
|
||||||
|
args: {
|
||||||
|
loading: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const NoDomain: Story = {
|
||||||
|
args: {
|
||||||
|
noDomain: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Simple: Story = {
|
||||||
|
args: {
|
||||||
|
simple: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const LocalUser: Story = {
|
||||||
|
args: {
|
||||||
|
username: 'localuser',
|
||||||
|
name: 'Local User',
|
||||||
|
localDomain: '',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Linked: Story = {
|
||||||
|
render({ name, username, loading, ...args }) {
|
||||||
|
const account = !loading
|
||||||
|
? accountFactoryState({
|
||||||
|
display_name: name,
|
||||||
|
acct: username,
|
||||||
|
})
|
||||||
|
: undefined;
|
||||||
|
return <LinkedDisplayName {...args} account={account} />;
|
||||||
|
},
|
||||||
|
};
|
||||||
122
app/javascript/mastodon/components/display_name/index.tsx
Normal file
122
app/javascript/mastodon/components/display_name/index.tsx
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
import type { ComponentPropsWithoutRef, FC } from 'react';
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import type { LinkProps } from 'react-router-dom';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { EmojiHTML } from '@/mastodon/features/emoji/emoji_html';
|
||||||
|
import type { Account } from '@/mastodon/models/account';
|
||||||
|
import { isModernEmojiEnabled } from '@/mastodon/utils/environment';
|
||||||
|
|
||||||
|
import { Skeleton } from '../skeleton';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
account?: Account;
|
||||||
|
localDomain?: string;
|
||||||
|
simple?: boolean;
|
||||||
|
noDomain?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DisplayName: FC<Props & ComponentPropsWithoutRef<'span'>> = ({
|
||||||
|
account,
|
||||||
|
localDomain,
|
||||||
|
simple = false,
|
||||||
|
noDomain = false,
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}) => {
|
||||||
|
const username = useMemo(() => {
|
||||||
|
if (!account || noDomain) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
let acct = account.get('acct');
|
||||||
|
|
||||||
|
if (!acct.includes('@') && localDomain) {
|
||||||
|
acct = `${acct}@${localDomain}`;
|
||||||
|
}
|
||||||
|
return `@${acct}`;
|
||||||
|
}, [account, localDomain, noDomain]);
|
||||||
|
|
||||||
|
if (!account) {
|
||||||
|
if (simple) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<span {...props} className={classNames('display-name', className)}>
|
||||||
|
<bdi>
|
||||||
|
<strong className='display-name__html'>
|
||||||
|
<Skeleton width='10ch' />
|
||||||
|
</strong>
|
||||||
|
</bdi>
|
||||||
|
{!noDomain && (
|
||||||
|
<span className='display-name__account'>
|
||||||
|
|
||||||
|
<Skeleton width='7ch' />
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const accountName = isModernEmojiEnabled()
|
||||||
|
? account.get('display_name')
|
||||||
|
: account.get('display_name_html');
|
||||||
|
if (simple) {
|
||||||
|
return (
|
||||||
|
<bdi>
|
||||||
|
<EmojiHTML {...props} htmlString={accountName} shallow as='span' />
|
||||||
|
</bdi>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span {...props} className={classNames('display-name', className)}>
|
||||||
|
<bdi>
|
||||||
|
<EmojiHTML
|
||||||
|
className='display-name__html'
|
||||||
|
htmlString={accountName}
|
||||||
|
shallow
|
||||||
|
as='strong'
|
||||||
|
/>
|
||||||
|
</bdi>
|
||||||
|
{username && (
|
||||||
|
<span className='display-name__account'> {username}</span>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const LinkedDisplayName: FC<
|
||||||
|
Props & { asProps?: ComponentPropsWithoutRef<'span'> } & Partial<LinkProps>
|
||||||
|
> = ({
|
||||||
|
account,
|
||||||
|
asProps = {},
|
||||||
|
className,
|
||||||
|
localDomain,
|
||||||
|
simple,
|
||||||
|
noDomain,
|
||||||
|
...linkProps
|
||||||
|
}) => {
|
||||||
|
const displayProps = {
|
||||||
|
account,
|
||||||
|
className,
|
||||||
|
localDomain,
|
||||||
|
simple,
|
||||||
|
noDomain,
|
||||||
|
...asProps,
|
||||||
|
};
|
||||||
|
if (!account) {
|
||||||
|
return <DisplayName {...displayProps} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Link
|
||||||
|
to={`/@${account.acct}`}
|
||||||
|
title={`@${account.acct}`}
|
||||||
|
data-hover-card-account={account.id}
|
||||||
|
{...linkProps}
|
||||||
|
>
|
||||||
|
<DisplayName {...displayProps} />
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -69,7 +69,7 @@ const messages = defineMessages({
|
|||||||
},
|
},
|
||||||
reblog_private: {
|
reblog_private: {
|
||||||
id: 'status.reblog_private',
|
id: 'status.reblog_private',
|
||||||
defaultMessage: 'Boost with original visibility',
|
defaultMessage: 'Share again with your followers',
|
||||||
},
|
},
|
||||||
reblog_cannot: {
|
reblog_cannot: {
|
||||||
id: 'status.cannot_reblog',
|
id: 'status.cannot_reblog',
|
||||||
|
|||||||
@ -20,11 +20,12 @@ import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'mastodon/
|
|||||||
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
|
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
|
||||||
|
|
||||||
import { Dropdown } from 'mastodon/components/dropdown_menu';
|
import { Dropdown } from 'mastodon/components/dropdown_menu';
|
||||||
import { me } from '../initial_state';
|
import { me } from '../../initial_state';
|
||||||
|
|
||||||
import { IconButton } from './icon_button';
|
import { IconButton } from '../icon_button';
|
||||||
import { isFeatureEnabled } from '../utils/environment';
|
import { isFeatureEnabled } from '../../utils/environment';
|
||||||
import { ReblogButton } from './status/reblog_button';
|
import { ReblogButton } from '../status/reblog_button';
|
||||||
|
import { RemoveQuoteHint } from './remove_quote_hint';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
delete: { id: 'status.delete', defaultMessage: 'Delete' },
|
delete: { id: 'status.delete', defaultMessage: 'Delete' },
|
||||||
@ -77,6 +78,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||||||
status: ImmutablePropTypes.map.isRequired,
|
status: ImmutablePropTypes.map.isRequired,
|
||||||
relationship: ImmutablePropTypes.record,
|
relationship: ImmutablePropTypes.record,
|
||||||
quotedAccountId: PropTypes.string,
|
quotedAccountId: PropTypes.string,
|
||||||
|
contextType: PropTypes.string,
|
||||||
onReply: PropTypes.func,
|
onReply: PropTypes.func,
|
||||||
onFavourite: PropTypes.func,
|
onFavourite: PropTypes.func,
|
||||||
onDelete: PropTypes.func,
|
onDelete: PropTypes.func,
|
||||||
@ -240,7 +242,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { status, relationship, quotedAccountId, intl, withDismiss, withCounters, scrollKey } = this.props;
|
const { status, relationship, quotedAccountId, contextType, intl, withDismiss, withCounters, scrollKey } = this.props;
|
||||||
const { signedIn, permissions } = this.props.identity;
|
const { signedIn, permissions } = this.props.identity;
|
||||||
|
|
||||||
const publicStatus = ['public', 'unlisted'].includes(status.get('visibility'));
|
const publicStatus = ['public', 'unlisted'].includes(status.get('visibility'));
|
||||||
@ -249,6 +251,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||||||
const account = status.get('account');
|
const account = status.get('account');
|
||||||
const writtenByMe = status.getIn(['account', 'id']) === me;
|
const writtenByMe = status.getIn(['account', 'id']) === me;
|
||||||
const isRemote = status.getIn(['account', 'username']) !== status.getIn(['account', 'acct']);
|
const isRemote = status.getIn(['account', 'username']) !== status.getIn(['account', 'acct']);
|
||||||
|
const isQuotingMe = quotedAccountId === me;
|
||||||
|
|
||||||
let menu = [];
|
let menu = [];
|
||||||
|
|
||||||
@ -293,7 +296,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||||||
menu.push({ text: intl.formatMessage(messages.direct, { name: account.get('username') }), action: this.handleDirectClick });
|
menu.push({ text: intl.formatMessage(messages.direct, { name: account.get('username') }), action: this.handleDirectClick });
|
||||||
menu.push(null);
|
menu.push(null);
|
||||||
|
|
||||||
if (quotedAccountId === me) {
|
if (isQuotingMe) {
|
||||||
menu.push({ text: intl.formatMessage(messages.revokeQuote, { name: account.get('username') }), action: this.handleRevokeQuoteClick, dangerous: true });
|
menu.push({ text: intl.formatMessage(messages.revokeQuote, { name: account.get('username') }), action: this.handleRevokeQuoteClick, dangerous: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,6 +363,8 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||||||
const bookmarkTitle = intl.formatMessage(status.get('bookmarked') ? messages.removeBookmark : messages.bookmark);
|
const bookmarkTitle = intl.formatMessage(status.get('bookmarked') ? messages.removeBookmark : messages.bookmark);
|
||||||
const favouriteTitle = intl.formatMessage(status.get('favourited') ? messages.removeFavourite : messages.favourite);
|
const favouriteTitle = intl.formatMessage(status.get('favourited') ? messages.removeFavourite : messages.favourite);
|
||||||
const isReply = status.get('in_reply_to_account_id') === status.getIn(['account', 'id']);
|
const isReply = status.get('in_reply_to_account_id') === status.getIn(['account', 'id']);
|
||||||
|
|
||||||
|
const shouldShowQuoteRemovalHint = isQuotingMe && contextType === 'notifications';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='status__action-bar'>
|
<div className='status__action-bar'>
|
||||||
@ -375,17 +380,23 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||||||
<div className='status__action-bar__button-wrapper'>
|
<div className='status__action-bar__button-wrapper'>
|
||||||
<IconButton className='status__action-bar__button bookmark-icon' disabled={!signedIn} active={status.get('bookmarked')} title={bookmarkTitle} icon='bookmark' iconComponent={status.get('bookmarked') ? BookmarkIcon : BookmarkBorderIcon} onClick={this.handleBookmarkClick} />
|
<IconButton className='status__action-bar__button bookmark-icon' disabled={!signedIn} active={status.get('bookmarked')} title={bookmarkTitle} icon='bookmark' iconComponent={status.get('bookmarked') ? BookmarkIcon : BookmarkBorderIcon} onClick={this.handleBookmarkClick} />
|
||||||
</div>
|
</div>
|
||||||
<div className='status__action-bar__button-wrapper'>
|
<RemoveQuoteHint className='status__action-bar__button-wrapper' canShowHint={shouldShowQuoteRemovalHint}>
|
||||||
<Dropdown
|
{(dismissQuoteHint) => (
|
||||||
scrollKey={scrollKey}
|
<Dropdown
|
||||||
status={status}
|
scrollKey={scrollKey}
|
||||||
items={menu}
|
status={status}
|
||||||
icon='ellipsis-h'
|
items={menu}
|
||||||
iconComponent={MoreHorizIcon}
|
icon='ellipsis-h'
|
||||||
direction='right'
|
iconComponent={MoreHorizIcon}
|
||||||
title={intl.formatMessage(messages.more)}
|
direction='right'
|
||||||
/>
|
title={intl.formatMessage(messages.more)}
|
||||||
</div>
|
onOpen={() => {
|
||||||
|
dismissQuoteHint();
|
||||||
|
return true;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</RemoveQuoteHint>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -0,0 +1,90 @@
|
|||||||
|
import { useRef } from 'react';
|
||||||
|
|
||||||
|
import { FormattedMessage, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
import Overlay from 'react-overlays/Overlay';
|
||||||
|
|
||||||
|
import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react';
|
||||||
|
|
||||||
|
import { Button } from '../button';
|
||||||
|
import { useDismissableBannerState } from '../dismissable_banner';
|
||||||
|
import { Icon } from '../icon';
|
||||||
|
|
||||||
|
const DISMISSABLE_BANNER_ID = 'notifications/remove_quote_hint';
|
||||||
|
|
||||||
|
export const RemoveQuoteHint: React.FC<{
|
||||||
|
canShowHint: boolean;
|
||||||
|
className?: string;
|
||||||
|
children: (dismiss: () => void) => React.ReactNode;
|
||||||
|
}> = ({ canShowHint, className, children }) => {
|
||||||
|
const anchorRef = useRef<HTMLDivElement>(null);
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const { isVisible, dismiss } = useDismissableBannerState({
|
||||||
|
id: DISMISSABLE_BANNER_ID,
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={className} ref={anchorRef}>
|
||||||
|
{children(dismiss)}
|
||||||
|
{isVisible && canShowHint && (
|
||||||
|
<Overlay
|
||||||
|
show
|
||||||
|
flip
|
||||||
|
offset={[12, 10]}
|
||||||
|
placement='bottom-end'
|
||||||
|
target={anchorRef.current}
|
||||||
|
container={anchorRef.current}
|
||||||
|
>
|
||||||
|
{({ props, placement }) => (
|
||||||
|
<div
|
||||||
|
{...props}
|
||||||
|
className={classNames(
|
||||||
|
'info-tooltip info-tooltip--solid dropdown-animation',
|
||||||
|
placement,
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<h4>
|
||||||
|
<FormattedMessage
|
||||||
|
id='remove_quote_hint.title'
|
||||||
|
defaultMessage='Want to remove your quoted post?'
|
||||||
|
/>
|
||||||
|
</h4>
|
||||||
|
<FormattedMessage
|
||||||
|
id='remove_quote_hint.message'
|
||||||
|
defaultMessage='You can do so from the {icon} options menu.'
|
||||||
|
values={{
|
||||||
|
icon: (
|
||||||
|
<Icon
|
||||||
|
id='ellipsis-h'
|
||||||
|
icon={MoreHorizIcon}
|
||||||
|
aria-label={intl.formatMessage({
|
||||||
|
id: 'status.more',
|
||||||
|
defaultMessage: 'More',
|
||||||
|
})}
|
||||||
|
style={{ verticalAlign: 'middle' }}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{(text) => <p>{text}</p>}
|
||||||
|
</FormattedMessage>
|
||||||
|
<FormattedMessage
|
||||||
|
id='remove_quote_hint.button_label'
|
||||||
|
defaultMessage='Got it'
|
||||||
|
>
|
||||||
|
{(text) => (
|
||||||
|
<Button plain compact onClick={dismiss}>
|
||||||
|
{text}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</FormattedMessage>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Overlay>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -1,7 +1,5 @@
|
|||||||
import type { ComponentPropsWithoutRef, ElementType } from 'react';
|
import type { ComponentPropsWithoutRef, ElementType } from 'react';
|
||||||
|
|
||||||
import { isModernEmojiEnabled } from '@/mastodon/utils/environment';
|
|
||||||
|
|
||||||
import { useEmojify } from './hooks';
|
import { useEmojify } from './hooks';
|
||||||
import type { CustomEmojiMapArg } from './types';
|
import type { CustomEmojiMapArg } from './types';
|
||||||
|
|
||||||
@ -12,16 +10,21 @@ type EmojiHTMLProps<Element extends ElementType = 'div'> = Omit<
|
|||||||
htmlString: string;
|
htmlString: string;
|
||||||
extraEmojis?: CustomEmojiMapArg;
|
extraEmojis?: CustomEmojiMapArg;
|
||||||
as?: Element;
|
as?: Element;
|
||||||
|
shallow?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ModernEmojiHTML = <Element extends ElementType>({
|
export const EmojiHTML = ({
|
||||||
extraEmojis,
|
extraEmojis,
|
||||||
htmlString,
|
htmlString,
|
||||||
as: asElement, // Rename for syntax highlighting
|
as: Wrapper = 'div', // Rename for syntax highlighting
|
||||||
|
shallow,
|
||||||
...props
|
...props
|
||||||
}: EmojiHTMLProps<Element>) => {
|
}: EmojiHTMLProps<ElementType>) => {
|
||||||
const Wrapper = asElement ?? 'div';
|
const emojifiedHtml = useEmojify({
|
||||||
const emojifiedHtml = useEmojify(htmlString, extraEmojis);
|
text: htmlString,
|
||||||
|
extraEmojis,
|
||||||
|
deep: !shallow,
|
||||||
|
});
|
||||||
|
|
||||||
if (emojifiedHtml === null) {
|
if (emojifiedHtml === null) {
|
||||||
return null;
|
return null;
|
||||||
@ -31,14 +34,3 @@ export const ModernEmojiHTML = <Element extends ElementType>({
|
|||||||
<Wrapper {...props} dangerouslySetInnerHTML={{ __html: emojifiedHtml }} />
|
<Wrapper {...props} dangerouslySetInnerHTML={{ __html: emojifiedHtml }} />
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const EmojiHTML = <Element extends ElementType>(
|
|
||||||
props: EmojiHTMLProps<Element>,
|
|
||||||
) => {
|
|
||||||
if (isModernEmojiEnabled()) {
|
|
||||||
return <ModernEmojiHTML {...props} />;
|
|
||||||
}
|
|
||||||
const { as: asElement, htmlString, extraEmojis, ...rest } = props;
|
|
||||||
const Wrapper = asElement ?? 'div';
|
|
||||||
return <Wrapper {...rest} dangerouslySetInnerHTML={{ __html: htmlString }} />;
|
|
||||||
};
|
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import { isModernEmojiEnabled } from '@/mastodon/utils/environment';
|
|||||||
|
|
||||||
import { toSupportedLocale } from './locale';
|
import { toSupportedLocale } from './locale';
|
||||||
import { determineEmojiMode } from './mode';
|
import { determineEmojiMode } from './mode';
|
||||||
|
import { emojifyElement, emojifyText } from './render';
|
||||||
import type {
|
import type {
|
||||||
CustomEmojiMapArg,
|
CustomEmojiMapArg,
|
||||||
EmojiAppState,
|
EmojiAppState,
|
||||||
@ -15,7 +16,17 @@ import type {
|
|||||||
} from './types';
|
} from './types';
|
||||||
import { stringHasAnyEmoji } from './utils';
|
import { stringHasAnyEmoji } from './utils';
|
||||||
|
|
||||||
export function useEmojify(text: string, extraEmojis?: CustomEmojiMapArg) {
|
interface UseEmojifyOptions {
|
||||||
|
text: string;
|
||||||
|
extraEmojis?: CustomEmojiMapArg;
|
||||||
|
deep?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEmojify({
|
||||||
|
text,
|
||||||
|
extraEmojis,
|
||||||
|
deep = true,
|
||||||
|
}: UseEmojifyOptions) {
|
||||||
const [emojifiedText, setEmojifiedText] = useState<string | null>(null);
|
const [emojifiedText, setEmojifiedText] = useState<string | null>(null);
|
||||||
|
|
||||||
const appState = useEmojiAppState();
|
const appState = useEmojiAppState();
|
||||||
@ -36,17 +47,23 @@ export function useEmojify(text: string, extraEmojis?: CustomEmojiMapArg) {
|
|||||||
|
|
||||||
const emojify = useCallback(
|
const emojify = useCallback(
|
||||||
async (input: string) => {
|
async (input: string) => {
|
||||||
const wrapper = document.createElement('div');
|
let result: string | null = null;
|
||||||
wrapper.innerHTML = input;
|
if (deep) {
|
||||||
const { emojifyElement } = await import('./render');
|
const wrapper = document.createElement('div');
|
||||||
const result = await emojifyElement(wrapper, appState, extra);
|
wrapper.innerHTML = input;
|
||||||
|
if (await emojifyElement(wrapper, appState, extra)) {
|
||||||
|
result = wrapper.innerHTML;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = await emojifyText(text, appState, extra);
|
||||||
|
}
|
||||||
if (result) {
|
if (result) {
|
||||||
setEmojifiedText(result.innerHTML);
|
setEmojifiedText(result);
|
||||||
} else {
|
} else {
|
||||||
setEmojifiedText(input);
|
setEmojifiedText(input);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[appState, extra],
|
[appState, deep, extra, text],
|
||||||
);
|
);
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
if (isModernEmojiEnabled() && !!text.trim() && stringHasAnyEmoji(text)) {
|
if (isModernEmojiEnabled() && !!text.trim() && stringHasAnyEmoji(text)) {
|
||||||
|
|||||||
@ -33,7 +33,7 @@ const messages = defineMessages({
|
|||||||
reblog: { id: 'status.reblog', defaultMessage: 'Boost' },
|
reblog: { id: 'status.reblog', defaultMessage: 'Boost' },
|
||||||
reblog_private: {
|
reblog_private: {
|
||||||
id: 'status.reblog_private',
|
id: 'status.reblog_private',
|
||||||
defaultMessage: 'Boost with original visibility',
|
defaultMessage: 'Share again with your followers',
|
||||||
},
|
},
|
||||||
cancel_reblog_private: {
|
cancel_reblog_private: {
|
||||||
id: 'status.cancel_reblog_private',
|
id: 'status.cancel_reblog_private',
|
||||||
|
|||||||
@ -92,8 +92,7 @@ const messages = defineMessages({
|
|||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
layout: state.getIn(['meta', 'layout']),
|
layout: state.getIn(['meta', 'layout']),
|
||||||
isComposing: state.getIn(['compose', 'is_composing']),
|
isComposing: state.getIn(['compose', 'is_composing']),
|
||||||
hasComposingText: state.getIn(['compose', 'text']).trim().length !== 0,
|
hasComposingContents: state.getIn(['compose', 'text']).trim().length !== 0 || state.getIn(['compose', 'media_attachments']).size > 0 || state.getIn(['compose', 'poll']) !== null || state.getIn(['compose', 'quoted_status_id']) !== null,
|
||||||
hasMediaAttachments: state.getIn(['compose', 'media_attachments']).size > 0,
|
|
||||||
canUploadMore: !state.getIn(['compose', 'media_attachments']).some(x => ['audio', 'video'].includes(x.get('type'))) && state.getIn(['compose', 'media_attachments']).size < state.getIn(['server', 'server', 'configuration', 'statuses', 'max_media_attachments']),
|
canUploadMore: !state.getIn(['compose', 'media_attachments']).some(x => ['audio', 'video'].includes(x.get('type'))) && state.getIn(['compose', 'media_attachments']).size < state.getIn(['server', 'server', 'configuration', 'statuses', 'max_media_attachments']),
|
||||||
firstLaunch: state.getIn(['settings', 'introductionVersion'], 0) < INTRODUCTION_VERSION,
|
firstLaunch: state.getIn(['settings', 'introductionVersion'], 0) < INTRODUCTION_VERSION,
|
||||||
newAccount: !state.getIn(['accounts', me, 'note']) && !state.getIn(['accounts', me, 'bot']) && state.getIn(['accounts', me, 'following_count'], 0) === 0 && state.getIn(['accounts', me, 'statuses_count'], 0) === 0,
|
newAccount: !state.getIn(['accounts', me, 'note']) && !state.getIn(['accounts', me, 'bot']) && state.getIn(['accounts', me, 'following_count'], 0) === 0 && state.getIn(['accounts', me, 'statuses_count'], 0) === 0,
|
||||||
@ -241,8 +240,7 @@ class UI extends PureComponent {
|
|||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
children: PropTypes.node,
|
children: PropTypes.node,
|
||||||
isComposing: PropTypes.bool,
|
isComposing: PropTypes.bool,
|
||||||
hasComposingText: PropTypes.bool,
|
hasComposingContents: PropTypes.bool,
|
||||||
hasMediaAttachments: PropTypes.bool,
|
|
||||||
canUploadMore: PropTypes.bool,
|
canUploadMore: PropTypes.bool,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
layout: PropTypes.string.isRequired,
|
layout: PropTypes.string.isRequired,
|
||||||
@ -257,11 +255,11 @@ class UI extends PureComponent {
|
|||||||
};
|
};
|
||||||
|
|
||||||
handleBeforeUnload = e => {
|
handleBeforeUnload = e => {
|
||||||
const { intl, dispatch, isComposing, hasComposingText, hasMediaAttachments } = this.props;
|
const { intl, dispatch, isComposing, hasComposingContents } = this.props;
|
||||||
|
|
||||||
dispatch(synchronouslySubmitMarkers());
|
dispatch(synchronouslySubmitMarkers());
|
||||||
|
|
||||||
if (isComposing && (hasComposingText || hasMediaAttachments)) {
|
if (isComposing && hasComposingContents) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
// Setting returnValue to any string causes confirmation dialog.
|
// Setting returnValue to any string causes confirmation dialog.
|
||||||
// Many browsers no longer display this text to users,
|
// Many browsers no longer display this text to users,
|
||||||
|
|||||||
@ -29,6 +29,8 @@
|
|||||||
"account.endorse": "Lakaat war-wel war ar profil",
|
"account.endorse": "Lakaat war-wel war ar profil",
|
||||||
"account.familiar_followers_one": "Heuilhet gant {name1}",
|
"account.familiar_followers_one": "Heuilhet gant {name1}",
|
||||||
"account.familiar_followers_two": "Heuilhet gant {name1} ha {name2}",
|
"account.familiar_followers_two": "Heuilhet gant {name1} ha {name2}",
|
||||||
|
"account.featured.accounts": "Profiloù",
|
||||||
|
"account.featured.hashtags": "Gerioù-klik",
|
||||||
"account.featured_tags.last_status_at": "Toud diwezhañ : {date}",
|
"account.featured_tags.last_status_at": "Toud diwezhañ : {date}",
|
||||||
"account.featured_tags.last_status_never": "Embannadur ebet",
|
"account.featured_tags.last_status_never": "Embannadur ebet",
|
||||||
"account.follow": "Heuliañ",
|
"account.follow": "Heuliañ",
|
||||||
@ -39,6 +41,7 @@
|
|||||||
"account.followers_you_know_counter": "{counter} a anavezit",
|
"account.followers_you_know_counter": "{counter} a anavezit",
|
||||||
"account.following": "Koumanantoù",
|
"account.following": "Koumanantoù",
|
||||||
"account.follows.empty": "An implijer·ez-mañ na heul den ebet.",
|
"account.follows.empty": "An implijer·ez-mañ na heul den ebet.",
|
||||||
|
"account.follows_you": "Ho heuilh",
|
||||||
"account.go_to_profile": "Gwelet ar profil",
|
"account.go_to_profile": "Gwelet ar profil",
|
||||||
"account.hide_reblogs": "Kuzh skignadennoù gant @{name}",
|
"account.hide_reblogs": "Kuzh skignadennoù gant @{name}",
|
||||||
"account.in_memoriam": "E koun.",
|
"account.in_memoriam": "E koun.",
|
||||||
@ -89,7 +92,10 @@
|
|||||||
"alt_text_modal.done": "Graet",
|
"alt_text_modal.done": "Graet",
|
||||||
"announcement.announcement": "Kemennad",
|
"announcement.announcement": "Kemennad",
|
||||||
"annual_report.summary.followers.followers": "heulier",
|
"annual_report.summary.followers.followers": "heulier",
|
||||||
|
"annual_report.summary.followers.total": "{count} en holl",
|
||||||
"annual_report.summary.highlighted_post.possessive": "{name}",
|
"annual_report.summary.highlighted_post.possessive": "{name}",
|
||||||
|
"annual_report.summary.most_used_app.most_used_app": "arload muiañ implijet",
|
||||||
|
"annual_report.summary.most_used_hashtag.most_used_hashtag": "ar gerioù-klik implijet ar muiañ",
|
||||||
"annual_report.summary.most_used_hashtag.none": "Hini ebet",
|
"annual_report.summary.most_used_hashtag.none": "Hini ebet",
|
||||||
"annual_report.summary.new_posts.new_posts": "toudoù nevez",
|
"annual_report.summary.new_posts.new_posts": "toudoù nevez",
|
||||||
"attachments_list.unprocessed": "(ket meret)",
|
"attachments_list.unprocessed": "(ket meret)",
|
||||||
@ -149,7 +155,7 @@
|
|||||||
"compose.saved.body": "Enrollet.",
|
"compose.saved.body": "Enrollet.",
|
||||||
"compose_form.direct_message_warning_learn_more": "Gouzout hiroc'h",
|
"compose_form.direct_message_warning_learn_more": "Gouzout hiroc'h",
|
||||||
"compose_form.encryption_warning": "Toudoù war Mastodon na vezont ket sifret penn-da-benn. Na rannit ket titouroù kizidik dre Mastodon.",
|
"compose_form.encryption_warning": "Toudoù war Mastodon na vezont ket sifret penn-da-benn. Na rannit ket titouroù kizidik dre Mastodon.",
|
||||||
"compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
|
"compose_form.hashtag_warning": "Ne vo ket listennet an toud-mañ dindan gerioù-klik ebet dre m'eo anlistennet. N'eus nemet an toudoù foran a c'hall bezañ klasket dre c'her-klik.",
|
||||||
"compose_form.lock_disclaimer": "N'eo ket {locked} ho kont. An holl a c'hal ho heuliañ evit gwelet ho toudoù prevez.",
|
"compose_form.lock_disclaimer": "N'eo ket {locked} ho kont. An holl a c'hal ho heuliañ evit gwelet ho toudoù prevez.",
|
||||||
"compose_form.lock_disclaimer.lock": "prennet",
|
"compose_form.lock_disclaimer.lock": "prennet",
|
||||||
"compose_form.placeholder": "Petra emaoc'h o soñjal e-barzh ?",
|
"compose_form.placeholder": "Petra emaoc'h o soñjal e-barzh ?",
|
||||||
@ -168,6 +174,7 @@
|
|||||||
"confirmations.block.confirm": "Stankañ",
|
"confirmations.block.confirm": "Stankañ",
|
||||||
"confirmations.delete.confirm": "Dilemel",
|
"confirmations.delete.confirm": "Dilemel",
|
||||||
"confirmations.delete.message": "Ha sur oc'h e fell deoc'h dilemel an toud-mañ ?",
|
"confirmations.delete.message": "Ha sur oc'h e fell deoc'h dilemel an toud-mañ ?",
|
||||||
|
"confirmations.delete.title": "Dilemel an toud?",
|
||||||
"confirmations.delete_list.confirm": "Dilemel",
|
"confirmations.delete_list.confirm": "Dilemel",
|
||||||
"confirmations.delete_list.message": "Ha sur eo hoc'h eus c'hoant da zilemel ar roll-mañ da vat ?",
|
"confirmations.delete_list.message": "Ha sur eo hoc'h eus c'hoant da zilemel ar roll-mañ da vat ?",
|
||||||
"confirmations.delete_list.title": "Dilemel al listenn?",
|
"confirmations.delete_list.title": "Dilemel al listenn?",
|
||||||
@ -176,10 +183,14 @@
|
|||||||
"confirmations.follow_to_list.title": "Heuliañ an implijer·ez?",
|
"confirmations.follow_to_list.title": "Heuliañ an implijer·ez?",
|
||||||
"confirmations.logout.confirm": "Digevreañ",
|
"confirmations.logout.confirm": "Digevreañ",
|
||||||
"confirmations.logout.message": "Ha sur oc'h e fell deoc'h digevreañ ?",
|
"confirmations.logout.message": "Ha sur oc'h e fell deoc'h digevreañ ?",
|
||||||
|
"confirmations.logout.title": "Digevreañ?",
|
||||||
"confirmations.mute.confirm": "Kuzhat",
|
"confirmations.mute.confirm": "Kuzhat",
|
||||||
"confirmations.redraft.confirm": "Diverkañ ha skrivañ en-dro",
|
"confirmations.redraft.confirm": "Diverkañ ha skrivañ en-dro",
|
||||||
"confirmations.unfollow.confirm": "Diheuliañ",
|
"confirmations.unfollow.confirm": "Diheuliañ",
|
||||||
"confirmations.unfollow.message": "Ha sur oc'h e fell deoc'h paouez da heuliañ {name} ?",
|
"confirmations.unfollow.message": "Ha sur oc'h e fell deoc'h paouez da heuliañ {name} ?",
|
||||||
|
"confirmations.unfollow.title": "Paouez da heuliañ an implijer·ez?",
|
||||||
|
"content_warning.hide": "Kuzhat an embannadur",
|
||||||
|
"content_warning.show": "Diskwel memes tra",
|
||||||
"content_warning.show_more": "Diskouez muioc'h",
|
"content_warning.show_more": "Diskouez muioc'h",
|
||||||
"conversation.delete": "Dilemel ar gaozeadenn",
|
"conversation.delete": "Dilemel ar gaozeadenn",
|
||||||
"conversation.mark_as_read": "Merkañ evel lennet",
|
"conversation.mark_as_read": "Merkañ evel lennet",
|
||||||
@ -224,8 +235,8 @@
|
|||||||
"empty_column.domain_blocks": "N'eus domani kuzh ebet c'hoazh.",
|
"empty_column.domain_blocks": "N'eus domani kuzh ebet c'hoazh.",
|
||||||
"empty_column.explore_statuses": "N'eus tuadur ebet evit c'hoazh. Distroit diwezhatoc'h !",
|
"empty_column.explore_statuses": "N'eus tuadur ebet evit c'hoazh. Distroit diwezhatoc'h !",
|
||||||
"empty_column.follow_requests": "N'ho peus reked heuliañ ebet c'hoazh. Pa vo resevet unan e teuio war wel amañ.",
|
"empty_column.follow_requests": "N'ho peus reked heuliañ ebet c'hoazh. Pa vo resevet unan e teuio war wel amañ.",
|
||||||
"empty_column.followed_tags": "N'emaoc'h oc'h heuliañ hashtag ebet evit poent. Pa vioc'h e vo d'o gwelet amañ.",
|
"empty_column.followed_tags": "N'emaoc'h oc'h heuliañ ger-klik ebet evit poent. Pa vioc'h e vo d'o gwelet amañ.",
|
||||||
"empty_column.hashtag": "N'eus netra en hashtag-mañ c'hoazh.",
|
"empty_column.hashtag": "N'eus netra er ger-klik-mañ c'hoazh.",
|
||||||
"empty_column.home": "Goullo eo ho red-amzer degemer! Kit da weladenniñ {public} pe implijit ar c'hlask evit kregiñ ganti ha kejañ gant implijer·ien·ezed all.",
|
"empty_column.home": "Goullo eo ho red-amzer degemer! Kit da weladenniñ {public} pe implijit ar c'hlask evit kregiñ ganti ha kejañ gant implijer·ien·ezed all.",
|
||||||
"empty_column.list": "Goullo eo al listenn-mañ evit c'hoazh. Pa vo embannet toudoù nevez gant e izili e teuint war wel amañ.",
|
"empty_column.list": "Goullo eo al listenn-mañ evit c'hoazh. Pa vo embannet toudoù nevez gant e izili e teuint war wel amañ.",
|
||||||
"empty_column.mutes": "N'ho peus kuzhet implijer ebet c'hoazh.",
|
"empty_column.mutes": "N'ho peus kuzhet implijer ebet c'hoazh.",
|
||||||
@ -241,7 +252,7 @@
|
|||||||
"explore.title": "Diouzh ar c'hiz",
|
"explore.title": "Diouzh ar c'hiz",
|
||||||
"explore.trending_links": "Keleier",
|
"explore.trending_links": "Keleier",
|
||||||
"explore.trending_statuses": "Embannadurioù",
|
"explore.trending_statuses": "Embannadurioù",
|
||||||
"explore.trending_tags": "Hashtagoù",
|
"explore.trending_tags": "Gerioù-klik",
|
||||||
"featured_carousel.next": "War-raok",
|
"featured_carousel.next": "War-raok",
|
||||||
"featured_carousel.post": "Embannadenn",
|
"featured_carousel.post": "Embannadenn",
|
||||||
"featured_carousel.previous": "War-gil",
|
"featured_carousel.previous": "War-gil",
|
||||||
@ -269,7 +280,8 @@
|
|||||||
"follow_suggestions.friends_of_friends_longer": "Diouzh ar c'hiz e-touez an dud heuliet ganeoc'h",
|
"follow_suggestions.friends_of_friends_longer": "Diouzh ar c'hiz e-touez an dud heuliet ganeoc'h",
|
||||||
"follow_suggestions.popular_suggestion_longer": "Diouzh ar c'hiz war {domain}",
|
"follow_suggestions.popular_suggestion_longer": "Diouzh ar c'hiz war {domain}",
|
||||||
"follow_suggestions.view_all": "Gwelet pep tra",
|
"follow_suggestions.view_all": "Gwelet pep tra",
|
||||||
"followed_tags": "Hashtagoù o heuliañ",
|
"follow_suggestions.who_to_follow": "Piv heuliañ",
|
||||||
|
"followed_tags": "Gerioù-klik o heuliañ",
|
||||||
"footer.about": "Diwar-benn",
|
"footer.about": "Diwar-benn",
|
||||||
"footer.directory": "Kavlec'h ar profiloù",
|
"footer.directory": "Kavlec'h ar profiloù",
|
||||||
"footer.get_app": "Pellgargañ an arload",
|
"footer.get_app": "Pellgargañ an arload",
|
||||||
@ -281,19 +293,23 @@
|
|||||||
"generic.saved": "Enrollet",
|
"generic.saved": "Enrollet",
|
||||||
"getting_started.heading": "Loc'hañ",
|
"getting_started.heading": "Loc'hañ",
|
||||||
"hashtag.admin_moderation": "Digeriñ an etrefas evezhiañ evit #{name}",
|
"hashtag.admin_moderation": "Digeriñ an etrefas evezhiañ evit #{name}",
|
||||||
|
"hashtag.browse": "Furchal dre an toudoù gant #{hashtag}",
|
||||||
|
"hashtag.browse_from_account": "Furchal dre an toudoù gant @{name} gant #{hashtag}",
|
||||||
"hashtag.column_header.tag_mode.all": "ha(g) {additional}",
|
"hashtag.column_header.tag_mode.all": "ha(g) {additional}",
|
||||||
"hashtag.column_header.tag_mode.any": "pe {additional}",
|
"hashtag.column_header.tag_mode.any": "pe {additional}",
|
||||||
"hashtag.column_header.tag_mode.none": "hep {additional}",
|
"hashtag.column_header.tag_mode.none": "hep {additional}",
|
||||||
"hashtag.column_settings.select.no_options_message": "N'eus bet kavet ali ebet",
|
"hashtag.column_settings.select.no_options_message": "N'eus bet kavet ali ebet",
|
||||||
"hashtag.column_settings.select.placeholder": "Ouzhpennañ hashtagoù…",
|
"hashtag.column_settings.select.placeholder": "Ouzhpennañ gerioù-klik…",
|
||||||
"hashtag.column_settings.tag_mode.all": "An holl anezho",
|
"hashtag.column_settings.tag_mode.all": "An holl anezho",
|
||||||
"hashtag.column_settings.tag_mode.any": "Unan e mesk anezho",
|
"hashtag.column_settings.tag_mode.any": "Unan e mesk anezho",
|
||||||
"hashtag.column_settings.tag_mode.none": "Hini ebet anezho",
|
"hashtag.column_settings.tag_mode.none": "Hini ebet anezho",
|
||||||
"hashtag.column_settings.tag_toggle": "Endelc'her gerioù-alc'hwez ouzhpenn evit ar bannad-mañ",
|
"hashtag.column_settings.tag_toggle": "Endelc'her gerioù-alc'hwez ouzhpenn evit ar bannad-mañ",
|
||||||
"hashtag.counter_by_uses": "{count, plural, one {{counter} embannadur} other {{counter} embannadur}}",
|
"hashtag.counter_by_uses": "{count, plural, one {{counter} embannadur} other {{counter} embannadur}}",
|
||||||
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} embannadur} other {{counter} embannadur}} hiziv",
|
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} embannadur} other {{counter} embannadur}} hiziv",
|
||||||
|
"hashtag.feature": "Lakaat war-wel war ar profil",
|
||||||
"hashtag.follow": "Heuliañ ar ger-klik",
|
"hashtag.follow": "Heuliañ ar ger-klik",
|
||||||
"hashtag.unfollow": "Paouez heuliañ an hashtag",
|
"hashtag.mute": "Kuzhat #{hashtag}",
|
||||||
|
"hashtag.unfollow": "Diheuliañ ar ger-klik",
|
||||||
"hashtags.and_other": "…{count, plural, one {hag # all} other {ha # all}}",
|
"hashtags.and_other": "…{count, plural, one {hag # all} other {ha # all}}",
|
||||||
"home.column_settings.show_quotes": "Diskouez an arroudennoù",
|
"home.column_settings.show_quotes": "Diskouez an arroudennoù",
|
||||||
"home.column_settings.show_reblogs": "Diskouez ar skignadennoù",
|
"home.column_settings.show_reblogs": "Diskouez ar skignadennoù",
|
||||||
@ -302,12 +318,14 @@
|
|||||||
"home.pending_critical_update.body": "Hizivait ho servijer Mastodon kerkent ha ma c'hallit mar plij!",
|
"home.pending_critical_update.body": "Hizivait ho servijer Mastodon kerkent ha ma c'hallit mar plij!",
|
||||||
"home.pending_critical_update.link": "Gwelet an hizivadennoù",
|
"home.pending_critical_update.link": "Gwelet an hizivadennoù",
|
||||||
"home.show_announcements": "Diskouez ar c'hemennoù",
|
"home.show_announcements": "Diskouez ar c'hemennoù",
|
||||||
|
"interaction_modal.go": "Mont di",
|
||||||
"interaction_modal.on_another_server": "War ur servijer all",
|
"interaction_modal.on_another_server": "War ur servijer all",
|
||||||
"interaction_modal.on_this_server": "War ar servijer-mañ",
|
"interaction_modal.on_this_server": "War ar servijer-mañ",
|
||||||
"interaction_modal.title.favourite": "Ouzhpennañ embannadur {name} d'ar re vuiañ-karet",
|
"interaction_modal.title.favourite": "Ouzhpennañ embannadur {name} d'ar re vuiañ-karet",
|
||||||
"interaction_modal.title.follow": "Heuliañ {name}",
|
"interaction_modal.title.follow": "Heuliañ {name}",
|
||||||
"interaction_modal.title.reblog": "Skignañ toud {name}",
|
"interaction_modal.title.reblog": "Skignañ toud {name}",
|
||||||
"interaction_modal.title.reply": "Respont da doud {name}",
|
"interaction_modal.title.reply": "Respont da doud {name}",
|
||||||
|
"interaction_modal.username_prompt": "D.s. {example}",
|
||||||
"intervals.full.days": "{number, plural, one {# devezh} other{# a zevezhioù}}",
|
"intervals.full.days": "{number, plural, one {# devezh} other{# a zevezhioù}}",
|
||||||
"intervals.full.hours": "{number, plural, one {# eurvezh} other{# eurvezh}}",
|
"intervals.full.hours": "{number, plural, one {# eurvezh} other{# eurvezh}}",
|
||||||
"intervals.full.minutes": "{number, plural, one {# munut} other{# a vunutoù}}",
|
"intervals.full.minutes": "{number, plural, one {# munut} other{# a vunutoù}}",
|
||||||
@ -345,12 +363,14 @@
|
|||||||
"keyboard_shortcuts.toot": "Kregiñ gant un toud nevez",
|
"keyboard_shortcuts.toot": "Kregiñ gant un toud nevez",
|
||||||
"keyboard_shortcuts.unfocus": "Difokus an dachenn testenn/klask",
|
"keyboard_shortcuts.unfocus": "Difokus an dachenn testenn/klask",
|
||||||
"keyboard_shortcuts.up": "Pignat er roll",
|
"keyboard_shortcuts.up": "Pignat er roll",
|
||||||
|
"learn_more_link.got_it": "Mat eo",
|
||||||
"lightbox.close": "Serriñ",
|
"lightbox.close": "Serriñ",
|
||||||
"lightbox.next": "Da-heul",
|
"lightbox.next": "Da-heul",
|
||||||
"lightbox.previous": "A-raok",
|
"lightbox.previous": "A-raok",
|
||||||
"limited_account_hint.action": "Diskouez an aelad memes tra",
|
"limited_account_hint.action": "Diskouez ar profil memes tra",
|
||||||
"limited_account_hint.title": "Kuzhet eo bet ar profil-mañ gant an evezhierien eus {domain}.",
|
"limited_account_hint.title": "Kuzhet eo bet ar profil-mañ gant an evezhierien eus {domain}.",
|
||||||
"link_preview.author": "Gant {name}",
|
"link_preview.author": "Gant {name}",
|
||||||
|
"link_preview.more_from_author": "Muioc'h gant {name}",
|
||||||
"lists.add_member": "Ouzhpennañ",
|
"lists.add_member": "Ouzhpennañ",
|
||||||
"lists.add_to_list": "Ouzhpennañ d'al listenn",
|
"lists.add_to_list": "Ouzhpennañ d'al listenn",
|
||||||
"lists.create": "Krouiñ",
|
"lists.create": "Krouiñ",
|
||||||
@ -359,13 +379,19 @@
|
|||||||
"lists.done": "Graet",
|
"lists.done": "Graet",
|
||||||
"lists.edit": "Kemmañ al listenn",
|
"lists.edit": "Kemmañ al listenn",
|
||||||
"lists.list_name": "Anv al listenn",
|
"lists.list_name": "Anv al listenn",
|
||||||
|
"lists.new_list_name": "Anv nevez al listenn",
|
||||||
|
"lists.no_lists_yet": "Listenn ebet c'hoazh.",
|
||||||
"lists.replies_policy.followed": "Pep implijer.ez heuliet",
|
"lists.replies_policy.followed": "Pep implijer.ez heuliet",
|
||||||
"lists.replies_policy.list": "Izili ar roll",
|
"lists.replies_policy.list": "Izili ar roll",
|
||||||
"lists.replies_policy.none": "Den ebet",
|
"lists.replies_policy.none": "Den ebet",
|
||||||
|
"lists.save": "Enrollañ",
|
||||||
|
"lists.search": "Klask",
|
||||||
"load_pending": "{count, plural, one {# dra nevez} other {# dra nevez}}",
|
"load_pending": "{count, plural, one {# dra nevez} other {# dra nevez}}",
|
||||||
"loading_indicator.label": "O kargañ…",
|
"loading_indicator.label": "O kargañ…",
|
||||||
|
"media_gallery.hide": "Kuzhat",
|
||||||
"navigation_bar.about": "Diwar-benn",
|
"navigation_bar.about": "Diwar-benn",
|
||||||
"navigation_bar.account_settings": "Ger-tremen ha surentez",
|
"navigation_bar.account_settings": "Ger-tremen ha surentez",
|
||||||
|
"navigation_bar.administration": "Merañ",
|
||||||
"navigation_bar.automated_deletion": "Dilemel an embannadenn ent-emgefreek",
|
"navigation_bar.automated_deletion": "Dilemel an embannadenn ent-emgefreek",
|
||||||
"navigation_bar.blocks": "Implijer·ezed·ien berzet",
|
"navigation_bar.blocks": "Implijer·ezed·ien berzet",
|
||||||
"navigation_bar.bookmarks": "Sinedoù",
|
"navigation_bar.bookmarks": "Sinedoù",
|
||||||
@ -374,11 +400,12 @@
|
|||||||
"navigation_bar.favourites": "Muiañ-karet",
|
"navigation_bar.favourites": "Muiañ-karet",
|
||||||
"navigation_bar.filters": "Gerioù kuzhet",
|
"navigation_bar.filters": "Gerioù kuzhet",
|
||||||
"navigation_bar.follow_requests": "Pedadoù heuliañ",
|
"navigation_bar.follow_requests": "Pedadoù heuliañ",
|
||||||
"navigation_bar.followed_tags": "Hashtagoù o heuliañ",
|
"navigation_bar.followed_tags": "Gerioù-klik o heuliañ",
|
||||||
"navigation_bar.follows_and_followers": "Heuliadennoù ha heulier·ezed·ien",
|
"navigation_bar.follows_and_followers": "Heuliadennoù ha heulier·ezed·ien",
|
||||||
"navigation_bar.import_export": "Enporzhiañ hag ezporzhiañ",
|
"navigation_bar.import_export": "Enporzhiañ hag ezporzhiañ",
|
||||||
"navigation_bar.lists": "Listennoù",
|
"navigation_bar.lists": "Listennoù",
|
||||||
"navigation_bar.logout": "Digennaskañ",
|
"navigation_bar.logout": "Digennaskañ",
|
||||||
|
"navigation_bar.moderation": "Habaskadur",
|
||||||
"navigation_bar.more": "Muioc'h",
|
"navigation_bar.more": "Muioc'h",
|
||||||
"navigation_bar.mutes": "Implijer·ion·ezed kuzhet",
|
"navigation_bar.mutes": "Implijer·ion·ezed kuzhet",
|
||||||
"navigation_bar.preferences": "Gwellvezioù",
|
"navigation_bar.preferences": "Gwellvezioù",
|
||||||
@ -391,6 +418,8 @@
|
|||||||
"notification.follow.name_and_others": "{name} <a>{count, plural, one {hag # den all} two {ha # zen all} few {ha # den all} many {ha # den all} other {ha # den all}}</a> zo o heuliañ ac'hanoc'h",
|
"notification.follow.name_and_others": "{name} <a>{count, plural, one {hag # den all} two {ha # zen all} few {ha # den all} many {ha # den all} other {ha # den all}}</a> zo o heuliañ ac'hanoc'h",
|
||||||
"notification.follow_request": "Gant {name} eo bet goulennet ho heuliañ",
|
"notification.follow_request": "Gant {name} eo bet goulennet ho heuliañ",
|
||||||
"notification.label.reply": "Respont",
|
"notification.label.reply": "Respont",
|
||||||
|
"notification.mention": "Meneg",
|
||||||
|
"notification.mentioned_you": "Gant {name} oc'h bet meneget",
|
||||||
"notification.moderation-warning.learn_more": "Gouzout hiroc'h",
|
"notification.moderation-warning.learn_more": "Gouzout hiroc'h",
|
||||||
"notification.own_poll": "Echu eo ho sontadeg",
|
"notification.own_poll": "Echu eo ho sontadeg",
|
||||||
"notification.reblog": "Gant {name} eo bet skignet ho toud",
|
"notification.reblog": "Gant {name} eo bet skignet ho toud",
|
||||||
@ -447,7 +476,7 @@
|
|||||||
"onboarding.profile.display_name": "Anv diskouezet",
|
"onboarding.profile.display_name": "Anv diskouezet",
|
||||||
"onboarding.profile.display_name_hint": "Hoc'h anv klok pe hoc'h anv fentus…",
|
"onboarding.profile.display_name_hint": "Hoc'h anv klok pe hoc'h anv fentus…",
|
||||||
"onboarding.profile.note": "Berr-ha-berr",
|
"onboarding.profile.note": "Berr-ha-berr",
|
||||||
"onboarding.profile.note_hint": "Gallout a rit @menegiñ tud all pe #hashtagoù…",
|
"onboarding.profile.note_hint": "Gallout a rit @menegiñ tud all pe #gerioù-klik…",
|
||||||
"onboarding.profile.save_and_continue": "Enrollañ ha kenderc'hel",
|
"onboarding.profile.save_and_continue": "Enrollañ ha kenderc'hel",
|
||||||
"onboarding.profile.upload_avatar": "Enporzhiañ ur skeudenn profil",
|
"onboarding.profile.upload_avatar": "Enporzhiañ ur skeudenn profil",
|
||||||
"password_confirmation.mismatching": "Disheñvel eo an daou c'her-termen-se",
|
"password_confirmation.mismatching": "Disheñvel eo an daou c'her-termen-se",
|
||||||
@ -480,6 +509,7 @@
|
|||||||
"relative_time.minutes": "{number}m",
|
"relative_time.minutes": "{number}m",
|
||||||
"relative_time.seconds": "{number}eil",
|
"relative_time.seconds": "{number}eil",
|
||||||
"relative_time.today": "hiziv",
|
"relative_time.today": "hiziv",
|
||||||
|
"remove_quote_hint.button_label": "Mat eo",
|
||||||
"reply_indicator.cancel": "Nullañ",
|
"reply_indicator.cancel": "Nullañ",
|
||||||
"reply_indicator.poll": "Sontadeg",
|
"reply_indicator.poll": "Sontadeg",
|
||||||
"report.block": "Stankañ",
|
"report.block": "Stankañ",
|
||||||
@ -528,7 +558,7 @@
|
|||||||
"search.placeholder": "Klask",
|
"search.placeholder": "Klask",
|
||||||
"search.quick_action.account_search": "Profiloù a glot gant {x}",
|
"search.quick_action.account_search": "Profiloù a glot gant {x}",
|
||||||
"search.quick_action.go_to_account": "Mont d'ar profil {x}",
|
"search.quick_action.go_to_account": "Mont d'ar profil {x}",
|
||||||
"search.quick_action.go_to_hashtag": "Mont d'an hashtag {x}",
|
"search.quick_action.go_to_hashtag": "Mont d'ar ger-klik {x}",
|
||||||
"search.quick_action.open_url": "Digeriñ an URL e-barzh Mastodon",
|
"search.quick_action.open_url": "Digeriñ an URL e-barzh Mastodon",
|
||||||
"search.quick_action.status_search": "Embannadurioù a glot gant {x}",
|
"search.quick_action.status_search": "Embannadurioù a glot gant {x}",
|
||||||
"search.search_or_paste": "Klask pe pegañ un URL",
|
"search.search_or_paste": "Klask pe pegañ un URL",
|
||||||
@ -541,7 +571,7 @@
|
|||||||
"search_popout.user": "implijer·ez",
|
"search_popout.user": "implijer·ez",
|
||||||
"search_results.accounts": "Profiloù",
|
"search_results.accounts": "Profiloù",
|
||||||
"search_results.all": "Pep tra",
|
"search_results.all": "Pep tra",
|
||||||
"search_results.hashtags": "Hashtagoù",
|
"search_results.hashtags": "Gerioù-klik",
|
||||||
"search_results.no_results": "Disoc'h ebet.",
|
"search_results.no_results": "Disoc'h ebet.",
|
||||||
"search_results.see_all": "Gwelet pep tra",
|
"search_results.see_all": "Gwelet pep tra",
|
||||||
"search_results.statuses": "Toudoù",
|
"search_results.statuses": "Toudoù",
|
||||||
@ -607,6 +637,7 @@
|
|||||||
"subscribed_languages.save": "Enrollañ ar cheñchamantoù",
|
"subscribed_languages.save": "Enrollañ ar cheñchamantoù",
|
||||||
"subscribed_languages.target": "Cheñch ar yezhoù koumanantet evit {target}",
|
"subscribed_languages.target": "Cheñch ar yezhoù koumanantet evit {target}",
|
||||||
"tabs_bar.home": "Degemer",
|
"tabs_bar.home": "Degemer",
|
||||||
|
"tabs_bar.menu": "Lañser",
|
||||||
"tabs_bar.notifications": "Kemennoù",
|
"tabs_bar.notifications": "Kemennoù",
|
||||||
"tabs_bar.publish": "Embannadenn nevez",
|
"tabs_bar.publish": "Embannadenn nevez",
|
||||||
"tabs_bar.search": "Klask",
|
"tabs_bar.search": "Klask",
|
||||||
@ -638,6 +669,8 @@
|
|||||||
"video.hide": "Kuzhat ar video",
|
"video.hide": "Kuzhat ar video",
|
||||||
"video.pause": "Paouez",
|
"video.pause": "Paouez",
|
||||||
"video.play": "Lenn",
|
"video.play": "Lenn",
|
||||||
|
"visibility_modal.privacy_label": "Gwelusted",
|
||||||
"visibility_modal.quote_followers": "Tud koumanantet hepken",
|
"visibility_modal.quote_followers": "Tud koumanantet hepken",
|
||||||
"visibility_modal.quote_public": "Pep den"
|
"visibility_modal.quote_public": "Pep den",
|
||||||
|
"visibility_modal.save": "Enrollañ"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -768,6 +768,9 @@
|
|||||||
"relative_time.minutes": "{number} m",
|
"relative_time.minutes": "{number} m",
|
||||||
"relative_time.seconds": "{number} s",
|
"relative_time.seconds": "{number} s",
|
||||||
"relative_time.today": "dnes",
|
"relative_time.today": "dnes",
|
||||||
|
"remove_quote_hint.button_label": "Chápu",
|
||||||
|
"remove_quote_hint.message": "Můžete to udělat z {icon} nabídky možností.",
|
||||||
|
"remove_quote_hint.title": "Chcete odstranit citovaný příspěvek?",
|
||||||
"reply_indicator.attachments": "{count, plural, one {{counter} příloha} few {{counter} přílohy} other {{counter} příloh}}",
|
"reply_indicator.attachments": "{count, plural, one {{counter} příloha} few {{counter} přílohy} other {{counter} příloh}}",
|
||||||
"reply_indicator.cancel": "Zrušit",
|
"reply_indicator.cancel": "Zrušit",
|
||||||
"reply_indicator.poll": "Anketa",
|
"reply_indicator.poll": "Anketa",
|
||||||
@ -863,6 +866,7 @@
|
|||||||
"status.block": "Blokovat @{name}",
|
"status.block": "Blokovat @{name}",
|
||||||
"status.bookmark": "Přidat do záložek",
|
"status.bookmark": "Přidat do záložek",
|
||||||
"status.cancel_reblog_private": "Zrušit boostnutí",
|
"status.cancel_reblog_private": "Zrušit boostnutí",
|
||||||
|
"status.cannot_quote": "Citování je na tomo příspěvku zakázáno",
|
||||||
"status.cannot_reblog": "Tento příspěvek nemůže být boostnutý",
|
"status.cannot_reblog": "Tento příspěvek nemůže být boostnutý",
|
||||||
"status.context.load_new_replies": "K dispozici jsou nové odpovědi",
|
"status.context.load_new_replies": "K dispozici jsou nové odpovědi",
|
||||||
"status.context.loading": "Hledání dalších odpovědí",
|
"status.context.loading": "Hledání dalších odpovědí",
|
||||||
@ -988,6 +992,7 @@
|
|||||||
"visibility_modal.header": "Viditelnost a interakce",
|
"visibility_modal.header": "Viditelnost a interakce",
|
||||||
"visibility_modal.helper.direct_quoting": "Soukromé zmínky, které jsou vytvořeny na Mastodonu, nemohou být citovány ostatními.",
|
"visibility_modal.helper.direct_quoting": "Soukromé zmínky, které jsou vytvořeny na Mastodonu, nemohou být citovány ostatními.",
|
||||||
"visibility_modal.helper.privacy_editing": "Publikované příspěvky nemohou změnit svou viditelnost.",
|
"visibility_modal.helper.privacy_editing": "Publikované příspěvky nemohou změnit svou viditelnost.",
|
||||||
|
"visibility_modal.helper.privacy_private_self_quote": "Citace vlastních soukromých příspěvků nelze zveřejnit.",
|
||||||
"visibility_modal.helper.private_quoting": "Příspěvky pouze pro sledující, které jsou vytvořeny na Mastodonu, nemohou být citovány ostatními.",
|
"visibility_modal.helper.private_quoting": "Příspěvky pouze pro sledující, které jsou vytvořeny na Mastodonu, nemohou být citovány ostatními.",
|
||||||
"visibility_modal.helper.unlisted_quoting": "Když vás lidé citují, jejich příspěvek bude v časové ose populárních příspěvků také skryt.",
|
"visibility_modal.helper.unlisted_quoting": "Když vás lidé citují, jejich příspěvek bude v časové ose populárních příspěvků také skryt.",
|
||||||
"visibility_modal.instructions": "Nastavte, kdo bude moci interagovat s tímto příspěvkem. Tyto nastavení též můžete změnit pro všechny budoucí příspěvky v <link>Nastavení > Výchozí nastavení příspěvků</link>.",
|
"visibility_modal.instructions": "Nastavte, kdo bude moci interagovat s tímto příspěvkem. Tyto nastavení též můžete změnit pro všechny budoucí příspěvky v <link>Nastavení > Výchozí nastavení příspěvků</link>.",
|
||||||
|
|||||||
@ -768,6 +768,7 @@
|
|||||||
"relative_time.minutes": "{number}m",
|
"relative_time.minutes": "{number}m",
|
||||||
"relative_time.seconds": "{number}s",
|
"relative_time.seconds": "{number}s",
|
||||||
"relative_time.today": "i dag",
|
"relative_time.today": "i dag",
|
||||||
|
"remove_quote_hint.button_label": "Forstået",
|
||||||
"reply_indicator.attachments": "{count, plural, one {# vedhæftning} other {# vedhæftninger}}",
|
"reply_indicator.attachments": "{count, plural, one {# vedhæftning} other {# vedhæftninger}}",
|
||||||
"reply_indicator.cancel": "Afbryd",
|
"reply_indicator.cancel": "Afbryd",
|
||||||
"reply_indicator.poll": "Afstemning",
|
"reply_indicator.poll": "Afstemning",
|
||||||
|
|||||||
@ -768,6 +768,9 @@
|
|||||||
"relative_time.minutes": "{number} Min.",
|
"relative_time.minutes": "{number} Min.",
|
||||||
"relative_time.seconds": "{number} Sek.",
|
"relative_time.seconds": "{number} Sek.",
|
||||||
"relative_time.today": "heute",
|
"relative_time.today": "heute",
|
||||||
|
"remove_quote_hint.button_label": "Verstanden",
|
||||||
|
"remove_quote_hint.message": "Klicke dafür im Beitrag auf „{icon} Mehr“.",
|
||||||
|
"remove_quote_hint.title": "Möchtest du aus dem zitierten Beitrag entfernt werden?",
|
||||||
"reply_indicator.attachments": "{count, plural, one {# Anhang} other {# Anhänge}}",
|
"reply_indicator.attachments": "{count, plural, one {# Anhang} other {# Anhänge}}",
|
||||||
"reply_indicator.cancel": "Abbrechen",
|
"reply_indicator.cancel": "Abbrechen",
|
||||||
"reply_indicator.poll": "Umfrage",
|
"reply_indicator.poll": "Umfrage",
|
||||||
|
|||||||
@ -768,6 +768,9 @@
|
|||||||
"relative_time.minutes": "{number}m",
|
"relative_time.minutes": "{number}m",
|
||||||
"relative_time.seconds": "{number}s",
|
"relative_time.seconds": "{number}s",
|
||||||
"relative_time.today": "today",
|
"relative_time.today": "today",
|
||||||
|
"remove_quote_hint.button_label": "Got it",
|
||||||
|
"remove_quote_hint.message": "You can do so from the {icon} options menu.",
|
||||||
|
"remove_quote_hint.title": "Want to remove your quoted post?",
|
||||||
"reply_indicator.attachments": "{count, plural, one {# attachment} other {# attachments}}",
|
"reply_indicator.attachments": "{count, plural, one {# attachment} other {# attachments}}",
|
||||||
"reply_indicator.cancel": "Cancel",
|
"reply_indicator.cancel": "Cancel",
|
||||||
"reply_indicator.poll": "Poll",
|
"reply_indicator.poll": "Poll",
|
||||||
@ -910,7 +913,7 @@
|
|||||||
"status.read_more": "Read more",
|
"status.read_more": "Read more",
|
||||||
"status.reblog": "Boost",
|
"status.reblog": "Boost",
|
||||||
"status.reblog_or_quote": "Boost or quote",
|
"status.reblog_or_quote": "Boost or quote",
|
||||||
"status.reblog_private": "Boost with original visibility",
|
"status.reblog_private": "Share again with your followers",
|
||||||
"status.reblogged_by": "{name} boosted",
|
"status.reblogged_by": "{name} boosted",
|
||||||
"status.reblogs": "{count, plural, one {boost} other {boosts}}",
|
"status.reblogs": "{count, plural, one {boost} other {boosts}}",
|
||||||
"status.reblogs.empty": "No one has boosted this post yet. When someone does, they will show up here.",
|
"status.reblogs.empty": "No one has boosted this post yet. When someone does, they will show up here.",
|
||||||
@ -988,7 +991,7 @@
|
|||||||
"visibility_modal.button_title": "Set visibility",
|
"visibility_modal.button_title": "Set visibility",
|
||||||
"visibility_modal.header": "Visibility and interaction",
|
"visibility_modal.header": "Visibility and interaction",
|
||||||
"visibility_modal.helper.direct_quoting": "Private mentions authored on Mastodon can't be quoted by others.",
|
"visibility_modal.helper.direct_quoting": "Private mentions authored on Mastodon can't be quoted by others.",
|
||||||
"visibility_modal.helper.privacy_editing": "Published posts cannot change their visibility.",
|
"visibility_modal.helper.privacy_editing": "Visibility can't be changed after a post is published.",
|
||||||
"visibility_modal.helper.privacy_private_self_quote": "Self-quotes of private posts cannot be made public.",
|
"visibility_modal.helper.privacy_private_self_quote": "Self-quotes of private posts cannot be made public.",
|
||||||
"visibility_modal.helper.private_quoting": "Follower-only posts authored on Mastodon can't be quoted by others.",
|
"visibility_modal.helper.private_quoting": "Follower-only posts authored on Mastodon can't be quoted by others.",
|
||||||
"visibility_modal.helper.unlisted_quoting": "When people quote you, their post will also be hidden from trending timelines.",
|
"visibility_modal.helper.unlisted_quoting": "When people quote you, their post will also be hidden from trending timelines.",
|
||||||
|
|||||||
@ -30,6 +30,8 @@
|
|||||||
"account.edit_profile": "Redakti la profilon",
|
"account.edit_profile": "Redakti la profilon",
|
||||||
"account.enable_notifications": "Sciigu min kiam @{name} afiŝos",
|
"account.enable_notifications": "Sciigu min kiam @{name} afiŝos",
|
||||||
"account.endorse": "Montri en profilo",
|
"account.endorse": "Montri en profilo",
|
||||||
|
"account.familiar_followers_one": "Sekvita de {name1}",
|
||||||
|
"account.familiar_followers_two": "Sekvita de {name1} kaj {name2}",
|
||||||
"account.featured": "Montrita",
|
"account.featured": "Montrita",
|
||||||
"account.featured.accounts": "Profiloj",
|
"account.featured.accounts": "Profiloj",
|
||||||
"account.featured.hashtags": "Kradvortoj",
|
"account.featured.hashtags": "Kradvortoj",
|
||||||
@ -305,6 +307,7 @@
|
|||||||
"emoji_button.search_results": "Serĉaj rezultoj",
|
"emoji_button.search_results": "Serĉaj rezultoj",
|
||||||
"emoji_button.symbols": "Simboloj",
|
"emoji_button.symbols": "Simboloj",
|
||||||
"emoji_button.travel": "Vojaĝoj kaj lokoj",
|
"emoji_button.travel": "Vojaĝoj kaj lokoj",
|
||||||
|
"empty_column.account_featured.me": "Vi ankoraŭ nenion prezentis. Ĉu vi sciis, ke vi povas prezenti viajn plej ofte uzatajn kradvortojn, kaj eĉ la kontojn de viaj amikoj sur via profilo?",
|
||||||
"empty_column.account_featured_other.unknown": "Ĉi tiu konto ankoraŭ ne montris ion ajn.",
|
"empty_column.account_featured_other.unknown": "Ĉi tiu konto ankoraŭ ne montris ion ajn.",
|
||||||
"empty_column.account_hides_collections": "Ĉi tiu uzanto elektis ne disponebligi ĉi tiu informon",
|
"empty_column.account_hides_collections": "Ĉi tiu uzanto elektis ne disponebligi ĉi tiu informon",
|
||||||
"empty_column.account_suspended": "Konto suspendita",
|
"empty_column.account_suspended": "Konto suspendita",
|
||||||
@ -338,6 +341,7 @@
|
|||||||
"explore.trending_links": "Novaĵoj",
|
"explore.trending_links": "Novaĵoj",
|
||||||
"explore.trending_statuses": "Afiŝoj",
|
"explore.trending_statuses": "Afiŝoj",
|
||||||
"explore.trending_tags": "Kradvortoj",
|
"explore.trending_tags": "Kradvortoj",
|
||||||
|
"featured_carousel.header": "{count, plural, one {Alpinglita afiŝo} other {Alpinglitaj afiŝoj}}",
|
||||||
"featured_carousel.next": "Antaŭen",
|
"featured_carousel.next": "Antaŭen",
|
||||||
"featured_carousel.post": "Afiŝi",
|
"featured_carousel.post": "Afiŝi",
|
||||||
"featured_carousel.previous": "Malantaŭen",
|
"featured_carousel.previous": "Malantaŭen",
|
||||||
@ -751,6 +755,9 @@
|
|||||||
"relative_time.minutes": "{number}m",
|
"relative_time.minutes": "{number}m",
|
||||||
"relative_time.seconds": "{number}s",
|
"relative_time.seconds": "{number}s",
|
||||||
"relative_time.today": "hodiaŭ",
|
"relative_time.today": "hodiaŭ",
|
||||||
|
"remove_quote_hint.button_label": "Komprenite",
|
||||||
|
"remove_quote_hint.message": "Vi povas fari tion el la menuo de opcioj {icon}.",
|
||||||
|
"remove_quote_hint.title": "Ĉu vi volas forigi vian cititan afiŝon?",
|
||||||
"reply_indicator.attachments": "{count, plural, one {# aldonaĵo} other {# aldonaĵoj}}",
|
"reply_indicator.attachments": "{count, plural, one {# aldonaĵo} other {# aldonaĵoj}}",
|
||||||
"reply_indicator.cancel": "Nuligi",
|
"reply_indicator.cancel": "Nuligi",
|
||||||
"reply_indicator.poll": "Balotenketo",
|
"reply_indicator.poll": "Balotenketo",
|
||||||
@ -846,6 +853,7 @@
|
|||||||
"status.block": "Bloki @{name}",
|
"status.block": "Bloki @{name}",
|
||||||
"status.bookmark": "Aldoni al la legosignoj",
|
"status.bookmark": "Aldoni al la legosignoj",
|
||||||
"status.cancel_reblog_private": "Ne plu diskonigi",
|
"status.cancel_reblog_private": "Ne plu diskonigi",
|
||||||
|
"status.cannot_quote": "Citaĵoj estas malebligitaj en ĉi tiu afiŝo",
|
||||||
"status.cannot_reblog": "Ĉi tiun afiŝon ne eblas diskonigi",
|
"status.cannot_reblog": "Ĉi tiun afiŝon ne eblas diskonigi",
|
||||||
"status.context.load_new_replies": "Disponeblaj novaj respondoj",
|
"status.context.load_new_replies": "Disponeblaj novaj respondoj",
|
||||||
"status.context.loading": "Serĉante pliajn respondojn",
|
"status.context.loading": "Serĉante pliajn respondojn",
|
||||||
@ -971,6 +979,7 @@
|
|||||||
"visibility_modal.helper.privacy_editing": "Publikigitaj afiŝoj ne povas ŝanĝi sian videblon.",
|
"visibility_modal.helper.privacy_editing": "Publikigitaj afiŝoj ne povas ŝanĝi sian videblon.",
|
||||||
"visibility_modal.helper.private_quoting": "Afiŝoj nur por sekvantoj verkitaj ĉe Mastodon ne povas esti cititaj de aliaj.",
|
"visibility_modal.helper.private_quoting": "Afiŝoj nur por sekvantoj verkitaj ĉe Mastodon ne povas esti cititaj de aliaj.",
|
||||||
"visibility_modal.helper.unlisted_quoting": "Kiam homoj citas vin, ilia afiŝo ankaŭ estos kaŝita de tendencaj templinioj.",
|
"visibility_modal.helper.unlisted_quoting": "Kiam homoj citas vin, ilia afiŝo ankaŭ estos kaŝita de tendencaj templinioj.",
|
||||||
|
"visibility_modal.privacy_label": "Videbleco",
|
||||||
"visibility_modal.quote_followers": "Nur sekvantoj",
|
"visibility_modal.quote_followers": "Nur sekvantoj",
|
||||||
"visibility_modal.quote_label": "Kiu povas citi",
|
"visibility_modal.quote_label": "Kiu povas citi",
|
||||||
"visibility_modal.quote_nobody": "Nur mi",
|
"visibility_modal.quote_nobody": "Nur mi",
|
||||||
|
|||||||
@ -768,6 +768,9 @@
|
|||||||
"relative_time.minutes": "{number}m",
|
"relative_time.minutes": "{number}m",
|
||||||
"relative_time.seconds": "{number}s",
|
"relative_time.seconds": "{number}s",
|
||||||
"relative_time.today": "hoy",
|
"relative_time.today": "hoy",
|
||||||
|
"remove_quote_hint.button_label": "Entendido",
|
||||||
|
"remove_quote_hint.message": "Podés hacerlo desde el menú de opciones {icon}.",
|
||||||
|
"remove_quote_hint.title": "¿Querés eliminar tu mensaje citado?",
|
||||||
"reply_indicator.attachments": "{count, plural,one {# adjunto} other {# adjuntos}}",
|
"reply_indicator.attachments": "{count, plural,one {# adjunto} other {# adjuntos}}",
|
||||||
"reply_indicator.cancel": "Cancelar",
|
"reply_indicator.cancel": "Cancelar",
|
||||||
"reply_indicator.poll": "Encuesta",
|
"reply_indicator.poll": "Encuesta",
|
||||||
|
|||||||
@ -768,6 +768,9 @@
|
|||||||
"relative_time.minutes": "{number} m",
|
"relative_time.minutes": "{number} m",
|
||||||
"relative_time.seconds": "{number} s",
|
"relative_time.seconds": "{number} s",
|
||||||
"relative_time.today": "hoy",
|
"relative_time.today": "hoy",
|
||||||
|
"remove_quote_hint.button_label": "Entendido",
|
||||||
|
"remove_quote_hint.message": "Puedes hacerlo desde el menú de opciones {icon}.",
|
||||||
|
"remove_quote_hint.title": "¿Quieres eliminar tu publicación citada?",
|
||||||
"reply_indicator.attachments": "{count, plural, one {# adjunto} other {# adjuntos}}",
|
"reply_indicator.attachments": "{count, plural, one {# adjunto} other {# adjuntos}}",
|
||||||
"reply_indicator.cancel": "Cancelar",
|
"reply_indicator.cancel": "Cancelar",
|
||||||
"reply_indicator.poll": "Encuesta",
|
"reply_indicator.poll": "Encuesta",
|
||||||
|
|||||||
@ -768,6 +768,9 @@
|
|||||||
"relative_time.minutes": "{number} m",
|
"relative_time.minutes": "{number} m",
|
||||||
"relative_time.seconds": "{number} s",
|
"relative_time.seconds": "{number} s",
|
||||||
"relative_time.today": "hoy",
|
"relative_time.today": "hoy",
|
||||||
|
"remove_quote_hint.button_label": "Entendido",
|
||||||
|
"remove_quote_hint.message": "Puedes hacerlo desde el menú de opciones {icon}.",
|
||||||
|
"remove_quote_hint.title": "¿Quieres eliminar tu publicación citada?",
|
||||||
"reply_indicator.attachments": "{count, plural, one {# adjunto} other {# adjuntos}}",
|
"reply_indicator.attachments": "{count, plural, one {# adjunto} other {# adjuntos}}",
|
||||||
"reply_indicator.cancel": "Cancelar",
|
"reply_indicator.cancel": "Cancelar",
|
||||||
"reply_indicator.poll": "Encuesta",
|
"reply_indicator.poll": "Encuesta",
|
||||||
|
|||||||
@ -863,6 +863,7 @@
|
|||||||
"status.block": "Blokeeri @{name}",
|
"status.block": "Blokeeri @{name}",
|
||||||
"status.bookmark": "Järjehoidja",
|
"status.bookmark": "Järjehoidja",
|
||||||
"status.cancel_reblog_private": "Lõpeta jagamine",
|
"status.cancel_reblog_private": "Lõpeta jagamine",
|
||||||
|
"status.cannot_quote": "Selle postituse tsiteerimine pole lubatud",
|
||||||
"status.cannot_reblog": "Seda postitust ei saa jagada",
|
"status.cannot_reblog": "Seda postitust ei saa jagada",
|
||||||
"status.context.load_new_replies": "Leidub uusi vastuseid",
|
"status.context.load_new_replies": "Leidub uusi vastuseid",
|
||||||
"status.context.loading": "Kontrollin täiendavate vastuste olemasolu",
|
"status.context.loading": "Kontrollin täiendavate vastuste olemasolu",
|
||||||
@ -988,9 +989,13 @@
|
|||||||
"visibility_modal.header": "Nähtavus ja kasutus",
|
"visibility_modal.header": "Nähtavus ja kasutus",
|
||||||
"visibility_modal.helper.direct_quoting": "Ainult mainituile mõeldud Mastodoni postitusi ei saa teiste poolt tsiteerida.",
|
"visibility_modal.helper.direct_quoting": "Ainult mainituile mõeldud Mastodoni postitusi ei saa teiste poolt tsiteerida.",
|
||||||
"visibility_modal.helper.privacy_editing": "Avaldatud postitused ei saa muuta oma nähtavust.",
|
"visibility_modal.helper.privacy_editing": "Avaldatud postitused ei saa muuta oma nähtavust.",
|
||||||
|
"visibility_modal.helper.privacy_private_self_quote": "Privaatsete postituste tsiteerimist oma enda poolt pole võimalik teha avalikuks.",
|
||||||
"visibility_modal.helper.private_quoting": "Ainult jälgijatele mõeldud Mastodoni postitusi ei saa teiste poolt tsiteerida.",
|
"visibility_modal.helper.private_quoting": "Ainult jälgijatele mõeldud Mastodoni postitusi ei saa teiste poolt tsiteerida.",
|
||||||
"visibility_modal.helper.unlisted_quoting": "Kui teised kasutajad sind tsiteerivad, siis nende postitused peidetakse ajajoonelt, mis näitavad populaarsust koguvaid postitusi.",
|
"visibility_modal.helper.unlisted_quoting": "Kui teised kasutajad sind tsiteerivad, siis nende postitused peidetakse ajajoonelt, mis näitavad populaarsust koguvaid postitusi.",
|
||||||
|
"visibility_modal.instructions": "Halda seda, kes võivad antud postitusega suhestuda. Lisaks võid kõikide tulevaste postituste seadistusi muuta valikust <link>Eelistused > Postituse vaikeseadistused</link>.",
|
||||||
|
"visibility_modal.privacy_label": "Nähtavus",
|
||||||
"visibility_modal.quote_followers": "Ainult jälgijad",
|
"visibility_modal.quote_followers": "Ainult jälgijad",
|
||||||
|
"visibility_modal.quote_label": "Kes võivad tsiteerida",
|
||||||
"visibility_modal.quote_nobody": "Ainult mina",
|
"visibility_modal.quote_nobody": "Ainult mina",
|
||||||
"visibility_modal.quote_public": "Kõik",
|
"visibility_modal.quote_public": "Kõik",
|
||||||
"visibility_modal.save": "Salvesta"
|
"visibility_modal.save": "Salvesta"
|
||||||
|
|||||||
@ -852,6 +852,7 @@
|
|||||||
"status.block": "انسداد @{name}",
|
"status.block": "انسداد @{name}",
|
||||||
"status.bookmark": "نشانک",
|
"status.bookmark": "نشانک",
|
||||||
"status.cancel_reblog_private": "ناتقویت",
|
"status.cancel_reblog_private": "ناتقویت",
|
||||||
|
"status.cannot_quote": "نقل قول برای این پست غیرفعال است",
|
||||||
"status.cannot_reblog": "این فرسته قابل تقویت نیست",
|
"status.cannot_reblog": "این فرسته قابل تقویت نیست",
|
||||||
"status.context.load_new_replies": "پاسخهای جدیدی موجودند",
|
"status.context.load_new_replies": "پاسخهای جدیدی موجودند",
|
||||||
"status.context.loading": "بررسی کردن برای پاسخهای بیشتر",
|
"status.context.loading": "بررسی کردن برای پاسخهای بیشتر",
|
||||||
|
|||||||
@ -768,6 +768,9 @@
|
|||||||
"relative_time.minutes": "{number} min",
|
"relative_time.minutes": "{number} min",
|
||||||
"relative_time.seconds": "{number} s",
|
"relative_time.seconds": "{number} s",
|
||||||
"relative_time.today": "tänään",
|
"relative_time.today": "tänään",
|
||||||
|
"remove_quote_hint.button_label": "Selvä",
|
||||||
|
"remove_quote_hint.message": "Voit tehdä sen {icon}-valikosta.",
|
||||||
|
"remove_quote_hint.title": "Haluatko poistaa lainatun julkaisusi?",
|
||||||
"reply_indicator.attachments": "{count, plural, one {# liite} other {# liitettä}}",
|
"reply_indicator.attachments": "{count, plural, one {# liite} other {# liitettä}}",
|
||||||
"reply_indicator.cancel": "Peruuta",
|
"reply_indicator.cancel": "Peruuta",
|
||||||
"reply_indicator.poll": "Äänestys",
|
"reply_indicator.poll": "Äänestys",
|
||||||
|
|||||||
@ -490,6 +490,7 @@
|
|||||||
"keyboard_shortcuts.open_media": "Ouvrir média",
|
"keyboard_shortcuts.open_media": "Ouvrir média",
|
||||||
"keyboard_shortcuts.pinned": "Ouvrir la liste de publications épinglés",
|
"keyboard_shortcuts.pinned": "Ouvrir la liste de publications épinglés",
|
||||||
"keyboard_shortcuts.profile": "Ouvrir le profil de l’auteur·rice",
|
"keyboard_shortcuts.profile": "Ouvrir le profil de l’auteur·rice",
|
||||||
|
"keyboard_shortcuts.quote": "Citer la publication",
|
||||||
"keyboard_shortcuts.reply": "Répondre au message",
|
"keyboard_shortcuts.reply": "Répondre au message",
|
||||||
"keyboard_shortcuts.requests": "Ouvrir la liste de demandes d’abonnement",
|
"keyboard_shortcuts.requests": "Ouvrir la liste de demandes d’abonnement",
|
||||||
"keyboard_shortcuts.search": "Focuser sur le champ de recherche",
|
"keyboard_shortcuts.search": "Focuser sur le champ de recherche",
|
||||||
@ -599,6 +600,7 @@
|
|||||||
"notification.label.mention": "Mention",
|
"notification.label.mention": "Mention",
|
||||||
"notification.label.private_mention": "Mention privée",
|
"notification.label.private_mention": "Mention privée",
|
||||||
"notification.label.private_reply": "Répondre en privé",
|
"notification.label.private_reply": "Répondre en privé",
|
||||||
|
"notification.label.quote": "{name} a cité votre publication",
|
||||||
"notification.label.reply": "Réponse",
|
"notification.label.reply": "Réponse",
|
||||||
"notification.mention": "Mention",
|
"notification.mention": "Mention",
|
||||||
"notification.mentioned_you": "{name} vous a mentionné·e",
|
"notification.mentioned_you": "{name} vous a mentionné·e",
|
||||||
@ -613,6 +615,7 @@
|
|||||||
"notification.moderation_warning.action_suspend": "Votre compte a été suspendu.",
|
"notification.moderation_warning.action_suspend": "Votre compte a été suspendu.",
|
||||||
"notification.own_poll": "Votre sondage est terminé",
|
"notification.own_poll": "Votre sondage est terminé",
|
||||||
"notification.poll": "Un sondage auquel vous avez participé vient de se terminer",
|
"notification.poll": "Un sondage auquel vous avez participé vient de se terminer",
|
||||||
|
"notification.quoted_update": "{name} a modifié une publication que vous avez cité",
|
||||||
"notification.reblog": "{name} a boosté votre message",
|
"notification.reblog": "{name} a boosté votre message",
|
||||||
"notification.reblog.name_and_others_with_link": "{name} et <a>{count, plural, one {# autre} other {# autres}}</a> ont boosté votre message",
|
"notification.reblog.name_and_others_with_link": "{name} et <a>{count, plural, one {# autre} other {# autres}}</a> ont boosté votre message",
|
||||||
"notification.relationships_severance_event": "Connexions perdues avec {name}",
|
"notification.relationships_severance_event": "Connexions perdues avec {name}",
|
||||||
@ -656,6 +659,7 @@
|
|||||||
"notifications.column_settings.mention": "Mentions:",
|
"notifications.column_settings.mention": "Mentions:",
|
||||||
"notifications.column_settings.poll": "Résultats des sondages:",
|
"notifications.column_settings.poll": "Résultats des sondages:",
|
||||||
"notifications.column_settings.push": "Notifications push",
|
"notifications.column_settings.push": "Notifications push",
|
||||||
|
"notifications.column_settings.quote": "Citations:",
|
||||||
"notifications.column_settings.reblog": "Boosts:",
|
"notifications.column_settings.reblog": "Boosts:",
|
||||||
"notifications.column_settings.show": "Afficher dans la colonne",
|
"notifications.column_settings.show": "Afficher dans la colonne",
|
||||||
"notifications.column_settings.sound": "Jouer un son",
|
"notifications.column_settings.sound": "Jouer un son",
|
||||||
@ -731,12 +735,18 @@
|
|||||||
"privacy.private.short": "Abonnés",
|
"privacy.private.short": "Abonnés",
|
||||||
"privacy.public.long": "Tout le monde sur et en dehors de Mastodon",
|
"privacy.public.long": "Tout le monde sur et en dehors de Mastodon",
|
||||||
"privacy.public.short": "Public",
|
"privacy.public.short": "Public",
|
||||||
|
"privacy.quote.anyone": "{visibility}, n'importe qui peut citer",
|
||||||
|
"privacy.quote.disabled": "{visibility}, citations désactivées",
|
||||||
|
"privacy.quote.limited": "{visibility}, citations limitées",
|
||||||
"privacy.unlisted.additional": "Se comporte exactement comme « public », sauf que le message n'apparaîtra pas dans les flux en direct, les hashtags, explorer ou la recherche Mastodon, même si vous les avez activé au niveau de votre compte.",
|
"privacy.unlisted.additional": "Se comporte exactement comme « public », sauf que le message n'apparaîtra pas dans les flux en direct, les hashtags, explorer ou la recherche Mastodon, même si vous les avez activé au niveau de votre compte.",
|
||||||
"privacy.unlisted.long": "Moins de fanfares algorithmiques",
|
"privacy.unlisted.long": "Moins de fanfares algorithmiques",
|
||||||
"privacy.unlisted.short": "Public discret",
|
"privacy.unlisted.short": "Public discret",
|
||||||
"privacy_policy.last_updated": "Dernière mise à jour {date}",
|
"privacy_policy.last_updated": "Dernière mise à jour {date}",
|
||||||
"privacy_policy.title": "Politique de confidentialité",
|
"privacy_policy.title": "Politique de confidentialité",
|
||||||
|
"quote_error.poll": "Les citations ne sont pas autorisées avec les sondages.",
|
||||||
|
"quote_error.quote": "Une seule citation à la fois est autorisée.",
|
||||||
"quote_error.unauthorized": "Vous n'êtes pas autorisé⋅e à citer cette publication.",
|
"quote_error.unauthorized": "Vous n'êtes pas autorisé⋅e à citer cette publication.",
|
||||||
|
"quote_error.upload": "La citation n'est pas autorisée avec un média joint.",
|
||||||
"recommended": "Recommandé",
|
"recommended": "Recommandé",
|
||||||
"refresh": "Actualiser",
|
"refresh": "Actualiser",
|
||||||
"regeneration_indicator.please_stand_by": "Veuillez patienter.",
|
"regeneration_indicator.please_stand_by": "Veuillez patienter.",
|
||||||
@ -843,14 +853,17 @@
|
|||||||
"status.admin_account": "Ouvrir l’interface de modération pour @{name}",
|
"status.admin_account": "Ouvrir l’interface de modération pour @{name}",
|
||||||
"status.admin_domain": "Ouvrir l’interface de modération pour {domain}",
|
"status.admin_domain": "Ouvrir l’interface de modération pour {domain}",
|
||||||
"status.admin_status": "Ouvrir ce message dans l’interface de modération",
|
"status.admin_status": "Ouvrir ce message dans l’interface de modération",
|
||||||
|
"status.all_disabled": "Partages et citations sont désactivés",
|
||||||
"status.block": "Bloquer @{name}",
|
"status.block": "Bloquer @{name}",
|
||||||
"status.bookmark": "Ajouter aux signets",
|
"status.bookmark": "Ajouter aux signets",
|
||||||
"status.cancel_reblog_private": "Débooster",
|
"status.cancel_reblog_private": "Débooster",
|
||||||
|
"status.cannot_quote": "Les citations sont désactivées sur cette publication",
|
||||||
"status.cannot_reblog": "Cette publication ne peut pas être boostée",
|
"status.cannot_reblog": "Cette publication ne peut pas être boostée",
|
||||||
"status.context.load_new_replies": "Nouvelles réponses disponibles",
|
"status.context.load_new_replies": "Nouvelles réponses disponibles",
|
||||||
"status.continued_thread": "Suite du fil",
|
"status.continued_thread": "Suite du fil",
|
||||||
"status.copy": "Copier un lien vers cette publication",
|
"status.copy": "Copier un lien vers cette publication",
|
||||||
"status.delete": "Supprimer",
|
"status.delete": "Supprimer",
|
||||||
|
"status.delete.success": "Publication supprimée",
|
||||||
"status.detailed_status": "Vue détaillée de la conversation",
|
"status.detailed_status": "Vue détaillée de la conversation",
|
||||||
"status.direct": "Mention privée @{name}",
|
"status.direct": "Mention privée @{name}",
|
||||||
"status.direct_indicator": "Mention privée",
|
"status.direct_indicator": "Mention privée",
|
||||||
@ -875,9 +888,12 @@
|
|||||||
"status.pin": "Épingler sur profil",
|
"status.pin": "Épingler sur profil",
|
||||||
"status.quote": "Citation",
|
"status.quote": "Citation",
|
||||||
"status.quote.cancel": "Annuler la citation",
|
"status.quote.cancel": "Annuler la citation",
|
||||||
|
"status.quote_error.filtered": "Caché en raison de l'un de vos filtres",
|
||||||
"status.quote_error.not_available": "Publication non disponible",
|
"status.quote_error.not_available": "Publication non disponible",
|
||||||
"status.quote_error.pending_approval": "Publication en attente",
|
"status.quote_error.pending_approval": "Publication en attente",
|
||||||
"status.quote_error.pending_approval_popout.title": "Publication en attente ? Restez calme",
|
"status.quote_error.pending_approval_popout.title": "Publication en attente ? Restez calme",
|
||||||
|
"status.quote_followers_only": "Seul·e·s mes abonné·e·s peuvent citer cette publication",
|
||||||
|
"status.quote_manual_review": "L'auteur va vérifier manuellement",
|
||||||
"status.quote_policy_change": "Changer qui peut vous citer",
|
"status.quote_policy_change": "Changer qui peut vous citer",
|
||||||
"status.quote_private": "Les publications privées ne peuvent pas être citées",
|
"status.quote_private": "Les publications privées ne peuvent pas être citées",
|
||||||
"status.read_more": "En savoir plus",
|
"status.read_more": "En savoir plus",
|
||||||
@ -955,6 +971,10 @@
|
|||||||
"video.volume_up": "Augmenter le volume",
|
"video.volume_up": "Augmenter le volume",
|
||||||
"visibility_modal.button_title": "Définir la visibilité",
|
"visibility_modal.button_title": "Définir la visibilité",
|
||||||
"visibility_modal.header": "Visibilité et interactions",
|
"visibility_modal.header": "Visibilité et interactions",
|
||||||
|
"visibility_modal.privacy_label": "Visibilité",
|
||||||
|
"visibility_modal.quote_followers": "Abonné·e·s seulement",
|
||||||
|
"visibility_modal.quote_label": "Autoriser les citations pour",
|
||||||
|
"visibility_modal.quote_nobody": "Juste moi",
|
||||||
"visibility_modal.quote_public": "Tout le monde",
|
"visibility_modal.quote_public": "Tout le monde",
|
||||||
"visibility_modal.save": "Sauvegarder"
|
"visibility_modal.save": "Sauvegarder"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -490,6 +490,7 @@
|
|||||||
"keyboard_shortcuts.open_media": "Ouvrir le média",
|
"keyboard_shortcuts.open_media": "Ouvrir le média",
|
||||||
"keyboard_shortcuts.pinned": "Ouvrir la liste des messages épinglés",
|
"keyboard_shortcuts.pinned": "Ouvrir la liste des messages épinglés",
|
||||||
"keyboard_shortcuts.profile": "Ouvrir le profil de l’auteur·rice",
|
"keyboard_shortcuts.profile": "Ouvrir le profil de l’auteur·rice",
|
||||||
|
"keyboard_shortcuts.quote": "Citer la publication",
|
||||||
"keyboard_shortcuts.reply": "Répondre au message",
|
"keyboard_shortcuts.reply": "Répondre au message",
|
||||||
"keyboard_shortcuts.requests": "Ouvrir la liste de demandes d’abonnement",
|
"keyboard_shortcuts.requests": "Ouvrir la liste de demandes d’abonnement",
|
||||||
"keyboard_shortcuts.search": "Se placer dans le champ de recherche",
|
"keyboard_shortcuts.search": "Se placer dans le champ de recherche",
|
||||||
@ -599,6 +600,7 @@
|
|||||||
"notification.label.mention": "Mention",
|
"notification.label.mention": "Mention",
|
||||||
"notification.label.private_mention": "Mention privée",
|
"notification.label.private_mention": "Mention privée",
|
||||||
"notification.label.private_reply": "Répondre en privé",
|
"notification.label.private_reply": "Répondre en privé",
|
||||||
|
"notification.label.quote": "{name} a cité votre publication",
|
||||||
"notification.label.reply": "Réponse",
|
"notification.label.reply": "Réponse",
|
||||||
"notification.mention": "Mention",
|
"notification.mention": "Mention",
|
||||||
"notification.mentioned_you": "{name} vous a mentionné·e",
|
"notification.mentioned_you": "{name} vous a mentionné·e",
|
||||||
@ -613,6 +615,7 @@
|
|||||||
"notification.moderation_warning.action_suspend": "Votre compte a été suspendu.",
|
"notification.moderation_warning.action_suspend": "Votre compte a été suspendu.",
|
||||||
"notification.own_poll": "Votre sondage est terminé",
|
"notification.own_poll": "Votre sondage est terminé",
|
||||||
"notification.poll": "Un sondage auquel vous avez participé vient de se terminer",
|
"notification.poll": "Un sondage auquel vous avez participé vient de se terminer",
|
||||||
|
"notification.quoted_update": "{name} a modifié une publication que vous avez cité",
|
||||||
"notification.reblog": "{name} a partagé votre message",
|
"notification.reblog": "{name} a partagé votre message",
|
||||||
"notification.reblog.name_and_others_with_link": "{name} et <a>{count, plural, one {# autre} other {# autres}}</a> ont boosté votre message",
|
"notification.reblog.name_and_others_with_link": "{name} et <a>{count, plural, one {# autre} other {# autres}}</a> ont boosté votre message",
|
||||||
"notification.relationships_severance_event": "Connexions perdues avec {name}",
|
"notification.relationships_severance_event": "Connexions perdues avec {name}",
|
||||||
@ -656,6 +659,7 @@
|
|||||||
"notifications.column_settings.mention": "Mentions :",
|
"notifications.column_settings.mention": "Mentions :",
|
||||||
"notifications.column_settings.poll": "Résultats des sondages :",
|
"notifications.column_settings.poll": "Résultats des sondages :",
|
||||||
"notifications.column_settings.push": "Notifications push",
|
"notifications.column_settings.push": "Notifications push",
|
||||||
|
"notifications.column_settings.quote": "Citations:",
|
||||||
"notifications.column_settings.reblog": "Partages :",
|
"notifications.column_settings.reblog": "Partages :",
|
||||||
"notifications.column_settings.show": "Afficher dans la colonne",
|
"notifications.column_settings.show": "Afficher dans la colonne",
|
||||||
"notifications.column_settings.sound": "Jouer un son",
|
"notifications.column_settings.sound": "Jouer un son",
|
||||||
@ -731,12 +735,18 @@
|
|||||||
"privacy.private.short": "Abonnés",
|
"privacy.private.short": "Abonnés",
|
||||||
"privacy.public.long": "Tout le monde sur et en dehors de Mastodon",
|
"privacy.public.long": "Tout le monde sur et en dehors de Mastodon",
|
||||||
"privacy.public.short": "Public",
|
"privacy.public.short": "Public",
|
||||||
|
"privacy.quote.anyone": "{visibility}, n'importe qui peut citer",
|
||||||
|
"privacy.quote.disabled": "{visibility}, citations désactivées",
|
||||||
|
"privacy.quote.limited": "{visibility}, citations limitées",
|
||||||
"privacy.unlisted.additional": "Se comporte exactement comme « public », sauf que le message n'apparaîtra pas dans les flux en direct, les hashtags, explorer ou la recherche Mastodon, même si vous les avez activé au niveau de votre compte.",
|
"privacy.unlisted.additional": "Se comporte exactement comme « public », sauf que le message n'apparaîtra pas dans les flux en direct, les hashtags, explorer ou la recherche Mastodon, même si vous les avez activé au niveau de votre compte.",
|
||||||
"privacy.unlisted.long": "Moins de fanfares algorithmiques",
|
"privacy.unlisted.long": "Moins de fanfares algorithmiques",
|
||||||
"privacy.unlisted.short": "Public discret",
|
"privacy.unlisted.short": "Public discret",
|
||||||
"privacy_policy.last_updated": "Dernière mise à jour {date}",
|
"privacy_policy.last_updated": "Dernière mise à jour {date}",
|
||||||
"privacy_policy.title": "Politique de confidentialité",
|
"privacy_policy.title": "Politique de confidentialité",
|
||||||
|
"quote_error.poll": "Les citations ne sont pas autorisées avec les sondages.",
|
||||||
|
"quote_error.quote": "Une seule citation à la fois est autorisée.",
|
||||||
"quote_error.unauthorized": "Vous n'êtes pas autorisé⋅e à citer cette publication.",
|
"quote_error.unauthorized": "Vous n'êtes pas autorisé⋅e à citer cette publication.",
|
||||||
|
"quote_error.upload": "La citation n'est pas autorisée avec un média joint.",
|
||||||
"recommended": "Recommandé",
|
"recommended": "Recommandé",
|
||||||
"refresh": "Actualiser",
|
"refresh": "Actualiser",
|
||||||
"regeneration_indicator.please_stand_by": "Veuillez patienter.",
|
"regeneration_indicator.please_stand_by": "Veuillez patienter.",
|
||||||
@ -843,14 +853,17 @@
|
|||||||
"status.admin_account": "Ouvrir l’interface de modération pour @{name}",
|
"status.admin_account": "Ouvrir l’interface de modération pour @{name}",
|
||||||
"status.admin_domain": "Ouvrir l’interface de modération pour {domain}",
|
"status.admin_domain": "Ouvrir l’interface de modération pour {domain}",
|
||||||
"status.admin_status": "Ouvrir ce message dans l’interface de modération",
|
"status.admin_status": "Ouvrir ce message dans l’interface de modération",
|
||||||
|
"status.all_disabled": "Partages et citations sont désactivés",
|
||||||
"status.block": "Bloquer @{name}",
|
"status.block": "Bloquer @{name}",
|
||||||
"status.bookmark": "Ajouter aux marque-pages",
|
"status.bookmark": "Ajouter aux marque-pages",
|
||||||
"status.cancel_reblog_private": "Annuler le partage",
|
"status.cancel_reblog_private": "Annuler le partage",
|
||||||
|
"status.cannot_quote": "Les citations sont désactivées sur cette publication",
|
||||||
"status.cannot_reblog": "Ce message ne peut pas être partagé",
|
"status.cannot_reblog": "Ce message ne peut pas être partagé",
|
||||||
"status.context.load_new_replies": "Nouvelles réponses disponibles",
|
"status.context.load_new_replies": "Nouvelles réponses disponibles",
|
||||||
"status.continued_thread": "Suite du fil",
|
"status.continued_thread": "Suite du fil",
|
||||||
"status.copy": "Copier le lien vers le message",
|
"status.copy": "Copier le lien vers le message",
|
||||||
"status.delete": "Supprimer",
|
"status.delete": "Supprimer",
|
||||||
|
"status.delete.success": "Publication supprimée",
|
||||||
"status.detailed_status": "Vue détaillée de la conversation",
|
"status.detailed_status": "Vue détaillée de la conversation",
|
||||||
"status.direct": "Mention privée @{name}",
|
"status.direct": "Mention privée @{name}",
|
||||||
"status.direct_indicator": "Mention privée",
|
"status.direct_indicator": "Mention privée",
|
||||||
@ -875,9 +888,12 @@
|
|||||||
"status.pin": "Épingler sur le profil",
|
"status.pin": "Épingler sur le profil",
|
||||||
"status.quote": "Citation",
|
"status.quote": "Citation",
|
||||||
"status.quote.cancel": "Annuler la citation",
|
"status.quote.cancel": "Annuler la citation",
|
||||||
|
"status.quote_error.filtered": "Caché en raison de l'un de vos filtres",
|
||||||
"status.quote_error.not_available": "Publication non disponible",
|
"status.quote_error.not_available": "Publication non disponible",
|
||||||
"status.quote_error.pending_approval": "Publication en attente",
|
"status.quote_error.pending_approval": "Publication en attente",
|
||||||
"status.quote_error.pending_approval_popout.title": "Publication en attente ? Restez calme",
|
"status.quote_error.pending_approval_popout.title": "Publication en attente ? Restez calme",
|
||||||
|
"status.quote_followers_only": "Seul·e·s mes abonné·e·s peuvent citer cette publication",
|
||||||
|
"status.quote_manual_review": "L'auteur va vérifier manuellement",
|
||||||
"status.quote_policy_change": "Changer qui peut vous citer",
|
"status.quote_policy_change": "Changer qui peut vous citer",
|
||||||
"status.quote_private": "Les publications privées ne peuvent pas être citées",
|
"status.quote_private": "Les publications privées ne peuvent pas être citées",
|
||||||
"status.read_more": "En savoir plus",
|
"status.read_more": "En savoir plus",
|
||||||
@ -955,6 +971,10 @@
|
|||||||
"video.volume_up": "Augmenter le volume",
|
"video.volume_up": "Augmenter le volume",
|
||||||
"visibility_modal.button_title": "Définir la visibilité",
|
"visibility_modal.button_title": "Définir la visibilité",
|
||||||
"visibility_modal.header": "Visibilité et interactions",
|
"visibility_modal.header": "Visibilité et interactions",
|
||||||
|
"visibility_modal.privacy_label": "Visibilité",
|
||||||
|
"visibility_modal.quote_followers": "Abonné·e·s seulement",
|
||||||
|
"visibility_modal.quote_label": "Autoriser les citations pour",
|
||||||
|
"visibility_modal.quote_nobody": "Juste moi",
|
||||||
"visibility_modal.quote_public": "Tout le monde",
|
"visibility_modal.quote_public": "Tout le monde",
|
||||||
"visibility_modal.save": "Sauvegarder"
|
"visibility_modal.save": "Sauvegarder"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -768,6 +768,9 @@
|
|||||||
"relative_time.minutes": "{number}m",
|
"relative_time.minutes": "{number}m",
|
||||||
"relative_time.seconds": "{number}s",
|
"relative_time.seconds": "{number}s",
|
||||||
"relative_time.today": "hoxe",
|
"relative_time.today": "hoxe",
|
||||||
|
"remove_quote_hint.button_label": "Entendido",
|
||||||
|
"remove_quote_hint.message": "Pódelo facer desde o {icon} menú de opcións.",
|
||||||
|
"remove_quote_hint.title": "Queres eliminar a publicación citada?",
|
||||||
"reply_indicator.attachments": "{count, plural, one {# adxunto} other {# adxuntos}}",
|
"reply_indicator.attachments": "{count, plural, one {# adxunto} other {# adxuntos}}",
|
||||||
"reply_indicator.cancel": "Desbotar",
|
"reply_indicator.cancel": "Desbotar",
|
||||||
"reply_indicator.poll": "Enquisa",
|
"reply_indicator.poll": "Enquisa",
|
||||||
|
|||||||
@ -768,6 +768,9 @@
|
|||||||
"relative_time.minutes": "{number} דקות",
|
"relative_time.minutes": "{number} דקות",
|
||||||
"relative_time.seconds": "{number} שניות",
|
"relative_time.seconds": "{number} שניות",
|
||||||
"relative_time.today": "היום",
|
"relative_time.today": "היום",
|
||||||
|
"remove_quote_hint.button_label": "הבנתי",
|
||||||
|
"remove_quote_hint.message": "ניתן לעשות זאת מתפריט האפשרויות {icon}",
|
||||||
|
"remove_quote_hint.title": "להסיר את ההודעה המצוטטת?",
|
||||||
"reply_indicator.attachments": "{count, plural,one {# קובץ מצורף}other {# קבצים מצורפים}}",
|
"reply_indicator.attachments": "{count, plural,one {# קובץ מצורף}other {# קבצים מצורפים}}",
|
||||||
"reply_indicator.cancel": "ביטול",
|
"reply_indicator.cancel": "ביטול",
|
||||||
"reply_indicator.poll": "משאל",
|
"reply_indicator.poll": "משאל",
|
||||||
|
|||||||
@ -768,6 +768,9 @@
|
|||||||
"relative_time.minutes": "{number}mín",
|
"relative_time.minutes": "{number}mín",
|
||||||
"relative_time.seconds": "{number}sek",
|
"relative_time.seconds": "{number}sek",
|
||||||
"relative_time.today": "í dag",
|
"relative_time.today": "í dag",
|
||||||
|
"remove_quote_hint.button_label": "Náði því",
|
||||||
|
"remove_quote_hint.message": "Þú getur gert það úr {icon} valmyndinni.",
|
||||||
|
"remove_quote_hint.title": "Viltu fjarlægja tilvitnuðu færsluna þína?",
|
||||||
"reply_indicator.attachments": "{count, plural, one {# viðhengi} other {# viðhengi}}",
|
"reply_indicator.attachments": "{count, plural, one {# viðhengi} other {# viðhengi}}",
|
||||||
"reply_indicator.cancel": "Hætta við",
|
"reply_indicator.cancel": "Hætta við",
|
||||||
"reply_indicator.poll": "Könnun",
|
"reply_indicator.poll": "Könnun",
|
||||||
|
|||||||
@ -97,8 +97,8 @@
|
|||||||
"admin.impact_report.title": "Ietekmes kopsavilkums",
|
"admin.impact_report.title": "Ietekmes kopsavilkums",
|
||||||
"alert.rate_limited.message": "Lūdzu, mēģini vēlreiz pēc {retry_time, time, medium}.",
|
"alert.rate_limited.message": "Lūdzu, mēģini vēlreiz pēc {retry_time, time, medium}.",
|
||||||
"alert.rate_limited.title": "Biežums ierobežots",
|
"alert.rate_limited.title": "Biežums ierobežots",
|
||||||
"alert.unexpected.message": "Radās negaidīta kļūda.",
|
"alert.unexpected.message": "Atgadījās neparedzēta kļūda.",
|
||||||
"alert.unexpected.title": "Ups!",
|
"alert.unexpected.title": "Ak vai!",
|
||||||
"alt_text_badge.title": "Alt teksts",
|
"alt_text_badge.title": "Alt teksts",
|
||||||
"alt_text_modal.add_alt_text": "Pievienot aprakstošo tekstu",
|
"alt_text_modal.add_alt_text": "Pievienot aprakstošo tekstu",
|
||||||
"alt_text_modal.add_text_from_image": "Pievienot tekstu no attēla",
|
"alt_text_modal.add_text_from_image": "Pievienot tekstu no attēla",
|
||||||
@ -140,7 +140,7 @@
|
|||||||
"bundle_column_error.copy_stacktrace": "Ievietot kļūdu ziņojumu starpliktuvē",
|
"bundle_column_error.copy_stacktrace": "Ievietot kļūdu ziņojumu starpliktuvē",
|
||||||
"bundle_column_error.error.body": "Pieprasīto lapu nevarēja atveidot. Tas varētu būt saistīts ar kļūdu mūsu kodā, vai tā ir pārlūkprogrammas saderības problēma.",
|
"bundle_column_error.error.body": "Pieprasīto lapu nevarēja atveidot. Tas varētu būt saistīts ar kļūdu mūsu kodā, vai tā ir pārlūkprogrammas saderības problēma.",
|
||||||
"bundle_column_error.error.title": "Ak vai!",
|
"bundle_column_error.error.title": "Ak vai!",
|
||||||
"bundle_column_error.network.body": "Mēģinot ielādēt šo lapu, radās kļūda. Tas varētu būt saistīts ar īslaicīgu interneta savienojuma vai šī servera problēmu.",
|
"bundle_column_error.network.body": "Kļūda lapas ielādēšanas laikā. Tas varētu būt īzlaicīgs sarežģījums ar interneta savienojumu vai šo serveri.",
|
||||||
"bundle_column_error.network.title": "Tīkla kļūda",
|
"bundle_column_error.network.title": "Tīkla kļūda",
|
||||||
"bundle_column_error.retry": "Mēģināt vēlreiz",
|
"bundle_column_error.retry": "Mēģināt vēlreiz",
|
||||||
"bundle_column_error.return": "Atgriezties",
|
"bundle_column_error.return": "Atgriezties",
|
||||||
@ -202,7 +202,7 @@
|
|||||||
"compose_form.poll.switch_to_multiple": "Mainīt aptaujas veidu, lai atļautu vairākas izvēles",
|
"compose_form.poll.switch_to_multiple": "Mainīt aptaujas veidu, lai atļautu vairākas izvēles",
|
||||||
"compose_form.poll.switch_to_single": "Mainīt aptaujas veidu, lai atļautu vienu izvēli",
|
"compose_form.poll.switch_to_single": "Mainīt aptaujas veidu, lai atļautu vienu izvēli",
|
||||||
"compose_form.poll.type": "Stils",
|
"compose_form.poll.type": "Stils",
|
||||||
"compose_form.publish": "Nosūtīt",
|
"compose_form.publish": "Iesūtīt",
|
||||||
"compose_form.reply": "Atbildēt",
|
"compose_form.reply": "Atbildēt",
|
||||||
"compose_form.save_changes": "Atjaunināt",
|
"compose_form.save_changes": "Atjaunināt",
|
||||||
"compose_form.spoiler.marked": "Noņemt satura brīdinājumu",
|
"compose_form.spoiler.marked": "Noņemt satura brīdinājumu",
|
||||||
@ -509,10 +509,11 @@
|
|||||||
"navigation_bar.filters": "Apklusinātie vārdi",
|
"navigation_bar.filters": "Apklusinātie vārdi",
|
||||||
"navigation_bar.follow_requests": "Sekošanas pieprasījumi",
|
"navigation_bar.follow_requests": "Sekošanas pieprasījumi",
|
||||||
"navigation_bar.followed_tags": "Sekojamie tēmturi",
|
"navigation_bar.followed_tags": "Sekojamie tēmturi",
|
||||||
"navigation_bar.follows_and_followers": "Sekojamie un sekotāji",
|
"navigation_bar.follows_and_followers": "Seko un sekotāji",
|
||||||
"navigation_bar.lists": "Saraksti",
|
"navigation_bar.lists": "Saraksti",
|
||||||
"navigation_bar.logout": "Iziet",
|
"navigation_bar.logout": "Iziet",
|
||||||
"navigation_bar.moderation": "Satura pārraudzība",
|
"navigation_bar.moderation": "Satura pārraudzība",
|
||||||
|
"navigation_bar.more": "Vairāk",
|
||||||
"navigation_bar.mutes": "Apklusinātie lietotāji",
|
"navigation_bar.mutes": "Apklusinātie lietotāji",
|
||||||
"navigation_bar.opened_in_classic_interface": "Ieraksti, konti un citas noteiktas lapas pēc noklusējuma tiek atvērtas klasiskajā tīmekļa saskarnē.",
|
"navigation_bar.opened_in_classic_interface": "Ieraksti, konti un citas noteiktas lapas pēc noklusējuma tiek atvērtas klasiskajā tīmekļa saskarnē.",
|
||||||
"navigation_bar.preferences": "Iestatījumi",
|
"navigation_bar.preferences": "Iestatījumi",
|
||||||
@ -734,6 +735,7 @@
|
|||||||
"status.bookmark": "Grāmatzīme",
|
"status.bookmark": "Grāmatzīme",
|
||||||
"status.cancel_reblog_private": "Nepastiprināt",
|
"status.cancel_reblog_private": "Nepastiprināt",
|
||||||
"status.cannot_reblog": "Šo ierakstu nevar pastiprināt",
|
"status.cannot_reblog": "Šo ierakstu nevar pastiprināt",
|
||||||
|
"status.context.loading": "Pārbauda, vai ir vairāk atbilžu",
|
||||||
"status.continued_thread": "Turpināts pavediens",
|
"status.continued_thread": "Turpināts pavediens",
|
||||||
"status.copy": "Ievietot ieraksta saiti starpliktuvē",
|
"status.copy": "Ievietot ieraksta saiti starpliktuvē",
|
||||||
"status.delete": "Dzēst",
|
"status.delete": "Dzēst",
|
||||||
|
|||||||
@ -768,6 +768,9 @@
|
|||||||
"relative_time.minutes": "{number}m",
|
"relative_time.minutes": "{number}m",
|
||||||
"relative_time.seconds": "{number}s",
|
"relative_time.seconds": "{number}s",
|
||||||
"relative_time.today": "vandaag",
|
"relative_time.today": "vandaag",
|
||||||
|
"remove_quote_hint.button_label": "Begrepen",
|
||||||
|
"remove_quote_hint.message": "Je kunt dit doen vanuit het {icon} optiesmenu.",
|
||||||
|
"remove_quote_hint.title": "Wil je jouw geciteerd bericht verwijderen?",
|
||||||
"reply_indicator.attachments": "{count, plural, one {# bijlage} other {# bijlagen}}",
|
"reply_indicator.attachments": "{count, plural, one {# bijlage} other {# bijlagen}}",
|
||||||
"reply_indicator.cancel": "Annuleren",
|
"reply_indicator.cancel": "Annuleren",
|
||||||
"reply_indicator.poll": "Peiling",
|
"reply_indicator.poll": "Peiling",
|
||||||
|
|||||||
@ -768,6 +768,9 @@
|
|||||||
"relative_time.minutes": "{number} phút",
|
"relative_time.minutes": "{number} phút",
|
||||||
"relative_time.seconds": "{number}s",
|
"relative_time.seconds": "{number}s",
|
||||||
"relative_time.today": "hôm nay",
|
"relative_time.today": "hôm nay",
|
||||||
|
"remove_quote_hint.button_label": "Đã hiểu",
|
||||||
|
"remove_quote_hint.message": "Bạn cũng có thể làm trong menu tùy chọn {icon}",
|
||||||
|
"remove_quote_hint.title": "Gỡ tút mà bạn đã trích dẫn?",
|
||||||
"reply_indicator.attachments": "{count, plural, other {# tập tin đính kèm}}",
|
"reply_indicator.attachments": "{count, plural, other {# tập tin đính kèm}}",
|
||||||
"reply_indicator.cancel": "Hủy bỏ",
|
"reply_indicator.cancel": "Hủy bỏ",
|
||||||
"reply_indicator.poll": "Vốt",
|
"reply_indicator.poll": "Vốt",
|
||||||
|
|||||||
@ -768,6 +768,9 @@
|
|||||||
"relative_time.minutes": "{number} 分钟前",
|
"relative_time.minutes": "{number} 分钟前",
|
||||||
"relative_time.seconds": "{number} 秒前",
|
"relative_time.seconds": "{number} 秒前",
|
||||||
"relative_time.today": "今天",
|
"relative_time.today": "今天",
|
||||||
|
"remove_quote_hint.button_label": "明白了",
|
||||||
|
"remove_quote_hint.message": "你可以通过 {icon} 选项菜单进行此操作。",
|
||||||
|
"remove_quote_hint.title": "是否需要删除你的引用嘟文?",
|
||||||
"reply_indicator.attachments": "{count, plural, other {# 个附件}}",
|
"reply_indicator.attachments": "{count, plural, other {# 个附件}}",
|
||||||
"reply_indicator.cancel": "取消",
|
"reply_indicator.cancel": "取消",
|
||||||
"reply_indicator.poll": "投票",
|
"reply_indicator.poll": "投票",
|
||||||
|
|||||||
@ -768,6 +768,9 @@
|
|||||||
"relative_time.minutes": "{number} 分鐘前",
|
"relative_time.minutes": "{number} 分鐘前",
|
||||||
"relative_time.seconds": "{number} 秒",
|
"relative_time.seconds": "{number} 秒",
|
||||||
"relative_time.today": "今天",
|
"relative_time.today": "今天",
|
||||||
|
"remove_quote_hint.button_label": "了解",
|
||||||
|
"remove_quote_hint.message": "您能自 {icon} 選單完成此操作。",
|
||||||
|
"remove_quote_hint.title": "是否想要移除您的引用嘟文?",
|
||||||
"reply_indicator.attachments": "{count, plural, other {# 個附加檔案}}",
|
"reply_indicator.attachments": "{count, plural, other {# 個附加檔案}}",
|
||||||
"reply_indicator.cancel": "取消",
|
"reply_indicator.cancel": "取消",
|
||||||
"reply_indicator.poll": "投票",
|
"reply_indicator.poll": "投票",
|
||||||
|
|||||||
@ -101,9 +101,9 @@ const RootStateRecord = ImmutableRecord(initialRootState, 'RootState');
|
|||||||
export const rootReducer = combineReducers(reducers, RootStateRecord);
|
export const rootReducer = combineReducers(reducers, RootStateRecord);
|
||||||
|
|
||||||
export function reducerWithInitialState(
|
export function reducerWithInitialState(
|
||||||
stateOverrides: Record<string, unknown> = {},
|
...stateOverrides: Record<string, unknown>[]
|
||||||
) {
|
) {
|
||||||
const initialStateRecord = mergeDeep(initialRootState, stateOverrides);
|
const initialStateRecord = mergeDeep(initialRootState, ...stateOverrides);
|
||||||
const PatchedRootStateRecord = ImmutableRecord(
|
const PatchedRootStateRecord = ImmutableRecord(
|
||||||
initialStateRecord,
|
initialStateRecord,
|
||||||
'RootState',
|
'RootState',
|
||||||
|
|||||||
@ -117,6 +117,7 @@ const initialState = ImmutableMap({
|
|||||||
'explore/links': false,
|
'explore/links': false,
|
||||||
'explore/statuses': false,
|
'explore/statuses': false,
|
||||||
'explore/tags': false,
|
'explore/tags': false,
|
||||||
|
'notifications/remove_quote_hint': false,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -201,6 +201,41 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.button--plain {
|
||||||
|
color: $highlight-text-color;
|
||||||
|
background: transparent;
|
||||||
|
padding: 6px;
|
||||||
|
|
||||||
|
// The button has no outline, so we use negative margin to
|
||||||
|
// visually align its label with its surroundings while maintaining
|
||||||
|
// a generous click target
|
||||||
|
margin-inline: -6px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&:focus,
|
||||||
|
&:hover {
|
||||||
|
border-color: transparent;
|
||||||
|
color: lighten($highlight-text-color, 4%);
|
||||||
|
background-color: transparent;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled,
|
||||||
|
&.disabled {
|
||||||
|
opacity: 0.7;
|
||||||
|
border-color: transparent;
|
||||||
|
color: $ui-button-disabled-color;
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&:focus,
|
||||||
|
&:hover {
|
||||||
|
border-color: transparent;
|
||||||
|
color: $ui-button-disabled-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.button-tertiary {
|
&.button-tertiary {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
padding: 6px 17px;
|
padding: 6px 17px;
|
||||||
@ -436,8 +471,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body > [data-popper-placement] {
|
[data-popper-placement] {
|
||||||
z-index: 3;
|
z-index: 9999;
|
||||||
}
|
}
|
||||||
|
|
||||||
.invisible {
|
.invisible {
|
||||||
@ -7092,7 +7127,8 @@ a.status-card {
|
|||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-gallery__alt__popover {
|
.info-tooltip {
|
||||||
|
color: $white;
|
||||||
background: color.change($black, $alpha: 0.65);
|
background: color.change($black, $alpha: 0.65);
|
||||||
backdrop-filter: $backdrop-blur-filter;
|
backdrop-filter: $backdrop-blur-filter;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
@ -7104,20 +7140,36 @@ a.status-card {
|
|||||||
max-height: 30em;
|
max-height: 30em;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
|
&--solid {
|
||||||
|
color: var(--nested-card-text);
|
||||||
|
background:
|
||||||
|
/* This is a bit of a silly hack for layering two background colours
|
||||||
|
* since --nested-card-background is too transparent for a tooltip */
|
||||||
|
linear-gradient(
|
||||||
|
var(--nested-card-background),
|
||||||
|
var(--nested-card-background)
|
||||||
|
),
|
||||||
|
linear-gradient(var(--background-color), var(--background-color));
|
||||||
|
border: var(--nested-card-border);
|
||||||
|
}
|
||||||
|
|
||||||
h4 {
|
h4 {
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: $white;
|
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
color: color.change($white, $alpha: 0.85);
|
opacity: 0.85;
|
||||||
white-space: pre-line;
|
white-space: pre-line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
margin-block-start: 8px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.attachment-list {
|
.attachment-list {
|
||||||
|
|||||||
@ -27,7 +27,7 @@ class DomainAllow < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def allowed_domains
|
def allowed_domains
|
||||||
select(:domain)
|
pluck(:domain)
|
||||||
end
|
end
|
||||||
|
|
||||||
def rule_for(domain)
|
def rule_for(domain)
|
||||||
|
|||||||
@ -34,7 +34,7 @@ class Relay < ApplicationRecord
|
|||||||
payload = Oj.dump(follow_activity(activity_id))
|
payload = Oj.dump(follow_activity(activity_id))
|
||||||
|
|
||||||
update!(state: :pending, follow_activity_id: activity_id)
|
update!(state: :pending, follow_activity_id: activity_id)
|
||||||
DeliveryFailureTracker.reset!(inbox_url)
|
reset_delivery_tracker
|
||||||
ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
|
ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -43,12 +43,16 @@ class Relay < ApplicationRecord
|
|||||||
payload = Oj.dump(unfollow_activity(activity_id))
|
payload = Oj.dump(unfollow_activity(activity_id))
|
||||||
|
|
||||||
update!(state: :idle, follow_activity_id: nil)
|
update!(state: :idle, follow_activity_id: nil)
|
||||||
DeliveryFailureTracker.reset!(inbox_url)
|
reset_delivery_tracker
|
||||||
ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
|
ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def reset_delivery_tracker
|
||||||
|
DeliveryFailureTracker.reset!(inbox_url)
|
||||||
|
end
|
||||||
|
|
||||||
def follow_activity(activity_id)
|
def follow_activity(activity_id)
|
||||||
{
|
{
|
||||||
'@context': ActivityPub::TagManager::CONTEXT,
|
'@context': ActivityPub::TagManager::CONTEXT,
|
||||||
|
|||||||
@ -244,6 +244,15 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
|
|||||||
canQuote: {
|
canQuote: {
|
||||||
automaticApproval: approved_uris,
|
automaticApproval: approved_uris,
|
||||||
},
|
},
|
||||||
|
canReply: {
|
||||||
|
always: 'https://www.w3.org/ns/activitystreams#Public',
|
||||||
|
},
|
||||||
|
canLike: {
|
||||||
|
always: 'https://www.w3.org/ns/activitystreams#Public',
|
||||||
|
},
|
||||||
|
canAnnounce: {
|
||||||
|
always: 'https://www.w3.org/ns/activitystreams#Public',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
- if status.with_poll?
|
- if status.with_poll?
|
||||||
.poll
|
.poll
|
||||||
%ul
|
%ul
|
||||||
- status.preloadable_poll.options.each_with_index do |option, _index|
|
- status.preloadable_poll.options.each do |option|
|
||||||
%li
|
%li
|
||||||
%label.poll__option.disabled<>
|
%label.poll__option.disabled<>
|
||||||
- if status.preloadable_poll.multiple?
|
- if status.preloadable_poll.multiple?
|
||||||
|
|||||||
@ -15,6 +15,15 @@ class Web::PushNotificationWorker
|
|||||||
|
|
||||||
return if @notification.updated_at < TTL.ago
|
return if @notification.updated_at < TTL.ago
|
||||||
|
|
||||||
|
# Clean up old Web::PushSubscriptions that were added before validation of
|
||||||
|
# the endpoint and keys: #30542, #30540
|
||||||
|
unless @subscription.valid?
|
||||||
|
Rails.logger.debug { "Web::PushSubscription is invalid, removing: #{subscription_id}" }
|
||||||
|
@subscription.destroy!
|
||||||
|
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
# Polymorphically associated activity could have been deleted
|
# Polymorphically associated activity could have been deleted
|
||||||
# in the meantime, so we have to double-check before proceeding
|
# in the meantime, so we have to double-check before proceeding
|
||||||
return unless @notification.activity.present? && @subscription.pushable?(@notification)
|
return unless @notification.activity.present? && @subscription.pushable?(@notification)
|
||||||
|
|||||||
@ -63,6 +63,7 @@ br:
|
|||||||
all: Pep tra
|
all: Pep tra
|
||||||
local: Lec'hel
|
local: Lec'hel
|
||||||
remote: A-bell
|
remote: A-bell
|
||||||
|
title: Lec'hiadur
|
||||||
media_attachments: Restroù media stag
|
media_attachments: Restroù media stag
|
||||||
moderation:
|
moderation:
|
||||||
active: Oberiant
|
active: Oberiant
|
||||||
@ -180,6 +181,7 @@ br:
|
|||||||
name: Anv
|
name: Anv
|
||||||
registrations:
|
registrations:
|
||||||
confirm: Kadarnaat
|
confirm: Kadarnaat
|
||||||
|
save: Enrollañ
|
||||||
status: Statud
|
status: Statud
|
||||||
follow_recommendations:
|
follow_recommendations:
|
||||||
status: Statud
|
status: Statud
|
||||||
@ -260,6 +262,7 @@ br:
|
|||||||
title: Disklêriadennoù
|
title: Disklêriadennoù
|
||||||
unresolved: Andiskoulmet
|
unresolved: Andiskoulmet
|
||||||
updated_at: Nevesaet
|
updated_at: Nevesaet
|
||||||
|
view_profile: Gwelet ar profil
|
||||||
roles:
|
roles:
|
||||||
categories:
|
categories:
|
||||||
devops: DevOps
|
devops: DevOps
|
||||||
@ -287,6 +290,7 @@ br:
|
|||||||
danger_zone: Takad dañjer
|
danger_zone: Takad dañjer
|
||||||
discovery:
|
discovery:
|
||||||
privacy: Buhez prevez
|
privacy: Buhez prevez
|
||||||
|
profile_directory: Kavlec'h ar profiloù
|
||||||
title: Dizoloadur
|
title: Dizoloadur
|
||||||
trends: Luskadoù
|
trends: Luskadoù
|
||||||
domain_blocks:
|
domain_blocks:
|
||||||
@ -310,6 +314,10 @@ br:
|
|||||||
strikes:
|
strikes:
|
||||||
actions:
|
actions:
|
||||||
delete_statuses: Dilamet eo bet toudoù %{target} gant %{name}
|
delete_statuses: Dilamet eo bet toudoù %{target} gant %{name}
|
||||||
|
tags:
|
||||||
|
title: Gerioù-klik
|
||||||
|
terms_of_service:
|
||||||
|
save_draft: Enrollañ ar brouilhed
|
||||||
trends:
|
trends:
|
||||||
allow: Aotren
|
allow: Aotren
|
||||||
approved: Aprouet
|
approved: Aprouet
|
||||||
@ -324,7 +332,7 @@ br:
|
|||||||
dashboard:
|
dashboard:
|
||||||
tag_uses_measure: implijoù hollek
|
tag_uses_measure: implijoù hollek
|
||||||
not_usable: N'haller ket en implijout
|
not_usable: N'haller ket en implijout
|
||||||
title: Hashtagoù diouzh ar c'hiz
|
title: Gerioù-klik diouzh ar c'hiz
|
||||||
warning_presets:
|
warning_presets:
|
||||||
add_new: Ouzhpenniñ unan nevez
|
add_new: Ouzhpenniñ unan nevez
|
||||||
delete: Dilemel
|
delete: Dilemel
|
||||||
@ -342,7 +350,7 @@ br:
|
|||||||
none: ur c'hemenn diwall
|
none: ur c'hemenn diwall
|
||||||
new_trends:
|
new_trends:
|
||||||
new_trending_tags:
|
new_trending_tags:
|
||||||
title: Hashtagoù diouzh ar c'hiz
|
title: Gerioù-klik diouzh ar c'hiz
|
||||||
appearance:
|
appearance:
|
||||||
discovery: Dizoloadur
|
discovery: Dizoloadur
|
||||||
localization:
|
localization:
|
||||||
@ -350,6 +358,7 @@ br:
|
|||||||
guide_link: https://crowdin.com/project/mastodon
|
guide_link: https://crowdin.com/project/mastodon
|
||||||
application_mailer:
|
application_mailer:
|
||||||
view: 'Sellet :'
|
view: 'Sellet :'
|
||||||
|
view_profile: Gwelet ar profil
|
||||||
view_status: Gwelet ar c'hannad
|
view_status: Gwelet ar c'hannad
|
||||||
auth:
|
auth:
|
||||||
delete_account: Dilemel ar gont
|
delete_account: Dilemel ar gont
|
||||||
@ -396,6 +405,8 @@ br:
|
|||||||
created_at: Deiziad
|
created_at: Deiziad
|
||||||
title_actions:
|
title_actions:
|
||||||
none: Diwall
|
none: Diwall
|
||||||
|
edit_profile:
|
||||||
|
other: All
|
||||||
emoji_styles:
|
emoji_styles:
|
||||||
auto: Emgefreek
|
auto: Emgefreek
|
||||||
twemoji: Twemoji
|
twemoji: Twemoji
|
||||||
@ -422,6 +433,8 @@ br:
|
|||||||
other: "%{count} a gannadoù"
|
other: "%{count} a gannadoù"
|
||||||
two: "%{count} gannad"
|
two: "%{count} gannad"
|
||||||
title: Siloù
|
title: Siloù
|
||||||
|
new:
|
||||||
|
save: Enrollañ ar sil nevez
|
||||||
statuses:
|
statuses:
|
||||||
index:
|
index:
|
||||||
title: Toudoù silet
|
title: Toudoù silet
|
||||||
@ -547,7 +560,7 @@ br:
|
|||||||
back: Distreiñ da vMastodon
|
back: Distreiñ da vMastodon
|
||||||
development: Diorren
|
development: Diorren
|
||||||
edit_profile: Kemmañ ar profil
|
edit_profile: Kemmañ ar profil
|
||||||
featured_tags: Hashtagoù pennañ
|
featured_tags: Gerioù-klik pennañ
|
||||||
import: Enporzhiañ
|
import: Enporzhiañ
|
||||||
import_and_export: Enporzhiañ hag ezporzhiañ
|
import_and_export: Enporzhiañ hag ezporzhiañ
|
||||||
preferences: Gwellvezioù
|
preferences: Gwellvezioù
|
||||||
@ -609,6 +622,9 @@ br:
|
|||||||
edit_profile_title: Personelaat ho profil
|
edit_profile_title: Personelaat ho profil
|
||||||
feature_action: Gouzout hiroc'h
|
feature_action: Gouzout hiroc'h
|
||||||
follow_action: Heuliañ
|
follow_action: Heuliañ
|
||||||
|
hashtags_title: Gerioù-klik diouzh ar c'hiz
|
||||||
|
hashtags_view_more: Gwelet muioc'h a c'herioù-klik diouzh ar c'hiz
|
||||||
|
share_title: Rannit ho kont Mastodon
|
||||||
sign_in_action: Kevreañ
|
sign_in_action: Kevreañ
|
||||||
subject: Donemat e Mastodon
|
subject: Donemat e Mastodon
|
||||||
title: Degemer mat e bourzh, %{name}!
|
title: Degemer mat e bourzh, %{name}!
|
||||||
|
|||||||
@ -1894,6 +1894,9 @@ cy:
|
|||||||
self_vote: Nid oes modd i chi bleidleisio yn eich polau eich hun
|
self_vote: Nid oes modd i chi bleidleisio yn eich polau eich hun
|
||||||
too_few_options: rhaid cael mwy nag un eitem
|
too_few_options: rhaid cael mwy nag un eitem
|
||||||
too_many_options: ni all gynnwys mwy na %{max} eitem
|
too_many_options: ni all gynnwys mwy na %{max} eitem
|
||||||
|
vote: Pleidleisio
|
||||||
|
posting_defaults:
|
||||||
|
explanation: Bydd y gosodiadau hyn yn cael eu defnyddio fel rhagosodiadau pan fyddwch chi'n creu postiadau newydd, ond gallwch chi eu golygu fesul postiad o fewn y cyfansoddwr.
|
||||||
preferences:
|
preferences:
|
||||||
other: Arall
|
other: Arall
|
||||||
posting_defaults: Rhagosodiadau postio
|
posting_defaults: Rhagosodiadau postio
|
||||||
|
|||||||
@ -367,7 +367,7 @@ en:
|
|||||||
title: Custom emojis
|
title: Custom emojis
|
||||||
uncategorized: Uncategorized
|
uncategorized: Uncategorized
|
||||||
unlist: Unlist
|
unlist: Unlist
|
||||||
unlisted: Quiet public
|
unlisted: Unlisted
|
||||||
update_failed_msg: Could not update that emoji
|
update_failed_msg: Could not update that emoji
|
||||||
updated_msg: Emoji successfully updated!
|
updated_msg: Emoji successfully updated!
|
||||||
upload: Upload
|
upload: Upload
|
||||||
@ -1923,7 +1923,7 @@ en:
|
|||||||
private_long: Only show to followers
|
private_long: Only show to followers
|
||||||
public: Public
|
public: Public
|
||||||
public_long: Anyone on and off Mastodon
|
public_long: Anyone on and off Mastodon
|
||||||
unlisted: Unlisted
|
unlisted: Quiet public
|
||||||
unlisted_long: Hidden from Mastodon search results, trending, and public timelines
|
unlisted_long: Hidden from Mastodon search results, trending, and public timelines
|
||||||
statuses_cleanup:
|
statuses_cleanup:
|
||||||
enabled: Automatically delete old posts
|
enabled: Automatically delete old posts
|
||||||
|
|||||||
@ -581,6 +581,8 @@ eo:
|
|||||||
all: Ĉiuj
|
all: Ĉiuj
|
||||||
limited: Limigita
|
limited: Limigita
|
||||||
title: Moderigado
|
title: Moderigado
|
||||||
|
moderation_notes:
|
||||||
|
title: Notoj de moderigado
|
||||||
private_comment: Privata komento
|
private_comment: Privata komento
|
||||||
public_comment: Publika komento
|
public_comment: Publika komento
|
||||||
purge: Purigu
|
purge: Purigu
|
||||||
@ -1081,12 +1083,18 @@ eo:
|
|||||||
trending: Popularaĵoj
|
trending: Popularaĵoj
|
||||||
username_blocks:
|
username_blocks:
|
||||||
add_new: Aldoni novan
|
add_new: Aldoni novan
|
||||||
|
comparison:
|
||||||
|
contains: Enhavas
|
||||||
|
equals: Egalas
|
||||||
|
contains_html: Enhavas %{string}
|
||||||
delete: Forigi
|
delete: Forigi
|
||||||
edit:
|
edit:
|
||||||
title: Redakti uzantnoman regulon
|
title: Redakti uzantnoman regulon
|
||||||
|
matches_exactly_html: Egalas %{string}
|
||||||
new:
|
new:
|
||||||
create: Krei regulon
|
create: Krei regulon
|
||||||
title: Krei novan uzantnoman regulon
|
title: Krei novan uzantnoman regulon
|
||||||
|
no_username_block_selected: Neniuj uzantnomaj reguloj estis ŝanĝitaj ĉar neniuj estis elektitaj
|
||||||
not_permitted: Ne permesita
|
not_permitted: Ne permesita
|
||||||
title: Uzantnomaj reguloj
|
title: Uzantnomaj reguloj
|
||||||
updated_msg: Sukcese ĝisdatigita uzantnoma regulo
|
updated_msg: Sukcese ĝisdatigita uzantnoma regulo
|
||||||
@ -1356,6 +1364,8 @@ eo:
|
|||||||
other: Alia
|
other: Alia
|
||||||
emoji_styles:
|
emoji_styles:
|
||||||
auto: Aŭtomata
|
auto: Aŭtomata
|
||||||
|
native: Denaska
|
||||||
|
twemoji: Twemoji
|
||||||
errors:
|
errors:
|
||||||
'400': La peto kiun vi sendis estas nevalida au malformas.
|
'400': La peto kiun vi sendis estas nevalida au malformas.
|
||||||
'403': Vi ne havas la rajton por vidi ĉi tiun paĝon.
|
'403': Vi ne havas la rajton por vidi ĉi tiun paĝon.
|
||||||
@ -1720,6 +1730,8 @@ eo:
|
|||||||
too_few_options: devas enhavi pli da unu propono
|
too_few_options: devas enhavi pli da unu propono
|
||||||
too_many_options: ne povas enhavi pli da %{max} proponoj
|
too_many_options: ne povas enhavi pli da %{max} proponoj
|
||||||
vote: Voĉdoni
|
vote: Voĉdoni
|
||||||
|
posting_defaults:
|
||||||
|
explanation: Ĉi tiuj agordoj estos uzataj kiel defaŭltaj kiam vi kreas novajn afiŝojn, sed vi povas redakti ilin per afiŝo en la redaktilo.
|
||||||
preferences:
|
preferences:
|
||||||
other: Aliaj aferoj
|
other: Aliaj aferoj
|
||||||
posting_defaults: Afiŝaj defaŭltoj
|
posting_defaults: Afiŝaj defaŭltoj
|
||||||
@ -1944,6 +1956,9 @@ eo:
|
|||||||
does_not_match_previous_name: ne kongruas kun la antaŭa nomo
|
does_not_match_previous_name: ne kongruas kun la antaŭa nomo
|
||||||
terms_of_service:
|
terms_of_service:
|
||||||
title: Kondiĉoj de uzado
|
title: Kondiĉoj de uzado
|
||||||
|
terms_of_service_interstitial:
|
||||||
|
past_preamble_html: Ni ŝanĝis niajn servkondiĉojn ekde via lasta vizito. Ni instigas vin revizii la ĝisdatigitajn kondiĉojn.
|
||||||
|
title: La servkondiĉoj de %{domain} ŝanĝiĝas
|
||||||
themes:
|
themes:
|
||||||
contrast: Mastodon (Forta kontrasto)
|
contrast: Mastodon (Forta kontrasto)
|
||||||
default: Mastodon (Malhela)
|
default: Mastodon (Malhela)
|
||||||
|
|||||||
@ -1549,8 +1549,8 @@ lv:
|
|||||||
muting: Importē noklusinātos kontus
|
muting: Importē noklusinātos kontus
|
||||||
type: Importa veids
|
type: Importa veids
|
||||||
type_groups:
|
type_groups:
|
||||||
constructive: Seko un Grāmatzīmes
|
constructive: Seko un grāmatzīmes
|
||||||
destructive: Bloķētie un noklusinātie
|
destructive: Liegtie un noklusinātie
|
||||||
types:
|
types:
|
||||||
blocking: Bloķēšanas saraksts
|
blocking: Bloķēšanas saraksts
|
||||||
bookmarks: Grāmatzīmes
|
bookmarks: Grāmatzīmes
|
||||||
|
|||||||
@ -2,6 +2,8 @@
|
|||||||
br:
|
br:
|
||||||
simple_form:
|
simple_form:
|
||||||
hints:
|
hints:
|
||||||
|
account:
|
||||||
|
note: 'Gallout a rit @menegiñ tud all pe #gerioù-klik.'
|
||||||
defaults:
|
defaults:
|
||||||
avatar: WEBP, PNG, GIF pe JPG. Bihanoc'h eget %{size}. A vo izelaet betek %{dimensions}px
|
avatar: WEBP, PNG, GIF pe JPG. Bihanoc'h eget %{size}. A vo izelaet betek %{dimensions}px
|
||||||
header: WEBP, PNG, GIF pe JPG. Bihanoc'h eget %{size}. A vo izelaet betek %{dimensions}px
|
header: WEBP, PNG, GIF pe JPG. Bihanoc'h eget %{size}. A vo izelaet betek %{dimensions}px
|
||||||
@ -56,7 +58,7 @@ br:
|
|||||||
username: Anv
|
username: Anv
|
||||||
whole_word: Ger a-bezh
|
whole_word: Ger a-bezh
|
||||||
featured_tag:
|
featured_tag:
|
||||||
name: Hashtag
|
name: Ger-klik
|
||||||
invite:
|
invite:
|
||||||
comment: Evezhiadenn
|
comment: Evezhiadenn
|
||||||
invite_request:
|
invite_request:
|
||||||
@ -71,8 +73,8 @@ br:
|
|||||||
hint: Titouroù ouzhpenn
|
hint: Titouroù ouzhpenn
|
||||||
text: Reolenn
|
text: Reolenn
|
||||||
tag:
|
tag:
|
||||||
name: Hashtag
|
name: Ger-klik
|
||||||
trendable: Aotren an hashtag-mañ da zont war wel dindan tuadurioù
|
trendable: Aotren ar ger-klik-mañ da zont war wel dindan tuadurioù
|
||||||
user:
|
user:
|
||||||
role: Roll
|
role: Roll
|
||||||
time_zone: Gwerzhid eur
|
time_zone: Gwerzhid eur
|
||||||
|
|||||||
@ -56,10 +56,12 @@ eo:
|
|||||||
scopes: Kiujn API-ojn la aplikaĵo permesiĝos atingi. Se vi elektas supran amplekson, vi ne bezonas elekti la individuajn.
|
scopes: Kiujn API-ojn la aplikaĵo permesiĝos atingi. Se vi elektas supran amplekson, vi ne bezonas elekti la individuajn.
|
||||||
setting_aggregate_reblogs: Ne montri novajn plusendojn de mesaĝoj lastatempe plusenditaj (nur efikas al nove ricevitaj plusendoj)
|
setting_aggregate_reblogs: Ne montri novajn plusendojn de mesaĝoj lastatempe plusenditaj (nur efikas al nove ricevitaj plusendoj)
|
||||||
setting_always_send_emails: Normale, la sciigoj per retpoŝto ne estos senditaj kiam vi uzas Mastodon aktive
|
setting_always_send_emails: Normale, la sciigoj per retpoŝto ne estos senditaj kiam vi uzas Mastodon aktive
|
||||||
|
setting_default_quote_policy: Ĉi tiu agordo nur validos por afiŝoj kreitaj per la sekva versio de Mastodon, sed vi povas elekti vian preferon prepare.
|
||||||
setting_default_sensitive: La tiklaj vidaŭdaĵoj estas implicite kaŝitaj kaj povas esti malkaŝitaj per alklako
|
setting_default_sensitive: La tiklaj vidaŭdaĵoj estas implicite kaŝitaj kaj povas esti malkaŝitaj per alklako
|
||||||
setting_display_media_default: Kaŝi plurmediojn markitajn kiel tiklaj
|
setting_display_media_default: Kaŝi plurmediojn markitajn kiel tiklaj
|
||||||
setting_display_media_hide_all: Ĉiam kaŝi la vidaŭdaĵojn
|
setting_display_media_hide_all: Ĉiam kaŝi la vidaŭdaĵojn
|
||||||
setting_display_media_show_all: Ĉiam montri la vidaŭdaĵojn
|
setting_display_media_show_all: Ĉiam montri la vidaŭdaĵojn
|
||||||
|
setting_emoji_style: Kiel montri emoĝiojn. "Aŭtomata" provos uzi denaskajn emoĝiojn, sed uzas Twemoji por malnovaj retumiloj.
|
||||||
setting_system_scrollbars_ui: Aplikas nur por surtablaj retumiloj baziĝas de Safari kaj Chrome
|
setting_system_scrollbars_ui: Aplikas nur por surtablaj retumiloj baziĝas de Safari kaj Chrome
|
||||||
setting_use_blurhash: Transirojn estas bazita sur la koloroj de la kaŝitaj aŭdovidaĵoj sed ne montri iun ajn detalon
|
setting_use_blurhash: Transirojn estas bazita sur la koloroj de la kaŝitaj aŭdovidaĵoj sed ne montri iun ajn detalon
|
||||||
setting_use_pending_items: Kaŝi tempoliniajn ĝisdatigojn malantaŭ klako anstataŭ aŭtomate rulumi la fluon
|
setting_use_pending_items: Kaŝi tempoliniajn ĝisdatigojn malantaŭ klako anstataŭ aŭtomate rulumi la fluon
|
||||||
@ -148,6 +150,9 @@ eo:
|
|||||||
min_age: Ne devus esti malsupre la minimuma aĝo postulita de la leĝoj de via jurisdikcio.
|
min_age: Ne devus esti malsupre la minimuma aĝo postulita de la leĝoj de via jurisdikcio.
|
||||||
user:
|
user:
|
||||||
chosen_languages: Kun tio markita nur mesaĝoj en elektitaj lingvoj aperos en publikaj tempolinioj
|
chosen_languages: Kun tio markita nur mesaĝoj en elektitaj lingvoj aperos en publikaj tempolinioj
|
||||||
|
date_of_birth:
|
||||||
|
one: Ni devas certigi, ke vi estas almenaŭ %{count}-jaraĝa por uzi %{domain}. Ni ne konservos ĉi tion.
|
||||||
|
other: Ni devas certigi, ke vi estas almenaŭ %{count}-jaraĝaj por uzi %{domain}. Ni ne konservos ĉi tion.
|
||||||
role: La rolo kontrolas kiujn permesojn la uzanto havas.
|
role: La rolo kontrolas kiujn permesojn la uzanto havas.
|
||||||
user_role:
|
user_role:
|
||||||
color: Koloro uzita por la rolo sur la UI, kun RGB-formato
|
color: Koloro uzita por la rolo sur la UI, kun RGB-formato
|
||||||
@ -227,6 +232,8 @@ eo:
|
|||||||
setting_auto_play_gif: Aŭtomate ekigi GIF-ojn
|
setting_auto_play_gif: Aŭtomate ekigi GIF-ojn
|
||||||
setting_boost_modal: Montri konfirman fenestron antaŭ ol diskonigi mesaĝon
|
setting_boost_modal: Montri konfirman fenestron antaŭ ol diskonigi mesaĝon
|
||||||
setting_default_language: Publikada lingvo
|
setting_default_language: Publikada lingvo
|
||||||
|
setting_default_privacy: Afiŝa videblo
|
||||||
|
setting_default_quote_policy: Kiu povas citi
|
||||||
setting_default_sensitive: Ĉiam marki la vidaŭdaĵojn kiel tiklaj
|
setting_default_sensitive: Ĉiam marki la vidaŭdaĵojn kiel tiklaj
|
||||||
setting_delete_modal: Montri konfirman fenestron antaŭ ol forigi mesaĝon
|
setting_delete_modal: Montri konfirman fenestron antaŭ ol forigi mesaĝon
|
||||||
setting_disable_hover_cards: Malebligi profilan antaŭmontron kiam oni musumas
|
setting_disable_hover_cards: Malebligi profilan antaŭmontron kiam oni musumas
|
||||||
@ -235,6 +242,7 @@ eo:
|
|||||||
setting_display_media_default: Implicita
|
setting_display_media_default: Implicita
|
||||||
setting_display_media_hide_all: Kaŝi ĉiujn
|
setting_display_media_hide_all: Kaŝi ĉiujn
|
||||||
setting_display_media_show_all: Montri ĉiujn
|
setting_display_media_show_all: Montri ĉiujn
|
||||||
|
setting_emoji_style: Emoĝio-stilo
|
||||||
setting_expand_spoilers: Ĉiam malfoldas mesaĝojn markitajn per averto pri enhavo
|
setting_expand_spoilers: Ĉiam malfoldas mesaĝojn markitajn per averto pri enhavo
|
||||||
setting_hide_network: Kaŝi viajn sekvantojn kaj sekvatojn
|
setting_hide_network: Kaŝi viajn sekvantojn kaj sekvatojn
|
||||||
setting_missing_alt_text_modal: Montru konfirman dialogon antaŭ afiŝado de aŭdvidaĵoj sen altteksto
|
setting_missing_alt_text_modal: Montru konfirman dialogon antaŭ afiŝado de aŭdvidaĵoj sen altteksto
|
||||||
@ -317,6 +325,7 @@ eo:
|
|||||||
follow_request: Sendi retmesaĝon kiam iu petas sekvi vin
|
follow_request: Sendi retmesaĝon kiam iu petas sekvi vin
|
||||||
mention: Sendi retmesaĝon kiam iu mencias vin
|
mention: Sendi retmesaĝon kiam iu mencias vin
|
||||||
pending_account: Sendi retmesaĝon kiam nova konto bezonas kontrolon
|
pending_account: Sendi retmesaĝon kiam nova konto bezonas kontrolon
|
||||||
|
quote: Iu citis vin
|
||||||
reblog: Sendi retmesaĝon kiam iu diskonigas vian mesaĝon
|
reblog: Sendi retmesaĝon kiam iu diskonigas vian mesaĝon
|
||||||
report: Nova raporto estas proponita
|
report: Nova raporto estas proponita
|
||||||
software_updates:
|
software_updates:
|
||||||
@ -363,6 +372,8 @@ eo:
|
|||||||
name: Nomo
|
name: Nomo
|
||||||
permissions_as_keys: Permesoj
|
permissions_as_keys: Permesoj
|
||||||
position: Prioritato
|
position: Prioritato
|
||||||
|
username_block:
|
||||||
|
allow_with_approval: Permesi aliĝojn kun aprobo
|
||||||
webhook:
|
webhook:
|
||||||
events: Ŝaltitaj eventoj
|
events: Ŝaltitaj eventoj
|
||||||
template: Utilŝarĝa ŝablono
|
template: Utilŝarĝa ŝablono
|
||||||
|
|||||||
@ -182,9 +182,9 @@ module Paperclip
|
|||||||
t += 1 if t.negative?
|
t += 1 if t.negative?
|
||||||
t -= 1 if t > 1
|
t -= 1 if t > 1
|
||||||
|
|
||||||
return (p + ((q - p) * 6 * t)) if t < 1 / 6.0
|
return p + ((q - p) * 6 * t) if t < 1 / 6.0
|
||||||
return q if t < 1 / 2.0
|
return q if t < 1 / 2.0
|
||||||
return (p + ((q - p) * ((2 / 3.0) - t) * 6)) if t < 2 / 3.0
|
return p + ((q - p) * ((2 / 3.0) - t) * 6) if t < 2 / 3.0
|
||||||
|
|
||||||
p
|
p
|
||||||
end
|
end
|
||||||
|
|||||||
@ -17,17 +17,6 @@ RSpec.describe Admin::ExportDomainAllowsController do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET #export' do
|
|
||||||
it 'renders instances' do
|
|
||||||
Fabricate(:domain_allow, domain: 'good.domain')
|
|
||||||
Fabricate(:domain_allow, domain: 'better.domain')
|
|
||||||
|
|
||||||
get :export, params: { format: :csv }
|
|
||||||
expect(response).to have_http_status(200)
|
|
||||||
expect(response.body).to eq(domain_allows_csv_file)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'POST #import' do
|
describe 'POST #import' do
|
||||||
it 'allows imported domains' do
|
it 'allows imported domains' do
|
||||||
post :import, params: { admin_import: { data: fixture_file_upload('domain_allows.csv') } }
|
post :import, params: { admin_import: { data: fixture_file_upload('domain_allows.csv') } }
|
||||||
@ -50,10 +39,4 @@ RSpec.describe Admin::ExportDomainAllowsController do
|
|||||||
expect(flash[:error]).to eq(I18n.t('admin.export_domain_allows.no_file'))
|
expect(flash[:error]).to eq(I18n.t('admin.export_domain_allows.no_file'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def domain_allows_csv_file
|
|
||||||
File.read(File.join(file_fixture_path, 'domain_allows.csv'))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -342,42 +342,6 @@ RSpec.describe Auth::RegistrationsController do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when age verification is enabled' do
|
|
||||||
subject { post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', agreement: 'true' }.merge(date_of_birth) } }
|
|
||||||
|
|
||||||
before do
|
|
||||||
Setting.min_age = 16
|
|
||||||
end
|
|
||||||
|
|
||||||
let(:date_of_birth) { {} }
|
|
||||||
|
|
||||||
context 'when date of birth is below age limit' do
|
|
||||||
let(:date_of_birth) { 13.years.ago.then { |date| { 'date_of_birth(1i)': date.day.to_s, 'date_of_birth(2i)': date.month.to_s, 'date_of_birth(3i)': date.year.to_s } } }
|
|
||||||
|
|
||||||
it 'does not create user' do
|
|
||||||
subject
|
|
||||||
user = User.find_by(email: 'test@example.com')
|
|
||||||
expect(user).to be_nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when date of birth is above age limit' do
|
|
||||||
let(:date_of_birth) { 17.years.ago.then { |date| { 'date_of_birth(1i)': date.day.to_s, 'date_of_birth(2i)': date.month.to_s, 'date_of_birth(3i)': date.year.to_s } } }
|
|
||||||
|
|
||||||
it 'redirects to setup and creates user' do
|
|
||||||
subject
|
|
||||||
|
|
||||||
expect(response).to redirect_to auth_setup_path
|
|
||||||
|
|
||||||
expect(User.find_by(email: 'test@example.com'))
|
|
||||||
.to be_present
|
|
||||||
.and have_attributes(
|
|
||||||
age_verified_at: not_eq(nil)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
it_behaves_like 'registration mode based responses', :create
|
it_behaves_like 'registration mode based responses', :create
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -12,4 +12,19 @@ RSpec.describe DomainAllow do
|
|||||||
it { is_expected.to_not allow_value('xn--r9j5b5b').for(:domain) }
|
it { is_expected.to_not allow_value('xn--r9j5b5b').for(:domain) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '.allowed_domains' do
|
||||||
|
subject { described_class.allowed_domains }
|
||||||
|
|
||||||
|
context 'without domain allows' do
|
||||||
|
it { is_expected.to be_an(Array).and(be_empty) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with domain allows' do
|
||||||
|
let!(:allowed_domain) { Fabricate :domain_allow }
|
||||||
|
let!(:other_allowed_domain) { Fabricate :domain_allow }
|
||||||
|
|
||||||
|
it { is_expected.to contain_exactly(allowed_domain.domain, other_allowed_domain.domain) }
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -33,7 +33,7 @@ RSpec.describe Relay do
|
|||||||
|
|
||||||
describe 'Callbacks' do
|
describe 'Callbacks' do
|
||||||
describe 'Ensure disabled on destroy' do
|
describe 'Ensure disabled on destroy' do
|
||||||
before { stub_delivery_worker }
|
before { stub_services }
|
||||||
|
|
||||||
context 'when relay is enabled' do
|
context 'when relay is enabled' do
|
||||||
let(:relay) { Fabricate :relay, state: :accepted }
|
let(:relay) { Fabricate :relay, state: :accepted }
|
||||||
@ -71,7 +71,7 @@ RSpec.describe Relay do
|
|||||||
describe '#disable' do
|
describe '#disable' do
|
||||||
let(:relay) { Fabricate :relay, state: :accepted, follow_activity_id: 'https://host.example/123' }
|
let(:relay) { Fabricate :relay, state: :accepted, follow_activity_id: 'https://host.example/123' }
|
||||||
|
|
||||||
before { stub_delivery_worker }
|
before { stub_services }
|
||||||
|
|
||||||
it 'changes state to idle and removes the activity id' do
|
it 'changes state to idle and removes the activity id' do
|
||||||
expect { relay.disable! }
|
expect { relay.disable! }
|
||||||
@ -79,13 +79,15 @@ RSpec.describe Relay do
|
|||||||
.and change { relay.reload.follow_activity_id }.to(be_nil)
|
.and change { relay.reload.follow_activity_id }.to(be_nil)
|
||||||
expect(ActivityPub::DeliveryWorker)
|
expect(ActivityPub::DeliveryWorker)
|
||||||
.to have_received(:perform_async).with(match('Undo'), Account.representative.id, relay.inbox_url)
|
.to have_received(:perform_async).with(match('Undo'), Account.representative.id, relay.inbox_url)
|
||||||
|
expect(DeliveryFailureTracker)
|
||||||
|
.to have_received(:reset!).with(relay.inbox_url)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#enable' do
|
describe '#enable' do
|
||||||
let(:relay) { Fabricate :relay, state: :idle, follow_activity_id: '' }
|
let(:relay) { Fabricate :relay, state: :idle, follow_activity_id: '' }
|
||||||
|
|
||||||
before { stub_delivery_worker }
|
before { stub_services }
|
||||||
|
|
||||||
it 'changes state to pending and populates the activity id' do
|
it 'changes state to pending and populates the activity id' do
|
||||||
expect { relay.enable! }
|
expect { relay.enable! }
|
||||||
@ -93,10 +95,13 @@ RSpec.describe Relay do
|
|||||||
.and change { relay.reload.follow_activity_id }.to(be_present)
|
.and change { relay.reload.follow_activity_id }.to(be_present)
|
||||||
expect(ActivityPub::DeliveryWorker)
|
expect(ActivityPub::DeliveryWorker)
|
||||||
.to have_received(:perform_async).with(match('Follow'), Account.representative.id, relay.inbox_url)
|
.to have_received(:perform_async).with(match('Follow'), Account.representative.id, relay.inbox_url)
|
||||||
|
expect(DeliveryFailureTracker)
|
||||||
|
.to have_received(:reset!).with(relay.inbox_url)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def stub_delivery_worker
|
def stub_services
|
||||||
allow(ActivityPub::DeliveryWorker).to receive(:perform_async)
|
allow(ActivityPub::DeliveryWorker).to receive(:perform_async)
|
||||||
|
allow(DeliveryFailureTracker).to receive(:reset!)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -3,9 +3,9 @@
|
|||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
RSpec.describe 'Admin Export Domain Allows' do
|
RSpec.describe 'Admin Export Domain Allows' do
|
||||||
describe 'POST /admin/export_domain_allows/import' do
|
before { sign_in Fabricate(:admin_user) }
|
||||||
before { sign_in Fabricate(:admin_user) }
|
|
||||||
|
|
||||||
|
describe 'POST /admin/export_domain_allows/import' do
|
||||||
it 'gracefully handles invalid nested params' do
|
it 'gracefully handles invalid nested params' do
|
||||||
post import_admin_export_domain_allows_path(admin_import: 'invalid')
|
post import_admin_export_domain_allows_path(admin_import: 'invalid')
|
||||||
|
|
||||||
@ -13,4 +13,28 @@ RSpec.describe 'Admin Export Domain Allows' do
|
|||||||
.to redirect_to(admin_instances_path)
|
.to redirect_to(admin_instances_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'GET /admin/export_domain_allows/export.csv' do
|
||||||
|
before do
|
||||||
|
Fabricate(:domain_allow, domain: 'good.domain')
|
||||||
|
Fabricate(:domain_allow, domain: 'better.domain')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns CSV response with instance domain values' do
|
||||||
|
get export_admin_export_domain_allows_path(format: :csv)
|
||||||
|
|
||||||
|
expect(response)
|
||||||
|
.to have_http_status(200)
|
||||||
|
expect(response.body)
|
||||||
|
.to eq(domain_allows_csv_file)
|
||||||
|
expect(response.media_type)
|
||||||
|
.to eq('text/csv')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def domain_allows_csv_file
|
||||||
|
File.read(File.join(file_fixture_path, 'domain_allows.csv'))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -110,9 +110,12 @@ RSpec.describe '/api/v1/accounts' do
|
|||||||
let(:date_of_birth) { 13.years.ago.strftime('%d.%m.%Y') }
|
let(:date_of_birth) { 13.years.ago.strftime('%d.%m.%Y') }
|
||||||
|
|
||||||
it 'returns http unprocessable entity' do
|
it 'returns http unprocessable entity' do
|
||||||
subject
|
expect { subject }
|
||||||
|
.to not_change(User, :count)
|
||||||
|
.and not_change(Account, :count)
|
||||||
|
|
||||||
expect(response).to have_http_status(422)
|
expect(response)
|
||||||
|
.to have_http_status(422)
|
||||||
expect(response.content_type)
|
expect(response.content_type)
|
||||||
.to start_with('application/json')
|
.to start_with('application/json')
|
||||||
end
|
end
|
||||||
@ -122,9 +125,27 @@ RSpec.describe '/api/v1/accounts' do
|
|||||||
let(:date_of_birth) { 17.years.ago.strftime('%d.%m.%Y') }
|
let(:date_of_birth) { 17.years.ago.strftime('%d.%m.%Y') }
|
||||||
|
|
||||||
it 'creates a user', :aggregate_failures do
|
it 'creates a user', :aggregate_failures do
|
||||||
subject
|
expect { subject }
|
||||||
|
.to change(User, :count).by(1)
|
||||||
|
.and change(Account, :count).by(1)
|
||||||
|
|
||||||
expect(response).to have_http_status(200)
|
expect(response)
|
||||||
|
.to have_http_status(200)
|
||||||
|
expect(response.content_type)
|
||||||
|
.to start_with('application/json')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when date of birth is over age limit in ISO-8601 format' do
|
||||||
|
let(:date_of_birth) { 17.years.ago.to_date.iso8601 }
|
||||||
|
|
||||||
|
it 'creates a user', :aggregate_failures do
|
||||||
|
expect { subject }
|
||||||
|
.to change(User, :count).by(1)
|
||||||
|
.and change(Account, :count).by(1)
|
||||||
|
|
||||||
|
expect(response)
|
||||||
|
.to have_http_status(200)
|
||||||
expect(response.content_type)
|
expect(response.content_type)
|
||||||
.to start_with('application/json')
|
.to start_with('application/json')
|
||||||
end
|
end
|
||||||
|
|||||||
58
spec/system/auth/registrations_spec.rb
Normal file
58
spec/system/auth/registrations_spec.rb
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'Auth Registration' do
|
||||||
|
context 'when age verification is enabled' do
|
||||||
|
before { Setting.min_age = 16 }
|
||||||
|
|
||||||
|
context 'when date of birth is below age limit' do
|
||||||
|
let(:date_of_birth) { 13.years.ago }
|
||||||
|
|
||||||
|
it 'does not create user record and displays errors' do
|
||||||
|
visit new_user_registration_path
|
||||||
|
expect(page)
|
||||||
|
.to have_title(I18n.t('auth.register'))
|
||||||
|
|
||||||
|
expect { fill_in_and_submit_form }
|
||||||
|
.to not_change(User, :count)
|
||||||
|
expect(page)
|
||||||
|
.to have_content(/error below/)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when date of birth is above age limit' do
|
||||||
|
let(:date_of_birth) { 17.years.ago }
|
||||||
|
|
||||||
|
it 'creates user and marks as verified' do
|
||||||
|
visit new_user_registration_path
|
||||||
|
expect(page)
|
||||||
|
.to have_title(I18n.t('auth.register'))
|
||||||
|
|
||||||
|
expect { fill_in_and_submit_form }
|
||||||
|
.to change(User, :count).by(1)
|
||||||
|
expect(User.last)
|
||||||
|
.to have_attributes(email: 'test@example.com', age_verified_at: be_present)
|
||||||
|
expect(page)
|
||||||
|
.to have_content(I18n.t('auth.setup.title'))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def fill_in_and_submit_form
|
||||||
|
# Avoid the registration spam check
|
||||||
|
travel_to 10.seconds.from_now
|
||||||
|
|
||||||
|
fill_in 'user_account_attributes_username', with: 'test'
|
||||||
|
fill_in 'user_email', with: 'test@example.com'
|
||||||
|
fill_in 'user_password', with: 'Test.123.Pass'
|
||||||
|
fill_in 'user_password_confirmation', with: 'Test.123.Pass'
|
||||||
|
check 'user_agreement'
|
||||||
|
|
||||||
|
find('input[aria-label="Day"]').fill_in with: date_of_birth.day
|
||||||
|
find('input[autocomplete="bday-month"]').fill_in with: date_of_birth.month
|
||||||
|
find('input[autocomplete="bday-year"]').fill_in with: date_of_birth.year
|
||||||
|
|
||||||
|
click_on I18n.t('auth.register')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -36,6 +36,9 @@ RSpec.describe Web::PushNotificationWorker do
|
|||||||
let(:std_input) { 'When I grow up, I want to be a watermelon' }
|
let(:std_input) { 'When I grow up, I want to be a watermelon' }
|
||||||
let(:std_ciphertext) { 'DGv6ra1nlYgDCS1FRnbzlwAAEABBBP4z9KsN6nGRTbVYI_c7VJSPQTBtkgcy27mlmlMoZIIgDll6e3vCYLocInmYWAmS6TlzAC8wEqKK6PBru3jl7A_yl95bQpu6cVPTpK4Mqgkf1CXztLVBSt2Ks3oZwbuwXPXLWyouBWLVWGNWQexSgSxsj_Qulcy4a-fN' }
|
let(:std_ciphertext) { 'DGv6ra1nlYgDCS1FRnbzlwAAEABBBP4z9KsN6nGRTbVYI_c7VJSPQTBtkgcy27mlmlMoZIIgDll6e3vCYLocInmYWAmS6TlzAC8wEqKK6PBru3jl7A_yl95bQpu6cVPTpK4Mqgkf1CXztLVBSt2Ks3oZwbuwXPXLWyouBWLVWGNWQexSgSxsj_Qulcy4a-fN' }
|
||||||
|
|
||||||
|
# Invalid subscription:
|
||||||
|
let(:invalid_subscription) { Fabricate.build(:web_push_subscription, user_id: user.id, key_p256dh: 'invalid', key_auth: 'invalid', endpoint: endpoint, standard: true, data: { alerts: { notification.type => true } }) }
|
||||||
|
|
||||||
describe 'perform' do
|
describe 'perform' do
|
||||||
around do |example|
|
around do |example|
|
||||||
original_private = Rails.configuration.x.vapid.private_key
|
original_private = Rails.configuration.x.vapid.private_key
|
||||||
@ -83,6 +86,25 @@ RSpec.describe Web::PushNotificationWorker do
|
|||||||
end
|
end
|
||||||
# rubocop:enable RSpec/SubjectStub
|
# rubocop:enable RSpec/SubjectStub
|
||||||
|
|
||||||
|
context 'with invalid record that will fail' do
|
||||||
|
before do
|
||||||
|
# Fabricator always runs validation, here we deliberately want to bypass
|
||||||
|
# the validation, simulating an invalid Web::PushSubscription that was
|
||||||
|
# created before PRs #30542, #30540 added validation.
|
||||||
|
invalid_subscription.save(validate: false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'removes the record and does not process the request' do
|
||||||
|
expect { subject.perform(invalid_subscription.id, notification.id) }
|
||||||
|
.to_not raise_error
|
||||||
|
|
||||||
|
expect { invalid_subscription.reload }
|
||||||
|
.to raise_error ActiveRecord::RecordNotFound
|
||||||
|
|
||||||
|
expect(a_request(:post, endpoint)).to_not have_been_made
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def legacy_web_push_endpoint_request
|
def legacy_web_push_endpoint_request
|
||||||
a_request(
|
a_request(
|
||||||
:post,
|
:post,
|
||||||
|
|||||||
12
yarn.lock
12
yarn.lock
@ -3180,8 +3180,8 @@ __metadata:
|
|||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@reduxjs/toolkit@npm:^2.0.1":
|
"@reduxjs/toolkit@npm:^2.0.1":
|
||||||
version: 2.8.2
|
version: 2.9.0
|
||||||
resolution: "@reduxjs/toolkit@npm:2.8.2"
|
resolution: "@reduxjs/toolkit@npm:2.9.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@standard-schema/spec": "npm:^1.0.0"
|
"@standard-schema/spec": "npm:^1.0.0"
|
||||||
"@standard-schema/utils": "npm:^0.3.0"
|
"@standard-schema/utils": "npm:^0.3.0"
|
||||||
@ -3197,7 +3197,7 @@ __metadata:
|
|||||||
optional: true
|
optional: true
|
||||||
react-redux:
|
react-redux:
|
||||||
optional: true
|
optional: true
|
||||||
checksum: 10c0/6a7a33bad5f1100340757151ff86ca0c4c248f030ae56ce0e6f1d98b39fa87c8f193e9faa2ebd6d5a4c0416921e9f9f7a2bbdd81156c39f08f6bf5ce70c2b927
|
checksum: 10c0/eef65436b3cd96a264de09e94b8a9d585773578442ef3c1c5f2b3bb261a727405e89b004965198f95c5391645b7dbc6576dc07b46de1bede1d6c62c13c17c7d0
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -11973,8 +11973,8 @@ __metadata:
|
|||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"sass@npm:^1.62.1":
|
"sass@npm:^1.62.1":
|
||||||
version: 1.91.0
|
version: 1.92.0
|
||||||
resolution: "sass@npm:1.91.0"
|
resolution: "sass@npm:1.92.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@parcel/watcher": "npm:^2.4.1"
|
"@parcel/watcher": "npm:^2.4.1"
|
||||||
chokidar: "npm:^4.0.0"
|
chokidar: "npm:^4.0.0"
|
||||||
@ -11985,7 +11985,7 @@ __metadata:
|
|||||||
optional: true
|
optional: true
|
||||||
bin:
|
bin:
|
||||||
sass: sass.js
|
sass: sass.js
|
||||||
checksum: 10c0/5be1c98f7a618cb5f90b62f63d2aa0f78f9bf369c93ec7cd9880752a26b0ead19aa63cc341e8a26ce6c74d080baa5705f1685dff52fe6a3f28a7828ae50182b6
|
checksum: 10c0/bdff9fa6988620e2a81962efdd016e3894d19934cfadc105cf41db767f59dd47afd8ff32840e612ef700cb67e19d9e83c108f1724eb8f0bef56c4877dbe6f14d
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user