@rimori/client 1.0.4 → 1.0.5

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.
@@ -2,25 +2,33 @@ import { SupabaseClient } from "@supabase/supabase-js";
2
2
  import { LanguageLevel } from "../utils/difficultyConverter";
3
3
  export interface UserInfo {
4
4
  motherTongue: string;
5
- languageLevel: LanguageLevel;
6
- contextMenuOnSelect: boolean;
7
- }
8
- export interface SystemSettings {
5
+ xp: number;
6
+ listening_level: LanguageLevel;
7
+ reading_level: LanguageLevel;
8
+ speaking_level: LanguageLevel;
9
+ writing_level: LanguageLevel;
10
+ understanding_level: LanguageLevel;
11
+ grammar_level: LanguageLevel;
12
+ longterm_goal: string;
13
+ motivation_type: string;
14
+ study_buddy: string;
15
+ preferred_genre: string;
16
+ milestone: string;
17
+ settings: {
18
+ contextMenuOnSelect: boolean;
19
+ };
9
20
  }
10
21
  export declare class SettingsController {
11
22
  private pluginId;
12
23
  private supabase;
13
24
  constructor(supabase: SupabaseClient, pluginId: string);
14
- private getSettingsType;
15
25
  private fetchSettings;
16
- private saveSettings;
26
+ setSettings(settings: any): Promise<void>;
17
27
  getUserInfo(): Promise<UserInfo>;
18
28
  /**
19
29
  * Get the settings for the plugin. T can be any type of settings, UserSettings or SystemSettings.
20
30
  * @param defaultSettings The default settings to use if no settings are found.
21
- * @param genericSettings The type of settings to get.
22
31
  * @returns The settings for the plugin.
23
32
  */
24
- getSettings<T extends object>(defaultSettings: T, genericSettings?: "user" | "system"): Promise<T>;
25
- setSettings(settings: any, genericSettings?: "user" | "system"): Promise<void>;
33
+ getSettings<T extends object>(defaultSettings: T): Promise<T>;
26
34
  }
@@ -12,50 +12,56 @@ export class SettingsController {
12
12
  this.supabase = supabase;
13
13
  this.pluginId = pluginId;
14
14
  }
