mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-04-26 15:07:39 +00:00
- Change default server port from 800 to 4020 to avoid privileged port restrictions - Rename TunnelServerDemo.swift to TunnelServer.swift for clarity - Remove redundant TunnelServerExample.swift - Update tty-fwd binary - Add SettingsWindowDelegate for improved window management - Update UI components and session monitoring - Add modern Swift refactoring documentation The server was failing to start because it was trying to bind to port 800, which requires root privileges on macOS. Port 4020 is now used as the default.
71 lines
No EOL
2.4 KiB
Swift
71 lines
No EOL
2.4 KiB
Swift
import AppKit
|
|
import SwiftUI
|
|
|
|
/// A window delegate that handles animated resizing of the settings window
|
|
class SettingsWindowDelegate: NSObject, NSWindowDelegate {
|
|
static let shared = SettingsWindowDelegate()
|
|
|
|
private override init() {
|
|
super.init()
|
|
}
|
|
|
|
/// Animates the window to a new size
|
|
func animateWindowResize(to newSize: CGSize, duration: TimeInterval = 0.3) {
|
|
guard let window = NSApp.windows.first(where: { $0.title.contains("Settings") || $0.title.contains("Preferences") }) else {
|
|
return
|
|
}
|
|
|
|
// Calculate the new frame maintaining the window's top-left position
|
|
var newFrame = window.frame
|
|
let heightDifference = newSize.height - newFrame.height
|
|
newFrame.size = newSize
|
|
newFrame.origin.y -= heightDifference // Keep top edge in place
|
|
|
|
// Animate the frame change
|
|
NSAnimationContext.runAnimationGroup { context in
|
|
context.duration = duration
|
|
context.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
|
|
window.animator().setFrame(newFrame, display: true)
|
|
}
|
|
}
|
|
|
|
func windowWillClose(_ notification: Notification) {
|
|
// Clean up if needed
|
|
}
|
|
}
|
|
|
|
/// A view modifier that sets up the window delegate for animated resizing
|
|
struct AnimatedWindowResizing: ViewModifier {
|
|
let size: CGSize
|
|
|
|
func body(content: Content) -> some View {
|
|
content
|
|
.onAppear {
|
|
setupWindowDelegate()
|
|
// Initial resize without animation
|
|
SettingsWindowDelegate.shared.animateWindowResize(to: size, duration: 0)
|
|
}
|
|
.onChange(of: size) { _, newSize in
|
|
SettingsWindowDelegate.shared.animateWindowResize(to: newSize)
|
|
}
|
|
}
|
|
|
|
private func setupWindowDelegate() {
|
|
Task { @MainActor in
|
|
// Small delay to ensure window is created
|
|
try? await Task.sleep(for: .milliseconds(100))
|
|
|
|
if let window = NSApp.windows.first(where: { $0.title.contains("Settings") || $0.title.contains("Preferences") }) {
|
|
window.delegate = SettingsWindowDelegate.shared
|
|
// Disable window resizing by user
|
|
window.styleMask.remove(.resizable)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
extension View {
|
|
func animatedWindowResizing(size: CGSize) -> some View {
|
|
modifier(AnimatedWindowResizing(size: size))
|
|
}
|
|
} |