71 lines
2.5 KiB
Swift
71 lines
2.5 KiB
Swift
import SwiftUI
|
|
|
|
@MainActor
|
|
@Observable
|
|
final class SpikeLog {
|
|
var lines: [String] = []
|
|
|
|
func log(_ line: String) {
|
|
lines.append(line)
|
|
}
|
|
}
|
|
|
|
struct SpikeView: View {
|
|
@Environment(Store.self) private var store
|
|
@Environment(SpikeLog.self) private var spike
|
|
|
|
var body: some View {
|
|
let selection = Binding(get: { store.selectedTaskId ?? "" }, set: { store.focusTask($0) })
|
|
VStack(spacing: 0) {
|
|
HStack {
|
|
Picker("Task", selection: selection) {
|
|
Text("None").tag("")
|
|
ForEach(store.activeTasks(), id: \.task.id) { row in
|
|
Text(verbatim: "\(row.project.name): \(row.task.title) · \(store.taskState(row.task).label)").tag(row.task.id)
|
|
}
|
|
}
|
|
.frame(width: 420)
|
|
Text(verbatim: "\(store.me?.displayName ?? "") · \(store.activeTasks().count) active tasks · \(store.inbox.count) inbox · \(store.transcriptLoading() ? "loading" : "\(store.transcript.count) events") · \(store.connected ? "connected" : "reconnecting…")")
|
|
.foregroundStyle(Palette.muted)
|
|
Spacer()
|
|
}
|
|
.padding(8)
|
|
Divider()
|
|
TabView {
|
|
Tab("Composer", systemImage: "keyboard") {
|
|
ComposerSpike()
|
|
}
|
|
Tab("Transcript", systemImage: "text.alignleft") {
|
|
TranscriptSpike()
|
|
.id(store.selectedTaskId)
|
|
}
|
|
Tab("Terminal", systemImage: "terminal") {
|
|
TerminalSpike()
|
|
.id(store.selectedTaskId)
|
|
}
|
|
Tab("Font", systemImage: "textformat") {
|
|
FontSpike()
|
|
}
|
|
Tab("SVG", systemImage: "photo") {
|
|
SVGSpike()
|
|
.id(store.selectedTaskId)
|
|
}
|
|
}
|
|
.padding(8)
|
|
Divider()
|
|
ScrollView {
|
|
VStack(alignment: .leading, spacing: 2) {
|
|
ForEach(Array(spike.lines.enumerated()), id: \.offset) { _, line in
|
|
Text(line)
|
|
}
|
|
}
|
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
.padding(8)
|
|
}
|
|
.defaultScrollAnchor(.bottom)
|
|
.frame(height: 140)
|
|
}
|
|
.frame(minWidth: 1000, minHeight: 700)
|
|
}
|
|
}
|