[feat] pin an unpin models

This commit is contained in:
游薪渝(揽清) 2025-06-20 17:52:14 +08:00
parent 569d23a0ad
commit 018ff22032
3 changed files with 53 additions and 34 deletions

View File

@ -19,10 +19,10 @@ class ModelListViewModel: ObservableObject {
@Published var selectedModel: ModelInfo?
private let modelClient = ModelClient()
private let pinnedModelKey = "com.mnnllm.pinnedModelId"
private let pinnedModelKey = "com.mnnllm.pinnedModelIds"
private var pinnedModelId: String? {
get { UserDefaults.standard.string(forKey: pinnedModelKey) }
public var pinnedModelIds: [String] {
get { UserDefaults.standard.stringArray(forKey: pinnedModelKey) ?? [] }
set { UserDefaults.standard.setValue(newValue, forKey: pinnedModelKey) }
}
@ -70,12 +70,12 @@ class ModelListViewModel: ObservableObject {
for i in 0..<fetchedModels.count {
fetchedModels[i].isDownloaded = ModelStorageManager.shared.isModelDownloaded(fetchedModels[i].modelId)
}
//
if let pinnedId = pinnedModelId, let idx = fetchedModels.firstIndex(where: { $0.modelId == pinnedId }) {
let pinned = fetchedModels.remove(at: idx)
fetchedModels.insert(pinned, at: 0)
//
let pinned = pinnedModelIds.reversed().compactMap { id in
fetchedModels.first(where: { $0.modelId == id })
}
models = fetchedModels
let rest = fetchedModels.filter { !pinnedModelIds.contains($0.modelId) }
models = pinned + rest
} catch {
showError = true
errorMessage = "Error: \(error.localizedDescription)"
@ -126,15 +126,17 @@ class ModelListViewModel: ObservableObject {
guard let index = models.firstIndex(where: { $0.modelId == model.modelId }) else { return }
let pinned = models.remove(at: index)
models.insert(pinned, at: 0)
pinnedModelId = model.modelId
var ids = pinnedModelIds.filter { $0 != model.modelId }
ids.append(model.modelId)
pinnedModelIds = ids
}
func unpinModel(_ model: ModelInfo) {
guard let index = models.firstIndex(where: { $0.modelId == model.modelId }) else { return }
let unpinned = models.remove(at: index)
let insertIndex = models.firstIndex(where: { !$0.isDownloaded || $0.modelId != model.modelId }) ?? models.endIndex
let insertIndex = models.count //
models.insert(unpinned, at: insertIndex)
pinnedModelId = nil
pinnedModelIds = pinnedModelIds.filter { $0 != model.modelId }
}
func deleteModel(_ model: ModelInfo) async {

View File

@ -44,29 +44,7 @@ struct ModelListView: View {
}
}
.swipeActions(edge: .trailing, allowsFullSwipe: false) {
if let firstModel = viewModel.filteredModels.first, firstModel.modelId == model.modelId {
Button {
viewModel.unpinModel(model)
} label: {
Label("取消置顶", systemImage: "pin.slash")
}.tint(.gray)
} else {
Button {
viewModel.pinModel(model)
} label: {
Label("置顶", systemImage: "pin")
}.tint(.yellow)
}
if model.isDownloaded {
Button(role: .destructive) {
Task {
await viewModel.deleteModel(model)
}
} label: {
Label("Delete", systemImage: "trash")
}
}
SwipeActionsView(model: model, viewModel: viewModel)
}
}
}

View File

@ -0,0 +1,39 @@
//
// SwipeActionsView.swift
// MNNLLMiOS
//
// Created by () on 2025/1/3.
//
import SwiftUI
struct SwipeActionsView: View {
let model: ModelInfo
@ObservedObject var viewModel: ModelListViewModel
var body: some View {
if viewModel.pinnedModelIds.contains(model.modelId) {
Button {
viewModel.unpinModel(model)
} label: {
Label("取消置顶", systemImage: "pin.slash")
}.tint(.gray)
} else {
Button {
viewModel.pinModel(model)
} label: {
Label("置顶", systemImage: "pin")
}.tint(.yellow)
}
if model.isDownloaded {
Button(role: .destructive) {
Task {
await viewModel.deleteModel(model)
}
} label: {
Label("Delete", systemImage: "trash")
}
}
}
}