Make Account.avatar optional for gotosocial
This commit is contained in:
parent
80c79ded3b
commit
de93d6e171
|
@ -20,8 +20,9 @@ public final class Account: AccountProtocol, Decodable {
|
||||||
public let statusesCount: Int
|
public let statusesCount: Int
|
||||||
public let note: String
|
public let note: String
|
||||||
public let url: URL
|
public let url: URL
|
||||||
public let avatar: URL
|
// required on mastodon, but optional on gotosocial
|
||||||
public let avatarStatic: URL
|
public let avatar: URL?
|
||||||
|
public let avatarStatic: URL?
|
||||||
public let header: URL?
|
public let header: URL?
|
||||||
public let headerStatic: URL?
|
public let headerStatic: URL?
|
||||||
public private(set) var emojis: [Emoji]
|
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.statusesCount = try container.decode(Int.self, forKey: .statusesCount)
|
||||||
self.note = try container.decode(String.self, forKey: .note)
|
self.note = try container.decode(String.self, forKey: .note)
|
||||||
self.url = try container.decode(URL.self, forKey: .url)
|
self.url = try container.decode(URL.self, forKey: .url)
|
||||||
self.avatar = try container.decode(URL.self, forKey: .avatar)
|
self.avatar = try? container.decode(URL.self, forKey: .avatar)
|
||||||
self.avatarStatic = try container.decode(URL.self, forKey: .avatarStatic)
|
self.avatarStatic = try? container.decode(URL.self, forKey: .avatarStatic)
|
||||||
self.header = try? container.decode(URL.self, forKey: .header)
|
self.header = try? container.decode(URL.self, forKey: .header)
|
||||||
self.headerStatic = try? container.decode(URL.self, forKey: .headerStatic)
|
self.headerStatic = try? container.decode(URL.self, forKey: .headerStatic)
|
||||||
self.emojis = try container.decode([Emoji].self, forKey: .emojis)
|
self.emojis = try container.decode([Emoji].self, forKey: .emojis)
|
||||||
|
|
|
@ -22,7 +22,7 @@ public protocol AccountProtocol {
|
||||||
var statusesCount: Int { get }
|
var statusesCount: Int { get }
|
||||||
var note: String { get }
|
var note: String { get }
|
||||||
var url: URL { get }
|
var url: URL { get }
|
||||||
var avatar: URL { get }
|
var avatar: URL? { get }
|
||||||
var header: URL? { get }
|
var header: URL? { get }
|
||||||
var moved: Bool? { get }
|
var moved: Bool? { get }
|
||||||
var bot: Bool? { get }
|
var bot: Bool? { get }
|
||||||
|
|
|
@ -29,8 +29,9 @@ class AccountActivityItemSource: NSObject, UIActivityItemSource {
|
||||||
metadata.originalURL = account.url
|
metadata.originalURL = account.url
|
||||||
metadata.url = account.url
|
metadata.url = account.url
|
||||||
metadata.title = "\(account.displayName) (@\(account.username)@\(account.url.host!)"
|
metadata.title = "\(account.displayName) (@\(account.username)@\(account.url.host!)"
|
||||||
if let data = ImageCache.avatars.getData(account.avatar),
|
if let avatar = account.avatar,
|
||||||
let image = UIImage(data: data) {
|
let data = ImageCache.avatars.getData(avatar),
|
||||||
|
let image = UIImage(data: data) {
|
||||||
metadata.iconProvider = NSItemProvider(object: image)
|
metadata.iconProvider = NSItemProvider(object: image)
|
||||||
}
|
}
|
||||||
return metadata
|
return metadata
|
||||||
|
|
|
@ -32,8 +32,9 @@ class StatusActivityItemSource: NSObject, UIActivityItemSource {
|
||||||
let doc = try! SwiftSoup.parse(status.content)
|
let doc = try! SwiftSoup.parse(status.content)
|
||||||
let content = try! doc.text()
|
let content = try! doc.text()
|
||||||
metadata.title = "\(status.account.displayName): \"\(content)\""
|
metadata.title = "\(status.account.displayName): \"\(content)\""
|
||||||
if let data = ImageCache.avatars.getData(status.account.avatar),
|
if let avatar = status.account.avatar,
|
||||||
let image = UIImage(data: data) {
|
let data = ImageCache.avatars.getData(avatar),
|
||||||
|
let image = UIImage(data: data) {
|
||||||
metadata.iconProvider = NSItemProvider(object: image)
|
metadata.iconProvider = NSItemProvider(object: image)
|
||||||
}
|
}
|
||||||
return metadata
|
return metadata
|
||||||
|
|
|
@ -19,7 +19,7 @@ public final class AccountMO: NSManagedObject, AccountProtocol {
|
||||||
}
|
}
|
||||||
|
|
||||||
@NSManaged public var acct: String
|
@NSManaged public var acct: String
|
||||||
@NSManaged public var avatar: URL
|
@NSManaged public var avatar: URL?
|
||||||
@NSManaged public var botCD: Bool
|
@NSManaged public var botCD: Bool
|
||||||
@NSManaged public var createdAt: Date
|
@NSManaged public var createdAt: Date
|
||||||
@NSManaged public var displayName: String
|
@NSManaged public var displayName: String
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="19574" systemVersion="21C52" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="19574" systemVersion="21D49" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||||
<entity name="Account" representedClassName="AccountMO" syncable="YES">
|
<entity name="Account" representedClassName="AccountMO" syncable="YES">
|
||||||
<attribute name="acct" attributeType="String"/>
|
<attribute name="acct" attributeType="String"/>
|
||||||
<attribute name="avatar" attributeType="URI"/>
|
<attribute name="avatar" optional="YES" attributeType="URI"/>
|
||||||
<attribute name="botCD" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
<attribute name="botCD" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||||
<attribute name="createdAt" attributeType="Date" usesScalarValueType="NO"/>
|
<attribute name="createdAt" attributeType="Date" usesScalarValueType="NO"/>
|
||||||
<attribute name="displayName" attributeType="String"/>
|
<attribute name="displayName" attributeType="String"/>
|
||||||
|
|
|
@ -189,7 +189,7 @@ struct ComposeAutocompleteMentionsView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var avatar: URL {
|
var avatar: URL? {
|
||||||
switch self {
|
switch self {
|
||||||
case let .pachyderm(account):
|
case let .pachyderm(account):
|
||||||
return account.avatar
|
return account.avatar
|
||||||
|
|
|
@ -86,13 +86,15 @@ class ExpandThreadTableViewCell: UITableViewCell {
|
||||||
xConstraint
|
xConstraint
|
||||||
])
|
])
|
||||||
|
|
||||||
let req = ImageCache.avatars.get(account.avatar) { [weak accountImageView] (_, image) in
|
if let avatar = account.avatar {
|
||||||
DispatchQueue.main.async {
|
let req = ImageCache.avatars.get(avatar) { [weak accountImageView] (_, image) in
|
||||||
accountImageView?.image = image
|
DispatchQueue.main.async {
|
||||||
|
accountImageView?.image = image
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let req = req {
|
||||||
|
avatarRequests.append(req)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if let req = req {
|
|
||||||
avatarRequests.append(req)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,17 +55,19 @@ class FeaturedProfileCollectionViewCell: UICollectionViewCell {
|
||||||
noteTextView.setEmojis(account.emojis)
|
noteTextView.setEmojis(account.emojis)
|
||||||
|
|
||||||
avatarImageView.image = nil
|
avatarImageView.image = nil
|
||||||
avatarRequest = ImageCache.avatars.get(account.avatar) { [weak self] (_, image) in
|
if let avatar = account.avatar {
|
||||||
defer {
|
avatarRequest = ImageCache.avatars.get(avatar) { [weak self] (_, image) in
|
||||||
self?.avatarRequest = nil
|
defer {
|
||||||
}
|
self?.avatarRequest = nil
|
||||||
guard let self = self,
|
}
|
||||||
let image = image,
|
guard let self = self,
|
||||||
self.account?.id == account.id else {
|
let image = image,
|
||||||
return
|
self.account?.id == account.id else {
|
||||||
}
|
return
|
||||||
DispatchQueue.main.async {
|
}
|
||||||
self.avatarImageView.image = image
|
DispatchQueue.main.async {
|
||||||
|
self.avatarImageView.image = image
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,8 +86,10 @@ class FastSwitchingAccountView: UIView {
|
||||||
|
|
||||||
let controller = MastodonController.getForAccount(account)
|
let controller = MastodonController.getForAccount(account)
|
||||||
controller.getOwnAccount { [weak self] (result) in
|
controller.getOwnAccount { [weak self] (result) in
|
||||||
guard let self = self, case let .success(account) = result else { return }
|
guard let self = self,
|
||||||
self.avatarRequest = ImageCache.avatars.get(account.avatar) { [weak avatarImageView] (_, image) in
|
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 }
|
guard let avatarImageView = avatarImageView, let image = image else { return }
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
avatarImageView.image = image
|
avatarImageView.image = image
|
||||||
|
|
|
@ -259,7 +259,8 @@ extension NotificationsTableViewController: UITableViewDataSourcePrefetching {
|
||||||
for indexPath in indexPaths {
|
for indexPath in indexPaths {
|
||||||
guard let group = dataSource.itemIdentifier(for: indexPath) else { continue }
|
guard let group = dataSource.itemIdentifier(for: indexPath) else { continue }
|
||||||
for notification in group.notifications {
|
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 {
|
for indexPath in indexPaths {
|
||||||
guard let group = dataSource.itemIdentifier(for: indexPath) else { continue }
|
guard let group = dataSource.itemIdentifier(for: indexPath) else { continue }
|
||||||
for notification in group.notifications {
|
for notification in group.notifications {
|
||||||
ImageCache.avatars.cancelWithoutCallback(notification.account.avatar)
|
guard let avatar = notification.account.avatar else { continue }
|
||||||
|
ImageCache.avatars.cancelWithoutCallback(avatar)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,9 @@ struct LocalAccountAvatarView: View {
|
||||||
func loadImage() {
|
func loadImage() {
|
||||||
let controller = MastodonController.getForAccount(localAccountInfo)
|
let controller = MastodonController.getForAccount(localAccountInfo)
|
||||||
controller.getOwnAccount { (result) in
|
controller.getOwnAccount { (result) in
|
||||||
guard case let .success(account) = result else { return }
|
guard case let .success(account) = result,
|
||||||
_ = ImageCache.avatars.get(account.avatar) { (_, image) in
|
let avatar = account.avatar else { return }
|
||||||
|
_ = ImageCache.avatars.get(avatar) { (_, image) in
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.avatarImage = image
|
self.avatarImage = image
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ class MyProfileViewController: ProfileViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setAvatarTabBarImage<Account: AccountProtocol>(account: Account) {
|
private func setAvatarTabBarImage<Account: AccountProtocol>(account: Account) {
|
||||||
let avatarURL = account.avatar
|
guard let avatarURL = account.avatar else { return }
|
||||||
_ = ImageCache.avatars.get(avatarURL, completion: { [weak self] (_, image) in
|
_ = ImageCache.avatars.get(avatarURL, completion: { [weak self] (_, image) in
|
||||||
guard let self = self,
|
guard let self = self,
|
||||||
let image = image,
|
let image = image,
|
||||||
|
|
|
@ -21,7 +21,8 @@ extension StatusTablePrefetching {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for status in statuses {
|
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 {
|
for attachment in status.attachments where attachment.kind == .image {
|
||||||
ImageCache.attachments.fetchIfNotCached(attachment.url)
|
ImageCache.attachments.fetchIfNotCached(attachment.url)
|
||||||
}
|
}
|
||||||
|
@ -36,7 +37,8 @@ extension StatusTablePrefetching {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for status in statuses {
|
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 {
|
for attachment in status.attachments where attachment.kind == .image {
|
||||||
ImageCache.attachments.cancelWithoutCallback(attachment.url)
|
ImageCache.attachments.cancelWithoutCallback(attachment.url)
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,17 +62,18 @@ class AccountTableViewCell: UITableViewCell {
|
||||||
|
|
||||||
let accountID = self.accountID
|
let accountID = self.accountID
|
||||||
|
|
||||||
let avatarURL = account.avatar
|
if let avatarURL = account.avatar {
|
||||||
avatarRequest = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in
|
avatarRequest = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
self.avatarRequest = nil
|
self.avatarRequest = nil
|
||||||
|
|
||||||
guard let image = image,
|
guard let image = image,
|
||||||
self.accountID == accountID,
|
self.accountID == accountID,
|
||||||
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else { return }
|
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else { return }
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.avatarImageView.image = transformedImage
|
self.avatarImageView.image = transformedImage
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,11 +69,13 @@ class LargeAccountDetailView: UIView {
|
||||||
displayNameLabel.updateForAccountDisplayName(account: account)
|
displayNameLabel.updateForAccountDisplayName(account: account)
|
||||||
usernameLabel.text = "@\(account.acct)"
|
usernameLabel.text = "@\(account.acct)"
|
||||||
|
|
||||||
avatarRequest = ImageCache.avatars.get(account.avatar) { [weak self] (_, image) in
|
if let avatar = account.avatar {
|
||||||
guard let self = self, let image = image else { return }
|
avatarRequest = ImageCache.avatars.get(avatar) { [weak self] (_, image) in
|
||||||
self.avatarRequest = nil
|
guard let self = self, let image = image else { return }
|
||||||
DispatchQueue.main.async {
|
self.avatarRequest = nil
|
||||||
self.avatarImageView.image = image
|
DispatchQueue.main.async {
|
||||||
|
self.avatarImageView.image = image
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,21 +83,22 @@ class ActionNotificationGroupTableViewCell: UITableViewCell {
|
||||||
imageView.translatesAutoresizingMaskIntoConstraints = false
|
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
imageView.layer.masksToBounds = true
|
imageView.layer.masksToBounds = true
|
||||||
imageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * 30
|
imageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * 30
|
||||||
let avatarURL = account.avatar
|
if let avatarURL = account.avatar {
|
||||||
avatarRequests[account.id] = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in
|
avatarRequests[account.id] = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
guard let image = image,
|
guard let image = image,
|
||||||
self.group.id == group.id,
|
self.group.id == group.id,
|
||||||
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else {
|
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.avatarRequests.removeValue(forKey: account.id)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.avatarRequests.removeValue(forKey: account.id)
|
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)
|
actionAvatarStackView.addArrangedSubview(imageView)
|
||||||
|
@ -131,21 +132,22 @@ class ActionNotificationGroupTableViewCell: UITableViewCell {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
let avatarURL = account.avatar
|
if let avatarURL = account.avatar {
|
||||||
avatarRequests[account.id] = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in
|
avatarRequests[account.id] = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
guard let image = image,
|
guard let image = image,
|
||||||
self.group.id == groupID,
|
self.group.id == groupID,
|
||||||
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else {
|
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.avatarRequests.removeValue(forKey: account.id)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.avatarRequests.removeValue(forKey: account.id)
|
self.avatarRequests.removeValue(forKey: account.id)
|
||||||
|
imageView.image = transformedImage
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
self.avatarRequests.removeValue(forKey: account.id)
|
|
||||||
imageView.image = transformedImage
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,18 +64,19 @@ class FollowNotificationGroupTableViewCell: UITableViewCell {
|
||||||
imageView.translatesAutoresizingMaskIntoConstraints = false
|
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
imageView.layer.masksToBounds = true
|
imageView.layer.masksToBounds = true
|
||||||
imageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * 30
|
imageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * 30
|
||||||
let avatarURL = account.avatar
|
if let avatarURL = account.avatar {
|
||||||
avatarRequests[account.id] = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in
|
avatarRequests[account.id] = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in
|
||||||
guard let self = self,
|
guard let self = self,
|
||||||
let image = image,
|
let image = image,
|
||||||
self.group.id == group.id,
|
self.group.id == group.id,
|
||||||
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else {
|
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.avatarRequests.removeValue(forKey: account.id)
|
self.avatarRequests.removeValue(forKey: account.id)
|
||||||
imageView.image = transformedImage
|
imageView.image = transformedImage
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
avatarStackView.addArrangedSubview(imageView)
|
avatarStackView.addArrangedSubview(imageView)
|
||||||
|
@ -98,21 +99,22 @@ class FollowNotificationGroupTableViewCell: UITableViewCell {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
let avatarURL = account.avatar
|
if let avatarURL = account.avatar {
|
||||||
avatarRequests[account.id] = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in
|
avatarRequests[account.id] = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
guard let image = image,
|
guard let image = image,
|
||||||
self.group.id == groupID,
|
self.group.id == groupID,
|
||||||
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else {
|
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.avatarRequests.removeValue(forKey: account.id)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.avatarRequests.removeValue(forKey: account.id)
|
self.avatarRequests.removeValue(forKey: account.id)
|
||||||
|
imageView.image = transformedImage
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
self.avatarRequests.removeValue(forKey: account.id)
|
|
||||||
imageView.image = transformedImage
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,19 +67,21 @@ class FollowRequestNotificationTableViewCell: UITableViewCell {
|
||||||
actionLabel.text = "Request to follow from \(account.displayName)"
|
actionLabel.text = "Request to follow from \(account.displayName)"
|
||||||
actionLabel.setEmojis(account.emojis, identifier: account.id)
|
actionLabel.setEmojis(account.emojis, identifier: account.id)
|
||||||
}
|
}
|
||||||
let avatarURL = account.avatar
|
|
||||||
avatarRequest = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in
|
if let avatarURL = account.avatar {
|
||||||
guard let self = self else { return }
|
avatarRequest = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in
|
||||||
self.avatarRequest = nil
|
guard let self = self else { return }
|
||||||
|
self.avatarRequest = nil
|
||||||
guard self.account == account,
|
|
||||||
let image = image,
|
guard self.account == account,
|
||||||
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else {
|
let image = image,
|
||||||
return
|
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else {
|
||||||
}
|
return
|
||||||
|
}
|
||||||
DispatchQueue.main.async {
|
|
||||||
self.avatarImageView.image = transformedImage
|
DispatchQueue.main.async {
|
||||||
|
self.avatarImageView.image = transformedImage
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,22 +202,23 @@ class ProfileHeaderView: UIView {
|
||||||
isGrayscale = Preferences.shared.grayscaleImages
|
isGrayscale = Preferences.shared.grayscaleImages
|
||||||
|
|
||||||
let accountID = account.id
|
let accountID = account.id
|
||||||
let avatarURL = account.avatar
|
if let avatarURL = account.avatar {
|
||||||
// always load original for avatars, because ImageCache.avatars stores them scaled-down in memory
|
// 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
|
avatarRequest = ImageCache.avatars.get(avatarURL, loadOriginal: true) { [weak self] (_, image) in
|
||||||
guard let self = self,
|
guard let self = self,
|
||||||
let image = image,
|
let image = image,
|
||||||
self.accountID == accountID,
|
self.accountID == accountID,
|
||||||
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else {
|
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self?.avatarRequest = nil
|
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 {
|
if let header = account.header {
|
||||||
|
@ -243,10 +244,11 @@ class ProfileHeaderView: UIView {
|
||||||
// MARK: Interaction
|
// MARK: Interaction
|
||||||
|
|
||||||
@objc func avatarPressed() {
|
@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
|
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() {
|
@objc func headerPressed() {
|
||||||
|
|
|
@ -251,16 +251,17 @@ class BaseStatusTableViewCell: UITableViewCell, MenuPreviewProvider {
|
||||||
func updateGrayscaleableUI(account: AccountMO, status: StatusMO) {
|
func updateGrayscaleableUI(account: AccountMO, status: StatusMO) {
|
||||||
isGrayscale = Preferences.shared.grayscaleImages
|
isGrayscale = Preferences.shared.grayscaleImages
|
||||||
|
|
||||||
let avatarURL = account.avatar
|
|
||||||
let accountID = account.id
|
let accountID = account.id
|
||||||
avatarRequest = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in
|
if let avatarURL = account.avatar {
|
||||||
guard let self = self,
|
avatarRequest = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in
|
||||||
let image = image,
|
guard let self = self,
|
||||||
self.accountID == accountID,
|
let image = image,
|
||||||
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else { return }
|
self.accountID == accountID,
|
||||||
|
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else { return }
|
||||||
DispatchQueue.main.async {
|
|
||||||
self.avatarImageView.image = transformedImage
|
DispatchQueue.main.async {
|
||||||
|
self.avatarImageView.image = transformedImage
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -269,7 +269,7 @@ struct XCBActions {
|
||||||
"followers": account.followersCount.description,
|
"followers": account.followersCount.description,
|
||||||
"following": account.followingCount.description,
|
"following": account.followingCount.description,
|
||||||
"url": account.url.absoluteString,
|
"url": account.url.absoluteString,
|
||||||
"avatarURL": account.avatar.absoluteString,
|
"avatarURL": account.avatar?.absoluteString,
|
||||||
"headerURL": account.header?.absoluteString
|
"headerURL": account.header?.absoluteString
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
@ -284,7 +284,7 @@ struct XCBActions {
|
||||||
"followers": account.followersCount.description,
|
"followers": account.followersCount.description,
|
||||||
"following": account.followingCount.description,
|
"following": account.followingCount.description,
|
||||||
"url": account.url.absoluteString,
|
"url": account.url.absoluteString,
|
||||||
"avatarURL": account.avatar.absoluteString,
|
"avatarURL": account.avatar?.absoluteString,
|
||||||
"headerURL": account.header?.absoluteString
|
"headerURL": account.header?.absoluteString
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue