diff --git a/packages/hms-video-store/src/index.ts b/packages/hms-video-store/src/index.ts index ad9e01d8cd..69f95cf389 100644 --- a/packages/hms-video-store/src/index.ts +++ b/packages/hms-video-store/src/index.ts @@ -18,6 +18,7 @@ export { parsedUserAgent, simulcastMapping, DeviceType, + HMSPeerType, } from './internal'; export type { @@ -51,7 +52,6 @@ export type { HMSPollQuestionOption, HMSQuizLeaderboardResponse, HMSQuizLeaderboardSummary, - HMSPeerType, } from './internal'; export { EventBus } from './events/EventBus'; diff --git a/packages/hms-video-store/src/interfaces/peer/hms-peer.ts b/packages/hms-video-store/src/interfaces/peer/hms-peer.ts index f3788b964d..e3100831ad 100644 --- a/packages/hms-video-store/src/interfaces/peer/hms-peer.ts +++ b/packages/hms-video-store/src/interfaces/peer/hms-peer.ts @@ -1,7 +1,10 @@ import { HMSAudioTrack, HMSTrack, HMSVideoTrack } from '../../media/tracks'; import { HMSRole } from '../role'; -export type HMSPeerType = 'sip' | 'regular'; +export enum HMSPeerType { + SIP = 'sip', + REGULAR = 'regular', +} export interface HMSPeer { peerId: string; diff --git a/packages/hms-video-store/src/interfaces/peer/index.ts b/packages/hms-video-store/src/interfaces/peer/index.ts index 1b4b1f69af..c92ba38909 100644 --- a/packages/hms-video-store/src/interfaces/peer/index.ts +++ b/packages/hms-video-store/src/interfaces/peer/index.ts @@ -1,4 +1,5 @@ -export type { HMSPeer, HMSPeerType } from './hms-peer'; +export type { HMSPeer } from './hms-peer'; export type { HMSLocalPeer } from './hms-local-peer'; export type { HMSRemotePeer } from './hms-remote-peer'; export type { HMSConnectionQuality } from './connection-quality'; +export { HMSPeerType } from './hms-peer'; diff --git a/packages/hms-video-store/src/notification-manager/fixtures.ts b/packages/hms-video-store/src/notification-manager/fixtures.ts index 0764ff3985..5bb8fe4485 100644 --- a/packages/hms-video-store/src/notification-manager/fixtures.ts +++ b/packages/hms-video-store/src/notification-manager/fixtures.ts @@ -1,10 +1,11 @@ import { MessageNotification, PeerListNotification, PeerNotification, SpeakerList } from './HMSNotifications'; +import { HMSPeerType } from '../interfaces'; export const FAKE_PEER_ID = 'peer_id_1'; export const fakePeer: PeerNotification = { peer_id: 'peer_id_0', - info: { data: 'data', name: 'Sarvesh0', user_id: 'customer_user_id', type: 'regular' }, + info: { data: 'data', name: 'Sarvesh0', user_id: 'customer_user_id', type: HMSPeerType.REGULAR }, role: 'host', tracks: {}, groups: [], @@ -17,7 +18,7 @@ export const fakePeerList: PeerListNotification = { name: 'Sarvesh1', data: 'data', user_id: 'customer_user_id', - type: 'regular', + type: HMSPeerType.REGULAR, }, role: 'host', peer_id: FAKE_PEER_ID, @@ -33,7 +34,7 @@ export const fakePeerList: PeerListNotification = { track_id_2: { mute: false, type: 'video', - source: 'regular', + source: HMSPeerType.REGULAR, description: '', track_id: 'track_id_2', stream_id: 'stream_id_1', @@ -46,7 +47,7 @@ export const fakePeerList: PeerListNotification = { name: 'Sarvesh3', data: 'data', user_id: 'customer_user_id', - type: 'regular', + type: HMSPeerType.REGULAR, }, peer_id: 'peer_id_3', role: 'viewer', @@ -87,7 +88,7 @@ export const fakeReconnectPeerList: PeerListNotification = { name: 'Sarvesh1', data: 'data', user_id: 'customer_user_id', - type: 'regular', + type: HMSPeerType.REGULAR, }, role: 'host', peer_id: FAKE_PEER_ID, @@ -103,7 +104,7 @@ export const fakeReconnectPeerList: PeerListNotification = { track_id_2: { mute: false, type: 'video', - source: 'regular', + source: HMSPeerType.REGULAR, description: '', track_id: 'track_id_2', stream_id: 'stream_id_1', @@ -116,7 +117,7 @@ export const fakeReconnectPeerList: PeerListNotification = { name: 'Sarvesh2', data: 'data', user_id: 'customer_user_id', - type: 'regular', + type: HMSPeerType.REGULAR, }, peer_id: 'peer_id_2', role: 'viewer', diff --git a/packages/hms-video-store/src/sdk/LocalTrackManager.test.ts b/packages/hms-video-store/src/sdk/LocalTrackManager.test.ts index c7088c3c90..34f1dd8e44 100644 --- a/packages/hms-video-store/src/sdk/LocalTrackManager.test.ts +++ b/packages/hms-video-store/src/sdk/LocalTrackManager.test.ts @@ -5,7 +5,7 @@ import { AnalyticsTimer } from '../analytics/AnalyticsTimer'; import { DeviceManager } from '../device-manager'; import { HMSException } from '../error/HMSException'; import { EventBus } from '../events/EventBus'; -import { HMSLocalVideoTrack, HMSTrackType } from '../internal'; +import { HMSLocalVideoTrack, HMSPeerType, HMSTrackType } from '../internal'; import { HMSLocalStream } from '../media/streams/HMSLocalStream'; import { HMSTrack } from '../media/tracks'; import { PolicyParams } from '../notification-manager'; @@ -96,7 +96,7 @@ const publishParams = hostRole.publishParams; let localPeer = new HMSLocalPeer({ name: 'test', role: hostRole, - type: 'regular', + type: HMSPeerType.REGULAR, }); testStore.addPeer(localPeer); @@ -232,7 +232,7 @@ describe('LocalTrackManager', () => { localPeer = new HMSLocalPeer({ name: 'test', role: hostRole, - type: 'regular', + type: HMSPeerType.REGULAR, }); testStore.addPeer(localPeer); }); @@ -410,7 +410,7 @@ describe('LocalTrackManager', () => { localPeer = new HMSLocalPeer({ name: 'test', role: hostRole, - type: 'regular', + type: HMSPeerType.REGULAR, }); testStore.addPeer(localPeer); mockGetUserMedia.mockClear(); @@ -424,7 +424,7 @@ describe('LocalTrackManager', () => { kind: 'video', getSettings: () => ({ deviceId: 'video-device-id', groupId: 'video-group-id' }), } as MediaStreamTrack, - 'regular', + HMSPeerType.REGULAR, testEventBus, ); localPeer.videoTrack = mockVideoTrack; @@ -456,7 +456,7 @@ describe('LocalTrackManager', () => { kind: 'video', getSettings: () => ({ deviceId: 'video-device-id', groupId: 'video-group-id' }), } as MediaStreamTrack, - 'regular', + HMSPeerType.REGULAR, testEventBus, ); diff --git a/packages/hms-video-store/src/sdk/index.ts b/packages/hms-video-store/src/sdk/index.ts index 3532316635..2793872f90 100644 --- a/packages/hms-video-store/src/sdk/index.ts +++ b/packages/hms-video-store/src/sdk/index.ts @@ -28,6 +28,7 @@ import { HMSDeviceChangeEvent, HMSFrameworkInfo, HMSMessageInput, + HMSPeerType, HMSPlaylistSettings, HMSPlaylistType, HMSPreviewConfig, @@ -1300,7 +1301,7 @@ export class HMSSdk implements HMSInterface { role: policy, // default value is the original role if user didn't pass asRole in config asRole: asRolePolicy || policy, - type: 'regular', + type: HMSPeerType.REGULAR, }); this.store.addPeer(localPeer); diff --git a/packages/hms-video-store/src/sdk/models/peer/peer.test.ts b/packages/hms-video-store/src/sdk/models/peer/peer.test.ts index b463bf03ff..f9c51519e0 100644 --- a/packages/hms-video-store/src/sdk/models/peer/peer.test.ts +++ b/packages/hms-video-store/src/sdk/models/peer/peer.test.ts @@ -46,7 +46,7 @@ describe('HMSLocalPeer', () => { name: 'John Doe', role: getParamsForRole(role), customerUserId: userId, - type: 'regular' as HMSPeerType, + type: HMSPeerType.REGULAR as HMSPeerType, }; const peer = new HMSLocalPeer(params); @@ -82,7 +82,7 @@ describe('HMSRemotPeer', () => { name: 'John Doe', data: 'data', user_id: 'customer_user_id', - type: 'regular', + type: HMSPeerType.REGULAR, }, role: 'viewer', tracks: {}, @@ -94,7 +94,7 @@ describe('HMSRemotPeer', () => { role: getParamsForRole(peerInfo.role), customerUserId: peerInfo.info.user_id, metadata: peerInfo.info.data, - type: 'regular', + type: HMSPeerType.REGULAR, }); it('should be constructed using params', () => { diff --git a/packages/hms-video-store/src/selectors/selectorsByID.ts b/packages/hms-video-store/src/selectors/selectorsByID.ts index 88f123e27c..9b8ded6e9f 100644 --- a/packages/hms-video-store/src/selectors/selectorsByID.ts +++ b/packages/hms-video-store/src/selectors/selectorsByID.ts @@ -163,6 +163,8 @@ export const selectAppDataByPath = (...keys: string[]) => */ export const selectPeerNameByID = byIDCurry(createSelector(selectPeerByIDBare, peer => peer?.name)); +export const selectPeerTypeByID = byIDCurry(createSelector(selectPeerByIDBare, peer => peer?.type)); + /** * Select the {@link HMSTrack} object given a track ID. */ diff --git a/packages/hms-video-store/src/test/fakeStore/fakeHMSStore.ts b/packages/hms-video-store/src/test/fakeStore/fakeHMSStore.ts index 16cd092863..abee93b855 100644 --- a/packages/hms-video-store/src/test/fakeStore/fakeHMSStore.ts +++ b/packages/hms-video-store/src/test/fakeStore/fakeHMSStore.ts @@ -9,7 +9,7 @@ import { HMSTrackSource, HMSTrackType, } from '../../'; -import { HMSSimulcastLayer } from '../../internal'; +import { HMSPeerType, HMSSimulcastLayer } from '../../internal'; import { HMSAudioTrack, HMSPlaylist, HMSPlaylistType, HMSRole, HMSScreenVideoTrack, HMSVideoTrack } from '../../schema'; function makeTrack( @@ -98,7 +98,7 @@ export const makeFakeStore = (): HMSStore => { metadata: '{}', groups: [], isHandRaised: false, - type: 'regular', + type: HMSPeerType.REGULAR, }, '2': { id: '2', @@ -111,7 +111,7 @@ export const makeFakeStore = (): HMSStore => { metadata: '{"hello":"world"}', groups: [], isHandRaised: false, - type: 'regular', + type: HMSPeerType.REGULAR, }, '3': { id: '3', @@ -123,16 +123,16 @@ export const makeFakeStore = (): HMSStore => { auxiliaryTracks: [], groups: [], isHandRaised: false, - type: 'regular', + type: HMSPeerType.REGULAR, }, }, tracks: { - '101': makeTrack('101', 'video', 'regular', '1'), - '102': makeTrack('102', 'audio', 'regular', '1'), - '103': makeTrack('103', 'video', 'regular', '2'), - '104': makeTrack('104', 'audio', 'regular', '2'), + '101': makeTrack('101', 'video', HMSPeerType.REGULAR, '1'), + '102': makeTrack('102', 'audio', HMSPeerType.REGULAR, '1'), + '103': makeTrack('103', 'video', HMSPeerType.REGULAR, '2'), + '104': makeTrack('104', 'audio', HMSPeerType.REGULAR, '2'), '105': makeTrack('105', 'video', 'screen', '2'), - '106': makeTrack('106', 'audio', 'regular', '2'), + '106': makeTrack('106', 'audio', HMSPeerType.REGULAR, '2'), '107': makeTrack('107', 'audio', 'screen', '2'), }, playlist: { diff --git a/packages/hms-video-store/src/test/fixtures.ts b/packages/hms-video-store/src/test/fixtures.ts index af71471999..1db9e7ac2c 100644 --- a/packages/hms-video-store/src/test/fixtures.ts +++ b/packages/hms-video-store/src/test/fixtures.ts @@ -1,3 +1,4 @@ +import { HMSPeerType } from '../interfaces'; import { HMSAudioTrack, HMSPeer, HMSTrackType, HMSVideoTrack } from '../'; let counter = 100; @@ -20,6 +21,6 @@ export const makeFakePeer = (): HMSPeer => { videoTrack: '', groups: [], isHandRaised: false, - type: 'regular', + type: HMSPeerType.REGULAR, }; }; diff --git a/packages/react-icons/assets/CallIcon.svg b/packages/react-icons/assets/CallIcon.svg new file mode 100644 index 0000000000..5179faad6b --- /dev/null +++ b/packages/react-icons/assets/CallIcon.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/react-icons/src/CallIcon.tsx b/packages/react-icons/src/CallIcon.tsx new file mode 100644 index 0000000000..2a8656dcf5 --- /dev/null +++ b/packages/react-icons/src/CallIcon.tsx @@ -0,0 +1,11 @@ +import * as React from 'react'; +import { SVGProps } from 'react'; +const SvgCallIcon = (props: SVGProps) => ( + + + +); +export default SvgCallIcon; diff --git a/packages/react-icons/src/index.ts b/packages/react-icons/src/index.ts index 6516a7e3a2..267cae5f6b 100644 --- a/packages/react-icons/src/index.ts +++ b/packages/react-icons/src/index.ts @@ -44,6 +44,7 @@ export { default as BuildingIcon } from './BuildingIcon'; export { default as CalculatorIcon } from './CalculatorIcon'; export { default as CalculatorIconsIcon } from './CalculatorIconsIcon'; export { default as CalendarIcon } from './CalendarIcon'; +export { default as CallIcon } from './CallIcon'; export { default as CameraFlipIcon } from './CameraFlipIcon'; export { default as CardIcon } from './CardIcon'; export { default as CardWithCvcIcon } from './CardWithCvcIcon'; diff --git a/packages/roomkit-react/src/Avatar/Avatar.tsx b/packages/roomkit-react/src/Avatar/Avatar.tsx index 90ae31d39f..c9dd366d9e 100644 --- a/packages/roomkit-react/src/Avatar/Avatar.tsx +++ b/packages/roomkit-react/src/Avatar/Avatar.tsx @@ -47,14 +47,14 @@ type Props = VariantProps & }; export const Avatar: React.FC = ({ name, css, ...props }) => { - const { initials } = getAvatarBg(name); - let { color } = getAvatarBg(name); + const info = getAvatarBg(name); + let { color } = info; if (!name) { color = '#7E47EB'; } return ( - {initials || } + {info.initials || } ); }; diff --git a/packages/roomkit-react/src/Avatar/getAvatarBg.ts b/packages/roomkit-react/src/Avatar/getAvatarBg.ts index 7b7357da04..0ecc311111 100644 --- a/packages/roomkit-react/src/Avatar/getAvatarBg.ts +++ b/packages/roomkit-react/src/Avatar/getAvatarBg.ts @@ -2,13 +2,17 @@ const getInitials = (name: string | undefined) => { if (!name) { return undefined; } else { - return name - .trim() - .match(/(^\S\S?|\b\S)?/g) - ?.join('') - ?.match(/(^\S|\S$)?/g) - ?.join('') - .toUpperCase(); + return ( + name + .trim() + // remove non chars/digits + .replace(/[^a-zA-Z0-9]/g, '') + .match(/(^\S\S?|\b\S)?/g) + ?.join('') + ?.match(/(^\S|\S$)?/g) + ?.join('') + .toUpperCase() + ); } }; diff --git a/packages/roomkit-react/src/Prebuilt/components/Connection/TileConnection.tsx b/packages/roomkit-react/src/Prebuilt/components/Connection/TileConnection.tsx index a6c8852e32..c7edec3796 100644 --- a/packages/roomkit-react/src/Prebuilt/components/Connection/TileConnection.tsx +++ b/packages/roomkit-react/src/Prebuilt/components/Connection/TileConnection.tsx @@ -1,6 +1,12 @@ import React from 'react'; -import { selectScreenShareByPeerID, selectSessionStore, useHMSStore } from '@100mslive/react-sdk'; -import { PinIcon, ShareScreenIcon, SpotlightIcon } from '@100mslive/react-icons'; +import { + HMSPeerType, + selectPeerTypeByID, + selectScreenShareByPeerID, + selectSessionStore, + useHMSStore, +} from '@100mslive/react-sdk'; +import { CallIcon, PinIcon, ShareScreenIcon, SpotlightIcon } from '@100mslive/react-icons'; import { Flex, styled, Text, textEllipsis } from '../../..'; import { ConnectionIndicator } from './ConnectionIndicator'; import { SESSION_STORE_KEY } from '../../common/constants'; @@ -20,12 +26,18 @@ const TileConnection = ({ }) => { const spotlighted = useHMSStore(selectSessionStore(SESSION_STORE_KEY.SPOTLIGHT)) === peerId; const isPeerScreenSharing = !!useHMSStore(selectScreenShareByPeerID(peerId)); + const peerType = useHMSStore(selectPeerTypeByID(peerId)); return ( {!hideLabel ? ( <> {name ? ( + {peerType === HMSPeerType.SIP && ( + + + + )} {isPeerScreenSharing && ( diff --git a/packages/roomkit-react/src/Prebuilt/components/Footer/ParticipantList.tsx b/packages/roomkit-react/src/Prebuilt/components/Footer/ParticipantList.tsx index 0747fcb219..cbe59e447e 100644 --- a/packages/roomkit-react/src/Prebuilt/components/Footer/ParticipantList.tsx +++ b/packages/roomkit-react/src/Prebuilt/components/Footer/ParticipantList.tsx @@ -2,6 +2,7 @@ import React, { Fragment, useCallback, useState } from 'react'; import { useDebounce, useMedia } from 'react-use'; import { HMSPeer, + HMSPeerType, HMSRoleName, selectHandRaisedPeers, selectHasPeerHandRaised, @@ -14,6 +15,7 @@ import { } from '@100mslive/react-sdk'; import { AddIcon, + CallIcon, ChangeRoleIcon, CrossIcon, HandIcon, @@ -184,6 +186,7 @@ export const Participant = ({ {isConnected && peer.roleName ? ( { const isHandRaised = useHMSStore(selectHasPeerHandRaised(peerId)); const canChangeRole = useHMSStore(selectPermissions)?.changeRole; @@ -290,7 +295,16 @@ const ParticipantActions = React.memo( ) : ( <> - + {peerType === HMSPeerType.REGULAR && } + {peerType === HMSPeerType.SIP && ( + + + + )} {isHandRaised && ( { @@ -11,7 +11,7 @@ export const makeFakeParticipant = (name: string, role = 'Student'): HMSPeerWith isLocal: counter === 1, groups: [], isHandRaised: false, - type: 'regular', + type: HMSPeerType.REGULAR, }, isAudioEnabled: false, };