From d5b9ae15cccb35a2c75299650cb3a77c3e368ef5 Mon Sep 17 00:00:00 2001 From: Chili Palmer Date: Fri, 17 Apr 2026 14:13:38 +0200 Subject: [PATCH] fix: weird model selector fixed --- MLXServer/ContentView.swift | 29 +++++++++++ MLXServer/Views/ModelPickerView.swift | 73 ++++++--------------------- 2 files changed, 45 insertions(+), 57 deletions(-) diff --git a/MLXServer/ContentView.swift b/MLXServer/ContentView.swift index e112fe6..b323b0e 100644 --- a/MLXServer/ContentView.swift +++ b/MLXServer/ContentView.swift @@ -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 { diff --git a/MLXServer/Views/ModelPickerView.swift b/MLXServer/Views/ModelPickerView.swift index f0c8771..d22cb9b 100644 --- a/MLXServer/Views/ModelPickerView.swift +++ b/MLXServer/Views/ModelPickerView.swift @@ -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 { - 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 } }