Update Feeds to use higher resolution images when available. Issue #1208

This commit is contained in:
Maurice Parker 2019-10-28 20:57:26 -05:00
parent 55b9310f9c
commit 66b6d43408
4 changed files with 56 additions and 34 deletions

View File

@ -31,24 +31,9 @@ class MasterFeedTableViewCell : VibrantTableViewCell {
} }
} }
var faviconImage: UIImage? { var avatarImage: UIImage? {
didSet { didSet {
faviconImageView.image = faviconImage avatarImageView.image = avatarImage
if self.traitCollection.userInterfaceStyle == .dark {
DispatchQueue.global(qos: .background).async {
if self.faviconImage?.isDark() ?? false {
DispatchQueue.main.async {
self.faviconImageView.backgroundColor = AppAssets.avatarBackgroundColor
}
} else {
DispatchQueue.main.async {
self.faviconImageView.backgroundColor = nil
}
}
}
}
} }
} }
@ -106,12 +91,7 @@ class MasterFeedTableViewCell : VibrantTableViewCell {
return label return label
}() }()
private let faviconImageView: UIImageView = { private let avatarImageView = MasterTimelineAvatarView()
let imageView = NonIntrinsicImageView(image: AppAssets.faviconTemplateImage)
imageView.layer.cornerRadius = MasterFeedTableViewCellLayout.faviconCornerRadius
imageView.clipsToBounds = true
return imageView
}()
private let bottomSeparatorView: UIView = { private let bottomSeparatorView: UIView = {
let view = UIView() let view = UIView()
@ -188,7 +168,7 @@ private extension MasterFeedTableViewCell {
func commonInit() { func commonInit() {
addSubviewAtInit(unreadCountView) addSubviewAtInit(unreadCountView)
addSubviewAtInit(faviconImageView) addSubviewAtInit(avatarImageView)
addSubviewAtInit(titleView) addSubviewAtInit(titleView)
addDisclosureView() addDisclosureView()
addSubviewAtInit(bottomSeparatorView) addSubviewAtInit(bottomSeparatorView)
@ -209,7 +189,7 @@ private extension MasterFeedTableViewCell {
} }
func layoutWith(_ layout: MasterFeedTableViewCellLayout) { func layoutWith(_ layout: MasterFeedTableViewCellLayout) {
faviconImageView.setFrameIfNotEqual(layout.faviconRect) avatarImageView.setFrameIfNotEqual(layout.faviconRect)
titleView.setFrameIfNotEqual(layout.titleRect) titleView.setFrameIfNotEqual(layout.titleRect)
unreadCountView.setFrameIfNotEqual(layout.unreadCountRect) unreadCountView.setFrameIfNotEqual(layout.unreadCountRect)
disclosureButton?.setFrameIfNotEqual(layout.disclosureButtonRect) disclosureButton?.setFrameIfNotEqual(layout.disclosureButtonRect)
@ -225,7 +205,7 @@ private extension MasterFeedTableViewCell {
UIView.animate(withDuration: duration) { UIView.animate(withDuration: duration) {
self.disclosureButton?.tintColor = disclosureTintColor self.disclosureButton?.tintColor = disclosureTintColor
self.faviconImageView.tintColor = faviconTintColor self.avatarImageView.tintColor = faviconTintColor
} }
} }

View File

@ -12,7 +12,7 @@ import RSCore
struct MasterFeedTableViewCellLayout { struct MasterFeedTableViewCellLayout {
private static let editingControlIndent = CGFloat(integerLiteral: 40) private static let editingControlIndent = CGFloat(integerLiteral: 40)
private static let imageSize = CGSize(width: 20, height: 20) private static let imageSize = CGSize(width: 32, height: 32)
private static let imageMarginRight = CGFloat(integerLiteral: 11) private static let imageMarginRight = CGFloat(integerLiteral: 11)
private static let unreadCountMarginLeft = CGFloat(integerLiteral: 8) private static let unreadCountMarginLeft = CGFloat(integerLiteral: 8)
private static let unreadCountMarginRight = CGFloat(integerLiteral: 16) private static let unreadCountMarginRight = CGFloat(integerLiteral: 16)

View File

@ -53,6 +53,7 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
NotificationCenter.default.addObserver(self, selector: #selector(unreadCountDidChange(_:)), name: .UnreadCountDidChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(unreadCountDidChange(_:)), name: .UnreadCountDidChange, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(faviconDidBecomeAvailable(_:)), name: .FaviconDidBecomeAvailable, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(faviconDidBecomeAvailable(_:)), name: .FaviconDidBecomeAvailable, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(feedIconDidBecomeAvailable(_:)), name: .FeedIconDidBecomeAvailable, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(feedSettingDidChange(_:)), name: .FeedSettingDidChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(feedSettingDidChange(_:)), name: .FeedSettingDidChange, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(feedMetadataDidChange(_:)), name: .FeedMetadataDidChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(feedMetadataDidChange(_:)), name: .FeedMetadataDidChange, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(userDidAddFeed(_:)), name: .UserDidAddFeed, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(userDidAddFeed(_:)), name: .UserDidAddFeed, object: nil)
@ -106,7 +107,11 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
} }
@objc func faviconDidBecomeAvailable(_ note: Notification) { @objc func faviconDidBecomeAvailable(_ note: Notification) {
applyToAvailableCells(configureFavicon) applyToAvailableCells(configureAvatar)
}
@objc func feedIconDidBecomeAvailable(_ note: Notification) {
applyToAvailableCells(configureAvatar)
} }
@objc func feedSettingDidChange(_ note: Notification) { @objc func feedSettingDidChange(_ note: Notification) {
@ -627,7 +632,7 @@ private extension MasterFeedViewController {
cell.name = nameFor(node) cell.name = nameFor(node)
cell.unreadCount = coordinator.unreadCountFor(node) cell.unreadCount = coordinator.unreadCountFor(node)
configureFavicon(cell, node) configureAvatar(cell, node)
guard let indexPath = dataSource.indexPath(for: node) else { return } guard let indexPath = dataSource.indexPath(for: node) else { return }
let rowsInSection = tableView.numberOfRows(inSection: indexPath.section) let rowsInSection = tableView.numberOfRows(inSection: indexPath.section)
@ -639,14 +644,28 @@ private extension MasterFeedViewController {
} }
func configureFavicon(_ cell: MasterFeedTableViewCell, _ node: Node) { func configureAvatar(_ cell: MasterFeedTableViewCell, _ node: Node) {
cell.faviconImage = imageFor(node) cell.avatarImage = imageFor(node)
} }
func imageFor(_ node: Node) -> UIImage? { func imageFor(_ node: Node) -> UIImage? {
if let feed = node.representedObject as? Feed {
let feedIconImage = appDelegate.feedIconDownloader.icon(for: feed)
if feedIconImage != nil {
return feedIconImage
}
if let faviconImage = appDelegate.faviconDownloader.faviconAsAvatar(for: feed) {
return faviconImage
}
}
if let smallIconProvider = node.representedObject as? SmallIconProvider { if let smallIconProvider = node.representedObject as? SmallIconProvider {
return smallIconProvider.smallIcon return smallIconProvider.smallIcon
} }
return nil return nil
} }

View File

@ -14,11 +14,30 @@ final class MasterTimelineAvatarView: UIView {
didSet { didSet {
if image !== oldValue { if image !== oldValue {
imageView.image = image imageView.image = image
setNeedsLayout()
if self.traitCollection.userInterfaceStyle == .dark {
DispatchQueue.global(qos: .background).async {
if self.image?.isDark() ?? false {
DispatchQueue.main.async {
self.isDisconcernable = false
self.setNeedsLayout()
}
} else {
DispatchQueue.main.async {
self.isDisconcernable = true
self.setNeedsLayout()
}
}
}
} else {
self.setNeedsLayout()
}
} }
} }
} }
private var isDisconcernable = true
private let imageView: UIImageView = { private let imageView: UIImageView = {
let imageView = NonIntrinsicImageView(image: AppAssets.faviconTemplateImage) let imageView = NonIntrinsicImageView(image: AppAssets.faviconTemplateImage)
imageView.contentMode = .scaleAspectFit imageView.contentMode = .scaleAspectFit
@ -27,10 +46,14 @@ final class MasterTimelineAvatarView: UIView {
return imageView return imageView
}() }()
private var hasExposedVerticalBackground: Bool { private var isVerticalBackgroundExposed: Bool {
return imageView.frame.size.height < bounds.size.height return imageView.frame.size.height < bounds.size.height
} }
private var isSymbolImage: Bool {
return imageView.image?.isSymbolImage ?? false
}
override init(frame: CGRect) { override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
commonInit() commonInit()
@ -51,7 +74,7 @@ final class MasterTimelineAvatarView: UIView {
override func layoutSubviews() { override func layoutSubviews() {
imageView.setFrameIfNotEqual(rectForImageView()) imageView.setFrameIfNotEqual(rectForImageView())
if hasExposedVerticalBackground { if (isVerticalBackgroundExposed && !isSymbolImage) || !isDisconcernable {
backgroundColor = AppAssets.avatarBackgroundColor backgroundColor = AppAssets.avatarBackgroundColor
} else { } else {
backgroundColor = nil backgroundColor = nil