Merge commit 'b902c825054b953599cd0341acf428332fca5044' into glitch-soc/merge-upstream

This commit is contained in:
Claire committed 2026-06-12 18:37:02 +02:00
commit 08027edb10
76 files changed
+914 -690

No files matched your search

@@ -30,8 +30,8 @@ export const HoverCardController: React.FC = () => {
const cardRef = useRef<HTMLDivElement | null>(null);
const [setLeaveTimeout, cancelLeaveTimeout] = useTimeout();
const [setEnterTimeout, cancelEnterTimeout, delayEnterTimeout] = useTimeout();
const [setMoveTimeout, cancelMoveTimeout] = useTimeout();
const [setScrollTimeout] = useTimeout();
const lastMouseMoveTime = useRef<number>(0);
const handleClose = useCallback(() => {
cancelEnterTimeout();
@@ -50,7 +50,6 @@ export const HoverCardController: React.FC = () => {
useEffect(() => {
let isScrolling = false;
let isUsingTouch = false;
let isActiveMouseMovement = false;
let currentAnchor: HTMLElement | null = null;
let currentTitle: string | null = null;
@@ -84,31 +83,40 @@ export const HoverCardController: React.FC = () => {
return;
}
// Bail out if we're scrolling, a touch is active,
// or if there was no active mouse movement
if (isScrolling || !isActiveMouseMovement || isUsingTouch) {
return;
}
// This 0ms timeout is needed to push processing of this code
// until after the mousemove event was run, in order to be able
// to track the most recent value of lastMouseMoveTime.current
setTimeout(() => {
// Check if mouse moved within the active movement threshold
const timeSinceLastMove = Date.now() - lastMouseMoveTime.current;
const hasRecentMovement = timeSinceLastMove < activeMovementThreshold;
// We've entered an anchor
if (isHoverCardAnchor(target)) {
cancelLeaveTimeout();
// Bail out if we're scrolling, a touch is active,
// or if there was no active mouse movement
if (isScrolling || !hasRecentMovement || isUsingTouch) {
return;
}
currentAnchor?.removeAttribute('aria-describedby');
currentAnchor = target;
// We've entered an anchor
if (isHoverCardAnchor(target)) {
cancelLeaveTimeout();
currentTitle = target.getAttribute('title');
target.removeAttribute('title');
currentAnchor?.removeAttribute('aria-describedby');
currentAnchor = target;
setEnterTimeout(() => {
open(target);
}, enterDelay);
}
currentTitle = target.getAttribute('title');
target.removeAttribute('title');
// We've entered the hover card
if (target === currentAnchor || target === cardRef.current) {
cancelLeaveTimeout();
}
setEnterTimeout(() => {
open(target);
}, enterDelay);
}
// We've entered the hover card
if (target === currentAnchor || target === cardRef.current) {
cancelLeaveTimeout();
}
}, 0);
};
const handleMouseLeave = (e: MouseEvent) => {
@@ -149,18 +157,15 @@ export const HoverCardController: React.FC = () => {
isUsingTouch = false;
}
const hasMoved = Math.max(e.movementX, e.movementY) > 0;
const hasMoved =
Math.max(Math.abs(e.movementX), Math.abs(e.movementY)) > 0;
if (!hasMoved) {
return;
}
delayEnterTimeout(enterDelay);
cancelMoveTimeout();
isActiveMouseMovement = true;
setMoveTimeout(() => {
isActiveMouseMovement = false;
}, activeMovementThreshold);
lastMouseMoveTime.current = Date.now();
};
document.body.addEventListener('touchstart', handleTouchStart, {
@@ -204,8 +209,6 @@ export const HoverCardController: React.FC = () => {
setOpen,
setAccountId,
setAnchor,
setMoveTimeout,
cancelMoveTimeout,
]);
return (
@@ -3,6 +3,7 @@ import { useCallback, useId, useState } from 'react';
import { FormattedMessage, useIntl, defineMessages } from 'react-intl';
import type { ApiCollectionJSON } from '@/mastodon/api_types/collections';
import { EmptyState } from '@/mastodon/components/empty_state';
import { LoadingIndicator } from '@/mastodon/components/loading_indicator';
import { NavigationFocusTarget } from '@/mastodon/components/navigation_focus_target';
import { useCurrentAccountId } from '@/mastodon/hooks/useAccountId';
@@ -16,7 +17,10 @@ import { IconButton } from 'mastodon/components/icon_button';
import { useAppDispatch, useAppSelector } from 'mastodon/store';
import { MAX_COLLECTION_ACCOUNT_COUNT } from '../collections/editor/accounts';
import { useCollectionsCreatedBy } from '../collections/overview/created_by_account';
import {
NewCollectionButton,
useCollectionsCreatedBy,
} from '../collections/overview/created_by_account';
import { CollectionToggle } from './collection_toggle';
@@ -136,6 +140,23 @@ export const CollectionAdder: React.FC<{
>
{status === 'loading' || !account ? (
<LoadingIndicator />
) : collections.length === 0 ? (
<EmptyState
title={
<FormattedMessage
id='empty_column.collections_self'
defaultMessage='You have not created any collections yet.'
/>
}
message={
<FormattedMessage
id='empty_column.account_featured_self.showcase_accounts_desc'
defaultMessage='Collections are curated lists of accounts to help others discover more of the Fediverse.'
/>
}
>
<NewCollectionButton onClick={onClose} />
</EmptyState>
) : (
collections.map((item) => (
<ListItem key={item.id} collection={item} account={account} />
@@ -19,7 +19,7 @@ const messages = defineMessages({
revokeCollectionInclusionMessage: {
id: 'confirmations.revoke_collection_inclusion.message',
defaultMessage:
"This action is permanent, and the curator won't be able to re-add you to the collection later on.",
"The curator won't be able to re-add you to this collection for 24 hours. To prevent them from adding you to collections permanently, you can block them.",
},
revokeCollectionInclusionConfirm: {
id: 'confirmations.revoke_collection_inclusion.confirm',
@@ -26,8 +26,14 @@ import {
} from '../editor';
import classes from '../styles.module.scss';
const CreateButton: React.FC = () => (
<Link to='/collections/new' className='button button--compact'>
export const NewCollectionButton: React.FC<{ onClick?: () => void }> = ({
onClick,
}) => (
<Link
to='/collections/new'
className='button button--compact'
onClick={onClick}
>
<Icon id='plus' icon={AddIcon} />
<FormattedMessage {...editorMessages.newCollection} />
</Link>
@@ -97,7 +103,7 @@ export const CollectionsCreatedByAccount: React.FC = () => {
/>
}
>
<CreateButton />
<NewCollectionButton />
</EmptyState>
);
} else {
@@ -129,7 +135,7 @@ export const CollectionsCreatedByAccount: React.FC = () => {
}}
/>
</h2>
{showCreateButton && <CreateButton />}
{showCreateButton && <NewCollectionButton />}
</div>
<ItemList>
{isOwnCollectionPage && !canCreateMoreCollections && (
@@ -316,8 +316,8 @@ class ComposeForm extends ImmutablePureComponent {
className='compose-form__input'
/>
<UploadForm />
<PollForm />
<UploadForm />
<ComposeQuotedStatus />
<div className='compose-form__footer'>
@@ -5,6 +5,7 @@ import { customEmojiFactory, unicodeEmojiFactory } from '@/testing/factories';
import {
putEmojiData,
search,
loadEmojiByHexcode,
testClear,
testGet,
@@ -31,6 +32,108 @@ describe('emoji database', () => {
indexedDB = new IDBFactory();
});
describe('search', () => {
beforeEach(async () => {
await putEmojiData([], 'en');
});
test('test no query tokens', async () => {
await putEmojiData([rawEmojiFactory()], 'en');
await expect(search({ query: ' ', locale: 'en' })).resolves.toEqual([]);
});
test('unicode results', async () => {
await putEmojiData(
[
rawEmojiFactory({
hexcode: 'unicode_hex',
label: 'Party Popper',
shortcodes: ['party_popper'],
unicode: '🎉',
}),
],
'en',
);
await expect(
search({ query: 'party', locale: 'en' }),
).resolves.toContainEqual(
expect.objectContaining({
hexcode: 'unicode_hex',
}),
);
});
test('custom results', async () => {
await putCustomEmojiData({
emojis: [customEmojiFactory({ shortcode: 'party_custom' })],
});
await expect(
search({ query: 'party', locale: 'en' }),
).resolves.toContainEqual(
expect.objectContaining({
shortcode: 'party_custom',
}),
);
});
test('shortcode results', async () => {
await putEmojiData([rawEmojiFactory()], 'en');
await putLegacyShortcodes({
test: ['legacy_smile'],
});
await expect(
search({ query: 'legacy', locale: 'en' }),
).resolves.toContainEqual(
expect.objectContaining({
hexcode: 'test',
}),
);
});
test('full custom emoji search', async () => {
await putCustomEmojiData({
emojis: [
customEmojiFactory({ shortcode: 'arrow' }),
customEmojiFactory({ shortcode: 'party_parrot' }),
],
});
const result = await search({ query: 'arro', locale: 'en' });
expect(result).toContainEqual(
// Test for ordinary IDB search
expect.objectContaining({
shortcode: 'arrow',
}),
);
expect(result).toContainEqual(
// Test for manual iteration search
expect.objectContaining({
shortcode: 'party_parrot',
}),
);
});
test('limit test', async () => {
await putCustomEmojiData({
emojis: [
customEmojiFactory({ shortcode: 'limit' }),
customEmojiFactory({ shortcode: 'limit_extra' }),
],
});
await expect(
search({ query: 'limit', locale: 'en', limit: 1 }),
).resolves.toEqual([
expect.objectContaining({
shortcode: 'limit',
}),
]);
});
});
describe('putEmojiData', () => {
test('adds to loaded locales', async () => {
const { loadedLocales } = await testGet();
@@ -12,7 +12,7 @@ import {
transformCustomEmojiData,
transformEmojiData,
} from './normalize';
import type { AnyEmojiData, CacheKey } from './types';
import type { AnyEmojiData, CacheKey, CustomEmojiData } from './types';
import { emojiLogger } from './utils';
const loadedLocales = new Set<Locale>();
@@ -78,6 +78,8 @@ export async function search({
// Create an array of emoji results
const db = await loadDB();
const resultArrays: ScoreMap[] = [];
const existingCustomShortcodes = new Set<string>();
for (let i = 0; i < queryTokens.length; i++) {
const token = queryTokens[i];
if (!token) continue;
@@ -96,6 +98,7 @@ export async function search({
],
);
const resultMap: ScoreMap = new Map();
for (const emoji of unicodeResults) {
const score = getScoreForEmoji(emoji, token);
if (score === null) {
@@ -103,11 +106,13 @@ export async function search({
}
resultMap.set(emoji.hexcode, { ...emoji, score });
}
for (const emoji of customResults) {
const score = getScoreForEmoji(emoji, token);
if (score === null) {
continue;
}
existingCustomShortcodes.add(emoji.shortcode);
resultMap.set(emoji.shortcode, { ...emoji, score });
}
@@ -119,7 +124,14 @@ export async function search({
if (!emoji) {
continue;
}
const score = getScoreForEmoji(emoji, token);
// Score the emoji with the legacy shortcode, even though it's not part of the emoji.
const score = getScoreForEmoji(
{
...emoji,
shortcodes: [...shortcodeResult.shortcodes, ...emoji.shortcodes],
},
token,
);
if (score === null) {
continue;
}
@@ -146,21 +158,19 @@ export async function search({
);
// If there are no results, try a cursor-based custom emoji search instead.
if (results.length === 0) {
const trx = db.transaction('custom', 'readonly');
const foundEmojis = new Set<string>();
for await (const cursor of trx.store) {
const emoji = cursor.value;
const score = getScoreForEmoji(emoji, query, false);
if (score === null || foundEmojis.has(emoji.shortcode)) {
continue;
}
results.push({ ...emoji, score });
foundEmojis.add(emoji.shortcode);
if (results.length === 0 || results.length < limit) {
const customEmojisFound = await fullCustomSearch(
query,
existingCustomShortcodes,
);
if (customEmojisFound.length > 0) {
log(
'cursor search found %d results for "%s"',
customEmojisFound.length,
query,
);
results.push(...customEmojisFound);
}
log('cursor search found %d results for "%s"', foundEmojis.size, query);
await trx.done;
}
// Sort by score, descending.
@@ -191,7 +201,14 @@ function getScoreForEmoji(
}
let index = 1;
const searchTokens = checkTokens ? [id, ...emoji.tokens] : [id];
const searchTokens = [id];
if (checkTokens) {
// Check shortcodes before tokens as they are more important.
if ('shortcodes' in emoji) {
searchTokens.push(...emoji.shortcodes);
}
searchTokens.push(...emoji.tokens);
}
for (const token of searchTokens) {
const tokenIndex = token.indexOf(query);
if (tokenIndex !== -1) {
@@ -203,6 +220,51 @@ function getScoreForEmoji(
return null;
}
async function fullCustomSearch(query: string, existing = new Set<string>()) {
const db = await loadDB();
const trx = db.transaction('custom', 'readonly');
const foundEmojis = new Set<string>();
// First iterate over chunks of 1,000 custom emoji keys and find any matches.
const chunkSize = 1_000;
let lastKey: string | null = null;
let keys: string[] = [];
do {
const keyRange = lastKey ? IDBKeyRange.lowerBound(lastKey, true) : null;
keys = await trx.store.getAllKeys(keyRange, chunkSize);
if (keys.length === 0) {
break;
}
log('cursor search got batch of %d emojis', keys.length);
lastKey = keys.at(-1) ?? null;
for (const key of keys) {
if (!foundEmojis.has(key) && !existing.has(key) && key.includes(query)) {
foundEmojis.add(key);
}
}
} while (keys.length === chunkSize);
// Next get the full emojis for all matches.
const emojis = await Promise.all(
foundEmojis.keys().map((key) => trx.store.get(key)),
);
const results: (CustomEmojiData & { score: number })[] = [];
for (const emoji of emojis) {
if (emoji) {
const score = getScoreForEmoji(emoji, query, false);
if (score && score > 0) {
results.push({
score,
...emoji,
});
}
}
}
return results;
}
export async function putEmojiData(emojis: CompactEmoji[], locale: Locale) {
loadedLocales.add(locale);
const db = await loadDB();
+1
View File
@@ -649,6 +649,7 @@
"empty_column.collections": "{acct} пакуль не стварыў(-ла) аніводнай калекцыі.",
"empty_column.collections.featured_in": "Вас пакуль не дадалі ў ніякія калекцыі.",
"empty_column.collections.featured_in_undiscoverable": "Каб людзі маглі дадаваць Вас у калекцыі, Вам трэба даць ім дазвол знаходзіць Вас у <link>Налады > Прыватнасць і пошук</link>",
"empty_column.collections_self": "Вы пакуль не стварылі ніводнай калекцыі.",
"empty_column.community": "Мясцовая стужка пустая. Напішыце нешта публічнае, каб разварушыць справу!",
"empty_column.direct": "Пакуль у Вас няма асабістых згадванняў. Калі Вы дашляце або атрымаеце штосьці, яно з’явіцца тут.",
"empty_column.disabled_feed": "Гэта стужка была адключаная Вашымі адміністратарамі сервера.",
+1
View File
@@ -649,6 +649,7 @@
"empty_column.collections": "{acct} har endnu ikke oprettet nogen samlinger.",
"empty_column.collections.featured_in": "Du er ikke blevet tilføjet til nogen samlinger endnu.",
"empty_column.collections.featured_in_undiscoverable": "For at andre kan føje dig til samlinger, skal du give tilladelse til at blive vist i opdagelsesfunktioner under <link>Præferencer > Fortrolighed og rækkevidde</link>",
"empty_column.collections_self": "Du har endnu ikke oprettet nogen samlinger.",
"empty_column.community": "Den lokale tidslinje er tom. Skriv noget offentligt for at sætte tingene i gang!",
"empty_column.direct": "Du har ikke nogen private omtaler endnu. Når du sender eller modtager en, vil den blive vist her.",
"empty_column.disabled_feed": "Dette feed er blevet deaktiveret af dine serveradministratorer.",
+1
View File
@@ -649,6 +649,7 @@
"empty_column.collections": "{acct} hat noch keine Sammlungen erstellt.",
"empty_column.collections.featured_in": "Du wurdest noch keiner Sammlung hinzugefügt.",
"empty_column.collections.featured_in_undiscoverable": "Damit du zu Sammlungen hinzugefügt werden kannst, muss „Mich beim Entdecken berücksichtigen“ unter <link>Einstellungen > Datenschutz und Reichweite</link> aktiviert werden",
"empty_column.collections_self": "Du hast noch keine Sammlungen erstellt.",
"empty_column.community": "Die lokale Timeline ist leer. Schreibe einen öffentlichen Beitrag, um den Stein ins Rollen zu bringen!",
"empty_column.direct": "Du hast noch keine privaten Erwähnungen. Sobald du eine sendest oder erhältst, wird sie hier erscheinen.",
"empty_column.disabled_feed": "Diesen Feed haben deine Server-Administrator*innen deaktiviert.",
+1
View File
@@ -649,6 +649,7 @@
"empty_column.collections": "Ο χρήστης {acct} δεν έχει δημιουργήσει ακόμη καμία συλλογή.",
"empty_column.collections.featured_in": "Δεν έχετε προστεθεί ακόμη σε καμία συλλογή.",
"empty_column.collections.featured_in_undiscoverable": "Προκειμένου ο κόσμος να σας προσθέσει σε συλλογές, πρέπει να επιτρέψετε την ανάδειξή σας σε εμπειρίες ανακάλυψης από τις <link>Προτιμήσεις > Ιδιωτικότητα και προσιτότητα</link>",
"empty_column.collections_self": "Δεν έχετε δημιουργήσει ακόμη καμία συλλογή.",
"empty_column.community": "Η τοπική ροή είναι κενή. Γράψε κάτι δημόσια για να αρχίσει να κυλά η μπάλα!",
"empty_column.direct": "Δεν έχεις καμία ιδιωτική επισήμανση ακόμη. Όταν στείλεις ή λάβεις μία, θα εμφανιστεί εδώ.",
"empty_column.disabled_feed": "Αυτή η ροή έχει απενεργοποιηθεί από τους διαχειριστές του διακομιστή σας.",
+2 -1
View File
@@ -561,7 +561,7 @@
"confirmations.remove_from_followers.message": "{name} will stop following you. Are you sure you want to proceed?",
"confirmations.remove_from_followers.title": "Remove follower?",
"confirmations.revoke_collection_inclusion.confirm": "Remove me",
"confirmations.revoke_collection_inclusion.message": "This action is permanent, and the curator won't be able to re-add you to the collection later on.",
"confirmations.revoke_collection_inclusion.message": "The curator won't be able to re-add you to this collection for 24 hours. To prevent them from adding you to collections permanently, you can block them.",
"confirmations.revoke_collection_inclusion.title": "Remove yourself from this collection?",
"confirmations.revoke_quote.confirm": "Remove post",
"confirmations.revoke_quote.message": "This action cannot be undone.",
@@ -649,6 +649,7 @@
"empty_column.collections": "{acct} has not created any collections yet.",
"empty_column.collections.featured_in": "You have not been added to any collections yet.",
"empty_column.collections.featured_in_undiscoverable": "In order for people to add you to collections, you need to allow featuring in discovery experiences from <link>Preferences > Privacy and reach</link>",
"empty_column.collections_self": "You have not created any collections yet.",
"empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
"empty_column.direct": "You don't have any private mentions yet. When you send or receive one, it will show up here.",
"empty_column.disabled_feed": "This feed has been disabled by your server administrators.",
@@ -649,6 +649,7 @@
"empty_column.collections": "{acct} todavía no creó ninguna colección.",
"empty_column.collections.featured_in": "Todavía no te agregaron a ninguna colección.",
"empty_column.collections.featured_in_undiscoverable": "Para que la gente pueda agregarte a colecciones, tenés que permitir que te destacen en las experiencias de descubrimiento en <link>Configuración > Privacidad y alcance</link>",
"empty_column.collections_self": "Aún no has creado ninguna colección.",
"empty_column.community": "La línea temporal local está vacía. ¡Escribí algo en modo público para que se empiece a correr la bola!",
"empty_column.direct": "Todavía no tenés ninguna mención privada. Cuando enviés o recibás una, se mostrará acá.",
"empty_column.disabled_feed": "Esta línea temporal fue deshabilitada por los administradores de tu servidor.",
+2 -1
View File
@@ -649,6 +649,7 @@
"empty_column.collections": "{acct} todavía no ha creado ninguna colección.",
"empty_column.collections.featured_in": "Aún no te han añadido a ninguna colección.",
"empty_column.collections.featured_in_undiscoverable": "Para que los usuarios puedan añadirte a sus colecciones, debes habilitar la opción de aparecer en las experiencias de descubrimiento desde <link>Preferencias > Privacidad y alcance</link>",
"empty_column.collections_self": "Aún no has creado ninguna colección.",
"empty_column.community": "La cronología local está vacía. ¡Escribe algo públicamente para ponerla en marcha!",
"empty_column.direct": "Aún no tienes ninguna mención privada. Cuando envíes o recibas una, aparecerá aquí.",
"empty_column.disabled_feed": "Esta cronología fue desactivada por los administradores de tu servidor.",
@@ -780,7 +781,7 @@
"home.pending_critical_update.link": "Ver actualizaciones",
"home.pending_critical_update.title": "¡Actualización de seguridad crítica disponible!",
"home.show_announcements": "Mostrar anuncios",
"ignore_notifications_modal.bots_title": "¿Ignorar notificaciones de bots?",
"ignore_notifications_modal.bots_title": "¿Ignorar las notificaciones de los bots?",
"ignore_notifications_modal.disclaimer": "Mastodon no puede informar a los usuarios que has ignorado sus notificaciones. Ignorar notificaciones no impedirá que se sigan enviando los mensajes.",
"ignore_notifications_modal.filter_instead": "Filtrar en su lugar",
"ignore_notifications_modal.filter_to_act_users": "Aún podrás aceptar, rechazar o reportar usuarios",
+1
View File
@@ -649,6 +649,7 @@
"empty_column.collections": "{acct} aún no ha creado ninguna colección.",
"empty_column.collections.featured_in": "Aún no te han añadido a ninguna colección.",
"empty_column.collections.featured_in_undiscoverable": "Para que la gente pueda añadirte a colecciones, debes permitir ser destacado en algoritmos de descubrimiento desde <link>Preferencias > Privacidad y alcance</link>",
"empty_column.collections_self": "Aún no has creado ninguna colección.",
"empty_column.community": "La línea de tiempo local está vacía. ¡Escribe algo para empezar la fiesta!",
"empty_column.direct": "Aún no tienes menciones privadas. Cuando envíes o recibas una, aparecerán aquí.",
"empty_column.disabled_feed": "Esta cronología ha sido desactivada por los administradores del servidor.",
+1
View File
@@ -649,6 +649,7 @@
"empty_column.collections": "{acct} ei ole luonut vielä yhtään kokoelmaa.",
"empty_column.collections.featured_in": "Sinua ei ole vielä lisätty mihinkään kokoelmaan.",
"empty_column.collections.featured_in_undiscoverable": "Jotta sinut voi lisätä kokoelmiin, esittely löydettävyyskokemuksissa on sallittava kohdassa <link>Asetukset > Yksityisyys ja tavoittavuus</link>",
"empty_column.collections_self": "Et ole luonut vielä yhtään kokoelmaa.",
"empty_column.community": "Paikallinen aikajana on tyhjä. Kirjoita jotain julkista, niin homma lähtee käyntiin!",
"empty_column.direct": "Yksityismainintoja ei vielä ole. Jos lähetät tai sinulle lähetetään sellaisia, näet ne täällä.",
"empty_column.disabled_feed": "Palvelimen ylläpito on poistanut käytöstä tämän syötteen.",
@@ -649,6 +649,7 @@
"empty_column.collections": "{acct} n'a pas encore créé de collection.",
"empty_column.collections.featured_in": "Vous n'avez pas encore été ajouté·e à une collection.",
"empty_column.collections.featured_in_undiscoverable": "Afin que l'on puisse vous ajouter à des collections, vous devez autoriser d'apparaître dans les expériences de découverte depuis <link>Vie privée et visibilité</link>",
"empty_column.collections_self": "Vous n'avez pas encore créé de collection.",
"empty_column.community": "Le fil local est vide. Écrivez donc quelque chose pour le remplir!",
"empty_column.direct": "Vous n'avez pas encore de mentions privées. Quand vous en envoyez ou en recevez, elles apparaîtront ici.",
"empty_column.disabled_feed": "Ce flux a été désactivé par les administrateur·rice·s de votre serveur.",
+1
View File
@@ -649,6 +649,7 @@
"empty_column.collections": "{acct} n'a pas encore créé de collection.",
"empty_column.collections.featured_in": "Vous n'avez pas encore été ajouté·e à une collection.",
"empty_column.collections.featured_in_undiscoverable": "Afin que l'on puisse vous ajouter à des collections, vous devez autoriser d'apparaître dans les expériences de découverte depuis <link>Vie privée et visibilité</link>",
"empty_column.collections_self": "Vous n'avez pas encore créé de collection.",
"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 mentions privées. Quand vous en enverrez ou recevrez, elles apparaîtront ici.",
"empty_column.disabled_feed": "Ce flux a été désactivé par les administrateur·rice·s de votre serveur.",
+1
View File
@@ -649,6 +649,7 @@
"empty_column.collections": "Níl aon bhailiúcháin cruthaithe ag {acct} go fóill.",
"empty_column.collections.featured_in": "Níor cuireadh le haon bhailiúchán thú go fóill.",
"empty_column.collections.featured_in_undiscoverable": "Chun go mbeidh daoine in ann tú a chur le bailiúcháin, ní mór duit cead a thabhairt duit a bheith le feiceáil i dtaithí fionnachtana ó <link>Sainroghanna > Príobháideacht agus raon feidhme</link>",
"empty_column.collections_self": "Níl aon bhailiúcháin cruthaithe agat go fóill.",
"empty_column.community": "Tá an amlíne áitiúil folamh. Foilsigh rud éigin go poiblí le tús a chur le cúrsaí!",
"empty_column.direct": "Níl aon tagairtí príobháideacha agat fós. Nuair a sheolann tú nó a gheobhaidh tú ceann, beidh sé le feiceáil anseo.",
"empty_column.disabled_feed": "Tá an fotha seo díchumasaithe ag riarthóirí do fhreastalaí.",
+1
View File
@@ -649,6 +649,7 @@
"empty_column.collections": "{acct} non ha ancora creato alcuna collezione.",
"empty_column.collections.featured_in": "Non sei ancora stato/a aggiunto/a ad alcuna collezione.",
"empty_column.collections.featured_in_undiscoverable": "Affinché le persone possano aggiungerti alle collezioni, è necessario consentire che il profilo sia visibile nelle esperienze di scoperta tramite <link>Preferenze > Privacy e visibilità</link>",
"empty_column.collections_self": "Non hai ancora creato alcuna collezione.",
"empty_column.community": "La cronologia locale è vuota. Scrivi qualcosa pubblicamente per dare inizio alla festa!",
"empty_column.direct": "Non hai ancora alcuna menzione privata. Quando ne invierai o riceverai una, apparirà qui.",
"empty_column.disabled_feed": "Questo feed è stato disabilitato dagli amministratori del tuo server.",
+9 -9
View File
@@ -78,7 +78,7 @@
"account.media": "Multivide",
"account.mention": "Pieminēt @{name}",
"account.menu.add_to_list": "Pievienot sarakstam…",
"account.menu.block": "Bloķēt kontu",
"account.menu.block": "Liegt kontu",
"account.menu.block_domain": "Liegt {domain}",
"account.menu.copy": "Kopēt saiti",
"account.menu.mute": "Apklusināt kontu",
@@ -112,7 +112,7 @@
"account.unblock": "Atcelt liegšanu @{name}",
"account.unblock_domain": "Atcelt domēna {domain} liegšanu",
"account.unblock_domain_short": "Atcelt liegšanu",
"account.unblock_short": "Atbloķēt",
"account.unblock_short": "Atcelt liegšanu",
"account.unendorse": "Neizcelt profilā",
"account.unfollow": "Pārstāt sekot",
"account.unmute": "Noņemt apklusinājumu @{name}",
@@ -178,11 +178,11 @@
"annual_report.summary.percentile.we_wont_tell_bernie": "Mēs neteiksim Bērnijam.",
"attachments_list.unprocessed": "(neapstrādāti)",
"audio.hide": "Slēpt audio",
"block_modal.remote_users_caveat": "Mēs lūgsim serverim {domain} ņemt vērā Tavu lēmumu. Tomēr sadarbība nav garantēta, jo atsevišķi serveri bloķēšanu var apstrādāt citādi. Publiski ieraksti, iespējams, joprojām būs redzami lietotājiem, kuri nav pieteikušies.",
"block_modal.remote_users_caveat": "Mēs vaicāsim serverim {domain} ņemt vērā Tavu lēmumu. Tomēr atbilstība nav nodrošināta, jo atsevišķi serveri liegšanu var apstrādāt citādi. Publiski ieraksti joprojām var būt redzami lietotājiem, kuri nav pieteikušies.",
"block_modal.show_less": "Rādīt mazāk",
"block_modal.show_more": "Rādīt vairāk",
"block_modal.they_will_know": "Lietotājs varēs redzēt, ka ir bloķēts.",
"block_modal.title": "Bloķēt lietotāju?",
"block_modal.they_will_know": "Lietotājs varēs redzēt, ka ir liegts.",
"block_modal.title": "Liegt lietotāju?",
"boost_modal.combo": "Nospied {combo}, lai nākamreiz šo izlaistu",
"boost_modal.reblog": "Pastiprināt ierakstu?",
"boost_modal.undo_reblog": "Atcelt ieraksta pastiprināšanu?",
@@ -204,7 +204,7 @@
"closed_registrations_modal.preamble": "Mastodon ir decentralizēts, tāpēc neatkarīgi no tā, kur Tu izveido savu kontu, varēsi sekot un mijiedarboties ar ikvienu šajā serverī. Tu pat vari to pašizvietot!",
"closed_registrations_modal.title": "Reģistrēšanās Mastodon",
"collections.accounts.empty_title": "Šī kolekcija ir tukša",
"collections.block_collection_owner": "Bloķēt kontu",
"collections.block_collection_owner": "Liegt kontu",
"collections.collection_description": "Apraksts",
"collections.collection_language": "Valoda",
"collections.collection_language_none": "Nav",
@@ -316,8 +316,8 @@
"confirmations.revoke_quote.confirm": "Noņemt ierakstu",
"confirmations.revoke_quote.message": "Šo darbību nevar atsaukt.",
"confirmations.revoke_quote.title": "Noņemt ierakstu?",
"confirmations.unblock.confirm": "Atbloķēt",
"confirmations.unblock.title": "Atbloķēt {name}?",
"confirmations.unblock.confirm": "Atcelt liegšanu",
"confirmations.unblock.title": "Atcelt {name} liegumu?",
"confirmations.unfollow.confirm": "Pārstāt sekot",
"confirmations.unfollow.title": "Pārtraukt sekot {name}?",
"confirmations.withdraw_request.confirm": "Atsaukt pieprasījumu",
@@ -341,7 +341,7 @@
"dismissable_banner.dismiss": "Atcelt",
"dismissable_banner.public_timeline": "Šie ir jaunākie Fediverse lietotāju publiskie ieraksti, kuriem {domain} seko cilvēki.",
"domain_block_modal.block": "Liegt serveri",
"domain_block_modal.block_account_instead": "Tā vietā bloķēt @{name}",
"domain_block_modal.block_account_instead": "Tā vietā liegt @{name}",
"domain_block_modal.they_cant_follow": "Neviens no šī servera nevarēs Tev sekot.",
"domain_block_modal.they_wont_know": "Viņi nezinās, ka tikuši liegti.",
"domain_block_modal.title": "Liegt domēnu?",
@@ -649,6 +649,7 @@
"empty_column.collections": "{acct} não criou nenhuma coleção ainda.",
"empty_column.collections.featured_in": "Você ainda não foi adicionado a uma coleção.",
"empty_column.collections.featured_in_undiscoverable": "Para as pessoas adicionarem você às coleções, você precisa permitir destaque de experiências de descoberta através de <link>Preferências > Privacidade e alcance</link>",
"empty_column.collections_self": "Você ainda não criou nenhuma coleção.",
"empty_column.community": "A linha local está vazia. Publique algo para começar!",
"empty_column.direct": "Você ainda não possui menções privadas. Caso você enviar ou receber uma, ela aparecerá aqui.",
"empty_column.disabled_feed": "Este feed foi desativado pelos administradores de seu servidor.",
+1
View File
@@ -644,6 +644,7 @@
"empty_column.collections": "{acct} s’ka krijuar ende ndonjë koleksion.",
"empty_column.collections.featured_in": "S’jeni shtuar ende te ndonjë koleksion.",
"empty_column.collections.featured_in_undiscoverable": "Që njerëzit t’ju shtojnë te koleksione, lypset të lejoni shfaqjen si i zgjedhur në raste zbulimi, që nga <link>Parapëlqime > Privatësi dhe shtrirje</link>",
"empty_column.collections_self": "S’keni krijuar ende ndonjë koleksion.",
"empty_column.community": "Rrjedha kohore vendore është e zbrazët. Shkruani diçka publikisht që t’i hyhet valles!",
"empty_column.direct": "S’keni ende ndonjë përmendje private. Kur dërgoni ose merrni një të tillë, do të shfaqet këtu.",
"empty_column.disabled_feed": "Kjo prurje është çaktivizuar nga përgjegjësit e shërbyesit tuaj.",
+5
View File
@@ -649,6 +649,7 @@
"empty_column.collections": "{acct} har ännu inte skapat några samlingar.",
"empty_column.collections.featured_in": "Du har inte lagts till i några samlingar än.",
"empty_column.collections.featured_in_undiscoverable": "För att personer ska kunna lägga till dig i samlingar, måste du tillåta att inkluderas i upptäcktsupplevelser från <link>Inställningar> Sekretess och räckvidd</link>",
"empty_column.collections_self": "Du har inte skapat några samlingar än.",
"empty_column.community": "Den lokala tidslinjen är tom. Skriv något offentligt för att sätta bollen i rullning!",
"empty_column.direct": "Du har inga privata omnämnanden. När du skickar eller tar emot ett direktmeddelande kommer det att visas här.",
"empty_column.disabled_feed": "Detta flöde har inaktiverats av dina serveradministratörer.",
@@ -780,6 +781,7 @@
"home.pending_critical_update.link": "Se uppdateringar",
"home.pending_critical_update.title": "En kritisk säkerhetsuppdatering är tillgänglig!",
"home.show_announcements": "Visa notiser",
"ignore_notifications_modal.bots_title": "Ignorera aviseringar från botar?",
"ignore_notifications_modal.disclaimer": "Mastodon kan inte informera användarna om att du har ignorerat deras meddelanden. Ignorering av aviseringar kommer inte att stoppa själva meddelandena från att skickas.",
"ignore_notifications_modal.filter_instead": "Filtrera istället",
"ignore_notifications_modal.filter_to_act_users": "Du kommer fortfarande att kunna acceptera, avvisa eller rapportera användare",
@@ -846,6 +848,7 @@
"keyboard_shortcuts.toggle_sensitivity": "Visa/gömma media",
"keyboard_shortcuts.toot": "Starta nytt inlägg",
"keyboard_shortcuts.top": "Flytta till början av listan",
"keyboard_shortcuts.translate": "Översätt ett inlägg",
"keyboard_shortcuts.unfocus": "Avfokusera skrivfält/sökfält",
"keyboard_shortcuts.up": "Flytta uppåt i listan",
"learn_more_link.got_it": "Jag förstår",
@@ -1041,6 +1044,8 @@
"notifications.policy.drop": "Ignorera",
"notifications.policy.drop_hint": "Skicka ut i tomrummet för aldrig synas till igen",
"notifications.policy.filter": "Filtrera",
"notifications.policy.filter_bots_hint": "Konton markerade som automatiserade",
"notifications.policy.filter_bots_title": "Botar",
"notifications.policy.filter_hint": "Skicka till inkorgen för filtrerade aviserings",
"notifications.policy.filter_limited_accounts_hint": "Begränsade av servermoderatorer",
"notifications.policy.filter_limited_accounts_title": "Modererade konton",
+1
View File
@@ -649,6 +649,7 @@
"empty_column.collections": "{acct} henüz bir koleksiyon oluşturmadı.",
"empty_column.collections.featured_in": "Henüz herhangi bir koleksiyona eklenmediniz.",
"empty_column.collections.featured_in_undiscoverable": "Kullanıcıların sizi koleksiyonlarına ekleyebilmesi için, <link>Tercihler > Gizlilik ve erişim</link> bölümünden keşif deneyimlerinde öne çıkarılmaya izin vermeniz gerekir",
"empty_column.collections_self": "Henüz bir koleksiyon oluşturmadınız.",
"empty_column.community": "Yerel zaman çizelgesi boş. Daha fazla eğlence için herkese açık bir gönderi paylaşın!",
"empty_column.direct": "Henüz doğrudan değinmeniz yok. Bir tane gönderdiğinizde veya aldığınızda burada listelenecek.",
"empty_column.disabled_feed": "Bu akış sunucu yöneticileri tarafından devre dışı bırakılmıştır.",
+1
View File
@@ -649,6 +649,7 @@
"empty_column.collections": "{acct} chưa tạo gói khởi đầu nào.",
"empty_column.collections.featured_in": "Bạn chưa được thêm vào gói khởi đầu nào.",
"empty_column.collections.featured_in_undiscoverable": "Để mọi người có thể thêm bạn vào gói khởi đầu, bạn cần cho phép hiển thị trong trải nghiệm khám phá ở <link>Thiết lập > Riêng tư và tiếp cận</link>",
"empty_column.collections_self": "Bạn chưa tạo gói khởi đầu nào.",
"empty_column.community": "Máy chủ của bạn chưa có tút nào công khai. Bạn hãy thử viết gì đó đi!",
"empty_column.direct": "Bạn chưa có tin nhắn riêng nào. Khi bạn gửi hoặc nhận một tin nhắn riêng, nó sẽ xuất hiện ở đây.",
"empty_column.disabled_feed": "Bảng tin này bị vô hiệu hóa bởi quản trị viên máy chủ của bạn.",
@@ -649,6 +649,7 @@
"empty_column.collections": "{acct} 尚未创建任何收藏列表。",
"empty_column.collections.featured_in": "你还没有被添加到收藏列表过。",
"empty_column.collections.featured_in_undiscoverable": "如果想让其他人将你添加到收藏列表,请前往<link>偏好设置 > 隐私与可达性</link>在发现功能中允许推荐",
"empty_column.collections_self": "你尚未创建任何收藏列表。",
"empty_column.community": "本站时间线还没有内容,写点什么并公开发布,让它活跃起来吧!",
"empty_column.direct": "你还未使用过私下提及。当你发出或者收到私下提及时,它将显示在此。",
"empty_column.disabled_feed": "此动态已被你的服务器管理员禁用。",
@@ -649,6 +649,7 @@
"empty_column.collections": "{acct} 尚未建立任何收藏名單。",
"empty_column.collections.featured_in": "您尚未被加入至任何收藏名單。",
"empty_column.collections.featured_in_undiscoverable": "如欲被其他人將您加入至收藏名單,您必須於 <link>偏好設定 > 隱私權與觸及</link> 啟用探索相關功能",
"empty_column.collections_self": "您尚未建立任何收藏名單。",
"empty_column.community": "本站時間軸是空的。快公開嘟些文搶頭香啊!",
"empty_column.direct": "您還沒有收到任何私訊。當您私訊別人或收到私訊時,它將於此顯示。",
"empty_column.disabled_feed": "此內容已被您的伺服器管理員停用。",
@@ -2498,7 +2498,7 @@ a.account__display-name {
overflow: hidden;
strong,
span {
span:not(.emojione) {
display: block;
text-overflow: ellipsis;
overflow: hidden;