@rimori/client 1.3.1 → 1.4.3

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.
Files changed (148) hide show
  1. package/.prettierignore +35 -0
  2. package/README.md +77 -71
  3. package/dist/cli/scripts/init/dev-registration.d.ts +1 -1
  4. package/dist/cli/scripts/init/dev-registration.js +4 -4
  5. package/dist/cli/scripts/init/main.js +1 -1
  6. package/dist/cli/scripts/init/package-setup.d.ts +1 -1
  7. package/dist/cli/scripts/init/package-setup.js +3 -3
  8. package/dist/cli/scripts/init/router-transformer.js +19 -12
  9. package/dist/cli/scripts/init/vite-config.d.ts +2 -2
  10. package/dist/cli/scripts/init/vite-config.js +2 -2
  11. package/dist/cli/scripts/release/release-config-upload.js +9 -9
  12. package/dist/cli/scripts/release/release-db-update.d.ts +1 -1
  13. package/dist/cli/scripts/release/release-db-update.js +9 -9
  14. package/dist/cli/scripts/release/release-file-upload.js +2 -2
  15. package/dist/cli/scripts/release/release.js +2 -2
  16. package/dist/cli/types/DatabaseTypes.d.ts +2 -2
  17. package/dist/components/CRUDModal.d.ts +1 -1
  18. package/dist/components/CRUDModal.js +3 -3
  19. package/dist/components/MarkdownEditor.js +16 -16
  20. package/dist/components/Spinner.js +2 -2
  21. package/dist/components/ai/Assistant.js +7 -8
  22. package/dist/components/ai/Avatar.d.ts +2 -2
  23. package/dist/components/ai/Avatar.js +14 -7
  24. package/dist/components/ai/EmbeddedAssistent/AudioInputField.js +5 -6
  25. package/dist/components/ai/EmbeddedAssistent/CircleAudioAvatar.d.ts +1 -1
  26. package/dist/components/ai/EmbeddedAssistent/CircleAudioAvatar.js +1 -2
  27. package/dist/components/ai/EmbeddedAssistent/TTS/MessageSender.d.ts +1 -2
  28. package/dist/components/ai/EmbeddedAssistent/TTS/MessageSender.js +4 -2
  29. package/dist/components/ai/EmbeddedAssistent/TTS/Player.js +1 -1
  30. package/dist/components/ai/EmbeddedAssistent/VoiceRecoder.js +2 -3
  31. package/dist/components/audio/Playbutton.js +10 -7
  32. package/dist/components/components/ContextMenu.d.ts +1 -1
  33. package/dist/components/components/ContextMenu.js +19 -16
  34. package/dist/components.d.ts +10 -10
  35. package/dist/components.js +10 -10
  36. package/dist/core/controller/AIController.d.ts +2 -2
  37. package/dist/core/controller/AIController.js +20 -18
  38. package/dist/core/controller/ExerciseController.d.ts +52 -0
  39. package/dist/core/controller/ExerciseController.js +73 -0
  40. package/dist/core/controller/ObjectController.js +5 -5
  41. package/dist/core/controller/SettingsController.d.ts +22 -7
  42. package/dist/core/controller/SettingsController.js +73 -8
  43. package/dist/core/controller/SharedContentController.d.ts +3 -3
  44. package/dist/core/controller/SharedContentController.js +38 -20
  45. package/dist/core/controller/VoiceController.js +6 -4
  46. package/dist/core/core.d.ts +15 -14
  47. package/dist/core/core.js +7 -7
  48. package/dist/fromRimori/EventBus.js +23 -23
  49. package/dist/fromRimori/PluginTypes.d.ts +4 -4
  50. package/dist/hooks/UseChatHook.d.ts +3 -3
  51. package/dist/hooks/UseChatHook.js +9 -3
  52. package/dist/index.d.ts +10 -10
  53. package/dist/index.js +9 -9
  54. package/dist/plugin/AccomplishmentHandler.d.ts +5 -5
  55. package/dist/plugin/AccomplishmentHandler.js +31 -27
  56. package/dist/plugin/AudioController.d.ts +1 -1
  57. package/dist/plugin/AudioController.js +6 -6
  58. package/dist/plugin/Logger.d.ts +5 -0
  59. package/dist/plugin/Logger.js +65 -13
  60. package/dist/plugin/PluginController.d.ts +7 -1
  61. package/dist/plugin/PluginController.js +32 -27
  62. package/dist/plugin/RimoriClient.d.ts +39 -14
  63. package/dist/plugin/RimoriClient.js +60 -31
  64. package/dist/plugin/StandaloneClient.d.ts +1 -1
  65. package/dist/plugin/StandaloneClient.js +35 -16
  66. package/dist/plugin/ThemeSetter.js +4 -4
  67. package/dist/providers/PluginProvider.js +44 -14
  68. package/dist/utils/Language.js +57 -57
  69. package/dist/utils/PluginUtils.js +3 -3
  70. package/dist/utils/difficultyConverter.d.ts +1 -1
  71. package/dist/utils/difficultyConverter.js +1 -1
  72. package/dist/utils/endpoint.js +2 -2
  73. package/dist/worker/WorkerSetup.d.ts +1 -1
  74. package/dist/worker/WorkerSetup.js +6 -6
  75. package/eslint.config.js +53 -0
  76. package/example/docs/devdocs.md +50 -40
  77. package/example/docs/overview.md +1 -1
  78. package/example/docs/userdocs.md +4 -1
  79. package/example/rimori.config.ts +51 -49
  80. package/example/worker/vite.config.ts +3 -3
  81. package/example/worker/worker.ts +2 -2
  82. package/package.json +17 -4
  83. package/prettier.config.js +8 -0
  84. package/src/cli/scripts/init/dev-registration.ts +5 -8
  85. package/src/cli/scripts/init/env-setup.ts +1 -1
  86. package/src/cli/scripts/init/file-operations.ts +1 -1
  87. package/src/cli/scripts/init/html-cleaner.ts +2 -5
  88. package/src/cli/scripts/init/main.ts +16 -13
  89. package/src/cli/scripts/init/package-setup.ts +11 -15
  90. package/src/cli/scripts/init/router-transformer.ts +40 -37
  91. package/src/cli/scripts/init/tailwind-config.ts +17 -26
  92. package/src/cli/scripts/init/vite-config.ts +3 -3
  93. package/src/cli/scripts/release/release-config-upload.ts +11 -11
  94. package/src/cli/scripts/release/release-db-update.ts +12 -12
  95. package/src/cli/scripts/release/release-file-upload.ts +3 -3
  96. package/src/cli/scripts/release/release.ts +4 -4
  97. package/src/cli/types/DatabaseTypes.ts +7 -8
  98. package/src/components/CRUDModal.tsx +64 -48
  99. package/src/components/MarkdownEditor.tsx +58 -27
  100. package/src/components/Spinner.tsx +24 -17
  101. package/src/components/ai/Assistant.tsx +70 -70
  102. package/src/components/ai/Avatar.tsx +20 -16
  103. package/src/components/ai/EmbeddedAssistent/AudioInputField.tsx +63 -54
  104. package/src/components/ai/EmbeddedAssistent/CircleAudioAvatar.tsx +14 -5
  105. package/src/components/ai/EmbeddedAssistent/TTS/MessageSender.ts +75 -74
  106. package/src/components/ai/EmbeddedAssistent/TTS/Player.ts +177 -178
  107. package/src/components/ai/EmbeddedAssistent/VoiceRecoder.tsx +109 -94
  108. package/src/components/ai/utils.ts +4 -4
  109. package/src/components/audio/Playbutton.tsx +101 -93
  110. package/src/components/components/ContextMenu.tsx +47 -35
  111. package/src/components.ts +10 -10
  112. package/src/core/controller/AIController.ts +62 -50
  113. package/src/core/controller/ExerciseController.ts +98 -0
  114. package/src/core/controller/ObjectController.ts +15 -10
  115. package/src/core/controller/SettingsController.ts +89 -16
  116. package/src/core/controller/SharedContentController.ts +80 -44
  117. package/src/core/controller/VoiceController.ts +10 -8
  118. package/src/core/core.ts +15 -15
  119. package/src/fromRimori/EventBus.ts +76 -47
  120. package/src/fromRimori/PluginTypes.ts +26 -17
  121. package/src/fromRimori/readme.md +2 -2
  122. package/src/hooks/UseChatHook.ts +25 -15
  123. package/src/index.ts +10 -10
  124. package/src/plugin/AccomplishmentHandler.ts +53 -35
  125. package/src/plugin/AudioController.ts +18 -12
  126. package/src/plugin/Logger.ts +77 -19
  127. package/src/plugin/PluginController.ts +60 -44
  128. package/src/plugin/RimoriClient.ts +133 -69
  129. package/src/plugin/StandaloneClient.ts +51 -24
  130. package/src/plugin/ThemeSetter.ts +5 -5
  131. package/src/providers/PluginProvider.tsx +90 -36
  132. package/src/style.scss +3 -3
  133. package/src/utils/Language.ts +58 -58
  134. package/src/utils/PluginUtils.ts +16 -20
  135. package/src/utils/difficultyConverter.ts +2 -2
  136. package/src/utils/endpoint.ts +3 -2
  137. package/src/worker/WorkerSetup.ts +8 -9
  138. package/tsconfig.json +2 -4
  139. package/dist/components/LoggerExample.d.ts +0 -6
  140. package/dist/components/LoggerExample.js +0 -79
  141. package/dist/core/controller/AudioController.d.ts +0 -0
  142. package/dist/core/controller/AudioController.js +0 -1
  143. package/dist/hooks/UseLogger.d.ts +0 -30
  144. package/dist/hooks/UseLogger.js +0 -122
  145. package/dist/plugin/LoggerExample.d.ts +0 -16
  146. package/dist/plugin/LoggerExample.js +0 -140
  147. package/dist/utils/audioFormats.d.ts +0 -26
  148. package/dist/utils/audioFormats.js +0 -67
