Skip to content
This repository has been archived by the owner on Oct 18, 2024. It is now read-only.

Commit

Permalink
refactor: improve local participant updates in the global state
Browse files Browse the repository at this point in the history
  • Loading branch information
carlossantos74 committed Jul 9, 2024
1 parent db26565 commit 5f041ca
Show file tree
Hide file tree
Showing 9 changed files with 42 additions and 53 deletions.
1 change: 0 additions & 1 deletion __mocks__/participants.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ export const MOCK_AVATAR: Avatar = {
export const MOCK_LOCAL_PARTICIPANT: Participant = {
id: 'unit-test-local-participant-id',
name: 'unit-test-local-participant-name',
color: '#000',
avatar: {
imageUrl: 'unit-test-avatar-thumbnail.png',
model3DUrl: 'unit-test-avatar-model.glb',
Expand Down
1 change: 0 additions & 1 deletion src/common/types/participant.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export interface Participant {
id: string;
name?: string;
type?: ParticipantType;
color?: string;
slot?: Slot;
avatar?: Avatar;
isHost?: boolean;
Expand Down
2 changes: 1 addition & 1 deletion src/components/presence-mouse/canvas/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ export class PointersCanvas extends BaseComponent {
const pointerUser = divPointer.getElementsByClassName('pointer-mouse')[0] as HTMLDivElement;

if (pointerUser) {
pointerUser.style.backgroundImage = `url(https://production.cdn.superviz.com/static/mouse-pointers/${mouse.slot.colorName}.svg)`;
pointerUser.style.backgroundImage = `url(https://production.cdn.superviz.com/static/mouse-pointers/${mouse.slot?.colorName}.svg)`;
}

if (mouseUser) {
Expand Down
2 changes: 1 addition & 1 deletion src/components/presence-mouse/html/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,7 @@ export class PointersHTML extends BaseComponent {
const pointerUser = mouseFollower.getElementsByClassName('pointer-mouse')[0] as HTMLDivElement;

if (pointerUser) {
pointerUser.style.backgroundImage = `url(https://production.cdn.superviz.com/static/mouse-pointers/${participant.slot.colorName}.svg)`;
pointerUser.style.backgroundImage = `url(https://production.cdn.superviz.com/static/mouse-pointers/${participant.slot?.colorName}.svg)`;
}

if (mouseUser) {
Expand Down
9 changes: 5 additions & 4 deletions src/components/video/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { useStore } from '../../common/utils/use-store';
import { IOC } from '../../services/io';
import { Presence3DManager } from '../../services/presence-3d-manager';
import { VideoFrameState } from '../../services/video-conference-manager/types';
import { ParticipantToFrame } from './types';

import { VideoConference } from '.';
import { MEETING_COLORS } from '../../common/types/meeting-colors.types';
Expand Down Expand Up @@ -678,7 +679,6 @@ describe('VideoConference', () => {
isHost: true,
avatar: MOCK_AVATAR,
type: ParticipantType.HOST,
color: 'turquoise',
slot: {
colorName: 'turquoise',
index: 0,
Expand All @@ -691,14 +691,15 @@ describe('VideoConference', () => {

VideoConferenceInstance['onRealtimeParticipantsDidChange'](participant);

const expectedParticipants = {
const expectedParticipants: ParticipantToFrame = {
timestamp: 0,
name: MOCK_LOCAL_PARTICIPANT.name,
name: MOCK_LOCAL_PARTICIPANT.name as string,
isHost: true,
avatar: MOCK_AVATAR,
type: ParticipantType.HOST,
color: 'turquoise',
participantId: MOCK_LOCAL_PARTICIPANT.id,
color: MEETING_COLORS.turquoise,
id: MOCK_LOCAL_PARTICIPANT.id,
slot: {
colorName: 'turquoise',
index: 0,
Expand Down
12 changes: 8 additions & 4 deletions src/components/video/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import {
import { BaseComponent } from '../base';
import { ComponentNames } from '../types';

import { ParticipandToFrame, VideoComponentOptions } from './types';
import { ParticipantToFrame, VideoComponentOptions } from './types';
import { MEETING_COLORS } from '../../common/types/meeting-colors.types';

const KICK_PARTICIPANTS_TIME = 1000 * 60;
Expand Down Expand Up @@ -321,14 +321,17 @@ export class VideoConference extends BaseComponent {
* */
private createParticipantFromPresence = (
participant: PresenceEvent<Participant>,
): Participant => {
): ParticipantToFrame => {
return {
participantId: participant.id,
id: participant.id,
color: participant.data.slot?.color || MEETING_COLORS.gray,
avatar: participant.data.avatar,
type: participant.data.type,
name: participant.data.name,
isHost: participant.data.isHost,
timestamp: participant.timestamp,
slot: participant.data.slot,
};
};

Expand Down Expand Up @@ -672,11 +675,12 @@ export class VideoConference extends BaseComponent {
*/
private onRealtimeParticipantsDidChange = (participants: Participant[]): void => {
this.logger.log('video conference @ on participants did change', participants);
const participantList: ParticipandToFrame[] = participants.map((participant) => {
const participantList: ParticipantToFrame[] = participants.map((participant) => {
return {
id: participant.id,
timestamp: participant.timestamp,
participantId: participant.id,
color: participant.slot?.colorName ?? 'gray',
color: participant.slot?.color || MEETING_COLORS.gray,
name: participant.name,
isHost: participant.isHost ?? false,
avatar: participant.avatar,
Expand Down
6 changes: 4 additions & 2 deletions src/components/video/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Avatar, ParticipantType } from '../../common/types/participant.types';
import { Avatar, ParticipantType, Slot } from '../../common/types/participant.types';
import { DevicesOptions } from '../../common/types/sdk-options.types';
import {
CamerasPosition,
Expand Down Expand Up @@ -46,12 +46,14 @@ export interface VideoComponentOptions {
};
}

export type ParticipandToFrame = {
export type ParticipantToFrame = {
id: string;
timestamp: number;
participantId: string;
color: string;
name: string;
isHost: boolean;
avatar?: Avatar;
type: ParticipantType;
slot: Slot;
};
60 changes: 22 additions & 38 deletions src/core/launcher/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ export class Launcher extends Observable implements DefaultLauncher {
private activeComponents: ComponentNames[] = [];
private componentsToAttachAfterJoin: Partial<BaseComponent>[] = [];
private activeComponentsInstances: Partial<BaseComponent>[] = [];
private participant: Participant;

private ioc: IOC;
private room: Socket.Room;
private eventBus: EventBus = new EventBus();
private timestamp: number = 0;

private useStore = useStore.bind(this) as typeof useStore;

Expand All @@ -47,6 +47,9 @@ export class Launcher extends Observable implements DefaultLauncher {
localParticipant.publish({ ...participant });
participants.subscribe(this.onParticipantListUpdate);
isDomainWhitelisted.subscribe(this.onAuthentication);
localParticipant.subscribe((participant) => {
this.participant = participant;
});

group.publish(participantGroup);
this.ioc = new IOC(localParticipant.value);
Expand Down Expand Up @@ -144,7 +147,7 @@ export class Launcher extends Observable implements DefaultLauncher {

this.activeComponents.splice(this.activeComponents.indexOf(component.name), 1);
localParticipant.publish({
...localParticipant.value,
...this.participant,
activeComponents: this.activeComponents,
});
};
Expand Down Expand Up @@ -244,14 +247,9 @@ export class Launcher extends Observable implements DefaultLauncher {
this.logger.log('launcher service @ onParticipantListUpdate', participants);
const { localParticipant } = useStore(StoreType.GLOBAL);

const participant: Participant = Object.values(participants)
.filter((participant) => participant.id === localParticipant.value.id)
.map((participant) => {
return {
...participant,
color: participant.slot?.color,
};
})[0];
const participant: Participant = Object.values(participants).find(
(participant) => participant.id === localParticipant.value.id,
);

if (!participant || isEqual(localParticipant.value, participant)) return;

Expand Down Expand Up @@ -279,8 +277,7 @@ export class Launcher extends Observable implements DefaultLauncher {
* @returns {void}
*/
private onParticipantJoined = (participant: Socket.PresenceEvent<Participant>): void => {
const { localParticipant } = useStore(StoreType.GLOBAL);
if (participant.id !== localParticipant.value.id) return;
if (participant.id !== this.participant.id) return;

this.logger.log('launcher service @ onParticipantJoined - local participant joined');
this.attachComponentsAfterJoin();
Expand All @@ -301,7 +298,7 @@ export class Launcher extends Observable implements DefaultLauncher {

private startIOC = (): void => {
this.logger.log('launcher service @ startIOC');
const { participants, localParticipant } = useStore(StoreType.GLOBAL);
const { participants } = useStore(StoreType.GLOBAL);
// retrieve the current participants in the room

this.ioc.stateSubject.subscribe((state) => {
Expand All @@ -321,9 +318,9 @@ export class Launcher extends Observable implements DefaultLauncher {
};
});

participantsMap[localParticipant.value.id] = {
...participantsMap[localParticipant.value.id],
...localParticipant.value,
participantsMap[this.participant.id] = {
...participantsMap[this.participant.id],
...this.participant,
};

participants.publish(participantsMap);
Expand Down Expand Up @@ -351,21 +348,18 @@ export class Launcher extends Observable implements DefaultLauncher {
private onParticipantJoinedIOC = async (
presence: Socket.PresenceEvent<Participant>,
): Promise<void> => {
const { localParticipant } = useStore(StoreType.GLOBAL);
if (presence.id !== localParticipant.value.id) return;
if (presence.id !== this.participant.id) return;

// Assign a slot to the participant
const slot = new SlotService(this.room);
await slot.assignSlot();

this.timestamp = presence.timestamp;

this.room.presence.update(localParticipant.value);
this.room.presence.update(this.participant);

this.logger.log('launcher service @ onParticipantJoined - local participant joined');
this.onParticipantJoined(presence);
this.publish(ParticipantEvent.LOCAL_JOINED, localParticipant.value);
this.publish(ParticipantEvent.JOINED, localParticipant.value);
this.publish(ParticipantEvent.LOCAL_JOINED, this.participant);
this.publish(ParticipantEvent.JOINED, this.participant);
};

/**
Expand Down Expand Up @@ -399,27 +393,17 @@ export class Launcher extends Observable implements DefaultLauncher {
private onParticipantUpdatedIOC = (presence: Socket.PresenceEvent<Participant>): void => {
const { localParticipant } = useStore(StoreType.GLOBAL);

if (
localParticipant.value &&
presence.id === localParticipant.value.id &&
!isEqual(localParticipant.value, presence.data)
) {
if (presence.data.timestamp === this.timestamp) {
this.timestamp = 0;
return;
}

if (localParticipant.value && presence.id === localParticipant.value.id) {
localParticipant.publish({
...presence.data,
...localParticipant.value,
timestamp: presence.timestamp,
} as Participant);

this.timestamp = presence.timestamp;
this.room.presence.update(localParticipant.value);

this.publish(ParticipantEvent.LOCAL_UPDATED, presence.data);

this.publish(ParticipantEvent.LOCAL_UPDATED, {
...presence.data,
...localParticipant.value,
});
this.logger.log('Publishing ParticipantEvent.UPDATED', presence.data);
}

Expand Down
2 changes: 1 addition & 1 deletion src/web-components/who-is-online/components/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class WhoIsOnlineMessages extends WebComponentsBaseElement {
super();
const { localParticipant } = this.useStore(StoreType.GLOBAL);
localParticipant.subscribe((participant: Participant) => {
this.participantColor = participant.color;
this.participantColor = participant.slot.color;
});

const { following } = this.useStore(StoreType.WHO_IS_ONLINE);
Expand Down

0 comments on commit 5f041ca

Please sign in to comment.