fix: weird model selector fixed

This commit is contained in:
2026-04-17 14:13:38 +02:00
parent 6e20bd538b
commit d5b9ae15cc
2 changed files with 45 additions and 57 deletions

View File

@@ -11,6 +11,7 @@ struct ContentView: View {
@State private var showLoadError = false
@State private var showMonitor = false
@State private var showScenePicker = false
@State private var confirmRedownload: ModelConfig?
@State private var exportDocument: ChatExportDocument?
@State private var documentErrorMessage: String?
@State private var exportErrorMessage: String?
@@ -67,6 +68,24 @@ struct ContentView: View {
private var alertContent: some View {
AnyView(lifecycleContent)
.alert("Re-download Model?", isPresented: .init(
get: { confirmRedownload != nil },
set: { if !$0 { confirmRedownload = nil } }
)) {
Button("Re-download", role: .destructive) {
if let config = confirmRedownload {
confirmRedownload = nil
Task { await modelManager.redownloadModel(config) }
}
}
Button("Cancel", role: .cancel) {
confirmRedownload = nil
}
} message: {
if let config = confirmRedownload {
Text("This will delete the local cache for \(config.displayName) and download it again from HuggingFace.")
}
}
.alert("Model Error", isPresented: $showLoadError) {
Button("Retry") {
if let config = modelManager.currentModel ?? modelManager.availableModels.first {
@@ -167,6 +186,16 @@ struct ContentView: View {
@ViewBuilder
private var toolbarButtons: some View {
// Re-download current model
if let current = modelManager.currentModel, !modelManager.isLoading {
Button {
confirmRedownload = current
} label: {
Label("Re-download Model", systemImage: "arrow.clockwise")
}
.help("Re-download \(current.displayName)")
}
// API server toggle
let isRunning = chatVM?.apiServer.isRunning == true
Button {

View File

@@ -2,72 +2,31 @@ import SwiftUI
struct ModelPickerView: View {
@Environment(ModelManager.self) private var modelManager
@State private var confirmRedownload: ModelConfig?
var body: some View {
HStack(spacing: 8) {
Picker("Model", selection: selectedModelBinding) {
ForEach(modelManager.availableModels) { config in
Menu {
ForEach(modelManager.availableModels) { config in
Button {
guard config.id != modelManager.currentModel?.id else { return }
Task { await modelManager.loadModel(config) }
} label: {
Label(
config.isCurated ? config.displayName : config.repoId,
systemImage: config.isLocal ? "checkmark.circle.fill" : "arrow.down.circle"
).tag(config.id)
)
}
}
.frame(width: 260)
.disabled(modelManager.isLoading)
// Re-download button (visible when a model is loaded)
if let current = modelManager.currentModel, !modelManager.isLoading {
Button {
confirmRedownload = current
} label: {
Image(systemName: "arrow.clockwise")
.font(.caption)
}
.buttonStyle(.borderless)
.help("Re-download \(current.displayName)")
}
}
.alert("Re-download Model?", isPresented: .init(
get: { confirmRedownload != nil },
set: { if !$0 { confirmRedownload = nil } }
)) {
Button("Re-download", role: .destructive) {
if let config = confirmRedownload {
Task { await modelManager.redownloadModel(config) }
}
}
Button("Cancel", role: .cancel) {
confirmRedownload = nil
}
} message: {
if let config = confirmRedownload {
Text("This will delete the local cache for \(config.displayName) and download it again from HuggingFace.")
}
} label: {
Text(currentModelLabel)
.lineLimit(1)
.frame(minWidth: 200)
}
.menuStyle(.button)
.disabled(modelManager.isLoading)
}
private var selectedModelBinding: Binding<String> {
Binding(
get: {
if let currentId = modelManager.currentModel?.id {
return currentId
}
if let defaultId = Preferences.defaultModelId,
let config = modelManager.availableModels.first(where: { $0.id == defaultId || $0.repoId == defaultId }) {
return config.id
}
return ModelConfig.default.id
},
set: { newId in
guard let config = modelManager.availableModels.first(where: { $0.id == newId }) ?? ModelConfig.resolve(newId) else {
return
}
Task {
await modelManager.loadModel(config)
}
}
)
private var currentModelLabel: String {
guard let model = modelManager.currentModel else { return "Select Model" }
return model.isCurated ? model.displayName : model.repoId
}
}