Skip to content

Commit 49a2124

Browse files
committed
i18n properly
1 parent 8bd75c3 commit 49a2124

12 files changed

Lines changed: 143 additions & 132 deletions

Build/index.html

Lines changed: 96 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,111 @@
1-
<!DOCTYPE html>
1+
<!doctype html>
22
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1" />
6+
<!-- Fallback Metadata -->
7+
<meta
8+
name="description"
9+
content="A modern music player interface with playlists, song management, and an amazing visualizer."
10+
/>
11+
<meta
12+
property="og:image"
13+
content="https://nellowtcs.me/assets/icon-1024.png"
14+
/>
15+
<meta
16+
property="og:description"
17+
content="A modern music player interface with playlists, song management, and an amazing visualizer."
18+
/>
19+
<meta property="og:title" content="HTMLPlayer (beta)" />
320

4-
<head>
5-
<meta charset="UTF-8" />
6-
<meta name="viewport" content="width=device-width, initial-scale=1" />
7-
<!-- Fallback Metadata -->
8-
<meta name="description"
9-
content="A modern music player interface with playlists, song management, and an amazing visualizer." />
10-
<meta property="og:image" content="https://nellowtcs.me/assets/icon-1024.png" />
11-
<meta property="og:description"
12-
content="A modern music player interface with playlists, song management, and an amazing visualizer." />
13-
<meta property="og:title" content="HTMLPlayer (beta)" />
21+
<script>
22+
(function () {
23+
// Vite will replace these exact strings during build
24+
const isSingleFile = __IS_SINGLE_FILE__;
25+
const iconData = __INLINED_ICON__;
1426

15-
<script>
16-
(function () {
17-
// Vite will replace these exact strings during build
18-
const isSingleFile = __IS_SINGLE_FILE__;
19-
const iconData = __INLINED_ICON__;
27+
if (isSingleFile && iconData) {
28+
const link =
29+
document.querySelector("link[rel*='icon']") ||
30+
document.createElement("link");
31+
link.type = "image/png";
32+
link.rel = "icon";
33+
link.href = iconData;
34+
document.head.appendChild(link);
2035

21-
if (isSingleFile && iconData) {
22-
const link = document.querySelector("link[rel*='icon']") || document.createElement('link');
23-
link.type = 'image/png';
24-
link.rel = 'icon';
25-
link.href = iconData;
26-
document.head.appendChild(link);
27-
28-
const ogImage = document.querySelector('meta[property="og:image"]') || document.createElement('meta');
29-
ogImage.setAttribute('property', 'og:image');
30-
ogImage.content = iconData;
31-
document.head.appendChild(ogImage);
32-
}
33-
})();
34-
</script>
36+
const ogImage =
37+
document.querySelector('meta[property="og:image"]') ||
38+
document.createElement("meta");
39+
ogImage.setAttribute("property", "og:image");
40+
ogImage.content = iconData;
41+
document.head.appendChild(ogImage);
42+
}
43+
})();
44+
</script>
3545

36-
<link href="./src/global.css" rel="stylesheet" />
37-
<!-- Default theme loaded first for instant styling and first load -->
38-
<link href="./src/themes/Themes/Blue/Blue.theme.css" rel="stylesheet" id="theme-link" />
46+
<link href="./src/global.css" rel="stylesheet" />
47+
<!-- Default theme loaded first for instant styling and first load -->
48+
<link
49+
href="./src/themes/Themes/Blue/Blue.theme.css"
50+
rel="stylesheet"
51+
id="theme-link"
52+
/>
3953

40-
<!-- Load user's saved theme and dark mode preference ASAP -->
41-
<script>
42-
(function () {
43-
// Apply dark mode immediately if needed (before theme switching)
44-
const savedMode = localStorage.getItem('themeMode') || 'auto';
45-
if (savedMode === 'dark') {
46-
document.documentElement.classList.add('dark');
47-
} else if (savedMode === 'auto') {
48-
// Check system preference
49-
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
50-
document.documentElement.classList.add('dark');
54+
<!-- Load user's saved theme and dark mode preference ASAP -->
55+
<script>
56+
(function () {
57+
// Apply dark mode immediately if needed (before theme switching)
58+
const savedMode = localStorage.getItem("themeMode") || "auto";
59+
if (savedMode === "dark") {
60+
document.documentElement.classList.add("dark");
61+
} else if (savedMode === "auto") {
62+
// Check system preference
63+
if (
64+
window.matchMedia &&
65+
window.matchMedia("(prefers-color-scheme: dark)").matches
66+
) {
67+
document.documentElement.classList.add("dark");
68+
}
5169
}
52-
}
53-
})();
54-
</script>
55-
56-
<title>HTMLPlayer</title>
57-
</head>
58-
<body>
59-
<!-- Loading screen shown before React loads -->
60-
<div id="loading-screen" class="loadingScreen">
61-
<div class="loadingContent">
62-
<div class="loadingSpinner"></div>
63-
<h1 class="loadingTitle">HTMLPlayer</h1>
64-
<p class="loadingText" id="loading-text">Loading the loading message...</p>
70+
})();
71+
</script>
6572

