@fraku/video 0.1.59 → 0.1.61

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.
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Triggers the browser's native permission prompt for the given media kind.
3
+ * Works cross-browser: the native prompt appears when permission state is
4
+ * "prompt"; if permission is already "denied" the call rejects immediately.
5
+ *
6
+ * The acquired tracks are stopped right away — we only need the permission
7
+ * grant, not an active stream.
8
+ *
9
+ * @returns 'granted' if the user allowed access, 'denied' if the user explicitly
10
+ * denied the permission (NotAllowedError), or 'error' for any other failure
11
+ * (e.g. device not found, hardware error).
12
+ */
13
+ export type BrowserPermissionResult = 'granted' | 'denied' | 'error';
14
+ export declare function requestBrowserPermission(kind: 'audio' | 'video'): Promise<BrowserPermissionResult>;
@@ -1,2 +1,4 @@
1
- declare const MainSessionPage: () => import("react/jsx-runtime").JSX.Element;
1
+ declare const MainSessionPage: ({ devTools }: {
2
+ devTools?: boolean;
3
+ }) => import("react/jsx-runtime").JSX.Element;
2
4
  export default MainSessionPage;
@@ -0,0 +1,24 @@
1
+ import { Participant } from '@zoom/videosdk';
2
+ import { Menu } from 'primereact/menu';
3
+ import { RefObject } from 'react';
4
+
5
+ type ActionCellProps = {
6
+ p: Participant;
7
+ currentUserId: number;
8
+ canToggleUserAudio: boolean;
9
+ loading: boolean;
10
+ showUserMenuButton: boolean;
11
+ handleToggleParticipantMic: (p: Participant) => Promise<void>;
12
+ setSelectedUser: (p: Participant) => void;
13
+ userMenuRef: RefObject<Menu>;
14
+ };
15
+ /**
16
+ * ActionCell reads selfCameraPermission / selfMicPermission directly from
17
+ * useVideoContext() rather than accepting them as props. This is intentional:
18
+ * PrimeReact DataTable memoizes row rendering based on row data, so changes to
19
+ * the parent's closure (props) don't trigger cell re-renders. As a React
20
+ * component subscribed to context, ActionCell re-renders independently when
21
+ * permission state changes.
22
+ */
23
+ declare const ActionCell: ({ p, currentUserId, canToggleUserAudio, loading, showUserMenuButton, handleToggleParticipantMic, setSelectedUser, userMenuRef }: ActionCellProps) => import("react/jsx-runtime").JSX.Element;
24
+ export default ActionCell;
@@ -12,7 +12,7 @@ export type AudioContextType = {
12
12
  speakerList: MediaDevice[];
13
13
  activeSpeakerId: string;
14
14
  switchSpeaker: (deviceId: string) => Promise<void>;
15
- startAudio: () => Promise<void>;
15
+ startAudio: (muteOverride?: boolean) => Promise<void>;
16
16
  setMicList: (mics: MediaDevice[]) => void;
17
17
  setSpeakerList: (speakers: MediaDevice[]) => void;
18
18
  setActiveMicId: (id: string) => void;
@@ -1,7 +1,7 @@
1
1
  import { SettingsTab } from '../../components/ConfigDialog/context';
2
2
  import { AcceptParticipationDialogConfig } from '../../components/AcceptParticipationDialog/types';
3
3
 
4
- export type NotifySeverity = 'info' | 'success' | 'error';
4
+ export type NotifySeverity = 'info' | 'success' | 'warn' | 'error';
5
5
  export type AlertDialogProps = {
6
6
  header?: string;
7
7
  message: string;
@@ -2,6 +2,7 @@ import { default as ZoomVideo } from '@zoom/videosdk';
2
2
 
3
3
  export type SessionContextType = {
4
4
  zmClient: ReturnType<typeof ZoomVideo.createClient>;
5
+ clientInitialized: boolean;
5
6
  sessionStarted: boolean;
6
7
  signature: string;
7
8
  isSessionStarted: () => boolean;
@@ -1,9 +1,14 @@
1
1
  import { ActiveSpeaker, Participant } from '@zoom/videosdk';
2
2
 
3
+ export type NetworkQuality = {
4
+ uplink: number;
5
+ downlink: number;
6
+ };
3
7
  export type UsersContextType = {
4
8
  activeSpeakers: ActiveSpeaker[];
5
9
  activeVideoParticipant: Participant | null;
6
10
  currentUser: Participant | null;
11
+ networkQualityMap: Map<number, NetworkQuality>;
7
12
  screenSharingUser: Participant | null;
8
13
  users: Participant[];
9
14
  };
@@ -1,2 +1,3 @@
1
1
  export { default } from './UsersProvider';
2
2
  export { useUsersContext } from './context';
3
+ export type { NetworkQuality } from './context';
@@ -11,8 +11,11 @@ export type VirtualBackgroundState = {
11
11
  customImages: CustomBackgroundImage[];
12
12
  activeCustomImageId: string | null;
13
13
  };
14
+ export type BrowserPermissionState = 'granted' | 'denied' | 'prompt' | 'unknown';
14
15
  export type VideoContextType = {
15
16
  activeCameraId: string;
17
+ selfCameraPermission: BrowserPermissionState;
18
+ selfMicPermission: BrowserPermissionState;
16
19
  attachSharedVideo: ({ userId, videoPlayer }: {
17
20
  userId: number;
18
21
  videoPlayer: VideoPlayer;
@@ -38,5 +41,5 @@ export type VideoContextType = {
38
41
  uploadBackgroundImage: (file: File) => Promise<void>;
39
42
  virtualBackground: VirtualBackgroundState;
40
43
  };
41
- export declare const VideoContext: import('react').Context<VideoContextType>;
44
+ export declare const VideoContext: import('react').Context<VideoContextType | null>;
42
45
  export declare const useVideoContext: () => VideoContextType;
@@ -7,9 +7,10 @@ type UseVideoEventHandlersParams = {
7
7
  onVideoStopped: () => void;
8
8
  onDeviceChange: () => void;
9
9
  onScreenShareStopped: () => void;
10
+ onPermissionRestored: (name: 'camera' | 'microphone') => void;
10
11
  };
11
12
  /**
12
13
  * Custom hook to manage Zoom video event subscriptions
13
14
  */
14
- export declare const useVideoEventHandlers: ({ zmClient, sessionStarted, onVideoStarted, onVideoStopped, onDeviceChange, onScreenShareStopped }: UseVideoEventHandlersParams) => void;
15
+ export declare const useVideoEventHandlers: ({ zmClient, sessionStarted, onVideoStarted, onVideoStopped, onDeviceChange, onScreenShareStopped, onPermissionRestored }: UseVideoEventHandlersParams) => void;
15
16
  export {};
@@ -0,0 +1,25 @@
1
+ import { ActiveMediaFailedCode } from '@zoom/videosdk';
2
+
3
+ export type MediaFailedConfig = {
4
+ messageKey: string;
5
+ mutesMic?: boolean;
6
+ stopVideo?: boolean;
7
+ stopSharing?: boolean;
8
+ reloadPage?: boolean;
9
+ requestPermission?: 'audio' | 'video';
10
+ };
11
+ export declare const MEDIA_FAILED_CONFIGS: Record<ActiveMediaFailedCode, MediaFailedConfig>;
12
+ type ShowMediaFailedDialogParams = {
13
+ config: MediaFailedConfig;
14
+ alert: (opts: {
15
+ message: string;
16
+ }) => void;
17
+ confirm: (opts: {
18
+ header: string;
19
+ message: string;
20
+ onAccept: () => void | Promise<void>;
21
+ }) => void;
22
+ t: (key: string) => string;
23
+ };
24
+ export declare const showMediaFailedDialog: ({ config, alert, confirm, t }: ShowMediaFailedDialogParams) => void;
25
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -20,5 +20,7 @@ export type VideoPluginProps = {
20
20
  credentials: Credentials;
21
21
  language?: string;
22
22
  className?: string;
23
+ /** Renders a floating panel to simulate active-media-failed errors. For development only. */
24
+ devTools?: boolean;
23
25
  };
24
26
  export type ReactSetter<T> = React.Dispatch<React.SetStateAction<T>>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fraku/video",
3
3
  "private": false,
4
- "version": "0.1.59",
4
+ "version": "0.1.61",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.js",
@@ -60,12 +60,12 @@
60
60
  "react-i18next": "^16.5.4",
61
61
  "react-use": "^17.6.0",
62
62
  "styled-components": "^5.3.11",
63
- "tailwind-merge": "^3.4.0",
63
+ "tailwind-merge": "^3.5.0",
64
64
  "uuid": "^13.0.0"
65
65
  },
66
66
  "devDependencies": {
67
67
  "@playwright/test": "^1.58.2",
68
- "@storybook/react-vite": "^10.2.10",
68
+ "@storybook/react-vite": "^10.2.14",
69
69
  "@storybook/test-runner": "^0.24.2",
70
70
  "@tailwindcss/container-queries": "^0.1.1",
71
71
  "@testing-library/jest-dom": "^6.9.1",
@@ -80,8 +80,8 @@
80
80
  "@vitejs/plugin-react": "^4.3.4",
81
81
  "@vitest/coverage-v8": "^4.0.18",
82
82
  "@vitest/ui": "^4.0.18",
83
- "autoprefixer": "^10.4.23",
84
- "baseline-browser-mapping": "^2.9.19",
83
+ "autoprefixer": "^10.4.27",
84
+ "baseline-browser-mapping": "^2.10.0",
85
85
  "eslint": "^8.55.0",
86
86
  "eslint-plugin-react": "^7.37.5",
87
87
  "eslint-plugin-react-hooks": "^4.6.0",
@@ -92,7 +92,7 @@
92
92
  "postcss": "^8.5.6",
93
93
  "react": "^18.2.0",
94
94
  "react-dom": "^18.2.0",
95
- "storybook": "^10.2.10",
95
+ "storybook": "^10.2.14",
96
96
  "tailwindcss": "^3.4.17",
97
97
  "typescript": "^5.2.2",
98
98
  "vite": "^6.0.7",