@rimori/client 1.4.0 → 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.
- 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
package/dist/utils/Language.js
CHANGED
|
@@ -1,61 +1,61 @@
|
|
|
1
1
|
export const languageKeys = {
|
|
2
|
-
sq:
|
|
3
|
-
ar:
|
|
4
|
-
hy:
|
|
5
|
-
az:
|
|
6
|
-
bn:
|
|
7
|
-
bs:
|
|
8
|
-
bg:
|
|
9
|
-
ca:
|
|
10
|
-
zh:
|
|
11
|
-
hr:
|
|
12
|
-
cs:
|
|
13
|
-
da:
|
|
14
|
-
nl:
|
|
15
|
-
en:
|
|
16
|
-
et:
|
|
17
|
-
fi:
|
|
18
|
-
fr:
|
|
19
|
-
gl:
|
|
20
|
-
de:
|
|
21
|
-
el:
|
|
22
|
-
he:
|
|
23
|
-
hi:
|
|
24
|
-
hu:
|
|
25
|
-
is:
|
|
26
|
-
id:
|
|
27
|
-
it:
|
|
28
|
-
ja:
|
|
29
|
-
kn:
|
|
30
|
-
kk:
|
|
31
|
-
ko:
|
|
32
|
-
lv:
|
|
33
|
-
lt:
|
|
34
|
-
mk:
|
|
35
|
-
ms:
|
|
36
|
-
mr:
|
|
37
|
-
mi:
|
|
38
|
-
ne:
|
|
39
|
-
no:
|
|
40
|
-
fa:
|
|
41
|
-
pl:
|
|
42
|
-
pt:
|
|
43
|
-
ro:
|
|
44
|
-
ru:
|
|
45
|
-
sr:
|
|
46
|
-
sk:
|
|
47
|
-
sl:
|
|
48
|
-
es:
|
|
49
|
-
sw:
|
|
50
|
-
sv:
|
|
51
|
-
tl:
|
|
52
|
-
ta:
|
|
53
|
-
th:
|
|
54
|
-
tr:
|
|
55
|
-
uk:
|
|
56
|
-
ur:
|
|
57
|
-
vi:
|
|
58
|
-
cy:
|
|
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
|
};
|
|
60
60
|
/**
|
|
61
61
|
* Get the language name from the language code
|
|
@@ -2,11 +2,11 @@ export function isFullscreen() {
|
|
|
2
2
|
return !!document.fullscreenElement;
|
|
3
3
|
}
|
|
4
4
|
export function triggerFullscreen(onStateChange, selector) {
|
|
5
|
-
document.addEventListener(
|
|
5
|
+
document.addEventListener('fullscreenchange', () => {
|
|
6
6
|
onStateChange(isFullscreen());
|
|
7
7
|
});
|
|
8
8
|
try {
|
|
9
|
-
const ref = document.querySelector(selector ||
|
|
9
|
+
const ref = document.querySelector(selector || '#root');
|
|
10
10
|
if (!isFullscreen()) {
|
|
11
11
|
// @ts-ignore
|
|
12
12
|
ref.requestFullscreen() || ref.webkitRequestFullscreen();
|
|
@@ -17,7 +17,7 @@ export function triggerFullscreen(onStateChange, selector) {
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
catch (error) {
|
|
20
|
-
console.error(
|
|
20
|
+
console.error('Failed to enter fullscreen', error.message);
|
|
21
21
|
}
|
|
22
22
|
onStateChange(isFullscreen());
|
|
23
23
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type LanguageLevel =
|
|
1
|
+
export type LanguageLevel = 'Pre-A1' | 'A1' | 'A2' | 'B1' | 'B2' | 'C1' | 'C2' | 'Post-C2';
|
|
2
2
|
export declare function getDifficultyLevel(difficulty: LanguageLevel): number;
|
|
3
3
|
export declare function getDifficultyLabel(difficulty: number): LanguageLevel;
|
|
4
4
|
export declare function getNeighborDifficultyLevel(difficulty: LanguageLevel, difficultyAdjustment: number): LanguageLevel;
|
package/dist/utils/endpoint.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const DEFAULT_ENDPOINT =
|
|
2
|
-
export const DEFAULT_ANON_KEY =
|
|
1
|
+
export const DEFAULT_ENDPOINT = 'https://pheptqdoqsdnadgoihvr.supabase.co';
|
|
2
|
+
export const DEFAULT_ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InBoZXB0cWRvcXNkbmFkZ29paHZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MzE2OTY2ODcsImV4cCI6MjA0NzI3MjY4N30.4GPFAXTF8685FaXISdAPNCIM-H3RGLo8GbyhQpu1mP0';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RimoriClient } from
|
|
1
|
+
import { RimoriClient } from '../plugin/RimoriClient';
|
|
2
2
|
/**
|
|
3
3
|
* Sets up the web worker for the plugin to be able receive and send messages to Rimori.
|
|
4
4
|
* @param pluginId - The id of the plugin to setup the worker for.
|
|
@@ -7,8 +7,8 @@ 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 { EventBusHandler } from
|
|
11
|
-
import { PluginController } from
|
|
10
|
+
import { EventBusHandler } from '../fromRimori/EventBus';
|
|
11
|
+
import { PluginController } from '../plugin/PluginController';
|
|
12
12
|
/**
|
|
13
13
|
* Sets up the web worker for the plugin to be able receive and send messages to Rimori.
|
|
14
14
|
* @param pluginId - The id of the plugin to setup the worker for.
|
|
@@ -21,17 +21,17 @@ export function setupWorker(pluginId, init) {
|
|
|
21
21
|
isWorker: true,
|
|
22
22
|
location: {},
|
|
23
23
|
parent: {
|
|
24
|
-
postMessage: () => { }
|
|
24
|
+
postMessage: () => { },
|
|
25
25
|
},
|
|
26
|
-
addEventListener: () => { }
|
|
26
|
+
addEventListener: () => { },
|
|
27
27
|
};
|
|
28
28
|
// Assign the mock to globalThis.
|
|
29
29
|
Object.assign(globalThis, { window: mockWindow });
|
|
30
|
-
EventBusHandler.getInstance(
|
|
30
|
+
EventBusHandler.getInstance('Worker EventBus');
|
|
31
31
|
const rimoriClient = yield PluginController.getInstance(pluginId);
|
|
32
32
|
console.debug('[Worker] RimoriClient initialized.');
|
|
33
33
|
yield init(rimoriClient);
|
|
34
34
|
console.debug('[Worker] Worker initialized.');
|
|
35
|
-
self.postMessage({ type:
|
|
35
|
+
self.postMessage({ type: 'rimori:acknowledged', pluginId: pluginId });
|
|
36
36
|
});
|
|
37
37
|
}
|
package/example/docs/devdocs.md
CHANGED
|
@@ -13,41 +13,44 @@ All communication uses the Rimori event bus with the pattern: `<plugin_id>.<area
|
|
|
13
13
|
### 1. Create Flashcards
|
|
14
14
|
|
|
15
15
|
#### Basic Creation
|
|
16
|
+
|
|
16
17
|
```javascript
|
|
17
18
|
// Create a simple flashcard
|
|
18
|
-
plugin.event.emit(
|
|
19
|
-
front:
|
|
20
|
-
back:
|
|
21
|
-
deckId:
|
|
22
|
-
frontTags: [
|
|
23
|
-
backTags: [
|
|
19
|
+
plugin.event.emit('pl123456789.flashcard.create', {
|
|
20
|
+
front: 'Hello',
|
|
21
|
+
back: 'Hola',
|
|
22
|
+
deckId: 'deck-123', // optional, uses default deck if omitted
|
|
23
|
+
frontTags: ['lang:en'],
|
|
24
|
+
backTags: ['lang:es'],
|
|
24
25
|
});
|
|
25
26
|
```
|
|
26
27
|
|
|
27
28
|
#### Language-based Creation
|
|
29
|
+
|
|
28
30
|
```javascript
|
|
29
31
|
// Create flashcard with automatic lookup
|
|
30
|
-
plugin.event.emit(
|
|
31
|
-
word:
|
|
32
|
-
language:
|
|
33
|
-
deckId:
|
|
32
|
+
plugin.event.emit('pl123456789.flashcard.createLangCard', {
|
|
33
|
+
word: 'perro',
|
|
34
|
+
language: 'es', // optional, uses user's mother tongue if omitted
|
|
35
|
+
deckId: 'spanish-nouns', // optional
|
|
34
36
|
});
|
|
35
37
|
```
|
|
36
38
|
|
|
37
39
|
### 2. Lookup Requests
|
|
38
40
|
|
|
39
41
|
#### Basic Translation
|
|
42
|
+
|
|
40
43
|
```javascript
|
|
41
44
|
// Request word translation
|
|
42
|
-
const translation = await plugin.event.request(
|
|
43
|
-
word:
|
|
44
|
-
language:
|
|
45
|
+
const translation = await plugin.event.request('pl123456789.lookup.requestBasic', {
|
|
46
|
+
word: 'laufen',
|
|
47
|
+
language: 'de', // optional
|
|
45
48
|
});
|
|
46
49
|
|
|
47
50
|
// Returns:
|
|
48
51
|
// {
|
|
49
52
|
// input: "laufen",
|
|
50
|
-
// language: "de",
|
|
53
|
+
// language: "de",
|
|
51
54
|
// type: "verb",
|
|
52
55
|
// swedish_translation: "att springa",
|
|
53
56
|
// translation: "to run"
|
|
@@ -55,11 +58,12 @@ const translation = await plugin.event.request("pl123456789.lookup.requestBasic"
|
|
|
55
58
|
```
|
|
56
59
|
|
|
57
60
|
#### Advanced Lookup
|
|
61
|
+
|
|
58
62
|
```javascript
|
|
59
63
|
// Get detailed word information
|
|
60
|
-
const details = await plugin.event.request(
|
|
61
|
-
word:
|
|
62
|
-
language:
|
|
64
|
+
const details = await plugin.event.request('pl123456789.lookup.request', {
|
|
65
|
+
word: 'laufen',
|
|
66
|
+
language: 'de',
|
|
63
67
|
});
|
|
64
68
|
|
|
65
69
|
// Returns extended object with grammar, examples, tenses, etc.
|
|
@@ -68,14 +72,15 @@ const details = await plugin.event.request("pl123456789.lookup.request", {
|
|
|
68
72
|
### 3. Deck Management
|
|
69
73
|
|
|
70
74
|
#### Get Available Decks
|
|
75
|
+
|
|
71
76
|
```javascript
|
|
72
|
-
const decks = await plugin.event.request(
|
|
77
|
+
const decks = await plugin.event.request('pl123456789.deck.requestOpenToday');
|
|
73
78
|
|
|
74
79
|
// Returns:
|
|
75
80
|
// [
|
|
76
81
|
// {
|
|
77
82
|
// id: "deck-123",
|
|
78
|
-
// name: "Spanish Vocabulary",
|
|
83
|
+
// name: "Spanish Vocabulary",
|
|
79
84
|
// total_new: 5,
|
|
80
85
|
// total_learning: 12,
|
|
81
86
|
// total_review: 8
|
|
@@ -84,9 +89,10 @@ const decks = await plugin.event.request("pl123456789.deck.requestOpenToday");
|
|
|
84
89
|
```
|
|
85
90
|
|
|
86
91
|
#### Create New Deck
|
|
92
|
+
|
|
87
93
|
```javascript
|
|
88
|
-
const newDeck = await plugin.event.request(
|
|
89
|
-
name:
|
|
94
|
+
const newDeck = await plugin.event.request('pl123456789.deck.create', {
|
|
95
|
+
name: 'German Verbs',
|
|
90
96
|
});
|
|
91
97
|
|
|
92
98
|
// Returns: { id: "deck-456", name: "German Verbs", last_used: "2025-01-06T..." }
|
|
@@ -95,35 +101,37 @@ const newDeck = await plugin.event.request("pl123456789.deck.create", {
|
|
|
95
101
|
### 4. Trigger Training
|
|
96
102
|
|
|
97
103
|
#### Open Flashcard Training
|
|
104
|
+
|
|
98
105
|
```javascript
|
|
99
106
|
// Open training in main panel
|
|
100
|
-
plugin.event.emit(
|
|
101
|
-
pluginId:
|
|
102
|
-
actionKey:
|
|
103
|
-
deck:
|
|
104
|
-
total_amount: 20 // or "default"
|
|
107
|
+
plugin.event.emit('global.mainPanel.triggerAction', {
|
|
108
|
+
pluginId: 'pl123456789',
|
|
109
|
+
actionKey: 'flashcards',
|
|
110
|
+
deck: 'latest', // or "random", "oldest", "mix", deck ID
|
|
111
|
+
total_amount: 20, // or "default"
|
|
105
112
|
});
|
|
106
113
|
```
|
|
107
114
|
|
|
108
115
|
## Worker Function Example
|
|
109
116
|
|
|
110
117
|
### Background Deck Sync
|
|
118
|
+
|
|
111
119
|
```javascript
|
|
112
120
|
// worker/listeners/deck-sync.ts
|
|
113
121
|
import { WorkerEventListener } from '@rimori/client';
|
|
114
122
|
|
|
115
123
|
export const deckSyncListener: WorkerEventListener = {
|
|
116
124
|
eventName: 'pl123456789.deck.syncProgress',
|
|
117
|
-
|
|
125
|
+
|
|
118
126
|
async handler(data: { userId: string; deckId: string }) {
|
|
119
127
|
const { userId, deckId } = data;
|
|
120
|
-
|
|
128
|
+
|
|
121
129
|
// Calculate learning statistics
|
|
122
130
|
const stats = await calculateDeckProgress(deckId, userId);
|
|
123
|
-
|
|
131
|
+
|
|
124
132
|
// Update user's learning streak
|
|
125
133
|
await updateLearningStreak(userId, stats);
|
|
126
|
-
|
|
134
|
+
|
|
127
135
|
// Send progress update to main thread
|
|
128
136
|
self.postMessage({
|
|
129
137
|
type: 'progress-updated',
|
|
@@ -143,10 +151,10 @@ async function calculateDeckProgress(deckId: string, userId: string) {
|
|
|
143
151
|
.select('*')
|
|
144
152
|
.eq('deck_id', deckId)
|
|
145
153
|
.eq('user_id', userId);
|
|
146
|
-
|
|
154
|
+
|
|
147
155
|
const reviewed = cards.filter(c => c.last_review_date >= getTodayStart());
|
|
148
156
|
const accuracy = reviewed.reduce((acc, c) => acc + c.ease_factor, 0) / reviewed.length;
|
|
149
|
-
|
|
157
|
+
|
|
150
158
|
return {
|
|
151
159
|
reviewed: reviewed.length,
|
|
152
160
|
accuracy: Math.round(accuracy * 100),
|
|
@@ -185,6 +193,7 @@ interface Deck {
|
|
|
185
193
|
## Integration Examples
|
|
186
194
|
|
|
187
195
|
### Dictionary Plugin → Flashcards
|
|
196
|
+
|
|
188
197
|
```javascript
|
|
189
198
|
// When user looks up a word in dictionary
|
|
190
199
|
function onWordLookup(word: string, translation: string) {
|
|
@@ -198,15 +207,16 @@ function onWordLookup(word: string, translation: string) {
|
|
|
198
207
|
}
|
|
199
208
|
```
|
|
200
209
|
|
|
201
|
-
### Study Planner → Flashcards
|
|
210
|
+
### Study Planner → Flashcards
|
|
211
|
+
|
|
202
212
|
```javascript
|
|
203
213
|
// Trigger daily flashcard session
|
|
204
214
|
function scheduleDailyReview() {
|
|
205
|
-
plugin.event.emit(
|
|
206
|
-
pluginId:
|
|
207
|
-
actionKey:
|
|
208
|
-
deck:
|
|
209
|
-
total_amount: 30
|
|
215
|
+
plugin.event.emit('global.mainPanel.triggerAction', {
|
|
216
|
+
pluginId: 'pl123456789',
|
|
217
|
+
actionKey: 'flashcards',
|
|
218
|
+
deck: 'mix',
|
|
219
|
+
total_amount: 30,
|
|
210
220
|
});
|
|
211
221
|
}
|
|
212
222
|
```
|
|
@@ -215,9 +225,9 @@ function scheduleDailyReview() {
|
|
|
215
225
|
|
|
216
226
|
```javascript
|
|
217
227
|
try {
|
|
218
|
-
await plugin.event.request(
|
|
228
|
+
await plugin.event.request('pl123456789.flashcard.create', cardData);
|
|
219
229
|
} catch (error) {
|
|
220
|
-
console.error(
|
|
230
|
+
console.error('Failed to create flashcard:', error);
|
|
221
231
|
// Handle error appropriately
|
|
222
232
|
}
|
|
223
233
|
```
|
package/example/docs/overview.md
CHANGED
|
@@ -9,7 +9,7 @@ Simple Flashcards uses proven spaced repetition algorithms to help you memorize
|
|
|
9
9
|
## 🎯 Perfect for
|
|
10
10
|
|
|
11
11
|
- **Language learners** building vocabulary with audio pronunciation
|
|
12
|
-
- **Students** memorizing facts, formulas, and definitions
|
|
12
|
+
- **Students** memorizing facts, formulas, and definitions
|
|
13
13
|
- **Professionals** learning technical terms and concepts
|
|
14
14
|
- **Anyone** who wants to remember information long-term
|
|
15
15
|
|
package/example/docs/userdocs.md
CHANGED
|
@@ -62,7 +62,7 @@ Speed up your review sessions with keyboard shortcuts that eliminate the need fo
|
|
|
62
62
|
- **Spacebar** - Reveal the answer when studying the front of a card
|
|
63
63
|
- **Number keys 1-4** - Rate your recall (Again, Hard, Good, Easy respectively)
|
|
64
64
|
- **5 key** - Play audio for the front of the card (if language tags are present)
|
|
65
|
-
- **h key** - Play audio for the back of the card (if language tags are present)
|
|
65
|
+
- **h key** - Play audio for the back of the card (if language tags are present)
|
|
66
66
|
- **v key** - Edit the current flashcard during review
|
|
67
67
|
|
|
68
68
|
These shortcuts allow you to maintain focus and rhythm during your learning sessions.
|
|
@@ -109,15 +109,18 @@ To get the most out of your flashcard learning:
|
|
|
109
109
|
## Troubleshooting Common Issues
|
|
110
110
|
|
|
111
111
|
**Audio not playing when expected?**
|
|
112
|
+
|
|
112
113
|
- Verify that your device volume is turned up and not muted
|
|
113
114
|
- Check that the flashcard has proper language tags (e.g., `lang:en` for English)
|
|
114
115
|
- Try refreshing the page if audio features seem unresponsive
|
|
115
116
|
|
|
116
117
|
**Flashcards not saving properly?**
|
|
118
|
+
|
|
117
119
|
- Ensure you have a stable internet connection for data synchronization
|
|
118
120
|
- Verify you clicked the save icon after entering card content
|
|
119
121
|
- Try creating the card again if the first attempt failed
|
|
120
122
|
|
|
121
123
|
**Progress not updating correctly?**
|
|
124
|
+
|
|
122
125
|
- Refresh the page to ensure you're seeing the latest data
|
|
123
126
|
- Check that you're rating cards rather than just viewing them
|
package/example/rimori.config.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RimoriPluginConfig } from
|
|
1
|
+
import { RimoriPluginConfig } from '@rimori/client';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* This is an example of a Rimori plugin configuration file. It is based on the Rimori Flashcards plugin.
|
|
@@ -6,84 +6,86 @@ import { RimoriPluginConfig } from "@rimori/client";
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
const config: RimoriPluginConfig = {
|
|
9
|
-
id:
|
|
9
|
+
id: 'pl1234567890', // This is the plugin id. You can find it in the plugin's package.json file.
|
|
10
10
|
info: {
|
|
11
|
-
title:
|
|
12
|
-
description:
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
title: 'Flashcards',
|
|
12
|
+
description:
|
|
13
|
+
"The Rimori Flashcards Plugin is a powerful tool for learning and memorization using spaced repetition. It helps you efficiently review information, whether you're learning a language, preparing for exams, or mastering new skills. The plugin uses advanced algorithms to schedule your reviews at optimal intervals, maximizing retention while minimizing study time.",
|
|
14
|
+
logo: 'logo.png',
|
|
15
|
+
website: 'https://rimori.se',
|
|
15
16
|
},
|
|
16
17
|
pages: {
|
|
17
18
|
main: [
|
|
18
19
|
{
|
|
19
|
-
id:
|
|
20
|
-
url:
|
|
20
|
+
id: '1',
|
|
21
|
+
url: '#/',
|
|
21
22
|
show: true,
|
|
22
|
-
name:
|
|
23
|
-
root:
|
|
24
|
-
description:
|
|
23
|
+
name: 'Flashcards',
|
|
24
|
+
root: 'vocabulary',
|
|
25
|
+
description: 'Quickly memorizing info by using flashcards.',
|
|
25
26
|
},
|
|
26
|
-
{
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
{
|
|
28
|
+
// This is a page that is not shown in the navbar. It is used to trigger the flashcards action.
|
|
29
|
+
id: '2',
|
|
30
|
+
url: '#/deck/custom',
|
|
29
31
|
show: false,
|
|
30
|
-
root:
|
|
31
|
-
name:
|
|
32
|
-
description:
|
|
32
|
+
root: 'vocabulary',
|
|
33
|
+
name: 'Latest flashcard deck training',
|
|
34
|
+
description: 'Training the latest flashcards.',
|
|
33
35
|
action: {
|
|
34
|
-
key:
|
|
36
|
+
key: 'flashcards',
|
|
35
37
|
parameters: {
|
|
36
38
|
total_amount: {
|
|
37
39
|
type: 'number',
|
|
38
|
-
description: 'Number of flashcards to practice. Default is 70 (10 new + 20 reviewed + 40 forgotten).'
|
|
40
|
+
description: 'Number of flashcards to practice. Default is 70 (10 new + 20 reviewed + 40 forgotten).',
|
|
39
41
|
},
|
|
40
42
|
deck: {
|
|
41
43
|
type: 'string',
|
|
42
44
|
enum: ['latest', 'random', 'oldest', 'mix', 'best_known'],
|
|
43
|
-
description: 'Type of deck to practice from'
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
45
|
+
description: 'Type of deck to practice from',
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
48
50
|
],
|
|
49
51
|
sidebar: [
|
|
50
52
|
{
|
|
51
|
-
id:
|
|
52
|
-
url:
|
|
53
|
-
name:
|
|
54
|
-
icon:
|
|
55
|
-
description:
|
|
53
|
+
id: 'translate',
|
|
54
|
+
url: '#/sidebar/translate',
|
|
55
|
+
name: 'Translate',
|
|
56
|
+
icon: 'translate.png',
|
|
57
|
+
description: 'Translate words.',
|
|
56
58
|
},
|
|
57
59
|
{
|
|
58
|
-
id:
|
|
59
|
-
url:
|
|
60
|
-
name:
|
|
61
|
-
icon:
|
|
62
|
-
description:
|
|
63
|
-
}
|
|
60
|
+
id: 'flashcard_quick_add',
|
|
61
|
+
url: '#/sidebar/add',
|
|
62
|
+
name: 'Quick add',
|
|
63
|
+
icon: 'logo.png',
|
|
64
|
+
description: 'Quickly add a word to your flashcards.',
|
|
65
|
+
},
|
|
64
66
|
],
|
|
65
|
-
settings:
|
|
67
|
+
settings: '/settings',
|
|
66
68
|
},
|
|
67
69
|
context_menu_actions: [
|
|
68
70
|
{
|
|
69
|
-
text:
|
|
70
|
-
plugin_id:
|
|
71
|
-
action_key:
|
|
71
|
+
text: 'Translate',
|
|
72
|
+
plugin_id: 'pl1234567890',
|
|
73
|
+
action_key: 'translate',
|
|
72
74
|
},
|
|
73
75
|
{
|
|
74
|
-
text:
|
|
75
|
-
plugin_id:
|
|
76
|
-
action_key:
|
|
77
|
-
}
|
|
76
|
+
text: 'Quick add',
|
|
77
|
+
plugin_id: 'pl1234567890',
|
|
78
|
+
action_key: 'flashcard_quick_add',
|
|
79
|
+
},
|
|
78
80
|
],
|
|
79
81
|
documentation: {
|
|
80
|
-
overview_path:
|
|
81
|
-
user_path:
|
|
82
|
-
developer_path:
|
|
82
|
+
overview_path: 'docs/overview.md',
|
|
83
|
+
user_path: 'docs/userdocs.md',
|
|
84
|
+
developer_path: 'docs/devdocs.md',
|
|
83
85
|
},
|
|
84
86
|
worker: {
|
|
85
|
-
url:
|
|
86
|
-
}
|
|
87
|
+
url: 'web-worker.js',
|
|
88
|
+
},
|
|
87
89
|
};
|
|
88
90
|
|
|
89
|
-
export default config;
|
|
91
|
+
export default config;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { defineConfig } from 'vite'
|
|
2
|
-
import path from 'path'
|
|
1
|
+
import { defineConfig } from 'vite';
|
|
2
|
+
import path from 'path';
|
|
3
3
|
|
|
4
4
|
export default defineConfig({
|
|
5
5
|
root: __dirname,
|
|
@@ -20,4 +20,4 @@ export default defineConfig({
|
|
|
20
20
|
},
|
|
21
21
|
},
|
|
22
22
|
},
|
|
23
|
-
})
|
|
23
|
+
});
|
package/example/worker/worker.ts
CHANGED
|
@@ -4,8 +4,8 @@ setupWorker(async (client: RimoriClient) => {
|
|
|
4
4
|
console.log('[Worker] initialized');
|
|
5
5
|
|
|
6
6
|
// listening to events for this plugin to create flashcards
|
|
7
|
-
client.event.respond<{ front: string
|
|
7
|
+
client.event.respond<{ front: string; back: string }>('flashcards.create', ({ data }) => {
|
|
8
8
|
console.log('[Worker] creating flashcards in database', data);
|
|
9
9
|
return { success: true };
|
|
10
10
|
});
|
|
11
|
-
});
|
|
11
|
+
});
|