e8c3e4644e
CI / lint-and-build (push) Has been cancelled
- Swift 6 + SwiftUI + SwiftData 直接调用阿里云 VOD API - 自实现 POP 签名,无需 Node 后端 - 视频列表、搜索、批量下载到用户选择目录 - 下载文件自动使用视频标题重命名 - 浏览器下载与下载工具(aria2/wget)两种方式 - Web 版标记为废弃,README/AGENTS/MEMORY 更新
136 lines
4.4 KiB
Swift
136 lines
4.4 KiB
Swift
import SwiftUI
|
|
import SwiftData
|
|
|
|
struct AccountListView: View {
|
|
@EnvironmentObject var accountStore: AccountStore
|
|
@Query(sort: \Account.createdAt, order: .reverse) private var accounts: [Account]
|
|
@State private var showForm = false
|
|
@State private var editingAccount: Account?
|
|
|
|
var body: some View {
|
|
VStack {
|
|
HStack {
|
|
Spacer()
|
|
Button("添加账号") {
|
|
editingAccount = nil
|
|
showForm = true
|
|
}
|
|
.buttonStyle(.borderedProminent)
|
|
}
|
|
.padding()
|
|
|
|
List(accounts) { account in
|
|
HStack {
|
|
VStack(alignment: .leading) {
|
|
Text(account.name)
|
|
.font(.headline)
|
|
Text("\(account.accessKeyId) / \(account.region)")
|
|
.font(.caption)
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
|
|
Spacer()
|
|
|
|
if account.isActive {
|
|
Text("当前使用")
|
|
.font(.caption)
|
|
.foregroundStyle(.green)
|
|
} else {
|
|
Button("切换") {
|
|
Task { await accountStore.switchActive(account) }
|
|
}
|
|
.buttonStyle(.borderless)
|
|
}
|
|
|
|
Button("编辑") {
|
|
editingAccount = account
|
|
showForm = true
|
|
}
|
|
.buttonStyle(.borderless)
|
|
|
|
Button("删除") {
|
|
Task { await accountStore.deleteAccount(account) }
|
|
}
|
|
.buttonStyle(.borderless)
|
|
.foregroundStyle(.red)
|
|
}
|
|
.padding(.vertical, 4)
|
|
}
|
|
}
|
|
.sheet(isPresented: $showForm) {
|
|
AccountFormView(account: editingAccount)
|
|
}
|
|
}
|
|
}
|
|
|
|
struct AccountFormView: View {
|
|
@Environment(\.dismiss) private var dismiss
|
|
@EnvironmentObject var accountStore: AccountStore
|
|
@Query(sort: \Account.createdAt, order: .reverse) private var accounts: [Account]
|
|
|
|
var account: Account?
|
|
|
|
@State private var name = ""
|
|
@State private var accessKeyId = ""
|
|
@State private var accessKeySecret = ""
|
|
@State private var region = "cn-shanghai"
|
|
@State private var endpoint = ""
|
|
|
|
var body: some View {
|
|
VStack(alignment: .leading, spacing: 16) {
|
|
Text(account == nil ? "添加账号" : "编辑账号")
|
|
.font(.title2)
|
|
|
|
Form {
|
|
TextField("名称", text: $name)
|
|
TextField("AccessKey ID", text: $accessKeyId)
|
|
SecureField(account == nil ? "AccessKey Secret" : "AccessKey Secret(留空则不修改)", text: $accessKeySecret)
|
|
TextField("Region", text: $region)
|
|
TextField("Endpoint(可选)", text: $endpoint)
|
|
}
|
|
|
|
HStack {
|
|
Spacer()
|
|
Button("取消") {
|
|
dismiss()
|
|
}
|
|
Button("保存") {
|
|
Task { await save() }
|
|
}
|
|
.buttonStyle(.borderedProminent)
|
|
}
|
|
}
|
|
.padding()
|
|
.frame(minWidth: 400)
|
|
.onAppear {
|
|
if let account = account {
|
|
name = account.name
|
|
accessKeyId = account.accessKeyId
|
|
region = account.region
|
|
endpoint = account.endpoint ?? ""
|
|
}
|
|
}
|
|
}
|
|
|
|
private func save() async {
|
|
let secret = accessKeySecret.isEmpty ? (account?.accessKeySecret ?? "") : accessKeySecret
|
|
let newAccount = Account(
|
|
id: account?.id ?? UUID(),
|
|
name: name,
|
|
accessKeyId: accessKeyId,
|
|
accessKeySecret: secret,
|
|
region: region,
|
|
endpoint: endpoint.isEmpty ? nil : endpoint,
|
|
isActive: account?.isActive ?? (accounts.isEmpty ? true : false),
|
|
createdAt: account?.createdAt ?? Date(),
|
|
updatedAt: Date()
|
|
)
|
|
if account != nil {
|
|
await accountStore.updateAccount(newAccount)
|
|
} else {
|
|
await accountStore.addAccount(newAccount)
|
|
}
|
|
dismiss()
|
|
}
|
|
}
|