diff --git a/external/lang b/external/lang index c7fd514d..c84778b2 160000 --- a/external/lang +++ b/external/lang @@ -1 +1 @@ -Subproject commit c7fd514d4d83561e1802ae722501192d316cfe50 +Subproject commit c84778b2a87cc3f8b0b2778ca1f523d692a18875 diff --git a/scripts/locale.js b/scripts/locale.js new file mode 100644 index 00000000..09b67bae --- /dev/null +++ b/scripts/locale.js @@ -0,0 +1,22 @@ +const { readdirSync } = require("fs"); + +console.log( + "var locale_keys = " + + JSON.stringify([ + ...readdirSync("node_modules/dayjs/locale") + .filter((x) => x.endsWith(".js")) + .map((x) => { + v = x.split("."); + v.pop(); + return v.join("."); + }), + ...readdirSync("external/lang") + .filter((x) => x.endsWith(".json")) + .map((x) => { + v = x.split("."); + v.pop(); + return v.join("."); + }), + ]) + + ";", +); diff --git a/src/components/common/LocaleSelector.tsx b/src/components/common/LocaleSelector.tsx index 5fdaef24..5ac49279 100644 --- a/src/components/common/LocaleSelector.tsx +++ b/src/components/common/LocaleSelector.tsx @@ -1,9 +1,9 @@ import { useApplicationState } from "../../mobx/State"; -import { Language, Languages } from "../../context/Locale"; - import ComboBox from "../ui/ComboBox"; +import { Language, Languages } from "../../../external/lang/Languages"; + /** * Component providing a language selector combobox. * Note: this is not an observer but this is fine as we are just using a combobox. diff --git a/src/context/Locale.tsx b/src/context/Locale.tsx index 3a8a2cf7..ab7ce398 100644 --- a/src/context/Locale.tsx +++ b/src/context/Locale.tsx @@ -10,6 +10,7 @@ import { useCallback, useEffect, useState } from "preact/hooks"; import { useApplicationState } from "../mobx/State"; +import { Languages } from "../../external/lang/Languages"; import definition from "../../external/lang/en.json"; export const dayjs = dayJS; @@ -18,207 +19,6 @@ dayjs.extend(calendar); dayjs.extend(format); dayjs.extend(update); -export enum Language { - ENGLISH = "en", - - ARABIC = "ar", - AZERBAIJANI = "az", - BELARUSIAN = "be", - BULGARIAN = "bg", - BENGALI = "bn", - CATALONIAN = "ca", - CZECH = "cs", - DANISH = "da", - GERMAN = "de", - GREEK = "el", - SPANISH = "es", - ESTONIAN = "et", - FINNISH = "fi", - FILIPINO = "fil", - FRENCH = "fr", - IRISH = "ga", - HINDI = "hi", - CROATIAN = "hr", - HUNGARIAN = "hu", - INDONESIAN = "id", - ITALIAN = "it", - JAPANESE = "ja", - KOREAN = "ko", - LUXEMBOURGISH = "lb", - LITHUANIAN = "lt", - MACEDONIAN = "mk", - MALAY = "ms", - NORWEGIAN_BOKMAL = "nb_NO", - DUTCH = "nl", - PERSIAN = "fa", - POLISH = "pl", - PORTUGUESE_BRAZIL = "pt_BR", - PORTUGUESE_PORTUGAL = "pt_PT", - ROMANIAN = "ro", - RUSSIAN = "ru", - SLOVAK = "sk", - SLOVENIAN = "sl", - SERBIAN = "sr", - SINHALESE = "si", - SWEDISH = "sv", - TAMIL = "ta", - THAI = "th", - TURKISH = "tr", - UKRANIAN = "uk", - VIETNAMESE = "vi", - CHINESE_SIMPLIFIED = "zh_Hans", - LATVIAN = "lv", - - TOKIPONA = "tokipona", - ESPERANTO = "esperanto", - - OWO = "owo", - PIRATE = "pr", - BOTTOM = "bottom", - LEET = "leet", - PIGLATIN = "piglatin", - ENCHANTMENT_TABLE = "enchantment", -} - -export interface LanguageEntry { - display: string; - emoji: string; - i18n: string; - dayjs?: string; - rtl?: boolean; - cat?: "const" | "alt"; -} - -export const Languages: { [key in Language]: LanguageEntry } = { - en: { - display: "English (Traditional)", - emoji: "🇬🇧", - i18n: "en", - dayjs: "en-gb", - }, - - ar: { display: "عربي", emoji: "🇸🇦", i18n: "ar", rtl: true }, - az: { display: "Azərbaycan dili", emoji: "🇦🇿", i18n: "az" }, - be: { display: "беларуская", emoji: "🇧🇾", i18n: "be" }, - bg: { display: "български", emoji: "🇧🇬", i18n: "bg" }, - bn: { display: "বাংলা", emoji: "🇧🇩", i18n: "bn" }, - ca: { display: "Català", emoji: "🇪🇸", i18n: "ca" }, - cs: { display: "Čeština", emoji: "🇨🇿", i18n: "cs" }, - da: { display: "Danskers", emoji: "🇩🇰", i18n: "da" }, - de: { display: "Deutsch", emoji: "🇩🇪", i18n: "de" }, - el: { display: "Ελληνικά", emoji: "🇬🇷", i18n: "el" }, - es: { display: "Español", emoji: "🇪🇸", i18n: "es" }, - et: { display: "eesti", emoji: "🇪🇪", i18n: "et" }, - fi: { display: "suomi", emoji: "🇫🇮", i18n: "fi" }, - fil: { display: "Pilipino", emoji: "🇵🇭", i18n: "fil", dayjs: "tl-ph" }, - fr: { display: "Français", emoji: "🇫🇷", i18n: "fr" }, - ga: { display: "Gaeilge", emoji: "🇮🇪", i18n: "ga" }, - hi: { display: "हिन्दी", emoji: "🇮🇳", i18n: "hi" }, - hr: { display: "Hrvatski", emoji: "🇭🇷", i18n: "hr" }, - hu: { display: "magyar", emoji: "🇭🇺", i18n: "hu" }, - id: { display: "bahasa Indonesia", emoji: "🇮🇩", i18n: "id" }, - it: { display: "Italiano", emoji: "🇮🇹", i18n: "it" }, - ja: { display: "日本語", emoji: "🇯🇵", i18n: "ja" }, - ko: { display: "한국어", emoji: "🇰🇷", i18n: "ko" }, - lb: { display: "Lëtzebuergesch", emoji: "🇱🇺", i18n: "lb" }, - lt: { display: "Lietuvių", emoji: "🇱🇹", i18n: "lt" }, - mk: { display: "Македонски", emoji: "🇲🇰", i18n: "mk" }, - ms: { display: "Melayu", emoji: "🇲🇾", i18n: "ms" }, - nb_NO: { display: "Norsk bokmål", emoji: "🇳🇴", i18n: "nb_NO", dayjs: "nb" }, - nl: { display: "Nederlands", emoji: "🇳🇱", i18n: "nl" }, - fa: { display: "فارسی", emoji: "🇮🇷", i18n: "fa" }, - pl: { display: "Polski", emoji: "🇵🇱", i18n: "pl" }, - pt_BR: { - display: "Português (do Brasil)", - emoji: "🇧🇷", - i18n: "pt_BR", - dayjs: "pt-br", - }, - pt_PT: { - display: "Português (Portugal)", - emoji: "🇵🇹", - i18n: "pt_PT", - dayjs: "pt", - }, - ro: { display: "Română", emoji: "🇷🇴", i18n: "ro" }, - ru: { display: "Русский", emoji: "🇷🇺", i18n: "ru" }, - sk: { display: "Slovensky", emoji: "🇸🇰", i18n: "sk" }, - sl: { display: "Slovenščina", emoji: "🇸🇮", i18n: "sl" }, - sr: { display: "Српски", emoji: "🇷🇸", i18n: "sr" }, - si: { display: "සිංහල", emoji: "🇱🇰", i18n: "si" }, - sv: { display: "Svenska", emoji: "🇸🇪", i18n: "sv" }, - ta: { display: "தமிழ்", emoji: "🇮🇳", i18n: "ta" }, - th: { display: "ไทย", emoji: "🇹🇭", i18n: "th" }, - tr: { display: "Türkçe", emoji: "🇹🇷", i18n: "tr" }, - uk: { display: "Українська", emoji: "🇺🇦", i18n: "uk" }, - vi: { display: "Tiếng Việt", emoji: "🇻🇳", i18n: "vi" }, - zh_Hans: { - display: "中文 (简体)", - emoji: "🇨🇳", - i18n: "zh_Hans", - dayjs: "zh", - }, - lv: { display: "Latviešu", emoji: "🇱🇻", i18n: "lv" }, - - tokipona: { - display: "Toki Pona", - emoji: "🙂", - i18n: "tokipona", - dayjs: "en-gb", - cat: "const", - }, - esperanto: { - display: "Esperanto", - emoji: "EO", - i18n: "eo", - dayjs: "en-gb", - cat: "const", - }, - - owo: { - display: "OwO", - emoji: "😸", - i18n: "owo", - dayjs: "en-gb", - cat: "alt", - }, - pr: { - display: "Pirate", - emoji: "🏴‍☠️", - i18n: "pr", - dayjs: "en-gb", - cat: "alt", - }, - bottom: { - display: "Bottom", - emoji: "🥺", - i18n: "bottom", - dayjs: "en-gb", - cat: "alt", - }, - leet: { - display: "1337", - emoji: "💾", - i18n: "leet", - dayjs: "en-gb", - cat: "alt", - }, - enchantment: { - display: "Enchantment Table", - emoji: "🪄", - i18n: "enchantment", - dayjs: "en-gb", - cat: "alt", - }, - piglatin: { - display: "Pig Latin", - emoji: "🐖", - i18n: "piglatin", - dayjs: "en-gb", - cat: "alt", - }, -}; - interface Props { children: JSX.Element | JSX.Element[]; } diff --git a/src/mobx/legacy/redux.ts b/src/mobx/legacy/redux.ts index 1069494e..90269845 100644 --- a/src/mobx/legacy/redux.ts +++ b/src/mobx/legacy/redux.ts @@ -1,14 +1,9 @@ import { runInAction } from "mobx"; import { Session } from "revolt-api/types/Auth"; -import { Language } from "../../context/Locale"; -import { - Fonts, - MonospaceFonts, - Overrides, - ThemeOptions, -} from "../../context/Theme"; +import { Fonts, MonospaceFonts, Overrides } from "../../context/Theme"; +import { Language } from "../../../external/lang/Languages"; import State from "../State"; import { Data as DataAuth } from "../stores/Auth"; import { Data as DataLocaleOptions } from "../stores/LocaleOptions"; diff --git a/src/mobx/stores/LocaleOptions.ts b/src/mobx/stores/LocaleOptions.ts index a22d3b3c..24a7161b 100644 --- a/src/mobx/stores/LocaleOptions.ts +++ b/src/mobx/stores/LocaleOptions.ts @@ -1,7 +1,6 @@ import { action, computed, makeAutoObservable } from "mobx"; -import { Language, Languages } from "../../context/Locale"; - +import { Languages, Language } from "../../../external/lang/Languages"; import Persistent from "../interfaces/Persistent"; import Store from "../interfaces/Store"; import Syncable from "../interfaces/Syncable"; diff --git a/src/pages/settings/panes/Languages.tsx b/src/pages/settings/panes/Languages.tsx index 541218d4..7ea9d283 100644 --- a/src/pages/settings/panes/Languages.tsx +++ b/src/pages/settings/panes/Languages.tsx @@ -6,12 +6,6 @@ import { useMemo } from "preact/hooks"; import { useApplicationState } from "../../../mobx/State"; -import { - Language, - LanguageEntry, - Languages as Langs, -} from "../../../context/Locale"; - import Emoji from "../../../components/common/Emoji"; import Checkbox from "../../../components/ui/Checkbox"; import Tip from "../../../components/ui/Tip"; @@ -20,6 +14,12 @@ import esperantoFlagSVG from "../assets/esperanto.svg"; import tamilFlagPNG from "../assets/tamil_nadu_flag.png"; import tokiponaSVG from "../assets/toki_pona.svg"; +import { + Language, + LanguageEntry, + Languages as Langs, +} from "../../../../external/lang/Languages"; + type Key = [Language, LanguageEntry]; interface Props { diff --git a/src/sw.ts b/src/sw.ts index f5e6a2c0..5daf6258 100644 --- a/src/sw.ts +++ b/src/sw.ts @@ -1,5 +1,5 @@ /// -import { precacheAndRoute } from "workbox-precaching"; +import { precacheAndRoute, cleanupOutdatedCaches } from "workbox-precaching"; declare let self: ServiceWorkerGlobalScope; @@ -7,7 +7,40 @@ self.addEventListener("message", (event) => { if (event.data && event.data.type === "SKIP_WAITING") self.skipWaiting(); }); -precacheAndRoute(self.__WB_MANIFEST); +cleanupOutdatedCaches(); + +// Generate list using scripts/locale.js +// prettier-ignore +var locale_keys = ["af","am","ar-dz","ar-kw","ar-ly","ar-ma","ar-sa","ar-tn","ar","az","be","bg","bi","bm","bn","bo","br","bs","ca","cs","cv","cy","da","de-at","de-ch","de","dv","el","en-au","en-ca","en-gb","en-ie","en-il","en-in","en-nz","en-sg","en-tt","en","eo","es-do","es-pr","es-us","es","et","eu","fa","fi","fo","fr-ca","fr-ch","fr","fy","ga","gd","gl","gom-latn","gu","he","hi","hr","ht","hu","hy-am","id","is","it-ch","it","ja","jv","ka","kk","km","kn","ko","ku","ky","lb","lo","lt","lv","me","mi","mk","ml","mn","mr","ms-my","ms","mt","my","nb","ne","nl-be","nl","nn","oc-lnc","pa-in","pl","pt-br","pt","ro","ru","rw","sd","se","si","sk","sl","sq","sr-cyrl","sr","ss","sv-fi","sv","sw","ta","te","tet","tg","th","tk","tl-ph","tlh","tr","tzl","tzm-latn","tzm","ug-cn","uk","ur","uz-latn","uz","vi","x-pseudo","yo","zh-cn","zh-hk","zh-tw","zh","ang","ar","az","be","bg","bn","bottom","br","ca","ca@valencia","cs","cy","da","de","de_CH","el","en","en_US","enchantment","enm","eo","es","et","eu","fa","fi","fil","fr","frm","ga","got","he","hi","hr","hu","id","it","ja","ko","la","lb","leet","li","lt","lv","mk","ml","ms","mt","nb_NO","nl","owo","peo","piglatin","pl","pr","pt_BR","pt_PT","ro","ro_MD","ru","si","sk","sl","sq","sr","sv","ta","te","th","tlh-qaak","tokipona","tr","uk","vi","zh_Hans","zh_Hant"]; + +precacheAndRoute( + self.__WB_MANIFEST.filter((entry) => { + try { + const url = typeof entry === "string" ? entry : entry.url; + if (url.includes("-legacy")) return false; + + const fn = url.split("/").pop(); + if (fn) { + if ( + fn.endsWith("css") && + !isNaN(parseInt(fn.substring(0, 3))) + ) { + return false; + } + + for (const key of locale_keys) { + if (fn.startsWith(key + ".")) { + return false; + } + } + } + + return true; + } catch (err) { + return false; + } + }), +); self.addEventListener("push", (event) => { async function process() { diff --git a/tsconfig.json b/tsconfig.json index 722675db..1df4e75d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,5 +19,5 @@ "types": ["vite-plugin-pwa/client"], "experimentalDecorators": true }, - "include": ["src", "ui/ui.tsx"] + "include": ["src", "ui/ui.tsx", "external/lang/Languages.ts"] }