mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 06:43:25 +01:00
Supports viewing full screen app screenshots from AppViewController
[Missed] Uses layout config for PreviewAppScreenshots
This commit is contained in:
@@ -142,6 +142,14 @@ final class AppViewController: UIViewController
|
||||
self.view.layoutIfNeeded()
|
||||
}
|
||||
|
||||
override func viewIsAppearing(_ animated: Bool)
|
||||
{
|
||||
super.viewIsAppearing(animated)
|
||||
|
||||
// Prevent banner temporarily flashing a color due to being added back to self.view.
|
||||
self.bannerView.backgroundEffectView.backgroundColor = .clear
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool)
|
||||
{
|
||||
super.viewDidAppear(animated)
|
||||
@@ -191,21 +199,7 @@ final class AppViewController: UIViewController
|
||||
self._shouldResetLayout = false
|
||||
}
|
||||
|
||||
let statusBarHeight: Double
|
||||
|
||||
if let navigationController, navigationController.presentingViewController != nil, navigationController.modalPresentationStyle != .fullScreen
|
||||
{
|
||||
statusBarHeight = 20
|
||||
}
|
||||
else if let statusBarManager = self.view.window?.windowScene?.statusBarManager
|
||||
{
|
||||
statusBarHeight = statusBarManager.statusBarFrame.height
|
||||
}
|
||||
else
|
||||
{
|
||||
statusBarHeight = 0
|
||||
}
|
||||
|
||||
let statusBarHeight = (self.view.window ?? self.presentedViewController?.view.window)?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0
|
||||
let cornerRadius = self.contentViewControllerShadowView.layer.cornerRadius
|
||||
|
||||
let inset = 12 as CGFloat
|
||||
|
||||
@@ -129,6 +129,21 @@ private extension AppScreenshotsViewController
|
||||
}
|
||||
}
|
||||
|
||||
extension AppScreenshotsViewController
|
||||
{
|
||||
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
|
||||
{
|
||||
let screenshot = self.dataSource.item(at: indexPath)
|
||||
|
||||
let previewViewController = PreviewAppScreenshotsViewController(app: self.app)
|
||||
previewViewController.currentScreenshot = screenshot
|
||||
|
||||
let navigationController = UINavigationController(rootViewController: previewViewController)
|
||||
navigationController.modalPresentationStyle = .fullScreen
|
||||
self.present(navigationController, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 17, *)
|
||||
#Preview(traits: .portrait) {
|
||||
DatabaseManager.shared.startForPreview()
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
//
|
||||
// PreviewAppScreenshotsViewController.swift
|
||||
// AltStore
|
||||
//
|
||||
// Created by Riley Testut on 9/19/23.
|
||||
// Copyright © 2023 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
import AltStoreCore
|
||||
import Roxas
|
||||
|
||||
import Nuke
|
||||
|
||||
class PreviewAppScreenshotsViewController: UICollectionViewController
|
||||
{
|
||||
let app: StoreApp
|
||||
|
||||
var currentScreenshot: AppScreenshot?
|
||||
|
||||
private lazy var dataSource = self.makeDataSource()
|
||||
|
||||
init(app: StoreApp)
|
||||
{
|
||||
self.app = app
|
||||
|
||||
super.init(collectionViewLayout: UICollectionViewFlowLayout())
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func viewDidLoad()
|
||||
{
|
||||
super.viewDidLoad()
|
||||
|
||||
let tintColor = self.app.tintColor ?? .altPrimary
|
||||
self.navigationController?.view.tintColor = tintColor
|
||||
|
||||
self.view.backgroundColor = .systemBackground
|
||||
self.collectionView.backgroundColor = nil
|
||||
|
||||
let collectionViewLayout = self.makeLayout()
|
||||
self.collectionView.collectionViewLayout = collectionViewLayout
|
||||
|
||||
self.collectionView.directionalLayoutMargins.leading = 20
|
||||
self.collectionView.directionalLayoutMargins.trailing = 20
|
||||
|
||||
self.collectionView.preservesSuperviewLayoutMargins = true
|
||||
self.collectionView.insetsLayoutMarginsFromSafeArea = true
|
||||
|
||||
self.collectionView.alwaysBounceVertical = false
|
||||
self.collectionView.register(AppScreenshotCollectionViewCell.self, forCellWithReuseIdentifier: RSTCellContentGenericCellIdentifier)
|
||||
|
||||
self.collectionView.dataSource = self.dataSource
|
||||
self.collectionView.prefetchDataSource = self.dataSource
|
||||
|
||||
let doneButton = UIBarButtonItem(systemItem: .done, primaryAction: UIAction { [weak self] _ in
|
||||
self?.dismiss(animated: true)
|
||||
})
|
||||
self.navigationItem.rightBarButtonItem = doneButton
|
||||
}
|
||||
|
||||
override func viewIsAppearing(_ animated: Bool)
|
||||
{
|
||||
super.viewIsAppearing(animated)
|
||||
|
||||
if let screenshot = self.currentScreenshot, let index = self.dataSource.items.firstIndex(of: screenshot)
|
||||
{
|
||||
let indexPath = IndexPath(item: index, section: 0)
|
||||
self.collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension PreviewAppScreenshotsViewController
|
||||
{
|
||||
func makeLayout() -> UICollectionViewCompositionalLayout
|
||||
{
|
||||
let layoutConfig = UICollectionViewCompositionalLayoutConfiguration()
|
||||
layoutConfig.contentInsetsReference = .none
|
||||
|
||||
let layout = UICollectionViewCompositionalLayout(sectionProvider: { [weak self] (sectionIndex, layoutEnvironment) -> NSCollectionLayoutSection? in
|
||||
guard let self else { return nil }
|
||||
|
||||
let contentInsets = self.collectionView.directionalLayoutMargins
|
||||
let groupWidth = layoutEnvironment.container.contentSize.width - (contentInsets.leading + contentInsets.trailing)
|
||||
let groupHeight = layoutEnvironment.container.contentSize.height - (contentInsets.top + contentInsets.bottom)
|
||||
|
||||
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0))
|
||||
let item = NSCollectionLayoutItem(layoutSize: itemSize)
|
||||
|
||||
let groupSize = NSCollectionLayoutSize(widthDimension: .absolute(groupWidth), heightDimension: .absolute(groupHeight))
|
||||
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
|
||||
|
||||
let layoutSection = NSCollectionLayoutSection(group: group)
|
||||
layoutSection.orthogonalScrollingBehavior = .groupPagingCentered
|
||||
layoutSection.interGroupSpacing = 10
|
||||
return layoutSection
|
||||
}, configuration: layoutConfig)
|
||||
|
||||
return layout
|
||||
}
|
||||
|
||||
func makeDataSource() -> RSTArrayCollectionViewPrefetchingDataSource<AppScreenshot, UIImage>
|
||||
{
|
||||
let dataSource = RSTArrayCollectionViewPrefetchingDataSource<AppScreenshot, UIImage>(items: self.app.screenshots)
|
||||
dataSource.cellConfigurationHandler = { (cell, screenshot, indexPath) in
|
||||
let cell = cell as! AppScreenshotCollectionViewCell
|
||||
cell.imageView.image = nil
|
||||
cell.imageView.isIndicatingActivity = true
|
||||
|
||||
var aspectRatio = screenshot.size ?? AppScreenshot.defaultAspectRatio
|
||||
if aspectRatio.width > aspectRatio.height
|
||||
{
|
||||
aspectRatio = CGSize(width: aspectRatio.height, height: aspectRatio.width)
|
||||
}
|
||||
|
||||
cell.aspectRatio = aspectRatio
|
||||
}
|
||||
dataSource.prefetchHandler = { (screenshot, indexPath, completionHandler) in
|
||||
let imageURL = screenshot.imageURL
|
||||
return RSTAsyncBlockOperation() { (operation) in
|
||||
let request = ImageRequest(url: imageURL, processors: [.screenshot])
|
||||
ImagePipeline.shared.loadImage(with: request, progress: nil) { result in
|
||||
guard !operation.isCancelled else { return operation.finish() }
|
||||
|
||||
switch result
|
||||
{
|
||||
case .success(let response): completionHandler(response.image, nil)
|
||||
case .failure(let error): completionHandler(nil, error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dataSource.prefetchCompletionHandler = { (cell, image, indexPath, error) in
|
||||
let cell = cell as! AppScreenshotCollectionViewCell
|
||||
cell.imageView.isIndicatingActivity = false
|
||||
cell.imageView.image = image
|
||||
|
||||
if let error = error
|
||||
{
|
||||
print("Error loading image:", error)
|
||||
}
|
||||
}
|
||||
|
||||
return dataSource
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 17, *)
|
||||
#Preview(traits: .portrait) {
|
||||
DatabaseManager.shared.startForPreview()
|
||||
|
||||
let fetchRequest = StoreApp.fetchRequest()
|
||||
let storeApp = try! DatabaseManager.shared.viewContext.fetch(fetchRequest).first!
|
||||
|
||||
let previewViewController = PreviewAppScreenshotsViewController(app: storeApp)
|
||||
|
||||
let navigationController = UINavigationController(rootViewController: previewViewController)
|
||||
return navigationController
|
||||
}
|
||||
Reference in New Issue
Block a user