Merge remote-tracking branch 'origin/next' into next-emoji-reacts

next-interactions
Alex Gleason 3 years ago
commit 733d240893
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7

@ -0,0 +1,95 @@
{
"id": "108046244464677537",
"created_at": "2022-03-30T15:40:53.287Z",
"in_reply_to_id": null,
"in_reply_to_account_id": null,
"sensitive": false,
"spoiler_text": "",
"visibility": "public",
"language": null,
"uri": "https://truthsocial.com/users/alex/statuses/108046244464677537",
"url": "https://truthsocial.com/@alex/108046244464677537",
"replies_count": 0,
"reblogs_count": 0,
"favourites_count": 0,
"favourited": false,
"reblogged": false,
"muted": false,
"bookmarked": false,
"pinned": false,
"content": "",
"reblog": null,
"application": {
"name": "Soapbox FE",
"website": "https://soapbox.pub/"
},
"account": {
"id": "107759994408336377",
"username": "alex",
"acct": "alex",
"display_name": "Alex Gleason",
"locked": false,
"bot": false,
"discoverable": null,
"group": false,
"created_at": "2022-02-08T00:00:00.000Z",
"note": "<p>Launching Truth Social</p>",
"url": "https://truthsocial.com/@alex",
"avatar": "https://static-assets.truthsocial.com/tmtg:prime-truth-social-assets/accounts/avatars/107/759/994/408/336/377/original/119cb0dd1fa615b7.png",
"avatar_static": "https://static-assets.truthsocial.com/tmtg:prime-truth-social-assets/accounts/avatars/107/759/994/408/336/377/original/119cb0dd1fa615b7.png",
"header": "https://static-assets.truthsocial.com/tmtg:prime-truth-social-assets/accounts/headers/107/759/994/408/336/377/original/31f62b0453ccf554.png",
"header_static": "https://static-assets.truthsocial.com/tmtg:prime-truth-social-assets/accounts/headers/107/759/994/408/336/377/original/31f62b0453ccf554.png",
"followers_count": 4713,
"following_count": 43,
"statuses_count": 7,
"last_status_at": "2022-03-30",
"verified": true,
"location": "Texas",
"website": "https://soapbox.pub/",
"emojis": [],
"fields": []
},
"media_attachments": [
{
"id": "108046243948255335",
"type": "video",
"url": "https://static-assets.truthsocial.com/tmtg:prime-truth-social-assets/media_attachments/files/108/046/243/948/255/335/original/3b17ce701c0d6f08.mp4",
"preview_url": "https://static-assets.truthsocial.com/tmtg:prime-truth-social-assets/cache/preview_cards/images/000/543/912/original/e1fcf6ace01d9ded.jpg",
"external_video_id": "vwfnq9",
"remote_url": null,
"preview_remote_url": null,
"text_url": "https://truthsocial.com/media/SpbYvqKIT2VubC9FFn0",
"meta": {
"original": {
"width": 988,
"height": 556,
"frame_rate": "60/1",
"duration": 1.949025,
"bitrate": 402396
}
},
"description": null,
"blurhash": null
}
],
"mentions": [],
"tags": [],
"emojis": [],
"card": {
"url": "https://rumble.com/vz1trd-video-upload-for-108046244464677537.html?mref=ummtf&mc=3nvg0",
"title": "Video upload for 108046244464677537",
"description": "",
"type": "video",
"author_name": "hostid1",
"author_url": "https://rumble.com/user/hostid1",
"provider_name": "Rumble.com",
"provider_url": "https://rumble.com/",
"html": "<iframe src=\"https://rumble.com/embed/vwfnq9/\" width=\"988\" height=\"556\" frameborder=\"0\" title=\"Video upload for 108046244464677537\" allowfullscreen=\"\"></iframe>",
"width": 988,
"height": 556,
"image": "https://static-assets.truthsocial.com/tmtg:prime-truth-social-assets/cache/preview_cards/images/000/543/912/original/e1fcf6ace01d9ded.jpg",
"embed_url": "",
"blurhash": "UQH1;m~8sks,%M~9?DRk-mRnR+xs9cWVj[bH"
},
"poll": null
}

@ -0,0 +1,111 @@
import { InstanceRecord } from 'soapbox/normalizers';
import rootReducer from 'soapbox/reducers';
import { mockStore } from 'soapbox/test_helpers';
import { uploadCompose } from '../compose';
describe('uploadCompose()', () => {
describe('with images', () => {
let files, store;
beforeEach(() => {
const instance = InstanceRecord({
configuration: {
statuses: {
max_media_attachments: 4,
},
media_attachments: {
image_size_limit: 10,
},
},
});
const state = rootReducer(undefined, {})
.set('me', '1234')
.set('instance', instance);
store = mockStore(state);
files = [{
uri: 'image.png',
name: 'Image',
size: 15,
type: 'image/png',
}];
});
it('creates an alert if exceeds max size', async() => {
const mockIntl = {
formatMessage: jest.fn().mockReturnValue('Image exceeds the current file size limit (10 Bytes)'),
};
const expectedActions = [
{ type: 'COMPOSE_UPLOAD_REQUEST', skipLoading: true },
{
type: 'ALERT_SHOW',
message: 'Image exceeds the current file size limit (10 Bytes)',
actionLabel: undefined,
actionLink: undefined,
severity: 'error',
},
{ type: 'COMPOSE_UPLOAD_FAIL', error: true, skipLoading: true },
];
await store.dispatch(uploadCompose(files, mockIntl));
const actions = store.getActions();
expect(actions).toEqual(expectedActions);
});
});
describe('with videos', () => {
let files, store;
beforeEach(() => {
const instance = InstanceRecord({
configuration: {
statuses: {
max_media_attachments: 4,
},
media_attachments: {
video_size_limit: 10,
},
},
});
const state = rootReducer(undefined, {})
.set('me', '1234')
.set('instance', instance);
store = mockStore(state);
files = [{
uri: 'video.mp4',
name: 'Video',
size: 15,
type: 'video/mp4',
}];
});
it('creates an alert if exceeds max size', async() => {
const mockIntl = {
formatMessage: jest.fn().mockReturnValue('Video exceeds the current file size limit (10 Bytes)'),
};
const expectedActions = [
{ type: 'COMPOSE_UPLOAD_REQUEST', skipLoading: true },
{
type: 'ALERT_SHOW',
message: 'Video exceeds the current file size limit (10 Bytes)',
actionLabel: undefined,
actionLink: undefined,
severity: 'error',
},
{ type: 'COMPOSE_UPLOAD_FAIL', error: true, skipLoading: true },
];
await store.dispatch(uploadCompose(files, mockIntl));
const actions = store.getActions();
expect(actions).toEqual(expectedActions);
});
});
});

