Files
cheetah/Cheetah/Views/CoachView.swift
2023-04-26 12:13:57 -04:00

106 lines
3.4 KiB
Swift

import SwiftUI
import LibWhisper
struct CoachView: View {
@ObservedObject var viewModel: AppViewModel
@State var answer: String
@State var answerSelection = NSRange()
@State var showError = false
@State var errorDescription = ""
init(viewModel: AppViewModel) {
self.viewModel = viewModel
self.answer = viewModel.answer ?? ""
}
var spinner: some View {
ProgressView().scaleEffect(0.5)
}
@ViewBuilder
var body: some View {
Picker("Audio input device", selection: $viewModel.selectedDevice) {
Text("-").tag(nil as CaptureDevice?)
ForEach(viewModel.devices, id: \.self) {
Text($0.name).tag($0 as CaptureDevice?)
}
}
.labelsHidden()
.pickerStyle(.menu)
ZStack {
HStack(spacing: 10) {
Button(action: {
viewModel.answerRequest = .answerQuestion
}, label: {
Text("Answer")
})
Button(action: {
viewModel.answerRequest = .refineAnswer(selection: Range(answerSelection, in: answer))
}, label: {
Text("Refine")
})
Button(action: {
viewModel.answerRequest = .analyzeCode
}, label: {
Text("Analyze")
})
}
.disabled((viewModel.authToken == nil || viewModel.analyzer == nil) && !viewModel.buttonsAlwaysEnabled)
HStack {
Spacer()
switch viewModel.answerRequest {
case .none:
spinner.hidden()
default:
spinner
}
}
}
.onReceive(viewModel.$errorDescription) {
if let error = $0 {
self.showError = true
self.errorDescription = error
}
}
.alert(errorDescription, isPresented: $showError) {
Button("OK", role: .cancel) {
self.showError = false
}
}
HStack {
VStack(alignment: .leading, spacing: 20) {
if let transcript = viewModel.transcript {
Text(transcript)
.lineLimit(1)
.truncationMode(.head)
.font(.footnote.italic())
}
ScrollView {
if answer != "" {
NSTextFieldWrapper(text: $answer, selectedRange: $answerSelection)
.onChange(of: viewModel.answer) {
if let newAnswer = $0 {
self.answer = newAnswer
}
}
}
if let solution = viewModel.codeAnswer {
HStack {
Text(solution)
.textSelection(.enabled)
.font(.footnote)
.monospaced()
.lineSpacing(1.2)
Spacer()
}
}
}
.frame(maxHeight: 600)
}
Spacer()
}
}
}