mediasfu-shared 1.0.1 → 1.0.2

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 (125) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +103 -222
  3. package/dist/index.cjs +7500 -2163
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.d.ts +4203 -273
  6. package/dist/index.js +7521 -2184
  7. package/dist/index.js.map +1 -1
  8. package/package.json +85 -78
  9. package/src/ProducerClient/producerClientEmits/joinRoomClient.ts +57 -0
  10. package/src/ProducerClient/producerClientEmits/updateRoomParametersClient.ts +401 -0
  11. package/src/consumers/addVideosGrid.ts +3 -2
  12. package/src/consumers/changeVids.ts +111 -41
  13. package/src/consumers/checkPermission.ts +35 -1
  14. package/src/consumers/connectRecvTransport.ts +42 -1
  15. package/src/consumers/consumerResume.ts +2 -2
  16. package/src/consumers/dispStreams.ts +83 -37
  17. package/src/consumers/frameworkConsumerContract.ts +6 -0
  18. package/src/consumers/generatePageContent.ts +24 -10
  19. package/src/consumers/getPipedProducersAlt.ts +112 -16
  20. package/src/consumers/gridLayout/addVideosGrid.engine.ts +42 -0
  21. package/src/consumers/gridLayout/prepopulateUserMedia.engine.ts +444 -0
  22. package/src/consumers/mixStreams.ts +45 -14
  23. package/src/consumers/onScreenChanges.ts +25 -10
  24. package/src/consumers/prepopulateUserMedia.ts +3 -2
  25. package/src/consumers/processConsumerTransports.ts +68 -23
  26. package/src/consumers/processConsumerTransportsAudio.ts +53 -16
  27. package/src/consumers/reUpdateInter.ts +61 -21
  28. package/src/consumers/readjust.ts +30 -14
  29. package/src/consumers/reorderStreams.ts +76 -42
  30. package/src/consumers/resumePauseAudioStreams.ts +66 -17
  31. package/src/consumers/resumePauseStreams.ts +53 -10
  32. package/src/consumers/socketReceiveMethods/joinConsumeRoom.ts +8 -0
  33. package/src/consumers/socketReceiveMethods/newPipeProducer.ts +114 -0
  34. package/src/consumers/socketReceiveMethods/producerClosed.ts +13 -0
  35. package/src/consumers/streamSuccessScreen.ts +2 -2
  36. package/src/consumers/streamSuccessVideo.ts +5 -0
  37. package/src/consumers/translationConsumerSwitch.ts +299 -0
  38. package/src/index.ts +85 -1
  39. package/src/methods/coHostMethods/modifyCoHostSettings.ts +9 -9
  40. package/src/methods/displaySettings/modifyDisplaySettings.ts +5 -0
  41. package/src/methods/index.ts +66 -0
  42. package/src/methods/message/sendMessage.ts +12 -29
  43. package/src/methods/panelists/focusPanelists.ts +83 -0
  44. package/src/methods/panelists/index.ts +3 -0
  45. package/src/methods/panelists/launchPanelists.ts +13 -0
  46. package/src/methods/panelists/updatePanelists.ts +135 -0
  47. package/src/methods/permissions/index.ts +3 -0
  48. package/src/methods/permissions/launchPermissions.ts +13 -0
  49. package/src/methods/permissions/updateParticipantPermission.ts +127 -0
  50. package/src/methods/permissions/updatePermissionConfig.ts +52 -0
  51. package/src/methods/polls/pollUpdated.ts +88 -0
  52. package/src/methods/recording/confirmRecording.ts +15 -12
  53. package/src/methods/recording/recordResumeTimer.ts +2 -2
  54. package/src/methods/recording/recordStartTimer.ts +2 -2
  55. package/src/methods/recording/timeLeftRecording.ts +25 -0
  56. package/src/methods/requests/hostRequestResponse.ts +153 -0
  57. package/src/methods/settings/modifySettings.ts +17 -17
  58. package/src/methods/socketReceive/allMembers.ts +450 -0
  59. package/src/methods/socketReceive/allMembersRest.ts +480 -0
  60. package/src/methods/socketReceive/allWaitingRoomMembers.ts +35 -0
  61. package/src/methods/socketReceive/banParticipant.ts +73 -0
  62. package/src/methods/socketReceive/controlMediaHost.ts +280 -0
  63. package/src/methods/socketReceive/disconnect.ts +40 -0
  64. package/src/methods/socketReceive/disconnectUserSelf.ts +56 -0
  65. package/src/methods/socketReceive/getDomains.ts +112 -0
  66. package/src/methods/socketReceive/meetingEnded.ts +49 -0
  67. package/src/methods/socketReceive/meetingStillThere.ts +26 -0
  68. package/src/methods/socketReceive/panelistReceiveMethods.ts +195 -0
  69. package/src/methods/socketReceive/participantRequested.ts +48 -0
  70. package/src/methods/socketReceive/permissionReceiveMethods.ts +59 -0
  71. package/src/methods/socketReceive/personJoined.ts +35 -0
  72. package/src/methods/socketReceive/producerMediaClosed.ts +223 -0
  73. package/src/methods/socketReceive/producerMediaPaused.ts +267 -0
  74. package/src/methods/socketReceive/producerMediaResumed.ts +157 -0
  75. package/src/methods/socketReceive/reInitiateRecording.ts +53 -0
  76. package/src/methods/socketReceive/receiveMessage.ts +117 -0
  77. package/src/methods/socketReceive/recordingNotice.ts +286 -0
  78. package/src/methods/socketReceive/roomRecordParams.ts +122 -0
  79. package/src/methods/socketReceive/screenProducerId.ts +61 -0
  80. package/src/methods/socketReceive/startRecords.ts +46 -0
  81. package/src/methods/socketReceive/stoppedRecording.ts +44 -0
  82. package/src/methods/socketReceive/translationReceiveMethods.ts +581 -0
  83. package/src/methods/socketReceive/updateConsumingDomains.ts +128 -0
  84. package/src/methods/socketReceive/updateMediaSettings.ts +45 -0
  85. package/src/methods/socketReceive/updatedCoHost.ts +75 -0
  86. package/src/methods/socketReceive/userWaiting.ts +45 -0
  87. package/src/methods/stream/clickAudio.ts +380 -0
  88. package/src/methods/stream/clickChat.ts +36 -0
  89. package/src/methods/stream/clickScreenShare.ts +173 -0
  90. package/src/methods/stream/clickVideo.ts +22 -5
  91. package/src/methods/stream/index.ts +1 -0
  92. package/src/methods/utils/SoundPlayer.ts +31 -0
  93. package/src/methods/utils/checkLimitsAndMakeRequest.ts +156 -2
  94. package/src/methods/utils/createResponseJoinRoom.ts +47 -0
  95. package/src/methods/utils/createRoomOnMediaSFU.ts +160 -0
  96. package/src/methods/utils/formatNumber.ts +42 -0
  97. package/src/methods/utils/generateRandomMessages.ts +70 -0
  98. package/src/methods/utils/generateRandomParticipants.ts +100 -0
  99. package/src/methods/utils/generateRandomPolls.ts +43 -0
  100. package/src/methods/utils/generateRandomRequestList.ts +51 -0
  101. package/src/methods/utils/generateRandomWaitingRoomList.ts +17 -0
  102. package/src/methods/utils/getModalPosition.ts +23 -0
  103. package/src/methods/utils/getOverlayPosition.ts +37 -0
  104. package/src/methods/utils/initialValuesState.ts +405 -0
  105. package/src/methods/utils/joinRoomOnMediaSFU.ts +124 -0
  106. package/src/methods/utils/liveSubtitle.ts +107 -0
  107. package/src/methods/utils/meetingTimeRemaining.ts +33 -0
  108. package/src/methods/utils/meetingTimer/startMeetingProgressTimer.ts +72 -0
  109. package/src/methods/utils/producer/aParams.ts +10 -0
  110. package/src/methods/utils/producer/hParams.ts +26 -0
  111. package/src/methods/utils/producer/screenParams.ts +13 -0
  112. package/src/methods/utils/producer/vParams.ts +26 -0
  113. package/src/methods/utils/producer/videoCaptureConstraints.ts +65 -0
  114. package/src/methods/utils/resolveMediaSFURoomApi.ts +16 -0
  115. package/src/methods/utils/sleep.ts +24 -0
  116. package/src/methods/utils/translationLanguages.ts +308 -0
  117. package/src/methods/utils/webrtc.ts +44 -0
  118. package/src/methods/welcome/handleWelcomeRequest.ts +11 -2
  119. package/src/methods/welcome/index.ts +5 -1
  120. package/src/methods/whiteboard/captureCanvasStream.ts +128 -0
  121. package/src/producers/producerEmits/joinConRoom.ts +2 -2
  122. package/src/producers/producerEmits/joinLocalRoom.ts +240 -0
  123. package/src/producers/producerEmits/joinRoom.ts +129 -0
  124. package/src/types/shared-base-types.ts +14 -3
  125. package/src/types/types.ts +255 -0
