Fix the ddi bugs

This commit is contained in:
Stephen B 2025-12-16 13:36:04 -05:00
parent 50fdf332b7
commit 81cf50c40f
2 changed files with 41 additions and 4 deletions

View file

@ -233,7 +233,7 @@ class TunnelManager: ObservableObject {
}
VPNLogger.shared.log("VPN status updated: \(self.tunnelStatus.rawValue)")
if connectionStatus == .connected && heartbeatStartPending {
startHeartbeatInBackground()
startHeartbeatInBackground(showErrorUI: heartbeatPendingShowUI)
}
}
}
@ -502,6 +502,7 @@ class DNSChecker: ObservableObject {
var pubHeartBeat = false
private var heartbeatStartPending = false
private var heartbeatStartInProgress = false
private var heartbeatPendingShowUI = true
@main
struct HeartbeatApp: App {
@ -516,6 +517,7 @@ struct HeartbeatApp: App {
@StateObject private var mount = MountingProgress.shared
@StateObject private var themeExpansionManager = ThemeExpansionManager()
@Environment(\.scenePhase) private var scenePhase // Observe scene lifecycle
@State private var shouldAttemptHeartbeatRestart = false
init() {
registerAdvancedOptionsDefault()
@ -565,6 +567,20 @@ struct HeartbeatApp: App {
}
}
private func handleScenePhaseChange(_ newPhase: ScenePhase) {
switch newPhase {
case .background:
shouldAttemptHeartbeatRestart = true
case .active:
if shouldAttemptHeartbeatRestart {
shouldAttemptHeartbeatRestart = false
startHeartbeatInBackground(showErrorUI: false)
}
default:
break
}
}
private var globalAccent: Color {
themeExpansionManager.resolvedAccentColor(from: customAccentColorHex)
}
@ -629,6 +645,9 @@ struct HeartbeatApp: App {
HeartbeatApp.updateUIKitTint(customHex: newHex,
hasAccess: themeExpansionManager.hasThemeExpansion)
}
.onChange(of: scenePhase) { newPhase in
handleScenePhaseChange(newPhase)
}
.sheet(isPresented: $showWelcomeSheet) {
WelcomeSheetView {
// When the user taps "Continue", mark the app as launched and start the VPN if allowed.
@ -753,12 +772,13 @@ func isPairing() -> Bool {
return true
}
func startHeartbeatInBackground(requireVPNConnection: Bool? = nil) {
func startHeartbeatInBackground(requireVPNConnection: Bool? = nil, showErrorUI: Bool = true) {
assert(Thread.isMainThread, "startHeartbeatInBackground must be called on the main thread")
let pairingFileURL = URL.documentsDirectory.appendingPathComponent("pairingFile.plist")
guard FileManager.default.fileExists(atPath: pairingFileURL.path) else {
heartbeatStartPending = false
heartbeatPendingShowUI = true
return
}
@ -768,6 +788,7 @@ func startHeartbeatInBackground(requireVPNConnection: Bool? = nil) {
if !heartbeatStartPending {
print("Heartbeat start deferred until VPN connects")
}
heartbeatPendingShowUI = showErrorUI
heartbeatStartPending = true
return
}
@ -777,6 +798,7 @@ func startHeartbeatInBackground(requireVPNConnection: Bool? = nil) {
}
heartbeatStartPending = false
heartbeatPendingShowUI = true
heartbeatStartInProgress = true
DispatchQueue.global(qos: .userInteractive).async {
@ -798,6 +820,7 @@ func startHeartbeatInBackground(requireVPNConnection: Bool? = nil) {
let err2 = error as NSError
let code = err2.code
print("Error: \(error.localizedDescription) (Code: \(code))")
guard showErrorUI else { return }
DispatchQueue.main.async {
if code == -9 {
do {

View file

@ -76,6 +76,7 @@ struct HomeView: View {
@State private var isSchedulingInitialSetup = false
@AppStorage("cachedAppNamesData") private var cachedAppNamesData: Data?
@AppStorage("autoStartVPN") private var autoStartVPN = true
@State private var lastDDIIndicatorStatus: StartupIndicatorStatus = .idle
@AppStorage("appTheme") private var appThemeRaw: String = AppTheme.system.rawValue
@Environment(\.themeExpansionManager) private var themeExpansion
@ -195,6 +196,7 @@ struct HomeView: View {
hasAutoStartedConnectionCheck = true
runConnectionDiagnostics(autoStart: true)
}
lastDDIIndicatorStatus = ddiIndicatorStatus
NotificationCenter.default.addObserver(
forName: NSNotification.Name("ShowPairingFilePicker"),
object: nil,
@ -212,6 +214,9 @@ struct HomeView: View {
refreshBackground()
checkPairingFileExists()
heartbeatOK = pubHeartBeat
if !mounting.coolisMounted {
MountingProgress.shared.checkforMounted()
}
}
.onChange(of: pairingFileExists) { _, newValue in
if newValue {
@ -233,6 +238,9 @@ struct HomeView: View {
loadAppListIfNeeded()
syncFavoriteAppNamesWithCache()
}
.onChange(of: ddiIndicatorStatus) { _, newStatus in
handleDDIIndicatorChange(newStatus)
}
.onChange(of: recentApps) { _, _ in
loadAppListIfNeeded()
}
@ -269,6 +277,7 @@ struct HomeView: View {
isImportingFile = false
pairingFileIsValid = true
withAnimation { showPairingFileMessage = true }
MountingProgress.shared.checkforMounted()
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
withAnimation { showPairingFileMessage = false }
}
@ -651,6 +660,12 @@ struct HomeView: View {
isCellularActive = false
}
private func handleDDIIndicatorChange(_ newStatus: StartupIndicatorStatus) {
defer { lastDDIIndicatorStatus = newStatus }
guard lastDDIIndicatorStatus == .success, newStatus == .warning else { return }
startHeartbeatInBackground(showErrorUI: false)
}
private var pairingStatusDescription: String {
if isValidatingPairingFile { return "Validating pairing file…" }
if pairingFileExists {
@ -1178,8 +1193,7 @@ struct HomeView: View {
refreshBackground()
checkPairingFileExists()
loadAppListIfNeeded()
if tunnel.tunnelStatus == .connected {
if tunnel.tunnelStatus == .connected || !requiresLoopbackVPN {
MountingProgress.shared.checkforMounted()
}
}