mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-28 23:54:32 +00:00
Merge branch 'main' of https://github.com/Ebullioscopic/Atoll into feature/lunar-support
conflict resolution needed
This commit is contained in:
commit
9396a5a8ff
4 changed files with 78 additions and 16 deletions
|
|
@ -158,9 +158,13 @@ struct NotchNotesView: View {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback to text if not editing and clipboard has text
|
// Handle text paste
|
||||||
if !isEditingNewNote && selectedNoteId == nil {
|
if let text = pasteboard.string(forType: .string) {
|
||||||
if let text = pasteboard.string(forType: .string) {
|
if isEditingNewNote || selectedNoteId != nil {
|
||||||
|
// In editor: insert text at the end of content since we intercepted the shortcut
|
||||||
|
editorContent.append(text)
|
||||||
|
} else {
|
||||||
|
// Not in editor: create a new note with the pasted text
|
||||||
createNoteWithContent(text)
|
createNoteWithContent(text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -203,6 +203,25 @@ struct ChatMessagesView: View {
|
||||||
.foregroundColor(.primary)
|
.foregroundColor(.primary)
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
|
Button(action: {
|
||||||
|
screenAssistantManager.resetConversationContext()
|
||||||
|
}) {
|
||||||
|
HStack(spacing: 6) {
|
||||||
|
Image(systemName: "arrow.counterclockwise")
|
||||||
|
.font(.caption)
|
||||||
|
Text("Reset Context")
|
||||||
|
.font(.caption)
|
||||||
|
}
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
.padding(.horizontal, 8)
|
||||||
|
.padding(.vertical, 5)
|
||||||
|
.background(Color.gray.opacity(0.12))
|
||||||
|
.cornerRadius(8)
|
||||||
|
}
|
||||||
|
.disabled(screenAssistantManager.isLoading)
|
||||||
|
.buttonStyle(PlainButtonStyle())
|
||||||
|
.help("Clear conversation and attachments")
|
||||||
|
|
||||||
Button(action: {
|
Button(action: {
|
||||||
screenAssistantManager.closePanels()
|
screenAssistantManager.closePanels()
|
||||||
|
|
|
||||||
|
|
@ -6558,27 +6558,27 @@ struct ClipboardSettings: View {
|
||||||
HStack {
|
HStack {
|
||||||
Text("Display Mode")
|
Text("Display Mode")
|
||||||
Spacer()
|
Spacer()
|
||||||
Picker("Display Mode", selection: $clipboardDisplayMode) {
|
Picker("", selection: $clipboardDisplayMode) {
|
||||||
ForEach(ClipboardDisplayMode.allCases, id: \.self) { mode in
|
ForEach(ClipboardDisplayMode.allCases, id: \.self) { mode in
|
||||||
Text(mode.displayName).tag(mode)
|
Text(mode.displayName).tag(mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.pickerStyle(.menu)
|
.pickerStyle(.menu)
|
||||||
.frame(width: 100)
|
.frame(minWidth: 100)
|
||||||
}
|
}
|
||||||
.settingsHighlight(id: highlightID("Display Mode"))
|
.settingsHighlight(id: highlightID("Display Mode"))
|
||||||
|
|
||||||
HStack {
|
HStack {
|
||||||
Text("History Size")
|
Text("History Size")
|
||||||
Spacer()
|
Spacer()
|
||||||
Picker("History Size", selection: $clipboardHistorySize) {
|
Picker("", selection: $clipboardHistorySize) {
|
||||||
Text("3 items").tag(3)
|
Text("3 items").tag(3)
|
||||||
Text("5 items").tag(5)
|
Text("5 items").tag(5)
|
||||||
Text("7 items").tag(7)
|
Text("7 items").tag(7)
|
||||||
Text("10 items").tag(10)
|
Text("10 items").tag(10)
|
||||||
}
|
}
|
||||||
.pickerStyle(.menu)
|
.pickerStyle(.menu)
|
||||||
.frame(width: 100)
|
.frame(minWidth: 100)
|
||||||
}
|
}
|
||||||
.settingsHighlight(id: highlightID("History Size"))
|
.settingsHighlight(id: highlightID("History Size"))
|
||||||
|
|
||||||
|
|
@ -6769,16 +6769,16 @@ struct ScreenAssistantSettings: View {
|
||||||
HStack {
|
HStack {
|
||||||
Text("Display Mode")
|
Text("Display Mode")
|
||||||
Spacer()
|
Spacer()
|
||||||
Picker("Display Mode", selection: $screenAssistantDisplayMode) {
|
Picker("", selection: $screenAssistantDisplayMode) {
|
||||||
ForEach(ScreenAssistantDisplayMode.allCases, id: \.self) { mode in
|
ForEach(ScreenAssistantDisplayMode.allCases, id: \.self) { mode in
|
||||||
Text(mode.displayName).tag(mode)
|
Text(mode.displayName).tag(mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.pickerStyle(.menu)
|
.pickerStyle(.menu)
|
||||||
.frame(width: 100)
|
.frame(minWidth: 100)
|
||||||
}
|
}
|
||||||
.settingsHighlight(id: highlightID("Display Mode"))
|
.settingsHighlight(id: highlightID("Display Mode"))
|
||||||
|
|
||||||
HStack {
|
HStack {
|
||||||
Text("Attached Files")
|
Text("Attached Files")
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
@ -6896,27 +6896,27 @@ struct ColorPickerSettings: View {
|
||||||
HStack {
|
HStack {
|
||||||
Text("Display Mode")
|
Text("Display Mode")
|
||||||
Spacer()
|
Spacer()
|
||||||
Picker("Display Mode", selection: $colorPickerDisplayMode) {
|
Picker("", selection: $colorPickerDisplayMode) {
|
||||||
ForEach(ColorPickerDisplayMode.allCases, id: \.self) { mode in
|
ForEach(ColorPickerDisplayMode.allCases, id: \.self) { mode in
|
||||||
Text(mode.displayName).tag(mode)
|
Text(mode.displayName).tag(mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.pickerStyle(.menu)
|
.pickerStyle(.menu)
|
||||||
.frame(width: 100)
|
.frame(minWidth: 100)
|
||||||
}
|
}
|
||||||
.settingsHighlight(id: highlightID("Display Mode"))
|
.settingsHighlight(id: highlightID("Display Mode"))
|
||||||
|
|
||||||
HStack {
|
HStack {
|
||||||
Text("History Size")
|
Text("History Size")
|
||||||
Spacer()
|
Spacer()
|
||||||
Picker("History Size", selection: $colorHistorySize) {
|
Picker("", selection: $colorHistorySize) {
|
||||||
Text("5 colors").tag(5)
|
Text("5 colors").tag(5)
|
||||||
Text("10 colors").tag(10)
|
Text("10 colors").tag(10)
|
||||||
Text("15 colors").tag(15)
|
Text("15 colors").tag(15)
|
||||||
Text("20 colors").tag(20)
|
Text("20 colors").tag(20)
|
||||||
}
|
}
|
||||||
.pickerStyle(.menu)
|
.pickerStyle(.menu)
|
||||||
.frame(width: 100)
|
.frame(minWidth: 100)
|
||||||
}
|
}
|
||||||
.settingsHighlight(id: highlightID("History Size"))
|
.settingsHighlight(id: highlightID("History Size"))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,7 @@ class ScreenAssistantManager: NSObject, ObservableObject {
|
||||||
|
|
||||||
private var audioRecorder: AVAudioRecorder?
|
private var audioRecorder: AVAudioRecorder?
|
||||||
private var recordingTimer: Timer?
|
private var recordingTimer: Timer?
|
||||||
|
private var activeRequest: URLSessionTask?
|
||||||
|
|
||||||
// Panel management
|
// Panel management
|
||||||
private var chatMessagesPanel: ChatMessagesPanel?
|
private var chatMessagesPanel: ChatMessagesPanel?
|
||||||
|
|
@ -664,10 +665,18 @@ class ScreenAssistantManager: NSObject, ObservableObject {
|
||||||
let task = URLSession.shared.dataTask(with: request) { [weak self] data, response, error in
|
let task = URLSession.shared.dataTask(with: request) { [weak self] data, response, error in
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
|
|
||||||
|
// Ensure this callback belongs to the current in-flight request
|
||||||
|
guard self.activeRequest === task else { return }
|
||||||
|
|
||||||
|
self.isLoading = false
|
||||||
|
self.activeRequest = nil
|
||||||
|
|
||||||
self.handleResponse(data: data, response: response, error: error, provider: provider)
|
self.handleResponse(data: data, response: response, error: error, provider: provider)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activeRequest = task
|
||||||
task.resume()
|
task.resume()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -690,10 +699,18 @@ class ScreenAssistantManager: NSObject, ObservableObject {
|
||||||
let task = URLSession.shared.dataTask(with: request) { [weak self] data, response, error in
|
let task = URLSession.shared.dataTask(with: request) { [weak self] data, response, error in
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
|
|
||||||
|
// Ensure this callback belongs to the current in-flight request
|
||||||
|
guard self.activeRequest === task else { return }
|
||||||
|
|
||||||
|
self.isLoading = false
|
||||||
|
self.activeRequest = nil
|
||||||
|
|
||||||
self.handleResponse(data: data, response: response, error: error, provider: .openai)
|
self.handleResponse(data: data, response: response, error: error, provider: .openai)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activeRequest = task
|
||||||
task.resume()
|
task.resume()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -717,17 +734,29 @@ class ScreenAssistantManager: NSObject, ObservableObject {
|
||||||
let task = URLSession.shared.dataTask(with: request) { [weak self] data, response, error in
|
let task = URLSession.shared.dataTask(with: request) { [weak self] data, response, error in
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
|
|
||||||
|
// Ensure this callback belongs to the current in-flight request
|
||||||
|
guard self.activeRequest === task else { return }
|
||||||
|
|
||||||
|
self.isLoading = false
|
||||||
|
self.activeRequest = nil
|
||||||
|
|
||||||
self.handleResponse(data: data, response: response, error: error, provider: .claude)
|
self.handleResponse(data: data, response: response, error: error, provider: .claude)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activeRequest = task
|
||||||
task.resume()
|
task.resume()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Response Handlers
|
// MARK: - Response Handlers
|
||||||
|
|
||||||
private func handleResponse(data: Data?, response: URLResponse?, error: Error?, provider: AIModelProvider) {
|
private func handleResponse(data: Data?, response: URLResponse?, error: Error?, provider: AIModelProvider) {
|
||||||
isLoading = false
|
// Check if the request was cancelled (e.g., by resetConversationContext)
|
||||||
|
if let error = error as? NSError, error.code == NSURLErrorCancelled {
|
||||||
|
print("ℹ️ ScreenAssistant: Request was cancelled")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if let error = error {
|
if let error = error {
|
||||||
print("❌ ScreenAssistant: Network error - \(error)")
|
print("❌ ScreenAssistant: Network error - \(error)")
|
||||||
|
|
@ -1103,7 +1132,17 @@ class ScreenAssistantManager: NSObject, ObservableObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
func clearChat() {
|
func clearChat() {
|
||||||
|
resetConversationContext()
|
||||||
|
}
|
||||||
|
|
||||||
|
func resetConversationContext() {
|
||||||
|
// Cancel any in-flight request
|
||||||
|
activeRequest?.cancel()
|
||||||
|
activeRequest = nil
|
||||||
|
|
||||||
|
isLoading = false
|
||||||
chatMessages.removeAll()
|
chatMessages.removeAll()
|
||||||
|
clearAllFiles()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func addAssistantMessage(_ content: String) {
|
private func addAssistantMessage(_ content: String) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue