mirror of
https://github.com/yattee/yattee.git
synced 2024-12-22 05:23:41 +00:00
Improve windows handling on macOS
This commit is contained in:
parent
3baa7a6893
commit
8a74938b98
@ -50,7 +50,7 @@ final class NavigationModel: ObservableObject {
|
||||
) {
|
||||
let recent = RecentItem(from: channel)
|
||||
#if os(macOS)
|
||||
OpenWindow.main.open()
|
||||
Windows.main.open()
|
||||
#else
|
||||
player.hide()
|
||||
#endif
|
||||
|
@ -33,7 +33,7 @@ final class PlayerModel: ObservableObject {
|
||||
@Published var streamSelection: Stream? { didSet { rebuildTVMenu() } }
|
||||
|
||||
@Published var queue = [PlayerQueueItem]() { didSet { Defaults[.queue] = queue } }
|
||||
@Published var currentItem: PlayerQueueItem!
|
||||
@Published var currentItem: PlayerQueueItem! { didSet { updateWindowTitle() }}
|
||||
@Published var historyVideos = [Video]()
|
||||
|
||||
@Published var preservedTime: CMTime?
|
||||
@ -103,13 +103,13 @@ final class PlayerModel: ObservableObject {
|
||||
func show() {
|
||||
guard !presentingPlayer else {
|
||||
#if os(macOS)
|
||||
OpenWindow.player.focus()
|
||||
Windows.player.focus()
|
||||
#endif
|
||||
return
|
||||
}
|
||||
#if os(macOS)
|
||||
OpenWindow.player.open()
|
||||
OpenWindow.player.focus()
|
||||
Windows.player.open()
|
||||
Windows.player.focus()
|
||||
#endif
|
||||
presentingPlayer = true
|
||||
}
|
||||
@ -122,9 +122,9 @@ final class PlayerModel: ObservableObject {
|
||||
func togglePlayer() {
|
||||
#if os(macOS)
|
||||
if !presentingPlayer {
|
||||
OpenWindow.player.open()
|
||||
Windows.player.open()
|
||||
}
|
||||
OpenWindow.player.focus()
|
||||
Windows.player.focus()
|
||||
#else
|
||||
if presentingPlayer {
|
||||
hide()
|
||||
@ -804,6 +804,12 @@ final class PlayerModel: ObservableObject {
|
||||
}
|
||||
#endif
|
||||
|
||||
func updateWindowTitle() {
|
||||
#if os(macOS)
|
||||
Windows.player.window?.title = windowTitle
|
||||
#endif
|
||||
}
|
||||
|
||||
#if os(macOS)
|
||||
var windowTitle: String {
|
||||
currentVideo.isNil ? "Not playing" : "\(currentVideo!.title) - \(currentVideo!.author)"
|
||||
|
@ -14,7 +14,7 @@ struct OpenURLHandler {
|
||||
}
|
||||
|
||||
#if os(macOS)
|
||||
guard url.host != OpenWindow.player.location else {
|
||||
guard url.host != Windows.player.location else {
|
||||
return
|
||||
}
|
||||
#endif
|
||||
@ -28,7 +28,7 @@ struct OpenURLHandler {
|
||||
}
|
||||
|
||||
#if os(macOS)
|
||||
OpenWindow.main.open()
|
||||
Windows.main.open()
|
||||
#endif
|
||||
|
||||
accounts.api.video(id).load().onSuccess { response in
|
||||
|
@ -47,12 +47,18 @@ struct YatteeApp: App {
|
||||
.environmentObject(thumbnails)
|
||||
.environmentObject(menu)
|
||||
.environmentObject(search)
|
||||
#if !os(macOS)
|
||||
.onReceive(
|
||||
NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)
|
||||
) { _ in
|
||||
player.handleEnterForeground()
|
||||
}
|
||||
#if os(macOS)
|
||||
.background(
|
||||
HostingWindowFinder { window in
|
||||
Windows.mainWindow = window
|
||||
}
|
||||
)
|
||||
#else
|
||||
.onReceive(
|
||||
NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)
|
||||
) { _ in
|
||||
player.handleEnterForeground()
|
||||
}
|
||||
#endif
|
||||
#if os(iOS)
|
||||
.handlesExternalEvents(preferring: Set(["*"]), allowing: Set(["*"]))
|
||||
@ -81,6 +87,11 @@ struct YatteeApp: App {
|
||||
#if os(macOS)
|
||||
WindowGroup(player.windowTitle) {
|
||||
VideoPlayerView()
|
||||
.background(
|
||||
HostingWindowFinder { window in
|
||||
Windows.playerWindow = window
|
||||
}
|
||||
)
|
||||
.onAppear { player.presentingPlayer = true }
|
||||
.onDisappear { player.presentingPlayer = false }
|
||||
.environment(\.managedObjectContext, persistenceController.container.viewContext)
|
||||
|
@ -240,7 +240,7 @@
|
||||
37732FF22703A26300F04329 /* AccountValidationStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37732FEF2703A26300F04329 /* AccountValidationStatus.swift */; };
|
||||
37732FF42703D32400F04329 /* Sidebar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37732FF32703D32400F04329 /* Sidebar.swift */; };
|
||||
37732FF52703D32400F04329 /* Sidebar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37732FF32703D32400F04329 /* Sidebar.swift */; };
|
||||
37737786276F9858000521C1 /* OpenWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37737785276F9858000521C1 /* OpenWindow.swift */; };
|
||||
37737786276F9858000521C1 /* Windows.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37737785276F9858000521C1 /* Windows.swift */; };
|
||||
3774122A27387B6C00423605 /* InstancesModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3774122927387B6C00423605 /* InstancesModelTests.swift */; };
|
||||
3774122F27387C7600423605 /* VideosApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 376A33DF2720CAD6000C1D6B /* VideosApp.swift */; };
|
||||
3774123327387CB000423605 /* Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372915E52687E3B900F5A35B /* Defaults.swift */; };
|
||||
@ -690,7 +690,7 @@
|
||||
376CD21526FBE18D001E1AC1 /* Instance+Fixtures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Instance+Fixtures.swift"; sourceTree = "<group>"; };
|
||||
37732FEF2703A26300F04329 /* AccountValidationStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountValidationStatus.swift; sourceTree = "<group>"; };
|
||||
37732FF32703D32400F04329 /* Sidebar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sidebar.swift; sourceTree = "<group>"; };
|
||||
37737785276F9858000521C1 /* OpenWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenWindow.swift; sourceTree = "<group>"; };
|
||||
37737785276F9858000521C1 /* Windows.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Windows.swift; sourceTree = "<group>"; };
|
||||
3774122927387B6C00423605 /* InstancesModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstancesModelTests.swift; sourceTree = "<group>"; };
|
||||
377A20A82693C9A2002842B8 /* TypedContentAccessors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TypedContentAccessors.swift; sourceTree = "<group>"; };
|
||||
3782B94E27553A6700990149 /* SearchSuggestions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchSuggestions.swift; sourceTree = "<group>"; };
|
||||
@ -1182,7 +1182,7 @@
|
||||
37BE7AF227601DBF00DBECED /* Updates */,
|
||||
374C0542272496E4009BDDBE /* AppDelegate.swift */,
|
||||
37FD43DB270470B70073EE42 /* InstancesSettings.swift */,
|
||||
37737785276F9858000521C1 /* OpenWindow.swift */,
|
||||
37737785276F9858000521C1 /* Windows.swift */,
|
||||
374108D0272B11B2006C5CC8 /* PictureInPictureDelegate.swift */,
|
||||
37BE0BDB26A2367F0092E2DB /* Player.swift */,
|
||||
37BE0BD926A214630092E2DB /* PlayerViewController.swift */,
|
||||
@ -2060,7 +2060,7 @@
|
||||
374710062755291C00CE0F87 /* SearchField.swift in Sources */,
|
||||
378AE93F274EDFB5006A4EE1 /* Tint+Backport.swift in Sources */,
|
||||
37C194C826F6A9C8005D3B96 /* RecentsModel.swift in Sources */,
|
||||
37737786276F9858000521C1 /* OpenWindow.swift in Sources */,
|
||||
37737786276F9858000521C1 /* Windows.swift in Sources */,
|
||||
37BE0BDC26A2367F0092E2DB /* Player.swift in Sources */,
|
||||
3743CA53270F284F00E4D32B /* View+Borders.swift in Sources */,
|
||||
37599F39272B4D740087F250 /* FavoriteButton.swift in Sources */,
|
||||
|
@ -1,40 +0,0 @@
|
||||
import AppKit
|
||||
import Foundation
|
||||
|
||||
enum OpenWindow: String, CaseIterable {
|
||||
case player, main
|
||||
|
||||
var window: NSWindow? {
|
||||
// this is not solid but works as long as there is only two windows in the app
|
||||
// needs to be changed in case we ever have more windows to handle
|
||||
|
||||
switch self {
|
||||
case .player:
|
||||
return NSApplication.shared.windows.last
|
||||
case .main:
|
||||
return NSApplication.shared.windows.first
|
||||
}
|
||||
}
|
||||
|
||||
func focus() {
|
||||
window?.makeKeyAndOrderFront(self)
|
||||
}
|
||||
|
||||
var location: String {
|
||||
switch self {
|
||||
case .player:
|
||||
return rawValue
|
||||
case .main:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func open() {
|
||||
switch self {
|
||||
case .player:
|
||||
NSWorkspace.shared.open(URL(string: "yattee://\(location)")!)
|
||||
case .main:
|
||||
Self.main.focus()
|
||||
}
|
||||
}
|
||||
}
|
55
macOS/Windows.swift
Normal file
55
macOS/Windows.swift
Normal file
@ -0,0 +1,55 @@
|
||||
import AppKit
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
enum Windows: String, CaseIterable {
|
||||
case player, main
|
||||
|
||||
static var mainWindow: NSWindow?
|
||||
static var playerWindow: NSWindow?
|
||||
|
||||
weak var window: NSWindow? {
|
||||
switch self {
|
||||
case .player:
|
||||
return Self.playerWindow
|
||||
case .main:
|
||||
return Self.mainWindow
|
||||
}
|
||||
}
|
||||
|
||||
func focus() {
|
||||
window?.makeKeyAndOrderFront(self)
|
||||
}
|
||||
|
||||
var location: String {
|
||||
switch self {
|
||||
case .player:
|
||||
return rawValue
|
||||
case .main:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func open() {
|
||||
switch self {
|
||||
case .player:
|
||||
NSWorkspace.shared.open(URL(string: "yattee://\(location)")!)
|
||||
case .main:
|
||||
Self.main.focus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct HostingWindowFinder: NSViewRepresentable {
|
||||
var callback: (NSWindow?) -> Void
|
||||
|
||||
func makeNSView(context _: Self.Context) -> NSView {
|
||||
let view = NSView()
|
||||
DispatchQueue.main.async { [weak view] in
|
||||
self.callback(view?.window)
|
||||
}
|
||||
return view
|
||||
}
|
||||
|
||||
func updateNSView(_: NSView, context _: Context) {}
|
||||
}
|
Loading…
Reference in New Issue
Block a user