@@ -6,6 +6,7 @@ export interface ModifyDisplaySettingsParameters extends OnScreenChangesParamete
6
6
  meetingDisplayType: string
7
7
  autoWave: boolean
8
8
  forceFullDisplay: boolean
9
+ showSubtitlesOnCards?: boolean
9
10
  meetingVideoOptimized: boolean
10
11
  islevel: string
11
12
  recordStarted: boolean
@@ -19,6 +20,7 @@ export interface ModifyDisplaySettingsParameters extends OnScreenChangesParamete
19
20
  updateMeetingDisplayType: (displayType: string) => void
20
21
  updateAutoWave: (autoWave: boolean) => void
21
22
  updateForceFullDisplay: (forceFullDisplay: boolean) => void
23
+ updateShowSubtitlesOnCards?: (showSubtitlesOnCards: boolean) => void
22
24
  updateMeetingVideoOptimized: (optimized: boolean) => void
23
25
  updatePrevForceFullDisplay: (forceFullDisplay: boolean) => void
24
26
  updatePrevMeetingDisplayType: (displayType: string) => void
@@ -121,6 +123,7 @@ export const modifyDisplaySettings = async ({
121
123
  meetingDisplayType,
122
124
  autoWave,
123
125
  forceFullDisplay,
126
+ showSubtitlesOnCards = true,
124
127
  meetingVideoOptimized,
125
128
  islevel,
126
129
  recordStarted,
@@ -134,6 +137,7 @@ export const modifyDisplaySettings = async ({
134
137
  updateMeetingDisplayType,
135
138
  updateAutoWave,
136
139
  updateForceFullDisplay,
140
+ updateShowSubtitlesOnCards,
137
141
  updateMeetingVideoOptimized,
138
142
  updatePrevForceFullDisplay,
139
143
  updatePrevMeetingDisplayType,
@@ -148,6 +152,7 @@ export const modifyDisplaySettings = async ({
148
152
  // Update previous states
149
153
  updateAutoWave(autoWave)
150
154
  updateForceFullDisplay(forceFullDisplay)
155
+ updateShowSubtitlesOnCards?.(showSubtitlesOnCards)
151
156
 
152
157
  if (
153
158
  islevel === '2' &&
@@ -3,3 +3,69 @@
3
3
  export * from './prejoin';
4
4
  // Welcome methods
5
5
  export * from './welcome';
6
+ // Panelists methods
7
+ export * from './panelists';
8
+ // Permissions methods
9
+ export * from './permissions';
10
+ // Shared utility methods
11
+ export * from './utils/liveSubtitle';
12
+ export * from './utils/translationLanguages';
13
+ export * from './utils/SoundPlayer';
14
+ export * from './utils/getOverlayPosition';
15
+ export * from './utils/sleep';
16
+ export * from './utils/formatNumber';
17
+ export * from './utils/generateRandomMessages';
18
+ export * from './utils/generateRandomParticipants';
19
+ export * from './utils/generateRandomPolls';
20
+ export * from './utils/generateRandomRequestList';
21
+ export * from './utils/generateRandomWaitingRoomList';
22
+ export * from './utils/initialValuesState';
23
+ export * from './utils/webrtc';
24
+ export * from './utils/checkLimitsAndMakeRequest';
25
+ export * from './utils/createResponseJoinRoom';
26
+ export * from './utils/joinRoomOnMediaSFU';
27
+ export * from './utils/createRoomOnMediaSFU';
28
+ export * from './utils/meetingTimer/startMeetingProgressTimer';
29
+ export * from './utils/meetingTimeRemaining';
30
+ export * from './utils/producer/aParams';
31
+ export * from './utils/producer/hParams';
32
+ export * from './utils/producer/vParams';
33
+ export * from './utils/producer/screenParams';
34
+ export * from './utils/producer/videoCaptureConstraints';
35
+ export * from './utils/validateAlphanumeric';
36
+ export * from './polls/pollUpdated';
37
+ export * from './requests/hostRequestResponse';
38
+ export * from './stream/clickAudio';
39
+ export * from './stream/clickChat';
40
+ export * from './stream/clickScreenShare';
41
+ export * from './whiteboard/captureCanvasStream';
42
+ export * from './recording/timeLeftRecording';
43
+ export * from './socketReceive/allWaitingRoomMembers';
44
+ export * from './socketReceive/allMembers';
45
+ export * from './socketReceive/allMembersRest';
46
+ export * from './socketReceive/banParticipant';
47
+ export * from './socketReceive/controlMediaHost';
48
+ export * from './socketReceive/disconnect';
49
+ export * from './socketReceive/disconnectUserSelf';
50
+ export * from './socketReceive/getDomains';
51
+ export * from './socketReceive/meetingEnded';
52
+ export * from './socketReceive/meetingStillThere';
53
+ export * from './socketReceive/panelistReceiveMethods';
54
+ export * from './socketReceive/participantRequested';
55
+ export * from './socketReceive/permissionReceiveMethods';
56
+ export * from './socketReceive/personJoined';
57
+ export * from './socketReceive/producerMediaClosed';
58
+ export * from './socketReceive/producerMediaPaused';
59
+ export * from './socketReceive/producerMediaResumed';
60
+ export * from './socketReceive/receiveMessage';
61
+ export * from './socketReceive/recordingNotice';
62
+ export * from './socketReceive/reInitiateRecording';
63
+ export * from './socketReceive/roomRecordParams';
64
+ export * from './socketReceive/screenProducerId';
65
+ export * from './socketReceive/startRecords';
66
+ export * from './socketReceive/stoppedRecording';
67
+ export * from './socketReceive/translationReceiveMethods';
68
+ export * from './socketReceive/updateMediaSettings';
69
+ export * from './socketReceive/updateConsumingDomains';
70
+ export * from './socketReceive/updatedCoHost';
71
+ export * from './socketReceive/userWaiting';
@@ -77,7 +77,6 @@ export const sendMessage = async ({
77
77
  member,
78
78
  sender,
79
79
  islevel,
80
- eventType,
81
80
  showAlert,
82
81
  coHostResponsibility,
83
82
  coHost,
@@ -87,34 +86,18 @@ export const sendMessage = async ({
87
86
  }: SendMessageOptions): Promise<void> => {
88
87
  let chatValue = false;
89
88
 
90
- // Check if messages count exceeds the limit
91
- if (eventType === "broadcast") {
92
- if (messagesLength >= 100) {
93
- showAlert?.({
94
- message: "You have reached the maximum number of messages",
95
- type: "danger",
96
- duration: 3000,
97
- });
98
- return;
99
- }
100
- } else if (eventType === "chat") {
101
- if (messagesLength >= 500) {
102
- showAlert?.({
103
- message: "You have reached the maximum number of messages",
104
- type: "danger",
105
- duration: 3000,
106
- });
107
- return;
108
- }
109
- } else {
110
- if (messagesLength >= 100000) {
111
- showAlert?.({
112
- message: "You have reached the maximum number of messages",
113
- type: "danger",
114
- duration: 3000,
115
- });
116
- return;
117
- }
89
+ // Check message count limit based on room type prefix
90
+ if (
91
+ (messagesLength > 100 && roomName.startsWith("d")) ||
92
+ (messagesLength > 500 && roomName.startsWith("s")) ||
93
+ (messagesLength > 100000 && roomName.startsWith("p"))
94
+ ) {
95
+ showAlert?.({
96
+ message: "You have reached the maximum number of messages allowed.",
97
+ type: "danger",
98
+ duration: 3000,
99
+ });
100
+ return;
118
101
  }
119
102
 
120
103
  // Check if message is valid
@@ -0,0 +1,83 @@
1
+ import { Socket } from 'socket.io-client';
2
+ import type { ShowAlert } from '../../types/types';
3
+
4
+ export interface FocusPanelistsOptions {
5
+ socket: Socket;
6
+ roomName: string;
7
+ member: string;
8
+ islevel: string;
9
+ focusEnabled: boolean;
10
+ muteOthersMic?: boolean;
11
+ muteOthersCamera?: boolean;
12
+ showAlert?: ShowAlert;
13
+ }
14
+
15
+ export interface UnfocusPanelistsOptions {
16
+ socket: Socket;
17
+ roomName: string;
18
+ member: string;
19
+ islevel: string;
20
+ showAlert?: ShowAlert;
21
+ }
22
+
23
+ export type FocusPanelistsType = (options: FocusPanelistsOptions) => Promise<void>;
24
+ export type UnfocusPanelistsType = (options: UnfocusPanelistsOptions) => Promise<void>;
25
+
26
+ export const focusPanelists = async ({
27
+ socket,
28
+ roomName,
29
+ member: _member,
30
+ islevel,
31
+ focusEnabled,
32
+ muteOthersMic = false,
33
+ muteOthersCamera = false,
34
+ showAlert,
35
+ }: FocusPanelistsOptions): Promise<void> => {
36
+ if (islevel !== '2') {
37
+ showAlert?.({ message: 'Only the host can focus panelists', type: 'danger', duration: 3000 });
38
+ return;
39
+ }
40
+
41
+ socket.emit(
42
+ 'focusPanelists',
43
+ {
44
+ roomName,
45
+ focusEnabled,
46
+ muteOthersMic,
47
+ muteOthersCamera,
48
+ },
49
+ (response: { success: boolean; reason?: string }) => {
50
+ if (!response?.success) {
51
+ showAlert?.({ message: response?.reason || 'Failed to focus panelists', type: 'danger', duration: 3000 });
52
+ }
53
+ }
54
+ );
55
+ };
56
+
57
+ export const unfocusPanelists = async ({
58
+ socket,
59
+ roomName,
60
+ member: _member,
61
+ islevel,
62
+ showAlert,
63
+ }: UnfocusPanelistsOptions): Promise<void> => {
64
+ if (islevel !== '2') {
65
+ showAlert?.({ message: 'Only the host can unfocus panelists', type: 'danger', duration: 3000 });
66
+ return;
67
+ }
68
+
69
+ socket.emit(
70
+ 'focusPanelists',
71
+ {
72
+ roomName,
73
+ focusEnabled: false,
74
+ muteOthersMic: false,
75
+ muteOthersCamera: false,
76
+ },
77
+ (response: { success: boolean; reason?: string }) => {
78
+ if (!response?.success) {
79
+ showAlert?.({ message: response?.reason || 'Failed to unfocus panelists', type: 'danger', duration: 3000 });
80
+ }
81
+ }
82
+ );
83
+ };
@@ -0,0 +1,3 @@
1
+ export * from './launchPanelists';
2
+ export * from './updatePanelists';
3
+ export * from './focusPanelists';
@@ -0,0 +1,13 @@
1
+ export interface LaunchPanelistsOptions {
2
+ updateIsPanelistsModalVisible: (visible: boolean) => void;
3
+ isPanelistsModalVisible: boolean;
4
+ }
5
+
6
+ export type LaunchPanelistsType = (options: LaunchPanelistsOptions) => void;
7
+
8
+ export const launchPanelists = ({
9
+ updateIsPanelistsModalVisible,
10
+ isPanelistsModalVisible,
11
+ }: LaunchPanelistsOptions): void => {
12
+ updateIsPanelistsModalVisible(!isPanelistsModalVisible);
13
+ };
@@ -0,0 +1,135 @@
1
+ import { Socket } from 'socket.io-client';
2
+ import type { Participant, ShowAlert } from '../../types/types';
3
+
4
+ export interface UpdatePanelistsOptions {
5
+ socket: Socket;
6
+ panelists: Participant[];
7
+ roomName: string;
8
+ member: string;
9
+ islevel: string;
10
+ showAlert?: ShowAlert;
11
+ }
12
+
13
+ export interface AddPanelistOptions {
14
+ socket: Socket;
15
+ participant: Participant;
16
+ currentPanelists: Participant[];
17
+ maxPanelists: number;
18
+ roomName: string;
19
+ member: string;
20
+ islevel: string;
21
+ showAlert?: ShowAlert;
22
+ }
23
+
24
+ export interface RemovePanelistOptions {
25
+ socket: Socket;
26
+ participant: Participant;
27
+ roomName: string;
28
+ member: string;
29
+ islevel: string;
30
+ showAlert?: ShowAlert;
31
+ }
32
+
33
+ export type UpdatePanelistsType = (options: UpdatePanelistsOptions) => Promise<void>;
34
+ export type AddPanelistType = (options: AddPanelistOptions) => Promise<boolean>;
35
+ export type RemovePanelistType = (options: RemovePanelistOptions) => Promise<void>;
36
+
37
+ export const updatePanelists = async ({
38
+ socket,
39
+ panelists,
40
+ roomName,
41
+ member: _member,
42
+ islevel,
43
+ showAlert,
44
+ }: UpdatePanelistsOptions): Promise<void> => {
45
+ if (islevel !== '2') {
46
+ showAlert?.({ message: 'Only the host can update panelists', type: 'danger', duration: 3000 });
47
+ return;
48
+ }
49
+
50
+ socket.emit(
51
+ 'updatePanelists',
52
+ {
53
+ panelists: panelists.map((p) => ({ id: p.id, name: p.name })),
54
+ roomName,
55
+ },
56
+ (response: { success: boolean; reason?: string }) => {
57
+ if (!response?.success) {
58
+ showAlert?.({ message: response?.reason || 'Failed to update panelists', type: 'danger', duration: 3000 });
59
+ }
60
+ }
61
+ );
62
+ };
63
+
64
+ export const addPanelist = async ({
65
+ socket,
66
+ participant,
67
+ currentPanelists,
68
+ maxPanelists,
69
+ roomName,
70
+ member: _member,
71
+ islevel,
72
+ showAlert,
73
+ }: AddPanelistOptions): Promise<boolean> => {
74
+ if (islevel !== '2') {
75
+ showAlert?.({ message: 'Only the host can add panelists', type: 'danger', duration: 3000 });
76
+ return false;
77
+ }
78
+
79
+ if (currentPanelists.some((p) => p.id === participant.id)) {
80
+ showAlert?.({ message: `${participant.name} is already a panelist`, type: 'success', duration: 3000 });
81
+ return false;
82
+ }
83
+
84
+ if (currentPanelists.length >= maxPanelists) {
85
+ showAlert?.({ message: `Maximum panelist limit (${maxPanelists}) reached`, type: 'danger', duration: 3000 });
86
+ return false;
87
+ }
88
+
89
+ return new Promise((resolve) => {
90
+ socket.emit(
91
+ 'addPanelist',
92
+ {
93
+ participantId: participant.id,
94
+ participantName: participant.name,
95
+ roomName,
96
+ },
97
+ (response: { success: boolean; reason?: string }) => {
98
+ if (!response?.success) {
99
+ showAlert?.({ message: response?.reason || 'Failed to add panelist', type: 'danger', duration: 3000 });
100
+ resolve(false);
101
+ } else {
102
+ resolve(true);
103
+ }
104
+ }
105
+ );
106
+ });
107
+ };
108
+
109
+ export const removePanelist = async ({
110
+ socket,
111
+ participant,
112
+ roomName,
113
+ member: _member,
114
+ islevel,
115
+ showAlert,
116
+ }: RemovePanelistOptions): Promise<void> => {
117
+ if (islevel !== '2') {
118
+ showAlert?.({ message: 'Only the host can remove panelists', type: 'danger', duration: 3000 });
119
+ return;
120
+ }
121
+
122
+ socket.emit(
123
+ 'removePanelist',
124
+ {
125
+ participantId: participant.id,
126
+ participantName: participant.name,
127
+ roomName,
128
+ },
129
+ (response: { success: boolean; reason?: string }) => {
130
+ if (!response?.success) {
131
+ showAlert?.({ message: response?.reason || 'Failed to remove panelist', type: 'danger', duration: 3000 });
132
+ }
133
+ }
134
+ );
135
+ };
@@ -0,0 +1,3 @@
1
+ export * from './launchPermissions';
2
+ export * from './updateParticipantPermission';
3
+ export * from './updatePermissionConfig';
@@ -0,0 +1,13 @@
1
+ export interface LaunchPermissionsOptions {
2
+ updateIsPermissionsModalVisible: (visible: boolean) => void;
3
+ isPermissionsModalVisible: boolean;
4
+ }
5
+
6
+ export type LaunchPermissionsType = (options: LaunchPermissionsOptions) => void;
7
+
8
+ export const launchPermissions = ({
9
+ updateIsPermissionsModalVisible,
10
+ isPermissionsModalVisible,
11
+ }: LaunchPermissionsOptions): void => {
12
+ updateIsPermissionsModalVisible(!isPermissionsModalVisible);
13
+ };
@@ -0,0 +1,127 @@
1
+ import { Socket } from 'socket.io-client';
2
+ import type { Participant, ShowAlert } from '../../types/types';
3
+
4
+ export type PermissionLevel = '0' | '1' | '2';
5
+
6
+ export interface UpdateParticipantPermissionOptions {
7
+ socket: Socket;
8
+ participant: Participant;
9
+ newLevel: PermissionLevel;
10
+ member: string;
11
+ islevel: string;
12
+ roomName: string;
13
+ showAlert?: ShowAlert;
14
+ }
15
+
16
+ export interface BulkUpdateParticipantPermissionsOptions {
17
+ socket: Socket;
18
+ participants: Participant[];
19
+ newLevel: PermissionLevel;
20
+ member: string;
21
+ islevel: string;
22
+ roomName: string;
23
+ showAlert?: ShowAlert;
24
+ maxBatchSize?: number;
25
+ }
26
+
27
+ export const updateParticipantPermission = async ({
28
+ socket,
29
+ participant,
30
+ newLevel,
31
+ member: _member,
32
+ islevel,
33
+ roomName,
34
+ showAlert,
35
+ }: UpdateParticipantPermissionOptions): Promise<void> => {
36
+ if (islevel !== '2') {
37
+ showAlert?.({ message: 'Only the host can update participant permissions', type: 'danger', duration: 3000 });
38
+ return;
39
+ }
40
+
41
+ if (participant.islevel === '2') {
42
+ showAlert?.({ message: "Cannot change the host's permission level", type: 'danger', duration: 3000 });
43
+ return;
44
+ }
45
+
46
+ if (participant.islevel === newLevel) return;
47
+
48
+ return new Promise<void>((resolve) => {
49
+ socket.emit(
50
+ 'updateParticipantPermission',
51
+ {
52
+ participantId: participant.id,
53
+ participantName: participant.name,
54
+ newLevel,
55
+ roomName,
56
+ },
57
+ (response: { success: boolean; reason?: string }) => {
58
+ if (!response?.success) {
59
+ showAlert?.({ message: response?.reason || 'Failed to update permission', type: 'danger', duration: 3000 });
60
+ }
61
+ resolve();
62
+ }
63
+ );
64
+ });
65
+ };
66
+
67
+ export const bulkUpdateParticipantPermissions = async ({
68
+ socket,
69
+ participants,
70
+ newLevel,
71
+ member: _member,
72
+ islevel,
73
+ roomName,
74
+ showAlert,
75
+ maxBatchSize = 50,
76
+ }: BulkUpdateParticipantPermissionsOptions): Promise<void> => {
77
+ if (islevel !== '2') {
78
+ showAlert?.({ message: 'Only the host can update participant permissions', type: 'danger', duration: 3000 });
79
+ return;
80
+ }
81
+
82
+ const eligibleParticipants = participants.filter(
83
+ (p) => p.islevel !== '2' && p.islevel !== newLevel
84
+ );
85
+
86
+ if (eligibleParticipants.length === 0) {
87
+ showAlert?.({
88
+ message: 'No participants to update',
89
+ type: 'info',
90
+ duration: 3000,
91
+ });
92
+ return;
93
+ }
94
+
95
+ const batch = eligibleParticipants.slice(0, maxBatchSize);
96
+
97
+ return new Promise<void>((resolve) => {
98
+ socket.emit(
99
+ 'bulkUpdateParticipantPermissions',
100
+ {
101
+ updates: batch.map((p) => ({
102
+ participantId: p.id,
103
+ participantName: p.name,
104
+ newLevel,
105
+ })),
106
+ roomName,
107
+ },
108
+ (response: { success: boolean; reason?: string }) => {
109
+ if (!response?.success) {
110
+ showAlert?.({
111
+ message: response?.reason || 'Failed to update permissions',
112
+ type: 'danger',
113
+ duration: 3000,
114
+ });
115
+ } else if (eligibleParticipants.length > maxBatchSize) {
116
+ showAlert?.({
117
+ message: `Updated ${batch.length} participants. ${eligibleParticipants.length - maxBatchSize} remaining.`,
118
+ type: 'info',
119
+ duration: 3000,
120
+ });
121
+ }
122
+
123
+ resolve();
124
+ }
125
+ );
126
+ });
127
+ };
@@ -0,0 +1,52 @@
1
+ import { Socket } from 'socket.io-client';
2
+ import type { ShowAlert } from '../../types/types';
3
+
4
+ export interface PermissionCapabilities {
5
+ useMic: 'allow' | 'approval' | 'disallow';
6
+ useCamera: 'allow' | 'approval' | 'disallow';
7
+ useScreen: 'allow' | 'approval' | 'disallow';
8
+ useChat: 'allow' | 'disallow';
9
+ }
10
+
11
+ export interface PermissionConfig {
12
+ level0: PermissionCapabilities;
13
+ level1: PermissionCapabilities;
14
+ }
15
+
16
+ export interface UpdatePermissionConfigOptions {
17
+ socket: Socket;
18
+ config: PermissionConfig;
19
+ member: string;
20
+ islevel: string;
21
+ roomName: string;
22
+ showAlert?: ShowAlert;
23
+ }
24
+
25
+ export const updatePermissionConfig = async ({
26
+ socket,
27
+ config,
28
+ islevel,
29
+ roomName,
30
+ showAlert,
31
+ }: UpdatePermissionConfigOptions): Promise<void> => {
32
+ if (islevel !== '2') {
33
+ showAlert?.({ message: 'Only the host can update permission configuration', type: 'danger', duration: 3000 });
34
+ return;
35
+ }
36
+
37
+ return new Promise<void>((resolve) => {
38
+ socket.emit(
39
+ 'updatePermissionConfig',
40
+ {
41
+ config,
42
+ roomName,
43
+ },
44
+ (response: { success: boolean; reason?: string }) => {
45
+ if (!response?.success) {
46
+ showAlert?.({ message: response?.reason || 'Failed to update permission config', type: 'danger', duration: 3000 });
47
+ }
48
+ resolve();
49
+ }
50
+ );
51
+ });
52
+ };
@@ -0,0 +1,88 @@
1
+ import type { Poll, PollUpdatedData, ShowAlert } from '../../types/types';
2
+
3
+ export interface PollUpdatedOptions {
4
+ data: PollUpdatedData;
5
+ polls: Poll[];
6
+ poll: Poll;
7
+ member: string;
8
+ islevel: string;
9
+ showAlert?: ShowAlert;
10
+ updatePolls: (polls: Poll[]) => void;
11
+ updatePoll: (poll: Poll) => void;
12
+ updateIsPollModalVisible: (isVisible: boolean) => void;
13
+ }
14
+
15
+ export type PollUpdatedType = (options: PollUpdatedOptions) => Promise<void>;
16
+
17
+ /**
18
+ * Reconciles poll update payloads with current poll state.
19
+ *
20
+ * This helper updates the poll collection, manages active poll visibility, and
21
+ * emits user-facing alerts when a new poll starts or an active poll ends.
22
+ *
23
+ * @param options Poll update handling options.
24
+ * @returns A promise that resolves after local poll state has been synchronized.
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * await pollUpdated({
29
+ * data,
30
+ * polls,
31
+ * poll,
32
+ * member: 'Ada',
33
+ * islevel: '1',
34
+ * updatePolls: setPolls,
35
+ * updatePoll: setCurrentPoll,
36
+ * updateIsPollModalVisible: setPollModalVisible,
37
+ * });
38
+ * ```
39
+ */
40
+ export const pollUpdated = async ({
41
+ data,
42
+ polls,
43
+ poll,
44
+ member,
45
+ islevel,
46
+ showAlert,
47
+ updatePolls,
48
+ updatePoll,
49
+ updateIsPollModalVisible,
50
+ }: PollUpdatedOptions): Promise<void> => {
51
+ try {
52
+ if (data.polls) {
53
+ polls = data.polls;
54
+ updatePolls(data.polls);
55
+ } else {
56
+ polls = [data.poll];
57
+ updatePolls(polls);
58
+ }
59
+
60
+ let tempPoll: Poll | { id: string } = { id: '' };
61
+
62
+ if (poll) {
63
+ tempPoll = { ...poll };
64
+ }
65
+
66
+ if (data.status !== 'ended') {
67
+ poll = data.poll;
68
+ updatePoll(data.poll);
69
+ }
70
+
71
+ if (data.status === 'started' && islevel !== '2') {
72
+ if (!poll.voters || (poll.voters && !poll.voters[member])) {
73
+ showAlert?.({
74
+ message: 'New poll started',
75
+ type: 'success',
76
+ duration: 3000,
77
+ });
78
+ updateIsPollModalVisible(true);
79
+ }
80
+ } else if (data.status === 'ended') {
81
+ if (tempPoll.id === data.poll.id) {
82
+ showAlert?.({ message: 'Poll ended', type: 'danger', duration: 3000 });
83
+ updatePoll(data.poll);
84
+ }
85
+ }
86
+ } catch {
87
+ }
88
+ };