Merge commit '1ae3b4672bffbc4aaf26f60c7063d6901239de5d' into glitch-soc/merge-upstream

This commit is contained in:
Claire
2025-12-05 20:00:40 +01:00
46 changed files with 281 additions and 315 deletions

View File

@@ -1,9 +1,14 @@
import type { FC } from 'react';
import { useContext, useEffect, useState } from 'react';
import classNames from 'classnames';
import { EMOJI_TYPE_CUSTOM } from '@/mastodon/features/emoji/constants';
import { useEmojiAppState } from '@/mastodon/features/emoji/mode';
import { unicodeHexToUrl } from '@/mastodon/features/emoji/normalize';
import {
emojiToInversionClassName,
unicodeHexToUrl,
} from '@/mastodon/features/emoji/normalize';
import {
isStateLoaded,
loadEmojiDataToState,
@@ -41,6 +46,9 @@ export const Emoji: FC<EmojiProps> = ({
}, [appState.currentLocale, state]);
const animate = useContext(AnimateEmojiContext);
const inversionClass = emojiToInversionClassName(code);
const fallback = showFallback ? code : null;
// If the code is invalid or we otherwise know it's not valid, show the fallback.
@@ -79,7 +87,7 @@ export const Emoji: FC<EmojiProps> = ({
src={src}
alt={state.data.unicode}
title={state.data.label}
className='emojione'
className={classNames('emojione', inversionClass)}
loading='lazy'
/>
);

View File

@@ -116,3 +116,29 @@ export const EMOJIS_WITH_LIGHT_BORDER = [
'🪽', // 1FAE8
'🪿', // 1FABF
];
export const EMOJIS_REQUIRING_INVERSION_IN_LIGHT_MODE = [
'⛓️', // 26D3-FE0F
];
export const EMOJIS_REQUIRING_INVERSION_IN_DARK_MODE = [
'🔜', // 1F51C
'🔙', // 1F519
'🔛', // 1F51B
'🔝', // 1F51D
'🔚', // 1F51A
'©️', // 00A9 FE0F
'➰', // 27B0
'💱', // 1F4B1
'✔️', // 2714 FE0F
'➗', // 2797
'💲', // 1F4B2
'', // 2796
'✖️', // 2716 FE0F
'', // 2795
'®️', // 00AE FE0F
'🕷️', // 1F577 FE0F
'📞', // 1F4DE
'™️', // 2122 FE0F
'〰️', // 3030 FE0F
];

View File

@@ -1,5 +1,6 @@
import Trie from 'substring-trie';
import { getUserTheme, isDarkMode } from '@/mastodon/utils/theme';
import { assetHost } from 'mastodon/utils/config';
import { autoPlayGif } from '../../initial_state';
@@ -97,9 +98,9 @@ const emojifyTextNode = (node, customEmojis) => {
const { filename, shortCode } = unicodeMapping[unicode_emoji];
const title = shortCode ? `:${shortCode}:` : '';
const isSystemTheme = !!document.body?.classList.contains('theme-system');
const isSystemTheme = getUserTheme() === 'system';
const theme = (isSystemTheme || document.body?.classList.contains('theme-mastodon-light')) ? 'light' : 'dark';
const theme = (isSystemTheme || !isDarkMode()) ? 'light' : 'dark';
const imageFilename = emojiFilename(filename, theme);

View File

@@ -3,6 +3,7 @@
import { createAppSelector, useAppSelector } from '@/mastodon/store';
import { isDevelopment } from '@/mastodon/utils/environment';
import { isDarkMode } from '@/mastodon/utils/theme';
import {
EMOJI_MODE_NATIVE,
@@ -27,7 +28,7 @@ export function useEmojiAppState(): EmojiAppState {
currentLocale: locale,
locales: [locale],
mode,
darkTheme: document.body.classList.contains('theme-default'),
darkTheme: isDarkMode(),
};
}

View File

@@ -10,6 +10,8 @@ import {
SKIN_TONE_CODES,
EMOJIS_WITH_DARK_BORDER,
EMOJIS_WITH_LIGHT_BORDER,
EMOJIS_REQUIRING_INVERSION_IN_LIGHT_MODE,
EMOJIS_REQUIRING_INVERSION_IN_DARK_MODE,
} from './constants';
import type { CustomEmojiMapArg, ExtraCustomEmojiMap } from './types';
@@ -150,6 +152,16 @@ export function twemojiToUnicodeInfo(
return hexNumbersToString(mappedCodes);
}
export function emojiToInversionClassName(emoji: string): string | null {
if (EMOJIS_REQUIRING_INVERSION_IN_DARK_MODE.includes(emoji)) {
return 'invert-on-dark';
}
if (EMOJIS_REQUIRING_INVERSION_IN_LIGHT_MODE.includes(emoji)) {
return 'invert-on-light';
}
return null;
}
export function cleanExtraEmojis(extraEmojis?: CustomEmojiMapArg) {
if (!extraEmojis) {
return null;

View File

@@ -48,8 +48,10 @@ const handleIframeUrl = (html: string, url: string, providerName: string) => {
iframeUrl.searchParams.set('autoplay', '1');
iframeUrl.searchParams.set('auto_play', '1');
if (startTime && providerName === 'YouTube')
iframeUrl.searchParams.set('start', startTime);
if (providerName === 'YouTube') {
iframeUrl.searchParams.set('start', startTime ?? '');
iframe.referrerPolicy = 'strict-origin-when-cross-origin';
}
iframe.src = iframeUrl.href;

View File

@@ -135,6 +135,7 @@
"annual_report.summary.new_posts.new_posts": "новыя допісы",
"annual_report.summary.percentile.text": "<topLabel>Гэта падымае Вас у топ</topLabel><percentage></percentage><bottomLabel> карыстальнікаў {domain}.</bottomLabel>",
"annual_report.summary.percentile.we_wont_tell_bernie": "КДБ пра гэта не даведаецца.",
"annual_report.summary.share_message": "Мой архетып {archetype}!",
"annual_report.summary.thanks": "Дзякуй за ўдзел у Mastodon!",
"attachments_list.unprocessed": "(неапрацаваны)",
"audio.hide": "Схаваць аўдыя",

View File

@@ -147,7 +147,7 @@
"block_modal.they_will_know": "Das Profil wird erkennen können, dass du es blockiert hast.",
"block_modal.title": "Profil blockieren?",
"block_modal.you_wont_see_mentions": "Du wirst keine Beiträge sehen, die dieses Profil erwähnen.",
"boost_modal.combo": "Mit {combo} erscheint dieses Fenster beim nächsten Mal nicht mehr",
"boost_modal.combo": "Mit {combo} erscheint dieses Fenster nicht mehr",
"boost_modal.reblog": "Beitrag teilen?",
"boost_modal.undo_reblog": "Beitrag nicht mehr teilen?",
"bundle_column_error.copy_stacktrace": "Fehlerbericht kopieren",
@@ -200,7 +200,7 @@
"column_search.cancel": "Abbrechen",
"community.column_settings.local_only": "Nur lokal",
"community.column_settings.media_only": "Nur Beiträge mit Medien",
"community.column_settings.remote_only": "Nur andere Mastodon-Server",
"community.column_settings.remote_only": "Nur andere Server im Fediverse",
"compose.error.blank_post": "Beitrag muss einen Inhalt haben.",
"compose.language.change": "Sprache festlegen",
"compose.language.search": "Sprachen suchen …",
@@ -213,13 +213,13 @@
"compose_form.lock_disclaimer": "Dein Profil ist nicht {locked}. Andere können dir folgen und deine Beiträge sehen, die nur für Follower bestimmt sind.",
"compose_form.lock_disclaimer.lock": "geschützt",
"compose_form.placeholder": "Was gibts Neues?",
"compose_form.poll.duration": "Umfragedauer",
"compose_form.poll.duration": "Laufzeit",
"compose_form.poll.multiple": "Mehrfachauswahl",
"compose_form.poll.option_placeholder": "{number}. Auswahl",
"compose_form.poll.single": "Einfachauswahl",
"compose_form.poll.switch_to_multiple": "Mehrfachauswahl erlauben",
"compose_form.poll.switch_to_single": "Nur Einfachauswahl erlauben",
"compose_form.poll.type": "Art",
"compose_form.poll.type": "Typ",
"compose_form.publish": "Veröffentlichen",
"compose_form.reply": "Antworten",
"compose_form.save_changes": "Aktualisieren",
@@ -232,7 +232,7 @@
"confirmations.delete.message": "Möchtest du diesen Beitrag wirklich löschen?",
"confirmations.delete.title": "Beitrag löschen?",
"confirmations.delete_list.confirm": "Löschen",
"confirmations.delete_list.message": "Möchtest du diese Liste für immer löschen?",
"confirmations.delete_list.message": "Bist du dir sicher, dass du diese Liste endgültig löschen möchtest?",
"confirmations.delete_list.title": "Liste löschen?",
"confirmations.discard_draft.confirm": "Verwerfen und fortfahren",
"confirmations.discard_draft.edit.cancel": "Bearbeitung fortsetzen",
@@ -247,31 +247,31 @@
"confirmations.follow_to_list.message": "Du musst {name} folgen, um das Profil zu einer Liste hinzufügen zu können.",
"confirmations.follow_to_list.title": "Profil folgen?",
"confirmations.logout.confirm": "Abmelden",
"confirmations.logout.message": "Bist du sicher, dass du dich abmelden möchtest?",
"confirmations.logout.message": "Möchtest du dich wirklich ausloggen?",
"confirmations.logout.title": "Abmelden?",
"confirmations.missing_alt_text.confirm": "Bildbeschreibung hinzufügen",
"confirmations.missing_alt_text.message": "Dein Beitrag enthält Medien ohne Bildbeschreibung. Mit ALT-Texten erreichst Du auch Menschen, die blind oder sehbehindert sind.",
"confirmations.missing_alt_text.secondary": "Trotzdem veröffentlichen",
"confirmations.missing_alt_text.title": "Bildbeschreibung hinzufügen?",
"confirmations.mute.confirm": "Stummschalten",
"confirmations.private_quote_notify.cancel": "Zurück zum Bearbeiten",
"confirmations.private_quote_notify.cancel": "Zurück zur Bearbeitung",
"confirmations.private_quote_notify.confirm": "Beitrag veröffentlichen",
"confirmations.private_quote_notify.do_not_show_again": "Diesen Hinweis nicht mehr anzeigen",
"confirmations.private_quote_notify.message": "Dein Beitrag wird von dem zitierten sowie den erwähnten Profilen gesehen werden können, auch wenn sie dir nicht folgen.",
"confirmations.private_quote_notify.title": "Mit Followern und erwähnten Profilen teilen?",
"confirmations.quiet_post_quote_info.dismiss": "Nicht mehr anzeigen",
"confirmations.quiet_post_quote_info.dismiss": "Nicht erneut erinnern",
"confirmations.quiet_post_quote_info.got_it": "Verstanden",
"confirmations.quiet_post_quote_info.message": "Beim Zitieren eines Beitrags, dessen Sichtbarkeit „Öffentlich (still)“ ist, wird auch dein Beitrag, der das Zitat enthält, aus den Trends und öffentlichen Timelines ausgeblendet.",
"confirmations.quiet_post_quote_info.title": "Zitieren eines Beitrags mit der Sichtbarkeit „Öffentlich (still)“",
"confirmations.redraft.confirm": "Löschen und neu erstellen",
"confirmations.redraft.message": "Möchtest du diesen Beitrag wirklich löschen und neu verfassen? Alle Favoriten sowie die bisher geteilten Beiträge werden verloren gehen und Antworten auf den ursprünglichen Beitrag verlieren den Zusammenhang.",
"confirmations.redraft.title": "Beitrag löschen und neu verfassen?",
"confirmations.redraft.title": "Beitrag löschen & neu verfassen?",
"confirmations.remove_from_followers.confirm": "Follower entfernen",
"confirmations.remove_from_followers.message": "{name} wird dir nicht länger folgen. Bist du dir sicher?",
"confirmations.remove_from_followers.title": "Follower entfernen?",
"confirmations.revoke_quote.confirm": "Zitat entfernen",
"confirmations.revoke_quote.message": "Diese Aktion kann nicht rückgängig gemacht werden.",
"confirmations.revoke_quote.title": "Zitieren meines Beitrags entfernen?",
"confirmations.revoke_quote.title": "Mein Zitat aus diesem Beitrag entfernen?",
"confirmations.unblock.confirm": "Blockierung aufheben",
"confirmations.unblock.title": "Blockierung von {name} aufheben?",
"confirmations.unfollow.confirm": "Entfolgen",
@@ -309,7 +309,7 @@
"domain_pill.activitypub_lets_connect": "Somit kannst du dich nicht nur auf Mastodon mit Leuten verbinden und mit ihnen interagieren, sondern über alle sozialen Apps hinweg.",
"domain_pill.activitypub_like_language": "ActivityPub ist sozusagen die Sprache, die Mastodon mit anderen sozialen Netzwerken spricht.",
"domain_pill.server": "Server",
"domain_pill.their_handle": "Die vollständige Adresse:",
"domain_pill.their_handle": "Vollständige Adresse:",
"domain_pill.their_server": "Die digitale Heimat, in der sich alle Beiträge dieses Profils befinden.",
"domain_pill.their_username": "Die eindeutige Identifizierung auf einem Server. Es ist möglich, denselben Profilnamen auf verschiedenen Servern im Fediverse zu finden.",
"domain_pill.username": "Profilname",
@@ -327,7 +327,7 @@
"emoji_button.custom": "Spezielle Emojis dieses Servers",
"emoji_button.flags": "Flaggen",
"emoji_button.food": "Essen & Trinken",
"emoji_button.label": "Emoji einfügen",
"emoji_button.label": "Emoji hinzufügen",
"emoji_button.nature": "Natur",
"emoji_button.not_found": "Keine passenden Emojis gefunden",
"emoji_button.objects": "Gegenstände",
@@ -349,8 +349,8 @@
"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.",
"empty_column.domain_blocks": "Du hast noch keine Domains blockiert.",
"empty_column.explore_statuses": "Momentan ist nichts im Trend. Schau später wieder vorbei!",
"empty_column.domain_blocks": "Du hast bisher keine Domains blockiert.",
"empty_column.explore_statuses": "Momentan trendet nichts. Schau später wieder vorbei!",
"empty_column.favourited_statuses": "Du hast noch keine Beiträge favorisiert. Sobald du einen favorisierst, wird er hier erscheinen.",
"empty_column.favourites": "Diesen Beitrag hat bisher noch niemand favorisiert. Sobald es jemand tut, wird das Profil hier erscheinen.",
"empty_column.follow_requests": "Es liegen derzeit keine Follower-Anfragen vor. Sobald du eine erhältst, wird sie hier erscheinen.",
@@ -458,7 +458,7 @@
"hints.profiles.see_more_posts": "Weitere Beiträge auf {domain} ansehen",
"home.column_settings.show_quotes": "Zitierte Beiträge anzeigen",
"home.column_settings.show_reblogs": "Geteilte Beiträge anzeigen",
"home.column_settings.show_replies": "Antworten anzeigen",
"home.column_settings.show_replies": "Antworten zu Beiträgen anzeigen",
"home.hide_announcements": "Ankündigungen ausblenden",
"home.pending_critical_update.body": "Bitte aktualisiere deinen Mastodon-Server so schnell wie möglich!",
"home.pending_critical_update.link": "Updates ansehen",

View File

@@ -135,6 +135,7 @@
"annual_report.summary.new_posts.new_posts": "new posts",
"annual_report.summary.percentile.text": "<topLabel>That puts you in the top</topLabel><percentage></percentage><bottomLabel>of {domain} users.</bottomLabel>",
"annual_report.summary.percentile.we_wont_tell_bernie": "We won't tell Bernie.",
"annual_report.summary.share_message": "I got the {archetype} archetype!",
"annual_report.summary.thanks": "Thanks for being part of Mastodon!",
"attachments_list.unprocessed": "(unprocessed)",
"audio.hide": "Hide audio",

View File

@@ -626,7 +626,7 @@
"notification.follow_request.name_and_others": "{name} et {count, plural, one {# autre} other {# autres}} ont demandé à vous suivre",
"notification.label.mention": "Mention",
"notification.label.private_mention": "Mention privée",
"notification.label.private_reply": "Répondre en privé",
"notification.label.private_reply": "Réponse privée",
"notification.label.quote": "{name} a cité votre publication",
"notification.label.reply": "Réponse",
"notification.mention": "Mention",

View File

@@ -626,7 +626,7 @@
"notification.follow_request.name_and_others": "{name} et {count, plural, one {# autre} other {# autres}} ont demandé à vous suivre",
"notification.label.mention": "Mention",
"notification.label.private_mention": "Mention privée",
"notification.label.private_reply": "Répondre en privé",
"notification.label.private_reply": "Réponse privée",
"notification.label.quote": "{name} a cité votre publication",
"notification.label.reply": "Réponse",
"notification.mention": "Mention",

View File

@@ -56,7 +56,7 @@
"account.follows_you": "Leanann tú",
"account.go_to_profile": "Téigh go dtí próifíl",
"account.hide_reblogs": "Folaigh moltaí ó @{name}",
"account.in_memoriam": "Cuimhneachán.",
"account.in_memoriam": "Ón tseanaimsir.",
"account.joined_short": "Cláraithe",
"account.languages": "Athraigh teangacha foscríofa",
"account.link_verified_on": "Seiceáladh úinéireacht an naisc seo ar {date}",
@@ -135,6 +135,7 @@
"annual_report.summary.new_posts.new_posts": "postanna nua",
"annual_report.summary.percentile.text": "<topLabel>Cuireann sé sin i mbarr</topLabel><percentage></percentage><bottomLabel> úsáideoirí {domain}.</bottomLabel> thú",
"annual_report.summary.percentile.we_wont_tell_bernie": "Ní inseoidh muid do Bernie.",
"annual_report.summary.share_message": "Fuair mé an t-archetíopa {archetype}!",
"annual_report.summary.thanks": "Go raibh maith agat as a bheith mar chuid de Mastodon!",
"attachments_list.unprocessed": "(neamhphróiseáilte)",
"audio.hide": "Cuir fuaim i bhfolach",

View File

@@ -135,6 +135,7 @@
"annual_report.summary.new_posts.new_posts": "novas publicacións",
"annual_report.summary.percentile.text": "<topLabel>Sitúante no top</topLabel><percentage></percentage><bottomLabel> das usuarias de {domain}.</bottomLabel>",
"annual_report.summary.percentile.we_wont_tell_bernie": "Moito tes que contarnos!",
"annual_report.summary.share_message": "Resulta que son… {archetype}!",
"annual_report.summary.thanks": "Grazas por ser parte de Mastodon!",
"attachments_list.unprocessed": "(sen procesar)",
"audio.hide": "Agochar audio",

View File

@@ -113,6 +113,10 @@
"alt_text_modal.describe_for_people_with_visual_impairments": "Descrivi questo per le persone con disabilità visive…",
"alt_text_modal.done": "Fatto",
"announcement.announcement": "Annuncio",
"annual_report.announcement.action_build": "Costruisci il mio Wrapstodon",
"annual_report.announcement.action_view": "Visualizza il mio Wrapstodon",
"annual_report.announcement.description": "Scopri di più sul tuo coinvolgimento su Mastodon nell'ultimo anno.",
"annual_report.announcement.title": "Wrapstodon {year} è arrivato",
"annual_report.summary.archetype.booster": "Cacciatore/trice di tendenze",
"annual_report.summary.archetype.lurker": "L'osservatore/trice",
"annual_report.summary.archetype.oracle": "L'oracolo",
@@ -131,6 +135,7 @@
"annual_report.summary.new_posts.new_posts": "nuovi post",
"annual_report.summary.percentile.text": "<topLabel>Ciò ti colloca in cima</topLabel><percentage></percentage><bottomLabel>agli utenti di {domain}.</bottomLabel>",
"annual_report.summary.percentile.we_wont_tell_bernie": "Non lo diremo a Bernie.",
"annual_report.summary.share_message": "Ho ottenuto l'archetipo: {archetype}!",
"annual_report.summary.thanks": "Grazie per far parte di Mastodon!",
"attachments_list.unprocessed": "(non elaborato)",
"audio.hide": "Nascondi audio",

View File

@@ -14,7 +14,7 @@
"about.powered_by": "Decentralizuota socialinė medija, veikianti pagal „{mastodon}“",
"about.rules": "Serverio taisyklės",
"account.account_note_header": "Asmeninė pastaba",
"account.add_or_remove_from_list": "Pridėti arba pašalinti iš sąrašų",
"account.add_or_remove_from_list": "Įtraukti arba šalinti iš sąrašų",
"account.badges.bot": "Automatizuotas",
"account.badges.group": "Grupė",
"account.block": "Blokuoti @{name}",
@@ -135,7 +135,7 @@
"annual_report.summary.new_posts.new_posts": "nauji įrašai",
"annual_report.summary.percentile.text": "<topLabel>Tai reiškia, kad esate tarp</topLabel><percentage></percentage><bottomLabel>populiariausių {domain} naudotojų.</bottomLabel>",
"annual_report.summary.percentile.we_wont_tell_bernie": "Mes nesakysime Bernie.",
"annual_report.summary.share_message": "Aš gavau {archetype}!",
"annual_report.summary.share_message": "Aš gavau {archetype}!",
"annual_report.summary.thanks": "Dėkojame, kad esate „Mastodon“ dalis!",
"attachments_list.unprocessed": "(neapdorotas)",
"audio.hide": "Slėpti garsą",
@@ -921,7 +921,7 @@
"status.more": "Daugiau",
"status.mute": "Nutildyti @{name}",
"status.mute_conversation": "Nutildyti pokalbį",
"status.open": "Išplėsti šį įrašą",
"status.open": "Išskleisti šį įrašą",
"status.pin": "Prisegti prie profilio",
"status.quote": "Paminėjimai",
"status.quote.cancel": "Atšaukti paminėjimą",
@@ -1016,14 +1016,21 @@
"video.pause": "Pristabdyti",
"video.play": "Leisti",
"video.skip_backward": "Praleisti atgal",
"video.skip_forward": "Praleisti į priekį",
"video.unmute": "Atšaukti nutildymą",
"video.volume_down": "Patildyti",
"video.volume_up": "Pagarsinti",
"visibility_modal.button_title": "Nustatyti matomumą",
"visibility_modal.direct_quote_warning.text": "Jei išsaugosite dabartinius nustatymus, įterpta citata bus konvertuota į nuorodą.",
"visibility_modal.direct_quote_warning.title": "Cituojami įrašai negali būti įterpiami į privačius paminėjimus",
"visibility_modal.helper.direct_quoting": "Privatūs paminėjimai, parašyti platformoje „Mastodon“, negali būti cituojami kitų.",
"visibility_modal.helper.privacy_private_self_quote": "Privačių įrašų paminėjimai negali būti skelbiami viešai.",
"visibility_modal.helper.private_quoting": "Tik sekėjams skirti įrašai, parašyti platformoje „Mastodon“, negali būti cituojami kitų.",
"visibility_modal.helper.unlisted_quoting": "Kai žmonės jus cituos, jų įrašai taip pat bus paslėpti iš populiariausių naujienų srauto.",
"visibility_modal.privacy_label": "Matomumas",
"visibility_modal.quote_followers": "Tik sekėjai",
"visibility_modal.quote_label": "Kas gali cituoti",
"visibility_modal.quote_nobody": "Tik aš",
"visibility_modal.quote_public": "Visi"
"visibility_modal.quote_public": "Visi",
"visibility_modal.save": "Išsaugoti"
}

View File

@@ -135,6 +135,7 @@
"annual_report.summary.new_posts.new_posts": "yeni gönderiler",
"annual_report.summary.percentile.text": "<bottomLabel>{domain} kullanıcılarının</bottomLabel><percentage></percentage><topLabel>üst dilimindesiniz</topLabel>",
"annual_report.summary.percentile.we_wont_tell_bernie": "Bernie'ye söylemeyiz.",
"annual_report.summary.share_message": "{archetype} arketipindeyim!",
"annual_report.summary.thanks": "Mastodon'un bir parçası olduğunuz için teşekkürler!",
"attachments_list.unprocessed": "(işlenmemiş)",
"audio.hide": "Sesi gizle",

View File

@@ -42,13 +42,6 @@ interface AnnualReportV2 {
time_series: TimeSeriesMonth[];
top_hashtags: NameAndCount[];
top_statuses: TopStatuses;
most_used_apps: NameAndCount[];
type_distribution: {
total: number;
reblogs: number;
replies: number;
standalone: number;
};
}
export type AnnualReport = {

View File

@@ -530,7 +530,7 @@ export const composeReducer = (state = initialState, action) => {
map.set('sensitive', action.status.get('sensitive'));
map.set('language', action.status.get('language'));
map.set('id', null);
map.set('quoted_status_id', action.status.getIn(['quote', 'quoted_status']));
map.set('quoted_status_id', action.status.getIn(['quote', 'quoted_status'], null));
// Mastodon-authored posts can be expected to have at most one automatic approval policy
map.set('quote_policy', action.status.getIn(['quote_approval', 'automatic', 0]) || 'nobody');
@@ -567,7 +567,7 @@ export const composeReducer = (state = initialState, action) => {
map.set('idempotencyKey', uuid());
map.set('sensitive', action.status.get('sensitive'));
map.set('language', action.status.get('language'));
map.set('quoted_status_id', action.status.getIn(['quote', 'quoted_status']));
map.set('quoted_status_id', action.status.getIn(['quote', 'quoted_status'], null));
// Mastodon-authored posts can be expected to have at most one automatic approval policy
map.set('quote_policy', action.status.getIn(['quote_approval', 'automatic', 0]) || 'nobody');

View File

@@ -0,0 +1,13 @@
export function getUserTheme() {
const { userTheme } = document.documentElement.dataset;
return userTheme;
}
export function isDarkMode() {
const { userTheme } = document.documentElement.dataset;
return (
(userTheme === 'system' &&
window.matchMedia('(prefers-color-scheme: dark)').matches) ||
userTheme !== 'mastodon-light'
);
}

View File

@@ -1,2 +1 @@
@use 'mastodon/variables';
@use 'common';

View File

@@ -1,3 +1,4 @@
@use 'mastodon/variables';
@use 'mastodon/mixins';
@use 'fonts/roboto';
@use 'fonts/roboto-mono';
@@ -21,5 +22,4 @@
@use 'mastodon/admin';
@use 'mastodon/dashboard';
@use 'mastodon/rtl';
@use 'mastodon/accessibility';
@use 'mastodon/rich_text';

View File

@@ -1,3 +1,2 @@
@use 'mastodon/variables';
@use 'common';
@use 'mastodon/high-contrast';

View File

@@ -1,4 +1 @@
@use 'mastodon/variables' with (
$emojis-requiring-inversion: 'chains'
);
@use 'common';

View File

@@ -20,8 +20,3 @@ $no-columns-breakpoint: 600px;
$font-sans-serif: 'mastodon-font-sans-serif' !default;
$font-display: 'mastodon-font-display' !default;
$font-monospace: 'mastodon-font-monospace' !default;
$emojis-requiring-inversion: 'back' 'copyright' 'curly_loop' 'currency_exchange'
'end' 'heavy_check_mark' 'heavy_division_sign' 'heavy_dollar_sign'
'heavy_minus_sign' 'heavy_multiplication_x' 'heavy_plus_sign' 'on'
'registered' 'soon' 'spider' 'telephone_receiver' 'tm' 'top' 'wavy_dash' !default;

View File

@@ -1,13 +0,0 @@
@use 'variables' as *;
%emoji-color-inversion {
filter: invert(1);
}
.emojione {
@each $emoji in $emojis-requiring-inversion {
&[title=':#{$emoji}:'] {
@extend %emoji-color-inversion;
}
}
}

View File

@@ -10,6 +10,8 @@ html {
--outline-focus-default: 2px solid var(--color-text-brand);
--avatar-border-radius: 8px;
--max-media-height-small: 460px;
--max-media-height-large: 566px;
// Variable for easily inverting directional UI elements,
--text-x-direction: 1;

View File

@@ -7165,7 +7165,18 @@ a.status-card {
// The size of single images is determined by their
// aspect-ratio, applied via inline style attribute
width: initial;
max-height: 460px;
// Prevent extremely tall images from essentially becoming invisible
min-width: 120px;
max-height: var(--max-media-height-small);
@container (width > 500px) {
max-height: var(--max-media-height-large);
}
.detailed-status & {
max-height: calc(2 * var(--max-media-height-large));
}
}
&--layout-2 {
@@ -7500,7 +7511,7 @@ a.status-card {
position: relative;
color: var(--color-text-on-media);
background: var(--color-bg-media);
max-height: 460px;
max-height: var(--max-media-height-small);
border-radius: 8px;
box-sizing: border-box;
display: flex;
@@ -7508,6 +7519,10 @@ a.status-card {
outline-offset: -1px;
z-index: 2;
@container (width > 500px) {
max-height: var(--max-media-height-large);
}
video {
display: block;
z-index: -2;

View File

@@ -1,3 +1,15 @@
@function css-alpha($base-color, $amount) {
@return #{rgb(from $base-color r g b / $amount)};
}
@mixin invert-on-light {
.invert-on-light {
filter: invert(1);
}
}
@mixin invert-on-dark {
.invert-on-dark {
filter: invert(1);
}
}

View File

@@ -1,6 +1,7 @@
@use 'base';
@use 'dark';
@use 'light';
@use 'utils';
html {
@include base.palette;
@@ -10,6 +11,7 @@ html {
@media (prefers-color-scheme: dark) {
@include dark.tokens;
@include utils.invert-on-dark;
@media (prefers-contrast: more) {
@include dark.contrast-overrides;
@@ -18,6 +20,7 @@ html {
@media (prefers-color-scheme: light) {
@include light.tokens;
@include utils.invert-on-light;
@media (prefers-contrast: more) {
@include light.contrast-overrides;
@@ -33,6 +36,7 @@ html:where(
color-scheme: dark;
@include dark.tokens;
@include utils.invert-on-dark;
}
html[data-user-theme='contrast'],
@@ -45,4 +49,5 @@ html:where([data-user-theme='mastodon-light']) {
color-scheme: light;
@include light.tokens;
@include utils.invert-on-light;
}