fix: canonicalize widget date locales
This commit is contained in:
1 parent
2efa6bcd4c
commit
25b835dca9
9 files changed
+39
-11
No files matched your search
@@ -6,7 +6,7 @@ import type { SupportedLanguage } from "../config";
|
||||
import type englishTranslation from "../lang/en.json";
|
||||
|
||||
export { useChangeLocale } from "./use-change-locale";
|
||||
export { useCurrentLocale } from "./use-current-locale";
|
||||
export { useCurrentIntlLocale, useCurrentLocale } from "./use-current-locale";
|
||||
|
||||
declare module "next-intl" {
|
||||
interface AppConfig {
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import { useLocale } from "next-intl";
|
||||
|
||||
import { getIntlLocale } from "../config";
|
||||
|
||||
export const useCurrentLocale = useLocale;
|
||||
|
||||
export const useCurrentIntlLocale = () => getIntlLocale(useLocale());
|
||||
@@ -0,0 +1,16 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { getIntlLocale } from "./config";
|
||||
|
||||
describe("getIntlLocale", () => {
|
||||
it("maps Homarr-specific locale keys to canonical Intl locales", () => {
|
||||
expect(getIntlLocale("cn")).toBe("zh-CN");
|
||||
expect(getIntlLocale("zh")).toBe("zh-TW");
|
||||
expect(getIntlLocale("cr")).toBe("en");
|
||||
});
|
||||
|
||||
it("preserves locale keys that Intl already understands", () => {
|
||||
expect(getIntlLocale("fr")).toBe("fr");
|
||||
expect(getIntlLocale("de-CH")).toBe("de-CH");
|
||||
});
|
||||
});
|
||||
@@ -438,5 +438,13 @@ export type LanguageIconDefinition =
|
||||
|
||||
export { fallbackLocale } from "./languages";
|
||||
|
||||
const intlLocaleOverrides: Partial<Record<SupportedLanguage, string>> = {
|
||||
cn: "zh-CN",
|
||||
cr: "en",
|
||||
zh: "zh-TW",
|
||||
};
|
||||
|
||||
export const getIntlLocale = (locale: SupportedLanguage): string => intlLocaleOverrides[locale] ?? locale;
|
||||
|
||||
export const isLocaleRTL = (locale: SupportedLanguage) =>
|
||||
"isRTL" in localeConfigurations[locale] && localeConfigurations[locale].isRTL;
|
||||
@@ -5,7 +5,7 @@ import { Avatar, Badge, Card, Group, ScrollArea, SimpleGrid, Stack, Text } from
|
||||
import { clientApi } from "@homarr/api/client";
|
||||
import { formatByteRate } from "@homarr/common";
|
||||
import { getIconUrl } from "@homarr/definitions";
|
||||
import { useCurrentLocale, useScopedI18n } from "@homarr/translation/client";
|
||||
import { useCurrentIntlLocale, useScopedI18n } from "@homarr/translation/client";
|
||||
|
||||
import type { WidgetComponentProps } from "../definition";
|
||||
|
||||
@@ -47,7 +47,7 @@ const ArchiveTeamWarriorWidgetContent = ({
|
||||
isAdvanced: boolean;
|
||||
}) => {
|
||||
const t = useScopedI18n("widget.archiveTeamWarrior");
|
||||
const locale = useCurrentLocale();
|
||||
const locale = useCurrentIntlLocale();
|
||||
const [data] = clientApi.widget.archiveTeamWarrior.getStatus.useSuspenseQuery({ integrationId });
|
||||
|
||||
const status = data.status;
|
||||
|
||||
@@ -24,7 +24,7 @@ import { getIconUrl } from "@homarr/definitions";
|
||||
import type { MediaRelease } from "@homarr/integrations/types";
|
||||
import { mediaTypeConfigurations } from "@homarr/integrations/types";
|
||||
import type { TranslationFunction } from "@homarr/translation";
|
||||
import { useCurrentLocale, useI18n } from "@homarr/translation/client";
|
||||
import { useCurrentIntlLocale, useI18n } from "@homarr/translation/client";
|
||||
import type { TablerIcon } from "@homarr/ui";
|
||||
import { OverflowBadge } from "@homarr/ui";
|
||||
|
||||
@@ -78,7 +78,7 @@ const formatReleaseDate = (value: unknown, locale: string, compact: boolean) =>
|
||||
};
|
||||
|
||||
const Item = ({ item, options, isAdvanced, width, height }: ItemProps) => {
|
||||
const locale = useCurrentLocale();
|
||||
const locale = useCurrentIntlLocale();
|
||||
const t = useI18n();
|
||||
const length = formatLength(item.length, item.type, t);
|
||||
const isCompact = !isAdvanced && (width < 340 || height < 180);
|
||||
|
||||
@@ -7,7 +7,7 @@ import { IconBinaryTree } from "@tabler/icons-react";
|
||||
import { clientApi } from "@homarr/api/client";
|
||||
import { useIntegrationsWithInteractAccess } from "@homarr/auth/client";
|
||||
import { useRegisterSpotlightContextActions } from "@homarr/spotlight";
|
||||
import { useCurrentLocale, useI18n } from "@homarr/translation/client";
|
||||
import { useCurrentIntlLocale, useI18n } from "@homarr/translation/client";
|
||||
|
||||
import type { WidgetComponentProps } from "../../definition";
|
||||
|
||||
@@ -20,7 +20,7 @@ export default function SmartHomeEntityStateWidget({
|
||||
displayMode,
|
||||
}: WidgetComponentProps<"smartHome-entityState">) {
|
||||
const t = useI18n();
|
||||
const locale = useCurrentLocale();
|
||||
const locale = useCurrentIntlLocale();
|
||||
// It will always have at least one integration as otherwise the NoIntegrationSelectedError would be thrown in item-content.tsx
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const integrationId = integrationIds[0]!;
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Group, SimpleGrid, Stack, Text } from "@mantine/core";
|
||||
import { IconArrowDown, IconArrowUp, IconCircleCheck, IconCircleX, IconWaveSine } from "@tabler/icons-react";
|
||||
|
||||
import type { SpeedtestTrackerResult } from "@homarr/integrations/types";
|
||||
import { useCurrentLocale, useScopedI18n } from "@homarr/translation/client";
|
||||
import { useCurrentIntlLocale, useScopedI18n } from "@homarr/translation/client";
|
||||
|
||||
import { formatResultSpeed } from "./helpers";
|
||||
import { SectionLabel } from "./section-label";
|
||||
@@ -12,7 +12,7 @@ import { SpeedStatCard } from "./speed-stat-card";
|
||||
|
||||
export function LatestResultSection({ result, width = 500 }: { result: SpeedtestTrackerResult; width?: number }) {
|
||||
const t = useScopedI18n("widget.speedtestTracker");
|
||||
const locale = useCurrentLocale();
|
||||
const locale = useCurrentIntlLocale();
|
||||
const timestamp = Intl.DateTimeFormat(locale, {
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { Center, Flex, ScrollArea, SimpleGrid, Stack, Text } from "@mantine/core";
|
||||
|
||||
import { clientApi } from "@homarr/api/client";
|
||||
import { useCurrentLocale, useScopedI18n } from "@homarr/translation/client";
|
||||
import { useCurrentIntlLocale, useScopedI18n } from "@homarr/translation/client";
|
||||
|
||||
import type { WidgetComponentProps } from "../definition";
|
||||
import { VpnIntegrationCard } from "./vpn-card";
|
||||
@@ -21,7 +21,7 @@ export default function VpnWidget({
|
||||
});
|
||||
const t = useScopedI18n("widget.vpn");
|
||||
const tCommon = useScopedI18n("common");
|
||||
const locale = useCurrentLocale();
|
||||
const locale = useCurrentIntlLocale();
|
||||
const dense = displayMode === "compact" && (width < 240 || height < 120);
|
||||
|
||||
if (isPending || integrations.length === 0) {
|
||||
|
||||
Reference in new issue
Block a user