141 lines
5.7 KiB
Swift
141 lines
5.7 KiB
Swift
//
|
|
// HomeViewController.swift
|
|
// Reader
|
|
//
|
|
// Created by Shadowfacts on 11/25/21.
|
|
//
|
|
|
|
import UIKit
|
|
import CoreData
|
|
|
|
class HomeViewController: UIViewController {
|
|
|
|
let fervorController: FervorController
|
|
|
|
private var collectionView: UICollectionView!
|
|
private var dataSource: UICollectionViewDiffableDataSource<Section, Item>!
|
|
private var groupResultsController: NSFetchedResultsController<Group>!
|
|
private var feedResultsController: NSFetchedResultsController<Feed>!
|
|
|
|
init(fervorController: FervorController) {
|
|
self.fervorController = fervorController
|
|
|
|
super.init(nibName: nil, bundle: nil)
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
|
|
view.backgroundColor = .systemBackground
|
|
|
|
// let label = UILabel()
|
|
// label.translatesAutoresizingMaskIntoConstraints = false
|
|
// label.text = "Logged in to \(fervorController.instanceURL.host!)"
|
|
// view.addSubview(label)
|
|
// NSLayoutConstraint.activate([
|
|
// label.centerXAnchor.constraint(equalTo: view.centerXAnchor),
|
|
// label.centerYAnchor.constraint(equalTo: view.centerYAnchor),
|
|
// ])
|
|
|
|
let configuration = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
|
|
let layout = UICollectionViewCompositionalLayout.list(using: configuration)
|
|
collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: layout)
|
|
collectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
collectionView.delegate = self
|
|
view.addSubview(collectionView)
|
|
|
|
dataSource = createDataSource()
|
|
|
|
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
|
|
snapshot.appendSections([.groups, .feeds])
|
|
dataSource.apply(snapshot, animatingDifferences: false)
|
|
|
|
let groupReq = Group.fetchRequest()
|
|
groupReq.sortDescriptors = [NSSortDescriptor(key: "title", ascending: true)]
|
|
groupResultsController = NSFetchedResultsController(fetchRequest: groupReq, managedObjectContext: fervorController.persistentContainer.viewContext, sectionNameKeyPath: nil, cacheName: nil)
|
|
groupResultsController.delegate = self
|
|
try! groupResultsController.performFetch()
|
|
|
|
let feedReq = Feed.fetchRequest()
|
|
feedReq.sortDescriptors = [NSSortDescriptor(key: "title", ascending: true)]
|
|
feedResultsController = NSFetchedResultsController(fetchRequest: feedReq, managedObjectContext: fervorController.persistentContainer.viewContext, sectionNameKeyPath: nil, cacheName: nil)
|
|
feedResultsController.delegate = self
|
|
try! feedResultsController.performFetch()
|
|
}
|
|
|
|
private func createDataSource() -> UICollectionViewDiffableDataSource<Section, Item> {
|
|
let listCell = UICollectionView.CellRegistration<UICollectionViewListCell, Item> { cell, indexPath, item in
|
|
var config = cell.defaultContentConfiguration()
|
|
config.text = item.title
|
|
cell.contentConfiguration = config
|
|
|
|
cell.accessories = [.disclosureIndicator()]
|
|
}
|
|
let dataSource = UICollectionViewDiffableDataSource<Section, Item>(collectionView: collectionView) { collectionView, indexPath, item in
|
|
return collectionView.dequeueConfiguredReusableCell(using: listCell, for: indexPath, item: item)
|
|
}
|
|
return dataSource
|
|
}
|
|
|
|
}
|
|
|
|
extension HomeViewController {
|
|
enum Section: Hashable {
|
|
case groups
|
|
case feeds
|
|
}
|
|
enum Item: Hashable {
|
|
case group(Group)
|
|
case feed(Feed)
|
|
|
|
var title: String {
|
|
switch self {
|
|
case let .group(group):
|
|
// todo: manual codegen for models so this force unwrap isn't necessary
|
|
return group.title!
|
|
case let .feed(feed):
|
|
return feed.title!
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
extension HomeViewController: NSFetchedResultsControllerDelegate {
|
|
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChangeContentWith snapshot: NSDiffableDataSourceSnapshotReference) {
|
|
var snapshot = dataSource.snapshot()
|
|
if controller == groupResultsController {
|
|
if snapshot.sectionIdentifiers.contains(.groups) {
|
|
snapshot.deleteItems(snapshot.itemIdentifiers(inSection: .groups))
|
|
}
|
|
snapshot.appendItems(controller.fetchedObjects!.map { .group($0 as! Group) }, toSection: .groups)
|
|
} else if controller == feedResultsController {
|
|
if snapshot.sectionIdentifiers.contains(.feeds) {
|
|
snapshot.deleteItems(snapshot.itemIdentifiers(inSection: .feeds))
|
|
}
|
|
snapshot.appendItems(controller.fetchedObjects!.map { .feed($0 as! Feed) }, toSection: .feeds)
|
|
}
|
|
dataSource.apply(snapshot, animatingDifferences: false)
|
|
}
|
|
}
|
|
|
|
extension HomeViewController: UICollectionViewDelegate {
|
|
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
|
collectionView.deselectItem(at: indexPath, animated: true)
|
|
guard let item = dataSource.itemIdentifier(for: indexPath) else {
|
|
return
|
|
}
|
|
let req = Reader.Item.fetchRequest()
|
|
switch item {
|
|
case .group(let group):
|
|
req.predicate = NSPredicate(format: "feed in %@", group.feeds!)
|
|
case .feed(let feed):
|
|
req.predicate = NSPredicate(format: "feed = %@", feed)
|
|
}
|
|
show(ItemsViewController(fervorController: fervorController, fetchRequest: req), sender: nil)
|
|
}
|
|
}
|