Merge pull request #3414 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to ef6405ab28
This commit is contained in:
17
.github/workflows/haml-lint-problem-matcher.json
vendored
17
.github/workflows/haml-lint-problem-matcher.json
vendored
@@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"problemMatcher": [
|
|
||||||
{
|
|
||||||
"owner": "haml-lint",
|
|
||||||
"severity": "warning",
|
|
||||||
"pattern": [
|
|
||||||
{
|
|
||||||
"regexp": "^(.*):(\\d+)\\s\\[W]\\s(.*):\\s(.*)$",
|
|
||||||
"file": 1,
|
|
||||||
"line": 2,
|
|
||||||
"code": 3,
|
|
||||||
"message": 4
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
1
.github/workflows/lint-haml.yml
vendored
1
.github/workflows/lint-haml.yml
vendored
@@ -42,5 +42,4 @@ jobs:
|
|||||||
|
|
||||||
- name: Run haml-lint
|
- name: Run haml-lint
|
||||||
run: |
|
run: |
|
||||||
echo "::add-matcher::.github/workflows/haml-lint-problem-matcher.json"
|
|
||||||
bin/haml-lint --reporter github
|
bin/haml-lint --reporter github
|
||||||
|
|||||||
@@ -749,7 +749,7 @@ GEM
|
|||||||
rspec-expectations (~> 3.13)
|
rspec-expectations (~> 3.13)
|
||||||
rspec-mocks (~> 3.13)
|
rspec-mocks (~> 3.13)
|
||||||
rspec-support (~> 3.13)
|
rspec-support (~> 3.13)
|
||||||
rspec-sidekiq (5.2.0)
|
rspec-sidekiq (5.3.0)
|
||||||
rspec-core (~> 3.0)
|
rspec-core (~> 3.0)
|
||||||
rspec-expectations (~> 3.0)
|
rspec-expectations (~> 3.0)
|
||||||
rspec-mocks (~> 3.0)
|
rspec-mocks (~> 3.0)
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
import { apiRequestPost, apiRequestGet } from 'flavours/glitch/api';
|
import {
|
||||||
|
apiRequestPost,
|
||||||
|
apiRequestGet,
|
||||||
|
apiRequestDelete,
|
||||||
|
} from 'flavours/glitch/api';
|
||||||
import type {
|
import type {
|
||||||
ApiAccountJSON,
|
ApiAccountJSON,
|
||||||
ApiFamiliarFollowersJSON,
|
ApiFamiliarFollowersJSON,
|
||||||
} from 'flavours/glitch/api_types/accounts';
|
} from 'flavours/glitch/api_types/accounts';
|
||||||
import type { ApiRelationshipJSON } from 'flavours/glitch/api_types/relationships';
|
import type { ApiRelationshipJSON } from 'flavours/glitch/api_types/relationships';
|
||||||
import type { ApiHashtagJSON } from 'flavours/glitch/api_types/tags';
|
import type {
|
||||||
|
ApiFeaturedTagJSON,
|
||||||
|
ApiHashtagJSON,
|
||||||
|
} from 'flavours/glitch/api_types/tags';
|
||||||
|
|
||||||
export const apiSubmitAccountNote = (id: string, value: string) =>
|
export const apiSubmitAccountNote = (id: string, value: string) =>
|
||||||
apiRequestPost<ApiRelationshipJSON>(`v1/accounts/${id}/note`, {
|
apiRequestPost<ApiRelationshipJSON>(`v1/accounts/${id}/note`, {
|
||||||
@@ -30,7 +37,19 @@ export const apiRemoveAccountFromFollowers = (id: string) =>
|
|||||||
);
|
);
|
||||||
|
|
||||||
export const apiGetFeaturedTags = (id: string) =>
|
export const apiGetFeaturedTags = (id: string) =>
|
||||||
apiRequestGet<ApiHashtagJSON>(`v1/accounts/${id}/featured_tags`);
|
apiRequestGet<ApiHashtagJSON[]>(`v1/accounts/${id}/featured_tags`);
|
||||||
|
|
||||||
|
export const apiGetCurrentFeaturedTags = () =>
|
||||||
|
apiRequestGet<ApiFeaturedTagJSON[]>(`v1/featured_tags`);
|
||||||
|
|
||||||
|
export const apiPostFeaturedTag = (name: string) =>
|
||||||
|
apiRequestPost<ApiFeaturedTagJSON>('v1/featured_tags', { name });
|
||||||
|
|
||||||
|
export const apiDeleteFeaturedTag = (id: string) =>
|
||||||
|
apiRequestDelete(`v1/featured_tags/${id}`);
|
||||||
|
|
||||||
|
export const apiGetTagSuggestions = () =>
|
||||||
|
apiRequestGet<ApiHashtagJSON[]>('v1/featured_tags/suggestions');
|
||||||
|
|
||||||
export const apiGetEndorsedAccounts = (id: string) =>
|
export const apiGetEndorsedAccounts = (id: string) =>
|
||||||
apiRequestGet<ApiAccountJSON>(`v1/accounts/${id}/endorsements`);
|
apiRequestGet<ApiAccountJSON>(`v1/accounts/${id}/endorsements`);
|
||||||
|
|||||||
@@ -4,11 +4,29 @@ interface ApiHistoryJSON {
|
|||||||
uses: string;
|
uses: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ApiHashtagJSON {
|
interface ApiHashtagBase {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
url: string;
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ApiHashtagJSON extends ApiHashtagBase {
|
||||||
history: [ApiHistoryJSON, ...ApiHistoryJSON[]];
|
history: [ApiHistoryJSON, ...ApiHistoryJSON[]];
|
||||||
following?: boolean;
|
following?: boolean;
|
||||||
featuring?: boolean;
|
featuring?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ApiFeaturedTagJSON extends ApiHashtagBase {
|
||||||
|
statuses_count: number;
|
||||||
|
last_status_at: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function hashtagToFeaturedTag(tag: ApiHashtagJSON): ApiFeaturedTagJSON {
|
||||||
|
return {
|
||||||
|
id: tag.id,
|
||||||
|
name: tag.name,
|
||||||
|
url: tag.url,
|
||||||
|
statuses_count: 0,
|
||||||
|
last_status_at: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.input {
|
.input {
|
||||||
padding-right: 45px;
|
padding-inline-end: 45px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menuButton {
|
.menuButton {
|
||||||
|
|||||||
@@ -82,11 +82,23 @@ const ComboboxDemo: React.FC = () => {
|
|||||||
|
|
||||||
const meta = {
|
const meta = {
|
||||||
title: 'Components/Form Fields/ComboboxField',
|
title: 'Components/Form Fields/ComboboxField',
|
||||||
component: ComboboxDemo,
|
component: ComboboxField,
|
||||||
} satisfies Meta<typeof ComboboxDemo>;
|
render: () => <ComboboxDemo />,
|
||||||
|
} satisfies Meta<typeof ComboboxField>;
|
||||||
|
|
||||||
export default meta;
|
export default meta;
|
||||||
|
|
||||||
type Story = StoryObj<typeof meta>;
|
type Story = StoryObj<typeof meta>;
|
||||||
|
|
||||||
export const Example: Story = {};
|
export const Example: Story = {
|
||||||
|
args: {
|
||||||
|
// Adding these types to keep TS happy, they're not passed on to `ComboboxDemo`
|
||||||
|
label: '',
|
||||||
|
value: '',
|
||||||
|
onChange: () => undefined,
|
||||||
|
items: [],
|
||||||
|
getItemId: () => '',
|
||||||
|
renderItem: () => <>Nothing</>,
|
||||||
|
onSelectItem: () => undefined,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import type { ComponentPropsWithoutRef } from 'react';
|
|
||||||
import { forwardRef, useCallback, useId, useRef, useState } from 'react';
|
import { forwardRef, useCallback, useId, useRef, useState } from 'react';
|
||||||
|
|
||||||
import { useIntl } from 'react-intl';
|
import { useIntl } from 'react-intl';
|
||||||
@@ -9,6 +8,7 @@ import Overlay from 'react-overlays/Overlay';
|
|||||||
|
|
||||||
import KeyboardArrowDownIcon from '@/material-icons/400-24px/keyboard_arrow_down.svg?react';
|
import KeyboardArrowDownIcon from '@/material-icons/400-24px/keyboard_arrow_down.svg?react';
|
||||||
import KeyboardArrowUpIcon from '@/material-icons/400-24px/keyboard_arrow_up.svg?react';
|
import KeyboardArrowUpIcon from '@/material-icons/400-24px/keyboard_arrow_up.svg?react';
|
||||||
|
import SearchIcon from '@/material-icons/400-24px/search.svg?react';
|
||||||
import { matchWidth } from 'flavours/glitch/components/dropdown/utils';
|
import { matchWidth } from 'flavours/glitch/components/dropdown/utils';
|
||||||
import { IconButton } from 'flavours/glitch/components/icon_button';
|
import { IconButton } from 'flavours/glitch/components/icon_button';
|
||||||
import { useOnClickOutside } from 'flavours/glitch/hooks/useOnClickOutside';
|
import { useOnClickOutside } from 'flavours/glitch/hooks/useOnClickOutside';
|
||||||
@@ -17,6 +17,7 @@ import classes from './combobox.module.scss';
|
|||||||
import { FormFieldWrapper } from './form_field_wrapper';
|
import { FormFieldWrapper } from './form_field_wrapper';
|
||||||
import type { CommonFieldWrapperProps } from './form_field_wrapper';
|
import type { CommonFieldWrapperProps } from './form_field_wrapper';
|
||||||
import { TextInput } from './text_input_field';
|
import { TextInput } from './text_input_field';
|
||||||
|
import type { TextInputProps } from './text_input_field';
|
||||||
|
|
||||||
interface ComboboxItem {
|
interface ComboboxItem {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -27,17 +28,45 @@ export interface ComboboxItemState {
|
|||||||
isDisabled: boolean;
|
isDisabled: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ComboboxProps<
|
interface ComboboxProps<T extends ComboboxItem> extends TextInputProps {
|
||||||
T extends ComboboxItem,
|
/**
|
||||||
> extends ComponentPropsWithoutRef<'input'> {
|
* The value of the combobox's text input
|
||||||
|
*/
|
||||||
value: string;
|
value: string;
|
||||||
|
/**
|
||||||
|
* Change handler for the text input field
|
||||||
|
*/
|
||||||
onChange: React.ChangeEventHandler<HTMLInputElement>;
|
onChange: React.ChangeEventHandler<HTMLInputElement>;
|
||||||
|
/**
|
||||||
|
* Set this to true when the list of options is dynamic and currently loading.
|
||||||
|
* Causes a loading indicator to be displayed inside of the dropdown menu.
|
||||||
|
*/
|
||||||
isLoading?: boolean;
|
isLoading?: boolean;
|
||||||
|
/**
|
||||||
|
* The set of options/suggestions that should be rendered in the dropdown menu.
|
||||||
|
*/
|
||||||
items: T[];
|
items: T[];
|
||||||
getItemId: (item: T) => string;
|
/**
|
||||||
|
* A function that must return a unique id for each option passed via `items`
|
||||||
|
*/
|
||||||
|
getItemId?: (item: T) => string;
|
||||||
|
/**
|
||||||
|
* Providing this function turns the combobox into a multi-select box that assumes
|
||||||
|
* multiple options to be selectable. Single-selection is handled automatically.
|
||||||
|
*/
|
||||||
getIsItemSelected?: (item: T) => boolean;
|
getIsItemSelected?: (item: T) => boolean;
|
||||||
|
/**
|
||||||
|
* Use this function to mark items as disabled, if needed
|
||||||
|
*/
|
||||||
getIsItemDisabled?: (item: T) => boolean;
|
getIsItemDisabled?: (item: T) => boolean;
|
||||||
|
/**
|
||||||
|
* Customise the rendering of each option.
|
||||||
|
* The rendered content must not contain other interactive content!
|
||||||
|
*/
|
||||||
renderItem: (item: T, state: ComboboxItemState) => React.ReactElement;
|
renderItem: (item: T, state: ComboboxItemState) => React.ReactElement;
|
||||||
|
/**
|
||||||
|
* The main selection handler, called when an option is selected or deselected.
|
||||||
|
*/
|
||||||
onSelectItem: (item: T) => void;
|
onSelectItem: (item: T) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,8 +74,12 @@ interface Props<T extends ComboboxItem>
|
|||||||
extends ComboboxProps<T>, CommonFieldWrapperProps {}
|
extends ComboboxProps<T>, CommonFieldWrapperProps {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The combobox field allows users to select one or multiple items
|
* The combobox field allows users to select one or more items
|
||||||
* from a large list of options by searching or filtering.
|
* by searching or filtering a large or dynamic list of options.
|
||||||
|
*
|
||||||
|
* It is an implementation of the [APG Combobox pattern](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/),
|
||||||
|
* with inspiration taken from Sarah Higley's extensive combobox
|
||||||
|
* [research & implementations](https://sarahmhigley.com/writing/select-your-poison/).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const ComboboxFieldWithRef = <T extends ComboboxItem>(
|
export const ComboboxFieldWithRef = <T extends ComboboxItem>(
|
||||||
@@ -80,7 +113,7 @@ const ComboboxWithRef = <T extends ComboboxItem>(
|
|||||||
value,
|
value,
|
||||||
isLoading = false,
|
isLoading = false,
|
||||||
items,
|
items,
|
||||||
getItemId,
|
getItemId = (item) => item.id,
|
||||||
getIsItemDisabled,
|
getIsItemDisabled,
|
||||||
getIsItemSelected,
|
getIsItemSelected,
|
||||||
disabled,
|
disabled,
|
||||||
@@ -88,6 +121,7 @@ const ComboboxWithRef = <T extends ComboboxItem>(
|
|||||||
onSelectItem,
|
onSelectItem,
|
||||||
onChange,
|
onChange,
|
||||||
onKeyDown,
|
onKeyDown,
|
||||||
|
icon = SearchIcon,
|
||||||
className,
|
className,
|
||||||
...otherProps
|
...otherProps
|
||||||
}: ComboboxProps<T>,
|
}: ComboboxProps<T>,
|
||||||
@@ -306,6 +340,7 @@ const ComboboxWithRef = <T extends ComboboxItem>(
|
|||||||
value={value}
|
value={value}
|
||||||
onChange={handleInputChange}
|
onChange={handleInputChange}
|
||||||
onKeyDown={handleInputKeyDown}
|
onKeyDown={handleInputKeyDown}
|
||||||
|
icon={icon}
|
||||||
className={classNames(classes.input, className)}
|
className={classNames(classes.input, className)}
|
||||||
ref={mergeRefs}
|
ref={mergeRefs}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -20,6 +20,15 @@
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.iconWrapper & {
|
||||||
|
// Make space for icon displayed at start of input
|
||||||
|
padding-inline-start: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::placeholder {
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
outline-color: var(--color-text-brand);
|
outline-color: var(--color-text-brand);
|
||||||
}
|
}
|
||||||
@@ -40,3 +49,17 @@
|
|||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.iconWrapper {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
pointer-events: none;
|
||||||
|
position: absolute;
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
inset-inline-start: 10px;
|
||||||
|
inset-block-start: 10px;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import type { Meta, StoryObj } from '@storybook/react-vite';
|
import type { Meta, StoryObj } from '@storybook/react-vite';
|
||||||
|
|
||||||
|
import SearchIcon from '@/material-icons/400-24px/search.svg?react';
|
||||||
|
|
||||||
import { TextInputField, TextInput } from './text_input_field';
|
import { TextInputField, TextInput } from './text_input_field';
|
||||||
|
|
||||||
const meta = {
|
const meta = {
|
||||||
@@ -42,6 +44,14 @@ export const WithError: Story = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const WithIcon: Story = {
|
||||||
|
args: {
|
||||||
|
label: 'Search',
|
||||||
|
hint: undefined,
|
||||||
|
icon: SearchIcon,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
export const Plain: Story = {
|
export const Plain: Story = {
|
||||||
render(args) {
|
render(args) {
|
||||||
return <TextInput {...args} />;
|
return <TextInput {...args} />;
|
||||||
|
|||||||
@@ -3,12 +3,18 @@ import { forwardRef } from 'react';
|
|||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
import type { IconProp } from 'flavours/glitch/components/icon';
|
||||||
|
import { Icon } from 'flavours/glitch/components/icon';
|
||||||
|
|
||||||
import { FormFieldWrapper } from './form_field_wrapper';
|
import { FormFieldWrapper } from './form_field_wrapper';
|
||||||
import type { CommonFieldWrapperProps } from './form_field_wrapper';
|
import type { CommonFieldWrapperProps } from './form_field_wrapper';
|
||||||
import classes from './text_input.module.scss';
|
import classes from './text_input.module.scss';
|
||||||
|
|
||||||
interface Props
|
export interface TextInputProps extends ComponentPropsWithoutRef<'input'> {
|
||||||
extends ComponentPropsWithoutRef<'input'>, CommonFieldWrapperProps {}
|
icon?: IconProp;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Props extends TextInputProps, CommonFieldWrapperProps {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple form field for single-line text.
|
* A simple form field for single-line text.
|
||||||
@@ -33,16 +39,33 @@ export const TextInputField = forwardRef<HTMLInputElement, Props>(
|
|||||||
|
|
||||||
TextInputField.displayName = 'TextInputField';
|
TextInputField.displayName = 'TextInputField';
|
||||||
|
|
||||||
export const TextInput = forwardRef<
|
export const TextInput = forwardRef<HTMLInputElement, TextInputProps>(
|
||||||
HTMLInputElement,
|
({ type = 'text', icon, className, ...otherProps }, ref) => (
|
||||||
ComponentPropsWithoutRef<'input'>
|
<WrapFieldWithIcon icon={icon}>
|
||||||
>(({ type = 'text', className, ...otherProps }, ref) => (
|
<input
|
||||||
<input
|
type={type}
|
||||||
type={type}
|
{...otherProps}
|
||||||
{...otherProps}
|
className={classNames(className, classes.input)}
|
||||||
className={classNames(className, classes.input)}
|
ref={ref}
|
||||||
ref={ref}
|
/>
|
||||||
/>
|
</WrapFieldWithIcon>
|
||||||
));
|
),
|
||||||
|
);
|
||||||
|
|
||||||
TextInput.displayName = 'TextInput';
|
TextInput.displayName = 'TextInput';
|
||||||
|
|
||||||
|
const WrapFieldWithIcon: React.FC<{
|
||||||
|
icon?: IconProp;
|
||||||
|
children: React.ReactElement;
|
||||||
|
}> = ({ icon, children }) => {
|
||||||
|
if (icon) {
|
||||||
|
return (
|
||||||
|
<div className={classes.iconWrapper}>
|
||||||
|
<Icon icon={icon} id='input-icon' className={classes.icon} />
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return children;
|
||||||
|
};
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
import type { FC } from 'react';
|
||||||
|
|
||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { Column } from '@/flavours/glitch/components/column';
|
||||||
|
import { ColumnHeader } from '@/flavours/glitch/components/column_header';
|
||||||
|
import { LoadingIndicator } from '@/flavours/glitch/components/loading_indicator';
|
||||||
|
import BundleColumnError from '@/flavours/glitch/features/ui/components/bundle_column_error';
|
||||||
|
|
||||||
|
import { useColumnsContext } from '../../ui/util/columns_context';
|
||||||
|
import classes from '../styles.module.scss';
|
||||||
|
|
||||||
|
export const AccountEditEmptyColumn: FC<{
|
||||||
|
notFound?: boolean;
|
||||||
|
}> = ({ notFound }) => {
|
||||||
|
const { multiColumn } = useColumnsContext();
|
||||||
|
|
||||||
|
if (notFound) {
|
||||||
|
return <BundleColumnError multiColumn={multiColumn} errorType='routing' />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Column bindToDocument={!multiColumn} className={classes.column}>
|
||||||
|
<LoadingIndicator />
|
||||||
|
</Column>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const AccountEditColumn: FC<{
|
||||||
|
title: string;
|
||||||
|
to: string;
|
||||||
|
children: React.ReactNode;
|
||||||
|
}> = ({ to, title, children }) => {
|
||||||
|
const { multiColumn } = useColumnsContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Column bindToDocument={!multiColumn} className={classes.column}>
|
||||||
|
<ColumnHeader
|
||||||
|
title={title}
|
||||||
|
className={classes.columnHeader}
|
||||||
|
showBackButton
|
||||||
|
extraButton={
|
||||||
|
<Link to={to} className='button'>
|
||||||
|
<FormattedMessage
|
||||||
|
id='account_edit.column_button'
|
||||||
|
defaultMessage='Done'
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{children}
|
||||||
|
</Column>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
import type { FC, MouseEventHandler } from 'react';
|
||||||
|
|
||||||
|
import type { MessageDescriptor } from 'react-intl';
|
||||||
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
import { Button } from '@/flavours/glitch/components/button';
|
||||||
|
import { IconButton } from '@/flavours/glitch/components/icon_button';
|
||||||
|
import DeleteIcon from '@/material-icons/400-24px/delete.svg?react';
|
||||||
|
import EditIcon from '@/material-icons/400-24px/edit.svg?react';
|
||||||
|
|
||||||
|
import classes from '../styles.module.scss';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
add: {
|
||||||
|
id: 'account_edit.button.add',
|
||||||
|
defaultMessage: 'Add {item}',
|
||||||
|
},
|
||||||
|
edit: {
|
||||||
|
id: 'account_edit.button.edit',
|
||||||
|
defaultMessage: 'Edit {item}',
|
||||||
|
},
|
||||||
|
delete: {
|
||||||
|
id: 'account_edit.button.delete',
|
||||||
|
defaultMessage: 'Delete {item}',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export interface EditButtonProps {
|
||||||
|
onClick: MouseEventHandler;
|
||||||
|
item: string | MessageDescriptor;
|
||||||
|
edit?: boolean;
|
||||||
|
icon?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const EditButton: FC<EditButtonProps> = ({
|
||||||
|
onClick,
|
||||||
|
item,
|
||||||
|
edit = false,
|
||||||
|
icon = edit,
|
||||||
|
disabled,
|
||||||
|
}) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const itemText = typeof item === 'string' ? item : intl.formatMessage(item);
|
||||||
|
const label = intl.formatMessage(messages[edit ? 'edit' : 'add'], {
|
||||||
|
item: itemText,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (icon) {
|
||||||
|
return (
|
||||||
|
<EditIconButton title={label} onClick={onClick} disabled={disabled} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
className={classes.editButton}
|
||||||
|
onClick={onClick}
|
||||||
|
disabled={disabled}
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const EditIconButton: FC<{
|
||||||
|
onClick: MouseEventHandler;
|
||||||
|
title: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
}> = ({ title, onClick, disabled }) => (
|
||||||
|
<IconButton
|
||||||
|
icon='pencil'
|
||||||
|
iconComponent={EditIcon}
|
||||||
|
onClick={onClick}
|
||||||
|
className={classes.editButton}
|
||||||
|
title={title}
|
||||||
|
disabled={disabled}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const DeleteIconButton: FC<{
|
||||||
|
onClick: MouseEventHandler;
|
||||||
|
item: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
}> = ({ onClick, item, disabled }) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
return (
|
||||||
|
<IconButton
|
||||||
|
icon='delete'
|
||||||
|
iconComponent={DeleteIcon}
|
||||||
|
onClick={onClick}
|
||||||
|
className={classNames(classes.editButton, classes.deleteButton)}
|
||||||
|
title={intl.formatMessage(messages.delete, { item })}
|
||||||
|
disabled={disabled}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
import classes from '../styles.module.scss';
|
||||||
|
|
||||||
|
import { DeleteIconButton, EditButton } from './edit_button';
|
||||||
|
|
||||||
|
interface AnyItem {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AccountEditItemListProps<Item extends AnyItem = AnyItem> {
|
||||||
|
renderItem?: (item: Item) => React.ReactNode;
|
||||||
|
items: Item[];
|
||||||
|
onEdit?: (item: Item) => void;
|
||||||
|
onDelete?: (item: Item) => void;
|
||||||
|
disabled?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AccountEditItemList = <Item extends AnyItem>({
|
||||||
|
renderItem,
|
||||||
|
items,
|
||||||
|
onEdit,
|
||||||
|
onDelete,
|
||||||
|
disabled,
|
||||||
|
}: AccountEditItemListProps<Item>) => {
|
||||||
|
if (items.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ul className={classes.itemList}>
|
||||||
|
{items.map((item) => (
|
||||||
|
<li key={item.id}>
|
||||||
|
<span>{renderItem?.(item) ?? item.name}</span>
|
||||||
|
<AccountEditItemButtons
|
||||||
|
item={item}
|
||||||
|
onEdit={onEdit}
|
||||||
|
onDelete={onDelete}
|
||||||
|
disabled={disabled}
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
type AccountEditItemButtonsProps<Item extends AnyItem = AnyItem> = Pick<
|
||||||
|
AccountEditItemListProps<Item>,
|
||||||
|
'onEdit' | 'onDelete' | 'disabled'
|
||||||
|
> & { item: Item };
|
||||||
|
|
||||||
|
const AccountEditItemButtons = <Item extends AnyItem>({
|
||||||
|
item,
|
||||||
|
onDelete,
|
||||||
|
onEdit,
|
||||||
|
disabled,
|
||||||
|
}: AccountEditItemButtonsProps<Item>) => {
|
||||||
|
const handleEdit = useCallback(() => {
|
||||||
|
onEdit?.(item);
|
||||||
|
}, [item, onEdit]);
|
||||||
|
const handleDelete = useCallback(() => {
|
||||||
|
onDelete?.(item);
|
||||||
|
}, [item, onDelete]);
|
||||||
|
|
||||||
|
if (!onEdit && !onDelete) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={classes.itemListButtons}>
|
||||||
|
{onEdit && (
|
||||||
|
<EditButton
|
||||||
|
edit
|
||||||
|
item={item.name}
|
||||||
|
disabled={disabled}
|
||||||
|
onClick={handleEdit}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{onDelete && (
|
||||||
|
<DeleteIconButton
|
||||||
|
item={item.name}
|
||||||
|
disabled={disabled}
|
||||||
|
onClick={handleDelete}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,55 +1,36 @@
|
|||||||
import type { FC, ReactNode } from 'react';
|
import type { FC, ReactNode } from 'react';
|
||||||
|
|
||||||
import type { MessageDescriptor } from 'react-intl';
|
import type { MessageDescriptor } from 'react-intl';
|
||||||
import { defineMessage, FormattedMessage, useIntl } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
import { IconButton } from '@/flavours/glitch/components/icon_button';
|
|
||||||
import EditIcon from '@/material-icons/400-24px/edit.svg?react';
|
|
||||||
|
|
||||||
import classes from '../styles.module.scss';
|
import classes from '../styles.module.scss';
|
||||||
|
|
||||||
const buttonMessage = defineMessage({
|
|
||||||
id: 'account_edit.section_edit_button',
|
|
||||||
defaultMessage: 'Edit',
|
|
||||||
});
|
|
||||||
|
|
||||||
interface AccountEditSectionProps {
|
interface AccountEditSectionProps {
|
||||||
title: MessageDescriptor;
|
title: MessageDescriptor;
|
||||||
description?: MessageDescriptor;
|
description?: MessageDescriptor;
|
||||||
showDescription?: boolean;
|
showDescription?: boolean;
|
||||||
onEdit?: () => void;
|
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
className?: string;
|
className?: string;
|
||||||
extraButtons?: ReactNode;
|
buttons?: ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AccountEditSection: FC<AccountEditSectionProps> = ({
|
export const AccountEditSection: FC<AccountEditSectionProps> = ({
|
||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
showDescription,
|
showDescription,
|
||||||
onEdit,
|
|
||||||
children,
|
children,
|
||||||
className,
|
className,
|
||||||
extraButtons,
|
buttons,
|
||||||
}) => {
|
}) => {
|
||||||
const intl = useIntl();
|
|
||||||
return (
|
return (
|
||||||
<section className={classNames(className, classes.section)}>
|
<section className={classNames(className, classes.section)}>
|
||||||
<header className={classes.sectionHeader}>
|
<header className={classes.sectionHeader}>
|
||||||
<h3 className={classes.sectionTitle}>
|
<h3 className={classes.sectionTitle}>
|
||||||
<FormattedMessage {...title} />
|
<FormattedMessage {...title} />
|
||||||
</h3>
|
</h3>
|
||||||
{onEdit && (
|
{buttons}
|
||||||
<IconButton
|
|
||||||
icon='pencil'
|
|
||||||
iconComponent={EditIcon}
|
|
||||||
onClick={onEdit}
|
|
||||||
title={`${intl.formatMessage(buttonMessage)} ${intl.formatMessage(title)}`}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{extraButtons}
|
|
||||||
</header>
|
</header>
|
||||||
{showDescription && (
|
{showDescription && (
|
||||||
<p className={classes.sectionSubtitle}>
|
<p className={classes.sectionSubtitle}>
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import type { ChangeEventHandler, FC } from 'react';
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
import { useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
import type { ApiFeaturedTagJSON } from '@/flavours/glitch/api_types/tags';
|
||||||
|
import { Combobox } from '@/flavours/glitch/components/form_fields';
|
||||||
|
import {
|
||||||
|
addFeaturedTag,
|
||||||
|
clearSearch,
|
||||||
|
updateSearchQuery,
|
||||||
|
} from '@/flavours/glitch/reducers/slices/profile_edit';
|
||||||
|
import { useAppDispatch, useAppSelector } from '@/flavours/glitch/store';
|
||||||
|
import SearchIcon from '@/material-icons/400-24px/search.svg?react';
|
||||||
|
|
||||||
|
import classes from '../styles.module.scss';
|
||||||
|
|
||||||
|
export const AccountEditTagSearch: FC = () => {
|
||||||
|
const { query, isLoading, results } = useAppSelector(
|
||||||
|
(state) => state.profileEdit.search,
|
||||||
|
);
|
||||||
|
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const handleSearchChange: ChangeEventHandler<HTMLInputElement> = useCallback(
|
||||||
|
(e) => {
|
||||||
|
void dispatch(updateSearchQuery(e.target.value));
|
||||||
|
},
|
||||||
|
[dispatch],
|
||||||
|
);
|
||||||
|
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const handleSelect = useCallback(
|
||||||
|
(item: ApiFeaturedTagJSON) => {
|
||||||
|
void dispatch(clearSearch());
|
||||||
|
void dispatch(addFeaturedTag({ name: item.name }));
|
||||||
|
},
|
||||||
|
[dispatch],
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Combobox
|
||||||
|
value={query}
|
||||||
|
onChange={handleSearchChange}
|
||||||
|
placeholder={intl.formatMessage({
|
||||||
|
id: 'account_edit_tags.search_placeholder',
|
||||||
|
defaultMessage: 'Enter a hashtag…',
|
||||||
|
})}
|
||||||
|
items={results ?? []}
|
||||||
|
isLoading={isLoading}
|
||||||
|
renderItem={renderItem}
|
||||||
|
onSelectItem={handleSelect}
|
||||||
|
className={classes.autoComplete}
|
||||||
|
icon={SearchIcon}
|
||||||
|
type='search'
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderItem = (item: ApiFeaturedTagJSON) => <p>#{item.name}</p>;
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
import { useCallback, useEffect } from 'react';
|
||||||
|
import type { FC } from 'react';
|
||||||
|
|
||||||
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
import type { ApiFeaturedTagJSON } from '@/flavours/glitch/api_types/tags';
|
||||||
|
import { LoadingIndicator } from '@/flavours/glitch/components/loading_indicator';
|
||||||
|
import { Tag } from '@/flavours/glitch/components/tags/tag';
|
||||||
|
import { useAccount } from '@/flavours/glitch/hooks/useAccount';
|
||||||
|
import { useCurrentAccountId } from '@/flavours/glitch/hooks/useAccountId';
|
||||||
|
import {
|
||||||
|
addFeaturedTag,
|
||||||
|
deleteFeaturedTag,
|
||||||
|
fetchFeaturedTags,
|
||||||
|
fetchSuggestedTags,
|
||||||
|
} from '@/flavours/glitch/reducers/slices/profile_edit';
|
||||||
|
import { useAppDispatch, useAppSelector } from '@/flavours/glitch/store';
|
||||||
|
|
||||||
|
import { AccountEditColumn, AccountEditEmptyColumn } from './components/column';
|
||||||
|
import { AccountEditItemList } from './components/item_list';
|
||||||
|
import { AccountEditTagSearch } from './components/tag_search';
|
||||||
|
import classes from './styles.module.scss';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
columnTitle: {
|
||||||
|
id: 'account_edit_tags.column_title',
|
||||||
|
defaultMessage: 'Edit featured hashtags',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const AccountEditFeaturedTags: FC = () => {
|
||||||
|
const accountId = useCurrentAccountId();
|
||||||
|
const account = useAccount(accountId);
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const { tags, tagSuggestions, isLoading, isPending } = useAppSelector(
|
||||||
|
(state) => state.profileEdit,
|
||||||
|
);
|
||||||
|
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
useEffect(() => {
|
||||||
|
void dispatch(fetchFeaturedTags());
|
||||||
|
void dispatch(fetchSuggestedTags());
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
|
const handleDeleteTag = useCallback(
|
||||||
|
({ id }: { id: string }) => {
|
||||||
|
void dispatch(deleteFeaturedTag({ tagId: id }));
|
||||||
|
},
|
||||||
|
[dispatch],
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!accountId || !account) {
|
||||||
|
return <AccountEditEmptyColumn notFound={!accountId} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AccountEditColumn
|
||||||
|
title={intl.formatMessage(messages.columnTitle)}
|
||||||
|
to='/profile/edit'
|
||||||
|
>
|
||||||
|
<div className={classes.wrapper}>
|
||||||
|
<FormattedMessage
|
||||||
|
id='account_edit_tags.help_text'
|
||||||
|
defaultMessage='Featured hashtags help users discover and interact with your profile. They appear as filters on your Profile page’s Activity view.'
|
||||||
|
tagName='p'
|
||||||
|
/>
|
||||||
|
<AccountEditTagSearch />
|
||||||
|
{tagSuggestions.length > 0 && (
|
||||||
|
<div className={classes.tagSuggestions}>
|
||||||
|
<FormattedMessage
|
||||||
|
id='account_edit_tags.suggestions'
|
||||||
|
defaultMessage='Suggestions:'
|
||||||
|
/>
|
||||||
|
{tagSuggestions.map((tag) => (
|
||||||
|
<SuggestedTag name={tag.name} key={tag.id} disabled={isPending} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{isLoading && <LoadingIndicator />}
|
||||||
|
<AccountEditItemList
|
||||||
|
items={tags}
|
||||||
|
disabled={isPending}
|
||||||
|
renderItem={renderTag}
|
||||||
|
onDelete={handleDeleteTag}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</AccountEditColumn>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
function renderTag(tag: ApiFeaturedTagJSON) {
|
||||||
|
return (
|
||||||
|
<div className={classes.tagItem}>
|
||||||
|
<h4>#{tag.name}</h4>
|
||||||
|
{tag.statuses_count > 0 && (
|
||||||
|
<FormattedMessage
|
||||||
|
id='account_edit_tags.tag_status_count'
|
||||||
|
defaultMessage='{count} posts'
|
||||||
|
values={{ count: tag.statuses_count }}
|
||||||
|
tagName='p'
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const SuggestedTag: FC<{ name: string; disabled?: boolean }> = ({
|
||||||
|
name,
|
||||||
|
disabled,
|
||||||
|
}) => {
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const handleAddTag = useCallback(() => {
|
||||||
|
void dispatch(addFeaturedTag({ name }));
|
||||||
|
}, [dispatch, name]);
|
||||||
|
return <Tag name={name} onClick={handleAddTag} disabled={disabled} />;
|
||||||
|
};
|
||||||
@@ -1,28 +1,31 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback, useEffect } from 'react';
|
||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
|
|
||||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { Link } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
|
|
||||||
import type { ModalType } from '@/flavours/glitch/actions/modal';
|
import type { ModalType } from '@/flavours/glitch/actions/modal';
|
||||||
import { openModal } from '@/flavours/glitch/actions/modal';
|
import { openModal } from '@/flavours/glitch/actions/modal';
|
||||||
import { AccountBio } from '@/flavours/glitch/components/account_bio';
|
import { AccountBio } from '@/flavours/glitch/components/account_bio';
|
||||||
import { Avatar } from '@/flavours/glitch/components/avatar';
|
import { Avatar } from '@/flavours/glitch/components/avatar';
|
||||||
import { Column } from '@/flavours/glitch/components/column';
|
|
||||||
import { ColumnHeader } from '@/flavours/glitch/components/column_header';
|
|
||||||
import { DisplayNameSimple } from '@/flavours/glitch/components/display_name/simple';
|
import { DisplayNameSimple } from '@/flavours/glitch/components/display_name/simple';
|
||||||
import { LoadingIndicator } from '@/flavours/glitch/components/loading_indicator';
|
|
||||||
import BundleColumnError from '@/flavours/glitch/features/ui/components/bundle_column_error';
|
|
||||||
import { useAccount } from '@/flavours/glitch/hooks/useAccount';
|
import { useAccount } from '@/flavours/glitch/hooks/useAccount';
|
||||||
import { useCurrentAccountId } from '@/flavours/glitch/hooks/useAccountId';
|
import { useCurrentAccountId } from '@/flavours/glitch/hooks/useAccountId';
|
||||||
import { autoPlayGif } from '@/flavours/glitch/initial_state';
|
import { autoPlayGif } from '@/flavours/glitch/initial_state';
|
||||||
import { useAppDispatch } from '@/flavours/glitch/store';
|
import { fetchFeaturedTags } from '@/flavours/glitch/reducers/slices/profile_edit';
|
||||||
|
import { useAppDispatch, useAppSelector } from '@/flavours/glitch/store';
|
||||||
|
|
||||||
|
import { AccountEditColumn, AccountEditEmptyColumn } from './components/column';
|
||||||
|
import { EditButton } from './components/edit_button';
|
||||||
import { AccountEditSection } from './components/section';
|
import { AccountEditSection } from './components/section';
|
||||||
import classes from './styles.module.scss';
|
import classes from './styles.module.scss';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
|
columnTitle: {
|
||||||
|
id: 'account_edit.column_title',
|
||||||
|
defaultMessage: 'Edit Profile',
|
||||||
|
},
|
||||||
displayNameTitle: {
|
displayNameTitle: {
|
||||||
id: 'account_edit.display_name.title',
|
id: 'account_edit.display_name.title',
|
||||||
defaultMessage: 'Display name',
|
defaultMessage: 'Display name',
|
||||||
@@ -58,6 +61,10 @@ const messages = defineMessages({
|
|||||||
defaultMessage:
|
defaultMessage:
|
||||||
'Help others identify, and have quick access to, your favorite topics.',
|
'Help others identify, and have quick access to, your favorite topics.',
|
||||||
},
|
},
|
||||||
|
featuredHashtagsItem: {
|
||||||
|
id: 'account_edit.featured_hashtags.item',
|
||||||
|
defaultMessage: 'hashtags',
|
||||||
|
},
|
||||||
profileTabTitle: {
|
profileTabTitle: {
|
||||||
id: 'account_edit.profile_tab.title',
|
id: 'account_edit.profile_tab.title',
|
||||||
defaultMessage: 'Profile tab settings',
|
defaultMessage: 'Profile tab settings',
|
||||||
@@ -68,12 +75,20 @@ const messages = defineMessages({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const AccountEdit: FC<{ multiColumn: boolean }> = ({ multiColumn }) => {
|
export const AccountEdit: FC = () => {
|
||||||
const accountId = useCurrentAccountId();
|
const accountId = useCurrentAccountId();
|
||||||
const account = useAccount(accountId);
|
const account = useAccount(accountId);
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
const { tags: featuredTags, isLoading: isTagsLoading } = useAppSelector(
|
||||||
|
(state) => state.profileEdit,
|
||||||
|
);
|
||||||
|
useEffect(() => {
|
||||||
|
void dispatch(fetchFeaturedTags());
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
const handleOpenModal = useCallback(
|
const handleOpenModal = useCallback(
|
||||||
(type: ModalType, props?: Record<string, unknown>) => {
|
(type: ModalType, props?: Record<string, unknown>) => {
|
||||||
dispatch(openModal({ modalType: type, modalProps: props ?? {} }));
|
dispatch(openModal({ modalType: type, modalProps: props ?? {} }));
|
||||||
@@ -87,38 +102,25 @@ export const AccountEdit: FC<{ multiColumn: boolean }> = ({ multiColumn }) => {
|
|||||||
handleOpenModal('ACCOUNT_EDIT_BIO');
|
handleOpenModal('ACCOUNT_EDIT_BIO');
|
||||||
}, [handleOpenModal]);
|
}, [handleOpenModal]);
|
||||||
|
|
||||||
if (!accountId) {
|
const history = useHistory();
|
||||||
return <BundleColumnError multiColumn={multiColumn} errorType='routing' />;
|
const handleFeaturedTagsEdit = useCallback(() => {
|
||||||
}
|
history.push('/profile/featured_tags');
|
||||||
|
}, [history]);
|
||||||
|
|
||||||
if (!account) {
|
if (!accountId || !account) {
|
||||||
return (
|
return <AccountEditEmptyColumn notFound={!accountId} />;
|
||||||
<Column bindToDocument={!multiColumn} className={classes.column}>
|
|
||||||
<LoadingIndicator />
|
|
||||||
</Column>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const headerSrc = autoPlayGif ? account.header : account.header_static;
|
const headerSrc = autoPlayGif ? account.header : account.header_static;
|
||||||
|
const hasName = !!account.display_name;
|
||||||
|
const hasBio = !!account.note_plain;
|
||||||
|
const hasTags = !isTagsLoading && featuredTags.length > 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Column bindToDocument={!multiColumn} className={classes.column}>
|
<AccountEditColumn
|
||||||
<ColumnHeader
|
title={intl.formatMessage(messages.columnTitle)}
|
||||||
title={intl.formatMessage({
|
to={`/@${account.acct}`}
|
||||||
id: 'account_edit.column_title',
|
>
|
||||||
defaultMessage: 'Edit Profile',
|
|
||||||
})}
|
|
||||||
className={classes.columnHeader}
|
|
||||||
showBackButton
|
|
||||||
extraButton={
|
|
||||||
<Link to={`/@${account.acct}`} className='button'>
|
|
||||||
<FormattedMessage
|
|
||||||
id='account_edit.column_button'
|
|
||||||
defaultMessage='Done'
|
|
||||||
/>
|
|
||||||
</Link>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<header>
|
<header>
|
||||||
<div className={classes.profileImage}>
|
<div className={classes.profileImage}>
|
||||||
{headerSrc && <img src={headerSrc} alt='' />}
|
{headerSrc && <img src={headerSrc} alt='' />}
|
||||||
@@ -129,8 +131,14 @@ export const AccountEdit: FC<{ multiColumn: boolean }> = ({ multiColumn }) => {
|
|||||||
<AccountEditSection
|
<AccountEditSection
|
||||||
title={messages.displayNameTitle}
|
title={messages.displayNameTitle}
|
||||||
description={messages.displayNamePlaceholder}
|
description={messages.displayNamePlaceholder}
|
||||||
showDescription={account.display_name.length === 0}
|
showDescription={!hasName}
|
||||||
onEdit={handleNameEdit}
|
buttons={
|
||||||
|
<EditButton
|
||||||
|
onClick={handleNameEdit}
|
||||||
|
item={messages.displayNameTitle}
|
||||||
|
edit={hasName}
|
||||||
|
/>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<DisplayNameSimple account={account} />
|
<DisplayNameSimple account={account} />
|
||||||
</AccountEditSection>
|
</AccountEditSection>
|
||||||
@@ -138,8 +146,14 @@ export const AccountEdit: FC<{ multiColumn: boolean }> = ({ multiColumn }) => {
|
|||||||
<AccountEditSection
|
<AccountEditSection
|
||||||
title={messages.bioTitle}
|
title={messages.bioTitle}
|
||||||
description={messages.bioPlaceholder}
|
description={messages.bioPlaceholder}
|
||||||
showDescription={!account.note_plain}
|
showDescription={!hasBio}
|
||||||
onEdit={handleBioEdit}
|
buttons={
|
||||||
|
<EditButton
|
||||||
|
onClick={handleBioEdit}
|
||||||
|
item={messages.bioTitle}
|
||||||
|
edit={hasBio}
|
||||||
|
/>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<AccountBio accountId={accountId} />
|
<AccountBio accountId={accountId} />
|
||||||
</AccountEditSection>
|
</AccountEditSection>
|
||||||
@@ -153,14 +167,23 @@ export const AccountEdit: FC<{ multiColumn: boolean }> = ({ multiColumn }) => {
|
|||||||
<AccountEditSection
|
<AccountEditSection
|
||||||
title={messages.featuredHashtagsTitle}
|
title={messages.featuredHashtagsTitle}
|
||||||
description={messages.featuredHashtagsPlaceholder}
|
description={messages.featuredHashtagsPlaceholder}
|
||||||
showDescription
|
showDescription={!hasTags}
|
||||||
/>
|
buttons={
|
||||||
|
<EditButton
|
||||||
|
onClick={handleFeaturedTagsEdit}
|
||||||
|
edit={hasTags}
|
||||||
|
item={messages.featuredHashtagsItem}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{featuredTags.map((tag) => `#${tag.name}`).join(', ')}
|
||||||
|
</AccountEditSection>
|
||||||
|
|
||||||
<AccountEditSection
|
<AccountEditSection
|
||||||
title={messages.profileTabTitle}
|
title={messages.profileTabTitle}
|
||||||
description={messages.profileTabSubtitle}
|
description={messages.profileTabSubtitle}
|
||||||
showDescription
|
showDescription
|
||||||
/>
|
/>
|
||||||
</Column>
|
</AccountEditColumn>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,15 +1,4 @@
|
|||||||
.column {
|
// Profile Edit Page
|
||||||
border: 1px solid var(--color-border-primary);
|
|
||||||
border-top-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.columnHeader {
|
|
||||||
:global(.column-header__buttons) {
|
|
||||||
align-items: center;
|
|
||||||
padding-inline-end: 16px;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.profileImage {
|
.profileImage {
|
||||||
height: 120px;
|
height: 120px;
|
||||||
@@ -35,40 +24,41 @@
|
|||||||
border: 1px solid var(--color-border-primary);
|
border: 1px solid var(--color-border-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.section {
|
// Featured Tags Page
|
||||||
padding: 20px;
|
|
||||||
border-bottom: 1px solid var(--color-border-primary);
|
.wrapper {
|
||||||
font-size: 15px;
|
padding: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sectionHeader {
|
.autoComplete,
|
||||||
|
.tagSuggestions {
|
||||||
|
margin: 12px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tagSuggestions {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
gap: 4px;
|
||||||
|
flex-wrap: wrap;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
|
|
||||||
> button {
|
// Add more padding to the suggestions label
|
||||||
border: 1px solid var(--color-border-primary);
|
> span {
|
||||||
border-radius: 8px;
|
margin-right: 4px;
|
||||||
box-sizing: border-box;
|
|
||||||
padding: 4px;
|
|
||||||
|
|
||||||
svg {
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sectionTitle {
|
.tagItem {
|
||||||
flex-grow: 1;
|
> h4 {
|
||||||
font-size: 17px;
|
font-size: 15px;
|
||||||
font-weight: 600;
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
> p {
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sectionSubtitle {
|
// Modals
|
||||||
color: var(--color-text-secondary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.inputWrapper {
|
.inputWrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -100,6 +90,104 @@ textarea.inputText {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Column component
|
||||||
|
|
||||||
|
.column {
|
||||||
|
border: 1px solid var(--color-border-primary);
|
||||||
|
border-top-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.columnHeader {
|
||||||
|
:global(.column-header__buttons) {
|
||||||
|
align-items: center;
|
||||||
|
padding-inline-end: 16px;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Edit button component
|
||||||
|
|
||||||
|
.editButton {
|
||||||
|
border: 1px solid var(--color-border-primary);
|
||||||
|
border-radius: 8px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 4px;
|
||||||
|
transition:
|
||||||
|
color 0.2s ease-in-out,
|
||||||
|
background-color 0.2s ease-in-out;
|
||||||
|
|
||||||
|
&:global(.button) {
|
||||||
|
background-color: var(--color-bg-primary);
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
font-size: 13px;
|
||||||
|
padding: 4px 8px;
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&:focus,
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--color-bg-brand-softer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.deleteButton {
|
||||||
|
--default-icon-color: var(--color-text-error);
|
||||||
|
--hover-bg-color: var(--color-bg-error-base-hover);
|
||||||
|
--hover-icon-color: var(--color-text-on-error-base);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Item list component
|
||||||
|
|
||||||
|
.itemList {
|
||||||
|
> li {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 12px 0;
|
||||||
|
|
||||||
|
> :first-child {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemListButtons {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Section component
|
||||||
|
|
||||||
|
.section {
|
||||||
|
padding: 20px;
|
||||||
|
border-bottom: 1px solid var(--color-border-primary);
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sectionHeader {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sectionTitle {
|
||||||
|
flex-grow: 1;
|
||||||
|
font-size: 17px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sectionSubtitle {
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Counter component
|
||||||
|
|
||||||
.counter {
|
.counter {
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useCallback, useMemo, useState } from 'react';
|
import { useCallback, useId, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import { FormattedMessage, useIntl } from 'react-intl';
|
import { FormattedMessage, useIntl } from 'react-intl';
|
||||||
|
|
||||||
@@ -18,10 +18,7 @@ import { Button } from 'flavours/glitch/components/button';
|
|||||||
import { Callout } from 'flavours/glitch/components/callout';
|
import { Callout } from 'flavours/glitch/components/callout';
|
||||||
import { DisplayName } from 'flavours/glitch/components/display_name';
|
import { DisplayName } from 'flavours/glitch/components/display_name';
|
||||||
import { EmptyState } from 'flavours/glitch/components/empty_state';
|
import { EmptyState } from 'flavours/glitch/components/empty_state';
|
||||||
import {
|
import { FormStack, Combobox } from 'flavours/glitch/components/form_fields';
|
||||||
FormStack,
|
|
||||||
ComboboxField,
|
|
||||||
} from 'flavours/glitch/components/form_fields';
|
|
||||||
import { Icon } from 'flavours/glitch/components/icon';
|
import { Icon } from 'flavours/glitch/components/icon';
|
||||||
import { IconButton } from 'flavours/glitch/components/icon_button';
|
import { IconButton } from 'flavours/glitch/components/icon_button';
|
||||||
import ScrollableList from 'flavours/glitch/components/scrollable_list';
|
import ScrollableList from 'flavours/glitch/components/scrollable_list';
|
||||||
@@ -331,6 +328,12 @@ export const CollectionAccounts: React.FC<{
|
|||||||
[canSubmit, id, history, accountIds],
|
[canSubmit, id, history, accountIds],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const inputId = useId();
|
||||||
|
const inputLabel = intl.formatMessage({
|
||||||
|
id: 'collections.search_accounts_label',
|
||||||
|
defaultMessage: 'Search for accounts to add…',
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit} className={classes.form}>
|
<form onSubmit={handleSubmit} className={classes.form}>
|
||||||
<FormStack className={classes.formFieldStack}>
|
<FormStack className={classes.formFieldStack}>
|
||||||
@@ -351,21 +354,12 @@ export const CollectionAccounts: React.FC<{
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<ComboboxField
|
<label htmlFor={inputId} className='sr-only'>
|
||||||
label={
|
{inputLabel}
|
||||||
<FormattedMessage
|
</label>
|
||||||
id='collections.search_accounts_label'
|
<Combobox
|
||||||
defaultMessage='Search for accounts to add…'
|
id={inputId}
|
||||||
/>
|
placeholder={inputLabel}
|
||||||
}
|
|
||||||
hint={
|
|
||||||
hasMaxAccounts ? (
|
|
||||||
<FormattedMessage
|
|
||||||
id='collections.search_accounts_max_reached'
|
|
||||||
defaultMessage='You have added the maximum number of accounts'
|
|
||||||
/>
|
|
||||||
) : undefined
|
|
||||||
}
|
|
||||||
value={hasMaxAccounts ? '' : searchValue}
|
value={hasMaxAccounts ? '' : searchValue}
|
||||||
onChange={handleSearchValueChange}
|
onChange={handleSearchValueChange}
|
||||||
onKeyDown={handleSearchKeyDown}
|
onKeyDown={handleSearchKeyDown}
|
||||||
@@ -379,6 +373,12 @@ export const CollectionAccounts: React.FC<{
|
|||||||
isEditMode ? instantToggleAccountItem : toggleAccountItem
|
isEditMode ? instantToggleAccountItem : toggleAccountItem
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
{hasMaxAccounts && (
|
||||||
|
<FormattedMessage
|
||||||
|
id='collections.search_accounts_max_reached'
|
||||||
|
defaultMessage='You have added the maximum number of accounts'
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
{hasMinAccounts && (
|
{hasMinAccounts && (
|
||||||
<Callout>
|
<Callout>
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ import {
|
|||||||
AccountFeatured,
|
AccountFeatured,
|
||||||
AccountAbout,
|
AccountAbout,
|
||||||
AccountEdit,
|
AccountEdit,
|
||||||
|
AccountEditFeaturedTags,
|
||||||
Quotes,
|
Quotes,
|
||||||
} from './util/async-components';
|
} from './util/async-components';
|
||||||
import { ColumnsContextProvider } from './util/columns_context';
|
import { ColumnsContextProvider } from './util/columns_context';
|
||||||
@@ -172,9 +173,8 @@ class SwitchingColumnsArea extends PureComponent {
|
|||||||
redirect = <Redirect from='/' to='/about' exact />;
|
redirect = <Redirect from='/' to='/about' exact />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const profileRedesignEnabled = isServerFeatureEnabled('profile_redesign');
|
|
||||||
const profileRedesignRoutes = [];
|
const profileRedesignRoutes = [];
|
||||||
if (profileRedesignEnabled) {
|
if (isServerFeatureEnabled('profile_redesign')) {
|
||||||
profileRedesignRoutes.push(
|
profileRedesignRoutes.push(
|
||||||
<WrappedRoute key="posts" path={['/@:acct/posts', '/accounts/:id/posts']} exact component={AccountTimeline} content={children} />,
|
<WrappedRoute key="posts" path={['/@:acct/posts', '/accounts/:id/posts']} exact component={AccountTimeline} content={children} />,
|
||||||
);
|
);
|
||||||
@@ -196,13 +196,27 @@ class SwitchingColumnsArea extends PureComponent {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If the redesign is not enabled but someone shares an /about link, redirect to the root.
|
|
||||||
profileRedesignRoutes.push(
|
profileRedesignRoutes.push(
|
||||||
|
<WrappedRoute path={['/@:acct', '/accounts/:id']} exact component={AccountTimeline} content={children} />,
|
||||||
|
// If the redesign is not enabled but someone shares an /about link, redirect to the root.
|
||||||
<Redirect key="about-acct-redirect" from='/@:acct/about' to='/@:acct' exact />,
|
<Redirect key="about-acct-redirect" from='/@:acct/about' to='/@:acct' exact />,
|
||||||
<Redirect key="about-id-redirect" from='/accounts/:id/about' to='/accounts/:id' exact />
|
<Redirect key="about-id-redirect" from='/accounts/:id/about' to='/accounts/:id' exact />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isClientFeatureEnabled('profile_editing')) {
|
||||||
|
profileRedesignRoutes.push(
|
||||||
|
<WrappedRoute key="edit" path='/profile/edit' component={AccountEdit} content={children} />,
|
||||||
|
<WrappedRoute key="featured_tags" path='/profile/featured_tags' component={AccountEditFeaturedTags} content={children} />
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
// If profile editing is not enabled, redirect to the home timeline as the current editing pages are outside React Router.
|
||||||
|
profileRedesignRoutes.push(
|
||||||
|
<Redirect key="edit-redirect" from='/profile/edit' to='/' exact />,
|
||||||
|
<Redirect key="featured-tags-redirect" from='/profile/featured_tags' to='/' exact />,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ColumnsContextProvider multiColumn={!singleColumn}>
|
<ColumnsContextProvider multiColumn={!singleColumn}>
|
||||||
<ColumnsAreaContainer ref={this.setRef} singleColumn={singleColumn}>
|
<ColumnsAreaContainer ref={this.setRef} singleColumn={singleColumn}>
|
||||||
@@ -242,8 +256,6 @@ class SwitchingColumnsArea extends PureComponent {
|
|||||||
<WrappedRoute path='/bookmarks' component={BookmarkedStatuses} content={children} />
|
<WrappedRoute path='/bookmarks' component={BookmarkedStatuses} content={children} />
|
||||||
<WrappedRoute path='/pinned' component={PinnedStatuses} content={children} />
|
<WrappedRoute path='/pinned' component={PinnedStatuses} content={children} />
|
||||||
|
|
||||||
{isClientFeatureEnabled('profile_editing') && <WrappedRoute key="edit" path='/profile/edit' component={AccountEdit} content={children} />}
|
|
||||||
|
|
||||||
<WrappedRoute path={['/start', '/start/profile']} exact component={OnboardingProfile} content={children} />
|
<WrappedRoute path={['/start', '/start/profile']} exact component={OnboardingProfile} content={children} />
|
||||||
<WrappedRoute path='/start/follows' component={OnboardingFollows} content={children} />
|
<WrappedRoute path='/start/follows' component={OnboardingFollows} content={children} />
|
||||||
<WrappedRoute path='/directory' component={Directory} content={children} />
|
<WrappedRoute path='/directory' component={Directory} content={children} />
|
||||||
@@ -251,8 +263,8 @@ class SwitchingColumnsArea extends PureComponent {
|
|||||||
<WrappedRoute path='/search' component={Search} content={children} />
|
<WrappedRoute path='/search' component={Search} content={children} />
|
||||||
<WrappedRoute path={['/publish', '/statuses/new']} component={Compose} content={children} />
|
<WrappedRoute path={['/publish', '/statuses/new']} component={Compose} content={children} />
|
||||||
|
|
||||||
{!profileRedesignEnabled && <WrappedRoute path={['/@:acct', '/accounts/:id']} exact component={AccountTimeline} content={children} />}
|
|
||||||
{...profileRedesignRoutes}
|
{...profileRedesignRoutes}
|
||||||
|
|
||||||
<WrappedRoute path={['/@:acct/featured', '/accounts/:id/featured']} component={AccountFeatured} content={children} />
|
<WrappedRoute path={['/@:acct/featured', '/accounts/:id/featured']} component={AccountFeatured} content={children} />
|
||||||
<WrappedRoute path='/@:acct/tagged/:tagged?' exact component={AccountTimeline} content={children} />
|
<WrappedRoute path='/@:acct/tagged/:tagged?' exact component={AccountTimeline} content={children} />
|
||||||
<WrappedRoute path={['/@:acct/with_replies', '/accounts/:id/with_replies']} component={AccountTimeline} content={children} componentParams={{ withReplies: true }} />
|
<WrappedRoute path={['/@:acct/with_replies', '/accounts/:id/with_replies']} component={AccountTimeline} content={children} componentParams={{ withReplies: true }} />
|
||||||
|
|||||||
@@ -103,6 +103,11 @@ export function AccountEdit() {
|
|||||||
.then((module) => ({ default: module.AccountEdit }));
|
.then((module) => ({ default: module.AccountEdit }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function AccountEditFeaturedTags() {
|
||||||
|
return import('../../account_edit/featured_tags')
|
||||||
|
.then((module) => ({ default: module.AccountEditFeaturedTags }));
|
||||||
|
}
|
||||||
|
|
||||||
export function Followers () {
|
export function Followers () {
|
||||||
return import('../../followers');
|
return import('../../followers');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import { annualReport } from './annual_report';
|
import { annualReport } from './annual_report';
|
||||||
import { collections } from './collections';
|
import { collections } from './collections';
|
||||||
|
import { profileEdit } from './profile_edit';
|
||||||
|
|
||||||
export const sliceReducers = {
|
export const sliceReducers = {
|
||||||
annualReport,
|
annualReport,
|
||||||
collections,
|
collections,
|
||||||
|
profileEdit,
|
||||||
};
|
};
|
||||||
|
|||||||
178
app/javascript/flavours/glitch/reducers/slices/profile_edit.ts
Normal file
178
app/javascript/flavours/glitch/reducers/slices/profile_edit.ts
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
import type { PayloadAction } from '@reduxjs/toolkit';
|
||||||
|
import { createSlice } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
|
import { debounce } from 'lodash';
|
||||||
|
|
||||||
|
import {
|
||||||
|
apiDeleteFeaturedTag,
|
||||||
|
apiGetCurrentFeaturedTags,
|
||||||
|
apiGetTagSuggestions,
|
||||||
|
apiPostFeaturedTag,
|
||||||
|
} from '@/flavours/glitch/api/accounts';
|
||||||
|
import { apiGetSearch } from '@/flavours/glitch/api/search';
|
||||||
|
import { hashtagToFeaturedTag } from '@/flavours/glitch/api_types/tags';
|
||||||
|
import type { ApiFeaturedTagJSON } from '@/flavours/glitch/api_types/tags';
|
||||||
|
import type { AppDispatch } from '@/flavours/glitch/store';
|
||||||
|
import {
|
||||||
|
createAppAsyncThunk,
|
||||||
|
createDataLoadingThunk,
|
||||||
|
} from '@/flavours/glitch/store/typed_functions';
|
||||||
|
|
||||||
|
interface ProfileEditState {
|
||||||
|
tags: ApiFeaturedTagJSON[];
|
||||||
|
tagSuggestions: ApiFeaturedTagJSON[];
|
||||||
|
isLoading: boolean;
|
||||||
|
isPending: boolean;
|
||||||
|
search: {
|
||||||
|
query: string;
|
||||||
|
isLoading: boolean;
|
||||||
|
results?: ApiFeaturedTagJSON[];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const initialState: ProfileEditState = {
|
||||||
|
tags: [],
|
||||||
|
tagSuggestions: [],
|
||||||
|
isLoading: true,
|
||||||
|
isPending: false,
|
||||||
|
search: {
|
||||||
|
query: '',
|
||||||
|
isLoading: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const profileEditSlice = createSlice({
|
||||||
|
name: 'profileEdit',
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
setSearchQuery(state, action: PayloadAction<string>) {
|
||||||
|
if (state.search.query === action.payload) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state.search.query = action.payload;
|
||||||
|
state.search.isLoading = false;
|
||||||
|
state.search.results = undefined;
|
||||||
|
},
|
||||||
|
clearSearch(state) {
|
||||||
|
state.search.query = '';
|
||||||
|
state.search.isLoading = false;
|
||||||
|
state.search.results = undefined;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
extraReducers(builder) {
|
||||||
|
builder.addCase(fetchSuggestedTags.fulfilled, (state, action) => {
|
||||||
|
state.tagSuggestions = action.payload.map(hashtagToFeaturedTag);
|
||||||
|
state.isLoading = false;
|
||||||
|
});
|
||||||
|
builder.addCase(fetchFeaturedTags.fulfilled, (state, action) => {
|
||||||
|
state.tags = action.payload;
|
||||||
|
state.isLoading = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.addCase(addFeaturedTag.pending, (state) => {
|
||||||
|
state.isPending = true;
|
||||||
|
});
|
||||||
|
builder.addCase(addFeaturedTag.rejected, (state) => {
|
||||||
|
state.isPending = false;
|
||||||
|
});
|
||||||
|
builder.addCase(addFeaturedTag.fulfilled, (state, action) => {
|
||||||
|
state.tags = [...state.tags, action.payload].toSorted(
|
||||||
|
(a, b) => b.statuses_count - a.statuses_count,
|
||||||
|
);
|
||||||
|
state.tagSuggestions = state.tagSuggestions.filter(
|
||||||
|
(tag) => tag.name !== action.meta.arg.name,
|
||||||
|
);
|
||||||
|
state.isPending = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.addCase(deleteFeaturedTag.pending, (state) => {
|
||||||
|
state.isPending = true;
|
||||||
|
});
|
||||||
|
builder.addCase(deleteFeaturedTag.rejected, (state) => {
|
||||||
|
state.isPending = false;
|
||||||
|
});
|
||||||
|
builder.addCase(deleteFeaturedTag.fulfilled, (state, action) => {
|
||||||
|
state.tags = state.tags.filter((tag) => tag.id !== action.meta.arg.tagId);
|
||||||
|
state.isPending = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.addCase(fetchSearchResults.pending, (state) => {
|
||||||
|
state.search.isLoading = true;
|
||||||
|
});
|
||||||
|
builder.addCase(fetchSearchResults.rejected, (state) => {
|
||||||
|
state.search.isLoading = false;
|
||||||
|
state.search.results = undefined;
|
||||||
|
});
|
||||||
|
builder.addCase(fetchSearchResults.fulfilled, (state, action) => {
|
||||||
|
state.search.isLoading = false;
|
||||||
|
const searchResults: ApiFeaturedTagJSON[] = [];
|
||||||
|
const currentTags = new Set(state.tags.map((tag) => tag.name));
|
||||||
|
|
||||||
|
for (const tag of action.payload) {
|
||||||
|
if (currentTags.has(tag.name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
searchResults.push(hashtagToFeaturedTag(tag));
|
||||||
|
if (searchResults.length >= 10) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state.search.results = searchResults;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const profileEdit = profileEditSlice.reducer;
|
||||||
|
export const { clearSearch } = profileEditSlice.actions;
|
||||||
|
|
||||||
|
export const fetchFeaturedTags = createDataLoadingThunk(
|
||||||
|
`${profileEditSlice.name}/fetchFeaturedTags`,
|
||||||
|
apiGetCurrentFeaturedTags,
|
||||||
|
{ useLoadingBar: false },
|
||||||
|
);
|
||||||
|
|
||||||
|
export const fetchSuggestedTags = createDataLoadingThunk(
|
||||||
|
`${profileEditSlice.name}/fetchSuggestedTags`,
|
||||||
|
apiGetTagSuggestions,
|
||||||
|
{ useLoadingBar: false },
|
||||||
|
);
|
||||||
|
|
||||||
|
export const addFeaturedTag = createDataLoadingThunk(
|
||||||
|
`${profileEditSlice.name}/addFeaturedTag`,
|
||||||
|
({ name }: { name: string }) => apiPostFeaturedTag(name),
|
||||||
|
{
|
||||||
|
condition(arg, { getState }) {
|
||||||
|
const state = getState();
|
||||||
|
return !state.profileEdit.tags.some((tag) => tag.name === arg.name);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export const deleteFeaturedTag = createDataLoadingThunk(
|
||||||
|
`${profileEditSlice.name}/deleteFeaturedTag`,
|
||||||
|
({ tagId }: { tagId: string }) => apiDeleteFeaturedTag(tagId),
|
||||||
|
);
|
||||||
|
|
||||||
|
const debouncedFetchSearchResults = debounce(
|
||||||
|
async (dispatch: AppDispatch, query: string) => {
|
||||||
|
await dispatch(fetchSearchResults({ q: query }));
|
||||||
|
},
|
||||||
|
300,
|
||||||
|
);
|
||||||
|
|
||||||
|
export const updateSearchQuery = createAppAsyncThunk(
|
||||||
|
`${profileEditSlice.name}/updateSearchQuery`,
|
||||||
|
(query: string, { dispatch }) => {
|
||||||
|
dispatch(profileEditSlice.actions.setSearchQuery(query));
|
||||||
|
|
||||||
|
if (query.trim().length > 0) {
|
||||||
|
void debouncedFetchSearchResults(dispatch, query);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export const fetchSearchResults = createDataLoadingThunk(
|
||||||
|
`${profileEditSlice.name}/fetchSearchResults`,
|
||||||
|
({ q }: { q: string }) => apiGetSearch({ q, type: 'hashtags', limit: 11 }),
|
||||||
|
(result) => result.hashtags,
|
||||||
|
);
|
||||||
@@ -77,7 +77,8 @@ const initialState = ImmutableMap({
|
|||||||
follow_requests: initialListState,
|
follow_requests: initialListState,
|
||||||
blocks: initialListState,
|
blocks: initialListState,
|
||||||
mutes: initialListState,
|
mutes: initialListState,
|
||||||
featured_tags: initialListState,
|
/** @type {ImmutableMap<string, typeof initialListState>} */
|
||||||
|
featured_tags: ImmutableMap(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const normalizeList = (state, path, accounts, next) => {
|
const normalizeList = (state, path, accounts, next) => {
|
||||||
|
|||||||
@@ -377,6 +377,15 @@ $content-width: 840px;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
details > summary {
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
padding-top: 24px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: $no-columns-breakpoint) {
|
@media screen and (max-width: $no-columns-breakpoint) {
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
|
|||||||
@@ -1733,7 +1733,7 @@ body > [data-popper-placement] {
|
|||||||
.detailed-status__display-name {
|
.detailed-status__display-name {
|
||||||
color: var(--color-text-tertiary);
|
color: var(--color-text-tertiary);
|
||||||
|
|
||||||
span {
|
span:not(.account__avatar) {
|
||||||
display: inline;
|
display: inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
import { apiRequestPost, apiRequestGet } from 'mastodon/api';
|
import { apiRequestPost, apiRequestGet, apiRequestDelete } from 'mastodon/api';
|
||||||
import type {
|
import type {
|
||||||
ApiAccountJSON,
|
ApiAccountJSON,
|
||||||
ApiFamiliarFollowersJSON,
|
ApiFamiliarFollowersJSON,
|
||||||
} from 'mastodon/api_types/accounts';
|
} from 'mastodon/api_types/accounts';
|
||||||
import type { ApiRelationshipJSON } from 'mastodon/api_types/relationships';
|
import type { ApiRelationshipJSON } from 'mastodon/api_types/relationships';
|
||||||
import type { ApiHashtagJSON } from 'mastodon/api_types/tags';
|
import type {
|
||||||
|
ApiFeaturedTagJSON,
|
||||||
|
ApiHashtagJSON,
|
||||||
|
} from 'mastodon/api_types/tags';
|
||||||
|
|
||||||
export const apiSubmitAccountNote = (id: string, value: string) =>
|
export const apiSubmitAccountNote = (id: string, value: string) =>
|
||||||
apiRequestPost<ApiRelationshipJSON>(`v1/accounts/${id}/note`, {
|
apiRequestPost<ApiRelationshipJSON>(`v1/accounts/${id}/note`, {
|
||||||
@@ -30,7 +33,19 @@ export const apiRemoveAccountFromFollowers = (id: string) =>
|
|||||||
);
|
);
|
||||||
|
|
||||||
export const apiGetFeaturedTags = (id: string) =>
|
export const apiGetFeaturedTags = (id: string) =>
|
||||||
apiRequestGet<ApiHashtagJSON>(`v1/accounts/${id}/featured_tags`);
|
apiRequestGet<ApiHashtagJSON[]>(`v1/accounts/${id}/featured_tags`);
|
||||||
|
|
||||||
|
export const apiGetCurrentFeaturedTags = () =>
|
||||||
|
apiRequestGet<ApiFeaturedTagJSON[]>(`v1/featured_tags`);
|
||||||
|
|
||||||
|
export const apiPostFeaturedTag = (name: string) =>
|
||||||
|
apiRequestPost<ApiFeaturedTagJSON>('v1/featured_tags', { name });
|
||||||
|
|
||||||
|
export const apiDeleteFeaturedTag = (id: string) =>
|
||||||
|
apiRequestDelete(`v1/featured_tags/${id}`);
|
||||||
|
|
||||||
|
export const apiGetTagSuggestions = () =>
|
||||||
|
apiRequestGet<ApiHashtagJSON[]>('v1/featured_tags/suggestions');
|
||||||
|
|
||||||
export const apiGetEndorsedAccounts = (id: string) =>
|
export const apiGetEndorsedAccounts = (id: string) =>
|
||||||
apiRequestGet<ApiAccountJSON>(`v1/accounts/${id}/endorsements`);
|
apiRequestGet<ApiAccountJSON>(`v1/accounts/${id}/endorsements`);
|
||||||
|
|||||||
@@ -4,11 +4,29 @@ interface ApiHistoryJSON {
|
|||||||
uses: string;
|
uses: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ApiHashtagJSON {
|
interface ApiHashtagBase {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
url: string;
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ApiHashtagJSON extends ApiHashtagBase {
|
||||||
history: [ApiHistoryJSON, ...ApiHistoryJSON[]];
|
history: [ApiHistoryJSON, ...ApiHistoryJSON[]];
|
||||||
following?: boolean;
|
following?: boolean;
|
||||||
featuring?: boolean;
|
featuring?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ApiFeaturedTagJSON extends ApiHashtagBase {
|
||||||
|
statuses_count: number;
|
||||||
|
last_status_at: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function hashtagToFeaturedTag(tag: ApiHashtagJSON): ApiFeaturedTagJSON {
|
||||||
|
return {
|
||||||
|
id: tag.id,
|
||||||
|
name: tag.name,
|
||||||
|
url: tag.url,
|
||||||
|
statuses_count: 0,
|
||||||
|
last_status_at: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.input {
|
.input {
|
||||||
padding-right: 45px;
|
padding-inline-end: 45px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menuButton {
|
.menuButton {
|
||||||
|
|||||||
@@ -82,11 +82,23 @@ const ComboboxDemo: React.FC = () => {
|
|||||||
|
|
||||||
const meta = {
|
const meta = {
|
||||||
title: 'Components/Form Fields/ComboboxField',
|
title: 'Components/Form Fields/ComboboxField',
|
||||||
component: ComboboxDemo,
|
component: ComboboxField,
|
||||||
} satisfies Meta<typeof ComboboxDemo>;
|
render: () => <ComboboxDemo />,
|
||||||
|
} satisfies Meta<typeof ComboboxField>;
|
||||||
|
|
||||||
export default meta;
|
export default meta;
|
||||||
|
|
||||||
type Story = StoryObj<typeof meta>;
|
type Story = StoryObj<typeof meta>;
|
||||||
|
|
||||||
export const Example: Story = {};
|
export const Example: Story = {
|
||||||
|
args: {
|
||||||
|
// Adding these types to keep TS happy, they're not passed on to `ComboboxDemo`
|
||||||
|
label: '',
|
||||||
|
value: '',
|
||||||
|
onChange: () => undefined,
|
||||||
|
items: [],
|
||||||
|
getItemId: () => '',
|
||||||
|
renderItem: () => <>Nothing</>,
|
||||||
|
onSelectItem: () => undefined,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import type { ComponentPropsWithoutRef } from 'react';
|
|
||||||
import { forwardRef, useCallback, useId, useRef, useState } from 'react';
|
import { forwardRef, useCallback, useId, useRef, useState } from 'react';
|
||||||
|
|
||||||
import { useIntl } from 'react-intl';
|
import { useIntl } from 'react-intl';
|
||||||
@@ -9,6 +8,7 @@ import Overlay from 'react-overlays/Overlay';
|
|||||||
|
|
||||||
import KeyboardArrowDownIcon from '@/material-icons/400-24px/keyboard_arrow_down.svg?react';
|
import KeyboardArrowDownIcon from '@/material-icons/400-24px/keyboard_arrow_down.svg?react';
|
||||||
import KeyboardArrowUpIcon from '@/material-icons/400-24px/keyboard_arrow_up.svg?react';
|
import KeyboardArrowUpIcon from '@/material-icons/400-24px/keyboard_arrow_up.svg?react';
|
||||||
|
import SearchIcon from '@/material-icons/400-24px/search.svg?react';
|
||||||
import { matchWidth } from 'mastodon/components/dropdown/utils';
|
import { matchWidth } from 'mastodon/components/dropdown/utils';
|
||||||
import { IconButton } from 'mastodon/components/icon_button';
|
import { IconButton } from 'mastodon/components/icon_button';
|
||||||
import { useOnClickOutside } from 'mastodon/hooks/useOnClickOutside';
|
import { useOnClickOutside } from 'mastodon/hooks/useOnClickOutside';
|
||||||
@@ -17,6 +17,7 @@ import classes from './combobox.module.scss';
|
|||||||
import { FormFieldWrapper } from './form_field_wrapper';
|
import { FormFieldWrapper } from './form_field_wrapper';
|
||||||
import type { CommonFieldWrapperProps } from './form_field_wrapper';
|
import type { CommonFieldWrapperProps } from './form_field_wrapper';
|
||||||
import { TextInput } from './text_input_field';
|
import { TextInput } from './text_input_field';
|
||||||
|
import type { TextInputProps } from './text_input_field';
|
||||||
|
|
||||||
interface ComboboxItem {
|
interface ComboboxItem {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -27,17 +28,45 @@ export interface ComboboxItemState {
|
|||||||
isDisabled: boolean;
|
isDisabled: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ComboboxProps<
|
interface ComboboxProps<T extends ComboboxItem> extends TextInputProps {
|
||||||
T extends ComboboxItem,
|
/**
|
||||||
> extends ComponentPropsWithoutRef<'input'> {
|
* The value of the combobox's text input
|
||||||
|
*/
|
||||||
value: string;
|
value: string;
|
||||||
|
/**
|
||||||
|
* Change handler for the text input field
|
||||||
|
*/
|
||||||
onChange: React.ChangeEventHandler<HTMLInputElement>;
|
onChange: React.ChangeEventHandler<HTMLInputElement>;
|
||||||
|
/**
|
||||||
|
* Set this to true when the list of options is dynamic and currently loading.
|
||||||
|
* Causes a loading indicator to be displayed inside of the dropdown menu.
|
||||||
|
*/
|
||||||
isLoading?: boolean;
|
isLoading?: boolean;
|
||||||
|
/**
|
||||||
|
* The set of options/suggestions that should be rendered in the dropdown menu.
|
||||||
|
*/
|
||||||
items: T[];
|
items: T[];
|
||||||
getItemId: (item: T) => string;
|
/**
|
||||||
|
* A function that must return a unique id for each option passed via `items`
|
||||||
|
*/
|
||||||
|
getItemId?: (item: T) => string;
|
||||||
|
/**
|
||||||
|
* Providing this function turns the combobox into a multi-select box that assumes
|
||||||
|
* multiple options to be selectable. Single-selection is handled automatically.
|
||||||
|
*/
|
||||||
getIsItemSelected?: (item: T) => boolean;
|
getIsItemSelected?: (item: T) => boolean;
|
||||||
|
/**
|
||||||
|
* Use this function to mark items as disabled, if needed
|
||||||
|
*/
|
||||||
getIsItemDisabled?: (item: T) => boolean;
|
getIsItemDisabled?: (item: T) => boolean;
|
||||||
|
/**
|
||||||
|
* Customise the rendering of each option.
|
||||||
|
* The rendered content must not contain other interactive content!
|
||||||
|
*/
|
||||||
renderItem: (item: T, state: ComboboxItemState) => React.ReactElement;
|
renderItem: (item: T, state: ComboboxItemState) => React.ReactElement;
|
||||||
|
/**
|
||||||
|
* The main selection handler, called when an option is selected or deselected.
|
||||||
|
*/
|
||||||
onSelectItem: (item: T) => void;
|
onSelectItem: (item: T) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,8 +74,12 @@ interface Props<T extends ComboboxItem>
|
|||||||
extends ComboboxProps<T>, CommonFieldWrapperProps {}
|
extends ComboboxProps<T>, CommonFieldWrapperProps {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The combobox field allows users to select one or multiple items
|
* The combobox field allows users to select one or more items
|
||||||
* from a large list of options by searching or filtering.
|
* by searching or filtering a large or dynamic list of options.
|
||||||
|
*
|
||||||
|
* It is an implementation of the [APG Combobox pattern](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/),
|
||||||
|
* with inspiration taken from Sarah Higley's extensive combobox
|
||||||
|
* [research & implementations](https://sarahmhigley.com/writing/select-your-poison/).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const ComboboxFieldWithRef = <T extends ComboboxItem>(
|
export const ComboboxFieldWithRef = <T extends ComboboxItem>(
|
||||||
@@ -80,7 +113,7 @@ const ComboboxWithRef = <T extends ComboboxItem>(
|
|||||||
value,
|
value,
|
||||||
isLoading = false,
|
isLoading = false,
|
||||||
items,
|
items,
|
||||||
getItemId,
|
getItemId = (item) => item.id,
|
||||||
getIsItemDisabled,
|
getIsItemDisabled,
|
||||||
getIsItemSelected,
|
getIsItemSelected,
|
||||||
disabled,
|
disabled,
|
||||||
@@ -88,6 +121,7 @@ const ComboboxWithRef = <T extends ComboboxItem>(
|
|||||||
onSelectItem,
|
onSelectItem,
|
||||||
onChange,
|
onChange,
|
||||||
onKeyDown,
|
onKeyDown,
|
||||||
|
icon = SearchIcon,
|
||||||
className,
|
className,
|
||||||
...otherProps
|
...otherProps
|
||||||
}: ComboboxProps<T>,
|
}: ComboboxProps<T>,
|
||||||
@@ -306,6 +340,7 @@ const ComboboxWithRef = <T extends ComboboxItem>(
|
|||||||
value={value}
|
value={value}
|
||||||
onChange={handleInputChange}
|
onChange={handleInputChange}
|
||||||
onKeyDown={handleInputKeyDown}
|
onKeyDown={handleInputKeyDown}
|
||||||
|
icon={icon}
|
||||||
className={classNames(classes.input, className)}
|
className={classNames(classes.input, className)}
|
||||||
ref={mergeRefs}
|
ref={mergeRefs}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -20,6 +20,15 @@
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.iconWrapper & {
|
||||||
|
// Make space for icon displayed at start of input
|
||||||
|
padding-inline-start: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::placeholder {
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
outline-color: var(--color-text-brand);
|
outline-color: var(--color-text-brand);
|
||||||
}
|
}
|
||||||
@@ -40,3 +49,17 @@
|
|||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.iconWrapper {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
pointer-events: none;
|
||||||
|
position: absolute;
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
inset-inline-start: 10px;
|
||||||
|
inset-block-start: 10px;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import type { Meta, StoryObj } from '@storybook/react-vite';
|
import type { Meta, StoryObj } from '@storybook/react-vite';
|
||||||
|
|
||||||
|
import SearchIcon from '@/material-icons/400-24px/search.svg?react';
|
||||||
|
|
||||||
import { TextInputField, TextInput } from './text_input_field';
|
import { TextInputField, TextInput } from './text_input_field';
|
||||||
|
|
||||||
const meta = {
|
const meta = {
|
||||||
@@ -42,6 +44,14 @@ export const WithError: Story = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const WithIcon: Story = {
|
||||||
|
args: {
|
||||||
|
label: 'Search',
|
||||||
|
hint: undefined,
|
||||||
|
icon: SearchIcon,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
export const Plain: Story = {
|
export const Plain: Story = {
|
||||||
render(args) {
|
render(args) {
|
||||||
return <TextInput {...args} />;
|
return <TextInput {...args} />;
|
||||||
|
|||||||
@@ -3,12 +3,18 @@ import { forwardRef } from 'react';
|
|||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
import type { IconProp } from 'mastodon/components/icon';
|
||||||
|
import { Icon } from 'mastodon/components/icon';
|
||||||
|
|
||||||
import { FormFieldWrapper } from './form_field_wrapper';
|
import { FormFieldWrapper } from './form_field_wrapper';
|
||||||
import type { CommonFieldWrapperProps } from './form_field_wrapper';
|
import type { CommonFieldWrapperProps } from './form_field_wrapper';
|
||||||
import classes from './text_input.module.scss';
|
import classes from './text_input.module.scss';
|
||||||
|
|
||||||
interface Props
|
export interface TextInputProps extends ComponentPropsWithoutRef<'input'> {
|
||||||
extends ComponentPropsWithoutRef<'input'>, CommonFieldWrapperProps {}
|
icon?: IconProp;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Props extends TextInputProps, CommonFieldWrapperProps {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple form field for single-line text.
|
* A simple form field for single-line text.
|
||||||
@@ -33,16 +39,33 @@ export const TextInputField = forwardRef<HTMLInputElement, Props>(
|
|||||||
|
|
||||||
TextInputField.displayName = 'TextInputField';
|
TextInputField.displayName = 'TextInputField';
|
||||||
|
|
||||||
export const TextInput = forwardRef<
|
export const TextInput = forwardRef<HTMLInputElement, TextInputProps>(
|
||||||
HTMLInputElement,
|
({ type = 'text', icon, className, ...otherProps }, ref) => (
|
||||||
ComponentPropsWithoutRef<'input'>
|
<WrapFieldWithIcon icon={icon}>
|
||||||
>(({ type = 'text', className, ...otherProps }, ref) => (
|
<input
|
||||||
<input
|
type={type}
|
||||||
type={type}
|
{...otherProps}
|
||||||
{...otherProps}
|
className={classNames(className, classes.input)}
|
||||||
className={classNames(className, classes.input)}
|
ref={ref}
|
||||||
ref={ref}
|
/>
|
||||||
/>
|
</WrapFieldWithIcon>
|
||||||
));
|
),
|
||||||
|
);
|
||||||
|
|
||||||
TextInput.displayName = 'TextInput';
|
TextInput.displayName = 'TextInput';
|
||||||
|
|
||||||
|
const WrapFieldWithIcon: React.FC<{
|
||||||
|
icon?: IconProp;
|
||||||
|
children: React.ReactElement;
|
||||||
|
}> = ({ icon, children }) => {
|
||||||
|
if (icon) {
|
||||||
|
return (
|
||||||
|
<div className={classes.iconWrapper}>
|
||||||
|
<Icon icon={icon} id='input-icon' className={classes.icon} />
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return children;
|
||||||
|
};
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
import type { FC } from 'react';
|
||||||
|
|
||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { Column } from '@/mastodon/components/column';
|
||||||
|
import { ColumnHeader } from '@/mastodon/components/column_header';
|
||||||
|
import { LoadingIndicator } from '@/mastodon/components/loading_indicator';
|
||||||
|
import BundleColumnError from '@/mastodon/features/ui/components/bundle_column_error';
|
||||||
|
|
||||||
|
import { useColumnsContext } from '../../ui/util/columns_context';
|
||||||
|
import classes from '../styles.module.scss';
|
||||||
|
|
||||||
|
export const AccountEditEmptyColumn: FC<{
|
||||||
|
notFound?: boolean;
|
||||||
|
}> = ({ notFound }) => {
|
||||||
|
const { multiColumn } = useColumnsContext();
|
||||||
|
|
||||||
|
if (notFound) {
|
||||||
|
return <BundleColumnError multiColumn={multiColumn} errorType='routing' />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Column bindToDocument={!multiColumn} className={classes.column}>
|
||||||
|
<LoadingIndicator />
|
||||||
|
</Column>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const AccountEditColumn: FC<{
|
||||||
|
title: string;
|
||||||
|
to: string;
|
||||||
|
children: React.ReactNode;
|
||||||
|
}> = ({ to, title, children }) => {
|
||||||
|
const { multiColumn } = useColumnsContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Column bindToDocument={!multiColumn} className={classes.column}>
|
||||||
|
<ColumnHeader
|
||||||
|
title={title}
|
||||||
|
className={classes.columnHeader}
|
||||||
|
showBackButton
|
||||||
|
extraButton={
|
||||||
|
<Link to={to} className='button'>
|
||||||
|
<FormattedMessage
|
||||||
|
id='account_edit.column_button'
|
||||||
|
defaultMessage='Done'
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{children}
|
||||||
|
</Column>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
import type { FC, MouseEventHandler } from 'react';
|
||||||
|
|
||||||
|
import type { MessageDescriptor } from 'react-intl';
|
||||||
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
import { Button } from '@/mastodon/components/button';
|
||||||
|
import { IconButton } from '@/mastodon/components/icon_button';
|
||||||
|
import DeleteIcon from '@/material-icons/400-24px/delete.svg?react';
|
||||||
|
import EditIcon from '@/material-icons/400-24px/edit.svg?react';
|
||||||
|
|
||||||
|
import classes from '../styles.module.scss';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
add: {
|
||||||
|
id: 'account_edit.button.add',
|
||||||
|
defaultMessage: 'Add {item}',
|
||||||
|
},
|
||||||
|
edit: {
|
||||||
|
id: 'account_edit.button.edit',
|
||||||
|
defaultMessage: 'Edit {item}',
|
||||||
|
},
|
||||||
|
delete: {
|
||||||
|
id: 'account_edit.button.delete',
|
||||||
|
defaultMessage: 'Delete {item}',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export interface EditButtonProps {
|
||||||
|
onClick: MouseEventHandler;
|
||||||
|
item: string | MessageDescriptor;
|
||||||
|
edit?: boolean;
|
||||||
|
icon?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const EditButton: FC<EditButtonProps> = ({
|
||||||
|
onClick,
|
||||||
|
item,
|
||||||
|
edit = false,
|
||||||
|
icon = edit,
|
||||||
|
disabled,
|
||||||
|
}) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const itemText = typeof item === 'string' ? item : intl.formatMessage(item);
|
||||||
|
const label = intl.formatMessage(messages[edit ? 'edit' : 'add'], {
|
||||||
|
item: itemText,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (icon) {
|
||||||
|
return (
|
||||||
|
<EditIconButton title={label} onClick={onClick} disabled={disabled} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
className={classes.editButton}
|
||||||
|
onClick={onClick}
|
||||||
|
disabled={disabled}
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const EditIconButton: FC<{
|
||||||
|
onClick: MouseEventHandler;
|
||||||
|
title: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
}> = ({ title, onClick, disabled }) => (
|
||||||
|
<IconButton
|
||||||
|
icon='pencil'
|
||||||
|
iconComponent={EditIcon}
|
||||||
|
onClick={onClick}
|
||||||
|
className={classes.editButton}
|
||||||
|
title={title}
|
||||||
|
disabled={disabled}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const DeleteIconButton: FC<{
|
||||||
|
onClick: MouseEventHandler;
|
||||||
|
item: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
}> = ({ onClick, item, disabled }) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
return (
|
||||||
|
<IconButton
|
||||||
|
icon='delete'
|
||||||
|
iconComponent={DeleteIcon}
|
||||||
|
onClick={onClick}
|
||||||
|
className={classNames(classes.editButton, classes.deleteButton)}
|
||||||
|
title={intl.formatMessage(messages.delete, { item })}
|
||||||
|
disabled={disabled}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
import classes from '../styles.module.scss';
|
||||||
|
|
||||||
|
import { DeleteIconButton, EditButton } from './edit_button';
|
||||||
|
|
||||||
|
interface AnyItem {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AccountEditItemListProps<Item extends AnyItem = AnyItem> {
|
||||||
|
renderItem?: (item: Item) => React.ReactNode;
|
||||||
|
items: Item[];
|
||||||
|
onEdit?: (item: Item) => void;
|
||||||
|
onDelete?: (item: Item) => void;
|
||||||
|
disabled?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AccountEditItemList = <Item extends AnyItem>({
|
||||||
|
renderItem,
|
||||||
|
items,
|
||||||
|
onEdit,
|
||||||
|
onDelete,
|
||||||
|
disabled,
|
||||||
|
}: AccountEditItemListProps<Item>) => {
|
||||||
|
if (items.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ul className={classes.itemList}>
|
||||||
|
{items.map((item) => (
|
||||||
|
<li key={item.id}>
|
||||||
|
<span>{renderItem?.(item) ?? item.name}</span>
|
||||||
|
<AccountEditItemButtons
|
||||||
|
item={item}
|
||||||
|
onEdit={onEdit}
|
||||||
|
onDelete={onDelete}
|
||||||
|
disabled={disabled}
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
type AccountEditItemButtonsProps<Item extends AnyItem = AnyItem> = Pick<
|
||||||
|
AccountEditItemListProps<Item>,
|
||||||
|
'onEdit' | 'onDelete' | 'disabled'
|
||||||
|
> & { item: Item };
|
||||||
|
|
||||||
|
const AccountEditItemButtons = <Item extends AnyItem>({
|
||||||
|
item,
|
||||||
|
onDelete,
|
||||||
|
onEdit,
|
||||||
|
disabled,
|
||||||
|
}: AccountEditItemButtonsProps<Item>) => {
|
||||||
|
const handleEdit = useCallback(() => {
|
||||||
|
onEdit?.(item);
|
||||||
|
}, [item, onEdit]);
|
||||||
|
const handleDelete = useCallback(() => {
|
||||||
|
onDelete?.(item);
|
||||||
|
}, [item, onDelete]);
|
||||||
|
|
||||||
|
if (!onEdit && !onDelete) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={classes.itemListButtons}>
|
||||||
|
{onEdit && (
|
||||||
|
<EditButton
|
||||||
|
edit
|
||||||
|
item={item.name}
|
||||||
|
disabled={disabled}
|
||||||
|
onClick={handleEdit}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{onDelete && (
|
||||||
|
<DeleteIconButton
|
||||||
|
item={item.name}
|
||||||
|
disabled={disabled}
|
||||||
|
onClick={handleDelete}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,55 +1,36 @@
|
|||||||
import type { FC, ReactNode } from 'react';
|
import type { FC, ReactNode } from 'react';
|
||||||
|
|
||||||
import type { MessageDescriptor } from 'react-intl';
|
import type { MessageDescriptor } from 'react-intl';
|
||||||
import { defineMessage, FormattedMessage, useIntl } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
import { IconButton } from '@/mastodon/components/icon_button';
|
|
||||||
import EditIcon from '@/material-icons/400-24px/edit.svg?react';
|
|
||||||
|
|
||||||
import classes from '../styles.module.scss';
|
import classes from '../styles.module.scss';
|
||||||
|
|
||||||
const buttonMessage = defineMessage({
|
|
||||||
id: 'account_edit.section_edit_button',
|
|
||||||
defaultMessage: 'Edit',
|
|
||||||
});
|
|
||||||
|
|
||||||
interface AccountEditSectionProps {
|
interface AccountEditSectionProps {
|
||||||
title: MessageDescriptor;
|
title: MessageDescriptor;
|
||||||
description?: MessageDescriptor;
|
description?: MessageDescriptor;
|
||||||
showDescription?: boolean;
|
showDescription?: boolean;
|
||||||
onEdit?: () => void;
|
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
className?: string;
|
className?: string;
|
||||||
extraButtons?: ReactNode;
|
buttons?: ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AccountEditSection: FC<AccountEditSectionProps> = ({
|
export const AccountEditSection: FC<AccountEditSectionProps> = ({
|
||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
showDescription,
|
showDescription,
|
||||||
onEdit,
|
|
||||||
children,
|
children,
|
||||||
className,
|
className,
|
||||||
extraButtons,
|
buttons,
|
||||||
}) => {
|
}) => {
|
||||||
const intl = useIntl();
|
|
||||||
return (
|
return (
|
||||||
<section className={classNames(className, classes.section)}>
|
<section className={classNames(className, classes.section)}>
|
||||||
<header className={classes.sectionHeader}>
|
<header className={classes.sectionHeader}>
|
||||||
<h3 className={classes.sectionTitle}>
|
<h3 className={classes.sectionTitle}>
|
||||||
<FormattedMessage {...title} />
|
<FormattedMessage {...title} />
|
||||||
</h3>
|
</h3>
|
||||||
{onEdit && (
|
{buttons}
|
||||||
<IconButton
|
|
||||||
icon='pencil'
|
|
||||||
iconComponent={EditIcon}
|
|
||||||
onClick={onEdit}
|
|
||||||
title={`${intl.formatMessage(buttonMessage)} ${intl.formatMessage(title)}`}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{extraButtons}
|
|
||||||
</header>
|
</header>
|
||||||
{showDescription && (
|
{showDescription && (
|
||||||
<p className={classes.sectionSubtitle}>
|
<p className={classes.sectionSubtitle}>
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import type { ChangeEventHandler, FC } from 'react';
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
import { useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
import type { ApiFeaturedTagJSON } from '@/mastodon/api_types/tags';
|
||||||
|
import { Combobox } from '@/mastodon/components/form_fields';
|
||||||
|
import {
|
||||||
|
addFeaturedTag,
|
||||||
|
clearSearch,
|
||||||
|
updateSearchQuery,
|
||||||
|
} from '@/mastodon/reducers/slices/profile_edit';
|
||||||
|
import { useAppDispatch, useAppSelector } from '@/mastodon/store';
|
||||||
|
import SearchIcon from '@/material-icons/400-24px/search.svg?react';
|
||||||
|
|
||||||
|
import classes from '../styles.module.scss';
|
||||||
|
|
||||||
|
export const AccountEditTagSearch: FC = () => {
|
||||||
|
const { query, isLoading, results } = useAppSelector(
|
||||||
|
(state) => state.profileEdit.search,
|
||||||
|
);
|
||||||
|
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const handleSearchChange: ChangeEventHandler<HTMLInputElement> = useCallback(
|
||||||
|
(e) => {
|
||||||
|
void dispatch(updateSearchQuery(e.target.value));
|
||||||
|
},
|
||||||
|
[dispatch],
|
||||||
|
);
|
||||||
|
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const handleSelect = useCallback(
|
||||||
|
(item: ApiFeaturedTagJSON) => {
|
||||||
|
void dispatch(clearSearch());
|
||||||
|
void dispatch(addFeaturedTag({ name: item.name }));
|
||||||
|
},
|
||||||
|
[dispatch],
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Combobox
|
||||||
|
value={query}
|
||||||
|
onChange={handleSearchChange}
|
||||||
|
placeholder={intl.formatMessage({
|
||||||
|
id: 'account_edit_tags.search_placeholder',
|
||||||
|
defaultMessage: 'Enter a hashtag…',
|
||||||
|
})}
|
||||||
|
items={results ?? []}
|
||||||
|
isLoading={isLoading}
|
||||||
|
renderItem={renderItem}
|
||||||
|
onSelectItem={handleSelect}
|
||||||
|
className={classes.autoComplete}
|
||||||
|
icon={SearchIcon}
|
||||||
|
type='search'
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderItem = (item: ApiFeaturedTagJSON) => <p>#{item.name}</p>;
|
||||||
117
app/javascript/mastodon/features/account_edit/featured_tags.tsx
Normal file
117
app/javascript/mastodon/features/account_edit/featured_tags.tsx
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
import { useCallback, useEffect } from 'react';
|
||||||
|
import type { FC } from 'react';
|
||||||
|
|
||||||
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
import type { ApiFeaturedTagJSON } from '@/mastodon/api_types/tags';
|
||||||
|
import { LoadingIndicator } from '@/mastodon/components/loading_indicator';
|
||||||
|
import { Tag } from '@/mastodon/components/tags/tag';
|
||||||
|
import { useAccount } from '@/mastodon/hooks/useAccount';
|
||||||
|
import { useCurrentAccountId } from '@/mastodon/hooks/useAccountId';
|
||||||
|
import {
|
||||||
|
addFeaturedTag,
|
||||||
|
deleteFeaturedTag,
|
||||||
|
fetchFeaturedTags,
|
||||||
|
fetchSuggestedTags,
|
||||||
|
} from '@/mastodon/reducers/slices/profile_edit';
|
||||||
|
import { useAppDispatch, useAppSelector } from '@/mastodon/store';
|
||||||
|
|
||||||
|
import { AccountEditColumn, AccountEditEmptyColumn } from './components/column';
|
||||||
|
import { AccountEditItemList } from './components/item_list';
|
||||||
|
import { AccountEditTagSearch } from './components/tag_search';
|
||||||
|
import classes from './styles.module.scss';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
columnTitle: {
|
||||||
|
id: 'account_edit_tags.column_title',
|
||||||
|
defaultMessage: 'Edit featured hashtags',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const AccountEditFeaturedTags: FC = () => {
|
||||||
|
const accountId = useCurrentAccountId();
|
||||||
|
const account = useAccount(accountId);
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const { tags, tagSuggestions, isLoading, isPending } = useAppSelector(
|
||||||
|
(state) => state.profileEdit,
|
||||||
|
);
|
||||||
|
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
useEffect(() => {
|
||||||
|
void dispatch(fetchFeaturedTags());
|
||||||
|
void dispatch(fetchSuggestedTags());
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
|
const handleDeleteTag = useCallback(
|
||||||
|
({ id }: { id: string }) => {
|
||||||
|
void dispatch(deleteFeaturedTag({ tagId: id }));
|
||||||
|
},
|
||||||
|
[dispatch],
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!accountId || !account) {
|
||||||
|
return <AccountEditEmptyColumn notFound={!accountId} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AccountEditColumn
|
||||||
|
title={intl.formatMessage(messages.columnTitle)}
|
||||||
|
to='/profile/edit'
|
||||||
|
>
|
||||||
|
<div className={classes.wrapper}>
|
||||||
|
<FormattedMessage
|
||||||
|
id='account_edit_tags.help_text'
|
||||||
|
defaultMessage='Featured hashtags help users discover and interact with your profile. They appear as filters on your Profile page’s Activity view.'
|
||||||
|
tagName='p'
|
||||||
|
/>
|
||||||
|
<AccountEditTagSearch />
|
||||||
|
{tagSuggestions.length > 0 && (
|
||||||
|
<div className={classes.tagSuggestions}>
|
||||||
|
<FormattedMessage
|
||||||
|
id='account_edit_tags.suggestions'
|
||||||
|
defaultMessage='Suggestions:'
|
||||||
|
/>
|
||||||
|
{tagSuggestions.map((tag) => (
|
||||||
|
<SuggestedTag name={tag.name} key={tag.id} disabled={isPending} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{isLoading && <LoadingIndicator />}
|
||||||
|
<AccountEditItemList
|
||||||
|
items={tags}
|
||||||
|
disabled={isPending}
|
||||||
|
renderItem={renderTag}
|
||||||
|
onDelete={handleDeleteTag}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</AccountEditColumn>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
function renderTag(tag: ApiFeaturedTagJSON) {
|
||||||
|
return (
|
||||||
|
<div className={classes.tagItem}>
|
||||||
|
<h4>#{tag.name}</h4>
|
||||||
|
{tag.statuses_count > 0 && (
|
||||||
|
<FormattedMessage
|
||||||
|
id='account_edit_tags.tag_status_count'
|
||||||
|
defaultMessage='{count} posts'
|
||||||
|
values={{ count: tag.statuses_count }}
|
||||||
|
tagName='p'
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const SuggestedTag: FC<{ name: string; disabled?: boolean }> = ({
|
||||||
|
name,
|
||||||
|
disabled,
|
||||||
|
}) => {
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const handleAddTag = useCallback(() => {
|
||||||
|
void dispatch(addFeaturedTag({ name }));
|
||||||
|
}, [dispatch, name]);
|
||||||
|
return <Tag name={name} onClick={handleAddTag} disabled={disabled} />;
|
||||||
|
};
|
||||||
@@ -1,28 +1,31 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback, useEffect } from 'react';
|
||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
|
|
||||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { Link } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
|
|
||||||
import type { ModalType } from '@/mastodon/actions/modal';
|
import type { ModalType } from '@/mastodon/actions/modal';
|
||||||
import { openModal } from '@/mastodon/actions/modal';
|
import { openModal } from '@/mastodon/actions/modal';
|
||||||
import { AccountBio } from '@/mastodon/components/account_bio';
|
import { AccountBio } from '@/mastodon/components/account_bio';
|
||||||
import { Avatar } from '@/mastodon/components/avatar';
|
import { Avatar } from '@/mastodon/components/avatar';
|
||||||
import { Column } from '@/mastodon/components/column';
|
|
||||||
import { ColumnHeader } from '@/mastodon/components/column_header';
|
|
||||||
import { DisplayNameSimple } from '@/mastodon/components/display_name/simple';
|
import { DisplayNameSimple } from '@/mastodon/components/display_name/simple';
|
||||||
import { LoadingIndicator } from '@/mastodon/components/loading_indicator';
|
|
||||||
import BundleColumnError from '@/mastodon/features/ui/components/bundle_column_error';
|
|
||||||
import { useAccount } from '@/mastodon/hooks/useAccount';
|
import { useAccount } from '@/mastodon/hooks/useAccount';
|
||||||
import { useCurrentAccountId } from '@/mastodon/hooks/useAccountId';
|
import { useCurrentAccountId } from '@/mastodon/hooks/useAccountId';
|
||||||
import { autoPlayGif } from '@/mastodon/initial_state';
|
import { autoPlayGif } from '@/mastodon/initial_state';
|
||||||
import { useAppDispatch } from '@/mastodon/store';
|
import { fetchFeaturedTags } from '@/mastodon/reducers/slices/profile_edit';
|
||||||
|
import { useAppDispatch, useAppSelector } from '@/mastodon/store';
|
||||||
|
|
||||||
|
import { AccountEditColumn, AccountEditEmptyColumn } from './components/column';
|
||||||
|
import { EditButton } from './components/edit_button';
|
||||||
import { AccountEditSection } from './components/section';
|
import { AccountEditSection } from './components/section';
|
||||||
import classes from './styles.module.scss';
|
import classes from './styles.module.scss';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
|
columnTitle: {
|
||||||
|
id: 'account_edit.column_title',
|
||||||
|
defaultMessage: 'Edit Profile',
|
||||||
|
},
|
||||||
displayNameTitle: {
|
displayNameTitle: {
|
||||||
id: 'account_edit.display_name.title',
|
id: 'account_edit.display_name.title',
|
||||||
defaultMessage: 'Display name',
|
defaultMessage: 'Display name',
|
||||||
@@ -58,6 +61,10 @@ const messages = defineMessages({
|
|||||||
defaultMessage:
|
defaultMessage:
|
||||||
'Help others identify, and have quick access to, your favorite topics.',
|
'Help others identify, and have quick access to, your favorite topics.',
|
||||||
},
|
},
|
||||||
|
featuredHashtagsItem: {
|
||||||
|
id: 'account_edit.featured_hashtags.item',
|
||||||
|
defaultMessage: 'hashtags',
|
||||||
|
},
|
||||||
profileTabTitle: {
|
profileTabTitle: {
|
||||||
id: 'account_edit.profile_tab.title',
|
id: 'account_edit.profile_tab.title',
|
||||||
defaultMessage: 'Profile tab settings',
|
defaultMessage: 'Profile tab settings',
|
||||||
@@ -68,12 +75,20 @@ const messages = defineMessages({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const AccountEdit: FC<{ multiColumn: boolean }> = ({ multiColumn }) => {
|
export const AccountEdit: FC = () => {
|
||||||
const accountId = useCurrentAccountId();
|
const accountId = useCurrentAccountId();
|
||||||
const account = useAccount(accountId);
|
const account = useAccount(accountId);
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
const { tags: featuredTags, isLoading: isTagsLoading } = useAppSelector(
|
||||||
|
(state) => state.profileEdit,
|
||||||
|
);
|
||||||
|
useEffect(() => {
|
||||||
|
void dispatch(fetchFeaturedTags());
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
const handleOpenModal = useCallback(
|
const handleOpenModal = useCallback(
|
||||||
(type: ModalType, props?: Record<string, unknown>) => {
|
(type: ModalType, props?: Record<string, unknown>) => {
|
||||||
dispatch(openModal({ modalType: type, modalProps: props ?? {} }));
|
dispatch(openModal({ modalType: type, modalProps: props ?? {} }));
|
||||||
@@ -87,38 +102,25 @@ export const AccountEdit: FC<{ multiColumn: boolean }> = ({ multiColumn }) => {
|
|||||||
handleOpenModal('ACCOUNT_EDIT_BIO');
|
handleOpenModal('ACCOUNT_EDIT_BIO');
|
||||||
}, [handleOpenModal]);
|
}, [handleOpenModal]);
|
||||||
|
|
||||||
if (!accountId) {
|
const history = useHistory();
|
||||||
return <BundleColumnError multiColumn={multiColumn} errorType='routing' />;
|
const handleFeaturedTagsEdit = useCallback(() => {
|
||||||
}
|
history.push('/profile/featured_tags');
|
||||||
|
}, [history]);
|
||||||
|
|
||||||
if (!account) {
|
if (!accountId || !account) {
|
||||||
return (
|
return <AccountEditEmptyColumn notFound={!accountId} />;
|
||||||
<Column bindToDocument={!multiColumn} className={classes.column}>
|
|
||||||
<LoadingIndicator />
|
|
||||||
</Column>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const headerSrc = autoPlayGif ? account.header : account.header_static;
|
const headerSrc = autoPlayGif ? account.header : account.header_static;
|
||||||
|
const hasName = !!account.display_name;
|
||||||
|
const hasBio = !!account.note_plain;
|
||||||
|
const hasTags = !isTagsLoading && featuredTags.length > 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Column bindToDocument={!multiColumn} className={classes.column}>
|
<AccountEditColumn
|
||||||
<ColumnHeader
|
title={intl.formatMessage(messages.columnTitle)}
|
||||||
title={intl.formatMessage({
|
to={`/@${account.acct}`}
|
||||||
id: 'account_edit.column_title',
|
>
|
||||||
defaultMessage: 'Edit Profile',
|
|
||||||
})}
|
|
||||||
className={classes.columnHeader}
|
|
||||||
showBackButton
|
|
||||||
extraButton={
|
|
||||||
<Link to={`/@${account.acct}`} className='button'>
|
|
||||||
<FormattedMessage
|
|
||||||
id='account_edit.column_button'
|
|
||||||
defaultMessage='Done'
|
|
||||||
/>
|
|
||||||
</Link>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<header>
|
<header>
|
||||||
<div className={classes.profileImage}>
|
<div className={classes.profileImage}>
|
||||||
{headerSrc && <img src={headerSrc} alt='' />}
|
{headerSrc && <img src={headerSrc} alt='' />}
|
||||||
@@ -129,8 +131,14 @@ export const AccountEdit: FC<{ multiColumn: boolean }> = ({ multiColumn }) => {
|
|||||||
<AccountEditSection
|
<AccountEditSection
|
||||||
title={messages.displayNameTitle}
|
title={messages.displayNameTitle}
|
||||||
description={messages.displayNamePlaceholder}
|
description={messages.displayNamePlaceholder}
|
||||||
showDescription={account.display_name.length === 0}
|
showDescription={!hasName}
|
||||||
onEdit={handleNameEdit}
|
buttons={
|
||||||
|
<EditButton
|
||||||
|
onClick={handleNameEdit}
|
||||||
|
item={messages.displayNameTitle}
|
||||||
|
edit={hasName}
|
||||||
|
/>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<DisplayNameSimple account={account} />
|
<DisplayNameSimple account={account} />
|
||||||
</AccountEditSection>
|
</AccountEditSection>
|
||||||
@@ -138,8 +146,14 @@ export const AccountEdit: FC<{ multiColumn: boolean }> = ({ multiColumn }) => {
|
|||||||
<AccountEditSection
|
<AccountEditSection
|
||||||
title={messages.bioTitle}
|
title={messages.bioTitle}
|
||||||
description={messages.bioPlaceholder}
|
description={messages.bioPlaceholder}
|
||||||
showDescription={!account.note_plain}
|
showDescription={!hasBio}
|
||||||
onEdit={handleBioEdit}
|
buttons={
|
||||||
|
<EditButton
|
||||||
|
onClick={handleBioEdit}
|
||||||
|
item={messages.bioTitle}
|
||||||
|
edit={hasBio}
|
||||||
|
/>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<AccountBio accountId={accountId} />
|
<AccountBio accountId={accountId} />
|
||||||
</AccountEditSection>
|
</AccountEditSection>
|
||||||
@@ -153,14 +167,23 @@ export const AccountEdit: FC<{ multiColumn: boolean }> = ({ multiColumn }) => {
|
|||||||
<AccountEditSection
|
<AccountEditSection
|
||||||
title={messages.featuredHashtagsTitle}
|
title={messages.featuredHashtagsTitle}
|
||||||
description={messages.featuredHashtagsPlaceholder}
|
description={messages.featuredHashtagsPlaceholder}
|
||||||
showDescription
|
showDescription={!hasTags}
|
||||||
/>
|
buttons={
|
||||||
|
<EditButton
|
||||||
|
onClick={handleFeaturedTagsEdit}
|
||||||
|
edit={hasTags}
|
||||||
|
item={messages.featuredHashtagsItem}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{featuredTags.map((tag) => `#${tag.name}`).join(', ')}
|
||||||
|
</AccountEditSection>
|
||||||
|
|
||||||
<AccountEditSection
|
<AccountEditSection
|
||||||
title={messages.profileTabTitle}
|
title={messages.profileTabTitle}
|
||||||
description={messages.profileTabSubtitle}
|
description={messages.profileTabSubtitle}
|
||||||
showDescription
|
showDescription
|
||||||
/>
|
/>
|
||||||
</Column>
|
</AccountEditColumn>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,15 +1,4 @@
|
|||||||
.column {
|
// Profile Edit Page
|
||||||
border: 1px solid var(--color-border-primary);
|
|
||||||
border-top-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.columnHeader {
|
|
||||||
:global(.column-header__buttons) {
|
|
||||||
align-items: center;
|
|
||||||
padding-inline-end: 16px;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.profileImage {
|
.profileImage {
|
||||||
height: 120px;
|
height: 120px;
|
||||||
@@ -35,40 +24,41 @@
|
|||||||
border: 1px solid var(--color-border-primary);
|
border: 1px solid var(--color-border-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.section {
|
// Featured Tags Page
|
||||||
padding: 20px;
|
|
||||||
border-bottom: 1px solid var(--color-border-primary);
|
.wrapper {
|
||||||
font-size: 15px;
|
padding: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sectionHeader {
|
.autoComplete,
|
||||||
|
.tagSuggestions {
|
||||||
|
margin: 12px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tagSuggestions {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
gap: 4px;
|
||||||
|
flex-wrap: wrap;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
|
|
||||||
> button {
|
// Add more padding to the suggestions label
|
||||||
border: 1px solid var(--color-border-primary);
|
> span {
|
||||||
border-radius: 8px;
|
margin-right: 4px;
|
||||||
box-sizing: border-box;
|
|
||||||
padding: 4px;
|
|
||||||
|
|
||||||
svg {
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sectionTitle {
|
.tagItem {
|
||||||
flex-grow: 1;
|
> h4 {
|
||||||
font-size: 17px;
|
font-size: 15px;
|
||||||
font-weight: 600;
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
> p {
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sectionSubtitle {
|
// Modals
|
||||||
color: var(--color-text-secondary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.inputWrapper {
|
.inputWrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -100,6 +90,104 @@ textarea.inputText {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Column component
|
||||||
|
|
||||||
|
.column {
|
||||||
|
border: 1px solid var(--color-border-primary);
|
||||||
|
border-top-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.columnHeader {
|
||||||
|
:global(.column-header__buttons) {
|
||||||
|
align-items: center;
|
||||||
|
padding-inline-end: 16px;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Edit button component
|
||||||
|
|
||||||
|
.editButton {
|
||||||
|
border: 1px solid var(--color-border-primary);
|
||||||
|
border-radius: 8px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 4px;
|
||||||
|
transition:
|
||||||
|
color 0.2s ease-in-out,
|
||||||
|
background-color 0.2s ease-in-out;
|
||||||
|
|
||||||
|
&:global(.button) {
|
||||||
|
background-color: var(--color-bg-primary);
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
font-size: 13px;
|
||||||
|
padding: 4px 8px;
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&:focus,
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--color-bg-brand-softer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.deleteButton {
|
||||||
|
--default-icon-color: var(--color-text-error);
|
||||||
|
--hover-bg-color: var(--color-bg-error-base-hover);
|
||||||
|
--hover-icon-color: var(--color-text-on-error-base);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Item list component
|
||||||
|
|
||||||
|
.itemList {
|
||||||
|
> li {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 12px 0;
|
||||||
|
|
||||||
|
> :first-child {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.itemListButtons {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Section component
|
||||||
|
|
||||||
|
.section {
|
||||||
|
padding: 20px;
|
||||||
|
border-bottom: 1px solid var(--color-border-primary);
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sectionHeader {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sectionTitle {
|
||||||
|
flex-grow: 1;
|
||||||
|
font-size: 17px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sectionSubtitle {
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Counter component
|
||||||
|
|
||||||
.counter {
|
.counter {
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useCallback, useMemo, useState } from 'react';
|
import { useCallback, useId, useMemo, useState } from 'react';
|
||||||
|
|
||||||
import { FormattedMessage, useIntl } from 'react-intl';
|
import { FormattedMessage, useIntl } from 'react-intl';
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ import { Button } from 'mastodon/components/button';
|
|||||||
import { Callout } from 'mastodon/components/callout';
|
import { Callout } from 'mastodon/components/callout';
|
||||||
import { DisplayName } from 'mastodon/components/display_name';
|
import { DisplayName } from 'mastodon/components/display_name';
|
||||||
import { EmptyState } from 'mastodon/components/empty_state';
|
import { EmptyState } from 'mastodon/components/empty_state';
|
||||||
import { FormStack, ComboboxField } from 'mastodon/components/form_fields';
|
import { FormStack, Combobox } from 'mastodon/components/form_fields';
|
||||||
import { Icon } from 'mastodon/components/icon';
|
import { Icon } from 'mastodon/components/icon';
|
||||||
import { IconButton } from 'mastodon/components/icon_button';
|
import { IconButton } from 'mastodon/components/icon_button';
|
||||||
import ScrollableList from 'mastodon/components/scrollable_list';
|
import ScrollableList from 'mastodon/components/scrollable_list';
|
||||||
@@ -328,6 +328,12 @@ export const CollectionAccounts: React.FC<{
|
|||||||
[canSubmit, id, history, accountIds],
|
[canSubmit, id, history, accountIds],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const inputId = useId();
|
||||||
|
const inputLabel = intl.formatMessage({
|
||||||
|
id: 'collections.search_accounts_label',
|
||||||
|
defaultMessage: 'Search for accounts to add…',
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit} className={classes.form}>
|
<form onSubmit={handleSubmit} className={classes.form}>
|
||||||
<FormStack className={classes.formFieldStack}>
|
<FormStack className={classes.formFieldStack}>
|
||||||
@@ -348,21 +354,12 @@ export const CollectionAccounts: React.FC<{
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<ComboboxField
|
<label htmlFor={inputId} className='sr-only'>
|
||||||
label={
|
{inputLabel}
|
||||||
<FormattedMessage
|
</label>
|
||||||
id='collections.search_accounts_label'
|
<Combobox
|
||||||
defaultMessage='Search for accounts to add…'
|
id={inputId}
|
||||||
/>
|
placeholder={inputLabel}
|
||||||
}
|
|
||||||
hint={
|
|
||||||
hasMaxAccounts ? (
|
|
||||||
<FormattedMessage
|
|
||||||
id='collections.search_accounts_max_reached'
|
|
||||||
defaultMessage='You have added the maximum number of accounts'
|
|
||||||
/>
|
|
||||||
) : undefined
|
|
||||||
}
|
|
||||||
value={hasMaxAccounts ? '' : searchValue}
|
value={hasMaxAccounts ? '' : searchValue}
|
||||||
onChange={handleSearchValueChange}
|
onChange={handleSearchValueChange}
|
||||||
onKeyDown={handleSearchKeyDown}
|
onKeyDown={handleSearchKeyDown}
|
||||||
@@ -376,6 +373,12 @@ export const CollectionAccounts: React.FC<{
|
|||||||
isEditMode ? instantToggleAccountItem : toggleAccountItem
|
isEditMode ? instantToggleAccountItem : toggleAccountItem
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
{hasMaxAccounts && (
|
||||||
|
<FormattedMessage
|
||||||
|
id='collections.search_accounts_max_reached'
|
||||||
|
defaultMessage='You have added the maximum number of accounts'
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
{hasMinAccounts && (
|
{hasMinAccounts && (
|
||||||
<Callout>
|
<Callout>
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ import {
|
|||||||
AccountFeatured,
|
AccountFeatured,
|
||||||
AccountAbout,
|
AccountAbout,
|
||||||
AccountEdit,
|
AccountEdit,
|
||||||
|
AccountEditFeaturedTags,
|
||||||
Quotes,
|
Quotes,
|
||||||
} from './util/async-components';
|
} from './util/async-components';
|
||||||
import { ColumnsContextProvider } from './util/columns_context';
|
import { ColumnsContextProvider } from './util/columns_context';
|
||||||
@@ -164,9 +165,8 @@ class SwitchingColumnsArea extends PureComponent {
|
|||||||
redirect = <Redirect from='/' to='/about' exact />;
|
redirect = <Redirect from='/' to='/about' exact />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const profileRedesignEnabled = isServerFeatureEnabled('profile_redesign');
|
|
||||||
const profileRedesignRoutes = [];
|
const profileRedesignRoutes = [];
|
||||||
if (profileRedesignEnabled) {
|
if (isServerFeatureEnabled('profile_redesign')) {
|
||||||
profileRedesignRoutes.push(
|
profileRedesignRoutes.push(
|
||||||
<WrappedRoute key="posts" path={['/@:acct/posts', '/accounts/:id/posts']} exact component={AccountTimeline} content={children} />,
|
<WrappedRoute key="posts" path={['/@:acct/posts', '/accounts/:id/posts']} exact component={AccountTimeline} content={children} />,
|
||||||
);
|
);
|
||||||
@@ -188,13 +188,27 @@ class SwitchingColumnsArea extends PureComponent {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If the redesign is not enabled but someone shares an /about link, redirect to the root.
|
|
||||||
profileRedesignRoutes.push(
|
profileRedesignRoutes.push(
|
||||||
|
<WrappedRoute path={['/@:acct', '/accounts/:id']} exact component={AccountTimeline} content={children} />,
|
||||||
|
// If the redesign is not enabled but someone shares an /about link, redirect to the root.
|
||||||
<Redirect key="about-acct-redirect" from='/@:acct/about' to='/@:acct' exact />,
|
<Redirect key="about-acct-redirect" from='/@:acct/about' to='/@:acct' exact />,
|
||||||
<Redirect key="about-id-redirect" from='/accounts/:id/about' to='/accounts/:id' exact />
|
<Redirect key="about-id-redirect" from='/accounts/:id/about' to='/accounts/:id' exact />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isClientFeatureEnabled('profile_editing')) {
|
||||||
|
profileRedesignRoutes.push(
|
||||||
|
<WrappedRoute key="edit" path='/profile/edit' component={AccountEdit} content={children} />,
|
||||||
|
<WrappedRoute key="featured_tags" path='/profile/featured_tags' component={AccountEditFeaturedTags} content={children} />
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
// If profile editing is not enabled, redirect to the home timeline as the current editing pages are outside React Router.
|
||||||
|
profileRedesignRoutes.push(
|
||||||
|
<Redirect key="edit-redirect" from='/profile/edit' to='/' exact />,
|
||||||
|
<Redirect key="featured-tags-redirect" from='/profile/featured_tags' to='/' exact />,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ColumnsContextProvider multiColumn={!singleColumn}>
|
<ColumnsContextProvider multiColumn={!singleColumn}>
|
||||||
<ColumnsAreaContainer ref={this.setRef} singleColumn={singleColumn}>
|
<ColumnsAreaContainer ref={this.setRef} singleColumn={singleColumn}>
|
||||||
@@ -234,8 +248,6 @@ class SwitchingColumnsArea extends PureComponent {
|
|||||||
<WrappedRoute path='/bookmarks' component={BookmarkedStatuses} content={children} />
|
<WrappedRoute path='/bookmarks' component={BookmarkedStatuses} content={children} />
|
||||||
<WrappedRoute path='/pinned' component={PinnedStatuses} content={children} />
|
<WrappedRoute path='/pinned' component={PinnedStatuses} content={children} />
|
||||||
|
|
||||||
{isClientFeatureEnabled('profile_editing') && <WrappedRoute key="edit" path='/profile/edit' component={AccountEdit} content={children} />}
|
|
||||||
|
|
||||||
<WrappedRoute path={['/start', '/start/profile']} exact component={OnboardingProfile} content={children} />
|
<WrappedRoute path={['/start', '/start/profile']} exact component={OnboardingProfile} content={children} />
|
||||||
<WrappedRoute path='/start/follows' component={OnboardingFollows} content={children} />
|
<WrappedRoute path='/start/follows' component={OnboardingFollows} content={children} />
|
||||||
<WrappedRoute path='/directory' component={Directory} content={children} />
|
<WrappedRoute path='/directory' component={Directory} content={children} />
|
||||||
@@ -243,8 +255,8 @@ class SwitchingColumnsArea extends PureComponent {
|
|||||||
<WrappedRoute path='/search' component={Search} content={children} />
|
<WrappedRoute path='/search' component={Search} content={children} />
|
||||||
<WrappedRoute path={['/publish', '/statuses/new']} component={Compose} content={children} />
|
<WrappedRoute path={['/publish', '/statuses/new']} component={Compose} content={children} />
|
||||||
|
|
||||||
{!profileRedesignEnabled && <WrappedRoute path={['/@:acct', '/accounts/:id']} exact component={AccountTimeline} content={children} />}
|
|
||||||
{...profileRedesignRoutes}
|
{...profileRedesignRoutes}
|
||||||
|
|
||||||
<WrappedRoute path={['/@:acct/featured', '/accounts/:id/featured']} component={AccountFeatured} content={children} />
|
<WrappedRoute path={['/@:acct/featured', '/accounts/:id/featured']} component={AccountFeatured} content={children} />
|
||||||
<WrappedRoute path='/@:acct/tagged/:tagged?' exact component={AccountTimeline} content={children} />
|
<WrappedRoute path='/@:acct/tagged/:tagged?' exact component={AccountTimeline} content={children} />
|
||||||
<WrappedRoute path={['/@:acct/with_replies', '/accounts/:id/with_replies']} component={AccountTimeline} content={children} componentParams={{ withReplies: true }} />
|
<WrappedRoute path={['/@:acct/with_replies', '/accounts/:id/with_replies']} component={AccountTimeline} content={children} componentParams={{ withReplies: true }} />
|
||||||
|
|||||||
@@ -103,6 +103,11 @@ export function AccountEdit() {
|
|||||||
.then((module) => ({ default: module.AccountEdit }));
|
.then((module) => ({ default: module.AccountEdit }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function AccountEditFeaturedTags() {
|
||||||
|
return import('../../account_edit/featured_tags')
|
||||||
|
.then((module) => ({ default: module.AccountEditFeaturedTags }));
|
||||||
|
}
|
||||||
|
|
||||||
export function Followers () {
|
export function Followers () {
|
||||||
return import('../../followers');
|
return import('../../followers');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,6 +145,7 @@
|
|||||||
"account_edit.char_counter": "{currentLength}/{maxLength} znaků",
|
"account_edit.char_counter": "{currentLength}/{maxLength} znaků",
|
||||||
"account_edit.column_button": "Hotovo",
|
"account_edit.column_button": "Hotovo",
|
||||||
"account_edit.column_title": "Upravit profil",
|
"account_edit.column_title": "Upravit profil",
|
||||||
|
"account_edit.custom_fields.placeholder": "Přidejte svá zájmena, externí odkazy nebo cokoliv jiného, co chcete sdílet.",
|
||||||
"account_edit.custom_fields.title": "Vlastní pole",
|
"account_edit.custom_fields.title": "Vlastní pole",
|
||||||
"account_edit.save": "Uložit",
|
"account_edit.save": "Uložit",
|
||||||
"account_edit.section_edit_button": "Upravit",
|
"account_edit.section_edit_button": "Upravit",
|
||||||
@@ -250,12 +251,14 @@
|
|||||||
"closed_registrations_modal.find_another_server": "Najít jiný server",
|
"closed_registrations_modal.find_another_server": "Najít jiný server",
|
||||||
"closed_registrations_modal.preamble": "Mastodon je decentralizovaný, takže bez ohledu na to, kde vytvoříte svůj účet, budete moci sledovat a komunikovat s kýmkoli na tomto serveru. Můžete ho dokonce hostovat!",
|
"closed_registrations_modal.preamble": "Mastodon je decentralizovaný, takže bez ohledu na to, kde vytvoříte svůj účet, budete moci sledovat a komunikovat s kýmkoli na tomto serveru. Můžete ho dokonce hostovat!",
|
||||||
"closed_registrations_modal.title": "Registrace na Mastodon",
|
"closed_registrations_modal.title": "Registrace na Mastodon",
|
||||||
|
"collections.collection_description": "Popis",
|
||||||
"collections.collection_name": "Název",
|
"collections.collection_name": "Název",
|
||||||
"collections.collection_topic": "Téma",
|
"collections.collection_topic": "Téma",
|
||||||
"collections.confirm_account_removal": "Jste si jisti, že chcete odstranit tento účet z této sbírky?",
|
"collections.confirm_account_removal": "Jste si jisti, že chcete odstranit tento účet z této sbírky?",
|
||||||
"collections.content_warning": "Varování o obsahu",
|
"collections.content_warning": "Varování o obsahu",
|
||||||
"collections.continue": "Pokračovat",
|
"collections.continue": "Pokračovat",
|
||||||
"collections.mark_as_sensitive_hint": "Skryje popis kolekce a účty za varováním obsahu. Název kolekce bude stále viditelný.",
|
"collections.mark_as_sensitive_hint": "Skryje popis kolekce a účty za varováním obsahu. Název kolekce bude stále viditelný.",
|
||||||
|
"collections.name_length_hint": "Limit 40 znaků",
|
||||||
"collections.new_collection": "Nová sbírka",
|
"collections.new_collection": "Nová sbírka",
|
||||||
"collections.no_collections_yet": "Ještě nemáte žádné sbírky.",
|
"collections.no_collections_yet": "Ještě nemáte žádné sbírky.",
|
||||||
"collections.remove_account": "Odstranit tento účet",
|
"collections.remove_account": "Odstranit tento účet",
|
||||||
@@ -335,6 +338,8 @@
|
|||||||
"confirmations.delete.confirm": "Smazat",
|
"confirmations.delete.confirm": "Smazat",
|
||||||
"confirmations.delete.message": "Opravdu chcete smazat tento příspěvek?",
|
"confirmations.delete.message": "Opravdu chcete smazat tento příspěvek?",
|
||||||
"confirmations.delete.title": "Smazat příspěvek?",
|
"confirmations.delete.title": "Smazat příspěvek?",
|
||||||
|
"confirmations.delete_collection.confirm": "Smazat",
|
||||||
|
"confirmations.delete_collection.message": "Tuto akci nelze vrátit zpět.",
|
||||||
"confirmations.delete_collection.title": "Smazat „{name}“?",
|
"confirmations.delete_collection.title": "Smazat „{name}“?",
|
||||||
"confirmations.delete_list.confirm": "Smazat",
|
"confirmations.delete_list.confirm": "Smazat",
|
||||||
"confirmations.delete_list.message": "Opravdu chcete tento seznam navždy smazat?",
|
"confirmations.delete_list.message": "Opravdu chcete tento seznam navždy smazat?",
|
||||||
|
|||||||
@@ -390,6 +390,9 @@
|
|||||||
"confirmations.discard_draft.post.title": "Dileu drafft eich postiad?",
|
"confirmations.discard_draft.post.title": "Dileu drafft eich postiad?",
|
||||||
"confirmations.discard_edit_media.confirm": "Dileu",
|
"confirmations.discard_edit_media.confirm": "Dileu",
|
||||||
"confirmations.discard_edit_media.message": "Mae gennych newidiadau heb eu cadw i'r disgrifiad cyfryngau neu'r rhagolwg - eu dileu beth bynnag?",
|
"confirmations.discard_edit_media.message": "Mae gennych newidiadau heb eu cadw i'r disgrifiad cyfryngau neu'r rhagolwg - eu dileu beth bynnag?",
|
||||||
|
"confirmations.follow_to_collection.confirm": "Dilyn ac ychwanegu at y casgliad",
|
||||||
|
"confirmations.follow_to_collection.message": "Mae angen i chi fod yn dilyn {name} i'w hychwanegu at gasgliad.",
|
||||||
|
"confirmations.follow_to_collection.title": "Dilyn cyfrif?",
|
||||||
"confirmations.follow_to_list.confirm": "Dilyn ac ychwanegu at y rhestr",
|
"confirmations.follow_to_list.confirm": "Dilyn ac ychwanegu at y rhestr",
|
||||||
"confirmations.follow_to_list.message": "Mae angen i chi fod yn dilyn {name} i'w ychwanegu at restr.",
|
"confirmations.follow_to_list.message": "Mae angen i chi fod yn dilyn {name} i'w ychwanegu at restr.",
|
||||||
"confirmations.follow_to_list.title": "Dilyn defnyddiwr?",
|
"confirmations.follow_to_list.title": "Dilyn defnyddiwr?",
|
||||||
|
|||||||
@@ -296,6 +296,7 @@
|
|||||||
"collections.name_length_hint": "Begrænset til 40 tegn",
|
"collections.name_length_hint": "Begrænset til 40 tegn",
|
||||||
"collections.new_collection": "Ny samling",
|
"collections.new_collection": "Ny samling",
|
||||||
"collections.no_collections_yet": "Ingen samlinger endnu.",
|
"collections.no_collections_yet": "Ingen samlinger endnu.",
|
||||||
|
"collections.old_last_post_note": "Seneste indlæg er fra over en uge siden",
|
||||||
"collections.remove_account": "Fjern denne konto",
|
"collections.remove_account": "Fjern denne konto",
|
||||||
"collections.search_accounts_label": "Søg efter konti for at tilføje…",
|
"collections.search_accounts_label": "Søg efter konti for at tilføje…",
|
||||||
"collections.search_accounts_max_reached": "Du har tilføjet det maksimale antal konti",
|
"collections.search_accounts_max_reached": "Du har tilføjet det maksimale antal konti",
|
||||||
@@ -390,6 +391,9 @@
|
|||||||
"confirmations.discard_draft.post.title": "Kassér dit indlægsudkast?",
|
"confirmations.discard_draft.post.title": "Kassér dit indlægsudkast?",
|
||||||
"confirmations.discard_edit_media.confirm": "Kassér",
|
"confirmations.discard_edit_media.confirm": "Kassér",
|
||||||
"confirmations.discard_edit_media.message": "Der er ugemte ændringer i mediebeskrivelsen eller forhåndsvisningen, kassér dem alligevel?",
|
"confirmations.discard_edit_media.message": "Der er ugemte ændringer i mediebeskrivelsen eller forhåndsvisningen, kassér dem alligevel?",
|
||||||
|
"confirmations.follow_to_collection.confirm": "Følg og føj til samling",
|
||||||
|
"confirmations.follow_to_collection.message": "Du skal følge {name} for at føje vedkommende til en samling.",
|
||||||
|
"confirmations.follow_to_collection.title": "Følg konto?",
|
||||||
"confirmations.follow_to_list.confirm": "Følg og føj til liste",
|
"confirmations.follow_to_list.confirm": "Følg og føj til liste",
|
||||||
"confirmations.follow_to_list.message": "Du skal følge {name} for at føje vedkommende til en liste.",
|
"confirmations.follow_to_list.message": "Du skal følge {name} for at føje vedkommende til en liste.",
|
||||||
"confirmations.follow_to_list.title": "Følg bruger?",
|
"confirmations.follow_to_list.title": "Følg bruger?",
|
||||||
|
|||||||
@@ -152,7 +152,7 @@
|
|||||||
"account_edit.custom_fields.title": "Zusatzfelder",
|
"account_edit.custom_fields.title": "Zusatzfelder",
|
||||||
"account_edit.display_name.placeholder": "Dein Anzeigename wird auf deinem Profil und in Timelines angezeigt.",
|
"account_edit.display_name.placeholder": "Dein Anzeigename wird auf deinem Profil und in Timelines angezeigt.",
|
||||||
"account_edit.display_name.title": "Anzeigename",
|
"account_edit.display_name.title": "Anzeigename",
|
||||||
"account_edit.featured_hashtags.placeholder": "Hilf anderen dabei, deine Lieblingsthemen zu identifizieren und diese leicht zugänglich zu machen.",
|
"account_edit.featured_hashtags.placeholder": "Präsentiere deine Lieblingsthemen und ermögliche anderen einen schnellen Zugriff darauf.",
|
||||||
"account_edit.featured_hashtags.title": "Vorgestellte Hashtags",
|
"account_edit.featured_hashtags.title": "Vorgestellte Hashtags",
|
||||||
"account_edit.name_modal.add_title": "Anzeigenamen hinzufügen",
|
"account_edit.name_modal.add_title": "Anzeigenamen hinzufügen",
|
||||||
"account_edit.name_modal.edit_title": "Anzeigenamen bearbeiten",
|
"account_edit.name_modal.edit_title": "Anzeigenamen bearbeiten",
|
||||||
@@ -296,6 +296,7 @@
|
|||||||
"collections.name_length_hint": "Maximal 40 Zeichen",
|
"collections.name_length_hint": "Maximal 40 Zeichen",
|
||||||
"collections.new_collection": "Neue Sammlung",
|
"collections.new_collection": "Neue Sammlung",
|
||||||
"collections.no_collections_yet": "Bisher keine Sammlungen vorhanden.",
|
"collections.no_collections_yet": "Bisher keine Sammlungen vorhanden.",
|
||||||
|
"collections.old_last_post_note": "Neuester Beitrag mehr als eine Woche alt",
|
||||||
"collections.remove_account": "Dieses Konto entfernen",
|
"collections.remove_account": "Dieses Konto entfernen",
|
||||||
"collections.search_accounts_label": "Suche nach Konten, um sie hinzuzufügen …",
|
"collections.search_accounts_label": "Suche nach Konten, um sie hinzuzufügen …",
|
||||||
"collections.search_accounts_max_reached": "Du hast die Höchstzahl an Konten hinzugefügt",
|
"collections.search_accounts_max_reached": "Du hast die Höchstzahl an Konten hinzugefügt",
|
||||||
@@ -390,6 +391,9 @@
|
|||||||
"confirmations.discard_draft.post.title": "Entwurf verwerfen?",
|
"confirmations.discard_draft.post.title": "Entwurf verwerfen?",
|
||||||
"confirmations.discard_edit_media.confirm": "Verwerfen",
|
"confirmations.discard_edit_media.confirm": "Verwerfen",
|
||||||
"confirmations.discard_edit_media.message": "Du hast Änderungen an der Medienbeschreibung oder -vorschau vorgenommen, die noch nicht gespeichert sind. Trotzdem verwerfen?",
|
"confirmations.discard_edit_media.message": "Du hast Änderungen an der Medienbeschreibung oder -vorschau vorgenommen, die noch nicht gespeichert sind. Trotzdem verwerfen?",
|
||||||
|
"confirmations.follow_to_collection.confirm": "Folgen und zur Sammlung hinzufügen",
|
||||||
|
"confirmations.follow_to_collection.message": "Du musst {name} folgen, um das Profil zu einer Sammlung hinzufügen zu können.",
|
||||||
|
"confirmations.follow_to_collection.title": "Konto folgen?",
|
||||||
"confirmations.follow_to_list.confirm": "Folgen und zur Liste hinzufügen",
|
"confirmations.follow_to_list.confirm": "Folgen und zur Liste hinzufügen",
|
||||||
"confirmations.follow_to_list.message": "Du musst {name} folgen, um das Profil zu einer Liste hinzufügen zu können.",
|
"confirmations.follow_to_list.message": "Du musst {name} folgen, um das Profil zu einer Liste hinzufügen zu können.",
|
||||||
"confirmations.follow_to_list.title": "Profil folgen?",
|
"confirmations.follow_to_list.title": "Profil folgen?",
|
||||||
|
|||||||
@@ -296,6 +296,7 @@
|
|||||||
"collections.name_length_hint": "Όριο 40 χαρακτήρων",
|
"collections.name_length_hint": "Όριο 40 χαρακτήρων",
|
||||||
"collections.new_collection": "Νέα συλλογή",
|
"collections.new_collection": "Νέα συλλογή",
|
||||||
"collections.no_collections_yet": "Καμία συλλογή ακόμη.",
|
"collections.no_collections_yet": "Καμία συλλογή ακόμη.",
|
||||||
|
"collections.old_last_post_note": "Τελευταία ανάρτηση πριν από μια εβδομάδα",
|
||||||
"collections.remove_account": "Αφαίρεση λογαριασμού",
|
"collections.remove_account": "Αφαίρεση λογαριασμού",
|
||||||
"collections.search_accounts_label": "Αναζήτηση λογαριασμών για προσθήκη…",
|
"collections.search_accounts_label": "Αναζήτηση λογαριασμών για προσθήκη…",
|
||||||
"collections.search_accounts_max_reached": "Έχετε προσθέσει τον μέγιστο αριθμό λογαριασμών",
|
"collections.search_accounts_max_reached": "Έχετε προσθέσει τον μέγιστο αριθμό λογαριασμών",
|
||||||
@@ -390,6 +391,9 @@
|
|||||||
"confirmations.discard_draft.post.title": "Απόρριψη της πρόχειρης ανάρτησης σας;",
|
"confirmations.discard_draft.post.title": "Απόρριψη της πρόχειρης ανάρτησης σας;",
|
||||||
"confirmations.discard_edit_media.confirm": "Απόρριψη",
|
"confirmations.discard_edit_media.confirm": "Απόρριψη",
|
||||||
"confirmations.discard_edit_media.message": "Έχεις μη αποθηκευμένες αλλαγές στην περιγραφή πολυμέσων ή στην προεπισκόπηση, απόρριψη ούτως ή άλλως;",
|
"confirmations.discard_edit_media.message": "Έχεις μη αποθηκευμένες αλλαγές στην περιγραφή πολυμέσων ή στην προεπισκόπηση, απόρριψη ούτως ή άλλως;",
|
||||||
|
"confirmations.follow_to_collection.confirm": "Ακολουθήστε και προσθέστε στη συλλογή",
|
||||||
|
"confirmations.follow_to_collection.message": "Πρέπει να ακολουθήσετε τον χρήστη {name} για να τους προσθέσετε σε μια συλλογή.",
|
||||||
|
"confirmations.follow_to_collection.title": "Ακολουθήστε τον λογαριασμό;",
|
||||||
"confirmations.follow_to_list.confirm": "Ακολούθησε και πρόσθεσε στη λίστα",
|
"confirmations.follow_to_list.confirm": "Ακολούθησε και πρόσθεσε στη λίστα",
|
||||||
"confirmations.follow_to_list.message": "Πρέπει να ακολουθήσεις τον χρήστη {name} για να τον προσθέσεις σε μια λίστα.",
|
"confirmations.follow_to_list.message": "Πρέπει να ακολουθήσεις τον χρήστη {name} για να τον προσθέσεις σε μια λίστα.",
|
||||||
"confirmations.follow_to_list.title": "Ακολούθηση χρήστη;",
|
"confirmations.follow_to_list.title": "Ακολούθηση χρήστη;",
|
||||||
|
|||||||
@@ -296,6 +296,7 @@
|
|||||||
"collections.name_length_hint": "40 characters limit",
|
"collections.name_length_hint": "40 characters limit",
|
||||||
"collections.new_collection": "New collection",
|
"collections.new_collection": "New collection",
|
||||||
"collections.no_collections_yet": "No collections yet.",
|
"collections.no_collections_yet": "No collections yet.",
|
||||||
|
"collections.old_last_post_note": "Last posted over a week ago",
|
||||||
"collections.remove_account": "Remove this account",
|
"collections.remove_account": "Remove this account",
|
||||||
"collections.search_accounts_label": "Search for accounts to add…",
|
"collections.search_accounts_label": "Search for accounts to add…",
|
||||||
"collections.search_accounts_max_reached": "You have added the maximum number of accounts",
|
"collections.search_accounts_max_reached": "You have added the maximum number of accounts",
|
||||||
@@ -390,6 +391,9 @@
|
|||||||
"confirmations.discard_draft.post.title": "Discard your draft post?",
|
"confirmations.discard_draft.post.title": "Discard your draft post?",
|
||||||
"confirmations.discard_edit_media.confirm": "Discard",
|
"confirmations.discard_edit_media.confirm": "Discard",
|
||||||
"confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?",
|
"confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?",
|
||||||
|
"confirmations.follow_to_collection.confirm": "Follow and add to collection",
|
||||||
|
"confirmations.follow_to_collection.message": "You need to be following {name} to add them to a collection.",
|
||||||
|
"confirmations.follow_to_collection.title": "Follow account?",
|
||||||
"confirmations.follow_to_list.confirm": "Follow and add to list",
|
"confirmations.follow_to_list.confirm": "Follow and add to list",
|
||||||
"confirmations.follow_to_list.message": "You need to be following {name} to add them to a list.",
|
"confirmations.follow_to_list.message": "You need to be following {name} to add them to a list.",
|
||||||
"confirmations.follow_to_list.title": "Follow user?",
|
"confirmations.follow_to_list.title": "Follow user?",
|
||||||
|
|||||||
@@ -145,6 +145,9 @@
|
|||||||
"account_edit.bio.title": "Bio",
|
"account_edit.bio.title": "Bio",
|
||||||
"account_edit.bio_modal.add_title": "Add bio",
|
"account_edit.bio_modal.add_title": "Add bio",
|
||||||
"account_edit.bio_modal.edit_title": "Edit bio",
|
"account_edit.bio_modal.edit_title": "Edit bio",
|
||||||
|
"account_edit.button.add": "Add {item}",
|
||||||
|
"account_edit.button.delete": "Delete {item}",
|
||||||
|
"account_edit.button.edit": "Edit {item}",
|
||||||
"account_edit.char_counter": "{currentLength}/{maxLength} characters",
|
"account_edit.char_counter": "{currentLength}/{maxLength} characters",
|
||||||
"account_edit.column_button": "Done",
|
"account_edit.column_button": "Done",
|
||||||
"account_edit.column_title": "Edit Profile",
|
"account_edit.column_title": "Edit Profile",
|
||||||
@@ -152,6 +155,7 @@
|
|||||||
"account_edit.custom_fields.title": "Custom fields",
|
"account_edit.custom_fields.title": "Custom fields",
|
||||||
"account_edit.display_name.placeholder": "Your display name is how your name appears on your profile and in timelines.",
|
"account_edit.display_name.placeholder": "Your display name is how your name appears on your profile and in timelines.",
|
||||||
"account_edit.display_name.title": "Display name",
|
"account_edit.display_name.title": "Display name",
|
||||||
|
"account_edit.featured_hashtags.item": "hashtags",
|
||||||
"account_edit.featured_hashtags.placeholder": "Help others identify, and have quick access to, your favorite topics.",
|
"account_edit.featured_hashtags.placeholder": "Help others identify, and have quick access to, your favorite topics.",
|
||||||
"account_edit.featured_hashtags.title": "Featured hashtags",
|
"account_edit.featured_hashtags.title": "Featured hashtags",
|
||||||
"account_edit.name_modal.add_title": "Add display name",
|
"account_edit.name_modal.add_title": "Add display name",
|
||||||
@@ -159,7 +163,11 @@
|
|||||||
"account_edit.profile_tab.subtitle": "Customize the tabs on your profile and what they display.",
|
"account_edit.profile_tab.subtitle": "Customize the tabs on your profile and what they display.",
|
||||||
"account_edit.profile_tab.title": "Profile tab settings",
|
"account_edit.profile_tab.title": "Profile tab settings",
|
||||||
"account_edit.save": "Save",
|
"account_edit.save": "Save",
|
||||||
"account_edit.section_edit_button": "Edit",
|
"account_edit_tags.column_title": "Edit featured hashtags",
|
||||||
|
"account_edit_tags.help_text": "Featured hashtags help users discover and interact with your profile. They appear as filters on your Profile page’s Activity view.",
|
||||||
|
"account_edit_tags.search_placeholder": "Enter a hashtag…",
|
||||||
|
"account_edit_tags.suggestions": "Suggestions:",
|
||||||
|
"account_edit_tags.tag_status_count": "{count} posts",
|
||||||
"account_note.placeholder": "Click to add note",
|
"account_note.placeholder": "Click to add note",
|
||||||
"admin.dashboard.daily_retention": "User retention rate by day after sign-up",
|
"admin.dashboard.daily_retention": "User retention rate by day after sign-up",
|
||||||
"admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
|
"admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
|
||||||
|
|||||||
@@ -296,6 +296,7 @@
|
|||||||
"collections.name_length_hint": "Límite de 40 caracteres",
|
"collections.name_length_hint": "Límite de 40 caracteres",
|
||||||
"collections.new_collection": "Nueva colección",
|
"collections.new_collection": "Nueva colección",
|
||||||
"collections.no_collections_yet": "No hay colecciones aún.",
|
"collections.no_collections_yet": "No hay colecciones aún.",
|
||||||
|
"collections.old_last_post_note": "Último mensaje hace más de una semana",
|
||||||
"collections.remove_account": "Eliminar esta cuenta",
|
"collections.remove_account": "Eliminar esta cuenta",
|
||||||
"collections.search_accounts_label": "Buscar cuentas para agregar…",
|
"collections.search_accounts_label": "Buscar cuentas para agregar…",
|
||||||
"collections.search_accounts_max_reached": "Agregaste el número máximo de cuentas",
|
"collections.search_accounts_max_reached": "Agregaste el número máximo de cuentas",
|
||||||
@@ -390,6 +391,9 @@
|
|||||||
"confirmations.discard_draft.post.title": "¿Descartar tu borrador?",
|
"confirmations.discard_draft.post.title": "¿Descartar tu borrador?",
|
||||||
"confirmations.discard_edit_media.confirm": "Descartar",
|
"confirmations.discard_edit_media.confirm": "Descartar",
|
||||||
"confirmations.discard_edit_media.message": "Tenés cambios sin guardar en la descripción de medios o en la vista previa, ¿querés descartarlos de todos modos?",
|
"confirmations.discard_edit_media.message": "Tenés cambios sin guardar en la descripción de medios o en la vista previa, ¿querés descartarlos de todos modos?",
|
||||||
|
"confirmations.follow_to_collection.confirm": "Seguir y agregar a la colección",
|
||||||
|
"confirmations.follow_to_collection.message": "Necesitás seguir a {name} para agregarle a una colección.",
|
||||||
|
"confirmations.follow_to_collection.title": "¿Seguir cuenta?",
|
||||||
"confirmations.follow_to_list.confirm": "Seguir y agregar a la lista",
|
"confirmations.follow_to_list.confirm": "Seguir y agregar a la lista",
|
||||||
"confirmations.follow_to_list.message": "Necesitás seguir a {name} para agregarle a una lista.",
|
"confirmations.follow_to_list.message": "Necesitás seguir a {name} para agregarle a una lista.",
|
||||||
"confirmations.follow_to_list.title": "¿Querés seguirle?",
|
"confirmations.follow_to_list.title": "¿Querés seguirle?",
|
||||||
|
|||||||
@@ -296,6 +296,7 @@
|
|||||||
"collections.name_length_hint": "Limitado a 40 caracteres",
|
"collections.name_length_hint": "Limitado a 40 caracteres",
|
||||||
"collections.new_collection": "Nueva colección",
|
"collections.new_collection": "Nueva colección",
|
||||||
"collections.no_collections_yet": "No hay colecciones todavía.",
|
"collections.no_collections_yet": "No hay colecciones todavía.",
|
||||||
|
"collections.old_last_post_note": "Última publicación hace más de una semana",
|
||||||
"collections.remove_account": "Eliminar esta cuenta",
|
"collections.remove_account": "Eliminar esta cuenta",
|
||||||
"collections.search_accounts_label": "Buscar cuentas para añadir…",
|
"collections.search_accounts_label": "Buscar cuentas para añadir…",
|
||||||
"collections.search_accounts_max_reached": "Has añadido el número máximo de cuentas",
|
"collections.search_accounts_max_reached": "Has añadido el número máximo de cuentas",
|
||||||
@@ -390,6 +391,9 @@
|
|||||||
"confirmations.discard_draft.post.title": "¿Deseas descartar tu borrador?",
|
"confirmations.discard_draft.post.title": "¿Deseas descartar tu borrador?",
|
||||||
"confirmations.discard_edit_media.confirm": "Descartar",
|
"confirmations.discard_edit_media.confirm": "Descartar",
|
||||||
"confirmations.discard_edit_media.message": "Tienes cambios sin guardar en la descripción o vista previa del archivo, ¿deseas descartarlos de cualquier manera?",
|
"confirmations.discard_edit_media.message": "Tienes cambios sin guardar en la descripción o vista previa del archivo, ¿deseas descartarlos de cualquier manera?",
|
||||||
|
"confirmations.follow_to_collection.confirm": "Seguir y añadir a la colección",
|
||||||
|
"confirmations.follow_to_collection.message": "Debes seguir a {name} para agregarlo a una colección.",
|
||||||
|
"confirmations.follow_to_collection.title": "¿Seguir cuenta?",
|
||||||
"confirmations.follow_to_list.confirm": "Seguir y agregar a la lista",
|
"confirmations.follow_to_list.confirm": "Seguir y agregar a la lista",
|
||||||
"confirmations.follow_to_list.message": "Tienes que seguir a {name} para añadirlo a una lista.",
|
"confirmations.follow_to_list.message": "Tienes que seguir a {name} para añadirlo a una lista.",
|
||||||
"confirmations.follow_to_list.title": "¿Seguir a usuario?",
|
"confirmations.follow_to_list.title": "¿Seguir a usuario?",
|
||||||
|
|||||||
@@ -141,8 +141,25 @@
|
|||||||
"account.unmute": "Dejar de silenciar a @{name}",
|
"account.unmute": "Dejar de silenciar a @{name}",
|
||||||
"account.unmute_notifications_short": "Dejar de silenciar notificaciones",
|
"account.unmute_notifications_short": "Dejar de silenciar notificaciones",
|
||||||
"account.unmute_short": "Dejar de silenciar",
|
"account.unmute_short": "Dejar de silenciar",
|
||||||
|
"account_edit.bio.placeholder": "Añade una breve introducción para ayudar a los demás a identificarte.",
|
||||||
|
"account_edit.bio.title": "Biografía",
|
||||||
|
"account_edit.bio_modal.add_title": "Añadir biografía",
|
||||||
|
"account_edit.bio_modal.edit_title": "Editar biografía",
|
||||||
|
"account_edit.char_counter": "{currentLength}/{maxLength} caracteres",
|
||||||
"account_edit.column_button": "Hecho",
|
"account_edit.column_button": "Hecho",
|
||||||
"account_edit.column_title": "Editar perfil",
|
"account_edit.column_title": "Editar perfil",
|
||||||
|
"account_edit.custom_fields.placeholder": "Añade tus pronombres, enlaces externos o cualquier otra cosa que quieras compartir.",
|
||||||
|
"account_edit.custom_fields.title": "Campos personalizados",
|
||||||
|
"account_edit.display_name.placeholder": "Tu nombre de usuario es el nombre que aparece en tu perfil y en las cronologías.",
|
||||||
|
"account_edit.display_name.title": "Nombre para mostrar",
|
||||||
|
"account_edit.featured_hashtags.placeholder": "Ayuda a otros a identificar tus temas favoritos y a acceder rápidamente a ellos.",
|
||||||
|
"account_edit.featured_hashtags.title": "Etiquetas destacadas",
|
||||||
|
"account_edit.name_modal.add_title": "Añadir nombre para mostrar",
|
||||||
|
"account_edit.name_modal.edit_title": "Editar nombre para mostrar",
|
||||||
|
"account_edit.profile_tab.subtitle": "Personaliza las pestañas de tu perfil y lo que muestran.",
|
||||||
|
"account_edit.profile_tab.title": "Configuración de la pestaña de perfil",
|
||||||
|
"account_edit.save": "Guardar",
|
||||||
|
"account_edit.section_edit_button": "Editar",
|
||||||
"account_note.placeholder": "Haz clic para añadir nota",
|
"account_note.placeholder": "Haz clic para añadir nota",
|
||||||
"admin.dashboard.daily_retention": "Tasa de retención de usuarios por día después del registro",
|
"admin.dashboard.daily_retention": "Tasa de retención de usuarios por día después del registro",
|
||||||
"admin.dashboard.monthly_retention": "Tasa de retención de usuarios por mes después del registro",
|
"admin.dashboard.monthly_retention": "Tasa de retención de usuarios por mes después del registro",
|
||||||
@@ -267,6 +284,7 @@
|
|||||||
"collections.detail.curated_by_you": "Seleccionado por ti",
|
"collections.detail.curated_by_you": "Seleccionado por ti",
|
||||||
"collections.detail.loading": "Cargando colección…",
|
"collections.detail.loading": "Cargando colección…",
|
||||||
"collections.detail.share": "Compartir esta colección",
|
"collections.detail.share": "Compartir esta colección",
|
||||||
|
"collections.edit_details": "Editar detalles",
|
||||||
"collections.error_loading_collections": "Se ha producido un error al intentar cargar tus colecciones.",
|
"collections.error_loading_collections": "Se ha producido un error al intentar cargar tus colecciones.",
|
||||||
"collections.hints.accounts_counter": "{count} / {max} cuentas",
|
"collections.hints.accounts_counter": "{count} / {max} cuentas",
|
||||||
"collections.hints.add_more_accounts": "¡Añade al menos {count, plural, one {# cuenta} other {# cuentas}} para continuar",
|
"collections.hints.add_more_accounts": "¡Añade al menos {count, plural, one {# cuenta} other {# cuentas}} para continuar",
|
||||||
@@ -275,11 +293,14 @@
|
|||||||
"collections.manage_accounts": "Administrar cuentas",
|
"collections.manage_accounts": "Administrar cuentas",
|
||||||
"collections.mark_as_sensitive": "Marcar como sensible",
|
"collections.mark_as_sensitive": "Marcar como sensible",
|
||||||
"collections.mark_as_sensitive_hint": "Oculta la descripción de la colección y las cuentas detrás de una advertencia de contenido. El nombre de la colección seguirá siendo visible.",
|
"collections.mark_as_sensitive_hint": "Oculta la descripción de la colección y las cuentas detrás de una advertencia de contenido. El nombre de la colección seguirá siendo visible.",
|
||||||
|
"collections.name_length_hint": "Límite de 40 caracteres",
|
||||||
"collections.new_collection": "Nueva colección",
|
"collections.new_collection": "Nueva colección",
|
||||||
"collections.no_collections_yet": "Aún no hay colecciones.",
|
"collections.no_collections_yet": "Aún no hay colecciones.",
|
||||||
|
"collections.old_last_post_note": "Última publicación hace más de una semana",
|
||||||
"collections.remove_account": "Borrar esta cuenta",
|
"collections.remove_account": "Borrar esta cuenta",
|
||||||
"collections.search_accounts_label": "Buscar cuentas para añadir…",
|
"collections.search_accounts_label": "Buscar cuentas para añadir…",
|
||||||
"collections.search_accounts_max_reached": "Has añadido el número máximo de cuentas",
|
"collections.search_accounts_max_reached": "Has añadido el número máximo de cuentas",
|
||||||
|
"collections.sensitive": "Sensible",
|
||||||
"collections.topic_hint": "Añadir una etiqueta que ayude a otros a entender el tema principal de esta colección.",
|
"collections.topic_hint": "Añadir una etiqueta que ayude a otros a entender el tema principal de esta colección.",
|
||||||
"collections.view_collection": "Ver colección",
|
"collections.view_collection": "Ver colección",
|
||||||
"collections.visibility_public": "Pública",
|
"collections.visibility_public": "Pública",
|
||||||
@@ -370,6 +391,9 @@
|
|||||||
"confirmations.discard_draft.post.title": "¿Descartar tu borrador?",
|
"confirmations.discard_draft.post.title": "¿Descartar tu borrador?",
|
||||||
"confirmations.discard_edit_media.confirm": "Descartar",
|
"confirmations.discard_edit_media.confirm": "Descartar",
|
||||||
"confirmations.discard_edit_media.message": "Tienes cambios sin guardar en la descripción o vista previa del archivo audiovisual, ¿descartarlos de todos modos?",
|
"confirmations.discard_edit_media.message": "Tienes cambios sin guardar en la descripción o vista previa del archivo audiovisual, ¿descartarlos de todos modos?",
|
||||||
|
"confirmations.follow_to_collection.confirm": "Seguir y añadir a la colección",
|
||||||
|
"confirmations.follow_to_collection.message": "Debes seguir a {name} para añadirlo a una colección.",
|
||||||
|
"confirmations.follow_to_collection.title": "¿Seguir cuenta?",
|
||||||
"confirmations.follow_to_list.confirm": "Seguir y añadir a la lista",
|
"confirmations.follow_to_list.confirm": "Seguir y añadir a la lista",
|
||||||
"confirmations.follow_to_list.message": "Necesitas seguir a {name} para agregarlo a una lista.",
|
"confirmations.follow_to_list.message": "Necesitas seguir a {name} para agregarlo a una lista.",
|
||||||
"confirmations.follow_to_list.title": "¿Seguir usuario?",
|
"confirmations.follow_to_list.title": "¿Seguir usuario?",
|
||||||
|
|||||||
@@ -296,6 +296,7 @@
|
|||||||
"collections.name_length_hint": "40 merkin rajoitus",
|
"collections.name_length_hint": "40 merkin rajoitus",
|
||||||
"collections.new_collection": "Uusi kokoelma",
|
"collections.new_collection": "Uusi kokoelma",
|
||||||
"collections.no_collections_yet": "Ei vielä kokoelmia.",
|
"collections.no_collections_yet": "Ei vielä kokoelmia.",
|
||||||
|
"collections.old_last_post_note": "Julkaissut viimeksi yli viikko sitten",
|
||||||
"collections.remove_account": "Poista tämä tili",
|
"collections.remove_account": "Poista tämä tili",
|
||||||
"collections.search_accounts_label": "Hae lisättäviä tilejä…",
|
"collections.search_accounts_label": "Hae lisättäviä tilejä…",
|
||||||
"collections.search_accounts_max_reached": "Olet lisännyt enimmäismäärän tilejä",
|
"collections.search_accounts_max_reached": "Olet lisännyt enimmäismäärän tilejä",
|
||||||
@@ -390,6 +391,9 @@
|
|||||||
"confirmations.discard_draft.post.title": "Hylätäänkö luonnosjulkaisusi?",
|
"confirmations.discard_draft.post.title": "Hylätäänkö luonnosjulkaisusi?",
|
||||||
"confirmations.discard_edit_media.confirm": "Hylkää",
|
"confirmations.discard_edit_media.confirm": "Hylkää",
|
||||||
"confirmations.discard_edit_media.message": "Sinulla on tallentamattomia muutoksia median kuvaukseen tai esikatseluun. Hylätäänkö ne silti?",
|
"confirmations.discard_edit_media.message": "Sinulla on tallentamattomia muutoksia median kuvaukseen tai esikatseluun. Hylätäänkö ne silti?",
|
||||||
|
"confirmations.follow_to_collection.confirm": "Seuraa ja lisää kokoelmaan",
|
||||||
|
"confirmations.follow_to_collection.message": "Sinun on seurattava tiliä {name}, jotta voit lisätä sen kokoelmaan.",
|
||||||
|
"confirmations.follow_to_collection.title": "Seurataanko tiliä?",
|
||||||
"confirmations.follow_to_list.confirm": "Seuraa ja lisää listaan",
|
"confirmations.follow_to_list.confirm": "Seuraa ja lisää listaan",
|
||||||
"confirmations.follow_to_list.message": "Sinun on seurattava käyttäjää {name}, jotta voit lisätä hänet listaan.",
|
"confirmations.follow_to_list.message": "Sinun on seurattava käyttäjää {name}, jotta voit lisätä hänet listaan.",
|
||||||
"confirmations.follow_to_list.title": "Seurataanko käyttäjää?",
|
"confirmations.follow_to_list.title": "Seurataanko käyttäjää?",
|
||||||
|
|||||||
@@ -141,8 +141,25 @@
|
|||||||
"account.unmute": "Doyv ikki @{name}",
|
"account.unmute": "Doyv ikki @{name}",
|
||||||
"account.unmute_notifications_short": "Tendra fráboðanir",
|
"account.unmute_notifications_short": "Tendra fráboðanir",
|
||||||
"account.unmute_short": "Doyv ikki",
|
"account.unmute_short": "Doyv ikki",
|
||||||
|
"account_edit.bio.placeholder": "Legg eina stutta kunning afturat soleiðis at onnur kunnu eyðmerkja teg.",
|
||||||
|
"account_edit.bio.title": "Ævilýsing",
|
||||||
|
"account_edit.bio_modal.add_title": "Legg ævilýsing afturat",
|
||||||
|
"account_edit.bio_modal.edit_title": "Rætta ævilýsing",
|
||||||
|
"account_edit.char_counter": "{currentLength}/{maxLength} tekn",
|
||||||
"account_edit.column_button": "Liðugt",
|
"account_edit.column_button": "Liðugt",
|
||||||
"account_edit.column_title": "Rætta vanga",
|
"account_edit.column_title": "Rætta vanga",
|
||||||
|
"account_edit.custom_fields.placeholder": "Legg tíni forheiti, uttanhýsis leinki ella okkurt annað, sum tú kundi hugsað tær at deilt.",
|
||||||
|
"account_edit.custom_fields.title": "Serfelt",
|
||||||
|
"account_edit.display_name.placeholder": "Títt vísta navn er soleiðis sum navnið hjá tær verður víst á vanganum og á tíðarrásum.",
|
||||||
|
"account_edit.display_name.title": "Víst navn",
|
||||||
|
"account_edit.featured_hashtags.placeholder": "Hjálp øðrum at eyðmekja og hava skjóta atgongd til tíni yndisevni.",
|
||||||
|
"account_edit.featured_hashtags.title": "Sermerkt frámerki",
|
||||||
|
"account_edit.name_modal.add_title": "Legg víst navn afturat",
|
||||||
|
"account_edit.name_modal.edit_title": "Rætta víst navn",
|
||||||
|
"account_edit.profile_tab.subtitle": "Tillaga spjøldrini á vanganum hjá tær og tað, tey vísa.",
|
||||||
|
"account_edit.profile_tab.title": "Stillingar fyri spjøldur á vanga",
|
||||||
|
"account_edit.save": "Goym",
|
||||||
|
"account_edit.section_edit_button": "Rætta",
|
||||||
"account_note.placeholder": "Klikka fyri at leggja viðmerking afturat",
|
"account_note.placeholder": "Klikka fyri at leggja viðmerking afturat",
|
||||||
"admin.dashboard.daily_retention": "Hvussu nógvir brúkarar eru eftir, síðani tey skrásettu seg, roknað í døgum",
|
"admin.dashboard.daily_retention": "Hvussu nógvir brúkarar eru eftir, síðani tey skrásettu seg, roknað í døgum",
|
||||||
"admin.dashboard.monthly_retention": "Hvussu nógvir brúkarar eru eftir síðani tey skrásettu seg, roknað í mánaðum",
|
"admin.dashboard.monthly_retention": "Hvussu nógvir brúkarar eru eftir síðani tey skrásettu seg, roknað í mánaðum",
|
||||||
@@ -262,6 +279,12 @@
|
|||||||
"collections.create_collection": "Ger savn",
|
"collections.create_collection": "Ger savn",
|
||||||
"collections.delete_collection": "Strika savn",
|
"collections.delete_collection": "Strika savn",
|
||||||
"collections.description_length_hint": "Í mesta lagi 100 tekn",
|
"collections.description_length_hint": "Í mesta lagi 100 tekn",
|
||||||
|
"collections.detail.accounts_heading": "Kontur",
|
||||||
|
"collections.detail.curated_by_author": "Snikkað til av {author}",
|
||||||
|
"collections.detail.curated_by_you": "Snikkað til av tær",
|
||||||
|
"collections.detail.loading": "Innlesi savn…",
|
||||||
|
"collections.detail.share": "Deil hetta savnið",
|
||||||
|
"collections.edit_details": "Rætta smálutir",
|
||||||
"collections.error_loading_collections": "Ein feilur hendi, tá tú royndi at finna fram søvnini hjá tær.",
|
"collections.error_loading_collections": "Ein feilur hendi, tá tú royndi at finna fram søvnini hjá tær.",
|
||||||
"collections.hints.accounts_counter": "{count} / {max} kontur",
|
"collections.hints.accounts_counter": "{count} / {max} kontur",
|
||||||
"collections.hints.add_more_accounts": "Legg minst {count, plural, one {# kontu} other {# kontur}} afturat fyri at halda fram",
|
"collections.hints.add_more_accounts": "Legg minst {count, plural, one {# kontu} other {# kontur}} afturat fyri at halda fram",
|
||||||
@@ -270,11 +293,14 @@
|
|||||||
"collections.manage_accounts": "Umsit kontur",
|
"collections.manage_accounts": "Umsit kontur",
|
||||||
"collections.mark_as_sensitive": "Merk sum viðkvæmt",
|
"collections.mark_as_sensitive": "Merk sum viðkvæmt",
|
||||||
"collections.mark_as_sensitive_hint": "Fjalið lýsingina av og konturnar hjá savninum aftan fyri eina innihaldsávaring. Savnsnavnið verður framvegis sjónligt.",
|
"collections.mark_as_sensitive_hint": "Fjalið lýsingina av og konturnar hjá savninum aftan fyri eina innihaldsávaring. Savnsnavnið verður framvegis sjónligt.",
|
||||||
|
"collections.name_length_hint": "Í mesta lagi 40 tekn",
|
||||||
"collections.new_collection": "Nýtt savn",
|
"collections.new_collection": "Nýtt savn",
|
||||||
"collections.no_collections_yet": "Eingi søvn enn.",
|
"collections.no_collections_yet": "Eingi søvn enn.",
|
||||||
|
"collections.old_last_post_note": "Postaði seinast fyri meira enn einari viku síðani",
|
||||||
"collections.remove_account": "Strika hesa kontuna",
|
"collections.remove_account": "Strika hesa kontuna",
|
||||||
"collections.search_accounts_label": "Leita eftir kontum at leggja afturat…",
|
"collections.search_accounts_label": "Leita eftir kontum at leggja afturat…",
|
||||||
"collections.search_accounts_max_reached": "Tú hevur lagt afturat mesta talið av kontum",
|
"collections.search_accounts_max_reached": "Tú hevur lagt afturat mesta talið av kontum",
|
||||||
|
"collections.sensitive": "Viðkvæmt",
|
||||||
"collections.topic_hint": "Legg afturat eitt frámerki, sum hjálpir øðrum at skilja høvuðevnið í hesum savninum.",
|
"collections.topic_hint": "Legg afturat eitt frámerki, sum hjálpir øðrum at skilja høvuðevnið í hesum savninum.",
|
||||||
"collections.view_collection": "Vís savn",
|
"collections.view_collection": "Vís savn",
|
||||||
"collections.visibility_public": "Alment",
|
"collections.visibility_public": "Alment",
|
||||||
@@ -365,6 +391,9 @@
|
|||||||
"confirmations.discard_draft.post.title": "Vraka kladdupostin?",
|
"confirmations.discard_draft.post.title": "Vraka kladdupostin?",
|
||||||
"confirmations.discard_edit_media.confirm": "Vraka",
|
"confirmations.discard_edit_media.confirm": "Vraka",
|
||||||
"confirmations.discard_edit_media.message": "Tú hevur broytingar í miðlalýsingini ella undansýningini, sum ikki eru goymdar. Vilt tú kortini vraka?",
|
"confirmations.discard_edit_media.message": "Tú hevur broytingar í miðlalýsingini ella undansýningini, sum ikki eru goymdar. Vilt tú kortini vraka?",
|
||||||
|
"confirmations.follow_to_collection.confirm": "Fylg og legg afturat savni",
|
||||||
|
"confirmations.follow_to_collection.message": "Tú mást fylgja {name} fyri at leggja tey afturat einum savni.",
|
||||||
|
"confirmations.follow_to_collection.title": "Fylg kontu?",
|
||||||
"confirmations.follow_to_list.confirm": "Fylg og legg afturat lista",
|
"confirmations.follow_to_list.confirm": "Fylg og legg afturat lista",
|
||||||
"confirmations.follow_to_list.message": "Tú mást fylgja {name} fyri at leggja tey afturat einum lista.",
|
"confirmations.follow_to_list.message": "Tú mást fylgja {name} fyri at leggja tey afturat einum lista.",
|
||||||
"confirmations.follow_to_list.title": "Fylg brúkara?",
|
"confirmations.follow_to_list.title": "Fylg brúkara?",
|
||||||
|
|||||||
@@ -141,15 +141,25 @@
|
|||||||
"account.unmute": "Ne plus masquer @{name}",
|
"account.unmute": "Ne plus masquer @{name}",
|
||||||
"account.unmute_notifications_short": "Ne plus masquer les notifications",
|
"account.unmute_notifications_short": "Ne plus masquer les notifications",
|
||||||
"account.unmute_short": "Ne plus masquer",
|
"account.unmute_short": "Ne plus masquer",
|
||||||
"account_edit.bio.placeholder": "Ajouter une courte introduction pour aider à vous connaître.",
|
"account_edit.bio.placeholder": "Ajouter une courte introduction pour aider les autres à vous connaître.",
|
||||||
"account_edit.bio.title": "Présentation",
|
"account_edit.bio.title": "Présentation",
|
||||||
"account_edit.bio_modal.add_title": "Ajouter une présentation",
|
"account_edit.bio_modal.add_title": "Ajouter une présentation",
|
||||||
"account_edit.bio_modal.edit_title": "Modifier la présentation",
|
"account_edit.bio_modal.edit_title": "Modifier la présentation",
|
||||||
"account_edit.char_counter": "{currentLength}/{maxLength} caractères",
|
"account_edit.char_counter": "{currentLength}/{maxLength} caractères",
|
||||||
"account_edit.column_button": "Terminé",
|
"account_edit.column_button": "Terminé",
|
||||||
"account_edit.column_title": "Modifier le profil",
|
"account_edit.column_title": "Modifier le profil",
|
||||||
|
"account_edit.custom_fields.placeholder": "Ajouter vos pronoms, vos sites, ou tout ce que vous voulez partager.",
|
||||||
|
"account_edit.custom_fields.title": "Champs personnalisés",
|
||||||
|
"account_edit.display_name.placeholder": "Votre nom public est le nom qui apparaît sur votre profil et dans les fils d'actualités.",
|
||||||
|
"account_edit.display_name.title": "Nom public",
|
||||||
|
"account_edit.featured_hashtags.placeholder": "Aider les autres à identifier et à accéder rapidement à vos sujets préférés.",
|
||||||
|
"account_edit.featured_hashtags.title": "Hashtags mis en avant",
|
||||||
|
"account_edit.name_modal.add_title": "Ajouter un nom public",
|
||||||
|
"account_edit.name_modal.edit_title": "Modifier le nom public",
|
||||||
|
"account_edit.profile_tab.subtitle": "Personnaliser les onglets de votre profil et leur contenu.",
|
||||||
|
"account_edit.profile_tab.title": "Paramètres de l'onglet du profil",
|
||||||
"account_edit.save": "Enregistrer",
|
"account_edit.save": "Enregistrer",
|
||||||
"account_edit.section_edit_button": "Éditer",
|
"account_edit.section_edit_button": "Modifier",
|
||||||
"account_note.placeholder": "Cliquez pour ajouter une note",
|
"account_note.placeholder": "Cliquez pour ajouter une note",
|
||||||
"admin.dashboard.daily_retention": "Taux de rétention des comptes par jour après inscription",
|
"admin.dashboard.daily_retention": "Taux de rétention des comptes par jour après inscription",
|
||||||
"admin.dashboard.monthly_retention": "Taux de rétention des comptes par mois après inscription",
|
"admin.dashboard.monthly_retention": "Taux de rétention des comptes par mois après inscription",
|
||||||
@@ -242,7 +252,7 @@
|
|||||||
"bundle_column_error.routing.body": "La page demandée est introuvable. Êtes-vous sûr que l’URL dans la barre d’adresse est correcte?",
|
"bundle_column_error.routing.body": "La page demandée est introuvable. Êtes-vous sûr que l’URL dans la barre d’adresse est correcte?",
|
||||||
"bundle_column_error.routing.title": "404",
|
"bundle_column_error.routing.title": "404",
|
||||||
"bundle_modal_error.close": "Fermer",
|
"bundle_modal_error.close": "Fermer",
|
||||||
"bundle_modal_error.message": "Un problème s'est produit lors du chargement de cet écran.",
|
"bundle_modal_error.message": "Une erreur s’est produite lors du chargement de cet écran.",
|
||||||
"bundle_modal_error.retry": "Réessayer",
|
"bundle_modal_error.retry": "Réessayer",
|
||||||
"callout.dismiss": "Rejeter",
|
"callout.dismiss": "Rejeter",
|
||||||
"carousel.current": "<sr>Diapositive</sr> {current, number} / {max, number}",
|
"carousel.current": "<sr>Diapositive</sr> {current, number} / {max, number}",
|
||||||
@@ -274,6 +284,7 @@
|
|||||||
"collections.detail.curated_by_you": "Organisée par vous",
|
"collections.detail.curated_by_you": "Organisée par vous",
|
||||||
"collections.detail.loading": "Chargement de la collection…",
|
"collections.detail.loading": "Chargement de la collection…",
|
||||||
"collections.detail.share": "Partager la collection",
|
"collections.detail.share": "Partager la collection",
|
||||||
|
"collections.edit_details": "Modifier les détails",
|
||||||
"collections.error_loading_collections": "Une erreur s'est produite durant le chargement de vos collections.",
|
"collections.error_loading_collections": "Une erreur s'est produite durant le chargement de vos collections.",
|
||||||
"collections.hints.accounts_counter": "{count} / {max} comptes",
|
"collections.hints.accounts_counter": "{count} / {max} comptes",
|
||||||
"collections.hints.add_more_accounts": "Ajouter au moins {count, plural, one {# compte} other {# comptes}} pour continuer",
|
"collections.hints.add_more_accounts": "Ajouter au moins {count, plural, one {# compte} other {# comptes}} pour continuer",
|
||||||
@@ -282,11 +293,14 @@
|
|||||||
"collections.manage_accounts": "Gérer les comptes",
|
"collections.manage_accounts": "Gérer les comptes",
|
||||||
"collections.mark_as_sensitive": "Marquer comme sensible",
|
"collections.mark_as_sensitive": "Marquer comme sensible",
|
||||||
"collections.mark_as_sensitive_hint": "Masque la description et les comptes de la collection derrière un avertissement au public. Le titre reste visible.",
|
"collections.mark_as_sensitive_hint": "Masque la description et les comptes de la collection derrière un avertissement au public. Le titre reste visible.",
|
||||||
|
"collections.name_length_hint": "Maximum 40 caractères",
|
||||||
"collections.new_collection": "Nouvelle collection",
|
"collections.new_collection": "Nouvelle collection",
|
||||||
"collections.no_collections_yet": "Aucune collection pour le moment.",
|
"collections.no_collections_yet": "Aucune collection pour le moment.",
|
||||||
|
"collections.old_last_post_note": "Dernière publication il y a plus d'une semaine",
|
||||||
"collections.remove_account": "Supprimer ce compte",
|
"collections.remove_account": "Supprimer ce compte",
|
||||||
"collections.search_accounts_label": "Chercher des comptes à ajouter…",
|
"collections.search_accounts_label": "Chercher des comptes à ajouter…",
|
||||||
"collections.search_accounts_max_reached": "Vous avez ajouté le nombre maximum de comptes",
|
"collections.search_accounts_max_reached": "Vous avez ajouté le nombre maximum de comptes",
|
||||||
|
"collections.sensitive": "Sensible",
|
||||||
"collections.topic_hint": "Ajouter un hashtag pour aider les autres personnes à comprendre le sujet de la collection.",
|
"collections.topic_hint": "Ajouter un hashtag pour aider les autres personnes à comprendre le sujet de la collection.",
|
||||||
"collections.view_collection": "Voir la collection",
|
"collections.view_collection": "Voir la collection",
|
||||||
"collections.visibility_public": "Publique",
|
"collections.visibility_public": "Publique",
|
||||||
@@ -332,7 +346,7 @@
|
|||||||
"community.column_settings.local_only": "Local seulement",
|
"community.column_settings.local_only": "Local seulement",
|
||||||
"community.column_settings.media_only": "Média seulement",
|
"community.column_settings.media_only": "Média seulement",
|
||||||
"community.column_settings.remote_only": "À distance seulement",
|
"community.column_settings.remote_only": "À distance seulement",
|
||||||
"compose.error.blank_post": "Le message ne peut être laissé vide.",
|
"compose.error.blank_post": "Le message ne peut pas être vide.",
|
||||||
"compose.language.change": "Changer de langue",
|
"compose.language.change": "Changer de langue",
|
||||||
"compose.language.search": "Rechercher des langues…",
|
"compose.language.search": "Rechercher des langues…",
|
||||||
"compose.published.body": "Publiée.",
|
"compose.published.body": "Publiée.",
|
||||||
@@ -369,24 +383,27 @@
|
|||||||
"confirmations.delete_list.message": "Voulez-vous vraiment supprimer définitivement cette liste?",
|
"confirmations.delete_list.message": "Voulez-vous vraiment supprimer définitivement cette liste?",
|
||||||
"confirmations.delete_list.title": "Supprimer la liste ?",
|
"confirmations.delete_list.title": "Supprimer la liste ?",
|
||||||
"confirmations.discard_draft.confirm": "Effacer et continuer",
|
"confirmations.discard_draft.confirm": "Effacer et continuer",
|
||||||
"confirmations.discard_draft.edit.cancel": "Retour vers l'éditeur",
|
"confirmations.discard_draft.edit.cancel": "Reprendre l'édition",
|
||||||
"confirmations.discard_draft.edit.message": "Continued va perdre les changements que vous avez faits dans le message courant.",
|
"confirmations.discard_draft.edit.message": "Si vous continuez, toutes les modifications apportées au message en cours d'édition seront annulées.",
|
||||||
"confirmations.discard_draft.edit.title": "Jeter les changements faits au message?",
|
"confirmations.discard_draft.edit.title": "Annuler les modifications apportées à votre message ?",
|
||||||
"confirmations.discard_draft.post.cancel": "Retour au brouillon",
|
"confirmations.discard_draft.post.cancel": "Retour au brouillon",
|
||||||
"confirmations.discard_draft.post.message": "En continuant, vous perdez le message que vous êtes en train d'écrire.",
|
"confirmations.discard_draft.post.message": "Si vous continuez, vous supprimerez le message que vous êtes en train de composer.",
|
||||||
"confirmations.discard_draft.post.title": "Jeter le brouillon de message?",
|
"confirmations.discard_draft.post.title": "Abandonner votre brouillon ?",
|
||||||
"confirmations.discard_edit_media.confirm": "Rejeter",
|
"confirmations.discard_edit_media.confirm": "Rejeter",
|
||||||
"confirmations.discard_edit_media.message": "Vous avez des modifications non enregistrées de la description ou de l'aperçu du média, voulez-vous quand même les supprimer?",
|
"confirmations.discard_edit_media.message": "Vous avez des modifications non enregistrées de la description ou de l'aperçu du média, voulez-vous quand même les supprimer?",
|
||||||
|
"confirmations.follow_to_collection.confirm": "Suivre et ajouter à la collection",
|
||||||
|
"confirmations.follow_to_collection.message": "Vous devez suivre {name} pour l'ajouter à une collection.",
|
||||||
|
"confirmations.follow_to_collection.title": "Suivre le compte ?",
|
||||||
"confirmations.follow_to_list.confirm": "Suivre et ajouter à la liste",
|
"confirmations.follow_to_list.confirm": "Suivre et ajouter à la liste",
|
||||||
"confirmations.follow_to_list.message": "Vous devez suivre {name} pour l'ajouter à une liste.",
|
"confirmations.follow_to_list.message": "Vous devez suivre {name} pour l'ajouter à une liste.",
|
||||||
"confirmations.follow_to_list.title": "Suivre l'utilisateur ?",
|
"confirmations.follow_to_list.title": "Suivre l'utilisateur·rice ?",
|
||||||
"confirmations.logout.confirm": "Se déconnecter",
|
"confirmations.logout.confirm": "Se déconnecter",
|
||||||
"confirmations.logout.message": "Voulez-vous vraiment vous déconnecter?",
|
"confirmations.logout.message": "Voulez-vous vraiment vous déconnecter?",
|
||||||
"confirmations.logout.title": "Se déconnecter ?",
|
"confirmations.logout.title": "Se déconnecter ?",
|
||||||
"confirmations.missing_alt_text.confirm": "Ajouter un texte alternatif",
|
"confirmations.missing_alt_text.confirm": "Ajouter un texte alternatif",
|
||||||
"confirmations.missing_alt_text.message": "Votre post contient des médias sans texte alternatif. Ajouter des descriptions rend votre contenu accessible à un plus grand nombre de personnes.",
|
"confirmations.missing_alt_text.message": "Votre message contient des médias sans texte alternatif. L'ajout de descriptions aide à rendre votre contenu accessible à plus de personnes.",
|
||||||
"confirmations.missing_alt_text.secondary": "Publier quand-même",
|
"confirmations.missing_alt_text.secondary": "Publier quand même",
|
||||||
"confirmations.missing_alt_text.title": "Ajouter un texte alternatif?",
|
"confirmations.missing_alt_text.title": "Ajouter un texte alternatif ?",
|
||||||
"confirmations.mute.confirm": "Masquer",
|
"confirmations.mute.confirm": "Masquer",
|
||||||
"confirmations.private_quote_notify.cancel": "Retour à l'édition",
|
"confirmations.private_quote_notify.cancel": "Retour à l'édition",
|
||||||
"confirmations.private_quote_notify.confirm": "Publier",
|
"confirmations.private_quote_notify.confirm": "Publier",
|
||||||
@@ -395,17 +412,17 @@
|
|||||||
"confirmations.private_quote_notify.title": "Partager avec les personnes abonnées et mentionnées ?",
|
"confirmations.private_quote_notify.title": "Partager avec les personnes abonnées et mentionnées ?",
|
||||||
"confirmations.quiet_post_quote_info.dismiss": "Ne plus me rappeler",
|
"confirmations.quiet_post_quote_info.dismiss": "Ne plus me rappeler",
|
||||||
"confirmations.quiet_post_quote_info.got_it": "Compris",
|
"confirmations.quiet_post_quote_info.got_it": "Compris",
|
||||||
"confirmations.quiet_post_quote_info.message": "Lorsque vous citez un message public silencieux, votre message sera caché des fils tendances.",
|
"confirmations.quiet_post_quote_info.message": "Lorsque vous citez un message public discret, votre message sera caché des fils tendances.",
|
||||||
"confirmations.quiet_post_quote_info.title": "Citation de messages publics silencieux",
|
"confirmations.quiet_post_quote_info.title": "Citation d'un message public discret",
|
||||||
"confirmations.redraft.confirm": "Supprimer et réécrire",
|
"confirmations.redraft.confirm": "Supprimer et réécrire",
|
||||||
"confirmations.redraft.message": "Êtes-vous sûr·e de vouloir effacer cette publication pour la réécrire? Ses ses mises en favori et boosts seront perdus et ses réponses seront orphelines.",
|
"confirmations.redraft.message": "Êtes-vous sûr·e de vouloir effacer cette publication pour la réécrire? Ses ses mises en favori et boosts seront perdus et ses réponses seront orphelines.",
|
||||||
"confirmations.redraft.title": "Supprimer et réécrire le message ?",
|
"confirmations.redraft.title": "Supprimer et réécrire le message ?",
|
||||||
"confirmations.remove_from_followers.confirm": "Supprimer l'abonné·e",
|
"confirmations.remove_from_followers.confirm": "Supprimer l'abonné·e",
|
||||||
"confirmations.remove_from_followers.message": "{name} cessera de vous suivre. Êtes-vous sûr de vouloir continuer ?",
|
"confirmations.remove_from_followers.message": "{name} cessera de vous suivre. Voulez-vous vraiment continuer ?",
|
||||||
"confirmations.remove_from_followers.title": "Supprimer l'abonné·e ?",
|
"confirmations.remove_from_followers.title": "Supprimer l'abonné·e ?",
|
||||||
"confirmations.revoke_quote.confirm": "Retirer la publication",
|
"confirmations.revoke_quote.confirm": "Retirer le message",
|
||||||
"confirmations.revoke_quote.message": "Cette action ne peut pas être annulée.",
|
"confirmations.revoke_quote.message": "Cette action ne peut pas être annulée.",
|
||||||
"confirmations.revoke_quote.title": "Retirer la publication ?",
|
"confirmations.revoke_quote.title": "Retirer le message ?",
|
||||||
"confirmations.unblock.confirm": "Débloquer",
|
"confirmations.unblock.confirm": "Débloquer",
|
||||||
"confirmations.unblock.title": "Débloquer {name} ?",
|
"confirmations.unblock.title": "Débloquer {name} ?",
|
||||||
"confirmations.unfollow.confirm": "Ne plus suivre",
|
"confirmations.unfollow.confirm": "Ne plus suivre",
|
||||||
@@ -430,7 +447,7 @@
|
|||||||
"disabled_account_banner.text": "Votre compte {disabledAccount} est présentement désactivé.",
|
"disabled_account_banner.text": "Votre compte {disabledAccount} est présentement désactivé.",
|
||||||
"dismissable_banner.community_timeline": "Voici les publications publiques les plus récentes de personnes dont les comptes sont hébergés par {domain}.",
|
"dismissable_banner.community_timeline": "Voici les publications publiques les plus récentes de personnes dont les comptes sont hébergés par {domain}.",
|
||||||
"dismissable_banner.dismiss": "Rejeter",
|
"dismissable_banner.dismiss": "Rejeter",
|
||||||
"dismissable_banner.public_timeline": "Il s'agit des messages publics les plus récents publiés par des personnes sur le fediverse que les personnes sur {domain} suivent.",
|
"dismissable_banner.public_timeline": "Il s'agit des messages publics les plus récents publiés par des personnes sur le fédivers que les personnes sur {domain} suivent.",
|
||||||
"domain_block_modal.block": "Bloquer le serveur",
|
"domain_block_modal.block": "Bloquer le serveur",
|
||||||
"domain_block_modal.block_account_instead": "Bloquer @{name} à la place",
|
"domain_block_modal.block_account_instead": "Bloquer @{name} à la place",
|
||||||
"domain_block_modal.they_can_interact_with_old_posts": "Les personnes de ce serveur peuvent interagir avec vos anciens messages.",
|
"domain_block_modal.they_can_interact_with_old_posts": "Les personnes de ce serveur peuvent interagir avec vos anciens messages.",
|
||||||
@@ -444,12 +461,12 @@
|
|||||||
"domain_pill.activitypub_like_language": "ActivityPub est comme une langue que Mastodon utilise pour communiquer avec les autres réseaux sociaux.",
|
"domain_pill.activitypub_like_language": "ActivityPub est comme une langue que Mastodon utilise pour communiquer avec les autres réseaux sociaux.",
|
||||||
"domain_pill.server": "Serveur",
|
"domain_pill.server": "Serveur",
|
||||||
"domain_pill.their_handle": "Son identifiant :",
|
"domain_pill.their_handle": "Son identifiant :",
|
||||||
"domain_pill.their_server": "Son foyer numérique, là où tous ses posts résident.",
|
"domain_pill.their_server": "Son foyer numérique, là où tous ses messages résident.",
|
||||||
"domain_pill.their_username": "Son identifiant unique sur leur serveur. Il est possible de rencontrer des utilisateur·rice·s avec le même nom sur différents serveurs.",
|
"domain_pill.their_username": "Son identifiant unique sur leur serveur. Il est possible de rencontrer des utilisateur·rice·s avec le même nom sur différents serveurs.",
|
||||||
"domain_pill.username": "Nom d’utilisateur",
|
"domain_pill.username": "Nom d’utilisateur·rice",
|
||||||
"domain_pill.whats_in_a_handle": "Qu'est-ce qu'un identifiant ?",
|
"domain_pill.whats_in_a_handle": "Qu'est-ce qu'un identifiant ?",
|
||||||
"domain_pill.who_they_are": "Comme un identifiant contient le nom et le service hébergeant une personne, vous pouvez interagir sur <button>les plateformes sociales implémentant ActivityPub</button>.",
|
"domain_pill.who_they_are": "Comme un identifiant contient le nom et le service hébergeant une personne, vous pouvez interagir sur <button>les plateformes sociales implémentant ActivityPub</button>.",
|
||||||
"domain_pill.who_you_are": "Comme un identifiant indique votre nom et le service vous hébergeant, vous pouvez interagir avec <button>les autres plateformes sociales implémentant ActivityPub</button>.",
|
"domain_pill.who_you_are": "Comme un identifiant indique votre nom et le service vous hébergeant, tout le monde peut interagir avec vous à l'aide de <button>plateformes sociales implémentant ActivityPub</button>.",
|
||||||
"domain_pill.your_handle": "Votre identifiant :",
|
"domain_pill.your_handle": "Votre identifiant :",
|
||||||
"domain_pill.your_server": "Votre foyer numérique, là où vos messages résident. Vous souhaitez changer ? Lancez un transfert vers un autre serveur quand vous le voulez et vos abonné·e·s suivront automatiquement.",
|
"domain_pill.your_server": "Votre foyer numérique, là où vos messages résident. Vous souhaitez changer ? Lancez un transfert vers un autre serveur quand vous le voulez et vos abonné·e·s suivront automatiquement.",
|
||||||
"domain_pill.your_username": "Votre identifiant unique sur ce serveur. Il est possible de rencontrer des utilisateur·rice·s ayant le même nom d'utilisateur sur différents serveurs.",
|
"domain_pill.your_username": "Votre identifiant unique sur ce serveur. Il est possible de rencontrer des utilisateur·rice·s ayant le même nom d'utilisateur sur différents serveurs.",
|
||||||
@@ -1018,7 +1035,7 @@
|
|||||||
"server_banner.about_active_users": "Personnes utilisant ce serveur au cours des 30 derniers jours (Comptes actifs mensuellement)",
|
"server_banner.about_active_users": "Personnes utilisant ce serveur au cours des 30 derniers jours (Comptes actifs mensuellement)",
|
||||||
"server_banner.active_users": "comptes actifs",
|
"server_banner.active_users": "comptes actifs",
|
||||||
"server_banner.administered_by": "Administré par:",
|
"server_banner.administered_by": "Administré par:",
|
||||||
"server_banner.is_one_of_many": "{domain} est l'un des nombreux serveurs Mastodon indépendants que vous pouvez utiliser pour participer au fédiverse.",
|
"server_banner.is_one_of_many": "{domain} est l'un des nombreux serveurs Mastodon indépendants que vous pouvez utiliser pour participer au fédivers.",
|
||||||
"server_banner.server_stats": "Statistiques du serveur:",
|
"server_banner.server_stats": "Statistiques du serveur:",
|
||||||
"sign_in_banner.create_account": "Créer un compte",
|
"sign_in_banner.create_account": "Créer un compte",
|
||||||
"sign_in_banner.follow_anyone": "Suivez n'importe qui à travers le fédivers et affichez tout dans un ordre chronologique. Ni algorithmes, ni publicités, ni appâts à clics en perspective.",
|
"sign_in_banner.follow_anyone": "Suivez n'importe qui à travers le fédivers et affichez tout dans un ordre chronologique. Ni algorithmes, ni publicités, ni appâts à clics en perspective.",
|
||||||
|
|||||||
@@ -141,15 +141,25 @@
|
|||||||
"account.unmute": "Ne plus masquer @{name}",
|
"account.unmute": "Ne plus masquer @{name}",
|
||||||
"account.unmute_notifications_short": "Réactiver les notifications",
|
"account.unmute_notifications_short": "Réactiver les notifications",
|
||||||
"account.unmute_short": "Ne plus masquer",
|
"account.unmute_short": "Ne plus masquer",
|
||||||
"account_edit.bio.placeholder": "Ajouter une courte introduction pour aider à vous connaître.",
|
"account_edit.bio.placeholder": "Ajouter une courte introduction pour aider les autres à vous connaître.",
|
||||||
"account_edit.bio.title": "Présentation",
|
"account_edit.bio.title": "Présentation",
|
||||||
"account_edit.bio_modal.add_title": "Ajouter une présentation",
|
"account_edit.bio_modal.add_title": "Ajouter une présentation",
|
||||||
"account_edit.bio_modal.edit_title": "Modifier la présentation",
|
"account_edit.bio_modal.edit_title": "Modifier la présentation",
|
||||||
"account_edit.char_counter": "{currentLength}/{maxLength} caractères",
|
"account_edit.char_counter": "{currentLength}/{maxLength} caractères",
|
||||||
"account_edit.column_button": "Terminé",
|
"account_edit.column_button": "Terminé",
|
||||||
"account_edit.column_title": "Modifier le profil",
|
"account_edit.column_title": "Modifier le profil",
|
||||||
|
"account_edit.custom_fields.placeholder": "Ajouter vos pronoms, vos sites, ou tout ce que vous voulez partager.",
|
||||||
|
"account_edit.custom_fields.title": "Champs personnalisés",
|
||||||
|
"account_edit.display_name.placeholder": "Votre nom public est le nom qui apparaît sur votre profil et dans les fils d'actualités.",
|
||||||
|
"account_edit.display_name.title": "Nom public",
|
||||||
|
"account_edit.featured_hashtags.placeholder": "Aider les autres à identifier et à accéder rapidement à vos sujets préférés.",
|
||||||
|
"account_edit.featured_hashtags.title": "Hashtags mis en avant",
|
||||||
|
"account_edit.name_modal.add_title": "Ajouter un nom public",
|
||||||
|
"account_edit.name_modal.edit_title": "Modifier le nom public",
|
||||||
|
"account_edit.profile_tab.subtitle": "Personnaliser les onglets de votre profil et leur contenu.",
|
||||||
|
"account_edit.profile_tab.title": "Paramètres de l'onglet du profil",
|
||||||
"account_edit.save": "Enregistrer",
|
"account_edit.save": "Enregistrer",
|
||||||
"account_edit.section_edit_button": "Éditer",
|
"account_edit.section_edit_button": "Modifier",
|
||||||
"account_note.placeholder": "Cliquez pour ajouter une note",
|
"account_note.placeholder": "Cliquez pour ajouter une note",
|
||||||
"admin.dashboard.daily_retention": "Taux de rétention des utilisateur·rice·s par jour après inscription",
|
"admin.dashboard.daily_retention": "Taux de rétention des utilisateur·rice·s par jour après inscription",
|
||||||
"admin.dashboard.monthly_retention": "Taux de rétention des utilisateur·rice·s par mois après inscription",
|
"admin.dashboard.monthly_retention": "Taux de rétention des utilisateur·rice·s par mois après inscription",
|
||||||
@@ -157,7 +167,7 @@
|
|||||||
"admin.dashboard.retention.cohort": "Mois d'inscription",
|
"admin.dashboard.retention.cohort": "Mois d'inscription",
|
||||||
"admin.dashboard.retention.cohort_size": "Nouveaux comptes",
|
"admin.dashboard.retention.cohort_size": "Nouveaux comptes",
|
||||||
"admin.impact_report.instance_accounts": "Profils de comptes que cela supprimerait",
|
"admin.impact_report.instance_accounts": "Profils de comptes que cela supprimerait",
|
||||||
"admin.impact_report.instance_followers": "Abonnées que nos utilisateurs perdraient",
|
"admin.impact_report.instance_followers": "Abonné·e·s que nos utilisateur·rice·s perdraient",
|
||||||
"admin.impact_report.instance_follows": "Abonné·e·s que leurs utilisateur·rice·s perdraient",
|
"admin.impact_report.instance_follows": "Abonné·e·s que leurs utilisateur·rice·s perdraient",
|
||||||
"admin.impact_report.title": "Résumé de l'impact",
|
"admin.impact_report.title": "Résumé de l'impact",
|
||||||
"alert.rate_limited.message": "Veuillez réessayer après {retry_time, time, medium}.",
|
"alert.rate_limited.message": "Veuillez réessayer après {retry_time, time, medium}.",
|
||||||
@@ -238,11 +248,11 @@
|
|||||||
"bundle_column_error.network.body": "Une erreur s'est produite lors du chargement de cette page. Cela peut être dû à un problème temporaire avec votre connexion internet ou avec ce serveur.",
|
"bundle_column_error.network.body": "Une erreur s'est produite lors du chargement de cette page. Cela peut être dû à un problème temporaire avec votre connexion internet ou avec ce serveur.",
|
||||||
"bundle_column_error.network.title": "Erreur réseau",
|
"bundle_column_error.network.title": "Erreur réseau",
|
||||||
"bundle_column_error.retry": "Réessayer",
|
"bundle_column_error.retry": "Réessayer",
|
||||||
"bundle_column_error.return": "Retour à l'accueil",
|
"bundle_column_error.return": "Retourner à l'accueil",
|
||||||
"bundle_column_error.routing.body": "La page demandée est introuvable. Êtes-vous sûr que l’URL dans la barre d’adresse est correcte ?",
|
"bundle_column_error.routing.body": "La page demandée est introuvable. Est-ce que l'URL dans la barre d’adresse est correcte ?",
|
||||||
"bundle_column_error.routing.title": "404",
|
"bundle_column_error.routing.title": "404",
|
||||||
"bundle_modal_error.close": "Fermer",
|
"bundle_modal_error.close": "Fermer",
|
||||||
"bundle_modal_error.message": "Un problème s'est produit lors du chargement de cet écran.",
|
"bundle_modal_error.message": "Une erreur s’est produite lors du chargement de cet écran.",
|
||||||
"bundle_modal_error.retry": "Réessayer",
|
"bundle_modal_error.retry": "Réessayer",
|
||||||
"callout.dismiss": "Rejeter",
|
"callout.dismiss": "Rejeter",
|
||||||
"carousel.current": "<sr>Diapositive</sr> {current, number} / {max, number}",
|
"carousel.current": "<sr>Diapositive</sr> {current, number} / {max, number}",
|
||||||
@@ -274,6 +284,7 @@
|
|||||||
"collections.detail.curated_by_you": "Organisée par vous",
|
"collections.detail.curated_by_you": "Organisée par vous",
|
||||||
"collections.detail.loading": "Chargement de la collection…",
|
"collections.detail.loading": "Chargement de la collection…",
|
||||||
"collections.detail.share": "Partager la collection",
|
"collections.detail.share": "Partager la collection",
|
||||||
|
"collections.edit_details": "Modifier les détails",
|
||||||
"collections.error_loading_collections": "Une erreur s'est produite durant le chargement de vos collections.",
|
"collections.error_loading_collections": "Une erreur s'est produite durant le chargement de vos collections.",
|
||||||
"collections.hints.accounts_counter": "{count} / {max} comptes",
|
"collections.hints.accounts_counter": "{count} / {max} comptes",
|
||||||
"collections.hints.add_more_accounts": "Ajouter au moins {count, plural, one {# compte} other {# comptes}} pour continuer",
|
"collections.hints.add_more_accounts": "Ajouter au moins {count, plural, one {# compte} other {# comptes}} pour continuer",
|
||||||
@@ -282,11 +293,14 @@
|
|||||||
"collections.manage_accounts": "Gérer les comptes",
|
"collections.manage_accounts": "Gérer les comptes",
|
||||||
"collections.mark_as_sensitive": "Marquer comme sensible",
|
"collections.mark_as_sensitive": "Marquer comme sensible",
|
||||||
"collections.mark_as_sensitive_hint": "Masque la description et les comptes de la collection derrière un avertissement au public. Le titre reste visible.",
|
"collections.mark_as_sensitive_hint": "Masque la description et les comptes de la collection derrière un avertissement au public. Le titre reste visible.",
|
||||||
|
"collections.name_length_hint": "Maximum 40 caractères",
|
||||||
"collections.new_collection": "Nouvelle collection",
|
"collections.new_collection": "Nouvelle collection",
|
||||||
"collections.no_collections_yet": "Aucune collection pour le moment.",
|
"collections.no_collections_yet": "Aucune collection pour le moment.",
|
||||||
|
"collections.old_last_post_note": "Dernière publication il y a plus d'une semaine",
|
||||||
"collections.remove_account": "Supprimer ce compte",
|
"collections.remove_account": "Supprimer ce compte",
|
||||||
"collections.search_accounts_label": "Chercher des comptes à ajouter…",
|
"collections.search_accounts_label": "Chercher des comptes à ajouter…",
|
||||||
"collections.search_accounts_max_reached": "Vous avez ajouté le nombre maximum de comptes",
|
"collections.search_accounts_max_reached": "Vous avez ajouté le nombre maximum de comptes",
|
||||||
|
"collections.sensitive": "Sensible",
|
||||||
"collections.topic_hint": "Ajouter un hashtag pour aider les autres personnes à comprendre le sujet de la collection.",
|
"collections.topic_hint": "Ajouter un hashtag pour aider les autres personnes à comprendre le sujet de la collection.",
|
||||||
"collections.view_collection": "Voir la collection",
|
"collections.view_collection": "Voir la collection",
|
||||||
"collections.visibility_public": "Publique",
|
"collections.visibility_public": "Publique",
|
||||||
@@ -295,10 +309,10 @@
|
|||||||
"collections.visibility_unlisted": "Non listée",
|
"collections.visibility_unlisted": "Non listée",
|
||||||
"collections.visibility_unlisted_hint": "Visible pour les personnes ayant le lien. N'apparaît pas dans les résultats de recherche et les recommandations.",
|
"collections.visibility_unlisted_hint": "Visible pour les personnes ayant le lien. N'apparaît pas dans les résultats de recherche et les recommandations.",
|
||||||
"column.about": "À propos",
|
"column.about": "À propos",
|
||||||
"column.blocks": "Utilisateurs bloqués",
|
"column.blocks": "Comptes bloqués",
|
||||||
"column.bookmarks": "Marque-pages",
|
"column.bookmarks": "Marque-pages",
|
||||||
"column.collections": "Mes collections",
|
"column.collections": "Mes collections",
|
||||||
"column.community": "Fil public local",
|
"column.community": "Fil local",
|
||||||
"column.create_list": "Créer une liste",
|
"column.create_list": "Créer une liste",
|
||||||
"column.direct": "Mentions privées",
|
"column.direct": "Mentions privées",
|
||||||
"column.directory": "Parcourir les profils",
|
"column.directory": "Parcourir les profils",
|
||||||
@@ -332,10 +346,10 @@
|
|||||||
"community.column_settings.local_only": "Local seulement",
|
"community.column_settings.local_only": "Local seulement",
|
||||||
"community.column_settings.media_only": "Média uniquement",
|
"community.column_settings.media_only": "Média uniquement",
|
||||||
"community.column_settings.remote_only": "Distant seulement",
|
"community.column_settings.remote_only": "Distant seulement",
|
||||||
"compose.error.blank_post": "Le message ne peut être laissé vide.",
|
"compose.error.blank_post": "Le message ne peut pas être vide.",
|
||||||
"compose.language.change": "Changer de langue",
|
"compose.language.change": "Modifier la langue",
|
||||||
"compose.language.search": "Rechercher des langues...",
|
"compose.language.search": "Rechercher langue…",
|
||||||
"compose.published.body": "Message Publié.",
|
"compose.published.body": "Message publié.",
|
||||||
"compose.published.open": "Ouvrir",
|
"compose.published.open": "Ouvrir",
|
||||||
"compose.saved.body": "Message enregistré.",
|
"compose.saved.body": "Message enregistré.",
|
||||||
"compose_form.direct_message_warning_learn_more": "En savoir plus",
|
"compose_form.direct_message_warning_learn_more": "En savoir plus",
|
||||||
@@ -348,8 +362,8 @@
|
|||||||
"compose_form.poll.multiple": "Choix multiple",
|
"compose_form.poll.multiple": "Choix multiple",
|
||||||
"compose_form.poll.option_placeholder": "Option {number}",
|
"compose_form.poll.option_placeholder": "Option {number}",
|
||||||
"compose_form.poll.single": "Choix unique",
|
"compose_form.poll.single": "Choix unique",
|
||||||
"compose_form.poll.switch_to_multiple": "Changer le sondage pour autoriser plusieurs choix",
|
"compose_form.poll.switch_to_multiple": "Modifier le sondage pour autoriser plusieurs choix",
|
||||||
"compose_form.poll.switch_to_single": "Modifier le sondage pour autoriser qu'un seul choix",
|
"compose_form.poll.switch_to_single": "Modifier le sondage pour autoriser un seul choix",
|
||||||
"compose_form.poll.type": "Style",
|
"compose_form.poll.type": "Style",
|
||||||
"compose_form.publish": "Publier",
|
"compose_form.publish": "Publier",
|
||||||
"compose_form.reply": "Répondre",
|
"compose_form.reply": "Répondre",
|
||||||
@@ -369,24 +383,27 @@
|
|||||||
"confirmations.delete_list.message": "Voulez-vous vraiment supprimer définitivement cette liste ?",
|
"confirmations.delete_list.message": "Voulez-vous vraiment supprimer définitivement cette liste ?",
|
||||||
"confirmations.delete_list.title": "Supprimer la liste ?",
|
"confirmations.delete_list.title": "Supprimer la liste ?",
|
||||||
"confirmations.discard_draft.confirm": "Effacer et continuer",
|
"confirmations.discard_draft.confirm": "Effacer et continuer",
|
||||||
"confirmations.discard_draft.edit.cancel": "Retour vers l'éditeur",
|
"confirmations.discard_draft.edit.cancel": "Reprendre l'édition",
|
||||||
"confirmations.discard_draft.edit.message": "Continued va perdre les changements que vous avez faits dans le message courant.",
|
"confirmations.discard_draft.edit.message": "Si vous continuez, toutes les modifications apportées au message en cours d'édition seront annulées.",
|
||||||
"confirmations.discard_draft.edit.title": "Jeter les changements faits au message?",
|
"confirmations.discard_draft.edit.title": "Annuler les modifications apportées à votre message ?",
|
||||||
"confirmations.discard_draft.post.cancel": "Retour au brouillon",
|
"confirmations.discard_draft.post.cancel": "Retour au brouillon",
|
||||||
"confirmations.discard_draft.post.message": "En continuant, vous perdez le message que vous êtes en train d'écrire.",
|
"confirmations.discard_draft.post.message": "Si vous continuez, vous supprimerez le message que vous êtes en train de composer.",
|
||||||
"confirmations.discard_draft.post.title": "Jeter le brouillon de message?",
|
"confirmations.discard_draft.post.title": "Abandonner votre brouillon ?",
|
||||||
"confirmations.discard_edit_media.confirm": "Rejeter",
|
"confirmations.discard_edit_media.confirm": "Supprimer",
|
||||||
"confirmations.discard_edit_media.message": "Vous avez des modifications non enregistrées de la description ou de l'aperçu du média, les supprimer quand même ?",
|
"confirmations.discard_edit_media.message": "Vous avez des modifications non enregistrées de la description ou de l'aperçu du média. Voulez-vous les supprimer ?",
|
||||||
|
"confirmations.follow_to_collection.confirm": "Suivre et ajouter à la collection",
|
||||||
|
"confirmations.follow_to_collection.message": "Vous devez suivre {name} pour l'ajouter à une collection.",
|
||||||
|
"confirmations.follow_to_collection.title": "Suivre le compte ?",
|
||||||
"confirmations.follow_to_list.confirm": "Suivre et ajouter à la liste",
|
"confirmations.follow_to_list.confirm": "Suivre et ajouter à la liste",
|
||||||
"confirmations.follow_to_list.message": "Vous devez suivre {name} pour l'ajouter à une liste.",
|
"confirmations.follow_to_list.message": "Vous devez suivre {name} pour l'ajouter à une liste.",
|
||||||
"confirmations.follow_to_list.title": "Suivre l'utilisateur ?",
|
"confirmations.follow_to_list.title": "Suivre l'utilisateur·rice ?",
|
||||||
"confirmations.logout.confirm": "Se déconnecter",
|
"confirmations.logout.confirm": "Se déconnecter",
|
||||||
"confirmations.logout.message": "Voulez-vous vraiment vous déconnecter ?",
|
"confirmations.logout.message": "Voulez-vous vraiment vous déconnecter ?",
|
||||||
"confirmations.logout.title": "Se déconnecter ?",
|
"confirmations.logout.title": "Se déconnecter ?",
|
||||||
"confirmations.missing_alt_text.confirm": "Ajouter un texte alternatif",
|
"confirmations.missing_alt_text.confirm": "Ajouter un texte alternatif",
|
||||||
"confirmations.missing_alt_text.message": "Votre post contient des médias sans texte alternatif. Ajouter des descriptions rend votre contenu accessible à un plus grand nombre de personnes.",
|
"confirmations.missing_alt_text.message": "Votre message contient des médias sans texte alternatif. L'ajout de descriptions aide à rendre votre contenu accessible à plus de personnes.",
|
||||||
"confirmations.missing_alt_text.secondary": "Publier quand-même",
|
"confirmations.missing_alt_text.secondary": "Publier quand même",
|
||||||
"confirmations.missing_alt_text.title": "Ajouter un texte alternatif?",
|
"confirmations.missing_alt_text.title": "Ajouter un texte alternatif ?",
|
||||||
"confirmations.mute.confirm": "Masquer",
|
"confirmations.mute.confirm": "Masquer",
|
||||||
"confirmations.private_quote_notify.cancel": "Retour à l'édition",
|
"confirmations.private_quote_notify.cancel": "Retour à l'édition",
|
||||||
"confirmations.private_quote_notify.confirm": "Publier",
|
"confirmations.private_quote_notify.confirm": "Publier",
|
||||||
@@ -395,17 +412,17 @@
|
|||||||
"confirmations.private_quote_notify.title": "Partager avec les personnes abonnées et mentionnées ?",
|
"confirmations.private_quote_notify.title": "Partager avec les personnes abonnées et mentionnées ?",
|
||||||
"confirmations.quiet_post_quote_info.dismiss": "Ne plus me rappeler",
|
"confirmations.quiet_post_quote_info.dismiss": "Ne plus me rappeler",
|
||||||
"confirmations.quiet_post_quote_info.got_it": "Compris",
|
"confirmations.quiet_post_quote_info.got_it": "Compris",
|
||||||
"confirmations.quiet_post_quote_info.message": "Lorsque vous citez un message public silencieux, votre message sera caché des fils tendances.",
|
"confirmations.quiet_post_quote_info.message": "Lorsque vous citez un message public discret, votre message sera caché des fils tendances.",
|
||||||
"confirmations.quiet_post_quote_info.title": "Citation de messages publics silencieux",
|
"confirmations.quiet_post_quote_info.title": "Citation d'un message public discret",
|
||||||
"confirmations.redraft.confirm": "Supprimer et ré-écrire",
|
"confirmations.redraft.confirm": "Supprimer et réécrire",
|
||||||
"confirmations.redraft.message": "Voulez-vous vraiment supprimer le message pour le réécrire ? Ses partages ainsi que ses mises en favori seront perdues, et ses réponses seront orphelines.",
|
"confirmations.redraft.message": "Voulez-vous vraiment supprimer le message pour le réécrire ? Ses partages ainsi que ses mises en favori seront perdus, et ses réponses seront orphelines.",
|
||||||
"confirmations.redraft.title": "Supprimer et réécrire le message ?",
|
"confirmations.redraft.title": "Supprimer et réécrire le message ?",
|
||||||
"confirmations.remove_from_followers.confirm": "Supprimer l'abonné·e",
|
"confirmations.remove_from_followers.confirm": "Supprimer l'abonné·e",
|
||||||
"confirmations.remove_from_followers.message": "{name} cessera de vous suivre. Êtes-vous sûr de vouloir continuer ?",
|
"confirmations.remove_from_followers.message": "{name} cessera de vous suivre. Voulez-vous vraiment continuer ?",
|
||||||
"confirmations.remove_from_followers.title": "Supprimer l'abonné·e ?",
|
"confirmations.remove_from_followers.title": "Supprimer l'abonné·e ?",
|
||||||
"confirmations.revoke_quote.confirm": "Retirer la publication",
|
"confirmations.revoke_quote.confirm": "Retirer le message",
|
||||||
"confirmations.revoke_quote.message": "Cette action ne peut pas être annulée.",
|
"confirmations.revoke_quote.message": "Cette action ne peut pas être annulée.",
|
||||||
"confirmations.revoke_quote.title": "Retirer la publication ?",
|
"confirmations.revoke_quote.title": "Retirer le message ?",
|
||||||
"confirmations.unblock.confirm": "Débloquer",
|
"confirmations.unblock.confirm": "Débloquer",
|
||||||
"confirmations.unblock.title": "Débloquer {name} ?",
|
"confirmations.unblock.title": "Débloquer {name} ?",
|
||||||
"confirmations.unfollow.confirm": "Ne plus suivre",
|
"confirmations.unfollow.confirm": "Ne plus suivre",
|
||||||
@@ -422,15 +439,15 @@
|
|||||||
"copy_icon_button.copied": "Copié dans le presse-papier",
|
"copy_icon_button.copied": "Copié dans le presse-papier",
|
||||||
"copypaste.copied": "Copié",
|
"copypaste.copied": "Copié",
|
||||||
"copypaste.copy_to_clipboard": "Copier dans le presse-papiers",
|
"copypaste.copy_to_clipboard": "Copier dans le presse-papiers",
|
||||||
"directory.federated": "Du fédiverse connu",
|
"directory.federated": "Du fédivers connu",
|
||||||
"directory.local": "De {domain} seulement",
|
"directory.local": "De {domain} seulement",
|
||||||
"directory.new_arrivals": "Inscrit·e·s récemment",
|
"directory.new_arrivals": "Inscrit·e·s récemment",
|
||||||
"directory.recently_active": "Actif·ve·s récemment",
|
"directory.recently_active": "Actif·ve·s récemment",
|
||||||
"disabled_account_banner.account_settings": "Paramètres du compte",
|
"disabled_account_banner.account_settings": "Paramètres du compte",
|
||||||
"disabled_account_banner.text": "Votre compte {disabledAccount} est actuellement désactivé.",
|
"disabled_account_banner.text": "Votre compte {disabledAccount} est actuellement désactivé.",
|
||||||
"dismissable_banner.community_timeline": "Voici les messages publics les plus récents des comptes hébergés par {domain}.",
|
"dismissable_banner.community_timeline": "Voici les messages publics les plus récents des comptes hébergés par {domain}.",
|
||||||
"dismissable_banner.dismiss": "Rejeter",
|
"dismissable_banner.dismiss": "Fermer",
|
||||||
"dismissable_banner.public_timeline": "Il s'agit des messages publics les plus récents publiés par des personnes sur le fediverse que les personnes sur {domain} suivent.",
|
"dismissable_banner.public_timeline": "Il s'agit des messages publics les plus récents publiés par des personnes sur le fédivers que les personnes sur {domain} suivent.",
|
||||||
"domain_block_modal.block": "Bloquer le serveur",
|
"domain_block_modal.block": "Bloquer le serveur",
|
||||||
"domain_block_modal.block_account_instead": "Bloquer @{name} à la place",
|
"domain_block_modal.block_account_instead": "Bloquer @{name} à la place",
|
||||||
"domain_block_modal.they_can_interact_with_old_posts": "Les personnes de ce serveur peuvent interagir avec vos anciens messages.",
|
"domain_block_modal.they_can_interact_with_old_posts": "Les personnes de ce serveur peuvent interagir avec vos anciens messages.",
|
||||||
@@ -444,17 +461,17 @@
|
|||||||
"domain_pill.activitypub_like_language": "ActivityPub est comme une langue que Mastodon utilise pour communiquer avec les autres réseaux sociaux.",
|
"domain_pill.activitypub_like_language": "ActivityPub est comme une langue que Mastodon utilise pour communiquer avec les autres réseaux sociaux.",
|
||||||
"domain_pill.server": "Serveur",
|
"domain_pill.server": "Serveur",
|
||||||
"domain_pill.their_handle": "Son identifiant :",
|
"domain_pill.their_handle": "Son identifiant :",
|
||||||
"domain_pill.their_server": "Son foyer numérique, là où tous ses posts résident.",
|
"domain_pill.their_server": "Son foyer numérique, là où tous ses messages résident.",
|
||||||
"domain_pill.their_username": "Son identifiant unique sur leur serveur. Il est possible de rencontrer des utilisateur·rice·s avec le même nom sur différents serveurs.",
|
"domain_pill.their_username": "Son identifiant unique sur leur serveur. Il est possible de rencontrer des utilisateur·rice·s avec le même nom sur différents serveurs.",
|
||||||
"domain_pill.username": "Nom d’utilisateur",
|
"domain_pill.username": "Nom d’utilisateur·rice",
|
||||||
"domain_pill.whats_in_a_handle": "Qu'est-ce qu'un identifiant ?",
|
"domain_pill.whats_in_a_handle": "Qu'est-ce qu'un identifiant ?",
|
||||||
"domain_pill.who_they_are": "Comme un identifiant contient le nom et le service hébergeant une personne, vous pouvez interagir sur <button>les plateformes sociales implémentant ActivityPub</button>.",
|
"domain_pill.who_they_are": "Comme un identifiant contient le nom et le service hébergeant une personne, vous pouvez interagir sur <button>les plateformes sociales implémentant ActivityPub</button>.",
|
||||||
"domain_pill.who_you_are": "Comme un identifiant indique votre nom et le service vous hébergeant, vous pouvez interagir avec <button>les autres plateformes sociales implémentant ActivityPub</button>.",
|
"domain_pill.who_you_are": "Comme un identifiant indique votre nom et le service vous hébergeant, tout le monde peut interagir avec vous à l'aide de <button>plateformes sociales implémentant ActivityPub</button>.",
|
||||||
"domain_pill.your_handle": "Votre identifiant :",
|
"domain_pill.your_handle": "Votre identifiant :",
|
||||||
"domain_pill.your_server": "Votre foyer numérique, là où vos messages résident. Vous souhaitez changer ? Lancez un transfert vers un autre serveur quand vous le voulez et vos abonné·e·s suivront automatiquement.",
|
"domain_pill.your_server": "Votre foyer numérique, là où vos messages résident. Vous souhaitez changer ? Lancez un transfert vers un autre serveur quand vous le voulez et vos abonné·e·s suivront automatiquement.",
|
||||||
"domain_pill.your_username": "Votre identifiant unique sur ce serveur. Il est possible de rencontrer des utilisateur·rice·s ayant le même nom d'utilisateur sur différents serveurs.",
|
"domain_pill.your_username": "Votre identifiant unique sur ce serveur. Il est possible de rencontrer des utilisateur·rice·s ayant le même nom d'utilisateur sur différents serveurs.",
|
||||||
"dropdown.empty": "Sélectionner une option",
|
"dropdown.empty": "Sélectionner une option",
|
||||||
"embed.instructions": "Intégrez ce message à votre site en copiant le code ci-dessous.",
|
"embed.instructions": "Intégrer ce message à votre site en copiant le code ci-dessous.",
|
||||||
"embed.preview": "Il apparaîtra comme cela :",
|
"embed.preview": "Il apparaîtra comme cela :",
|
||||||
"emoji_button.activity": "Activités",
|
"emoji_button.activity": "Activités",
|
||||||
"emoji_button.clear": "Effacer",
|
"emoji_button.clear": "Effacer",
|
||||||
@@ -1018,7 +1035,7 @@
|
|||||||
"server_banner.about_active_users": "Personnes utilisant ce serveur au cours des 30 derniers jours (Comptes actifs mensuellement)",
|
"server_banner.about_active_users": "Personnes utilisant ce serveur au cours des 30 derniers jours (Comptes actifs mensuellement)",
|
||||||
"server_banner.active_users": "comptes actifs",
|
"server_banner.active_users": "comptes actifs",
|
||||||
"server_banner.administered_by": "Administré par :",
|
"server_banner.administered_by": "Administré par :",
|
||||||
"server_banner.is_one_of_many": "{domain} est l'un des nombreux serveurs Mastodon indépendants que vous pouvez utiliser pour participer au fédiverse.",
|
"server_banner.is_one_of_many": "{domain} est l'un des nombreux serveurs Mastodon indépendants que vous pouvez utiliser pour participer au fédivers.",
|
||||||
"server_banner.server_stats": "Statistiques du serveur :",
|
"server_banner.server_stats": "Statistiques du serveur :",
|
||||||
"sign_in_banner.create_account": "Créer un compte",
|
"sign_in_banner.create_account": "Créer un compte",
|
||||||
"sign_in_banner.follow_anyone": "Suivez n'importe qui à travers le fédivers et affichez tout dans un ordre chronologique. Ni algorithmes, ni publicités, ni appâts à clics en perspective.",
|
"sign_in_banner.follow_anyone": "Suivez n'importe qui à travers le fédivers et affichez tout dans un ordre chronologique. Ni algorithmes, ni publicités, ni appâts à clics en perspective.",
|
||||||
@@ -1120,7 +1137,7 @@
|
|||||||
"status.unpin": "Retirer du profil",
|
"status.unpin": "Retirer du profil",
|
||||||
"subscribed_languages.lead": "Seuls les messages dans les langues sélectionnées apparaîtront sur votre fil principal et vos listes de fils après le changement. Sélectionnez aucune pour recevoir les messages dans toutes les langues.",
|
"subscribed_languages.lead": "Seuls les messages dans les langues sélectionnées apparaîtront sur votre fil principal et vos listes de fils après le changement. Sélectionnez aucune pour recevoir les messages dans toutes les langues.",
|
||||||
"subscribed_languages.save": "Enregistrer les modifications",
|
"subscribed_languages.save": "Enregistrer les modifications",
|
||||||
"subscribed_languages.target": "Changer les langues abonnées pour {target}",
|
"subscribed_languages.target": "Modifier les langues d'abonnements pour {target}",
|
||||||
"tabs_bar.home": "Accueil",
|
"tabs_bar.home": "Accueil",
|
||||||
"tabs_bar.menu": "Menu",
|
"tabs_bar.menu": "Menu",
|
||||||
"tabs_bar.notifications": "Notifications",
|
"tabs_bar.notifications": "Notifications",
|
||||||
|
|||||||
@@ -141,8 +141,25 @@
|
|||||||
"account.unmute": "Deixar de silenciar a @{name}",
|
"account.unmute": "Deixar de silenciar a @{name}",
|
||||||
"account.unmute_notifications_short": "Reactivar notificacións",
|
"account.unmute_notifications_short": "Reactivar notificacións",
|
||||||
"account.unmute_short": "Non silenciar",
|
"account.unmute_short": "Non silenciar",
|
||||||
|
"account_edit.bio.placeholder": "Escribe unha breve presentación para que te coñezan mellor.",
|
||||||
|
"account_edit.bio.title": "Sobre ti",
|
||||||
|
"account_edit.bio_modal.add_title": "Engadir biografía",
|
||||||
|
"account_edit.bio_modal.edit_title": "Editar biografía",
|
||||||
|
"account_edit.char_counter": "{currentLength}/{maxLength} caracteres",
|
||||||
"account_edit.column_button": "Feito",
|
"account_edit.column_button": "Feito",
|
||||||
"account_edit.column_title": "Editar perfil",
|
"account_edit.column_title": "Editar perfil",
|
||||||
|
"account_edit.custom_fields.placeholder": "Engade os teus pronomes, ligazóns externas, ou o que queiras compartir.",
|
||||||
|
"account_edit.custom_fields.title": "Campos personalizados",
|
||||||
|
"account_edit.display_name.placeholder": "O nome público é o nome que aparece no perfil e nas cronoloxías.",
|
||||||
|
"account_edit.display_name.title": "Nome público",
|
||||||
|
"account_edit.featured_hashtags.placeholder": "Facilita que te identifiquen, e da acceso rápido aos teus intereses favoritos.",
|
||||||
|
"account_edit.featured_hashtags.title": "Cancelos destacados",
|
||||||
|
"account_edit.name_modal.add_title": "Engadir nome público",
|
||||||
|
"account_edit.name_modal.edit_title": "Editar o nome público",
|
||||||
|
"account_edit.profile_tab.subtitle": "Personaliza as pestanas e o seu contido no teu perfil.",
|
||||||
|
"account_edit.profile_tab.title": "Perfil e axustes das pestanas",
|
||||||
|
"account_edit.save": "Gardar",
|
||||||
|
"account_edit.section_edit_button": "Editar",
|
||||||
"account_note.placeholder": "Preme para engadir nota",
|
"account_note.placeholder": "Preme para engadir nota",
|
||||||
"admin.dashboard.daily_retention": "Ratio de retención de usuarias diaria após rexistrarse",
|
"admin.dashboard.daily_retention": "Ratio de retención de usuarias diaria após rexistrarse",
|
||||||
"admin.dashboard.monthly_retention": "Ratio de retención de usuarias mensual após o rexistro",
|
"admin.dashboard.monthly_retention": "Ratio de retención de usuarias mensual após o rexistro",
|
||||||
@@ -267,6 +284,7 @@
|
|||||||
"collections.detail.curated_by_you": "Seleccionadas por ti",
|
"collections.detail.curated_by_you": "Seleccionadas por ti",
|
||||||
"collections.detail.loading": "Cargando colección…",
|
"collections.detail.loading": "Cargando colección…",
|
||||||
"collections.detail.share": "Compartir esta colección",
|
"collections.detail.share": "Compartir esta colección",
|
||||||
|
"collections.edit_details": "Editar detalles",
|
||||||
"collections.error_loading_collections": "Houbo un erro ao intentar cargar as túas coleccións.",
|
"collections.error_loading_collections": "Houbo un erro ao intentar cargar as túas coleccións.",
|
||||||
"collections.hints.accounts_counter": "{count} / {max} contas",
|
"collections.hints.accounts_counter": "{count} / {max} contas",
|
||||||
"collections.hints.add_more_accounts": "Engade polo menos {count, plural, one {# conta} other {# contas}} para continuar",
|
"collections.hints.add_more_accounts": "Engade polo menos {count, plural, one {# conta} other {# contas}} para continuar",
|
||||||
@@ -275,11 +293,14 @@
|
|||||||
"collections.manage_accounts": "Xestionar contas",
|
"collections.manage_accounts": "Xestionar contas",
|
||||||
"collections.mark_as_sensitive": "Marcar como sensible",
|
"collections.mark_as_sensitive": "Marcar como sensible",
|
||||||
"collections.mark_as_sensitive_hint": "Oculta a descrición e contas da colección detrás dun aviso sobre o contido. O nome da colección permanece visible.",
|
"collections.mark_as_sensitive_hint": "Oculta a descrición e contas da colección detrás dun aviso sobre o contido. O nome da colección permanece visible.",
|
||||||
|
"collections.name_length_hint": "Límite de 40 caracteres",
|
||||||
"collections.new_collection": "Nova colección",
|
"collections.new_collection": "Nova colección",
|
||||||
"collections.no_collections_yet": "Aínda non tes coleccións.",
|
"collections.no_collections_yet": "Aínda non tes coleccións.",
|
||||||
|
"collections.old_last_post_note": "Hai máis dunha semana da última publicación",
|
||||||
"collections.remove_account": "Retirar esta conta",
|
"collections.remove_account": "Retirar esta conta",
|
||||||
"collections.search_accounts_label": "Buscar contas para engadir…",
|
"collections.search_accounts_label": "Buscar contas para engadir…",
|
||||||
"collections.search_accounts_max_reached": "Acadaches o máximo de contas permitidas",
|
"collections.search_accounts_max_reached": "Acadaches o máximo de contas permitidas",
|
||||||
|
"collections.sensitive": "Sensible",
|
||||||
"collections.topic_hint": "Engadir un cancelo para que axudar a que outras persoas coñezan a temática desta colección.",
|
"collections.topic_hint": "Engadir un cancelo para que axudar a que outras persoas coñezan a temática desta colección.",
|
||||||
"collections.view_collection": "Ver colección",
|
"collections.view_collection": "Ver colección",
|
||||||
"collections.visibility_public": "Pública",
|
"collections.visibility_public": "Pública",
|
||||||
@@ -370,6 +391,9 @@
|
|||||||
"confirmations.discard_draft.post.title": "Desbotar o borrador?",
|
"confirmations.discard_draft.post.title": "Desbotar o borrador?",
|
||||||
"confirmations.discard_edit_media.confirm": "Descartar",
|
"confirmations.discard_edit_media.confirm": "Descartar",
|
||||||
"confirmations.discard_edit_media.message": "Tes cambios sen gardar para a vista previa ou descrición do multimedia, descartamos os cambios?",
|
"confirmations.discard_edit_media.message": "Tes cambios sen gardar para a vista previa ou descrición do multimedia, descartamos os cambios?",
|
||||||
|
"confirmations.follow_to_collection.confirm": "Seguir e engadir á colección",
|
||||||
|
"confirmations.follow_to_collection.message": "Tes que seguir a {name} para poder engadila a unha colección.",
|
||||||
|
"confirmations.follow_to_collection.title": "Seguir a conta?",
|
||||||
"confirmations.follow_to_list.confirm": "Seguir e engadir á lista",
|
"confirmations.follow_to_list.confirm": "Seguir e engadir á lista",
|
||||||
"confirmations.follow_to_list.message": "Tes que seguir a {name} para poder engadila a unha lista.",
|
"confirmations.follow_to_list.message": "Tes que seguir a {name} para poder engadila a unha lista.",
|
||||||
"confirmations.follow_to_list.title": "Seguir á usuaria?",
|
"confirmations.follow_to_list.title": "Seguir á usuaria?",
|
||||||
|
|||||||
@@ -141,8 +141,25 @@
|
|||||||
"account.unmute": "הפסקת השתקת @{name}",
|
"account.unmute": "הפסקת השתקת @{name}",
|
||||||
"account.unmute_notifications_short": "הפעלת הודעות",
|
"account.unmute_notifications_short": "הפעלת הודעות",
|
||||||
"account.unmute_short": "ביטול השתקה",
|
"account.unmute_short": "ביטול השתקה",
|
||||||
|
"account_edit.bio.placeholder": "הוסיפו הצגה קצרה כדי לעזור לאחרים לזהות אותך.",
|
||||||
|
"account_edit.bio.title": "ביוגרפיה",
|
||||||
|
"account_edit.bio_modal.add_title": "הוסיפו ביוגרפיה",
|
||||||
|
"account_edit.bio_modal.edit_title": "עריכת ביוגרפיה",
|
||||||
|
"account_edit.char_counter": "{currentLength}/{maxLength} תווים",
|
||||||
"account_edit.column_button": "סיום",
|
"account_edit.column_button": "סיום",
|
||||||
"account_edit.column_title": "עריכת הפרופיל",
|
"account_edit.column_title": "עריכת הפרופיל",
|
||||||
|
"account_edit.custom_fields.placeholder": "הוסיפו צורת פניה, קישורים חיצוניים וכל דבר שתרצו לשתף.",
|
||||||
|
"account_edit.custom_fields.title": "שדות בהתאמה אישית",
|
||||||
|
"account_edit.display_name.placeholder": "שם התצוגה שלכן הוא איך שהשם יופיע בפרופיל ובצירי הזמנים.",
|
||||||
|
"account_edit.display_name.title": "שם תצוגה",
|
||||||
|
"account_edit.featured_hashtags.placeholder": "עזרו לאחרים לזהות ולגשת בקלות לנושאים החביבים עליכם.",
|
||||||
|
"account_edit.featured_hashtags.title": "תגיות נבחרות",
|
||||||
|
"account_edit.name_modal.add_title": "הוספת שם תצוגה",
|
||||||
|
"account_edit.name_modal.edit_title": "עריכת שם תצוגה",
|
||||||
|
"account_edit.profile_tab.subtitle": "התאימו את הטאבים בפרופיל שלכם ומה שהם יציגו.",
|
||||||
|
"account_edit.profile_tab.title": "הגדרות טאבים לפרופיל",
|
||||||
|
"account_edit.save": "שמירה",
|
||||||
|
"account_edit.section_edit_button": "עריכה",
|
||||||
"account_note.placeholder": "יש ללחוץ כדי להוסיף הערות",
|
"account_note.placeholder": "יש ללחוץ כדי להוסיף הערות",
|
||||||
"admin.dashboard.daily_retention": "קצב שימור משתמשים יומי אחרי ההרשמה",
|
"admin.dashboard.daily_retention": "קצב שימור משתמשים יומי אחרי ההרשמה",
|
||||||
"admin.dashboard.monthly_retention": "קצב שימור משתמשים (פר חודש) אחרי ההרשמה",
|
"admin.dashboard.monthly_retention": "קצב שימור משתמשים (פר חודש) אחרי ההרשמה",
|
||||||
@@ -267,6 +284,7 @@
|
|||||||
"collections.detail.curated_by_you": "נאצר על ידיך",
|
"collections.detail.curated_by_you": "נאצר על ידיך",
|
||||||
"collections.detail.loading": "טוען אוסף…",
|
"collections.detail.loading": "טוען אוסף…",
|
||||||
"collections.detail.share": "שיתוף אוסף",
|
"collections.detail.share": "שיתוף אוסף",
|
||||||
|
"collections.edit_details": "עריכת פרטים",
|
||||||
"collections.error_loading_collections": "חלה שגיאה בנסיון לטעון את אוספיך.",
|
"collections.error_loading_collections": "חלה שגיאה בנסיון לטעון את אוספיך.",
|
||||||
"collections.hints.accounts_counter": "{count} \\ {max} חשבונות",
|
"collections.hints.accounts_counter": "{count} \\ {max} חשבונות",
|
||||||
"collections.hints.add_more_accounts": "הוסיפו לפחות {count, plural,one {חשבון אחד}other {# חשבונות}} כדי להמשיך",
|
"collections.hints.add_more_accounts": "הוסיפו לפחות {count, plural,one {חשבון אחד}other {# חשבונות}} כדי להמשיך",
|
||||||
@@ -275,11 +293,14 @@
|
|||||||
"collections.manage_accounts": "ניהול חשבונות",
|
"collections.manage_accounts": "ניהול חשבונות",
|
||||||
"collections.mark_as_sensitive": "מסומנים כרגישים",
|
"collections.mark_as_sensitive": "מסומנים כרגישים",
|
||||||
"collections.mark_as_sensitive_hint": "הסתרת תיאור וחשבונות האוסף מאחורי אזהרת תוכן. שם האוסף עדיין ישאר גלוי.",
|
"collections.mark_as_sensitive_hint": "הסתרת תיאור וחשבונות האוסף מאחורי אזהרת תוכן. שם האוסף עדיין ישאר גלוי.",
|
||||||
|
"collections.name_length_hint": "מגבלה של 40 תווים",
|
||||||
"collections.new_collection": "אוסף חדש",
|
"collections.new_collection": "אוסף חדש",
|
||||||
"collections.no_collections_yet": "עוד אין אוספים.",
|
"collections.no_collections_yet": "עוד אין אוספים.",
|
||||||
|
"collections.old_last_post_note": "פרסמו לאחרונה לפני יותר משבוע",
|
||||||
"collections.remove_account": "הסר חשבון זה",
|
"collections.remove_account": "הסר חשבון זה",
|
||||||
"collections.search_accounts_label": "לחפש חשבונות להוספה…",
|
"collections.search_accounts_label": "לחפש חשבונות להוספה…",
|
||||||
"collections.search_accounts_max_reached": "הגעת למספר החשבונות המירבי",
|
"collections.search_accounts_max_reached": "הגעת למספר החשבונות המירבי",
|
||||||
|
"collections.sensitive": "רגיש",
|
||||||
"collections.topic_hint": "הוספת תגית שמסייעת לאחרים להבין את הנושא הראשי של האוסף.",
|
"collections.topic_hint": "הוספת תגית שמסייעת לאחרים להבין את הנושא הראשי של האוסף.",
|
||||||
"collections.view_collection": "צפיה באוסף",
|
"collections.view_collection": "צפיה באוסף",
|
||||||
"collections.visibility_public": "פומבי",
|
"collections.visibility_public": "פומבי",
|
||||||
@@ -370,6 +391,9 @@
|
|||||||
"confirmations.discard_draft.post.title": "לוותר על הטיוטא?",
|
"confirmations.discard_draft.post.title": "לוותר על הטיוטא?",
|
||||||
"confirmations.discard_edit_media.confirm": "השלך",
|
"confirmations.discard_edit_media.confirm": "השלך",
|
||||||
"confirmations.discard_edit_media.message": "יש לך שינויים לא שמורים לתיאור המדיה. להשליך אותם בכל זאת?",
|
"confirmations.discard_edit_media.message": "יש לך שינויים לא שמורים לתיאור המדיה. להשליך אותם בכל זאת?",
|
||||||
|
"confirmations.follow_to_collection.confirm": "עקיבה והוספה לאוסף",
|
||||||
|
"confirmations.follow_to_collection.message": "כדי להכניס את {name} לאוסף, ראשית יש לעקוב אחריהם.",
|
||||||
|
"confirmations.follow_to_collection.title": "לעקוב אחר החשבון?",
|
||||||
"confirmations.follow_to_list.confirm": "עקיבה והוספה לרשימה",
|
"confirmations.follow_to_list.confirm": "עקיבה והוספה לרשימה",
|
||||||
"confirmations.follow_to_list.message": "כדי להכניס את {name} לרשימה, ראשית יש לעקוב אחריהם.",
|
"confirmations.follow_to_list.message": "כדי להכניס את {name} לרשימה, ראשית יש לעקוב אחריהם.",
|
||||||
"confirmations.follow_to_list.title": "לעקוב אחר המשתמש.ת?",
|
"confirmations.follow_to_list.title": "לעקוב אחר המשתמש.ת?",
|
||||||
|
|||||||
@@ -8,10 +8,13 @@
|
|||||||
"about.domain_blocks.silenced.title": "Ograničen",
|
"about.domain_blocks.silenced.title": "Ograničen",
|
||||||
"about.domain_blocks.suspended.explanation": "Podatci s ovog poslužitelja neće se obrađivati, pohranjivati ili razmjenjivati, što onemogućuje bilo kakvu interakciju ili komunikaciju s korisnicima s ovog poslužitelja.",
|
"about.domain_blocks.suspended.explanation": "Podatci s ovog poslužitelja neće se obrađivati, pohranjivati ili razmjenjivati, što onemogućuje bilo kakvu interakciju ili komunikaciju s korisnicima s ovog poslužitelja.",
|
||||||
"about.domain_blocks.suspended.title": "Suspendiran",
|
"about.domain_blocks.suspended.title": "Suspendiran",
|
||||||
|
"about.language_label": "Jezik",
|
||||||
"about.not_available": "Te informacije nisu dostupne na ovom poslužitelju.",
|
"about.not_available": "Te informacije nisu dostupne na ovom poslužitelju.",
|
||||||
"about.powered_by": "Decentralizirani društveni mediji koje pokreće {mastodon}",
|
"about.powered_by": "Decentralizirani društveni mediji koje pokreće {mastodon}",
|
||||||
"about.rules": "Pravila servera",
|
"about.rules": "Pravila servera",
|
||||||
|
"account.activity": "Aktivnost",
|
||||||
"account.add_or_remove_from_list": "Dodaj ili ukloni s liste",
|
"account.add_or_remove_from_list": "Dodaj ili ukloni s liste",
|
||||||
|
"account.badges.admin": "Admin",
|
||||||
"account.badges.bot": "Bot",
|
"account.badges.bot": "Bot",
|
||||||
"account.badges.group": "Grupa",
|
"account.badges.group": "Grupa",
|
||||||
"account.block": "Blokiraj @{name}",
|
"account.block": "Blokiraj @{name}",
|
||||||
@@ -23,12 +26,16 @@
|
|||||||
"account.direct": "Privatno spomeni @{name}",
|
"account.direct": "Privatno spomeni @{name}",
|
||||||
"account.disable_notifications": "Nemoj me obavjestiti kada @{name} napravi objavu",
|
"account.disable_notifications": "Nemoj me obavjestiti kada @{name} napravi objavu",
|
||||||
"account.edit_profile": "Uredi profil",
|
"account.edit_profile": "Uredi profil",
|
||||||
|
"account.edit_profile_short": "Uredi",
|
||||||
"account.enable_notifications": "Obavjesti me kada @{name} napravi objavu",
|
"account.enable_notifications": "Obavjesti me kada @{name} napravi objavu",
|
||||||
"account.endorse": "Istakni na profilu",
|
"account.endorse": "Istakni na profilu",
|
||||||
"account.featured_tags.last_status_at": "Zadnji post {date}",
|
"account.featured_tags.last_status_at": "Zadnji post {date}",
|
||||||
"account.featured_tags.last_status_never": "Nema postova",
|
"account.featured_tags.last_status_never": "Nema postova",
|
||||||
"account.follow": "Prati",
|
"account.follow": "Prati",
|
||||||
"account.follow_back": "Slijedi natrag",
|
"account.follow_back": "Slijedi natrag",
|
||||||
|
"account.follow_request_cancel": "Poništi zahtjev",
|
||||||
|
"account.follow_request_cancel_short": "Odustani",
|
||||||
|
"account.follow_request_short": "Zatraži",
|
||||||
"account.followers": "Pratitelji",
|
"account.followers": "Pratitelji",
|
||||||
"account.followers.empty": "Nitko još ne prati korisnika/cu.",
|
"account.followers.empty": "Nitko još ne prati korisnika/cu.",
|
||||||
"account.following": "Pratim",
|
"account.following": "Pratim",
|
||||||
@@ -42,11 +49,19 @@
|
|||||||
"account.locked_info": "Status privatnosti ovog računa postavljen je na zaključano. Vlasnik ručno pregledava tko ih može pratiti.",
|
"account.locked_info": "Status privatnosti ovog računa postavljen je na zaključano. Vlasnik ručno pregledava tko ih može pratiti.",
|
||||||
"account.media": "Medijski sadržaj",
|
"account.media": "Medijski sadržaj",
|
||||||
"account.mention": "Spomeni @{name}",
|
"account.mention": "Spomeni @{name}",
|
||||||
|
"account.menu.block": "Blokiraj račun",
|
||||||
|
"account.menu.block_domain": "Blokiraj {domain}",
|
||||||
|
"account.menu.copy": "Kopiraj poveznicu",
|
||||||
|
"account.menu.mention": "Spomeni",
|
||||||
|
"account.menu.remove_follower": "Ukloni pratitelja",
|
||||||
|
"account.menu.report": "Prijavi račun",
|
||||||
"account.mute": "Utišaj @{name}",
|
"account.mute": "Utišaj @{name}",
|
||||||
"account.mute_notifications_short": "Utišaj obavijesti",
|
"account.mute_notifications_short": "Utišaj obavijesti",
|
||||||
"account.mute_short": "Utišaj",
|
"account.mute_short": "Utišaj",
|
||||||
"account.muted": "Utišano",
|
"account.muted": "Utišano",
|
||||||
"account.no_bio": "Nije dan opis.",
|
"account.no_bio": "Nije dan opis.",
|
||||||
|
"account.node_modal.save": "Spremi",
|
||||||
|
"account.note.edit_button": "Uredi",
|
||||||
"account.open_original_page": "Otvori originalnu stranicu",
|
"account.open_original_page": "Otvori originalnu stranicu",
|
||||||
"account.posts": "Objave",
|
"account.posts": "Objave",
|
||||||
"account.posts_with_replies": "Objave i odgovori",
|
"account.posts_with_replies": "Objave i odgovori",
|
||||||
@@ -62,6 +77,17 @@
|
|||||||
"account.unmute": "Poništi utišavanje @{name}",
|
"account.unmute": "Poništi utišavanje @{name}",
|
||||||
"account.unmute_notifications_short": "Uključi utišane obavijesti",
|
"account.unmute_notifications_short": "Uključi utišane obavijesti",
|
||||||
"account.unmute_short": "Poništi utišavanje",
|
"account.unmute_short": "Poništi utišavanje",
|
||||||
|
"account_edit.bio.title": "Biografija",
|
||||||
|
"account_edit.bio_modal.add_title": "Dodaj biografiju",
|
||||||
|
"account_edit.bio_modal.edit_title": "Uredi biografiju",
|
||||||
|
"account_edit.char_counter": "{currentLength}/{maxLength} znakova",
|
||||||
|
"account_edit.column_button": "Završi",
|
||||||
|
"account_edit.column_title": "Uredi profil",
|
||||||
|
"account_edit.custom_fields.title": "Prilagođena polja",
|
||||||
|
"account_edit.featured_hashtags.title": "Istaknuti hashtagovi",
|
||||||
|
"account_edit.profile_tab.title": "Prikaz kartice profila",
|
||||||
|
"account_edit.save": "Spremi",
|
||||||
|
"account_edit.section_edit_button": "Uredi",
|
||||||
"account_note.placeholder": "Kliknite za dodavanje bilješke",
|
"account_note.placeholder": "Kliknite za dodavanje bilješke",
|
||||||
"admin.dashboard.daily_retention": "Stopa zadržavanja korisnika po danu nakon prijave",
|
"admin.dashboard.daily_retention": "Stopa zadržavanja korisnika po danu nakon prijave",
|
||||||
"admin.dashboard.monthly_retention": "Stopa zadržavanja korisnika po mjesecu nakon prijave",
|
"admin.dashboard.monthly_retention": "Stopa zadržavanja korisnika po mjesecu nakon prijave",
|
||||||
@@ -76,7 +102,15 @@
|
|||||||
"alert.rate_limited.title": "Ograničenje učestalosti",
|
"alert.rate_limited.title": "Ograničenje učestalosti",
|
||||||
"alert.unexpected.message": "Dogodila se neočekivana greška.",
|
"alert.unexpected.message": "Dogodila se neočekivana greška.",
|
||||||
"alert.unexpected.title": "Ups!",
|
"alert.unexpected.title": "Ups!",
|
||||||
|
"alt_text_badge.title": "Alternativni tekst",
|
||||||
|
"alt_text_modal.add_alt_text": "Dodaj altenativni tekst",
|
||||||
|
"alt_text_modal.add_text_from_image": "Dodaj tekst iz slike",
|
||||||
|
"alt_text_modal.cancel": "Odustani",
|
||||||
|
"alt_text_modal.done": "Gotovo",
|
||||||
"announcement.announcement": "Najava",
|
"announcement.announcement": "Najava",
|
||||||
|
"annual_report.announcement.action_dismiss": "Ne hvala",
|
||||||
|
"annual_report.nav_item.badge": "Novi",
|
||||||
|
"annual_report.shared_page.donate": "Doniraj",
|
||||||
"attachments_list.unprocessed": "(neobrađeno)",
|
"attachments_list.unprocessed": "(neobrađeno)",
|
||||||
"audio.hide": "Sakrij audio",
|
"audio.hide": "Sakrij audio",
|
||||||
"boost_modal.combo": "Možete pritisnuti {combo} kako biste preskočili ovo sljedeći put",
|
"boost_modal.combo": "Možete pritisnuti {combo} kako biste preskočili ovo sljedeći put",
|
||||||
|
|||||||
@@ -296,6 +296,7 @@
|
|||||||
"collections.name_length_hint": "40 stafa takmörk",
|
"collections.name_length_hint": "40 stafa takmörk",
|
||||||
"collections.new_collection": "Nýtt safn",
|
"collections.new_collection": "Nýtt safn",
|
||||||
"collections.no_collections_yet": "Engin söfn ennþá.",
|
"collections.no_collections_yet": "Engin söfn ennþá.",
|
||||||
|
"collections.old_last_post_note": "Birti síðast fyrir meira en viku síðan",
|
||||||
"collections.remove_account": "Fjarlægja þennan aðgang",
|
"collections.remove_account": "Fjarlægja þennan aðgang",
|
||||||
"collections.search_accounts_label": "Leita að aðgöngum til að bæta við…",
|
"collections.search_accounts_label": "Leita að aðgöngum til að bæta við…",
|
||||||
"collections.search_accounts_max_reached": "Þú hefur þegar bætt við leyfilegum hámarksfjölda aðganga",
|
"collections.search_accounts_max_reached": "Þú hefur þegar bætt við leyfilegum hámarksfjölda aðganga",
|
||||||
@@ -390,6 +391,9 @@
|
|||||||
"confirmations.discard_draft.post.title": "Henda drögum að færslunni þinni?",
|
"confirmations.discard_draft.post.title": "Henda drögum að færslunni þinni?",
|
||||||
"confirmations.discard_edit_media.confirm": "Henda",
|
"confirmations.discard_edit_media.confirm": "Henda",
|
||||||
"confirmations.discard_edit_media.message": "Þú ert með óvistaðar breytingar á lýsingu myndefnis eða forskoðunar, henda þeim samt?",
|
"confirmations.discard_edit_media.message": "Þú ert með óvistaðar breytingar á lýsingu myndefnis eða forskoðunar, henda þeim samt?",
|
||||||
|
"confirmations.follow_to_collection.confirm": "Fylgjast með og bæta í safn",
|
||||||
|
"confirmations.follow_to_collection.message": "Þú þarft að fylgjast með {name} til að geta bætt viðkomandi í safn.",
|
||||||
|
"confirmations.follow_to_collection.title": "Fylgjast með notandaaðgangnum?",
|
||||||
"confirmations.follow_to_list.confirm": "Fylgjast með og bæta á lista",
|
"confirmations.follow_to_list.confirm": "Fylgjast með og bæta á lista",
|
||||||
"confirmations.follow_to_list.message": "Þú þarft að fylgjast með {name} til að bæta viðkomandi á lista.",
|
"confirmations.follow_to_list.message": "Þú þarft að fylgjast með {name} til að bæta viðkomandi á lista.",
|
||||||
"confirmations.follow_to_list.title": "Fylgjast með notanda?",
|
"confirmations.follow_to_list.title": "Fylgjast með notanda?",
|
||||||
|
|||||||
@@ -296,6 +296,7 @@
|
|||||||
"collections.name_length_hint": "Limite di 40 caratteri",
|
"collections.name_length_hint": "Limite di 40 caratteri",
|
||||||
"collections.new_collection": "Nuova collezione",
|
"collections.new_collection": "Nuova collezione",
|
||||||
"collections.no_collections_yet": "Nessuna collezione ancora.",
|
"collections.no_collections_yet": "Nessuna collezione ancora.",
|
||||||
|
"collections.old_last_post_note": "Ultimo post più di una settimana fa",
|
||||||
"collections.remove_account": "Rimuovi questo account",
|
"collections.remove_account": "Rimuovi questo account",
|
||||||
"collections.search_accounts_label": "Cerca account da aggiungere…",
|
"collections.search_accounts_label": "Cerca account da aggiungere…",
|
||||||
"collections.search_accounts_max_reached": "Hai aggiunto il numero massimo di account",
|
"collections.search_accounts_max_reached": "Hai aggiunto il numero massimo di account",
|
||||||
@@ -390,6 +391,9 @@
|
|||||||
"confirmations.discard_draft.post.title": "Scartare la tua bozza del post?",
|
"confirmations.discard_draft.post.title": "Scartare la tua bozza del post?",
|
||||||
"confirmations.discard_edit_media.confirm": "Scarta",
|
"confirmations.discard_edit_media.confirm": "Scarta",
|
||||||
"confirmations.discard_edit_media.message": "Hai delle modifiche non salvate alla descrizione o anteprima del media, scartarle comunque?",
|
"confirmations.discard_edit_media.message": "Hai delle modifiche non salvate alla descrizione o anteprima del media, scartarle comunque?",
|
||||||
|
"confirmations.follow_to_collection.confirm": "Segui e aggiungi alla collezione",
|
||||||
|
"confirmations.follow_to_collection.message": "Devi seguire {name} per aggiungerlo/a ad una collezione.",
|
||||||
|
"confirmations.follow_to_collection.title": "Seguire l'account?",
|
||||||
"confirmations.follow_to_list.confirm": "Segui e aggiungi alla lista",
|
"confirmations.follow_to_list.confirm": "Segui e aggiungi alla lista",
|
||||||
"confirmations.follow_to_list.message": "Devi seguire {name} per aggiungerli a una lista.",
|
"confirmations.follow_to_list.message": "Devi seguire {name} per aggiungerli a una lista.",
|
||||||
"confirmations.follow_to_list.title": "Seguire l'utente?",
|
"confirmations.follow_to_list.title": "Seguire l'utente?",
|
||||||
|
|||||||
@@ -141,6 +141,25 @@
|
|||||||
"account.unmute": "取消消音 @{name}",
|
"account.unmute": "取消消音 @{name}",
|
||||||
"account.unmute_notifications_short": "Kā通知取消消音",
|
"account.unmute_notifications_short": "Kā通知取消消音",
|
||||||
"account.unmute_short": "取消消音",
|
"account.unmute_short": "取消消音",
|
||||||
|
"account_edit.bio.placeholder": "加一段短紹介,幫tsān別lâng認捌lí。",
|
||||||
|
"account_edit.bio.title": "個人紹介",
|
||||||
|
"account_edit.bio_modal.add_title": "加添個人紹介",
|
||||||
|
"account_edit.bio_modal.edit_title": "編個人紹介",
|
||||||
|
"account_edit.char_counter": "{currentLength}/{maxLength} ê字",
|
||||||
|
"account_edit.column_button": "做好ah",
|
||||||
|
"account_edit.column_title": "編輯個人資料",
|
||||||
|
"account_edit.custom_fields.placeholder": "加lí ê代名詞、外部連結,á是其他lí beh分享ê。",
|
||||||
|
"account_edit.custom_fields.title": "自訂欄",
|
||||||
|
"account_edit.display_name.placeholder": "Lí ê顯示ê名是lí ê名佇lí ê個人資料kap時間線出現ê方式。",
|
||||||
|
"account_edit.display_name.title": "顯示ê名",
|
||||||
|
"account_edit.featured_hashtags.placeholder": "幫tsān別lâng認捌,kap緊緊接近使用lí收藏ê主題。",
|
||||||
|
"account_edit.featured_hashtags.title": "特色ê hashtag",
|
||||||
|
"account_edit.name_modal.add_title": "加添顯示ê名",
|
||||||
|
"account_edit.name_modal.edit_title": "編顯示ê名",
|
||||||
|
"account_edit.profile_tab.subtitle": "自訂lí ê個人資料ê分頁kap顯示ê內容。",
|
||||||
|
"account_edit.profile_tab.title": "個人資料分頁設定",
|
||||||
|
"account_edit.save": "儲存",
|
||||||
|
"account_edit.section_edit_button": "編輯",
|
||||||
"account_note.placeholder": "Tshi̍h tse加註kha",
|
"account_note.placeholder": "Tshi̍h tse加註kha",
|
||||||
"admin.dashboard.daily_retention": "註冊以後ê用者維持率(用kang計算)",
|
"admin.dashboard.daily_retention": "註冊以後ê用者維持率(用kang計算)",
|
||||||
"admin.dashboard.monthly_retention": "註冊以後ê用者維持率",
|
"admin.dashboard.monthly_retention": "註冊以後ê用者維持率",
|
||||||
@@ -244,9 +263,12 @@
|
|||||||
"closed_registrations_modal.preamble": "因為Mastodon非中心化,所以bô論tī tá tsi̍t ê服侍器建立口座,lí lóng ē當跟tuè tsi̍t ê服侍器ê逐ê lâng,kap hām in交流。Lí iā ē當ka-tī起tsi̍t ê站!",
|
"closed_registrations_modal.preamble": "因為Mastodon非中心化,所以bô論tī tá tsi̍t ê服侍器建立口座,lí lóng ē當跟tuè tsi̍t ê服侍器ê逐ê lâng,kap hām in交流。Lí iā ē當ka-tī起tsi̍t ê站!",
|
||||||
"closed_registrations_modal.title": "註冊 Mastodon ê口座",
|
"closed_registrations_modal.title": "註冊 Mastodon ê口座",
|
||||||
"collections.account_count": "{count, plural, other {# ê口座}}",
|
"collections.account_count": "{count, plural, other {# ê口座}}",
|
||||||
|
"collections.accounts.empty_description": "加lí跟tuè ê口座,上tsē {count} ê",
|
||||||
|
"collections.accounts.empty_title": "收藏內底無半項",
|
||||||
"collections.collection_description": "說明",
|
"collections.collection_description": "說明",
|
||||||
"collections.collection_name": "名",
|
"collections.collection_name": "名",
|
||||||
"collections.collection_topic": "主題",
|
"collections.collection_topic": "主題",
|
||||||
|
"collections.confirm_account_removal": "Lí確定beh對收藏suá掉tsit ê口座?",
|
||||||
"collections.content_warning": "內容警告",
|
"collections.content_warning": "內容警告",
|
||||||
"collections.continue": "繼續",
|
"collections.continue": "繼續",
|
||||||
"collections.create.accounts_subtitle": "Kan-ta通加lí所綴而且選擇加入探索ê。",
|
"collections.create.accounts_subtitle": "Kan-ta通加lí所綴而且選擇加入探索ê。",
|
||||||
@@ -257,13 +279,28 @@
|
|||||||
"collections.create_collection": "建立收藏",
|
"collections.create_collection": "建立收藏",
|
||||||
"collections.delete_collection": "Thâi掉收藏",
|
"collections.delete_collection": "Thâi掉收藏",
|
||||||
"collections.description_length_hint": "限制 100 字",
|
"collections.description_length_hint": "限制 100 字",
|
||||||
|
"collections.detail.accounts_heading": "口座",
|
||||||
|
"collections.detail.curated_by_author": "{author} 揀ê",
|
||||||
|
"collections.detail.curated_by_you": "Lí揀ê",
|
||||||
|
"collections.detail.loading": "載入收藏……",
|
||||||
|
"collections.detail.share": "分享tsit ê收藏",
|
||||||
|
"collections.edit_details": "編輯詳細",
|
||||||
"collections.error_loading_collections": "佇載入lí ê收藏ê時陣出tshê。",
|
"collections.error_loading_collections": "佇載入lí ê收藏ê時陣出tshê。",
|
||||||
|
"collections.hints.accounts_counter": "{count} / {max} ê口座",
|
||||||
|
"collections.hints.add_more_accounts": "加上無 {count, plural, other {# ê口座}}來繼續",
|
||||||
|
"collections.hints.can_not_remove_more_accounts": "收藏定著愛上無 {count, plural, other {# ê口座}}。Bē當suá掉koh較tsē口座。",
|
||||||
"collections.last_updated_at": "上尾更新tī:{date}",
|
"collections.last_updated_at": "上尾更新tī:{date}",
|
||||||
"collections.manage_accounts": "管理口座",
|
"collections.manage_accounts": "管理口座",
|
||||||
"collections.mark_as_sensitive": "標做敏感ê",
|
"collections.mark_as_sensitive": "標做敏感ê",
|
||||||
"collections.mark_as_sensitive_hint": "Kā收藏ê描述kap口座tshàng佇內容警告ê後壁。收藏ê名猶原會當看。",
|
"collections.mark_as_sensitive_hint": "Kā收藏ê描述kap口座tshàng佇內容警告ê後壁。收藏ê名猶原會當看。",
|
||||||
|
"collections.name_length_hint": "限制 40 字",
|
||||||
"collections.new_collection": "新ê收藏",
|
"collections.new_collection": "新ê收藏",
|
||||||
"collections.no_collections_yet": "Iáu無收藏。",
|
"collections.no_collections_yet": "Iáu無收藏。",
|
||||||
|
"collections.old_last_post_note": "頂改佇超過一禮拜進前PO文",
|
||||||
|
"collections.remove_account": "Suá掉tsit ê口座",
|
||||||
|
"collections.search_accounts_label": "Tshuē口座來加添……",
|
||||||
|
"collections.search_accounts_max_reached": "Lí已經加kàu口座數ê盡磅ah。",
|
||||||
|
"collections.sensitive": "敏感ê",
|
||||||
"collections.topic_hint": "加 hashtag,幫tsān別lâng了解tsit ê收藏ê主題。",
|
"collections.topic_hint": "加 hashtag,幫tsān別lâng了解tsit ê收藏ê主題。",
|
||||||
"collections.view_collection": "看收藏",
|
"collections.view_collection": "看收藏",
|
||||||
"collections.visibility_public": "公共ê",
|
"collections.visibility_public": "公共ê",
|
||||||
@@ -354,6 +391,9 @@
|
|||||||
"confirmations.discard_draft.post.title": "Kám beh棄sak lí PO文ê草稿?",
|
"confirmations.discard_draft.post.title": "Kám beh棄sak lí PO文ê草稿?",
|
||||||
"confirmations.discard_edit_media.confirm": "棄sak",
|
"confirmations.discard_edit_media.confirm": "棄sak",
|
||||||
"confirmations.discard_edit_media.message": "Lí佇媒體敘述á是先看māi ê所在有iáu buē儲存ê改變,kám beh kā in棄sak?",
|
"confirmations.discard_edit_media.message": "Lí佇媒體敘述á是先看māi ê所在有iáu buē儲存ê改變,kám beh kā in棄sak?",
|
||||||
|
"confirmations.follow_to_collection.confirm": "跟tuè,加入kàu收藏",
|
||||||
|
"confirmations.follow_to_collection.message": "Beh kā {name} 加添kàu收藏,lí tio̍h先跟tuè伊。",
|
||||||
|
"confirmations.follow_to_collection.title": "敢beh跟tuè口座?",
|
||||||
"confirmations.follow_to_list.confirm": "跟tuè,加入kàu列單",
|
"confirmations.follow_to_list.confirm": "跟tuè,加入kàu列單",
|
||||||
"confirmations.follow_to_list.message": "Beh kā {name} 加添kàu列單,lí tio̍h先跟tuè伊。",
|
"confirmations.follow_to_list.message": "Beh kā {name} 加添kàu列單,lí tio̍h先跟tuè伊。",
|
||||||
"confirmations.follow_to_list.title": "Kám beh跟tuè tsit ê用者?",
|
"confirmations.follow_to_list.title": "Kám beh跟tuè tsit ê用者?",
|
||||||
|
|||||||
@@ -141,8 +141,25 @@
|
|||||||
"account.unmute": "@{name} niet langer negeren",
|
"account.unmute": "@{name} niet langer negeren",
|
||||||
"account.unmute_notifications_short": "Meldingen niet langer negeren",
|
"account.unmute_notifications_short": "Meldingen niet langer negeren",
|
||||||
"account.unmute_short": "Niet langer negeren",
|
"account.unmute_short": "Niet langer negeren",
|
||||||
|
"account_edit.bio.placeholder": "Voeg een korte introductie toe om anderen te helpen je te identificeren.",
|
||||||
|
"account_edit.bio.title": "Biografie",
|
||||||
|
"account_edit.bio_modal.add_title": "Biografie toevoegen",
|
||||||
|
"account_edit.bio_modal.edit_title": "Biografie bewerken",
|
||||||
|
"account_edit.char_counter": "{currentLength}/{maxLength} tekens",
|
||||||
"account_edit.column_button": "Klaar",
|
"account_edit.column_button": "Klaar",
|
||||||
"account_edit.column_title": "Profiel bewerken",
|
"account_edit.column_title": "Profiel bewerken",
|
||||||
|
"account_edit.custom_fields.placeholder": "Voeg je voornaamwoorden, externe links of iets anders toe dat je wilt delen.",
|
||||||
|
"account_edit.custom_fields.title": "Aangepaste velden",
|
||||||
|
"account_edit.display_name.placeholder": "Je weergavenaam wordt weergegeven op jouw profiel en in tijdlijnen.",
|
||||||
|
"account_edit.display_name.title": "Weergavenaam",
|
||||||
|
"account_edit.featured_hashtags.placeholder": "Help anderen je favoriete onderwerpen te identificeren en er snel toegang toe te hebben.",
|
||||||
|
"account_edit.featured_hashtags.title": "Uitgelichte hashtags",
|
||||||
|
"account_edit.name_modal.add_title": "Weergavenaam toevoegen",
|
||||||
|
"account_edit.name_modal.edit_title": "Weergavenaam bewerken",
|
||||||
|
"account_edit.profile_tab.subtitle": "Pas de tabbladen op je profiel aan en wat ze weergeven.",
|
||||||
|
"account_edit.profile_tab.title": "Instellingen voor tabblad Profiel",
|
||||||
|
"account_edit.save": "Opslaan",
|
||||||
|
"account_edit.section_edit_button": "Bewerken",
|
||||||
"account_note.placeholder": "Klik om een opmerking toe te voegen",
|
"account_note.placeholder": "Klik om een opmerking toe te voegen",
|
||||||
"admin.dashboard.daily_retention": "Retentiegraad van gebruikers per dag, vanaf registratie",
|
"admin.dashboard.daily_retention": "Retentiegraad van gebruikers per dag, vanaf registratie",
|
||||||
"admin.dashboard.monthly_retention": "Retentiegraad van gebruikers per maand, vanaf registratie",
|
"admin.dashboard.monthly_retention": "Retentiegraad van gebruikers per maand, vanaf registratie",
|
||||||
@@ -267,6 +284,7 @@
|
|||||||
"collections.detail.curated_by_you": "Samengesteld door jou",
|
"collections.detail.curated_by_you": "Samengesteld door jou",
|
||||||
"collections.detail.loading": "Verzameling laden…",
|
"collections.detail.loading": "Verzameling laden…",
|
||||||
"collections.detail.share": "Deze verzameling delen",
|
"collections.detail.share": "Deze verzameling delen",
|
||||||
|
"collections.edit_details": "Gegevens bewerken",
|
||||||
"collections.error_loading_collections": "Er is een fout opgetreden bij het laden van je verzamelingen.",
|
"collections.error_loading_collections": "Er is een fout opgetreden bij het laden van je verzamelingen.",
|
||||||
"collections.hints.accounts_counter": "{count} / {max} accounts",
|
"collections.hints.accounts_counter": "{count} / {max} accounts",
|
||||||
"collections.hints.add_more_accounts": "Voeg ten minste {count, plural, one {# account} other {# accounts}} toe om door te gaan",
|
"collections.hints.add_more_accounts": "Voeg ten minste {count, plural, one {# account} other {# accounts}} toe om door te gaan",
|
||||||
@@ -275,12 +293,15 @@
|
|||||||
"collections.manage_accounts": "Accounts beheren",
|
"collections.manage_accounts": "Accounts beheren",
|
||||||
"collections.mark_as_sensitive": "Als gevoelig markeren",
|
"collections.mark_as_sensitive": "Als gevoelig markeren",
|
||||||
"collections.mark_as_sensitive_hint": "Verbergt de omschrijving en de accounts van de verzameling achter een waarschuwing. De naam van de verzameling blijft zichtbaar.",
|
"collections.mark_as_sensitive_hint": "Verbergt de omschrijving en de accounts van de verzameling achter een waarschuwing. De naam van de verzameling blijft zichtbaar.",
|
||||||
|
"collections.name_length_hint": "Limiet van 40 tekens",
|
||||||
"collections.new_collection": "Nieuwe verzameling",
|
"collections.new_collection": "Nieuwe verzameling",
|
||||||
"collections.no_collections_yet": "Nog geen verzamelingen.",
|
"collections.no_collections_yet": "Nog geen verzamelingen.",
|
||||||
|
"collections.old_last_post_note": "Laatst gepost over een week geleden",
|
||||||
"collections.remove_account": "Deze account verwijderen",
|
"collections.remove_account": "Deze account verwijderen",
|
||||||
"collections.search_accounts_label": "Zoek naar accounts om toe te voegen…",
|
"collections.search_accounts_label": "Zoek naar accounts om toe te voegen…",
|
||||||
"collections.search_accounts_max_reached": "Je hebt het maximum aantal accounts toegevoegd",
|
"collections.search_accounts_max_reached": "Je hebt het maximum aantal accounts toegevoegd",
|
||||||
"collections.topic_hint": "Voeg een hashtag toe die anderen helpt het hoofdonderwerp van deze collectie te begrijpen.",
|
"collections.sensitive": "Gevoelig",
|
||||||
|
"collections.topic_hint": "Voeg een hashtag toe die anderen helpt het hoofdonderwerp van deze verzameling te begrijpen.",
|
||||||
"collections.view_collection": "Verzameling bekijken",
|
"collections.view_collection": "Verzameling bekijken",
|
||||||
"collections.visibility_public": "Openbaar",
|
"collections.visibility_public": "Openbaar",
|
||||||
"collections.visibility_public_hint": "Te zien onder zoekresultaten en in andere gebieden waar aanbevelingen verschijnen.",
|
"collections.visibility_public_hint": "Te zien onder zoekresultaten en in andere gebieden waar aanbevelingen verschijnen.",
|
||||||
@@ -370,6 +391,9 @@
|
|||||||
"confirmations.discard_draft.post.title": "Conceptbericht verwijderen?",
|
"confirmations.discard_draft.post.title": "Conceptbericht verwijderen?",
|
||||||
"confirmations.discard_edit_media.confirm": "Verwijderen",
|
"confirmations.discard_edit_media.confirm": "Verwijderen",
|
||||||
"confirmations.discard_edit_media.message": "Je hebt niet-opgeslagen wijzigingen in de mediabeschrijving of voorvertonning, wil je deze toch verwijderen?",
|
"confirmations.discard_edit_media.message": "Je hebt niet-opgeslagen wijzigingen in de mediabeschrijving of voorvertonning, wil je deze toch verwijderen?",
|
||||||
|
"confirmations.follow_to_collection.confirm": "Volgen en toevoegen aan verzameling",
|
||||||
|
"confirmations.follow_to_collection.message": "Je moet {name} volgen om ze aan een verzameling toe te voegen.",
|
||||||
|
"confirmations.follow_to_collection.title": "Account volgen?",
|
||||||
"confirmations.follow_to_list.confirm": "Volgen en toevoegen aan de lijst",
|
"confirmations.follow_to_list.confirm": "Volgen en toevoegen aan de lijst",
|
||||||
"confirmations.follow_to_list.message": "Je moet {name} volgen om ze toe te voegen aan een lijst.",
|
"confirmations.follow_to_list.message": "Je moet {name} volgen om ze toe te voegen aan een lijst.",
|
||||||
"confirmations.follow_to_list.title": "Gebruiker volgen?",
|
"confirmations.follow_to_list.title": "Gebruiker volgen?",
|
||||||
|
|||||||
@@ -141,6 +141,25 @@
|
|||||||
"account.unmute": "Opphev demping av @{name}",
|
"account.unmute": "Opphev demping av @{name}",
|
||||||
"account.unmute_notifications_short": "Opphev demping av varslingar",
|
"account.unmute_notifications_short": "Opphev demping av varslingar",
|
||||||
"account.unmute_short": "Opphev demping",
|
"account.unmute_short": "Opphev demping",
|
||||||
|
"account_edit.bio.placeholder": "Skriv ei kort innleiing slik at andre kan sjå kven du er.",
|
||||||
|
"account_edit.bio.title": "Om meg",
|
||||||
|
"account_edit.bio_modal.add_title": "Skriv om deg sjølv",
|
||||||
|
"account_edit.bio_modal.edit_title": "Endre bio",
|
||||||
|
"account_edit.char_counter": "{currentLength}/{maxLength} teikn",
|
||||||
|
"account_edit.column_button": "Ferdig",
|
||||||
|
"account_edit.column_title": "Rediger profil",
|
||||||
|
"account_edit.custom_fields.placeholder": "Legg til pronomen, lenkjer eller kva du elles vil dela.",
|
||||||
|
"account_edit.custom_fields.title": "Eigne felt",
|
||||||
|
"account_edit.display_name.placeholder": "Det synlege namnet ditt er det som syner på profilen din og i tidsliner.",
|
||||||
|
"account_edit.display_name.title": "Synleg namn",
|
||||||
|
"account_edit.featured_hashtags.placeholder": "Hjelp andre å finna og få rask tilgang til favorittemna dine.",
|
||||||
|
"account_edit.featured_hashtags.title": "Utvalde emneknaggar",
|
||||||
|
"account_edit.name_modal.add_title": "Legg til synleg namn",
|
||||||
|
"account_edit.name_modal.edit_title": "Endre synleg namn",
|
||||||
|
"account_edit.profile_tab.subtitle": "Tilpass fanene på profilen din og kva dei syner.",
|
||||||
|
"account_edit.profile_tab.title": "Innstillingar for profilfane",
|
||||||
|
"account_edit.save": "Lagre",
|
||||||
|
"account_edit.section_edit_button": "Rediger",
|
||||||
"account_note.placeholder": "Klikk for å leggja til merknad",
|
"account_note.placeholder": "Klikk for å leggja til merknad",
|
||||||
"admin.dashboard.daily_retention": "Mengda brukarar aktive ved dagar etter registrering",
|
"admin.dashboard.daily_retention": "Mengda brukarar aktive ved dagar etter registrering",
|
||||||
"admin.dashboard.monthly_retention": "Mengda brukarar aktive ved månader etter registrering",
|
"admin.dashboard.monthly_retention": "Mengda brukarar aktive ved månader etter registrering",
|
||||||
@@ -260,6 +279,12 @@
|
|||||||
"collections.create_collection": "Lag ei samling",
|
"collections.create_collection": "Lag ei samling",
|
||||||
"collections.delete_collection": "Slett samlinga",
|
"collections.delete_collection": "Slett samlinga",
|
||||||
"collections.description_length_hint": "Maks 100 teikn",
|
"collections.description_length_hint": "Maks 100 teikn",
|
||||||
|
"collections.detail.accounts_heading": "Kontoar",
|
||||||
|
"collections.detail.curated_by_author": "Kuratert av {author}",
|
||||||
|
"collections.detail.curated_by_you": "Kuratert av deg",
|
||||||
|
"collections.detail.loading": "Lastar inn samling…",
|
||||||
|
"collections.detail.share": "Del denne samlinga",
|
||||||
|
"collections.edit_details": "Rediger detaljar",
|
||||||
"collections.error_loading_collections": "Noko gjekk gale då me prøvde å henta samlingane dine.",
|
"collections.error_loading_collections": "Noko gjekk gale då me prøvde å henta samlingane dine.",
|
||||||
"collections.hints.accounts_counter": "{count} av {max} kontoar",
|
"collections.hints.accounts_counter": "{count} av {max} kontoar",
|
||||||
"collections.hints.add_more_accounts": "Legg til minst {count, plural, one {# konto} other {# kontoar}} for å halda fram",
|
"collections.hints.add_more_accounts": "Legg til minst {count, plural, one {# konto} other {# kontoar}} for å halda fram",
|
||||||
@@ -268,11 +293,14 @@
|
|||||||
"collections.manage_accounts": "Handter kontoar",
|
"collections.manage_accounts": "Handter kontoar",
|
||||||
"collections.mark_as_sensitive": "Merk som ømtolig",
|
"collections.mark_as_sensitive": "Merk som ømtolig",
|
||||||
"collections.mark_as_sensitive_hint": "Gøymer skildringa og kontoane i samlinga bak ei innhaldsåtvaring. Namnet på samlinga blir framleis synleg.",
|
"collections.mark_as_sensitive_hint": "Gøymer skildringa og kontoane i samlinga bak ei innhaldsåtvaring. Namnet på samlinga blir framleis synleg.",
|
||||||
|
"collections.name_length_hint": "Maks 40 teikn",
|
||||||
"collections.new_collection": "Ny samling",
|
"collections.new_collection": "Ny samling",
|
||||||
"collections.no_collections_yet": "Du har ingen samlingar enno.",
|
"collections.no_collections_yet": "Du har ingen samlingar enno.",
|
||||||
|
"collections.old_last_post_note": "Sist lagt ut for over ei veke sidan",
|
||||||
"collections.remove_account": "Fjern denne kontoen",
|
"collections.remove_account": "Fjern denne kontoen",
|
||||||
"collections.search_accounts_label": "Søk etter kontoar å leggja til…",
|
"collections.search_accounts_label": "Søk etter kontoar å leggja til…",
|
||||||
"collections.search_accounts_max_reached": "Du har nådd grensa for kor mange kontoar du kan leggja til",
|
"collections.search_accounts_max_reached": "Du har nådd grensa for kor mange kontoar du kan leggja til",
|
||||||
|
"collections.sensitive": "Ømtolig",
|
||||||
"collections.topic_hint": "Legg til ein emneknagg som hjelper andre å forstå hovudemnet for denne samlinga.",
|
"collections.topic_hint": "Legg til ein emneknagg som hjelper andre å forstå hovudemnet for denne samlinga.",
|
||||||
"collections.view_collection": "Sjå samlinga",
|
"collections.view_collection": "Sjå samlinga",
|
||||||
"collections.visibility_public": "Offentleg",
|
"collections.visibility_public": "Offentleg",
|
||||||
@@ -363,6 +391,9 @@
|
|||||||
"confirmations.discard_draft.post.title": "Forkast kladden?",
|
"confirmations.discard_draft.post.title": "Forkast kladden?",
|
||||||
"confirmations.discard_edit_media.confirm": "Forkast",
|
"confirmations.discard_edit_media.confirm": "Forkast",
|
||||||
"confirmations.discard_edit_media.message": "Du har ulagra endringar i mediaskildringa eller førehandsvisinga. Vil du forkasta dei likevel?",
|
"confirmations.discard_edit_media.message": "Du har ulagra endringar i mediaskildringa eller førehandsvisinga. Vil du forkasta dei likevel?",
|
||||||
|
"confirmations.follow_to_collection.confirm": "Fylg og legg til samlinga",
|
||||||
|
"confirmations.follow_to_collection.message": "Du må fylgja {name} for å leggja dei til ei samling.",
|
||||||
|
"confirmations.follow_to_collection.title": "Fylg kontoen?",
|
||||||
"confirmations.follow_to_list.confirm": "Fylg og legg til lista",
|
"confirmations.follow_to_list.confirm": "Fylg og legg til lista",
|
||||||
"confirmations.follow_to_list.message": "Du må fylgja {name} for å leggja dei til ei liste.",
|
"confirmations.follow_to_list.message": "Du må fylgja {name} for å leggja dei til ei liste.",
|
||||||
"confirmations.follow_to_list.title": "Vil du fylgja brukaren?",
|
"confirmations.follow_to_list.title": "Vil du fylgja brukaren?",
|
||||||
|
|||||||
@@ -293,6 +293,7 @@
|
|||||||
"collections.name_length_hint": "Kufi 40 shenja",
|
"collections.name_length_hint": "Kufi 40 shenja",
|
||||||
"collections.new_collection": "Koleksion i ri",
|
"collections.new_collection": "Koleksion i ri",
|
||||||
"collections.no_collections_yet": "Ende pa koleksione.",
|
"collections.no_collections_yet": "Ende pa koleksione.",
|
||||||
|
"collections.old_last_post_note": "Të postuarat e fundit gjatë një jave më parë",
|
||||||
"collections.remove_account": "Hiqe këtë llogari",
|
"collections.remove_account": "Hiqe këtë llogari",
|
||||||
"collections.search_accounts_label": "Kërkoni për llogari për shtim…",
|
"collections.search_accounts_label": "Kërkoni për llogari për shtim…",
|
||||||
"collections.search_accounts_max_reached": "Keni shtuar numrin maksimum të llogarive",
|
"collections.search_accounts_max_reached": "Keni shtuar numrin maksimum të llogarive",
|
||||||
@@ -387,6 +388,9 @@
|
|||||||
"confirmations.discard_draft.post.title": "Të hidhet tej skica e postimit tuaj?",
|
"confirmations.discard_draft.post.title": "Të hidhet tej skica e postimit tuaj?",
|
||||||
"confirmations.discard_edit_media.confirm": "Hidhe tej",
|
"confirmations.discard_edit_media.confirm": "Hidhe tej",
|
||||||
"confirmations.discard_edit_media.message": "Keni ndryshime të paruajtura te përshkrimi ose paraparja e medias, të hidhen tej, sido qoftë?",
|
"confirmations.discard_edit_media.message": "Keni ndryshime të paruajtura te përshkrimi ose paraparja e medias, të hidhen tej, sido qoftë?",
|
||||||
|
"confirmations.follow_to_collection.confirm": "Ndiqe dhe shtoje në koleksion",
|
||||||
|
"confirmations.follow_to_collection.message": "Që ta shtoni te një koleksion, duhet të jeni duke e ndjekur {name}.",
|
||||||
|
"confirmations.follow_to_collection.title": "Të ndiqet llogaria?",
|
||||||
"confirmations.follow_to_list.confirm": "Ndiqe dhe shtoje te listë",
|
"confirmations.follow_to_list.confirm": "Ndiqe dhe shtoje te listë",
|
||||||
"confirmations.follow_to_list.message": "Lypset të jeni duke e ndjekur {name}, që të shtohte te një listë.",
|
"confirmations.follow_to_list.message": "Lypset të jeni duke e ndjekur {name}, që të shtohte te një listë.",
|
||||||
"confirmations.follow_to_list.title": "Të ndiqet përdoruesi?",
|
"confirmations.follow_to_list.title": "Të ndiqet përdoruesi?",
|
||||||
|
|||||||
@@ -141,8 +141,25 @@
|
|||||||
"account.unmute": "@{name} adlı kişinin sesini aç",
|
"account.unmute": "@{name} adlı kişinin sesini aç",
|
||||||
"account.unmute_notifications_short": "Bildirimlerin sesini aç",
|
"account.unmute_notifications_short": "Bildirimlerin sesini aç",
|
||||||
"account.unmute_short": "Susturmayı kaldır",
|
"account.unmute_short": "Susturmayı kaldır",
|
||||||
|
"account_edit.bio.placeholder": "Diğerlerinin sizi tanımasına yardımcı olmak için kısa bir tanıtım ekleyin.",
|
||||||
|
"account_edit.bio.title": "Kişisel bilgiler",
|
||||||
|
"account_edit.bio_modal.add_title": "Kişisel bilgi ekle",
|
||||||
|
"account_edit.bio_modal.edit_title": "Kişisel bilgiyi düzenle",
|
||||||
|
"account_edit.char_counter": "{currentLength}/{maxLength} karakter",
|
||||||
"account_edit.column_button": "Tamamlandı",
|
"account_edit.column_button": "Tamamlandı",
|
||||||
"account_edit.column_title": "Profili Düzenle",
|
"account_edit.column_title": "Profili Düzenle",
|
||||||
|
"account_edit.custom_fields.placeholder": "Zamirlerinizi, harici bağlantılarınızı veya paylaşmak istediğiniz diğer bilgileri ekleyin.",
|
||||||
|
"account_edit.custom_fields.title": "Özel alanlar",
|
||||||
|
"account_edit.display_name.placeholder": "Görünen adınız profilinizde ve zaman akışlarında adınızın nasıl göründüğüdür.",
|
||||||
|
"account_edit.display_name.title": "Görünen ad",
|
||||||
|
"account_edit.featured_hashtags.placeholder": "Başkalarının favori konularınızı tanımlamasına ve bunlara hızlı bir şekilde erişmesine yardımcı olun.",
|
||||||
|
"account_edit.featured_hashtags.title": "Öne çıkan etiketler",
|
||||||
|
"account_edit.name_modal.add_title": "Görünen ad ekle",
|
||||||
|
"account_edit.name_modal.edit_title": "Görünen adı düzenle",
|
||||||
|
"account_edit.profile_tab.subtitle": "Profilinizdeki sekmeleri ve bunların görüntülediği bilgileri özelleştirin.",
|
||||||
|
"account_edit.profile_tab.title": "Profil sekme ayarları",
|
||||||
|
"account_edit.save": "Kaydet",
|
||||||
|
"account_edit.section_edit_button": "Düzenle",
|
||||||
"account_note.placeholder": "Not eklemek için tıklayın",
|
"account_note.placeholder": "Not eklemek için tıklayın",
|
||||||
"admin.dashboard.daily_retention": "Kayıttan sonra günlük kullanıcı saklama oranı",
|
"admin.dashboard.daily_retention": "Kayıttan sonra günlük kullanıcı saklama oranı",
|
||||||
"admin.dashboard.monthly_retention": "Kayıttan sonra aylık kullanıcı saklama oranı",
|
"admin.dashboard.monthly_retention": "Kayıttan sonra aylık kullanıcı saklama oranı",
|
||||||
@@ -267,6 +284,7 @@
|
|||||||
"collections.detail.curated_by_you": "Sizin derledikleriniz",
|
"collections.detail.curated_by_you": "Sizin derledikleriniz",
|
||||||
"collections.detail.loading": "Koleksiyon yükleniyor…",
|
"collections.detail.loading": "Koleksiyon yükleniyor…",
|
||||||
"collections.detail.share": "Bu koleksiyonu paylaş",
|
"collections.detail.share": "Bu koleksiyonu paylaş",
|
||||||
|
"collections.edit_details": "Ayrıntıları düzenle",
|
||||||
"collections.error_loading_collections": "Koleksiyonlarınızı yüklemeye çalışırken bir hata oluştu.",
|
"collections.error_loading_collections": "Koleksiyonlarınızı yüklemeye çalışırken bir hata oluştu.",
|
||||||
"collections.hints.accounts_counter": "{count} / {max} hesap",
|
"collections.hints.accounts_counter": "{count} / {max} hesap",
|
||||||
"collections.hints.add_more_accounts": "Devam etmek için en az {count, plural, one {# hesap} other {# hesap}} ekleyin",
|
"collections.hints.add_more_accounts": "Devam etmek için en az {count, plural, one {# hesap} other {# hesap}} ekleyin",
|
||||||
@@ -275,11 +293,14 @@
|
|||||||
"collections.manage_accounts": "Hesapları yönet",
|
"collections.manage_accounts": "Hesapları yönet",
|
||||||
"collections.mark_as_sensitive": "Hassas olarak işaretle",
|
"collections.mark_as_sensitive": "Hassas olarak işaretle",
|
||||||
"collections.mark_as_sensitive_hint": "Koleksiyonun açıklamasını ve hesaplarını içerik uyarısının arkasında gizler. Koleksiyon adı hala görünür olacaktır.",
|
"collections.mark_as_sensitive_hint": "Koleksiyonun açıklamasını ve hesaplarını içerik uyarısının arkasında gizler. Koleksiyon adı hala görünür olacaktır.",
|
||||||
|
"collections.name_length_hint": "40 karakterle sınırlı",
|
||||||
"collections.new_collection": "Yeni koleksiyon",
|
"collections.new_collection": "Yeni koleksiyon",
|
||||||
"collections.no_collections_yet": "Henüz hiçbir koleksiyon yok.",
|
"collections.no_collections_yet": "Henüz hiçbir koleksiyon yok.",
|
||||||
|
"collections.old_last_post_note": "Son gönderi bir haftadan önce",
|
||||||
"collections.remove_account": "Bu hesabı çıkar",
|
"collections.remove_account": "Bu hesabı çıkar",
|
||||||
"collections.search_accounts_label": "Eklemek için hesap arayın…",
|
"collections.search_accounts_label": "Eklemek için hesap arayın…",
|
||||||
"collections.search_accounts_max_reached": "Maksimum hesabı eklediniz",
|
"collections.search_accounts_max_reached": "Maksimum hesabı eklediniz",
|
||||||
|
"collections.sensitive": "Hassas",
|
||||||
"collections.topic_hint": "Bu koleksiyonun ana konusunu başkalarının anlamasına yardımcı olacak bir etiket ekleyin.",
|
"collections.topic_hint": "Bu koleksiyonun ana konusunu başkalarının anlamasına yardımcı olacak bir etiket ekleyin.",
|
||||||
"collections.view_collection": "Koleksiyonu görüntüle",
|
"collections.view_collection": "Koleksiyonu görüntüle",
|
||||||
"collections.visibility_public": "Herkese açık",
|
"collections.visibility_public": "Herkese açık",
|
||||||
@@ -370,6 +391,9 @@
|
|||||||
"confirmations.discard_draft.post.title": "Taslak gönderiniz silinsin mi?",
|
"confirmations.discard_draft.post.title": "Taslak gönderiniz silinsin mi?",
|
||||||
"confirmations.discard_edit_media.confirm": "Vazgeç",
|
"confirmations.discard_edit_media.confirm": "Vazgeç",
|
||||||
"confirmations.discard_edit_media.message": "Medya açıklaması veya ön izlemede kaydedilmemiş değişiklikleriniz var, yine de vazgeçmek istiyor musunuz?",
|
"confirmations.discard_edit_media.message": "Medya açıklaması veya ön izlemede kaydedilmemiş değişiklikleriniz var, yine de vazgeçmek istiyor musunuz?",
|
||||||
|
"confirmations.follow_to_collection.confirm": "Takip et ve koleksiyona ekle",
|
||||||
|
"confirmations.follow_to_collection.message": "Bir koleksiyona eklemek için {name} kişisini takip etmeniz gerekiyor.",
|
||||||
|
"confirmations.follow_to_collection.title": "Hesabı takip et?",
|
||||||
"confirmations.follow_to_list.confirm": "Takip et ve yapılacaklar listesine ekle",
|
"confirmations.follow_to_list.confirm": "Takip et ve yapılacaklar listesine ekle",
|
||||||
"confirmations.follow_to_list.message": "Bir listeye eklemek için {name} kişisini takip etmeniz gerekiyor.",
|
"confirmations.follow_to_list.message": "Bir listeye eklemek için {name} kişisini takip etmeniz gerekiyor.",
|
||||||
"confirmations.follow_to_list.title": "Kullanıcıyı takip et?",
|
"confirmations.follow_to_list.title": "Kullanıcıyı takip et?",
|
||||||
|
|||||||
@@ -296,6 +296,7 @@
|
|||||||
"collections.name_length_hint": "Giới hạn 40 ký tự",
|
"collections.name_length_hint": "Giới hạn 40 ký tự",
|
||||||
"collections.new_collection": "Collection mới",
|
"collections.new_collection": "Collection mới",
|
||||||
"collections.no_collections_yet": "Chưa có collection.",
|
"collections.no_collections_yet": "Chưa có collection.",
|
||||||
|
"collections.old_last_post_note": "Đăng lần cuối hơn một tuần trước",
|
||||||
"collections.remove_account": "Gỡ tài khoản này",
|
"collections.remove_account": "Gỡ tài khoản này",
|
||||||
"collections.search_accounts_label": "Tìm tài khoản để thêm…",
|
"collections.search_accounts_label": "Tìm tài khoản để thêm…",
|
||||||
"collections.search_accounts_max_reached": "Bạn đã đạt đến số lượng tài khoản tối đa",
|
"collections.search_accounts_max_reached": "Bạn đã đạt đến số lượng tài khoản tối đa",
|
||||||
@@ -390,6 +391,9 @@
|
|||||||
"confirmations.discard_draft.post.title": "Bỏ tút đang soạn?",
|
"confirmations.discard_draft.post.title": "Bỏ tút đang soạn?",
|
||||||
"confirmations.discard_edit_media.confirm": "Bỏ qua",
|
"confirmations.discard_edit_media.confirm": "Bỏ qua",
|
||||||
"confirmations.discard_edit_media.message": "Bạn chưa lưu thay đổi của phần mô tả hoặc bản xem trước của media, vẫn bỏ qua?",
|
"confirmations.discard_edit_media.message": "Bạn chưa lưu thay đổi của phần mô tả hoặc bản xem trước của media, vẫn bỏ qua?",
|
||||||
|
"confirmations.follow_to_collection.confirm": "Theo dõi & thêm vào collection",
|
||||||
|
"confirmations.follow_to_collection.message": "Bạn cần theo dõi {name} trước khi thêm họ vào collection.",
|
||||||
|
"confirmations.follow_to_collection.title": "Theo dõi tài khoản?",
|
||||||
"confirmations.follow_to_list.confirm": "Theo dõi & thêm vào danh sách",
|
"confirmations.follow_to_list.confirm": "Theo dõi & thêm vào danh sách",
|
||||||
"confirmations.follow_to_list.message": "Bạn cần theo dõi {name} trước khi thêm họ vào danh sách.",
|
"confirmations.follow_to_list.message": "Bạn cần theo dõi {name} trước khi thêm họ vào danh sách.",
|
||||||
"confirmations.follow_to_list.title": "Theo dõi tài khoản?",
|
"confirmations.follow_to_list.title": "Theo dõi tài khoản?",
|
||||||
|
|||||||
@@ -141,8 +141,25 @@
|
|||||||
"account.unmute": "不再隐藏 @{name}",
|
"account.unmute": "不再隐藏 @{name}",
|
||||||
"account.unmute_notifications_short": "恢复通知",
|
"account.unmute_notifications_short": "恢复通知",
|
||||||
"account.unmute_short": "取消隐藏",
|
"account.unmute_short": "取消隐藏",
|
||||||
|
"account_edit.bio.placeholder": "添加一段简短介绍,帮助其他人认识你。",
|
||||||
|
"account_edit.bio.title": "简介",
|
||||||
|
"account_edit.bio_modal.add_title": "添加个人简介",
|
||||||
|
"account_edit.bio_modal.edit_title": "编辑个人简介",
|
||||||
|
"account_edit.char_counter": "{currentLength}/{maxLength} 个字",
|
||||||
"account_edit.column_button": "完成",
|
"account_edit.column_button": "完成",
|
||||||
"account_edit.column_title": "修改个人资料",
|
"account_edit.column_title": "修改个人资料",
|
||||||
|
"account_edit.custom_fields.placeholder": "添加你的人称代词、外部链接,或其他你想分享的内容。",
|
||||||
|
"account_edit.custom_fields.title": "自定义字段",
|
||||||
|
"account_edit.display_name.placeholder": "你的显示名称是指你的名字在个人资料及时间线上出现时的样子。",
|
||||||
|
"account_edit.display_name.title": "显示名称",
|
||||||
|
"account_edit.featured_hashtags.placeholder": "帮助其他人认识并快速访问你最喜欢的话题。",
|
||||||
|
"account_edit.featured_hashtags.title": "精选话题标签",
|
||||||
|
"account_edit.name_modal.add_title": "添加显示名称",
|
||||||
|
"account_edit.name_modal.edit_title": "编辑显示名称",
|
||||||
|
"account_edit.profile_tab.subtitle": "自定义你个人资料的标签页及其显示的内容。",
|
||||||
|
"account_edit.profile_tab.title": "个人资料标签页设置",
|
||||||
|
"account_edit.save": "保存",
|
||||||
|
"account_edit.section_edit_button": "编辑",
|
||||||
"account_note.placeholder": "点击添加备注",
|
"account_note.placeholder": "点击添加备注",
|
||||||
"admin.dashboard.daily_retention": "注册后用户留存率(按日计算)",
|
"admin.dashboard.daily_retention": "注册后用户留存率(按日计算)",
|
||||||
"admin.dashboard.monthly_retention": "注册后用户留存率(按月计算)",
|
"admin.dashboard.monthly_retention": "注册后用户留存率(按月计算)",
|
||||||
@@ -267,6 +284,7 @@
|
|||||||
"collections.detail.curated_by_you": "由你精心挑选",
|
"collections.detail.curated_by_you": "由你精心挑选",
|
||||||
"collections.detail.loading": "正在加载收藏列表…",
|
"collections.detail.loading": "正在加载收藏列表…",
|
||||||
"collections.detail.share": "分享此收藏列表",
|
"collections.detail.share": "分享此收藏列表",
|
||||||
|
"collections.edit_details": "编辑详情",
|
||||||
"collections.error_loading_collections": "加载你的收藏列表时发生错误。",
|
"collections.error_loading_collections": "加载你的收藏列表时发生错误。",
|
||||||
"collections.hints.accounts_counter": "{count} / {max} 个账号",
|
"collections.hints.accounts_counter": "{count} / {max} 个账号",
|
||||||
"collections.hints.add_more_accounts": "添加至少 {count, plural, other {# 个账号}}以继续",
|
"collections.hints.add_more_accounts": "添加至少 {count, plural, other {# 个账号}}以继续",
|
||||||
@@ -275,11 +293,14 @@
|
|||||||
"collections.manage_accounts": "管理账户",
|
"collections.manage_accounts": "管理账户",
|
||||||
"collections.mark_as_sensitive": "标记为敏感内容",
|
"collections.mark_as_sensitive": "标记为敏感内容",
|
||||||
"collections.mark_as_sensitive_hint": "将此收藏列表的说明用内容警告隐藏。此收藏列表的名称仍将可见。",
|
"collections.mark_as_sensitive_hint": "将此收藏列表的说明用内容警告隐藏。此收藏列表的名称仍将可见。",
|
||||||
|
"collections.name_length_hint": "40 字限制",
|
||||||
"collections.new_collection": "新建收藏列表",
|
"collections.new_collection": "新建收藏列表",
|
||||||
"collections.no_collections_yet": "尚无收藏列表。",
|
"collections.no_collections_yet": "尚无收藏列表。",
|
||||||
|
"collections.old_last_post_note": "上次发言于一周多以前",
|
||||||
"collections.remove_account": "移除此账号",
|
"collections.remove_account": "移除此账号",
|
||||||
"collections.search_accounts_label": "搜索要添加的账号…",
|
"collections.search_accounts_label": "搜索要添加的账号…",
|
||||||
"collections.search_accounts_max_reached": "你添加的账号数量已达上限",
|
"collections.search_accounts_max_reached": "你添加的账号数量已达上限",
|
||||||
|
"collections.sensitive": "敏感内容",
|
||||||
"collections.topic_hint": "添加话题标签,帮助他人了解此收藏列表的主题。",
|
"collections.topic_hint": "添加话题标签,帮助他人了解此收藏列表的主题。",
|
||||||
"collections.view_collection": "查看收藏列表",
|
"collections.view_collection": "查看收藏列表",
|
||||||
"collections.visibility_public": "公开",
|
"collections.visibility_public": "公开",
|
||||||
@@ -370,6 +391,9 @@
|
|||||||
"confirmations.discard_draft.post.title": "丢弃你的嘟文草稿?",
|
"confirmations.discard_draft.post.title": "丢弃你的嘟文草稿?",
|
||||||
"confirmations.discard_edit_media.confirm": "丢弃",
|
"confirmations.discard_edit_media.confirm": "丢弃",
|
||||||
"confirmations.discard_edit_media.message": "你还有未保存的媒体描述或预览修改,仍要丢弃吗?",
|
"confirmations.discard_edit_media.message": "你还有未保存的媒体描述或预览修改,仍要丢弃吗?",
|
||||||
|
"confirmations.follow_to_collection.confirm": "关注并添加到收藏列表",
|
||||||
|
"confirmations.follow_to_collection.message": "你需要先关注 {name},才能将其添加到收藏列表。",
|
||||||
|
"confirmations.follow_to_collection.title": "要关注账号吗?",
|
||||||
"confirmations.follow_to_list.confirm": "关注并添加到列表",
|
"confirmations.follow_to_list.confirm": "关注并添加到列表",
|
||||||
"confirmations.follow_to_list.message": "你需要先关注 {name},才能将其添加到列表。",
|
"confirmations.follow_to_list.message": "你需要先关注 {name},才能将其添加到列表。",
|
||||||
"confirmations.follow_to_list.title": "确定要关注此用户?",
|
"confirmations.follow_to_list.title": "确定要关注此用户?",
|
||||||
|
|||||||
@@ -296,6 +296,7 @@
|
|||||||
"collections.name_length_hint": "40 字限制",
|
"collections.name_length_hint": "40 字限制",
|
||||||
"collections.new_collection": "新增收藏名單",
|
"collections.new_collection": "新增收藏名單",
|
||||||
"collections.no_collections_yet": "您沒有任何收藏名單。",
|
"collections.no_collections_yet": "您沒有任何收藏名單。",
|
||||||
|
"collections.old_last_post_note": "上次發表嘟文已超過一週",
|
||||||
"collections.remove_account": "移除此帳號",
|
"collections.remove_account": "移除此帳號",
|
||||||
"collections.search_accounts_label": "搜尋帳號以加入...",
|
"collections.search_accounts_label": "搜尋帳號以加入...",
|
||||||
"collections.search_accounts_max_reached": "您新增之帳號數已達上限",
|
"collections.search_accounts_max_reached": "您新增之帳號數已達上限",
|
||||||
@@ -390,6 +391,9 @@
|
|||||||
"confirmations.discard_draft.post.title": "是否捨棄您的嘟文草稿?",
|
"confirmations.discard_draft.post.title": "是否捨棄您的嘟文草稿?",
|
||||||
"confirmations.discard_edit_media.confirm": "捨棄",
|
"confirmations.discard_edit_media.confirm": "捨棄",
|
||||||
"confirmations.discard_edit_media.message": "您於媒體描述或預覽區塊有未儲存的變更。是否要捨棄這些變更?",
|
"confirmations.discard_edit_media.message": "您於媒體描述或預覽區塊有未儲存的變更。是否要捨棄這些變更?",
|
||||||
|
"confirmations.follow_to_collection.confirm": "跟隨並加入至收藏名單",
|
||||||
|
"confirmations.follow_to_collection.message": "您必須先跟隨 {name} 以將其加入至收藏名單。",
|
||||||
|
"confirmations.follow_to_collection.title": "是否跟隨此帳號?",
|
||||||
"confirmations.follow_to_list.confirm": "跟隨並加入至列表",
|
"confirmations.follow_to_list.confirm": "跟隨並加入至列表",
|
||||||
"confirmations.follow_to_list.message": "您必須先跟隨 {name} 以將其加入至列表。",
|
"confirmations.follow_to_list.message": "您必須先跟隨 {name} 以將其加入至列表。",
|
||||||
"confirmations.follow_to_list.title": "是否跟隨該使用者?",
|
"confirmations.follow_to_list.title": "是否跟隨該使用者?",
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import { annualReport } from './annual_report';
|
import { annualReport } from './annual_report';
|
||||||
import { collections } from './collections';
|
import { collections } from './collections';
|
||||||
|
import { profileEdit } from './profile_edit';
|
||||||
|
|
||||||
export const sliceReducers = {
|
export const sliceReducers = {
|
||||||
annualReport,
|
annualReport,
|
||||||
collections,
|
collections,
|
||||||
|
profileEdit,
|
||||||
};
|
};
|
||||||
|
|||||||
178
app/javascript/mastodon/reducers/slices/profile_edit.ts
Normal file
178
app/javascript/mastodon/reducers/slices/profile_edit.ts
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
import type { PayloadAction } from '@reduxjs/toolkit';
|
||||||
|
import { createSlice } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
|
import { debounce } from 'lodash';
|
||||||
|
|
||||||
|
import {
|
||||||
|
apiDeleteFeaturedTag,
|
||||||
|
apiGetCurrentFeaturedTags,
|
||||||
|
apiGetTagSuggestions,
|
||||||
|
apiPostFeaturedTag,
|
||||||
|
} from '@/mastodon/api/accounts';
|
||||||
|
import { apiGetSearch } from '@/mastodon/api/search';
|
||||||
|
import { hashtagToFeaturedTag } from '@/mastodon/api_types/tags';
|
||||||
|
import type { ApiFeaturedTagJSON } from '@/mastodon/api_types/tags';
|
||||||
|
import type { AppDispatch } from '@/mastodon/store';
|
||||||
|
import {
|
||||||
|
createAppAsyncThunk,
|
||||||
|
createDataLoadingThunk,
|
||||||
|
} from '@/mastodon/store/typed_functions';
|
||||||
|
|
||||||
|
interface ProfileEditState {
|
||||||
|
tags: ApiFeaturedTagJSON[];
|
||||||
|
tagSuggestions: ApiFeaturedTagJSON[];
|
||||||
|
isLoading: boolean;
|
||||||
|
isPending: boolean;
|
||||||
|
search: {
|
||||||
|
query: string;
|
||||||
|
isLoading: boolean;
|
||||||
|
results?: ApiFeaturedTagJSON[];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const initialState: ProfileEditState = {
|
||||||
|
tags: [],
|
||||||
|
tagSuggestions: [],
|
||||||
|
isLoading: true,
|
||||||
|
isPending: false,
|
||||||
|
search: {
|
||||||
|
query: '',
|
||||||
|
isLoading: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const profileEditSlice = createSlice({
|
||||||
|
name: 'profileEdit',
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
setSearchQuery(state, action: PayloadAction<string>) {
|
||||||
|
if (state.search.query === action.payload) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state.search.query = action.payload;
|
||||||
|
state.search.isLoading = false;
|
||||||
|
state.search.results = undefined;
|
||||||
|
},
|
||||||
|
clearSearch(state) {
|
||||||
|
state.search.query = '';
|
||||||
|
state.search.isLoading = false;
|
||||||
|
state.search.results = undefined;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
extraReducers(builder) {
|
||||||
|
builder.addCase(fetchSuggestedTags.fulfilled, (state, action) => {
|
||||||
|
state.tagSuggestions = action.payload.map(hashtagToFeaturedTag);
|
||||||
|
state.isLoading = false;
|
||||||
|
});
|
||||||
|
builder.addCase(fetchFeaturedTags.fulfilled, (state, action) => {
|
||||||
|
state.tags = action.payload;
|
||||||
|
state.isLoading = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.addCase(addFeaturedTag.pending, (state) => {
|
||||||
|
state.isPending = true;
|
||||||
|
});
|
||||||
|
builder.addCase(addFeaturedTag.rejected, (state) => {
|
||||||
|
state.isPending = false;
|
||||||
|
});
|
||||||
|
builder.addCase(addFeaturedTag.fulfilled, (state, action) => {
|
||||||
|
state.tags = [...state.tags, action.payload].toSorted(
|
||||||
|
(a, b) => b.statuses_count - a.statuses_count,
|
||||||
|
);
|
||||||
|
state.tagSuggestions = state.tagSuggestions.filter(
|
||||||
|
(tag) => tag.name !== action.meta.arg.name,
|
||||||
|
);
|
||||||
|
state.isPending = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.addCase(deleteFeaturedTag.pending, (state) => {
|
||||||
|
state.isPending = true;
|
||||||
|
});
|
||||||
|
builder.addCase(deleteFeaturedTag.rejected, (state) => {
|
||||||
|
state.isPending = false;
|
||||||
|
});
|
||||||
|
builder.addCase(deleteFeaturedTag.fulfilled, (state, action) => {
|
||||||
|
state.tags = state.tags.filter((tag) => tag.id !== action.meta.arg.tagId);
|
||||||
|
state.isPending = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.addCase(fetchSearchResults.pending, (state) => {
|
||||||
|
state.search.isLoading = true;
|
||||||
|
});
|
||||||
|
builder.addCase(fetchSearchResults.rejected, (state) => {
|
||||||
|
state.search.isLoading = false;
|
||||||
|
state.search.results = undefined;
|
||||||
|
});
|
||||||
|
builder.addCase(fetchSearchResults.fulfilled, (state, action) => {
|
||||||
|
state.search.isLoading = false;
|
||||||
|
const searchResults: ApiFeaturedTagJSON[] = [];
|
||||||
|
const currentTags = new Set(state.tags.map((tag) => tag.name));
|
||||||
|
|
||||||
|
for (const tag of action.payload) {
|
||||||
|
if (currentTags.has(tag.name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
searchResults.push(hashtagToFeaturedTag(tag));
|
||||||
|
if (searchResults.length >= 10) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state.search.results = searchResults;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const profileEdit = profileEditSlice.reducer;
|
||||||
|
export const { clearSearch } = profileEditSlice.actions;
|
||||||
|
|
||||||
|
export const fetchFeaturedTags = createDataLoadingThunk(
|
||||||
|
`${profileEditSlice.name}/fetchFeaturedTags`,
|
||||||
|
apiGetCurrentFeaturedTags,
|
||||||
|
{ useLoadingBar: false },
|
||||||
|
);
|
||||||
|
|
||||||
|
export const fetchSuggestedTags = createDataLoadingThunk(
|
||||||
|
`${profileEditSlice.name}/fetchSuggestedTags`,
|
||||||
|
apiGetTagSuggestions,
|
||||||
|
{ useLoadingBar: false },
|
||||||
|
);
|
||||||
|
|
||||||
|
export const addFeaturedTag = createDataLoadingThunk(
|
||||||
|
`${profileEditSlice.name}/addFeaturedTag`,
|
||||||
|
({ name }: { name: string }) => apiPostFeaturedTag(name),
|
||||||
|
{
|
||||||
|
condition(arg, { getState }) {
|
||||||
|
const state = getState();
|
||||||
|
return !state.profileEdit.tags.some((tag) => tag.name === arg.name);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export const deleteFeaturedTag = createDataLoadingThunk(
|
||||||
|
`${profileEditSlice.name}/deleteFeaturedTag`,
|
||||||
|
({ tagId }: { tagId: string }) => apiDeleteFeaturedTag(tagId),
|
||||||
|
);
|
||||||
|
|
||||||
|
const debouncedFetchSearchResults = debounce(
|
||||||
|
async (dispatch: AppDispatch, query: string) => {
|
||||||
|
await dispatch(fetchSearchResults({ q: query }));
|
||||||
|
},
|
||||||
|
300,
|
||||||
|
);
|
||||||
|
|
||||||
|
export const updateSearchQuery = createAppAsyncThunk(
|
||||||
|
`${profileEditSlice.name}/updateSearchQuery`,
|
||||||
|
(query: string, { dispatch }) => {
|
||||||
|
dispatch(profileEditSlice.actions.setSearchQuery(query));
|
||||||
|
|
||||||
|
if (query.trim().length > 0) {
|
||||||
|
void debouncedFetchSearchResults(dispatch, query);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export const fetchSearchResults = createDataLoadingThunk(
|
||||||
|
`${profileEditSlice.name}/fetchSearchResults`,
|
||||||
|
({ q }: { q: string }) => apiGetSearch({ q, type: 'hashtags', limit: 11 }),
|
||||||
|
(result) => result.hashtags,
|
||||||
|
);
|
||||||
@@ -77,7 +77,8 @@ const initialState = ImmutableMap({
|
|||||||
follow_requests: initialListState,
|
follow_requests: initialListState,
|
||||||
blocks: initialListState,
|
blocks: initialListState,
|
||||||
mutes: initialListState,
|
mutes: initialListState,
|
||||||
featured_tags: initialListState,
|
/** @type {ImmutableMap<string, typeof initialListState>} */
|
||||||
|
featured_tags: ImmutableMap(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const normalizeList = (state, path, accounts, next) => {
|
const normalizeList = (state, path, accounts, next) => {
|
||||||
|
|||||||
@@ -378,6 +378,15 @@ $content-width: 840px;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
details > summary {
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
padding-top: 24px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: $no-columns-breakpoint) {
|
@media screen and (max-width: $no-columns-breakpoint) {
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
|
|||||||
@@ -1670,7 +1670,7 @@ body > [data-popper-placement] {
|
|||||||
.detailed-status__display-name {
|
.detailed-status__display-name {
|
||||||
color: var(--color-text-tertiary);
|
color: var(--color-text-tertiary);
|
||||||
|
|
||||||
span {
|
span:not(.account__avatar) {
|
||||||
display: inline;
|
display: inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,41 +41,43 @@
|
|||||||
%p
|
%p
|
||||||
= t 'admin.reports.statuses_description_html'
|
= t 'admin.reports.statuses_description_html'
|
||||||
|
|
||||||
%h4
|
%details{ open: @report.status_ids.any? }
|
||||||
= t 'admin.reports.statuses'
|
%summary
|
||||||
|
= t 'admin.reports.statuses', count: @report.status_ids.size
|
||||||
|
|
||||||
= form_with model: @form, url: batch_admin_account_statuses_path(@report.target_account_id, report_id: @report.id) do |f|
|
= form_with model: @form, url: batch_admin_account_statuses_path(@report.target_account_id, report_id: @report.id) do |f|
|
||||||
.batch-table
|
|
||||||
.batch-table__toolbar
|
|
||||||
%label.batch-table__toolbar__select.batch-checkbox-all
|
|
||||||
= check_box_tag :batch_checkbox_all, nil, false
|
|
||||||
.batch-table__toolbar__actions
|
|
||||||
= link_to safe_join([material_symbol('add'), t('admin.reports.add_to_report')]),
|
|
||||||
admin_account_statuses_path(@report.target_account_id, report_id: @report.id),
|
|
||||||
class: 'table-action-link'
|
|
||||||
- if !@statuses.empty? && @report.unresolved?
|
|
||||||
= f.button safe_join([material_symbol('close'), t('admin.statuses.batch.remove_from_report')]), name: :remove_from_report, class: 'table-action-link', type: :submit
|
|
||||||
.batch-table__body
|
|
||||||
- if @statuses.empty?
|
|
||||||
= nothing_here 'nothing-here--under-tabs'
|
|
||||||
- else
|
|
||||||
= render partial: 'admin/shared/status_batch_row', collection: @statuses, as: :status, locals: { f: f }
|
|
||||||
|
|
||||||
- if Mastodon::Feature.collections_enabled?
|
|
||||||
%h4
|
|
||||||
= t 'admin.reports.collections'
|
|
||||||
|
|
||||||
%form
|
|
||||||
.batch-table
|
.batch-table
|
||||||
.batch-table__toolbar
|
.batch-table__toolbar
|
||||||
%label.batch-table__toolbar__select.batch-checkbox-all
|
%label.batch-table__toolbar__select.batch-checkbox-all
|
||||||
-# = check_box_tag :batch_checkbox_all, nil, false
|
= check_box_tag :batch_checkbox_all, nil, false
|
||||||
.batch-table__toolbar__actions
|
.batch-table__toolbar__actions
|
||||||
|
= link_to safe_join([material_symbol('add'), t('admin.reports.add_to_report')]),
|
||||||
|
admin_account_statuses_path(@report.target_account_id, report_id: @report.id),
|
||||||
|
class: 'table-action-link'
|
||||||
|
- if !@statuses.empty? && @report.unresolved?
|
||||||
|
= f.button safe_join([material_symbol('close'), t('admin.statuses.batch.remove_from_report')]), name: :remove_from_report, class: 'table-action-link', type: :submit
|
||||||
.batch-table__body
|
.batch-table__body
|
||||||
- if @report.collections.empty?
|
- if @statuses.empty?
|
||||||
= nothing_here 'nothing-here--under-tabs'
|
= nothing_here 'nothing-here--under-tabs'
|
||||||
- else
|
- else
|
||||||
= render partial: 'admin/shared/collection_batch_row', collection: @report.collections, as: :collection
|
= render partial: 'admin/shared/status_batch_row', collection: @statuses, as: :status, locals: { f: f }
|
||||||
|
|
||||||
|
- if Mastodon::Feature.collections_enabled?
|
||||||
|
%details{ open: @report.collections.any? }
|
||||||
|
%summary
|
||||||
|
= t 'admin.reports.collections', count: @report.collections.size
|
||||||
|
|
||||||
|
%form
|
||||||
|
.batch-table
|
||||||
|
.batch-table__toolbar
|
||||||
|
%label.batch-table__toolbar__select.batch-checkbox-all
|
||||||
|
-# = check_box_tag :batch_checkbox_all, nil, false
|
||||||
|
.batch-table__toolbar__actions
|
||||||
|
.batch-table__body
|
||||||
|
- if @report.collections.empty?
|
||||||
|
= nothing_here 'nothing-here--under-tabs'
|
||||||
|
- else
|
||||||
|
= render partial: 'admin/shared/collection_batch_row', collection: @report.collections, as: :collection
|
||||||
|
|
||||||
- if @report.unresolved?
|
- if @report.unresolved?
|
||||||
%hr.spacer/
|
%hr.spacer/
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ de:
|
|||||||
date_of_birth:
|
date_of_birth:
|
||||||
below_limit: liegt unterhalb des Mindestalters
|
below_limit: liegt unterhalb des Mindestalters
|
||||||
email:
|
email:
|
||||||
blocked: verwendet einen unerlaubten E-Mail-Anbieter
|
blocked: verwendet einen unerlaubten E-Mail-Provider
|
||||||
unreachable: scheint nicht zu existieren
|
unreachable: scheint nicht zu existieren
|
||||||
role_id:
|
role_id:
|
||||||
elevated: kann nicht höher als deine derzeitige Rolle sein
|
elevated: kann nicht höher als deine derzeitige Rolle sein
|
||||||
|
|||||||
@@ -717,7 +717,7 @@ cs:
|
|||||||
cancel: Zrušit
|
cancel: Zrušit
|
||||||
category: Kategorie
|
category: Kategorie
|
||||||
category_description_html: Důvod nahlášení tohoto účtu a/nebo obsahu bude uveden v komunikaci s nahlášeným účtem
|
category_description_html: Důvod nahlášení tohoto účtu a/nebo obsahu bude uveden v komunikaci s nahlášeným účtem
|
||||||
collections: Sbírky
|
collections: Sbírky (%{count})
|
||||||
comment:
|
comment:
|
||||||
none: Žádné
|
none: Žádné
|
||||||
comment_description_html: 'Pro upřesnění uživatel %{name} napsal:'
|
comment_description_html: 'Pro upřesnění uživatel %{name} napsal:'
|
||||||
@@ -753,7 +753,7 @@ cs:
|
|||||||
resolved_msg: Hlášení úspěšně vyřešeno!
|
resolved_msg: Hlášení úspěšně vyřešeno!
|
||||||
skip_to_actions: Přeskočit k akcím
|
skip_to_actions: Přeskočit k akcím
|
||||||
status: Stav
|
status: Stav
|
||||||
statuses: Příspěvky
|
statuses: Příspěvky (%{count})
|
||||||
statuses_description_html: Obsah porušující pravidla bude uveden v komunikaci s nahlášeným účtem
|
statuses_description_html: Obsah porušující pravidla bude uveden v komunikaci s nahlášeným účtem
|
||||||
summary:
|
summary:
|
||||||
action_preambles:
|
action_preambles:
|
||||||
|
|||||||
@@ -30,12 +30,12 @@ cy:
|
|||||||
pin_errors:
|
pin_errors:
|
||||||
following: Rhaid i chi fod yn dilyn y person rydych am ei gymeradwyo, yn barod
|
following: Rhaid i chi fod yn dilyn y person rydych am ei gymeradwyo, yn barod
|
||||||
posts:
|
posts:
|
||||||
few: Postiadau
|
few: Postiad
|
||||||
many: Postiadau
|
many: Postiad
|
||||||
one: Postiad
|
one: Postiad
|
||||||
other: Postiadau
|
other: Postiad
|
||||||
two: Postiadau
|
two: Bostiad
|
||||||
zero: Postiadau
|
zero: Postiad
|
||||||
posts_tab_heading: Postiadau
|
posts_tab_heading: Postiadau
|
||||||
self_follow_error: Chewch chi ddim dilyn eich cyfrif eich hun
|
self_follow_error: Chewch chi ddim dilyn eich cyfrif eich hun
|
||||||
admin:
|
admin:
|
||||||
@@ -745,7 +745,7 @@ cy:
|
|||||||
cancel: Canslo
|
cancel: Canslo
|
||||||
category: Categori
|
category: Categori
|
||||||
category_description_html: Bydd y rheswm dros adrodd am y cyfrif a/neu’r cynnwys hwn yn cael ei ddyfynnu wrth gyfathrebu â’r cyfrif a adroddwyd
|
category_description_html: Bydd y rheswm dros adrodd am y cyfrif a/neu’r cynnwys hwn yn cael ei ddyfynnu wrth gyfathrebu â’r cyfrif a adroddwyd
|
||||||
collections: Casgliadau
|
collections: Casgliadau (%{count})
|
||||||
comment:
|
comment:
|
||||||
none: Dim
|
none: Dim
|
||||||
comment_description_html: 'I ddarparu rhagor o wybodaeth, ysgrifennodd %{name}:'
|
comment_description_html: 'I ddarparu rhagor o wybodaeth, ysgrifennodd %{name}:'
|
||||||
@@ -781,7 +781,7 @@ cy:
|
|||||||
resolved_msg: Llwyddwyd i ddatrys yr adroddiad!
|
resolved_msg: Llwyddwyd i ddatrys yr adroddiad!
|
||||||
skip_to_actions: Mynd i gamau gweithredu
|
skip_to_actions: Mynd i gamau gweithredu
|
||||||
status: Statws
|
status: Statws
|
||||||
statuses: Postiadau
|
statuses: Postiadau (%{count})
|
||||||
statuses_description_html: Bydd cynnwys tramgwyddus yn cael ei ddyfynnu wrth gyfathrebu â'r cyfrif a adroddwyd
|
statuses_description_html: Bydd cynnwys tramgwyddus yn cael ei ddyfynnu wrth gyfathrebu â'r cyfrif a adroddwyd
|
||||||
summary:
|
summary:
|
||||||
action_preambles:
|
action_preambles:
|
||||||
@@ -2213,6 +2213,8 @@ cy:
|
|||||||
past_preamble_html: Rydym wedi newid ein telerau gwasanaeth ers eich ymweliad diwethaf. Rydym yn eich annog i ddarllen y telerau wedi'u diweddaru.
|
past_preamble_html: Rydym wedi newid ein telerau gwasanaeth ers eich ymweliad diwethaf. Rydym yn eich annog i ddarllen y telerau wedi'u diweddaru.
|
||||||
review_link: Darllen y telerau gwasanaeth
|
review_link: Darllen y telerau gwasanaeth
|
||||||
title: Mae telerau gwasanaeth %{domain} yn newid
|
title: Mae telerau gwasanaeth %{domain} yn newid
|
||||||
|
themes:
|
||||||
|
default: Mastodon
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
default: "%b %d, %Y, %H:%M"
|
default: "%b %d, %Y, %H:%M"
|
||||||
|
|||||||
@@ -689,7 +689,7 @@ da:
|
|||||||
cancel: Afbryd
|
cancel: Afbryd
|
||||||
category: Kategori
|
category: Kategori
|
||||||
category_description_html: Årsagen til anmeldelsen af denne konto og/eller indhold refereres i kommunikationen med den anmeldte konto
|
category_description_html: Årsagen til anmeldelsen af denne konto og/eller indhold refereres i kommunikationen med den anmeldte konto
|
||||||
collections: Samlinger
|
collections: Samlinger (%{count})
|
||||||
comment:
|
comment:
|
||||||
none: Ingen
|
none: Ingen
|
||||||
comment_description_html: 'For at give mere information, skrev %{name}:'
|
comment_description_html: 'For at give mere information, skrev %{name}:'
|
||||||
@@ -725,7 +725,7 @@ da:
|
|||||||
resolved_msg: Anmeldelse løst!
|
resolved_msg: Anmeldelse løst!
|
||||||
skip_to_actions: Overspring til foranstaltninger
|
skip_to_actions: Overspring til foranstaltninger
|
||||||
status: Status
|
status: Status
|
||||||
statuses: Indlæg
|
statuses: Indlæg (%{count})
|
||||||
statuses_description_html: Krænkende indhold citeres i kommunikationen med den anmeldte konto
|
statuses_description_html: Krænkende indhold citeres i kommunikationen med den anmeldte konto
|
||||||
summary:
|
summary:
|
||||||
action_preambles:
|
action_preambles:
|
||||||
|
|||||||
@@ -541,7 +541,7 @@ de:
|
|||||||
instances:
|
instances:
|
||||||
audit_log:
|
audit_log:
|
||||||
title: Neueste Protokolle
|
title: Neueste Protokolle
|
||||||
view_all: Alle Protokolle anzeigen
|
view_all: Protokolle
|
||||||
availability:
|
availability:
|
||||||
description_html:
|
description_html:
|
||||||
one: Wenn die Zustellung an die Domain <strong>%{count} Tag</strong> lang erfolglos bleibt, werden keine weiteren Zustellversuche unternommen, bis eine Zustellung <em>von</em> der Domain empfangen wird.
|
one: Wenn die Zustellung an die Domain <strong>%{count} Tag</strong> lang erfolglos bleibt, werden keine weiteren Zustellversuche unternommen, bis eine Zustellung <em>von</em> der Domain empfangen wird.
|
||||||
@@ -689,7 +689,7 @@ de:
|
|||||||
cancel: Abbrechen
|
cancel: Abbrechen
|
||||||
category: Kategorie
|
category: Kategorie
|
||||||
category_description_html: Der Grund, weshalb dieses Konto und/oder der Inhalt gemeldet worden ist, wird in der Kommunikation mit dem gemeldeten Konto erwähnt
|
category_description_html: Der Grund, weshalb dieses Konto und/oder der Inhalt gemeldet worden ist, wird in der Kommunikation mit dem gemeldeten Konto erwähnt
|
||||||
collections: Sammlungen
|
collections: Sammlungen (%{count})
|
||||||
comment:
|
comment:
|
||||||
none: Ohne ergänzenden Kommentar
|
none: Ohne ergänzenden Kommentar
|
||||||
comment_description_html: "%{name} ergänzte die Meldung um folgende Hinweis:"
|
comment_description_html: "%{name} ergänzte die Meldung um folgende Hinweis:"
|
||||||
@@ -725,7 +725,7 @@ de:
|
|||||||
resolved_msg: Meldung erfolgreich geklärt!
|
resolved_msg: Meldung erfolgreich geklärt!
|
||||||
skip_to_actions: Zur Maßnahme springen
|
skip_to_actions: Zur Maßnahme springen
|
||||||
status: Status
|
status: Status
|
||||||
statuses: Beiträge
|
statuses: Beiträge (%{count})
|
||||||
statuses_description_html: Beanstandete Inhalte werden in der Kommunikation mit dem gemeldeten Konto erwähnt
|
statuses_description_html: Beanstandete Inhalte werden in der Kommunikation mit dem gemeldeten Konto erwähnt
|
||||||
summary:
|
summary:
|
||||||
action_preambles:
|
action_preambles:
|
||||||
@@ -773,47 +773,47 @@ de:
|
|||||||
other: "%{count} Berechtigungen"
|
other: "%{count} Berechtigungen"
|
||||||
privileges:
|
privileges:
|
||||||
administrator: Administrator*in
|
administrator: Administrator*in
|
||||||
administrator_description: Benutzer*innen mit dieser Berechtigung werden alle Beschränkungen umgehen
|
administrator_description: Beschränkung aller Berechtigungen umgehen
|
||||||
delete_user_data: Kontodaten löschen
|
delete_user_data: Kontodaten löschen
|
||||||
delete_user_data_description: Erlaubt Benutzer*innen, die Daten anderer Benutzer*innen sofort zu löschen
|
delete_user_data_description: Daten anderer Profile ohne Verzögerung löschen
|
||||||
invite_users: Leute einladen
|
invite_users: Einladungen
|
||||||
invite_users_description: Erlaubt bereits registrierten Benutzer*innen, neue Leute zum Server einzuladen
|
invite_users_description: Erlaubt bereits registrierten Benutzer*innen, neue Leute zum Server einzuladen
|
||||||
manage_announcements: Ankündigungen verwalten
|
manage_announcements: Ankündigungen
|
||||||
manage_announcements_description: Erlaubt Profilen, Ankündigungen auf dem Server zu verwalten
|
manage_announcements_description: Ankündigungen dieses Servers verwalten
|
||||||
manage_appeals: Einsprüche verwalten
|
manage_appeals: Einsprüche
|
||||||
manage_appeals_description: Erlaubt es Benutzer*innen, Entscheidungen der Moderator*innen zu widersprechen
|
manage_appeals_description: Entscheidungen von Moderator*innen bzgl. Einsprüchen von Benutzer*innen überarbeiten
|
||||||
manage_blocks: Sperrungen verwalten
|
manage_blocks: Sperren
|
||||||
manage_blocks_description: Erlaubt Nutzer*innen das Sperren von E-Mail-Anbietern und IP-Adressen
|
manage_blocks_description: E-Mail-Provider und IP-Adressen sperren
|
||||||
manage_custom_emojis: Eigene Emojis verwalten
|
manage_custom_emojis: Emojis
|
||||||
manage_custom_emojis_description: Erlaubt es Benutzer*innen, eigene Emojis auf dem Server zu verwalten
|
manage_custom_emojis_description: Spezielle Emojis dieses Servers verwalten
|
||||||
manage_federation: Föderation verwalten
|
manage_federation: Föderation
|
||||||
manage_federation_description: Erlaubt Benutzer*innen, Domains anderer Mastodon-Server zu sperren oder zuzulassen – und die Zustellbarkeit zu steuern
|
manage_federation_description: Domains anderer Mastodon-Server sperren/zulassen – und Zustellbarkeit kontrollieren
|
||||||
manage_invites: Einladungen verwalten
|
manage_invites: Einladungen
|
||||||
manage_invites_description: Erlaubt es Benutzer*innen, Einladungslinks zu durchsuchen und zu deaktivieren
|
manage_invites_description: Einladungslinks durchsuchen und deaktivieren
|
||||||
manage_reports: Meldungen verwalten
|
manage_reports: Meldungen
|
||||||
manage_reports_description: Erlaubt es Benutzer*innen, Meldungen zu überprüfen und Vorfälle zu moderieren
|
manage_reports_description: Meldungen überprüfen und Vorfälle moderieren
|
||||||
manage_roles: Rollen verwalten
|
manage_roles: Rollen verwalten
|
||||||
manage_roles_description: Erlaubt es Benutzer*innen, Rollen, die sich unterhalb der eigenen Rolle befinden, zu verwalten und zuzuweisen
|
manage_roles_description: Rollen, die sich unterhalb der eigenen Rolle befinden, verwalten und zuweisen
|
||||||
manage_rules: Serverregeln verwalten
|
manage_rules: Serverregeln
|
||||||
manage_rules_description: Erlaubt es Benutzer*innen, Serverregeln zu ändern
|
manage_rules_description: Serverregeln ändern
|
||||||
manage_settings: Einstellungen verwalten
|
manage_settings: Einstellungen
|
||||||
manage_settings_description: Erlaubt Nutzer*innen, Einstellungen dieses Servers zu ändern
|
manage_settings_description: Einstellungen dieses Servers ändern
|
||||||
manage_taxonomies: Hashtags verwalten
|
manage_taxonomies: Hashtags
|
||||||
manage_taxonomies_description: Ermöglicht Benutzer*innen, die Trends zu überprüfen und die Hashtag-Einstellungen zu aktualisieren
|
manage_taxonomies_description: Trends überprüfen und Einstellungen für Hashtags
|
||||||
manage_user_access: Kontozugriff verwalten
|
manage_user_access: Kontozugriff
|
||||||
manage_user_access_description: Erlaubt Nutzer*innen, die Zwei-Faktor-Authentisierung anderer zu deaktivieren, ihre E-Mail-Adresse zu ändern und ihr Passwort zurückzusetzen
|
manage_user_access_description: Zwei-Faktor-Authentisierungen anderer können deaktiviert, E-Mail-Adressen geändert und Passwörter zurückgesetzt werden
|
||||||
manage_users: Konten verwalten
|
manage_users: Konten
|
||||||
manage_users_description: Erlaubt es Benutzer*innen, die Details anderer Profile einzusehen und diese Accounts zu moderieren
|
manage_users_description: Erlaubt es Benutzer*innen, die Details anderer Profile einzusehen und diese Accounts zu moderieren
|
||||||
manage_webhooks: Webhooks verwalten
|
manage_webhooks: Webhooks
|
||||||
manage_webhooks_description: Erlaubt es Benutzer*innen, Webhooks für administrative Vorkommnisse einzurichten
|
manage_webhooks_description: Webhooks für administrative Vorgänge einrichten
|
||||||
view_audit_log: Protokoll anzeigen
|
view_audit_log: Protokoll anzeigen
|
||||||
view_audit_log_description: Erlaubt es Benutzer*innen, den Verlauf der administrativen Handlungen auf diesem Server einzusehen
|
view_audit_log_description: Verlauf der administrativen Vorgänge auf diesem Server
|
||||||
view_dashboard: Dashboard anzeigen
|
view_dashboard: Dashboard
|
||||||
view_dashboard_description: Gewährt Benutzer*innen den Zugriff auf das Dashboard und verschiedene Metriken
|
view_dashboard_description: Dashboard und verschiedene Metriken
|
||||||
view_devops: DevOps
|
view_devops: DevOps
|
||||||
view_devops_description: Erlaubt es Benutzer*innen, auf die Sidekiq- und pgHero-Dashboards zuzugreifen
|
view_devops_description: Auf Sidekiq- und pgHero-Dashboards zugreifen
|
||||||
view_feeds: Live-Feeds und Hashtags anzeigen
|
view_feeds: Live-Feeds und Hashtags anzeigen
|
||||||
view_feeds_description: Ermöglicht Nutzer*innen unabhängig von den Servereinstellungen den Zugriff auf die Live-Feeds und Hashtags
|
view_feeds_description: Zugriff auf Live-Feeds und Hashtags – unabhängig der Servereinstellungen
|
||||||
requires_2fa: Zwei-Faktor-Authentisierung erforderlich
|
requires_2fa: Zwei-Faktor-Authentisierung erforderlich
|
||||||
title: Rollen
|
title: Rollen
|
||||||
rules:
|
rules:
|
||||||
@@ -1972,7 +1972,7 @@ de:
|
|||||||
pending_approval: Veröffentlichung ausstehend
|
pending_approval: Veröffentlichung ausstehend
|
||||||
revoked: Beitrag durch Autor*in entfernt
|
revoked: Beitrag durch Autor*in entfernt
|
||||||
quote_policies:
|
quote_policies:
|
||||||
followers: Nur Follower und ich
|
followers: Nur Follower
|
||||||
nobody: Nur ich
|
nobody: Nur ich
|
||||||
public: Alle
|
public: Alle
|
||||||
quote_post_author: Zitierte %{acct}
|
quote_post_author: Zitierte %{acct}
|
||||||
|
|||||||
@@ -83,6 +83,10 @@ fr-CA:
|
|||||||
access_denied: Le/la propriétaire de la ressource ou le serveur d’autorisation a refusé la requête.
|
access_denied: Le/la propriétaire de la ressource ou le serveur d’autorisation a refusé la requête.
|
||||||
credential_flow_not_configured: Le flux des identifiants du mot de passe du/de la propriétaire de la ressource a échoué car Doorkeeper.configure.resource_owner_from_credentials n’est pas configuré.
|
credential_flow_not_configured: Le flux des identifiants du mot de passe du/de la propriétaire de la ressource a échoué car Doorkeeper.configure.resource_owner_from_credentials n’est pas configuré.
|
||||||
invalid_client: L’authentification du client a échoué à cause d’un client inconnu, d’aucune authentification de client incluse ou d’une méthode d’authentification non prise en charge.
|
invalid_client: L’authentification du client a échoué à cause d’un client inconnu, d’aucune authentification de client incluse ou d’une méthode d’authentification non prise en charge.
|
||||||
|
invalid_code_challenge_method:
|
||||||
|
one: Le code de la méthode de défi doit être %{challenge_methods}.
|
||||||
|
other: 'Le code de la méthode de défi doit être l''une de ces valeurs : %{challenge_methods}.'
|
||||||
|
zero: Le serveur d'autorisation ne supporte pas PKCE car il n'y a aucune valeur de code de méthode de défi acceptée.
|
||||||
invalid_grant: L’autorisation accordée est invalide, expirée, révoquée, ne concorde pas avec l’URI de redirection utilisée dans la requête d’autorisation, ou a été délivrée à un autre client.
|
invalid_grant: L’autorisation accordée est invalide, expirée, révoquée, ne concorde pas avec l’URI de redirection utilisée dans la requête d’autorisation, ou a été délivrée à un autre client.
|
||||||
invalid_redirect_uri: L’URI de redirection n’est pas valide.
|
invalid_redirect_uri: L’URI de redirection n’est pas valide.
|
||||||
invalid_request:
|
invalid_request:
|
||||||
|
|||||||
@@ -83,6 +83,10 @@ fr:
|
|||||||
access_denied: Le propriétaire de la ressource ou le serveur d’autorisation a refusé la requête.
|
access_denied: Le propriétaire de la ressource ou le serveur d’autorisation a refusé la requête.
|
||||||
credential_flow_not_configured: Le flux des identifiants du mot de passe du propriétaire de la ressource a échoué car Doorkeeper.configure.resource_owner_from_credentials n’est pas configuré.
|
credential_flow_not_configured: Le flux des identifiants du mot de passe du propriétaire de la ressource a échoué car Doorkeeper.configure.resource_owner_from_credentials n’est pas configuré.
|
||||||
invalid_client: L’authentification du client a échoué à cause d’un client inconnu, d’aucune authentification de client incluse ou d’une méthode d’authentification non prise en charge.
|
invalid_client: L’authentification du client a échoué à cause d’un client inconnu, d’aucune authentification de client incluse ou d’une méthode d’authentification non prise en charge.
|
||||||
|
invalid_code_challenge_method:
|
||||||
|
one: Le code de la méthode de défi doit être %{challenge_methods}.
|
||||||
|
other: 'Le code de la méthode de défi doit être l''une de ces valeurs : %{challenge_methods}.'
|
||||||
|
zero: Le serveur d'autorisation ne supporte pas PKCE car il n'y a aucune valeur de code de méthode de défi acceptée.
|
||||||
invalid_grant: L’autorisation accordée est invalide, expirée, annulée, ne concorde pas avec l’URL de redirection utilisée dans la requête d’autorisation, ou a été délivrée à un autre client.
|
invalid_grant: L’autorisation accordée est invalide, expirée, annulée, ne concorde pas avec l’URL de redirection utilisée dans la requête d’autorisation, ou a été délivrée à un autre client.
|
||||||
invalid_redirect_uri: L’URL de redirection n’est pas valide.
|
invalid_redirect_uri: L’URL de redirection n’est pas valide.
|
||||||
invalid_request:
|
invalid_request:
|
||||||
|
|||||||
@@ -83,6 +83,10 @@ nn:
|
|||||||
access_denied: Ressurseigaren eller autorisasjonstenaren avviste førespurnaden.
|
access_denied: Ressurseigaren eller autorisasjonstenaren avviste førespurnaden.
|
||||||
credential_flow_not_configured: Flyten «Resource Owner Password Credentials» kunne ikkje fullførast sidan «Doorkeeper.configure.resource_owner_from_credentials» ikkje er konfigurert.
|
credential_flow_not_configured: Flyten «Resource Owner Password Credentials» kunne ikkje fullførast sidan «Doorkeeper.configure.resource_owner_from_credentials» ikkje er konfigurert.
|
||||||
invalid_client: Klientautentisering feila på grunn av ukjent klient, ingen inkludert autentisering, eller ikkje støtta autentiseringsmetode.
|
invalid_client: Klientautentisering feila på grunn av ukjent klient, ingen inkludert autentisering, eller ikkje støtta autentiseringsmetode.
|
||||||
|
invalid_code_challenge_method:
|
||||||
|
one: code_challenge_method må vera %{challenge_methods}.
|
||||||
|
other: code_challenge_method må vera ein av %{challenge_methods}.
|
||||||
|
zero: Godkjenningstenaren støttar ikkje PKCE fordi det ikkje er nokon aksepterte verdiar av code_challenge_method.
|
||||||
invalid_grant: Autoriseringa er ugyldig, utløpt, oppheva, stemmer ikkje med omdirigerings-URIen eller var tildelt ein annan klient.
|
invalid_grant: Autoriseringa er ugyldig, utløpt, oppheva, stemmer ikkje med omdirigerings-URIen eller var tildelt ein annan klient.
|
||||||
invalid_redirect_uri: Omdirigerings-URLen er ikkje gyldig.
|
invalid_redirect_uri: Omdirigerings-URLen er ikkje gyldig.
|
||||||
invalid_request:
|
invalid_request:
|
||||||
|
|||||||
@@ -689,7 +689,7 @@ el:
|
|||||||
cancel: Άκυρο
|
cancel: Άκυρο
|
||||||
category: Κατηγορία
|
category: Κατηγορία
|
||||||
category_description_html: Ο λόγος για τον οποίο αναφέρθηκε αυτός ο λογαριασμός και/ή το περιεχόμενο θα εσωκλείεται σε επικοινωνία με τον αναφερόμενο λογαριασμό
|
category_description_html: Ο λόγος για τον οποίο αναφέρθηκε αυτός ο λογαριασμός και/ή το περιεχόμενο θα εσωκλείεται σε επικοινωνία με τον αναφερόμενο λογαριασμό
|
||||||
collections: Συλλογές
|
collections: Συλλογές (%{count})
|
||||||
comment:
|
comment:
|
||||||
none: Κανένα
|
none: Κανένα
|
||||||
comment_description_html: 'Για να δώσει περισσότερες πληροφορίες, ο/η %{name} έγραψε:'
|
comment_description_html: 'Για να δώσει περισσότερες πληροφορίες, ο/η %{name} έγραψε:'
|
||||||
@@ -725,7 +725,7 @@ el:
|
|||||||
resolved_msg: Η αναφορά επιλύθηκε επιτυχώς!
|
resolved_msg: Η αναφορά επιλύθηκε επιτυχώς!
|
||||||
skip_to_actions: Μετάβαση στις ενέργειες
|
skip_to_actions: Μετάβαση στις ενέργειες
|
||||||
status: Κατάσταση
|
status: Κατάσταση
|
||||||
statuses: Αναρτήσεις
|
statuses: Αναρτήσεις (%{count})
|
||||||
statuses_description_html: Το προσβλητικό περιεχόμενο θα εσωκλείεται στην επικοινωνία με τον αναφερόμενο λογαριασμό
|
statuses_description_html: Το προσβλητικό περιεχόμενο θα εσωκλείεται στην επικοινωνία με τον αναφερόμενο λογαριασμό
|
||||||
summary:
|
summary:
|
||||||
action_preambles:
|
action_preambles:
|
||||||
|
|||||||
@@ -689,7 +689,7 @@ en-GB:
|
|||||||
cancel: Cancel
|
cancel: Cancel
|
||||||
category: Category
|
category: Category
|
||||||
category_description_html: The reason this account and/or content was reported will be cited in communication with the reported account
|
category_description_html: The reason this account and/or content was reported will be cited in communication with the reported account
|
||||||
collections: Collections
|
collections: Collections (%{count})
|
||||||
comment:
|
comment:
|
||||||
none: None
|
none: None
|
||||||
comment_description_html: 'To provide more information, %{name} wrote:'
|
comment_description_html: 'To provide more information, %{name} wrote:'
|
||||||
@@ -725,7 +725,7 @@ en-GB:
|
|||||||
resolved_msg: Report successfully resolved!
|
resolved_msg: Report successfully resolved!
|
||||||
skip_to_actions: Skip to actions
|
skip_to_actions: Skip to actions
|
||||||
status: Status
|
status: Status
|
||||||
statuses: Posts
|
statuses: Posts (%{count})
|
||||||
statuses_description_html: Offending content will be cited in communication with the reported account
|
statuses_description_html: Offending content will be cited in communication with the reported account
|
||||||
summary:
|
summary:
|
||||||
action_preambles:
|
action_preambles:
|
||||||
|
|||||||
@@ -689,7 +689,7 @@ en:
|
|||||||
cancel: Cancel
|
cancel: Cancel
|
||||||
category: Category
|
category: Category
|
||||||
category_description_html: The reason this account and/or content was reported will be cited in communication with the reported account
|
category_description_html: The reason this account and/or content was reported will be cited in communication with the reported account
|
||||||
collections: Collections
|
collections: Collections (%{count})
|
||||||
comment:
|
comment:
|
||||||
none: None
|
none: None
|
||||||
comment_description_html: 'To provide more information, %{name} wrote:'
|
comment_description_html: 'To provide more information, %{name} wrote:'
|
||||||
@@ -725,7 +725,7 @@ en:
|
|||||||
resolved_msg: Report successfully resolved!
|
resolved_msg: Report successfully resolved!
|
||||||
skip_to_actions: Skip to actions
|
skip_to_actions: Skip to actions
|
||||||
status: Status
|
status: Status
|
||||||
statuses: Posts
|
statuses: Posts (%{count})
|
||||||
statuses_description_html: Offending content will be cited in communication with the reported account
|
statuses_description_html: Offending content will be cited in communication with the reported account
|
||||||
summary:
|
summary:
|
||||||
action_preambles:
|
action_preambles:
|
||||||
|
|||||||
@@ -689,7 +689,7 @@ es-AR:
|
|||||||
cancel: Cancelar
|
cancel: Cancelar
|
||||||
category: Categoría
|
category: Categoría
|
||||||
category_description_html: El motivo por el que se denunció esta cuenta o contenido será citado en las comunicaciones con la cuenta denunciada
|
category_description_html: El motivo por el que se denunció esta cuenta o contenido será citado en las comunicaciones con la cuenta denunciada
|
||||||
collections: Colecciones
|
collections: Colecciones (%{count})
|
||||||
comment:
|
comment:
|
||||||
none: Ninguno
|
none: Ninguno
|
||||||
comment_description_html: 'Para proporcionar más información, %{name} escribió:'
|
comment_description_html: 'Para proporcionar más información, %{name} escribió:'
|
||||||
@@ -725,7 +725,7 @@ es-AR:
|
|||||||
resolved_msg: "¡Denuncia exitosamente resuelta!"
|
resolved_msg: "¡Denuncia exitosamente resuelta!"
|
||||||
skip_to_actions: Ir directamente a las acciones
|
skip_to_actions: Ir directamente a las acciones
|
||||||
status: Estado
|
status: Estado
|
||||||
statuses: Mensajes
|
statuses: Mensajes (%{count})
|
||||||
statuses_description_html: El contenido ofensivo se citará en la comunicación con la cuenta denunciada
|
statuses_description_html: El contenido ofensivo se citará en la comunicación con la cuenta denunciada
|
||||||
summary:
|
summary:
|
||||||
action_preambles:
|
action_preambles:
|
||||||
|
|||||||
@@ -689,7 +689,7 @@ es-MX:
|
|||||||
cancel: Cancelar
|
cancel: Cancelar
|
||||||
category: Categoría
|
category: Categoría
|
||||||
category_description_html: La razón por la que se reportó esta cuenta o contenido será citada en las comunicaciones con la cuenta reportada
|
category_description_html: La razón por la que se reportó esta cuenta o contenido será citada en las comunicaciones con la cuenta reportada
|
||||||
collections: Colecciones
|
collections: Colecciones (%{count})
|
||||||
comment:
|
comment:
|
||||||
none: Ninguno
|
none: Ninguno
|
||||||
comment_description_html: 'Para proporcionar más información, %{name} escribió:'
|
comment_description_html: 'Para proporcionar más información, %{name} escribió:'
|
||||||
@@ -725,7 +725,7 @@ es-MX:
|
|||||||
resolved_msg: "¡La denuncia se ha resuelto correctamente!"
|
resolved_msg: "¡La denuncia se ha resuelto correctamente!"
|
||||||
skip_to_actions: Ir directamente a las acciones
|
skip_to_actions: Ir directamente a las acciones
|
||||||
status: Estado
|
status: Estado
|
||||||
statuses: Publicaciones
|
statuses: Publicaciones (%{count})
|
||||||
statuses_description_html: El contenido ofensivo se citará en comunicación con la cuenta reportada
|
statuses_description_html: El contenido ofensivo se citará en comunicación con la cuenta reportada
|
||||||
summary:
|
summary:
|
||||||
action_preambles:
|
action_preambles:
|
||||||
|
|||||||
@@ -348,8 +348,8 @@ es:
|
|||||||
number_of_accounts:
|
number_of_accounts:
|
||||||
one: 1 cuenta
|
one: 1 cuenta
|
||||||
other: "%{count} cuentas"
|
other: "%{count} cuentas"
|
||||||
open: Pública
|
open: Abrir
|
||||||
view_publicly: Vista pública
|
view_publicly: Ver públicamente
|
||||||
critical_update_pending: Actualización crítica pendiente
|
critical_update_pending: Actualización crítica pendiente
|
||||||
custom_emojis:
|
custom_emojis:
|
||||||
assign_category: Asignar categoría
|
assign_category: Asignar categoría
|
||||||
@@ -689,7 +689,7 @@ es:
|
|||||||
cancel: Cancelar
|
cancel: Cancelar
|
||||||
category: Categoría
|
category: Categoría
|
||||||
category_description_html: La razón por la que se reportó esta cuenta o contenido será citada en las comunicaciones con la cuenta reportada
|
category_description_html: La razón por la que se reportó esta cuenta o contenido será citada en las comunicaciones con la cuenta reportada
|
||||||
collections: Colecciones
|
collections: Colecciones (%{count})
|
||||||
comment:
|
comment:
|
||||||
none: Ninguno
|
none: Ninguno
|
||||||
comment_description_html: 'Para proporcionar más información, %{name} escribió:'
|
comment_description_html: 'Para proporcionar más información, %{name} escribió:'
|
||||||
@@ -725,7 +725,7 @@ es:
|
|||||||
resolved_msg: "¡La denuncia se ha resuelto correctamente!"
|
resolved_msg: "¡La denuncia se ha resuelto correctamente!"
|
||||||
skip_to_actions: Ir directamente a las acciones
|
skip_to_actions: Ir directamente a las acciones
|
||||||
status: Estado
|
status: Estado
|
||||||
statuses: Publicaciones
|
statuses: Publicaciones (%{count})
|
||||||
statuses_description_html: El contenido ofensivo se citará en la comunicación con la cuenta reportada
|
statuses_description_html: El contenido ofensivo se citará en la comunicación con la cuenta reportada
|
||||||
summary:
|
summary:
|
||||||
action_preambles:
|
action_preambles:
|
||||||
|
|||||||
@@ -689,7 +689,7 @@ fi:
|
|||||||
cancel: Peruuta
|
cancel: Peruuta
|
||||||
category: Luokka
|
category: Luokka
|
||||||
category_description_html: Syy siihen, miksi tämä tili ja/tai sisältö raportoitiin, mainitaan ilmoitetun tilin kanssa viestiessä
|
category_description_html: Syy siihen, miksi tämä tili ja/tai sisältö raportoitiin, mainitaan ilmoitetun tilin kanssa viestiessä
|
||||||
collections: Kokoelmat
|
collections: Kokoelmat (%{count})
|
||||||
comment:
|
comment:
|
||||||
none: Ei mitään
|
none: Ei mitään
|
||||||
comment_description_html: 'Antaakseen lisätietoja %{name} kirjoitti:'
|
comment_description_html: 'Antaakseen lisätietoja %{name} kirjoitti:'
|
||||||
@@ -725,7 +725,7 @@ fi:
|
|||||||
resolved_msg: Raportin ratkaisu onnistui!
|
resolved_msg: Raportin ratkaisu onnistui!
|
||||||
skip_to_actions: Siirry toimiin
|
skip_to_actions: Siirry toimiin
|
||||||
status: Tila
|
status: Tila
|
||||||
statuses: Julkaisut
|
statuses: Julkaisut (%{count})
|
||||||
statuses_description_html: Loukkaava sisältö mainitaan raportoidun tilin yhteydessä
|
statuses_description_html: Loukkaava sisältö mainitaan raportoidun tilin yhteydessä
|
||||||
summary:
|
summary:
|
||||||
action_preambles:
|
action_preambles:
|
||||||
@@ -2090,7 +2090,7 @@ fi:
|
|||||||
subject: Kaksivaiheisen todennuksen virhe
|
subject: Kaksivaiheisen todennuksen virhe
|
||||||
title: Kaksivaiheisen todennuksen toinen vaihe epäonnistui
|
title: Kaksivaiheisen todennuksen toinen vaihe epäonnistui
|
||||||
suspicious_sign_in:
|
suspicious_sign_in:
|
||||||
change_password: vaihda salasanasi
|
change_password: vaihdat salasanasi
|
||||||
details: 'Tässä on tiedot kirjautumisesta:'
|
details: 'Tässä on tiedot kirjautumisesta:'
|
||||||
explanation: Olemme havainneet kirjautumisen tilillesi uudesta IP-osoitteesta.
|
explanation: Olemme havainneet kirjautumisen tilillesi uudesta IP-osoitteesta.
|
||||||
further_actions_html: Jos tämä et ollut sinä, suosittelemme, että %{action} heti ja otat käyttöön kaksivaiheisen todennuksen pitääksesi tilisi turvassa.
|
further_actions_html: Jos tämä et ollut sinä, suosittelemme, että %{action} heti ja otat käyttöön kaksivaiheisen todennuksen pitääksesi tilisi turvassa.
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ fo:
|
|||||||
label: Broyt leiklut
|
label: Broyt leiklut
|
||||||
no_role: Eingin leiklutur
|
no_role: Eingin leiklutur
|
||||||
title: Broyt leiklut hjá %{username}
|
title: Broyt leiklut hjá %{username}
|
||||||
|
collections: Søvn
|
||||||
confirm: Vátta
|
confirm: Vátta
|
||||||
confirmed: Váttað
|
confirmed: Váttað
|
||||||
confirming: Váttar
|
confirming: Váttar
|
||||||
@@ -337,6 +338,12 @@ fo:
|
|||||||
unpublish: Tak útgávu aftur
|
unpublish: Tak útgávu aftur
|
||||||
unpublished_msg: Kunngerð tikin aftur!
|
unpublished_msg: Kunngerð tikin aftur!
|
||||||
updated_msg: Kunngerð dagførd!
|
updated_msg: Kunngerð dagførd!
|
||||||
|
collections:
|
||||||
|
accounts: Kontur
|
||||||
|
collection_title: Savn hjá %{name}
|
||||||
|
contents: Innihald
|
||||||
|
open: Opin
|
||||||
|
view_publicly: Vís fyri øllum
|
||||||
critical_update_pending: Kritisk dagføring bíðar
|
critical_update_pending: Kritisk dagføring bíðar
|
||||||
custom_emojis:
|
custom_emojis:
|
||||||
assign_category: Tilluta bólk
|
assign_category: Tilluta bólk
|
||||||
@@ -676,6 +683,7 @@ fo:
|
|||||||
cancel: Angra
|
cancel: Angra
|
||||||
category: Bólkur
|
category: Bólkur
|
||||||
category_description_html: Orsøkin, at hendan kontan og/ella tilfarið var melda verður fráboðað í samskifti við meldaðu kontuni
|
category_description_html: Orsøkin, at hendan kontan og/ella tilfarið var melda verður fráboðað í samskifti við meldaðu kontuni
|
||||||
|
collections: Søvn
|
||||||
comment:
|
comment:
|
||||||
none: Eingin
|
none: Eingin
|
||||||
comment_description_html: 'Fyri at veita fleiri upplýsingar skrivaði %{name}:'
|
comment_description_html: 'Fyri at veita fleiri upplýsingar skrivaði %{name}:'
|
||||||
@@ -705,11 +713,13 @@ fo:
|
|||||||
report: 'Melding #%{id}'
|
report: 'Melding #%{id}'
|
||||||
reported_account: Meldað konta
|
reported_account: Meldað konta
|
||||||
reported_by: Meldað av
|
reported_by: Meldað av
|
||||||
|
reported_content: Meldað innihald
|
||||||
reported_with_application: Fráboðað við umsókn
|
reported_with_application: Fráboðað við umsókn
|
||||||
resolved: Loyst
|
resolved: Loyst
|
||||||
resolved_msg: Melding avgreidd!
|
resolved_msg: Melding avgreidd!
|
||||||
skip_to_actions: Leyp til atgerðir
|
skip_to_actions: Leyp til atgerðir
|
||||||
status: Støða
|
status: Støða
|
||||||
|
statuses: Postar
|
||||||
statuses_description_html: Tilfarið, sum brotið viðvíkur, fer at vera siterað í samskifti við meldaðu kontuni
|
statuses_description_html: Tilfarið, sum brotið viðvíkur, fer at vera siterað í samskifti við meldaðu kontuni
|
||||||
summary:
|
summary:
|
||||||
action_preambles:
|
action_preambles:
|
||||||
|
|||||||
@@ -692,7 +692,7 @@ fr-CA:
|
|||||||
cancel: Annuler
|
cancel: Annuler
|
||||||
category: Catégorie
|
category: Catégorie
|
||||||
category_description_html: La raison pour laquelle ce compte et/ou ce contenu a été signalé sera citée dans la communication avec le compte signalé
|
category_description_html: La raison pour laquelle ce compte et/ou ce contenu a été signalé sera citée dans la communication avec le compte signalé
|
||||||
collections: Collections
|
collections: Collections (%{count})
|
||||||
comment:
|
comment:
|
||||||
none: Aucun
|
none: Aucun
|
||||||
comment_description_html: 'Pour fournir plus d''informations, %{name} a écrit :'
|
comment_description_html: 'Pour fournir plus d''informations, %{name} a écrit :'
|
||||||
@@ -728,7 +728,7 @@ fr-CA:
|
|||||||
resolved_msg: Signalement résolu avec succès !
|
resolved_msg: Signalement résolu avec succès !
|
||||||
skip_to_actions: Passer aux actions
|
skip_to_actions: Passer aux actions
|
||||||
status: Statut
|
status: Statut
|
||||||
statuses: Messages
|
statuses: Messages (%{count})
|
||||||
statuses_description_html: Le contenu offensant sera cité dans la communication avec le compte signalé
|
statuses_description_html: Le contenu offensant sera cité dans la communication avec le compte signalé
|
||||||
summary:
|
summary:
|
||||||
action_preambles:
|
action_preambles:
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ fr:
|
|||||||
collections: Collections
|
collections: Collections
|
||||||
confirm: Confirmer
|
confirm: Confirmer
|
||||||
confirmed: Confirmé
|
confirmed: Confirmé
|
||||||
confirming: Confirmation
|
confirming: Confirmation en attente
|
||||||
custom: Personnaliser
|
custom: Personnaliser
|
||||||
delete: Supprimer les données
|
delete: Supprimer les données
|
||||||
deleted: Supprimé
|
deleted: Supprimé
|
||||||
@@ -692,7 +692,7 @@ fr:
|
|||||||
cancel: Annuler
|
cancel: Annuler
|
||||||
category: Catégorie
|
category: Catégorie
|
||||||
category_description_html: La raison pour laquelle ce compte et/ou ce contenu a été signalé sera citée dans la communication avec le compte signalé
|
category_description_html: La raison pour laquelle ce compte et/ou ce contenu a été signalé sera citée dans la communication avec le compte signalé
|
||||||
collections: Collections
|
collections: Collections (%{count})
|
||||||
comment:
|
comment:
|
||||||
none: Aucun
|
none: Aucun
|
||||||
comment_description_html: 'Pour fournir plus d''informations, %{name} a écrit :'
|
comment_description_html: 'Pour fournir plus d''informations, %{name} a écrit :'
|
||||||
@@ -728,7 +728,7 @@ fr:
|
|||||||
resolved_msg: Signalement résolu avec succès !
|
resolved_msg: Signalement résolu avec succès !
|
||||||
skip_to_actions: Passer aux actions
|
skip_to_actions: Passer aux actions
|
||||||
status: Statut
|
status: Statut
|
||||||
statuses: Messages
|
statuses: Messages (%{count})
|
||||||
statuses_description_html: Le contenu offensant sera cité dans la communication avec le compte signalé
|
statuses_description_html: Le contenu offensant sera cité dans la communication avec le compte signalé
|
||||||
summary:
|
summary:
|
||||||
action_preambles:
|
action_preambles:
|
||||||
|
|||||||
@@ -731,7 +731,7 @@ ga:
|
|||||||
cancel: Cealaigh
|
cancel: Cealaigh
|
||||||
category: Catagóir
|
category: Catagóir
|
||||||
category_description_html: Luafar an chúis ar tuairiscíodh an cuntas seo agus/nó an t-ábhar seo i gcumarsáid leis an gcuntas tuairiscithe
|
category_description_html: Luafar an chúis ar tuairiscíodh an cuntas seo agus/nó an t-ábhar seo i gcumarsáid leis an gcuntas tuairiscithe
|
||||||
collections: Bailiúcháin
|
collections: Bailiúcháin (%{count})
|
||||||
comment:
|
comment:
|
||||||
none: Dada
|
none: Dada
|
||||||
comment_description_html: 'Chun tuilleadh eolais a sholáthar, scríobh %{name}:'
|
comment_description_html: 'Chun tuilleadh eolais a sholáthar, scríobh %{name}:'
|
||||||
@@ -767,7 +767,7 @@ ga:
|
|||||||
resolved_msg: D'éirigh le réiteach an tuairisc!
|
resolved_msg: D'éirigh le réiteach an tuairisc!
|
||||||
skip_to_actions: Léim ar ghníomhartha
|
skip_to_actions: Léim ar ghníomhartha
|
||||||
status: Stádas
|
status: Stádas
|
||||||
statuses: Poist
|
statuses: Poist (%{count})
|
||||||
statuses_description_html: Luafar ábhar ciontach i gcumarsáid leis an gcuntas tuairiscithe
|
statuses_description_html: Luafar ábhar ciontach i gcumarsáid leis an gcuntas tuairiscithe
|
||||||
summary:
|
summary:
|
||||||
action_preambles:
|
action_preambles:
|
||||||
|
|||||||
@@ -689,7 +689,7 @@ gl:
|
|||||||
cancel: Cancelar
|
cancel: Cancelar
|
||||||
category: Categoría
|
category: Categoría
|
||||||
category_description_html: A razón para denunciar esta conta ou contido será citada na comunicación coa conta denunciada
|
category_description_html: A razón para denunciar esta conta ou contido será citada na comunicación coa conta denunciada
|
||||||
collections: Coleccións
|
collections: Coleccións (%{count})
|
||||||
comment:
|
comment:
|
||||||
none: Ningún
|
none: Ningún
|
||||||
comment_description_html: 'Como información engadida, %{name} escribiu:'
|
comment_description_html: 'Como información engadida, %{name} escribiu:'
|
||||||
@@ -725,7 +725,7 @@ gl:
|
|||||||
resolved_msg: Resolveuse con éxito a denuncia!
|
resolved_msg: Resolveuse con éxito a denuncia!
|
||||||
skip_to_actions: Ir a accións
|
skip_to_actions: Ir a accións
|
||||||
status: Estado
|
status: Estado
|
||||||
statuses: Publicacións
|
statuses: Publicacións (%{count})
|
||||||
statuses_description_html: O contido ofensivo será citado na comunicación coa conta denunciada
|
statuses_description_html: O contido ofensivo será citado na comunicación coa conta denunciada
|
||||||
summary:
|
summary:
|
||||||
action_preambles:
|
action_preambles:
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ he:
|
|||||||
label: שינוי תפקיד
|
label: שינוי תפקיד
|
||||||
no_role: ללא תפקיד
|
no_role: ללא תפקיד
|
||||||
title: שינוי תפקיד עבור %{username}
|
title: שינוי תפקיד עבור %{username}
|
||||||
|
collections: אוספים
|
||||||
confirm: אישור
|
confirm: אישור
|
||||||
confirmed: אושר
|
confirmed: אושר
|
||||||
confirming: בתהליך אישור
|
confirming: בתהליך אישור
|
||||||
@@ -348,6 +349,17 @@ he:
|
|||||||
unpublish: ביטול פרסום
|
unpublish: ביטול פרסום
|
||||||
unpublished_msg: פרסום ההכרזה בוטל בהצלחה!
|
unpublished_msg: פרסום ההכרזה בוטל בהצלחה!
|
||||||
updated_msg: ההכרזה עודכנה בהצלחה!
|
updated_msg: ההכרזה עודכנה בהצלחה!
|
||||||
|
collections:
|
||||||
|
accounts: חשבונות
|
||||||
|
collection_title: אוספים מאת %{name}
|
||||||
|
contents: תוכן
|
||||||
|
number_of_accounts:
|
||||||
|
many: "%{count} חשבונות"
|
||||||
|
one: חשבון אחד
|
||||||
|
other: "%{count} חשבונות"
|
||||||
|
two: חשבונותיים
|
||||||
|
open: פתיחה
|
||||||
|
view_publicly: צפיה בפומבי
|
||||||
critical_update_pending: עידכון קריטי ממתין
|
critical_update_pending: עידכון קריטי ממתין
|
||||||
custom_emojis:
|
custom_emojis:
|
||||||
assign_category: הקצאת קטגוריה
|
assign_category: הקצאת קטגוריה
|
||||||
@@ -705,6 +717,7 @@ he:
|
|||||||
cancel: ביטול
|
cancel: ביטול
|
||||||
category: קטגוריה
|
category: קטגוריה
|
||||||
category_description_html: הסיבה בגללה חשבון זה ו/או תוכנו דווחו תצוטט בתקשורת עם החשבון המדווח
|
category_description_html: הסיבה בגללה חשבון זה ו/או תוכנו דווחו תצוטט בתקשורת עם החשבון המדווח
|
||||||
|
collections: אוספים
|
||||||
comment:
|
comment:
|
||||||
none: ללא
|
none: ללא
|
||||||
comment_description_html: 'על מנת לספק עוד מידע, %{name} כתב\ה:'
|
comment_description_html: 'על מנת לספק עוד מידע, %{name} כתב\ה:'
|
||||||
@@ -734,11 +747,13 @@ he:
|
|||||||
report: 'דווח על #%{id}'
|
report: 'דווח על #%{id}'
|
||||||
reported_account: חשבון מדווח
|
reported_account: חשבון מדווח
|
||||||
reported_by: דווח על ידי
|
reported_by: דווח על ידי
|
||||||
|
reported_content: התוכן עליו דווח
|
||||||
reported_with_application: דיווחים באמצעות יישומון
|
reported_with_application: דיווחים באמצעות יישומון
|
||||||
resolved: פתור
|
resolved: פתור
|
||||||
resolved_msg: הדו"ח נפתר בהצלחה!
|
resolved_msg: הדו"ח נפתר בהצלחה!
|
||||||
skip_to_actions: דלג/י לפעולות
|
skip_to_actions: דלג/י לפעולות
|
||||||
status: מצב
|
status: מצב
|
||||||
|
statuses: הודעות
|
||||||
statuses_description_html: התוכן הפוגע יצוטט בתקשורת עם החשבון המדווח
|
statuses_description_html: התוכן הפוגע יצוטט בתקשורת עם החשבון המדווח
|
||||||
summary:
|
summary:
|
||||||
action_preambles:
|
action_preambles:
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user