mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-03-25 09:25:50 +00:00
103 lines
3.3 KiB
Swift
103 lines
3.3 KiB
Swift
import AppKit
|
|
import SwiftUI
|
|
|
|
/// Handles the presentation of the welcome screen window.
|
|
///
|
|
/// Manages the lifecycle and presentation of the onboarding welcome window,
|
|
/// including window configuration, positioning, and notification-based showing.
|
|
/// Configured as a floating panel with transparent titlebar for modern appearance.
|
|
@MainActor
|
|
final class WelcomeWindowController: NSWindowController, NSWindowDelegate {
|
|
static let shared = WelcomeWindowController()
|
|
|
|
private var windowObserver: NSObjectProtocol?
|
|
|
|
private init() {
|
|
let welcomeView = WelcomeView()
|
|
.environment(SessionMonitor.shared)
|
|
.environment(ServerManager.shared)
|
|
.environment(NgrokService.shared)
|
|
.environment(SystemPermissionManager.shared)
|
|
.environment(TerminalLauncher.shared)
|
|
let hostingController = NSHostingController(rootView: welcomeView)
|
|
|
|
let window = NSWindow(contentViewController: hostingController)
|
|
window.title = "Welcome to VibeTunnel"
|
|
window.styleMask = [.titled, .closable, .fullSizeContentView]
|
|
window.titlebarAppearsTransparent = true
|
|
window.titleVisibility = .hidden
|
|
window.isMovableByWindowBackground = true
|
|
window.setFrameAutosaveName("WelcomeWindow")
|
|
window.isReleasedWhenClosed = false
|
|
// Use normal window level instead of floating
|
|
window.level = .normal
|
|
|
|
// Set content view mode to ensure proper cleanup
|
|
hostingController.sizingOptions = [.preferredContentSize]
|
|
|
|
super.init(window: window)
|
|
|
|
// Set self as window delegate
|
|
window.delegate = self
|
|
|
|
// Listen for notification to show welcome screen
|
|
NotificationCenter.default.addObserver(
|
|
self,
|
|
selector: #selector(handleShowWelcomeNotification),
|
|
name: .showWelcomeScreen,
|
|
object: nil
|
|
)
|
|
}
|
|
|
|
@available(*, unavailable)
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
func show() {
|
|
guard let window else { return }
|
|
|
|
// Ensure dock icon is visible for window activation
|
|
DockIconManager.shared.temporarilyShowDock()
|
|
|
|
// Center window on the active screen (screen with mouse cursor)
|
|
WindowCenteringHelper.centerOnActiveScreen(window)
|
|
|
|
// Ensure window is visible and in front
|
|
window.makeKeyAndOrderFront(nil)
|
|
window.orderFrontRegardless()
|
|
|
|
// Force activation to bring window to front
|
|
NSApp.activate(ignoringOtherApps: true)
|
|
|
|
// Temporarily raise window level to ensure it's on top
|
|
window.level = .floating
|
|
|
|
// Reset level after a short delay
|
|
Task { @MainActor in
|
|
try? await Task.sleep(for: .milliseconds(100))
|
|
window.level = .normal
|
|
}
|
|
}
|
|
|
|
@objc
|
|
private func handleShowWelcomeNotification() {
|
|
show()
|
|
}
|
|
|
|
// MARK: - NSWindowDelegate
|
|
|
|
func windowWillClose(_ notification: Notification) {
|
|
// Ensure any async tasks are cancelled
|
|
Task { @MainActor in
|
|
// Give SwiftUI time to clean up
|
|
try? await Task.sleep(for: .milliseconds(100))
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Notification Extension
|
|
|
|
extension Notification.Name {
|
|
static let showWelcomeScreen = Notification.Name("showWelcomeScreen")
|
|
}
|