Initial commit: suixinkan_ios UIKit rewrite project.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@ -0,0 +1,231 @@
|
||||
//
|
||||
// AssetsViewControllers.swift
|
||||
// suixinkan
|
||||
//
|
||||
// Created by Codex on 2026/6/26.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
/// 云盘列表页。
|
||||
final class CloudStorageViewController: ModuleTableViewController {
|
||||
private let viewModel = CloudStorageViewModel()
|
||||
|
||||
override func viewDidLoad() {
|
||||
title = "云盘"
|
||||
navigationItem.rightBarButtonItem = UIBarButtonItem(
|
||||
title: "传输",
|
||||
style: .plain,
|
||||
target: self,
|
||||
action: #selector(openTransit)
|
||||
)
|
||||
super.viewDidLoad()
|
||||
wireViewModel(viewModel) { }
|
||||
}
|
||||
|
||||
override func tableRowCount() -> Int { viewModel.files.count }
|
||||
|
||||
override func configureCell(_ cell: TitleSubtitleTableViewCell, at indexPath: IndexPath) {
|
||||
let file = viewModel.files[indexPath.row]
|
||||
cell.configure(title: file.name, subtitle: file.updatedAt, detail: "\(file.fileSize)")
|
||||
}
|
||||
|
||||
override func reloadContent() async {
|
||||
await viewModel.reload(api: services.assetsAPI)
|
||||
}
|
||||
|
||||
override func willDisplayTableRow(at indexPath: IndexPath) {
|
||||
guard indexPath.row >= viewModel.files.count - 2 else { return }
|
||||
Task { await viewModel.loadMore(api: services.assetsAPI) }
|
||||
}
|
||||
|
||||
@objc private func openTransit() {
|
||||
navigationController?.pushViewController(CloudStorageTransitViewController(), animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
extension CloudStorageViewModel: ViewModelBindable {}
|
||||
|
||||
/// 云盘传输记录页。
|
||||
final class CloudStorageTransitViewController: ModuleTableViewController {
|
||||
private let store = CloudTransferStore.shared
|
||||
|
||||
override func viewDidLoad() {
|
||||
title = "传输记录"
|
||||
super.viewDidLoad()
|
||||
store.onChange = { [weak self] in self?.reloadTable() }
|
||||
}
|
||||
|
||||
override func tableRowCount() -> Int { store.records.count }
|
||||
|
||||
override func configureCell(_ cell: TitleSubtitleTableViewCell, at indexPath: IndexPath) {
|
||||
let record = store.records[indexPath.row]
|
||||
cell.configure(title: record.fileName, subtitle: record.message, detail: "\(record.progress)%")
|
||||
}
|
||||
|
||||
override func reloadContent() async {}
|
||||
}
|
||||
|
||||
enum MediaLibraryKindRoute {
|
||||
case material
|
||||
case sample
|
||||
}
|
||||
|
||||
/// 素材库 / 样片库列表页。
|
||||
final class MediaLibraryViewController: ModuleTableViewController {
|
||||
private let kind: MediaLibraryKindRoute
|
||||
private let viewModel: MediaLibraryViewModel
|
||||
|
||||
init(kind: MediaLibraryKindRoute = .material) {
|
||||
self.kind = kind
|
||||
switch kind {
|
||||
case .material:
|
||||
viewModel = MediaLibraryViewModel(kind: .material)
|
||||
case .sample:
|
||||
viewModel = MediaLibraryViewModel(kind: .sample)
|
||||
}
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
title = kind == .sample ? "样片库" : "素材库"
|
||||
navigationItem.rightBarButtonItem = UIBarButtonItem(
|
||||
title: "上传",
|
||||
style: .plain,
|
||||
target: self,
|
||||
action: #selector(openUpload)
|
||||
)
|
||||
super.viewDidLoad()
|
||||
wireViewModel(viewModel) { }
|
||||
}
|
||||
|
||||
override func tableRowCount() -> Int { viewModel.items.count }
|
||||
|
||||
override func configureCell(_ cell: TitleSubtitleTableViewCell, at indexPath: IndexPath) {
|
||||
let item = viewModel.items[indexPath.row]
|
||||
cell.configure(title: item.name, subtitle: item.projectName, detail: item.createdAt)
|
||||
}
|
||||
|
||||
override func reloadContent() async {
|
||||
await viewModel.reload(api: services.assetsAPI)
|
||||
}
|
||||
|
||||
@objc private func openUpload() {
|
||||
navigationController?.pushViewController(MediaLibraryUploadViewController(kind: kind), animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
extension MediaLibraryViewModel: ViewModelBindable {}
|
||||
|
||||
/// 素材 / 样片上传页。
|
||||
final class MediaLibraryUploadViewController: ModuleTableViewController {
|
||||
private let kind: MediaLibraryKindRoute
|
||||
private let viewModel = MediaLibraryEditorViewModel()
|
||||
private let nameField = UITextField()
|
||||
|
||||
init(kind: MediaLibraryKindRoute) {
|
||||
self.kind = kind
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
title = kind == .sample ? "上传样片" : "上传素材"
|
||||
navigationItem.rightBarButtonItem = UIBarButtonItem(
|
||||
title: "提交",
|
||||
style: .done,
|
||||
target: self,
|
||||
action: #selector(submit)
|
||||
)
|
||||
super.viewDidLoad()
|
||||
nameField.placeholder = "素材名称"
|
||||
nameField.borderStyle = .roundedRect
|
||||
nameField.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: 52)
|
||||
tableView.tableHeaderView = nameField
|
||||
wireViewModel(viewModel) { }
|
||||
}
|
||||
|
||||
override func tableRowCount() -> Int { viewModel.projects.count }
|
||||
|
||||
override func configureCell(_ cell: TitleSubtitleTableViewCell, at indexPath: IndexPath) {
|
||||
let project = viewModel.projects[indexPath.row]
|
||||
cell.configure(title: project.name, subtitle: project.statusName)
|
||||
}
|
||||
|
||||
override func reloadContent() async {
|
||||
await viewModel.loadProjects(scenicId: services.currentScenicId, api: services.assetsAPI)
|
||||
}
|
||||
|
||||
@objc private func submit() {
|
||||
viewModel.name = nameField.text ?? ""
|
||||
Task {
|
||||
let mediaKind: MediaLibraryKind = kind == .sample ? .sample : .material
|
||||
let success = await viewModel.submit(
|
||||
kind: mediaKind,
|
||||
scenicId: services.currentScenicId,
|
||||
api: services.assetsAPI,
|
||||
uploadService: services.ossUploadService
|
||||
)
|
||||
if success { navigationController?.popViewController(animated: true) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension MediaLibraryEditorViewModel: ViewModelBindable {}
|
||||
|
||||
/// 相册列表页。
|
||||
final class AlbumListViewController: ModuleTableViewController {
|
||||
private let viewModel = AlbumListViewModel()
|
||||
|
||||
override func viewDidLoad() {
|
||||
title = "相册"
|
||||
super.viewDidLoad()
|
||||
wireViewModel(viewModel) { }
|
||||
}
|
||||
|
||||
override func tableRowCount() -> Int { viewModel.folders.count }
|
||||
|
||||
override func configureCell(_ cell: TitleSubtitleTableViewCell, at indexPath: IndexPath) {
|
||||
let folder = viewModel.folders[indexPath.row]
|
||||
cell.configure(title: folder.name, subtitle: folder.createTime, detail: "\(folder.totalCount) 张")
|
||||
}
|
||||
|
||||
override func reloadContent() async {
|
||||
await viewModel.reload(api: services.assetsAPI, scenicId: services.currentScenicId)
|
||||
}
|
||||
}
|
||||
|
||||
extension AlbumListViewModel: ViewModelBindable {}
|
||||
|
||||
/// 相册预告页。
|
||||
final class AlbumTrailerViewController: ModuleTableViewController {
|
||||
private let viewModel = AlbumTrailerViewModel()
|
||||
|
||||
override func viewDidLoad() {
|
||||
title = "相册预告"
|
||||
super.viewDidLoad()
|
||||
wireViewModel(viewModel) { }
|
||||
}
|
||||
|
||||
override func tableRowCount() -> Int { viewModel.folders.count }
|
||||
|
||||
override func configureCell(_ cell: TitleSubtitleTableViewCell, at indexPath: IndexPath) {
|
||||
let folder = viewModel.folders[indexPath.row]
|
||||
cell.configure(title: folder.name, subtitle: folder.createTime, detail: "\(folder.totalCount) 张")
|
||||
}
|
||||
|
||||
override func reloadContent() async {
|
||||
await viewModel.loadFolders(api: services.assetsAPI, scenicId: services.currentScenicId)
|
||||
}
|
||||
}
|
||||
|
||||
extension AlbumTrailerViewModel: ViewModelBindable {}
|
||||
Reference in New Issue
Block a user