@@ -133,6 +133,31 @@ export const createDefaultCallingHandlers = memoizeOne(
133133 } ;
134134
135135 const onToggleCamera = async ( options ?: VideoStreamOptions ) : Promise < void > => {
136+ const previewOn = _isPreviewOn ( callClient . getState ( ) . deviceManager ) ;
137+
138+ if ( previewOn && call && call . state === 'Connecting' ) {
139+ // This is to workaround: https://skype.visualstudio.com/SPOOL/_workitems/edit/3030558.
140+ // The root cause of the issue is caused by never transitioning the unparented view to the
141+ // call object when going from configuration page (disconnected call state) to connecting.
142+ //
143+ // Currently the only time the local video stream is moved from unparented view to the call
144+ // object is when we transition from connecting -> call state. If the camera was on,
145+ // inside the MediaGallery we trigger toggleCamera. This triggers onStartLocalVideo which
146+ // destroys the unparentedView and creates a new stream in the call - so all looks well.
147+ //
148+ // However, if someone turns off their camera during the lobbyOrConnecting screen, the
149+ // call.localVideoStreams will be empty (as the stream is currently stored in the unparented
150+ // views and was never transitioned to the call object) and thus we incorrectly try to create
151+ // a new video stream for the call object, instead of only stopping the unparented view.
152+ //
153+ // The correct fix for this is to ensure that callAgent.onStartCall is called with the
154+ // localvideostream as a videoOption. That will mean call.onLocalVideoStreamsUpdated will
155+ // be triggered when the call is in connecting state, which we can then transition the
156+ // local video stream to the stateful call client and get into a clean state.
157+ await onDisposeLocalStreamView ( ) ;
158+ return ;
159+ }
160+
136161 if ( call && ( _isInCall ( call . state ) || _isInLobbyOrConnecting ( call . state ) ) ) {
137162 const stream = call . localVideoStreams . find ( ( stream ) => stream . mediaStreamType === 'Video' ) ;
138163 if ( stream ) {
@@ -143,7 +168,6 @@ export const createDefaultCallingHandlers = memoizeOne(
143168 } else {
144169 const selectedCamera = callClient . getState ( ) . deviceManager . selectedCamera ;
145170 if ( selectedCamera ) {
146- const previewOn = _isPreviewOn ( callClient . getState ( ) . deviceManager ) ;
147171 if ( previewOn ) {
148172 await onDisposeLocalStreamView ( ) ;
149173 } else {
0 commit comments