Merge remote-tracking branch 'origin/develop' into accounts-scss
This commit is contained in:
commit
d3f93d0325
|
@ -9,7 +9,7 @@
|
|||
"declaration-block-no-redundant-longhand-properties": null,
|
||||
"declaration-colon-newline-after": null,
|
||||
"declaration-empty-line-before": "never",
|
||||
"font-family-no-missing-generic-family-keyword": [true, { "ignoreFontFamilies": ["ForkAwesome", "Font Awesome 5 Free", "OpenDyslexic", "soapbox"] }],
|
||||
"font-family-no-missing-generic-family-keyword": [true, { "ignoreFontFamilies": ["ForkAwesome", "Font Awesome 5 Free"] }],
|
||||
"max-line-length": null,
|
||||
"no-descending-specificity": null,
|
||||
"no-duplicate-selectors": null,
|
||||
|
|
|
@ -1 +1 @@
|
|||
nodejs 18.12.1
|
||||
nodejs 18.13.0
|
||||
|
|
|
@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
### Changed
|
||||
- Posts: letterbox images to 19:6 again.
|
||||
- Status Info: moved context (repost, pinned) to improve UX.
|
||||
- Posts: remove file icon from empty link previews.
|
||||
|
||||
### Fixed
|
||||
- Layout: use accent color for "floating action button" (mobile compose button).
|
||||
|
@ -29,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Modals: close modal when navigating to a different page.
|
||||
- Modals: fix "View context" button in media modal.
|
||||
- Posts: let unauthenticated users to translate posts if allowed by backend.
|
||||
- Chats: fix jumpy scrollbar.
|
||||
|
||||
## [3.0.0] - 2022-12-25
|
||||
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
import loadPolyfills from './soapbox/load-polyfills';
|
||||
|
||||
// Load iframe event listener
|
||||
require('./soapbox/iframe');
|
||||
|
||||
// @ts-ignore
|
||||
require.context('./assets/images/', true);
|
||||
|
||||
// Load stylesheet
|
||||
require('react-datepicker/dist/react-datepicker.css');
|
||||
require('./styles/application.scss');
|
||||
|
||||
loadPolyfills().then(() => {
|
||||
require('./soapbox/main').default();
|
||||
}).catch(e => {
|
||||
console.error(e);
|
||||
});
|
|
@ -1,94 +0,0 @@
|
|||
Copyright (c) 2019-07-29, Abbie Gonzalez (https://abbiecod.es|support@abbiecod.es),
|
||||
with Reserved Font Name OpenDyslexic.
|
||||
Copyright (c) 12/2012 - 2019
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -10,10 +10,10 @@ import {
|
|||
} from './importer';
|
||||
|
||||
import type { AxiosError, CancelToken } from 'axios';
|
||||
import type { History } from 'history';
|
||||
import type { Map as ImmutableMap } from 'immutable';
|
||||
import type { AppDispatch, RootState } from 'soapbox/store';
|
||||
import type { APIEntity, Status } from 'soapbox/types/entities';
|
||||
import type { History } from 'soapbox/types/history';
|
||||
|
||||
const ACCOUNT_CREATE_REQUEST = 'ACCOUNT_CREATE_REQUEST';
|
||||
const ACCOUNT_CREATE_SUCCESS = 'ACCOUNT_CREATE_SUCCESS';
|
||||
|
|
|
@ -6,8 +6,8 @@ import { getFeatures } from 'soapbox/utils/features';
|
|||
|
||||
import api, { getLinks } from '../api';
|
||||
|
||||
import type { History } from 'history';
|
||||
import type { AppDispatch, RootState } from 'soapbox/store';
|
||||
import type { History } from 'soapbox/types/history';
|
||||
|
||||
const CHATS_FETCH_REQUEST = 'CHATS_FETCH_REQUEST';
|
||||
const CHATS_FETCH_SUCCESS = 'CHATS_FETCH_SUCCESS';
|
||||
|
|
|
@ -19,11 +19,11 @@ import { openModal, closeModal } from './modals';
|
|||
import { getSettings } from './settings';
|
||||
import { createStatus } from './statuses';
|
||||
|
||||
import type { History } from 'history';
|
||||
import type { Emoji } from 'soapbox/components/autosuggest-emoji';
|
||||
import type { AutoSuggestion } from 'soapbox/components/autosuggest-input';
|
||||
import type { AppDispatch, RootState } from 'soapbox/store';
|
||||
import type { Account, APIEntity, Status, Tag } from 'soapbox/types/entities';
|
||||
import type { History } from 'soapbox/types/history';
|
||||
|
||||
const { CancelToken, isCancel } = axios;
|
||||
|
||||
|
|
|
@ -107,7 +107,10 @@ const updateNotificationsQueue = (notification: APIEntity, intlMessages: Record<
|
|||
|
||||
// Desktop notifications
|
||||
try {
|
||||
if (showAlert && !filtered) {
|
||||
// eslint-disable-next-line compat/compat
|
||||
const isNotificationsEnabled = window.Notification?.permission === 'granted';
|
||||
|
||||
if (showAlert && !filtered && isNotificationsEnabled) {
|
||||
const title = new IntlMessageFormat(intlMessages[`notification.${notification.type}`], intlLocale).format({ name: notification.account.display_name.length > 0 ? notification.account.display_name : notification.account.username });
|
||||
const body = (notification.status && notification.status.spoiler_text.length > 0) ? notification.status.spoiler_text : unescapeHTML(notification.status ? notification.status.content : '');
|
||||
|
||||
|
|
|
@ -47,7 +47,6 @@ const defaultSettings = ImmutableMap({
|
|||
autoloadMore: true,
|
||||
|
||||
systemFont: false,
|
||||
dyslexicFont: false,
|
||||
demetricator: false,
|
||||
|
||||
isDeveloper: false,
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
import 'intl';
|
||||
import 'intl/locale-data/jsonp/en';
|
||||
import 'es6-symbol/implement';
|
||||
// @ts-ignore: No types
|
||||
import includes from 'array-includes';
|
||||
// @ts-ignore: No types
|
||||
import isNaN from 'is-nan';
|
||||
import assign from 'object-assign';
|
||||
// @ts-ignore: No types
|
||||
import values from 'object.values';
|
||||
|
||||
import { decode as decodeBase64 } from './utils/base64';
|
||||
|
||||
if (!Array.prototype.includes) {
|
||||
includes.shim();
|
||||
}
|
||||
|
||||
if (!Object.assign) {
|
||||
Object.assign = assign;
|
||||
}
|
||||
|
||||
if (!Object.values) {
|
||||
values.shim();
|
||||
}
|
||||
|
||||
if (!Number.isNaN) {
|
||||
Number.isNaN = isNaN;
|
||||
}
|
||||
|
||||
if (!HTMLCanvasElement.prototype.toBlob) {
|
||||
const BASE64_MARKER = ';base64,';
|
||||
|
||||
Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {
|
||||
value(callback: any, type = 'image/png', quality: any) {
|
||||
const dataURL = this.toDataURL(type, quality);
|
||||
let data;
|
||||
|
||||
if (dataURL.includes(BASE64_MARKER)) {
|
||||
const [, base64] = dataURL.split(BASE64_MARKER);
|
||||
data = decodeBase64(base64);
|
||||
} else {
|
||||
[, data] = dataURL.split(',');
|
||||
}
|
||||
|
||||
callback(new Blob([data], { type }));
|
||||
},
|
||||
});
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
import React from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { unblockDomain } from 'soapbox/actions/domain-blocks';
|
||||
import { useAppDispatch } from 'soapbox/hooks';
|
||||
|
||||
import { HStack, IconButton, Text } from './ui';
|
||||
|
||||
|
@ -16,7 +16,7 @@ interface IDomain {
|
|||
}
|
||||
|
||||
const Domain: React.FC<IDomain> = ({ domain }) => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const intl = useIntl();
|
||||
|
||||
// const onBlockDomain = () => {
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import classNames from 'clsx';
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import { usePopper } from 'react-popper';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { simpleEmojiReact } from 'soapbox/actions/emoji-reacts';
|
||||
import { openModal } from 'soapbox/actions/modals';
|
||||
import { EmojiSelector } from 'soapbox/components/ui';
|
||||
import { useAppSelector, useOwnAccount, useSoapboxConfig } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useAppSelector, useOwnAccount, useSoapboxConfig } from 'soapbox/hooks';
|
||||
import { isUserTouching } from 'soapbox/is-mobile';
|
||||
import { getReactForStatus } from 'soapbox/utils/emoji-reacts';
|
||||
|
||||
|
@ -17,7 +16,7 @@ interface IEmojiButtonWrapper {
|
|||
|
||||
/** Provides emoji reaction functionality to the underlying button component */
|
||||
const EmojiButtonWrapper: React.FC<IEmojiButtonWrapper> = ({ statusId, children }): JSX.Element | null => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const ownAccount = useOwnAccount();
|
||||
const status = useAppSelector(state => state.statuses.get(statusId));
|
||||
const soapboxConfig = useSoapboxConfig();
|
||||
|
|
|
@ -90,7 +90,7 @@ const IconButton: React.FC<IIconButton> = ({
|
|||
type='button'
|
||||
>
|
||||
<div>
|
||||
<Icon className={iconClassName} src={src} fixedWidth aria-hidden='true' />
|
||||
<Icon className={iconClassName} src={src} aria-hidden='true' />
|
||||
</div>
|
||||
{text && <span className='icon-button__text'>{text}</span>}
|
||||
</button>
|
||||
|
|
|
@ -1,27 +1,28 @@
|
|||
/**
|
||||
* Icon: abstract icon class that can render icons from multiple sets.
|
||||
* Icon: abstact component to render SVG icons.
|
||||
* @module soapbox/components/icon
|
||||
* @see soapbox/components/fork_awesome_icon
|
||||
* @see soapbox/components/svg_icon
|
||||
*/
|
||||
|
||||
import classNames from 'clsx';
|
||||
import React from 'react';
|
||||
import InlineSVG from 'react-inlinesvg'; // eslint-disable-line no-restricted-imports
|
||||
|
||||
import ForkAwesomeIcon, { IForkAwesomeIcon } from './fork-awesome-icon';
|
||||
import SvgIcon, { ISvgIcon } from './svg-icon';
|
||||
export interface IIcon extends React.HTMLAttributes<HTMLDivElement> {
|
||||
src: string,
|
||||
id?: string,
|
||||
alt?: string,
|
||||
className?: string,
|
||||
}
|
||||
|
||||
export type IIcon = IForkAwesomeIcon | ISvgIcon;
|
||||
|
||||
const Icon: React.FC<IIcon> = (props) => {
|
||||
if ((props as ISvgIcon).src) {
|
||||
const { src, ...rest } = (props as ISvgIcon);
|
||||
|
||||
return <SvgIcon src={src} {...rest} />;
|
||||
} else {
|
||||
const { id, fixedWidth, ...rest } = (props as IForkAwesomeIcon);
|
||||
|
||||
return <ForkAwesomeIcon id={id} fixedWidth={fixedWidth} {...rest} />;
|
||||
}
|
||||
const Icon: React.FC<IIcon> = ({ src, alt, className, ...rest }) => {
|
||||
return (
|
||||
<div
|
||||
className={classNames('svg-icon', className)}
|
||||
{...rest}
|
||||
>
|
||||
<InlineSVG src={src} title={alt} loader={<></>} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Icon;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import classNames from 'clsx';
|
||||
import React, { useState, useRef, useEffect } from 'react';
|
||||
import React, { useState, useRef, useLayoutEffect } from 'react';
|
||||
|
||||
import Blurhash from 'soapbox/components/blurhash';
|
||||
import Icon from 'soapbox/components/icon';
|
||||
|
@ -533,7 +533,7 @@ const MediaGallery: React.FC<IMediaGallery> = (props) => {
|
|||
/>
|
||||
));
|
||||
|
||||
useEffect(() => {
|
||||
useLayoutEffect(() => {
|
||||
if (node.current) {
|
||||
const { offsetWidth } = node.current;
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ import { useAppDispatch, usePrevious } from 'soapbox/hooks';
|
|||
import { queryClient } from 'soapbox/queries/client';
|
||||
import { IPolicy, PolicyKeys } from 'soapbox/queries/policies';
|
||||
|
||||
import type { UnregisterCallback } from 'history';
|
||||
import type { ModalType } from 'soapbox/features/ui/components/modal-root';
|
||||
import type { ReducerCompose } from 'soapbox/reducers/compose';
|
||||
import type { ReducerRecord as ReducerComposeEvent } from 'soapbox/reducers/compose-event';
|
||||
|
@ -55,7 +54,7 @@ const ModalRoot: React.FC<IModalRoot> = ({ children, onCancel, onClose, type })
|
|||
const ref = useRef<HTMLDivElement>(null);
|
||||
const activeElement = useRef<HTMLDivElement | null>(revealed ? document.activeElement as HTMLDivElement | null : null);
|
||||
const modalHistoryKey = useRef<number>();
|
||||
const unlistenHistory = useRef<UnregisterCallback>();
|
||||
const unlistenHistory = useRef<ReturnType<typeof history.listen>>();
|
||||
|
||||
const prevChildren = usePrevious(children);
|
||||
const prevType = usePrevious(type);
|
||||
|
|
|
@ -24,13 +24,13 @@ type SavedScrollPosition = {
|
|||
// NOTE: It's crucial to space lists with **padding** instead of margin!
|
||||
// Pass an `itemClassName` like `pb-3`, NOT a `space-y-3` className
|
||||
// https://virtuoso.dev/troubleshooting#list-does-not-scroll-to-the-bottom--items-jump-around
|
||||
const Item: Components<Context>['Item'] = ({ context, ...rest }) => (
|
||||
const Item: Components<JSX.Element, Context>['Item'] = ({ context, ...rest }) => (
|
||||
<div className={context?.itemClassName} {...rest} />
|
||||
);
|
||||
|
||||
/** Custom Virtuoso List component for the outer container. */
|
||||
// Ensure the className winds up here
|
||||
const List: Components<Context>['List'] = React.forwardRef((props, ref) => {
|
||||
const List: Components<JSX.Element, Context>['List'] = React.forwardRef((props, ref) => {
|
||||
const { context, ...rest } = props;
|
||||
return <div ref={ref} className={context?.listClassName} {...rest} />;
|
||||
});
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
import classNames from 'clsx';
|
||||
import React from 'react';
|
||||
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { Link, NavLink } from 'react-router-dom';
|
||||
|
||||
import { fetchOwnAccounts, logOut, switchAccount } from 'soapbox/actions/auth';
|
||||
|
@ -11,7 +10,7 @@ import { closeSidebar } from 'soapbox/actions/sidebar';
|
|||
import Account from 'soapbox/components/account';
|
||||
import { Stack } from 'soapbox/components/ui';
|
||||
import ProfileStats from 'soapbox/features/ui/components/profile-stats';
|
||||
import { useAppSelector, useFeatures } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useAppSelector, useFeatures } from 'soapbox/hooks';
|
||||
import { makeGetAccount, makeGetOtherAccounts } from 'soapbox/selectors';
|
||||
|
||||
import { Divider, HStack, Icon, IconButton, Text } from './ui';
|
||||
|
@ -81,7 +80,7 @@ const getOtherAccounts = makeGetOtherAccounts();
|
|||
|
||||
const SidebarMenu: React.FC = (): JSX.Element | null => {
|
||||
const intl = useIntl();
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const features = useFeatures();
|
||||
const getAccount = makeGetAccount();
|
||||
|
|
|
@ -26,7 +26,7 @@ interface IReadMoreButton {
|
|||
const ReadMoreButton: React.FC<IReadMoreButton> = ({ onClick }) => (
|
||||
<button className='flex items-center text-gray-900 dark:text-gray-300 border-0 bg-transparent p-0 pt-2 hover:underline active:underline' onClick={onClick}>
|
||||
<FormattedMessage id='status.read_more' defaultMessage='Read more' />
|
||||
<Icon className='inline-block h-5 w-5' src={require('@tabler/icons/chevron-right.svg')} fixedWidth />
|
||||
<Icon className='inline-block h-5 w-5' src={require('@tabler/icons/chevron-right.svg')} />
|
||||
</button>
|
||||
);
|
||||
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
/**
|
||||
* SvgIcon: abstact component to render SVG icons.
|
||||
* @module soapbox/components/svg_icon
|
||||
* @see soapbox/components/icon
|
||||
*/
|
||||
|
||||
import classNames from 'clsx';
|
||||
import React from 'react';
|
||||
import InlineSVG from 'react-inlinesvg'; // eslint-disable-line no-restricted-imports
|
||||
|
||||
export interface ISvgIcon extends React.HTMLAttributes<HTMLDivElement> {
|
||||
src: string,
|
||||
id?: string,
|
||||
alt?: string,
|
||||
className?: string,
|
||||
}
|
||||
|
||||
const SvgIcon: React.FC<ISvgIcon> = ({ src, alt, className, ...rest }) => {
|
||||
return (
|
||||
<div
|
||||
className={classNames('svg-icon', className)}
|
||||
{...rest}
|
||||
>
|
||||
<InlineSVG src={src} title={alt} loader={<></>} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SvgIcon;
|
|
@ -27,7 +27,7 @@ const FormGroup: React.FC<IFormGroup> = (props) => {
|
|||
if (React.isValidElement(inputChildren[0])) {
|
||||
firstChild = React.cloneElement(
|
||||
inputChildren[0],
|
||||
{ id: formFieldId, hasError },
|
||||
{ id: formFieldId },
|
||||
);
|
||||
}
|
||||
const isCheckboxFormGroup = firstChild?.type === Checkbox;
|
||||
|
|
|
@ -33,8 +33,6 @@ interface IInput extends Pick<React.InputHTMLAttributes<HTMLInputElement>, 'maxL
|
|||
value?: string | number,
|
||||
/** Change event handler for the input. */
|
||||
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void,
|
||||
/** Whether to display the input in red. */
|
||||
hasError?: boolean,
|
||||
/** An element to display as prefix to input. Cannot be used with icon. */
|
||||
prepend?: React.ReactElement,
|
||||
/** An element to display as suffix to input. Cannot be used with password type. */
|
||||
|
@ -48,7 +46,7 @@ const Input = React.forwardRef<HTMLInputElement, IInput>(
|
|||
(props, ref) => {
|
||||
const intl = useIntl();
|
||||
|
||||
const { type = 'text', icon, className, outerClassName, hasError, append, prepend, theme = 'normal', ...filteredProps } = props;
|
||||
const { type = 'text', icon, className, outerClassName, append, prepend, theme = 'normal', ...filteredProps } = props;
|
||||
|
||||
const [revealed, setRevealed] = React.useState(false);
|
||||
|
||||
|
@ -91,7 +89,6 @@ const Input = React.forwardRef<HTMLInputElement, IInput>(
|
|||
'rounded-md bg-white dark:bg-gray-900 border-gray-400 dark:border-gray-800': theme === 'normal',
|
||||
'rounded-full bg-gray-200 border-gray-200 dark:bg-gray-800 dark:border-gray-800 focus:bg-white': theme === 'search',
|
||||
'pr-7 rtl:pl-7 rtl:pr-3': isPassword || append,
|
||||
'text-red-600 border-red-600': hasError,
|
||||
'pl-8': typeof icon !== 'undefined',
|
||||
'pl-16': typeof prepend !== 'undefined',
|
||||
}, className)}
|
||||
|
|
|
@ -271,7 +271,6 @@ const SoapboxHead: React.FC<ISoapboxHead> = ({ children }) => {
|
|||
const bodyClass = classNames('bg-white dark:bg-gray-800 text-base h-full', {
|
||||
'no-reduce-motion': !settings.get('reduceMotion'),
|
||||
'underline-links': settings.get('underlineLinks'),
|
||||
'dyslexic': settings.get('dyslexicFont'),
|
||||
'demetricator': settings.get('demetricator'),
|
||||
});
|
||||
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useHistory, useParams } from 'react-router-dom';
|
||||
|
||||
import { toggleMainWindow } from 'soapbox/actions/chats';
|
||||
import { useOwnAccount, useSettings } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useOwnAccount, useSettings } from 'soapbox/hooks';
|
||||
import { IChat, useChat } from 'soapbox/queries/chats';
|
||||
|
||||
type WindowState = 'open' | 'minimized';
|
||||
|
@ -22,7 +21,7 @@ enum ChatWidgetScreens {
|
|||
|
||||
const ChatProvider: React.FC = ({ children }) => {
|
||||
const history = useHistory();
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const settings = useSettings();
|
||||
const account = useOwnAccount();
|
||||
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
import 'intersection-observer';
|
||||
import 'requestidlecallback';
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { useParams } from 'react-router-dom';
|
||||
|
||||
|
@ -66,10 +66,7 @@ const AccountGallery = () => {
|
|||
const hasMore = useAppSelector((state) => state.timelines.get(`account:${accountId}:media`)?.hasMore);
|
||||
|
||||
const [width, setWidth] = useState(323);
|
||||
|
||||
const handleRef = (c: HTMLDivElement) => {
|
||||
if (c) setWidth(c.offsetWidth);
|
||||
};
|
||||
const node = useRef<HTMLDivElement>(null);
|
||||
|
||||
const handleScrollToBottom = () => {
|
||||
if (hasMore) {
|
||||
|
@ -99,6 +96,12 @@ const AccountGallery = () => {
|
|||
}
|
||||
};
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (node.current) {
|
||||
setWidth(node.current.offsetWidth);
|
||||
}
|
||||
}, [node.current]);
|
||||
|
||||
useEffect(() => {
|
||||
if (accountId && accountId !== -1) {
|
||||
dispatch(fetchAccount(accountId));
|
||||
|
@ -140,7 +143,7 @@ const AccountGallery = () => {
|
|||
|
||||
return (
|
||||
<Column label={`@${accountUsername}`} transparent withHeader={false}>
|
||||
<div role='feed' className='flex flex-wrap gap-2' ref={handleRef}>
|
||||
<div role='feed' className='flex flex-wrap gap-2' ref={node}>
|
||||
{attachments.map((attachment, index) => attachment === null ? (
|
||||
<LoadMoreMedia key={'more:' + attachments.get(index + 1)?.id} maxId={index > 0 ? (attachments.get(index - 1)?.id || null) : null} onLoadMore={handleLoadMore} />
|
||||
) : (
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import classNames from 'clsx';
|
||||
import React from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { fetchAliasesSuggestions, clearAliasesSuggestions, changeAliasesSuggestions } from 'soapbox/actions/aliases';
|
||||
import Icon from 'soapbox/components/icon';
|
||||
import { Button } from 'soapbox/components/ui';
|
||||
import { useAppSelector } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
||||
|
||||
const messages = defineMessages({
|
||||
search: { id: 'aliases.search', defaultMessage: 'Search your old account' },
|
||||
|
@ -14,7 +13,7 @@ const messages = defineMessages({
|
|||
});
|
||||
|
||||
const Search: React.FC = () => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const intl = useIntl();
|
||||
|
||||
const value = useAppSelector(state => state.aliases.suggestions.value);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import classNames from 'clsx';
|
||||
import debounce from 'lodash/debounce';
|
||||
import throttle from 'lodash/throttle';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
|
||||
import Icon from 'soapbox/components/icon';
|
||||
|
@ -397,7 +397,7 @@ const Audio: React.FC<IAudio> = (props) => {
|
|||
|
||||
const progress = Math.min((currentTime / getDuration()) * 100, 100);
|
||||
|
||||
useEffect(() => {
|
||||
useLayoutEffect(() => {
|
||||
if (player.current) {
|
||||
_setDimensions();
|
||||
}
|
||||
|
|
|
@ -238,7 +238,6 @@ const RegistrationForm: React.FC<IRegistrationForm> = ({ inviteToken }) => {
|
|||
pattern='^[a-zA-Z\d_-]+'
|
||||
onChange={onUsernameChange}
|
||||
value={params.get('username', '')}
|
||||
hasError={usernameUnavailable}
|
||||
required
|
||||
/>
|
||||
</FormGroup>
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import debounce from 'lodash/debounce';
|
||||
import React from 'react';
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { fetchBlocks, expandBlocks } from 'soapbox/actions/blocks';
|
||||
import ScrollableList from 'soapbox/components/scrollable-list';
|
||||
import { Column, Spinner } from 'soapbox/components/ui';
|
||||
import AccountContainer from 'soapbox/containers/account-container';
|
||||
import { useAppSelector } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
||||
|
||||
const messages = defineMessages({
|
||||
heading: { id: 'column.blocks', defaultMessage: 'Blocked users' },
|
||||
|
@ -18,7 +17,7 @@ const handleLoadMore = debounce((dispatch) => {
|
|||
}, 300, { leading: true });
|
||||
|
||||
const Blocks: React.FC = () => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const intl = useIntl();
|
||||
|
||||
const accountIds = useAppSelector((state) => state.user_lists.blocks.items);
|
||||
|
|
|
@ -66,6 +66,21 @@ const List: Components['List'] = React.forwardRef((props, ref) => {
|
|||
return <div ref={ref} {...rest} className='mb-2' />;
|
||||
});
|
||||
|
||||
const Scroller: Components['Scroller'] = React.forwardRef((props, ref) => {
|
||||
const { style, context, ...rest } = props;
|
||||
|
||||
return (
|
||||
<div
|
||||
{...rest}
|
||||
ref={ref}
|
||||
style={{
|
||||
...style,
|
||||
scrollbarGutter: 'stable',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
interface IChatMessageList {
|
||||
/** Chat the messages are being rendered from. */
|
||||
chat: IChat,
|
||||
|
@ -472,6 +487,7 @@ const ChatMessageList: React.FC<IChatMessageList> = ({ chat }) => {
|
|||
}}
|
||||
components={{
|
||||
List,
|
||||
Scroller,
|
||||
Header: () => {
|
||||
if (hasNextPage || isFetchingNextPage) {
|
||||
return <Spinner withText={false} />;
|
||||
|
|
|
@ -6,7 +6,7 @@ import { __stub } from 'soapbox/api';
|
|||
import { normalizeAccount } from 'soapbox/normalizers';
|
||||
import { ReducerAccount } from 'soapbox/reducers/accounts';
|
||||
|
||||
import { render, screen } from '../../../../../jest/test-helpers';
|
||||
import { render, screen, waitFor } from '../../../../../jest/test-helpers';
|
||||
import ChatPage from '../chat-page';
|
||||
|
||||
describe('<ChatPage />', () => {
|
||||
|
@ -48,7 +48,10 @@ describe('<ChatPage />', () => {
|
|||
await userEvent.click(screen.getByTestId('button'));
|
||||
|
||||
expect(screen.getByTestId('chat-page')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('toast')).toHaveTextContent('Chat Settings updated successfully');
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('toast')).toHaveTextContent('Chat Settings updated successfully');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -77,7 +80,10 @@ describe('<ChatPage />', () => {
|
|||
it('renders the Chats', async () => {
|
||||
render(<ChatPage />, undefined, store);
|
||||
await userEvent.click(screen.getByTestId('button'));
|
||||
expect(screen.getByTestId('toast')).toHaveTextContent('Chat Settings failed to update.');
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('toast')).toHaveTextContent('Chat Settings failed to update.');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import classNames from 'clsx';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';
|
||||
import { matchPath, Route, Switch, useHistory } from 'react-router-dom';
|
||||
|
||||
import { Stack } from 'soapbox/components/ui';
|
||||
|
@ -44,7 +44,7 @@ const ChatPage: React.FC<IChatPage> = ({ chatId }) => {
|
|||
setHeight(fullHeight - top + offset);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
useLayoutEffect(() => {
|
||||
calculateHeight();
|
||||
}, [containerRef.current]);
|
||||
|
||||
|
|
|
@ -238,7 +238,7 @@ const ChatPageMain = () => {
|
|||
|
||||
<div className='h-full overflow-hidden'>
|
||||
<Chat
|
||||
className='h-full overflow-hidden'
|
||||
className='h-full'
|
||||
chat={chat}
|
||||
inputRef={inputRef}
|
||||
/>
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
import classNames from 'clsx';
|
||||
import { Map as ImmutableMap } from 'immutable';
|
||||
import debounce from 'lodash/debounce';
|
||||
import React, { useCallback } from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
import {
|
||||
|
@ -17,7 +15,8 @@ import {
|
|||
import AutosuggestAccountInput from 'soapbox/components/autosuggest-account-input';
|
||||
import { Input } from 'soapbox/components/ui';
|
||||
import SvgIcon from 'soapbox/components/ui/icon/svg-icon';
|
||||
import { useAppSelector } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
||||
import { AppDispatch, RootState } from 'soapbox/store';
|
||||
|
||||
const messages = defineMessages({
|
||||
placeholder: { id: 'search.placeholder', defaultMessage: 'Search' },
|
||||
|
@ -25,7 +24,7 @@ const messages = defineMessages({
|
|||
});
|
||||
|
||||
function redirectToAccount(accountId: string, routerHistory: any) {
|
||||
return (_dispatch: any, getState: () => ImmutableMap<string, any>) => {
|
||||
return (_dispatch: AppDispatch, getState: () => RootState) => {
|
||||
const acct = getState().getIn(['accounts', accountId, 'acct']);
|
||||
|
||||
if (acct && routerHistory) {
|
||||
|
@ -49,7 +48,7 @@ const Search = (props: ISearch) => {
|
|||
openInRoute = false,
|
||||
} = props;
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const history = useHistory();
|
||||
const intl = useIntl();
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import React, { useState } from 'react';
|
||||
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { changeSettingImmediate } from 'soapbox/actions/settings';
|
||||
import { Column, Button, Form, FormActions, FormGroup, Input, Text } from 'soapbox/components/ui';
|
||||
import { useAppDispatch } from 'soapbox/hooks';
|
||||
import toast from 'soapbox/toast';
|
||||
|
||||
const messages = defineMessages({
|
||||
|
@ -15,7 +15,7 @@ const messages = defineMessages({
|
|||
});
|
||||
|
||||
const DevelopersChallenge = () => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const intl = useIntl();
|
||||
|
||||
const [answer, setAnswer] = useState('');
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import React from 'react';
|
||||
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { Link, useHistory } from 'react-router-dom';
|
||||
|
||||
import { changeSettingImmediate } from 'soapbox/actions/settings';
|
||||
import { Column, Text } from 'soapbox/components/ui';
|
||||
import SvgIcon from 'soapbox/components/ui/icon/svg-icon';
|
||||
import { useAppDispatch } from 'soapbox/hooks';
|
||||
import toast from 'soapbox/toast';
|
||||
import sourceCode from 'soapbox/utils/code';
|
||||
|
||||
|
@ -31,7 +31,7 @@ const DashWidget: React.FC<IDashWidget> = ({ to, onClick, children }) => {
|
|||
};
|
||||
|
||||
const Developers: React.FC = () => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const history = useHistory();
|
||||
const intl = useIntl();
|
||||
|
||||
|
|
|
@ -134,12 +134,6 @@ const SettingsStore: React.FC = () => {
|
|||
<SettingToggle settings={settings} settingPath={['systemFont']} onChange={onToggleChange} />
|
||||
</ListItem>
|
||||
|
||||
<div className='dyslexic'>
|
||||
<ListItem label={<FormattedMessage id='preferences.fields.dyslexic_font_label' defaultMessage='Dyslexic mode' />}>
|
||||
<SettingToggle settings={settings} settingPath={['dyslexicFont']} onChange={onToggleChange} />
|
||||
</ListItem>
|
||||
</div>
|
||||
|
||||
<ListItem
|
||||
label={<FormattedMessage id='preferences.fields.demetricator_label' defaultMessage='Use Demetricator' />}
|
||||
hint={<FormattedMessage id='preferences.hints.demetricator' defaultMessage='Decrease social media anxiety by hiding all numbers from the site.' />}
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import classNames from 'clsx';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import { fetchDirectory, expandDirectory } from 'soapbox/actions/directory';
|
||||
import LoadMore from 'soapbox/components/load-more';
|
||||
import { Column, RadioButton, Stack, Text } from 'soapbox/components/ui';
|
||||
import { useAppSelector, useFeatures, useInstance } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useAppSelector, useFeatures, useInstance } from 'soapbox/hooks';
|
||||
|
||||
import AccountCard from './components/account-card';
|
||||
|
||||
|
@ -21,7 +20,7 @@ const messages = defineMessages({
|
|||
|
||||
const Directory = () => {
|
||||
const intl = useIntl();
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const { search } = useLocation();
|
||||
const params = new URLSearchParams(search);
|
||||
const instance = useInstance();
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import debounce from 'lodash/debounce';
|
||||
import React from 'react';
|
||||
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { fetchDomainBlocks, expandDomainBlocks } from 'soapbox/actions/domain-blocks';
|
||||
import Domain from 'soapbox/components/domain';
|
||||
import ScrollableList from 'soapbox/components/scrollable-list';
|
||||
import { Column, Spinner } from 'soapbox/components/ui';
|
||||
import { useAppSelector } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
||||
|
||||
const messages = defineMessages({
|
||||
heading: { id: 'column.domain_blocks', defaultMessage: 'Hidden domains' },
|
||||
|
@ -19,7 +18,7 @@ const handleLoadMore = debounce((dispatch) => {
|
|||
}, 300, { leading: true });
|
||||
|
||||
const DomainBlocks: React.FC = () => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const intl = useIntl();
|
||||
|
||||
const domains = useAppSelector((state) => state.domain_lists.blocks.items);
|
||||
|
|
|
@ -78,6 +78,9 @@ describe('<FeedCarousel />', () => {
|
|||
expect(screen.getAllByTestId('carousel-item-avatar')[0]).toHaveClass('ring-primary-600');
|
||||
});
|
||||
|
||||
// HACK: wait for state change
|
||||
await new Promise((r) => setTimeout(r, 0));
|
||||
|
||||
// Marked as seen, not selected
|
||||
await userEvent.click(screen.getAllByTestId('carousel-item-avatar')[0]);
|
||||
await waitFor(() => {
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import React, { useCallback } from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { authorizeFollowRequest, rejectFollowRequest } from 'soapbox/actions/accounts';
|
||||
import Account from 'soapbox/components/account';
|
||||
import { Button, HStack } from 'soapbox/components/ui';
|
||||
import { useAppSelector } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
||||
import { makeGetAccount } from 'soapbox/selectors';
|
||||
|
||||
const messages = defineMessages({
|
||||
|
@ -19,7 +18,7 @@ interface IAccountAuthorize {
|
|||
|
||||
const AccountAuthorize: React.FC<IAccountAuthorize> = ({ id }) => {
|
||||
const intl = useIntl();
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const getAccount = useCallback(makeGetAccount(), []);
|
||||
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import debounce from 'lodash/debounce';
|
||||
import React from 'react';
|
||||
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { fetchFollowRequests, expandFollowRequests } from 'soapbox/actions/accounts';
|
||||
import ScrollableList from 'soapbox/components/scrollable-list';
|
||||
import { Column, Spinner } from 'soapbox/components/ui';
|
||||
import { useAppSelector } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
||||
|
||||
import AccountAuthorize from './components/account-authorize';
|
||||
|
||||
|
@ -19,7 +18,7 @@ const handleLoadMore = debounce((dispatch) => {
|
|||
}, 300, { leading: true });
|
||||
|
||||
const FollowRequests: React.FC = () => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const intl = useIntl();
|
||||
|
||||
const accountIds = useAppSelector((state) => state.user_lists.follow_requests.items);
|
||||
|
|
|
@ -37,7 +37,7 @@ const List: React.FC<IList> = ({ listId }) => {
|
|||
|
||||
return (
|
||||
<div className='flex items-center gap-1.5 px-2 py-4 text-black dark:text-white'>
|
||||
<Icon src={require('@tabler/icons/list.svg')} fixedWidth />
|
||||
<Icon src={require('@tabler/icons/list.svg')} />
|
||||
<span className='flex-grow'>
|
||||
{list.title}
|
||||
</span>
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import React from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { changeListEditorTitle, submitListEditor } from 'soapbox/actions/lists';
|
||||
import { Button, Form, HStack, Input } from 'soapbox/components/ui';
|
||||
import { useAppSelector } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
||||
|
||||
const messages = defineMessages({
|
||||
label: { id: 'lists.new.title_placeholder', defaultMessage: 'New list title' },
|
||||
|
@ -13,7 +12,7 @@ const messages = defineMessages({
|
|||
});
|
||||
|
||||
const NewListForm: React.FC = () => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const intl = useIntl();
|
||||
|
||||
const value = useAppSelector((state) => state.listEditor.get('title'));
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { createSelector } from 'reselect';
|
||||
|
||||
|
@ -9,7 +8,7 @@ import { openModal } from 'soapbox/actions/modals';
|
|||
import Icon from 'soapbox/components/icon';
|
||||
import ScrollableList from 'soapbox/components/scrollable-list';
|
||||
import { Column, IconButton, Spinner } from 'soapbox/components/ui';
|
||||
import { useAppSelector } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
||||
|
||||
import NewListForm from './components/new-list-form';
|
||||
|
||||
|
@ -35,7 +34,7 @@ const getOrderedLists = createSelector([(state: RootState) => state.lists], list
|
|||
});
|
||||
|
||||
const Lists: React.FC = () => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const intl = useIntl();
|
||||
|
||||
const lists = useAppSelector((state) => getOrderedLists(state));
|
||||
|
@ -85,7 +84,7 @@ const Lists: React.FC = () => {
|
|||
>
|
||||
{lists.map((list: any) => (
|
||||
<Link key={list.id} to={`/list/${list.id}`} className='flex items-center gap-1.5 p-2 text-gray-900 dark:text-gray-100 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-lg'>
|
||||
<Icon src={require('@tabler/icons/list.svg')} fixedWidth />
|
||||
<Icon src={require('@tabler/icons/list.svg')} />
|
||||
<span className='flex-grow'>
|
||||
{list.title}
|
||||
</span>
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import debounce from 'lodash/debounce';
|
||||
import React from 'react';
|
||||
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { fetchMutes, expandMutes } from 'soapbox/actions/mutes';
|
||||
import ScrollableList from 'soapbox/components/scrollable-list';
|
||||
import { Column, Spinner } from 'soapbox/components/ui';
|
||||
import AccountContainer from 'soapbox/containers/account-container';
|
||||
import { useAppSelector } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
||||
|
||||
const messages = defineMessages({
|
||||
heading: { id: 'column.mutes', defaultMessage: 'Muted users' },
|
||||
|
@ -18,7 +17,7 @@ const handleLoadMore = debounce((dispatch) => {
|
|||
}, 300, { leading: true });
|
||||
|
||||
const Mutes: React.FC = () => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const intl = useIntl();
|
||||
|
||||
const accountIds = useAppSelector((state) => state.user_lists.mutes.items);
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import classNames from 'clsx';
|
||||
import React from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import ReactSwipeableViews from 'react-swipeable-views';
|
||||
|
||||
import { endOnboarding } from 'soapbox/actions/onboarding';
|
||||
import LandingGradient from 'soapbox/components/landing-gradient';
|
||||
import { HStack } from 'soapbox/components/ui';
|
||||
import { useFeatures } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useFeatures } from 'soapbox/hooks';
|
||||
|
||||
import AvatarSelectionStep from './steps/avatar-selection-step';
|
||||
import BioStep from './steps/bio-step';
|
||||
|
@ -17,7 +16,7 @@ import FediverseStep from './steps/fediverse-step';
|
|||
import SuggestedAccountsStep from './steps/suggested-accounts-step';
|
||||
|
||||
const OnboardingWizard = () => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const features = useFeatures();
|
||||
|
||||
const [currentStep, setCurrentStep] = React.useState<number>(0);
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import classNames from 'clsx';
|
||||
import React from 'react';
|
||||
import { defineMessages, FormattedMessage } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { patchMe } from 'soapbox/actions/me';
|
||||
import { Avatar, Button, Card, CardBody, Icon, Spinner, Stack, Text } from 'soapbox/components/ui';
|
||||
import { useOwnAccount } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useOwnAccount } from 'soapbox/hooks';
|
||||
import toast from 'soapbox/toast';
|
||||
import { isDefaultAvatar } from 'soapbox/utils/accounts';
|
||||
import resizeImage from 'soapbox/utils/resize-image';
|
||||
|
@ -17,7 +16,7 @@ const messages = defineMessages({
|
|||
});
|
||||
|
||||
const AvatarSelectionStep = ({ onNext }: { onNext: () => void }) => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const account = useOwnAccount();
|
||||
|
||||
const fileInput = React.useRef<HTMLInputElement>(null);
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import React from 'react';
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { patchMe } from 'soapbox/actions/me';
|
||||
import { Button, Card, CardBody, FormGroup, Stack, Text, Textarea } from 'soapbox/components/ui';
|
||||
import { useOwnAccount } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useOwnAccount } from 'soapbox/hooks';
|
||||
import toast from 'soapbox/toast';
|
||||
|
||||
import type { AxiosError } from 'axios';
|
||||
|
@ -16,7 +15,7 @@ const messages = defineMessages({
|
|||
|
||||
const BioStep = ({ onNext }: { onNext: () => void }) => {
|
||||
const intl = useIntl();
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const account = useOwnAccount();
|
||||
const [value, setValue] = React.useState<string>(account?.source.get('note') || '');
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import classNames from 'clsx';
|
||||
import React from 'react';
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { patchMe } from 'soapbox/actions/me';
|
||||
import StillImage from 'soapbox/components/still-image';
|
||||
import { Avatar, Button, Card, CardBody, Icon, Spinner, Stack, Text } from 'soapbox/components/ui';
|
||||
import { useOwnAccount } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useOwnAccount } from 'soapbox/hooks';
|
||||
import toast from 'soapbox/toast';
|
||||
import { isDefaultHeader } from 'soapbox/utils/accounts';
|
||||
import resizeImage from 'soapbox/utils/resize-image';
|
||||
|
@ -20,7 +19,7 @@ const messages = defineMessages({
|
|||
|
||||
const CoverPhotoSelectionStep = ({ onNext }: { onNext: () => void }) => {
|
||||
const intl = useIntl();
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const account = useOwnAccount();
|
||||
|
||||
const fileInput = React.useRef<HTMLInputElement>(null);
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import React from 'react';
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { patchMe } from 'soapbox/actions/me';
|
||||
import { Button, Card, CardBody, FormGroup, Input, Stack, Text } from 'soapbox/components/ui';
|
||||
import { useOwnAccount } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useOwnAccount } from 'soapbox/hooks';
|
||||
import toast from 'soapbox/toast';
|
||||
|
||||
import type { AxiosError } from 'axios';
|
||||
|
@ -16,7 +15,7 @@ const messages = defineMessages({
|
|||
|
||||
const DisplayNameStep = ({ onNext }: { onNext: () => void }) => {
|
||||
const intl = useIntl();
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const account = useOwnAccount();
|
||||
const [value, setValue] = React.useState<string>(account?.display_name || '');
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import React from 'react';
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { changeSetting } from 'soapbox/actions/settings';
|
||||
import List, { ListItem } from 'soapbox/components/list';
|
||||
import { Form } from 'soapbox/components/ui';
|
||||
import { SelectDropdown } from 'soapbox/features/forms';
|
||||
import SettingToggle from 'soapbox/features/notifications/components/setting-toggle';
|
||||
import { useFeatures, useSettings } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useFeatures, useSettings } from 'soapbox/hooks';
|
||||
|
||||
import ThemeToggle from '../ui/components/theme-toggle';
|
||||
|
||||
|
@ -89,7 +88,7 @@ const messages = defineMessages({
|
|||
|
||||
const Preferences = () => {
|
||||
const intl = useIntl();
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const features = useFeatures();
|
||||
const settings = useSettings();
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import React from 'react';
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { Link, Redirect } from 'react-router-dom';
|
||||
|
||||
import { logIn, verifyCredentials } from 'soapbox/actions/auth';
|
||||
|
@ -8,7 +7,7 @@ import { fetchInstance } from 'soapbox/actions/instance';
|
|||
import { openModal } from 'soapbox/actions/modals';
|
||||
import SiteLogo from 'soapbox/components/site-logo';
|
||||
import { Button, Form, HStack, IconButton, Input, Tooltip } from 'soapbox/components/ui';
|
||||
import { useAppSelector, useFeatures, useSoapboxConfig, useOwnAccount, useInstance } from 'soapbox/hooks';
|
||||
import { useAppSelector, useFeatures, useSoapboxConfig, useOwnAccount, useInstance, useAppDispatch } from 'soapbox/hooks';
|
||||
|
||||
import Sonar from './sonar';
|
||||
|
||||
|
@ -25,7 +24,7 @@ const messages = defineMessages({
|
|||
});
|
||||
|
||||
const Header = () => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const intl = useIntl();
|
||||
|
||||
const account = useOwnAccount();
|
||||
|
|
|
@ -2,13 +2,12 @@ import { OrderedSet as ImmutableOrderedSet } from 'immutable';
|
|||
import { debounce } from 'lodash';
|
||||
import React from 'react';
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useParams } from 'react-router-dom';
|
||||
|
||||
import { expandStatusQuotes, fetchStatusQuotes } from 'soapbox/actions/status-quotes';
|
||||
import StatusList from 'soapbox/components/status-list';
|
||||
import { Column } from 'soapbox/components/ui';
|
||||
import { useAppSelector } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
||||
|
||||
const messages = defineMessages({
|
||||
heading: { id: 'column.quotes', defaultMessage: 'Post quotes' },
|
||||
|
@ -18,7 +17,7 @@ const handleLoadMore = debounce((statusId: string, dispatch: React.Dispatch<any>
|
|||
dispatch(expandStatusQuotes(statusId)), 300, { leading: true });
|
||||
|
||||
const Quotes: React.FC = () => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const intl = useIntl();
|
||||
const { statusId } = useParams<{ statusId: string }>();
|
||||
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
import { fetchMfa } from 'soapbox/actions/mfa';
|
||||
import List, { ListItem } from 'soapbox/components/list';
|
||||
import { Card, CardBody, CardHeader, CardTitle, Column } from 'soapbox/components/ui';
|
||||
import { useAppSelector, useFeatures, useOwnAccount } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useAppSelector, useFeatures, useOwnAccount } from 'soapbox/hooks';
|
||||
|
||||
import Preferences from '../preferences';
|
||||
|
||||
|
@ -32,7 +31,7 @@ const messages = defineMessages({
|
|||
|
||||
/** User settings page. */
|
||||
const Settings = () => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const history = useHistory();
|
||||
const intl = useIntl();
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import { defineMessages, useIntl } from 'react-intl';
|
|||
// @ts-ignore
|
||||
import Overlay from 'react-overlays/lib/Overlay';
|
||||
|
||||
import Icon from 'soapbox/components/icon';
|
||||
import ForkAwesomeIcon from 'soapbox/components/fork-awesome-icon';
|
||||
|
||||
import IconPickerMenu from './icon-picker-menu';
|
||||
|
||||
|
@ -68,7 +68,7 @@ const IconPickerDropdown: React.FC<IIconPickerDropdown> = ({ value, onPickEmoji
|
|||
onKeyDown={onToggle}
|
||||
tabIndex={0}
|
||||
>
|
||||
<Icon id={value} />
|
||||
<ForkAwesomeIcon id={value} />
|
||||
</div>
|
||||
|
||||
<Overlay show={active} placement={placement} target={target.current}>
|
||||
|
|
|
@ -39,6 +39,7 @@ const messages = defineMessages({
|
|||
customCssLabel: { id: 'soapbox_config.custom_css.meta_fields.url_placeholder', defaultMessage: 'URL' },
|
||||
rawJSONLabel: { id: 'soapbox_config.raw_json_label', defaultMessage: 'Advanced: Edit raw JSON data' },
|
||||
rawJSONHint: { id: 'soapbox_config.raw_json_hint', defaultMessage: 'Edit the settings data directly. Changes made directly to the JSON file will override the form fields above. Click "Save" to apply your changes.' },
|
||||
rawJSONInvalid: { id: 'soapbox_config.raw_json_invalid', defaultMessage: 'is invalid' },
|
||||
verifiedCanEditNameLabel: { id: 'soapbox_config.verified_can_edit_name_label', defaultMessage: 'Allow verified users to edit their own display name.' },
|
||||
displayFqnLabel: { id: 'soapbox_config.display_fqn_label', defaultMessage: 'Display domain (eg @user@domain) for local accounts.' },
|
||||
greentextLabel: { id: 'soapbox_config.greentext_label', defaultMessage: 'Enable greentext support' },
|
||||
|
@ -394,11 +395,13 @@ const SoapboxConfig: React.FC = () => {
|
|||
expanded={jsonEditorExpanded}
|
||||
onToggle={toggleJSONEditor}
|
||||
>
|
||||
<FormGroup hintText={intl.formatMessage(messages.rawJSONHint)}>
|
||||
<FormGroup
|
||||
hintText={intl.formatMessage(messages.rawJSONHint)}
|
||||
errors={jsonValid ? undefined : [intl.formatMessage(messages.rawJSONInvalid)]}
|
||||
>
|
||||
<Textarea
|
||||
value={rawJSON}
|
||||
onChange={handleEditJSON}
|
||||
hasError={!jsonValid}
|
||||
isCodeEditor
|
||||
rows={12}
|
||||
/>
|
||||
|
|
|
@ -153,7 +153,7 @@ const Card: React.FC<ICard> = ({
|
|||
</Stack>
|
||||
);
|
||||
|
||||
let embed: React.ReactNode = '';
|
||||
let embed: React.ReactNode = null;
|
||||
|
||||
const canvas = (
|
||||
<Blurhash
|
||||
|
@ -240,12 +240,6 @@ const Card: React.FC<ICard> = ({
|
|||
{thumbnail}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
embed = (
|
||||
<div className='status-card__image status-card__image--empty'>
|
||||
<Icon src={require('@tabler/icons/file-text.svg')} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import React from 'react';
|
||||
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { importFetchedStatuses } from 'soapbox/actions/importer';
|
||||
import { expandTimelineSuccess } from 'soapbox/actions/timelines';
|
||||
import { useAppDispatch } from 'soapbox/hooks';
|
||||
|
||||
import { Column } from '../../components/ui';
|
||||
import Timeline from '../ui/components/timeline';
|
||||
|
@ -31,7 +31,7 @@ const onlyMedia = false;
|
|||
|
||||
const TestTimeline: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
React.useEffect(() => {
|
||||
dispatch(importFetchedStatuses(MOCK_STATUSES));
|
||||
|
|
|
@ -48,6 +48,8 @@ describe('<UI />', () => {
|
|||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('cta-banner')).toHaveTextContent('Sign up now to discuss');
|
||||
}, {
|
||||
timeout: 2000,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import React from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import {
|
||||
followAccount,
|
||||
|
@ -14,7 +13,7 @@ import {
|
|||
} from 'soapbox/actions/accounts';
|
||||
import { openModal } from 'soapbox/actions/modals';
|
||||
import { Button, HStack } from 'soapbox/components/ui';
|
||||
import { useAppSelector, useFeatures } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useAppSelector, useFeatures } from 'soapbox/hooks';
|
||||
|
||||
import type { Account as AccountEntity } from 'soapbox/types/entities';
|
||||
|
||||
|
@ -49,7 +48,7 @@ interface IActionButton {
|
|||
* `actionType` prop.
|
||||
*/
|
||||
const ActionButton: React.FC<IActionButton> = ({ account, actionType, small }) => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const features = useFeatures();
|
||||
const intl = useIntl();
|
||||
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import classNames from 'clsx';
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import { logOut } from 'soapbox/actions/auth';
|
||||
import { Text } from 'soapbox/components/ui';
|
||||
import emojify from 'soapbox/features/emoji/emoji';
|
||||
import { useSoapboxConfig, useOwnAccount, useFeatures } from 'soapbox/hooks';
|
||||
import { useSoapboxConfig, useOwnAccount, useFeatures, useAppDispatch } from 'soapbox/hooks';
|
||||
import sourceCode from 'soapbox/utils/code';
|
||||
|
||||
interface IFooterLink {
|
||||
|
@ -29,7 +28,7 @@ const LinkFooter: React.FC = (): JSX.Element => {
|
|||
const features = useFeatures();
|
||||
const soapboxConfig = useSoapboxConfig();
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const onClickLogOut: React.EventHandler<React.MouseEvent> = (e) => {
|
||||
dispatch(logOut());
|
||||
|
@ -76,7 +75,7 @@ const LinkFooter: React.FC = (): JSX.Element => {
|
|||
defaultMessage='{code_name} is open source software. You can contribute or report issues at {code_link} (v{code_version}).'
|
||||
values={{
|
||||
code_name: sourceCode.displayName,
|
||||
code_link: <Text theme='subtle'><a className='underline' href={sourceCode.url} rel='noopener' target='_blank'>{sourceCode.repository}</a></Text>,
|
||||
code_link: <Text theme='subtle' tag='span'><a className='underline' href={sourceCode.url} rel='noopener' target='_blank'>{sourceCode.repository}</a></Text>,
|
||||
code_version: sourceCode.version,
|
||||
}}
|
||||
/>
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import { NavLink } from 'react-router-dom';
|
||||
import { createSelector } from 'reselect';
|
||||
|
||||
import { fetchLists } from 'soapbox/actions/lists';
|
||||
import Icon from 'soapbox/components/icon';
|
||||
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
||||
|
||||
import type { List as ImmutableList } from 'immutable';
|
||||
import type { RootState } from 'soapbox/store';
|
||||
import type { List as ListEntity } from 'soapbox/types/entities';
|
||||
|
||||
const getOrderedLists = createSelector([(state: RootState) => state.lists], lists => {
|
||||
if (!lists) {
|
||||
return lists;
|
||||
}
|
||||
|
||||
return lists.toList().filter(item => !!item).sort((a, b) => (a as ListEntity).title.localeCompare((b as ListEntity).title)).take(4) as ImmutableList<ListEntity>;
|
||||
});
|
||||
|
||||
const ListPanel = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const lists = useAppSelector((state) => getOrderedLists(state));
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(fetchLists());
|
||||
}, []);
|
||||
|
||||
if (!lists || lists.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<hr />
|
||||
|
||||
{lists.map(list => (
|
||||
<NavLink key={list.id} className='column-link column-link--transparent' strict to={`/list/${list.id}`}><Icon className='column-link__icon' id='list-ul' fixedWidth />{list.title}</NavLink>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ListPanel;
|
|
@ -4,7 +4,7 @@ import React from 'react';
|
|||
|
||||
import { __stub } from 'soapbox/api';
|
||||
|
||||
import { render, screen } from '../../../../../../jest/test-helpers';
|
||||
import { render, screen, waitFor } from '../../../../../../jest/test-helpers';
|
||||
import { normalizeAccount, normalizeStatus } from '../../../../../../normalizers';
|
||||
import ReportModal from '../report-modal';
|
||||
|
||||
|
@ -64,6 +64,9 @@ describe('<ReportModal />', () => {
|
|||
await user.click(screen.getByTestId('rule-1'));
|
||||
await user.click(screen.getByText(/Next/));
|
||||
await user.click(screen.getByText(/Submit/));
|
||||
expect(screen.getByText(/Thanks for submitting your report/)).toBeInTheDocument();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText(/Thanks for submitting your report/)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
import { OrderedSet } from 'immutable';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import Toggle from 'react-toggle';
|
||||
|
||||
import { changeReportBlock, changeReportForward } from 'soapbox/actions/reports';
|
||||
import { fetchRules } from 'soapbox/actions/rules';
|
||||
import { Button, FormGroup, HStack, Stack, Text } from 'soapbox/components/ui';
|
||||
import StatusCheckBox from 'soapbox/features/report/components/status-check-box';
|
||||
import { useAppSelector, useFeatures } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useAppSelector, useFeatures } from 'soapbox/hooks';
|
||||
import { isRemote, getDomain } from 'soapbox/utils/accounts';
|
||||
|
||||
import type { ReducerAccount } from 'soapbox/reducers/accounts';
|
||||
|
@ -26,7 +25,7 @@ interface IOtherActionsStep {
|
|||
}
|
||||
|
||||
const OtherActionsStep = ({ account }: IOtherActionsStep) => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const features = useFeatures();
|
||||
const intl = useIntl();
|
||||
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import classNames from 'clsx';
|
||||
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { changeReportComment, changeReportRule } from 'soapbox/actions/reports';
|
||||
import { fetchRules } from 'soapbox/actions/rules';
|
||||
import { FormGroup, Stack, Text, Textarea } from 'soapbox/components/ui';
|
||||
import { useAppSelector } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
||||
|
||||
import type { ReducerAccount } from 'soapbox/reducers/accounts';
|
||||
|
||||
|
@ -22,7 +21,7 @@ interface IReasonStep {
|
|||
const RULES_HEIGHT = 385;
|
||||
|
||||
const ReasonStep = (_props: IReasonStep) => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const intl = useIntl();
|
||||
|
||||
const rulesListRef = useRef(null);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import classNames from 'clsx';
|
||||
import React, { useRef, useState } from 'react';
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { Link, Redirect } from 'react-router-dom';
|
||||
|
||||
import { logIn, verifyCredentials } from 'soapbox/actions/auth';
|
||||
|
@ -10,7 +9,7 @@ import { openSidebar } from 'soapbox/actions/sidebar';
|
|||
import SiteLogo from 'soapbox/components/site-logo';
|
||||
import { Avatar, Button, Form, HStack, IconButton, Input, Tooltip } from 'soapbox/components/ui';
|
||||
import Search from 'soapbox/features/compose/components/search';
|
||||
import { useOwnAccount, useSoapboxConfig } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useOwnAccount, useSoapboxConfig } from 'soapbox/hooks';
|
||||
|
||||
import ProfileDropdown from './profile-dropdown';
|
||||
|
||||
|
@ -24,7 +23,7 @@ const messages = defineMessages({
|
|||
});
|
||||
|
||||
const Navbar = () => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const intl = useIntl();
|
||||
|
||||
const node = useRef(null);
|
||||
|
|
|
@ -70,6 +70,7 @@ const PendingStatus: React.FC<IPendingStatus> = ({ idempotencyKey, className, mu
|
|||
account={account}
|
||||
timestamp={status.created_at}
|
||||
hideActions
|
||||
withLinkToProfile={false}
|
||||
/>
|
||||
</HStack>
|
||||
</div>
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import throttle from 'lodash/throttle';
|
||||
import React from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import { fetchOwnAccounts, logOut, switchAccount } from 'soapbox/actions/auth';
|
||||
import Account from 'soapbox/components/account';
|
||||
import { Menu, MenuButton, MenuDivider, MenuItem, MenuLink, MenuList } from 'soapbox/components/ui';
|
||||
import { useAppSelector, useFeatures } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useAppSelector, useFeatures } from 'soapbox/hooks';
|
||||
import { makeGetAccount } from 'soapbox/selectors';
|
||||
|
||||
import ThemeToggle from './theme-toggle';
|
||||
|
@ -35,7 +34,7 @@ type IMenuItem = {
|
|||
const getAccount = makeGetAccount();
|
||||
|
||||
const ProfileDropdown: React.FC<IProfileDropdown> = ({ account, children }) => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const features = useFeatures();
|
||||
const intl = useIntl();
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { OrderedSet as ImmutableOrderedSet } from 'immutable';
|
||||
import React, { useEffect } from 'react';
|
||||
import { FormattedList, FormattedMessage } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import { fetchAccountFamiliarFollowers } from 'soapbox/actions/familiar-followers';
|
||||
|
@ -9,7 +8,7 @@ import { openModal } from 'soapbox/actions/modals';
|
|||
import HoverRefWrapper from 'soapbox/components/hover-ref-wrapper';
|
||||
import { Text } from 'soapbox/components/ui';
|
||||
import VerificationBadge from 'soapbox/components/verification-badge';
|
||||
import { useAppSelector, useFeatures } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useAppSelector, useFeatures } from 'soapbox/hooks';
|
||||
import { makeGetAccount } from 'soapbox/selectors';
|
||||
|
||||
import type { Account } from 'soapbox/types/entities';
|
||||
|
@ -21,7 +20,7 @@ interface IProfileFamiliarFollowers {
|
|||
}
|
||||
|
||||
const ProfileFamiliarFollowers: React.FC<IProfileFamiliarFollowers> = ({ account }) => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const me = useAppSelector((state) => state.me);
|
||||
const features = useFeatures();
|
||||
const familiarFollowerIds = useAppSelector(state => state.user_lists.familiar_followers.get(account.id)?.items || ImmutableOrderedSet<string>());
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import { List as ImmutableList } from 'immutable';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { openModal } from 'soapbox/actions/modals';
|
||||
import { expandAccountMediaTimeline } from 'soapbox/actions/timelines';
|
||||
import { Spinner, Text, Widget } from 'soapbox/components/ui';
|
||||
import { useAppSelector } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
||||
import { getAccountGallery } from 'soapbox/selectors';
|
||||
|
||||
import MediaItem from '../../account-gallery/components/media-item';
|
||||
|
@ -18,7 +17,7 @@ interface IProfileMediaPanel {
|
|||
}
|
||||
|
||||
const ProfileMediaPanel: React.FC<IProfileMediaPanel> = ({ account }) => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
|
||||
import Icon from 'soapbox/components/icon';
|
||||
import ForkAwesomeIcon from 'soapbox/components/fork-awesome-icon';
|
||||
import { Widget, Stack, Text } from 'soapbox/components/ui';
|
||||
import { useInstance, useSettings, useSoapboxConfig } from 'soapbox/hooks';
|
||||
|
||||
|
@ -20,7 +20,7 @@ const PromoPanel: React.FC = () => {
|
|||
{promoItems.map((item, i) => (
|
||||
<Text key={i}>
|
||||
<a className='flex items-center' href={item.url} target='_blank'>
|
||||
<Icon id={item.icon} className='flex-none text-lg mr-2 rtl:mr-0 rtl:ml-2' fixedWidth />
|
||||
<ForkAwesomeIcon id={item.icon} className='flex-none text-lg mr-2 rtl:mr-0 rtl:ml-2' fixedWidth />
|
||||
{item.textLocales.get(locale) || item.text}
|
||||
</a>
|
||||
</Text>
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
import React from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { changeSetting } from 'soapbox/actions/settings';
|
||||
import { useSettings } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useSettings } from 'soapbox/hooks';
|
||||
|
||||
import ThemeSelector from './theme-selector';
|
||||
|
||||
/** Stateful theme selector. */
|
||||
const ThemeToggle: React.FC = () => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const themeMode = useSettings().get('themeMode');
|
||||
|
||||
const handleChange = (themeMode: string) => {
|
||||
|
|
|
@ -26,10 +26,10 @@ const UserPanel: React.FC<IUserPanel> = ({ accountId, action, badges, domain })
|
|||
const fqn = useAppSelector((state) => displayFqn(state));
|
||||
|
||||
if (!account) return null;
|
||||
const displayNameHtml = { __html: account.get('display_name_html') };
|
||||
const acct = !account.get('acct').includes('@') && domain ? `${account.get('acct')}@${domain}` : account.get('acct');
|
||||
const header = account.get('header');
|
||||
const verified = account.get('verified');
|
||||
const displayNameHtml = { __html: account.display_name_html };
|
||||
const acct = !account.acct.includes('@') && domain ? `${account.acct}@${domain}` : account.acct;
|
||||
const header = account.header;
|
||||
const verified = account.verified;
|
||||
|
||||
return (
|
||||
<div className='relative'>
|
||||
|
@ -43,11 +43,11 @@ const UserPanel: React.FC<IUserPanel> = ({ accountId, action, badges, domain })
|
|||
|
||||
<HStack justifyContent='between'>
|
||||
<Link
|
||||
to={`/@${account.get('acct')}`}
|
||||
to={`/@${account.acct}`}
|
||||
title={acct}
|
||||
className='-mt-12 block'
|
||||
>
|
||||
<Avatar src={account.avatar} className='h-20 w-20 bg-gray-50 ring-2 ring-white overflow-hidden' />
|
||||
<Avatar src={account.avatar} size={80} className='h-20 w-20 bg-gray-50 ring-2 ring-white overflow-hidden' />
|
||||
</Link>
|
||||
|
||||
{action && (
|
||||
|
@ -57,7 +57,7 @@ const UserPanel: React.FC<IUserPanel> = ({ accountId, action, badges, domain })
|
|||
</Stack>
|
||||
|
||||
<Stack>
|
||||
<Link to={`/@${account.get('acct')}`}>
|
||||
<Link to={`/@${account.acct}`}>
|
||||
<HStack space={1} alignItems='center'>
|
||||
<Text size='lg' weight='bold' dangerouslySetInnerHTML={displayNameHtml} />
|
||||
|
||||
|
@ -77,11 +77,11 @@ const UserPanel: React.FC<IUserPanel> = ({ accountId, action, badges, domain })
|
|||
</Stack>
|
||||
|
||||
<HStack alignItems='center' space={3}>
|
||||
{account.get('followers_count') >= 0 && (
|
||||
<Link to={`/@${account.get('acct')}/followers`} title={intl.formatNumber(account.get('followers_count'))}>
|
||||
{account.followers_count >= 0 && (
|
||||
<Link to={`/@${account.acct}/followers`} title={intl.formatNumber(account.followers_count)}>
|
||||
<HStack alignItems='center' space={1}>
|
||||
<Text theme='primary' weight='bold' size='sm'>
|
||||
{shortNumberFormat(account.get('followers_count'))}
|
||||
{shortNumberFormat(account.followers_count)}
|
||||
</Text>
|
||||
<Text weight='bold' size='sm'>
|
||||
<FormattedMessage id='account.followers' defaultMessage='Followers' />
|
||||
|
@ -90,11 +90,11 @@ const UserPanel: React.FC<IUserPanel> = ({ accountId, action, badges, domain })
|
|||
</Link>
|
||||
)}
|
||||
|
||||
{account.get('following_count') >= 0 && (
|
||||
<Link to={`/@${account.get('acct')}/following`} title={intl.formatNumber(account.get('following_count'))}>
|
||||
{account.following_count >= 0 && (
|
||||
<Link to={`/@${account.acct}/following`} title={intl.formatNumber(account.following_count)}>
|
||||
<HStack alignItems='center' space={1}>
|
||||
<Text theme='primary' weight='bold' size='sm'>
|
||||
{shortNumberFormat(account.get('following_count'))}
|
||||
{shortNumberFormat(account.following_count)}
|
||||
</Text>
|
||||
<Text weight='bold' size='sm'>
|
||||
<FormattedMessage id='account.follows' defaultMessage='Follows' />
|
||||
|
|
|
@ -472,7 +472,7 @@ const UI: React.FC = ({ children }) => {
|
|||
navigator.serviceWorker.addEventListener('message', handleServiceWorkerPostMessage);
|
||||
}
|
||||
|
||||
if (typeof window.Notification !== 'undefined' && Notification.permission === 'default') {
|
||||
if (window.Notification?.permission === 'default') {
|
||||
window.setTimeout(() => Notification.requestPermission(), 120 * 1000);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,10 @@ describe('<Registration />', () => {
|
|||
fireEvent.submit(screen.getByTestId('button'), { preventDefault: () => {} });
|
||||
});
|
||||
|
||||
expect(screen.getByTestId('toast')).toHaveTextContent(/welcome to/i);
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('toast')).toHaveTextContent(/welcome to/i);
|
||||
});
|
||||
|
||||
expect(screen.queryAllByRole('heading')).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
@ -38,7 +41,11 @@ describe('<Registration />', () => {
|
|||
describe('with invalid data', () => {
|
||||
it('handles 422 errors', async() => {
|
||||
__stub(mock => {
|
||||
mock.onPost('/api/v1/pepe/accounts').reply(422, {});
|
||||
mock.onPost('/api/v1/pepe/accounts').reply(
|
||||
422, {
|
||||
error: 'user_taken',
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
render(<Registration />);
|
||||
|
@ -47,7 +54,31 @@ describe('<Registration />', () => {
|
|||
fireEvent.submit(screen.getByTestId('button'), { preventDefault: () => {} });
|
||||
});
|
||||
|
||||
expect(screen.getByTestId('toast')).toHaveTextContent(/this username has already been taken/i);
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('toast')).toHaveTextContent(/this username has already been taken/i);
|
||||
});
|
||||
});
|
||||
|
||||
it('handles 422 errors with messages', async() => {
|
||||
__stub(mock => {
|
||||
mock.onPost('/api/v1/pepe/accounts').reply(
|
||||
422, {
|
||||
error: 'user_vip',
|
||||
message: 'This username is unavailable.',
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
render(<Registration />);
|
||||
|
||||
await waitFor(() => {
|
||||
fireEvent.submit(screen.getByTestId('button'), { preventDefault: () => {} });
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('toast')).toHaveTextContent(/this username is unavailable/i);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('handles generic errors', async() => {
|
||||
|
@ -61,7 +92,9 @@ describe('<Registration />', () => {
|
|||
fireEvent.submit(screen.getByTestId('button'), { preventDefault: () => {} });
|
||||
});
|
||||
|
||||
expect(screen.getByTestId('toast')).toHaveTextContent(/failed to register your account/i);
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('toast')).toHaveTextContent(/failed to register your account/i);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -58,9 +58,11 @@ const Registration = () => {
|
|||
intl.formatMessage(messages.success, { siteTitle: instance.title }),
|
||||
);
|
||||
})
|
||||
.catch((error: AxiosError) => {
|
||||
if (error?.response?.status === 422) {
|
||||
toast.error(intl.formatMessage(messages.usernameTaken));
|
||||
.catch((errorResponse: AxiosError<{ error: string, message: string }>) => {
|
||||
const error = errorResponse.response?.data?.error;
|
||||
|
||||
if (error) {
|
||||
toast.error(errorResponse.response?.data?.message || intl.formatMessage(messages.usernameTaken));
|
||||
} else {
|
||||
toast.error(intl.formatMessage(messages.error));
|
||||
}
|
||||
|
|
|
@ -60,7 +60,9 @@ describe('<EmailVerification />', () => {
|
|||
);
|
||||
});
|
||||
|
||||
expect(screen.getByTestId('form-group-error')).toHaveTextContent('is taken');
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('form-group-error')).toHaveTextContent('is taken');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -37,8 +37,10 @@ describe('<SmsVerification />', () => {
|
|||
);
|
||||
});
|
||||
|
||||
expect(screen.getByRole('heading')).toHaveTextContent('Verification code');
|
||||
expect(screen.getByTestId('toast')).toHaveTextContent('A verification code has been sent to your phone number.');
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole('heading')).toHaveTextContent('Verification code');
|
||||
expect(screen.getByTestId('toast')).toHaveTextContent('A verification code has been sent to your phone number.');
|
||||
});
|
||||
|
||||
act(() => {
|
||||
toast.remove();
|
||||
|
@ -68,8 +70,10 @@ describe('<SmsVerification />', () => {
|
|||
);
|
||||
});
|
||||
|
||||
expect(screen.getByRole('heading')).toHaveTextContent('Verification code');
|
||||
expect(screen.getByTestId('toast')).toHaveTextContent('A verification code has been sent to your phone number.');
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole('heading')).toHaveTextContent('Verification code');
|
||||
expect(screen.getByTestId('toast')).toHaveTextContent('A verification code has been sent to your phone number.');
|
||||
});
|
||||
|
||||
act(() => {
|
||||
toast.remove();
|
||||
|
@ -82,7 +86,9 @@ describe('<SmsVerification />', () => {
|
|||
await userEvent.type(screen.getByLabelText('Digit 5'), '5');
|
||||
await userEvent.type(screen.getByLabelText('Digit 6'), '6');
|
||||
|
||||
expect(screen.getByTestId('toast')).toHaveTextContent('Your SMS token has expired.');
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('toast')).toHaveTextContent('Your SMS token has expired.');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -106,7 +112,9 @@ describe('<SmsVerification />', () => {
|
|||
);
|
||||
});
|
||||
|
||||
expect(screen.getByTestId('toast')).toHaveTextContent('Failed to send SMS message to your phone number.');
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('toast')).toHaveTextContent('Failed to send SMS message to your phone number.');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import { logOut } from 'soapbox/actions/auth';
|
||||
|
@ -8,10 +7,10 @@ import { openModal } from 'soapbox/actions/modals';
|
|||
import LandingGradient from 'soapbox/components/landing-gradient';
|
||||
import SiteLogo from 'soapbox/components/site-logo';
|
||||
import { Button, Stack, Text } from 'soapbox/components/ui';
|
||||
import { useInstance, useOwnAccount } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useInstance, useOwnAccount } from 'soapbox/hooks';
|
||||
|
||||
const WaitlistPage = () => {
|
||||
const dispatch = useDispatch();
|
||||
const dispatch = useAppDispatch();
|
||||
const instance = useInstance();
|
||||
|
||||
const me = useOwnAccount();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import classNames from 'clsx';
|
||||
import debounce from 'lodash/debounce';
|
||||
import throttle from 'lodash/throttle';
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
|
||||
import Blurhash from 'soapbox/components/blurhash';
|
||||
|
@ -159,7 +159,7 @@ const Video: React.FC<IVideo> = ({
|
|||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
useLayoutEffect(() => {
|
||||
setDimensions();
|
||||
}, [player.current]);
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ const useDimensions = (): UseDimensionsResult => {
|
|||
);
|
||||
|
||||
useEffect((): any => {
|
||||
if (!element) return null;
|
||||
if (!element) return;
|
||||
observer.observe(element);
|
||||
|
||||
return () => {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
import { act } from '@testing-library/react';
|
||||
import { toast } from 'react-hot-toast';
|
||||
|
||||
import { __clear as clearApiMocks } from '../api/__mocks__';
|
||||
|
@ -17,7 +18,9 @@ require('fake-indexeddb/auto');
|
|||
|
||||
// Clear toasts after each test.
|
||||
afterEach(() => {
|
||||
toast.remove();
|
||||
act(() => {
|
||||
toast.remove();
|
||||
});
|
||||
});
|
||||
|
||||
const intersectionObserverMock = () => ({ observe: () => null, disconnect: () => null });
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
// Convenience function to load polyfills and return a promise when it's done.
|
||||
// If there are no polyfills, then this is just Promise.resolve() which means
|
||||
// it will execute in the same tick of the event loop (i.e. near-instant).
|
||||
|
||||
function importBasePolyfills() {
|
||||
return import(/* webpackChunkName: "base_polyfills" */ './base-polyfills');
|
||||
}
|
||||
|
||||
function importExtraPolyfills() {
|
||||
return import(/* webpackChunkName: "extra_polyfills" */ './extra-polyfills');
|
||||
}
|
||||
|
||||
function loadPolyfills() {
|
||||
const needsBasePolyfills = !(
|
||||
// @ts-ignore
|
||||
Array.prototype.includes &&
|
||||
// @ts-ignore
|
||||
HTMLCanvasElement.prototype.toBlob &&
|
||||
window.Intl &&
|
||||
// @ts-ignore
|
||||
Number.isNaN &&
|
||||
// @ts-ignore
|
||||
Object.assign &&
|
||||
// @ts-ignore
|
||||
Object.values &&
|
||||
window.Symbol
|
||||
);
|
||||
|
||||
// Older versions of Firefox and Safari do not have IntersectionObserver.
|
||||
// This avoids shipping them all the polyfills.
|
||||
const needsExtraPolyfills = !(
|
||||
window.IntersectionObserver &&
|
||||
window.IntersectionObserverEntry &&
|
||||
'isIntersecting' in IntersectionObserverEntry.prototype &&
|
||||
window.requestIdleCallback
|
||||
);
|
||||
|
||||
return Promise.all([
|
||||
needsBasePolyfills && importBasePolyfills(),
|
||||
needsExtraPolyfills && importExtraPolyfills(),
|
||||
]);
|
||||
}
|
||||
|
||||
export default loadPolyfills;
|
|
@ -147,7 +147,6 @@
|
|||
"alert.unexpected.links.support": "الدعم",
|
||||
"alert.unexpected.message": "حدث خطأ ما.",
|
||||
"alert.unexpected.return_home": "العودة للصفحة الرئيسة",
|
||||
"alert.unexpected.title": "المعذرة!",
|
||||
"aliases.account.add": "إنشاء اسم مستعار",
|
||||
"aliases.account_label": "الحساب القديم:",
|
||||
"aliases.aliases_list_delete": "إلغاء ربط الاسم المستعار",
|
||||
|
@ -186,18 +185,9 @@
|
|||
"bundle_modal_error.message": "حدث خطأ في أثناء تحميل الصفحة.",
|
||||
"bundle_modal_error.retry": "إعادة المحاولة",
|
||||
"card.back.label": "العودة",
|
||||
"chat_box.actions.send": "إرسال",
|
||||
"chat_box.input.placeholder": "إرسال رسالة…",
|
||||
"chat_panels.main_window.empty": "لا توجد رسائل، لبدء المحادثات زُر المِلف الشخصي لمستخدم ما.",
|
||||
"chat_panels.main_window.title": "المحادثات",
|
||||
"chat_window.close": "إغلاق المحادثة",
|
||||
"chats.actions.delete": "حذف الرسالة",
|
||||
"chats.actions.more": "المزيد",
|
||||
"chats.actions.report": "الإبلاغ عن المستخدم",
|
||||
"chats.attachment": "مُرفق",
|
||||
"chats.attachment_image": "صورة",
|
||||
"chats.audio_toggle_off": "الإشعارات الصوتية غير مُفعّلة",
|
||||
"chats.audio_toggle_on": "الإشعارات الصوتية مُفعّلة",
|
||||
"chats.dividers.today": "اليوم",
|
||||
"chats.search_placeholder": "بَدْء دردشة مع…",
|
||||
"column.admin.awaiting_approval": "في انتظار الموافقة",
|
||||
|
@ -270,13 +260,11 @@
|
|||
"column.public": "الاتحاد الاجتماعي",
|
||||
"column.reactions": "تفاعلات",
|
||||
"column.reblogs": "إعادة النشر",
|
||||
"column.remote": "الاتحاد الاجتماعي",
|
||||
"column.scheduled_statuses": "منشورات مُجدولة",
|
||||
"column.search": "البحث",
|
||||
"column.settings_store": "مخزن الإعدادات",
|
||||
"column.soapbox_config": "تهيئة بسّام",
|
||||
"column.test": "تجربة الخط الزمني",
|
||||
"column_back_button.label": "الرجوع",
|
||||
"column_forbidden.body": "ليست لديك الصلاحيات للدخول إلى هذه الصفحة.",
|
||||
"column_forbidden.title": "محظور",
|
||||
"common.cancel": "إلغاء",
|
||||
|
@ -372,8 +360,6 @@
|
|||
"confirmations.scheduled_status_delete.heading": "إلغاء جدولة المنشور",
|
||||
"confirmations.scheduled_status_delete.message": "هل تود حقا حذف هذا المنشور المجدول",
|
||||
"confirmations.unfollow.confirm": "إلغاء المتابعة",
|
||||
"confirmations.unfollow.heading": "إلغاء متابعة {name}",
|
||||
"confirmations.unfollow.message": "هل تود حقًّا إلغاء متابعة {name}؟",
|
||||
"crypto_donate.explanation_box.message": "{siteTitle} يقبل العملات الرقمية . بإمكانك التبرع عبر أي من هذه العناوين في الأسفل . شكرا لدعمك!",
|
||||
"crypto_donate.explanation_box.title": "يتم إرسال العملات الرقمية",
|
||||
"crypto_donate_panel.actions.view": "انقر لإظهار {count} {count, plural, one {wallet} other {wallets}}",
|
||||
|
@ -822,7 +808,6 @@
|
|||
"preferences.fields.display_media.default": "اخف الوسائط المصنفة بحساس",
|
||||
"preferences.fields.display_media.hide_all": "اخف جميع الوسائط",
|
||||
"preferences.fields.display_media.show_all": "اظهر جميع الوسائط",
|
||||
"preferences.fields.dyslexic_font_label": "وضع عسر القراءة",
|
||||
"preferences.fields.expand_spoilers_label": "توسيع المنشورات المعلّمة بتحذير دائمًا",
|
||||
"preferences.fields.language_label": "لغة الواجهة",
|
||||
"preferences.fields.media_display_label": "عرض الوسائط",
|
||||
|
@ -834,7 +819,6 @@
|
|||
"preferences.fields.underline_links_label": "إظهار الروابط في المنشورات من خلال وضع خط تحت الرابط",
|
||||
"preferences.fields.unfollow_modal_label": "أظهار إشعار لتأكيد إلغاء المتابعة قبل التنفيذ",
|
||||
"preferences.hints.demetricator": "تقليل قلق التواصل الاجتماعي من خلال إخفاء جميع الأرقام في المنصّة.",
|
||||
"preferences.hints.feed": "في الخط الزمني الخاص بك",
|
||||
"preferences.notifications.advanced": "عرض جميع تصنيفات الإشعارات",
|
||||
"preferences.options.content_type_markdown": "ماركداون",
|
||||
"preferences.options.content_type_plaintext": "نص عادي",
|
||||
|
@ -1016,7 +1000,6 @@
|
|||
"sms_verification.sent.body": "لقد أرسلنا لك رمزًا مكونًا من 6 أرقام عبر رسالة نصية قصيرة. رجاءً أدخله في الأسفل.",
|
||||
"sms_verification.sent.header": "تأكيد الرمز",
|
||||
"sms_verification.success": "تم إرسال رمز التحقق إلى رقم هاتفك.",
|
||||
"toast.view": "عرض",
|
||||
"soapbox_config.authenticated_profile_hint": "على المستخدمين أن يُسجلوا دخولهم كي يتمكنوا من عرض الردود والوسائط على الحسابات الشخصية للمستخدمين.",
|
||||
"soapbox_config.authenticated_profile_label": "حسابات شخصية تتطلب تسجيل الدخول لتصفحها",
|
||||
"soapbox_config.copyright_footer.meta_fields.label_placeholder": "حاشية حقوق الطبع والنشر",
|
||||
|
@ -1029,8 +1012,6 @@
|
|||
"soapbox_config.display_fqn_label": "عرض اسم النطاق للحسابات المحلية (مثال zaki@instance)",
|
||||
"soapbox_config.feed_injection_hint": "حقن الخط الزمني بمحتوى إضافي مثل حسابات مقترحة.",
|
||||
"soapbox_config.feed_injection_label": "حقن الخط الزمني",
|
||||
"soapbox_config.fields.accent_color_label": "لون التمييز",
|
||||
"soapbox_config.fields.brand_color_label": "لون العلامة التجارية",
|
||||
"soapbox_config.fields.crypto_addresses_label": "عناوين العملات الافتراضية",
|
||||
"soapbox_config.fields.home_footer_fields_label": "العناصر في حاشية الصفحة الرئيسية",
|
||||
"soapbox_config.fields.logo_label": "الشعار",
|
||||
|
@ -1139,7 +1120,6 @@
|
|||
"sw.update_text": "هناك تحديث متوفر",
|
||||
"sw.url": "رابط الإسكربت",
|
||||
"tabs_bar.all": "الكل",
|
||||
"tabs_bar.chats": "المحادثات",
|
||||
"tabs_bar.dashboard": "لوحة التحكم",
|
||||
"tabs_bar.fediverse": "الكون الفيدرالي الإجتماعي",
|
||||
"tabs_bar.home": "الرئيسية",
|
||||
|
@ -1161,10 +1141,10 @@
|
|||
"time_remaining.minutes": "{number, plural, one {# دقيقة} other {# دقائق}} متبقية",
|
||||
"time_remaining.moments": "لحظات متبقية",
|
||||
"time_remaining.seconds": "{number, plural, one {# ثانية} other {# ثوانٍ}} متبقية",
|
||||
"toast.view": "عرض",
|
||||
"trends.count_by_accounts": "{count} {rawCount, plural, one {person} آخرون {people}} يتحدثون",
|
||||
"trends.title": "الشائع",
|
||||
"trendsPanel.viewAll": "إظهار الكل",
|
||||
"ui.beforeunload": "محتوى المسودة سيضيع اذا خرجت",
|
||||
"unauthorized_modal.text": "يجب عليك تسجيل الدخول لتتمكن من القيام بذلك.",
|
||||
"unauthorized_modal.title": "التسجيل في {site_title}",
|
||||
"upload_area.title": "اسحب ملف وافلته لتحميله",
|
||||
|
|
|
@ -147,7 +147,6 @@
|
|||
"alert.unexpected.links.support": "Support",
|
||||
"alert.unexpected.message": "Asocedió un fallu inesperáu.",
|
||||
"alert.unexpected.return_home": "Return Home",
|
||||
"alert.unexpected.title": "¡Ups!",
|
||||
"aliases.account.add": "Create alias",
|
||||
"aliases.account_label": "Old account:",
|
||||
"aliases.aliases_list_delete": "Unlink alias",
|
||||
|
@ -186,18 +185,9 @@
|
|||
"bundle_modal_error.message": "Something went wrong while loading this modal.",
|
||||
"bundle_modal_error.retry": "Try again",
|
||||
"card.back.label": "Back",
|
||||
"chat_box.actions.send": "Send",
|
||||
"chat_box.input.placeholder": "Send a message…",
|
||||
"chat_panels.main_window.empty": "No chats found. To start a chat, visit a user's profile.",
|
||||
"chat_panels.main_window.title": "Chats",
|
||||
"chat_window.close": "Close chat",
|
||||
"chats.actions.delete": "Delete message",
|
||||
"chats.actions.more": "More",
|
||||
"chats.actions.report": "Report user",
|
||||
"chats.attachment": "Attachment",
|
||||
"chats.attachment_image": "Image",
|
||||
"chats.audio_toggle_off": "Audio notification off",
|
||||
"chats.audio_toggle_on": "Audio notification on",
|
||||
"chats.dividers.today": "Today",
|
||||
"chats.search_placeholder": "Start a chat with…",
|
||||
"column.admin.awaiting_approval": "Awaiting Approval",
|
||||
|
@ -270,13 +260,11 @@
|
|||
"column.public": "Llinia temporal federada",
|
||||
"column.reactions": "Reactions",
|
||||
"column.reblogs": "Reposts",
|
||||
"column.remote": "Federated timeline",
|
||||
"column.scheduled_statuses": "Scheduled Posts",
|
||||
"column.search": "Search",
|
||||
"column.settings_store": "Settings store",
|
||||
"column.soapbox_config": "Soapbox config",
|
||||
"column.test": "Test timeline",
|
||||
"column_back_button.label": "Atrás",
|
||||
"column_forbidden.body": "You do not have permission to access this page.",
|
||||
"column_forbidden.title": "Forbidden",
|
||||
"common.cancel": "Cancel",
|
||||
|
@ -372,8 +360,6 @@
|
|||
"confirmations.scheduled_status_delete.heading": "Cancel scheduled post",
|
||||
"confirmations.scheduled_status_delete.message": "Are you sure you want to cancel this scheduled post?",
|
||||
"confirmations.unfollow.confirm": "Unfollow",
|
||||
"confirmations.unfollow.heading": "Unfollow {name}",
|
||||
"confirmations.unfollow.message": "¿De xuru que quies dexar de siguir a {name}?",
|
||||
"crypto_donate.explanation_box.message": "{siteTitle} accepts cryptocurrency donations. You may send a donation to any of the addresses below. Thank you for your support!",
|
||||
"crypto_donate.explanation_box.title": "Sending cryptocurrency donations",
|
||||
"crypto_donate_panel.actions.view": "Click to see {count} {count, plural, one {wallet} other {wallets}}",
|
||||
|
@ -822,7 +808,6 @@
|
|||
"preferences.fields.display_media.default": "Hide media marked as sensitive",
|
||||
"preferences.fields.display_media.hide_all": "Always hide media",
|
||||
"preferences.fields.display_media.show_all": "Always show media",
|
||||
"preferences.fields.dyslexic_font_label": "Dyslexic mode",
|
||||
"preferences.fields.expand_spoilers_label": "Always expand posts marked with content warnings",
|
||||
"preferences.fields.language_label": "Language",
|
||||
"preferences.fields.media_display_label": "Media display",
|
||||
|
@ -834,7 +819,6 @@
|
|||
"preferences.fields.underline_links_label": "Always underline links in posts",
|
||||
"preferences.fields.unfollow_modal_label": "Show confirmation dialog before unfollowing someone",
|
||||
"preferences.hints.demetricator": "Decrease social media anxiety by hiding all numbers from the site.",
|
||||
"preferences.hints.feed": "In your home feed",
|
||||
"preferences.notifications.advanced": "Show all notification categories",
|
||||
"preferences.options.content_type_markdown": "Markdown",
|
||||
"preferences.options.content_type_plaintext": "Plain text",
|
||||
|
@ -1016,7 +1000,6 @@
|
|||
"sms_verification.sent.body": "We sent you a 6-digit code via SMS. Enter it below.",
|
||||
"sms_verification.sent.header": "Verification code",
|
||||
"sms_verification.success": "A verification code has been sent to your phone number.",
|
||||
"toast.view": "View",
|
||||
"soapbox_config.authenticated_profile_hint": "Users must be logged-in to view replies and media on user profiles.",
|
||||
"soapbox_config.authenticated_profile_label": "Profiles require authentication",
|
||||
"soapbox_config.copyright_footer.meta_fields.label_placeholder": "Copyright footer",
|
||||
|
@ -1029,8 +1012,6 @@
|
|||
"soapbox_config.display_fqn_label": "Display domain (eg @user@domain) for local accounts.",
|
||||
"soapbox_config.feed_injection_hint": "Inject the feed with additional content, such as suggested profiles.",
|
||||
"soapbox_config.feed_injection_label": "Feed injection",
|
||||
"soapbox_config.fields.accent_color_label": "Accent color",
|
||||
"soapbox_config.fields.brand_color_label": "Brand color",
|
||||
"soapbox_config.fields.crypto_addresses_label": "Cryptocurrency addresses",
|
||||
"soapbox_config.fields.home_footer_fields_label": "Home footer items",
|
||||
"soapbox_config.fields.logo_label": "Logo",
|
||||
|
@ -1139,7 +1120,6 @@
|
|||
"sw.update_text": "An update is available.",
|
||||
"sw.url": "Script URL",
|
||||
"tabs_bar.all": "All",
|
||||
"tabs_bar.chats": "Chats",
|
||||
"tabs_bar.dashboard": "Dashboard",
|
||||
"tabs_bar.fediverse": "Fediverse",
|
||||
"tabs_bar.home": "Aniciu",
|
||||
|
@ -1161,10 +1141,10 @@
|
|||
"time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
|
||||
"time_remaining.moments": "Moments remaining",
|
||||
"time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
|
||||
"toast.view": "View",
|
||||
"trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
|
||||
"trends.title": "Trends",
|
||||
"trendsPanel.viewAll": "View all",
|
||||
"ui.beforeunload": "El borrador va perdese si coles de Soapbox.",
|
||||
"unauthorized_modal.text": "You need to be logged in to do that.",
|
||||
"unauthorized_modal.title": "Sign up for {site_title}",
|
||||
"upload_area.title": "Drag & drop to upload",
|
||||
|
|
|
@ -147,7 +147,6 @@
|
|||
"alert.unexpected.links.support": "Support",
|
||||
"alert.unexpected.message": "An unexpected error occurred.",
|
||||
"alert.unexpected.return_home": "Return Home",
|
||||
"alert.unexpected.title": "Oops!",
|
||||
"aliases.account.add": "Create alias",
|
||||
"aliases.account_label": "Old account:",
|
||||
"aliases.aliases_list_delete": "Unlink alias",
|
||||
|
@ -186,18 +185,9 @@
|
|||
"bundle_modal_error.message": "Something went wrong while loading this modal.",
|
||||
"bundle_modal_error.retry": "Try again",
|
||||
"card.back.label": "Back",
|
||||
"chat_box.actions.send": "Send",
|
||||
"chat_box.input.placeholder": "Send a message…",
|
||||
"chat_panels.main_window.empty": "No chats found. To start a chat, visit a user's profile.",
|
||||
"chat_panels.main_window.title": "Chats",
|
||||
"chat_window.close": "Close chat",
|
||||
"chats.actions.delete": "Delete message",
|
||||
"chats.actions.more": "More",
|
||||
"chats.actions.report": "Report user",
|
||||
"chats.attachment": "Attachment",
|
||||
"chats.attachment_image": "Image",
|
||||
"chats.audio_toggle_off": "Audio notification off",
|
||||
"chats.audio_toggle_on": "Audio notification on",
|
||||
"chats.dividers.today": "Today",
|
||||
"chats.search_placeholder": "Start a chat with…",
|
||||
"column.admin.awaiting_approval": "Awaiting Approval",
|
||||
|
@ -270,13 +260,11 @@
|
|||
"column.public": "Публичен канал",
|
||||
"column.reactions": "Reactions",
|
||||
"column.reblogs": "Reposts",
|
||||
"column.remote": "Federated timeline",
|
||||
"column.scheduled_statuses": "Scheduled Posts",
|
||||
"column.search": "Search",
|
||||
"column.settings_store": "Settings store",
|
||||
"column.soapbox_config": "Soapbox config",
|
||||
"column.test": "Test timeline",
|
||||
"column_back_button.label": "Назад",
|
||||
"column_forbidden.body": "You do not have permission to access this page.",
|
||||
"column_forbidden.title": "Forbidden",
|
||||
"common.cancel": "Cancel",
|
||||
|
@ -372,8 +360,6 @@
|
|||
"confirmations.scheduled_status_delete.heading": "Cancel scheduled post",
|
||||
"confirmations.scheduled_status_delete.message": "Are you sure you want to cancel this scheduled post?",
|
||||
"confirmations.unfollow.confirm": "Unfollow",
|
||||
"confirmations.unfollow.heading": "Unfollow {name}",
|
||||
"confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
|
||||
"crypto_donate.explanation_box.message": "{siteTitle} accepts cryptocurrency donations. You may send a donation to any of the addresses below. Thank you for your support!",
|
||||
"crypto_donate.explanation_box.title": "Sending cryptocurrency donations",
|
||||
"crypto_donate_panel.actions.view": "Click to see {count} {count, plural, one {wallet} other {wallets}}",
|
||||
|
@ -822,7 +808,6 @@
|
|||
"preferences.fields.display_media.default": "Hide media marked as sensitive",
|
||||
"preferences.fields.display_media.hide_all": "Always hide media",
|
||||
"preferences.fields.display_media.show_all": "Always show media",
|
||||
"preferences.fields.dyslexic_font_label": "Dyslexic mode",
|
||||
"preferences.fields.expand_spoilers_label": "Always expand posts marked with content warnings",
|
||||
"preferences.fields.language_label": "Language",
|
||||
"preferences.fields.media_display_label": "Media display",
|
||||
|
@ -834,7 +819,6 @@
|
|||
"preferences.fields.underline_links_label": "Always underline links in posts",
|
||||
"preferences.fields.unfollow_modal_label": "Show confirmation dialog before unfollowing someone",
|
||||
"preferences.hints.demetricator": "Decrease social media anxiety by hiding all numbers from the site.",
|
||||
"preferences.hints.feed": "In your home feed",
|
||||
"preferences.notifications.advanced": "Show all notification categories",
|
||||
"preferences.options.content_type_markdown": "Markdown",
|
||||
"preferences.options.content_type_plaintext": "Plain text",
|
||||
|
@ -1016,7 +1000,6 @@
|
|||
"sms_verification.sent.body": "We sent you a 6-digit code via SMS. Enter it below.",
|
||||
"sms_verification.sent.header": "Verification code",
|
||||
"sms_verification.success": "A verification code has been sent to your phone number.",
|
||||
"toast.view": "View",
|
||||
"soapbox_config.authenticated_profile_hint": "Users must be logged-in to view replies and media on user profiles.",
|
||||
"soapbox_config.authenticated_profile_label": "Profiles require authentication",
|
||||
"soapbox_config.copyright_footer.meta_fields.label_placeholder": "Copyright footer",
|
||||
|
@ -1029,8 +1012,6 @@
|
|||
"soapbox_config.display_fqn_label": "Display domain (eg @user@domain) for local accounts.",
|
||||
"soapbox_config.feed_injection_hint": "Inject the feed with additional content, such as suggested profiles.",
|
||||
"soapbox_config.feed_injection_label": "Feed injection",
|
||||
"soapbox_config.fields.accent_color_label": "Accent color",
|
||||
"soapbox_config.fields.brand_color_label": "Brand color",
|
||||
"soapbox_config.fields.crypto_addresses_label": "Cryptocurrency addresses",
|
||||
"soapbox_config.fields.home_footer_fields_label": "Home footer items",
|
||||
"soapbox_config.fields.logo_label": "Logo",
|
||||
|
@ -1139,7 +1120,6 @@
|
|||
"sw.update_text": "An update is available.",
|
||||
"sw.url": "Script URL",
|
||||
"tabs_bar.all": "All",
|
||||
"tabs_bar.chats": "Chats",
|
||||
"tabs_bar.dashboard": "Dashboard",
|
||||
"tabs_bar.fediverse": "Fediverse",
|
||||
"tabs_bar.home": "Начало",
|
||||
|
@ -1161,10 +1141,10 @@
|
|||
"time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
|
||||
"time_remaining.moments": "Moments remaining",
|
||||
"time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
|
||||
"toast.view": "View",
|
||||
"trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
|
||||
"trends.title": "Trends",
|
||||
"trendsPanel.viewAll": "View all",
|
||||
"ui.beforeunload": "Your draft will be lost if you leave.",
|
||||
"unauthorized_modal.text": "You need to be logged in to do that.",
|
||||
"unauthorized_modal.title": "Sign up for {site_title}",
|
||||
"upload_area.title": "Drag & drop to upload",
|
||||
|
|
|
@ -147,7 +147,6 @@
|
|||
"alert.unexpected.links.support": "Support",
|
||||
"alert.unexpected.message": "অপ্রত্যাশিত একটি সমস্যা হয়েছে।",
|
||||
"alert.unexpected.return_home": "Return Home",
|
||||
"alert.unexpected.title": "ওহো!",
|
||||
"aliases.account.add": "Create alias",
|
||||
"aliases.account_label": "Old account:",
|
||||
"aliases.aliases_list_delete": "Unlink alias",
|
||||
|
@ -186,18 +185,9 @@
|
|||
"bundle_modal_error.message": "এই অংশটি দেখাতে যেয়ে কোনো সমস্যা হয়েছে।",
|
||||
"bundle_modal_error.retry": "আবার চেষ্টা করুন",
|
||||
"card.back.label": "Back",
|
||||
"chat_box.actions.send": "Send",
|
||||
"chat_box.input.placeholder": "Send a message…",
|
||||
"chat_panels.main_window.empty": "No chats found. To start a chat, visit a user's profile.",
|
||||
"chat_panels.main_window.title": "Chats",
|
||||
"chat_window.close": "Close chat",
|
||||
"chats.actions.delete": "Delete message",
|
||||
"chats.actions.more": "More",
|
||||
"chats.actions.report": "Report user",
|
||||
"chats.attachment": "Attachment",
|
||||
"chats.attachment_image": "Image",
|
||||
"chats.audio_toggle_off": "Audio notification off",
|
||||
"chats.audio_toggle_on": "Audio notification on",
|
||||
"chats.dividers.today": "Today",
|
||||
"chats.search_placeholder": "Start a chat with…",
|
||||
"column.admin.awaiting_approval": "Awaiting Approval",
|
||||
|
@ -270,13 +260,11 @@
|
|||
"column.public": "যুক্ত সময়রেখা",
|
||||
"column.reactions": "Reactions",
|
||||
"column.reblogs": "Reposts",
|
||||
"column.remote": "Federated timeline",
|
||||
"column.scheduled_statuses": "Scheduled Posts",
|
||||
"column.search": "Search",
|
||||
"column.settings_store": "Settings store",
|
||||
"column.soapbox_config": "Soapbox config",
|
||||
"column.test": "Test timeline",
|
||||
"column_back_button.label": "পেছনে",
|
||||
"column_forbidden.body": "You do not have permission to access this page.",
|
||||
"column_forbidden.title": "Forbidden",
|
||||
"common.cancel": "Cancel",
|
||||
|
@ -372,8 +360,6 @@
|
|||
"confirmations.scheduled_status_delete.heading": "Cancel scheduled post",
|
||||
"confirmations.scheduled_status_delete.message": "Are you sure you want to cancel this scheduled post?",
|
||||
"confirmations.unfollow.confirm": "অনুসরণ করা বাতিল করতে",
|
||||
"confirmations.unfollow.heading": "Unfollow {name}",
|
||||
"confirmations.unfollow.message": "আপনি কি নিশ্চিত {name} কে আর অনুসরণ করতে চান না ?",
|
||||
"crypto_donate.explanation_box.message": "{siteTitle} accepts cryptocurrency donations. You may send a donation to any of the addresses below. Thank you for your support!",
|
||||
"crypto_donate.explanation_box.title": "Sending cryptocurrency donations",
|
||||
"crypto_donate_panel.actions.view": "Click to see {count} {count, plural, one {wallet} other {wallets}}",
|
||||
|
@ -822,7 +808,6 @@
|
|||
"preferences.fields.display_media.default": "Hide media marked as sensitive",
|
||||
"preferences.fields.display_media.hide_all": "Always hide media",
|
||||
"preferences.fields.display_media.show_all": "Always show media",
|
||||
"preferences.fields.dyslexic_font_label": "Dyslexic mode",
|
||||
"preferences.fields.expand_spoilers_label": "Always expand posts marked with content warnings",
|
||||
"preferences.fields.language_label": "Language",
|
||||
"preferences.fields.media_display_label": "Media display",
|
||||
|
@ -834,7 +819,6 @@
|
|||
"preferences.fields.underline_links_label": "Always underline links in posts",
|
||||
"preferences.fields.unfollow_modal_label": "Show confirmation dialog before unfollowing someone",
|
||||
"preferences.hints.demetricator": "Decrease social media anxiety by hiding all numbers from the site.",
|
||||
"preferences.hints.feed": "In your home feed",
|
||||
"preferences.notifications.advanced": "Show all notification categories",
|
||||
"preferences.options.content_type_markdown": "Markdown",
|
||||
"preferences.options.content_type_plaintext": "Plain text",
|
||||
|
@ -1016,7 +1000,6 @@
|
|||
"sms_verification.sent.body": "We sent you a 6-digit code via SMS. Enter it below.",
|
||||
"sms_verification.sent.header": "Verification code",
|
||||
"sms_verification.success": "A verification code has been sent to your phone number.",
|
||||
"toast.view": "View",
|
||||
"soapbox_config.authenticated_profile_hint": "Users must be logged-in to view replies and media on user profiles.",
|
||||
"soapbox_config.authenticated_profile_label": "Profiles require authentication",
|
||||
"soapbox_config.copyright_footer.meta_fields.label_placeholder": "Copyright footer",
|
||||
|
@ -1029,8 +1012,6 @@
|
|||
"soapbox_config.display_fqn_label": "Display domain (eg @user@domain) for local accounts.",
|
||||
"soapbox_config.feed_injection_hint": "Inject the feed with additional content, such as suggested profiles.",
|
||||
"soapbox_config.feed_injection_label": "Feed injection",
|
||||
"soapbox_config.fields.accent_color_label": "Accent color",
|
||||
"soapbox_config.fields.brand_color_label": "Brand color",
|
||||
"soapbox_config.fields.crypto_addresses_label": "Cryptocurrency addresses",
|
||||
"soapbox_config.fields.home_footer_fields_label": "Home footer items",
|
||||
"soapbox_config.fields.logo_label": "Logo",
|
||||
|
@ -1139,7 +1120,6 @@
|
|||
"sw.update_text": "An update is available.",
|
||||
"sw.url": "Script URL",
|
||||
"tabs_bar.all": "All",
|
||||
"tabs_bar.chats": "Chats",
|
||||
"tabs_bar.dashboard": "Dashboard",
|
||||
"tabs_bar.fediverse": "Fediverse",
|
||||
"tabs_bar.home": "বাড়ি",
|
||||
|
@ -1161,10 +1141,10 @@
|
|||
"time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} বাকি আছে",
|
||||
"time_remaining.moments": "সময় বাকি আছে",
|
||||
"time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} বাকি আছে",
|
||||
"toast.view": "View",
|
||||
"trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} কথা বলছে",
|
||||
"trends.title": "Trends",
|
||||
"trendsPanel.viewAll": "View all",
|
||||
"ui.beforeunload": "যে পর্যন্ত এটা লেখা হয়েছে, Soapbox থেকে চলে গেলে এটা মুছে যাবে।",
|
||||
"unauthorized_modal.text": "You need to be logged in to do that.",
|
||||
"unauthorized_modal.title": "Sign up for {site_title}",
|
||||
"upload_area.title": "টেনে এখানে ছেড়ে দিলে এখানে যুক্ত করা যাবে",
|
||||
|
|
|
@ -147,7 +147,6 @@
|
|||
"alert.unexpected.links.support": "Support",
|
||||
"alert.unexpected.message": "Ur fazi dic'hortozet zo degouezhet.",
|
||||
"alert.unexpected.return_home": "Return Home",
|
||||
"alert.unexpected.title": "C'hem !",
|
||||
"aliases.account.add": "Create alias",
|
||||
"aliases.account_label": "Old account:",
|
||||
"aliases.aliases_list_delete": "Unlink alias",
|
||||
|
@ -186,18 +185,9 @@
|
|||
"bundle_modal_error.message": "Something went wrong while loading this modal.",
|
||||
"bundle_modal_error.retry": "Klask endro",
|
||||
"card.back.label": "Back",
|
||||
"chat_box.actions.send": "Send",
|
||||
"chat_box.input.placeholder": "Send a message…",
|
||||
"chat_panels.main_window.empty": "No chats found. To start a chat, visit a user's profile.",
|
||||
"chat_panels.main_window.title": "Chats",
|
||||
"chat_window.close": "Close chat",
|
||||
"chats.actions.delete": "Delete message",
|
||||
"chats.actions.more": "More",
|
||||
"chats.actions.report": "Report user",
|
||||
"chats.attachment": "Attachment",
|
||||
"chats.attachment_image": "Image",
|
||||
"chats.audio_toggle_off": "Audio notification off",
|
||||
"chats.audio_toggle_on": "Audio notification on",
|
||||
"chats.dividers.today": "Today",
|
||||
"chats.search_placeholder": "Start a chat with…",
|
||||
"column.admin.awaiting_approval": "Awaiting Approval",
|
||||
|
@ -270,13 +260,11 @@
|
|||
"column.public": "Federated timeline",
|
||||
"column.reactions": "Reactions",
|
||||
"column.reblogs": "Reposts",
|
||||
"column.remote": "Federated timeline",
|
||||
"column.scheduled_statuses": "Scheduled Posts",
|
||||
"column.search": "Search",
|
||||
"column.settings_store": "Settings store",
|
||||
"column.soapbox_config": "Soapbox config",
|
||||
"column.test": "Test timeline",
|
||||
"column_back_button.label": "Back",
|
||||
"column_forbidden.body": "You do not have permission to access this page.",
|
||||
"column_forbidden.title": "Forbidden",
|
||||
"common.cancel": "Cancel",
|
||||
|
@ -372,8 +360,6 @@
|
|||
"confirmations.scheduled_status_delete.heading": "Cancel scheduled post",
|
||||
"confirmations.scheduled_status_delete.message": "Are you sure you want to cancel this scheduled post?",
|
||||
"confirmations.unfollow.confirm": "Unfollow",
|
||||
"confirmations.unfollow.heading": "Unfollow {name}",
|
||||
"confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
|
||||
"crypto_donate.explanation_box.message": "{siteTitle} accepts cryptocurrency donations. You may send a donation to any of the addresses below. Thank you for your support!",
|
||||
"crypto_donate.explanation_box.title": "Sending cryptocurrency donations",
|
||||
"crypto_donate_panel.actions.view": "Click to see {count} {count, plural, one {wallet} other {wallets}}",
|
||||
|
@ -822,7 +808,6 @@
|
|||
"preferences.fields.display_media.default": "Hide media marked as sensitive",
|
||||
"preferences.fields.display_media.hide_all": "Always hide media",
|
||||
"preferences.fields.display_media.show_all": "Always show media",
|
||||
"preferences.fields.dyslexic_font_label": "Dyslexic mode",
|
||||
"preferences.fields.expand_spoilers_label": "Always expand posts marked with content warnings",
|
||||
"preferences.fields.language_label": "Language",
|
||||
"preferences.fields.media_display_label": "Media display",
|
||||
|
@ -834,7 +819,6 @@
|
|||
"preferences.fields.underline_links_label": "Always underline links in posts",
|
||||
"preferences.fields.unfollow_modal_label": "Show confirmation dialog before unfollowing someone",
|
||||
"preferences.hints.demetricator": "Decrease social media anxiety by hiding all numbers from the site.",
|
||||
"preferences.hints.feed": "In your home feed",
|
||||
"preferences.notifications.advanced": "Show all notification categories",
|
||||
"preferences.options.content_type_markdown": "Markdown",
|
||||
"preferences.options.content_type_plaintext": "Plain text",
|
||||
|
@ -1016,7 +1000,6 @@
|
|||
"sms_verification.sent.body": "We sent you a 6-digit code via SMS. Enter it below.",
|
||||
"sms_verification.sent.header": "Verification code",
|
||||
"sms_verification.success": "A verification code has been sent to your phone number.",
|
||||
"toast.view": "View",
|
||||
"soapbox_config.authenticated_profile_hint": "Users must be logged-in to view replies and media on user profiles.",
|
||||
"soapbox_config.authenticated_profile_label": "Profiles require authentication",
|
||||
"soapbox_config.copyright_footer.meta_fields.label_placeholder": "Copyright footer",
|
||||
|
@ -1029,8 +1012,6 @@
|
|||
"soapbox_config.display_fqn_label": "Display domain (eg @user@domain) for local accounts.",
|
||||
"soapbox_config.feed_injection_hint": "Inject the feed with additional content, such as suggested profiles.",
|
||||
"soapbox_config.feed_injection_label": "Feed injection",
|
||||
"soapbox_config.fields.accent_color_label": "Accent color",
|
||||
"soapbox_config.fields.brand_color_label": "Brand color",
|
||||
"soapbox_config.fields.crypto_addresses_label": "Cryptocurrency addresses",
|
||||
"soapbox_config.fields.home_footer_fields_label": "Home footer items",
|
||||
"soapbox_config.fields.logo_label": "Logo",
|
||||
|
@ -1139,7 +1120,6 @@
|
|||
"sw.update_text": "An update is available.",
|
||||
"sw.url": "Script URL",
|
||||
"tabs_bar.all": "All",
|
||||
"tabs_bar.chats": "Chats",
|
||||
"tabs_bar.dashboard": "Dashboard",
|
||||
"tabs_bar.fediverse": "Fediverse",
|
||||
"tabs_bar.home": "Home",
|
||||
|
@ -1161,10 +1141,10 @@
|
|||
"time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
|
||||
"time_remaining.moments": "Moments remaining",
|
||||
"time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
|
||||
"toast.view": "View",
|
||||
"trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
|
||||
"trends.title": "Trends",
|
||||
"trendsPanel.viewAll": "View all",
|
||||
"ui.beforeunload": "Your draft will be lost if you leave.",
|
||||
"unauthorized_modal.text": "You need to be logged in to do that.",
|
||||
"unauthorized_modal.title": "Sign up for {site_title}",
|
||||
"upload_area.title": "Drag & drop to upload",
|
||||
|
|
|
@ -147,7 +147,6 @@
|
|||
"alert.unexpected.links.support": "Support",
|
||||
"alert.unexpected.message": "S'ha produït un error inesperat.",
|
||||
"alert.unexpected.return_home": "Return Home",
|
||||
"alert.unexpected.title": "Vaja!",
|
||||
"aliases.account.add": "Create alias",
|
||||
"aliases.account_label": "Old account:",
|
||||
"aliases.aliases_list_delete": "Unlink alias",
|
||||
|
@ -186,18 +185,9 @@
|
|||
"bundle_modal_error.message": "S'ha produït un error en carregar aquest component.",
|
||||
"bundle_modal_error.retry": "Torna-ho a provar",
|
||||
"card.back.label": "Back",
|
||||
"chat_box.actions.send": "Envia",
|
||||
"chat_box.input.placeholder": "Envia un missatge…",
|
||||
"chat_panels.main_window.empty": "Cap xat trobat. Per arrencar un xat, visita el perfil d'un usuari.",
|
||||
"chat_panels.main_window.title": "Xats",
|
||||
"chat_window.close": "Close chat",
|
||||
"chats.actions.delete": "Elimina missatge",
|
||||
"chats.actions.more": "Més",
|
||||
"chats.actions.report": "Denunciar usuari",
|
||||
"chats.attachment": "Attachment",
|
||||
"chats.attachment_image": "Image",
|
||||
"chats.audio_toggle_off": "Notificació amb so desactivada",
|
||||
"chats.audio_toggle_on": "Notificació amb so activada",
|
||||
"chats.dividers.today": "Avui",
|
||||
"chats.search_placeholder": "Start a chat with…",
|
||||
"column.admin.awaiting_approval": "Esperant aprovació",
|
||||
|
@ -270,13 +260,11 @@
|
|||
"column.public": "Línia de temps federada",
|
||||
"column.reactions": "Reactions",
|
||||
"column.reblogs": "Reposts",
|
||||
"column.remote": "Línia de temps federada",
|
||||
"column.scheduled_statuses": "Scheduled Posts",
|
||||
"column.search": "Search",
|
||||
"column.settings_store": "Settings store",
|
||||
"column.soapbox_config": "Configuració de Soapbox",
|
||||
"column.test": "Test timeline",
|
||||
"column_back_button.label": "Enrere",
|
||||
"column_forbidden.body": "You do not have permission to access this page.",
|
||||
"column_forbidden.title": "Forbidden",
|
||||
"common.cancel": "Cancel",
|
||||
|
@ -372,8 +360,6 @@
|
|||
"confirmations.scheduled_status_delete.heading": "Cancel scheduled post",
|
||||
"confirmations.scheduled_status_delete.message": "Are you sure you want to cancel this scheduled post?",
|
||||
"confirmations.unfollow.confirm": "Deixa de seguir",
|
||||
"confirmations.unfollow.heading": "Unfollow {name}",
|
||||
"confirmations.unfollow.message": "Estàs segur que vols deixar de seguir {name}?",
|
||||
"crypto_donate.explanation_box.message": "{siteTitle} accepts cryptocurrency donations. You may send a donation to any of the addresses below. Thank you for your support!",
|
||||
"crypto_donate.explanation_box.title": "Sending cryptocurrency donations",
|
||||
"crypto_donate_panel.actions.view": "Click to see {count} {count, plural, one {wallet} other {wallets}}",
|
||||
|
@ -822,7 +808,6 @@
|
|||
"preferences.fields.display_media.default": "Amaga les imatges marcades com a sensibles",
|
||||
"preferences.fields.display_media.hide_all": "Oculta sempre les imatges",
|
||||
"preferences.fields.display_media.show_all": "Mostra sempre les imatges",
|
||||
"preferences.fields.dyslexic_font_label": "Dyslexic mode",
|
||||
"preferences.fields.expand_spoilers_label": "Expandeix sempre els missatges marcats amb avisos de contingut",
|
||||
"preferences.fields.language_label": "Llengua",
|
||||
"preferences.fields.media_display_label": "Visualització multimèdia",
|
||||
|
@ -834,7 +819,6 @@
|
|||
"preferences.fields.underline_links_label": "Always underline links in posts",
|
||||
"preferences.fields.unfollow_modal_label": "Show confirmation dialog before unfollowing someone",
|
||||
"preferences.hints.demetricator": "Decrease social media anxiety by hiding all numbers from the site.",
|
||||
"preferences.hints.feed": "In your home feed",
|
||||
"preferences.notifications.advanced": "Show all notification categories",
|
||||
"preferences.options.content_type_markdown": "Markdown",
|
||||
"preferences.options.content_type_plaintext": "Plain text",
|
||||
|
@ -1016,7 +1000,6 @@
|
|||
"sms_verification.sent.body": "We sent you a 6-digit code via SMS. Enter it below.",
|
||||
"sms_verification.sent.header": "Verification code",
|
||||
"sms_verification.success": "A verification code has been sent to your phone number.",
|
||||
"toast.view": "View",
|
||||
"soapbox_config.authenticated_profile_hint": "Users must be logged-in to view replies and media on user profiles.",
|
||||
"soapbox_config.authenticated_profile_label": "Profiles require authentication",
|
||||
"soapbox_config.copyright_footer.meta_fields.label_placeholder": "Peu de pàgina dels drets d'autor",
|
||||
|
@ -1029,8 +1012,6 @@
|
|||
"soapbox_config.display_fqn_label": "Mostra el domini (eg @user@domain) per als comptes locals.",
|
||||
"soapbox_config.feed_injection_hint": "Inject the feed with additional content, such as suggested profiles.",
|
||||
"soapbox_config.feed_injection_label": "Feed injection",
|
||||
"soapbox_config.fields.accent_color_label": "Accent color",
|
||||
"soapbox_config.fields.brand_color_label": "Color de la marca",
|
||||
"soapbox_config.fields.crypto_addresses_label": "Cryptocurrency addresses",
|
||||
"soapbox_config.fields.home_footer_fields_label": "Elements de peu de pàgina d'inici",
|
||||
"soapbox_config.fields.logo_label": "Logo",
|
||||
|
@ -1139,7 +1120,6 @@
|
|||
"sw.update_text": "An update is available.",
|
||||
"sw.url": "Script URL",
|
||||
"tabs_bar.all": "All",
|
||||
"tabs_bar.chats": "Xats",
|
||||
"tabs_bar.dashboard": "Tauler",
|
||||
"tabs_bar.fediverse": "Fediverse",
|
||||
"tabs_bar.home": "Inici",
|
||||
|
@ -1161,10 +1141,10 @@
|
|||
"time_remaining.minutes": "{number, plural, one {# minut} other {# minuts}} restants",
|
||||
"time_remaining.moments": "Moments restants",
|
||||
"time_remaining.seconds": "{number, plural, one {# segon} other {# segons}} restants",
|
||||
"toast.view": "View",
|
||||
"trends.count_by_accounts": "{count} {rawCount, plural, one {persona} other {persones}} parlant-hi",
|
||||
"trends.title": "Tendències",
|
||||
"trendsPanel.viewAll": "View all",
|
||||
"ui.beforeunload": "El teu esborrany es perdrà si surts de Soapbox.",
|
||||
"unauthorized_modal.text": "Heu d'iniciar sessió per fer això.",
|
||||
"unauthorized_modal.title": "Registrar-se a {site_title}",
|
||||
"upload_area.title": "Arrossega i deixa anar per a carregar",
|
||||
|
|
|
@ -147,7 +147,6 @@
|
|||
"alert.unexpected.links.support": "Support",
|
||||
"alert.unexpected.message": "Un prublemu inaspettatu hè accadutu.",
|
||||
"alert.unexpected.return_home": "Return Home",
|
||||
"alert.unexpected.title": "Uups!",
|
||||
"aliases.account.add": "Create alias",
|
||||
"aliases.account_label": "Old account:",
|
||||
"aliases.aliases_list_delete": "Unlink alias",
|
||||
|
@ -186,18 +185,9 @@
|
|||
"bundle_modal_error.message": "C'hè statu un prublemu caricandu st'elementu.",
|
||||
"bundle_modal_error.retry": "Pruvà torna",
|
||||
"card.back.label": "Back",
|
||||
"chat_box.actions.send": "Send",
|
||||
"chat_box.input.placeholder": "Send a message…",
|
||||
"chat_panels.main_window.empty": "No chats found. To start a chat, visit a user's profile.",
|
||||
"chat_panels.main_window.title": "Chats",
|
||||
"chat_window.close": "Close chat",
|
||||
"chats.actions.delete": "Delete message",
|
||||
"chats.actions.more": "More",
|
||||
"chats.actions.report": "Report user",
|
||||
"chats.attachment": "Attachment",
|
||||
"chats.attachment_image": "Image",
|
||||
"chats.audio_toggle_off": "Audio notification off",
|
||||
"chats.audio_toggle_on": "Audio notification on",
|
||||
"chats.dividers.today": "Today",
|
||||
"chats.search_placeholder": "Start a chat with…",
|
||||
"column.admin.awaiting_approval": "Awaiting Approval",
|
||||
|
@ -270,13 +260,11 @@
|
|||
"column.public": "Linea pubblica glubale",
|
||||
"column.reactions": "Reactions",
|
||||
"column.reblogs": "Reposts",
|
||||
"column.remote": "Federated timeline",
|
||||
"column.scheduled_statuses": "Scheduled Posts",
|
||||
"column.search": "Search",
|
||||
"column.settings_store": "Settings store",
|
||||
"column.soapbox_config": "Soapbox config",
|
||||
"column.test": "Test timeline",
|
||||
"column_back_button.label": "Ritornu",
|
||||
"column_forbidden.body": "You do not have permission to access this page.",
|
||||
"column_forbidden.title": "Forbidden",
|
||||
"common.cancel": "Cancel",
|
||||
|
@ -372,8 +360,6 @@
|
|||
"confirmations.scheduled_status_delete.heading": "Cancel scheduled post",
|
||||
"confirmations.scheduled_status_delete.message": "Are you sure you want to cancel this scheduled post?",
|
||||
"confirmations.unfollow.confirm": "Disabbunassi",
|
||||
"confirmations.unfollow.heading": "Unfollow {name}",
|
||||
"confirmations.unfollow.message": "Site sicuru·a ch'ùn vulete più siguità @{name}?",
|
||||
"crypto_donate.explanation_box.message": "{siteTitle} accepts cryptocurrency donations. You may send a donation to any of the addresses below. Thank you for your support!",
|
||||
"crypto_donate.explanation_box.title": "Sending cryptocurrency donations",
|
||||
"crypto_donate_panel.actions.view": "Click to see {count} {count, plural, one {wallet} other {wallets}}",
|
||||
|
@ -822,7 +808,6 @@
|
|||
"preferences.fields.display_media.default": "Hide media marked as sensitive",
|
||||
"preferences.fields.display_media.hide_all": "Always hide media",
|
||||
"preferences.fields.display_media.show_all": "Always show media",
|
||||
"preferences.fields.dyslexic_font_label": "Dyslexic mode",
|
||||
"preferences.fields.expand_spoilers_label": "Always expand posts marked with content warnings",
|
||||
"preferences.fields.language_label": "Language",
|
||||
"preferences.fields.media_display_label": "Media display",
|
||||
|
@ -834,7 +819,6 @@
|
|||
"preferences.fields.underline_links_label": "Always underline links in posts",
|
||||
"preferences.fields.unfollow_modal_label": "Show confirmation dialog before unfollowing someone",
|
||||
"preferences.hints.demetricator": "Decrease social media anxiety by hiding all numbers from the site.",
|
||||
"preferences.hints.feed": "In your home feed",
|
||||
"preferences.notifications.advanced": "Show all notification categories",
|
||||
"preferences.options.content_type_markdown": "Markdown",
|
||||
"preferences.options.content_type_plaintext": "Plain text",
|
||||
|
@ -1016,7 +1000,6 @@
|
|||
"sms_verification.sent.body": "We sent you a 6-digit code via SMS. Enter it below.",
|
||||
"sms_verification.sent.header": "Verification code",
|
||||
"sms_verification.success": "A verification code has been sent to your phone number.",
|
||||
"toast.view": "View",
|
||||
"soapbox_config.authenticated_profile_hint": "Users must be logged-in to view replies and media on user profiles.",
|
||||
"soapbox_config.authenticated_profile_label": "Profiles require authentication",
|
||||
"soapbox_config.copyright_footer.meta_fields.label_placeholder": "Copyright footer",
|
||||
|
@ -1029,8 +1012,6 @@
|
|||
"soapbox_config.display_fqn_label": "Display domain (eg @user@domain) for local accounts.",
|
||||
"soapbox_config.feed_injection_hint": "Inject the feed with additional content, such as suggested profiles.",
|
||||
"soapbox_config.feed_injection_label": "Feed injection",
|
||||
"soapbox_config.fields.accent_color_label": "Accent color",
|
||||
"soapbox_config.fields.brand_color_label": "Brand color",
|
||||
"soapbox_config.fields.crypto_addresses_label": "Cryptocurrency addresses",
|
||||
"soapbox_config.fields.home_footer_fields_label": "Home footer items",
|
||||
"soapbox_config.fields.logo_label": "Logo",
|
||||
|
@ -1139,7 +1120,6 @@
|
|||
"sw.update_text": "An update is available.",
|
||||
"sw.url": "Script URL",
|
||||
"tabs_bar.all": "All",
|
||||
"tabs_bar.chats": "Chats",
|
||||
"tabs_bar.dashboard": "Dashboard",
|
||||
"tabs_bar.fediverse": "Fediverse",
|
||||
"tabs_bar.home": "Accolta",
|
||||
|
@ -1161,10 +1141,10 @@
|
|||
"time_remaining.minutes": "{number, plural, one {# minuta ferma} other {# minute fermanu}} left",
|
||||
"time_remaining.moments": "Ci fermanu qualchi mumentu",
|
||||
"time_remaining.seconds": "{number, plural, one {# siconda ferma} other {# siconde fermanu}}",
|
||||
"toast.view": "View",
|
||||
"trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} parlanu",
|
||||
"trends.title": "Trends",
|
||||
"trendsPanel.viewAll": "View all",
|
||||
"ui.beforeunload": "A bruttacopia sarà persa s'ellu hè chjosu Soapbox.",
|
||||
"unauthorized_modal.text": "You need to be logged in to do that.",
|
||||
"unauthorized_modal.title": "Sign up for {site_title}",
|
||||
"upload_area.title": "Drag & drop per caricà un fugliale",
|
||||
|
|
|
@ -147,7 +147,6 @@
|
|||
"alert.unexpected.links.support": "Support",
|
||||
"alert.unexpected.message": "Došlo k neočekávané chybě.",
|
||||
"alert.unexpected.return_home": "Return Home",
|
||||
"alert.unexpected.title": "Jejda!",
|
||||
"aliases.account.add": "Vytvořit alias",
|
||||
"aliases.account_label": "Starý účet:",
|
||||
"aliases.aliases_list_delete": "Unlink alias",
|
||||
|
@ -186,18 +185,9 @@
|
|||
"bundle_modal_error.message": "Při načítání tohoto komponentu se něco pokazilo.",
|
||||
"bundle_modal_error.retry": "Zkusit znovu",
|
||||
"card.back.label": "Back",
|
||||
"chat_box.actions.send": "Poslat",
|
||||
"chat_box.input.placeholder": "Poslat zprávu…",
|
||||
"chat_panels.main_window.empty": "Žádné chaty nenalezeny. Chat můžete začít na něčím profilu.",
|
||||
"chat_panels.main_window.title": "Chaty",
|
||||
"chat_window.close": "Close chat",
|
||||
"chats.actions.delete": "Odstranit zprávu",
|
||||
"chats.actions.more": "Více",
|
||||
"chats.actions.report": "Nahlásit uživatele",
|
||||
"chats.attachment": "Attachment",
|
||||
"chats.attachment_image": "Image",
|
||||
"chats.audio_toggle_off": "Audio upozornění vypnuté",
|
||||
"chats.audio_toggle_on": "Audio upozornění zapnoté",
|
||||
"chats.dividers.today": "Dnes",
|
||||
"chats.search_placeholder": "Chatovat s…",
|
||||
"column.admin.awaiting_approval": "Čeká na schválení",
|
||||
|
@ -270,13 +260,11 @@
|
|||
"column.public": "Federovaná časová osa",
|
||||
"column.reactions": "Reactions",
|
||||
"column.reblogs": "Reposts",
|
||||
"column.remote": "Federated timeline",
|
||||
"column.scheduled_statuses": "Scheduled Posts",
|
||||
"column.search": "Search",
|
||||
"column.settings_store": "Settings store",
|
||||
"column.soapbox_config": "Soapbox nastavení",
|
||||
"column.test": "Test timeline",
|
||||
"column_back_button.label": "Zpět",
|
||||
"column_forbidden.body": "You do not have permission to access this page.",
|
||||
"column_forbidden.title": "Forbidden",
|
||||
"common.cancel": "Zrušit",
|
||||
|
@ -372,8 +360,6 @@
|
|||
"confirmations.scheduled_status_delete.heading": "Zrušit naplánovaný příspěvek",
|
||||
"confirmations.scheduled_status_delete.message": "Určitě chcete tento naplánovaný příspěvěk zrušit?",
|
||||
"confirmations.unfollow.confirm": "Přestat sledovat",
|
||||
"confirmations.unfollow.heading": "Přestat selovat uživatele {name}",
|
||||
"confirmations.unfollow.message": "jste si jistý/á, že chcete přestat sledovat uživatele {name}?",
|
||||
"crypto_donate.explanation_box.message": "{siteTitle} accepts cryptocurrency donations. You may send a donation to any of the addresses below. Thank you for your support!",
|
||||
"crypto_donate.explanation_box.title": "Sending cryptocurrency donations",
|
||||
"crypto_donate_panel.actions.view": "Click to see {count} {count, plural, one {wallet} other {wallets}}",
|
||||
|
@ -822,7 +808,6 @@
|
|||
"preferences.fields.display_media.default": "Skrývat média označená jako citlivá",
|
||||
"preferences.fields.display_media.hide_all": "Vždy skrývat média",
|
||||
"preferences.fields.display_media.show_all": "Vždy zobrazovat média",
|
||||
"preferences.fields.dyslexic_font_label": "Dyslexic mode",
|
||||
"preferences.fields.expand_spoilers_label": "Vždy rozbalit příspěvky označené varováním",
|
||||
"preferences.fields.language_label": "Jazyk",
|
||||
"preferences.fields.media_display_label": "Zobrazování médií",
|
||||
|
@ -834,7 +819,6 @@
|
|||
"preferences.fields.underline_links_label": "Always underline links in posts",
|
||||
"preferences.fields.unfollow_modal_label": "Show confirmation dialog before unfollowing someone",
|
||||
"preferences.hints.demetricator": "Decrease social media anxiety by hiding all numbers from the site.",
|
||||
"preferences.hints.feed": "Ve vaší časové ose",
|
||||
"preferences.notifications.advanced": "Show all notification categories",
|
||||
"preferences.options.content_type_markdown": "Markdown",
|
||||
"preferences.options.content_type_plaintext": "Prostý text",
|
||||
|
@ -1016,7 +1000,6 @@
|
|||
"sms_verification.sent.body": "We sent you a 6-digit code via SMS. Enter it below.",
|
||||
"sms_verification.sent.header": "Verification code",
|
||||
"sms_verification.success": "A verification code has been sent to your phone number.",
|
||||
"toast.view": "View",
|
||||
"soapbox_config.authenticated_profile_hint": "Pouze přihlášení uživatelé mohou prohlížet odpovědi a média na uživatelských profilech.",
|
||||
"soapbox_config.authenticated_profile_label": "Profily vyžadují přihlášení",
|
||||
"soapbox_config.copyright_footer.meta_fields.label_placeholder": "Copyright v zápatí",
|
||||
|
@ -1029,8 +1012,6 @@
|
|||
"soapbox_config.display_fqn_label": "Zobrazit doménu (např @uzivatel@domena) u místních účtů.",
|
||||
"soapbox_config.feed_injection_hint": "Inject the feed with additional content, such as suggested profiles.",
|
||||
"soapbox_config.feed_injection_label": "Feed injection",
|
||||
"soapbox_config.fields.accent_color_label": "Vedlejší barva",
|
||||
"soapbox_config.fields.brand_color_label": "Hlavní barva",
|
||||
"soapbox_config.fields.crypto_addresses_label": "Adresy kryptoměn",
|
||||
"soapbox_config.fields.home_footer_fields_label": "Zápatí časové osy",
|
||||
"soapbox_config.fields.logo_label": "Logo",
|
||||
|
@ -1139,7 +1120,6 @@
|
|||
"sw.update_text": "Je dostupná nová verze.",
|
||||
"sw.url": "Script URL",
|
||||
"tabs_bar.all": "All",
|
||||
"tabs_bar.chats": "Chaty",
|
||||
"tabs_bar.dashboard": "Ovládací panel",
|
||||
"tabs_bar.fediverse": "Fediverse",
|
||||
"tabs_bar.home": "Domů",
|
||||
|
@ -1161,10 +1141,10 @@
|
|||
"time_remaining.minutes": "{number, plural, one {Zbývá # minuta} few {Zbývají # minuty} many {Zbývá # minuty} other {Zbývá # minut}}",
|
||||
"time_remaining.moments": "Zbývá několik sekund",
|
||||
"time_remaining.seconds": "{number, plural, one {Zbývá # sekunda} few {Zbývají # sekundy} many {Zbývá # sekundy} other {Zbývá # sekund}}",
|
||||
"toast.view": "View",
|
||||
"trends.count_by_accounts": "{count} {rawCount, plural, one {člověk} few {lidé} many {lidí} other {lidí}} hovoří",
|
||||
"trends.title": "Trendy",
|
||||
"trendsPanel.viewAll": "View all",
|
||||
"ui.beforeunload": "Váš koncept se ztratí, pokud Soapbox opustíte.",
|
||||
"unauthorized_modal.text": "Nejprve se přihlašte.",
|
||||
"unauthorized_modal.title": "Registrovat se na {site_title}",
|
||||
"upload_area.title": "Přetažením nahrajete",
|
||||
|
|
|
@ -147,7 +147,6 @@
|
|||
"alert.unexpected.links.support": "Support",
|
||||
"alert.unexpected.message": "Digwyddodd gwall annisgwyl.",
|
||||
"alert.unexpected.return_home": "Return Home",
|
||||
"alert.unexpected.title": "Wps!",
|
||||
"aliases.account.add": "Create alias",
|
||||
"aliases.account_label": "Old account:",
|
||||
"aliases.aliases_list_delete": "Unlink alias",
|
||||
|
@ -186,18 +185,9 @@
|
|||
"bundle_modal_error.message": "Aeth rhywbeth o'i le tra'n llwytho'r elfen hon.",
|
||||
"bundle_modal_error.retry": "Ceiswich eto",
|
||||
"card.back.label": "Back",
|
||||
"chat_box.actions.send": "Send",
|
||||
"chat_box.input.placeholder": "Send a message…",
|
||||
"chat_panels.main_window.empty": "No chats found. To start a chat, visit a user's profile.",
|
||||
"chat_panels.main_window.title": "Chats",
|
||||
"chat_window.close": "Close chat",
|
||||
"chats.actions.delete": "Delete message",
|
||||
"chats.actions.more": "More",
|
||||
"chats.actions.report": "Report user",
|
||||
"chats.attachment": "Attachment",
|
||||
"chats.attachment_image": "Image",
|
||||
"chats.audio_toggle_off": "Audio notification off",
|
||||
"chats.audio_toggle_on": "Audio notification on",
|
||||
"chats.dividers.today": "Today",
|
||||
"chats.search_placeholder": "Start a chat with…",
|
||||
"column.admin.awaiting_approval": "Awaiting Approval",
|
||||
|
@ -270,13 +260,11 @@
|
|||
"column.public": "Ffrwd y ffederasiwn",
|
||||
"column.reactions": "Reactions",
|
||||
"column.reblogs": "Reposts",
|
||||
"column.remote": "Federated timeline",
|
||||
"column.scheduled_statuses": "Scheduled Posts",
|
||||
"column.search": "Search",
|
||||
"column.settings_store": "Settings store",
|
||||
"column.soapbox_config": "Soapbox config",
|
||||
"column.test": "Test timeline",
|
||||
"column_back_button.label": "Nôl",
|
||||
"column_forbidden.body": "You do not have permission to access this page.",
|
||||
"column_forbidden.title": "Forbidden",
|
||||
"common.cancel": "Cancel",
|
||||
|
@ -372,8 +360,6 @@
|
|||
"confirmations.scheduled_status_delete.heading": "Cancel scheduled post",
|
||||
"confirmations.scheduled_status_delete.message": "Are you sure you want to cancel this scheduled post?",
|
||||
"confirmations.unfollow.confirm": "Dad-ddilynwch",
|
||||
"confirmations.unfollow.heading": "Unfollow {name}",
|
||||
"confirmations.unfollow.message": "Ydych chi'n sicr eich bod am ddad-ddilyn {name}?",
|
||||
"crypto_donate.explanation_box.message": "{siteTitle} accepts cryptocurrency donations. You may send a donation to any of the addresses below. Thank you for your support!",
|
||||
"crypto_donate.explanation_box.title": "Sending cryptocurrency donations",
|
||||
"crypto_donate_panel.actions.view": "Click to see {count} {count, plural, one {wallet} other {wallets}}",
|
||||
|
@ -822,7 +808,6 @@
|
|||
"preferences.fields.display_media.default": "Hide media marked as sensitive",
|
||||
"preferences.fields.display_media.hide_all": "Always hide media",
|
||||
"preferences.fields.display_media.show_all": "Always show media",
|
||||
"preferences.fields.dyslexic_font_label": "Dyslexic mode",
|
||||
"preferences.fields.expand_spoilers_label": "Always expand posts marked with content warnings",
|
||||
"preferences.fields.language_label": "Language",
|
||||
"preferences.fields.media_display_label": "Media display",
|
||||
|
@ -834,7 +819,6 @@
|
|||
"preferences.fields.underline_links_label": "Always underline links in posts",
|
||||
"preferences.fields.unfollow_modal_label": "Show confirmation dialog before unfollowing someone",
|
||||
"preferences.hints.demetricator": "Decrease social media anxiety by hiding all numbers from the site.",
|
||||
"preferences.hints.feed": "In your home feed",
|
||||
"preferences.notifications.advanced": "Show all notification categories",
|
||||
"preferences.options.content_type_markdown": "Markdown",
|
||||
"preferences.options.content_type_plaintext": "Plain text",
|
||||
|
@ -1016,7 +1000,6 @@
|
|||
"sms_verification.sent.body": "We sent you a 6-digit code via SMS. Enter it below.",
|
||||
"sms_verification.sent.header": "Verification code",
|
||||
"sms_verification.success": "A verification code has been sent to your phone number.",
|
||||
"toast.view": "View",
|
||||
"soapbox_config.authenticated_profile_hint": "Users must be logged-in to view replies and media on user profiles.",
|
||||
"soapbox_config.authenticated_profile_label": "Profiles require authentication",
|
||||
"soapbox_config.copyright_footer.meta_fields.label_placeholder": "Copyright footer",
|
||||
|
@ -1029,8 +1012,6 @@
|
|||
"soapbox_config.display_fqn_label": "Display domain (eg @user@domain) for local accounts.",
|
||||
"soapbox_config.feed_injection_hint": "Inject the feed with additional content, such as suggested profiles.",
|
||||
"soapbox_config.feed_injection_label": "Feed injection",
|
||||
"soapbox_config.fields.accent_color_label": "Accent color",
|
||||
"soapbox_config.fields.brand_color_label": "Brand color",
|
||||
"soapbox_config.fields.crypto_addresses_label": "Cryptocurrency addresses",
|
||||
"soapbox_config.fields.home_footer_fields_label": "Home footer items",
|
||||
"soapbox_config.fields.logo_label": "Logo",
|
||||
|
@ -1139,7 +1120,6 @@
|
|||
"sw.update_text": "An update is available.",
|
||||
"sw.url": "Script URL",
|
||||
"tabs_bar.all": "All",
|
||||
"tabs_bar.chats": "Chats",
|
||||
"tabs_bar.dashboard": "Dashboard",
|
||||
"tabs_bar.fediverse": "Fediverse",
|
||||
"tabs_bar.home": "Hafan",
|
||||
|
@ -1161,10 +1141,10 @@
|
|||
"time_remaining.minutes": "{number, plural, one {# funud} other {# o funudau}} ar ôl",
|
||||
"time_remaining.moments": "Munudau ar ôl",
|
||||
"time_remaining.seconds": "{number, plural, one {# eiliad} other {# o eiliadau}} ar ôl",
|
||||
"toast.view": "View",
|
||||
"trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} yn siarad",
|
||||
"trends.title": "Trends",
|
||||
"trendsPanel.viewAll": "View all",
|
||||
"ui.beforeunload": "Mi fyddwch yn colli eich drafft os gadewch Soapbox.",
|
||||
"unauthorized_modal.text": "You need to be logged in to do that.",
|
||||
"unauthorized_modal.title": "Sign up for {site_title}",
|
||||
"upload_area.title": "Llusgwch & gollwing i uwchlwytho",
|
||||
|
|
|
@ -147,7 +147,6 @@
|
|||
"alert.unexpected.links.support": "Support",
|
||||
"alert.unexpected.message": "Der opstod en uventet fejl.",
|
||||
"alert.unexpected.return_home": "Return Home",
|
||||
"alert.unexpected.title": "Ups!",
|
||||
"aliases.account.add": "Create alias",
|
||||
"aliases.account_label": "Old account:",
|
||||
"aliases.aliases_list_delete": "Unlink alias",
|
||||
|
@ -186,18 +185,9 @@
|
|||
"bundle_modal_error.message": "Noget gik galt under indlæsningen af dette komponent.",
|
||||
"bundle_modal_error.retry": "Prøv igen",
|
||||
"card.back.label": "Back",
|
||||
"chat_box.actions.send": "Send",
|
||||
"chat_box.input.placeholder": "Send a message…",
|
||||
"chat_panels.main_window.empty": "No chats found. To start a chat, visit a user's profile.",
|
||||
"chat_panels.main_window.title": "Chats",
|
||||
"chat_window.close": "Close chat",
|
||||
"chats.actions.delete": "Delete message",
|
||||
"chats.actions.more": "More",
|
||||
"chats.actions.report": "Report user",
|
||||
"chats.attachment": "Attachment",
|
||||
"chats.attachment_image": "Image",
|
||||
"chats.audio_toggle_off": "Audio notification off",
|
||||
"chats.audio_toggle_on": "Audio notification on",
|
||||
"chats.dividers.today": "Today",
|
||||
"chats.search_placeholder": "Start a chat with…",
|
||||
"column.admin.awaiting_approval": "Awaiting Approval",
|
||||
|
@ -270,13 +260,11 @@
|
|||
"column.public": "Fælles tidslinje",
|
||||
"column.reactions": "Reactions",
|
||||
"column.reblogs": "Reposts",
|
||||
"column.remote": "Federated timeline",
|
||||
"column.scheduled_statuses": "Scheduled Posts",
|
||||
"column.search": "Search",
|
||||
"column.settings_store": "Settings store",
|
||||
"column.soapbox_config": "Soapbox config",
|
||||
"column.test": "Test timeline",
|
||||
"column_back_button.label": "Tilbage",
|
||||
"column_forbidden.body": "You do not have permission to access this page.",
|
||||
"column_forbidden.title": "Forbidden",
|
||||
"common.cancel": "Cancel",
|
||||
|
@ -372,8 +360,6 @@
|
|||
"confirmations.scheduled_status_delete.heading": "Cancel scheduled post",
|
||||
"confirmations.scheduled_status_delete.message": "Are you sure you want to cancel this scheduled post?",
|
||||
"confirmations.unfollow.confirm": "Følg ikke længere",
|
||||
"confirmations.unfollow.heading": "Unfollow {name}",
|
||||
"confirmations.unfollow.message": "Er du sikker på, du ikke længere vil følge {name}?",
|
||||
"crypto_donate.explanation_box.message": "{siteTitle} accepts cryptocurrency donations. You may send a donation to any of the addresses below. Thank you for your support!",
|
||||
"crypto_donate.explanation_box.title": "Sending cryptocurrency donations",
|
||||
"crypto_donate_panel.actions.view": "Click to see {count} {count, plural, one {wallet} other {wallets}}",
|
||||
|
@ -822,7 +808,6 @@
|
|||
"preferences.fields.display_media.default": "Hide media marked as sensitive",
|
||||
"preferences.fields.display_media.hide_all": "Always hide media",
|
||||
"preferences.fields.display_media.show_all": "Always show media",
|
||||
"preferences.fields.dyslexic_font_label": "Dyslexic mode",
|
||||
"preferences.fields.expand_spoilers_label": "Always expand posts marked with content warnings",
|
||||
"preferences.fields.language_label": "Language",
|
||||
"preferences.fields.media_display_label": "Media display",
|
||||
|
@ -834,7 +819,6 @@
|
|||
"preferences.fields.underline_links_label": "Always underline links in posts",
|
||||
"preferences.fields.unfollow_modal_label": "Show confirmation dialog before unfollowing someone",
|
||||
"preferences.hints.demetricator": "Decrease social media anxiety by hiding all numbers from the site.",
|
||||
"preferences.hints.feed": "In your home feed",
|
||||
"preferences.notifications.advanced": "Show all notification categories",
|
||||
"preferences.options.content_type_markdown": "Markdown",
|
||||
"preferences.options.content_type_plaintext": "Plain text",
|
||||
|
@ -1016,7 +1000,6 @@
|
|||
"sms_verification.sent.body": "We sent you a 6-digit code via SMS. Enter it below.",
|
||||
"sms_verification.sent.header": "Verification code",
|
||||
"sms_verification.success": "A verification code has been sent to your phone number.",
|
||||
"toast.view": "View",
|
||||
"soapbox_config.authenticated_profile_hint": "Users must be logged-in to view replies and media on user profiles.",
|
||||
"soapbox_config.authenticated_profile_label": "Profiles require authentication",
|
||||
"soapbox_config.copyright_footer.meta_fields.label_placeholder": "Copyright footer",
|
||||
|
@ -1029,8 +1012,6 @@
|
|||
"soapbox_config.display_fqn_label": "Display domain (eg @user@domain) for local accounts.",
|
||||
"soapbox_config.feed_injection_hint": "Inject the feed with additional content, such as suggested profiles.",
|
||||
"soapbox_config.feed_injection_label": "Feed injection",
|
||||
"soapbox_config.fields.accent_color_label": "Accent color",
|
||||
"soapbox_config.fields.brand_color_label": "Brand color",
|
||||
"soapbox_config.fields.crypto_addresses_label": "Cryptocurrency addresses",
|
||||
"soapbox_config.fields.home_footer_fields_label": "Home footer items",
|
||||
"soapbox_config.fields.logo_label": "Logo",
|
||||
|
@ -1139,7 +1120,6 @@
|
|||
"sw.update_text": "An update is available.",
|
||||
"sw.url": "Script URL",
|
||||
"tabs_bar.all": "All",
|
||||
"tabs_bar.chats": "Chats",
|
||||
"tabs_bar.dashboard": "Dashboard",
|
||||
"tabs_bar.fediverse": "Fediverse",
|
||||
"tabs_bar.home": "Hjem",
|
||||
|
@ -1161,10 +1141,10 @@
|
|||
"time_remaining.minutes": "{number, plural, one {# minut} other {# minutter}} tilbage",
|
||||
"time_remaining.moments": "Få øjeblikke tilbage",
|
||||
"time_remaining.seconds": "{number, plural, one {# sekund} other {# sekunder}} tilbage",
|
||||
"toast.view": "View",
|
||||
"trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {personer}} snakker",
|
||||
"trends.title": "Trends",
|
||||
"trendsPanel.viewAll": "View all",
|
||||
"ui.beforeunload": "Din kladde vil gå tabt hvis du forlader Soapbox.",
|
||||
"unauthorized_modal.text": "You need to be logged in to do that.",
|
||||
"unauthorized_modal.title": "Sign up for {site_title}",
|
||||
"upload_area.title": "Træk og slip for at uploade",
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue