Skip to content

Refactor CallCapabilities #1170

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 23 commits into from
Feb 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/shy-tools-call.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@signalwire/core': patch
'@signalwire/js': patch
---

Refacterd and moved call capabilites types and helpers from core to js
2 changes: 0 additions & 2 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import {
stripNamespacePrefix,
isJSONRPCRequest,
isJSONRPCResponse,
mapCapabilityPayload,
} from './utils'
import { WEBRTC_EVENT_TYPES, isWebrtcEventType } from './utils/common'
import { BaseSession } from './BaseSession'
Expand Down Expand Up @@ -75,7 +74,6 @@ export {
isJSONRPCResponse,
LOCAL_EVENT_PREFIX,
stripNamespacePrefix,
mapCapabilityPayload,
}

export * from './redux/features/component/componentSlice'
Expand Down
30 changes: 0 additions & 30 deletions packages/core/src/types/fabric.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,36 +19,6 @@ export * from './fabricRoomSession'
export * from './fabricMember'
export * from './fabricLayout'

interface CapabilityOnOffState {
on?: true
off?: true
}

interface MemberCapability {
muteAudio?: CapabilityOnOffState
muteVideo?: CapabilityOnOffState
microphoneVolume?: true
microphoneSensitivity?: true
speakerVolume?: true
deaf?: CapabilityOnOffState
raisehand?: CapabilityOnOffState
position?: true
meta?: true
remove?: true
}

export interface CallCapabilities {
self?: MemberCapability
member?: MemberCapability
end?: true
setLayout?: true
sendDigit?: true
vmutedHide?: CapabilityOnOffState
lock?: CapabilityOnOffState
device?: true
screenshare?: true
}

/**
* List of all call fabric events
*/
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/types/fabricRoomSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
SwEvent,
CallState,
CallPlay,
CallConnect,
CallConnect
} from '..'

