@gradio/core 0.19.3 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +50 -0
- package/dist/src/Blocks.svelte +62 -17
- package/dist/src/Render.svelte +39 -32
- package/dist/src/RenderComponent.svelte +17 -18
- package/dist/src/i18n.d.ts +14 -2
- package/dist/src/i18n.js +56 -23
- package/dist/src/init.d.ts +9 -1
- package/dist/src/init.js +241 -5
- package/dist/src/lang/en.json +3 -1
- package/dist/src/lang/get_lang_names.d.ts +1 -0
- package/dist/src/lang/get_lang_names.js +23 -0
- package/dist/src/lang/pt-BR.json +3 -1
- package/dist/src/lang/pt.json +3 -1
- package/package.json +51 -51
- package/src/Blocks.svelte +72 -18
- package/src/Render.svelte +41 -32
- package/src/RenderComponent.svelte +17 -18
- package/src/i18n.test.ts +22 -13
- package/src/i18n.ts +79 -31
- package/src/init.ts +361 -7
- package/src/lang/en.json +3 -1
- package/src/lang/get_lang_names.js +23 -0
- package/src/lang/pt-BR.json +3 -1
- package/src/lang/pt.json +3 -1
package/src/Blocks.svelte
CHANGED
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
import type { ComponentMeta, Dependency, LayoutNode } from "./types";
|
|
10
10
|
import type { UpdateTransaction } from "./init";
|
|
11
11
|
import { setupi18n } from "./i18n";
|
|
12
|
-
import { ApiDocs, ApiRecorder, Settings } from "./api_docs/";
|
|
13
12
|
import type { ThemeMode, Payload } from "./types";
|
|
14
13
|
import { Toast } from "@gradio/statustracker";
|
|
15
14
|
import type { ToastMessage } from "@gradio/statustracker";
|
|
@@ -17,6 +16,11 @@
|
|
|
17
16
|
import MountComponents from "./MountComponents.svelte";
|
|
18
17
|
import { prefix_css } from "./css";
|
|
19
18
|
|
|
19
|
+
import type ApiDocs from "./api_docs/ApiDocs.svelte";
|
|
20
|
+
import type ApiRecorder from "./api_docs/ApiRecorder.svelte";
|
|
21
|
+
import type Settings from "./api_docs/Settings.svelte";
|
|
22
|
+
import type { ComponentType } from "svelte";
|
|
23
|
+
|
|
20
24
|
import logo from "./images/logo.svg";
|
|
21
25
|
import api_logo from "./api_docs/img/api-logo.svg";
|
|
22
26
|
import settings_logo from "./api_docs/img/settings-logo.svg";
|
|
@@ -107,8 +111,39 @@
|
|
|
107
111
|
let allow_zoom = true;
|
|
108
112
|
let allow_video_trim = true;
|
|
109
113
|
|
|
110
|
-
|
|
114
|
+
// Lazy component loading state
|
|
115
|
+
let ApiDocs: ComponentType<ApiDocs> | null = null;
|
|
116
|
+
let ApiRecorder: ComponentType<ApiRecorder> | null = null;
|
|
117
|
+
let Settings: ComponentType<Settings> | null = null;
|
|
118
|
+
|
|
119
|
+
async function loadApiDocs(): Promise<void> {
|
|
120
|
+
if (!ApiDocs || !ApiRecorder) {
|
|
121
|
+
const api_docs_module = await import("./api_docs/ApiDocs.svelte");
|
|
122
|
+
const api_recorder_module = await import("./api_docs/ApiRecorder.svelte");
|
|
123
|
+
if (!ApiDocs) ApiDocs = api_docs_module.default;
|
|
124
|
+
if (!ApiRecorder) ApiRecorder = api_recorder_module.default;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async function loadApiRecorder(): Promise<void> {
|
|
129
|
+
if (!ApiRecorder) {
|
|
130
|
+
const api_recorder_module = await import("./api_docs/ApiRecorder.svelte");
|
|
131
|
+
ApiRecorder = api_recorder_module.default;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async function loadSettings(): Promise<void> {
|
|
136
|
+
if (!Settings) {
|
|
137
|
+
const settings_module = await import("./api_docs/Settings.svelte");
|
|
138
|
+
Settings = settings_module.default;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
async function set_api_docs_visible(visible: boolean): Promise<void> {
|
|
111
143
|
api_recorder_visible = false;
|
|
144
|
+
if (visible) {
|
|
145
|
+
await loadApiDocs();
|
|
146
|
+
}
|
|
112
147
|
api_docs_visible = visible;
|
|
113
148
|
let params = new URLSearchParams(window.location.search);
|
|
114
149
|
if (visible) {
|
|
@@ -119,7 +154,10 @@
|
|
|
119
154
|
history.replaceState(null, "", "?" + params.toString());
|
|
120
155
|
}
|
|
121
156
|
|
|
122
|
-
function set_settings_visible(visible: boolean): void {
|
|
157
|
+
async function set_settings_visible(visible: boolean): Promise<void> {
|
|
158
|
+
if (visible) {
|
|
159
|
+
await loadSettings();
|
|
160
|
+
}
|
|
123
161
|
let params = new URLSearchParams(window.location.search);
|
|
124
162
|
if (visible) {
|
|
125
163
|
params.set("view", "settings");
|
|
@@ -831,6 +869,17 @@
|
|
|
831
869
|
$is_screen_recording = isRecording;
|
|
832
870
|
}
|
|
833
871
|
);
|
|
872
|
+
|
|
873
|
+
// Load components if they should be visible on initial page load
|
|
874
|
+
if (api_docs_visible) {
|
|
875
|
+
loadApiDocs();
|
|
876
|
+
}
|
|
877
|
+
if (api_recorder_visible) {
|
|
878
|
+
loadApiRecorder();
|
|
879
|
+
}
|
|
880
|
+
if (settings_visible) {
|
|
881
|
+
loadSettings();
|
|
882
|
+
}
|
|
834
883
|
});
|
|
835
884
|
|
|
836
885
|
function screen_recording(): void {
|
|
@@ -840,11 +889,6 @@
|
|
|
840
889
|
screen_recorder.startRecording();
|
|
841
890
|
}
|
|
842
891
|
}
|
|
843
|
-
|
|
844
|
-
let i18n_ready = false;
|
|
845
|
-
setupi18n(app.config?.i18n_translations ?? undefined).then(() => {
|
|
846
|
-
i18n_ready = true;
|
|
847
|
-
});
|
|
848
892
|
</script>
|
|
849
893
|
|
|
850
894
|
<svelte:head>
|
|
@@ -858,7 +902,7 @@
|
|
|
858
902
|
|
|
859
903
|
<div class="wrap" style:min-height={app_mode ? "100%" : "auto"}>
|
|
860
904
|
<div class="contain" style:flex-grow={app_mode ? "1" : "auto"}>
|
|
861
|
-
{#if $_layout && app.config
|
|
905
|
+
{#if $_layout && app.config}
|
|
862
906
|
<MountComponents
|
|
863
907
|
rootNode={$_layout}
|
|
864
908
|
{root}
|
|
@@ -880,6 +924,10 @@
|
|
|
880
924
|
on:click={() => {
|
|
881
925
|
set_api_docs_visible(!api_docs_visible);
|
|
882
926
|
}}
|
|
927
|
+
on:mouseenter={() => {
|
|
928
|
+
loadApiDocs();
|
|
929
|
+
loadApiRecorder();
|
|
930
|
+
}}
|
|
883
931
|
class="show-api"
|
|
884
932
|
>
|
|
885
933
|
{#if app.config?.mcp_server}
|
|
@@ -916,6 +964,9 @@
|
|
|
916
964
|
on:click={() => {
|
|
917
965
|
set_settings_visible(!settings_visible);
|
|
918
966
|
}}
|
|
967
|
+
on:mouseenter={() => {
|
|
968
|
+
loadSettings();
|
|
969
|
+
}}
|
|
919
970
|
class="settings"
|
|
920
971
|
>
|
|
921
972
|
{$_("common.settings")}
|
|
@@ -925,7 +976,7 @@
|
|
|
925
976
|
{/if}
|
|
926
977
|
</div>
|
|
927
978
|
|
|
928
|
-
{#if api_recorder_visible}
|
|
979
|
+
{#if api_recorder_visible && ApiRecorder}
|
|
929
980
|
<!-- TODO: fix -->
|
|
930
981
|
<!-- svelte-ignore a11y-click-events-have-key-events-->
|
|
931
982
|
<!-- svelte-ignore a11y-no-static-element-interactions-->
|
|
@@ -936,11 +987,11 @@
|
|
|
936
987
|
api_recorder_visible = false;
|
|
937
988
|
}}
|
|
938
989
|
>
|
|
939
|
-
<ApiRecorder {api_calls} {dependencies} />
|
|
990
|
+
<svelte:component this={ApiRecorder} {api_calls} {dependencies} />
|
|
940
991
|
</div>
|
|
941
992
|
{/if}
|
|
942
993
|
|
|
943
|
-
{#if api_docs_visible && $_layout}
|
|
994
|
+
{#if api_docs_visible && $_layout && ApiDocs}
|
|
944
995
|
<div class="api-docs">
|
|
945
996
|
<!-- TODO: fix -->
|
|
946
997
|
<!-- svelte-ignore a11y-click-events-have-key-events-->
|
|
@@ -952,12 +1003,14 @@
|
|
|
952
1003
|
}}
|
|
953
1004
|
/>
|
|
954
1005
|
<div class="api-docs-wrap">
|
|
955
|
-
<
|
|
1006
|
+
<svelte:component
|
|
1007
|
+
this={ApiDocs}
|
|
956
1008
|
root_node={$_layout}
|
|
957
1009
|
on:close={(event) => {
|
|
958
1010
|
set_api_docs_visible(false);
|
|
959
1011
|
api_calls = [];
|
|
960
|
-
api_recorder_visible =
|
|
1012
|
+
api_recorder_visible = api_recorder_visible =
|
|
1013
|
+
event.detail?.api_recorder_visible;
|
|
961
1014
|
}}
|
|
962
1015
|
{dependencies}
|
|
963
1016
|
{root}
|
|
@@ -970,7 +1023,7 @@
|
|
|
970
1023
|
</div>
|
|
971
1024
|
{/if}
|
|
972
1025
|
|
|
973
|
-
{#if settings_visible && $_layout && app.config}
|
|
1026
|
+
{#if settings_visible && $_layout && app.config && Settings}
|
|
974
1027
|
<div class="api-docs">
|
|
975
1028
|
<!-- TODO: fix -->
|
|
976
1029
|
<!-- svelte-ignore a11y-click-events-have-key-events-->
|
|
@@ -982,13 +1035,14 @@
|
|
|
982
1035
|
}}
|
|
983
1036
|
/>
|
|
984
1037
|
<div class="api-docs-wrap">
|
|
985
|
-
<
|
|
1038
|
+
<svelte:component
|
|
1039
|
+
this={Settings}
|
|
986
1040
|
bind:allow_zoom
|
|
987
1041
|
bind:allow_video_trim
|
|
988
|
-
on:close={(
|
|
1042
|
+
on:close={() => {
|
|
989
1043
|
set_settings_visible(false);
|
|
990
1044
|
}}
|
|
991
|
-
on:start_recording={(
|
|
1045
|
+
on:start_recording={() => {
|
|
992
1046
|
screen_recording();
|
|
993
1047
|
}}
|
|
994
1048
|
pwa_enabled={app.config.pwa}
|
package/src/Render.svelte
CHANGED
|
@@ -54,7 +54,11 @@
|
|
|
54
54
|
|
|
55
55
|
$: {
|
|
56
56
|
if (node && node.type === "form") {
|
|
57
|
-
if (
|
|
57
|
+
if (
|
|
58
|
+
node.children?.every(
|
|
59
|
+
(c) => typeof c.props.visible === "boolean" && !c.props.visible
|
|
60
|
+
)
|
|
61
|
+
) {
|
|
58
62
|
node.props.visible = false;
|
|
59
63
|
} else {
|
|
60
64
|
node.props.visible = true;
|
|
@@ -76,34 +80,39 @@
|
|
|
76
80
|
);
|
|
77
81
|
</script>
|
|
78
82
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
83
|
+
{#if node.component}
|
|
84
|
+
<RenderComponent
|
|
85
|
+
_id={node?.id}
|
|
86
|
+
component={node.component}
|
|
87
|
+
bind:instance={node.instance}
|
|
88
|
+
bind:value={node.props.value}
|
|
89
|
+
elem_id={("elem_id" in node.props && node.props.elem_id) ||
|
|
90
|
+
`component-${node.id}`}
|
|
91
|
+
elem_classes={("elem_classes" in node.props && node.props.elem_classes) ||
|
|
92
|
+
[]}
|
|
93
|
+
{target}
|
|
94
|
+
{...node.props}
|
|
95
|
+
{theme_mode}
|
|
96
|
+
{root}
|
|
97
|
+
visible={typeof node.props.visible === "boolean"
|
|
98
|
+
? node.props.visible
|
|
99
|
+
: true}
|
|
100
|
+
>
|
|
101
|
+
{#if node.children && node.children.length}
|
|
102
|
+
{#each node.children as _node (_node.id)}
|
|
103
|
+
<svelte:self
|
|
104
|
+
node={_node}
|
|
105
|
+
component={_node.component}
|
|
106
|
+
{target}
|
|
107
|
+
id={_node.id}
|
|
108
|
+
{root}
|
|
109
|
+
{theme_mode}
|
|
110
|
+
on:destroy
|
|
111
|
+
on:mount
|
|
112
|
+
{max_file_size}
|
|
113
|
+
{client}
|
|
114
|
+
/>
|
|
115
|
+
{/each}
|
|
116
|
+
{/if}
|
|
117
|
+
</RenderComponent>
|
|
118
|
+
{/if}
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
return ProxiedMyClass;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
let _component = wrap(component);
|
|
53
53
|
|
|
54
54
|
const supported_props = [
|
|
55
55
|
"description",
|
|
@@ -72,20 +72,19 @@
|
|
|
72
72
|
$: value = translate_if_needed(value);
|
|
73
73
|
</script>
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
<svelte:component
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
<!-- {/if} -->
|
|
75
|
+
{#if visible}
|
|
76
|
+
<svelte:component
|
|
77
|
+
this={_component}
|
|
78
|
+
bind:this={instance}
|
|
79
|
+
bind:value
|
|
80
|
+
on:prop_change
|
|
81
|
+
{elem_id}
|
|
82
|
+
{elem_classes}
|
|
83
|
+
{target}
|
|
84
|
+
{...$$restProps}
|
|
85
|
+
{theme_mode}
|
|
86
|
+
{root}
|
|
87
|
+
>
|
|
88
|
+
<slot />
|
|
89
|
+
</svelte:component>
|
|
90
|
+
{/if}
|
package/src/i18n.test.ts
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
beforeEach,
|
|
8
8
|
afterEach
|
|
9
9
|
} from "vitest";
|
|
10
|
-
import { process_langs } from "./i18n";
|
|
10
|
+
import { Lang, process_langs } from "./i18n";
|
|
11
11
|
import languagesByAnyCode from "wikidata-lang/indexes/by_any_code";
|
|
12
12
|
import BCP47 from "./lang/BCP47_codes";
|
|
13
13
|
import {
|
|
@@ -36,22 +36,31 @@ describe("i18n", () => {
|
|
|
36
36
|
test("languages are loaded correctly", () => {
|
|
37
37
|
const langs = process_langs();
|
|
38
38
|
assert.ok(langs.en);
|
|
39
|
-
assert.ok(langs.en.common);
|
|
39
|
+
assert.ok((langs.en as { type: "static"; data: Lang }).data.common);
|
|
40
40
|
});
|
|
41
41
|
|
|
42
|
-
test("language codes follow the correct format", () => {
|
|
42
|
+
test("language codes follow the correct format", async () => {
|
|
43
43
|
const langs = Object.entries(process_langs());
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
await Promise.all(
|
|
46
|
+
langs.map(async ([code, translation]) => {
|
|
47
|
+
const BCP47_REGEX = /^.{2}-.{2}$/;
|
|
47
48
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
49
|
+
if (BCP47_REGEX.test(code)) {
|
|
50
|
+
assert.ok(BCP47.includes(code));
|
|
51
|
+
} else {
|
|
52
|
+
assert.exists(languagesByAnyCode[code]);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
let data: Lang;
|
|
56
|
+
if (translation.type === "lazy") {
|
|
57
|
+
data = await translation.data();
|
|
58
|
+
} else {
|
|
59
|
+
data = translation.data;
|
|
60
|
+
}
|
|
61
|
+
assert.ok(data.common);
|
|
62
|
+
})
|
|
63
|
+
);
|
|
55
64
|
});
|
|
56
65
|
|
|
57
66
|
describe("basic functions", () => {
|
|
@@ -106,7 +115,7 @@ describe("i18n", () => {
|
|
|
106
115
|
}
|
|
107
116
|
};
|
|
108
117
|
|
|
109
|
-
load_translations(custom_translations);
|
|
118
|
+
load_translations({ processed_langs: {}, custom_translations });
|
|
110
119
|
|
|
111
120
|
expect(mockAddMessages).toHaveBeenCalledTimes(2);
|
|
112
121
|
expect(mockAddMessages).toHaveBeenCalledWith(
|
package/src/i18n.ts
CHANGED
|
@@ -1,21 +1,66 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
addMessages,
|
|
3
|
+
init,
|
|
4
|
+
getLocaleFromNavigator,
|
|
5
|
+
locale,
|
|
6
|
+
register,
|
|
7
|
+
waitLocale
|
|
8
|
+
} from "svelte-i18n";
|
|
2
9
|
import { formatter } from "./gradio_helper";
|
|
3
10
|
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
11
|
+
const lang_map = {
|
|
12
|
+
ar: "العربية",
|
|
13
|
+
ca: "Català",
|
|
14
|
+
ckb: "کوردی",
|
|
15
|
+
de: "Deutsch",
|
|
16
|
+
en: "English",
|
|
17
|
+
es: "Español",
|
|
18
|
+
eu: "Euskara",
|
|
19
|
+
fa: "فارسی",
|
|
20
|
+
fi: "Suomi",
|
|
21
|
+
fr: "Français",
|
|
22
|
+
he: "עברית",
|
|
23
|
+
hi: "हिंदी",
|
|
24
|
+
ja: "日本語",
|
|
25
|
+
ko: "한국어",
|
|
26
|
+
lt: "Lietuvių",
|
|
27
|
+
nb: "Norsk bokmål",
|
|
28
|
+
nl: "Nederlands",
|
|
29
|
+
pl: "Polski",
|
|
30
|
+
"pt-BR": "Português do Brasil",
|
|
31
|
+
pt: "Português",
|
|
32
|
+
ro: "Română",
|
|
33
|
+
ru: "Русский",
|
|
34
|
+
sv: "Svenska",
|
|
35
|
+
ta: "தமிழ்",
|
|
36
|
+
th: "ภาษาไทย",
|
|
37
|
+
tr: "Türkçe",
|
|
38
|
+
uk: "Українська",
|
|
39
|
+
ur: "اردو",
|
|
40
|
+
uz: "O'zbek",
|
|
41
|
+
"zh-CN": "简体中文",
|
|
42
|
+
"zh-TW": "繁體中文"
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const langs = import.meta.glob("./lang/*.json");
|
|
46
|
+
import en from "./lang/en.json";
|
|
7
47
|
|
|
8
48
|
export interface I18nData {
|
|
9
49
|
__type__: "translation_metadata";
|
|
10
50
|
key: string;
|
|
11
51
|
}
|
|
12
52
|
|
|
53
|
+
export type Lang = {
|
|
54
|
+
[key: string]: Record<string, string> | string;
|
|
55
|
+
};
|
|
56
|
+
|
|
13
57
|
export interface LangsRecord {
|
|
14
|
-
[lang: string]:
|
|
58
|
+
[lang: string]:
|
|
59
|
+
| { type: "lazy"; data: () => Promise<Lang> }
|
|
60
|
+
| { type: "static"; data: Lang };
|
|
15
61
|
}
|
|
16
62
|
|
|
17
63
|
export function is_translation_metadata(obj: any): obj is I18nData {
|
|
18
|
-
console.log(obj);
|
|
19
64
|
const result =
|
|
20
65
|
obj &&
|
|
21
66
|
typeof obj === "object" &&
|
|
@@ -83,12 +128,17 @@ export function translate_if_needed(value: any): string {
|
|
|
83
128
|
}
|
|
84
129
|
|
|
85
130
|
export function process_langs(): LangsRecord {
|
|
86
|
-
|
|
87
|
-
Object.entries(langs).map(([path,
|
|
131
|
+
const lazy_langs = Object.fromEntries(
|
|
132
|
+
Object.entries(langs).map(([path, mod]) => [
|
|
88
133
|
path.split("/").pop()!.split(".")[0],
|
|
89
|
-
|
|
134
|
+
{ type: "lazy", data: mod }
|
|
90
135
|
])
|
|
91
136
|
);
|
|
137
|
+
|
|
138
|
+
return {
|
|
139
|
+
...lazy_langs,
|
|
140
|
+
en: { type: "static", data: en }
|
|
141
|
+
};
|
|
92
142
|
}
|
|
93
143
|
|
|
94
144
|
const processed_langs = process_langs();
|
|
@@ -96,7 +146,7 @@ const available_locales = Object.keys(processed_langs);
|
|
|
96
146
|
|
|
97
147
|
export const language_choices: [string, string][] = Object.entries(
|
|
98
148
|
processed_langs
|
|
99
|
-
).map(([code
|
|
149
|
+
).map(([code]) => [lang_map[code as keyof typeof lang_map] || code, code]);
|
|
100
150
|
|
|
101
151
|
export let all_common_keys: Set<string> = new Set();
|
|
102
152
|
|
|
@@ -116,8 +166,8 @@ export async function setupi18n(
|
|
|
116
166
|
previous_translations = custom_translations;
|
|
117
167
|
|
|
118
168
|
load_translations({
|
|
119
|
-
|
|
120
|
-
|
|
169
|
+
processed_langs,
|
|
170
|
+
custom_translations: custom_translations ?? {}
|
|
121
171
|
});
|
|
122
172
|
|
|
123
173
|
const browser_locale = getLocaleFromNavigator();
|
|
@@ -140,20 +190,6 @@ export async function setupi18n(
|
|
|
140
190
|
initialLocale: initial_locale
|
|
141
191
|
});
|
|
142
192
|
|
|
143
|
-
for (const lang_code in processed_langs) {
|
|
144
|
-
if (
|
|
145
|
-
processed_langs[lang_code] &&
|
|
146
|
-
typeof processed_langs[lang_code] === "object" &&
|
|
147
|
-
processed_langs[lang_code].common &&
|
|
148
|
-
typeof processed_langs[lang_code].common === "object"
|
|
149
|
-
) {
|
|
150
|
-
const common_ns = processed_langs[lang_code].common;
|
|
151
|
-
for (const key in common_ns) {
|
|
152
|
-
all_common_keys.add(`common.${key}`);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
193
|
i18n_initialized = true;
|
|
158
194
|
}
|
|
159
195
|
|
|
@@ -175,16 +211,28 @@ export function get_initial_locale(
|
|
|
175
211
|
return fallback_locale;
|
|
176
212
|
}
|
|
177
213
|
|
|
178
|
-
export function load_translations(
|
|
179
|
-
|
|
180
|
-
|
|
214
|
+
export function load_translations(translations: {
|
|
215
|
+
processed_langs: LangsRecord;
|
|
216
|
+
custom_translations: Record<string, Record<string, string>>;
|
|
217
|
+
}): void {
|
|
181
218
|
if (!translations) {
|
|
182
219
|
return;
|
|
183
220
|
}
|
|
184
221
|
|
|
185
222
|
try {
|
|
186
|
-
for (const lang in translations) {
|
|
187
|
-
addMessages(lang, translations[lang]);
|
|
223
|
+
for (const lang in translations.custom_translations) {
|
|
224
|
+
addMessages(lang, translations.custom_translations[lang]);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
for (const lang in translations.processed_langs) {
|
|
228
|
+
if (
|
|
229
|
+
lang === "en" &&
|
|
230
|
+
translations.processed_langs[lang].type === "static"
|
|
231
|
+
) {
|
|
232
|
+
addMessages(lang, en);
|
|
233
|
+
} else if (translations.processed_langs[lang].type === "lazy") {
|
|
234
|
+
register(lang, translations.processed_langs[lang].data);
|
|
235
|
+
}
|
|
188
236
|
}
|
|
189
237
|
} catch (e) {
|
|
190
238
|
console.error("Error loading translations:", e);
|