Skip to content
Snippets Groups Projects
Commit 8cc92e0c authored by insert's avatar insert
Browse files

Start work on fluent categories.

Fix Locale loading when syncing invalid lang.
parent c93f0245
No related merge requests found
......@@ -218,7 +218,7 @@ export const MessageDetail = observer(
<time className="copyTime">
<i className="copyBracket">[</i>
{dayjs(decodeTime(message._id)).format(
dict.dayjs.timeFormat,
dict.dayjs?.timeFormat,
)}
<i className="copyBracket">]</i>
</time>
......@@ -236,7 +236,7 @@ export const MessageDetail = observer(
<time>
<i className="copyBracket">[</i>
{dayjs(decodeTime(message._id)).format(
dict.dayjs.timeFormat,
dict.dayjs?.timeFormat,
)}
<i className="copyBracket">]</i>
</time>
......
import styled from "styled-components";
import { Children } from "../../../types/Preact";
const CategoryBase = styled.div`
height: 54px;
padding: 8px 12px;
border-radius: 6px;
margin-bottom: 10px;
background: var(--secondary-header);
gap: 12px;
display: flex;
align-items: center;
flex-direction: row;
`;
interface Props {
icon?: Children;
children?: Children;
}
export default function CategoryButton({ icon, children }: Props) {
return <CategoryBase>{icon}</CategoryBase>;
}
......@@ -149,35 +149,60 @@ interface Props {
locale: Language;
}
export interface Dictionary {
dayjs?: {
defaults?: {
twelvehour?: "yes" | "no";
separator?: string;
date?: "traditional" | "simplified" | "ISO8601";
};
timeFormat?: string;
};
[key: string]:
| Record<string, Omit<Dictionary, "dayjs">>
| string
| undefined;
}
function Locale({ children, locale }: Props) {
// TODO: create and use LanguageDefinition type here
const [defns, setDefinition] =
useState<Record<string, unknown>>(definition);
const lang = Languages[locale];
const [defns, setDefinition] = useState<Dictionary>(definition as any);
// Load relevant language information, fallback to English if invalid.
const lang = Languages[locale] ?? Languages.en;
// TODO: clean this up and use the built in Intl API
function transformLanguage(source: { [key: string]: any }) {
// Fallback untranslated strings to English (UK)
const obj = defaultsDeep(source, definition);
const dayjs = obj.dayjs;
const defaults = dayjs.defaults;
// Take relevant objects out, dayjs and defaults
// should exist given we just took defaults above.
const { dayjs } = obj;
const { defaults } = dayjs;
// Determine whether we are using 12-hour clock.
const twelvehour = defaults?.twelvehour
? defaults.twelvehour === "yes"
: false;
// Determine what date separator we are using.
const separator: string = defaults?.date_separator ?? "/";
// Determine what date format we are using.
const date: "traditional" | "simplified" | "ISO8601" =
defaults?.date_format ?? "traditional";
// Available date formats.
const DATE_FORMATS = {
traditional: `DD${separator}MM${separator}YYYY`,
simplified: `MM${separator}DD${separator}YYYY`,
ISO8601: "YYYY-MM-DD",
};
dayjs["sameElse"] = DATE_FORMATS[date];
// Replace data in dayjs object, make sure to provide fallbacks.
dayjs["sameElse"] = DATE_FORMATS[date] ?? DATE_FORMATS.traditional;
dayjs["timeFormat"] = twelvehour ? "hh:mm A" : "HH:mm";
// Replace {{time}} format string in dayjs strings with the time format.
Object.keys(dayjs)
.filter((k) => typeof dayjs[k] === "string")
.forEach(
......@@ -191,8 +216,10 @@ function Locale({ children, locale }: Props) {
return obj;
}
useEffect(() => {
function loadLanguage(locale: string) {
if (locale === "en") {
// If English, make sure to restore everything to defaults.
// Use what we already have.
const defn = transformLanguage(definition);
setDefinition(defn);
dayjs.locale("en");
......@@ -202,24 +229,33 @@ function Locale({ children, locale }: Props) {
import(`../../external/lang/${lang.i18n}.json`).then(
async (lang_file) => {
// Transform the definitions data.
const defn = transformLanguage(lang_file.default);
// Determine and load dayjs locales.
const target = lang.dayjs ?? lang.i18n;
const dayjs_locale = await import(
`../../node_modules/dayjs/esm/locale/${target}.js`
);
// Load dayjs locales.
dayjs.locale(target, dayjs_locale.default);
if (defn.dayjs) {
// Override dayjs calendar locales with our own.
dayjs.updateLocale(target, { calendar: defn.dayjs });
}
// Apply definition to app.
setDefinition(defn);
},
);
}, [locale, lang]);
}
useEffect(() => loadLanguage(locale), [locale, lang]);
useEffect(() => {
// Apply RTL language format.
document.body.style.direction = lang.rtl ? "rtl" : "";
}, [lang.rtl]);
......
import { IntlContext, translate } from "preact-i18n";
import { useContext } from "preact/hooks";
import { Dictionary } from "../context/Locale";
import { Children } from "../types/Preact";
interface Fields {
......@@ -12,18 +14,6 @@ interface Props {
fields: Fields;
}
export interface Dictionary {
dayjs: {
defaults: {
twelvehour: "yes" | "no";
separator: string;
date: "traditional" | "simplified" | "ISO8601";
};
timeFormat: string;
};
[key: string]: Object | string;
}
export interface IntlType {
intl: {
dictionary: Dictionary;
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment