mirror of
https://github.com/Ranchero-Software/NetNewsWire.git
synced 2025-02-01 03:26:54 +01:00
Fix bug where user avatars wouldn’t always show up in the timeline view promptly.
This commit is contained in:
parent
665561e5eb
commit
45f3f49a1f
@ -11,17 +11,19 @@ import Data
|
||||
|
||||
extension Notification.Name {
|
||||
|
||||
static let AvatarDidBecomeAvailable = Notification.Name("AvatarDidBecomeAvailableNotification") // UserInfoKey.author
|
||||
static let AvatarDidBecomeAvailable = Notification.Name("AvatarDidBecomeAvailableNotification") // UserInfoKey.imageURL (which is an avatarURL)
|
||||
}
|
||||
|
||||
final class AuthorAvatarDownloader {
|
||||
|
||||
private let imageDownloader: ImageDownloader
|
||||
private var cache = [String: NSImage]() // avatarURL: NSImage
|
||||
private var waitingForAvatarURLs = Set<String>()
|
||||
|
||||
init(imageDownloader: ImageDownloader) {
|
||||
|
||||
self.imageDownloader = imageDownloader
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(imageDidBecomeAvailable(_:)), name: .ImageDidBecomeAvailable, object: imageDownloader)
|
||||
}
|
||||
|
||||
func image(for author: Author) -> NSImage? {
|
||||
@ -33,21 +35,49 @@ final class AuthorAvatarDownloader {
|
||||
return cachedImage
|
||||
}
|
||||
if let image = imageDownloader.image(for: avatarURL) {
|
||||
cache[avatarURL] = image
|
||||
postAvatarDidBecomeAvailableNotification(author)
|
||||
handleImageDidBecomeAvailable(avatarURL, image)
|
||||
return image
|
||||
}
|
||||
else {
|
||||
waitingForAvatarURLs.insert(avatarURL)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@objc func imageDidBecomeAvailable(_ note: Notification) {
|
||||
|
||||
guard let avatarURL = note.userInfo?[UserInfoKey.url] as? String else {
|
||||
return
|
||||
}
|
||||
guard waitingForAvatarURLs.contains(avatarURL) else {
|
||||
return
|
||||
}
|
||||
guard let image = imageDownloader.image(for: avatarURL) else {
|
||||
return
|
||||
}
|
||||
|
||||
handleImageDidBecomeAvailable(avatarURL, image)
|
||||
}
|
||||
}
|
||||
|
||||
private extension AuthorAvatarDownloader {
|
||||
|
||||
func postAvatarDidBecomeAvailableNotification(_ author: Author) {
|
||||
func handleImageDidBecomeAvailable(_ avatarURL: String, _ image: NSImage) {
|
||||
|
||||
if cache[avatarURL] == nil {
|
||||
cache[avatarURL] = image
|
||||
}
|
||||
if waitingForAvatarURLs.contains(avatarURL) {
|
||||
waitingForAvatarURLs.remove(avatarURL)
|
||||
postAvatarDidBecomeAvailableNotification(avatarURL)
|
||||
}
|
||||
}
|
||||
|
||||
func postAvatarDidBecomeAvailableNotification(_ avatarURL: String) {
|
||||
|
||||
DispatchQueue.main.async {
|
||||
let userInfo: [AnyHashable: Any] = [UserInfoKey.author: author]
|
||||
NotificationCenter.default.post(name: .AvatarDidBecomeAvailable, object: self, userInfo: userInfo)
|
||||
NotificationCenter.default.post(name: .AvatarDidBecomeAvailable, object: self, userInfo: [UserInfoKey.url: avatarURL])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import RSWeb
|
||||
|
||||
extension Notification.Name {
|
||||
|
||||
static let ImageDidBecomeAvailable = Notification.Name("ImageDidBecomeAvailableNotification") // ImageDownloader.UserInfoKey.imageURL
|
||||
static let ImageDidBecomeAvailable = Notification.Name("ImageDidBecomeAvailableNotification") // UserInfoKey.url
|
||||
}
|
||||
|
||||
final class ImageDownloader {
|
||||
@ -24,10 +24,6 @@ final class ImageDownloader {
|
||||
private var urlsInProgress = Set<String>()
|
||||
private var badURLs = Set<String>() // That return a 404 or whatever. Just skip them in the future.
|
||||
|
||||
struct UserInfoKey {
|
||||
static let imageURL = "imageURL"
|
||||
}
|
||||
|
||||
init(folder: String) {
|
||||
|
||||
self.folder = folder
|
||||
@ -135,6 +131,6 @@ private extension ImageDownloader {
|
||||
|
||||
func postImageDidBecomeAvailableNotification(_ url: String) {
|
||||
|
||||
NotificationCenter.default.post(name: .ImageDidBecomeAvailable, object: self, userInfo: [UserInfoKey.imageURL: url])
|
||||
NotificationCenter.default.post(name: .ImageDidBecomeAvailable, object: self, userInfo: [UserInfoKey.url: url])
|
||||
}
|
||||
}
|
||||
|
@ -327,7 +327,7 @@ class TimelineViewController: NSViewController, UndoableCommandRunner {
|
||||
|
||||
@objc func avatarDidBecomeAvailable(_ note: Notification) {
|
||||
|
||||
guard let author = note.userInfo?[UserInfoKey.author] as? Author, let avatarURL = author.avatarURL else {
|
||||
guard let avatarURL = note.userInfo?[UserInfoKey.url] as? String else {
|
||||
return
|
||||
}
|
||||
let articlesToReload = articles.filter { (article) -> Bool in
|
||||
|
Loading…
x
Reference in New Issue
Block a user