mirror of https://github.com/alibaba/MNN.git
[feat] pin an unpin models
This commit is contained in:
parent
569d23a0ad
commit
018ff22032
|
|
@ -19,10 +19,10 @@ class ModelListViewModel: ObservableObject {
|
||||||
@Published var selectedModel: ModelInfo?
|
@Published var selectedModel: ModelInfo?
|
||||||
|
|
||||||
private let modelClient = ModelClient()
|
private let modelClient = ModelClient()
|
||||||
private let pinnedModelKey = "com.mnnllm.pinnedModelId"
|
private let pinnedModelKey = "com.mnnllm.pinnedModelIds"
|
||||||
|
|
||||||
private var pinnedModelId: String? {
|
public var pinnedModelIds: [String] {
|
||||||
get { UserDefaults.standard.string(forKey: pinnedModelKey) }
|
get { UserDefaults.standard.stringArray(forKey: pinnedModelKey) ?? [] }
|
||||||
set { UserDefaults.standard.setValue(newValue, forKey: pinnedModelKey) }
|
set { UserDefaults.standard.setValue(newValue, forKey: pinnedModelKey) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,12 +70,12 @@ class ModelListViewModel: ObservableObject {
|
||||||
for i in 0..<fetchedModels.count {
|
for i in 0..<fetchedModels.count {
|
||||||
fetchedModels[i].isDownloaded = ModelStorageManager.shared.isModelDownloaded(fetchedModels[i].modelId)
|
fetchedModels[i].isDownloaded = ModelStorageManager.shared.isModelDownloaded(fetchedModels[i].modelId)
|
||||||
}
|
}
|
||||||
// 保持置顶顺序
|
// 多模型置顶顺序,最新置顶的在最顶部
|
||||||
if let pinnedId = pinnedModelId, let idx = fetchedModels.firstIndex(where: { $0.modelId == pinnedId }) {
|
let pinned = pinnedModelIds.reversed().compactMap { id in
|
||||||
let pinned = fetchedModels.remove(at: idx)
|
fetchedModels.first(where: { $0.modelId == id })
|
||||||
fetchedModels.insert(pinned, at: 0)
|
|
||||||
}
|
}
|
||||||
models = fetchedModels
|
let rest = fetchedModels.filter { !pinnedModelIds.contains($0.modelId) }
|
||||||
|
models = pinned + rest
|
||||||
} catch {
|
} catch {
|
||||||
showError = true
|
showError = true
|
||||||
errorMessage = "Error: \(error.localizedDescription)"
|
errorMessage = "Error: \(error.localizedDescription)"
|
||||||
|
|
@ -126,15 +126,17 @@ class ModelListViewModel: ObservableObject {
|
||||||
guard let index = models.firstIndex(where: { $0.modelId == model.modelId }) else { return }
|
guard let index = models.firstIndex(where: { $0.modelId == model.modelId }) else { return }
|
||||||
let pinned = models.remove(at: index)
|
let pinned = models.remove(at: index)
|
||||||
models.insert(pinned, at: 0)
|
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) {
|
func unpinModel(_ model: ModelInfo) {
|
||||||
guard let index = models.firstIndex(where: { $0.modelId == model.modelId }) else { return }
|
guard let index = models.firstIndex(where: { $0.modelId == model.modelId }) else { return }
|
||||||
let unpinned = models.remove(at: index)
|
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)
|
models.insert(unpinned, at: insertIndex)
|
||||||
pinnedModelId = nil
|
pinnedModelIds = pinnedModelIds.filter { $0 != model.modelId }
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteModel(_ model: ModelInfo) async {
|
func deleteModel(_ model: ModelInfo) async {
|
||||||
|
|
|
||||||
|
|
@ -44,29 +44,7 @@ struct ModelListView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.swipeActions(edge: .trailing, allowsFullSwipe: false) {
|
.swipeActions(edge: .trailing, allowsFullSwipe: false) {
|
||||||
if let firstModel = viewModel.filteredModels.first, firstModel.modelId == model.modelId {
|
SwipeActionsView(model: model, viewModel: viewModel)
|
||||||
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")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue