@rimori/client 1.4.0 → 1.4.4
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/README.md +77 -71
- package/dist/cli/scripts/init/dev-registration.d.ts +1 -1
- package/dist/cli/scripts/init/dev-registration.js +4 -4
- package/dist/cli/scripts/init/main.js +1 -1
- package/dist/cli/scripts/init/package-setup.d.ts +1 -1
- package/dist/cli/scripts/init/package-setup.js +3 -3
- package/dist/cli/scripts/init/router-transformer.js +19 -12
- package/dist/cli/scripts/init/vite-config.d.ts +2 -2
- package/dist/cli/scripts/init/vite-config.js +2 -2
- package/dist/cli/scripts/release/release-config-upload.js +9 -9
- package/dist/cli/scripts/release/release-db-update.d.ts +1 -1
- package/dist/cli/scripts/release/release-db-update.js +9 -9
- package/dist/cli/scripts/release/release-file-upload.js +1 -1
- package/dist/cli/scripts/release/release.js +2 -2
- package/dist/components/CRUDModal.d.ts +1 -1
- package/dist/components/CRUDModal.js +3 -3
- package/dist/components/MarkdownEditor.js +16 -16
- package/dist/components/Spinner.js +2 -2
- package/dist/components/ai/Assistant.js +7 -8
- package/dist/components/ai/Avatar.d.ts +2 -2
- package/dist/components/ai/Avatar.js +10 -5
- package/dist/components/ai/EmbeddedAssistent/AudioInputField.js +5 -6
- package/dist/components/ai/EmbeddedAssistent/CircleAudioAvatar.d.ts +1 -1
- package/dist/components/ai/EmbeddedAssistent/CircleAudioAvatar.js +1 -2
- package/dist/components/ai/EmbeddedAssistent/TTS/MessageSender.d.ts +1 -2
- package/dist/components/ai/EmbeddedAssistent/TTS/MessageSender.js +4 -2
- package/dist/components/ai/EmbeddedAssistent/VoiceRecoder.js +2 -3
- package/dist/components/audio/Playbutton.js +10 -7
- package/dist/components/components/ContextMenu.d.ts +1 -1
- package/dist/components/components/ContextMenu.js +19 -16
- package/dist/components.d.ts +10 -10
- package/dist/components.js +10 -10
- package/dist/core/controller/AIController.d.ts +2 -2
- package/dist/core/controller/AIController.js +12 -12
- package/dist/core/controller/ExerciseController.d.ts +2 -2
- package/dist/core/controller/ExerciseController.js +2 -2
- package/dist/core/controller/ObjectController.js +5 -5
- package/dist/core/controller/SettingsController.d.ts +22 -7
- package/dist/core/controller/SettingsController.js +73 -8
- package/dist/core/controller/SharedContentController.d.ts +3 -3
- package/dist/core/controller/SharedContentController.js +38 -20
- package/dist/core/controller/VoiceController.js +6 -4
- package/dist/core/core.d.ts +15 -15
- package/dist/core/core.js +7 -7
- package/dist/fromRimori/EventBus.js +23 -23
- package/dist/fromRimori/PluginTypes.d.ts +4 -4
- package/dist/hooks/UseChatHook.d.ts +3 -3
- package/dist/hooks/UseChatHook.js +9 -3
- package/dist/index.d.ts +10 -10
- package/dist/index.js +9 -9
- package/dist/plugin/AccomplishmentHandler.d.ts +5 -5
- package/dist/plugin/AccomplishmentHandler.js +31 -27
- package/dist/plugin/AudioController.d.ts +1 -1
- package/dist/plugin/AudioController.js +6 -6
- package/dist/plugin/Logger.js +15 -13
- package/dist/plugin/PluginController.d.ts +7 -1
- package/dist/plugin/PluginController.js +32 -27
- package/dist/plugin/RimoriClient.d.ts +17 -18
- package/dist/plugin/RimoriClient.js +31 -31
- package/dist/plugin/StandaloneClient.d.ts +1 -1
- package/dist/plugin/StandaloneClient.js +35 -16
- package/dist/plugin/ThemeSetter.js +4 -4
- package/dist/providers/PluginProvider.js +44 -14
- package/dist/utils/Language.js +57 -57
- package/dist/utils/PluginUtils.js +3 -3
- package/dist/utils/difficultyConverter.d.ts +1 -1
- package/dist/utils/difficultyConverter.js +1 -1
- package/dist/utils/endpoint.js +2 -2
- package/dist/worker/WorkerSetup.d.ts +1 -1
- package/dist/worker/WorkerSetup.js +6 -6
- package/example/docs/devdocs.md +50 -40
- package/example/docs/overview.md +1 -1
- package/example/docs/userdocs.md +4 -1
- package/example/rimori.config.ts +51 -49
- package/example/worker/vite.config.ts +3 -3
- package/example/worker/worker.ts +2 -2
- package/package.json +14 -8
- package/prettier.config.js +1 -1
- package/src/cli/scripts/init/dev-registration.ts +5 -8
- package/src/cli/scripts/init/env-setup.ts +1 -1
- package/src/cli/scripts/init/file-operations.ts +1 -1
- package/src/cli/scripts/init/html-cleaner.ts +2 -5
- package/src/cli/scripts/init/main.ts +16 -13
- package/src/cli/scripts/init/package-setup.ts +11 -15
- package/src/cli/scripts/init/router-transformer.ts +40 -37
- package/src/cli/scripts/init/tailwind-config.ts +17 -26
- package/src/cli/scripts/init/vite-config.ts +3 -3
- package/src/cli/scripts/release/release-config-upload.ts +11 -11
- package/src/cli/scripts/release/release-db-update.ts +12 -12
- package/src/cli/scripts/release/release-file-upload.ts +2 -2
- package/src/cli/scripts/release/release.ts +4 -4
- package/src/cli/types/DatabaseTypes.ts +2 -10
- package/src/components/CRUDModal.tsx +64 -48
- package/src/components/MarkdownEditor.tsx +58 -27
- package/src/components/Spinner.tsx +24 -17
- package/src/components/ai/Assistant.tsx +70 -70
- package/src/components/ai/Avatar.tsx +17 -14
- package/src/components/ai/EmbeddedAssistent/AudioInputField.tsx +63 -54
- package/src/components/ai/EmbeddedAssistent/CircleAudioAvatar.tsx +14 -5
- package/src/components/ai/EmbeddedAssistent/TTS/MessageSender.ts +75 -74
- package/src/components/ai/EmbeddedAssistent/TTS/Player.ts +3 -4
- package/src/components/ai/EmbeddedAssistent/VoiceRecoder.tsx +109 -94
- package/src/components/ai/utils.ts +4 -4
- package/src/components/audio/Playbutton.tsx +101 -93
- package/src/components/components/ContextMenu.tsx +47 -35
- package/src/components.ts +10 -10
- package/src/core/controller/AIController.ts +29 -19
- package/src/core/controller/ExerciseController.ts +16 -23
- package/src/core/controller/ObjectController.ts +15 -10
- package/src/core/controller/SettingsController.ts +89 -16
- package/src/core/controller/SharedContentController.ts +80 -44
- package/src/core/controller/VoiceController.ts +10 -8
- package/src/core/core.ts +15 -16
- package/src/fromRimori/EventBus.ts +76 -47
- package/src/fromRimori/PluginTypes.ts +26 -17
- package/src/fromRimori/readme.md +2 -2
- package/src/hooks/UseChatHook.ts +25 -15
- package/src/index.ts +10 -10
- package/src/plugin/AccomplishmentHandler.ts +53 -35
- package/src/plugin/AudioController.ts +18 -12
- package/src/plugin/Logger.ts +28 -21
- package/src/plugin/PluginController.ts +60 -44
- package/src/plugin/RimoriClient.ts +102 -72
- package/src/plugin/StandaloneClient.ts +51 -24
- package/src/plugin/ThemeSetter.ts +5 -5
- package/src/providers/PluginProvider.tsx +90 -36
- package/src/style.scss +3 -3
- package/src/utils/Language.ts +58 -58
- package/src/utils/PluginUtils.ts +16 -20
- package/src/utils/difficultyConverter.ts +2 -2
- package/src/utils/endpoint.ts +3 -2
- package/src/worker/WorkerSetup.ts +8 -9
- package/tsconfig.json +2 -4
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import { createClient } from '@supabase/supabase-js';
|
|
11
11
|
import { EventBus } from '../fromRimori/EventBus';
|
|
12
|
-
import { RimoriClient } from
|
|
12
|
+
import { RimoriClient } from './RimoriClient';
|
|
13
13
|
import { StandaloneClient } from './StandaloneClient';
|
|
14
14
|
import { setTheme } from './ThemeSetter';
|
|
15
15
|
import { Logger } from './Logger';
|
|
@@ -36,11 +36,15 @@ export class PluginController {
|
|
|
36
36
|
}
|
|
37
37
|
initMessageChannel(worker = false) {
|
|
38
38
|
const listener = (event) => {
|
|
39
|
-
console.log(
|
|
39
|
+
console.log('[PluginController] window message', { origin: event.origin, data: event.data });
|
|
40
40
|
const { type, pluginId, queryParams, rimoriInfo } = event.data || {};
|
|
41
41
|
const [transferredPort] = event.ports || [];
|
|
42
|
-
if (type !==
|
|
43
|
-
console.log(
|
|
42
|
+
if (type !== 'rimori:init' || !transferredPort || pluginId !== this.pluginId) {
|
|
43
|
+
console.log('[PluginController] message ignored (not init or wrong plugin)', {
|
|
44
|
+
type,
|
|
45
|
+
pluginId,
|
|
46
|
+
hasPort: !!transferredPort,
|
|
47
|
+
});
|
|
44
48
|
return;
|
|
45
49
|
}
|
|
46
50
|
this.queryParams = queryParams || {};
|
|
@@ -49,7 +53,7 @@ export class PluginController {
|
|
|
49
53
|
if (rimoriInfo) {
|
|
50
54
|
this.rimoriInfo = rimoriInfo;
|
|
51
55
|
this.supabase = createClient(rimoriInfo.url, rimoriInfo.key, {
|
|
52
|
-
accessToken: () => Promise.resolve(rimoriInfo.token)
|
|
56
|
+
accessToken: () => Promise.resolve(rimoriInfo.token),
|
|
53
57
|
});
|
|
54
58
|
}
|
|
55
59
|
// Handle messages from parent
|
|
@@ -75,38 +79,38 @@ export class PluginController {
|
|
|
75
79
|
setTheme(theme);
|
|
76
80
|
}
|
|
77
81
|
// Forward plugin events to parent (only after MessageChannel is ready)
|
|
78
|
-
EventBus.on(
|
|
82
|
+
EventBus.on('*', (ev) => {
|
|
79
83
|
var _a;
|
|
80
|
-
if (ev.sender === this.pluginId && !ev.topic.startsWith(
|
|
84
|
+
if (ev.sender === this.pluginId && !ev.topic.startsWith('self.')) {
|
|
81
85
|
(_a = this.port) === null || _a === void 0 ? void 0 : _a.postMessage({ event: ev });
|
|
82
86
|
}
|
|
83
87
|
});
|
|
84
88
|
// Mark MessageChannel as ready and process pending requests
|
|
85
89
|
this.isMessageChannelReady = true;
|
|
86
90
|
// Process any pending requests
|
|
87
|
-
this.pendingRequests.forEach(request => request());
|
|
91
|
+
this.pendingRequests.forEach((request) => request());
|
|
88
92
|
this.pendingRequests = [];
|
|
89
93
|
};
|
|
90
94
|
if (worker) {
|
|
91
95
|
self.onmessage = listener;
|
|
92
96
|
}
|
|
93
97
|
else {
|
|
94
|
-
window.addEventListener(
|
|
98
|
+
window.addEventListener('message', listener);
|
|
95
99
|
}
|
|
96
100
|
this.sendHello(worker);
|
|
97
101
|
}
|
|
98
102
|
sendHello(isWorker = false) {
|
|
99
103
|
try {
|
|
100
|
-
const payload = { type:
|
|
104
|
+
const payload = { type: 'rimori:hello', pluginId: this.pluginId };
|
|
101
105
|
if (isWorker) {
|
|
102
106
|
self.postMessage(payload);
|
|
103
107
|
}
|
|
104
108
|
else {
|
|
105
|
-
window.parent.postMessage(payload,
|
|
109
|
+
window.parent.postMessage(payload, '*');
|
|
106
110
|
}
|
|
107
111
|
}
|
|
108
112
|
catch (e) {
|
|
109
|
-
console.error(
|
|
113
|
+
console.error('[PluginController] Error sending hello:', e);
|
|
110
114
|
}
|
|
111
115
|
}
|
|
112
116
|
static getInstance(pluginId_1) {
|
|
@@ -118,7 +122,7 @@ export class PluginController {
|
|
|
118
122
|
PluginController.instance = new PluginController(pluginId, standalone);
|
|
119
123
|
PluginController.client = yield RimoriClient.getInstance(PluginController.instance);
|
|
120
124
|
//only init logger in workers and on main plugin pages
|
|
121
|
-
if (PluginController.instance.getQueryParam(
|
|
125
|
+
if (PluginController.instance.getQueryParam('applicationMode') !== 'sidebar') {
|
|
122
126
|
Logger.getInstance(PluginController.client);
|
|
123
127
|
}
|
|
124
128
|
}
|
|
@@ -159,8 +163,8 @@ export class PluginController {
|
|
|
159
163
|
sender: this.pluginId,
|
|
160
164
|
topic: 'global.supabase.requestAccess',
|
|
161
165
|
data: {},
|
|
162
|
-
debug: false
|
|
163
|
-
}
|
|
166
|
+
debug: false,
|
|
167
|
+
},
|
|
164
168
|
};
|
|
165
169
|
return new Promise((resolve) => {
|
|
166
170
|
// Listen for the response
|
|
@@ -170,7 +174,7 @@ export class PluginController {
|
|
|
170
174
|
if (((_a = event.data) === null || _a === void 0 ? void 0 : _a.topic) === 'global.supabase.requestAccess' && ((_b = event.data) === null || _b === void 0 ? void 0 : _b.eventId) === eventId) {
|
|
171
175
|
this.rimoriInfo = event.data.data;
|
|
172
176
|
this.supabase = createClient(this.rimoriInfo.url, this.rimoriInfo.key, {
|
|
173
|
-
accessToken: () => Promise.resolve(this.getToken())
|
|
177
|
+
accessToken: () => Promise.resolve(this.getToken()),
|
|
174
178
|
});
|
|
175
179
|
self.onmessage = originalOnMessage; // Restore original handler
|
|
176
180
|
resolve({ supabase: this.supabase, info: this.rimoriInfo });
|
|
@@ -185,10 +189,11 @@ export class PluginController {
|
|
|
185
189
|
}
|
|
186
190
|
else {
|
|
187
191
|
// In main thread context, use EventBus
|
|
188
|
-
const { data } = yield EventBus.request(this.pluginId,
|
|
192
|
+
const { data } = yield EventBus.request(this.pluginId, 'global.supabase.requestAccess');
|
|
193
|
+
console.log({ data });
|
|
189
194
|
this.rimoriInfo = data;
|
|
190
195
|
this.supabase = createClient(this.rimoriInfo.url, this.rimoriInfo.key, {
|
|
191
|
-
accessToken: () => Promise.resolve(this.getToken())
|
|
196
|
+
accessToken: () => Promise.resolve(this.getToken()),
|
|
192
197
|
});
|
|
193
198
|
}
|
|
194
199
|
}
|
|
@@ -202,12 +207,12 @@ export class PluginController {
|
|
|
202
207
|
}
|
|
203
208
|
// If we don't have rimoriInfo, request it
|
|
204
209
|
if (!this.rimoriInfo) {
|
|
205
|
-
const { data } = yield EventBus.request(this.pluginId,
|
|
210
|
+
const { data } = yield EventBus.request(this.pluginId, 'global.supabase.requestAccess');
|
|
206
211
|
this.rimoriInfo = data;
|
|
207
212
|
return this.rimoriInfo.token;
|
|
208
213
|
}
|
|
209
214
|
// If token is expired, request fresh access
|
|
210
|
-
const { data } = yield EventBus.request(this.pluginId,
|
|
215
|
+
const { data } = yield EventBus.request(this.pluginId, 'global.supabase.requestAccess');
|
|
211
216
|
this.rimoriInfo.token = data.token;
|
|
212
217
|
this.rimoriInfo.expiration = data.expiration;
|
|
213
218
|
return this.rimoriInfo.token;
|
|
@@ -220,27 +225,27 @@ export class PluginController {
|
|
|
220
225
|
*/
|
|
221
226
|
getSupabaseUrl() {
|
|
222
227
|
if (!this.rimoriInfo) {
|
|
223
|
-
throw new Error(
|
|
228
|
+
throw new Error('Supabase info not found');
|
|
224
229
|
}
|
|
225
230
|
return this.rimoriInfo.url;
|
|
226
231
|
}
|
|
227
232
|
getBackendUrl() {
|
|
228
233
|
if (!this.rimoriInfo) {
|
|
229
|
-
throw new Error(
|
|
234
|
+
throw new Error('Rimori info not found');
|
|
230
235
|
}
|
|
231
236
|
return this.rimoriInfo.backendUrl;
|
|
232
237
|
}
|
|
233
238
|
getGlobalEventTopic(preliminaryTopic) {
|
|
234
239
|
var _a, _b;
|
|
235
|
-
if (preliminaryTopic.startsWith(
|
|
240
|
+
if (preliminaryTopic.startsWith('global.')) {
|
|
236
241
|
return preliminaryTopic;
|
|
237
242
|
}
|
|
238
|
-
if (preliminaryTopic.startsWith(
|
|
243
|
+
if (preliminaryTopic.startsWith('self.')) {
|
|
239
244
|
return preliminaryTopic;
|
|
240
245
|
}
|
|
241
|
-
const topicParts = preliminaryTopic.split(
|
|
246
|
+
const topicParts = preliminaryTopic.split('.');
|
|
242
247
|
if (topicParts.length === 3) {
|
|
243
|
-
if (!topicParts[0].startsWith(
|
|
248
|
+
if (!topicParts[0].startsWith('pl') && topicParts[0] !== 'global') {
|
|
244
249
|
throw new Error("The event topic must start with the plugin id or 'global'.");
|
|
245
250
|
}
|
|
246
251
|
return preliminaryTopic;
|
|
@@ -248,7 +253,7 @@ export class PluginController {
|
|
|
248
253
|
else if (topicParts.length > 3) {
|
|
249
254
|
throw new Error(`The event topic must consist of 3 parts. <pluginId>.<topic area>.<action>. Received: ${preliminaryTopic}`);
|
|
250
255
|
}
|
|
251
|
-
const topicRoot = (_b = (_a = this.rimoriInfo) === null || _a === void 0 ? void 0 : _a.pluginId) !== null && _b !== void 0 ? _b :
|
|
256
|
+
const topicRoot = (_b = (_a = this.rimoriInfo) === null || _a === void 0 ? void 0 : _a.pluginId) !== null && _b !== void 0 ? _b : 'global';
|
|
252
257
|
return `${topicRoot}.${preliminaryTopic}`;
|
|
253
258
|
}
|
|
254
259
|
}
|
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
import { PostgrestQueryBuilder } from
|
|
2
|
-
import { GenericSchema } from
|
|
3
|
-
import { Message, OnLLMResponse } from
|
|
4
|
-
import { ObjectRequest } from
|
|
5
|
-
import { UserInfo } from
|
|
6
|
-
import { SharedContent, SharedContentFilter, SharedContentObjectRequest } from
|
|
7
|
-
import { CreateExerciseParams } from
|
|
8
|
-
import { EventBusMessage, EventHandler, EventPayload } from
|
|
9
|
-
import { ActivePlugin, MainPanelAction, Plugin, Tool } from
|
|
10
|
-
import { AccomplishmentPayload } from
|
|
11
|
-
import { PluginController } from
|
|
12
|
-
import { ClientServerOptions } from "@supabase/postgrest-js/dist/cjs/types/common/common";
|
|
1
|
+
import { PostgrestQueryBuilder } from '@supabase/postgrest-js';
|
|
2
|
+
import { GenericSchema } from '@supabase/supabase-js/dist/module/lib/types';
|
|
3
|
+
import { Message, OnLLMResponse } from '../core/controller/AIController';
|
|
4
|
+
import { ObjectRequest } from '../core/controller/ObjectController';
|
|
5
|
+
import { UserInfo } from '../core/controller/SettingsController';
|
|
6
|
+
import { SharedContent, SharedContentFilter, SharedContentObjectRequest } from '../core/controller/SharedContentController';
|
|
7
|
+
import { CreateExerciseParams } from '../core/controller/ExerciseController';
|
|
8
|
+
import { EventBusMessage, EventHandler, EventPayload } from '../fromRimori/EventBus';
|
|
9
|
+
import { ActivePlugin, MainPanelAction, Plugin, Tool } from '../fromRimori/PluginTypes';
|
|
10
|
+
import { AccomplishmentPayload } from './AccomplishmentHandler';
|
|
11
|
+
import { PluginController } from './PluginController';
|
|
13
12
|
interface Db {
|
|
14
13
|
from: {
|
|
15
|
-
<TableName extends string & keyof GenericSchema['Tables'], Table extends GenericSchema['Tables'][TableName]>(relation: TableName): PostgrestQueryBuilder<
|
|
16
|
-
<ViewName extends string & keyof GenericSchema['Views'], View extends GenericSchema['Views'][ViewName]>(relation: ViewName): PostgrestQueryBuilder<
|
|
14
|
+
<TableName extends string & keyof GenericSchema['Tables'], Table extends GenericSchema['Tables'][TableName]>(relation: TableName): PostgrestQueryBuilder<GenericSchema, Table, TableName>;
|
|
15
|
+
<ViewName extends string & keyof GenericSchema['Views'], View extends GenericSchema['Views'][ViewName]>(relation: ViewName): PostgrestQueryBuilder<GenericSchema, View, ViewName>;
|
|
17
16
|
};
|
|
18
17
|
/**
|
|
19
18
|
* The table prefix for of database tables of the plugin.
|
|
@@ -205,10 +204,10 @@ export declare class RimoriClient {
|
|
|
205
204
|
*/
|
|
206
205
|
update: <T = any>(id: string, content: Partial<SharedContent<T>>) => Promise<SharedContent<T>>;
|
|
207
206
|
/**
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
207
|
+
* Complete a shared content item.
|
|
208
|
+
* @param contentType The type of shared content to complete. E.g. assignments, exercises, etc.
|
|
209
|
+
* @param assignmentId The id of the shared content item to complete.
|
|
210
|
+
*/
|
|
212
211
|
complete: (contentType: string, assignmentId: string) => Promise<void>;
|
|
213
212
|
/**
|
|
214
213
|
/**
|
|
@@ -7,14 +7,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import { generateText, streamChatGPT } from
|
|
11
|
-
import { generateObject } from
|
|
12
|
-
import { SettingsController } from
|
|
13
|
-
import { SharedContentController } from
|
|
14
|
-
import { getSTTResponse, getTTSResponse } from
|
|
15
|
-
import { ExerciseController } from
|
|
16
|
-
import { EventBus } from
|
|
17
|
-
import { AccomplishmentHandler } from
|
|
10
|
+
import { generateText, streamChatGPT } from '../core/controller/AIController';
|
|
11
|
+
import { generateObject } from '../core/controller/ObjectController';
|
|
12
|
+
import { SettingsController } from '../core/controller/SettingsController';
|
|
13
|
+
import { SharedContentController, } from '../core/controller/SharedContentController';
|
|
14
|
+
import { getSTTResponse, getTTSResponse } from '../core/controller/VoiceController';
|
|
15
|
+
import { ExerciseController } from '../core/controller/ExerciseController';
|
|
16
|
+
import { EventBus } from '../fromRimori/EventBus';
|
|
17
|
+
import { AccomplishmentHandler } from './AccomplishmentHandler';
|
|
18
18
|
export class RimoriClient {
|
|
19
19
|
constructor(supabase, info, pluginController) {
|
|
20
20
|
this.event = {
|
|
@@ -50,7 +50,7 @@ export class RimoriClient {
|
|
|
50
50
|
*/
|
|
51
51
|
on: (topic, callback) => {
|
|
52
52
|
const topics = Array.isArray(topic) ? topic : [topic];
|
|
53
|
-
return EventBus.on(topics.map(t => this.pluginController.getGlobalEventTopic(t)), callback);
|
|
53
|
+
return EventBus.on(topics.map((t) => this.pluginController.getGlobalEventTopic(t)), callback);
|
|
54
54
|
},
|
|
55
55
|
/**
|
|
56
56
|
* Subscribe to an event once.
|
|
@@ -67,7 +67,7 @@ export class RimoriClient {
|
|
|
67
67
|
*/
|
|
68
68
|
respond: (topic, data) => {
|
|
69
69
|
const topics = Array.isArray(topic) ? topic : [topic];
|
|
70
|
-
EventBus.respond(this.plugin.pluginId, topics.map(t => this.pluginController.getGlobalEventTopic(t)), data);
|
|
70
|
+
EventBus.respond(this.plugin.pluginId, topics.map((t) => this.pluginController.getGlobalEventTopic(t)), data);
|
|
71
71
|
},
|
|
72
72
|
/**
|
|
73
73
|
* Emit an accomplishment.
|
|
@@ -91,18 +91,18 @@ export class RimoriClient {
|
|
|
91
91
|
* @param text Optional text to be used for the action like for example text that the translator would look up.
|
|
92
92
|
*/
|
|
93
93
|
emitSidebarAction: (pluginId, actionKey, text) => {
|
|
94
|
-
this.event.emit(
|
|
94
|
+
this.event.emit('global.sidebar.triggerAction', { plugin_id: pluginId, action_key: actionKey, text });
|
|
95
95
|
},
|
|
96
96
|
onMainPanelAction: (callback) => {
|
|
97
97
|
// this needs to be a emit and on because the main panel action is triggered by the user and not by the plugin
|
|
98
|
-
this.event.emit(
|
|
99
|
-
this.event.on(
|
|
100
|
-
}
|
|
98
|
+
this.event.emit('action.requestMain');
|
|
99
|
+
this.event.on('action.requestMain', ({ data }) => callback(data));
|
|
100
|
+
},
|
|
101
101
|
};
|
|
102
102
|
this.navigation = {
|
|
103
103
|
toDashboard: () => {
|
|
104
|
-
this.event.emit(
|
|
105
|
-
}
|
|
104
|
+
this.event.emit('global.navigation.triggerToDashboard');
|
|
105
|
+
},
|
|
106
106
|
};
|
|
107
107
|
this.ai = {
|
|
108
108
|
getText: (messages, tools) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -113,7 +113,7 @@ export class RimoriClient {
|
|
|
113
113
|
const token = yield this.pluginController.getToken();
|
|
114
114
|
streamChatGPT(this.pluginController.getBackendUrl(), messages, tools || [], onMessage, token);
|
|
115
115
|
}),
|
|
116
|
-
getVoice: (text_1, ...args_1) => __awaiter(this, [text_1, ...args_1], void 0, function* (text, voice =
|
|
116
|
+
getVoice: (text_1, ...args_1) => __awaiter(this, [text_1, ...args_1], void 0, function* (text, voice = 'alloy', speed = 1, language) {
|
|
117
117
|
const token = yield this.pluginController.getToken();
|
|
118
118
|
return getTTSResponse(this.pluginController.getBackendUrl(), { input: text, voice, speed, language }, token);
|
|
119
119
|
}),
|
|
@@ -130,8 +130,8 @@ export class RimoriClient {
|
|
|
130
130
|
this.runtime = {
|
|
131
131
|
fetchBackend: (url, options) => __awaiter(this, void 0, void 0, function* () {
|
|
132
132
|
const token = yield this.pluginController.getToken();
|
|
133
|
-
return fetch(this.pluginController.getBackendUrl() + url, Object.assign(Object.assign({}, options), { headers: Object.assign(Object.assign({}, options.headers), {
|
|
134
|
-
})
|
|
133
|
+
return fetch(this.pluginController.getBackendUrl() + url, Object.assign(Object.assign({}, options), { headers: Object.assign(Object.assign({}, options.headers), { Authorization: `Bearer ${token}` }) }));
|
|
134
|
+
}),
|
|
135
135
|
};
|
|
136
136
|
this.community = {
|
|
137
137
|
/**
|
|
@@ -192,10 +192,10 @@ export class RimoriClient {
|
|
|
192
192
|
return yield this.sharedContentController.updateSharedContent(id, content);
|
|
193
193
|
}),
|
|
194
194
|
/**
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
195
|
+
* Complete a shared content item.
|
|
196
|
+
* @param contentType The type of shared content to complete. E.g. assignments, exercises, etc.
|
|
197
|
+
* @param assignmentId The id of the shared content item to complete.
|
|
198
|
+
*/
|
|
199
199
|
complete: (contentType, assignmentId) => __awaiter(this, void 0, void 0, function* () {
|
|
200
200
|
return yield this.sharedContentController.completeSharedContent(contentType, assignmentId);
|
|
201
201
|
}),
|
|
@@ -214,8 +214,8 @@ export class RimoriClient {
|
|
|
214
214
|
*/
|
|
215
215
|
remove: (id) => __awaiter(this, void 0, void 0, function* () {
|
|
216
216
|
return yield this.sharedContentController.removeSharedContent(id);
|
|
217
|
-
})
|
|
218
|
-
}
|
|
217
|
+
}),
|
|
218
|
+
},
|
|
219
219
|
};
|
|
220
220
|
this.exercise = {
|
|
221
221
|
/**
|
|
@@ -246,7 +246,7 @@ export class RimoriClient {
|
|
|
246
246
|
this.rimoriInfo = info;
|
|
247
247
|
this.superbase = supabase;
|
|
248
248
|
this.pluginController = pluginController;
|
|
249
|
-
this.settingsController = new SettingsController(supabase, info.pluginId);
|
|
249
|
+
this.settingsController = new SettingsController(supabase, info.pluginId, info.guild);
|
|
250
250
|
this.sharedContentController = new SharedContentController(this.superbase, this);
|
|
251
251
|
this.exerciseController = new ExerciseController(supabase, pluginController);
|
|
252
252
|
this.accomplishmentHandler = new AccomplishmentHandler(info.pluginId);
|
|
@@ -276,7 +276,7 @@ export class RimoriClient {
|
|
|
276
276
|
mainPanelPlugin: this.rimoriInfo.mainPanelPlugin,
|
|
277
277
|
sidePanelPlugin: this.rimoriInfo.sidePanelPlugin,
|
|
278
278
|
};
|
|
279
|
-
}
|
|
279
|
+
},
|
|
280
280
|
};
|
|
281
281
|
}
|
|
282
282
|
/**
|
|
@@ -301,11 +301,11 @@ export class RimoriClient {
|
|
|
301
301
|
}
|
|
302
302
|
getTableName(table) {
|
|
303
303
|
if (/[A-Z]/.test(table)) {
|
|
304
|
-
throw new Error(
|
|
304
|
+
throw new Error('Table name cannot include uppercase letters. Please use snake_case for table names.');
|
|
305
305
|
}
|
|
306
|
-
if (table.startsWith(
|
|
307
|
-
return table.replace(
|
|
306
|
+
if (table.startsWith('global_')) {
|
|
307
|
+
return table.replace('global_', '');
|
|
308
308
|
}
|
|
309
|
-
return this.db.tablePrefix +
|
|
309
|
+
return this.db.tablePrefix + '_' + table;
|
|
310
310
|
}
|
|
311
311
|
}
|
|
@@ -7,9 +7,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import { createClient } from
|
|
11
|
-
import { EventBus } from
|
|
12
|
-
import { DEFAULT_ANON_KEY, DEFAULT_ENDPOINT } from
|
|
10
|
+
import { createClient } from '@supabase/supabase-js';
|
|
11
|
+
import { EventBus } from '../fromRimori/EventBus';
|
|
12
|
+
import { DEFAULT_ANON_KEY, DEFAULT_ENDPOINT } from '../utils/endpoint';
|
|
13
13
|
export class StandaloneClient {
|
|
14
14
|
constructor(config) {
|
|
15
15
|
this.supabase = createClient(config.url, config.key);
|
|
@@ -18,8 +18,10 @@ export class StandaloneClient {
|
|
|
18
18
|
static getInstance() {
|
|
19
19
|
return __awaiter(this, void 0, void 0, function* () {
|
|
20
20
|
if (!StandaloneClient.instance) {
|
|
21
|
-
const config = yield fetch(
|
|
22
|
-
|
|
21
|
+
const config = yield fetch('https://app.rimori.se/config.json')
|
|
22
|
+
.then((res) => res.json())
|
|
23
|
+
.catch((err) => {
|
|
24
|
+
console.warn('Error fetching config.json, using default values', err);
|
|
23
25
|
});
|
|
24
26
|
StandaloneClient.instance = new StandaloneClient({
|
|
25
27
|
url: (config === null || config === void 0 ? void 0 : config.SUPABASE_URL) || DEFAULT_ENDPOINT,
|
|
@@ -45,33 +47,50 @@ export class StandaloneClient {
|
|
|
45
47
|
return __awaiter(this, void 0, void 0, function* () {
|
|
46
48
|
const { error } = yield this.supabase.auth.signInWithPassword({ email, password });
|
|
47
49
|
if (error) {
|
|
48
|
-
console.error(
|
|
50
|
+
console.error('Login failed:', error);
|
|
49
51
|
return false;
|
|
50
52
|
}
|
|
51
|
-
console.log(
|
|
53
|
+
console.log('Successfully logged in');
|
|
52
54
|
return true;
|
|
53
55
|
});
|
|
54
56
|
}
|
|
55
57
|
static initListeners(pluginId) {
|
|
56
58
|
return __awaiter(this, void 0, void 0, function* () {
|
|
57
|
-
console.warn(
|
|
59
|
+
console.warn('The plugin seams to not be running inside the Rimori platform. Switching to development standalone mode.');
|
|
58
60
|
// console.log("event that needs to be handled", event);
|
|
59
61
|
const { supabase, config } = yield StandaloneClient.getInstance();
|
|
60
62
|
// EventBus.on("*", async (event) => {
|
|
61
|
-
EventBus.respond(
|
|
63
|
+
EventBus.respond('standalone', 'global.supabase.requestAccess', () => __awaiter(this, void 0, void 0, function* () {
|
|
62
64
|
var _a;
|
|
63
65
|
const session = yield supabase.auth.getSession();
|
|
64
|
-
console.log(
|
|
66
|
+
console.log('session', session);
|
|
65
67
|
// Call the NestJS backend endpoint instead of the Supabase edge function
|
|
68
|
+
// get current guild id if any
|
|
69
|
+
let guildId = null;
|
|
70
|
+
try {
|
|
71
|
+
const { data: { user }, } = yield supabase.auth.getUser();
|
|
72
|
+
if (user) {
|
|
73
|
+
const { data: profile } = yield supabase
|
|
74
|
+
.from('profiles')
|
|
75
|
+
.select('current_guild_id')
|
|
76
|
+
.eq('user_id', user.id)
|
|
77
|
+
.maybeSingle();
|
|
78
|
+
guildId = (profile === null || profile === void 0 ? void 0 : profile.current_guild_id) || null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch (_) {
|
|
82
|
+
guildId = null;
|
|
83
|
+
}
|
|
66
84
|
const response = yield fetch(`${config.backendUrl}/plugin/token`, {
|
|
67
85
|
method: 'POST',
|
|
68
86
|
headers: {
|
|
69
87
|
'Content-Type': 'application/json',
|
|
70
|
-
|
|
88
|
+
Authorization: `Bearer ${(_a = session.data.session) === null || _a === void 0 ? void 0 : _a.access_token}`,
|
|
71
89
|
},
|
|
72
90
|
body: JSON.stringify({
|
|
73
|
-
pluginId: pluginId
|
|
74
|
-
|
|
91
|
+
pluginId: pluginId,
|
|
92
|
+
guildId: guildId,
|
|
93
|
+
}),
|
|
75
94
|
});
|
|
76
95
|
if (!response.ok) {
|
|
77
96
|
const errorText = yield response.text();
|
|
@@ -88,9 +107,9 @@ export class StandaloneClient {
|
|
|
88
107
|
expiration: new Date(Date.now() + 1000 * 60 * 60 * 1.5), // 1.5 hours
|
|
89
108
|
};
|
|
90
109
|
}));
|
|
91
|
-
EventBus.on(
|
|
92
|
-
console.log(
|
|
93
|
-
}), [
|
|
110
|
+
EventBus.on('*', (event) => __awaiter(this, void 0, void 0, function* () {
|
|
111
|
+
console.log('[standalone] would send event to parent', event);
|
|
112
|
+
}), ['standalone']);
|
|
94
113
|
});
|
|
95
114
|
}
|
|
96
115
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export function setTheme(theme) {
|
|
2
|
-
document.documentElement.classList.add(
|
|
2
|
+
document.documentElement.classList.add('dark:text-gray-200');
|
|
3
3
|
if (isDarkTheme(theme)) {
|
|
4
|
-
document.documentElement.setAttribute(
|
|
5
|
-
document.documentElement.classList.add('dark',
|
|
6
|
-
document.documentElement.style.background =
|
|
4
|
+
document.documentElement.setAttribute('data-theme', 'dark');
|
|
5
|
+
document.documentElement.classList.add('dark', 'dark:bg-gray-950');
|
|
6
|
+
document.documentElement.style.background = 'hsl(var(--background))';
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
9
|
export function isDarkTheme(theme) {
|
|
@@ -19,24 +19,24 @@ export const PluginProvider = ({ children, pluginId, settings }) => {
|
|
|
19
19
|
const [standaloneClient, setStandaloneClient] = useState(false);
|
|
20
20
|
const [applicationMode, setApplicationMode] = useState(null);
|
|
21
21
|
const [theme, setTheme] = useState(null);
|
|
22
|
-
const isSidebar = applicationMode ===
|
|
23
|
-
const isSettings = applicationMode ===
|
|
22
|
+
const isSidebar = applicationMode === 'sidebar';
|
|
23
|
+
const isSettings = applicationMode === 'settings';
|
|
24
24
|
useEffect(() => {
|
|
25
25
|
initEventBus(pluginId);
|
|
26
26
|
// Check if we're in an iframe context - if not, we're standalone
|
|
27
27
|
const standaloneDetected = window === window.parent;
|
|
28
28
|
if (standaloneDetected && !standaloneClient) {
|
|
29
|
-
StandaloneClient.getInstance().then(client => {
|
|
29
|
+
StandaloneClient.getInstance().then((client) => {
|
|
30
30
|
client.needsLogin().then((needLogin) => setStandaloneClient(needLogin ? client : true));
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
33
|
if ((!standaloneDetected && !plugin) || (standaloneDetected && standaloneClient === true)) {
|
|
34
|
-
PluginController.getInstance(pluginId, standaloneDetected).then(client => {
|
|
34
|
+
PluginController.getInstance(pluginId, standaloneDetected).then((client) => {
|
|
35
35
|
setPlugin(client);
|
|
36
36
|
// Get applicationMode and theme from MessageChannel query params
|
|
37
37
|
if (!standaloneDetected) {
|
|
38
|
-
const mode = client.getQueryParam(
|
|
39
|
-
const themeParam = client.getQueryParam(
|
|
38
|
+
const mode = client.getQueryParam('applicationMode');
|
|
39
|
+
const themeParam = client.getQueryParam('rm_theme');
|
|
40
40
|
setApplicationMode(mode);
|
|
41
41
|
setTheme(themeParam);
|
|
42
42
|
}
|
|
@@ -71,13 +71,13 @@ export const PluginProvider = ({ children, pluginId, settings }) => {
|
|
|
71
71
|
return () => body.removeEventListener('resize', handleResize);
|
|
72
72
|
}, [plugin]);
|
|
73
73
|
if (standaloneClient instanceof StandaloneClient) {
|
|
74
|
-
return _jsx(StandaloneAuth, { onLogin: (email, password) => __awaiter(void 0, void 0, void 0, function* () {
|
|
74
|
+
return (_jsx(StandaloneAuth, { onLogin: (email, password) => __awaiter(void 0, void 0, void 0, function* () {
|
|
75
75
|
if (yield standaloneClient.login(email, password))
|
|
76
76
|
setStandaloneClient(true);
|
|
77
|
-
}) });
|
|
77
|
+
}) }));
|
|
78
78
|
}
|
|
79
79
|
if (!plugin) {
|
|
80
|
-
return
|
|
80
|
+
return '';
|
|
81
81
|
}
|
|
82
82
|
return (_jsxs(PluginContext.Provider, { value: plugin, children: [!(settings === null || settings === void 0 ? void 0 : settings.disableContextMenu) && !isSidebar && !isSettings && _jsx(ContextMenu, { client: plugin }), children] }));
|
|
83
83
|
};
|
|
@@ -103,12 +103,12 @@ function getUrlParam(name) {
|
|
|
103
103
|
}
|
|
104
104
|
function initEventBus(pluginId) {
|
|
105
105
|
// For now, use URL fallback for EventBus naming - this will be updated once MessageChannel is ready
|
|
106
|
-
const isSidebar = getUrlParam(
|
|
107
|
-
EventBusHandler.getInstance(
|
|
106
|
+
const isSidebar = getUrlParam('applicationMode') === 'sidebar';
|
|
107
|
+
EventBusHandler.getInstance('Plugin EventBus ' + pluginId + ' ' + (isSidebar ? 'sidebar' : 'main'));
|
|
108
108
|
}
|
|
109
109
|
function StandaloneAuth({ onLogin }) {
|
|
110
|
-
const [user, setUser] = useState(
|
|
111
|
-
const [password, setPassword] = useState(
|
|
110
|
+
const [user, setUser] = useState('');
|
|
111
|
+
const [password, setPassword] = useState('');
|
|
112
112
|
return (_jsx("div", { style: {
|
|
113
113
|
position: 'fixed',
|
|
114
114
|
inset: 0,
|
|
@@ -116,7 +116,37 @@ function StandaloneAuth({ onLogin }) {
|
|
|
116
116
|
alignItems: 'center',
|
|
117
117
|
justifyContent: 'center',
|
|
118
118
|
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
|
119
|
-
}, children: _jsxs("div", { style: {
|
|
119
|
+
}, children: _jsxs("div", { style: {
|
|
120
|
+
backgroundColor: '#343534',
|
|
121
|
+
padding: '1rem',
|
|
122
|
+
borderRadius: '0.5rem',
|
|
123
|
+
width: '500px',
|
|
124
|
+
flexDirection: 'column',
|
|
125
|
+
display: 'flex',
|
|
126
|
+
alignItems: 'center',
|
|
127
|
+
justifyContent: 'center',
|
|
128
|
+
}, children: [_jsx("p", { style: { fontSize: '2rem', fontWeight: 'bold', marginBottom: '1rem', textAlign: 'center' }, children: "Rimori Login" }), _jsx("p", { style: { marginBottom: '1rem', textAlign: 'center' }, children: "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." }), _jsx("input", { style: {
|
|
129
|
+
marginBottom: '1rem',
|
|
130
|
+
width: '100%',
|
|
131
|
+
padding: '0.5rem',
|
|
132
|
+
borderRadius: '0.5rem',
|
|
133
|
+
border: 'none',
|
|
134
|
+
backgroundColor: '#444444',
|
|
135
|
+
}, type: "email", placeholder: "Email", onChange: (e) => setUser(e.target.value) }), _jsx("input", { style: {
|
|
136
|
+
marginBottom: '1rem',
|
|
137
|
+
width: '100%',
|
|
138
|
+
padding: '0.5rem',
|
|
139
|
+
borderRadius: '0.5rem',
|
|
140
|
+
border: 'none',
|
|
141
|
+
backgroundColor: '#444444',
|
|
142
|
+
}, type: "password", placeholder: "Password", onChange: (e) => setPassword(e.target.value) }), _jsx("button", { style: {
|
|
143
|
+
marginBottom: '1rem',
|
|
144
|
+
width: '100%',
|
|
145
|
+
padding: '0.5rem',
|
|
146
|
+
borderRadius: '0.5rem',
|
|
147
|
+
border: 'none',
|
|
148
|
+
backgroundColor: '#928358',
|
|
149
|
+
}, onClick: () => {
|
|
120
150
|
onLogin(user, password);
|
|
121
151
|
}, children: "Login" })] }) }));
|
|
122
152
|
}
|