Due to using the browsers' preferred languages by default, there was a possibility that the preferred language codes did not match any extension/source language, which lead to broken filtering. While this happened, it was also possible that the preferred languages still matched properly to a language in the language filter, which caused confusion. This was the case e.g., for "en-GB" or "en-US"
110 lines
3.1 KiB
TypeScript
110 lines
3.1 KiB
TypeScript
/*
|
|
* Copyright (C) Contributors to the Suwayomi project
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
import { t } from 'i18next';
|
|
import { ISOLanguage, IsoLanguages } from '@/modules/core/IsoLanguages.ts';
|
|
|
|
export enum DefaultLanguage {
|
|
ALL = 'all',
|
|
OTHER = 'other',
|
|
LOCAL_SOURCE = 'localsourcelang',
|
|
}
|
|
|
|
type LanguageObject = ISOLanguage & { orgCode: string; isoCode: string };
|
|
|
|
function getISOLanguage(code: string): LanguageObject | null {
|
|
if (IsoLanguages[code]) {
|
|
return {
|
|
...IsoLanguages[code],
|
|
orgCode: code,
|
|
isoCode: code,
|
|
};
|
|
}
|
|
|
|
if (IsoLanguages[code.toLocaleLowerCase()]) {
|
|
return {
|
|
...IsoLanguages[code.toLocaleLowerCase()],
|
|
orgCode: code,
|
|
isoCode: code.toLocaleLowerCase(),
|
|
};
|
|
}
|
|
|
|
const whereToCut = code.indexOf('-') !== -1 ? code.indexOf('-') : code.length;
|
|
const processedCode = code.toLocaleLowerCase().substring(0, whereToCut);
|
|
if (IsoLanguages[processedCode]) {
|
|
return {
|
|
...IsoLanguages[processedCode],
|
|
orgCode: code,
|
|
isoCode: processedCode,
|
|
};
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
export function getLanguage(code: string): LanguageObject {
|
|
const isoLanguage = getISOLanguage(code);
|
|
|
|
if (isoLanguage) {
|
|
return isoLanguage;
|
|
}
|
|
|
|
return {
|
|
orgCode: code,
|
|
isoCode: code,
|
|
name: t('global.language.label.language_with_code', { code }),
|
|
nativeName: t('global.language.label.language_with_code', { code }),
|
|
};
|
|
}
|
|
|
|
export function langCodeToName(code: string): string {
|
|
return getLanguage(code).nativeName;
|
|
}
|
|
|
|
export const toUniqueLanguageCodes = (codes: string[]): string[] => {
|
|
const languages = codes.map((code) => getLanguage(code));
|
|
const languagesByIsoCode = Object.groupBy(languages, (language) => language.isoCode);
|
|
|
|
return Object.entries(languagesByIsoCode)
|
|
.filter(([, languagesOfIsoCode]) => !!languagesOfIsoCode?.length)
|
|
.map(([, languagesOfIsoCode]) => languagesOfIsoCode![0].orgCode);
|
|
};
|
|
|
|
export const toComparableLanguage = (code: string): string => getLanguage(code).isoCode;
|
|
|
|
export const toComparableLanguages = (codes: string[]): string[] => codes.map(toComparableLanguage);
|
|
|
|
function defaultNativeLang(): readonly string[] {
|
|
const preferredLanguages = toUniqueLanguageCodes([...navigator.languages]);
|
|
|
|
if (!preferredLanguages.length) {
|
|
return ['en'];
|
|
}
|
|
|
|
return preferredLanguages;
|
|
}
|
|
|
|
export function extensionDefaultLangs(): string[] {
|
|
return [...defaultNativeLang()];
|
|
}
|
|
|
|
export function sourceDefualtLangs(): string[] {
|
|
return [...defaultNativeLang()];
|
|
}
|
|
|
|
export const langSortCmp = (a: string, b: string) => {
|
|
// puts english first for convience
|
|
const aLang = langCodeToName(a);
|
|
const bLang = langCodeToName(b);
|
|
|
|
if (a === 'en') return -1;
|
|
if (b === 'en') return 1;
|
|
|
|
return aLang.localeCompare(bLang);
|
|
};
|