@rimori/react-client 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/.prettierignore +35 -0
  2. package/LICENSE +201 -0
  3. package/README copy.md +1216 -0
  4. package/README.md +1 -0
  5. package/dist/components/MarkdownEditor.d.ts +8 -0
  6. package/dist/components/MarkdownEditor.js +48 -0
  7. package/dist/components/Spinner.d.ts +8 -0
  8. package/dist/components/Spinner.js +4 -0
  9. package/dist/components/ai/Assistant.d.ts +9 -0
  10. package/dist/components/ai/Assistant.js +58 -0
  11. package/dist/components/ai/Avatar.d.ts +14 -0
  12. package/dist/components/ai/Avatar.js +59 -0
  13. package/dist/components/ai/EmbeddedAssistent/AudioInputField.d.ts +7 -0
  14. package/dist/components/ai/EmbeddedAssistent/AudioInputField.js +37 -0
  15. package/dist/components/ai/EmbeddedAssistent/CircleAudioAvatar.d.ts +8 -0
  16. package/dist/components/ai/EmbeddedAssistent/CircleAudioAvatar.js +79 -0
  17. package/dist/components/ai/EmbeddedAssistent/TTS/MessageSender.d.ts +19 -0
  18. package/dist/components/ai/EmbeddedAssistent/TTS/MessageSender.js +91 -0
  19. package/dist/components/ai/EmbeddedAssistent/TTS/Player.d.ts +27 -0
  20. package/dist/components/ai/EmbeddedAssistent/TTS/Player.js +185 -0
  21. package/dist/components/ai/EmbeddedAssistent/VoiceRecoder.d.ts +11 -0
  22. package/dist/components/ai/EmbeddedAssistent/VoiceRecoder.js +95 -0
  23. package/dist/components/ai/utils.d.ts +6 -0
  24. package/dist/components/ai/utils.js +13 -0
  25. package/dist/components/audio/Playbutton.d.ts +15 -0
  26. package/dist/components/audio/Playbutton.js +80 -0
  27. package/dist/components/components/ContextMenu.d.ts +10 -0
  28. package/dist/components/components/ContextMenu.js +135 -0
  29. package/dist/hooks/I18nHooks.d.ts +11 -0
  30. package/dist/hooks/I18nHooks.js +25 -0
  31. package/dist/hooks/UseChatHook.d.ts +10 -0
  32. package/dist/hooks/UseChatHook.js +29 -0
  33. package/dist/providers/PluginProvider.d.ts +11 -0
  34. package/dist/providers/PluginProvider.js +142 -0
  35. package/dist/react-client/plugin/ThemeSetter.d.ts +2 -0
  36. package/dist/react-client/plugin/ThemeSetter.js +19 -0
  37. package/dist/react-client/src/components/ContextMenu.d.ts +10 -0
  38. package/dist/react-client/src/components/ContextMenu.js +135 -0
  39. package/dist/react-client/src/components/MarkdownEditor.d.ts +8 -0
  40. package/dist/react-client/src/components/MarkdownEditor.js +48 -0
  41. package/dist/react-client/src/components/Spinner.d.ts +8 -0
  42. package/dist/react-client/src/components/Spinner.js +4 -0
  43. package/dist/react-client/src/components/ai/Assistant.d.ts +9 -0
  44. package/dist/react-client/src/components/ai/Assistant.js +58 -0
  45. package/dist/react-client/src/components/ai/Avatar.d.ts +14 -0
  46. package/dist/react-client/src/components/ai/Avatar.js +59 -0
  47. package/dist/react-client/src/components/ai/EmbeddedAssistent/AudioInputField.d.ts +7 -0
  48. package/dist/react-client/src/components/ai/EmbeddedAssistent/AudioInputField.js +37 -0
  49. package/dist/react-client/src/components/ai/EmbeddedAssistent/CircleAudioAvatar.d.ts +8 -0
  50. package/dist/react-client/src/components/ai/EmbeddedAssistent/CircleAudioAvatar.js +79 -0
  51. package/dist/react-client/src/components/ai/EmbeddedAssistent/TTS/MessageSender.d.ts +19 -0
  52. package/dist/react-client/src/components/ai/EmbeddedAssistent/TTS/MessageSender.js +91 -0
  53. package/dist/react-client/src/components/ai/EmbeddedAssistent/TTS/Player.d.ts +27 -0
  54. package/dist/react-client/src/components/ai/EmbeddedAssistent/TTS/Player.js +185 -0
  55. package/dist/react-client/src/components/ai/EmbeddedAssistent/VoiceRecoder.d.ts +11 -0
  56. package/dist/react-client/src/components/ai/EmbeddedAssistent/VoiceRecoder.js +95 -0
  57. package/dist/react-client/src/components/ai/utils.d.ts +6 -0
  58. package/dist/react-client/src/components/ai/utils.js +13 -0
  59. package/dist/react-client/src/components/audio/Playbutton.d.ts +15 -0
  60. package/dist/react-client/src/components/audio/Playbutton.js +82 -0
  61. package/dist/react-client/src/components/components/ContextMenu.d.ts +10 -0
  62. package/dist/react-client/src/components/components/ContextMenu.js +135 -0
  63. package/dist/react-client/src/hooks/I18nHooks.d.ts +11 -0
  64. package/dist/react-client/src/hooks/I18nHooks.js +25 -0
  65. package/dist/react-client/src/hooks/UseChatHook.d.ts +10 -0
  66. package/dist/react-client/src/hooks/UseChatHook.js +29 -0
  67. package/dist/react-client/src/plugin/ThemeSetter.d.ts +2 -0
  68. package/dist/react-client/src/plugin/ThemeSetter.js +19 -0
  69. package/dist/react-client/src/providers/PluginProvider.d.ts +12 -0
  70. package/dist/react-client/src/providers/PluginProvider.js +142 -0
  71. package/dist/react-client/src/utils/FullscreenUtils.d.ts +2 -0
  72. package/dist/react-client/src/utils/FullscreenUtils.js +23 -0
  73. package/dist/react-client/src/utils/PluginUtils.d.ts +2 -0
  74. package/dist/react-client/src/utils/PluginUtils.js +23 -0
  75. package/dist/rimori-client/src/cli/types/DatabaseTypes.d.ts +103 -0
  76. package/dist/rimori-client/src/cli/types/DatabaseTypes.js +2 -0
  77. package/dist/rimori-client/src/controller/AIController.d.ts +15 -0
  78. package/dist/rimori-client/src/controller/AIController.js +255 -0
  79. package/dist/rimori-client/src/controller/AccomplishmentController.d.ts +38 -0
  80. package/dist/rimori-client/src/controller/AccomplishmentController.js +112 -0
  81. package/dist/rimori-client/src/controller/AudioController.d.ts +37 -0
  82. package/dist/rimori-client/src/controller/AudioController.js +68 -0
  83. package/dist/rimori-client/src/controller/ExerciseController.d.ts +54 -0
  84. package/dist/rimori-client/src/controller/ExerciseController.js +74 -0
  85. package/dist/rimori-client/src/controller/ObjectController.d.ts +42 -0
  86. package/dist/rimori-client/src/controller/ObjectController.js +76 -0
  87. package/dist/rimori-client/src/controller/SettingsController.d.ts +79 -0
  88. package/dist/rimori-client/src/controller/SettingsController.js +118 -0
  89. package/dist/rimori-client/src/controller/SharedContentController.d.ts +106 -0
  90. package/dist/rimori-client/src/controller/SharedContentController.js +285 -0
  91. package/dist/rimori-client/src/controller/TranslationController.d.ts +38 -0
  92. package/dist/rimori-client/src/controller/TranslationController.js +106 -0
  93. package/dist/rimori-client/src/controller/VoiceController.d.ts +9 -0
  94. package/dist/rimori-client/src/controller/VoiceController.js +37 -0
  95. package/dist/rimori-client/src/fromRimori/EventBus.d.ts +101 -0
  96. package/dist/rimori-client/src/fromRimori/EventBus.js +263 -0
  97. package/dist/rimori-client/src/fromRimori/PluginTypes.d.ts +174 -0
  98. package/dist/rimori-client/src/fromRimori/PluginTypes.js +1 -0
  99. package/dist/rimori-client/src/index.d.ts +11 -0
  100. package/dist/rimori-client/src/index.js +10 -0
  101. package/dist/rimori-client/src/plugin/CommunicationHandler.d.ts +48 -0
  102. package/dist/rimori-client/src/plugin/CommunicationHandler.js +234 -0
  103. package/dist/rimori-client/src/plugin/Logger.d.ts +73 -0
  104. package/dist/rimori-client/src/plugin/Logger.js +308 -0
  105. package/dist/rimori-client/src/plugin/RimoriClient.d.ts +258 -0
  106. package/dist/rimori-client/src/plugin/RimoriClient.js +375 -0
  107. package/dist/rimori-client/src/plugin/StandaloneClient.d.ts +17 -0
  108. package/dist/rimori-client/src/plugin/StandaloneClient.js +115 -0
  109. package/dist/rimori-client/src/utils/difficultyConverter.d.ts +4 -0
  110. package/dist/rimori-client/src/utils/difficultyConverter.js +10 -0
  111. package/dist/rimori-client/src/utils/endpoint.d.ts +2 -0
  112. package/dist/rimori-client/src/utils/endpoint.js +2 -0
  113. package/dist/style.css +110 -0
  114. package/dist/style.css.map +1 -0
  115. package/dist/utils/PluginUtils.d.ts +2 -0
  116. package/dist/utils/PluginUtils.js +23 -0
  117. package/eslint.config.js +53 -0
  118. package/index.ts +6 -0
  119. package/package.json +47 -0
  120. package/prettier.config.js +8 -0
  121. package/src/components/ContextMenu.tsx +177 -0
  122. package/src/components/MarkdownEditor.tsx +144 -0
  123. package/src/components/Spinner.tsx +29 -0
  124. package/src/components/ai/Assistant.tsx +96 -0
  125. package/src/components/ai/Avatar.tsx +99 -0
  126. package/src/components/ai/EmbeddedAssistent/AudioInputField.tsx +73 -0
  127. package/src/components/ai/EmbeddedAssistent/CircleAudioAvatar.tsx +107 -0
  128. package/src/components/ai/EmbeddedAssistent/TTS/MessageSender.ts +96 -0
  129. package/src/components/ai/EmbeddedAssistent/TTS/Player.ts +197 -0
  130. package/src/components/ai/EmbeddedAssistent/VoiceRecoder.tsx +129 -0
  131. package/src/components/ai/utils.ts +21 -0
  132. package/src/components/audio/Playbutton.tsx +126 -0
  133. package/src/hooks/I18nHooks.ts +33 -0
  134. package/src/hooks/UseChatHook.ts +38 -0
  135. package/src/plugin/ThemeSetter.ts +23 -0
  136. package/src/providers/PluginProvider.tsx +197 -0
  137. package/src/style.scss +136 -0
  138. package/src/utils/FullscreenUtils.ts +22 -0
  139. package/tsconfig.json +23 -0
