mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 06:43:25 +01:00
Tries to refresh apps that are about to expire first, and then always refreshes AltStore itself last, since refreshing AltStore means that the app will quit.
190 lines
6.0 KiB
Swift
190 lines
6.0 KiB
Swift
//
|
|
// AppDetailViewController.swift
|
|
// AltStore
|
|
//
|
|
// Created by Riley Testut on 5/9/19.
|
|
// Copyright © 2019 Riley Testut. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
import Roxas
|
|
|
|
@objc(ScreenshotCollectionViewCell)
|
|
private class ScreenshotCollectionViewCell: UICollectionViewCell
|
|
{
|
|
@IBOutlet var imageView: UIImageView!
|
|
}
|
|
|
|
extension AppDetailViewController
|
|
{
|
|
private enum Row: Int
|
|
{
|
|
case general
|
|
case screenshots
|
|
case description
|
|
}
|
|
}
|
|
|
|
class AppDetailViewController: UITableViewController
|
|
{
|
|
var app: App!
|
|
|
|
private lazy var screenshotsDataSource = self.makeScreenshotsDataSource()
|
|
|
|
@IBOutlet private var nameLabel: UILabel!
|
|
@IBOutlet private var developerButton: UIButton!
|
|
@IBOutlet private var appIconImageView: UIImageView!
|
|
|
|
@IBOutlet private var downloadButton: UIButton!
|
|
|
|
@IBOutlet private var screenshotsCollectionView: UICollectionView!
|
|
|
|
@IBOutlet private var descriptionLabel: UILabel!
|
|
|
|
override func viewDidLoad()
|
|
{
|
|
super.viewDidLoad()
|
|
|
|
self.tableView.delegate = self
|
|
self.screenshotsCollectionView.dataSource = self.screenshotsDataSource
|
|
|
|
self.downloadButton.activityIndicatorView.style = .white
|
|
|
|
self.update()
|
|
}
|
|
|
|
override func viewWillAppear(_ animated: Bool)
|
|
{
|
|
super.viewWillAppear(animated)
|
|
|
|
self.update()
|
|
}
|
|
|
|
override func viewDidLayoutSubviews()
|
|
{
|
|
super.viewDidLayoutSubviews()
|
|
|
|
guard let image = self.screenshotsDataSource.items.first else { return }
|
|
|
|
let aspectRatio = image.size.width / image.size.height
|
|
|
|
let height = self.screenshotsCollectionView.bounds.height
|
|
let width = self.screenshotsCollectionView.bounds.height * aspectRatio
|
|
|
|
let layout = self.screenshotsCollectionView.collectionViewLayout as! UICollectionViewFlowLayout
|
|
layout.itemSize = CGSize(width: width, height: height)
|
|
}
|
|
}
|
|
|
|
private extension AppDetailViewController
|
|
{
|
|
func update()
|
|
{
|
|
self.nameLabel.text = self.app.name
|
|
self.developerButton.setTitle(self.app.developerName, for: .normal)
|
|
self.appIconImageView.image = UIImage(named: self.app.iconName)
|
|
|
|
self.descriptionLabel.text = self.app.localizedDescription
|
|
|
|
if !self.downloadButton.isIndicatingActivity
|
|
{
|
|
if self.app.installedApp == nil
|
|
{
|
|
let text = String(format: NSLocalizedString("Download %@", comment: ""), self.app.name)
|
|
self.downloadButton.setTitle(text, for: .normal)
|
|
self.downloadButton.isEnabled = true
|
|
}
|
|
else
|
|
{
|
|
self.downloadButton.setTitle(NSLocalizedString("Installed", comment: ""), for: .normal)
|
|
self.downloadButton.isEnabled = false
|
|
}
|
|
}
|
|
}
|
|
|
|
func makeScreenshotsDataSource() -> RSTArrayCollectionViewDataSource<UIImage>
|
|
{
|
|
let screenshots = self.app.screenshotNames.compactMap(UIImage.init(named:))
|
|
|
|
let dataSource = RSTArrayCollectionViewDataSource(items: screenshots)
|
|
dataSource.cellConfigurationHandler = { (cell, screenshot, indexPath) in
|
|
let cell = cell as! ScreenshotCollectionViewCell
|
|
cell.imageView.image = screenshot
|
|
}
|
|
|
|
return dataSource
|
|
}
|
|
}
|
|
|
|
private extension AppDetailViewController
|
|
{
|
|
@IBAction func downloadApp(_ sender: UIButton)
|
|
{
|
|
guard self.app.installedApp == nil else { return }
|
|
|
|
sender.isIndicatingActivity = true
|
|
|
|
let progressView = UIProgressView(progressViewStyle: .bar)
|
|
progressView.translatesAutoresizingMaskIntoConstraints = false
|
|
progressView.progress = 0.0
|
|
|
|
let progress = AppManager.shared.install(self.app, presentingViewController: self) { (result) in
|
|
do
|
|
{
|
|
_ = try result.get()
|
|
|
|
DispatchQueue.main.async {
|
|
let toastView = RSTToastView(text: "Installed \(self.app.name)!", detailText: nil)
|
|
toastView.tintColor = .altPurple
|
|
toastView.show(in: self.navigationController!.view, duration: 2)
|
|
}
|
|
}
|
|
catch OperationError.cancelled
|
|
{
|
|
// Ignore
|
|
}
|
|
catch
|
|
{
|
|
DispatchQueue.main.async {
|
|
let toastView = RSTToastView(text: "Failed to install \(self.app.name)", detailText: error.localizedDescription)
|
|
toastView.tintColor = .altPurple
|
|
toastView.show(in: self.navigationController!.view, duration: 2)
|
|
}
|
|
}
|
|
|
|
DispatchQueue.main.async {
|
|
UIView.animate(withDuration: 0.4, animations: {
|
|
progressView.alpha = 0.0
|
|
}) { _ in
|
|
progressView.removeFromSuperview()
|
|
}
|
|
|
|
sender.isIndicatingActivity = false
|
|
self.update()
|
|
}
|
|
}
|
|
|
|
progressView.observedProgress = progress
|
|
|
|
if let navigationBar = self.navigationController?.navigationBar
|
|
{
|
|
navigationBar.addSubview(progressView)
|
|
|
|
NSLayoutConstraint.activate([progressView.widthAnchor.constraint(equalTo: navigationBar.widthAnchor),
|
|
progressView.bottomAnchor.constraint(equalTo: navigationBar.bottomAnchor)])
|
|
}
|
|
}
|
|
}
|
|
|
|
extension AppDetailViewController
|
|
{
|
|
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
|
|
{
|
|
guard indexPath.row == Row.screenshots.rawValue else { return super.tableView(tableView, heightForRowAt: indexPath) }
|
|
guard !self.screenshotsDataSource.items.isEmpty else { return 0.0 }
|
|
|
|
let height = self.view.bounds.height * 0.67
|
|
return height
|
|
}
|
|
}
|