@@ -1,11 +1,11 @@
1
- import { createClient, SupabaseClient } from "@supabase/supabase-js";
2
- import { EventBus } from "../fromRimori/EventBus";
3
- import { DEFAULT_ANON_KEY, DEFAULT_ENDPOINT } from "../utils/endpoint";
1
+ import { createClient, SupabaseClient } from '@supabase/supabase-js';
2
+ import { EventBus } from '../fromRimori/EventBus';
3
+ import { DEFAULT_ANON_KEY, DEFAULT_ENDPOINT } from '../utils/endpoint';
4
4
 
5
5
  export interface StandaloneConfig {
6
- url: string,
7
- key: string,
8
- backendUrl?: string
6
+ url: string;
7
+ key: string;
8
+ backendUrl?: string;
9
9
  }
10
10
 
11
11
  export class StandaloneClient {
@@ -20,9 +20,11 @@ export class StandaloneClient {
20
20
 
21
21
  public static async getInstance(): Promise<StandaloneClient> {
22
22
  if (!StandaloneClient.instance) {
23
- const config = await fetch("https://app.rimori.se/config.json").then(res => res.json()).catch(err => {
24
- console.warn("Error fetching config.json, using default values", err);
25
- });
23
+ const config = await fetch('https://app.rimori.se/config.json')
24
+ .then((res) => res.json())
25
+ .catch((err) => {
26
+ console.warn('Error fetching config.json, using default values', err);
27
+ });
26
28
  StandaloneClient.instance = new StandaloneClient({
27
29
  url: config?.SUPABASE_URL || DEFAULT_ENDPOINT,
28
30
  key: config?.SUPABASE_ANON_KEY || DEFAULT_ANON_KEY,
@@ -44,33 +46,54 @@ export class StandaloneClient {
44
46
  public async login(email: string, password: string) {
45
47
  const { error } = await this.supabase.auth.signInWithPassword({ email, password });
46
48
  if (error) {
47
- console.error("Login failed:", error);
49
+ console.error('Login failed:', error);
48
50
  return false;
49
51
  }
50
- console.log("Successfully logged in");
52
+ console.log('Successfully logged in');
51
53
  return true;
52
54
  }
53
55
 
54
56
  public static async initListeners(pluginId: string) {
55
- console.warn("The plugin seams to not be running inside the Rimori platform. Switching to development standalone mode.");
57
+ console.warn(
58
+ 'The plugin seams to not be running inside the Rimori platform. Switching to development standalone mode.',
59
+ );
56
60
  // console.log("event that needs to be handled", event);
57
61
  const { supabase, config } = await StandaloneClient.getInstance();
58
62
 
59
63
  // EventBus.on("*", async (event) => {
60
- EventBus.respond("standalone", "global.supabase.requestAccess", async () => {
64
+ EventBus.respond('standalone', 'global.supabase.requestAccess', async () => {
61
65
  const session = await supabase.auth.getSession();
62
- console.log("session", session);
63
-
66
+ console.log('session', session);
67
+
64
68
  // Call the NestJS backend endpoint instead of the Supabase edge function
69
+ // get current guild id if any
70
+ let guildId: string | null = null;
71
+ try {
72
+ const {
73
+ data: { user },
74
+ } = await supabase.auth.getUser();
75
+ if (user) {
76
+ const { data: profile } = await supabase
77
+ .from('profiles')
78
+ .select('current_guild_id')
79
+ .eq('user_id', user.id)
80
+ .maybeSingle();
81
+ guildId = (profile as { current_guild_id?: string | null } | null)?.current_guild_id || null;
82
+ }
83
+ } catch (_) {
84
+ guildId = null;
85
+ }
86
+
65
87
  const response = await fetch(`${config.backendUrl}/plugin/token`, {
66
88
  method: 'POST',
67
89
  headers: {
68
90
  'Content-Type': 'application/json',
69
- 'Authorization': `Bearer ${session.data.session?.access_token}`
91
+ Authorization: `Bearer ${session.data.session?.access_token}`,
70
92
  },
71
93
  body: JSON.stringify({
72
- pluginId: pluginId
73
- })
94
+ pluginId: pluginId,
95
+ guildId: guildId,
96
+ }),
74
97
  });
75
98
 
76
99
  if (!response.ok) {
@@ -79,7 +102,7 @@ export class StandaloneClient {
79
102
  }
80
103
 
81
104
  const data = await response.json();
82
-
105
+
83
106
  return {
84
107
  token: data.token,
85
108
  pluginId: pluginId,
@@ -88,11 +111,15 @@ export class StandaloneClient {
88
111
  backendUrl: config.backendUrl,
89
112
  tablePrefix: pluginId,
90
113
  expiration: new Date(Date.now() + 1000 * 60 * 60 * 1.5), // 1.5 hours
91
- }
114
+ };
92
115
  });
93
116
 
94
- EventBus.on("*", async (event) => {
95
- console.log("[standalone] would send event to parent", event);
96
- }, ["standalone"]);
117
+ EventBus.on(
118
+ '*',
119
+ async (event) => {
120
+ console.log('[standalone] would send event to parent', event);
121
+ },
122
+ ['standalone'],
123
+ );
97
124
  }
98
- }
125
+ }
@@ -1,10 +1,10 @@
1
1
  export function setTheme(theme?: string | null) {
2
- document.documentElement.classList.add("dark:text-gray-200");
2
+ document.documentElement.classList.add('dark:text-gray-200');
3
3
 
4
4
  if (isDarkTheme(theme)) {
5
- document.documentElement.setAttribute("data-theme", "dark");
6
- document.documentElement.classList.add('dark', "dark:bg-gray-950");
7
- document.documentElement.style.background = "hsl(var(--background))";
5
+ document.documentElement.setAttribute('data-theme', 'dark');
6
+ document.documentElement.classList.add('dark', 'dark:bg-gray-950');
7
+ document.documentElement.style.background = 'hsl(var(--background))';
8
8
  }
9
9
  }
10
10
 
@@ -20,4 +20,4 @@ export function isDarkTheme(theme?: string | null): boolean {
20
20
  }
21
21
 
22
22
  return theme === 'dark';
23
- }
23
+ }
@@ -10,7 +10,7 @@ interface PluginProviderProps {
10
10
  pluginId: string;
11
11
  settings?: {
12
12
  disableContextMenu?: boolean;
13
- }
13
+ };
14
14
  }
15
15
 
16
16
  const PluginContext = createContext<RimoriClient | null>(null);
@@ -20,29 +20,29 @@ export const PluginProvider: React.FC<PluginProviderProps> = ({ children, plugin
20
20
  const [standaloneClient, setStandaloneClient] = useState<StandaloneClient | boolean>(false);
21
21
  const [applicationMode, setApplicationMode] = useState<string | null>(null);
22
22
  const [theme, setTheme] = useState<string | null>(null);
23
-
24
- const isSidebar = applicationMode === "sidebar";
25
- const isSettings = applicationMode === "settings";
23
+
24
+ const isSidebar = applicationMode === 'sidebar';
25
+ const isSettings = applicationMode === 'settings';
26
26
 
27
27
  useEffect(() => {
28
28
  initEventBus(pluginId);
29
-
29
+
30
30
  // Check if we're in an iframe context - if not, we're standalone
31
31
  const standaloneDetected = window === window.parent;
32
-
32
+
33
33
  if (standaloneDetected && !standaloneClient) {
34
- StandaloneClient.getInstance().then(client => {
34
+ StandaloneClient.getInstance().then((client) => {
35
35
  client.needsLogin().then((needLogin) => setStandaloneClient(needLogin ? client : true));
36
36
  });
37
37
  }
38
38
 
39
39
  if ((!standaloneDetected && !plugin) || (standaloneDetected && standaloneClient === true)) {
40
- PluginController.getInstance(pluginId, standaloneDetected).then(client => {
40
+ PluginController.getInstance(pluginId, standaloneDetected).then((client) => {
41
41
  setPlugin(client);
42
42
  // Get applicationMode and theme from MessageChannel query params
43
43
  if (!standaloneDetected) {
44
- const mode = client.getQueryParam("applicationMode");
45
- const themeParam = client.getQueryParam("rm_theme");
44
+ const mode = client.getQueryParam('applicationMode');
45
+ const themeParam = client.getQueryParam('rm_theme');
46
46
  setApplicationMode(mode);
47
47
  setTheme(themeParam);
48
48
  }
@@ -81,13 +81,17 @@ export const PluginProvider: React.FC<PluginProviderProps> = ({ children, plugin
81
81
  }, [plugin]);
82
82
 
83
83
  if (standaloneClient instanceof StandaloneClient) {
84
- return <StandaloneAuth onLogin={async (email, password) => {
85
- if (await standaloneClient.login(email, password)) setStandaloneClient(true);
86
- }} />
84
+ return (
85
+ <StandaloneAuth
86
+ onLogin={async (email, password) => {
87
+ if (await standaloneClient.login(email, password)) setStandaloneClient(true);
88
+ }}
89
+ />
90
+ );
87
91
  }
88
92
 
89
93
  if (!plugin) {
90
- return ""
94
+ return '';
91
95
  }
92
96
 
93
97
  return (
@@ -114,7 +118,7 @@ function getUrlParam(name: string) {
114
118
  const hashValue = hashParams.get(name);
115
119
  if (hashValue) return hashValue;
116
120
  }
117
-
121
+
118
122
  // Fallback to regular URL search params
119
123
  const url = new URL(window.location.href);
120
124
  return url.searchParams.get(name);
@@ -122,34 +126,84 @@ function getUrlParam(name: string) {
122
126
 
123
127
  function initEventBus(pluginId: string) {
124
128
  // For now, use URL fallback for EventBus naming - this will be updated once MessageChannel is ready
125
- const isSidebar = getUrlParam("applicationMode") === "sidebar";
126
- EventBusHandler.getInstance("Plugin EventBus " + pluginId + " " + (isSidebar ? "sidebar" : "main"));
129
+ const isSidebar = getUrlParam('applicationMode') === 'sidebar';
130
+ EventBusHandler.getInstance('Plugin EventBus ' + pluginId + ' ' + (isSidebar ? 'sidebar' : 'main'));
127
131
  }
128
132
 
129
133
  function StandaloneAuth({ onLogin }: { onLogin: (user: string, password: string) => void }) {
130
- const [user, setUser] = useState("");
131
- const [password, setPassword] = useState("");
134
+ const [user, setUser] = useState('');
135
+ const [password, setPassword] = useState('');
132
136
  return (
133
- <div style={{
134
- position: 'fixed',
135
- inset: 0,
136
- display: 'flex',
137
- alignItems: 'center',
138
- justifyContent: 'center',
139
- backgroundColor: 'rgba(0, 0, 0, 0.5)',
140
- }}>
141
- <div style={{ backgroundColor: '#343534', padding: '1rem', borderRadius: '0.5rem', width: '500px', flexDirection: 'column', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
137
+ <div
138
+ style={{
139
+ position: 'fixed',
140
+ inset: 0,
141
+ display: 'flex',
142
+ alignItems: 'center',
143
+ justifyContent: 'center',
144
+ backgroundColor: 'rgba(0, 0, 0, 0.5)',
145
+ }}
146
+ >
147
+ <div
148
+ style={{
149
+ backgroundColor: '#343534',
150
+ padding: '1rem',
151
+ borderRadius: '0.5rem',
152
+ width: '500px',
153
+ flexDirection: 'column',
154
+ display: 'flex',
155
+ alignItems: 'center',
156
+ justifyContent: 'center',
157
+ }}
158
+ >
142
159
  <p style={{ fontSize: '2rem', fontWeight: 'bold', marginBottom: '1rem', textAlign: 'center' }}>Rimori Login</p>
143
160
  <p style={{ marginBottom: '1rem', textAlign: 'center' }}>
144
- Please login with your Rimori developer account for this plugin to be able to access the Rimori platform the same it will operate in the Rimori platform.
161
+ Please login with your Rimori developer account for this plugin to be able to access the Rimori platform the
162
+ same it will operate in the Rimori platform.
145
163
  </p>
146
164
  {/* email and password input */}
147
- <input style={{ marginBottom: '1rem', width: '100%', padding: '0.5rem', borderRadius: '0.5rem', border: 'none', backgroundColor: '#444444' }} type="email" placeholder="Email" onChange={(e) => setUser(e.target.value)} />
148
- <input style={{ marginBottom: '1rem', width: '100%', padding: '0.5rem', borderRadius: '0.5rem', border: 'none', backgroundColor: '#444444' }} type="password" placeholder="Password" onChange={(e) => setPassword(e.target.value)} />
149
- <button style={{ marginBottom: '1rem', width: '100%', padding: '0.5rem', borderRadius: '0.5rem', border: 'none', backgroundColor: '#928358' }} onClick={() => {
150
- onLogin(user, password);
151
- }}>Login</button>
165
+ <input
166
+ style={{
167
+ marginBottom: '1rem',
168
+ width: '100%',
169
+ padding: '0.5rem',
170
+ borderRadius: '0.5rem',
171
+ border: 'none',
172
+ backgroundColor: '#444444',
173
+ }}
174
+ type="email"
175
+ placeholder="Email"
176
+ onChange={(e) => setUser(e.target.value)}
177
+ />
178
+ <input
179
+ style={{
180
+ marginBottom: '1rem',
181
+ width: '100%',
182
+ padding: '0.5rem',
183
+ borderRadius: '0.5rem',
184
+ border: 'none',
185
+ backgroundColor: '#444444',
186
+ }}
187
+ type="password"
188
+ placeholder="Password"
189
+ onChange={(e) => setPassword(e.target.value)}
190
+ />
191
+ <button
192
+ style={{
193
+ marginBottom: '1rem',
194
+ width: '100%',
195
+ padding: '0.5rem',
196
+ borderRadius: '0.5rem',
197
+ border: 'none',
198
+ backgroundColor: '#928358',
199
+ }}
200
+ onClick={() => {
201
+ onLogin(user, password);
202
+ }}
203
+ >
204
+ Login
205
+ </button>
152
206
  </div>
153
207
  </div>
154
- )
155
- }
208
+ );
209
+ }
package/src/style.scss CHANGED
@@ -66,7 +66,7 @@ dialog::backdrop {
66
66
  ul {
67
67
  @apply list-disc pl-8;
68
68
 
69
- li>p {
69
+ li > p {
70
70
  @apply mb-1;
71
71
  }
72
72
  }
@@ -74,7 +74,7 @@ dialog::backdrop {
74
74
  ol {
75
75
  @apply list-decimal pl-7;
76
76
 
77
- li>p {
77
+ li > p {
78
78
  @apply mb-1;
79
79
  }
80
80
  }
@@ -133,4 +133,4 @@ dialog::backdrop {
133
133
  @apply max-w-full;
134
134
  }
135
135
  }
136
- }
136
+ }
@@ -1,61 +1,61 @@
1
1
  export const languageKeys = {
2
- sq: "albanian",
3
- ar: "arabic",
4
- hy: "armenian",
5
- az: "azerbaijani",
6
- bn: "bengali",
7
- bs: "bosnian",
8
- bg: "bulgarian",
9
- ca: "catalan",
10
- zh: "chinese",
11
- hr: "croatian",
12
- cs: "czech",
13
- da: "danish",
14
- nl: "dutch",
15
- en: "english",
16
- et: "estonian",
17
- fi: "finnish",
18
- fr: "french",
19
- gl: "galician",
20
- de: "german",
21
- el: "greek",
22
- he: "hebrew",
23
- hi: "hindi",
24
- hu: "hungarian",
25
- is: "icelandic",
26
- id: "indonesian",
27
- it: "italian",
28
- ja: "japanese",
29
- kn: "kannada",
30
- kk: "kazakh",
31
- ko: "korean",
32
- lv: "latvian",
33
- lt: "lithuanian",
34
- mk: "macedonian",
35
- ms: "malay",
36
- mr: "marathi",
37
- mi: "maori",
38
- ne: "nepali",
39
- no: "norwegian",
40
- fa: "persian",
41
- pl: "polish",
42
- pt: "portuguese",
43
- ro: "romanian",
44
- ru: "russian",
45
- sr: "serbian",
46
- sk: "slovak",
47
- sl: "slovenian",
48
- es: "spanish",
49
- sw: "swahili",
50
- sv: "swedish",
51
- tl: "filipino",
52
- ta: "tamil",
53
- th: "thai",
54
- tr: "turkish",
55
- uk: "ukrainian",
56
- ur: "urdu",
57
- vi: "vietnamese",
58
- cy: "welsh"
2
+ sq: 'albanian',
3
+ ar: 'arabic',
4
+ hy: 'armenian',
5
+ az: 'azerbaijani',
6
+ bn: 'bengali',
7
+ bs: 'bosnian',
8
+ bg: 'bulgarian',
9
+ ca: 'catalan',
10
+ zh: 'chinese',
11
+ hr: 'croatian',
12
+ cs: 'czech',
13
+ da: 'danish',
14
+ nl: 'dutch',
15
+ en: 'english',
16
+ et: 'estonian',
17
+ fi: 'finnish',
18
+ fr: 'french',
19
+ gl: 'galician',
20
+ de: 'german',
21
+ el: 'greek',
22
+ he: 'hebrew',
23
+ hi: 'hindi',
24
+ hu: 'hungarian',
25
+ is: 'icelandic',
26
+ id: 'indonesian',
27
+ it: 'italian',
28
+ ja: 'japanese',
29
+ kn: 'kannada',
30
+ kk: 'kazakh',
31
+ ko: 'korean',
32
+ lv: 'latvian',
33
+ lt: 'lithuanian',
34
+ mk: 'macedonian',
35
+ ms: 'malay',
36
+ mr: 'marathi',
37
+ mi: 'maori',
38
+ ne: 'nepali',
39
+ no: 'norwegian',
40
+ fa: 'persian',
41
+ pl: 'polish',
42
+ pt: 'portuguese',
43
+ ro: 'romanian',
44
+ ru: 'russian',
45
+ sr: 'serbian',
46
+ sk: 'slovak',
47
+ sl: 'slovenian',
48
+ es: 'spanish',
49
+ sw: 'swahili',
50
+ sv: 'swedish',
51
+ tl: 'filipino',
52
+ ta: 'tamil',
53
+ th: 'thai',
54
+ tr: 'turkish',
55
+ uk: 'ukrainian',
56
+ ur: 'urdu',
57
+ vi: 'vietnamese',
58
+ cy: 'welsh',
59
59
  } as const;
60
60
 
61
61
  export type Language = keyof typeof languageKeys;
@@ -69,4 +69,4 @@ export type Language = keyof typeof languageKeys;
69
69
  export function getLanguageName(languageCode: Language, capitalize: boolean = false): string {
70
70
  const lang = languageKeys[languageCode];
71
71
  return capitalize ? lang.charAt(0).toUpperCase() + lang.slice(1) : lang;
72
- }
72
+ }
@@ -1,26 +1,22 @@
1
1
  export function isFullscreen() {
2
- return !!document.fullscreenElement;
2
+ return !!document.fullscreenElement;
3
3
  }
4
4
 
5
5
  export function triggerFullscreen(onStateChange: (isFullscreen: boolean) => void, selector?: string) {
6
- document.addEventListener("fullscreenchange", () => {
7
- onStateChange(isFullscreen());
8
- });
9
- try {
10
- const ref = document.querySelector(selector || "#root")!
11
- if (!isFullscreen()) {
12
- // @ts-ignore
13
- ref.requestFullscreen() || ref.webkitRequestFullscreen()
14
- } else {
15
- // @ts-ignore
16
- document.exitFullscreen() || document.webkitExitFullscreen()
17
- }
18
- } catch (error: any) {
19
- console.error("Failed to enter fullscreen", error.message);
20
- }
6
+ document.addEventListener('fullscreenchange', () => {
21
7
  onStateChange(isFullscreen());
8
+ });
9
+ try {
10
+ const ref = document.querySelector(selector || '#root')!;
11
+ if (!isFullscreen()) {
12
+ // @ts-ignore
13
+ ref.requestFullscreen() || ref.webkitRequestFullscreen();
14
+ } else {
15
+ // @ts-ignore
16
+ document.exitFullscreen() || document.webkitExitFullscreen();
17
+ }
18
+ } catch (error: any) {
19
+ console.error('Failed to enter fullscreen', error.message);
20
+ }
21
+ onStateChange(isFullscreen());
22
22
  }
23
-
24
-
25
-
26
-
@@ -1,6 +1,6 @@
1
- const codes = ["Pre-A1", "A1", "A2", "B1", "B2", "C1", "C2", "Post-C2"];
1
+ const codes = ['Pre-A1', 'A1', 'A2', 'B1', 'B2', 'C1', 'C2', 'Post-C2'];
2
2
 
3
- export type LanguageLevel = "Pre-A1" | "A1" | "A2" | "B1" | "B2" | "C1" | "C2" | "Post-C2";
3
+ export type LanguageLevel = 'Pre-A1' | 'A1' | 'A2' | 'B1' | 'B2' | 'C1' | 'C2' | 'Post-C2';
4
4
 
5
5
  export function getDifficultyLevel(difficulty: LanguageLevel): number {
6
6
  return codes.indexOf(difficulty) + 1;
@@ -1,2 +1,3 @@
1
- export const DEFAULT_ENDPOINT = "https://pheptqdoqsdnadgoihvr.supabase.co";
2
- export const DEFAULT_ANON_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InBoZXB0cWRvcXNkbmFkZ29paHZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MzE2OTY2ODcsImV4cCI6MjA0NzI3MjY4N30.4GPFAXTF8685FaXISdAPNCIM-H3RGLo8GbyhQpu1mP0";
1
+ export const DEFAULT_ENDPOINT = 'https://pheptqdoqsdnadgoihvr.supabase.co';
2
+ export const DEFAULT_ANON_KEY =
3
+ 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InBoZXB0cWRvcXNkbmFkZ29paHZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MzE2OTY2ODcsImV4cCI6MjA0NzI3MjY4N30.4GPFAXTF8685FaXISdAPNCIM-H3RGLo8GbyhQpu1mP0';
@@ -1,6 +1,6 @@
1
- import { RimoriClient } from "../plugin/RimoriClient";
2
- import { EventBusHandler } from "../fromRimori/EventBus";
3
- import { PluginController } from "../plugin/PluginController";
1
+ import { RimoriClient } from '../plugin/RimoriClient';
2
+ import { EventBusHandler } from '../fromRimori/EventBus';
3
+ import { PluginController } from '../plugin/PluginController';
4
4
 
5
5
  /**
6
6
  * Sets up the web worker for the plugin to be able receive and send messages to Rimori.
@@ -8,21 +8,20 @@ import { PluginController } from "../plugin/PluginController";
8
8
  * @param init - The function containing the initialization logic.
9
9
  */
10
10
  export async function setupWorker(pluginId: string, init: (client: RimoriClient) => void | Promise<void>) {
11
-
12
11
  // Mock of the window object for the worker context to be able to use the PluginController.
13
12
  const mockWindow = {
14
13
  isWorker: true,
15
14
  location: {},
16
15
  parent: {
17
- postMessage: () => { }
16
+ postMessage: () => {},
18
17
  },
19
- addEventListener: () => { }
18
+ addEventListener: () => {},
20
19
  };
21
20
 
22
21
  // Assign the mock to globalThis.
23
22
  Object.assign(globalThis, { window: mockWindow });
24
23
 
25
- EventBusHandler.getInstance("Worker EventBus");
24
+ EventBusHandler.getInstance('Worker EventBus');
26
25
 
27
26
  const rimoriClient = await PluginController.getInstance(pluginId);
28
27
  console.debug('[Worker] RimoriClient initialized.');
@@ -30,5 +29,5 @@ export async function setupWorker(pluginId: string, init: (client: RimoriClient)
30
29
  await init(rimoriClient);
31
30
  console.debug('[Worker] Worker initialized.');
32
31
 
33
- self.postMessage({ type: "rimori:acknowledged", pluginId: pluginId });
34
- }
32
+ self.postMessage({ type: 'rimori:acknowledged', pluginId: pluginId });
33
+ }
package/tsconfig.json CHANGED
@@ -10,7 +10,5 @@
10
10
  "skipLibCheck": true,
11
11
  "strict": true
12
12
  },
13
- "include": [
14
- "src/**/*"
15
- ],
16
- }
13
+ "include": ["src/**/*"]
14
+ }
@@ -1,6 +0,0 @@
1
- import React from 'react';
2
- /**
3
- * Example component demonstrating Logger usage in a React component.
4
- * Shows how console methods are automatically captured by the Logger.
5
- */
6
- export declare const LoggerExample: React.FC;