From 5c808ec59e7400ed8e54efa1c73bbf4953e60013 Mon Sep 17 00:00:00 2001 From: Riley Testut Date: Thu, 7 Dec 2023 18:19:42 -0600 Subject: [PATCH] =?UTF-8?q?Shows=20app=E2=80=99s=20source=20icon=20on=20Ap?= =?UTF-8?q?pBannerView?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Excluding contexts where it is redundant (e.g. source detail page). --- AltStore/Browse/BrowseViewController.swift | 17 ++++---- AltStore/Components/AppBannerView.swift | 39 ++++++++++++++++++- AltStore/Components/AppBannerView.xib | 16 ++++++-- .../AppCardCollectionViewCell.swift | 4 +- .../SourceDetailContentViewController.swift | 10 +++-- 5 files changed, 68 insertions(+), 18 deletions(-) diff --git a/AltStore/Browse/BrowseViewController.swift b/AltStore/Browse/BrowseViewController.swift index 084010f4..b981125c 100644 --- a/AltStore/Browse/BrowseViewController.swift +++ b/AltStore/Browse/BrowseViewController.swift @@ -219,12 +219,16 @@ private extension BrowseViewController let context = self.source?.managedObjectContext ?? DatabaseManager.shared.viewContext let dataSource = RSTFetchedResultsCollectionViewPrefetchingDataSource(fetchRequest: fetchRequest, managedObjectContext: context) - dataSource.cellConfigurationHandler = { (cell, app, indexPath) in + dataSource.placeholderView = self.placeholderView + dataSource.cellConfigurationHandler = { [weak self] (cell, app, indexPath) in + guard let self else { return } + let cell = cell as! AppCardCollectionViewCell cell.layoutMargins.left = self.view.layoutMargins.left cell.layoutMargins.right = self.view.layoutMargins.right - cell.configure(for: app) + let showSourceIcon = (self.source == nil) // Hide source icon if redundant + cell.configure(for: app, showSourceIcon: showSourceIcon) cell.bannerView.iconImageView.image = nil cell.bannerView.iconImageView.isIndicatingActivity = true @@ -251,19 +255,18 @@ private extension BrowseViewController } } } - dataSource.prefetchCompletionHandler = { (cell, image, indexPath, error) in + dataSource.prefetchCompletionHandler = { [weak dataSource] (cell, image, indexPath, error) in let cell = cell as! AppCardCollectionViewCell cell.bannerView.iconImageView.isIndicatingActivity = false cell.bannerView.iconImageView.image = image - if let error = error + if let error = error, let dataSource { - print("Error loading image:", error) + let app = dataSource.item(at: indexPath) + Logger.main.debug("Failed to load app icon from \(app.iconURL, privacy: .public). \(error.localizedDescription, privacy: .public)") } } - dataSource.placeholderView = self.placeholderView - return dataSource } diff --git a/AltStore/Components/AppBannerView.swift b/AltStore/Components/AppBannerView.swift index 4cbe3632..17be3b22 100644 --- a/AltStore/Components/AppBannerView.swift +++ b/AltStore/Components/AppBannerView.swift @@ -11,6 +11,8 @@ import UIKit import AltStoreCore import Roxas +import Nuke + extension AppBannerView { enum Style @@ -65,6 +67,7 @@ class AppBannerView: RSTNibView @IBOutlet var button: PillButton! @IBOutlet var buttonLabel: UILabel! @IBOutlet var betaBadgeView: UIView! + @IBOutlet var sourceIconImageView: AppIconImageView! @IBOutlet var backgroundEffectView: UIVisualEffectView! @@ -97,6 +100,9 @@ class AppBannerView: RSTNibView self.betaBadgeView.isHidden = true + self.sourceIconImageView.style = .circular + self.sourceIconImageView.isHidden = true + self.layoutMargins = self.stackView.layoutMargins self.insetsLayoutMarginsFromSafeArea = false @@ -119,7 +125,7 @@ class AppBannerView: RSTNibView extension AppBannerView { - func configure(for app: AppProtocol, action: AppAction? = nil) + func configure(for app: AppProtocol, action: AppAction? = nil, showSourceIcon: Bool = true) { struct AppValues { @@ -170,6 +176,37 @@ extension AppBannerView self.buttonLabel.isHidden = true } + if let source = app.storeApp?.source, showSourceIcon + { + self.sourceIconImageView.isHidden = false + self.sourceIconImageView.backgroundColor = source.effectiveTintColor?.adjustedForDisplay ?? .altPrimary + + if let iconURL = source.effectiveIconURL + { + if let image = ImageCache.shared[iconURL] + { + self.sourceIconImageView.backgroundColor = .white + self.sourceIconImageView.image = image.image + } + else + { + self.sourceIconImageView.image = nil + + Nuke.loadImage(with: iconURL, into: self.sourceIconImageView) { result in + switch result + { + case .failure(let error): Logger.main.error("Failed to fetch source icon from \(iconURL, privacy: .public). \(error.localizedDescription, privacy: .public)") + case .success: self.sourceIconImageView.backgroundColor = .white // In case icon has transparent background. + } + } + } + } + } + else + { + self.sourceIconImageView.isHidden = true + } + let buttonAction: AppAction if let action diff --git a/AltStore/Components/AppBannerView.xib b/AltStore/Components/AppBannerView.xib index d140f5ae..fc3c120a 100644 --- a/AltStore/Components/AppBannerView.xib +++ b/AltStore/Components/AppBannerView.xib @@ -18,6 +18,7 @@ + @@ -58,18 +59,25 @@ - - + + -