forked from shadowfacts/Tusker
Fix profile header image not showing up on first load
The issue occurred because the profile header would kick off a request upon loading, then the profile table would request the initial set of statuses shortly thereafter which would result in reloadData being called which would cancel the request without removing the group, so the request generated by the newly-reloaded header cell would attach a callback to the cancelled request, resulting in the header image never displaying.
This commit is contained in:
parent
36326e4469
commit
d27bddb2ca
|
@ -18,7 +18,7 @@ class ImageCache {
|
|||
|
||||
let cache: Cache<Data>
|
||||
|
||||
var requests = [URL: RequestGroup]()
|
||||
private var groups = [URL: RequestGroup]()
|
||||
|
||||
init(name: String, memoryExpiry expiry: Expiry) {
|
||||
let storage = MemoryStorage<Data>(config: MemoryConfig(expiry: expiry))
|
||||
|
@ -43,14 +43,18 @@ class ImageCache {
|
|||
completion?(data)
|
||||
return nil
|
||||
} else {
|
||||
if let completion = completion, let group = requests[url] {
|
||||
if let completion = completion, let group = groups[url] {
|
||||
return group.addCallback(completion)
|
||||
} else {
|
||||
let group = RequestGroup(url: url)
|
||||
let request = group.addCallback(completion)
|
||||
group.run { (data) in
|
||||
try? self.cache.setObject(data, forKey: key)
|
||||
let group = RequestGroup(url: url) { (data) in
|
||||
if let data = data {
|
||||
try? self.cache.setObject(data, forKey: key)
|
||||
}
|
||||
self.groups.removeValue(forKey: url)
|
||||
}
|
||||
groups[url] = group
|
||||
let request = group.addCallback(completion)
|
||||
group.run()
|
||||
return request
|
||||
}
|
||||
}
|
||||
|
@ -61,29 +65,30 @@ class ImageCache {
|
|||
}
|
||||
|
||||
func cancelWithoutCallback(_ url: URL) {
|
||||
requests[url]?.cancelWithoutCallback()
|
||||
groups[url]?.cancelWithoutCallback()
|
||||
}
|
||||
|
||||
class RequestGroup {
|
||||
private class RequestGroup {
|
||||
let url: URL
|
||||
private let onFinished: (Data?) -> Void
|
||||
private var task: URLSessionDataTask?
|
||||
private var requests = [Request]()
|
||||
|
||||
init(url: URL) {
|
||||
init(url: URL, onFinished: @escaping (Data?) -> Void) {
|
||||
self.url = url
|
||||
self.onFinished = onFinished
|
||||
}
|
||||
|
||||
deinit {
|
||||
task?.cancel()
|
||||
}
|
||||
|
||||
func run(cache: @escaping (Data) -> Void) {
|
||||
func run() {
|
||||
task = URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in
|
||||
guard error == nil, let data = data else {
|
||||
self.complete(with: nil)
|
||||
return
|
||||
}
|
||||
cache(data)
|
||||
self.complete(with: data)
|
||||
})
|
||||
task!.resume()
|
||||
|
@ -123,11 +128,12 @@ class ImageCache {
|
|||
callback(data)
|
||||
}
|
||||
}
|
||||
self.onFinished(data)
|
||||
}
|
||||
}
|
||||
|
||||
class Request {
|
||||
weak var group: RequestGroup?
|
||||
private weak var group: RequestGroup?
|
||||
private(set) var callback: ((Data?) -> Void)?
|
||||
private(set) var cancelled: Bool = false
|
||||
|
||||
|
|
|
@ -16,20 +16,8 @@ class ProfileTableViewController: EnhancedTableViewController {
|
|||
|
||||
var accountID: String!
|
||||
|
||||
var pinnedStatuses: [(id: String, state: StatusState)] = [] {
|
||||
didSet {
|
||||
DispatchQueue.main.async {
|
||||
self.tableView.reloadData()
|
||||
}
|
||||
}
|
||||
}
|
||||
var timelineSegments: [[(id: String, state: StatusState)]] = [] {
|
||||
didSet {
|
||||
DispatchQueue.main.async {
|
||||
self.tableView.reloadData()
|
||||
}
|
||||
}
|
||||
}
|
||||
var pinnedStatuses: [(id: String, state: StatusState)] = []
|
||||
var timelineSegments: [[(id: String, state: StatusState)]] = []
|
||||
|
||||
var older: RequestRange?
|
||||
var newer: RequestRange?
|
||||
|
@ -124,6 +112,12 @@ class ProfileTableViewController: EnhancedTableViewController {
|
|||
|
||||
self.mastodonController.persistentContainer.addAll(statuses: statuses) {
|
||||
self.pinnedStatuses = statuses.map { ($0.id, .unknown) }
|
||||
let indexPaths = (0..<statuses.count).map { IndexPath(row: $0, section: 1) }
|
||||
DispatchQueue.main.async {
|
||||
UIView.performWithoutAnimation {
|
||||
self.tableView.insertRows(at: indexPaths, with: .none)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,6 +129,12 @@ class ProfileTableViewController: EnhancedTableViewController {
|
|||
|
||||
self.older = pagination?.older
|
||||
self.newer = pagination?.newer
|
||||
|
||||
DispatchQueue.main.async {
|
||||
UIView.performWithoutAnimation {
|
||||
self.tableView.insertSections(IndexSet(integer: 2), with: .none)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue