Align language sorting with mihon
Always show "All" as the first language and "Other" as the last
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
import { ISOLanguage, IsoLanguages } from '@/modules/core/IsoLanguages.ts';
|
import { ISOLanguage, IsoLanguages } from '@/modules/core/IsoLanguages.ts';
|
||||||
|
import { TranslationKey } from '@/Base.types.ts';
|
||||||
|
|
||||||
export enum DefaultLanguage {
|
export enum DefaultLanguage {
|
||||||
ALL = 'all',
|
ALL = 'all',
|
||||||
@@ -15,6 +16,12 @@ export enum DefaultLanguage {
|
|||||||
LOCAL_SOURCE = 'localsourcelang',
|
LOCAL_SOURCE = 'localsourcelang',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DEFAULT_LANGUAGE_TO_TRANSLATION: Record<DefaultLanguage, TranslationKey> = {
|
||||||
|
[DefaultLanguage.ALL]: 'extension.language.all',
|
||||||
|
[DefaultLanguage.OTHER]: 'extension.language.other',
|
||||||
|
[DefaultLanguage.LOCAL_SOURCE]: 'extension.language.other',
|
||||||
|
};
|
||||||
|
|
||||||
type LanguageObject = ISOLanguage & { orgCode: string; isoCode: string };
|
type LanguageObject = ISOLanguage & { orgCode: string; isoCode: string };
|
||||||
|
|
||||||
function getISOLanguage(code: string): LanguageObject | null {
|
function getISOLanguage(code: string): LanguageObject | null {
|
||||||
@@ -63,6 +70,11 @@ export function getLanguage(code: string): LanguageObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function languageCodeToName(code: string): string {
|
export function languageCodeToName(code: string): string {
|
||||||
|
const isCustomLanguage = Object.keys(DEFAULT_LANGUAGE_TO_TRANSLATION).includes(code);
|
||||||
|
if (isCustomLanguage) {
|
||||||
|
return t(DEFAULT_LANGUAGE_TO_TRANSLATION[code as DefaultLanguage]);
|
||||||
|
}
|
||||||
|
|
||||||
return getLanguage(code).nativeName;
|
return getLanguage(code).nativeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,5 +105,36 @@ export function getDefaultLanguages(): string[] {
|
|||||||
return [...defaultNativeLang(), DefaultLanguage.ALL];
|
return [...defaultNativeLang(), DefaultLanguage.ALL];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const languageSortComparator = (a: string, b: string) =>
|
/**
|
||||||
languageCodeToName(a).localeCompare(languageCodeToName(b));
|
* Sort languages by their native name.
|
||||||
|
* Custom languages are optionally treated specially:
|
||||||
|
* - All: first
|
||||||
|
* - Other: last
|
||||||
|
*/
|
||||||
|
export const languageSortComparator = (a: string, b: string, specialCustomLanguagesHandling?: boolean) => {
|
||||||
|
const isALanguageAll = a === DefaultLanguage.ALL;
|
||||||
|
const isALanguageOther = a === DefaultLanguage.OTHER || a === DefaultLanguage.LOCAL_SOURCE;
|
||||||
|
|
||||||
|
const isBLanguageAll = b === DefaultLanguage.ALL;
|
||||||
|
const isBLanguageOther = b === DefaultLanguage.OTHER || b === DefaultLanguage.LOCAL_SOURCE;
|
||||||
|
|
||||||
|
if (specialCustomLanguagesHandling) {
|
||||||
|
if (isALanguageAll || isBLanguageOther) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isALanguageOther || isBLanguageAll) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return languageCodeToName(a).localeCompare(languageCodeToName(b));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort languages by their native name.
|
||||||
|
* Custom languages are treated specially:
|
||||||
|
* - All: first
|
||||||
|
* - Other: last
|
||||||
|
*/
|
||||||
|
export const languageSpecialSortComparator = (a: string, b: string) => languageSortComparator(a, b, true);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
DefaultLanguage,
|
DefaultLanguage,
|
||||||
languageCodeToName,
|
languageCodeToName,
|
||||||
languageSortComparator,
|
languageSpecialSortComparator,
|
||||||
toComparableLanguage,
|
toComparableLanguage,
|
||||||
toComparableLanguages,
|
toComparableLanguages,
|
||||||
toUniqueLanguageCodes,
|
toUniqueLanguageCodes,
|
||||||
@@ -86,7 +86,7 @@ export function groupExtensionsByLanguage(extensions: TExtension[]): GroupedExte
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return languageSortComparator(a, b);
|
return languageSpecialSortComparator(a, b);
|
||||||
});
|
});
|
||||||
|
|
||||||
const groupedExtensionsSortedByLanguage = extensionsBySortedLanguage.map(([language, extensionsOfLanguage]) => [
|
const groupedExtensionsSortedByLanguage = extensionsBySortedLanguage.map(([language, extensionsOfLanguage]) => [
|
||||||
@@ -97,8 +97,9 @@ export function groupExtensionsByLanguage(extensions: TExtension[]): GroupedExte
|
|||||||
return groupedExtensionsSortedByLanguage.filter(([, extensionsOfLanguage]) => !!extensionsOfLanguage.length);
|
return groupedExtensionsSortedByLanguage.filter(([, extensionsOfLanguage]) => !!extensionsOfLanguage.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getLanguagesFromExtensions = (extensions: TExtension[]): string[] =>
|
export const getLanguagesFromExtensions = (extensions: TExtension[]): string[] => [
|
||||||
[...new Set(extensions.map((extension) => extension.lang))].toSorted(languageSortComparator);
|
...new Set(extensions.map((extension) => extension.lang)),
|
||||||
|
];
|
||||||
|
|
||||||
export const filterExtensions = (
|
export const filterExtensions = (
|
||||||
extensions: TExtension[],
|
extensions: TExtension[],
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import {
|
|||||||
} from '@/modules/source/Source.types.ts';
|
} from '@/modules/source/Source.types.ts';
|
||||||
import {
|
import {
|
||||||
DefaultLanguage,
|
DefaultLanguage,
|
||||||
languageSortComparator,
|
languageSpecialSortComparator,
|
||||||
toComparableLanguage,
|
toComparableLanguage,
|
||||||
toComparableLanguages,
|
toComparableLanguages,
|
||||||
toUniqueLanguageCodes,
|
toUniqueLanguageCodes,
|
||||||
@@ -37,15 +37,15 @@ export class Sources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static getLanguages(sources: (SourceIdInfo & SourceLanguageInfo)[]): string[] {
|
static getLanguages(sources: (SourceIdInfo & SourceLanguageInfo)[]): string[] {
|
||||||
return [...new Set(sources.map((source) => Sources.getLanguage(source)))].toSorted(languageSortComparator);
|
return [...new Set(sources.map(Sources.getLanguage))];
|
||||||
}
|
}
|
||||||
|
|
||||||
static groupByLanguage<Source extends SourceIdInfo & SourceLanguageInfo & SourceDisplayNameInfo>(
|
static groupByLanguage<Source extends SourceIdInfo & SourceLanguageInfo & SourceDisplayNameInfo>(
|
||||||
sources: Source[],
|
sources: Source[],
|
||||||
): Record<string, Source[]> {
|
): Record<string, Source[]> {
|
||||||
const sourcesByLanguage = Object.groupBy(sources, (source) => Sources.getLanguage(source));
|
const sourcesByLanguage = Object.groupBy(sources, Sources.getLanguage);
|
||||||
const sourcesBySortedLanguage = Object.entries(sourcesByLanguage).toSorted(([a], [b]) =>
|
const sourcesBySortedLanguage = Object.entries(sourcesByLanguage).toSorted(([a], [b]) =>
|
||||||
languageSortComparator(a, b),
|
languageSpecialSortComparator(a, b),
|
||||||
);
|
);
|
||||||
const sortedSourcesBySortedLanguage = sourcesBySortedLanguage.map(([language, sourcesOfLanguage]) => [
|
const sortedSourcesBySortedLanguage = sourcesBySortedLanguage.map(([language, sourcesOfLanguage]) => [
|
||||||
language,
|
language,
|
||||||
|
|||||||
Reference in New Issue
Block a user