@rimori/react-client 0.4.0-next.1 → 0.4.0-next.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.
@@ -125,7 +125,7 @@ export const AudioPlayer = ({ text, voice, language, hide, playListenerEvent, in
125
125
  // console.log("playOnMount", playOnMount);
126
126
  togglePlayback();
127
127
  }, [playOnMount]);
128
- return (_jsx("div", { className: "group relative", children: _jsxs("div", { className: "flex flex-row items-end", children: [!hide && (_jsx("button", { className: "text-gray-500", onClick: togglePlayback, disabled: isLoading, children: isLoading ? _jsx(Spinner, {}) : isPlaying ? _jsx(FaStopCircle, { size: '25px' }) : _jsx(FaPlayCircle, { size: '25px' }) })), enableSpeedAdjustment && (_jsxs("div", { className: "ml-1 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex flex-row text-sm text-gray-500", children: [_jsx("span", { className: "pr-1", children: "Speed: " }), _jsx("select", { value: speed, className: "appearance-none cursor-pointer pr-0 p-0 rounded shadow leading-tight focus:outline-none focus:bg-gray-800 focus:ring bg-transparent border-0", onChange: (e) => setSpeed(parseFloat(e.target.value)), disabled: isLoading, children: AudioPlayOptions.map((s) => (_jsx("option", { value: s, children: s }, s))) })] }))] }) }));
128
+ return (_jsx("div", { className: "group relative", children: _jsxs("div", { className: "flex flex-row items-end", children: [!hide && (_jsx("button", { className: "text-gray-400", onClick: togglePlayback, disabled: isLoading, children: isLoading ? (_jsx(Spinner, { size: "25px" })) : isPlaying ? (_jsx(FaStopCircle, { size: "25px" })) : (_jsx(FaPlayCircle, { size: "25px" })) })), enableSpeedAdjustment && (_jsxs("div", { className: "ml-1 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex flex-row text-sm text-gray-500", children: [_jsx("span", { className: "pr-1", children: "Speed: " }), _jsx("select", { value: speed, className: "appearance-none cursor-pointer pr-0 p-0 rounded shadow leading-tight focus:outline-none focus:bg-gray-800 focus:ring bg-transparent border-0", onChange: (e) => setSpeed(parseFloat(e.target.value)), disabled: isLoading, children: AudioPlayOptions.map((s) => (_jsx("option", { value: s, children: s }, s))) })] }))] }) }));
129
129
  };
130
130
  const Spinner = ({ text, className, size = '30px' }) => {
131
131
  return (_jsxs("div", { className: 'flex items-center space-x-2 ' + className, children: [_jsxs("svg", { style: { width: size, height: size }, className: "animate-spin -ml-1 mr-3 h-5 w-5 text-white", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [_jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), _jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })] }), text && _jsx("span", { className: "", children: text })] }));
@@ -1,5 +1,6 @@
1
1
  import React, { ReactNode } from 'react';
2
2
  import { RimoriClient } from '@rimori/client';
3
+ import type { UserInfo } from '@rimori/client';
3
4
  interface PluginProviderProps {
4
5
  children: ReactNode;
5
6
  pluginId: string;
@@ -8,5 +9,7 @@ interface PluginProviderProps {
8
9
  };
9
10
  }
10
11
  export declare const PluginProvider: React.FC<PluginProviderProps>;
11
- export declare const useRimori: () => RimoriClient;
12
+ export declare const useRimori: () => RimoriClient & {
13
+ userInfo: UserInfo;
14
+ };
12
15
  export {};