73+
<title>HTMLPlayer</title>
74+
</head>
75+
<body>
76+
<!-- Loading screen shown before React loads -->
77+
<div id="loading-screen" class="loadingScreen">
78+
<div class="loadingContent">
79+
<div class="loadingSpinner"></div>
80+
<h1 class="loadingTitle">HTMLPlayer</h1>
81+
<p class="loadingText" id="loading-text">
82+
Loading the loading message...
83+
</p>
84+
</div>
6685
</div>
67-
</div>
6886

69-
<div id="root"></div>
87+
<div id="root"></div>
7088

71-
<!-- Load fun loading messages -->
72-
<script>
73-
(function () {
74-
const userLang = (navigator.language || 'en').substring(0, 2);
75-
const lang = (userLang === 'fr') ? 'fr' : 'en';
76-
const loadingText = document.getElementById('loading-text');
77-
78-
const updateText = (messages) => {
79-
if (loadingText && messages) {
80-
const randomMessage = messages[Math.floor(Math.random() * messages.length)];
81-
loadingText.textContent = randomMessage;
82-
}
83-
};
89+
<!-- Load fun loading messages -->
90+
<script>
91+
(function () {
92+
const userLang = (navigator.language || "en").substring(0, 2);
93+
const lang = userLang === "fr" ? "fr" : "en";
94+
const loadingText = document.getElementById("loading-text");
8495

85-
// Statically replaced by the custom plugin
86-
const inlined = __INLINED_MESSAGES__;
96+
const updateText = (messages) => {
97+
if (loadingText && messages) {
98+
const randomMessage =
99+
messages[Math.floor(Math.random() * messages.length)];
100+
loadingText.textContent = randomMessage;
101+
}
102+
};
87103

88-
if (inlined) {
89-
updateText(inlined[lang] || inlined.en);
90-
} else {
91-
fetch(`./locales/${lang}/loading-messages-${lang}.json`)
92-
.then(res => res.json())
93-
.then(updateText)
94-
.catch(() => console.warn('Loading messages failed.'));
95-
}
96-
})();
97-
</script>
104+
// Statically replaced by the custom plugin
105+
const inlined = __INLINED_MESSAGES__;
106+
})();
107+
</script>
98108

99-
<script type="module" src="./src/pages/main.tsx"></script>
100-
</body>
109+
<script type="module" src="./src/pages/main.tsx"></script>
110+
</body>
101111
</html>

Build/package-lock.json

