mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-04-22 14:06:02 +00:00
modernize mac code
This commit is contained in:
parent
26413645b3
commit
a314fe8bf0
9 changed files with 86 additions and 19 deletions
61
VibeTunnel/Core/Extensions/EnvironmentValues+Services.swift
Normal file
61
VibeTunnel/Core/Extensions/EnvironmentValues+Services.swift
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
import SwiftUI
|
||||
|
||||
// MARK: - Environment Keys
|
||||
|
||||
private struct ServerManagerKey: EnvironmentKey {
|
||||
static let defaultValue: ServerManager? = nil
|
||||
}
|
||||
|
||||
private struct NgrokServiceKey: EnvironmentKey {
|
||||
static let defaultValue: NgrokService? = nil
|
||||
}
|
||||
|
||||
private struct AppleScriptPermissionManagerKey: EnvironmentKey {
|
||||
static let defaultValue: AppleScriptPermissionManager? = nil
|
||||
}
|
||||
|
||||
private struct TerminalLauncherKey: EnvironmentKey {
|
||||
static let defaultValue: TerminalLauncher? = nil
|
||||
}
|
||||
|
||||
// MARK: - Environment Values Extensions
|
||||
|
||||
extension EnvironmentValues {
|
||||
var serverManager: ServerManager {
|
||||
get { self[ServerManagerKey.self] }
|
||||
set { self[ServerManagerKey.self] = newValue }
|
||||
}
|
||||
|
||||
var ngrokService: NgrokService {
|
||||
get { self[NgrokServiceKey.self] }
|
||||
set { self[NgrokServiceKey.self] = newValue }
|
||||
}
|
||||
|
||||
var appleScriptPermissionManager: AppleScriptPermissionManager {
|
||||
get { self[AppleScriptPermissionManagerKey.self] }
|
||||
set { self[AppleScriptPermissionManagerKey.self] = newValue }
|
||||
}
|
||||
|
||||
var terminalLauncher: TerminalLauncher {
|
||||
get { self[TerminalLauncherKey.self] }
|
||||
set { self[TerminalLauncherKey.self] = newValue }
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - View Extensions
|
||||
|
||||
extension View {
|
||||
/// Injects all VibeTunnel services into the environment
|
||||
func withVibeTunnelServices(
|
||||
serverManager: ServerManager = .shared,
|
||||
ngrokService: NgrokService = .shared,
|
||||
appleScriptPermissionManager: AppleScriptPermissionManager = .shared,
|
||||
terminalLauncher: TerminalLauncher = .shared
|
||||
) -> some View {
|
||||
self
|
||||
.environment(\.serverManager, serverManager)
|
||||
.environment(\.ngrokService, ngrokService)
|
||||
.environment(\.appleScriptPermissionManager, appleScriptPermissionManager)
|
||||
.environment(\.terminalLauncher, terminalLauncher)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import AppKit
|
||||
import Foundation
|
||||
import OSLog
|
||||
import Observation
|
||||
|
||||
/// Manages AppleScript automation permissions for VibeTunnel.
|
||||
///
|
||||
|
|
@ -8,11 +9,12 @@ import OSLog
|
|||
/// terminal applications via AppleScript. It provides continuous monitoring
|
||||
/// and user-friendly permission request flows.
|
||||
@MainActor
|
||||
final class AppleScriptPermissionManager: ObservableObject {
|
||||
@Observable
|
||||
final class AppleScriptPermissionManager {
|
||||
static let shared = AppleScriptPermissionManager()
|
||||
|
||||
@Published private(set) var hasPermission = false
|
||||
@Published private(set) var isChecking = false
|
||||
private(set) var hasPermission = false
|
||||
private(set) var isChecking = false
|
||||
|
||||
private let logger = Logger(
|
||||
subsystem: Bundle.main.bundleIdentifier ?? "VibeTunnel",
|
||||
|
|
@ -30,7 +32,7 @@ final class AppleScriptPermissionManager: ObservableObject {
|
|||
}
|
||||
|
||||
deinit {
|
||||
monitoringTask?.cancel()
|
||||
// Task will be cancelled automatically when the object is deallocated
|
||||
}
|
||||
|
||||
/// Checks if we have AppleScript automation permissions.
|
||||
|
|
|
|||
|
|
@ -104,8 +104,8 @@ final class NgrokService: NgrokTunnelProtocol {
|
|||
/// The ngrok process if using CLI mode
|
||||
private var ngrokProcess: Process?
|
||||
|
||||
/// Timer for periodic status updates
|
||||
private var statusTimer: Timer?
|
||||
/// Task for periodic status updates
|
||||
private var statusTask: Task<Void, Never>?
|
||||
|
||||
private let logger = Logger(subsystem: "sh.vibetunnel.vibetunnel", category: "NgrokService")
|
||||
|
||||
|
|
@ -136,8 +136,8 @@ final class NgrokService: NgrokTunnelProtocol {
|
|||
ngrokProcess = nil
|
||||
}
|
||||
|
||||
statusTimer?.invalidate()
|
||||
statusTimer = nil
|
||||
statusTask?.cancel()
|
||||
statusTask = nil
|
||||
|
||||
isActive = false
|
||||
publicUrl = nil
|
||||
|
|
@ -257,11 +257,12 @@ final class NgrokService: NgrokTunnelProtocol {
|
|||
|
||||
/// Monitors tunnel status periodically
|
||||
private func startStatusMonitoring() {
|
||||
statusTimer?.invalidate()
|
||||
statusTask?.cancel()
|
||||
|
||||
statusTimer = Timer.scheduledTimer(withTimeInterval: 5.0, repeats: true) { _ in
|
||||
Task { @MainActor in
|
||||
statusTask = Task { @MainActor in
|
||||
while !Task.isCancelled {
|
||||
await self.updateTunnelStatus()
|
||||
try? await Task.sleep(nanoseconds: 5_000_000_000) // 5 seconds
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import Combine
|
||||
import Foundation
|
||||
import Logging
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ struct DashboardSettingsView: View {
|
|||
@State private var passwordError: String?
|
||||
@State private var passwordSaved = false
|
||||
|
||||
@StateObject private var permissionManager = AppleScriptPermissionManager.shared
|
||||
@State private var permissionManager = AppleScriptPermissionManager.shared
|
||||
|
||||
@State private var ngrokAuthToken = ""
|
||||
@State private var ngrokStatus: NgrokTunnelStatus?
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
/// General settings tab for basic app preferences
|
||||
|
|
@ -128,7 +127,7 @@ struct GeneralSettingsView: View {
|
|||
// MARK: - Permissions Section
|
||||
|
||||
private struct PermissionsSection: View {
|
||||
@StateObject private var appleScriptManager = AppleScriptPermissionManager.shared
|
||||
@State private var appleScriptManager = AppleScriptPermissionManager.shared
|
||||
@State private var accessibilityUpdateTrigger = 0
|
||||
|
||||
private var hasAccessibilityPermission: Bool {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import SwiftUI
|
|||
/// - ``AccessibilityPermissionManager`` for accessibility permissions
|
||||
/// - Terminal selection stored in UserDefaults
|
||||
struct RequestPermissionsPageView: View {
|
||||
@StateObject private var appleScriptManager = AppleScriptPermissionManager.shared
|
||||
@State private var appleScriptManager = AppleScriptPermissionManager.shared
|
||||
@State private var accessibilityUpdateTrigger = 0
|
||||
|
||||
private var hasAccessibilityPermission: Bool {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ struct WelcomeView: View {
|
|||
@AppStorage(AppConstants.UserDefaultsKeys.welcomeVersion)
|
||||
private var welcomeVersion = 0
|
||||
@State private var cliInstaller = CLIInstaller()
|
||||
@StateObject private var permissionManager = AppleScriptPermissionManager.shared
|
||||
@State private var permissionManager = AppleScriptPermissionManager.shared
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 0) {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@ struct VibeTunnelApp: App {
|
|||
@NSApplicationDelegateAdaptor(AppDelegate.self)
|
||||
var appDelegate
|
||||
@State private var sessionMonitor = SessionMonitor.shared
|
||||
@State private var serverManager = ServerManager.shared
|
||||
@State private var ngrokService = NgrokService.shared
|
||||
@State private var appleScriptPermissionManager = AppleScriptPermissionManager.shared
|
||||
@State private var terminalLauncher = TerminalLauncher.shared
|
||||
|
||||
init() {
|
||||
// No special initialization needed
|
||||
|
|
@ -28,6 +32,7 @@ struct VibeTunnelApp: App {
|
|||
// Welcome Window
|
||||
WindowGroup("Welcome", id: "welcome") {
|
||||
WelcomeView()
|
||||
.withVibeTunnelServices()
|
||||
}
|
||||
.windowResizability(.contentSize)
|
||||
.defaultSize(width: 580, height: 480)
|
||||
|
|
@ -35,6 +40,7 @@ struct VibeTunnelApp: App {
|
|||
|
||||
Settings {
|
||||
SettingsView()
|
||||
.withVibeTunnelServices()
|
||||
}
|
||||
.commands {
|
||||
CommandGroup(after: .appInfo) {
|
||||
|
|
@ -55,7 +61,7 @@ struct VibeTunnelApp: App {
|
|||
MenuBarExtra {
|
||||
MenuBarView()
|
||||
.environment(sessionMonitor)
|
||||
.environment(serverMonitor)
|
||||
.withVibeTunnelServices()
|
||||
} label: {
|
||||
Image("menubar")
|
||||
.renderingMode(.template)
|
||||
|
|
@ -159,7 +165,6 @@ final class AppDelegate: NSObject, NSApplicationDelegate, @preconcurrency UNUser
|
|||
// Check if server actually started
|
||||
if serverManager.isRunning {
|
||||
logger.info("HTTP server started successfully on port \(self.serverManager.port)")
|
||||
logger.info("Server mode: \(self.serverManager.serverMode.displayName)")
|
||||
|
||||
// Start monitoring sessions after server starts
|
||||
sessionMonitor.startMonitoring()
|
||||
|
|
|
|||
Loading…
Reference in a new issue