ios: CallKit enhancements (#2010)
* ios: CallKit enhancements * better checks
This commit is contained in:
committed by
GitHub
parent
0404b020e6
commit
840df89ca6
@@ -94,6 +94,16 @@ class AppDelegate: NSObject, UIApplicationDelegate {
|
||||
return configuration
|
||||
}
|
||||
|
||||
func applicationProtectedDataWillBecomeUnavailable(_ application: UIApplication) {
|
||||
logger.debug("AppDelegate: will lock screen")
|
||||
ChatModel.shared.onLockScreenCurrently = true
|
||||
}
|
||||
|
||||
func applicationProtectedDataDidBecomeAvailable(_ application: UIApplication) {
|
||||
logger.debug("AppDelegate: did unlock screen")
|
||||
ChatModel.shared.onLockScreenCurrently = false
|
||||
}
|
||||
|
||||
private func receiveMessages(_ completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
|
||||
let complete = BGManager.shared.completionHandler {
|
||||
logger.debug("AppDelegate: completed BGManager.receiveMessages")
|
||||
|
||||
@@ -17,6 +17,7 @@ struct ContentView: View {
|
||||
@Binding var doAuthenticate: Bool
|
||||
@Binding var userAuthorized: Bool?
|
||||
@Binding var canConnectCall: Bool
|
||||
@Binding var lastSuccessfulUnlock: TimeInterval?
|
||||
@AppStorage(DEFAULT_SHOW_LA_NOTICE) private var prefShowLANotice = false
|
||||
@AppStorage(DEFAULT_LA_NOTICE_SHOWN) private var prefLANoticeShown = false
|
||||
@AppStorage(DEFAULT_PERFORM_LA) private var prefPerformLA = false
|
||||
@@ -27,7 +28,7 @@ struct ContentView: View {
|
||||
var body: some View {
|
||||
ZStack {
|
||||
if chatModel.showCallView, let call = chatModel.activeCall {
|
||||
ActiveCallView(call: call, userAuthorized: $userAuthorized, canConnectCall: $canConnectCall)
|
||||
ActiveCallView(call: call, canConnectCall: $canConnectCall)
|
||||
}
|
||||
if prefPerformLA && userAuthorized != true {
|
||||
Rectangle().fill(colorScheme == .dark ? .black : .white)
|
||||
@@ -128,6 +129,7 @@ struct ContentView: View {
|
||||
case .success:
|
||||
userAuthorized = true
|
||||
canConnectCall = true
|
||||
lastSuccessfulUnlock = ProcessInfo.processInfo.systemUptime
|
||||
case .failed:
|
||||
break
|
||||
case .unavailable:
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
import Foundation
|
||||
import Combine
|
||||
import SwiftUI
|
||||
import WebKit
|
||||
import SimpleXChat
|
||||
|
||||
final class ChatModel: ObservableObject {
|
||||
@@ -59,7 +58,9 @@ final class ChatModel: ObservableObject {
|
||||
@Published var stopPreviousRecPlay: Bool = false // value is not taken into account, only the fact it switches
|
||||
@Published var draft: ComposeState?
|
||||
@Published var draftChatId: String?
|
||||
var callWebView: WKWebView?
|
||||
|
||||
var sceneWasActiveAtLeastOnce = false
|
||||
var onLockScreenCurrently = false
|
||||
|
||||
var messageDelivery: Dictionary<Int64, () -> Void> = [:]
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ struct SimpleXApp: App {
|
||||
@State private var doAuthenticate = false
|
||||
@State private var canConnectCall = false
|
||||
@State private var enteredBackground: TimeInterval? = nil
|
||||
@State private var lastSuccessfulUnlock: TimeInterval? = nil
|
||||
|
||||
init() {
|
||||
hs_init(0, nil)
|
||||
@@ -35,7 +36,7 @@ struct SimpleXApp: App {
|
||||
|
||||
var body: some Scene {
|
||||
return WindowGroup {
|
||||
ContentView(doAuthenticate: $doAuthenticate, userAuthorized: $userAuthorized, canConnectCall: $canConnectCall)
|
||||
ContentView(doAuthenticate: $doAuthenticate, userAuthorized: $userAuthorized, canConnectCall: $canConnectCall, lastSuccessfulUnlock: $lastSuccessfulUnlock)
|
||||
.environmentObject(chatModel)
|
||||
.onOpenURL { url in
|
||||
logger.debug("ContentView.onOpenURL: \(url)")
|
||||
@@ -65,6 +66,7 @@ struct SimpleXApp: App {
|
||||
NtfManager.shared.setNtfBadgeCount(chatModel.totalUnreadCountForAllUsers())
|
||||
case .active:
|
||||
CallController.shared.onEndCall = nil
|
||||
chatModel.sceneWasActiveAtLeastOnce = true
|
||||
let appState = appStateGroupDefault.get()
|
||||
startChatAndActivate()
|
||||
if appState.inactive && chatModel.chatRunning == true {
|
||||
@@ -74,7 +76,7 @@ struct SimpleXApp: App {
|
||||
}
|
||||
}
|
||||
doAuthenticate = authenticationExpired()
|
||||
canConnectCall = !(doAuthenticate && prefPerformLA)
|
||||
canConnectCall = !(doAuthenticate && prefPerformLA) || unlockedRecently()
|
||||
default:
|
||||
break
|
||||
}
|
||||
@@ -114,6 +116,15 @@ struct SimpleXApp: App {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func unlockedRecently() -> Bool {
|
||||
if let lastSuccessfulUnlock = lastSuccessfulUnlock {
|
||||
return ProcessInfo.processInfo.systemUptime - lastSuccessfulUnlock < 2
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
private func updateChats() {
|
||||
do {
|
||||
let chats = try apiGetChats()
|
||||
|
||||
@@ -14,7 +14,6 @@ struct ActiveCallView: View {
|
||||
@EnvironmentObject var m: ChatModel
|
||||
@Environment(\.scenePhase) var scenePhase
|
||||
@ObservedObject var call: Call
|
||||
@Binding var userAuthorized: Bool?
|
||||
@Binding var canConnectCall: Bool
|
||||
@State private var client: WebRTCClient? = nil
|
||||
@State private var activeCall: WebRTCClient.Call? = nil
|
||||
@@ -39,11 +38,7 @@ struct ActiveCallView: View {
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
logger.debug("ActiveCallView: appear client is nil \(client == nil), userAuthorized \(userAuthorized.debugDescription, privacy: .public), scenePhase \(String(describing: scenePhase), privacy: .public)")
|
||||
createWebRTCClient()
|
||||
}
|
||||
.onChange(of: userAuthorized) { _ in
|
||||
logger.debug("ActiveCallView: userAuthorized changed to \(userAuthorized.debugDescription, privacy: .public)")
|
||||
logger.debug("ActiveCallView: appear client is nil \(client == nil), canConnectCall \(canConnectCall, privacy: .public), scenePhase \(String(describing: scenePhase), privacy: .public)")
|
||||
createWebRTCClient()
|
||||
}
|
||||
.onChange(of: canConnectCall) { _ in
|
||||
@@ -60,8 +55,22 @@ struct ActiveCallView: View {
|
||||
}
|
||||
|
||||
private func createWebRTCClient() {
|
||||
if client == nil && ((userAuthorized == true && canConnectCall) || scenePhase == .background) {
|
||||
client = WebRTCClient($activeCall, { msg in await MainActor.run { processRtcMessage(msg: msg) } }, $localRendererAspectRatio)
|
||||
if client == nil && (canConnectCall || m.onLockScreenCurrently) {
|
||||
createWebRTCClientWithoutWait()
|
||||
} else if (!m.sceneWasActiveAtLeastOnce) {
|
||||
// This code waits a second until it recheck `sceneWasActiveAtLeastOnce`.
|
||||
// It helps to know whether a call from lockscreen or not.
|
||||
// After the second `sceneWasActiveAtLeastOnce` will still be false when the call from lockscreen
|
||||
Task {
|
||||
try? await Task.sleep(nanoseconds: 1_000_000_000)
|
||||
createWebRTCClientWithoutWait()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func createWebRTCClientWithoutWait() {
|
||||
if client == nil && (canConnectCall || !m.sceneWasActiveAtLeastOnce || m.onLockScreenCurrently) {
|
||||
client = WebRTCClient($activeCall, { msg in await MainActor.run {processRtcMessage(msg: msg)} }, $localRendererAspectRatio)
|
||||
sendCommandToClient()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user