Tusker/Tusker/Screens/Asset Picker/AssetCollectionsListViewCon...

159 lines
5.7 KiB
Swift

//
// AssetCollectionsListViewController.swift
// Tusker
//
// Created by Shadowfacts on 1/1/20.
// Copyright © 2020 Shadowfacts. All rights reserved.
//
import UIKit
import Photos
class AssetCollectionsListViewController: UITableViewController {
weak var assetCollectionDelegate: AssetCollectionViewControllerDelegate?
var dataSource: DataSource!
init() {
super.init(style: .plain)
title = NSLocalizedString("Collections", comment: "asset collections list title")
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelPressed))
tableView.register(UINib(nibName: "AllPhotosTableViewCell", bundle: .main), forCellReuseIdentifier: "allPhotosCell")
tableView.register(UINib(nibName: "AlbumTableViewCell", bundle: .main), forCellReuseIdentifier: "albumCell")
tableView.allowsFocus = true
tableView.backgroundColor = .appGroupedBackground
dataSource = DataSource(tableView: tableView, cellProvider: { (tableView, indexPath, item) -> UITableViewCell? in
switch item {
case .cameraRoll:
return tableView.dequeueReusableCell(withIdentifier: "allPhotosCell", for: indexPath)
case let .album(collection):
let cell = tableView.dequeueReusableCell(withIdentifier: "albumCell", for: indexPath) as! AlbumTableViewCell
cell.updateUI(album: collection)
return cell
}
})
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
snapshot.appendSections([.system, .albums, .sharedAlbums, .smartAlbums])
snapshot.appendItems([.cameraRoll], toSection: .system)
let smartAlbums = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .any, options: nil)
var smartAlbumItems = [Item]()
smartAlbums.enumerateObjects { (collection, _, _) in
guard collection.assetCollectionSubtype != .smartAlbumAllHidden else {
return
}
smartAlbumItems.append(.album(collection))
}
// sort these manually, using PHFetchOptions.sortDescriptors seems like it just doesn't work with fetchAssetCollections
smartAlbumItems.sort(by: { $0.title < $1.title })
snapshot.appendItems(smartAlbumItems, toSection: .smartAlbums)
let albums = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: nil)
var albumItems = [Item]()
var sharedItems = [Item]()
albums.enumerateObjects { (collection, _, _) in
if collection.estimatedAssetCount > 0 {
if collection.assetCollectionSubtype == .albumCloudShared {
sharedItems.append(.album(collection))
} else {
albumItems.append(.album(collection))
}
}
}
albumItems.sort(by: { $0.title < $1.title })
sharedItems.sort(by: { $0.title < $1.title })
snapshot.appendItems(albumItems, toSection: .albums)
snapshot.appendItems(sharedItems, toSection: .sharedAlbums)
dataSource.apply(snapshot, animatingDifferences: false)
}
// MARK: - Table view delegate
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch dataSource.itemIdentifier(for: indexPath) {
case nil:
return
case .cameraRoll:
let assetCollection = AssetCollectionViewController()
assetCollection.delegate = assetCollectionDelegate
show(assetCollection, sender: self)
case let .album(collection):
let assetCollection = AlbumAssetCollectionViewController(collection: collection)
assetCollection.delegate = assetCollectionDelegate
show(assetCollection, sender: self)
}
}
// MARK: - Interaction
@objc func cancelPressed() {
dismiss(animated: true)
}
}
extension AssetCollectionsListViewController {
enum Section {
case system
case albums
case sharedAlbums
case smartAlbums
}
enum Item: Hashable {
case cameraRoll
case album(PHAssetCollection)
func hash(into hasher: inout Hasher) {
switch self {
case .cameraRoll:
hasher.combine("cameraRoll")
case let .album(collection):
hasher.combine("album")
hasher.combine(collection.localIdentifier)
}
}
var title: String {
switch self {
case .cameraRoll:
return "All Photos"
case .album(let collection):
return collection.localizedTitle ?? ""
}
}
}
class DataSource: UITableViewDiffableDataSource<Section, Item> {
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
switch sectionIdentifier(for: section) {
case .albums:
return NSLocalizedString("Albums", comment: "albums section title")
case .sharedAlbums:
return NSLocalizedString("Shared Albums", comment: "shared albums section title")
case .smartAlbums:
return NSLocalizedString("Smart Albums", comment: "smart albums section title")
default:
return nil
}
}
}
}