@ -1,5 +1,7 @@
import { defineMessages } from 'react-intl';
import { httpErrorMessages } from 'soapbox/utils/errors';
const messages = defineMessages({
unexpectedTitle: { id: 'alert.unexpected.title', defaultMessage: 'Oops!' },
unexpectedMessage: { id: 'alert.unexpected.message', defaultMessage: 'An unexpected error occurred.' },
@ -34,7 +36,7 @@ export function showAlert(title = messages.unexpectedTitle, message = messages.u
}
export function showAlertForError(error) {
return (dispatch, getState) => {
return (dispatch, _getState) => {
if (error.response) {
const { data, status, statusText } = error.response;
@ -48,13 +50,16 @@ export function showAlertForError(error) {
}
let message = statusText;
const title = `${status}`;
if (data.error) {
message = data.error;
}
return dispatch(showAlert(title, message, 'error'));
if (!message) {
message = httpErrorMessages.find((httpError) => httpError.code === status)?.description;
}
return dispatch(showAlert('', message, 'error'));
} else {
console.error(error);
return dispatch(showAlert(undefined, undefined, 'error'));

@ -6,6 +6,7 @@ import { defineMessages } from 'react-intl';
import snackbar from 'soapbox/actions/snackbar';
import { isLoggedIn } from 'soapbox/utils/auth';
import { getFeatures } from 'soapbox/utils/features';
import { formatBytes } from 'soapbox/utils/media';
import api from '../api';
import { search as emojiSearch } from '../features/emoji/emoji_mart_search_light';
@ -78,10 +79,12 @@ export const COMPOSE_ADD_TO_MENTIONS = 'COMPOSE_ADD_TO_MENTIONS';
export const COMPOSE_REMOVE_FROM_MENTIONS = 'COMPOSE_REMOVE_FROM_MENTIONS';
const messages = defineMessages({
uploadErrorLimit: { id: 'upload_error.limit', defaultMessage: 'File upload limit exceeded.' },
uploadErrorPoll: { id: 'upload_error.poll', defaultMessage: 'File upload not allowed with polls.' },
exceededImageSizeLimit: { id: 'upload_error.image_size_limit', defaultMessage: 'Image exceeds the current file size limit ({limit})' },
exceededVideoSizeLimit: { id: 'upload_error.video_size_limit', defaultMessage: 'Video exceeds the current file size limit ({limit})' },
scheduleError: { id: 'compose.invalid_schedule', defaultMessage: 'You must schedule a post at least 5 minutes out.' },
success: { id: 'compose.submit_success', defaultMessage: 'Your post was sent' },
uploadErrorLimit: { id: 'upload_error.limit', defaultMessage: 'File upload limit exceeded.' },
uploadErrorPoll: { id: 'upload_error.poll', defaultMessage: 'File upload not allowed with polls.' },
view: { id: 'snackbar.view', defaultMessage: 'View' },
});
@ -295,10 +298,12 @@ export function submitComposeFail(error) {
};
}
export function uploadCompose(files) {
export function uploadCompose(files, intl) {
return function(dispatch, getState) {
if (!isLoggedIn(getState)) return;
const attachmentLimit = getState().getIn(['instance', 'configuration', 'statuses', 'max_media_attachments']);
const maxImageSize = getState().getIn(['instance', 'configuration', 'media_attachments', 'image_size_limit']);
const maxVideoSize = getState().getIn(['instance', 'configuration', 'media_attachments', 'video_size_limit']);
const media = getState().getIn(['compose', 'media_attachments']);
const progress = new Array(files.length).fill(0);
@ -314,6 +319,22 @@ export function uploadCompose(files) {
Array.from(files).forEach((f, i) => {
if (media.size + i > attachmentLimit - 1) return;
const isImage = f.type.match(/image.*/);
const isVideo = f.type.match(/video.*/);
if (isImage && maxImageSize && (f.size > maxImageSize)) {
const limit = formatBytes(maxImageSize);
const message = intl.formatMessage(messages.exceededImageSizeLimit, { limit });
dispatch(snackbar.error(message));
dispatch(uploadComposeFail(true));
return;
} else if (isVideo && maxVideoSize && (f.size > maxVideoSize)) {
const limit = formatBytes(maxVideoSize);
const message = intl.formatMessage(messages.exceededVideoSizeLimit, { limit });
dispatch(snackbar.error(message));
dispatch(uploadComposeFail(true));
return;
}
// FIXME: Don't define function in loop
/* eslint-disable no-loop-func */
resizeImage(f).then(file => {

@ -1,10 +1,15 @@
import PropTypes from 'prop-types';
import React from 'react';
import Icon from 'soapbox/components/icon';
import { shortNumberFormat } from 'soapbox/utils/numbers';
const IconWithCounter = ({ icon, count, ...rest }) => {
interface IIconWithCounter extends React.HTMLAttributes<HTMLDivElement> {
count: number,
icon?: string;
src?: string;
}
const IconWithCounter: React.FC<IIconWithCounter> = ({ icon, count, ...rest }) => {
return (
<div className='relative'>
<Icon id={icon} {...rest} />
@ -16,9 +21,4 @@ const IconWithCounter = ({ icon, count, ...rest }) => {
);
};
IconWithCounter.propTypes = {
icon: PropTypes.string,
count: PropTypes.number.isRequired,
};
export default IconWithCounter;

@ -203,7 +203,7 @@ class ModalRoot extends React.PureComponent {
<div
ref={this.setRef}
className={classNames({
'fixed top-0 left-0 z-1000 w-full h-full overflow-x-hidden overflow-y-auto': true,
'fixed top-0 left-0 z-[100] w-full h-full overflow-x-hidden overflow-y-auto': true,
'pointer-events-none': !visible,
})}
style={{ opacity: revealed ? 1 : 0 }}

@ -71,7 +71,7 @@ const PollOptionText: React.FC<IPollOptionText> = ({ poll, option, index, active
onChange={handleOptionChange}
/>
<HStack alignItems='center' className='p-1'>
<HStack alignItems='center' className='p-1 text-gray-900 dark:text-gray-300'>
{!showResults && (
<span
className={classNames('inline-block w-4 h-4 mr-2.5 border border-solid border-primary-600 rounded-full', {

@ -439,8 +439,7 @@ class Status extends ImmutablePureComponent {
} else if (size === 1 && status.getIn(['media_attachments', 0, 'type']) === 'video') {
const video = status.getIn(['media_attachments', 0]);
const external_id = (video.get('external_video_id'));
if (external_id) {
if (video.external_video_id && status.card?.html) {
const { mediaWrapperWidth } = this.state;
const height = mediaWrapperWidth / (video.getIn(['meta', 'original', 'width']) / video.getIn(['meta', 'original', 'height']));
media = (
@ -449,16 +448,8 @@ class Status extends ImmutablePureComponent {
ref={this.setRef}
className='status-card__image status-card-video'
style={height ? { height } : {}}
>
<iframe
src={`https://rumble.com/embed/${external_id}/`}
frameBorder='0'
allowFullScreen
webkitallowfullscreen='true'
mozallowfullscreen='true'
title=''
/>
</div>
dangerouslySetInnerHTML={{ __html: status.card.html }}
/>
</div>
);
} else {

@ -0,0 +1,60 @@
import classNames from 'classnames';
import React from 'react';
import { NavLink, useLocation } from 'react-router-dom';
import IconWithCounter from 'soapbox/components/icon_with_counter';
import { Icon, Text } from 'soapbox/components/ui';
interface IThumbNavigationLink {
count?: number,
src: string,
text: string | React.ReactElement,
to: string,
exact?: boolean,
paths?: Array<string>,
}
const ThumbNavigationLink: React.FC<IThumbNavigationLink> = ({ count, src, text, to, exact, paths }): JSX.Element => {
const { pathname } = useLocation();
const isActive = (): boolean => {
if (paths) {
return paths.some(path => pathname.startsWith(path));
} else {
return exact ? pathname === to : pathname.startsWith(to);
}
};
const active = isActive();
return (
<NavLink to={to} exact={exact} className='thumb-navigation__link'>
{count !== undefined ? (
<IconWithCounter
src={require('@tabler/icons/icons/messages.svg')}
className={classNames({
'h-5 w-5': true,
'text-gray-600 dark:text-gray-300': !active,
'text-primary-600': active,
})}
count={count}
/>
) : (
<Icon
src={src}
className={classNames({
'h-5 w-5': true,
'text-gray-600 dark:text-gray-300': !active,
'text-primary-600': active,
})}
/>
)}
<Text tag='span' size='xs'>
{text}
</Text>
</NavLink>
);
};
export default ThumbNavigationLink;

@ -1,152 +0,0 @@
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux';
import { NavLink, withRouter } from 'react-router-dom';
import { getSoapboxConfig } from 'soapbox/actions/soapbox';
import IconWithCounter from 'soapbox/components/icon_with_counter';
import { Icon, Text } from 'soapbox/components/ui';
import { getFeatures } from 'soapbox/utils/features';
const mapStateToProps = state => {
const me = state.get('me');
const reportsCount = state.getIn(['admin', 'openReports']).count();
const approvalCount = state.getIn(['admin', 'awaitingApproval']).count();
const instance = state.get('instance');
return {
account: state.getIn(['accounts', me]),
logo: getSoapboxConfig(state).get('logo'),
notificationCount: state.getIn(['notifications', 'unread']),
chatsCount: state.getIn(['chats', 'items']).reduce((acc, curr) => acc + Math.min(curr.get('unread', 0), 1), 0),
dashboardCount: reportsCount + approvalCount,
features: getFeatures(instance),
};
};
export default @withRouter
@connect(mapStateToProps)
class ThumbNavigation extends React.PureComponent {
static propTypes = {
logo: PropTypes.string,
account: ImmutablePropTypes.record,
dashboardCount: PropTypes.number,
notificationCount: PropTypes.number,
chatsCount: PropTypes.number,
features: PropTypes.object.isRequired,
location: PropTypes.object,
}
render() {
const { account, notificationCount, chatsCount, location, features } = this.props;
return (
<div className='thumb-navigation'>
<NavLink to='/' exact className='thumb-navigation__link'>
<Icon
src={require('icons/feed.svg')}
className={classNames({
'h-5 w-5': true,
'text-gray-600': location.pathname !== '/',
'text-primary-600': location.pathname === '/',
})}
/>
<Text tag='span' size='xs'>
<FormattedMessage id='navigation.home' defaultMessage='Home' />
</Text>
</NavLink>
<NavLink to='/search' className='thumb-navigation__link'>
<Icon
src={require('@tabler/icons/icons/search.svg')}
className={classNames({
'h-5 w-5': true,
'text-gray-600': location.pathname !== '/search',
'text-primary-600': location.pathname === '/search',
})}
/>
<Text tag='span' size='xs'>
<FormattedMessage id='navigation.search' defaultMessage='Search' />
</Text>
</NavLink>
{account && (
<NavLink to='/notifications' className='thumb-navigation__link'>
<Icon
src={require('@tabler/icons/icons/bell.svg')}
className={classNames({
'h-5 w-5': true,
'text-gray-600': location.pathname !== '/notifications',
'text-primary-600': location.pathname === '/notifications',
})}
count={notificationCount}
/>
<Text tag='span' size='xs'>
<FormattedMessage id='navigation.notifications' defaultMessage='Alerts' />
</Text>
</NavLink>
)}
{account && (
features.chats ? (
<NavLink to='/chats' className='thumb-navigation__link'>
<IconWithCounter
src={require('@tabler/icons/icons/messages.svg')}
className={classNames({
'h-5 w-5': true,
'text-gray-600': location.pathname !== '/chats',
'text-primary-600': location.pathname === '/chats',
})}
count={chatsCount}
/>
<Text tag='span' size='xs'>
<FormattedMessage id='navigation.chats' defaultMessage='Chats' />
</Text>
</NavLink>
) : (
<NavLink to='/messages' className='thumb-navigation__link'>
<Icon
src={require('@tabler/icons/icons/mail.svg')}
className={classNames({
'h-5 w-5': true,
'text-gray-600': !['/messages', '/conversations'].includes(location.pathname),
'text-primary-600': ['/messages', '/conversations'].includes(location.pathname),
})}
/>
<Text tag='span' size='xs'>
<FormattedMessage id='navigation.direct_messages' defaultMessage='Messages' />
</Text>
</NavLink>
)
)}
{/* (account && isStaff(account)) && (
<NavLink to='/admin' className='thumb-navigation__link'>
<Icon
src={require('@tabler/icons/icons/dashboard.svg')}
className={classNames({
'h-5 w-5': true,
'text-gray-600': !location.pathname.startsWith('/admin'),
'text-primary-600': location.pathname.startsWith('/admin'),
})}
count={dashboardCount}
/>
<Text tag='span' size='xs'>
<FormattedMessage id='navigation.dashboard' defaultMessage='Dashboard' />
</Text>
</NavLink>
) */}
</div>
);
}
}

@ -0,0 +1,72 @@
import React from 'react';
import { FormattedMessage } from 'react-intl';
import ThumbNavigationLink from 'soapbox/components/thumb_navigation-link';
import { useAppSelector, useOwnAccount } from 'soapbox/hooks';
import { getFeatures } from 'soapbox/utils/features';
const ThumbNavigation: React.FC = (): JSX.Element => {
const account = useOwnAccount();
const notificationCount = useAppSelector((state) => state.notifications.unread);
const chatsCount = useAppSelector((state) => state.chats.get('items').reduce((acc: number, curr: any) => acc + Math.min(curr.get('unread', 0), 1), 0));
// const dashboardCount = useAppSelector((state) => state.admin.openReports.count() + state.admin.awaitingApproval.count());
const features = getFeatures(useAppSelector((state) => state.instance));
return (
<div className='thumb-navigation'>
<ThumbNavigationLink
src={require('icons/feed.svg')}
text={<FormattedMessage id='navigation.home' defaultMessage='Home' />}
to='/'
exact
/>
<ThumbNavigationLink
src={require('@tabler/icons/icons/search.svg')}
text={<FormattedMessage id='navigation.search' defaultMessage='Search' />}
to='/search'
exact
/>
{account && (
<ThumbNavigationLink
src={require('@tabler/icons/icons/bell.svg')}
text={<FormattedMessage id='navigation.notifications' defaultMessage='Alerts' />}
to='/notifications'
exact
count={notificationCount}
/>
)}
{account && (
features.chats ? (
<ThumbNavigationLink
src={require('@tabler/icons/icons/messages.svg')}
text={<FormattedMessage id='navigation.chats' defaultMessage='Chats' />}
to='/chats'
exact
count={chatsCount}
/>
) : (
<ThumbNavigationLink
src={require('@tabler/icons/icons/mail.svg')}
text={<FormattedMessage id='navigation.direct_messages' defaultMessage='Messages' />}
to='/messages'
paths={['/messages', '/conversations']}
/>
)
)}
{/* (account && isStaff(account)) && (
<ThumbNavigationLink
src={require('@tabler/icons/icons/dashboard.svg')}
text={<FormattedMessage id='navigation.dashboard' defaultMessage='Dashboard' />}
to='/admin'
count={dashboardCount}
/>
) */}
</div>
);
};
export default ThumbNavigation;

@ -32,7 +32,7 @@ const Column: React.FC<IColumn> = React.forwardRef((props, ref: React.ForwardedR
const renderChildren = () => {
if (transparent) {
return <div className='bg-white sm:bg-transparent'>{children}</div>;
return <div className='bg-white dark:bg-slate-800 sm:bg-transparent sm:dark:bg-transparent'>{children}</div>;
}
return (

@ -1,5 +1,5 @@
[data-reach-menu-popover] {
@apply origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 focus:outline-none;
@apply origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg bg-white dark:bg-slate-900 ring-1 ring-black ring-opacity-5 focus:outline-none;
z-index: 1003;
}
@ -9,7 +9,7 @@ div:focus[data-reach-menu-list] {
}
[data-reach-menu-item][data-selected] {
@apply bg-gray-100;
@apply bg-gray-100 dark:bg-slate-700;
}
[data-reach-menu-list] {
@ -18,11 +18,11 @@ div:focus[data-reach-menu-list] {
[data-reach-menu-item],
[data-reach-menu-link] {
@apply block px-4 py-2.5 text-sm text-gray-700 cursor-pointer;
@apply block px-4 py-2.5 text-sm text-gray-700 dark:text-gray-400 cursor-pointer;
}
[data-reach-menu-link] {
@apply hover:bg-gray-100;
@apply hover:bg-gray-100 dark:hover:bg-slate-700;
}
[data-reach-menu-item][data-disabled],
@ -31,5 +31,5 @@ div:focus[data-reach-menu-list] {
}
[data-reach-menu-popover] hr {
@apply my-1 mx-2 border-t border-gray-100;
@apply my-1 mx-2 border-t border-gray-100 dark:border-slate-600;
}

@ -20,7 +20,7 @@ const MenuList = (props: IMenuList) => (
<MenuPopover position={props.position === 'left' ? positionDefault : positionRight}>
<MenuItems
onKeyDown={(event) => event.nativeEvent.stopImmediatePropagation()}
className='py-1 bg-white rounded-lg shadow-menu'
className='py-1 bg-white dark:bg-slate-900 rounded-lg shadow-menu'
{...props}
/>
</MenuPopover>

@ -12,8 +12,8 @@ import {
} from 'soapbox/actions/chats';
import { uploadMedia } from 'soapbox/actions/media';
import IconButton from 'soapbox/components/icon_button';
import UploadProgress from 'soapbox/features/compose/components/upload-progress';
import UploadButton from 'soapbox/features/compose/components/upload_button';
import UploadProgress from 'soapbox/features/compose/components/upload_progress';
import { truncateFilename } from 'soapbox/utils/media';
import ChatMessageList from './chat_message_list';

@ -0,0 +1,45 @@
import React from 'react';
import { FormattedMessage } from 'react-intl';
import { spring } from 'react-motion';
import { HStack, Icon, Stack, Text } from 'soapbox/components/ui';
import { useAppSelector } from 'soapbox/hooks';
import Motion from '../../ui/util/optional_motion';
const UploadProgress = () => {
const active = useAppSelector((state) => state.compose.get('is_uploading'));
const progress = useAppSelector((state) => state.compose.get('progress'));
if (!active) {
return null;
}
return (
<HStack alignItems='center' space={2}>
<Icon
src={require('@tabler/icons/icons/cloud-upload.svg')}
className='w-7 h-7 text-gray-500'
/>
<Stack space={1}>
<Text theme='muted'>
<FormattedMessage id='upload_progress.label' defaultMessage='Uploading…' />
</Text>
<div className='w-full h-1.5 rounded-lg bg-gray-200 relative'>
<Motion defaultStyle={{ width: 0 }} style={{ width: spring(progress) }}>
{({ width }) =>
(<div
className='absolute left-0 top-0 h-1.5 bg-primary-600 rounded-lg'
style={{ width: `${width}%` }}
/>)
}
</Motion>
</div>
</Stack>
</HStack>
);
};
export default UploadProgress;

@ -4,8 +4,8 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
// import SensitiveButtonContainer from '../containers/sensitive_button_container';
import UploadProgress from '../components/upload-progress';
import UploadContainer from '../containers/upload_container';
import UploadProgressContainer from '../containers/upload_progress_container';
export default class UploadForm extends ImmutablePureComponent {
@ -21,7 +21,7 @@ export default class UploadForm extends ImmutablePureComponent {
return (
<div className='compose-form__upload-wrapper'>
<UploadProgressContainer />
<UploadProgress />
<div className={classes}>
{mediaIds.map(id => (

@ -1,45 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
import { FormattedMessage } from 'react-intl';
import spring from 'react-motion/lib/spring';
import Icon from 'soapbox/components/icon';
import Motion from '../../ui/util/optional_motion';
export default class UploadProgress extends React.PureComponent {
static propTypes = {
active: PropTypes.bool,
progress: PropTypes.number,
};
render() {
const { active, progress } = this.props;
if (!active) {
return null;
}
return (
<div className='upload-progress'>
<div className='upload-progress__icon'>
<Icon id='upload' />
</div>
<div className='upload-progress__message'>
<FormattedMessage id='upload_progress.label' defaultMessage='Uploading…' />
<div className='upload-progress__backdrop'>
<Motion defaultStyle={{ width: 0 }} style={{ width: spring(progress) }}>
{({ width }) =>
<div className='upload-progress__tracker' style={{ width: `${width}%` }} />
}
</Motion>
</div>
</div>
</div>
);
}
}

@ -39,7 +39,7 @@ const mapStateToProps = state => {
};
};
const mapDispatchToProps = (dispatch) => ({
const mapDispatchToProps = (dispatch, { intl }) => ({
onChange(text) {
dispatch(changeCompose(text));
@ -66,7 +66,7 @@ const mapDispatchToProps = (dispatch) => ({
},
onPaste(files) {
dispatch(uploadCompose(files));
dispatch(uploadCompose(files, intl));
},
onPickEmoji(position, data, needsSpace) {

@ -1,3 +1,4 @@
import { injectIntl } from 'react-intl';
import { connect } from 'react-redux';
import { uploadCompose } from '../../../actions/compose';
@ -8,12 +9,12 @@ const mapStateToProps = state => ({
resetFileKey: state.getIn(['compose', 'resetFileKey']),
});
const mapDispatchToProps = dispatch => ({
const mapDispatchToProps = (dispatch, { intl }) => ({
onSelectFile(files) {
dispatch(uploadCompose(files));
dispatch(uploadCompose(files, intl));
},
});
export default connect(mapStateToProps, mapDispatchToProps)(UploadButton);
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(UploadButton));

@ -1,6 +1,6 @@
import { connect } from 'react-redux';
import UploadProgress from '../components/upload_progress';
import UploadProgress from '../components/upload-progress';
const mapStateToProps = state => ({
active: state.getIn(['compose', 'is_uploading']),

@ -31,32 +31,32 @@ const Developers = () => {
return (
<Column label={intl.formatMessage(messages.heading)}>
<div className='grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-2'>
<Link to='/developers/apps/create' className='bg-gray-200 p-4 rounded flex flex-col items-center justify-center space-y-2 hover:-translate-y-1 transition-transform'>
<InlineSVG src={require('@tabler/icons/icons/apps.svg')} />
<Link to='/developers/apps/create' className='bg-gray-200 dark:bg-gray-600 p-4 rounded flex flex-col items-center justify-center space-y-2 hover:-translate-y-1 transition-transform'>
<InlineSVG src={require('@tabler/icons/icons/apps.svg')} className='dark:text-gray-100' />
<Text>
<FormattedMessage id='developers.navigation.app_create_label' defaultMessage='Create an app' />
</Text>
</Link>
<Link to='/developers/settings_store' className='bg-gray-200 p-4 rounded flex flex-col items-center justify-center space-y-2 hover:-translate-y-1 transition-transform'>
<InlineSVG src={require('@tabler/icons/icons/code-plus.svg')} />
<Link to='/developers/settings_store' className='bg-gray-200 dark:bg-gray-600 p-4 rounded flex flex-col items-center justify-center space-y-2 hover:-translate-y-1 transition-transform'>
<InlineSVG src={require('@tabler/icons/icons/code-plus.svg')} className='dark:text-gray-100' />
<Text>
<FormattedMessage id='developers.navigation.settings_store_label' defaultMessage='Settings store' />
</Text>
</Link>
<Link to='/error' className='bg-gray-200 p-4 rounded flex flex-col items-center justify-center space-y-2 hover:-translate-y-1 transition-transform'>
<InlineSVG src={require('@tabler/icons/icons/mood-sad.svg')} />
<Link to='/error' className='bg-gray-200 dark:bg-gray-600 p-4 rounded flex flex-col items-center justify-center space-y-2 hover:-translate-y-1 transition-transform'>
<InlineSVG src={require('@tabler/icons/icons/mood-sad.svg')} className='dark:text-gray-100' />
<Text>
<FormattedMessage id='developers.navigation.intentional_error_label' defaultMessage='Trigger an error' />
</Text>
</Link>
<button onClick={leaveDevelopers} className='bg-gray-200 p-4 rounded flex flex-col items-center justify-center space-y-2 hover:-translate-y-1 transition-transform'>
<InlineSVG src={require('@tabler/icons/icons/logout.svg')} />
<button onClick={leaveDevelopers} className='bg-gray-200 dark:bg-gray-600 p-4 rounded flex flex-col items-center justify-center space-y-2 hover:-translate-y-1 transition-transform'>
<InlineSVG src={require('@tabler/icons/icons/logout.svg')} className='dark:text-gray-100' />
<Text>
<FormattedMessage id='developers.navigation.leave_developers_label' defaultMessage='Leave developers' />

@ -11,6 +11,7 @@ import Avatar from 'soapbox/components/avatar';
import DisplayName from 'soapbox/components/display_name';
import Permalink from 'soapbox/components/permalink';
import RelativeTimestamp from 'soapbox/components/relative_timestamp';
import { Text } from 'soapbox/components/ui';
import ActionButton from 'soapbox/features/ui/components/action_button';
import { makeGetAccount } from 'soapbox/selectors';
import { shortNumberFormat } from 'soapbox/utils/numbers';
@ -73,9 +74,9 @@ class AccountCard extends ImmutablePureComponent {
</div>
<div className='directory__card__extra'>
<div className='accounts-table__count'>{shortNumberFormat(account.get('statuses_count'))} <small><FormattedMessage id='account.posts' defaultMessage='Toots' /></small></div>
<div className='accounts-table__count'>{shortNumberFormat(account.get('followers_count'))} <small><FormattedMessage id='account.followers' defaultMessage='Followers' /></small></div>
<div className='accounts-table__count'>{account.get('last_status_at') === null ? <FormattedMessage id='account.never_active' defaultMessage='Never' /> : <RelativeTimestamp timestamp={account.get('last_status_at')} />} <small><FormattedMessage id='account.last_status' defaultMessage='Last active' /></small></div>
<div className='accounts-table__count'><Text theme='primary' size='sm'>{shortNumberFormat(account.get('statuses_count'))}</Text> <small><FormattedMessage id='account.posts' defaultMessage='Toots' /></small></div>
<div className='accounts-table__count'><Text theme='primary' size='sm'>{shortNumberFormat(account.get('followers_count'))}</Text> <small><FormattedMessage id='account.followers' defaultMessage='Followers' /></small></div>
<div className='accounts-table__count'>{account.get('last_status_at') === null ? <Text theme='primary' size='sm'><FormattedMessage id='account.never_active' defaultMessage='Never' /></Text> : <RelativeTimestamp className='text-primary-600' timestamp={account.get('last_status_at')} />} <small><FormattedMessage id='account.last_status' defaultMessage='Last active' /></small></div>
</div>
</div>
);

@ -36,6 +36,7 @@ const hidesNetwork = account => {
const messages = defineMessages({
heading: { id: 'column.edit_profile', defaultMessage: 'Edit profile' },
header: { id: 'edit_profile.header', defaultMessage: 'Edit Profile' },
metaFieldLabel: { id: 'edit_profile.fields.meta_fields.label_placeholder', defaultMessage: 'Label' },
metaFieldContent: { id: 'edit_profile.fields.meta_fields.content_placeholder', defaultMessage: 'Content' },
verified: { id: 'edit_profile.fields.verified_display_name', defaultMessage: 'Verified users may not update their display name' },
@ -246,7 +247,7 @@ class EditProfile extends ImmutablePureComponent {
const canEditName = verifiedCanEditName || !verified;
return (
<Column label='Edit Profile'>
<Column label={intl.formatMessage(messages.header)}>
<Form onSubmit={this.handleSubmit}>
<FormGroup
labelText={<FormattedMessage id='edit_profile.fields.display_name_label' defaultMessage='Display name' />}

@ -5,7 +5,7 @@ import PlaceholderDisplayName from './placeholder_display_name';
import PlaceholderStatusContent from './placeholder_status_content';
const PlaceholderNotification = () => (
<div className='bg-white px-4 py-6 sm:p-6'>
<div className='bg-white dark:bg-slate-800 px-4 py-6 sm:p-6'>
<div className='w-full animate-pulse'>
<div className='mb-2'>
<PlaceholderStatusContent minLength={20} maxLength={20} />

@ -229,7 +229,7 @@ class EnableOtpForm extends ImmutablePureComponent {
<FormattedMessage id='mfa.setup_warning' defaultMessage="Write these codes down or save them somewhere secure - otherwise you won't see them again. If you lose access to your 2FA app and recovery codes you'll be locked out of your account." />
</Text>
<div className='bg-gray-100 rounded-lg p-4'>
<div className='bg-gray-100 dark:bg-slate-700 rounded-lg p-4'>
<Stack space={3}>
<Text weight='medium' align='center'>
<FormattedMessage id='mfa.setup_recoverycodes' defaultMessage='Recovery codes' />

@ -110,8 +110,7 @@ class DetailedStatus extends ImmutablePureComponent {
if (size > 0) {
if (size === 1 && status.getIn(['media_attachments', 0, 'type']) === 'video') {
const video = status.getIn(['media_attachments', 0]);
const external_id = (video.get('external_video_id'));
if (external_id) {
if (video.external_video_id && status.card?.html) {
const { mediaWrapperWidth } = this.state;
const height = mediaWrapperWidth / (video.getIn(['meta', 'original', 'width']) / video.getIn(['meta', 'original', 'height']));
media = (
@ -120,16 +119,8 @@ class DetailedStatus extends ImmutablePureComponent {
ref={this.setRef}
className='status-card-video'
style={{ height }}
>
<iframe
src={`https://rumble.com/embed/${external_id}/`}
frameborder='0'
allowFullScreen='true'
webkitallowfullscreen='true'
mozallowfullscreen='true'
title='Video'
/>
</div>
dangerouslySetInnerHTML={{ __html: status.card.html }}
/>
</div>
);
} else {

@ -13,13 +13,13 @@ export default () => (
</filter>
<path id='a' d='M0 0h1754v1336H0z' />
</defs>
<g fill='none' fill-rule='evenodd'>
<g fill='none' fillRule='evenodd'>
<mask id='b' fill='#fff'>
<use xlinkHref='#a' />
</mask>
<g mask='url(#b)'>
<path className='fill-bg-shape-1' d='M1257.79 335.852C1262 527.117 897.55 530.28 792.32 977.19 600.48 981.41 435.29 545.31 431.08 354.046 426.871 162.782 578.976 4.31 770.815.088c191.844-4.222 482.764 144.5 486.974 335.764Z' fill-rule='nonzero' filter='url(#c)' transform='translate(309.54 -367.538)' />
<path className='fill-bg-shape-2' d='M71.127 1126.654c206.164 179.412 502.452 211.232 661.777 71.072 159.325-140.163 295.165-510.155 8.23-504.412-320.079 6.405-381.35-817.422-540.675-677.258-31 368-335.497 931.182-129.332 1110.598Z' fill-rule='nonzero' filter='url(#d)' transform='translate(309.54 -141.056)' opacity='.1' />
<path className='fill-bg-shape-1' d='M1257.79 335.852C1262 527.117 897.55 530.28 792.32 977.19 600.48 981.41 435.29 545.31 431.08 354.046 426.871 162.782 578.976 4.31 770.815.088c191.844-4.222 482.764 144.5 486.974 335.764Z' fillRule='nonzero' filter='url(#c)' transform='translate(309.54 -367.538)' opacity='.1' />
<path className='fill-bg-shape-2' d='M71.127 1126.654c206.164 179.412 502.452 211.232 661.777 71.072 159.325-140.163 295.165-510.155 8.23-504.412-320.079 6.405-381.35-817.422-540.675-677.258-31 368-335.497 931.182-129.332 1110.598Z' fillRule='nonzero' filter='url(#d)' transform='translate(309.54 -141.056)' opacity='.1' />
</g>
</g>
</svg>

@ -3,7 +3,6 @@ import React from 'react';
import { defineMessages, injectIntl } from 'react-intl';
import Column from './column';
import ColumnHeader from './column_header';
const messages = defineMessages({
title: { id: 'column_forbidden.title', defaultMessage: 'Forbidden' },
@ -20,8 +19,7 @@ class ColumnForbidden extends React.PureComponent {
const { intl: { formatMessage } } = this.props;
return (
<Column>
<ColumnHeader icon='exclamation-circle' type={formatMessage(messages.title)} />
<Column label={formatMessage(messages.title)}>
<div className='error-column'>
{formatMessage(messages.body)}
</div>

@ -1,105 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { FormattedMessage, injectIntl } from 'react-intl';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { logOut } from 'soapbox/actions/auth';
import { getSoapboxConfig } from 'soapbox/actions/soapbox';
import { Text } from 'soapbox/components/ui';
import emojify from 'soapbox/features/emoji/emoji';
import { getBaseURL } from 'soapbox/utils/accounts';
import sourceCode from 'soapbox/utils/code';
import { getFeatures } from 'soapbox/utils/features';
import { openModal } from '../../../actions/modals';
const mapStateToProps = state => {
const me = state.get('me');
const account = state.getIn(['accounts', me]);
const instance = state.get('instance');
const features = getFeatures(instance);
const soapboxConfig = getSoapboxConfig(state);
return {
account,
soapboxConfig,
profileDirectory: features.profileDirectory,
federating: features.federating,
showAliases: features.accountAliasesAPI,
importAPI: features.importAPI,
baseURL: getBaseURL(account),
};
};
const mapDispatchToProps = (dispatch, { intl }) => ({
onOpenHotkeys(e) {
dispatch(openModal('HOTKEYS'));
e.preventDefault();
},
onClickLogOut(e) {
dispatch(logOut(intl));
e.preventDefault();
},
});
const LinkFooter = ({ onOpenHotkeys, account, profileDirectory, federating, showAliases, importAPI, onClickLogOut, baseURL, soapboxConfig }) => (
<div className='space-y-2'>
<ul className='flex flex-wrap items-center divide-x-dot'>
{account && <>
{profileDirectory && <li><Link to='/directory' className='text-gray-400 hover:text-gray-500 hover:underline'><FormattedMessage id='navigation_bar.profile_directory' defaultMessage='Profile directory' /></Link></li>}
<li><Link to='/blocks' className='text-gray-400 hover:text-gray-500 hover:underline'><FormattedMessage id='navigation_bar.blocks' defaultMessage='Blocks' /></Link></li>
<li><Link to='/mutes' className='text-gray-400 hover:text-gray-500 hover:underline'><FormattedMessage id='navigation_bar.mutes' defaultMessage='Mutes' /></Link></li>
{/* <li><Link to='/filters' className='text-gray-400 hover:text-gray-500 hover:underline'><FormattedMessage id='navigation_bar.filters' defaultMessage='Filters' /></Link></li> */}
{federating && <li><Link to='/domain_blocks' className='text-gray-400 hover:text-gray-500 hover:underline'><FormattedMessage id='navigation_bar.domain_blocks' defaultMessage='Domain blocks' /></Link></li>}
{/* <li><Link to='/follow_requests'><FormattedMessage id='navigation_bar.follow_requests' defaultMessage='Follow requests' /></Link></li> */}
{/* isAdmin(account) && <li><a href='/pleroma/admin' className='text-gray-400 hover:text-gray-500 hover:underline'><FormattedMessage id='navigation_bar.admin_settings' defaultMessage='AdminFE' /></a></li> */}
{/* isAdmin(account) && <li><Link to='/soapbox/config' className='text-gray-400 hover:text-gray-500 hover:underline'><FormattedMessage id='navigation_bar.soapbox_config' defaultMessage='Soapbox config' /></Link></li> */}
{/* <li><Link to='/settings/export'><FormattedMessage id='navigation_bar.export_data' defaultMessage='Export data' /></Link></li> */}
{/* <li>{importAPI ? (
<Link to='/settings/import'><FormattedMessage id='navigation_bar.import_data' defaultMessage='Import data' /></Link>
) : (
<a href={`${baseURL}/settings/import`}><FormattedMessage id='navigation_bar.import_data' defaultMessage='Import data' /></a>
)}</li> */}
{(federating && showAliases) && <li><Link to='/settings/aliases' className='text-gray-400 hover:text-gray-500 hover:underline'><FormattedMessage id='navigation_bar.account_aliases' defaultMessage='Account aliases' /></Link></li>}
{/* <li><a href='#' onClick={onOpenHotkeys}><FormattedMessage id='navigation_bar.keyboard_shortcuts' defaultMessage='Hotkeys' /></a></li> */}
</>}
{/* <li><Link to='/about'><FormattedMessage id='navigation_bar.info' defaultMessage='About this server' /></Link></li> */}
{account && <li><Link to='/auth/sign_out' onClick={onClickLogOut} className='text-gray-400 hover:text-gray-500 hover:underline'><FormattedMessage id='navigation_bar.logout' defaultMessage='Logout' /></Link></li>}
</ul>
<Text theme='muted' size='sm'>
{soapboxConfig.get('linkFooterMessage') ? (
<span
className='inline-block align-middle'
dangerouslySetInnerHTML={{ __html: emojify(soapboxConfig.get('linkFooterMessage')) }}
/>
) : (
<FormattedMessage
id='getting_started.open_source_notice'
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: <a href={sourceCode.url} rel='noopener' target='_blank'>{sourceCode.repository}</a>,
code_version: sourceCode.version,
}}
/>
)}
</Text>
</div>
);
LinkFooter.propTypes = {
account: ImmutablePropTypes.record,
soapboxConfig: ImmutablePropTypes.map,
profileDirectory: PropTypes.bool,
federating: PropTypes.bool,
showAliases: PropTypes.bool,
importAPI: PropTypes.bool,
onOpenHotkeys: PropTypes.func.isRequired,
onClickLogOut: PropTypes.func.isRequired,
baseURL: PropTypes.string,
};
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(LinkFooter));

@ -0,0 +1,88 @@
import classNames from 'classnames';
import React from 'react';
import { FormattedMessage, useIntl } 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 sourceCode from 'soapbox/utils/code';
interface IFooterLink {
to: string,
className?: string,
onClick?: React.EventHandler<React.MouseEvent>,
}
const FooterLink: React.FC<IFooterLink> = ({ children, className, ...rest }): JSX.Element => {
return (
<Link className={classNames('text-gray-400 hover:text-gray-500 hover:underline', className)} {...rest}>{children}</Link>
);
};
const LinkFooter: React.FC = (): JSX.Element => {
const account = useOwnAccount();
const features = useFeatures();
const soapboxConfig = useSoapboxConfig();
const intl = useIntl();
const dispatch = useDispatch();
const onClickLogOut: React.EventHandler<React.MouseEvent> = (e) => {
dispatch(logOut(intl));
e.preventDefault();
};
return (
<div className='space-y-2'>
<div className='flex flex-wrap items-center divide-x-dot'>
{account && <>
{features.profileDirectory && (
<FooterLink to='/directory'><FormattedMessage id='navigation_bar.profile_directory' defaultMessage='Profile directory' /></FooterLink>
)}
<FooterLink to='/blocks'><FormattedMessage id='navigation_bar.blocks' defaultMessage='Blocks' /></FooterLink>
<FooterLink to='/mutes'><FormattedMessage id='navigation_bar.mutes' defaultMessage='Mutes' /></FooterLink>
{features.filters && (
<FooterLink to='/filters'><FormattedMessage id='navigation_bar.filters' defaultMessage='Filters' /></FooterLink>
)}
{features.federating && (
<FooterLink to='/domain_blocks'><FormattedMessage id='navigation_bar.domain_blocks' defaultMessage='Domain blocks' /></FooterLink>
)}
{account.locked && (
<FooterLink to='/follow_requests'><FormattedMessage id='navigation_bar.follow_requests' defaultMessage='Follow requests' /></FooterLink>
)}
{features.importAPI && (
<FooterLink to='/settings/import'><FormattedMessage id='navigation_bar.import_data' defaultMessage='Import data' /></FooterLink>
)}
{(features.federating && features.accountMoving) && (
<FooterLink to='/settings/migration'><FormattedMessage id='navigation_bar.account_migration' defaultMessage='Move account' /></FooterLink>
)}
<FooterLink to='/auth/sign_out' onClick={onClickLogOut}><FormattedMessage id='navigation_bar.logout' defaultMessage='Logout' /></FooterLink>
</>}
</div>
<Text theme='muted' size='sm'>
{soapboxConfig.linkFooterMessage ? (
<span
className='inline-block align-middle'
dangerouslySetInnerHTML={{ __html: emojify(soapboxConfig.linkFooterMessage) }}
/>
) : (
<FormattedMessage
id='getting_started.open_source_notice'
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: <a href={sourceCode.url} rel='noopener' target='_blank'>{sourceCode.repository}</a>,
code_version: sourceCode.version,
}}
/>
)}
</Text>
</div>
);
};
export default LinkFooter;

@ -426,7 +426,7 @@ class UI extends React.PureComponent {
this.dragTargets = [];
if (e.dataTransfer && e.dataTransfer.files.length >= 1) {
this.props.dispatch(uploadCompose(e.dataTransfer.files));
this.props.dispatch(uploadCompose(e.dataTransfer.files, this.props.intl));
}
}

@ -1,4 +1,5 @@
export { useAppSelector } from './useAppSelector';
export { useFeatures } from './useFeatures';
export { useOnScreen } from './useOnScreen';
export { useOwnAccount } from './useOwnAccount';
export { useSettings } from './useSettings';

@ -0,0 +1,9 @@
import { useAppSelector } from 'soapbox/hooks';
import { getFeatures } from 'soapbox/utils/features';
import type { Features } from 'soapbox/utils/features';
/** Get features for the current instance */
export const useFeatures = (): Features => {
return useAppSelector((state) => getFeatures(state.instance));
};

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "لن يَظهر هذا التبويق إلا للمستخدمين المذكورين.",
"compose_form.hashtag_warning": "هذا التبويق لن يُدرَج تحت أي وسم كان بما أنه غير مُدرَج. لا يُسمح بالبحث إلّا عن التبويقات العمومية عن طريق الوسوم.",
"compose_form.lock_disclaimer": "حسابك ليس {locked}. يمكن لأي شخص متابعتك و عرض المنشورات.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Esti toot namái va unviase a los usuarios mentaos.",
"compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
"compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "This post will only be visible to all the mentioned users.",
"compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
"compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "শুধুমাত্র যাদেরকে উল্লেখ করা হয়েছে তাদেরকেই এই টুটটি পাঠানো হবে ।",
"compose_form.hashtag_warning": "কোনো হ্যাশট্যাগের ভেতরে এই টুটটি থাকবেনা কারণ এটি তালিকাবহির্ভূত। শুধুমাত্র প্রকাশ্য ঠোটগুলো হ্যাশট্যাগের ভেতরে খুঁজে পাওয়া যাবে।",
"compose_form.lock_disclaimer": "আপনার নিবন্ধনে তালা দেওয়া নেই, যে কেও আপনাকে অনুসরণ করতে পারবে এবং অনুশারকদের জন্য লেখা দেখতে পারবে।",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -223,7 +223,7 @@
"column.mfa_disable_button": "Disable",
"column.mfa_setup": "Proceed to Setup",
"column.mutes": "Muted users",
"column.notifications": "Alerts",
"column.notifications": "Notifications",
"column.pins": "Pinned posts",
"column.preferences": "Preferences",
"column.profile_directory": "Profile directory",
@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "This post will only be sent to all the mentioned users.",
"compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
"compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",
@ -937,7 +937,7 @@
"tabs_bar.header": "Account Info",
"tabs_bar.home": "Home",
"tabs_bar.news": "News",
"tabs_bar.notifications": "Alerts",
"tabs_bar.notifications": "Notifications",
"tabs_bar.post": "Post",
"tabs_bar.search": "Search",
"tabs_bar.theme_toggle_dark": "Switch to dark theme",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Aquesta publicació només serà enviada als usuaris esmentats.",
"compose_form.hashtag_warning": "Aquesta publicació no es mostrarà en cap etiqueta ja que no està llistat. Només els toots públics poden ser cercats per etiqueta.",
"compose_form.lock_disclaimer": "El teu compte no està bloquejat {locked}. Tothom pot seguir-te i veure els teus missatges a seguidors.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Configuració de Pleroma",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Solu l'utilizatori mintuvati puderenu vede stu statutu.",
"compose_form.hashtag_warning": "Stu statutu ùn hè \"Micca listatu\" è ùn sarà micca listatu indè e circate da hashtag. Per esse vistu in quesse, u statutu deve esse \"Pubblicu\".",
"compose_form.lock_disclaimer": "U vostru contu ùn hè micca {locked}. Tuttu u mondu pò seguitavi è vede i vostri statuti privati.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Tento příspěvek bude odeslán pouze zmíněným uživatelům.",
"compose_form.hashtag_warning": "Tento příspěvěk nebude zobrazen pod žádným hashtagem, neboť je neuvedený. Pouze veřejné příspěvky mohou být vyhledány podle hashtagu.",
"compose_form.lock_disclaimer": "Váš účet není {locked}. Kdokoliv vás může sledovat a vidět vaše příspěvky pouze pro sledující.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Adminské menu",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Mi fydd y tŵt hwn ond yn cael ei anfon at y defnyddwyr sy'n cael eu crybwyll.",
"compose_form.hashtag_warning": "Ni fydd y tŵt hwn wedi ei restru o dan unrhyw hashnod gan ei fod heb ei restru. Dim ond tŵtiau cyhoeddus gellid chwilota amdanynt drwy hashnod.",
"compose_form.lock_disclaimer": "Nid yw eich cyfri wedi'i {locked}. Gall unrhyw un eich dilyn i weld eich tŵtiau dilynwyr-yn-unig.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Dette trut vil kun blive sendt til de nævnte brugere.",
"compose_form.hashtag_warning": "Dette trut vil ikke blive vist under noget hashtag da det ikke er listet. Kun offentlige trut kan blive vist under søgninger med hashtags.",
"compose_form.lock_disclaimer": "Din konto er ikke {locked}. Alle kan følge dig for at se dine følger-kun indlæg.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Αυτό το τουτ θα σταλεί μόνο στους αναφερόμενους χρήστες.",
"compose_form.hashtag_warning": "Αυτό το τουτ δεν θα εμφανίζεται κάτω από κανένα hashtag καθώς είναι αφανές. Μόνο τα δημόσια τουτ μπορούν να αναζητηθούν ανά hashtag.",
"compose_form.lock_disclaimer": "Ο λογαριασμός σου δεν είναι {locked}. Οποιοσδήποτε μπορεί να σε ακολουθήσει για να δει τις δημοσιεύσεις σας προς τους ακολούθους σας.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -35,7 +35,7 @@
"account.muted": "Muted",
"account.never_active": "Never",
"account.posts": "Posts",
"account.posts_with_replies": "Posts & Replies",
"account.posts_with_replies": "Posts & replies",
"account.profile": "Profile",
"account.register": "Sign up",
"account.remote_follow": "Remote follow",
@ -223,7 +223,7 @@
"column.mfa_disable_button": "Disable",
"column.mfa_setup": "Proceed to Setup",
"column.mutes": "Muted users",
"column.notifications": "Alerts",
"column.notifications": "Notifications",
"column.pins": "Pinned posts",
"column.preferences": "Preferences",
"column.profile_directory": "Profile directory",
@ -328,7 +328,6 @@
"edit_federation.unlisted": "Force posts unlisted",
"edit_profile.error": "Profile update failed",
"edit_profile.fields.accepts_email_list_label": "Subscribe to newsletter",
"edit_profile.fields.avatar_label": "Avatar",
"edit_profile.fields.avatar_label": "Choose Profile Picture",
"edit_profile.fields.bio_label": "Bio",
"edit_profile.fields.bio_placeholder": "Tell us about yourself.",
@ -345,10 +344,10 @@
"edit_profile.fields.stranger_notifications_label": "Block notifications from strangers",
"edit_profile.fields.verified_display_name": "Verified users may not update their display name",
"edit_profile.hints.accepts_email_list": "Opt-in to news and marketing updates.",
"edit_profile.hints.avatar": "20 MB Max",
"edit_profile.hints.avatar": "PNG, GIF or JPG. Will be downscaled to {size}",
"edit_profile.hints.bot": "This account mainly performs automated actions and might not be monitored",
"edit_profile.hints.discoverable": "Display account in profile directory and allow indexing by external services",
"edit_profile.hints.header": "20 MB Max",
"edit_profile.hints.header": "PNG, GIF or JPG. Will be downscaled to {size}",
"edit_profile.hints.hide_network": "Who you follow and who follows you will not be shown on your profile",
"edit_profile.hints.locked": "Requires you to manually approve followers",
"edit_profile.hints.meta_fields": "You can have up to {count, plural, one {# item} other {# items}} displayed as a table on your profile",
@ -364,7 +363,7 @@
"emoji_button.food": "Food & Drink",
"emoji_button.label": "Insert emoji",
"emoji_button.nature": "Nature",
"emoji_button.not_found": "No emoji's found.",
"emoji_button.not_found": "No emojis found.",
"emoji_button.objects": "Objects",
"emoji_button.people": "People",
"emoji_button.recent": "Frequently used",
@ -439,13 +438,10 @@
"filters.filters_list_whole-word": "Whole word",
"filters.removed": "Filter deleted.",
"follow_recommendations.done": "Done",
"follow_recommendations.heading": "Follow people you'd like to see posts from! Here are some suggestions.",
"follow_recommendations.lead": "Dont be afraid to make mistakes; you can unfollow people at any time.",
"follow_recommendations.heading": "People To Follow",
"follow_recommendations.lead": "Here are some suggestions of exciting accounts to follow. Don't be afraid to make mistakes; you can unfollow people at any time.",
"follow_request.authorize": "Authorize",
"follow_request.reject": "Reject",
"follow_recommendations.heading": "Who To Follow",
"follow_recommendation.subhead": "Let's get started!",
"follow_recommendations.lead": "Here are some suggestions of exciting accounts to follow. Don't be afraid to make mistakes; you can unfollow people at any time.",
"forms.copy": "Copy",
"forms.hide_password": "Hide password",
"forms.show_password": "Show password",
@ -611,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "AdminFE",
@ -639,7 +635,6 @@
"navigation_bar.profile_directory": "Profile directory",
"navigation_bar.security": "Security",
"navigation_bar.soapbox_config": "Soapbox config",
"navigation.home": "Feed",
"notification.chat_mention": "{name} sent you a message",
"notification.favourite": "{name} liked your post",
"notification.follow": "{name} followed you",
@ -648,7 +643,7 @@
"notification.move": "{name} moved to {targetName}",
"notification.pleroma:emoji_reaction": "{name} reacted to your post",
"notification.poll": "A poll you have voted in has ended",
"notification.reblog": "{name} Reposted your post",
"notification.reblog": "{name} reposted your post",
"notifications.clear": "Clear notifications",
"notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
"notifications.column_settings.alert": "Desktop notifications",
@ -678,7 +673,7 @@
"notifications.filter.moves": "Moves",
"notifications.filter.polls": "Poll results",
"notifications.group": "{count} notifications",
"notifications.queue_label": "Recent Alerts",
"notifications.queue_label": "Click to see {count} new {count, plural, one {notification} other {notifications}}",
"password_reset.confirmation": "Check your email for confirmation.",
"password_reset.fields.username_placeholder": "Email or username",
"password_reset.reset": "Reset password",
@ -713,7 +708,6 @@
"preferences.fields.system_font_label": "Use system's default font",
"preferences.fields.underline_links_label": "Always underline links in posts",
"preferences.fields.unfollow_modal_label": "Show confirmation dialog before unfollowing someone",
"preferences.hints.feed": "In your home feed",
"preferences.hints.content_type_markdown": "Warning: experimental!",
"preferences.hints.demetricator": "Decrease social media anxiety by hiding all numbers from the site.",
"preferences.hints.halloween": "Beware: SPOOKY! Supports light/dark toggle.",
@ -742,7 +736,7 @@
"regeneration_indicator.sublabel": "Your home feed is being prepared!",
"register_invite.lead": "Complete the form below to create an account.",
"register_invite.title": "You've been invited to join {siteTitle}!",
"registration.agreement": "I agree to the {tos} and {pp}. I also agree to receive emails and understand that I may opt out of the subscription at any time.",
"registration.agreement": "I agree to the {tos}.",
"registration.captcha.hint": "Click the image to get a new captcha",
"registration.closed_message": "{instance} is not accepting new members",
"registration.closed_title": "Registrations Closed",
@ -759,7 +753,6 @@
"registration.reason_hint": "This will help us review your application",
"registration.sign_up": "Sign up",
"registration.tos": "Terms of Service",
"registration.pp": "Privacy Policy",
"registration.username_unavailable": "Username is already taken.",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
@ -912,7 +905,7 @@
"status.read_more": "Read more",
"status.reblog": "Repost",
"status.reblog_private": "Repost to original audience",
"status.reblogged_by": "{name} Reposted",
"status.reblogged_by": "{name} reposted",
"status.reblogs.empty": "No one has reposted this post yet. When someone does, they will show up here.",
"status.redraft": "Delete & re-draft",
"status.remove_account_from_group": "Remove account from group",
@ -927,13 +920,13 @@
"status.show_more": "Show more",
"status.show_more_all": "Show more for all",
"status.show_thread": "Show thread",
"status.title": "@{username}'s Post",
"status.title": "@{username}'s post",
"status.title_direct": "Direct message",
"status.unbookmark": "Remove bookmark",
"status.unbookmarked": "Bookmark removed.",
"status.unmute_conversation": "Unmute conversation",
"status.unpin": "Unpin from profile",
"status_list.queue_label": "Recent Posts",
"status_list.queue_label": "Click to see {count} new {count, plural, one {post} other {posts}}",
"statuses.tombstone": "One or more posts is unavailable.",
"suggestions.dismiss": "Dismiss suggestion",
"tabs_bar.all": "All",
@ -944,7 +937,7 @@
"tabs_bar.header": "Account Info",
"tabs_bar.home": "Home",
"tabs_bar.news": "News",
"tabs_bar.notifications": "Alerts",
"tabs_bar.notifications": "Notifications",
"tabs_bar.post": "Post",
"tabs_bar.search": "Search",
"tabs_bar.theme_toggle_dark": "Switch to dark theme",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Tiu mesaĝo estos sendita nur al menciitaj uzantoj.",
"compose_form.hashtag_warning": "Ĉi tiu mesaĝo ne estos listigita per ajna kradvorto. Nur publikaj mesaĝoj estas serĉeblaj per kradvortoj.",
"compose_form.lock_disclaimer": "Via konta ne estas {locked}. Iu ajn povas sekvi vin por vidi viajn mesaĝojn, kiuj estas nur por sekvantoj.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Este toot sólo será enviado a los usuarios mencionados.",
"compose_form.hashtag_warning": "Este toot no se mostrará bajo hashtags porque no es público. Sólo los toots públicos se pueden buscar por hashtag.",
"compose_form.lock_disclaimer": "Tu cuenta no está {locked}. Todos pueden seguirte para ver tus toots marcados como \"sólo para seguidores\".",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Este toot solo será enviado a los usuarios mencionados.",
"compose_form.hashtag_warning": "Este toot no se mostrará bajo hashtags porque no es público. Sólo los toots públicos se pueden buscar por hashtag.",
"compose_form.lock_disclaimer": "Tu cuenta no está bloqueada. Todos pueden seguirte para ver tus toots solo para seguidores.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "See tuut saadetakse ainult mainitud kasutajatele.",
"compose_form.hashtag_warning": "Seda tuuti ei kuvata ühegi sildi all, sest see on kirjendamata. Ainult avalikud tuutid on sildi järgi otsitavad.",
"compose_form.lock_disclaimer": "Sinu konto ei ole {locked}. Igaüks saab sind jälgida ja näha su ainult-jälgijatele postitusi.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Toot hau aipatutako erabiltzaileei besterik ez zaie bidaliko.",
"compose_form.hashtag_warning": "Toot hau ez da traoletan agertuko zerrendatu gabekoa baita. Traoletan toot publikoak besterik ez dira agertzen.",
"compose_form.lock_disclaimer": "Zure kontua ez dago {locked}. Edonork jarraitu zaitzake zure jarraitzaileentzako soilik diren mezuak ikusteko.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "این بوق تنها به کاربرانی که از آن‌ها نام برده شده فرستاده خواهد شد.",
"compose_form.hashtag_warning": "از آن‌جا که این بوق فهرست‌نشده است، در نتایج جستجوی هشتگ‌ها پیدا نخواهد شد. تنها بوق‌های عمومی را می‌توان با جستجوی هشتگ پیدا کرد.",
"compose_form.lock_disclaimer": "حساب شما {locked} نیست. هر کسی می‌تواند پیگیر شما شود و نوشته‌های ویژهٔ پیگیران شما را ببیند.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Tämä tuuttaus näkyy vain mainituille käyttäjille.",
"compose_form.hashtag_warning": "Tämä tuuttaus ei näy hashtag-hauissa, koska se on listaamaton. Hashtagien avulla voi hakea vain julkisia tuuttauksia.",
"compose_form.lock_disclaimer": "Tilisi ei ole {locked}. Kuka tahansa voi seurata tiliäsi ja nähdä vain seuraajille rajaamasi julkaisut.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -223,7 +223,7 @@
"column.mfa_disable_button": "Disable",
"column.mfa_setup": "Proceed to Setup",
"column.mutes": "Comptes masqués",
"column.notifications": "Alerts",
"column.notifications": "Notifications",
"column.pins": "Pinned posts",
"column.preferences": "Preferences",
"column.profile_directory": "Profile directory",
@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Ce pouet sera uniquement envoyé aux personnes mentionnées. Cependant, ladministration de votre instance et des instances réceptrices pourront inspecter ce message.",
"compose_form.hashtag_warning": "Ce pouet ne sera pas listé dans les recherches par hashtag car sa visibilité est réglée sur \"non listé\". Seuls les pouets avec une visibilité \"publique\" peuvent être recherchés par hashtag.",
"compose_form.lock_disclaimer": "Votre compte nest pas {locked}. Tout le monde peut vous suivre et voir vos pouets privés.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",
@ -937,7 +937,7 @@
"tabs_bar.header": "Account Info",
"tabs_bar.home": "Accueil",
"tabs_bar.news": "News",
"tabs_bar.notifications": "Alerts",
"tabs_bar.notifications": "Notifications",
"tabs_bar.post": "Post",
"tabs_bar.search": "Chercher",
"tabs_bar.theme_toggle_dark": "Switch to dark theme",

@ -223,7 +223,7 @@
"column.mfa_disable_button": "Disable",
"column.mfa_setup": "Proceed to Setup",
"column.mutes": "Muted users",
"column.notifications": "Alerts",
"column.notifications": "Notifications",
"column.pins": "Pinned posts",
"column.preferences": "Preferences",
"column.profile_directory": "Profile directory",
@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "This post will only be sent to all the mentioned users.",
"compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
"compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",
@ -937,7 +937,7 @@
"tabs_bar.header": "Account Info",
"tabs_bar.home": "Home",
"tabs_bar.news": "News",
"tabs_bar.notifications": "Alerts",
"tabs_bar.notifications": "Notifications",
"tabs_bar.post": "Post",
"tabs_bar.search": "Search",
"tabs_bar.theme_toggle_dark": "Switch to dark theme",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Este toot enviarase só as usuarias mencionadas. Porén, a súa proveedora de internet e calquera das instancias receptoras poderían examinar esta mensaxe.",
"compose_form.hashtag_warning": "Esta mensaxe non será listada baixo ningunha etiqueta xa que está marcada como non listada. Só os toots públicos poden buscarse por etiquetas.",
"compose_form.lock_disclaimer": "A súa conta non está {locked}. Calquera pode seguila para ver as súas mensaxes só-para-seguidoras.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -223,7 +223,7 @@
"column.mfa_disable_button": "Disable",
"column.mfa_setup": "Proceed to Setup",
"column.mutes": "Muted users",
"column.notifications": "Alerts",
"column.notifications": "Notifications",
"column.pins": "Pinned posts",
"column.preferences": "Preferences",
"column.profile_directory": "Profile directory",
@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "This toot will only be sent to all the mentioned users.",
"compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
"compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",
@ -937,7 +937,7 @@
"tabs_bar.header": "Account Info",
"tabs_bar.home": "Home",
"tabs_bar.news": "News",
"tabs_bar.notifications": "Alerts",
"tabs_bar.notifications": "Notifications",
"tabs_bar.post": "Post",
"tabs_bar.search": "Search",
"tabs_bar.theme_toggle_dark": "Switch to dark theme",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "This toot will only be visible to all the mentioned users.",
"compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
"compose_form.lock_disclaimer": "Tvoj račun nije {locked}. Svatko te može slijediti kako bi vidio postove namijenjene samo tvojim sljedbenicima.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Ezt a tülköt csak a benne megemlített felhasználók láthatják majd.",
"compose_form.hashtag_warning": "Ez a tülköd nem fog megjelenni semmilyen hashtag alatt mivel listázatlan. Csak nyilvános tülkök kereshetőek hashtaggel.",
"compose_form.lock_disclaimer": "A fiókod nincs {locked}. Bárki követni tud, hogy megtekintse a kizárólag követőknek szánt üzeneteidet.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "This toot will only be visible to all the mentioned users.",
"compose_form.hashtag_warning": "Այս թութը չի հաշվառվի որեւէ պիտակի տակ, քանզի այն ծածուկ է։ Միայն հրապարակային թթերը հնարավոր է որոնել պիտակներով։",
"compose_form.lock_disclaimer": "Քո հաշիվը {locked} չէ։ Յուրաքանչյուր ոք կարող է հետեւել քեզ եւ տեսնել միայն հետեւողների համար նախատեսված գրառումները։",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "This toot will only be visible to all the mentioned users.",
"compose_form.hashtag_warning": "Toot ini tidak akan ada dalam daftar tagar manapun karena telah di set sebagai tidak terdaftar. Hanya postingan publik yang bisa dicari dengan tagar.",
"compose_form.lock_disclaimer": "Akun anda tidak {locked}. Semua orang dapat mengikuti anda untuk melihat postingan khusus untuk pengikut anda.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "This toot will only be visible to all the mentioned users.",
"compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
"compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Questo toot sarà mandato solo a tutti gli utenti menzionati.",
"compose_form.hashtag_warning": "Questo toot non è listato, quindi non sarà trovato nelle ricerche per hashtag. Solo i toot pubblici possono essere cercati per hashtag.",
"compose_form.lock_disclaimer": "Il tuo account non è {locked}. Chiunque può decidere di seguirti per vedere i tuoi post per soli seguaci.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "この投稿はメンションされた人にのみ送信されます。",
"compose_form.hashtag_warning": "この投稿は公開設定ではないのでハッシュタグの一覧に表示されません。公開投稿だけがハッシュタグで検索できます。",
"compose_form.lock_disclaimer": "あなたのアカウントは{locked}になっていません。誰でもあなたをフォローすることができ、フォロワー限定の投稿を見ることができます。",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "管理者設定",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "ეს ტუტი გაეგზავნება მხოლოდ ნახსენებ მომხმარებლებს.",
"compose_form.hashtag_warning": "ეს ტუტი არ მოექცევა ჰეშტეგების ქვეს, რამეთუ ის არაა მითითებული. მხოლოდ ღია ტუტები მოიძებნება ჰეშტეგით.",
"compose_form.lock_disclaimer": "თქვენი ანგარიში არაა {locked}. ნებისმიერს შეიძლია გამოგყვეთ, რომ იხილოს თქვენი მიმდევრებზე გათვლილი პოსტები.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Тек аталған қолданушыларға.",
"compose_form.hashtag_warning": "Бұл пост іздеуде хэштегпен шықпайды, өйткені ол бәріне ашық емес. Тек ашық жазбаларды ғана хэштег арқылы іздеп табуға болады.",
"compose_form.lock_disclaimer": "Аккаунтыңыз {locked} емес. Кез келген адам жазылып, сізді оқи алады.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "이 툿은 멘션 된 유저들에게만 보여집니다.",
"compose_form.hashtag_warning": "이 툿은 어떤 해시태그로도 검색 되지 않습니다. 전체공개로 게시 된 툿만이 해시태그로 검색 될 수 있습니다.",
"compose_form.lock_disclaimer": "이 계정은 {locked}로 설정 되어 있지 않습니다. 누구나 이 계정을 팔로우 할 수 있으며, 팔로워 공개의 포스팅을 볼 수 있습니다.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -223,7 +223,7 @@
"column.mfa_disable_button": "Disable",
"column.mfa_setup": "Proceed to Setup",
"column.mutes": "Muted users",
"column.notifications": "Alerts",
"column.notifications": "Notifications",
"column.pins": "Pinned posts",
"column.preferences": "Preferences",
"column.profile_directory": "Profile directory",
@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "This post will only be sent to the mentioned users.",
"compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
"compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",
@ -937,7 +937,7 @@
"tabs_bar.header": "Account Info",
"tabs_bar.home": "Home",
"tabs_bar.news": "News",
"tabs_bar.notifications": "Alerts",
"tabs_bar.notifications": "Notifications",
"tabs_bar.post": "Post",
"tabs_bar.search": "Search",
"tabs_bar.theme_toggle_dark": "Switch to dark theme",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Šis ziņojums tiks nosūtīts tikai pieminētajiem lietotājiem.",
"compose_form.hashtag_warning": "Ziņojumu nebūs iespējams atrast zem haštagiem jo tas nav publisks. Tikai publiskos ziņojumus ir iespējams meklēt pēc tiem.",
"compose_form.lock_disclaimer": "Tavs konts nav {locked}. Ikviens var Tev sekot lai apskatītu tikai sekotājiem paredzētos ziņojumus.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",
@ -937,7 +937,7 @@
"tabs_bar.header": "Account Info",
"tabs_bar.home": "Home",
"tabs_bar.news": "News",
"tabs_bar.notifications": "Alerts",
"tabs_bar.notifications": "Notifications",
"tabs_bar.post": "Post",
"tabs_bar.search": "Search",
"tabs_bar.theme_toggle_dark": "Switch to dark theme",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "This post will only be sent to all the mentioned users.",
"compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
"compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",
@ -937,7 +937,7 @@
"tabs_bar.header": "Account Info",
"tabs_bar.home": "Дома",
"tabs_bar.news": "News",
"tabs_bar.notifications": "Alerts",
"tabs_bar.notifications": "Notifications",
"tabs_bar.post": "Post",
"tabs_bar.search": "Search",
"tabs_bar.theme_toggle_dark": "Switch to dark theme",

@ -223,7 +223,7 @@
"column.mfa_disable_button": "Disable",
"column.mfa_setup": "Proceed to Setup",
"column.mutes": "Muted users",
"column.notifications": "Alerts",
"column.notifications": "Notifications",
"column.pins": "Pinned posts",
"column.preferences": "Preferences",
"column.profile_directory": "Profile directory",
@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "This toot will only be sent to all the mentioned users.",
"compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
"compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",
@ -937,7 +937,7 @@
"tabs_bar.header": "Account Info",
"tabs_bar.home": "Home",
"tabs_bar.news": "News",
"tabs_bar.notifications": "Alerts",
"tabs_bar.notifications": "Notifications",
"tabs_bar.post": "Post",
"tabs_bar.search": "Search",
"tabs_bar.theme_toggle_dark": "Switch to dark theme",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Deze toot wordt alleen naar vermelde gebruikers verstuurd. Echter, de beheerders en moderatoren van jouw en de ontvangende server(s) kunnen dit bericht mogelijk wel bekijken.",
"compose_form.hashtag_warning": "Deze toot valt niet onder een hashtag te bekijken, omdat deze niet op openbare tijdlijnen wordt getoond. Alleen openbare toots kunnen via hashtags gevonden worden.",
"compose_form.lock_disclaimer": "Jouw account is niet {locked}. Iedereen kan jou volgen en kan de toots zien die je alleen aan jouw volgers hebt gericht.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Denne tuten vil kun verte synleg for nemnde brukarar.",
"compose_form.hashtag_warning": "Denne tuten vill ikkje bli lista under nokon knagg ettersom den ikkje er opplista. Berre offentlege tutar kan ble søkt på ved emneknagg.",
"compose_form.lock_disclaimer": "Din brukar er ikkje {locked}. Alle kan følje deg for å sjå føljar-modus poster.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",
@ -937,7 +937,7 @@
"tabs_bar.header": "Account Info",
"tabs_bar.home": "Heim",
"tabs_bar.news": "News",
"tabs_bar.notifications": "Alerts",
"tabs_bar.notifications": "Notifications",
"tabs_bar.post": "Post",
"tabs_bar.search": "Search",
"tabs_bar.theme_toggle_dark": "Switch to dark theme",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "This toot will only be visible to all the mentioned users.",
"compose_form.hashtag_warning": "Denne tuten blir ikke listet under noen emneknagger da den er ulistet. Kun offentlige tuter kan søktes etter med emneknagg.",
"compose_form.lock_disclaimer": "Din konto er ikke {locked}. Hvem som helst kan følge deg og se dine private poster.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Sols los mencionats poiràn veire aqueste tut.",
"compose_form.hashtag_warning": "Aqueste tut serà pas ligat a cap detiqueta estant ques pas listat. Òm pòt pas cercar que los tuts publics per etiqueta.",
"compose_form.lock_disclaimer": "Vòstre compte es pas {locked}. Tot lo monde pòt vos sègre e veire los estatuts reservats als seguidors.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -10,10 +10,12 @@
"account.block_domain": "Blokuj wszystko z {domain}",
"account.blocked": "Zablokowany(-a)",
"account.chat": "Napisz do @{name}",
"account.create_note": "Utwórz notatkę",
"account.deactivated": "Dezaktywowany(-a)",
"account.deactivated_description": "To konto zostało zdezaktywowane.",
"account.direct": "Wyślij wiadomość bezpośrednią do @{name}",
"account.domain_blocked": "Ukryto domenę",
"account.edit_note": "Edytuj notatkę",
"account.edit_profile": "Edytuj profil",
"account.endorse": "Polecaj na profilu",
"account.follow": "Śledź",
@ -27,7 +29,7 @@
"account.link_verified_on": "Własność tego odnośnika została potwierdzona {date}",
"account.locked_info": "To konto jest prywatne. Właściciel ręcznie wybiera kto może go śledzić.",
"account.login": "Zaloguj się",
"account.media": "Zawartość multimedialna",
"account.media": "Media",
"account.member_since": "Zarejestrowany(-a): {date}",
"account.mention": "Wspomnij",
"account.moved_to": "{name} przeniósł(-osła) się do:",
@ -52,7 +54,12 @@
"account.unfollow": "Przestań śledzić",
"account.unmute": "Cofnij wyciszenie @{name}",
"account.unsubscribe": "Przestań subskrybować wpisy @{name}",
"account.verified": "Zweryfikowane konto",
"account_gallery.none": "Brak zawartości multimedialnej do wyświetlenia.",
"account_note.hint": "Możesz pozostawić dla siebie notatkę o tym użytkowniku (tylko ty ją zobaczysz):",
"account_note.placeholder": "Nie wprowadzono opisu",
"account_note.save": "Zapisz",
"account_note.target": "Notatka o @{target}",
"account_search.placeholder": "Szukaj konta",
"admin.awaiting_approval.approved_message": "Przyjęto {acct}!",
"admin.awaiting_approval.empty_message": "Nikt nie oczekuje przyjęcia. Gdy zarejestruje się nowy użytkownik, możesz zatwierdzić go tutaj.",
@ -147,6 +154,7 @@
"bundle_modal_error.close": "Zamknij",
"bundle_modal_error.message": "Coś poszło nie tak podczas ładowania tego składnika.",
"bundle_modal_error.retry": "Spróbuj ponownie",
"card.back.label": "Wstecz",
"chat_box.actions.send": "Wyślij",
"chat_box.input.placeholder": "Wyślij wiadomość…",
"chat_panels.main_window.empty": "Nie znaleziono rozmów. Aby zacząć rozmowę, odwiedź profil użytkownika.",
@ -221,6 +229,7 @@
"column.mfa_confirm_button": "Potwierdź",
"column.mfa_disable_button": "Wyłącz",
"column.mfa_setup": "Przejdź do konfiguracji",
"column.migration": "Migracja konta",
"column.mutes": "Wyciszeni użytkownicy",
"column.notifications": "Powiadomienia",
"column.pins": "Przypięte wpisy",
@ -239,6 +248,7 @@
"column_forbidden.body": "Nie masz uprawnień, aby odwiedzić tę stronę.",
"column_forbidden.title": "Niedozwolone",
"column_header.show_settings": "Pokaż ustawienia",
"common.cancel": "Anuluj",
"community.column_settings.media_only": "Tylko zawartość multimedialna",
"community.column_settings.title": "Ustawienia lokalnej osi czasu",
"compose.character_counter.title": "Wykorzystano {chars} z {maxChars} znaków",
@ -349,6 +359,9 @@
"directory.recently_active": "Ostatnio aktywni",
"donate": "Przekaż darowiznę",
"donate_crypto": "Przekaż kryptowalutę",
"edit_email.header": "Zmień adres e-mail",
"edit_email.placeholder": "ja@example.com",
"edit_password.header": "Zmień hasło",
"edit_federation.followers_only": "Ukryj wpisy z wyjątkiem obserwowanych",
"edit_federation.force_nsfw": "Wymuś oznaczanie załączników jako wrażliwe",
"edit_federation.media_removal": "Wycinaj media",
@ -369,6 +382,8 @@
"edit_profile.fields.display_name_placeholder": "Nazwa",
"edit_profile.fields.header_label": "Nagłówek",
"edit_profile.fields.hide_network_label": "Ukryj swoją sieć",
"edit_profile.fields.location_label": "Lokalizacja",
"edit_profile.fields.location_placeholder": "Lokalizacja",
"edit_profile.fields.locked_label": "Zablokuj konto",
"edit_profile.fields.meta_fields.content_placeholder": "Treść",
"edit_profile.fields.meta_fields.label_placeholder": "Podpis",
@ -376,6 +391,9 @@
"edit_profile.fields.show_birthday_label": "Pokazuj moje urodziny",
"edit_profile.fields.stranger_notifications_label": "Blokuj powiadomienia od nieznajomych",
"edit_profile.fields.verified_display_name": "Zweryfikowani użytkownicy nie mogą zmieniać nazwy wyświetlanej",
"edit_profile.fields.website_label": "Strona internetowa",
"edit_profile.fields.website_placeholder": "Wyświetl link",
"edit_profile.header": "Edytuj profil",
"edit_profile.hints.accepts_email_list": "Otrzymuj wiadomości i nowości marketingowe.",
"edit_profile.hints.avatar": "PNG, GIF lub JPG. Zostanie zmniejszony do {size}",
"edit_profile.hints.bot": "To konto podejmuje głównie zautomatyzowane działania i może nie być nadzorowane",
@ -504,7 +522,10 @@
"header.about.label": "Informacje",
"header.back_to.label": "Wróć na {siteTitle}",
"header.home.label": "Strona główna",
"header.login.email.placeholder": "Adres e-mail",
"header.login.label": "Zaloguj się",
"header.login.password.label": "Hasło",
"header.register.label": "Rejestracja",
"home.column_settings.show_direct": "Pokazuj wiadomości bezpośrednie",
"home.column_settings.show_reblogs": "Pokazuj podbicia",
"home.column_settings.show_replies": "Pokazuj odpowiedzi",
@ -525,6 +546,8 @@
"import_data.success.blocks": "Pomyślnie zaimportowano zablokowane konta",
"import_data.success.followers": "Pomyślnie zaimportowano obserwowane konta",
"import_data.success.mutes": "Pomyślnie zaimportowano wyciszone konta",
"input.password.hide_password": "Ukryj hasło",
"input.password.show_password": "Pokazuj hasło",
"intervals.full.days": "{number, plural, one {# dzień} few {# dni} many {# dni} other {# dni}}",
"intervals.full.hours": "{number, plural, one {# godzina} few {# godziny} many {# godzin} other {# godzin}}",
"intervals.full.minutes": "{number, plural, one {# minuta} few {# minuty} many {# minut} other {# minut}}",
@ -573,6 +596,8 @@
"lists.search": "Szukaj wśród osób które śledzisz",
"lists.subheading": "Twoje listy",
"loading_indicator.label": "Ładowanie…",
"login_form.header": "Logowanie",
"login.fields.email_placeholder": "Adres e-mail",
"login.fields.instance_label": "Instancja",
"login.fields.instance_placeholder": "example.com",
"login.fields.otp_code_hint": "Wprowadź kod uwierzytelniania dwuetapowego wygenerowany przez aplikację mobilną lub jeden z kodów zapasowych",
@ -583,11 +608,14 @@
"login.otp_log_in": "Login OTP",
"login.otp_log_in.fail": "Nieprawidłowy kod, spróbuj ponownie.",
"login.reset_password_hint": "Problem z zalogowaniem?",
"login.sign_in": "Zaloguj się",
"media_gallery.toggle_visible": "Przełącz widoczność",
"media_panel.empty_message": "Nie znaleziono mediów.",
"media_panel.title": "Media",
"mfa.confirm.success_message": "Potwierdzono MFA",
"mfa.disabled": "Wyłączone",
"mfa.disable.success_message": "Wyłączono MFA",
"mfa.enabled": "Włączone",
"mfa.mfa_disable_enter_password": "Wprowadź obecne hasło, aby wyłączyć uwierzytelnianie dwuetapowe:",
"mfa.mfa_setup.code_hint": "Wprowadź kod z aplikacji do uwierzytelniania dwuskładnikowego.",
"mfa.mfa_setup.code_placeholder": "Kod",
@ -602,6 +630,14 @@
"mfa.setup_otp_title": "Wyłączono OTP",
"mfa.setup_recoverycodes": "Kody przywracania",
"mfa.setup_warning": "Zapisz te kody gdzieś w bezpiecznym miejscu jeżeli tego nie zrobisz, już ich nie zobaczysz. Jeśli utracisz dostęp do aplikacji 2FA i tych kodów, stracisz dostęp do swojego konta.",
"migration.fields.acct.label": "Adres nowego konta",
"migration.fields.acct.placeholder": "konto@domena",
"migration.fields.confirm_password.label": "Obecne hasło",
"migration.hint": "Ta opcja przeniesie Twoich obserwujących na nowe konto. Żadne inne dane nie zostaną przeniesione. Aby dokonać migracji, musisz najpierw {link} na swoim nowym koncie.",
"migration.hint.link": "utworzyć alias konta",
"migration.move_account.fail": "Przenoszenie konta nie powiodło się.",
"migration.move_account.success": "Pomyślnie przeniesiono konto.",
"migration.submit": "Przenieś obserwujących",
"missing_description_modal.cancel": "Anuluj",
"missing_description_modal.continue": "Opublikuj",
"missing_description_modal.text": "Nie podałeś(-aś) opisu dla wszystkich załączników. Czy na pewno chcesz kontynuować?",
@ -611,6 +647,7 @@
"morefollows.following_label": "…i {count} więcej {count, plural, one {obserwowany(-a)} few {obserwowanych} many {obserwowanych} other {obserwowanych}} na zdalnych stronach.",
"mute_modal.hide_notifications": "Chcesz ukryć powiadomienia od tego użytkownika?",
"navigation.chats": "Czaty",
"navigation.compose": "Utwórz wpis",
"navigation.dashboard": "Administracja",
"navigation.developers": "Programiści",
"navigation.direct_messages": "Wiadomości",
@ -619,6 +656,7 @@
"navigation.notifications": "Powiadomienia",
"navigation.search": "Szukaj",
"navigation_bar.account_aliases": "Aliasy kont",
"navigation_bar.account_migration": "Przenieś konto",
"navigation_bar.admin_settings": "Ustawienia administracyjne",
"navigation_bar.blocks": "Zablokowani użytkownicy",
"navigation_bar.compose": "Utwórz nowy wpis",
@ -650,6 +688,7 @@
"notification.follow": "{name} zaczął(-ęła) Cię śledzić",
"notification.follow_request": "{name} poprosił(a) Cię o możliwość śledzenia",
"notification.mention": "{name} wspomniał(a) o tobie",
"notification.mentioned": "{name} wspomniał(a) o tobie",
"notification.move": "{name} przeniósł(-osła) się na {targetName}",
"notification.pleroma:emoji_reaction": "{name} zareagował(a) na Twój wpis",
"notification.poll": "Głosowanie w którym brałeś(-aś) udział zakończyła się",
@ -689,6 +728,7 @@
"notifications.queue_label": "Naciśnij aby zobaczyć {count} {count, plural, one {nowe powiadomienie} few {nowe powiadomienia} many {nowych powiadomień} other {nowe powiadomienia}}",
"password_reset.confirmation": "Sprawdź swoją pocztę e-mail, aby potwierdzić.",
"password_reset.fields.username_placeholder": "Adres e-mail lub nazwa użytkownika",
"password_reset.header": "Resetowanie hasła",
"password_reset.reset": "Resetuj hasło",
"pinned_accounts.title": "Polecani przez {name}",
"pinned_statuses.none": "Brak przypięć do pokazania.",
@ -721,6 +761,7 @@
"preferences.fields.system_font_label": "Używaj domyślnej czcionki systemu",
"preferences.fields.underline_links_label": "Zawsze podkreślaj odnośniki we wpisach",
"preferences.fields.unfollow_modal_label": "Pokazuj prośbę o potwierdzenie przed cofnięciem obserwacji",
"preferences.hints.feed": "Na stronie głównej",
"preferences.hints.content_type_markdown": "Ostrzeżenie: eksperymentalne!",
"preferences.hints.demetricator": "Ogranicz uzależnienie od mediów społecznościowych ukrywając wszystkie liczby ze strony.",
"preferences.hints.halloween": "Uwaga: UPIORNE! Obsługuje ciemny i jasny motyw.",
@ -732,6 +773,7 @@
"preferences.options.privacy_followers_only": "Tylko dla obserwujących",
"preferences.options.privacy_public": "Publiczne",
"preferences.options.privacy_unlisted": "Niewypisane",
"pre_header.close": "Zamknij",
"privacy.change": "Dostosuj widoczność wpisów",
"privacy.direct.long": "Widoczny tylko dla wspomnianych",
"privacy.direct.short": "Bezpośrednio",
@ -844,6 +886,15 @@
"security.update_email.success": "Pomyślnie zaktualizowano adres e-mail.",
"security.update_password.fail": "Zmiana hasła nie powiodła się.",
"security.update_password.success": "Pomyślnie zmieniono hasło.",
"settings.change_email": "Zmień e-mail",
"settings.change_password": "Zmień hasło",
"settings.configure_mfa": "Konfiguruj uwierzytelnianie wieloskładnikowe",
"settings.delete_account": "Usuń konto",
"settings.edit_profile": "Edytuj profil",
"settings.preferences": "Preferencje",
"settings.profile": "Profil",
"settings.security": "Bezpieczeństwo",
"settings.settings": "Ustawienia",
"signup_panel.subtitle": "Zarejestruj się, aby przyłączyć się do dyskusji.",
"signup_panel.title": "Nowi na {site_title}?",
"snackbar.view": "Wyświetl",
@ -882,6 +933,10 @@
"soapbox_config.raw_json_label": "Zaawansowane: Edytuj surowe dane JSON",
"soapbox_config.save": "Zapisz",
"soapbox_config.saved": "Zapisano konfigurację Soapbox!",
"soapbox_config.single_user_mode_hint": "Strona główna będzie przekierowywała na profil podanego użytkownika.",
"soapbox_config.single_user_mode_label": "Tryb jednego użytkownika",
"soapbox_config.single_user_mode_profile_hint": "@nazwa",
"soapbox_config.single_user_mode_profile_label": "Nazwa głównego użytkownika",
"soapbox_config.verified_can_edit_name_label": "Pozwól zweryfikowanym użytkownikom na zmianę swojej nazwy wyświetlanej.",
"status.admin_account": "Otwórz interfejs moderacyjny dla @{name}",
"status.admin_status": "Otwórz ten wpis w interfejsie moderacyjnym",
@ -953,7 +1008,9 @@
"tabs_bar.news": "Nowości",
"tabs_bar.notifications": "Powiadomienia",
"tabs_bar.post": "Napisz coś",
"tabs_bar.profile": "Profil",
"tabs_bar.search": "Szukaj",
"tabs_bar.settings": "Ustawienia",
"tabs_bar.theme_toggle_dark": "Przełącz na ciemny motyw",
"tabs_bar.theme_toggle_light": "Przełącz na jasny motyw",
"time_remaining.days": "{number, plural, one {Pozostał # dzień} few {Pozostały # dni} many {Pozostało # dni} other {Pozostało # dni}}",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Este toot só será enviado aos usuários mencionados.",
"compose_form.hashtag_warning": "Esse toot não será listado em nenhuma hashtag por ser não listado. Somente toots públicos podem ser pesquisados por hashtag.",
"compose_form.lock_disclaimer": "A sua conta não está {locked}. Qualquer pessoa pode te seguir e visualizar postagens direcionadas a apenas seguidores.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Esta publicação será enviada apenas para os utilizadores mencionados.",
"compose_form.hashtag_warning": "Esta publicação não será listada em nenhuma hashtag por ser não listado. Apenas publicações públicas podem ser pesquisados por hashtags.",
"compose_form.lock_disclaimer": "A tua conta não está {locked}. Qualquer pessoa pode seguir-te e ver as publicações direcionadas apenas a seguidores.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Painel de Admin.",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Această postare va fi trimisă doar utilizatorilor menționați.",
"compose_form.hashtag_warning": "Această postare nu va fi listată sub nici un hastag. Doar postările publice pot fi găsite dupa un hastag.",
"compose_form.lock_disclaimer": "Contul tău nu este {locked}. Oricine te poate urmări fără aprobarea ta și vedea toate postările tale.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Этот статус будет виден только упомянутым пользователям.",
"compose_form.hashtag_warning": "Этот пост не будет показывается в поиске по хэштегу, т.к. он непубличный. Только публичные посты можно найти в поиске по хэштегу.",
"compose_form.lock_disclaimer": "Ваш аккаунт не {locked}. Любой человек может подписаться на Вас и просматривать посты для подписчиков.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Tento príspevok bude videný výhradne iba spomenutými užívateľmi. Ber ale na vedomie že správci tvojej a všetkých iných zahrnutých instancií majú možnosť skontrolovať túto správu.",
"compose_form.hashtag_warning": "Tento toot nebude zobrazený pod žiadným haštagom lebo nieje listovaný. Iba verejné tooty môžu byť nájdené podľa haštagu.",
"compose_form.lock_disclaimer": "Tvoj účet nie je {locked}. Ktokoľvek ťa môže nasledovať a vidieť tvoje správy pre sledujúcich.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Ta tut bo viden le vsem omenjenim uporabnikom.",
"compose_form.hashtag_warning": "Ta tut ne bo naveden pod nobenim ključnikom, ker ni javen. Samo javne tute lahko iščete s ključniki.",
"compose_form.lock_disclaimer": "Vaš račun ni {locked}. Vsakdo vam lahko sledi in si ogleda objave, ki so namenjene samo sledilcem.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Ky mesazh do tu dërgohet përdoruesve të përmendur.",
"compose_form.hashtag_warning": "Ky mesazh sdo të paraqitet nën ndonjë hashtag, ngaqë si është caktuar ndonjë. Vetëm mesazhet publike mund të kërkohen sipas hashtagësh.",
"compose_form.lock_disclaimer": "Llogaria juaj sështë {locked}. Mund ta ndjekë cilido, për të parë postimet tuaja vetëm për ndjekësit.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "This toot will only be visible to all the mentioned users.",
"compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
"compose_form.lock_disclaimer": "Vaš nalog nije {locked}. Svako može da Vas zaprati i da vidi objave namenjene samo Vašim pratiocima.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Ова труба ће бити послата споменутим корисницима.",
"compose_form.hashtag_warning": "Ова труба неће бити излистана под било којом тарабом јер је сакривена. Само јавне трубе могу бити претражене тарабом.",
"compose_form.lock_disclaimer": "Ваш налог није {locked}. Свако може да Вас запрати и да види објаве намењене само Вашим пратиоцима.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Denna post kommer endast att skickas nämnda nämnda användare.",
"compose_form.hashtag_warning": "Denna toot kommer inte att listas under någon hashtag eftersom den är onoterad. Endast offentliga toots kan sökas med hashtag.",
"compose_form.lock_disclaimer": "Ditt konto är inte {locked}. Vem som helst kan följa dig och även se dina inlägg som bara är för följare.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -223,7 +223,7 @@
"column.mfa_disable_button": "Disable",
"column.mfa_setup": "Proceed to Setup",
"column.mutes": "முடக்கப்பட்ட பயனர்கள்",
"column.notifications": "Alerts",
"column.notifications": "Notifications",
"column.pins": "Pinned posts",
"column.preferences": "Preferences",
"column.profile_directory": "Profile directory",
@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "This toot will only be sent to all the mentioned users.",
"compose_form.hashtag_warning": "இந்த toot பட்டியலிடப்படாதது போல எந்த ஹேஸ்டேக்கின் கீழ் பட்டியலிடப்படாது. ஹேஸ்டேக் மூலம் பொது டோட்டல்கள் மட்டுமே தேட முடியும்.",
"compose_form.lock_disclaimer": "உங்கள் கணக்கு அல்ல {locked}. உங்களுடைய பின்தொடர்பவர் மட்டும் இடுகைகளை யாராவது காணலாம்.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",
@ -937,7 +937,7 @@
"tabs_bar.header": "Account Info",
"tabs_bar.home": "Home",
"tabs_bar.news": "News",
"tabs_bar.notifications": "Alerts",
"tabs_bar.notifications": "Notifications",
"tabs_bar.post": "Post",
"tabs_bar.search": "தேடு",
"tabs_bar.theme_toggle_dark": "Switch to dark theme",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "ఈ టూట్ పేర్కొన్న వినియోగదారులకు మాత్రమే పంపబడుతుంది.",
"compose_form.hashtag_warning": "ఈ టూట్ అన్లిస్టెడ్ కాబట్టి ఏ హాష్ ట్యాగ్ క్రిందకూ రాదు. పబ్లిక్ టూట్ లను మాత్రమే హాష్ ట్యాగ్ ద్వారా శోధించవచ్చు.",
"compose_form.lock_disclaimer": "మీ ఖాతా {locked} చేయబడలేదు. ఎవరైనా మిమ్మల్ని అనుసరించి మీ అనుచరులకు-మాత్రమే పోస్ట్లను వీక్షించవచ్చు.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "จะส่งโพสต์นี้ไปยังผู้ใช้ที่กล่าวถึงเท่านั้น",
"compose_form.hashtag_warning": "จะไม่แสดงรายการโพสต์นี้ภายใต้แฮชแท็กใด ๆ เนื่องจากไม่อยู่ในรายการ เฉพาะโพสต์สาธารณะเท่านั้นที่สามารถค้นหาโดยแฮชแท็ก",
"compose_form.lock_disclaimer": "บัญชีของคุณไม่ได้ {locked} ใครก็ตามสามารถติดตามคุณเพื่อดูโพสต์สำหรับผู้ติดตามเท่านั้นของคุณ",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "Bu gönderi sadece belirtilen kullanıcılara gönderilecektir.",
"compose_form.hashtag_warning": "Bu paylaşım liste dışı olduğu için hiç bir hashtag'de yer almayacak. Sadece herkese açık gönderiler hashtaglerde bulunabilir.",
"compose_form.lock_disclaimer": "Hesabınız {locked} değil. Sadece takipçilerle paylaştığınız gönderileri görebilmek için sizi herhangi bir kullanıcı takip edebilir.",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "這文章只有被提及的用戶才可以看到。",
"compose_form.hashtag_warning": "這文章因為不是公開,所以不會被標籤搜索。只有公開的文章才會被標籤搜索。",
"compose_form.lock_disclaimer": "你的用戶狀態為「{locked}」,任何人都能立即關注你,然後看到「只有關注者能看」的文章。",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -244,7 +244,7 @@
"community.column_settings.title": "Local timeline settings",
"compose.character_counter.title": "Used {chars} out of {maxChars} characters",
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
"compose.submit_success": "Your TRUTH was sent!",
"compose.submit_success": "Your post was sent",
"compose_form.direct_message_warning": "這條嘟文只有被提及的使用者才看得到。",
"compose_form.hashtag_warning": "由於這則嘟文被設定成「不公開」,所以它將不會被列在任何主題標籤下。只有公開的嘟文才能藉主題標籤找到。",
"compose_form.lock_disclaimer": "您的帳戶尚未{locked}。任何人都能關注您並看到您設定成只有關注者能看的嘟文。",
@ -607,7 +607,7 @@
"navigation.direct_messages": "Messages",
"navigation.home": "Home",
"navigation.invites": "Invites",
"navigation.notifications": "Alerts",
"navigation.notifications": "Notifications",
"navigation.search": "Search",
"navigation_bar.account_aliases": "Account aliases",
"navigation_bar.admin_settings": "Admin settings",

@ -195,4 +195,10 @@ describe('normalizeStatus()', () => {
expect(result.card.type).toEqual('link');
expect(result.card.provider_url).toEqual('https://soapbox.pub');
});
it('preserves Truth Social external_video_id', () => {
const status = require('soapbox/__fixtures__/truthsocial-status-with-external-video.json');
const result = normalizeStatus(status);
expect(result.media_attachments.get(0).external_video_id).toBe('vwfnq9');
});
});

@ -15,6 +15,7 @@ import { mergeDefined } from 'soapbox/utils/normalizers';
export const AttachmentRecord = ImmutableRecord({
blurhash: undefined,
description: '',
external_video_id: null as string | null, // TruthSocial
id: '',
meta: ImmutableMap(),
pleroma: ImmutableMap(),

@ -112,6 +112,7 @@ export const SoapboxConfigRecord = ImmutableRecord({
authenticatedProfile: true,
singleUserMode: false,
singleUserModeProfile: '',
linkFooterMessage: '',
}, 'SoapboxConfig');
type SoapboxConfigMap = ImmutableMap<string, any>;
@ -150,12 +151,12 @@ const normalizeColors = (soapboxConfig: SoapboxConfigMap): SoapboxConfigMap => {
const maybeAddMissingColors = (soapboxConfig: SoapboxConfigMap): SoapboxConfigMap => {
const colors = soapboxConfig.get('colors');
const missing = {
'bg-shape-1': colors.getIn(['accent', '50']),
const missing = ImmutableMap({
'bg-shape-1': colors.getIn(['accent', '500']),
'bg-shape-2': colors.getIn(['primary', '500']),
};
});
return soapboxConfig.set('colors', colors.mergeDeep(missing));
return soapboxConfig.set('colors', missing.mergeDeep(colors));
};
export const normalizeSoapboxConfig = (soapboxConfig: Record<string, any>) => {

@ -1,21 +0,0 @@
import camelCase from 'lodash/camelCase';
import startCase from 'lodash/startCase';
const toSentence = (arr) => arr
.reduce(
(prev, curr, i) => prev + curr + (i === arr.length - 2 ? ' and ' : ', '),
'',
)
.slice(0, -2);
const buildErrorMessage = (errors) => {
const individualErrors = Object.keys(errors).map(
(attribute) => `${startCase(camelCase(attribute))} ${toSentence(
errors[attribute],
)}`,
);
return toSentence(individualErrors);
};
export { buildErrorMessage };

@ -0,0 +1,203 @@
import camelCase from 'lodash/camelCase';
import startCase from 'lodash/startCase';
const toSentence = (arr: string[]) => arr
.reduce(
(prev, curr, i) => prev + curr + (i === arr.length - 2 ? ' and ' : ', '),
'',
)
.slice(0, -2);
type Errors = {
[key: string]: string[]
}
const buildErrorMessage = (errors: Errors) => {
const individualErrors = Object.keys(errors).map(
(attribute) => `${startCase(camelCase(attribute))} ${toSentence(
errors[attribute],
)}`,
);
return toSentence(individualErrors);
};
const httpErrorMessages: { code: number, name: string, description: string }[] = [
{
code: 100,
name: 'Continue',
description: 'The server has received the request headers, and the client should proceed to send the request body',
},
{
code: 101,
name: 'Switching Protocols',
description: 'The requester has asked the server to switch protocols',
},
{
code: 103,
name: 'Checkpoint',
description: 'Used in the resumable requests proposal to resume aborted PUT or POST requests',
},
{
code: 200,
name: 'OK',
description: 'The request is OK (this is the standard response for successful HTTP requests)',
},
{
code: 201,
name: 'Created',
description: 'The request has been fulfilled',
},
{
code: 202,
name: 'Accepted',
description: 'The request has been accepted for processing',
},
{
code: 203,
name: 'Non-Authoritative Information',
description: 'The request has been successfully processed',
},
{
code: 204,
name: 'No Content',
description: 'The request has been successfully processed',
},
{
code: 205,
name: 'Reset Content',
description: 'The request has been successfully processed',
},
{
code: 206,
name: 'Partial Content',
description: 'The server is delivering only part of the resource due to a range header sent by the client',
},
{
code: 400,
name: 'Bad Request',
description: 'The request cannot be fulfilled due to bad syntax',
},
{
code: 401,
name: 'Unauthorized',
description: 'The request was a legal request',
},
{
code: 402,
name: 'Payment Required',
description: 'Reserved for future use',
},
{
code: 403,
name: 'Forbidden',
description: 'The request was a legal request',
},
{
code: 404,
name: 'Not Found',
description: 'The requested page could not be found but may be available again in the future',
},
{
code: 405,
name: 'Method Not Allowed',
description: 'A request was made of a page using a request method not supported by that page',
},
{
code: 406,
name: 'Not Acceptable',
description: 'The server can only generate a response that is not accepted by the client',
},
{
code: 407,
name: 'Proxy Authentication Required',
description: 'The client must first authenticate itself with the proxy',
},
{
code: 408,
name: 'Request',
description: ' Timeout\tThe server timed out waiting for the request',
},
{
code: 409,
name: 'Conflict',
description: 'The request could not be completed because of a conflict in the request',
},
{
code: 410,
name: 'Gone',
description: 'The requested page is no longer available',
},
{
code: 411,
name: 'Length Required',
description: 'The "Content-Length" is not defined. The server will not accept the request without it',
},
{
code: 412,
name: 'Precondition',
description: ' Failed. The precondition given in the request evaluated to false by the server',
},
{
code: 413,
name: 'Request Entity Too Large',
description: 'The server will not accept the request',
},
{
code: 414,
name: 'Request-URI Too Long',
description: 'The server will not accept the request',
},
{
code: 415,
name: 'Unsupported Media Type',
description: 'The server will not accept the request',
},
{
code: 416,
name: 'Requested Range Not Satisfiable',
description: 'The client has asked for a portion of the file',
},
{
code: 417,
name: 'Expectation Failed',
description: 'The server cannot meet the requirements of the Expect request-header field',
},
{
code: 500,
name: 'Internal Server Error',
description: 'An unexpected error occurred',
},
{
code: 501,
name: 'Not Implemented',
description: 'The server either does not recognize the request method',
},
{
code: 502,
name: 'Bad Gateway',
description: 'The server was acting as a gateway or proxy and received an invalid response from the upstream server',
},
{
code: 503,
name: 'Service Unavailable',
description: 'The server is currently unavailable (overloaded or down)',
},
{
code: 504,
name: 'Gateway Timeout',
description: 'The server was acting as a gateway or proxy and did not receive a timely response from the upstream server',
},
{
code: 505,
name: 'HTTP Version Not Supported',
description: 'The server does not support the HTTP protocol version used in the request',
},
{
code: 511,
name: 'Network Authentication Required',
description: 'The client needs to auth',
},
];
export { buildErrorMessage, httpErrorMessages };

@ -21,7 +21,7 @@ export const MITRA = 'Mitra';
export const TRUTHSOCIAL = 'TruthSocial';
const getInstanceFeatures = (instance: Instance) => {
const v = parseVersion(instance.get('version'));
const v = parseVersion(instance.version);
const features = instance.pleroma.getIn(['metadata', 'features'], ImmutableList()) as ImmutableList<string>;
const federation = instance.pleroma.getIn(['metadata', 'federation'], ImmutableMap()) as ImmutableMap<string, any>;
@ -48,14 +48,19 @@ const getInstanceFeatures = (instance: Instance) => {
]),
suggestions: any([
v.software === MASTODON && gte(v.compatVersion, '2.4.3'),
v.software === TRUTHSOCIAL,
features.includes('v2_suggestions'),
]),
suggestionsV2: any([
v.software === MASTODON && gte(v.compatVersion, '3.4.0'),
v.software === TRUTHSOCIAL,
features.includes('v2_suggestions'),
]),
blockersVisible: features.includes('blockers_visible'),
trends: v.software === MASTODON && gte(v.compatVersion, '3.0.0'),
trends: any([
v.software === MASTODON && gte(v.compatVersion, '3.0.0'),
v.software === TRUTHSOCIAL,
]),
mediaV2: any([
v.software === MASTODON && gte(v.compatVersion, '3.1.3'),
// Even though Pleroma supports these endpoints, it has disadvantages
@ -128,7 +133,7 @@ const getInstanceFeatures = (instance: Instance) => {
};
};
type Features = ReturnType<typeof getInstanceFeatures>;
export type Features = ReturnType<typeof getInstanceFeatures>;
export const getFeatures = createSelector([
(instance: Instance) => instance,

@ -1,10 +0,0 @@
export const truncateFilename = (url, maxLength) => {
const filename = url.split('/').pop();
if (filename.length <= maxLength) return filename;
return [
filename.substr(0, maxLength/2),
filename.substr(filename.length - maxLength/2),
].join('…');
};

@ -0,0 +1,28 @@
const truncateFilename = (url: string, maxLength: number) => {
const filename = url.split('/').pop();
if (!filename) {
return filename;
}
if (filename.length <= maxLength) return filename;
return [
filename.substr(0, maxLength/2),
filename.substr(filename.length - maxLength/2),
].join('…');
};
const formatBytes = (bytes: number, decimals: number = 2) => {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
};
export { formatBytes, truncateFilename };

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save