fix(i18n): numbers, units, dates and order in the UI language, and after a switch (E30 S3)
Every locale formatter takes the language as an argument. Under the React
Compiler a formatter that read the i18n singleton was memoized on its other
arguments, so a card kept "2 hr 4 min" after a switch to Hungarian; plexLang()
had the same flaw and left Plex queries in the old language. Components now
take the language from useTranslation, and the signature makes forgetting it
a type error.
- ratings, file sizes, stream stats: the language's decimal mark ("8,3")
- view and subscriber counts compact in the language ("1,2 E")
- seconds as the language's unit ("6 mp") in the sliders and the stats
- a person's birth and death dates as dates, not ISO strings
- A-Z lists by the shown name in the language's alphabet (compareText),
the tag catalog re-sorted by its translated names
- lint local/locale-format (was date-format) also refuses Intl.NumberFormat
outside lib/format.ts, localeCompare, and a component reading the language
off the i18n singleton
This commit is contained in:
@@ -46,7 +46,7 @@ describe("YT_SORT_KEYS", () => {
|
||||
|
||||
describe("sortYtResults", () => {
|
||||
it("leaves the provider's ranking alone on `relevance`", () => {
|
||||
expect(titles(sortYtResults(RESULTS, "relevance", "desc"))).toEqual([
|
||||
expect(titles(sortYtResults(RESULTS, "relevance", "desc", "en"))).toEqual([
|
||||
"b-old-short",
|
||||
"a-new-long",
|
||||
"c-mid-mid",
|
||||
@@ -54,12 +54,12 @@ describe("sortYtResults", () => {
|
||||
});
|
||||
|
||||
it("orders by upload date in both directions", () => {
|
||||
expect(titles(sortYtResults(RESULTS, "date", "desc"))).toEqual([
|
||||
expect(titles(sortYtResults(RESULTS, "date", "desc", "en"))).toEqual([
|
||||
"a-new-long",
|
||||
"c-mid-mid",
|
||||
"b-old-short",
|
||||
]);
|
||||
expect(titles(sortYtResults(RESULTS, "date", "asc"))).toEqual([
|
||||
expect(titles(sortYtResults(RESULTS, "date", "asc", "en"))).toEqual([
|
||||
"b-old-short",
|
||||
"c-mid-mid",
|
||||
"a-new-long",
|
||||
@@ -67,14 +67,18 @@ describe("sortYtResults", () => {
|
||||
});
|
||||
|
||||
it("orders by views and by length", () => {
|
||||
expect(titles(sortYtResults(RESULTS, "popular", "desc"))[0]).toBe("c-mid-mid");
|
||||
expect(titles(sortYtResults(RESULTS, "duration", "desc"))[0]).toBe("a-new-long");
|
||||
expect(titles(sortYtResults(RESULTS, "duration", "asc"))[0]).toBe("b-old-short");
|
||||
expect(titles(sortYtResults(RESULTS, "popular", "desc", "en"))[0]).toBe("c-mid-mid");
|
||||
expect(titles(sortYtResults(RESULTS, "duration", "desc", "en"))[0]).toBe("a-new-long");
|
||||
expect(titles(sortYtResults(RESULTS, "duration", "asc", "en"))[0]).toBe("b-old-short");
|
||||
});
|
||||
|
||||
it("orders by title alphabetically, not by code point", () => {
|
||||
const accented = [v({ title: "Zebra" }), v({ title: "Ábel" }), v({ title: "alma" })];
|
||||
expect(titles(sortYtResults(accented, "title", "asc"))).toEqual(["Ábel", "alma", "Zebra"]);
|
||||
expect(titles(sortYtResults(accented, "title", "asc", "en"))).toEqual([
|
||||
"Ábel",
|
||||
"alma",
|
||||
"Zebra",
|
||||
]);
|
||||
});
|
||||
|
||||
it("sinks results with no value to the END in both directions", () => {
|
||||
@@ -84,8 +88,16 @@ describe("sortYtResults", () => {
|
||||
v({ title: "long", duration_seconds: 900 }),
|
||||
v({ title: "short", duration_seconds: 60 }),
|
||||
];
|
||||
expect(titles(sortYtResults(mixed, "duration", "desc"))).toEqual(["long", "short", "unknown"]);
|
||||
expect(titles(sortYtResults(mixed, "duration", "asc"))).toEqual(["short", "long", "unknown"]);
|
||||
expect(titles(sortYtResults(mixed, "duration", "desc", "en"))).toEqual([
|
||||
"long",
|
||||
"short",
|
||||
"unknown",
|
||||
]);
|
||||
expect(titles(sortYtResults(mixed, "duration", "asc", "en"))).toEqual([
|
||||
"short",
|
||||
"long",
|
||||
"unknown",
|
||||
]);
|
||||
});
|
||||
|
||||
it("keeps the provider's ranking inside a tie, in both directions", () => {
|
||||
@@ -95,19 +107,27 @@ describe("sortYtResults", () => {
|
||||
v({ title: "second", view_count: 100 }),
|
||||
v({ title: "third", view_count: 5 }),
|
||||
];
|
||||
expect(titles(sortYtResults(tied, "popular", "desc"))).toEqual(["first", "second", "third"]);
|
||||
expect(titles(sortYtResults(tied, "popular", "asc"))).toEqual(["third", "first", "second"]);
|
||||
expect(titles(sortYtResults(tied, "popular", "desc", "en"))).toEqual([
|
||||
"first",
|
||||
"second",
|
||||
"third",
|
||||
]);
|
||||
expect(titles(sortYtResults(tied, "popular", "asc", "en"))).toEqual([
|
||||
"third",
|
||||
"first",
|
||||
"second",
|
||||
]);
|
||||
});
|
||||
|
||||
it("does not reorder anything for a key it cannot honour", () => {
|
||||
// A pref stored before this view offered a control can name `shuffle` or `priority`.
|
||||
expect(titles(sortYtResults(RESULTS, "priority", "desc"))).toEqual(titles(RESULTS));
|
||||
expect(titles(sortYtResults(RESULTS, "shuffle", "desc"))).toEqual(titles(RESULTS));
|
||||
expect(titles(sortYtResults(RESULTS, "priority", "desc", "en"))).toEqual(titles(RESULTS));
|
||||
expect(titles(sortYtResults(RESULTS, "shuffle", "desc", "en"))).toEqual(titles(RESULTS));
|
||||
});
|
||||
|
||||
it("does not mutate the array it was given", () => {
|
||||
const input = [...RESULTS];
|
||||
sortYtResults(input, "date", "asc");
|
||||
sortYtResults(input, "date", "asc", "en");
|
||||
expect(titles(input)).toEqual(titles(RESULTS));
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user