-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Expand file tree
/
Copy pathChatPanelWindow.swift
More file actions
116 lines (101 loc) · 3.35 KB
/
ChatPanelWindow.swift
File metadata and controls
116 lines (101 loc) · 3.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import AppKit
import ChatTab
import ComposableArchitecture
import Foundation
import SwiftUI
final class ChatPanelWindow: NSWindow {
override var canBecomeKey: Bool { true }
override var canBecomeMain: Bool { true }
private let storeObserver = NSObject()
var minimizeWindow: () -> Void = {}
init(
store: StoreOf<ChatPanelFeature>,
chatTabPool: ChatTabPool,
minimizeWindow: @escaping () -> Void
) {
self.minimizeWindow = minimizeWindow
// Initialize with zero rect initially to prevent flashing
super.init(
contentRect: .zero,
styleMask: [.resizable, .titled, .miniaturizable, .fullSizeContentView, .closable],
backing: .buffered,
defer: true // Use defer to prevent window from appearing immediately
)
titleVisibility = .hidden
addTitlebarAccessoryViewController({
let controller = NSTitlebarAccessoryViewController()
let view = NSHostingView(rootView: ChatTitleBar(store: store))
controller.view = view
view.frame = .init(x: 0, y: 0, width: 100, height: 40)
controller.layoutAttribute = .right
return controller
}())
titlebarAppearsTransparent = true
isReleasedWhenClosed = false
isOpaque = false
backgroundColor = .clear
level = widgetLevel(1)
collectionBehavior = [
.fullScreenAuxiliary,
// .transient,
.fullScreenPrimary,
.fullScreenAllowsTiling,
]
hasShadow = true
// Set contentView after basic configuration
contentView = NSHostingView(
rootView: ChatWindowView(
store: store,
toggleVisibility: { [weak self] isDisplayed in
guard let self else { return }
self.isPanelDisplayed = isDisplayed
}
)
.environment(\.chatTabPool, chatTabPool)
)
// Initialize as invisible first
alphaValue = 0
isPanelDisplayed = false
setIsVisible(true)
storeObserver.observe { [weak self] in
guard let self else { return }
let isDetached = store.isDetached
Task { @MainActor in
if UserDefaults.shared.value(for: \.disableFloatOnTopWhenTheChatPanelIsDetached) {
self.setFloatOnTop(!isDetached)
} else {
self.setFloatOnTop(true)
}
}
}
}
func setFloatOnTop(_ isFloatOnTop: Bool) {
let targetLevel: NSWindow.Level = isFloatOnTop
? .init(NSWindow.Level.floating.rawValue + 1)
: .normal
if targetLevel != level {
level = targetLevel
}
}
var isWindowHidden: Bool = false {
didSet {
alphaValue = isPanelDisplayed && !isWindowHidden ? 1 : 0
}
}
var isPanelDisplayed: Bool = false {
didSet {
alphaValue = isPanelDisplayed && !isWindowHidden ? 1 : 0
}
}
override var alphaValue: CGFloat {
didSet {
ignoresMouseEvents = alphaValue <= 0
}
}
override func miniaturize(_: Any?) {
minimizeWindow()
}
override func close() {
minimizeWindow()
}
}