Chat: drag handle with detents (fit, 1/3, 1/2, full screen), chat width setting; tall transparent panel
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -56,9 +56,11 @@ final class IslandWindowController: NSWindowController {
|
||||
let nW = geometry.width
|
||||
let nH = geometry.height
|
||||
|
||||
let panelW: CGFloat = 720
|
||||
let panelH: CGFloat = 320
|
||||
// Tall, transparent panel: the chat can grow down to the full screen height
|
||||
// and widen; clicks outside the island still pass through (pollFrame).
|
||||
let sf = screen.frame
|
||||
let panelW: CGFloat = 1100
|
||||
let panelH: CGFloat = sf.height
|
||||
let panel = IslandPanel(
|
||||
contentRect: NSRect(x: sf.midX - panelW/2, y: sf.maxY - panelH,
|
||||
width: panelW, height: panelH),
|
||||
@@ -232,10 +234,12 @@ final class IslandWindowController: NSWindowController {
|
||||
// in the app window immediately below the menu bar.
|
||||
let hoverRect = !hasNotch && state.mode != .expanded
|
||||
? islandRect : islandRect.insetBy(dx: -6, dy: -6)
|
||||
let inIsland = hoverRect.contains(local)
|
||||
// While the chat handle is dragged, count the pointer as inside (no collapse).
|
||||
let inIsland = hoverRect.contains(local) || state.chatDragHeight != nil
|
||||
|
||||
// Toggle click-through
|
||||
let shouldAcceptMouse = inIsland || inAttachDrag || attachDragStart != nil
|
||||
|| state.chatDragHeight != nil
|
||||
if panel.ignoresMouseEvents == shouldAcceptMouse {
|
||||
panel.ignoresMouseEvents = !shouldAcceptMouse
|
||||
if shouldAcceptMouse, let cv = panel.contentView {
|
||||
@@ -1015,12 +1019,10 @@ final class IslandWindowController: NSWindowController {
|
||||
let panelW = window?.frame.width ?? 720
|
||||
let (islandW, fixedH) = islandSize(mode: s.mode, view: s.view,
|
||||
progress: s.uploadProgress, nw: notchW, nh: notchH)
|
||||
// Chat view resizes dynamically — must match IslandContainer.chatPromptHeight
|
||||
// Chat view resizes dynamically — AppState.chatIslandHeight
|
||||
let islandH: CGFloat
|
||||
if s.mode == .expanded && s.view == .prompt {
|
||||
let base: CGFloat = 240
|
||||
let perMsg: CGFloat = 40
|
||||
islandH = min(300, base + CGFloat(s.chatHistory.count) * perMsg)
|
||||
islandH = s.chatIslandHeight
|
||||
} else {
|
||||
islandH = fixedH
|
||||
}
|
||||
@@ -1083,9 +1085,7 @@ final class IslandPanel: NSPanel {
|
||||
progress: s.uploadProgress, nw: nw, nh: nh)
|
||||
let h: CGFloat
|
||||
if s.mode == .expanded && s.view == .prompt {
|
||||
let base: CGFloat = 240
|
||||
let perMsg: CGFloat = 40
|
||||
h = min(300, base + CGFloat(s.chatHistory.count) * perMsg)
|
||||
h = s.chatIslandHeight
|
||||
} else {
|
||||
h = fixedH
|
||||
}
|
||||
@@ -1140,6 +1140,7 @@ extension Notification.Name {
|
||||
|
||||
// MARK: - islandSize (takes real notch dimensions)
|
||||
|
||||
@MainActor
|
||||
func islandSize(mode: IslandMode, view: IslandView,
|
||||
progress: Double = 0,
|
||||
nw: CGFloat = IslandConst.notchWidth,
|
||||
@@ -1149,6 +1150,8 @@ func islandSize(mode: IslandMode, view: IslandView,
|
||||
case .compact: return (nw + 160, nh)
|
||||
case .expanded:
|
||||
let layout = IslandConst.viewLayouts[view]!
|
||||
// BroV: the chat has its own width (Settings → Чат).
|
||||
if view == .prompt { return (AppState.shared.chatWidth, layout.height) }
|
||||
return (IslandConst.expandedWidth, layout.height)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user