From de93d6e171c258145ebe377f8c04f9b84b97b4fb Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Wed, 16 Feb 2022 22:12:47 -0500 Subject: [PATCH] Make Account.avatar optional for gotosocial --- Pachyderm/Model/Account.swift | 9 ++-- .../Model/Protocols/AccountProtocol.swift | 2 +- .../AccountActivityItemSource.swift | 5 +- .../Activities/StatusActivityItemSource.swift | 5 +- Tusker/CoreData/AccountMO.swift | 2 +- .../Tusker.xcdatamodel/contents | 4 +- .../Compose/ComposeAutocompleteView.swift | 2 +- .../ExpandThreadTableViewCell.swift | 14 +++--- .../FeaturedProfileCollectionViewCell.swift | 24 +++++---- .../FastSwitchingAccountView.swift | 6 ++- .../NotificationsTableViewController.swift | 6 ++- .../Preferences/LocalAccountAvatarView.swift | 5 +- .../Profile/MyProfileViewController.swift | 2 +- .../Utilities/StatusTablePrefetching.swift | 6 ++- .../Account Cell/AccountTableViewCell.swift | 23 +++++---- .../LargeAccountDetailView.swift | 12 +++-- ...ActionNotificationGroupTableViewCell.swift | 50 ++++++++++--------- ...FollowNotificationGroupTableViewCell.swift | 50 ++++++++++--------- ...llowRequestNotificationTableViewCell.swift | 28 ++++++----- .../Profile Header/ProfileHeaderView.swift | 36 ++++++------- .../Status/BaseStatusTableViewCell.swift | 19 +++---- Tusker/XCallbackURL/XCBActions.swift | 4 +- 22 files changed, 170 insertions(+), 144 deletions(-) diff --git a/Pachyderm/Model/Account.swift b/Pachyderm/Model/Account.swift index 688d24a2..bd76d9fc 100644 --- a/Pachyderm/Model/Account.swift +++ b/Pachyderm/Model/Account.swift @@ -20,8 +20,9 @@ public final class Account: AccountProtocol, Decodable { public let statusesCount: Int public let note: String public let url: URL - public let avatar: URL - public let avatarStatic: URL + // required on mastodon, but optional on gotosocial + public let avatar: URL? + public let avatarStatic: URL? public let header: URL? public let headerStatic: URL? public private(set) var emojis: [Emoji] @@ -44,8 +45,8 @@ public final class Account: AccountProtocol, Decodable { self.statusesCount = try container.decode(Int.self, forKey: .statusesCount) self.note = try container.decode(String.self, forKey: .note) self.url = try container.decode(URL.self, forKey: .url) - self.avatar = try container.decode(URL.self, forKey: .avatar) - self.avatarStatic = try container.decode(URL.self, forKey: .avatarStatic) + self.avatar = try? container.decode(URL.self, forKey: .avatar) + self.avatarStatic = try? container.decode(URL.self, forKey: .avatarStatic) self.header = try? container.decode(URL.self, forKey: .header) self.headerStatic = try? container.decode(URL.self, forKey: .headerStatic) self.emojis = try container.decode([Emoji].self, forKey: .emojis) diff --git a/Pachyderm/Model/Protocols/AccountProtocol.swift b/Pachyderm/Model/Protocols/AccountProtocol.swift index 47b29ee4..6b1be094 100644 --- a/Pachyderm/Model/Protocols/AccountProtocol.swift +++ b/Pachyderm/Model/Protocols/AccountProtocol.swift @@ -22,7 +22,7 @@ public protocol AccountProtocol { var statusesCount: Int { get } var note: String { get } var url: URL { get } - var avatar: URL { get } + var avatar: URL? { get } var header: URL? { get } var moved: Bool? { get } var bot: Bool? { get } diff --git a/Tusker/Activities/AccountActivityItemSource.swift b/Tusker/Activities/AccountActivityItemSource.swift index f1fde366..16529434 100644 --- a/Tusker/Activities/AccountActivityItemSource.swift +++ b/Tusker/Activities/AccountActivityItemSource.swift @@ -29,8 +29,9 @@ class AccountActivityItemSource: NSObject, UIActivityItemSource { metadata.originalURL = account.url metadata.url = account.url metadata.title = "\(account.displayName) (@\(account.username)@\(account.url.host!)" - if let data = ImageCache.avatars.getData(account.avatar), - let image = UIImage(data: data) { + if let avatar = account.avatar, + let data = ImageCache.avatars.getData(avatar), + let image = UIImage(data: data) { metadata.iconProvider = NSItemProvider(object: image) } return metadata diff --git a/Tusker/Activities/StatusActivityItemSource.swift b/Tusker/Activities/StatusActivityItemSource.swift index 3240413c..56768ac4 100644 --- a/Tusker/Activities/StatusActivityItemSource.swift +++ b/Tusker/Activities/StatusActivityItemSource.swift @@ -32,8 +32,9 @@ class StatusActivityItemSource: NSObject, UIActivityItemSource { let doc = try! SwiftSoup.parse(status.content) let content = try! doc.text() metadata.title = "\(status.account.displayName): \"\(content)\"" - if let data = ImageCache.avatars.getData(status.account.avatar), - let image = UIImage(data: data) { + if let avatar = status.account.avatar, + let data = ImageCache.avatars.getData(avatar), + let image = UIImage(data: data) { metadata.iconProvider = NSItemProvider(object: image) } return metadata diff --git a/Tusker/CoreData/AccountMO.swift b/Tusker/CoreData/AccountMO.swift index 7aeb90cb..2ebe40e1 100644 --- a/Tusker/CoreData/AccountMO.swift +++ b/Tusker/CoreData/AccountMO.swift @@ -19,7 +19,7 @@ public final class AccountMO: NSManagedObject, AccountProtocol { } @NSManaged public var acct: String - @NSManaged public var avatar: URL + @NSManaged public var avatar: URL? @NSManaged public var botCD: Bool @NSManaged public var createdAt: Date @NSManaged public var displayName: String diff --git a/Tusker/CoreData/Tusker.xcdatamodeld/Tusker.xcdatamodel/contents b/Tusker/CoreData/Tusker.xcdatamodeld/Tusker.xcdatamodel/contents index bfe62da7..0ad0d0b1 100644 --- a/Tusker/CoreData/Tusker.xcdatamodeld/Tusker.xcdatamodel/contents +++ b/Tusker/CoreData/Tusker.xcdatamodeld/Tusker.xcdatamodel/contents @@ -1,8 +1,8 @@ - + - + diff --git a/Tusker/Screens/Compose/ComposeAutocompleteView.swift b/Tusker/Screens/Compose/ComposeAutocompleteView.swift index 5fb018f3..6513dba8 100644 --- a/Tusker/Screens/Compose/ComposeAutocompleteView.swift +++ b/Tusker/Screens/Compose/ComposeAutocompleteView.swift @@ -189,7 +189,7 @@ struct ComposeAutocompleteMentionsView: View { } } - var avatar: URL { + var avatar: URL? { switch self { case let .pachyderm(account): return account.avatar diff --git a/Tusker/Screens/Conversation/ExpandThreadTableViewCell.swift b/Tusker/Screens/Conversation/ExpandThreadTableViewCell.swift index 88d823ba..e3d44ba7 100644 --- a/Tusker/Screens/Conversation/ExpandThreadTableViewCell.swift +++ b/Tusker/Screens/Conversation/ExpandThreadTableViewCell.swift @@ -86,13 +86,15 @@ class ExpandThreadTableViewCell: UITableViewCell { xConstraint ]) - let req = ImageCache.avatars.get(account.avatar) { [weak accountImageView] (_, image) in - DispatchQueue.main.async { - accountImageView?.image = image + if let avatar = account.avatar { + let req = ImageCache.avatars.get(avatar) { [weak accountImageView] (_, image) in + DispatchQueue.main.async { + accountImageView?.image = image + } + } + if let req = req { + avatarRequests.append(req) } - } - if let req = req { - avatarRequests.append(req) } } } diff --git a/Tusker/Screens/Explore/FeaturedProfileCollectionViewCell.swift b/Tusker/Screens/Explore/FeaturedProfileCollectionViewCell.swift index 6e5ae03f..b68c984c 100644 --- a/Tusker/Screens/Explore/FeaturedProfileCollectionViewCell.swift +++ b/Tusker/Screens/Explore/FeaturedProfileCollectionViewCell.swift @@ -55,17 +55,19 @@ class FeaturedProfileCollectionViewCell: UICollectionViewCell { noteTextView.setEmojis(account.emojis) avatarImageView.image = nil - avatarRequest = ImageCache.avatars.get(account.avatar) { [weak self] (_, image) in - defer { - self?.avatarRequest = nil - } - guard let self = self, - let image = image, - self.account?.id == account.id else { - return - } - DispatchQueue.main.async { - self.avatarImageView.image = image + if let avatar = account.avatar { + avatarRequest = ImageCache.avatars.get(avatar) { [weak self] (_, image) in + defer { + self?.avatarRequest = nil + } + guard let self = self, + let image = image, + self.account?.id == account.id else { + return + } + DispatchQueue.main.async { + self.avatarImageView.image = image + } } } diff --git a/Tusker/Screens/Fast Account Switcher/FastSwitchingAccountView.swift b/Tusker/Screens/Fast Account Switcher/FastSwitchingAccountView.swift index f306b5f0..6ef93d65 100644 --- a/Tusker/Screens/Fast Account Switcher/FastSwitchingAccountView.swift +++ b/Tusker/Screens/Fast Account Switcher/FastSwitchingAccountView.swift @@ -86,8 +86,10 @@ class FastSwitchingAccountView: UIView { let controller = MastodonController.getForAccount(account) controller.getOwnAccount { [weak self] (result) in - guard let self = self, case let .success(account) = result else { return } - self.avatarRequest = ImageCache.avatars.get(account.avatar) { [weak avatarImageView] (_, image) in + guard let self = self, + case let .success(account) = result, + let avatar = account.avatar else { return } + self.avatarRequest = ImageCache.avatars.get(avatar) { [weak avatarImageView] (_, image) in guard let avatarImageView = avatarImageView, let image = image else { return } DispatchQueue.main.async { avatarImageView.image = image diff --git a/Tusker/Screens/Notifications/NotificationsTableViewController.swift b/Tusker/Screens/Notifications/NotificationsTableViewController.swift index bfc5e4a3..d83a6928 100644 --- a/Tusker/Screens/Notifications/NotificationsTableViewController.swift +++ b/Tusker/Screens/Notifications/NotificationsTableViewController.swift @@ -259,7 +259,8 @@ extension NotificationsTableViewController: UITableViewDataSourcePrefetching { for indexPath in indexPaths { guard let group = dataSource.itemIdentifier(for: indexPath) else { continue } for notification in group.notifications { - ImageCache.avatars.fetchIfNotCached(notification.account.avatar) + guard let avatar = notification.account.avatar else { continue } + ImageCache.avatars.fetchIfNotCached(avatar) } } } @@ -268,7 +269,8 @@ extension NotificationsTableViewController: UITableViewDataSourcePrefetching { for indexPath in indexPaths { guard let group = dataSource.itemIdentifier(for: indexPath) else { continue } for notification in group.notifications { - ImageCache.avatars.cancelWithoutCallback(notification.account.avatar) + guard let avatar = notification.account.avatar else { continue } + ImageCache.avatars.cancelWithoutCallback(avatar) } } } diff --git a/Tusker/Screens/Preferences/LocalAccountAvatarView.swift b/Tusker/Screens/Preferences/LocalAccountAvatarView.swift index 46fa54d4..6d17804e 100644 --- a/Tusker/Screens/Preferences/LocalAccountAvatarView.swift +++ b/Tusker/Screens/Preferences/LocalAccountAvatarView.swift @@ -37,8 +37,9 @@ struct LocalAccountAvatarView: View { func loadImage() { let controller = MastodonController.getForAccount(localAccountInfo) controller.getOwnAccount { (result) in - guard case let .success(account) = result else { return } - _ = ImageCache.avatars.get(account.avatar) { (_, image) in + guard case let .success(account) = result, + let avatar = account.avatar else { return } + _ = ImageCache.avatars.get(avatar) { (_, image) in DispatchQueue.main.async { self.avatarImage = image } diff --git a/Tusker/Screens/Profile/MyProfileViewController.swift b/Tusker/Screens/Profile/MyProfileViewController.swift index f702142d..f0c02ff6 100644 --- a/Tusker/Screens/Profile/MyProfileViewController.swift +++ b/Tusker/Screens/Profile/MyProfileViewController.swift @@ -42,7 +42,7 @@ class MyProfileViewController: ProfileViewController { } private func setAvatarTabBarImage(account: Account) { - let avatarURL = account.avatar + guard let avatarURL = account.avatar else { return } _ = ImageCache.avatars.get(avatarURL, completion: { [weak self] (_, image) in guard let self = self, let image = image, diff --git a/Tusker/Screens/Utilities/StatusTablePrefetching.swift b/Tusker/Screens/Utilities/StatusTablePrefetching.swift index 46721f99..9af1fc3e 100644 --- a/Tusker/Screens/Utilities/StatusTablePrefetching.swift +++ b/Tusker/Screens/Utilities/StatusTablePrefetching.swift @@ -21,7 +21,8 @@ extension StatusTablePrefetching { return } for status in statuses { - ImageCache.avatars.fetchIfNotCached(status.account.avatar) + guard let avatar = status.account.avatar else { continue } + ImageCache.avatars.fetchIfNotCached(avatar) for attachment in status.attachments where attachment.kind == .image { ImageCache.attachments.fetchIfNotCached(attachment.url) } @@ -36,7 +37,8 @@ extension StatusTablePrefetching { return } for status in statuses { - ImageCache.avatars.cancelWithoutCallback(status.account.avatar) + guard let avatar = status.account.avatar else { continue } + ImageCache.avatars.cancelWithoutCallback(avatar) for attachment in status.attachments where attachment.kind == .image { ImageCache.attachments.cancelWithoutCallback(attachment.url) } diff --git a/Tusker/Views/Account Cell/AccountTableViewCell.swift b/Tusker/Views/Account Cell/AccountTableViewCell.swift index 8777ec94..30869306 100644 --- a/Tusker/Views/Account Cell/AccountTableViewCell.swift +++ b/Tusker/Views/Account Cell/AccountTableViewCell.swift @@ -62,17 +62,18 @@ class AccountTableViewCell: UITableViewCell { let accountID = self.accountID - let avatarURL = account.avatar - avatarRequest = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in - guard let self = self else { return } - self.avatarRequest = nil - - guard let image = image, - self.accountID == accountID, - let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else { return } - - DispatchQueue.main.async { - self.avatarImageView.image = transformedImage + if let avatarURL = account.avatar { + avatarRequest = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in + guard let self = self else { return } + self.avatarRequest = nil + + guard let image = image, + self.accountID == accountID, + let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else { return } + + DispatchQueue.main.async { + self.avatarImageView.image = transformedImage + } } } diff --git a/Tusker/Views/Account Detail/LargeAccountDetailView.swift b/Tusker/Views/Account Detail/LargeAccountDetailView.swift index e0a4feb9..f3e6f5c9 100644 --- a/Tusker/Views/Account Detail/LargeAccountDetailView.swift +++ b/Tusker/Views/Account Detail/LargeAccountDetailView.swift @@ -69,11 +69,13 @@ class LargeAccountDetailView: UIView { displayNameLabel.updateForAccountDisplayName(account: account) usernameLabel.text = "@\(account.acct)" - avatarRequest = ImageCache.avatars.get(account.avatar) { [weak self] (_, image) in - guard let self = self, let image = image else { return } - self.avatarRequest = nil - DispatchQueue.main.async { - self.avatarImageView.image = image + if let avatar = account.avatar { + avatarRequest = ImageCache.avatars.get(avatar) { [weak self] (_, image) in + guard let self = self, let image = image else { return } + self.avatarRequest = nil + DispatchQueue.main.async { + self.avatarImageView.image = image + } } } } diff --git a/Tusker/Views/Notifications/ActionNotificationGroupTableViewCell.swift b/Tusker/Views/Notifications/ActionNotificationGroupTableViewCell.swift index 81f2061c..e139823e 100644 --- a/Tusker/Views/Notifications/ActionNotificationGroupTableViewCell.swift +++ b/Tusker/Views/Notifications/ActionNotificationGroupTableViewCell.swift @@ -83,21 +83,22 @@ class ActionNotificationGroupTableViewCell: UITableViewCell { imageView.translatesAutoresizingMaskIntoConstraints = false imageView.layer.masksToBounds = true imageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * 30 - let avatarURL = account.avatar - avatarRequests[account.id] = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in - guard let self = self else { return } - guard let image = image, - self.group.id == group.id, - let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else { + if let avatarURL = account.avatar { + avatarRequests[account.id] = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in + guard let self = self else { return } + guard let image = image, + self.group.id == group.id, + let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else { + DispatchQueue.main.async { + self.avatarRequests.removeValue(forKey: account.id) + } + return + } + DispatchQueue.main.async { self.avatarRequests.removeValue(forKey: account.id) + imageView.image = transformedImage } - return - } - - DispatchQueue.main.async { - self.avatarRequests.removeValue(forKey: account.id) - imageView.image = transformedImage } } actionAvatarStackView.addArrangedSubview(imageView) @@ -131,21 +132,22 @@ class ActionNotificationGroupTableViewCell: UITableViewCell { continue } - let avatarURL = account.avatar - avatarRequests[account.id] = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in - guard let self = self else { return } - guard let image = image, - self.group.id == groupID, - let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else { + if let avatarURL = account.avatar { + avatarRequests[account.id] = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in + guard let self = self else { return } + guard let image = image, + self.group.id == groupID, + let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else { + DispatchQueue.main.async { + self.avatarRequests.removeValue(forKey: account.id) + } + return + } + DispatchQueue.main.async { self.avatarRequests.removeValue(forKey: account.id) + imageView.image = transformedImage } - return - } - - DispatchQueue.main.async { - self.avatarRequests.removeValue(forKey: account.id) - imageView.image = transformedImage } } } diff --git a/Tusker/Views/Notifications/FollowNotificationGroupTableViewCell.swift b/Tusker/Views/Notifications/FollowNotificationGroupTableViewCell.swift index 6181127e..75fe33a7 100644 --- a/Tusker/Views/Notifications/FollowNotificationGroupTableViewCell.swift +++ b/Tusker/Views/Notifications/FollowNotificationGroupTableViewCell.swift @@ -64,18 +64,19 @@ class FollowNotificationGroupTableViewCell: UITableViewCell { imageView.translatesAutoresizingMaskIntoConstraints = false imageView.layer.masksToBounds = true imageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * 30 - let avatarURL = account.avatar - avatarRequests[account.id] = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in - guard let self = self, - let image = image, - self.group.id == group.id, - let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else { - return - } - - DispatchQueue.main.async { - self.avatarRequests.removeValue(forKey: account.id) - imageView.image = transformedImage + if let avatarURL = account.avatar { + avatarRequests[account.id] = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in + guard let self = self, + let image = image, + self.group.id == group.id, + let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else { + return + } + + DispatchQueue.main.async { + self.avatarRequests.removeValue(forKey: account.id) + imageView.image = transformedImage + } } } avatarStackView.addArrangedSubview(imageView) @@ -98,21 +99,22 @@ class FollowNotificationGroupTableViewCell: UITableViewCell { continue } - let avatarURL = account.avatar - avatarRequests[account.id] = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in - guard let self = self else { return } - guard let image = image, - self.group.id == groupID, - let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else { + if let avatarURL = account.avatar { + avatarRequests[account.id] = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in + guard let self = self else { return } + guard let image = image, + self.group.id == groupID, + let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else { + DispatchQueue.main.async { + self.avatarRequests.removeValue(forKey: account.id) + } + return + } + DispatchQueue.main.async { self.avatarRequests.removeValue(forKey: account.id) + imageView.image = transformedImage } - return - } - - DispatchQueue.main.async { - self.avatarRequests.removeValue(forKey: account.id) - imageView.image = transformedImage } } } diff --git a/Tusker/Views/Notifications/FollowRequestNotificationTableViewCell.swift b/Tusker/Views/Notifications/FollowRequestNotificationTableViewCell.swift index 11783013..d81f07b7 100644 --- a/Tusker/Views/Notifications/FollowRequestNotificationTableViewCell.swift +++ b/Tusker/Views/Notifications/FollowRequestNotificationTableViewCell.swift @@ -67,19 +67,21 @@ class FollowRequestNotificationTableViewCell: UITableViewCell { actionLabel.text = "Request to follow from \(account.displayName)" actionLabel.setEmojis(account.emojis, identifier: account.id) } - let avatarURL = account.avatar - avatarRequest = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in - guard let self = self else { return } - self.avatarRequest = nil - - guard self.account == account, - let image = image, - let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else { - return - } - - DispatchQueue.main.async { - self.avatarImageView.image = transformedImage + + if let avatarURL = account.avatar { + avatarRequest = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in + guard let self = self else { return } + self.avatarRequest = nil + + guard self.account == account, + let image = image, + let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else { + return + } + + DispatchQueue.main.async { + self.avatarImageView.image = transformedImage + } } } } diff --git a/Tusker/Views/Profile Header/ProfileHeaderView.swift b/Tusker/Views/Profile Header/ProfileHeaderView.swift index 9d6df349..15c79041 100644 --- a/Tusker/Views/Profile Header/ProfileHeaderView.swift +++ b/Tusker/Views/Profile Header/ProfileHeaderView.swift @@ -202,22 +202,23 @@ class ProfileHeaderView: UIView { isGrayscale = Preferences.shared.grayscaleImages let accountID = account.id - let avatarURL = account.avatar - // always load original for avatars, because ImageCache.avatars stores them scaled-down in memory - avatarRequest = ImageCache.avatars.get(avatarURL, loadOriginal: true) { [weak self] (_, image) in - guard let self = self, - let image = image, - self.accountID == accountID, - let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else { - DispatchQueue.main.async { - self?.avatarRequest = nil + if let avatarURL = account.avatar { + // always load original for avatars, because ImageCache.avatars stores them scaled-down in memory + avatarRequest = ImageCache.avatars.get(avatarURL, loadOriginal: true) { [weak self] (_, image) in + guard let self = self, + let image = image, + self.accountID == accountID, + let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else { + DispatchQueue.main.async { + self?.avatarRequest = nil + } + return + } + + DispatchQueue.main.async { + self.avatarRequest = nil + self.avatarImageView.image = transformedImage } - return - } - - DispatchQueue.main.async { - self.avatarRequest = nil - self.avatarImageView.image = transformedImage } } if let header = account.header { @@ -243,10 +244,11 @@ class ProfileHeaderView: UIView { // MARK: Interaction @objc func avatarPressed() { - guard let account = mastodonController.persistentContainer.account(for: accountID) else { + guard let account = mastodonController.persistentContainer.account(for: accountID), + let avatar = account.avatar else { return } - delegate?.showLoadingLargeImage(url: account.avatar, cache: .avatars, description: nil, animatingFrom: avatarImageView) + delegate?.showLoadingLargeImage(url: avatar, cache: .avatars, description: nil, animatingFrom: avatarImageView) } @objc func headerPressed() { diff --git a/Tusker/Views/Status/BaseStatusTableViewCell.swift b/Tusker/Views/Status/BaseStatusTableViewCell.swift index 0720fca1..f04b588c 100644 --- a/Tusker/Views/Status/BaseStatusTableViewCell.swift +++ b/Tusker/Views/Status/BaseStatusTableViewCell.swift @@ -251,16 +251,17 @@ class BaseStatusTableViewCell: UITableViewCell, MenuPreviewProvider { func updateGrayscaleableUI(account: AccountMO, status: StatusMO) { isGrayscale = Preferences.shared.grayscaleImages - let avatarURL = account.avatar let accountID = account.id - avatarRequest = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in - guard let self = self, - let image = image, - self.accountID == accountID, - let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else { return } - - DispatchQueue.main.async { - self.avatarImageView.image = transformedImage + if let avatarURL = account.avatar { + avatarRequest = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in + guard let self = self, + let image = image, + self.accountID == accountID, + let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else { return } + + DispatchQueue.main.async { + self.avatarImageView.image = transformedImage + } } } diff --git a/Tusker/XCallbackURL/XCBActions.swift b/Tusker/XCallbackURL/XCBActions.swift index 78f8490e..5d44f618 100644 --- a/Tusker/XCallbackURL/XCBActions.swift +++ b/Tusker/XCallbackURL/XCBActions.swift @@ -269,7 +269,7 @@ struct XCBActions { "followers": account.followersCount.description, "following": account.followingCount.description, "url": account.url.absoluteString, - "avatarURL": account.avatar.absoluteString, + "avatarURL": account.avatar?.absoluteString, "headerURL": account.header?.absoluteString ]) } @@ -284,7 +284,7 @@ struct XCBActions { "followers": account.followersCount.description, "following": account.followingCount.description, "url": account.url.absoluteString, - "avatarURL": account.avatar.absoluteString, + "avatarURL": account.avatar?.absoluteString, "headerURL": account.header?.absoluteString ]) }