-
Notifications
You must be signed in to change notification settings - Fork 13k
feat: Media Call Client #36717
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
feat: Media Call Client #36717
Changes from all commits
Commits
Show all changes
88 commits
Select commit
Hold shift + click to select a range
60ceee8
WIP
gabriellsh e227c0d
Partially update impl
gabriellsh 9e0a391
lockfile
gabriellsh 88817a6
Implement sounds
gabriellsh 2b1e4d8
Send signals through stream
gabriellsh 1f4186a
Fix hangup
gabriellsh 91d114d
get correct peerinfo
gabriellsh effa92c
Fix stream not stopping
gabriellsh 49d7c0e
fix null node
gabriellsh becdc6f
Remove "old" voip
gabriellsh c4c9345
call instantly from hoom header
gabriellsh cb044ad
Update headerv2
gabriellsh 99eea31
Update toggle and peerInfo type. Get peerInfo from call/autocomplete …
gabriellsh 3a8fee6
Update call buttons
gabriellsh 30ddbf2
Update user menu
gabriellsh 3994429
extend webrtc processor and implement mute
gabriellsh 0bbcc5d
Implement hold
gabriellsh 1152833
ForwardRef for devicePickerButton
gabriellsh 5adc96b
WIP permission modals
gabriellsh eea0ce0
Fix Device change and lingering picker issues
gabriellsh 0d535df
Fix ts
gabriellsh af42960
implement ice config and fix lingering stream after switching devices
gabriellsh 4ba2dcb
Reflect base changes in client impl
gabriellsh 0fd92b2
Fix device picker disabled in some cases
gabriellsh a7931e2
Fix device list update & use previously selected device for new calls
gabriellsh 4647b5f
Fix pre-selected device
gabriellsh 508fcc8
add new translation strings
gabriellsh 6851f2a
Improve media call buttons
gabriellsh 2ebedf5
exclude own user from users list
gabriellsh 5818b47
Fix import
gabriellsh 5d7e57e
fix changed signatures
gabriellsh b7c5ac1
Update header actions
gabriellsh 034b8bc
fix useUserMenu
gabriellsh fb4f0a3
Update Icon
gabriellsh 72ea4c7
update `onCall`
gabriellsh 5b7c1e0
Remove old `useMediaCallAction`
gabriellsh a715a11
update MediaCallWidget.stories
gabriellsh 91d4e9c
fix Icon
gabriellsh 4c699d9
move `useMediaSessionInstance` to it's own file
gabriellsh a6cf548
Implement transfer modal
gabriellsh f2b1f27
Fix type imports
gabriellsh 4acae93
Fix translations
gabriellsh 8e4cd9d
Fix TS and memoized peerInfo
gabriellsh 5d381e0
Update contact avatar and session events
gabriellsh f296d79
Update instance implementation
gabriellsh b55e1b8
Update device switching
gabriellsh e22f9ec
Fix cbref type
gabriellsh 321239b
Cleanup session instance
gabriellsh bdecd09
Fix SessionId
gabriellsh 03c3ec8
Finish call transfering
gabriellsh b318288
Ensure all fns exist before instantiating
gabriellsh 41d9f0e
Add in-between states
gabriellsh db831c0
add connectionState
gabriellsh 9b48646
Fix connection state
gabriellsh 4525984
Hidden Calls
gabriellsh 91f7318
Reject incoming call when canceling permission request
gabriellsh 00007ac
Fallback to denied permission modal if prompt fails (safari)
gabriellsh d979f96
Fix device selection constraints
gabriellsh fc15a18
Fix random id generator
gabriellsh 9ebb798
Add button to user card
gabriellsh b2789f6
Fix device selection through keyboard
gabriellsh f546145
Fix cannot change output device if no call in progress
gabriellsh 7002534
change togglebutton tooltip based on pressed state
gabriellsh 7c657eb
update transfer modal with inline errors
gabriellsh 7961225
pass more information for transfer onConfirm
gabriellsh c77e386
success message on transfer
gabriellsh 8052e8b
Close transfer modal if call ends
gabriellsh e6ea8ea
Fix `*` size in keypad
gabriellsh ada4486
remove call action from blocked rooms
gabriellsh 4c1a6da
Exclude current peer from list
gabriellsh 2ef9a88
Permissions and license check
gabriellsh 6948361
remove logger
gabriellsh 8a100b5
Cleanup
gabriellsh 061f552
dtmf
gabriellsh ba3c306
Update snapshots
gabriellsh 3d0000a
Add changeset
gabriellsh ccd96fb
typo
gabriellsh 0d22733
memoize external provider values
gabriellsh 8f65055
Merge branch 'develop' into feat/mediaCallClient
gabriellsh f3fabe2
retrieve missed changes
gabriellsh 3c0a25f
remove duplicate key
gabriellsh a265e1d
Move files to v2
gabriellsh 2f35b65
remove comments
gabriellsh 699e952
remove from room header when blocked
gabriellsh aeb4a5d
update lockfile
gabriellsh 8a3e042
review
gabriellsh f0ff773
change prop naming to large
gabriellsh f657c2d
Merge branch 'develop' into feat/mediaCallClient
gabriellsh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| --- | ||
| "@rocket.chat/meteor": minor | ||
| "@rocket.chat/i18n": minor | ||
| "@rocket.chat/ui-voip": minor | ||
| --- | ||
|
|
||
| Introduces a new voice call architecture along with a new and improved call widget experience. |
16 changes: 0 additions & 16 deletions
16
apps/meteor/client/NavBarV2/NavBarVoipGroup/NavBarItemVoipDialer.tsx
This file was deleted.
Oops, something went wrong.
16 changes: 5 additions & 11 deletions
16
apps/meteor/client/NavBarV2/NavBarVoipGroup/NavBarVoipGroup.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 71 additions & 0 deletions
71
apps/meteor/client/hooks/roomActions/useMediaCallRoomAction.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| import type { TranslationKey } from '@rocket.chat/ui-contexts'; | ||
| import { useUserAvatarPath, useUserId } from '@rocket.chat/ui-contexts'; | ||
| import type { PeerInfo } from '@rocket.chat/ui-voip'; | ||
| import { useMediaCallAction } from '@rocket.chat/ui-voip'; | ||
| import { useMemo } from 'react'; | ||
|
|
||
| import { useRoom, useRoomSubscription } from '../../views/room/contexts/RoomContext'; | ||
| import type { RoomToolboxActionConfig } from '../../views/room/contexts/RoomToolboxContext'; | ||
| import { useUserInfoQuery } from '../useUserInfoQuery'; | ||
|
|
||
| const getPeerId = (uids: string[], ownUserId: string | null) => { | ||
| if (!ownUserId) { | ||
| return undefined; | ||
| } | ||
|
|
||
| const otherIds = uids.filter((uid) => uid !== ownUserId); | ||
|
|
||
| // If no id, it's an one user DM. If more than one, it's a group dm. Both are not supported as of now. | ||
| if (otherIds.length === 0 || otherIds.length > 1) { | ||
| return undefined; | ||
| } | ||
|
|
||
| return otherIds[0]; | ||
| }; | ||
|
|
||
| export const useMediaCallRoomAction = () => { | ||
| const { uids = [] } = useRoom(); | ||
| const subscription = useRoomSubscription(); | ||
| const ownUserId = useUserId(); | ||
|
|
||
| const getAvatarUrl = useUserAvatarPath(); | ||
|
|
||
| const peerId = getPeerId(uids, ownUserId); | ||
|
|
||
| const { data } = useUserInfoQuery({ userId: peerId as string }, { enabled: !!peerId }); | ||
|
|
||
| const peerInfo = useMemo<PeerInfo | undefined>(() => { | ||
| if (!data?.user?._id) { | ||
| return undefined; | ||
| } | ||
|
|
||
| return { | ||
| userId: data.user._id, | ||
| displayName: data.user.name || data.user.username || '', | ||
| avatarUrl: data.user.username | ||
| ? getAvatarUrl({ username: data.user.username, etag: data.user.avatarETag }) | ||
| : getAvatarUrl({ userId: data.user._id }), | ||
| }; | ||
| }, [data, getAvatarUrl]); | ||
|
|
||
| const callAction = useMediaCallAction(peerInfo); | ||
|
|
||
| const blocked = subscription?.blocked || subscription?.blocker; | ||
|
|
||
| return useMemo((): RoomToolboxActionConfig | undefined => { | ||
| if (!peerId || !callAction || blocked) { | ||
| return undefined; | ||
| } | ||
|
|
||
| const { action, title, icon } = callAction; | ||
|
|
||
| return { | ||
| id: 'start-voice-call', | ||
gabriellsh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| title: title as TranslationKey, | ||
gabriellsh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| icon, | ||
| featured: true, | ||
| action: () => action(), | ||
| groups: ['direct'] as const, | ||
| }; | ||
| }, [peerId, callAction, blocked]); | ||
| }; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| import { usePermission } from '@rocket.chat/ui-contexts'; | ||
| import { MediaCallProvider as MediaCallProviderBase, MediaCallContext } from '@rocket.chat/ui-voip'; | ||
gabriellsh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| import type { ReactNode } from 'react'; | ||
| import { useMemo } from 'react'; | ||
|
|
||
| import { useHasLicenseModule } from '../hooks/useHasLicenseModule'; | ||
| import { useVoipWarningModal } from '../hooks/useVoipWarningModal'; | ||
|
|
||
| const MediaCallProvider = ({ children }: { children: ReactNode }) => { | ||
| const dispatchWarning = useVoipWarningModal(); | ||
|
|
||
| const canMakeInternalCall = usePermission('allow-internal-voice-calls'); | ||
| const canMakeExternalCall = usePermission('allow-external-voice-calls'); | ||
|
|
||
| const hasModule = useHasLicenseModule('teams-voip'); | ||
|
|
||
| const unauthorizedContextValue = useMemo( | ||
| () => ({ | ||
| state: 'unauthorized' as const, | ||
| onToggleWidget: undefined, | ||
| onEndCall: undefined, | ||
| peerInfo: undefined, | ||
| }), | ||
| [], | ||
| ); | ||
|
|
||
| const unlicensedContextValue = useMemo( | ||
| () => ({ | ||
| state: 'unlicensed' as const, | ||
| onToggleWidget: dispatchWarning, | ||
| onEndCall: undefined, | ||
| peerInfo: undefined, | ||
| }), | ||
| [dispatchWarning], | ||
| ); | ||
|
|
||
| if (!hasModule) { | ||
| return <MediaCallContext.Provider value={unlicensedContextValue}>{children}</MediaCallContext.Provider>; | ||
| } | ||
|
|
||
| if (!canMakeInternalCall && !canMakeExternalCall) { | ||
| return <MediaCallContext.Provider value={unauthorizedContextValue}>{children}</MediaCallContext.Provider>; | ||
| } | ||
|
|
||
| return <MediaCallProviderBase>{children}</MediaCallProviderBase>; | ||
| }; | ||
|
|
||
| export default MediaCallProvider; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
50 changes: 50 additions & 0 deletions
50
apps/meteor/client/views/room/hooks/useUserInfoActions/actions/useUserMediaCallAction.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| import type { IRoom, IUser } from '@rocket.chat/core-typings'; | ||
| import { useUserAvatarPath, useUserId, useUserSubscription } from '@rocket.chat/ui-contexts'; | ||
| import { useMediaCallContext } from '@rocket.chat/ui-voip'; | ||
| import { useTranslation } from 'react-i18next'; | ||
|
|
||
| import { useUserCard } from '../../../contexts/UserCardContext'; | ||
| import type { UserInfoAction } from '../useUserInfoActions'; | ||
|
|
||
| export const useUserMediaCallAction = (user: Pick<IUser, '_id' | 'username' | 'name'>, rid: IRoom['_id']): UserInfoAction | undefined => { | ||
| const { t } = useTranslation(); | ||
| const ownUserId = useUserId(); | ||
| const { closeUserCard } = useUserCard(); | ||
| const { state, onToggleWidget } = useMediaCallContext(); | ||
| const getAvatarUrl = useUserAvatarPath(); | ||
|
|
||
| const currentSubscription = useUserSubscription(rid); | ||
|
|
||
| const blocked = currentSubscription?.blocked || currentSubscription?.blocker; | ||
|
|
||
| if (state === 'unauthorized') { | ||
| return undefined; | ||
| } | ||
|
|
||
| if (blocked) { | ||
| return undefined; | ||
| } | ||
|
|
||
| const disabled = !['closed', 'new', 'unlicensed'].includes(state); | ||
|
|
||
gabriellsh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if (user._id === ownUserId) { | ||
| return undefined; | ||
| } | ||
|
|
||
| const avatarUrl = user.username ? getAvatarUrl({ username: user.username }) : getAvatarUrl({ userId: user._id }); | ||
|
|
||
| return { | ||
| type: 'communication', | ||
| title: t('Voice_call__user_', { user: user.name || user.username || '' }), | ||
| icon: 'phone', | ||
| onClick: () => { | ||
| closeUserCard(); | ||
| onToggleWidget({ | ||
| userId: user._id, | ||
| displayName: user.name || user.username || '', | ||
| avatarUrl, | ||
| }); | ||
| }, | ||
| disabled, | ||
| }; | ||
| }; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.