@rimori/react-client 0.4.2 → 0.4.3-next.1

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.
@@ -126,6 +126,6 @@ const ContextMenu = ({ client }) => {
126
126
  } }, index))) }));
127
127
  };
128
128
  function MenuEntryItem(props) {
129
- return (_jsxs("button", { onClick: props.onClick, className: "px-4 py-2 text-left hover:bg-gray-500 dark:hover:bg-gray-600 w-full flex flex-row", children: [_jsx("span", { className: "flex-grow", children: props.iconUrl && _jsx("img", { src: props.iconUrl, alt: props.text, className: "w-4 h-4 mr-2" }) }), _jsx("span", { className: "flex-grow", children: props.text })] }));
129
+ return (_jsxs("button", { onClick: props.onClick, className: "px-2 md:px-4 py-2 text-left hover:bg-gray-500 dark:hover:bg-gray-600 w-full flex flex-row", children: [props.iconUrl && (_jsx("span", { className: "flex-grow", children: _jsx("img", { src: props.iconUrl, alt: props.text, className: "w-4 h-4 mr-2" }) })), _jsx("span", { className: "flex-grow", children: props.text })] }));
130
130
  }
131
131
  export default ContextMenu;
@@ -6,14 +6,14 @@ import { CircleAudioAvatar } from './EmbeddedAssistent/CircleAudioAvatar';
6
6
  import { useChat } from '../../hooks/UseChatHook';
7
7
  import { useRimori } from '../../providers/PluginProvider';
8
8
  import { getFirstMessages } from './utils';
