⬆️ v3.0.0 (#704)

This commit is contained in:
Luke Vella 2023-06-19 17:17:00 +01:00 committed by GitHub
parent 735056f25f
commit c22b3abc4d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
385 changed files with 19912 additions and 5250 deletions

View file

@ -1,3 +1,5 @@
import { trpc } from "@rallly/backend";
import { TimeFormat } from "@rallly/database";
import dayjs from "dayjs";
import duration from "dayjs/plugin/duration";
import isBetween from "dayjs/plugin/isBetween";
@ -8,127 +10,127 @@ import localizedFormat from "dayjs/plugin/localizedFormat";
import minMax from "dayjs/plugin/minMax";
import relativeTime from "dayjs/plugin/relativeTime";
import timezone from "dayjs/plugin/timezone";
import updateLocale from "dayjs/plugin/updateLocale";
import utc from "dayjs/plugin/utc";
import { useTranslation } from "next-i18next";
import { useRouter } from "next/router";
import * as React from "react";
import { useAsync, useLocalStorage } from "react-use";
import { useAsync } from "react-use";
import { getBrowserTimeZone } from "@/utils/date-time-utils";
import { useRequiredContext } from "../components/use-required-context";
export type TimeFormat = "12h" | "24h";
export type StartOfWeek = "monday" | "sunday";
const dayjsLocales: Record<
string,
{
weekStartsOn: StartOfWeek;
weekStart: number;
timeFormat: TimeFormat;
import: () => Promise<ILocale>;
}
> = {
en: {
weekStartsOn: "monday",
timeFormat: "12h",
weekStart: 1,
timeFormat: "hours12",
import: () => import("dayjs/locale/en"),
},
es: {
weekStartsOn: "monday",
timeFormat: "24h",
weekStart: 1,
timeFormat: "hours24",
import: () => import("dayjs/locale/es"),
},
ca: {
weekStartsOn: "monday",
timeFormat: "24h",
weekStart: 1,
timeFormat: "hours24",
import: () => import("dayjs/locale/ca"),
},
da: {
weekStartsOn: "monday",
timeFormat: "24h",
weekStart: 1,
timeFormat: "hours24",
import: () => import("dayjs/locale/da"),
},
de: {
weekStartsOn: "monday",
timeFormat: "24h",
weekStart: 1,
timeFormat: "hours24",
import: () => import("dayjs/locale/de"),
},
fi: {
weekStartsOn: "monday",
timeFormat: "24h",
weekStart: 1,
timeFormat: "hours24",
import: () => import("dayjs/locale/fi"),
},
fr: {
weekStartsOn: "monday",
timeFormat: "24h",
weekStart: 1,
timeFormat: "hours24",
import: () => import("dayjs/locale/fr"),
},
hr: {
weekStartsOn: "monday",
timeFormat: "24h",
weekStart: 1,
timeFormat: "hours24",
import: () => import("dayjs/locale/hr"),
},
it: {
weekStartsOn: "monday",
timeFormat: "24h",
weekStart: 1,
timeFormat: "hours24",
import: () => import("dayjs/locale/it"),
},
sv: {
weekStartsOn: "monday",
timeFormat: "24h",
weekStart: 1,
timeFormat: "hours24",
import: () => import("dayjs/locale/sv"),
},
sk: {
weekStartsOn: "monday",
timeFormat: "24h",
weekStart: 1,
timeFormat: "hours24",
import: () => import("dayjs/locale/sk"),
},
cs: {
weekStartsOn: "monday",
timeFormat: "24h",
weekStart: 1,
timeFormat: "hours24",
import: () => import("dayjs/locale/cs"),
},
pl: {
weekStartsOn: "monday",
timeFormat: "24h",
weekStart: 1,
timeFormat: "hours24",
import: () => import("dayjs/locale/pl"),
},
pt: {
weekStartsOn: "monday",
timeFormat: "24h",
weekStart: 1,
timeFormat: "hours24",
import: () => import("dayjs/locale/pt"),
},
"pt-BR": {
weekStartsOn: "sunday",
timeFormat: "24h",
weekStart: 0,
timeFormat: "hours24",
import: () => import("dayjs/locale/pt-br"),
},
ru: {
weekStartsOn: "monday",
timeFormat: "24h",
weekStart: 1,
timeFormat: "hours24",
import: () => import("dayjs/locale/ru"),
},
ko: {
weekStartsOn: "sunday",
timeFormat: "12h",
weekStart: 0,
timeFormat: "hours12",
import: () => import("dayjs/locale/ko"),
},
nl: {
weekStartsOn: "monday",
timeFormat: "24h",
weekStart: 1,
timeFormat: "hours24",
import: () => import("dayjs/locale/nl"),
},
hu: {
weekStartsOn: "monday",
timeFormat: "24h",
weekStart: 1,
timeFormat: "hours24",
import: () => import("dayjs/locale/hu"),
},
zh: {
weekStartsOn: "monday",
timeFormat: "24h",
weekStart: 1,
timeFormat: "hours24",
import: () => import("dayjs/locale/zh"),
},
vi: {
weekStartsOn: "monday",
timeFormat: "24h",
weekStart: 1,
timeFormat: "hours24",
import: () => import("dayjs/locale/vi"),
},
};
@ -143,78 +145,76 @@ dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.extend(duration);
dayjs.extend(isSameOrAfter);
dayjs.extend(updateLocale);
const DayjsContext = React.createContext<{
adjustTimeZone: (
date: dayjs.ConfigType,
keepLocalTime?: boolean,
) => dayjs.Dayjs;
dayjs: (date?: dayjs.ConfigType) => dayjs.Dayjs;
weekStartsOn: StartOfWeek;
locale: {
weekStart: number;
timeFormat: TimeFormat;
timeZone: string;
};
weekStart: number;
timeZone: string;
timeFormat: TimeFormat;
setWeekStartsOn: React.Dispatch<
React.SetStateAction<StartOfWeek | undefined>
>;
setTimeFormat: React.Dispatch<React.SetStateAction<TimeFormat | undefined>>;
} | null>(null);
export const useDayjs = () => {
return useRequiredContext(DayjsContext);
};
const DayjsProviderInner: React.FunctionComponent<{
export const DayjsProvider: React.FunctionComponent<{
children?: React.ReactNode;
}> = ({ children }) => {
const { i18n } = useTranslation();
const router = useRouter();
// Using language instead of router.locale because when transitioning from homepage to
// the app via <Link locale={false}> it will be set to "en" instead of the current locale.
const localeConfig = dayjsLocales[i18n.language];
const localeConfig = dayjsLocales[router.locale ?? "en"];
const { data } = trpc.userPreferences.get.useQuery();
const [weekStartsOn = localeConfig.weekStartsOn, setWeekStartsOn] =
useLocalStorage<StartOfWeek>("rallly-week-starts-on");
useAsync(async () => {
const locale = await localeConfig.import();
const localeTimeFormat = localeConfig.timeFormat;
const timeFormat = data?.timeFormat ?? localeConfig.timeFormat;
dayjs.locale("custom", {
...locale,
weekStart: data?.weekStart ?? locale.weekStart,
formats:
localeTimeFormat === data?.timeFormat
? locale.formats
: {
...locale.formats,
LT: timeFormat === "hours12" ? "h:mm A" : "HH:mm",
},
});
}, [localeConfig, data]);
const [timeFormat = localeConfig.timeFormat, setTimeFormat] =
useLocalStorage<TimeFormat>("rallly-time-format");
const locale = {
timeZone: getBrowserTimeZone(),
weekStart: localeConfig.weekStart,
timeFormat: localeConfig.timeFormat,
};
const { value: dayjsLocale } = useAsync(async () => {
return await localeConfig.import();
}, [localeConfig]);
if (!dayjsLocale) {
// wait for locale to load before rendering content
return null;
}
dayjs.locale({
...dayjsLocale,
weekStart: weekStartsOn
? weekStartsOn === "monday"
? 1
: 0
: dayjsLocale.weekStart,
formats:
localeConfig.timeFormat !== timeFormat
? {
...dayjsLocale.formats,
LT: timeFormat === "12h" ? "h:mm A" : "HH:mm",
}
: dayjsLocale.formats,
});
const preferredTimeZone = data?.timeZone ?? locale.timeZone;
return (
<DayjsContext.Provider
value={{
adjustTimeZone: (date, keepLocalTime) =>
keepLocalTime
? dayjs(date).tz("GMT")
: dayjs(date).tz(preferredTimeZone),
dayjs,
weekStartsOn: weekStartsOn ?? localeConfig.weekStartsOn,
timeFormat: timeFormat ?? localeConfig.timeFormat,
setWeekStartsOn,
setTimeFormat,
locale,
timeZone: preferredTimeZone,
weekStart: dayjs.localeData().firstDayOfWeek() === 0 ? 0 : 1,
timeFormat: data?.timeFormat ?? localeConfig.timeFormat,
}}
>
{children}
</DayjsContext.Provider>
);
};
export const DayjsProvider: React.FunctionComponent<{
children?: React.ReactNode;
}> = ({ children }) => {
return <DayjsProviderInner>{children}</DayjsProviderInner>;
};