Skip to content
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

FCE-1023: Change how prepareCamera works #282

Merged
merged 4 commits into from
Jan 14, 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: 2 additions & 4 deletions examples/fishjam-chat/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"bundleIdentifier": "io.fishjam.example.fishjamchat",
"infoPlist": {
"NSAppTransportSecurity": {
"NSAllowsArbitraryLoads": true //this allows for testing in local network without secured connections
"NSAllowsArbitraryLoads": true
},
"NSCameraUsageDescription": "We need to access your camera for video calls.",
"NSMicrophoneUsageDescription": "We need to access your microphone so you can talk during calls.",
Expand Down Expand Up @@ -68,9 +68,7 @@
}
}
],
[
"./plugin/build/with-local-paths-for-native-packages.js" // Only relevant for local development of packages/ios-client and packages/android-client
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: Removed those comments as the current version of expo prebuild removes it by default.

]
["./plugin/build/with-local-paths-for-native-packages.js"]
],
"extra": {
"eas": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,14 @@ class EmitableEvent private constructor(

fun currentCameraChanged(
localCamera: LocalCamera?,
isCameraOn: Boolean
isCameraOn: Boolean,
isCameraInitialized: Boolean
) = EmitableEvent(
EventName.CurrentCameraChanged,
mapOf(
"currentCamera" to localCamera,
"isCameraOn" to isCameraOn
"isCameraOn" to isCameraOn,
"isCameraInitialized" to isCameraInitialized
)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,17 @@ class RNFishjamClient(
var isScreenShareOn = false
var isConnected = false

private var isCameraInitialized = false
var isCameraInitialized = false
private set(value) {
field = value
emitEvent(
EmitableEvent.currentCameraChanged(
getCurrentCaptureDevice(),
isCameraOn,
value
)
)
}

private var connectPromise: Promise? = null
private var screenSharePermissionPromise: Promise? = null
Expand Down Expand Up @@ -293,7 +303,6 @@ class RNFishjamClient(

suspend fun startCamera(config: CameraConfig): Boolean {
if (isCameraInitialized) {
emitEvent(EmitableEvent.warning("Camera already started. You may only call startCamera once before leaveRoom is called."))
return true
}
if (!PermissionUtils.requestCameraPermission(appContext)) {
Expand Down Expand Up @@ -325,7 +334,13 @@ class RNFishjamClient(
) {
cameraTrack.setEnabled(isEnabled)
isCameraOn = isEnabled
emitEvent(EmitableEvent.currentCameraChanged(cameraTrack.getCaptureDevice()?.toLocalCamera(), isEnabled))
emitEvent(
EmitableEvent.currentCameraChanged(
cameraTrack.getCaptureDevice()?.toLocalCamera(),
isEnabled,
isCameraInitialized
)
)
localCameraTracksChangedListenersManager.notifyListeners()
}

Expand Down Expand Up @@ -905,6 +920,12 @@ class RNFishjamClient(
}

override fun onCaptureDeviceChanged(captureDevice: CaptureDevice?) {
emitEvent(EmitableEvent.currentCameraChanged(captureDevice?.toLocalCamera(), isCameraOn))
emitEvent(
EmitableEvent.currentCameraChanged(
captureDevice?.toLocalCamera(),
isCameraOn,
isCameraInitialized
)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,10 @@ class RNFishjamClientModule : Module() {
return@Property rnFishjamClient.reconnectionStatus.status
}

Property("isCameraInitialized") {
return@Property rnFishjamClient.isCameraInitialized
}

Function("getPeers") {
return@Function rnFishjamClient.getPeers()
}
Expand Down
5 changes: 4 additions & 1 deletion packages/react-native-client/ios/Events.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,15 @@ class EmitableEvent {
.init(event: .ReconnectionStatusChanged, eventContent: reconnectionStatus.rawValue)
}

static func currentCameraChanged(localCamera: LocalCamera?, isCameraOn: Bool) -> EmitableEvent {
static func currentCameraChanged(localCamera: LocalCamera?, isCameraOn: Bool, isCameraInitialized: Bool)
-> EmitableEvent
{
return .init(
event: .CurrentCameraChanged,
eventContent: [
"currentCamera": localCamera as Any,
"isCameraOn": isCameraOn,
"isCameraInitialized": isCameraInitialized,
])
}

Expand Down
20 changes: 12 additions & 8 deletions packages/react-native-client/ios/RNFishjamClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@ class RNFishjamClient: FishjamClientListener {
var isAppScreenShareOn = false
var isConnected = false

private var isCameraInitialized = false
private(set) var isCameraInitialized = false {
didSet {
emit(
event: .currentCameraChanged(
localCamera: currentCamera, isCameraOn: isCameraOn, isCameraInitialized: isCameraInitialized))
}
}

var connectPromise: Promise? = nil

Expand Down Expand Up @@ -254,11 +260,6 @@ class RNFishjamClient: FishjamClientListener {
try ensureCreated()

guard !isCameraInitialized else {
emit(
event: .warning(
message:
"Camera already started. You may only call startCamera once before leaveRoom is called."))

return true
}

Expand Down Expand Up @@ -292,7 +293,8 @@ class RNFishjamClient: FishjamClientListener {
isCameraOn = enabled
emit(
event: .currentCameraChanged(
localCamera: cameraTrack.currentCaptureDevice?.toLocalCamera(), isCameraOn: enabled))
localCamera: cameraTrack.currentCaptureDevice?.toLocalCamera(), isCameraOn: enabled,
isCameraInitialized: isCameraInitialized))
RNFishjamClient.localCameraTracksChangedListenersManager.notifyListeners()
}

Expand Down Expand Up @@ -913,6 +915,8 @@ class RNFishjamClient: FishjamClientListener {

extension RNFishjamClient: CameraCapturerDeviceChangedListener {
func onCaptureDeviceChanged(_ device: AVCaptureDevice?) {
emit(event: .currentCameraChanged(localCamera: device?.toLocalCamera(), isCameraOn: isCameraOn))
emit(
event: .currentCameraChanged(
localCamera: device?.toLocalCamera(), isCameraOn: isCameraOn, isCameraInitialized: isCameraInitialized))
}
}
4 changes: 4 additions & 0 deletions packages/react-native-client/ios/RNFishjamClientModule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ public class RNFishjamClientModule: Module {
return rnFishjamClient.isAppScreenShareOn
}

Property("isCameraInitialized") {
return rnFishjamClient.isCameraInitialized
}

Function("getPeers") {
return rnFishjamClient.getPeers()
}
Expand Down
1 change: 1 addition & 0 deletions packages/react-native-client/src/RNFishjamClientModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type RNFishjamClient = {
currentCamera: Camera | null;
peerStatus: PeerStatus;
reconnectionStatus: ReconnectionStatus;
isCameraInitialized: boolean;

getPeers: <
PeerMetadataType extends Metadata,
Expand Down
25 changes: 17 additions & 8 deletions packages/react-native-client/src/hooks/useCamera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export type Camera = {
export type CurrentCameraChangedType = {
currentCamera: Camera | null;
isCameraOn: boolean;
isCameraInitialized: boolean;
};

export type VideoQuality =
Expand Down Expand Up @@ -163,14 +164,18 @@ export function useCamera() {
defaultSimulcastConfig(), // TODO: Fetch from native
);

const { currentCamera: currentCameraState, isCameraOn } =
useFishjamEventState<CurrentCameraChangedType>(
ReceivableEvents.CurrentCameraChanged,
{
currentCamera: RNFishjamClientModule.currentCamera,
isCameraOn: RNFishjamClientModule.isCameraOn,
},
);
const {
currentCamera: currentCameraState,
isCameraOn,
isCameraInitialized,
} = useFishjamEventState<CurrentCameraChangedType>(
ReceivableEvents.CurrentCameraChanged,
{
currentCamera: RNFishjamClientModule.currentCamera,
isCameraOn: RNFishjamClientModule.isCameraOn,
isCameraInitialized: RNFishjamClientModule.isCameraInitialized,
},
);

// For Android Expo converts null to undefined ¯\_(ツ)_/¯
const currentCamera = currentCameraState ?? null;
Expand Down Expand Up @@ -248,6 +253,10 @@ export function useCamera() {
* @returns A promise that resolves to the list of available cameras.
*/
cameras,
/**
* A value indicating if camera was already initialized (if `prepareCamera` was called).
*/
isInitialized: isCameraInitialized,
/**
* Enable/disable current camera
*/
Expand Down
Loading