@@ -18,6 +18,7 @@ export const PluginProvider = ({ children, pluginId, settings }) => {
18
18
  const [standaloneClient, setStandaloneClient] = useState(false);
19
19
  const [applicationMode, setApplicationMode] = useState(null);
20
20
  const [theme, setTheme] = useState(null);
21
+ const [userInfo, setUserInfo] = useState(null);
21
22
  useTheme(theme);
22
23
  const isSidebar = applicationMode === 'sidebar';
23
24
  const isSettings = applicationMode === 'settings';
@@ -33,6 +34,8 @@ export const PluginProvider = ({ children, pluginId, settings }) => {
33
34
  if ((!standaloneDetected && !client) || (standaloneDetected && standaloneClient === true)) {
34
35
  void RimoriClient.getInstance(pluginId).then((client) => {
35
36
  setClient(client);
37
+ // Set initial userInfo
38
+ setUserInfo(client.plugin.getUserInfo());
36
39
  // Get applicationMode and theme from MessageChannel query params
37
40
  if (!standaloneDetected) {
38
41
  const mode = client.getQueryParam('applicationMode');
@@ -44,6 +47,16 @@ export const PluginProvider = ({ children, pluginId, settings }) => {
44
47
  });
45
48
  }
46
49
  }, [pluginId, standaloneClient, client]);
50
+ // Listen for RimoriInfo updates and update userInfo
51
+ useEffect(() => {
52
+ if (!client)
53
+ return;
54
+ const unsubscribe = client.plugin.onRimoriInfoUpdate((info) => {
55
+ console.log('[PluginProvider] Received RimoriInfo update, updating userInfo');
56
+ setUserInfo(info.profile);
57
+ });
58
+ return () => unsubscribe();
59
+ }, [client]);
47
60
  useEffect(() => {
48
61
  if (!client)
49
62
  return;
@@ -63,17 +76,19 @@ export const PluginProvider = ({ children, pluginId, settings }) => {
63
76
  setStandaloneClient(true);
64
77
  }) }));
65
78
  }
66
- if (!client) {
79
+ if (!client || !userInfo) {
67
80
  return '';
68
81
  }
69
- return (_jsxs(PluginContext.Provider, { value: client, children: [!(settings === null || settings === void 0 ? void 0 : settings.disableContextMenu) && !isSidebar && !isSettings && _jsx(ContextMenu, { client: client }), children] }));
82
+ return (_jsxs(PluginContext.Provider, { value: { client, userInfo }, children: [!(settings === null || settings === void 0 ? void 0 : settings.disableContextMenu) && !isSidebar && !isSettings && _jsx(ContextMenu, { client: client }), children] }));
70
83
  };
71
84
  export const useRimori = () => {
72
85
  const context = useContext(PluginContext);
73
86
  if (context === null) {
74
87
  throw new Error('useRimori must be used within an PluginProvider');
75
88
  }
76
- return context;
89
+ // Return client with userInfo at root level for easy access
90
+ // Maintains backwards compatibility - all client properties are still accessible
91
+ return Object.assign(context.client, { userInfo: context.userInfo });
77
92
  };