9
- import { isDarkTheme } from '../../hooks/ThemeSetter';
9
+ import { useTheme } from '../../hooks/ThemeSetter';
10
10
  export function Avatar({ avatarImageUrl, voiceId, agentTools, autoStartConversation, children, circleSize = '300px', className, }) {
11
- const { ai, event } = useRimori();
11
+ const { ai, event, plugin } = useRimori();
12
+ const { isDark: isDarkThemeValue } = useTheme(plugin.theme);
12
13
  const [agentReplying, setAgentReplying] = useState(false);
13
14
  const [isProcessingMessage, setIsProcessingMessage] = useState(false);
14
15
  const sender = useMemo(() => new MessageSender(ai.getVoice, voiceId), [voiceId]);
15
16
  const { messages, append, isLoading, lastMessage, setMessages } = useChat(agentTools);
16
- const isDarkThemeValue = useMemo(() => isDarkTheme(), []);
17
17
  useEffect(() => {
18
18
  console.log('messages', messages);
19
19
  }, [messages]);
@@ -1,2 +1,5 @@
1
- export declare function useTheme(theme?: string | null): boolean;
2
- export declare function isDarkTheme(theme?: string | null): boolean;
1
+ import { Theme } from '@rimori/client';
2
+ export declare function useTheme(theme?: Theme): {
3
+ isDark: boolean;
4
+ theme: Theme;
5
+ };
@@ -1,31 +1,13 @@
1
- import { useEffect, useState } from 'react';
2
- export function useTheme(theme) {
3
- const [isDark, setIsDark] = useState(false);
4
- useEffect(() => {
5
- const root = document.documentElement;
6
- const nextIsDark = isDarkTheme(theme);
7
- setIsDark(nextIsDark);
8
- root.classList.add('dark:text-gray-200');
9
- if (nextIsDark) {
10
- root.setAttribute('data-theme', 'dark');
11
- root.classList.add('dark', 'dark:bg-gray-950');
12
- root.style.background = 'hsl(var(--background))';
13
- return;
14
- }
15
- root.removeAttribute('data-theme');
16
- root.classList.remove('dark', 'dark:bg-gray-950');
17
- root.style.background = '';
18
- }, [theme]);
19
- return isDark;
1
+ export function useTheme(theme = 'system') {
2
+ const isDark = theme === 'system' ? systenUsesDarkMode() : theme === 'dark';
3
+ const dom = document.documentElement;
4
+ dom.style.background = 'hsl(var(--background))';
5
+ dom.classList.add('text-gray-900', 'dark:text-gray-200', 'bg-gray-50', 'dark:bg-gray-950');
6
+ const root = document.querySelector('#root');
7
+ root.style.background = 'hsl(var(--background))';
8
+ dom.classList[isDark ? 'add' : 'remove']('dark');
9
+ return { isDark, theme };
20
10
  }
21
- export function isDarkTheme(theme) {
22
- // If no theme provided, try to get from URL as fallback (for standalone mode)
23
- if (!theme) {
24
- const urlParams = new URLSearchParams(window.location.search);
25
- theme = urlParams.get('theme');
26
- }
27
- if (!theme || theme === 'system') {
28
- return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
29
- }
30
- return theme === 'dark';
11
+ function systenUsesDarkMode() {
12
+ return window.matchMedia('(prefers-color-scheme: dark)').matches;
31
13
  }
@@ -17,7 +17,7 @@ export const PluginProvider = ({ children, pluginId, settings }) => {
17
17
  const [client, setClient] = useState(null);
18
18
  const [standaloneClient, setStandaloneClient] = useState(false);
19
19
  const [applicationMode, setApplicationMode] = useState(null);
20
- const [theme, setTheme] = useState(null);
20
+ const [theme, setTheme] = useState(undefined);
21
21
  const [userInfo, setUserInfo] = useState(null);
22
22
  useTheme(theme);
23
23
  const isSidebar = applicationMode === 'sidebar';
@@ -38,10 +38,8 @@ export const PluginProvider = ({ children, pluginId, settings }) => {
38
38
  setUserInfo(client.plugin.getUserInfo());
39
39
  // Get applicationMode and theme from MessageChannel query params
40
40
  if (!standaloneDetected) {
41
- const mode = client.getQueryParam('applicationMode');
42
- const themeParam = client.getQueryParam('rm_theme');
43
- setApplicationMode(mode);
44
- setTheme(themeParam);
41
+ setTheme(client.plugin.theme);
42
+ setApplicationMode(client.plugin.applicationMode);
45
43
  client.event.emit('self.rimori.triggerInitFinished');
46
44
  }
47
45
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rimori/react-client",
3
- "version": "0.4.2",
3
+ "version": "0.4.3-next.1",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -23,7 +23,7 @@
23
23
  "format": "prettier --write ."
24
24
  },
25
25
  "peerDependencies": {
26
- "@rimori/client": "^2.5.3",
26
+ "@rimori/client": "2.5.5-next.3",
27
27
  "react": "^18.1.0",
28
28
  "react-dom": "^18.1.0"
29
29
  },
@@ -34,7 +34,7 @@
34
34
  },
35
35
  "devDependencies": {
36
36
  "@eslint/js": "^9.37.0",
37
- "@rimori/client": "^2.5.3",
37
+ "@rimori/client": "2.5.5-next.3",
38
38
  "@types/react": "^18.3.21",
39
39
  "eslint-config-prettier": "^10.1.8",
40
40
  "eslint-plugin-prettier": "^5.5.4",
@@ -161,11 +161,13 @@ function MenuEntryItem(props: { iconUrl?: string; text: string; onClick: () => v
161
161
  return (
162
162
  <button
163
163
  onClick={props.onClick}
164
- className="px-4 py-2 text-left hover:bg-gray-500 dark:hover:bg-gray-600 w-full flex flex-row"
164
+ className="px-2 md:px-4 py-2 text-left hover:bg-gray-500 dark:hover:bg-gray-600 w-full flex flex-row"
165
165
  >
166
- <span className="flex-grow">
167
- {props.iconUrl && <img src={props.iconUrl} alt={props.text} className="w-4 h-4 mr-2" />}
168
- </span>
166
+ {props.iconUrl && (
167
+ <span className="flex-grow">
168
+ <img src={props.iconUrl} alt={props.text} className="w-4 h-4 mr-2" />
169
+ </span>
170
+ )}
169
171
  <span className="flex-grow">{props.text}</span>
170
172
  {/* <span className="text-sm">Ctrl+Shift+xxxx</span> */}
171
173
  </button>
@@ -7,7 +7,7 @@ import { useChat } from '../../hooks/UseChatHook';
7
7
  import { useRimori } from '../../providers/PluginProvider';
8
8
  import { getFirstMessages } from './utils';
9
9
  import { FirstMessages } from './utils';
10
- import { isDarkTheme } from '../../hooks/ThemeSetter';
10
+ import { useTheme } from '../../hooks/ThemeSetter';
11
11
 
12
12
  interface Props {
13
13
  voiceId: string;
@@ -28,12 +28,12 @@ export function Avatar({
28
28
  circleSize = '300px',
29
29
  className,
30
30
  }: Props) {
31
- const { ai, event } = useRimori();
31
+ const { ai, event, plugin } = useRimori();
32
+ const { isDark: isDarkThemeValue } = useTheme(plugin.theme);
32
33
  const [agentReplying, setAgentReplying] = useState(false);
33
34
  const [isProcessingMessage, setIsProcessingMessage] = useState(false);
34
35
  const sender = useMemo(() => new MessageSender(ai.getVoice, voiceId), [voiceId]);
35
36
  const { messages, append, isLoading, lastMessage, setMessages } = useChat(agentTools);
36
- const isDarkThemeValue = useMemo(() => isDarkTheme(), []);
37
37
 
38
38
  useEffect(() => {
39
39
  console.log('messages', messages);
@@ -1,40 +1,20 @@
1
- import { useEffect, useState } from 'react';
1
+ import { Theme } from '@rimori/client';
2
2
 
3
- export function useTheme(theme?: string | null): boolean {
4
- const [isDark, setIsDark] = useState(false);
3
+ export function useTheme(theme: Theme = 'system'): { isDark: boolean; theme: Theme } {
4
+ const isDark = theme === 'system' ? systenUsesDarkMode() : theme === 'dark';
5
5
 
6
- useEffect(() => {
7
- const root = document.documentElement;
8
- const nextIsDark = isDarkTheme(theme);
6
+ const dom = document.documentElement;
7
+ dom.style.background = 'hsl(var(--background))';
8
+ dom.classList.add('text-gray-900', 'dark:text-gray-200', 'bg-gray-50', 'dark:bg-gray-950');
9
9
 
10
- setIsDark(nextIsDark);
11
- root.classList.add('dark:text-gray-200');
10
+ const root = document.querySelector('#root') as HTMLDivElement;
11
+ root.style.background = 'hsl(var(--background))';
12
12
 
13
- if (nextIsDark) {
14
- root.setAttribute('data-theme', 'dark');
15
- root.classList.add('dark', 'dark:bg-gray-950');
16
- root.style.background = 'hsl(var(--background))';
17
- return;
18
- }
13
+ dom.classList[isDark ? 'add' : 'remove']('dark');
19
14
 
20
- root.removeAttribute('data-theme');
21
- root.classList.remove('dark', 'dark:bg-gray-950');
22
- root.style.background = '';
23
- }, [theme]);
24
-
25
- return isDark;
15
+ return { isDark, theme };
26
16
  }
27
17
 
28
- export function isDarkTheme(theme?: string | null): boolean {
29
- // If no theme provided, try to get from URL as fallback (for standalone mode)
30
- if (!theme) {
31
- const urlParams = new URLSearchParams(window.location.search);
32
- theme = urlParams.get('theme');
33
- }
34
-
35
- if (!theme || theme === 'system') {
36
- return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
37
- }
38
-
39
- return theme === 'dark';
18
+ function systenUsesDarkMode(): boolean {
19
+ return window.matchMedia('(prefers-color-scheme: dark)').matches;
40
20
  }
@@ -3,6 +3,7 @@ import { EventBusHandler, RimoriClient, StandaloneClient } from '@rimori/client'
3
3
  import type { UserInfo } from '@rimori/client';
4
4
  import ContextMenu from '../components/ContextMenu';
5
5
  import { useTheme } from '../hooks/ThemeSetter';
6
+ import { Theme } from '@rimori/client';
6
7
 
7
8
  interface PluginProviderProps {
8
9
  children: ReactNode;
@@ -23,7 +24,7 @@ export const PluginProvider: React.FC<PluginProviderProps> = ({ children, plugin
23
24
  const [client, setClient] = useState<RimoriClient | null>(null);
24
25
  const [standaloneClient, setStandaloneClient] = useState<StandaloneClient | boolean>(false);
25
26
  const [applicationMode, setApplicationMode] = useState<string | null>(null);
26
- const [theme, setTheme] = useState<string | null>(null);
27
+ const [theme, setTheme] = useState<Theme | undefined>(undefined);
27
28
  const [userInfo, setUserInfo] = useState<UserInfo | null>(null);
28
29
 
29
30
  useTheme(theme);
@@ -51,10 +52,8 @@ export const PluginProvider: React.FC<PluginProviderProps> = ({ children, plugin
51
52
 
52
53
  // Get applicationMode and theme from MessageChannel query params
53
54
  if (!standaloneDetected) {
54
- const mode = client.getQueryParam('applicationMode');
55
- const themeParam = client.getQueryParam('rm_theme');
56
- setApplicationMode(mode);
57
- setTheme(themeParam);
55
+ setTheme(client.plugin.theme);
56
+ setApplicationMode(client.plugin.applicationMode);
58
57
  client.event.emit('self.rimori.triggerInitFinished');
59
58
  }
60
59
  });