Fix OTG album local path storage
This commit is contained in:
@ -16,7 +16,8 @@ final class TravelAlbumCameraImportViewController: UIViewController {
|
||||
}
|
||||
|
||||
private let viewModel: TravelAlbumCameraImportViewModel
|
||||
var onImportFinished: ((Int) -> Void)?
|
||||
var onImportFinished: ((Int, Int) -> Void)?
|
||||
var onImportCancelled: (() -> Void)?
|
||||
|
||||
private var collectionView: UICollectionView!
|
||||
private var sections: [TravelAlbumCameraImportSection] = []
|
||||
@ -75,6 +76,11 @@ final class TravelAlbumCameraImportViewController: UIViewController {
|
||||
collectionView.collectionViewLayout.invalidateLayout()
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
navigationController?.presentationController?.delegate = self
|
||||
}
|
||||
|
||||
private func setupUI() {
|
||||
let layout = UICollectionViewFlowLayout()
|
||||
layout.minimumLineSpacing = Layout.spacing
|
||||
@ -150,7 +156,6 @@ final class TravelAlbumCameraImportViewController: UIViewController {
|
||||
}
|
||||
viewModel.onSelectionUpdated = { [weak self] count in
|
||||
self?.updateImportButton(count: count)
|
||||
self?.collectionView.reloadData()
|
||||
}
|
||||
viewModel.onSonyMTPHelpVisibilityChanged = { [weak self] show in
|
||||
self?.updateHelpVisibility(show)
|
||||
@ -160,6 +165,7 @@ final class TravelAlbumCameraImportViewController: UIViewController {
|
||||
private func render(_ state: TravelAlbumCameraImportState) {
|
||||
switch state {
|
||||
case .idle, .loading:
|
||||
isModalInPresentation = false
|
||||
collectionView.isHidden = true
|
||||
messageLabel.isHidden = true
|
||||
helpButton.isHidden = true
|
||||
@ -168,6 +174,7 @@ final class TravelAlbumCameraImportViewController: UIViewController {
|
||||
activityIndicator.startAnimating()
|
||||
|
||||
case .loaded(let loadedSections):
|
||||
isModalInPresentation = false
|
||||
activityIndicator.stopAnimating()
|
||||
collectionView.isHidden = false
|
||||
messageLabel.isHidden = true
|
||||
@ -177,6 +184,7 @@ final class TravelAlbumCameraImportViewController: UIViewController {
|
||||
collectionView.reloadData()
|
||||
|
||||
case .importing(let current, let total):
|
||||
isModalInPresentation = true
|
||||
collectionView.isHidden = true
|
||||
messageLabel.isHidden = false
|
||||
messageLabel.text = "正在导入 \(current)/\(total)..."
|
||||
@ -185,13 +193,15 @@ final class TravelAlbumCameraImportViewController: UIViewController {
|
||||
navigationItem.leftBarButtonItem?.isEnabled = false
|
||||
activityIndicator.startAnimating()
|
||||
|
||||
case .finished(let count):
|
||||
case .finished(let importedCount, let failedCount):
|
||||
isModalInPresentation = false
|
||||
activityIndicator.stopAnimating()
|
||||
dismiss(animated: true) { [weak self] in
|
||||
self?.onImportFinished?(count)
|
||||
self?.onImportFinished?(importedCount, failedCount)
|
||||
}
|
||||
|
||||
case .failed(let message):
|
||||
isModalInPresentation = false
|
||||
activityIndicator.stopAnimating()
|
||||
collectionView.isHidden = true
|
||||
messageLabel.isHidden = false
|
||||
@ -229,7 +239,52 @@ final class TravelAlbumCameraImportViewController: UIViewController {
|
||||
return CGSize(width: width, height: width + 28)
|
||||
}
|
||||
|
||||
private func applyHeader(_ header: TravelAlbumCameraImportSectionHeaderView, at sectionIndex: Int) {
|
||||
let section = sections[sectionIndex]
|
||||
header.apply(
|
||||
title: section.title,
|
||||
count: section.photos.count,
|
||||
importableCount: viewModel.importablePhotoCount(in: section),
|
||||
importedCount: viewModel.importedPhotoCount(in: section),
|
||||
hasImportablePhotos: viewModel.hasImportablePhotos(in: section),
|
||||
fullySelected: viewModel.isSectionFullySelected(section),
|
||||
partiallySelected: viewModel.isSectionPartiallySelected(section)
|
||||
)
|
||||
header.onToggle = { [weak self] in
|
||||
self?.toggleSection(at: sectionIndex)
|
||||
}
|
||||
}
|
||||
|
||||
private func refreshVisibleHeader(at sectionIndex: Int) {
|
||||
let indexPath = IndexPath(item: 0, section: sectionIndex)
|
||||
guard let header = collectionView.supplementaryView(
|
||||
forElementKind: UICollectionView.elementKindSectionHeader,
|
||||
at: indexPath
|
||||
) as? TravelAlbumCameraImportSectionHeaderView else {
|
||||
return
|
||||
}
|
||||
applyHeader(header, at: sectionIndex)
|
||||
}
|
||||
|
||||
private func reloadItemsWithoutAnimation(_ indexPaths: [IndexPath]) {
|
||||
UIView.performWithoutAnimation {
|
||||
collectionView.reloadItems(at: indexPaths)
|
||||
collectionView.layoutIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
private func toggleSection(at sectionIndex: Int) {
|
||||
guard sections.indices.contains(sectionIndex) else { return }
|
||||
viewModel.toggleSection(sections[sectionIndex])
|
||||
let indexPaths = sections[sectionIndex].photos.indices.map {
|
||||
IndexPath(item: $0, section: sectionIndex)
|
||||
}
|
||||
reloadItemsWithoutAnimation(indexPaths)
|
||||
refreshVisibleHeader(at: sectionIndex)
|
||||
}
|
||||
|
||||
@objc private func cancelTapped() {
|
||||
onImportCancelled?()
|
||||
dismiss(animated: true)
|
||||
}
|
||||
|
||||
@ -282,21 +337,7 @@ extension TravelAlbumCameraImportViewController: UICollectionViewDataSource {
|
||||
withReuseIdentifier: TravelAlbumCameraImportSectionHeaderView.reuseIdentifier,
|
||||
for: indexPath
|
||||
) as! TravelAlbumCameraImportSectionHeaderView
|
||||
let section = sections[indexPath.section]
|
||||
header.apply(
|
||||
title: section.title,
|
||||
count: section.photos.count,
|
||||
importableCount: viewModel.importablePhotoCount(in: section),
|
||||
importedCount: viewModel.importedPhotoCount(in: section),
|
||||
hasImportablePhotos: viewModel.hasImportablePhotos(in: section),
|
||||
fullySelected: viewModel.isSectionFullySelected(section),
|
||||
partiallySelected: viewModel.isSectionPartiallySelected(section)
|
||||
)
|
||||
header.onToggle = { [weak self] in
|
||||
guard let self else { return }
|
||||
self.viewModel.toggleSection(section)
|
||||
self.collectionView.reloadSections(IndexSet(integer: indexPath.section))
|
||||
}
|
||||
applyHeader(header, at: indexPath.section)
|
||||
return header
|
||||
}
|
||||
}
|
||||
@ -306,8 +347,8 @@ extension TravelAlbumCameraImportViewController: UICollectionViewDelegateFlowLay
|
||||
let photo = sections[indexPath.section].photos[indexPath.item]
|
||||
guard !viewModel.isPhotoAlreadyInAlbum(id: photo.id) else { return }
|
||||
viewModel.togglePhoto(id: photo.id)
|
||||
collectionView.reloadItems(at: [indexPath])
|
||||
collectionView.reloadSections(IndexSet(integer: indexPath.section))
|
||||
reloadItemsWithoutAnimation([indexPath])
|
||||
refreshVisibleHeader(at: indexPath.section)
|
||||
}
|
||||
|
||||
func collectionView(
|
||||
@ -322,6 +363,12 @@ extension TravelAlbumCameraImportViewController: UICollectionViewDelegateFlowLay
|
||||
}
|
||||
}
|
||||
|
||||
extension TravelAlbumCameraImportViewController: UIAdaptivePresentationControllerDelegate {
|
||||
func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
|
||||
onImportCancelled?()
|
||||
}
|
||||
}
|
||||
|
||||
/// 相机历史照片导入 Cell。
|
||||
private final class TravelAlbumCameraImportPhotoCell: UICollectionViewCell {
|
||||
static let reuseIdentifier = "TravelAlbumCameraImportPhotoCell"
|
||||
|
||||
@ -421,10 +421,20 @@ final class WiredCameraTransferViewController: BaseViewController {
|
||||
|
||||
@objc private func historyImportTapped() {
|
||||
guard let importViewModel = viewModel.makeCameraImportViewModel() else { return }
|
||||
viewModel.pauseLiveTransferForHistoricalImport()
|
||||
let importController = TravelAlbumCameraImportViewController(viewModel: importViewModel)
|
||||
importController.onImportFinished = { [weak self] count in
|
||||
self?.viewModel.reloadLocalPhotos()
|
||||
self?.showToast("已导入 \(count) 张照片")
|
||||
importController.onImportFinished = { [weak self] importedCount, failedCount in
|
||||
guard let self else { return }
|
||||
self.viewModel.reloadLocalPhotos()
|
||||
self.viewModel.start()
|
||||
if failedCount > 0 {
|
||||
self.showToast("已导入 \(importedCount) 张,\(failedCount) 张失败")
|
||||
} else {
|
||||
self.showToast("已导入 \(importedCount) 张照片")
|
||||
}
|
||||
}
|
||||
importController.onImportCancelled = { [weak self] in
|
||||
self?.viewModel.start()
|
||||
}
|
||||
let navigationController = UINavigationController(rootViewController: importController)
|
||||
navigationController.modalPresentationStyle = .pageSheet
|
||||
|
||||
Reference in New Issue
Block a user