78
93
  function getUrlParam(name) {
79
94
  // First try to get from URL hash query params (for compatibility)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rimori/react-client",
3
- "version": "0.4.0-next.1",
3
+ "version": "0.4.0-next.3",
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.4.0-next.0",
26
+ "@rimori/client": "2.4.0-next.4",
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.4.0-next.0",
37
+ "@rimori/client": "2.4.0-next.4",
38
38
  "@types/react": "^18.3.21",
39
39
  "eslint-config-prettier": "^10.1.8",
40
40
  "eslint-plugin-prettier": "^5.5.4",
@@ -152,8 +152,14 @@ export const AudioPlayer: React.FC<AudioPlayerProps> = ({
152
152
  <div className="group relative">
153
153
  <div className="flex flex-row items-end">
154
154
  {!hide && (
155
- <button className="text-gray-500" onClick={togglePlayback} disabled={isLoading}>
156
- {isLoading ? <Spinner /> : isPlaying ? <FaStopCircle size={'25px'} /> : <FaPlayCircle size={'25px'} />}
155
+ <button className="text-gray-400" onClick={togglePlayback} disabled={isLoading}>
156
+ {isLoading ? (
157
+ <Spinner size="25px" />
158
+ ) : isPlaying ? (
159
+ <FaStopCircle size="25px" />
160
+ ) : (
161
+ <FaPlayCircle size="25px" />
162
+ )}
157
163
  </button>
158
164
  )}
159
165
  {enableSpeedAdjustment && (
@@ -1,5 +1,6 @@
1
1
  import React, { createContext, useContext, ReactNode, useEffect, useState } from 'react';
2
2
  import { EventBusHandler, RimoriClient, StandaloneClient } from '@rimori/client';
3
+ import type { UserInfo } from '@rimori/client';
3
4
  import ContextMenu from '../components/ContextMenu';
4
5
  import { useTheme } from '../hooks/ThemeSetter';
5
6
 
@@ -11,13 +12,19 @@ interface PluginProviderProps {
11
12
  };
12
13
  }
13
14
 
14
- const PluginContext = createContext<RimoriClient | null>(null);
15
+ interface PluginContextValue {
16
+ client: RimoriClient;
17
+ userInfo: UserInfo;
18
+ }
19
+
20
+ const PluginContext = createContext<PluginContextValue | null>(null);
15
21
 
16
22
  export const PluginProvider: React.FC<PluginProviderProps> = ({ children, pluginId, settings }) => {
17
23
  const [client, setClient] = useState<RimoriClient | null>(null);
18
24
  const [standaloneClient, setStandaloneClient] = useState<StandaloneClient | boolean>(false);
19
25
  const [applicationMode, setApplicationMode] = useState<string | null>(null);
20
26
  const [theme, setTheme] = useState<string | null>(null);
27
+ const [userInfo, setUserInfo] = useState<UserInfo | null>(null);
21
28
 
22
29
  useTheme(theme);
23
30
 
@@ -39,6 +46,9 @@ export const PluginProvider: React.FC<PluginProviderProps> = ({ children, plugin
39
46
  if ((!standaloneDetected && !client) || (standaloneDetected && standaloneClient === true)) {
40
47
  void RimoriClient.getInstance(pluginId).then((client) => {
41
48
  setClient(client);
49
+ // Set initial userInfo
50
+ setUserInfo(client.plugin.getUserInfo());
51
+
42
52
  // Get applicationMode and theme from MessageChannel query params
43
53
  if (!standaloneDetected) {
44
54
  const mode = client.getQueryParam('applicationMode');
@@ -51,6 +61,18 @@ export const PluginProvider: React.FC<PluginProviderProps> = ({ children, plugin
51
61
  }
52
62
  }, [pluginId, standaloneClient, client]);
53
63
 
64
+ // Listen for RimoriInfo updates and update userInfo
65
+ useEffect(() => {
66
+ if (!client) return;
67
+
68
+ const unsubscribe = client.plugin.onRimoriInfoUpdate((info) => {
69
+ console.log('[PluginProvider] Received RimoriInfo update, updating userInfo');
70
+ setUserInfo(info.profile);
71
+ });
72
+
73
+ return (): void => unsubscribe();
74
+ }, [client]);
75
+
54
76
  useEffect(() => {
55
77
  if (!client) return;
56
78
  if (isSidebar) return; //sidebar pages should not report url changes
@@ -74,24 +96,26 @@ export const PluginProvider: React.FC<PluginProviderProps> = ({ children, plugin
74
96
  );
75
97
  }
76
98
 
77
- if (!client) {
99
+ if (!client || !userInfo) {
78
100
  return '';
79
101
  }
80
102
 
81
103
  return (
82
- <PluginContext.Provider value={client}>
104
+ <PluginContext.Provider value={{ client, userInfo }}>
83
105
  {!settings?.disableContextMenu && !isSidebar && !isSettings && <ContextMenu client={client} />}
84
106
  {children}
85
107
  </PluginContext.Provider>
86
108
  );
87
109
  };
88
110
 
89
- export const useRimori = () => {
111
+ export const useRimori = (): RimoriClient & { userInfo: UserInfo } => {
90
112
  const context = useContext(PluginContext);
91
113
  if (context === null) {
92
114
  throw new Error('useRimori must be used within an PluginProvider');
93
115
  }
94
- return context;
116
+ // Return client with userInfo at root level for easy access
117
+ // Maintains backwards compatibility - all client properties are still accessible
118
+ return Object.assign(context.client, { userInfo: context.userInfo }) as RimoriClient & { userInfo: UserInfo };
95
119
  };
96
120
 
97
121
  function getUrlParam(name: string): string | null {