Merge remote-tracking branch 'origin/develop' into improve-chat-media
This commit is contained in:
commit
bab64a98af
41 changed files with 610 additions and 323 deletions
|
@ -5,4 +5,4 @@
|
|||
/tmp/**
|
||||
/coverage/**
|
||||
/custom/**
|
||||
!.eslintrc.js
|
||||
!.eslintrc.cjs
|
||||
|
|
|
@ -43,7 +43,7 @@ module.exports = {
|
|||
react: {
|
||||
version: 'detect',
|
||||
},
|
||||
'import/extensions': ['.js', '.jsx', '.ts', '.tsx'],
|
||||
'import/extensions': ['.js', '.jsx', '.cjs', '.mjs', '.ts', '.tsx'],
|
||||
'import/ignore': [
|
||||
'node_modules',
|
||||
'\\.(css|scss|json)$',
|
|
@ -48,10 +48,12 @@ lint-js:
|
|||
changes:
|
||||
- "**/*.js"
|
||||
- "**/*.jsx"
|
||||
- "**/*.cjs"
|
||||
- "**/*.mjs"
|
||||
- "**/*.ts"
|
||||
- "**/*.tsx"
|
||||
- ".eslintignore"
|
||||
- ".eslintrc.js"
|
||||
- ".eslintrc.cjs"
|
||||
|
||||
lint-sass:
|
||||
stage: test
|
||||
|
@ -72,7 +74,7 @@ jest:
|
|||
- "app/soapbox/**/*"
|
||||
- "webpack/**/*"
|
||||
- "custom/**/*"
|
||||
- "jest.config.js"
|
||||
- "jest.config.cjs"
|
||||
- "package.json"
|
||||
- "yarn.lock"
|
||||
- ".gitlab-ci.yml"
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
{
|
||||
"*.js": "eslint --cache",
|
||||
"*.cjs": "eslint --cache",
|
||||
"*.mjs": "eslint --cache",
|
||||
"*.ts": "eslint --cache",
|
||||
"*.tsx": "eslint --cache",
|
||||
"app/styles/**/*.scss": "stylelint"
|
||||
}
|
||||
|
|
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"css.validate": false,
|
||||
"editor.insertSpaces": true,
|
||||
"editor.tabSize": 2,
|
||||
"files.associations": {
|
||||
|
@ -15,5 +16,6 @@
|
|||
"fileMatch": ["renovate.json"],
|
||||
"url": "https://docs.renovatebot.com/renovate-schema.json"
|
||||
}
|
||||
]
|
||||
],
|
||||
"scss.validate": false
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
### Added
|
||||
- Admin: redirect the homepage to any URL.
|
||||
- Compatibility: added compatibility with Friendica.
|
||||
- Posts: bot badge on statuses from bot accounts.
|
||||
|
||||
### Changed
|
||||
- Chats: improved display of media attachments.
|
||||
|
@ -15,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
### Fixed
|
||||
- Chats: media attachments rendering at the wrong size and/or causing the chat to scroll on load.
|
||||
- Chats: don't display "copy" button for messages without text.
|
||||
- Posts: don't have to click the play button twice for embedded videos.
|
||||
- index.html: remove `referrer` meta tag so it doesn't conflict with backend's `Referrer-Policy` header.
|
||||
|
||||
### Removed
|
||||
- Admin: single user mode. Now the homepage can be redirected to any URL.
|
||||
|
@ -34,6 +38,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Status Info: moved context (repost, pinned) to improve UX.
|
||||
- Posts: remove file icon from empty link previews.
|
||||
- Settings: moved "Import data" under settings.
|
||||
- Composer: add more descriptive discard confirmation message.
|
||||
|
||||
### Fixed
|
||||
- Layout: use accent color for "floating action button" (mobile compose button).
|
||||
|
@ -45,12 +50,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Posts: fix monospace font in Markdown code blocks.
|
||||
- Modals: fix action buttons overflow
|
||||
- Editing: don't insert edited posts to the top of the feed.
|
||||
- Editing: don't display edited posts as pending posts.
|
||||
- Modals: close modal when navigating to a different page.
|
||||
- Modals: fix "View context" button in media modal.
|
||||
- Posts: let unauthenticated users to translate posts if allowed by backend.
|
||||
- Chats: fix jumpy scrollbar.
|
||||
- Composer: fix alignment of icon in submit button.
|
||||
- Login: add a border around QR codes.
|
||||
- Composer: don't display action button in reply indicator.
|
||||
|
||||
## [3.0.0] - 2022-12-25
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover, user-scalable=no">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="referrer" content="same-origin" />
|
||||
<link href="/manifest.json" rel="manifest">
|
||||
<!--server-generated-meta-->
|
||||
<%= snippets %>
|
||||
|
|
|
@ -50,6 +50,7 @@ const customApp = custom('app');
|
|||
|
||||
export const messages = defineMessages({
|
||||
loggedOut: { id: 'auth.logged_out', defaultMessage: 'Logged out.' },
|
||||
awaitingApproval: { id: 'auth.awaiting_approval', defaultMessage: 'Your account is awaiting approval' },
|
||||
invalidCredentials: { id: 'auth.invalid_credentials', defaultMessage: 'Wrong username or password' },
|
||||
});
|
||||
|
||||
|
@ -187,6 +188,8 @@ export const logIn = (username: string, password: string) =>
|
|||
if ((error.response?.data as any)?.error === 'mfa_required') {
|
||||
// If MFA is required, throw the error and handle it in the component.
|
||||
throw error;
|
||||
} else if ((error.response?.data as any)?.identifier === 'awaiting_approval') {
|
||||
toast.error(messages.awaitingApproval);
|
||||
} else {
|
||||
// Return "wrong password" message.
|
||||
toast.error(messages.invalidCredentials);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { Link, useHistory } from 'react-router-dom';
|
||||
|
||||
import HoverRefWrapper from 'soapbox/components/hover-ref-wrapper';
|
||||
|
@ -8,6 +9,7 @@ import { useAppSelector, useOnScreen } from 'soapbox/hooks';
|
|||
import { getAcct } from 'soapbox/utils/accounts';
|
||||
import { displayFqn } from 'soapbox/utils/state';
|
||||
|
||||
import Badge from './badge';
|
||||
import RelativeTimestamp from './relative-timestamp';
|
||||
import { Avatar, Emoji, HStack, Icon, IconButton, Stack, Text } from './ui';
|
||||
|
||||
|
@ -18,6 +20,10 @@ interface IInstanceFavicon {
|
|||
disabled?: boolean,
|
||||
}
|
||||
|
||||
const messages = defineMessages({
|
||||
bot: { id: 'account.badges.bot', defaultMessage: 'Bot' },
|
||||
});
|
||||
|
||||
const InstanceFavicon: React.FC<IInstanceFavicon> = ({ account, disabled }) => {
|
||||
const history = useHistory();
|
||||
|
||||
|
@ -151,6 +157,8 @@ const Account = ({
|
|||
return null;
|
||||
};
|
||||
|
||||
const intl = useIntl();
|
||||
|
||||
React.useEffect(() => {
|
||||
const style: React.CSSProperties = {};
|
||||
const actionWidth = actionRef.current?.clientWidth || 0;
|
||||
|
@ -223,6 +231,8 @@ const Account = ({
|
|||
/>
|
||||
|
||||
{account.verified && <VerificationBadge />}
|
||||
|
||||
{account.bot && <Badge slug='bot' title={intl.formatMessage(messages.bot)} />}
|
||||
</HStack>
|
||||
</LinkEl>
|
||||
</ProfilePopper>
|
||||
|
|
|
@ -16,7 +16,7 @@ import type { ReducerCompose } from 'soapbox/reducers/compose';
|
|||
import type { ReducerRecord as ReducerComposeEvent } from 'soapbox/reducers/compose-event';
|
||||
|
||||
const messages = defineMessages({
|
||||
confirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
|
||||
confirm: { id: 'confirmations.cancel.confirm', defaultMessage: 'Discard' },
|
||||
cancelEditing: { id: 'confirmations.cancel_editing.confirm', defaultMessage: 'Cancel editing' },
|
||||
});
|
||||
|
||||
|
@ -80,10 +80,10 @@ const ModalRoot: React.FC<IModalRoot> = ({ children, onCancel, onClose, type })
|
|||
icon: require('@tabler/icons/trash.svg'),
|
||||
heading: isEditing
|
||||
? <FormattedMessage id='confirmations.cancel_editing.heading' defaultMessage='Cancel post editing' />
|
||||
: <FormattedMessage id='confirmations.delete.heading' defaultMessage='Delete post' />,
|
||||
: <FormattedMessage id='confirmations.cancel.heading' defaultMessage='Discard post' />,
|
||||
message: isEditing
|
||||
? <FormattedMessage id='confirmations.cancel_editing.message' defaultMessage='Are you sure you want to cancel editing this post? All changes will be lost.' />
|
||||
: <FormattedMessage id='confirmations.delete.message' defaultMessage='Are you sure you want to delete this post?' />,
|
||||
: <FormattedMessage id='confirmations.cancel.message' defaultMessage='Are you sure you want to cancel creating this post?' />,
|
||||
confirm: intl.formatMessage(messages.confirm),
|
||||
onConfirm: () => {
|
||||
dispatch(closeModal('COMPOSE'));
|
||||
|
|
|
@ -7,6 +7,7 @@ import { Toaster } from 'react-hot-toast';
|
|||
import { IntlProvider } from 'react-intl';
|
||||
import { Provider } from 'react-redux';
|
||||
import { BrowserRouter, Switch, Redirect, Route } from 'react-router-dom';
|
||||
import { CompatRouter } from 'react-router-dom-v5-compat';
|
||||
// @ts-ignore: it doesn't have types
|
||||
import { ScrollContext } from 'react-router-scroll-4';
|
||||
|
||||
|
@ -173,26 +174,28 @@ const SoapboxMount = () => {
|
|||
return (
|
||||
<ErrorBoundary>
|
||||
<BrowserRouter basename={BuildConfig.FE_SUBDIRECTORY}>
|
||||
<ScrollContext shouldUpdateScroll={shouldUpdateScroll}>
|
||||
<Switch>
|
||||
<Route
|
||||
path='/embed/:statusId'
|
||||
render={(props) => <EmbeddedStatus params={props.match.params} />}
|
||||
/>
|
||||
<Redirect from='/@:username/:statusId/embed' to='/embed/:statusId' />
|
||||
<CompatRouter>
|
||||
<ScrollContext shouldUpdateScroll={shouldUpdateScroll}>
|
||||
<Switch>
|
||||
<Route
|
||||
path='/embed/:statusId'
|
||||
render={(props) => <EmbeddedStatus params={props.match.params} />}
|
||||
/>
|
||||
<Redirect from='/@:username/:statusId/embed' to='/embed/:statusId' />
|
||||
|
||||
<Route>
|
||||
{renderBody()}
|
||||
<Route>
|
||||
{renderBody()}
|
||||
|
||||
<BundleContainer fetchComponent={ModalContainer}>
|
||||
{Component => <Component />}
|
||||
</BundleContainer>
|
||||
<BundleContainer fetchComponent={ModalContainer}>
|
||||
{Component => <Component />}
|
||||
</BundleContainer>
|
||||
|
||||
<GdprBanner />
|
||||
<Toaster position='top-right' containerClassName='top-10' containerStyle={{ top: 75 }} />
|
||||
</Route>
|
||||
</Switch>
|
||||
</ScrollContext>
|
||||
<GdprBanner />
|
||||
<Toaster position='top-right' containerClassName='top-10' containerStyle={{ top: 75 }} />
|
||||
</Route>
|
||||
</Switch>
|
||||
</ScrollContext>
|
||||
</CompatRouter>
|
||||
</BrowserRouter>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
|
|
|
@ -40,6 +40,7 @@ const ReplyIndicator: React.FC<IReplyIndicator> = ({ status, hideActions, onCanc
|
|||
timestamp={status.created_at}
|
||||
showProfileHoverCard={false}
|
||||
withLinkToProfile={false}
|
||||
hideActions={hideActions}
|
||||
/>
|
||||
|
||||
<Text
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { List as ImmutableList } from 'immutable';
|
||||
import React, { useState, useEffect, useMemo } from 'react';
|
||||
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
||||
|
||||
|
@ -125,7 +126,7 @@ const accountToCredentials = (account: Account): AccountCredentials => {
|
|||
display_name: account.display_name,
|
||||
note: account.source.get('note'),
|
||||
locked: account.locked,
|
||||
fields_attributes: [...account.source.get<Iterable<AccountCredentialsField>>('fields', []).toJS()],
|
||||
fields_attributes: [...account.source.get<Iterable<AccountCredentialsField>>('fields', ImmutableList()).toJS()],
|
||||
stranger_notifications: account.getIn(['pleroma', 'notification_settings', 'block_from_strangers']) === true,
|
||||
accepts_email_list: account.getIn(['pleroma', 'accepts_email_list']) === true,
|
||||
hide_followers: hideNetwork,
|
||||
|
|
|
@ -5,7 +5,6 @@ import React, { useState, useEffect } from 'react';
|
|||
import Blurhash from 'soapbox/components/blurhash';
|
||||
import Icon from 'soapbox/components/icon';
|
||||
import { HStack, Stack, Text } from 'soapbox/components/ui';
|
||||
import { useSettings } from 'soapbox/hooks';
|
||||
import { normalizeAttachment } from 'soapbox/normalizers';
|
||||
import { addAutoPlay } from 'soapbox/utils/media';
|
||||
|
||||
|
@ -42,9 +41,6 @@ const Card: React.FC<ICard> = ({
|
|||
onOpenMedia,
|
||||
horizontal,
|
||||
}): JSX.Element => {
|
||||
const settings = useSettings();
|
||||
const shouldAutoPlayVideo = settings.get('autoPlayVideo');
|
||||
|
||||
const [width, setWidth] = useState(defaultWidth);
|
||||
const [embedded, setEmbedded] = useState(false);
|
||||
|
||||
|
@ -92,7 +88,7 @@ const Card: React.FC<ICard> = ({
|
|||
};
|
||||
|
||||
const renderVideo = () => {
|
||||
const content = { __html: shouldAutoPlayVideo ? addAutoPlay(card.html) : card.html };
|
||||
const content = { __html: addAutoPlay(card.html) };
|
||||
const ratio = getRatio(card);
|
||||
const height = width / ratio;
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import ComposeForm from '../../../compose/components/compose-form';
|
|||
|
||||
const messages = defineMessages({
|
||||
close: { id: 'lightbox.close', defaultMessage: 'Close' },
|
||||
confirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
|
||||
confirm: { id: 'confirmations.cancel.confirm', defaultMessage: 'Discard' },
|
||||
cancelEditing: { id: 'confirmations.cancel_editing.confirm', defaultMessage: 'Cancel editing' },
|
||||
});
|
||||
|
||||
|
@ -33,10 +33,10 @@ const ComposeModal: React.FC<IComposeModal> = ({ onClose }) => {
|
|||
icon: require('@tabler/icons/trash.svg'),
|
||||
heading: statusId
|
||||
? <FormattedMessage id='confirmations.cancel_editing.heading' defaultMessage='Cancel post editing' />
|
||||
: <FormattedMessage id='confirmations.delete.heading' defaultMessage='Delete post' />,
|
||||
: <FormattedMessage id='confirmations.cancel.heading' defaultMessage='Discard post' />,
|
||||
message: statusId
|
||||
? <FormattedMessage id='confirmations.cancel_editing.message' defaultMessage='Are you sure you want to cancel editing this post? All changes will be lost.' />
|
||||
: <FormattedMessage id='confirmations.delete.message' defaultMessage='Are you sure you want to delete this post?' />,
|
||||
: <FormattedMessage id='confirmations.cancel.message' defaultMessage='Are you sure you want to cancel creating this post?' />,
|
||||
confirm: intl.formatMessage(statusId ? messages.cancelEditing : messages.confirm),
|
||||
onConfirm: () => {
|
||||
dispatch(closeModal('COMPOSE'));
|
||||
|
|
|
@ -169,6 +169,7 @@
|
|||
"app_create.scopes_placeholder": "e.g. 'read write follow'",
|
||||
"app_create.submit": "Create app",
|
||||
"app_create.website_label": "Website",
|
||||
"auth.awaiting_approval": "Your account is awaiting approval",
|
||||
"auth.invalid_credentials": "Wrong username or password",
|
||||
"auth.logged_out": "Logged out.",
|
||||
"auth_layout.register": "Create an account",
|
||||
|
@ -430,6 +431,9 @@
|
|||
"confirmations.block.confirm": "Block",
|
||||
"confirmations.block.heading": "Block @{name}",
|
||||
"confirmations.block.message": "Are you sure you want to block {name}?",
|
||||
"confirmations.cancel.confirm": "Discard",
|
||||
"confirmations.cancel.heading": "Discard post",
|
||||
"confirmations.cancel.message": "Are you sure you want to cancel creating this post?",
|
||||
"confirmations.cancel_editing.confirm": "Cancel editing",
|
||||
"confirmations.cancel_editing.heading": "Cancel post editing",
|
||||
"confirmations.cancel_editing.message": "Are you sure you want to cancel editing this post? All changes will be lost.",
|
||||
|
|
|
@ -116,6 +116,7 @@
|
|||
"admin.statuses.status_deleted_message": "Post by @{acct} was deleted",
|
||||
"admin.statuses.status_marked_message_not_sensitive": "Post by @{acct} was marked not sensitive",
|
||||
"admin.statuses.status_marked_message_sensitive": "Post by @{acct} was marked sensitive",
|
||||
"admin.theme.title": "Diseño",
|
||||
"admin.user_index.empty": "No users found.",
|
||||
"admin.user_index.search_input_placeholder": "Who are you looking for?",
|
||||
"admin.users.actions.deactivate_user": "Deactivate @{name}",
|
||||
|
@ -185,6 +186,55 @@
|
|||
"bundle_modal_error.message": "Algo salió mal al cargar este componente.",
|
||||
"bundle_modal_error.retry": "Intentá de nuevo",
|
||||
"card.back.label": "Back",
|
||||
"chat.actions.send": "Enviar",
|
||||
"chat.failed_to_send": "Falló el envío del mensaje.",
|
||||
"chat.input.placeholder": "Escribe un mensaje",
|
||||
"chat.new_message.title": "Mensaje nuevo",
|
||||
"chat.page_settings.accepting_messages.label": "Permitir a los usuarios empezar un nuevo chat contigo",
|
||||
"chat.page_settings.play_sounds.label": "Reproducir un sonido cuando recibas un mensaje",
|
||||
"chat.page_settings.preferences": "Preferencias",
|
||||
"chat.page_settings.privacy": "Privacidad",
|
||||
"chat.page_settings.submit": "Guardar",
|
||||
"chat.page_settings.title": "Opciones de mensaje",
|
||||
"chat.retry": "¿Reintentar?",
|
||||
"chat.welcome.accepting_messages.label": "Permitir a los usuarios empezar un chat contigo",
|
||||
"chat.welcome.notice": "Podés cambiar estas opciones más tarde.",
|
||||
"chat.welcome.submit": "Guardar y continuar",
|
||||
"chat.welcome.subtitle": "Intercambiar mensajes directos con otros usuarios.",
|
||||
"chat.welcome.title": "¡Bienvenido/a a {br} Chats!",
|
||||
"chat_composer.unblock": "Desbloquear",
|
||||
"chat_list_item.blocked_you": "Este usuario te ha bloqueado",
|
||||
"chat_list_item.blocking": "Bloqueaste a este usuario/a",
|
||||
"chat_message_list.blocked": "Bloqueaste a este usuario/a",
|
||||
"chat_message_list.blockedBy": "Estás bloqueado/a por",
|
||||
"chat_message_list.network_failure.action": "Prueba nuevamente",
|
||||
"chat_message_list.network_failure.subtitle": "Hubo una falla de red.",
|
||||
"chat_message_list.network_failure.title": "¡Ups!",
|
||||
"chat_message_list_intro.actions.accept": "Aceptar",
|
||||
"chat_message_list_intro.actions.leave_chat": "Salir del chat",
|
||||
"chat_message_list_intro.actions.message_lifespan": "Los mensajes más viejos que {day} días son borrados.",
|
||||
"chat_message_list_intro.actions.report": "Reportar",
|
||||
"chat_message_list_intro.intro": "quiere empezar un chat contigo",
|
||||
"chat_message_list_intro.leave_chat.confirm": "Salir del chat",
|
||||
"chat_message_list_intro.leave_chat.heading": "Salir del chat",
|
||||
"chat_message_list_intro.leave_chat.message": "¿Estás seguro/a de salir del chat? Los mensajes serán borrados y el chat desaparecerá de tu bandeja de entrada.",
|
||||
"chat_search.blankslate.body": "Buscar alguien con quien chatear.",
|
||||
"chat_search.blankslate.title": "Empezar un chat",
|
||||
"chat_search.empty_results_blankslate.action": "Enviá un mensaje a alguien",
|
||||
"chat_search.empty_results_blankslate.body": "Intentá buscar otro nombre.",
|
||||
"chat_search.empty_results_blankslate.title": "No se encontraron coincidencias",
|
||||
"chat_search.placeholder": "Escribí un nombre",
|
||||
"chat_search.title": "Mensajes",
|
||||
"chat_settings.auto_delete.14days": "14 días",
|
||||
"chat_settings.auto_delete.2minutes": "2 minutos",
|
||||
"chat_settings.auto_delete.30days": "30 días",
|
||||
"chat_settings.auto_delete.7days": "7 días",
|
||||
"chat_settings.auto_delete.90days": "90 días",
|
||||
"chat_settings.auto_delete.days": "{day} días",
|
||||
"chat_settings.auto_delete.hint": "Los mensajes enviados serán borrados automáticamente después del tiempo seleccionado",
|
||||
"chat_settings.auto_delete.label": "Borrar automáticamente los mensajes",
|
||||
"chat_settings.block.confirm": "Bloquear",
|
||||
"chat_settings.block.heading": "Bloquear a @{acct}",
|
||||
"chats.actions.delete": "Delete message",
|
||||
"chats.actions.more": "More",
|
||||
"chats.actions.report": "Report user",
|
||||
|
|
|
@ -430,6 +430,9 @@
|
|||
"confirmations.block.confirm": "Bloquear",
|
||||
"confirmations.block.heading": "Block @{name}",
|
||||
"confirmations.block.message": "¿Estás seguro de que quieres bloquear a {name}?",
|
||||
"confirmations.cancel.confirm": "Descartar",
|
||||
"confirmations.cancel.heading": "Descartar la publicación",
|
||||
"confirmations.cancel.message": "¿Está seguro de que desea cancelar esta publicación?",
|
||||
"confirmations.cancel_editing.confirm": "Cancel editing",
|
||||
"confirmations.cancel_editing.heading": "Cancel post editing",
|
||||
"confirmations.cancel_editing.message": "Are you sure you want to cancel editing this post? All changes will be lost.",
|
||||
|
|
|
@ -1,180 +1,183 @@
|
|||
{
|
||||
"about.also_available": "Available in:",
|
||||
"accordion.collapse": "Collapse",
|
||||
"accordion.expand": "Expand",
|
||||
"about.also_available": "Disponible en:",
|
||||
"accordion.collapse": "Réduire",
|
||||
"accordion.expand": "Développer",
|
||||
"account.add_or_remove_from_list": "Ajouter ou retirer des listes",
|
||||
"account.badges.bot": "Robot",
|
||||
"account.birthday": "Born {date}",
|
||||
"account.birthday_today": "Birthday is today!",
|
||||
"account.birthday": "Naissance le {date}",
|
||||
"account.birthday_today": "Anniversaire aujourd'hui !",
|
||||
"account.block": "Bloquer @{name}",
|
||||
"account.block_domain": "Tout masquer venant de {domain}",
|
||||
"account.blocked": "Bloqué",
|
||||
"account.chat": "Chat with @{name}",
|
||||
"account.deactivated": "Deactivated",
|
||||
"account.deactivated": "Désactivé",
|
||||
"account.direct": "Envoyer un message direct à @{name}",
|
||||
"account.domain_blocked": "Domain hidden",
|
||||
"account.domain_blocked": "Domaine masqué",
|
||||
"account.edit_profile": "Modifier le profil",
|
||||
"account.endorse": "Recommander sur le profil",
|
||||
"account.endorse.success": "You are now featuring @{acct} on your profile",
|
||||
"account.familiar_followers": "Followed by {accounts}",
|
||||
"account.familiar_followers.empty": "No one you know follows {name}.",
|
||||
"account.familiar_followers.more": "{count} {count, plural, one {other} other {others}} you follow",
|
||||
"account.endorse.success": "Vous présentez @{acct} sur votre profil",
|
||||
"account.familiar_followers": "Suivi par {accounts}",
|
||||
"account.familiar_followers.empty": "Vous suivez à présent {name}.",
|
||||
"account.familiar_followers.more": "{count} {count, plural, one {other} other {others}} que vous suivez",
|
||||
"account.follow": "Suivre",
|
||||
"account.followers": "Abonné⋅e⋅s",
|
||||
"account.followers.empty": "Personne ne suit cet utilisateur·rice pour l’instant.",
|
||||
"account.follows": "Abonnements",
|
||||
"account.follows.empty": "Cet·te utilisateur·rice ne suit personne pour l’instant.",
|
||||
"account.follows_you": "Vous suit",
|
||||
"account.header.alt": "Profile header",
|
||||
"account.header.alt": "En-tête du profil",
|
||||
"account.hide_reblogs": "Masquer les partages de @{name}",
|
||||
"account.last_status": "Last active",
|
||||
"account.last_status": "Dernière activité",
|
||||
"account.link_verified_on": "La propriété de ce lien a été vérifiée le {date}",
|
||||
"account.locked_info": "Ce compte est verrouillé. Son propriétaire approuve manuellement qui peut le ou la suivre.",
|
||||
"account.login": "Log in",
|
||||
"account.media": "Média",
|
||||
"account.member_since": "Joined {date}",
|
||||
"account.member_since": "Inscription le {date}",
|
||||
"account.mention": "Mentionner",
|
||||
"account.mute": "Masquer @{name}",
|
||||
"account.muted": "Muted",
|
||||
"account.never_active": "Never",
|
||||
"account.muted": "Mise en silencieux",
|
||||
"account.never_active": "Jamais",
|
||||
"account.posts": "Pouets",
|
||||
"account.posts_with_replies": "Pouets et réponses",
|
||||
"account.profile": "Profile",
|
||||
"account.profile_external": "View profile on {domain}",
|
||||
"account.profile": "Profil",
|
||||
"account.profile_external": "Voir le profil sur {domain}",
|
||||
"account.register": "Sign up",
|
||||
"account.remote_follow": "Remote follow",
|
||||
"account.remove_from_followers": "Remove this follower",
|
||||
"account.remote_follow": "Suivre à distance",
|
||||
"account.remove_from_followers": "Supprimer cet abonnement",
|
||||
"account.report": "Signaler @{name}",
|
||||
"account.requested": "En attente d’approbation. Cliquez pour annuler la requête",
|
||||
"account.requested_small": "Awaiting approval",
|
||||
"account.search": "Search from @{name}",
|
||||
"account.search_self": "Search your posts",
|
||||
"account.requested_small": "En attente d'approbation",
|
||||
"account.search": "Recherche depuis @{name}",
|
||||
"account.search_self": "Chercher dans vos publications",
|
||||
"account.share": "Partager le profil de @{name}",
|
||||
"account.show_reblogs": "Afficher les partages de @{name}",
|
||||
"account.subscribe": "Subscribe to notifications from @{name}",
|
||||
"account.subscribe.failure": "An error occurred trying to subscribe to this account.",
|
||||
"account.subscribe.success": "You have subscribed to this account.",
|
||||
"account.subscribe": "S'abonner aux notifications de @{name}",
|
||||
"account.subscribe.failure": "Une erreur s'est produite en essayant de s'abonner à ce compte",
|
||||
"account.subscribe.success": "Vous vous êtes abonné⋅e à ce compte",
|
||||
"account.unblock": "Débloquer @{name}",
|
||||
"account.unblock_domain": "Ne plus masquer {domain}",
|
||||
"account.unendorse": "Ne plus recommander sur le profil",
|
||||
"account.unendorse.success": "You are no longer featuring @{acct}",
|
||||
"account.unendorse.success": "Vous ne présentez plus @{acct}",
|
||||
"account.unfollow": "Ne plus suivre",
|
||||
"account.unmute": "Ne plus masquer @{name}",
|
||||
"account.unsubscribe": "Unsubscribe to notifications from @{name}",
|
||||
"account.unsubscribe.failure": "An error occurred trying to unsubscribe to this account.",
|
||||
"account.unsubscribe.success": "You have unsubscribed from this account.",
|
||||
"account.verified": "Verified Account",
|
||||
"account_gallery.none": "No media to show.",
|
||||
"account_moderation_modal.admin_fe": "Open in AdminFE",
|
||||
"account_moderation_modal.fields.account_role": "Staff level",
|
||||
"account_moderation_modal.fields.badges": "Custom badges",
|
||||
"account_moderation_modal.fields.deactivate": "Deactivate account",
|
||||
"account.unsubscribe": "Se désinscrire des notifications de @{name}",
|
||||
"account.unsubscribe.failure": "Une erreur s'est produite en tentant de se désinscrire de ce compte.",
|
||||
"account.unsubscribe.success": "Vous vous êtes desabonné⋅e de ce profil",
|
||||
"account.verified": "Compte vérifié",
|
||||
"account_gallery.none": "Pas de média à montrer",
|
||||
"account_moderation_modal.admin_fe": "Ouvrir dans AdminFE",
|
||||
"account_moderation_modal.fields.account_role": "Rôle",
|
||||
"account_moderation_modal.fields.badges": "Badges personnalisés",
|
||||
"account_moderation_modal.fields.deactivate": "Désactiver le compte",
|
||||
"account_moderation_modal.fields.delete": "Delete account",
|
||||
"account_moderation_modal.fields.suggested": "Suggested in people to follow",
|
||||
"account_moderation_modal.fields.verified": "Verified account",
|
||||
"account_moderation_modal.fields.suggested": "Personnes suggérées",
|
||||
"account_moderation_modal.fields.verified": "Compte vérifié",
|
||||
"account_moderation_modal.info.id": "ID: {id}",
|
||||
"account_moderation_modal.roles.admin": "Admin",
|
||||
"account_moderation_modal.roles.moderator": "Moderator",
|
||||
"account_moderation_modal.roles.moderator": "Modérateur⋅ice",
|
||||
"account_moderation_modal.roles.user": "User",
|
||||
"account_moderation_modal.title": "Moderate @{acct}",
|
||||
"account_note.hint": "You can keep notes about this user for yourself (this will not be shared with them):",
|
||||
"account_note.placeholder": "No comment provided",
|
||||
"account_note.save": "Save",
|
||||
"account_moderation_modal.title": "Modérer @{acct}",
|
||||
"account_note.hint": "Vous pouvez garder des notes sur cet utilisateur⋅ice pour vous-même (ceci ne sera pas partagé avec eux):",
|
||||
"account_note.placeholder": "Pas de commentaire",
|
||||
"account_note.save": "Sauvegarder",
|
||||
"account_note.target": "Note for @{target}",
|
||||
"account_search.placeholder": "Search for an account",
|
||||
"actualStatus.edited": "Edited {date}",
|
||||
"actualStatuses.quote_tombstone": "Post is unavailable.",
|
||||
"admin.awaiting_approval.approved_message": "{acct} was approved!",
|
||||
"admin.awaiting_approval.empty_message": "There is nobody waiting for approval. When a new user signs up, you can review them here.",
|
||||
"admin.awaiting_approval.rejected_message": "{acct} was rejected.",
|
||||
"admin.dashboard.registration_mode.approval_hint": "Users can sign up, but their account only gets activated when an admin approves it.",
|
||||
"admin.dashboard.registration_mode.approval_label": "Approval Required",
|
||||
"admin.dashboard.registration_mode.closed_hint": "Nobody can sign up. You can still invite people.",
|
||||
"admin.dashboard.registration_mode.closed_label": "Closed",
|
||||
"admin.dashboard.registration_mode.open_hint": "Anyone can join.",
|
||||
"account_search.placeholder": "Rechercher un compte",
|
||||
"actualStatus.edited": "Edité le {date}",
|
||||
"actualStatuses.quote_tombstone": "Publication indisponible.",
|
||||
"admin.awaiting_approval.approved_message": "{acct} a été approuvé !",
|
||||
"admin.awaiting_approval.empty_message": "Personne n'attend d'approbation. Quand un nouveau compte s'affiche, vous pouvez l'examiner ici.",
|
||||
"admin.awaiting_approval.rejected_message": "{acct} a été rejeté",
|
||||
"admin.dashboard.registration_mode.approval_hint": "Tout le monde peut s'inscrire, mais leur compte ne s'active qu'après approbation.",
|
||||
"admin.dashboard.registration_mode.approval_label": "Approbation requise",
|
||||
"admin.dashboard.registration_mode.closed_hint": "Personne ne peut s'inscrire. Vous pouvez toujours inviter des gens.",
|
||||
"admin.dashboard.registration_mode.closed_label": "Fermé",
|
||||
"admin.dashboard.registration_mode.open_hint": "N'importe qui peut rejoindre.",
|
||||
"admin.dashboard.registration_mode.open_label": "Open",
|
||||
"admin.dashboard.registration_mode_label": "Registrations",
|
||||
"admin.dashboard.settings_saved": "Settings saved!",
|
||||
"admin.dashcounters.domain_count_label": "peers",
|
||||
"admin.dashcounters.mau_label": "monthly active users",
|
||||
"admin.dashcounters.retention_label": "user retention",
|
||||
"admin.dashboard.registration_mode_label": "Inscriptions",
|
||||
"admin.dashboard.settings_saved": "Paramètres sauvegardées !",
|
||||
"admin.dashcounters.domain_count_label": "pairs",
|
||||
"admin.dashcounters.mau_label": "comptes actifs mensuellement",
|
||||
"admin.dashcounters.retention_label": "rétention de comptes",
|
||||
"admin.dashcounters.status_count_label": "posts",
|
||||
"admin.dashcounters.user_count_label": "total users",
|
||||
"admin.dashcounters.user_count_label": "comptes au total",
|
||||
"admin.dashwidgets.email_list_header": "Email list",
|
||||
"admin.dashwidgets.software_header": "Software",
|
||||
"admin.latest_accounts_panel.more": "Click to see {count} {count, plural, one {account} other {accounts}}",
|
||||
"admin.latest_accounts_panel.title": "Latest Accounts",
|
||||
"admin.moderation_log.empty_message": "You have not performed any moderation actions yet. When you do, a history will be shown here.",
|
||||
"admin.reports.actions.close": "Close",
|
||||
"admin.latest_accounts_panel.more": "Cliquer pour voir {count} {count, plural, one {account} other {accounts}}",
|
||||
"admin.latest_accounts_panel.title": "Derniers comptes",
|
||||
"admin.moderation_log.empty_message": "Vous n'avez pas encore effectué d'acte de modération. Quand vous le ferez, un historique sera montrée ici.",
|
||||
"admin.reports.actions.close": "Fermer",
|
||||
"admin.reports.actions.view_status": "View post",
|
||||
"admin.reports.empty_message": "There are no open reports. If a user gets reported, they will show up here.",
|
||||
"admin.reports.report_closed_message": "Report on @{name} was closed",
|
||||
"admin.reports.empty_message": "Il n'y a pas de rapport ouvert. Si un profil est signalé, il se présentera ici.",
|
||||
"admin.reports.report_closed_message": "Le signalement de @{name} a été fermé",
|
||||
"admin.reports.report_title": "Report on {acct}",
|
||||
"admin.software.backend": "Backend",
|
||||
"admin.software.frontend": "Frontend",
|
||||
"admin.statuses.actions.delete_status": "Delete post",
|
||||
"admin.statuses.actions.mark_status_not_sensitive": "Mark post not sensitive",
|
||||
"admin.statuses.actions.mark_status_sensitive": "Mark post sensitive",
|
||||
"admin.statuses.status_deleted_message": "Post by @{acct} was deleted",
|
||||
"admin.statuses.status_marked_message_not_sensitive": "Post by @{acct} was marked not sensitive",
|
||||
"admin.statuses.status_marked_message_sensitive": "Post by @{acct} was marked sensitive",
|
||||
"admin.user_index.empty": "No users found.",
|
||||
"admin.user_index.search_input_placeholder": "Who are you looking for?",
|
||||
"admin.users.actions.deactivate_user": "Deactivate @{name}",
|
||||
"admin.statuses.actions.mark_status_not_sensitive": "Marquer la publication comme non sensible",
|
||||
"admin.statuses.actions.mark_status_sensitive": "Marquer la publication comme sensible",
|
||||
"admin.statuses.status_deleted_message": "Publication de @{acct} supprimée",
|
||||
"admin.statuses.status_marked_message_not_sensitive": "Publication de @{acct} marquée comme non sensible",
|
||||
"admin.statuses.status_marked_message_sensitive": "Publication de @{acct} marquée comme sensible",
|
||||
"admin.theme.title": "Thème",
|
||||
"admin.user_index.empty": "Aucun profil trouvé.",
|
||||
"admin.user_index.search_input_placeholder": "Qui recherchez-vous ?",
|
||||
"admin.users.actions.deactivate_user": "Désactiver @{name}",
|
||||
"admin.users.actions.delete_user": "Delete @{name}",
|
||||
"admin.users.actions.demote_to_moderator_message": "@{acct} was demoted to a moderator",
|
||||
"admin.users.actions.demote_to_user_message": "@{acct} was demoted to a regular user",
|
||||
"admin.users.actions.promote_to_admin_message": "@{acct} was promoted to an admin",
|
||||
"admin.users.actions.promote_to_moderator_message": "@{acct} was promoted to a moderator",
|
||||
"admin.users.badges_saved_message": "Custom badges updated.",
|
||||
"admin.users.remove_donor_message": "@{acct} was removed as a donor",
|
||||
"admin.users.set_donor_message": "@{acct} was set as a donor",
|
||||
"admin.users.user_deactivated_message": "@{acct} was deactivated",
|
||||
"admin.users.user_deleted_message": "@{acct} was deleted",
|
||||
"admin.users.user_suggested_message": "@{acct} was suggested",
|
||||
"admin.users.user_unsuggested_message": "@{acct} was unsuggested",
|
||||
"admin.users.user_unverified_message": "@{acct} was unverified",
|
||||
"admin.users.user_verified_message": "@{acct} was verified",
|
||||
"admin.users.actions.demote_to_moderator_message": "@{acct} a été rétrogradé⋅e au statut de modérateur⋅ice",
|
||||
"admin.users.actions.demote_to_user_message": "@{acct} a été rétrogradé⋅e au statut d'utilisateur⋅ice",
|
||||
"admin.users.actions.promote_to_admin_message": "@{acct} a été promu⋅e au statut d'administrateur⋅ice",
|
||||
"admin.users.actions.promote_to_moderator_message": "@{acct} a été promu⋅e au statut de modérateur⋅ice",
|
||||
"admin.users.badges_saved_message": "Badges personnalisés mis à jour.",
|
||||
"admin.users.remove_donor_message": "Le statut de donateur de @{acct} a été supprimé",
|
||||
"admin.users.set_donor_message": "Le statut de donateur a été octroyé à @{acct}",
|
||||
"admin.users.user_deactivated_message": "@{acct} a été désactivé⋅e",
|
||||
"admin.users.user_deleted_message": "@{acct} a été supprimé⋅e",
|
||||
"admin.users.user_suggested_message": "@{acct} a été suggéré⋅e",
|
||||
"admin.users.user_unsuggested_message": "@{acct} a été supprimé⋅e des suggestions",
|
||||
"admin.users.user_unverified_message": "@{acct} a été supprimé⋅e des comptes vérifiés",
|
||||
"admin.users.user_verified_message": "@{acct} a été ajouté⋅e aux comptes vérifiés",
|
||||
"admin_nav.awaiting_approval": "Awaiting Approval",
|
||||
"admin_nav.dashboard": "Dashboard",
|
||||
"admin_nav.reports": "Reports",
|
||||
"age_verification.body": "{siteTitle} requires users to be at least {ageMinimum} years old to access its platform. Anyone under the age of {ageMinimum} years old cannot access this platform.",
|
||||
"age_verification.fail": "You must be {ageMinimum, plural, one {# year} other {# years}} old or older.",
|
||||
"age_verification.header": "Enter your birth date",
|
||||
"alert.unexpected.body": "We're sorry for the interruption. If the problem persists, please reach out to our support team. You may also try to {clearCookies} (this will log you out).",
|
||||
"age_verification.body": "{siteTitle} requiert d'être agé de {ageMinimum} ans pour accéder à sa plateforme. Quiconque en dessous de {ageMinimum} ans ne peut accéder à cette plateforme.",
|
||||
"age_verification.fail": "Vous devez être âgé⋅e de {ageMinimum, plural, one {# year} other {# years}} ans ou plus.",
|
||||
"age_verification.header": "Entrez votre date de naissance",
|
||||
"alert.unexpected.body": "Nous vous prions de nous excuser pour l'interruption. Si le problème persiste, veuillez contacter notre équipe de support. Vous pouvez également essayer de {clearCookies} (ceci vous déconnectera).",
|
||||
"alert.unexpected.browser": "Browser",
|
||||
"alert.unexpected.clear_cookies": "clear cookies and browser data",
|
||||
"alert.unexpected.links.help": "Help Center",
|
||||
"alert.unexpected.clear_cookies": "supprimer les cookies et les données de navigation",
|
||||
"alert.unexpected.links.help": "Centre d'aide",
|
||||
"alert.unexpected.links.status": "Status",
|
||||
"alert.unexpected.links.support": "Support",
|
||||
"alert.unexpected.message": "Une erreur inattendue s’est produite.",
|
||||
"alert.unexpected.return_home": "Return Home",
|
||||
"aliases.account.add": "Create alias",
|
||||
"aliases.account_label": "Old account:",
|
||||
"aliases.aliases_list_delete": "Unlink alias",
|
||||
"aliases.search": "Search your old account",
|
||||
"aliases.success.add": "Account alias created successfully",
|
||||
"aliases.success.remove": "Account alias removed successfully",
|
||||
"announcements.title": "Announcements",
|
||||
"app_create.name_label": "App name",
|
||||
"aliases.account.add": "Créer un alias",
|
||||
"aliases.account_label": "Ancien compte :",
|
||||
"aliases.aliases_list_delete": "Délier l'alias",
|
||||
"aliases.search": "Recherche votre ancien compte",
|
||||
"aliases.success.add": "Alias de compte créé avec succès",
|
||||
"aliases.success.remove": "Alias de compte supprimé avec succès",
|
||||
"announcements.title": "Annonces",
|
||||
"app_create.name_label": "Nom de l'application",
|
||||
"app_create.name_placeholder": "e.g. 'Soapbox'",
|
||||
"app_create.redirect_uri_label": "Redirect URIs",
|
||||
"app_create.restart": "Create another",
|
||||
"app_create.results.app_label": "App",
|
||||
"app_create.results.explanation_text": "You created a new app and token! Please copy the credentials somewhere; you will not see them again after navigating away from this page.",
|
||||
"app_create.results.explanation_title": "App created successfully",
|
||||
"app_create.redirect_uri_label": "URIs de redirection",
|
||||
"app_create.restart": "Créer une autre application",
|
||||
"app_create.results.app_label": "Application",
|
||||
"app_create.results.explanation_text": "Vous avez créé une nouvelle application et jeton ! Veuillez copier les identifiants quelque part ; vous ne les verrez plus après avoir navigué hors de cette page.",
|
||||
"app_create.results.explanation_title": "Application créée avec succès",
|
||||
"app_create.results.token_label": "OAuth token",
|
||||
"app_create.scopes_label": "Scopes",
|
||||
"app_create.scopes_placeholder": "e.g. 'read write follow'",
|
||||
"app_create.submit": "Create app",
|
||||
"app_create.scopes_label": "Objectifs",
|
||||
"app_create.scopes_placeholder": "e.g. 'lire, écrire, suivre'",
|
||||
"app_create.submit": "Créer une application",
|
||||
"app_create.website_label": "Website",
|
||||
"auth.invalid_credentials": "Wrong username or password",
|
||||
"auth.logged_out": "Logged out.",
|
||||
"auth_layout.register": "Create an account",
|
||||
"backups.actions.create": "Create backup",
|
||||
"backups.empty_message": "No backups found. {action}",
|
||||
"backups.empty_message.action": "Create one now?",
|
||||
"backups.pending": "Pending",
|
||||
"auth.invalid_credentials": "Mauvais identifiant ou mot de passe",
|
||||
"auth.logged_out": "Déconnecté⋅e",
|
||||
"auth_layout.register": "Créer un compte",
|
||||
"backups.actions.create": "Créer une sauvegarde",
|
||||
"backups.empty_message": "Pas de sauvegarde trouvée. {action}",
|
||||
"backups.empty_message.action": "Créer maintenant ?",
|
||||
"backups.pending": "En attente",
|
||||
"badge_input.placeholder": "Enter a badge…",
|
||||
"birthday_panel.title": "Birthdays",
|
||||
"birthday_panel.title": "Anniversaires",
|
||||
"birthdays_modal.empty": "None of your friends have birthday today.",
|
||||
"boost_modal.combo": "Vous pouvez appuyer sur {combo} pour passer ceci, la prochaine fois",
|
||||
"boost_modal.title": "Repost?",
|
||||
|
@ -185,10 +188,80 @@
|
|||
"bundle_modal_error.message": "Une erreur s’est produite lors du chargement de ce composant.",
|
||||
"bundle_modal_error.retry": "Réessayer",
|
||||
"card.back.label": "Back",
|
||||
"chat.actions.send": "Envoyer",
|
||||
"chat.failed_to_send": "L'envoi du message a échoué.",
|
||||
"chat.input.placeholder": "Écrire un message",
|
||||
"chat.new_message.title": "Nouveau message",
|
||||
"chat.page_settings.accepting_messages.label": "Permettre aux autres de commencer une discussion avec vous",
|
||||
"chat.page_settings.play_sounds.label": "Émettre un son à la réception d'un message",
|
||||
"chat.page_settings.preferences": "Préférences",
|
||||
"chat.page_settings.privacy": "Vie privée",
|
||||
"chat.page_settings.submit": "Sauvegarder",
|
||||
"chat.page_settings.title": "Paramètres des messages",
|
||||
"chat.retry": "Réessayer ?",
|
||||
"chat.welcome.accepting_messages.label": "Permettre aux autres de commencer une nouvelle discussion avec vous",
|
||||
"chat.welcome.notice": "Vous pourrez changer ces paramètres ultérieurement.",
|
||||
"chat.welcome.submit": "Sauvegarder et continuer",
|
||||
"chat.welcome.subtitle": "Échanger des messages directs avec d'autres utilisateurs.",
|
||||
"chat.welcome.title": "Bienvenue dans la conversation de {br} !",
|
||||
"chat_composer.unblock": "Débloquer",
|
||||
"chat_list_item.blocked_you": "Cette personne vous bloque",
|
||||
"chat_list_item.blocking": "Vous avez bloqué cette personne",
|
||||
"chat_message_list.blocked": "Vous bloquez cette personne",
|
||||
"chat_message_list.blockedBy": "Vous êtes bloqué⋅e par",
|
||||
"chat_message_list.network_failure.action": "Essayer à nouveau",
|
||||
"chat_message_list.network_failure.subtitle": "Une erreur de réseau s'est produite.",
|
||||
"chat_message_list.network_failure.title": "Oups !",
|
||||
"chat_message_list_intro.actions.accept": "Accepter",
|
||||
"chat_message_list_intro.actions.leave_chat": "Quitter la conversation",
|
||||
"chat_message_list_intro.actions.message_lifespan": "Les messages datant de plus de {day} jours sont supprimés.",
|
||||
"chat_message_list_intro.actions.report": "Signaler",
|
||||
"chat_message_list_intro.intro": "veut commencer une discussion avec vous",
|
||||
"chat_message_list_intro.leave_chat.confirm": "Quitter la conversation",
|
||||
"chat_message_list_intro.leave_chat.heading": "Quitter la conversation",
|
||||
"chat_message_list_intro.leave_chat.message": "Êtes-vous sûr⋅e de quitter cette conversation ? Les messages seront supprimés pour vous et cette discussion sera supprimée de votre boîte de réception.",
|
||||
"chat_search.blankslate.body": "Chercher quelqu'un avec qui discuter.",
|
||||
"chat_search.blankslate.title": "Commencer une discussion",
|
||||
"chat_search.empty_results_blankslate.action": "Envoyer un message à quelqu'un",
|
||||
"chat_search.empty_results_blankslate.body": "Essayez de chercher un autre nom.",
|
||||
"chat_search.empty_results_blankslate.title": "Aucun résultat trouvé",
|
||||
"chat_search.placeholder": "Entrer un nom",
|
||||
"chat_search.title": "Messages",
|
||||
"chat_settings.auto_delete.14days": "14 jours",
|
||||
"chat_settings.auto_delete.2minutes": "2 minutes",
|
||||
"chat_settings.auto_delete.30days": "30 jours",
|
||||
"chat_settings.auto_delete.7days": "7 jours",
|
||||
"chat_settings.auto_delete.90days": "90 jours",
|
||||
"chat_settings.auto_delete.days": "{day} jours",
|
||||
"chat_settings.auto_delete.hint": "Les messages envoyés seront supprimés automatiquement après la période selectionnée",
|
||||
"chat_settings.auto_delete.label": "Supprimer les messages automatiquement",
|
||||
"chat_settings.block.confirm": "Bloquer",
|
||||
"chat_settings.block.heading": "Bloquer @{acct}",
|
||||
"chat_settings.block.message": "Bloquer empêchera ce profil de vous envoyer des messages directs et de voir votre contenu. Vous pouvez débloquer ultérieurement.",
|
||||
"chat_settings.leave.confirm": "Quitter la conversation",
|
||||
"chat_settings.leave.heading": "Quitter la conversation",
|
||||
"chat_settings.leave.message": "Êtes-vous sûr⋅e de quitter cette conversation ? Les messages seront supprimés pour vous et cette discussion sera supprimée de votre boîte de réception.",
|
||||
"chat_settings.options.block_user": "Bloquer @{acct}",
|
||||
"chat_settings.options.leave_chat": "Quitter la conversation",
|
||||
"chat_settings.options.report_user": "Signaler @{acct}",
|
||||
"chat_settings.options.unblock_user": "Débloquer @{acct}",
|
||||
"chat_settings.title": "Détails de la conversation",
|
||||
"chat_settings.unblock.confirm": "Débloquer",
|
||||
"chat_settings.unblock.heading": "Débloquer @{acct}",
|
||||
"chat_settings.unblock.message": "Débloquer permettra à ce profil de vous envoyer des messages directs et voir votre contenu.",
|
||||
"chat_window.auto_delete_label": "Supprimer automatiquement après {day} jours",
|
||||
"chat_window.auto_delete_tooltip": "Les messages de discussion sont paramétrer pour suppression automatique au bout de {day} jours après envoi.",
|
||||
"chats.actions.copy": "Copier",
|
||||
"chats.actions.delete": "Delete message",
|
||||
"chats.actions.deleteForMe": "Supprimer pour moi",
|
||||
"chats.actions.more": "More",
|
||||
"chats.actions.report": "Report user",
|
||||
"chats.dividers.today": "Today",
|
||||
"chats.main.blankslate.new_chat": "Envoyer à message à quelqu'un",
|
||||
"chats.main.blankslate.subtitle": "Chercher quelqu'un à qui parler",
|
||||
"chats.main.blankslate.title": "Pas de message pour le moment",
|
||||
"chats.main.blankslate_with_chats.subtitle": "Sélectionner depuis l'une de vos conversations ou créer un nouveau message.",
|
||||
"chats.main.blankslate_with_chats.title": "Sélectionner une discussion",
|
||||
"chats.search_placeholder": "Start a chat with…",
|
||||
"column.admin.awaiting_approval": "Awaiting Approval",
|
||||
"column.admin.dashboard": "Dashboard",
|
||||
|
@ -216,6 +289,9 @@
|
|||
"column.directory": "Browse profiles",
|
||||
"column.domain_blocks": "Domaines cachés",
|
||||
"column.edit_profile": "Edit profile",
|
||||
"column.event_map": "Emplacement de l'évènement",
|
||||
"column.event_participants": "Participants à l'évènement",
|
||||
"column.events": "Évènements",
|
||||
"column.export_data": "Export data",
|
||||
"column.familiar_followers": "People you know following {name}",
|
||||
"column.favourited_statuses": "Liked posts",
|
||||
|
@ -258,6 +334,7 @@
|
|||
"column.pins": "Pinned posts",
|
||||
"column.preferences": "Preferences",
|
||||
"column.public": "Fil public global",
|
||||
"column.quotes": "Citations",
|
||||
"column.reactions": "Reactions",
|
||||
"column.reblogs": "Reposts",
|
||||
"column.scheduled_statuses": "Scheduled Posts",
|
||||
|
@ -274,7 +351,33 @@
|
|||
"compose.edit_success": "Your post was edited",
|
||||
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
|
||||
"compose.submit_success": "Your post was sent",
|
||||
"compose_event.create": "Créer",
|
||||
"compose_event.edit_success": "Votre évènement a été édité",
|
||||
"compose_event.fields.approval_required": "Approuver les requêtes de participation manuellement",
|
||||
"compose_event.fields.banner_label": "Bannière d'évènement",
|
||||
"compose_event.fields.description_hint": "La syntaxe Markdown est supportée",
|
||||
"compose_event.fields.description_label": "Description de l'évènement",
|
||||
"compose_event.fields.description_placeholder": "Description",
|
||||
"compose_event.fields.end_time_label": "Date de fin de l'évènement",
|
||||
"compose_event.fields.end_time_placeholder": "L'évènement se finit le…",
|
||||
"compose_event.fields.has_end_time": "L'évènement a une date de fin",
|
||||
"compose_event.fields.location_label": "Lieu de l'évènement",
|
||||
"compose_event.fields.name_label": "Nom de l'évènement",
|
||||
"compose_event.fields.name_placeholder": "Nom",
|
||||
"compose_event.fields.start_time_label": "Date de début de l'évènement",
|
||||
"compose_event.fields.start_time_placeholder": "L'évènement commence le…",
|
||||
"compose_event.participation_requests.authorize": "Autoriser",
|
||||
"compose_event.participation_requests.authorize_success": "Utilisateur⋅ice accepté⋅e",
|
||||
"compose_event.participation_requests.reject": "Rejeter",
|
||||
"compose_event.participation_requests.reject_success": "Utilisateur⋅ice rejeté⋅e",
|
||||
"compose_event.reset_location": "Réinitaliser le lieu",
|
||||
"compose_event.submit_success": "Votre évènement a été créé",
|
||||
"compose_event.tabs.edit": "Éditer les détails",
|
||||
"compose_event.tabs.pending": "Gérer les requêtes",
|
||||
"compose_event.update": "Mettre à jour",
|
||||
"compose_event.upload_banner": "Téléverser une bannière d'évènement",
|
||||
"compose_form.direct_message_warning": "Ce pouet sera uniquement envoyé aux personnes mentionnées. Cependant, l’administration de votre instance et des instances réceptrices pourront inspecter ce message.",
|
||||
"compose_form.event_placeholder": "Publier cet évènement",
|
||||
"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 n’est pas {locked}. Tout le monde peut vous suivre et voir vos pouets privés.",
|
||||
"compose_form.lock_disclaimer.lock": "verrouillé",
|
||||
|
@ -327,18 +430,28 @@
|
|||
"confirmations.block.confirm": "Bloquer",
|
||||
"confirmations.block.heading": "Block @{name}",
|
||||
"confirmations.block.message": "Confirmez-vous le blocage de {name} ?",
|
||||
"confirmations.cancel.confirm": "Abandonner",
|
||||
"confirmations.cancel.heading": "Abandonner la publication",
|
||||
"confirmations.cancel.message": "Êtes-vous sûr⋅e de vouloir abandonner la création de cette publication ?",
|
||||
"confirmations.cancel_editing.confirm": "Cancel editing",
|
||||
"confirmations.cancel_editing.heading": "Cancel post editing",
|
||||
"confirmations.cancel_editing.message": "Are you sure you want to cancel editing this post? All changes will be lost.",
|
||||
"confirmations.cancel_event_editing.heading": "Annuler l'édition de l'évènement",
|
||||
"confirmations.cancel_event_editing.message": "Êtes-vous sûr⋅e de vouloir annuler l'édition de cet évènement ? Tous les changements seront perdus.",
|
||||
"confirmations.delete.confirm": "Supprimer",
|
||||
"confirmations.delete.heading": "Delete post",
|
||||
"confirmations.delete.message": "Confirmez-vous la suppression de ce pouet ?",
|
||||
"confirmations.delete_event.confirm": "Supprimer",
|
||||
"confirmations.delete_event.heading": "Supprimer l'évènement",
|
||||
"confirmations.delete_event.message": "Êtes-vous sûr⋅e de vouloir supprimer cet évènement ?",
|
||||
"confirmations.delete_list.confirm": "Supprimer",
|
||||
"confirmations.delete_list.heading": "Delete list",
|
||||
"confirmations.delete_list.message": "Êtes-vous sûr·e de vouloir supprimer définitivement cette liste ?",
|
||||
"confirmations.domain_block.confirm": "Masquer le domaine entier",
|
||||
"confirmations.domain_block.heading": "Block {domain}",
|
||||
"confirmations.domain_block.message": "Êtes-vous vraiment, vraiment sûr⋅e de vouloir bloquer {domain} en entier ? Dans la plupart des cas, quelques blocages ou masquages ciblés sont suffisants et préférables. Vous ne verrez plus de contenu provenant de ce domaine, ni dans fils publics, ni dans vos notifications. Vos abonné·e·s utilisant ce domaine seront retiré·e·s.",
|
||||
"confirmations.leave_event.confirm": "Quitter l'évènement",
|
||||
"confirmations.leave_event.message": "Si vous voulez rejoindre à nouveau l'évènement, la requête sera à nouveau validée manuellement. Êtes-vous sûr⋅e de continuer ?",
|
||||
"confirmations.mute.confirm": "Masquer",
|
||||
"confirmations.mute.heading": "Mute @{name}",
|
||||
"confirmations.mute.message": "Êtes-vous sûr·e de vouloir masquer {name} ?",
|
||||
|
@ -386,6 +499,7 @@
|
|||
"developers.navigation.network_error_label": "Network error",
|
||||
"developers.navigation.service_worker_label": "Service Worker",
|
||||
"developers.navigation.settings_store_label": "Settings store",
|
||||
"developers.navigation.show_toast": "Activer les notifications urgentes",
|
||||
"developers.navigation.test_timeline_label": "Test timeline",
|
||||
"developers.settings_store.advanced": "Advanced settings",
|
||||
"developers.settings_store.hint": "It is possible to directly edit your user settings here. BE CAREFUL! Editing this section can break your account, and you will only be able to recover through the API.",
|
||||
|
@ -484,6 +598,8 @@
|
|||
"empty_column.community": "Le fil public local est vide. Écrivez donc quelque chose pour le remplir !",
|
||||
"empty_column.direct": "Vous n’avez pas encore de messages directs. Lorsque vous en enverrez ou recevrez un, il s’affichera ici.",
|
||||
"empty_column.domain_blocks": "Il n’y a aucun domaine caché pour le moment.",
|
||||
"empty_column.event_participant_requests": "Il n'y a pas de requête de participation en attente.",
|
||||
"empty_column.event_participants": "Personne n'a rejoint cet évènement pour le moment. Quand quelqu'un le fera, cela apparaîtra ici.",
|
||||
"empty_column.favourited_statuses": "Vous n’avez aucun pouet favoris pour le moment. Lorsque vous en mettrez un en favori, il apparaîtra ici.",
|
||||
"empty_column.favourites": "Personne n’a encore mis ce pouet en favori. Lorsque quelqu’un le fera, il apparaîtra ici.",
|
||||
"empty_column.filters": "You haven't created any muted words yet.",
|
||||
|
@ -500,12 +616,36 @@
|
|||
"empty_column.notifications": "Vous n’avez pas encore de notification. Interagissez avec d’autres personnes pour débuter la conversation.",
|
||||
"empty_column.notifications_filtered": "You don't have any notifications of this type yet.",
|
||||
"empty_column.public": "Il n’y a rien ici ! Écrivez quelque chose publiquement, ou bien suivez manuellement des personnes d’autres instances pour le remplir",
|
||||
"empty_column.quotes": "Cette publication n'a pas été citée pour le moment.",
|
||||
"empty_column.remote": "There is nothing here! Manually follow users from {instance} to fill it up.",
|
||||
"empty_column.scheduled_statuses": "You don't have any scheduled statuses yet. When you add one, it will show up here.",
|
||||
"empty_column.search.accounts": "There are no people results for \"{term}\"",
|
||||
"empty_column.search.hashtags": "There are no hashtags results for \"{term}\"",
|
||||
"empty_column.search.statuses": "There are no posts results for \"{term}\"",
|
||||
"empty_column.test": "The test timeline is empty.",
|
||||
"event.banner": "Bannière de l'évènement",
|
||||
"event.copy": "Copier le lien de l'évènement",
|
||||
"event.date": "Date",
|
||||
"event.description": "Description",
|
||||
"event.discussion.empty": "Personne n'a commenté cet évènement pour l'instant. Quand quelqu'un le fera, cela apparaîtra ici.",
|
||||
"event.export_ics": "Exporter vers votre calendrier",
|
||||
"event.external": "Voir les évènements sur {domain}",
|
||||
"event.join_state.accept": "Participer",
|
||||
"event.join_state.empty": "Participer",
|
||||
"event.join_state.pending": "En attente",
|
||||
"event.join_state.rejected": "Participer",
|
||||
"event.location": "Lieu",
|
||||
"event.manage": "Gérer",
|
||||
"event.organized_by": "Organisé par {name}",
|
||||
"event.participants": "{count} {rawCount, plural, one {person} other {people}} participent",
|
||||
"event.show_on_map": "Montrer sur la carte",
|
||||
"event.website": "Liens externes",
|
||||
"event_map.navigate": "Naviguer",
|
||||
"events.create_event": "Créer un évènement",
|
||||
"events.joined_events": "Évènements rejoints",
|
||||
"events.joined_events.empty": "Vous n'avez rejoint aucun évènement pour le moment.",
|
||||
"events.recent_events": "Récents évènements",
|
||||
"events.recent_events.empty": "Il n'y a pas d'évènement public pour le moment.",
|
||||
"export_data.actions.export": "Export",
|
||||
"export_data.actions.export_blocks": "Export blocks",
|
||||
"export_data.actions.export_follows": "Export follows",
|
||||
|
@ -586,6 +726,12 @@
|
|||
"intervals.full.days": "{number, plural, one {# jour} other {# jours}}",
|
||||
"intervals.full.hours": "{number, plural, one {# heure} other {# heures}}",
|
||||
"intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
|
||||
"join_event.hint": "Vous pouvez dire à la personne organisatrice pourquoi vous voulez participer à cet évènement :",
|
||||
"join_event.join": "Demander à participer",
|
||||
"join_event.placeholder": "Envoyer un message à la personne organisatrice",
|
||||
"join_event.request_success": "Demander à participer à l'évènement",
|
||||
"join_event.success": "Évènements rejoints",
|
||||
"join_event.title": "Rejoindre l'évènement",
|
||||
"keyboard_shortcuts.back": "pour revenir en arrière",
|
||||
"keyboard_shortcuts.blocked": "pour ouvrir une liste d’utilisateur·rice·s bloqué·e·s",
|
||||
"keyboard_shortcuts.boost": "pour partager",
|
||||
|
@ -634,6 +780,7 @@
|
|||
"lists.search": "Rechercher parmi les gens que vous suivez",
|
||||
"lists.subheading": "Vos listes",
|
||||
"loading_indicator.label": "Chargement…",
|
||||
"location_search.placeholder": "Trouver une adresse",
|
||||
"login.fields.instance_label": "Instance",
|
||||
"login.fields.instance_placeholder": "example.com",
|
||||
"login.fields.otp_code_hint": "Enter the two-factor code generated by your phone app or use one of your recovery codes",
|
||||
|
@ -682,6 +829,8 @@
|
|||
"missing_description_modal.text": "You have not entered a description for all attachments. Continue anyway?",
|
||||
"missing_indicator.label": "Non trouvé",
|
||||
"missing_indicator.sublabel": "Ressource introuvable",
|
||||
"modals.policy.submit": "Accepter et continuer",
|
||||
"modals.policy.updateTitle": "Vous avez obtenu la dernière version de {siteTitle} ! Prenez un petit moment pour découvrir les excitantes nouveautés sur lesquelles nous avons travaillé.",
|
||||
"moderation_overlay.contact": "Contact",
|
||||
"moderation_overlay.hide": "Hide content",
|
||||
"moderation_overlay.show": "Show Content",
|
||||
|
@ -708,8 +857,10 @@
|
|||
"navigation_bar.compose": "Rédiger un nouveau toot",
|
||||
"navigation_bar.compose_direct": "Direct message",
|
||||
"navigation_bar.compose_edit": "Edit post",
|
||||
"navigation_bar.compose_event": "Gérer l'évènement",
|
||||
"navigation_bar.compose_quote": "Quote post",
|
||||
"navigation_bar.compose_reply": "Reply to post",
|
||||
"navigation_bar.create_event": "Créer un nouvel évènement",
|
||||
"navigation_bar.domain_blocks": "Domaines cachés",
|
||||
"navigation_bar.favourites": "Favoris",
|
||||
"navigation_bar.filters": "Mots silenciés",
|
||||
|
@ -732,6 +883,9 @@
|
|||
"notification.others": " + {count} {count, plural, one {other} other {others}}",
|
||||
"notification.pleroma:chat_mention": "{name} sent you a message",
|
||||
"notification.pleroma:emoji_reaction": "{name} reacted to your post",
|
||||
"notification.pleroma:event_reminder": "Un évènement auquel vous participez commence bientôt",
|
||||
"notification.pleroma:participation_accepted": "Votre participation à l'évènement a été acceptée",
|
||||
"notification.pleroma:participation_request": "{name} vous invite à rejoindre l'évènement",
|
||||
"notification.poll": "Un sondage auquel vous avez participé vient de se terminer",
|
||||
"notification.reblog": "{name} a partagé votre statut :",
|
||||
"notification.status": "{name} just posted",
|
||||
|
@ -805,6 +959,8 @@
|
|||
"preferences.fields.content_type_label": "Default post format",
|
||||
"preferences.fields.delete_modal_label": "Show confirmation dialog before deleting a post",
|
||||
"preferences.fields.demetricator_label": "Use Demetricator",
|
||||
"preferences.fields.demo_hint": "Utiliser le logo de Soapbox par défaut et son schéma de couleur. Utile pour prendre des captures d'écran.",
|
||||
"preferences.fields.demo_label": "Mode de démonstration",
|
||||
"preferences.fields.display_media.default": "Hide media marked as sensitive",
|
||||
"preferences.fields.display_media.hide_all": "Always hide media",
|
||||
"preferences.fields.display_media.show_all": "Always show media",
|
||||
|
@ -891,6 +1047,8 @@
|
|||
"remote_instance.unpin_host": "Unpin {host}",
|
||||
"remote_interaction.account_placeholder": "Enter your username@domain you want to act from",
|
||||
"remote_interaction.divider": "or",
|
||||
"remote_interaction.event_join": "Continuer à rejoindre",
|
||||
"remote_interaction.event_join_title": "Rejoindre un évènement distant",
|
||||
"remote_interaction.favourite": "Proceed to like",
|
||||
"remote_interaction.favourite_title": "Like a post remotely",
|
||||
"remote_interaction.follow": "Proceed to follow",
|
||||
|
@ -912,6 +1070,8 @@
|
|||
"reply_mentions.reply_empty": "Replying to post",
|
||||
"report.block": "Block {target}",
|
||||
"report.block_hint": "Do you also want to block this account?",
|
||||
"report.chatMessage.context": "En signalant le message d’un utilisateur, les cinq messages avant et cinq après celui sélectionné seront transmis à notre équipe de modération pour contexte.",
|
||||
"report.chatMessage.title": "Signaler le message",
|
||||
"report.confirmation.content": "If we find that this account is violating the {link} we will take further action on the matter.",
|
||||
"report.confirmation.title": "Thanks for submitting your report.",
|
||||
"report.done": "Done",
|
||||
|
@ -973,6 +1133,7 @@
|
|||
"settings.configure_mfa": "Configure MFA",
|
||||
"settings.delete_account": "Delete Account",
|
||||
"settings.edit_profile": "Edit Profile",
|
||||
"settings.messages.label": "Permettre aux autres de commencer une nouvelle discussion avec vous",
|
||||
"settings.other": "Other options",
|
||||
"settings.preferences": "Preferences",
|
||||
"settings.profile": "Profile",
|
||||
|
@ -1013,6 +1174,7 @@
|
|||
"soapbox_config.feed_injection_hint": "Inject the feed with additional content, such as suggested profiles.",
|
||||
"soapbox_config.feed_injection_label": "Feed injection",
|
||||
"soapbox_config.fields.crypto_addresses_label": "Cryptocurrency addresses",
|
||||
"soapbox_config.fields.edit_theme_label": "Éditer le thème",
|
||||
"soapbox_config.fields.home_footer_fields_label": "Home footer items",
|
||||
"soapbox_config.fields.logo_label": "Logo",
|
||||
"soapbox_config.fields.promo_panel_fields_label": "Promo panel items",
|
||||
|
@ -1020,6 +1182,7 @@
|
|||
"soapbox_config.greentext_label": "Enable greentext support",
|
||||
"soapbox_config.headings.advanced": "Advanced",
|
||||
"soapbox_config.headings.cryptocurrency": "Cryptocurrency",
|
||||
"soapbox_config.headings.events": "Évènements",
|
||||
"soapbox_config.headings.navigation": "Navigation",
|
||||
"soapbox_config.headings.options": "Options",
|
||||
"soapbox_config.headings.theme": "Theme",
|
||||
|
@ -1030,13 +1193,20 @@
|
|||
"soapbox_config.hints.promo_panel_icons.link": "Soapbox Icons List",
|
||||
"soapbox_config.home_footer.meta_fields.label_placeholder": "Label",
|
||||
"soapbox_config.home_footer.meta_fields.url_placeholder": "URL",
|
||||
"soapbox_config.media_preview_hint": "Certains backends offrent une version optimisée de médias pour l'affichage dans les délais. Cependant, ces images de prévisualisation peuvent être trop petites sans configuration supplémentaire.",
|
||||
"soapbox_config.media_preview_label": "Préférer les médias pour les vignettes",
|
||||
"soapbox_config.promo_panel.meta_fields.icon_placeholder": "Icon",
|
||||
"soapbox_config.promo_panel.meta_fields.label_placeholder": "Label",
|
||||
"soapbox_config.promo_panel.meta_fields.url_placeholder": "URL",
|
||||
"soapbox_config.raw_json_hint": "Edit the settings data directly. Changes made directly to the JSON file will override the form fields above. Click Save to apply your changes.",
|
||||
"soapbox_config.raw_json_invalid": "est invalide",
|
||||
"soapbox_config.raw_json_label": "Advanced: Edit raw JSON data",
|
||||
"soapbox_config.redirect_root_no_login_hint": "Chemin vers lequel rediriger la page d'accueil hors connexion.",
|
||||
"soapbox_config.redirect_root_no_login_label": "Rediriger la page d'accueil",
|
||||
"soapbox_config.save": "Save",
|
||||
"soapbox_config.saved": "Soapbox config saved!",
|
||||
"soapbox_config.tile_server_attribution_label": "Attribution des tuiles de carte",
|
||||
"soapbox_config.tile_server_label": "Serveur de tuiles de carte",
|
||||
"soapbox_config.verified_can_edit_name_label": "Allow verified users to edit their own display name.",
|
||||
"sponsored.info.message": "{siteTitle} displays ads to help fund our service.",
|
||||
"sponsored.info.title": "Why am I seeing this ad?",
|
||||
|
@ -1058,6 +1228,7 @@
|
|||
"status.favourite": "Ajouter aux favoris",
|
||||
"status.filtered": "Filtré",
|
||||
"status.interactions.favourites": "{count, plural, one {Like} other {Likes}}",
|
||||
"status.interactions.quotes": "{count, plural, one {Quote} other {Quotes}}",
|
||||
"status.interactions.reblogs": "{count, plural, one {Repost} other {Reposts}}",
|
||||
"status.load_more": "Charger plus",
|
||||
"status.mention": "Mentionner @{name}",
|
||||
|
@ -1125,6 +1296,13 @@
|
|||
"tabs_bar.profile": "Profile",
|
||||
"tabs_bar.search": "Chercher",
|
||||
"tabs_bar.settings": "Settings",
|
||||
"theme_editor.Reset": "Réinitialiser",
|
||||
"theme_editor.export": "Exporter le thème",
|
||||
"theme_editor.import": "Importer le thème",
|
||||
"theme_editor.import_success": "Le thème a été importé avec succès !",
|
||||
"theme_editor.restore": "Restaurer le thème par défaut",
|
||||
"theme_editor.save": "Sauvegarder le thème",
|
||||
"theme_editor.saved": "Thème mis à jour !",
|
||||
"theme_toggle.dark": "Dark",
|
||||
"theme_toggle.light": "Light",
|
||||
"theme_toggle.system": "System",
|
||||
|
@ -1137,6 +1315,7 @@
|
|||
"time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} restantes",
|
||||
"time_remaining.moments": "Encore quelques instants",
|
||||
"time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} restantes",
|
||||
"toast.view": "Voir",
|
||||
"trends.count_by_accounts": "{count} {rawCount, plural, one {personne} other {personnes}} discutent",
|
||||
"trends.title": "Trends",
|
||||
"trendsPanel.viewAll": "View all",
|
||||
|
|
|
@ -430,6 +430,9 @@
|
|||
"confirmations.block.confirm": "Conferma il blocco",
|
||||
"confirmations.block.heading": "Blocca @{name}",
|
||||
"confirmations.block.message": "Vuoi davvero bloccare {name}?",
|
||||
"confirmations.cancel.confirm": "Abbandona",
|
||||
"confirmations.cancel.heading": "Abbandona la pubblicazione",
|
||||
"confirmations.cancel.message": "Vuoi davvero abbandonare la creazione di questa pubblicazione?",
|
||||
"confirmations.cancel_editing.confirm": "Annulla modifiche",
|
||||
"confirmations.cancel_editing.heading": "Interrompi la pubblicazione di modifiche",
|
||||
"confirmations.cancel_editing.message": "Vuoi davvero annullare la modifica di questa pubblicazione? I cambiamenti verranno persi.",
|
||||
|
@ -496,6 +499,7 @@
|
|||
"developers.navigation.network_error_label": "Network error",
|
||||
"developers.navigation.service_worker_label": "Service Worker",
|
||||
"developers.navigation.settings_store_label": "Settings store",
|
||||
"developers.navigation.show_toast": "Attiva la notifica",
|
||||
"developers.navigation.test_timeline_label": "Timeline di prova",
|
||||
"developers.settings_store.advanced": "Impostazioni avanzate",
|
||||
"developers.settings_store.hint": "Poi modificare direttamente le tue impostazioni utente. Attenzione! Modificare questa sezione può danneggiare il tuo profilo, potresti soltanto recuperarlo tramite le API.",
|
||||
|
@ -826,6 +830,7 @@
|
|||
"missing_indicator.label": "Non trovato",
|
||||
"missing_indicator.sublabel": "Risorsa non trovata",
|
||||
"modals.policy.submit": "Accetta e continua",
|
||||
"modals.policy.updateTitle": "Ecco l'ultima versione di {siteTitle}! Prenditi un attimo di tempo per dare un'occhiata alle ultime interessanti novità che sono state introdotte.",
|
||||
"moderation_overlay.contact": "Contatto",
|
||||
"moderation_overlay.hide": "Nascondi il contenuto",
|
||||
"moderation_overlay.show": "Mostrami il contenuto",
|
||||
|
@ -1196,6 +1201,8 @@
|
|||
"soapbox_config.raw_json_hint": "Modifica direttamente le impostazioni. I cambiamenti scritti nel file JSON scavalcheranno i campi precedenti. Clicca Salva per applicare i cambiamenti.",
|
||||
"soapbox_config.raw_json_invalid": "non è valido",
|
||||
"soapbox_config.raw_json_label": "Modifica avanzata dei dati in formato JSON",
|
||||
"soapbox_config.redirect_root_no_login_hint": "Percorso in cui reindirizzare la pagina iniziale, quando i visitatori non sono autenticati.",
|
||||
"soapbox_config.redirect_root_no_login_label": "Reindirizza la pagina iniziale",
|
||||
"soapbox_config.save": "Salva",
|
||||
"soapbox_config.saved": "Hai salvato la configurazione di Soapbox!",
|
||||
"soapbox_config.tile_server_attribution_label": "Diritti della mappa",
|
||||
|
@ -1263,7 +1270,7 @@
|
|||
"status.unbookmarked": "Preferito rimosso.",
|
||||
"status.unmute_conversation": "Annulla silenzia conversazione",
|
||||
"status.unpin": "Non fissare in cima al profilo",
|
||||
"status_list.queue_label": "Leggi ancora {count} {count, plural, una {post} altre {posts}}",
|
||||
"status_list.queue_label": "Leggi ancora {count} {count, plural, one {pubblicazione} other {pubblicazioni}}",
|
||||
"statuses.quote_tombstone": "Pubblicazione non disponibile.",
|
||||
"statuses.tombstone": "Non è disponibile una o più pubblicazioni.",
|
||||
"streamfield.add": "Aggiungi",
|
||||
|
|
|
@ -21,11 +21,11 @@ import 'react-datepicker/dist/react-datepicker.css';
|
|||
|
||||
import '../soapbox/iframe';
|
||||
import '../styles/application.scss';
|
||||
import '../styles/tailwind.css';
|
||||
|
||||
import './precheck';
|
||||
import { default as Soapbox } from './containers/soapbox';
|
||||
import * as monitoring from './monitoring';
|
||||
import * as perf from './performance';
|
||||
import ready from './ready';
|
||||
import toast from './toast';
|
||||
|
||||
|
@ -34,8 +34,6 @@ const messages = defineMessages({
|
|||
updateText: { id: 'sw.update_text', defaultMessage: 'An update is available.' },
|
||||
});
|
||||
|
||||
perf.start('main()');
|
||||
|
||||
// Sentry
|
||||
monitoring.start();
|
||||
|
||||
|
@ -69,5 +67,4 @@ ready(() => {
|
|||
},
|
||||
});
|
||||
}
|
||||
perf.stop('main()');
|
||||
});
|
|
@ -140,6 +140,9 @@ export const normalizeInstance = (instance: Record<string, any>) => {
|
|||
return isNumber(value) ? value : getAttachmentLimit(software);
|
||||
});
|
||||
|
||||
// Urls can't be null, fix for Friendica
|
||||
if (instance.get('urls') === null) instance.delete('urls');
|
||||
|
||||
// Normalize version
|
||||
normalizeVersion(instance);
|
||||
fixTakahe(instance);
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
import * as BuildConfig from 'soapbox/build-config';
|
||||
|
||||
//
|
||||
// Tools for performance debugging, only enabled in development mode.
|
||||
// Open up Chrome Dev Tools, then Timeline, then User Timing to see output.
|
||||
// Also see config/webpack/loaders/mark.js for the webpack loader marks.
|
||||
//
|
||||
|
||||
let marky: any;
|
||||
|
||||
if (BuildConfig.NODE_ENV === 'development') {
|
||||
if (typeof performance !== 'undefined' && performance.setResourceTimingBufferSize) {
|
||||
// Increase Firefox's performance entry limit; otherwise it's capped to 150.
|
||||
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=1331135
|
||||
performance.setResourceTimingBufferSize(Infinity);
|
||||
}
|
||||
marky = require('marky');
|
||||
// allows us to easily do e.g. ReactPerf.printWasted() while debugging
|
||||
//window.ReactPerf = require('react-addons-perf');
|
||||
//window.ReactPerf.start();
|
||||
}
|
||||
|
||||
export function start(name: string): void {
|
||||
marky?.mark(name);
|
||||
}
|
||||
|
||||
export function stop(name: string): void {
|
||||
marky?.stop(name);
|
||||
}
|
|
@ -35,7 +35,7 @@ const deleteStatus = (state: State, idempotencyKey: string) => state.delete(idem
|
|||
export default function pending_statuses(state = initialState, action: AnyAction) {
|
||||
switch (action.type) {
|
||||
case STATUS_CREATE_REQUEST:
|
||||
return importStatus(state, ImmutableMap(fromJS(action.params)), action.idempotencyKey);
|
||||
return action.editing ? state : importStatus(state, ImmutableMap(fromJS(action.params)), action.idempotencyKey);
|
||||
case STATUS_CREATE_SUCCESS:
|
||||
return deleteStatus(state, action.idempotencyKey);
|
||||
default:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* eslint sort-keys: "error" */
|
||||
import { List as ImmutableList, Map as ImmutableMap } from 'immutable';
|
||||
import { createSelector } from 'reselect';
|
||||
import semverCoerce from 'semver/functions/coerce';
|
||||
import gte from 'semver/functions/gte';
|
||||
import lt from 'semver/functions/lt';
|
||||
import semverParse from 'semver/functions/parse';
|
||||
|
@ -15,18 +16,18 @@ const overrides = custom('features');
|
|||
/** Truthy array convenience function */
|
||||
const any = (arr: Array<any>): boolean => arr.some(Boolean);
|
||||
|
||||
/**
|
||||
* Friendica, decentralized social platform implementing multiple federation protocols.
|
||||
* @see {@link https://friendi.ca/}
|
||||
*/
|
||||
export const FRIENDICA = 'Friendica';
|
||||
|
||||
/**
|
||||
* Mastodon, the software upon which this is all based.
|
||||
* @see {@link https://joinmastodon.org/}
|
||||
*/
|
||||
export const MASTODON = 'Mastodon';
|
||||
|
||||
/**
|
||||
* Pleroma, a feature-rich alternative written in Elixir.
|
||||
* @see {@link https://pleroma.social/}
|
||||
*/
|
||||
export const PLEROMA = 'Pleroma';
|
||||
|
||||
/**
|
||||
* Mitra, a Rust backend with deep Ethereum integrations.
|
||||
* @see {@link https://codeberg.org/silverpill/mitra}
|
||||
|
@ -39,6 +40,18 @@ export const MITRA = 'Mitra';
|
|||
*/
|
||||
export const PIXELFED = 'Pixelfed';
|
||||
|
||||
/**
|
||||
* Pleroma, a feature-rich alternative written in Elixir.
|
||||
* @see {@link https://pleroma.social/}
|
||||
*/
|
||||
export const PLEROMA = 'Pleroma';
|
||||
|
||||
/**
|
||||
* Takahē, backend with support for serving multiple domains.
|
||||
* @see {@link https://jointakahe.org/}
|
||||
*/
|
||||
export const TAKAHE = 'Takahe';
|
||||
|
||||
/**
|
||||
* Truth Social, the Mastodon fork powering truthsocial.com
|
||||
* @see {@link https://help.truthsocial.com/open-source}
|
||||
|
@ -46,17 +59,9 @@ export const PIXELFED = 'Pixelfed';
|
|||
export const TRUTHSOCIAL = 'TruthSocial';
|
||||
|
||||
/**
|
||||
* Rebased, the recommended backend for Soapbox.
|
||||
* @see {@link https://gitlab.com/soapbox-pub/rebased}
|
||||
* Wildebeest, backend running on top of Cloudflare Pages.
|
||||
*/
|
||||
// NOTE: Rebased is named 'soapbox' for legacy reasons.
|
||||
export const REBASED = 'soapbox';
|
||||
|
||||
/**
|
||||
* glitch-soc, fork of Mastodon with a number of experimental features.
|
||||
* @see {@link https://glitch-soc.github.io/docs/}
|
||||
*/
|
||||
export const GLITCH = 'glitch';
|
||||
export const WILDEBEEST = 'Wildebeest';
|
||||
|
||||
/**
|
||||
* Akkoma, a Pleroma fork.
|
||||
|
@ -65,10 +70,17 @@ export const GLITCH = 'glitch';
|
|||
export const AKKOMA = 'akkoma';
|
||||
|
||||
/**
|
||||
* Takahē, backend with support for serving multiple domains.
|
||||
* @see {@link https://jointakahe.org/}
|
||||
* glitch-soc, fork of Mastodon with a number of experimental features.
|
||||
* @see {@link https://glitch-soc.github.io/docs/}
|
||||
*/
|
||||
export const TAKAHE = 'Takahe';
|
||||
export const GLITCH = 'glitch';
|
||||
|
||||
/**
|
||||
* Rebased, the recommended backend for Soapbox.
|
||||
* @see {@link https://gitlab.com/soapbox-pub/rebased}
|
||||
*/
|
||||
// NOTE: Rebased is named 'soapbox' for legacy reasons.
|
||||
export const REBASED = 'soapbox';
|
||||
|
||||
/** Parse features for the given instance */
|
||||
const getInstanceFeatures = (instance: Instance) => {
|
||||
|
@ -202,6 +214,7 @@ const getInstanceFeatures = (instance: Instance) => {
|
|||
* @see GET /api/v1/bookmarks
|
||||
*/
|
||||
bookmarks: any([
|
||||
v.software === FRIENDICA,
|
||||
v.software === MASTODON && gte(v.compatVersion, '3.1.0'),
|
||||
v.software === PLEROMA && gte(v.version, '0.9.9'),
|
||||
v.software === PIXELFED,
|
||||
|
@ -279,7 +292,7 @@ const getInstanceFeatures = (instance: Instance) => {
|
|||
|
||||
/**
|
||||
* Paginated chats API.
|
||||
* @see GET /api/v2/chats
|
||||
* @see GET /api/v2/pleroma/chats
|
||||
*/
|
||||
chatsV2: any([
|
||||
v.software === TRUTHSOCIAL,
|
||||
|
@ -296,6 +309,7 @@ const getInstanceFeatures = (instance: Instance) => {
|
|||
* @see {@link https://docs.joinmastodon.org/methods/timelines/conversations/}
|
||||
*/
|
||||
conversations: any([
|
||||
v.software === FRIENDICA,
|
||||
v.software === MASTODON && gte(v.compatVersion, '2.6.0'),
|
||||
v.software === PLEROMA && gte(v.version, '0.9.9'),
|
||||
v.software === PIXELFED,
|
||||
|
@ -307,16 +321,24 @@ const getInstanceFeatures = (instance: Instance) => {
|
|||
* @see GET /api/v1/timelines/direct
|
||||
*/
|
||||
directTimeline: any([
|
||||
v.software === FRIENDICA,
|
||||
v.software === MASTODON && lt(v.compatVersion, '3.0.0'),
|
||||
v.software === PLEROMA && gte(v.version, '0.9.9'),
|
||||
]),
|
||||
|
||||
/**
|
||||
* Ability to edit profile information.
|
||||
* @see PATCH /api/v1/accounts/update_credentials
|
||||
*/
|
||||
editProfile: any([
|
||||
v.software === FRIENDICA,
|
||||
v.software === MASTODON,
|
||||
v.software === MITRA,
|
||||
v.software === PIXELFED,
|
||||
v.software === PLEROMA,
|
||||
v.software === TAKAHE && gte(v.version, '0.7.0'),
|
||||
v.software === TRUTHSOCIAL,
|
||||
v.software === WILDEBEEST,
|
||||
]),
|
||||
|
||||
editStatuses: any([
|
||||
|
@ -469,6 +491,7 @@ const getInstanceFeatures = (instance: Instance) => {
|
|||
* @see GET /api/v1/timelines/list/:list_id
|
||||
*/
|
||||
lists: any([
|
||||
v.software === FRIENDICA,
|
||||
v.software === MASTODON && gte(v.compatVersion, '2.1.0'),
|
||||
v.software === PLEROMA && gte(v.version, '0.9.9'),
|
||||
]),
|
||||
|
@ -500,6 +523,7 @@ const getInstanceFeatures = (instance: Instance) => {
|
|||
*/
|
||||
mediaV2: any([
|
||||
v.software === MASTODON && gte(v.compatVersion, '3.1.3'),
|
||||
v.software === WILDEBEEST,
|
||||
// Even though Pleroma supports these endpoints, it has disadvantages
|
||||
// v.software === PLEROMA && gte(v.version, '2.1.0'),
|
||||
]),
|
||||
|
@ -581,6 +605,7 @@ const getInstanceFeatures = (instance: Instance) => {
|
|||
* @see {@link https://docs.joinmastodon.org/methods/instance/directory/}
|
||||
*/
|
||||
profileDirectory: any([
|
||||
v.software === FRIENDICA,
|
||||
v.software === MASTODON && gte(v.compatVersion, '3.0.0'),
|
||||
features.includes('profile_directory'),
|
||||
]),
|
||||
|
@ -600,9 +625,11 @@ const getInstanceFeatures = (instance: Instance) => {
|
|||
* @see GET /api/v1/timelines/public
|
||||
*/
|
||||
publicTimeline: any([
|
||||
v.software === FRIENDICA,
|
||||
v.software === MASTODON,
|
||||
v.software === PLEROMA,
|
||||
v.software === TAKAHE,
|
||||
v.software === WILDEBEEST,
|
||||
]),
|
||||
|
||||
/**
|
||||
|
@ -724,6 +751,7 @@ const getInstanceFeatures = (instance: Instance) => {
|
|||
* @see GET /api/v2/suggestions
|
||||
*/
|
||||
suggestionsV2: any([
|
||||
v.software === FRIENDICA,
|
||||
v.software === MASTODON && gte(v.compatVersion, '3.4.0'),
|
||||
v.software === TRUTHSOCIAL,
|
||||
features.includes('v2_suggestions'),
|
||||
|
@ -804,8 +832,9 @@ export const parseVersion = (version: string): Backend => {
|
|||
const regex = /^([\w+.]*)(?: \(compatible; ([\w]*) (.*)\))?$/;
|
||||
const match = regex.exec(version);
|
||||
|
||||
const semver = match ? semverParse(match[3] || match[1]) : null;
|
||||
const compat = match ? semverParse(match[1]) : null;
|
||||
const semverString = match && (match[3] || match[1]);
|
||||
const semver = match ? semverParse(semverString) || semverCoerce(semverString) : null;
|
||||
const compat = match ? semverParse(match[1]) || semverCoerce(match[1]) : null;
|
||||
|
||||
if (match && semver && compat) {
|
||||
return {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/** Convert HTML to a plaintext representation, preserving whitespace. */
|
||||
// NB: This function can still return unsafe HTML
|
||||
export const unescapeHTML = (html: string): string => {
|
||||
export const unescapeHTML = (html: string = ''): string => {
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.innerHTML = html.replace(/<br\s*\/?>/g, '\n').replace(/<\/p><[^>]*>/g, '\n\n').replace(/<[^>]*>/g, '');
|
||||
return wrapper.textContent || '';
|
||||
|
|
|
@ -57,28 +57,33 @@ enum VideoProviders {
|
|||
RUMBLE = 'rumble.com'
|
||||
}
|
||||
|
||||
/** Try adding autoplay to an iframe embed for platforms such as YouTube. */
|
||||
const addAutoPlay = (html: string): string => {
|
||||
const document = domParser.parseFromString(html, 'text/html').documentElement;
|
||||
const iframe = document.querySelector('iframe');
|
||||
|
||||
if (iframe) {
|
||||
const url = new URL(iframe.src);
|
||||
const provider = new URL(iframe.src).host;
|
||||
|
||||
if (provider === VideoProviders.RUMBLE) {
|
||||
url.searchParams.append('pub', '7a20');
|
||||
url.searchParams.append('autoplay', '2');
|
||||
} else {
|
||||
url.searchParams.append('autoplay', '1');
|
||||
url.searchParams.append('auto_play', '1');
|
||||
iframe.allow = 'autoplay';
|
||||
try {
|
||||
const document = domParser.parseFromString(html, 'text/html').documentElement;
|
||||
const iframe = document.querySelector('iframe');
|
||||
|
||||
if (iframe) {
|
||||
const url = new URL(iframe.src);
|
||||
const provider = new URL(iframe.src).host;
|
||||
|
||||
if (provider === VideoProviders.RUMBLE) {
|
||||
url.searchParams.append('pub', '7a20');
|
||||
url.searchParams.append('autoplay', '2');
|
||||
} else {
|
||||
url.searchParams.append('autoplay', '1');
|
||||
url.searchParams.append('auto_play', '1');
|
||||
iframe.allow = 'autoplay';
|
||||
}
|
||||
|
||||
iframe.src = url.toString();
|
||||
|
||||
// DOM parser creates html/body elements around original HTML fragment,
|
||||
// so we need to get innerHTML out of the body and not the entire document
|
||||
return (document.querySelector('body') as HTMLBodyElement).innerHTML;
|
||||
}
|
||||
|
||||
iframe.src = url.toString();
|
||||
|
||||
// DOM parser creates html/body elements around original HTML fragment,
|
||||
// so we need to get innerHTML out of the body and not the entire document
|
||||
return (document.querySelector('body') as HTMLBodyElement).innerHTML;
|
||||
} catch (e) {
|
||||
return html;
|
||||
}
|
||||
|
||||
return html;
|
||||
|
|
|
@ -35,63 +35,6 @@
|
|||
@import 'components/crypto-donate';
|
||||
@import 'components/aliases';
|
||||
@import 'components/icon';
|
||||
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer utilities {
|
||||
.break-word-nested > p {
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.shadow-inset {
|
||||
box-shadow: inset 0 0 0 1px rgb(255 255 255 / 10%);
|
||||
}
|
||||
|
||||
.truncate-child > * {
|
||||
@apply truncate;
|
||||
}
|
||||
|
||||
.d-screen {
|
||||
height: 100vh; // Backwards compatibility
|
||||
/* stylelint-disable-next-line unit-no-unknown */
|
||||
height: 100dvh;
|
||||
}
|
||||
|
||||
.bg-gradient-light {
|
||||
background: linear-gradient(
|
||||
115deg,
|
||||
rgba(0, 0, 0, 0) 0%,
|
||||
rgba(0, 0, 0, 0) 20%,
|
||||
rgba(var(--color-gradient-start) / 0.1) 35%,
|
||||
rgba(var(--color-gradient-end) / 0.1) 70%,
|
||||
rgba(0, 0, 0, 0) 80%,
|
||||
rgba(0, 0, 0, 0) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.bg-gradient-dark {
|
||||
background: linear-gradient(
|
||||
115deg,
|
||||
rgba(0, 0, 0, 0) 0%,
|
||||
rgba(0, 0, 0, 0) 30%,
|
||||
rgba(var(--color-gradient-start) / 0.1) 45%,
|
||||
rgba(var(--color-gradient-start) / 0.2) 55%,
|
||||
rgba(0, 0, 0, 0) 70%,
|
||||
rgba(0, 0, 0, 0) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.bg-gradient-sm {
|
||||
background: linear-gradient(
|
||||
112deg,
|
||||
rgba(var(--color-gradient-start) / 0.1) 0%,
|
||||
rgba(var(--color-gradient-end) / 0.1) 50%
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@import 'forms';
|
||||
@import 'utilities';
|
||||
@import 'components/datepicker';
|
||||
|
|
55
app/styles/tailwind.css
Normal file
55
app/styles/tailwind.css
Normal file
|
@ -0,0 +1,55 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer utilities {
|
||||
.break-word-nested > p {
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.shadow-inset {
|
||||
box-shadow: inset 0 0 0 1px rgb(255 255 255 / 10%);
|
||||
}
|
||||
|
||||
.truncate-child > * {
|
||||
@apply truncate;
|
||||
}
|
||||
|
||||
.d-screen {
|
||||
height: 100vh; /* Backwards compatibility */
|
||||
/* stylelint-disable-next-line unit-no-unknown */
|
||||
height: 100dvh;
|
||||
}
|
||||
|
||||
.bg-gradient-light {
|
||||
background: linear-gradient(
|
||||
115deg,
|
||||
rgba(0, 0, 0, 0) 0%,
|
||||
rgba(0, 0, 0, 0) 20%,
|
||||
rgba(var(--color-gradient-start) / 0.1) 35%,
|
||||
rgba(var(--color-gradient-end) / 0.1) 70%,
|
||||
rgba(0, 0, 0, 0) 80%,
|
||||
rgba(0, 0, 0, 0) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.bg-gradient-dark {
|
||||
background: linear-gradient(
|
||||
115deg,
|
||||
rgba(0, 0, 0, 0) 0%,
|
||||
rgba(0, 0, 0, 0) 30%,
|
||||
rgba(var(--color-gradient-start) / 0.1) 45%,
|
||||
rgba(var(--color-gradient-start) / 0.2) 55%,
|
||||
rgba(0, 0, 0, 0) 70%,
|
||||
rgba(0, 0, 0, 0) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.bg-gradient-sm {
|
||||
background: linear-gradient(
|
||||
112deg,
|
||||
rgba(var(--color-gradient-start) / 0.1) 0%,
|
||||
rgba(var(--color-gradient-end) / 0.1) 50%
|
||||
);
|
||||
}
|
||||
}
|
|
@ -18,6 +18,8 @@ module.exports = {
|
|||
],
|
||||
'collectCoverageFrom': [
|
||||
'app/soapbox/**/*.js',
|
||||
'app/soapbox/**/*.cjs',
|
||||
'app/soapbox/**/*.mjs',
|
||||
'app/soapbox/**/*.ts',
|
||||
'app/soapbox/**/*.tsx',
|
||||
'!app/soapbox/features/emoji/emoji-compressed.js',
|
||||
|
@ -43,6 +45,6 @@ module.exports = {
|
|||
],
|
||||
'transform': {
|
||||
'\\.[jt]sx?$': 'babel-jest',
|
||||
[`\\.(${ASSET_EXTS})$`]: '<rootDir>/jest/assetTransformer.js',
|
||||
[`\\.(${ASSET_EXTS})$`]: '<rootDir>/jest/assetTransformer.cjs',
|
||||
},
|
||||
};
|
|
@ -25,7 +25,7 @@
|
|||
"test:coverage": "${npm_execpath} run test --coverage",
|
||||
"test:all": "${npm_execpath} run test:coverage && ${npm_execpath} run lint",
|
||||
"lint": "${npm_execpath} run lint:js && ${npm_execpath} run lint:sass",
|
||||
"lint:js": "npx eslint --ext .js,.jsx,.ts,.tsx . --cache",
|
||||
"lint:js": "npx eslint --ext .js,.jsx,.cjs,.mjs,.ts,.tsx . --cache",
|
||||
"lint:sass": "npx stylelint app/styles/**/*.scss",
|
||||
"prepare": "husky install"
|
||||
},
|
||||
|
@ -135,8 +135,6 @@
|
|||
"line-awesome": "^1.3.0",
|
||||
"localforage": "^1.10.0",
|
||||
"lodash": "^4.7.11",
|
||||
"mark-loader": "^0.1.6",
|
||||
"marky": "^1.2.4",
|
||||
"mini-css-extract-plugin": "^2.6.0",
|
||||
"path-browserify": "^1.0.1",
|
||||
"postcss": "^8.4.14",
|
||||
|
@ -160,6 +158,7 @@
|
|||
"react-popper": "^2.3.0",
|
||||
"react-redux": "^8.0.0",
|
||||
"react-router-dom": "^5.3.0",
|
||||
"react-router-dom-v5-compat": "^6.6.2",
|
||||
"react-router-scroll-4": "^1.0.0-beta.2",
|
||||
"react-simple-pull-to-refresh": "^1.3.3",
|
||||
"react-sparklines": "^1.7.0",
|
||||
|
@ -176,7 +175,7 @@
|
|||
"sass": "^1.20.3",
|
||||
"sass-loader": "^13.0.0",
|
||||
"seedrandom": "^3.0.5",
|
||||
"semver": "^7.3.2",
|
||||
"semver": "^7.3.8",
|
||||
"stringz": "^2.0.0",
|
||||
"substring-trie": "^1.0.2",
|
||||
"terser-webpack-plugin": "^5.2.3",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const { parseColorMatrix } = require('./tailwind/colors');
|
||||
const { parseColorMatrix } = require('./tailwind/colors.cjs');
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
|
@ -1,7 +1,7 @@
|
|||
import {
|
||||
withOpacityValue,
|
||||
parseColorMatrix,
|
||||
} from '../colors';
|
||||
} from '../colors.cjs';
|
||||
|
||||
describe('withOpacityValue()', () => {
|
||||
it('returns a Tailwind color function with alpha support', () => {
|
||||
|
|
|
@ -12,7 +12,7 @@ const settings = {
|
|||
test_root_path: `${FE_BUILD_DIR}-test`,
|
||||
cache_path: 'tmp/cache',
|
||||
resolved_paths: [],
|
||||
extensions: [ '.mjs', '.js', '.jsx', '.ts', '.tsx', '.sass', '.scss', '.css', '.module.sass', '.module.scss', '.module.css', '.png', '.svg', '.gif', '.jpeg', '.jpg' ],
|
||||
extensions: [ '.js', '.jsx', '.cjs', '.mjs', '.ts', '.tsx', '.sass', '.scss', '.css', '.module.sass', '.module.scss', '.module.css', '.png', '.svg', '.gif', '.jpeg', '.jpg' ],
|
||||
};
|
||||
|
||||
const outputDir = env.NODE_ENV === 'test' ? settings.test_root_path : settings.public_root_path;
|
||||
|
|
|
@ -7,7 +7,7 @@ import type { RuleSetRule } from 'webpack';
|
|||
const isDevelopment = process.env.NODE_ENV === 'development';
|
||||
|
||||
const rule: RuleSetRule = {
|
||||
test: /\.(js|jsx|mjs|ts|tsx)$/,
|
||||
test: /\.(js|jsx|cjs|mjs|ts|tsx)$/,
|
||||
include: [
|
||||
settings.source_path,
|
||||
...settings.resolved_paths,
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
import { env } from 'process';
|
||||
|
||||
import type { RuleSetRule } from 'webpack';
|
||||
|
||||
let rule: RuleSetRule = {};
|
||||
|
||||
if (env.NODE_ENV !== 'production') {
|
||||
rule = {
|
||||
test: /\.js$/,
|
||||
loader: 'mark-loader',
|
||||
};
|
||||
}
|
||||
|
||||
export default rule;
|
51
yarn.lock
51
yarn.lock
|
@ -1273,6 +1273,13 @@
|
|||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/runtime@^7.7.6":
|
||||
version "7.20.7"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.7.tgz#fcb41a5a70550e04a7b708037c7c32f7f356d8fd"
|
||||
integrity sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.11"
|
||||
|
||||
"@babel/template@7", "@babel/template@^7.15.4", "@babel/template@^7.16.7", "@babel/template@^7.3.3":
|
||||
version "7.16.7"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155"
|
||||
|
@ -2256,6 +2263,11 @@
|
|||
redux-thunk "^2.4.1"
|
||||
reselect "^4.1.5"
|
||||
|
||||
"@remix-run/router@1.2.1":
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.2.1.tgz#812edd4104a15a493dda1ccac0b352270d7a188c"
|
||||
integrity sha512-XiY0IsyHR+DXYS5vBxpoBe/8veTeoRpMHP+vDosLZxL5bnpetzI0igkxkLZS235ldLzyfkxF+2divEwWHP3vMQ==
|
||||
|
||||
"@sentry/browser@7.11.1", "@sentry/browser@^7.11.1":
|
||||
version "7.11.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.11.1.tgz#377d417e833ef54c78a93ef720a742bda5022625"
|
||||
|
@ -6280,6 +6292,13 @@ history@^4.9.0:
|
|||
tiny-warning "^1.0.0"
|
||||
value-equal "^1.0.1"
|
||||
|
||||
history@^5.3.0:
|
||||
version "5.3.0"
|
||||
resolved "https://registry.yarnpkg.com/history/-/history-5.3.0.tgz#1548abaa245ba47992f063a0783db91ef201c73b"
|
||||
integrity sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.7.6"
|
||||
|
||||
hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
|
||||
version "3.3.2"
|
||||
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
|
||||
|
@ -8014,16 +8033,6 @@ map-obj@^4.0.0:
|
|||
resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.2.1.tgz#e4ea399dbc979ae735c83c863dd31bdf364277b7"
|
||||
integrity sha512-+WA2/1sPmDj1dlvvJmB5G6JKfY9dpn7EVBUL06+y6PoljPkh+6V1QihwxNkbcGxCRjt2b0F9K0taiCuo7MbdFQ==
|
||||
|
||||
mark-loader@^0.1.6:
|
||||
version "0.1.6"
|
||||
resolved "https://registry.yarnpkg.com/mark-loader/-/mark-loader-0.1.6.tgz#0abb477dca7421d70e20128ff6489f5cae8676d5"
|
||||
integrity sha1-CrtHfcp0IdcOIBKP9kifXK6GdtU=
|
||||
|
||||
marky@^1.2.4:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/marky/-/marky-1.2.4.tgz#d02bb4c08be2366687c778ecd2a328971ce23d7f"
|
||||
integrity sha512-zd2/GiSn6U3/jeFVZ0J9CA1LzQ8RfIVvXkb/U0swFHF/zT+dVohTAWjmo2DcIuofmIIIROlwTbd+shSeXmxr0w==
|
||||
|
||||
material-colors@^1.2.1:
|
||||
version "1.2.6"
|
||||
resolved "https://registry.yarnpkg.com/material-colors/-/material-colors-1.2.6.tgz#6d1958871126992ceecc72f4bcc4d8f010865f46"
|
||||
|
@ -9557,6 +9566,14 @@ react-refresh@^0.14.0:
|
|||
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e"
|
||||
integrity sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==
|
||||
|
||||
react-router-dom-v5-compat@^6.6.2:
|
||||
version "6.6.2"
|
||||
resolved "https://registry.yarnpkg.com/react-router-dom-v5-compat/-/react-router-dom-v5-compat-6.6.2.tgz#e8a985dd6092885305e0b04aa141f659b282e25f"
|
||||
integrity sha512-YpumAAZlXfgSOEBnEwvPfI68tAsWvhXHY9grFVprIluff/X7CjNNU0dWHwOmyY7Q+8kFi34NcAhCEYzUCaJbBQ==
|
||||
dependencies:
|
||||
history "^5.3.0"
|
||||
react-router "6.6.2"
|
||||
|
||||
react-router-dom@^5.3.0:
|
||||
version "5.3.0"
|
||||
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.3.0.tgz#da1bfb535a0e89a712a93b97dd76f47ad1f32363"
|
||||
|
@ -9594,6 +9611,13 @@ react-router@5.2.1:
|
|||
tiny-invariant "^1.0.2"
|
||||
tiny-warning "^1.0.0"
|
||||
|
||||
react-router@6.6.2:
|
||||
version "6.6.2"
|
||||
resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.6.2.tgz#556f7b56cff7fe32c5c02429fef3fcb2ecd08111"
|
||||
integrity sha512-uJPG55Pek3orClbURDvfljhqFvMgJRo59Pktywkk8hUUkTY2aRfza8Yhl/vZQXs+TNQyr6tu+uqz/fLxPICOGQ==
|
||||
dependencies:
|
||||
"@remix-run/router" "1.2.1"
|
||||
|
||||
react-side-effect@^2.1.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-2.1.1.tgz#66c5701c3e7560ab4822a4ee2742dee215d72eb3"
|
||||
|
@ -9838,6 +9862,11 @@ regenerator-runtime@^0.12.0:
|
|||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de"
|
||||
integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==
|
||||
|
||||
regenerator-runtime@^0.13.11:
|
||||
version "0.13.11"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
|
||||
integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
|
||||
|
||||
regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.9:
|
||||
version "0.13.9"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
|
||||
|
@ -10191,7 +10220,7 @@ semver@7.0.0:
|
|||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e"
|
||||
integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==
|
||||
|
||||
semver@7.3.5, semver@7.x, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5:
|
||||
semver@7.3.5, semver@7.x, semver@^7.3.4, semver@^7.3.5:
|
||||
version "7.3.5"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
|
||||
integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
|
||||
|
|
Loading…
Reference in a new issue