Fix crash when trying to load deleted statuses for restoration

This commit is contained in:
Shadowfacts 2023-01-08 17:56:21 -04:00
parent 8fb0fb66e3
commit cce6413e2b
1 changed files with 28 additions and 8 deletions

View File

@ -334,25 +334,31 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro
return false
}
loadViewIfNeeded()
var loaded = false
await controller.restoreInitial {
await loadStatusesToRestore(position: position)
applyItemsToRestore(position: position)
let hasStatusesToRestore = await loadStatusesToRestore(position: position)
if hasStatusesToRestore {
applyItemsToRestore(position: position)
loaded = true
}
}
return true
return loaded
}
@MainActor
private func loadStatusesToRestore(position: TimelinePosition) async {
private func loadStatusesToRestore(position: TimelinePosition) async -> Bool {
let unloaded = position.statusIDs.filter({ mastodonController.persistentContainer.status(for: $0) == nil })
guard !unloaded.isEmpty else {
return
return true
}
let statuses = await withTaskGroup(of: Status?.self) { group -> [Status] in
for id in unloaded {
group.addTask { @MainActor in
if let (status, _) = try? await self.mastodonController.run(Client.getStatus(id: id)) {
group.addTask {
do {
let (status, _) = try await self.mastodonController.run(Client.getStatus(id: id))
return status
} else {
} catch {
print(error)
return nil
}
}
@ -364,6 +370,20 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro
}
}
await mastodonController.persistentContainer.addAll(statuses: statuses, in: mastodonController.persistentContainer.viewContext)
// update the timeline position in case some statuses couldn't be loaded
if let center = position.centerStatusID {
let nearestLoadedStatusToCenter = position.statusIDs[position.statusIDs.firstIndex(of: center)!...].first(where: { id in
// was already loaded or was just now loaded
!unloaded.contains(id) || statuses.contains(where: { $0.id == id })
})
position.centerStatusID = nearestLoadedStatusToCenter
}
position.statusIDs = position.statusIDs.filter { id in
!unloaded.contains(id) || statuses.contains(where: { $0.id == id })
}
return !position.statusIDs.isEmpty
}
private func applyItemsToRestore(position: TimelinePosition) {