Create BearWave macOS radio-first app
This commit is contained in:
84
Sources/BearWaveApp/BearWaveApp.swift
Normal file
84
Sources/BearWaveApp/BearWaveApp.swift
Normal file
@@ -0,0 +1,84 @@
|
||||
import AppKit
|
||||
import BearWaveCore
|
||||
import SwiftUI
|
||||
|
||||
@main
|
||||
struct BearWaveApp: App {
|
||||
@NSApplicationDelegateAdaptor(AppDelegate.self) private var appDelegate
|
||||
@State private var model = AppModel()
|
||||
@State private var isMiniPlayer = false
|
||||
|
||||
private static var windowWidth: Double {
|
||||
let screen = NSScreen.main ?? NSScreen.screens.first
|
||||
let width = screen?.visibleFrame.width ?? 1440
|
||||
if width >= 1920 { return 1600 }
|
||||
return 1255
|
||||
}
|
||||
|
||||
var body: some Scene {
|
||||
WindowGroup("BearWave", id: "main") {
|
||||
ContentView(isMiniPlayer: $isMiniPlayer)
|
||||
.environment(model)
|
||||
.frame(
|
||||
minWidth: isMiniPlayer ? 555 : 1255,
|
||||
minHeight: isMiniPlayer ? 110 : 650
|
||||
)
|
||||
.onChange(of: isMiniPlayer) { _, newValue in
|
||||
resizeWindow(toMini: newValue)
|
||||
}
|
||||
.task {
|
||||
await model.start()
|
||||
}
|
||||
}
|
||||
.defaultSize(width: Self.windowWidth, height: 720)
|
||||
.commands {
|
||||
CommandGroup(after: .appTermination) {
|
||||
Button("Play/Pause") {
|
||||
model.playback.togglePlayPause()
|
||||
}
|
||||
.keyboardShortcut(.space, modifiers: [])
|
||||
}
|
||||
CommandGroup(after: .newItem) {
|
||||
Button(isMiniPlayer ? "Show Full Window" : "Mini Player") {
|
||||
isMiniPlayer.toggle()
|
||||
}
|
||||
.keyboardShortcut("m", modifiers: .command)
|
||||
}
|
||||
}
|
||||
|
||||
MenuBarExtra("BearWave", systemImage: model.playback.isPlaying ? "radio.fill" : "radio") {
|
||||
MenuBarContentView()
|
||||
.environment(model)
|
||||
}
|
||||
|
||||
Settings {
|
||||
SettingsView()
|
||||
.environment(model)
|
||||
.frame(width: 520)
|
||||
}
|
||||
}
|
||||
|
||||
private func resizeWindow(toMini: Bool) {
|
||||
let targetSize = toMini ? CGSize(width: 555, height: 110) : CGSize(width: Self.windowWidth, height: 720)
|
||||
Task { @MainActor in
|
||||
guard let window = NSApp.mainWindow ?? NSApp.windows.first else { return }
|
||||
let currentFrame = window.frame
|
||||
var newFrame = currentFrame
|
||||
newFrame.size = targetSize
|
||||
newFrame.origin.y = currentFrame.maxY - targetSize.height
|
||||
window.minSize = targetSize
|
||||
window.setFrame(newFrame, display: true, animate: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
func applicationDidFinishLaunching(_ notification: Notification) {
|
||||
NSApp.setActivationPolicy(.regular)
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
}
|
||||
|
||||
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user