@@ -0,0 +1,197 @@
1
+ import React, { createContext, useContext, ReactNode, useEffect, useState } from 'react';
2
+ import { EventBusHandler, RimoriClient, StandaloneClient } from '@rimori/client';
3
+ import ContextMenu from '../components/ContextMenu';
4
+
5
+ interface PluginProviderProps {
6
+ children: ReactNode;
7
+ pluginId: string;
8
+ settings?: {
9
+ disableContextMenu?: boolean;
10
+ };
11
+ }
12
+
13
+ const PluginContext = createContext<RimoriClient | null>(null);
14
+
15
+ export const PluginProvider: React.FC<PluginProviderProps> = ({ children, pluginId, settings }) => {
16
+ const [plugin, setPlugin] = useState<RimoriClient | null>(null);
17
+ const [standaloneClient, setStandaloneClient] = useState<StandaloneClient | boolean>(false);
18
+ const [applicationMode, setApplicationMode] = useState<string | null>(null);
19
+ const [theme, setTheme] = useState<string | null>(null);
20
+
21
+ const isSidebar = applicationMode === 'sidebar';
22
+ const isSettings = applicationMode === 'settings';
23
+
24
+ useEffect(() => {
25
+ initEventBus(pluginId);
26
+
27
+ // Check if we're in an iframe context - if not, we're standalone
28
+ const standaloneDetected = window === window.parent;
29
+
30
+ if (standaloneDetected && !standaloneClient) {
31
+ StandaloneClient.getInstance().then((client) => {
32
+ client.needsLogin().then((needLogin) => setStandaloneClient(needLogin ? client : true));
33
+ });
34
+ }
35
+
36
+ if ((!standaloneDetected && !plugin) || (standaloneDetected && standaloneClient === true)) {
37
+ RimoriClient.getInstance(pluginId).then((client) => {
38
+ setPlugin(client);
39
+ // Get applicationMode and theme from MessageChannel query params
40
+ if (!standaloneDetected) {
41
+ const mode = client.getQueryParam('applicationMode');
42
+ const themeParam = client.getQueryParam('rm_theme');
43
+ setApplicationMode(mode);
44
+ setTheme(themeParam);
45
+ }
46
+ });
47
+ }
48
+ }, [pluginId, standaloneClient]);
49
+
50
+ //route change
51
+ useEffect(() => {
52
+ if (!plugin) return;
53
+
54
+ //sidebar pages should not report url changes
55
+ if (isSidebar) return;
56
+
57
+ let lastHash = window.location.hash;
58
+ const emitUrlChange = (url: string) => plugin.event.emit('session.triggerUrlChange', { url });
59
+
60
+ const interval = setInterval(() => {
61
+ if (lastHash === window.location.hash) return;
62
+ lastHash = window.location.hash;
63
+ // console.log('url changed:', lastHash);
64
+ emitUrlChange(lastHash);
65
+ }, 1000);
66
+
67
+ emitUrlChange(lastHash);
68
+ return () => clearInterval(interval);
69
+ }, [plugin]);
70
+
71
+ if (standaloneClient instanceof StandaloneClient) {
72
+ return (
73
+ <StandaloneAuth
74
+ onLogin={async (email, password) => {
75
+ if (await standaloneClient.login(email, password)) setStandaloneClient(true);
76
+ }}
77
+ />
78
+ );
79
+ }
80
+
81
+ if (!plugin) {
82
+ return '';
83
+ }
84
+
85
+ return (
86
+ <PluginContext.Provider value={plugin}>
87
+ {!settings?.disableContextMenu && !isSidebar && !isSettings && <ContextMenu client={plugin} />}
88
+ {children}
89
+ </PluginContext.Provider>
90
+ );
91
+ };
92
+
93
+ export const useRimori = () => {
94
+ const context = useContext(PluginContext);
95
+ if (context === null) {
96
+ throw new Error('useRimori must be used within an PluginProvider');
97
+ }
98
+ return context;
99
+ };
100
+
101
+ function getUrlParam(name: string) {
102
+ // First try to get from URL hash query params (for compatibility)
103
+ const hashParts = window.location.hash.split('?');
104
+ if (hashParts.length > 1) {
105
+ const hashParams = new URLSearchParams(hashParts[1]);
106
+ const hashValue = hashParams.get(name);
107
+ if (hashValue) return hashValue;
108
+ }
109
+
110
+ // Fallback to regular URL search params
111
+ const url = new URL(window.location.href);
112
+ return url.searchParams.get(name);
113
+ }
114
+
115
+ function initEventBus(pluginId: string) {
116
+ // For now, use URL fallback for EventBus naming - this will be updated once MessageChannel is ready
117
+ const isSidebar = getUrlParam('applicationMode') === 'sidebar';
118
+ EventBusHandler.getInstance('Plugin EventBus ' + pluginId + ' ' + (isSidebar ? 'sidebar' : 'main'));
119
+ }
120
+
121
+ function StandaloneAuth({ onLogin }: { onLogin: (user: string, password: string) => void }) {
122
+ const [user, setUser] = useState('');
123
+ const [password, setPassword] = useState('');
124
+ return (
125
+ <div
126
+ style={{
127
+ position: 'fixed',
128
+ inset: 0,
129
+ display: 'flex',
130
+ alignItems: 'center',
131
+ justifyContent: 'center',
132
+ backgroundColor: 'rgba(0, 0, 0, 0.5)',
133
+ }}
134
+ >
135
+ <div
136
+ style={{
137
+ backgroundColor: '#343534',
138
+ padding: '1rem',
139
+ borderRadius: '0.5rem',
140
+ width: '500px',
141
+ flexDirection: 'column',
142
+ display: 'flex',
143
+ alignItems: 'center',
144
+ justifyContent: 'center',
145
+ }}
146
+ >
147
+ <p style={{ fontSize: '2rem', fontWeight: 'bold', marginBottom: '1rem', textAlign: 'center' }}>Rimori Login</p>
148
+ <p style={{ marginBottom: '1rem', textAlign: 'center' }}>
149
+ Please login with your Rimori developer account for this plugin to be able to access the Rimori platform the
150
+ same it will operate in the Rimori platform.
151
+ </p>
152
+ {/* email and password input */}
153
+ <input
154
+ style={{
155
+ marginBottom: '1rem',
156
+ width: '100%',
157
+ padding: '0.5rem',
158
+ borderRadius: '0.5rem',
159
+ border: 'none',
160
+ backgroundColor: '#444444',
161
+ }}
162
+ type="email"
163
+ placeholder="Email"
164
+ onChange={(e) => setUser(e.target.value)}
165
+ />
166
+ <input
167
+ style={{
168
+ marginBottom: '1rem',
169
+ width: '100%',
170
+ padding: '0.5rem',
171
+ borderRadius: '0.5rem',
172
+ border: 'none',
173
+ backgroundColor: '#444444',
174
+ }}
175
+ type="password"
176
+ placeholder="Password"
177
+ onChange={(e) => setPassword(e.target.value)}
178
+ />
179
+ <button
180
+ style={{
181
+ marginBottom: '1rem',
182
+ width: '100%',
183
+ padding: '0.5rem',
184
+ borderRadius: '0.5rem',
185
+ border: 'none',
186
+ backgroundColor: '#928358',
187
+ }}
188
+ onClick={() => {
189
+ onLogin(user, password);
190
+ }}
191
+ >
192
+ Login
193
+ </button>
194
+ </div>
195
+ </div>
196
+ );
197
+ }
package/src/style.scss ADDED
@@ -0,0 +1,136 @@
1
+ dialog::backdrop {
2
+ backdrop-filter: blur(2px);
3
+ // background: rgb(255, 255, 255, 0.5);
4
+ }
5
+
6
+ .dark * dialog::backdrop {
7
+ background: transparent;
8
+ }
9
+
10
+ .tiptap {
11
+ padding-top: 5px;
12
+ padding-left: 7px;
13
+ /* min-height: 300px; */
14
+
15
+ &:focus-visible {
16
+ outline: none;
17
+ }
18
+
19
+ h1,
20
+ h2,
21
+ h3,
22
+ h4,
23
+ h5,
24
+ h6 {
25
+ @apply font-bold;
26
+ margin-bottom: 1rem;
27
+ }
28
+
29
+ h1 {
30
+ @apply text-4xl;
31
+ }
32
+
33
+ h2 {
34
+ @apply text-3xl;
35
+ }
36
+
37
+ h3 {
38
+ @apply text-2xl;
39
+ }
40
+
41
+ h4 {
42
+ @apply text-xl;
43
+ }
44
+
45
+ h5 {
46
+ @apply text-lg;
47
+ }
48
+
49
+ h6 {
50
+ @apply text-base;
51
+ }
52
+
53
+ p {
54
+ @apply mb-4;
55
+ }
56
+
57
+ a {
58
+ @apply text-blue-600 hover:text-blue-800;
59
+ text-decoration: none;
60
+ }
61
+
62
+ a:hover {
63
+ @apply underline;
64
+ }
65
+
66
+ ul {
67
+ @apply list-disc pl-8;
68
+
69
+ li > p {
70
+ @apply mb-1;
71
+ }
72
+ }
73
+
74
+ ol {
75
+ @apply list-decimal pl-7;
76
+
77
+ li > p {
78
+ @apply mb-1;
79
+ }
80
+ }
81
+
82
+ blockquote {
83
+ @apply border-l-4 pl-4 italic text-gray-600 my-4;
84
+ border-color: #ccc;
85
+ }
86
+
87
+ code {
88
+ font-family: monospace;
89
+ }
90
+
91
+ pre {
92
+ @apply bg-gray-800 text-gray-500 p-4 rounded-lg overflow-x-auto;
93
+ font-family: monospace;
94
+ white-space: pre-wrap;
95
+ word-wrap: break-word;
96
+ }
97
+
98
+ img {
99
+ @apply max-w-full h-auto rounded-lg my-4;
100
+ }
101
+
102
+ table {
103
+ @apply table-auto w-full border-collapse mb-4;
104
+ }
105
+
106
+ th,
107
+ td {
108
+ @apply border px-4 py-2 text-left;
109
+ }
110
+
111
+ th {
112
+ @apply bg-gray-500 font-semibold;
113
+ }
114
+
115
+ tr:nth-child(even) {
116
+ @apply bg-gray-400;
117
+ }
118
+
119
+ @media (max-width: 768px) {
120
+ h1 {
121
+ @apply text-3xl;
122
+ }
123
+
124
+ h2 {
125
+ @apply text-2xl;
126
+ }
127
+
128
+ p {
129
+ @apply text-base;
130
+ }
131
+
132
+ img {
133
+ @apply max-w-full;
134
+ }
135
+ }
136
+ }
@@ -0,0 +1,22 @@
1
+ export function isFullscreen() {
2
+ return !!document.fullscreenElement;
3
+ }
4
+
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
+ }
21
+ onStateChange(isFullscreen());
22
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "outDir": "dist",
4
+ "module": "ESNext",
5
+ "target": "ES6",
6
+ "declaration": true,
7
+ "jsx": "react-jsx",
8
+ "moduleResolution": "node",
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "strict": true,
12
+ "baseUrl": ".",
13
+ "paths": {
14
+ "@rimori/client": [
15
+ "../rimori-client/src/index.ts"
16
+ ],
17
+ "@rimori/client/*": [
18
+ "../rimori-client/src/*"
19
+ ]
20
+ }
21
+ },
22
+ "include": ["src/**/*"]
23
+ }