Lines changed: 12 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Build/package.json

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"@fontsource/inter": "^5.2.8",
3333
"@fontsource/jetbrains-mono": "^5.2.8",
3434
"@fontsource/poppins": "^5.2.7",
35+
"@nisoku/satori-log": "^0.1.1",
3536
"@radix-ui/react-collapsible": "^1.1.12",
3637
"@radix-ui/react-dialog": "^1.1.15",
3738
"@radix-ui/react-dropdown-menu": "^2.1.16",
@@ -42,49 +43,49 @@
4243
"@radix-ui/react-switch": "^1.2.6",
4344
"@radix-ui/react-tooltip": "^1.2.8",
4445
"@reactour/tour": "^3.8.0",
45-
"@tauri-apps/api": "^2.9.1",
46-
"@tauri-apps/plugin-dialog": "^2.4.2",
47-
"@tauri-apps/plugin-fs": "^2.4.4",
46+
"@tauri-apps/api": "^2.10.1",
47+
"@tauri-apps/plugin-dialog": "^2.6.0",
48+
"@tauri-apps/plugin-fs": "^2.4.5",
4849
"@tauri-apps/plugin-notification": "^2.3.3",
49-
"@tauri-apps/plugin-opener": "^2.5.2",
50+
"@tauri-apps/plugin-opener": "^2.5.3",
5051
"@uppy/core": "^5.2.0",
51-
"@uppy/dashboard": "^5.1.0",
52-
"@uppy/react": "^5.1.1",
52+
"@uppy/dashboard": "^5.1.1",
53+
"@uppy/react": "^5.2.0",
5354
"@web-scrobbler/metadata-filter": "^3.2.0",
5455
"dompurify": "^3.3.1",
55-
"i18next": "^25.7.3",
56+
"i18next": "^25.8.6",
5657
"i18next-browser-languagedetector": "^8.2.0",
5758
"i18next-http-backend": "^3.0.2",
58-
"lodash": "^4.17.21",
59-
"lucide-react": "^0.562.0",
60-
"music-metadata": "^11.10.3",
61-
"react": "^19.2.3",
62-
"react-dom": "^19.2.3",
63-
"react-i18next": "^16.5.0",
59+
"lodash": "^4.17.23",
60+
"lucide-react": "^0.563.0",
61+
"music-metadata": "^11.12.0",
62+
"react": "^19.2.4",
63+
"react-dom": "^19.2.4",
64+
"react-i18next": "^16.5.4",
6465
"react-icons": "^5.5.0",
6566
"sonner": "^2.0.7",
6667
"vite-plugin-singlefile": "^2.3.0",
67-
"zustand": "^5.0.9"
68+
"zustand": "^5.0.11"
6869
},
6970
"devDependencies": {
7071
"@tauri-apps/cli": "^2",
71-
"@types/jasmine": "^5.1.13",
72+
"@types/jasmine": "^6.0.0",
7273
"@types/jest": "^30.0.0",
73-
"@types/lodash": "^4.17.21",
74-
"@types/node": "^25.0.3",
75-
"@types/react": "^19.2.7",
74+
"@types/lodash": "^4.17.23",
75+
"@types/node": "^25.2.3",
76+
"@types/react": "^19.2.14",
7677
"@types/react-dom": "^19.2.3",
77-
"@typescript-eslint/eslint-plugin": "^8.51.0",
78-
"@typescript-eslint/parser": "^8.51.0",
78+
"@typescript-eslint/eslint-plugin": "^8.55.0",
79+
"@typescript-eslint/parser": "^8.55.0",
7980
"@vite-pwa/assets-generator": "^1.0.2",
80-
"@vitejs/plugin-react": "^5.1.2",
81+
"@vitejs/plugin-react": "^5.1.4",
8182
"cloc": "^2.11.0",
8283
"cross-env": "^10.1.0",
83-
"eslint": "^9.39.2",
84+
"eslint": "^10.0.0",
8485
"eslint-plugin-react": "^7.37.5",
85-
"npm-check-updates": "^19.2.0",
86-
"prettier": "^3.7.4",
87-
"vite": "^7.3.0",
86+
"npm-check-updates": "^19.3.2",
87+
"prettier": "^3.8.1",
88+
"vite": "^7.3.1",
8889
"vite-plugin-pwa": "^1.2.0",
8990
"vite-plugin-top-level-await": "^1.6.0",
9091
"vite-plugin-wasm": "^3.5.0",

Build/src/helpers/i18nManual.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Import translations directly so Vite can bundle them
2-
import enTranslation from "../../public/locales/en/translation.json";
3-
import frTranslation from "../../public/locales/fr/translation.json";
2+
import enTranslation from "../locales/en/translation.json";
3+
import frTranslation from "../locales/fr/translation.json";
44

55
export const bundledResources = {
66
en: { translation: enTranslation },
File renamed without changes.
File renamed without changes.

Build/src/pages/main.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,8 @@ i18nInstance
3131
fallbackLng: "en",
3232
debug: true,
3333
supportedLngs: Object.keys(languageNames), // <-- dynamically from file
34-
resources: isSingleFile ? bundledResources : undefined,
35-
backend: !isSingleFile
36-
? {
37-
loadPath: "./locales/{{lng}}/translation.json",
38-
}
39-
: undefined,
34+
resources: bundledResources,
35+
4036
detection: {
4137
order: ["queryString", "cookie", "localStorage", "navigator"],
4238
caches: ["cookie", "localStorage"],

0 commit comments

Comments
 (0)