76 lines
2.9 KiB
Swift
76 lines
2.9 KiB
Swift
//
|
|
// HomeCollectionViewCell.swift
|
|
// Reader
|
|
//
|
|
// Created by Shadowfacts on 1/9/22.
|
|
//
|
|
|
|
import UIKit
|
|
import Fervor
|
|
import Persistence
|
|
import OSLog
|
|
|
|
private let signposter = OSSignposter(subsystem: "net.shadowfacts.Reader", category: "HomeCollectionViewCell")
|
|
|
|
class HomeCollectionViewCell: UICollectionViewListCell {
|
|
|
|
private var currentItemCountTask: Task<Void, Never>?
|
|
private var itemCount: Int?
|
|
|
|
#if !targetEnvironment(macCatalyst)
|
|
override func updateConfiguration(using state: UICellConfigurationState) {
|
|
var backgroundConfig = UIBackgroundConfiguration.listGroupedCell().updated(for: state)
|
|
if state.isHighlighted || state.isSelected {
|
|
backgroundConfig.backgroundColor = .appCellHighlightBackground
|
|
} else {
|
|
backgroundConfig.backgroundColor = .appBackground
|
|
}
|
|
self.backgroundConfiguration = backgroundConfig
|
|
}
|
|
#endif
|
|
|
|
override func prepareForReuse() {
|
|
super.prepareForReuse()
|
|
currentItemCountTask?.cancel()
|
|
itemCount = nil
|
|
}
|
|
|
|
func updateUI(item: ItemListType, persistentContainer: PersistentContainer) {
|
|
var config = UIListContentConfiguration.valueCell()
|
|
config.text = item.title
|
|
if let itemCount {
|
|
config.secondaryText = itemCount.formatted(.number)
|
|
}
|
|
config.secondaryTextProperties.color = .tintColor
|
|
self.contentConfiguration = config
|
|
|
|
currentItemCountTask = Task(priority: .userInitiated) {
|
|
let state = signposter.beginInterval("fetch count", id: signposter.makeSignpostID(), "\(String(item.hashValue, radix: 16), privacy: .public)")
|
|
if let count = await fetchCount(item: item, in: persistentContainer),
|
|
!Task.isCancelled {
|
|
self.itemCount = count
|
|
config.secondaryText = count.formatted(.number)
|
|
self.contentConfiguration = config
|
|
}
|
|
signposter.endInterval("fetch count", state)
|
|
}
|
|
}
|
|
|
|
private func fetchCount(item: ItemListType, in persistentContainer: PersistentContainer) async -> Int? {
|
|
guard let request = item.countFetchRequest else {
|
|
return nil
|
|
}
|
|
return await withCheckedContinuation({ continuation in
|
|
let state = signposter.beginInterval("waiting to perform", id: signposter.makeSignpostID(), "\(String(item.hashValue, radix: 16), privacy: .public)")
|
|
persistentContainer.performBackgroundTask { context in
|
|
signposter.endInterval("waiting to perform", state)
|
|
let state = signposter.beginInterval("count", id: signposter.makeSignpostID(), "\(String(item.hashValue, radix: 16), privacy: .public)")
|
|
let count = try? context.count(for: request)
|
|
signposter.endInterval("count", state)
|
|
continuation.resume(returning: count)
|
|
}
|
|
})
|
|
}
|
|
|
|
}
|