forked from BasedHardware/omi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMemoryPromptEditorWindow.swift
More file actions
139 lines (118 loc) · 3.99 KB
/
Copy pathMemoryPromptEditorWindow.swift
File metadata and controls
139 lines (118 loc) · 3.99 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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import Cocoa
import OmiTheme
import SwiftUI
/// Window for editing the memory extraction prompt
class MemoryPromptEditorWindow: NSWindow {
private static var sharedWindow: MemoryPromptEditorWindow?
static func show() {
if let existing = sharedWindow, existing.isVisible {
existing.makeKeyAndOrderFront(nil)
return
}
let window = MemoryPromptEditorWindow()
sharedWindow = window
window.makeKeyAndOrderFront(nil)
window.center()
}
init() {
super.init(
contentRect: NSRect(x: 0, y: 0, width: 700, height: 600),
styleMask: [.titled, .closable, .resizable, .miniaturizable, .fullSizeContentView],
backing: .buffered,
defer: false
)
title = "Memory Extraction Prompt"
minSize = NSSize(width: 500, height: 400)
isReleasedWhenClosed = false
// The inside of a titled window is glass: transparent, light-pinned, and shadowed by its own
// frame (`WindowGlass.Kind.titled`). Without the pin the title bar and the traffic lights stay in
// the machine's appearance — a dark title bar on a white sheet on a Dark Mac.
WindowGlass.wear(self, as: .titled)
contentView = NSHostingView(
rootView: MemoryPromptEditorView(onClose: { [weak self] in
self?.close()
}).withFontScaling())
}
}
struct MemoryPromptEditorView: View {
@State private var promptText: String
@State private var hasChanges: Bool = false
@State private var showingResetAlert: Bool = false
var onClose: (() -> Void)?
init(onClose: (() -> Void)? = nil) {
self.onClose = onClose
_promptText = State(initialValue: MemoryAssistantSettings.shared.analysisPrompt)
}
var body: some View {
VStack(spacing: 0) {
// Header
HStack {
VStack(alignment: .leading, spacing: OmiSpacing.xxs) {
Text("Memory Extraction Prompt")
.scaledFont(size: OmiType.subheading, weight: .semibold)
Text("Customize how the AI extracts memories from screenshots")
.scaledFont(size: OmiType.caption)
.foregroundColor(.secondary)
}
Spacer()
if hasChanges {
Text("Unsaved changes")
.scaledFont(size: OmiType.caption)
.foregroundColor(.orange)
.padding(.horizontal, OmiSpacing.sm)
.padding(.vertical, OmiSpacing.xxs)
.background(Color.orange.opacity(0.1))
.cornerRadius(OmiChrome.stripRadius)
}
}
.padding()
Divider()
// Editor
TextEditor(text: $promptText)
.scaledFont(size: OmiType.body, design: .monospaced)
.padding(OmiSpacing.sm)
.onChange(of: promptText) { _, newValue in
hasChanges = newValue != MemoryAssistantSettings.shared.analysisPrompt
}
Divider()
// Footer with buttons
HStack {
Button("Reset to Default") {
showingResetAlert = true
}
.alert("Reset Prompt?", isPresented: $showingResetAlert) {
Button("Cancel", role: .cancel) {}
Button("Reset", role: .destructive) {
promptText = MemoryAssistantSettings.defaultAnalysisPrompt
MemoryAssistantSettings.shared.resetPromptToDefault()
hasChanges = false
}
} message: {
Text("This will reset the memory extraction prompt to its default value. This cannot be undone.")
}
Spacer()
Button("Cancel") {
onClose?()
}
.keyboardShortcut(.escape, modifiers: [])
Button("Save") {
MemoryAssistantSettings.shared.analysisPrompt = promptText
hasChanges = false
onClose?()
}
.keyboardShortcut(.return, modifiers: .command)
.buttonStyle(.borderedProminent)
.disabled(!hasChanges)
}
.padding()
}
.frame(minWidth: 500, minHeight: 400)
.inkGlassPanel(cornerRadius: 0, shadow: nil)
}
}
#if canImport(PreviewsMacros)
#Preview {
MemoryPromptEditorView()
.frame(width: 700, height: 600)
}
#endif