Use native video call picture in picture! (#3190)

* Use native video call picture in picture!

* Handle isSupported, isPossible and web view errors.

* Use new canEnterPip method.

* Hide a room's Call button when already joined to the call.

* Tweak feature flag description.

* PR comments.
This commit is contained in:
Doug
2024-08-21 17:48:57 +01:00
committed by GitHub
parent 4e3ab9c04a
commit 304070e8cc
23 changed files with 256 additions and 66 deletions
@@ -28,6 +28,7 @@ struct RoomScreenCoordinatorParameters {
let voiceMessageMediaManager: VoiceMessageMediaManagerProtocol
let emojiProvider: EmojiProviderProtocol
let completionSuggestionService: CompletionSuggestionServiceProtocol
let ongoingCallRoomIDPublisher: CurrentValuePublisher<String?, Never>
let appMediator: AppMediatorProtocol
let appSettings: AppSettings
let composerDraftService: ComposerDraftServiceProtocol
@@ -64,6 +65,7 @@ final class RoomScreenCoordinator: CoordinatorProtocol {
init(parameters: RoomScreenCoordinatorParameters) {
roomViewModel = RoomScreenViewModel(roomProxy: parameters.roomProxy,
mediaProvider: parameters.mediaProvider,
ongoingCallRoomIDPublisher: parameters.ongoingCallRoomIDPublisher,
appMediator: parameters.appMediator,
appSettings: ServiceLocator.shared.settings,
analyticsService: ServiceLocator.shared.analytics)
@@ -46,6 +46,7 @@ struct RoomScreenViewState: BindableState {
var canJoinCall = false
var hasOngoingCall: Bool
var shouldShowCallButton = true
var bindings: RoomScreenViewStateBindings
}
@@ -53,6 +53,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
init(roomProxy: JoinedRoomProxyProtocol,
mediaProvider: MediaProviderProtocol,
ongoingCallRoomIDPublisher: CurrentValuePublisher<String?, Never>,
appMediator: AppMediatorProtocol,
appSettings: AppSettings,
analyticsService: AnalyticsService) {
@@ -68,7 +69,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
bindings: .init()),
mediaProvider: mediaProvider)
setupSubscriptions()
setupSubscriptions(ongoingCallRoomIDPublisher: ongoingCallRoomIDPublisher)
}
override func process(viewAction: RoomScreenViewAction) {
@@ -93,7 +94,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
state.lastScrollDirection = direction
}
private func setupSubscriptions() {
private func setupSubscriptions(ongoingCallRoomIDPublisher: CurrentValuePublisher<String?, Never>) {
let roomInfoSubscription = roomProxy
.actionsPublisher
.filter { $0 == .roomInfoUpdate }
@@ -135,6 +136,14 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
self?.setupPinnedEventsTimelineProviderIfNeeded()
}
.store(in: &cancellables)
ongoingCallRoomIDPublisher
.receive(on: DispatchQueue.main)
.sink { [weak self] ongoingCallRoomID in
guard let self else { return }
state.shouldShowCallButton = ongoingCallRoomID != roomProxy.id
}
.store(in: &cancellables)
}
private func buildPinnedEventContents(timelineItems: [TimelineItemProxy]) {
@@ -186,6 +195,7 @@ extension RoomScreenViewModel {
static func mock(roomProxyMock: JoinedRoomProxyMock) -> RoomScreenViewModel {
RoomScreenViewModel(roomProxy: roomProxyMock,
mediaProvider: MockMediaProvider(),
ongoingCallRoomIDPublisher: .init(.init(nil)),
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analyticsService: ServiceLocator.shared.analytics)
@@ -175,8 +175,10 @@ struct RoomScreen: View {
if !ProcessInfo.processInfo.isiOSAppOnMac {
ToolbarItem(placement: .primaryAction) {
callButton
.disabled(roomContext.viewState.canJoinCall == false)
if roomContext.viewState.shouldShowCallButton {
callButton
.disabled(!roomContext.viewState.canJoinCall)
}
}
}
}