mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-18 21:45:31 +09:00
fix(app,api): kick reasons, blocked counts and locale fallbacks (#3334)
This commit is contained in:
1 parent
a5c1362f4a
commit
4db13b0375
157 files changed
+3080
-1995
No files matched your search
@@ -14,6 +14,9 @@ const SUPPORTED_LOCALE_SET: ReadonlySet<LocaleCode> = new Set<LocaleCode>(SUPPOR
|
||||
const LANGUAGE_FALLBACK_BY_LANGUAGE_CODE: Record<string, LocaleCode> = {
|
||||
en: Locales.EN_US,
|
||||
es: Locales.ES_ES,
|
||||
nb: Locales.NO,
|
||||
nn: Locales.NO,
|
||||
no: Locales.NO,
|
||||
pt: Locales.PT_BR,
|
||||
zh: Locales.ZH_CN,
|
||||
sv: Locales.SV_SE,
|
||||
@@ -111,6 +114,7 @@ const LOCALE_METADATA_BY_CODE: Record<LocaleCode, LocaleMetadata> = {
|
||||
[Locales.NO]: {
|
||||
displayName: 'Norsk',
|
||||
flagCode: '1f1f3-1f1f4',
|
||||
aliases: ['nb', 'nn'],
|
||||
},
|
||||
[Locales.PL]: {
|
||||
displayName: 'Polski',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import type {LocaleCode} from '@fluxer/constants/src/Locales';
|
||||
import {type LocaleCode, Locales} from '@fluxer/constants/src/Locales';
|
||||
import {
|
||||
DEFAULT_LOCALE,
|
||||
findLocaleByLanguagePrefix,
|
||||
@@ -14,6 +14,9 @@ interface AcceptLanguagePreference {
|
||||
quality: number;
|
||||
}
|
||||
|
||||
const TRADITIONAL_CHINESE_SUBTAGS: ReadonlySet<string> = new Set(['hant', 'tw', 'hk', 'mo']);
|
||||
const SIMPLIFIED_CHINESE_SUBTAGS: ReadonlySet<string> = new Set(['hans', 'cn', 'sg']);
|
||||
|
||||
export function resolveLocaleFromAcceptLanguageHeader(acceptLanguageHeader: string | null | undefined): LocaleCode {
|
||||
if (!acceptLanguageHeader) {
|
||||
return DEFAULT_LOCALE;
|
||||
@@ -75,7 +78,15 @@ function findExactLocaleMatch(preferences: ReadonlyArray<AcceptLanguagePreferenc
|
||||
|
||||
function findLanguageFallbackMatch(preferences: ReadonlyArray<AcceptLanguagePreference>): LocaleCode | null {
|
||||
for (const {locale} of preferences) {
|
||||
const languageCode = getLanguageCode(locale);
|
||||
const [languageCode = '', ...subtags] = normalizeLocaleCode(locale).split('-');
|
||||
const chineseVariantLocale = findChineseVariantLocale(languageCode, subtags);
|
||||
if (chineseVariantLocale) {
|
||||
return chineseVariantLocale;
|
||||
}
|
||||
const languageLocale = getLocaleByCode(languageCode);
|
||||
if (languageLocale) {
|
||||
return languageLocale;
|
||||
}
|
||||
const preferredFallbackLocale = getPreferredLocaleForLanguageCode(languageCode);
|
||||
if (preferredFallbackLocale) {
|
||||
return preferredFallbackLocale;
|
||||
@@ -88,8 +99,17 @@ function findLanguageFallbackMatch(preferences: ReadonlyArray<AcceptLanguagePref
|
||||
return null;
|
||||
}
|
||||
|
||||
function getLanguageCode(locale: string): string {
|
||||
const normalizedLocale = normalizeLocaleCode(locale);
|
||||
const [languageCode] = normalizedLocale.split('-');
|
||||
return languageCode ?? '';
|
||||
function findChineseVariantLocale(languageCode: string, subtags: ReadonlyArray<string>): LocaleCode | null {
|
||||
if (languageCode !== 'zh') {
|
||||
return null;
|
||||
}
|
||||
for (const subtag of subtags) {
|
||||
if (TRADITIONAL_CHINESE_SUBTAGS.has(subtag)) {
|
||||
return Locales.ZH_TW;
|
||||
}
|
||||
if (SIMPLIFIED_CHINESE_SUBTAGS.has(subtag)) {
|
||||
return Locales.ZH_CN;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -62,6 +62,9 @@ const localeLookupCases: Array<LocaleLookupCase> = [
|
||||
{input: 'pt-br', expected: Locales.PT_BR},
|
||||
{input: 'sv', expected: Locales.SV_SE},
|
||||
{input: 'sv-se', expected: Locales.SV_SE},
|
||||
{input: 'nb', expected: Locales.NO},
|
||||
{input: 'nn', expected: Locales.NO},
|
||||
{input: 'NB', expected: Locales.NO},
|
||||
{input: 'xx', expected: null},
|
||||
{input: '', expected: null},
|
||||
{input: 'en-AU', expected: null},
|
||||
@@ -98,7 +101,31 @@ const acceptLanguageCases: Array<AcceptLanguageCase> = [
|
||||
{header: 'de;q=0.5, ja;q=0.9, fr;q=0.7', expected: Locales.JA},
|
||||
{header: 'de, fr;q=0.5', expected: Locales.DE},
|
||||
{header: 'xx-YY', expected: Locales.EN_US},
|
||||
{header: 'fr-CA', expected: Locales.EN_US},
|
||||
{header: 'fr-CA', expected: Locales.FR},
|
||||
{header: 'de-DE', expected: Locales.DE},
|
||||
{header: 'de-CH, fr-FR;q=0.8', expected: Locales.DE},
|
||||
{header: 'sv-FI', expected: Locales.SV_SE},
|
||||
{header: 'pt-PT', expected: Locales.PT_BR},
|
||||
{header: 'es-MX', expected: Locales.ES_ES},
|
||||
{header: 'nb', expected: Locales.NO},
|
||||
{header: 'nn', expected: Locales.NO},
|
||||
{header: 'nb-NO', expected: Locales.NO},
|
||||
{header: 'nn_NO', expected: Locales.NO},
|
||||
{header: 'no-NO', expected: Locales.NO},
|
||||
{header: 'nb-NO,nb;q=0.9,en-US;q=0.8,en;q=0.7', expected: Locales.NO},
|
||||
{header: 'zh-Hant', expected: Locales.ZH_TW},
|
||||
{header: 'zh-Hant-TW', expected: Locales.ZH_TW},
|
||||
{header: 'zh-Hant-HK', expected: Locales.ZH_TW},
|
||||
{header: 'zh-HK', expected: Locales.ZH_TW},
|
||||
{header: 'zh-MO', expected: Locales.ZH_TW},
|
||||
{header: 'zh_hant_tw', expected: Locales.ZH_TW},
|
||||
{header: 'zh-Hans', expected: Locales.ZH_CN},
|
||||
{header: 'zh-Hans-CN', expected: Locales.ZH_CN},
|
||||
{header: 'zh-SG', expected: Locales.ZH_CN},
|
||||
{header: 'zh-Hans-HK', expected: Locales.ZH_CN},
|
||||
{header: 'zh-Hant-CN', expected: Locales.ZH_TW},
|
||||
{header: 'zh-HK, zh-Hans;q=0.9', expected: Locales.ZH_TW},
|
||||
{header: 'zh-HK,zh;q=0.9', expected: Locales.ZH_TW},
|
||||
{header: ' de , fr ', expected: Locales.DE},
|
||||
{header: 'zh-TW', expected: Locales.ZH_TW},
|
||||
{header: 'zh-CN', expected: Locales.ZH_CN},
|
||||
|
||||
Reference in new issue
Block a user