15
- getSettingsType(genericSettings) {
16
- return genericSettings || "plugin";
17
- }
18
- fetchSettings(type) {
15
+ fetchSettings() {
19
16
  return __awaiter(this, void 0, void 0, function* () {
20
- const pluginId = type === "plugin" ? this.pluginId : type;
21
- const { data } = yield this.supabase.from("plugin_settings").select("*").eq("plugin_id", pluginId);
17
+ const { data } = yield this.supabase.from("plugin_settings").select("*").eq("plugin_id", this.pluginId);
22
18
  if (!data || data.length === 0) {
23
19
  return null;
24
20
  }
25
21
  return data[0].settings;
26
22
  });
27
23
  }
28
- saveSettings(settings, type) {
24
+ setSettings(settings) {
29
25
  return __awaiter(this, void 0, void 0, function* () {
30
- if (type !== "plugin") {
31
- throw new Error(`Cannot modify ${type} settings`);
32
- }
33
26
  yield this.supabase.from("plugin_settings").upsert({ plugin_id: this.pluginId, settings });
34
27
  });
35
28
  }
36
29
  getUserInfo() {
37
30
  return __awaiter(this, void 0, void 0, function* () {
38
- return this.getSettings({
39
- motherTongue: "sv",
40
- languageLevel: "A1",
41
- contextMenuOnSelect: true,
42
- }, "user");
31
+ const { data } = yield this.supabase.from("profiles").select("*");
32
+ if (!data || data.length === 0) {
33
+ return {
34
+ motherTongue: "en",
35
+ xp: 0,
36
+ listening_level: "Pre-A1",
37
+ reading_level: "Pre-A1",
38
+ speaking_level: "Pre-A1",
39
+ writing_level: "Pre-A1",
40
+ understanding_level: "Pre-A1",
41
+ grammar_level: "Pre-A1",
42
+ longterm_goal: "",
43
+ motivation_type: "self-motivated",
44
+ study_buddy: "clarence",
45
+ preferred_genre: "adventure",
46
+ milestone: "",
47
+ settings: {
48
+ contextMenuOnSelect: false,
49
+ }
50
+ };
51
+ }
52
+ return data[0];
43
53
  });
44
54
  }
45
55
  /**
46
56
  * Get the settings for the plugin. T can be any type of settings, UserSettings or SystemSettings.
47
57
  * @param defaultSettings The default settings to use if no settings are found.
48
- * @param genericSettings The type of settings to get.
49
58
  * @returns The settings for the plugin.
50
59
  */
51
- getSettings(defaultSettings, genericSettings) {
60
+ getSettings(defaultSettings) {
52
61
  return __awaiter(this, void 0, void 0, function* () {
53
- const type = this.getSettingsType(genericSettings);
54
- const storedSettings = yield this.fetchSettings(type);
62
+ const storedSettings = yield this.fetchSettings();
55
63
  if (!storedSettings) {
56
- if (type === "plugin") {
57
- yield this.saveSettings(defaultSettings, type);
58
- }
64
+ yield this.setSettings(defaultSettings);
59
65
  return defaultSettings;
60
66
  }
61
67
  // Handle settings migration
@@ -64,18 +70,10 @@ export class SettingsController {
64
70
  if (storedKeys.length !== defaultKeys.length) {
65
71
  const validStoredSettings = Object.fromEntries(Object.entries(storedSettings).filter(([key]) => defaultKeys.includes(key)));
66
72
  const mergedSettings = Object.assign(Object.assign({}, defaultSettings), validStoredSettings);
67
- if (type === "plugin") {
68
- yield this.saveSettings(mergedSettings, type);
69
- }
73
+ yield this.setSettings(mergedSettings);
70
74
  return mergedSettings;
71
75
  }
72
76
  return storedSettings;
73
77
  });
74
78
  }
75
- setSettings(settings, genericSettings) {
76
- return __awaiter(this, void 0, void 0, function* () {
77
- const type = this.getSettingsType(genericSettings);
78
- yield this.saveSettings(settings, type);
79
- });
80
- }
81
79
  }
@@ -11,7 +11,6 @@ import { createClient } from '@supabase/supabase-js';
11
11
  import { RimoriClient } from "./RimoriClient";
12
12
  import { EventBus } from './fromRimori/EventBus';
13
13
  import { setTheme } from './ThemeSetter';
14
- setTheme();
15
14
  export class PluginController {
16
15
  constructor(pluginId) {
17
16
  this.communicationSecret = null;
@@ -19,6 +18,9 @@ export class PluginController {
19
18
  this.supabaseInfo = null;
20
19
  this.pluginId = pluginId;
21
20
  this.getClient = this.getClient.bind(this);
21
+ if (typeof WorkerGlobalScope === 'undefined') {
22
+ setTheme();
23
+ }
22
24
  window.addEventListener("message", (event) => {
23
25
  // console.log("client: message received", event);
24
26
  const { topic, sender, data, eventId } = event.data.event;
@@ -1,13 +1,13 @@
1
1
  export function setTheme() {
2
2
  const urlParams = new URLSearchParams(window.location.search);
3
3
  let theme = urlParams.get('theme');
4
- const isSidebar = urlParams.get('applicationMode') === "sidebar";
5
4
  if (!theme || theme === 'system') {
6
5
  theme = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
7
6
  }
8
7
  document.documentElement.classList.add("dark:text-gray-200", "bg-white");
9
8
  if (theme === 'dark') {
10
- document.documentElement.classList.add('dark', isSidebar ? "bg-gray-920" : "bg-gray-950");
11
- document.documentElement.style.background = isSidebar ? "rgb(6, 12, 30)" : "rgb(3, 7, 18)";
9
+ document.documentElement.setAttribute("data-theme", "dark");
10
+ document.documentElement.classList.add('dark', "bg-gray-950");
11
+ document.documentElement.style.background = "hsl(var(--background))";
12
12
  }
13
13
  }
@@ -19,6 +19,7 @@ let debugEnabled = false;
19
19
  export function setupWorker(init) {
20
20
  // Mock of the window object for the worker context to be able to use the PluginController.
21
21
  const mockWindow = {
22
+ isWorker: true,
22
23
  location: { search: '?secret=123' },
23
24
  parent: {
24
25
  postMessage: (message) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rimori/client",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "exports": {
@@ -32,6 +32,7 @@
32
32
  "@tiptap/starter-kit": "2.10.3",
33
33
  "uuid": "11.1.0",
34
34
  "react-icons": "^5.4.0",
35
+ "react-markdown": "^10.1.0",
35
36
  "tiptap-markdown": "^0.8.10",
36
37
  "typescript": "^5.7.2"
37
38
  },
@@ -1,16 +1,23 @@
1
1
  import { SupabaseClient } from "@supabase/supabase-js";
2
2
  import { LanguageLevel } from "../utils/difficultyConverter";
3
3
 
4
- type SettingsType = "user" | "system" | "plugin";
5
-
6
4
  export interface UserInfo {
7
5
  motherTongue: string;
8
- languageLevel: LanguageLevel;
9
- contextMenuOnSelect: boolean;
10
- }
11
-
12
- export interface SystemSettings {
13
- // TODO: add system settings
6
+ xp: number;
7
+ listening_level: LanguageLevel;
8
+ reading_level: LanguageLevel;
9
+ speaking_level: LanguageLevel;
10
+ writing_level: LanguageLevel;
11
+ understanding_level: LanguageLevel;
12
+ grammar_level: LanguageLevel;
13
+ longterm_goal: string;
14
+ motivation_type: string;
15
+ study_buddy: string;
16
+ preferred_genre: string;
17
+ milestone: string;
18
+ settings: {
19
+ contextMenuOnSelect: boolean;
20
+ }
14
21
  }
15
22
 
16
23
  export class SettingsController {
@@ -22,13 +29,8 @@ export class SettingsController {
22
29
  this.pluginId = pluginId;
23
30
  }
24
31
 
25
- private getSettingsType(genericSettings?: "user" | "system"): SettingsType {
26
- return genericSettings || "plugin";
27
- }
28
-
29
- private async fetchSettings(type: SettingsType): Promise<any | null> {
30
- const pluginId = type === "plugin" ? this.pluginId : type;
31
- const { data } = await this.supabase.from("plugin_settings").select("*").eq("plugin_id", pluginId)
32
+ private async fetchSettings(): Promise<any | null> {
33
+ const { data } = await this.supabase.from("plugin_settings").select("*").eq("plugin_id", this.pluginId)
32
34
 
33
35
  if (!data || data.length === 0) {
34
36
  return null;
@@ -37,36 +39,47 @@ export class SettingsController {
37
39
  return data[0].settings;
38
40
  }
39
41
 
40
- private async saveSettings(settings: any, type: SettingsType): Promise<void> {
41
- if (type !== "plugin") {
42
- throw new Error(`Cannot modify ${type} settings`);
43
- }
44
-
42
+ public async setSettings(settings: any): Promise<void> {
45
43
  await this.supabase.from("plugin_settings").upsert({ plugin_id: this.pluginId, settings });
46
44
  }
47
45
 
48
46
  public async getUserInfo(): Promise<UserInfo> {
49
- return this.getSettings<UserInfo>({
50
- motherTongue: "sv",
51
- languageLevel: "A1",
52
- contextMenuOnSelect: true,
53
- }, "user");
47
+ const { data } = await this.supabase.from("profiles").select("*");
48
+
49
+ if (!data || data.length === 0) {
50
+ return {
51
+ motherTongue: "en",
52
+ xp: 0,
53
+ listening_level: "Pre-A1",
54
+ reading_level: "Pre-A1",
55
+ speaking_level: "Pre-A1",
56
+ writing_level: "Pre-A1",
57
+ understanding_level: "Pre-A1",
58
+ grammar_level: "Pre-A1",
59
+ longterm_goal: "",
60
+ motivation_type: "self-motivated",
61
+ study_buddy: "clarence",
62
+ preferred_genre: "adventure",
63
+ milestone: "",
64
+ settings: {
65
+ contextMenuOnSelect: false,
66
+ }
67
+ }
68
+ }
69
+
70
+ return data[0];
54
71
  }
55
72
 
56
73
  /**
57
74
  * Get the settings for the plugin. T can be any type of settings, UserSettings or SystemSettings.
58
75
  * @param defaultSettings The default settings to use if no settings are found.
59
- * @param genericSettings The type of settings to get.
60
76
  * @returns The settings for the plugin.
61
77
  */
62
- public async getSettings<T extends object>(defaultSettings: T, genericSettings?: "user" | "system"): Promise<T> {
63
- const type = this.getSettingsType(genericSettings);
64
- const storedSettings = await this.fetchSettings(type) as T | null;
78
+ public async getSettings<T extends object>(defaultSettings: T): Promise<T> {
79
+ const storedSettings = await this.fetchSettings() as T | null;
65
80
 
66
81
  if (!storedSettings) {
67
- if (type === "plugin") {
68
- await this.saveSettings(defaultSettings, type);
69
- }
82
+ await this.setSettings(defaultSettings);
70
83
  return defaultSettings;
71
84
  }
72
85
 
@@ -80,17 +93,10 @@ export class SettingsController {
80
93
  );
81
94
  const mergedSettings = { ...defaultSettings, ...validStoredSettings } as T;
82
95
 
83
- if (type === "plugin") {
84
- await this.saveSettings(mergedSettings, type);
85
- }
96
+ await this.setSettings(mergedSettings);
86
97
  return mergedSettings;
87
98
  }
88
99
 
89
100
  return storedSettings;
90
101
  }
91
-
92
- public async setSettings(settings: any, genericSettings?: "user" | "system"): Promise<void> {
93
- const type = this.getSettingsType(genericSettings);
94
- await this.saveSettings(settings, type);
95
- }
96
102
  }
@@ -3,7 +3,8 @@ import { RimoriClient } from "./RimoriClient";
3
3
  import { EventBus, EventBusMessage } from './fromRimori/EventBus';
4
4
  import { setTheme } from './ThemeSetter';
5
5
 
6
- setTheme();
6
+ // Add declaration for WorkerGlobalScope
7
+ declare const WorkerGlobalScope: any;
7
8
 
8
9
  interface SupabaseInfo {
9
10
  url: string,
@@ -26,6 +27,10 @@ export class PluginController {
26
27
  this.pluginId = pluginId;
27
28
  this.getClient = this.getClient.bind(this);
28
29
 
30
+ if (typeof WorkerGlobalScope === 'undefined') {
31
+ setTheme();
32
+ }
33
+
29
34
  window.addEventListener("message", (event) => {
30
35
  // console.log("client: message received", event);
31
36
  const { topic, sender, data, eventId } = event.data.event as EventBusMessage;
@@ -72,7 +77,7 @@ export class PluginController {
72
77
  return { supabase: this.supabase, tablePrefix: this.supabaseInfo.tablePrefix, pluginId: this.supabaseInfo.pluginId };
73
78
  }
74
79
 
75
- const {data} = await EventBus.request<SupabaseInfo>(this.pluginId, "global.supabase.requestAccess");
80
+ const { data } = await EventBus.request<SupabaseInfo>(this.pluginId, "global.supabase.requestAccess");
76
81
  this.supabaseInfo = data;
77
82
  this.supabase = createClient(this.supabaseInfo.url, this.supabaseInfo.key, {
78
83
  accessToken: () => Promise.resolve(this.getToken())
@@ -86,7 +91,7 @@ export class PluginController {
86
91
  return this.supabaseInfo.token;
87
92
  }
88
93
 
89
- const {data} = await EventBus.request<{ token: string, expiration: Date }>(this.pluginId, "global.supabase.requestAccess");
94
+ const { data } = await EventBus.request<{ token: string, expiration: Date }>(this.pluginId, "global.supabase.requestAccess");
90
95
 
91
96
  if (!this.supabaseInfo) {
92
97
  throw new Error("Supabase info not found");
@@ -2,8 +2,6 @@ export function setTheme() {
2
2
  const urlParams = new URLSearchParams(window.location.search);
3
3
 
4
4
  let theme = urlParams.get('theme');
5
- const isSidebar = urlParams.get('applicationMode') === "sidebar";
6
-
7
5
  if (!theme || theme === 'system') {
8
6
  theme = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
9
7
  }
@@ -11,7 +9,8 @@ export function setTheme() {
11
9
  document.documentElement.classList.add("dark:text-gray-200", "bg-white");
12
10
 
13
11
  if (theme === 'dark') {
14
- document.documentElement.classList.add('dark', isSidebar ? "bg-gray-920" : "bg-gray-950");
15
- document.documentElement.style.background = isSidebar ? "rgb(6, 12, 30)" : "rgb(3, 7, 18)";
12
+ document.documentElement.setAttribute("data-theme", "dark");
13
+ document.documentElement.classList.add('dark', "bg-gray-950");
14
+ document.documentElement.style.background = "hsl(var(--background))";
16
15
  }
17
16
  }
@@ -13,6 +13,7 @@ let debugEnabled = false;
13
13
  export function setupWorker(init: (controller: RimoriClient) => void | Promise<void>) {
14
14
  // Mock of the window object for the worker context to be able to use the PluginController.
15
15
  const mockWindow = {
16
+ isWorker: true,
16
17
  location: { search: '?secret=123' },
17
18
  parent: {
18
19
  postMessage: (message: { event: EventBusMessage }) => {