Leave behind svelte-i18n

This commit is contained in:
WardPearce
2025-06-05 12:38:20 +12:00
parent 06119eac37
commit 7d7d79db9d
33 changed files with 143 additions and 794 deletions
+1 -1
View File
@@ -44,4 +44,4 @@
"capacitor",
"electron"
]
}
}
+53 -738
View File
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -14,9 +14,9 @@
},
"devDependencies": {
"@capacitor/assets": "^3.0.5",
"@sveltejs/adapter-auto": "^3.2.5",
"@sveltejs/adapter-static": "^3.0.5",
"@sveltejs/kit": "^2.20.7",
"@sveltejs/adapter-auto": "^6.0.1",
"@sveltejs/adapter-static": "^3.0.8",
"@sveltejs/kit": "^2.21.2",
"@sveltejs/vite-plugin-svelte": "^5.0.3",
"@types/eslint": "^8.56.7",
"@types/event-source-polyfill": "^1.0.5",
@@ -57,6 +57,7 @@
"googlevideo": "^3.0.0",
"he": "^1.2.0",
"human-number": "^2.0.4",
"i18next": "^25.2.1",
"iso-3166": "^4.3.0",
"iso-639-1": "^3.1.5",
"material-dynamic-colors": "^1.1.1",
@@ -65,7 +66,6 @@
"peerjs": "^1.5.4",
"shaka-player": "^4.11.7",
"sponsorblock-api": "^0.2.4",
"svelte-i18n": "^4.0.1",
"svelte-infinite-loading": "^1.4.0",
"svelte-persisted-store": "^0.12.0",
"youtubei.js": "^13.4.0"
@@ -2,7 +2,7 @@
import { getBestThumbnail, proxyGoogleImage } from '$lib/images';
import { cleanNumber } from '$lib/numbers';
import { onMount } from 'svelte';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
import { get } from 'svelte/store';
import type { Channel } from '../api/model';
import { insecureRequestImageHandler, truncate } from '../misc';
@@ -1,6 +1,6 @@
<script lang="ts">
import { cleanNumber } from '$lib/numbers';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
import type { HashTag } from '../api/model';
import { truncate } from '../misc';
@@ -17,7 +17,7 @@
import shaka from 'shaka-player/dist/shaka-player.ui';
import { SponsorBlock, type Category, type Segment } from 'sponsorblock-api';
import { onDestroy, onMount } from 'svelte';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
import { get } from 'svelte/store';
import { deleteVideoProgress, getVideoProgress, saveVideoProgress } from '../api';
import type { VideoPlay } from '../api/model';
@@ -2,7 +2,7 @@
import { getBestThumbnail } from '$lib/images';
import { letterCase } from '$lib/letterCasing';
import { onMount } from 'svelte';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
import { get } from 'svelte/store';
import type { Playlist } from '../api/model';
import { insecureRequestImageHandler, truncate } from '../misc';
@@ -4,7 +4,7 @@
import { goto } from '$app/navigation';
import Mousetrap from 'mousetrap';
import { createEventDispatcher, onMount, tick } from 'svelte';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
import { getSearchSuggestions } from '../api';
import {
interfaceSearchHistoryEnabled,
@@ -1,7 +1,7 @@
<script lang="ts">
import { preventDefault } from 'svelte/legacy';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
import { get } from 'svelte/store';
import { ensureNoTrailingSlash } from '../../misc';
import { synciousInstanceStore, synciousStore } from '../../store';
@@ -11,7 +11,8 @@
<form
onsubmit={preventDefault(() =>
synciousInstanceStore.set(ensureNoTrailingSlash(synciousInstance)))}
synciousInstanceStore.set(ensureNoTrailingSlash(synciousInstance))
)}
>
<nav>
<div class="field label border max">
@@ -1,6 +1,6 @@
<script lang="ts">
import { instanceStore } from '$lib/store';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
import { get } from 'svelte/store';
</script>
@@ -1,7 +1,7 @@
<script lang="ts">
import { preventDefault } from 'svelte/legacy';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
import { get } from 'svelte/store';
import { ensureNoTrailingSlash } from '../../misc';
import {
@@ -7,7 +7,7 @@
import { Capacitor } from '@capacitor/core';
import ui from 'beercss';
import { iso31661 } from 'iso-3166';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
import { get } from 'svelte/store';
import { ensureNoTrailingSlash } from '../../misc';
import { getPages } from '../../navPages';
@@ -2,7 +2,7 @@
import { titleCase } from '$lib/letterCasing';
import { Capacitor } from '@capacitor/core';
import ISO6391 from 'iso-639-1';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
import { get } from 'svelte/store';
import {
playerAlwaysLoopStore,
@@ -1,7 +1,7 @@
<script lang="ts">
import { preventDefault } from 'svelte/legacy';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
import { get } from 'svelte/store';
import { ensureNoTrailingSlash } from '../../misc';
import { returnYTDislikesInstanceStore, returnYtDislikesStore } from '../../store';
@@ -11,7 +11,8 @@
<form
onsubmit={preventDefault(() =>
returnYTDislikesInstanceStore.set(ensureNoTrailingSlash(returnYTInstance)))}
returnYTDislikesInstanceStore.set(ensureNoTrailingSlash(returnYTInstance))
)}
>
<nav>
<div class="field label border max">
@@ -1,7 +1,7 @@
<script lang="ts">
import ISO6391 from 'iso-639-1';
import { onMount } from 'svelte';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
import { get } from 'svelte/store';
import ApiExtended from './ApiExtended.svelte';
import DataPreferences from './DataPreferences.svelte';
@@ -1,7 +1,7 @@
<script lang="ts">
import { preventDefault } from 'svelte/legacy';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
import { get } from 'svelte/store';
import { ensureNoTrailingSlash } from '../../misc';
import {
@@ -2,7 +2,7 @@
import { instanceStore } from '$lib/store';
import { Clipboard } from '@capacitor/clipboard';
import { Capacitor } from '@capacitor/core';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
import { get } from 'svelte/store';
import type { Notification, PlaylistPageVideo, Video, VideoBase } from '../api/model';
@@ -7,7 +7,7 @@
import ui from 'beercss';
import type { DataConnection } from 'peerjs';
import { onDestroy, onMount } from 'svelte';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
import { get } from 'svelte/store';
import { syncPartyConnectionsStore, syncPartyPeerStore } from '../store';
@@ -3,7 +3,7 @@
import { letterCase } from '$lib/letterCasing';
import { cleanNumber, videoLength } from '$lib/numbers';
import { onDestroy, onMount } from 'svelte';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
import { get } from 'svelte/store';
import { getDeArrow, getThumbnail, getVideoProgress } from '../api';
import type { Notification, PlaylistPageVideo, Video, VideoBase } from '../api/model';
@@ -2,7 +2,7 @@
import { videoLength } from '$lib/numbers';
import Fuse from 'fuse.js';
import { VTTCue, parseText, type ParsedCaptionsResult } from 'media-captions';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
import { get } from 'svelte/store';
import type { VideoPlay } from '../api/model';
import { decodeHtmlCharCodes } from '../misc';
@@ -1,6 +1,6 @@
<script lang="ts">
import Thumbnail from '$lib/components/Thumbnail.svelte';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
import { removePlaylistVideo } from '../api';
import type { PlaylistPageVideo, Video, VideoBase } from '../api/model';
import { authStore, feedLastItemId } from '../store';
+48 -15
View File
@@ -1,19 +1,52 @@
import { browser } from '$app/environment';
import { init, register } from 'svelte-i18n';
import i18next, { type InitOptions } from 'i18next';
import { writable, type Writable } from 'svelte/store';
const defaultLocale = 'en';
register('en', () => import('./locales/en.json'));
register('ru', () => import('./locales/ru.json'));
register('zh-CN', () => import('./locales/zh-CN.json'));
register('tr', () => import('./locales/tr.json'));
register('nl', () => import('./locales/nl.json'));
register('de', () => import('./locales/de.json'));
register('es', () => import('./locales/es.json'));
register('sh', () => import('./locales/sh.json'));
register('pt-BR', () => import('./locales/pt-BR.json'));
export const locale: Writable<string> = writable(defaultLocale);
export const _: Writable<(key: string, options?: any) => string> = writable(() => '');
init({
fallbackLocale: defaultLocale,
initialLocale: browser ? window.navigator.language : defaultLocale
});
const resources: Record<string, () => Promise<Record<string, any>>> = {
en: () => import('./locales/en.json'),
ru: () => import('./locales/ru.json'),
'zh-CN': () => import('./locales/zh-CN.json'),
tr: () => import('./locales/tr.json'),
nl: () => import('./locales/nl.json'),
de: () => import('./locales/de.json'),
es: () => import('./locales/es.json'),
sh: () => import('./locales/sh.json'),
'pt-BR': () => import('./locales/pt-BR.json')
};
function getUserLocale(): string {
if (typeof navigator !== 'undefined') {
const lang = navigator.language;
return resources[lang] ? lang : defaultLocale;
}
return defaultLocale;
}
export async function initI18n(selectedLocale: string = getUserLocale()): Promise<void> {
const langToLoad = resources[selectedLocale] ? selectedLocale : defaultLocale;
const translations = await resources[langToLoad]();
const options: InitOptions = {
lng: langToLoad,
fallbackLng: defaultLocale,
resources: {
[langToLoad]: {
translation: translations.default || translations
}
}
};
await i18next.init(options);
locale.set(langToLoad);
_.set(i18next.t.bind(i18next));
window.addEventListener('languagechange', () => {
const newLang = getUserLocale();
initI18n(newLang);
});
}
+1 -1
View File
@@ -1,4 +1,4 @@
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
import { get } from 'svelte/store';
// Must be a func do to how i18n is loaded
+1 -1
View File
@@ -32,7 +32,7 @@
import ui from 'beercss';
import 'material-dynamic-colors';
import { onMount } from 'svelte';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
import { get } from 'svelte/store';
import { pwaInfo } from 'virtual:pwa-info';
@@ -11,7 +11,7 @@
import { Clipboard } from '@capacitor/clipboard';
import { Capacitor } from '@capacitor/core';
import { onMount } from 'svelte';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
import InfiniteLoading, { type InfiniteEvent } from 'svelte-infinite-loading';
import { get } from 'svelte/store';
@@ -6,7 +6,7 @@
import { synciousStore } from '$lib/store';
import { error } from '@sveltejs/kit';
import { onMount } from 'svelte';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
import InfiniteLoading, { type InfiniteEvent } from 'svelte-infinite-loading';
import { get } from 'svelte/store';
@@ -8,7 +8,7 @@
import { Clipboard } from '@capacitor/clipboard';
import { Capacitor } from '@capacitor/core';
import { onMount } from 'svelte';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
let { data } = $props();
@@ -5,7 +5,7 @@
import ContentColumn from '$lib/components/ContentColumn.svelte';
import PlaylistThumbnail from '$lib/components/PlaylistThumbnail.svelte';
import { ui } from 'beercss';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
let { data } = $props();
@@ -9,7 +9,7 @@
import { extractUniqueId } from '$lib/misc.js';
import { feedLastItemId, searchCacheStore } from '$lib/store.js';
import { onMount } from 'svelte';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
import InfiniteLoading, { type InfiniteEvent } from 'svelte-infinite-loading';
let { data } = $props();
@@ -3,7 +3,7 @@
import type { PlaylistPageVideo, Video, VideoBase } from '$lib/api/model.js';
import VideoList from '$lib/components/VideoList.svelte';
import { feedCacheStore } from '$lib/store';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
import InfiniteLoading, { type InfiniteEvent } from 'svelte-infinite-loading';
let currentPage = 1;
@@ -1,7 +1,7 @@
<script lang="ts">
import { deleteUnsubscribe } from '$lib/api';
import Fuse from 'fuse.js';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
let { data } = $props();
@@ -35,7 +35,7 @@
import type { DataConnection } from 'peerjs';
import { type Segment } from 'sponsorblock-api';
import { onDestroy, onMount, tick } from 'svelte';
import { _ } from 'svelte-i18n';
import { _ } from '$lib/i18n';
import { get } from 'svelte/store';
let { data = $bindable() } = $props();
+5 -6
View File
@@ -2,14 +2,18 @@ import { browser } from '$app/environment';
import { goto } from '$app/navigation';
import { getResolveUrl } from '$lib/api';
import '$lib/i18n'; // Import to initialize. Important :)
import { initI18n } from '$lib/i18n';
import { getPages } from '$lib/navPages.js';
import { authStore, interfaceDefaultPage } from '$lib/store.js';
import { locale, waitLocale } from 'svelte-i18n';
import { get } from 'svelte/store';
export const ssr = false;
export async function load({ url }) {
if (browser) {
await initI18n();
}
if (url.pathname.startsWith('/@')) {
const username = url.pathname.split('/')[1];
@@ -21,11 +25,6 @@ export async function load({ url }) {
} catch {}
}
if (browser) {
locale.set(window.navigator.language);
}
await waitLocale();
const defaultPage = get(interfaceDefaultPage);
if (