Compare commits

..

3 Commits

Author SHA1 Message Date
Shadowfacts bb3e1b44b1 Hide live text controls when other gallery controls are hidden
Closes #189
2022-10-28 19:16:00 -04:00
Shadowfacts 868df25417 Disable pruning offscreen rows in new timelines
I don't think this is actually necessary, the system should kill us
often enough that the amount of items in the data source doesn't become
unmanageable.

Making modifications to the data source in viewDidDisappear was causing
the collection view's contentOffset to change to be scrolled to top
(roughly) when the view became visible again.

Disabling it also fixes several issues caused by updating the data
source even when there were no changes.

Closes #193
Closes #192
Closes #187
Closes #186
2022-10-28 19:05:07 -04:00
Shadowfacts 2801f65e67 Fix reblog labels in new cells not being tappable
Closes #197
2022-10-28 18:48:30 -04:00
4 changed files with 47 additions and 22 deletions

View File

@ -14,6 +14,7 @@ import VisionKit
protocol LargeImageContentView: UIView {
var animationImage: UIImage? { get }
var activityItemsForSharing: [Any] { get }
func setControlsVisible(_ controlsVisible: Bool)
func grayscaleStateChanged()
}
@ -22,6 +23,9 @@ class LargeImageImageContentView: UIImageView, LargeImageContentView {
#if !targetEnvironment(macCatalyst)
@available(iOS 16.0, *)
private static let analyzer = ImageAnalyzer()
private var _analysisInteraction: AnyObject?
@available(iOS 16.0, *)
private var analysisInteraction: ImageAnalysisInteraction? { _analysisInteraction as? ImageAnalysisInteraction }
#endif
var animationImage: UIImage? { image! }
@ -45,6 +49,7 @@ class LargeImageImageContentView: UIImageView, LargeImageContentView {
if #available(iOS 16.0, *),
ImageAnalyzer.isSupported {
let interaction = ImageAnalysisInteraction()
self._analysisInteraction = interaction
interaction.delegate = self
interaction.preferredInteractionTypes = .automatic
addInteraction(interaction)
@ -64,6 +69,17 @@ class LargeImageImageContentView: UIImageView, LargeImageContentView {
fatalError("init(coder:) has not been implemented")
}
func setControlsVisible(_ controlsVisible: Bool) {
#if !targetEnvironment(macCatalyst)
if #available(iOS 16.0, *),
let analysisInteraction {
// note: passing animated: true here doesn't seem to do anything by itself as of iOS 16.2 (20C5032e)
// so the LargeImageViewController handles animating, but we still need to pass true here otherwise it doesn't animate
analysisInteraction.setSupplementaryInterfaceHidden(!controlsVisible, animated: true)
}
#endif
}
func grayscaleStateChanged() {
guard let data = sourceData else {
return
@ -113,6 +129,9 @@ class LargeImageGifContentView: GIFImageView, LargeImageContentView {
fatalError("init(coder:) has not been implemented")
}
func setControlsVisible(_ controlsVisible: Bool) {
}
func grayscaleStateChanged() {
// todo
}
@ -151,6 +170,9 @@ class LargeImageGifvContentView: GifvAttachmentView, LargeImageContentView {
fatalError("init(coder:) has not been implemented")
}
func setControlsVisible(_ controlsVisible: Bool) {
}
func grayscaleStateChanged() {
// no-op, GifvAttachmentView observes the grayscale state itself
}

View File

@ -174,6 +174,7 @@ class LargeImageViewController: UIViewController, UIScrollViewDelegate, LargeIma
self.controlsVisible = controlsVisible
if animated {
UIView.animate(withDuration: 0.2) {
self.contentView.setControlsVisible(controlsVisible)
self.updateControlsView()
}
} else {

View File

@ -160,7 +160,7 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
pruneOffscreenRows()
// pruneOffscreenRows()
}
private func removeTimelineDescriptionCell() {
@ -170,27 +170,28 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro
isShowingTimelineDescription = false
}
private func pruneOffscreenRows() {
guard let lastVisibleIndexPath = collectionView.indexPathsForVisibleItems.last else {
return
}
var snapshot = dataSource.snapshot()
guard snapshot.indexOfSection(.statuses) != nil else {
return
}
let items = snapshot.itemIdentifiers(inSection: .statuses)
let pageSize = 20
let numberOfPagesToPrune = (items.count - lastVisibleIndexPath.row - 1) / pageSize
if numberOfPagesToPrune > 0 {
let itemsToRemove = Array(items.suffix(numberOfPagesToPrune * pageSize))
snapshot.deleteItems(itemsToRemove)
}
dataSource.apply(snapshot, animatingDifferences: false)
if case .status(id: let id, state: _) = snapshot.itemIdentifiers(inSection: .statuses).last {
older = .before(id: id, count: nil)
}
}
// private func pruneOffscreenRows() {
// guard let lastVisibleIndexPath = collectionView.indexPathsForVisibleItems.last else {
// return
// }
// var snapshot = dataSource.snapshot()
// guard snapshot.indexOfSection(.statuses) != nil else {
// return
// }
// let items = snapshot.itemIdentifiers(inSection: .statuses)
// let pageSize = 20
// let numberOfPagesToPrune = (items.count - lastVisibleIndexPath.row - 1) / pageSize
// if numberOfPagesToPrune > 0 {
// let itemsToRemove = Array(items.suffix(numberOfPagesToPrune * pageSize))
// snapshot.deleteItems(itemsToRemove)
//
// dataSource.apply(snapshot, animatingDifferences: false)
//
// if case .status(id: let id, state: _) = snapshot.itemIdentifiers(inSection: .statuses).last {
// older = .before(id: id, count: nil)
// }
// }
// }
@objc func refresh() {
Task {

View File

@ -18,6 +18,7 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti
$0.textColor = .secondaryLabel
// this needs to have a higher priorty than the content container's zero height constraint
$0.setContentHuggingPriority(.defaultHigh, for: .vertical)
$0.isUserInteractionEnabled = true
$0.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(reblogLabelPressed)))
}