mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-28 07:34:32 +00:00
Working and Hidden - with gemini api
This commit is contained in:
parent
2f7821f4fd
commit
fb4f7a92c4
4 changed files with 236 additions and 522 deletions
|
|
@ -606,18 +606,38 @@ struct StreamingChatMessageBubble: View {
|
|||
struct ScreenshotButton: View {
|
||||
@ObservedObject var screenAssistantManager = ScreenAssistantManager.shared
|
||||
@StateObject private var screenshotTool = ScreenshotSnippingTool.shared
|
||||
@State private var showingScreenshotOptions = false
|
||||
|
||||
var body: some View {
|
||||
Button(action: startScreenshot) {
|
||||
Image(systemName: getIconName())
|
||||
.foregroundColor(getIconColor())
|
||||
.font(.system(size: 20))
|
||||
HStack(spacing: 4) {
|
||||
// Main screenshot button
|
||||
Button(action: startQuickScreenshot) {
|
||||
Image(systemName: getIconName())
|
||||
.foregroundColor(getIconColor())
|
||||
.font(.system(size: 20))
|
||||
}
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
.help("Take area screenshot")
|
||||
.disabled(screenshotTool.isSnipping)
|
||||
.scaleEffect(screenshotTool.isSnipping ? 1.1 : 1.0)
|
||||
.animation(.easeInOut(duration: 0.2), value: screenshotTool.isSnipping)
|
||||
|
||||
// Options dropdown button
|
||||
Button(action: { showingScreenshotOptions.toggle() }) {
|
||||
Image(systemName: "chevron.down")
|
||||
.foregroundColor(.secondary)
|
||||
.font(.system(size: 12))
|
||||
}
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
.help("Screenshot options")
|
||||
.disabled(screenshotTool.isSnipping)
|
||||
.popover(isPresented: $showingScreenshotOptions) {
|
||||
ScreenshotOptionsPopover { type in
|
||||
startScreenshot(type: type)
|
||||
showingScreenshotOptions = false
|
||||
}
|
||||
}
|
||||
}
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
.help(getHelpText())
|
||||
.disabled(screenshotTool.isSnipping)
|
||||
.scaleEffect(screenshotTool.isSnipping ? 1.1 : 1.0)
|
||||
.animation(.easeInOut(duration: 0.2), value: screenshotTool.isSnipping)
|
||||
}
|
||||
|
||||
private func getIconName() -> String {
|
||||
|
|
@ -636,21 +656,22 @@ struct ScreenshotButton: View {
|
|||
}
|
||||
}
|
||||
|
||||
private func getHelpText() -> String {
|
||||
return screenshotTool.isSnipping ? "Taking screenshot..." : "Take screenshot"
|
||||
private func startQuickScreenshot() {
|
||||
// Default to area screenshot for quick action
|
||||
startScreenshot(type: .area)
|
||||
}
|
||||
|
||||
private func startScreenshot() {
|
||||
private func startScreenshot(type: ScreenshotSnippingTool.ScreenshotType) {
|
||||
// Start snipping with direct callback (ScreenshotApp-based approach)
|
||||
screenshotTool.startSnipping { [weak screenAssistantManager] screenshotURL in
|
||||
screenshotTool.startSnipping(type: type) { [weak screenAssistantManager] screenshotURL in
|
||||
guard let manager = screenAssistantManager else {
|
||||
print("❌ ScreenshotTool: ScreenAssistantManager deallocated during callback")
|
||||
return
|
||||
}
|
||||
|
||||
print("📁 ScreenshotTool: Adding screenshot to chat: \(screenshotURL.lastPathComponent)")
|
||||
print("📁 ScreenshotTool: Adding \(type.displayName.lowercased()) screenshot to chat: \(screenshotURL.lastPathComponent)")
|
||||
manager.addFiles([screenshotURL])
|
||||
print("📸 Screenshot captured and added to chat successfully")
|
||||
print("📸 \(type.displayName) screenshot captured and added to chat successfully")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -669,4 +690,141 @@ struct ChatPanelsVisualEffectView: NSViewRepresentable {
|
|||
}
|
||||
|
||||
func updateNSView(_ nsView: NSVisualEffectView, context: Context) {}
|
||||
}
|
||||
|
||||
// MARK: - Screenshot Options Popover (Hidden from Screen Recording)
|
||||
struct ScreenshotOptionsPopover: View {
|
||||
let onOptionSelected: (ScreenshotSnippingTool.ScreenshotType) -> Void
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 8) {
|
||||
Text("Screenshot Type")
|
||||
.font(.headline)
|
||||
.padding(.top, 8)
|
||||
|
||||
VStack(spacing: 4) {
|
||||
ScreenshotOptionButton(
|
||||
type: .area,
|
||||
description: "Select an area",
|
||||
onTap: onOptionSelected
|
||||
)
|
||||
|
||||
ScreenshotOptionButton(
|
||||
type: .window,
|
||||
description: "Select a window",
|
||||
onTap: onOptionSelected
|
||||
)
|
||||
|
||||
ScreenshotOptionButton(
|
||||
type: .full,
|
||||
description: "Capture full screen",
|
||||
onTap: onOptionSelected
|
||||
)
|
||||
}
|
||||
.padding(.bottom, 8)
|
||||
}
|
||||
.padding(.horizontal, 12)
|
||||
.frame(width: 200)
|
||||
.background(
|
||||
ScreenshotPopoverBackground()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Screenshot Option Button
|
||||
struct ScreenshotOptionButton: View {
|
||||
let type: ScreenshotSnippingTool.ScreenshotType
|
||||
let description: String
|
||||
let onTap: (ScreenshotSnippingTool.ScreenshotType) -> Void
|
||||
|
||||
var body: some View {
|
||||
Button(action: { onTap(type) }) {
|
||||
HStack(spacing: 12) {
|
||||
Image(systemName: type.iconName)
|
||||
.foregroundColor(.blue)
|
||||
.font(.system(size: 16))
|
||||
.frame(width: 20, alignment: .center)
|
||||
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
Text(type.displayName)
|
||||
.font(.system(size: 14, weight: .medium))
|
||||
.foregroundColor(.primary)
|
||||
|
||||
Text(description)
|
||||
.font(.system(size: 12))
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
|
||||
Spacer()
|
||||
}
|
||||
.padding(.horizontal, 8)
|
||||
.padding(.vertical, 6)
|
||||
.background(
|
||||
RoundedRectangle(cornerRadius: 6)
|
||||
.fill(Color.clear)
|
||||
.contentShape(Rectangle())
|
||||
)
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 6)
|
||||
.stroke(Color.clear, lineWidth: 1)
|
||||
)
|
||||
}
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
.background(
|
||||
RoundedRectangle(cornerRadius: 6)
|
||||
.fill(Color(NSColor.controlBackgroundColor))
|
||||
.opacity(0.5)
|
||||
)
|
||||
.onHover { isHovered in
|
||||
// Add subtle hover effect if needed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Screenshot Popover Background (Hidden from Screen Recording)
|
||||
struct ScreenshotPopoverBackground: NSViewRepresentable {
|
||||
func makeNSView(context: Context) -> NSView {
|
||||
let view = NSView()
|
||||
|
||||
// Apply screen capture protection like our other panels
|
||||
DispatchQueue.main.async {
|
||||
if let window = view.window {
|
||||
self.updateScreenCaptureVisibility(window: window)
|
||||
self.setupScreenCaptureObserver(window: window)
|
||||
}
|
||||
}
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
func updateNSView(_ nsView: NSView, context: Context) {
|
||||
// Update screen capture protection when view updates
|
||||
if let window = nsView.window {
|
||||
updateScreenCaptureVisibility(window: window)
|
||||
}
|
||||
}
|
||||
|
||||
private func updateScreenCaptureVisibility(window: NSWindow) {
|
||||
let shouldHide = Defaults[.hidePanelsFromScreenCapture]
|
||||
|
||||
if shouldHide {
|
||||
// Hide from screen capture and recording
|
||||
window.sharingType = .none
|
||||
print("🙈 ScreenshotPopover: Hidden from screen capture and recordings")
|
||||
} else {
|
||||
// Allow normal screen capture
|
||||
window.sharingType = .readOnly
|
||||
print("👁️ ScreenshotPopover: Visible in screen capture and recordings")
|
||||
}
|
||||
}
|
||||
|
||||
private func setupScreenCaptureObserver(window: NSWindow) {
|
||||
// Observe changes to hidePanelsFromScreenCapture setting
|
||||
Defaults.observe(.hidePanelsFromScreenCapture) { [weak window] change in
|
||||
DispatchQueue.main.async {
|
||||
guard let window = window else { return }
|
||||
self.updateScreenCaptureVisibility(window: window)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue