-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Expand file tree
/
Copy pathFloatingControlBarState.swift
More file actions
72 lines (62 loc) · 2.4 KB
/
FloatingControlBarState.swift
File metadata and controls
72 lines (62 loc) · 2.4 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
import Combine
import SwiftUI
/// A single question/answer exchange in the floating bar chat history.
struct FloatingChatExchange: Identifiable {
let id = UUID()
let question: String
let aiMessage: ChatMessage
}
/// A custom in-app notification rendered directly below the floating bar.
struct FloatingBarNotification: Identifiable, Equatable {
let id = UUID()
let title: String
let message: String
let assistantId: String
}
/// Observable object holding the state for the floating control bar.
@MainActor
class FloatingControlBarState: NSObject, ObservableObject {
@Published var isRecording: Bool = false
@Published var duration: Int = 0
@Published var isInitialising: Bool = false
@Published var isDragging: Bool = false
@Published var currentNotification: FloatingBarNotification? = nil
// AI conversation state
@Published var showingAIConversation: Bool = false
@Published var showingAIResponse: Bool = false
@Published var isAILoading: Bool = true
@Published var aiInputText: String = ""
@Published var currentAIMessage: ChatMessage? = nil
@Published var displayedQuery: String = ""
@Published var inputViewHeight: CGFloat = 120
@Published var responseContentHeight: CGFloat = 0
@Published var chatHistory: [FloatingChatExchange] = []
/// Convenience accessor for plain-text response (used by window geometry and error handling).
var aiResponseText: String {
get { currentAIMessage?.text ?? "" }
set {
if currentAIMessage != nil {
currentAIMessage?.text = newValue
} else {
currentAIMessage = ChatMessage(text: newValue, sender: .ai)
}
}
}
// Push-to-talk state
@Published var isVoiceListening: Bool = false
@Published var isVoiceLocked: Bool = false
@Published var voiceTranscript: String = ""
// Voice follow-up state (PTT while AI conversation is active)
@Published var isVoiceFollowUp: Bool = false
@Published var voiceFollowUpTranscript: String = ""
// Model selection
@Published var selectedModel: String = "claude-sonnet-4-6"
/// Available models for the floating bar picker
static let availableModels: [(id: String, label: String)] = [
("claude-sonnet-4-6", "Sonnet"),
("claude-opus-4-6", "Opus"),
]
var isShowingNotification: Bool {
currentNotification != nil
}
}