/**
Expand Down
109 changes: 1 addition & 108 deletions packages/core/src/utils/eventUtils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CallCapabilities } from '@signalwire/core'


export const stripNamespacePrefix = (
event: string,
Expand All @@ -15,110 +15,3 @@ export const stripNamespacePrefix = (
}
return event
}

const capabilityStringToObjectMap = {
device: { device: true } as CallCapabilities,
'digit.send': { sendDigit: true } as CallCapabilities,
end: { end: true } as CallCapabilities,
'layout.set': { setLayout: true } as CallCapabilities,
screenshare: { screenshare: true } as CallCapabilities,
'vmuted.hide.on': { vmutedHide: { on: true } } as CallCapabilities,
'vmuted.hide.off': { vmutedHide: { off: true } } as CallCapabilities,
'lock.on': { lock: { on: true } } as CallCapabilities,
'lock.off': { lock: { off: true } } as CallCapabilities,
'member.position.set': { member: { position: true } } as CallCapabilities,
'member.meta': { member: { meta: true } } as CallCapabilities,
'member.remove': { member: { remove: true } } as CallCapabilities,
'member.microphone.volume.set': {
member: { microphoneVolume: true },
} as CallCapabilities,
'member.microphone.sensitivity.set': {
member: { microphoneSensitivity: true },
} as CallCapabilities,
'member.speaker.volume.set': {
member: { speakerVolume: true },
} as CallCapabilities,
'member.deaf.on': { member: { deaf: { on: true } } } as CallCapabilities,
'member.deaf.off': { member: { deaf: { off: true } } } as CallCapabilities,
'member.mute.audio.on': {
member: { muteAudio: { on: true } },
} as CallCapabilities,
'member.mute.audio.off': {
member: { muteAudio: { off: true } },
} as CallCapabilities,
'member.mute.video.on': {
member: { muteVideo: { on: true } },
} as CallCapabilities,
'member.mute.video.off': {
member: { muteVideo: { off: true } },
} as CallCapabilities,
'member.raisehand.on': {
member: { raisehand: { on: true } },
} as CallCapabilities,
'member.raisehand.off': {
member: { raisehand: { off: true } },
} as CallCapabilities,
'self.position.set': { self: { position: true } } as CallCapabilities,
'self.meta': { self: { meta: true } } as CallCapabilities,
'self.remove': { self: { remove: true } } as CallCapabilities,
'self.microphone': {
self: { microphoneVolume: true, microphoneSensitivity: true },
} as CallCapabilities,
'self.microphone.volume.set': {
self: { microphoneVolume: true },
} as CallCapabilities,
'self.microphone.sensitivity.set': {
self: { microphoneSensitivity: true },
} as CallCapabilities,
'self.speaker.volume.set': {
self: { speakerVolume: true },
} as CallCapabilities,
'self.deaf.on': { self: { deaf: { on: true } } } as CallCapabilities,
'self.deaf.off': { self: { deaf: { off: true } } } as CallCapabilities,
'self.mute.audio.on': {
self: { muteAudio: { on: true } },
} as CallCapabilities,
'self.mute.audio.off': {
self: { muteAudio: { off: true } },
} as CallCapabilities,
'self.mute.video.on': {
self: { muteVideo: { on: true } },
} as CallCapabilities,
'self.mute.video.off': {
self: { muteVideo: { off: true } },
} as CallCapabilities,
'self.raisehand.on': {
self: { raisehand: { on: true } },
} as CallCapabilities,
'self.raisehand.off': {
self: { raisehand: { off: true } },
} as CallCapabilities,
}

const isObjectGuard = (o: unknown): o is Object => o instanceof Object

const capabilityStringToObjects = (capability: string) =>
Object.entries(capabilityStringToObjectMap)
.filter(([key]) => key.startsWith(capability))
.map(([_, value]) => value)

const mergeCapabilityObjects = <T extends Object>(target: T, source: T): T => {
const result = { ...target }
for (const key in source) {
if (
result[key] &&
isObjectGuard(target[key]) &&
isObjectGuard(source[key])
) {
result[key] = mergeCapabilityObjects(target[key], source[key])
} else {
result[key] = source[key]
}
}
return result
}

export const mapCapabilityPayload = (capabilities: string[]) =>
capabilities
.flatMap(capabilityStringToObjects)
.reduce<CallCapabilities>(mergeCapabilityObjects, {} as CallCapabilities)
64 changes: 32 additions & 32 deletions packages/js/src/fabric/FabricRoomSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {
connect,
BaseComponentContract,
BaseRPCResult,
CallCapabilities,
FabricLayoutChangedEventParams,
ExecuteExtendedOptions,
Rooms,
Expand Down Expand Up @@ -30,6 +29,7 @@ import { PREVIOUS_CALLID_STORAGE_KEY } from './utils/constants'
import { fabricWorker } from './workers'
import { FabricRoomSessionMember } from './FabricRoomSessionMember'
import { makeAudioElementSaga } from '../features/mediaElements/mediaElementsSagas'
import { CallCapabilitiesContract } from './interfaces/capabilities'

export interface FabricRoomSession
extends FabricRoomSessionContract,
Expand All @@ -51,7 +51,7 @@ export class FabricRoomSessionConnection
private _member?: FabricRoomSessionMember
private _currentLayoutEvent: FabricLayoutChangedEventParams
//describes what are methods are allow for the user in a call segment
private _capabilities: CallCapabilities = {}
private _capabilities?: CallCapabilitiesContract

constructor(options: FabricRoomSessionOptions) {
super(options)
Expand Down Expand Up @@ -81,11 +81,11 @@ export class FabricRoomSessionConnection
)?.position
}

get capabilities(): CallCapabilities {
get capabilities(): CallCapabilitiesContract | undefined {
return this._capabilities
}

set capabilities(capabilities: CallCapabilities) {
set capabilities(capabilities: CallCapabilitiesContract | undefined) {
this._capabilities = capabilities
}

Expand Down Expand Up @@ -209,8 +209,8 @@ export class FabricRoomSessionConnection
public async audioMute(params: MemberCommandParams) {
if (
!params || params.memberId === this.member.id
? !this.capabilities.self?.muteAudio?.off
: !this.capabilities.member?.muteAudio?.off
? !this.capabilities?.self.muteAudio.off
: !this.capabilities?.member.muteAudio.off
) {
throw Error('Missing audio mute capability')
}
Expand All @@ -224,8 +224,8 @@ export class FabricRoomSessionConnection
public async audioUnmute(params: MemberCommandParams) {
if (
!params || params.memberId === this.member.id
? !this.capabilities.self?.muteAudio?.on
: !this.capabilities.member?.muteAudio?.on
? !this.capabilities?.self.muteAudio.on
: !this.capabilities?.member.muteAudio.on
) {
throw Error('Missing audio unmute capability')
}
Expand All @@ -239,8 +239,8 @@ export class FabricRoomSessionConnection
public async videoMute(params: MemberCommandParams) {
if (
!params || params.memberId === this.member.id
? !this.capabilities.self?.muteVideo?.off
: !this.capabilities.member?.muteVideo?.on
? !this.capabilities?.self.muteVideo.off
: !this.capabilities?.member.muteVideo.on
) {
throw Error('Missing video mute capability')
}
Expand All @@ -254,8 +254,8 @@ export class FabricRoomSessionConnection
public async videoUnmute(params: MemberCommandParams) {
if (
!params || params.memberId === this.member.id
? !this.capabilities.self?.muteVideo?.on
: !this.capabilities.member?.muteVideo?.on
? !this.capabilities?.self.muteVideo.on
: !this.capabilities?.member.muteVideo.on
) {
throw Error('Missing video unmute capability')
}
Expand All @@ -269,8 +269,8 @@ export class FabricRoomSessionConnection
public async deaf(params: MemberCommandParams) {
if (
!params || params.memberId === this.member.id
? !this.capabilities.self?.deaf?.on
: !this.capabilities.member?.deaf?.on
? !this.capabilities?.self.deaf.on
: !this.capabilities?.member.deaf.on
) {
throw Error('Missing deaf capability')
}
Expand All @@ -283,8 +283,8 @@ export class FabricRoomSessionConnection
public async undeaf(params: MemberCommandParams) {
if (
!params || params.memberId === this.member.id
? !this.capabilities.self?.deaf?.off
: !this.capabilities.member?.deaf?.off
? !this.capabilities?.self.deaf.off
: !this.capabilities?.member.deaf.off
) {
throw Error('Missing undeaf capability')
}
Expand Down Expand Up @@ -321,7 +321,7 @@ export class FabricRoomSessionConnection
}

public async removeMember(params: Required<MemberCommandParams>) {
if (!this.capabilities.member?.remove) {
if (!this.capabilities?.member.remove) {
throw Error('Missing setLayout capability')
}
if (!params?.memberId) {
Expand All @@ -337,15 +337,15 @@ export class FabricRoomSessionConnection
const { raised = true, memberId } = params || {}
if (
memberId == this.member.id && raised
? !this.capabilities.self?.raisehand?.on
: !this.capabilities.member?.raisehand?.on
? !this.capabilities?.self.raisehand.on
: !this.capabilities?.member.raisehand.on
) {
throw Error('Missing raisehand capability')
}
if (
memberId == this.member.id && !raised
? !this.capabilities.self?.raisehand?.off
: !this.capabilities.member?.raisehand?.off
? !this.capabilities?.self.raisehand.off
: !this.capabilities?.member.raisehand.off
) {
throw Error('Missing lowerhand capability')
}
Expand All @@ -356,7 +356,7 @@ export class FabricRoomSessionConnection
}

public async setLayout(params: Rooms.SetLayoutParams) {
if (!this.capabilities.setLayout) {
if (!this.capabilities?.setLayout) {
throw Error('Missing setLayout capability')
}
const extraParams = {
Expand All @@ -372,8 +372,8 @@ export class FabricRoomSessionConnection
public async setInputVolume(params: MemberCommandWithVolumeParams) {
if (
!params || params.memberId === this.member.id
? !this.capabilities.self?.microphoneVolume
: !this.capabilities.member?.microphoneVolume
? !this.capabilities?.self.microphoneVolume
: !this.capabilities?.member.microphoneVolume
) {
throw Error('Missing setInputVolume capability')
}
Expand All @@ -389,8 +389,8 @@ export class FabricRoomSessionConnection
public async setOutputVolume(params: MemberCommandWithVolumeParams) {
if (
!params || params.memberId === this.member.id
? !this.capabilities.self?.speakerVolume
: !this.capabilities.member?.speakerVolume
? !this.capabilities?.self.speakerVolume
: !this.capabilities?.member.speakerVolume
) {
throw Error('Missing setOutputVolume capability')
}
Expand All @@ -406,8 +406,8 @@ export class FabricRoomSessionConnection
public async setInputSensitivity(params: MemberCommandWithValueParams) {
if (
!params || params.memberId === this.member.id
? !this.capabilities.self?.microphoneSensitivity
: !this.capabilities.member?.microphoneSensitivity
? !this.capabilities?.self.microphoneSensitivity
: !this.capabilities?.member.microphoneSensitivity
) {
throw Error('Missing setOutputVolume capability')
}
Expand All @@ -431,8 +431,8 @@ export class FabricRoomSessionConnection
Object.keys(positions).some((p) =>
['self', `${this.memberId}`].includes(p)
)
? !this.capabilities.self?.position
: !this.capabilities.member?.position
? !this.capabilities?.self.position
: !this.capabilities?.member.position
) {
throw Error('Missing setPositions capability')
}
Expand Down Expand Up @@ -478,7 +478,7 @@ export class FabricRoomSessionConnection
}

public async lock() {
if (!this.capabilities.lock?.on) {
if (!this.capabilities?.lock.on) {
throw Error('Missing lock capability')
}
return this.executeAction<BaseRPCResult>({
Expand All @@ -487,7 +487,7 @@ export class FabricRoomSessionConnection
}

public async unlock() {
if (!this.capabilities.lock?.off) {
if (!this.capabilities?.lock.off) {
throw Error('Missing unlock capability')
}
return this.executeAction<BaseRPCResult>({
Expand Down
Loading
Loading