From 7f1ae4816646f94fe2c32fe14a08826d43b06e52 Mon Sep 17 00:00:00 2001 From: Ilias Pavlidakis Date: Tue, 10 Oct 2023 15:35:31 +0300 Subject: [PATCH] Fix ChatView disappearing when call events happening (#181) --- .../CallView/DemoCallContainerView.swift | 7 ++- .../Sources/Views/CallView/DemoCallView.swift | 2 + .../Views/CallView/DemoChatModifier.swift | 44 +++++++++++++++++++ .../Sources/Views/Controls/DemoControls.swift | 14 ------ .../DemoWaitingLocalUserView.swift | 10 +++-- StreamVideo.xcodeproj/project.pbxproj | 5 ++- 6 files changed, 61 insertions(+), 21 deletions(-) create mode 100644 DemoApp/Sources/Views/CallView/DemoChatModifier.swift diff --git a/DemoApp/Sources/Views/CallView/DemoCallContainerView.swift b/DemoApp/Sources/Views/CallView/DemoCallContainerView.swift index c0b59628e..6b0f51025 100644 --- a/DemoApp/Sources/Views/CallView/DemoCallContainerView.swift +++ b/DemoApp/Sources/Views/CallView/DemoCallContainerView.swift @@ -13,10 +13,13 @@ internal struct DemoCallContainerView: View { @Injected(\.streamVideo) var streamVideo @Injected(\.appearance) var appearance @StateObject var viewModel: CallViewModel + @StateObject var chatViewModel: DemoChatViewModel @ObservedObject var appState = AppState.shared internal init(callId: String) { - _viewModel = StateObject(wrappedValue: CallViewModel()) + let callViewModel = CallViewModel() + _viewModel = StateObject(wrappedValue: callViewModel) + _chatViewModel = StateObject(wrappedValue: .init(callViewModel)) self.callId = callId } @@ -26,7 +29,7 @@ internal struct DemoCallContainerView: View { DemoCallModifier( viewFactory: DemoAppViewFactory.shared, viewModel: viewModel, - chatViewModel: .init(viewModel) + chatViewModel: chatViewModel ) ) .onContinueUserActivity( diff --git a/DemoApp/Sources/Views/CallView/DemoCallView.swift b/DemoApp/Sources/Views/CallView/DemoCallView.swift index c9f558064..242feb3e3 100644 --- a/DemoApp/Sources/Views/CallView/DemoCallView.swift +++ b/DemoApp/Sources/Views/CallView/DemoCallView.swift @@ -10,6 +10,7 @@ import EffectsLibrary struct DemoCallView: View { @Injected(\.appearance) var appearance + @Injected(\.chatViewModel) var chatViewModel var microphoneChecker: MicrophoneChecker @@ -74,6 +75,7 @@ struct DemoCallView: View { .onAppear { updateMicrophoneChecker() } + .chat(viewModel: viewModel, chatViewModel: chatViewModel) } private func updateMicrophoneChecker() { diff --git a/DemoApp/Sources/Views/CallView/DemoChatModifier.swift b/DemoApp/Sources/Views/CallView/DemoChatModifier.swift new file mode 100644 index 000000000..8c7530c07 --- /dev/null +++ b/DemoApp/Sources/Views/CallView/DemoChatModifier.swift @@ -0,0 +1,44 @@ +// +// Copyright © 2023 Stream.io Inc. All rights reserved. +// + +import Foundation +import SwiftUI +import StreamVideoSwiftUI + +struct ChatModifier: ViewModifier { + + @ObservedObject var viewModel: CallViewModel + @ObservedObject var chatViewModel: DemoChatViewModel + + func body(content: Content) -> some View { + content + .halfSheetIfAvailable( + isPresented: $chatViewModel.isChatVisible, + onDismiss: {} + ) { + if let channelController = chatViewModel.channelController { + VStack { + ChatControlsHeader(viewModel: viewModel) + ChatView( + channelController: channelController, + chatViewModel: chatViewModel, + callViewModel: viewModel + ) + } + } + } + } +} + +extension View { + + @ViewBuilder + func chat(viewModel: CallViewModel, chatViewModel: DemoChatViewModel?) -> some View { + if let chatViewModel { + self.modifier(ChatModifier(viewModel: viewModel, chatViewModel: chatViewModel)) + } else { + self + } + } +} diff --git a/DemoApp/Sources/Views/Controls/DemoControls.swift b/DemoApp/Sources/Views/Controls/DemoControls.swift index f354d8283..8166a03e4 100644 --- a/DemoApp/Sources/Views/Controls/DemoControls.swift +++ b/DemoApp/Sources/Views/Controls/DemoControls.swift @@ -21,7 +21,6 @@ struct AppControlsWithChat: View { @ObservedObject var reactionsHelper = AppState.shared.reactionsHelper @ObservedObject var viewModel: CallViewModel - @State private var isChatVisible = false init(viewModel: CallViewModel, canOpenChat: Bool = true) { self.viewModel = viewModel @@ -61,22 +60,9 @@ struct AppControlsWithChat: View { } .offset(y: -15) ) - .onReceive(chatViewModel?.$isChatVisible) { isChatVisible = canOpenChat && $0 } .onReceive(viewModel.$call, perform: { call in reactionsHelper.call = call }) - .halfSheetIfAvailable(isPresented: $isChatVisible, onDismiss: { chatViewModel?.isChatVisible = false }) { - if let chatViewModel = chatViewModel, let channelController = chatViewModel.channelController { - VStack { - ChatControlsHeader(viewModel: viewModel) - ChatView( - channelController: channelController, - chatViewModel: chatViewModel, - callViewModel: viewModel - ) - } - } - } } } diff --git a/DemoApp/Sources/Views/WaitingLocalUserView/DemoWaitingLocalUserView.swift b/DemoApp/Sources/Views/WaitingLocalUserView/DemoWaitingLocalUserView.swift index e30b8edfd..35f6d4d2d 100644 --- a/DemoApp/Sources/Views/WaitingLocalUserView/DemoWaitingLocalUserView.swift +++ b/DemoApp/Sources/Views/WaitingLocalUserView/DemoWaitingLocalUserView.swift @@ -14,11 +14,13 @@ struct DemoWaitingLocalUserView: View { @ObservedObject var viewModel: CallViewModel @State private var isSharePresented = false - @State private var isChatVisible = false private let viewFactory: Factory - internal init(viewFactory: Factory, viewModel: CallViewModel) { + internal init( + viewFactory: Factory, + viewModel: CallViewModel + ) { self.viewFactory = viewFactory self.viewModel = viewModel } @@ -28,7 +30,7 @@ struct DemoWaitingLocalUserView: View { viewFactory .makeInnerWaitingLocalUserView(viewModel: viewModel) - if !isChatVisible { + if chatViewModel?.isChatVisible == true { VStack { Spacer() VStack { @@ -82,7 +84,7 @@ struct DemoWaitingLocalUserView: View { } } } - .onReceive(chatViewModel?.$isChatVisible) { isChatVisible = $0 } + .chat(viewModel: viewModel, chatViewModel: chatViewModel) } private var callLink: String { diff --git a/StreamVideo.xcodeproj/project.pbxproj b/StreamVideo.xcodeproj/project.pbxproj index 1ac2c6455..77ee13d1f 100644 --- a/StreamVideo.xcodeproj/project.pbxproj +++ b/StreamVideo.xcodeproj/project.pbxproj @@ -38,6 +38,7 @@ 4046DEEE2A9F404300CA6D2F /* GDPerformanceView-Swift in Frameworks */ = {isa = PBXBuildFile; productRef = 4046DEED2A9F404300CA6D2F /* GDPerformanceView-Swift */; }; 4046DEF02A9F469100CA6D2F /* GDPerformanceView-Swift in Frameworks */ = {isa = PBXBuildFile; productRef = 4046DEEF2A9F469100CA6D2F /* GDPerformanceView-Swift */; settings = {ATTRIBUTES = (Required, ); }; }; 4046DEF22A9F510C00CA6D2F /* DebugMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4046DEF12A9F510C00CA6D2F /* DebugMenu.swift */; }; + 404A5CFB2AD5648100EF1C62 /* DemoChatModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 404A5CFA2AD5648100EF1C62 /* DemoChatModifier.swift */; }; 4059C3422AAF0CE40006928E /* DemoChatViewModel+Injection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4059C3412AAF0CE40006928E /* DemoChatViewModel+Injection.swift */; }; 406A8E8D2AA1D78C001F598A /* AppEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4030E59F2A9DF5BD003E8CBA /* AppEnvironment.swift */; }; 406A8E8E2AA1D79D001F598A /* UserState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40F445AD2A9DFC34004BE3DA /* UserState.swift */; }; @@ -898,6 +899,7 @@ 4046DEE82A9E381F00CA6D2F /* AppIntentVocabulary.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = AppIntentVocabulary.plist; sourceTree = ""; }; 4046DEEA2A9E38DC00CA6D2F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4046DEF12A9F510C00CA6D2F /* DebugMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugMenu.swift; sourceTree = ""; }; + 404A5CFA2AD5648100EF1C62 /* DemoChatModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoChatModifier.swift; sourceTree = ""; }; 4059C3412AAF0CE40006928E /* DemoChatViewModel+Injection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DemoChatViewModel+Injection.swift"; sourceTree = ""; }; 407D5D3C2ACEF0C500B5044E /* VisibilityThresholdModifier_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VisibilityThresholdModifier_Tests.swift; sourceTree = ""; }; 409386192AA09E4A00FF5AF4 /* MemoryLogDestination.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemoryLogDestination.swift; sourceTree = ""; }; @@ -1925,6 +1927,7 @@ 40D946442AA5F67E00C8861B /* DemoCallingTopView.swift */, 40F445DA2A9E2276004BE3DA /* DemoCallContentView.swift */, 40F446012A9E2C23004BE3DA /* DemoCallView.swift */, + 404A5CFA2AD5648100EF1C62 /* DemoChatModifier.swift */, ); path = CallView; sourceTree = ""; @@ -2113,7 +2116,6 @@ 82FF40B62A17C6CD00B4D95E /* ReconnectionView_Tests.swift */, 82FF40B82A17C6D600B4D95E /* RecordingView_Tests.swift */, 82FF40BA2A17C6DF00B4D95E /* ScreenSharingView_Tests.swift */, - 407D5D3C2ACEF0C500B5044E /* VisibilityThresholdModifier_Tests.swift */, 40D6ADDC2ACDB51C00EF5336 /* VideoRenderer_Tests.swift */, 407D5D3C2ACEF0C500B5044E /* VisibilityThresholdModifier_Tests.swift */, ); @@ -3801,6 +3803,7 @@ 847B47B72A260CF1000714CE /* CustomCallView.swift in Sources */, 40F445EA2A9E297B004BE3DA /* CallStateResponseFields+Identifiable.swift in Sources */, 40F445CC2A9E1FC9004BE3DA /* DemoChatViewFactory.swift in Sources */, + 404A5CFB2AD5648100EF1C62 /* DemoChatModifier.swift in Sources */, 842D8BDA2865B37800801910 /* DemoApp.swift in Sources */, 40F445E82A9E2824004BE3DA /* Call+Identifiable.swift in Sources */, 40F445FE2A9E2B46004BE3DA /* DemoWaitingLocalUserView.swift in Sources */,