mirror of
https://github.com/mastodon/mastodon-ios
synced 2025-04-11 22:58:02 +02:00
Refetch status on reblog or favorite
This is a temporary fix for favorites and boosts of boosted posts not displaying properly. A datamodel change in the future should make all of this logic less confusing. Fixes IOS-382
This commit is contained in:
parent
583c6a8874
commit
02a2294330
@ -28,6 +28,6 @@ extension DataSourceFacade {
|
||||
newStatus.showDespiteContentWarning = status.showDespiteContentWarning
|
||||
newStatus.showDespiteFilter = status.showDespiteFilter
|
||||
|
||||
provider.update(status: newStatus, intent: .bookmark(updatedStatus.bookmarked == true))
|
||||
provider.update(contentStatus: newStatus, intent: .bookmark(updatedStatus.bookmarked == true))
|
||||
}
|
||||
}
|
||||
|
@ -14,19 +14,23 @@ extension DataSourceFacade {
|
||||
@MainActor
|
||||
public static func responseToStatusFavoriteAction(
|
||||
provider: DataSourceProvider & AuthContextProvider,
|
||||
status: MastodonStatus
|
||||
wrappingStatus: MastodonStatus,
|
||||
contentStatus: MastodonStatus
|
||||
) async throws {
|
||||
FeedbackGenerator.shared.generate(.selectionChanged)
|
||||
|
||||
let updatedStatus = try await APIService.shared.favorite(
|
||||
status: status,
|
||||
status: contentStatus,
|
||||
authenticationBox: provider.authenticationBox
|
||||
).value
|
||||
|
||||
let newStatus: MastodonStatus = .fromEntity(updatedStatus)
|
||||
newStatus.showDespiteContentWarning = status.showDespiteContentWarning
|
||||
newStatus.showDespiteFilter = status.showDespiteFilter
|
||||
let showDespiteContentWarning = wrappingStatus.showDespiteContentWarning
|
||||
let showDespiteFilter = wrappingStatus.showDespiteFilter
|
||||
|
||||
provider.update(status: newStatus, intent: .favorite(updatedStatus.favourited == true))
|
||||
let newStatus: MastodonStatus = .fromEntity(updatedStatus)
|
||||
newStatus.showDespiteContentWarning = showDespiteContentWarning
|
||||
newStatus.showDespiteFilter = showDespiteFilter
|
||||
|
||||
provider.update(contentStatus: newStatus, intent: .favorite(updatedStatus.favourited == true))
|
||||
}
|
||||
}
|
||||
|
@ -15,28 +15,29 @@ extension DataSourceFacade {
|
||||
@MainActor
|
||||
static func responseToStatusReblogAction(
|
||||
provider: DataSourceProvider & AuthContextProvider,
|
||||
status: MastodonStatus
|
||||
wrappingStatus: MastodonStatus,
|
||||
contentStatus: MastodonStatus
|
||||
) async throws {
|
||||
if UserDefaults.shared.askBeforeBoostingAPost {
|
||||
let alertController = UIAlertController(
|
||||
title: status.entity.reblogged == true ? L10n.Common.Alerts.BoostAPost.titleUnboost : L10n.Common.Alerts.BoostAPost.titleBoost,
|
||||
title: contentStatus.entity.reblogged == true ? L10n.Common.Alerts.BoostAPost.titleUnboost : L10n.Common.Alerts.BoostAPost.titleBoost,
|
||||
message: nil,
|
||||
preferredStyle: .alert
|
||||
)
|
||||
let cancelAction = UIAlertAction(title: L10n.Common.Alerts.BoostAPost.cancel, style: .default)
|
||||
alertController.addAction(cancelAction)
|
||||
let confirmAction = UIAlertAction(
|
||||
title: status.entity.reblogged == true ? L10n.Common.Alerts.BoostAPost.unboost : L10n.Common.Alerts.BoostAPost.boost,
|
||||
title: contentStatus.entity.reblogged == true ? L10n.Common.Alerts.BoostAPost.unboost : L10n.Common.Alerts.BoostAPost.boost,
|
||||
style: .default
|
||||
) { _ in
|
||||
Task { @MainActor in
|
||||
try? await performReblog(provider: provider, status: status)
|
||||
try? await performReblog(provider: provider, status: contentStatus)
|
||||
}
|
||||
}
|
||||
alertController.addAction(confirmAction)
|
||||
provider.present(alertController, animated: true)
|
||||
} else {
|
||||
try await performReblog(provider: provider, status: status)
|
||||
try await performReblog(provider: provider, status: contentStatus)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -49,17 +50,17 @@ private extension DataSourceFacade {
|
||||
) async throws {
|
||||
FeedbackGenerator.shared.generate(.selectionChanged)
|
||||
|
||||
let updatedStatus = try await APIService.shared.reblog(
|
||||
let updatedContentStatus = try await APIService.shared.reblog(
|
||||
status: status,
|
||||
authenticationBox: provider.authenticationBox
|
||||
).value
|
||||
|
||||
let newStatus: MastodonStatus = .fromEntity(updatedStatus)
|
||||
let newStatus: MastodonStatus = .fromEntity(updatedContentStatus)
|
||||
newStatus.reblog?.showDespiteContentWarning = status.showDespiteContentWarning
|
||||
newStatus.reblog?.showDespiteFilter = status.showDespiteFilter
|
||||
newStatus.showDespiteContentWarning = status.showDespiteContentWarning
|
||||
newStatus.showDespiteFilter = status.showDespiteFilter
|
||||
|
||||
provider.update(status: newStatus, intent: .reblog(updatedStatus.reblogged == true))
|
||||
provider.update(contentStatus: newStatus, intent: .reblog(updatedContentStatus.reblogged == true))
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ extension DataSourceFacade {
|
||||
authenticationBox: dependency.authenticationBox
|
||||
).value.asMastodonStatus
|
||||
|
||||
dependency.update(status: deletedStatus, intent: .delete)
|
||||
dependency.update(contentStatus: deletedStatus, intent: .delete)
|
||||
}
|
||||
|
||||
}
|
||||
@ -116,12 +116,14 @@ extension DataSourceFacade {
|
||||
case .reblog:
|
||||
try await DataSourceFacade.responseToStatusReblogAction(
|
||||
provider: provider,
|
||||
status: _status
|
||||
wrappingStatus: status,
|
||||
contentStatus: _status
|
||||
)
|
||||
case .like:
|
||||
try await DataSourceFacade.responseToStatusFavoriteAction(
|
||||
provider: provider,
|
||||
status: _status
|
||||
wrappingStatus: status,
|
||||
contentStatus: _status
|
||||
)
|
||||
case .share:
|
||||
try await DataSourceFacade.responseToStatusShareAction(
|
||||
@ -391,19 +393,19 @@ extension DataSourceFacade {
|
||||
alertController.addAction(cancelAction)
|
||||
dependency.present(alertController, animated: true)
|
||||
case .boostStatus(_):
|
||||
guard let status: MastodonStatus = menuContext.statusViewModel?._originalStatus?.reblog ?? menuContext.statusViewModel?._originalStatus else {
|
||||
guard let wrappingStatus = menuContext.statusViewModel?._originalStatus else {
|
||||
assertionFailure()
|
||||
return
|
||||
}
|
||||
|
||||
try await responseToStatusReblogAction(provider: dependency, status: status)
|
||||
let contentStatus = menuContext.statusViewModel?._originalStatus?.reblog ?? wrappingStatus
|
||||
try await responseToStatusReblogAction(provider: dependency, wrappingStatus: wrappingStatus, contentStatus: contentStatus)
|
||||
case .favoriteStatus(_):
|
||||
guard let status: MastodonStatus = menuContext.statusViewModel?._originalStatus?.reblog ?? menuContext.statusViewModel?._originalStatus else {
|
||||
guard let wrappingStatus: MastodonStatus = menuContext.statusViewModel?._originalStatus else {
|
||||
assertionFailure()
|
||||
return
|
||||
}
|
||||
|
||||
try await responseToStatusFavoriteAction(provider: dependency, status: status)
|
||||
let contentStatus = menuContext.statusViewModel?._originalStatus?.reblog ?? wrappingStatus
|
||||
try await responseToStatusFavoriteAction(provider: dependency, wrappingStatus: wrappingStatus, contentStatus: contentStatus)
|
||||
case .copyStatusLink:
|
||||
guard let status: MastodonStatus = menuContext.statusViewModel?._originalStatus?.reblog ?? menuContext.statusViewModel?._originalStatus else {
|
||||
assertionFailure()
|
||||
|
@ -585,7 +585,7 @@ extension NotificationTableViewCellDelegate where Self: DataSourceProvider & Aut
|
||||
let newStatus: MastodonStatus = .fromEntity(entity)
|
||||
newStatus.poll = MastodonPoll(poll: newPoll, status: newStatus)
|
||||
|
||||
self.update(status: newStatus, intent: .pollVote)
|
||||
self.update(contentStatus: newStatus, intent: .pollVote)
|
||||
} catch {
|
||||
notificationView.statusView.viewModel.isVoting = false
|
||||
}
|
||||
|
@ -320,7 +320,7 @@ extension StatusTableViewCellDelegate where Self: DataSourceProvider & AuthConte
|
||||
let newStatus: MastodonStatus = .fromEntity(entity)
|
||||
newStatus.poll = MastodonPoll(poll: newPoll, status: newStatus)
|
||||
|
||||
self.update(status: newStatus, intent: .pollVote)
|
||||
self.update(contentStatus: newStatus, intent: .pollVote)
|
||||
} catch {
|
||||
let alert = UIAlertController(title: "Poll Error", message: "Something went wrong while processing your response: \(error)", preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: "OK", style: .cancel))
|
||||
|
@ -139,11 +139,12 @@ extension StatusTableViewControllerNavigateableCore where Self: DataSourceProvid
|
||||
@MainActor
|
||||
private func toggleReblog() async {
|
||||
guard let status = await statusRecord() else { return }
|
||||
|
||||
let contentStatus = status.reblog ?? status
|
||||
do {
|
||||
try await DataSourceFacade.responseToStatusReblogAction(
|
||||
provider: self,
|
||||
status: status
|
||||
wrappingStatus: status,
|
||||
contentStatus: contentStatus
|
||||
)
|
||||
} catch {
|
||||
assertionFailure()
|
||||
@ -153,11 +154,12 @@ extension StatusTableViewControllerNavigateableCore where Self: DataSourceProvid
|
||||
@MainActor
|
||||
private func toggleFavorite() async {
|
||||
guard let status = await statusRecord() else { return }
|
||||
|
||||
let contentStatus = status.reblog ?? status
|
||||
do {
|
||||
try await DataSourceFacade.responseToStatusFavoriteAction(
|
||||
provider: self,
|
||||
status: status
|
||||
wrappingStatus: status,
|
||||
contentStatus: contentStatus
|
||||
)
|
||||
} catch {
|
||||
assertionFailure()
|
||||
|
@ -38,7 +38,7 @@ extension DataSourceItem {
|
||||
|
||||
protocol DataSourceProvider: UIViewController {
|
||||
func item(from source: DataSourceItem.Source) async -> DataSourceItem?
|
||||
func update(status: MastodonStatus, intent: MastodonStatus.UpdateIntent)
|
||||
func update(contentStatus: MastodonStatus, intent: MastodonStatus.UpdateIntent)
|
||||
|
||||
var filterContext: Mastodon.Entity.FilterContext? { get }
|
||||
func didToggleContentWarningDisplayStatus(status: MastodonStatus)
|
||||
|
@ -36,8 +36,8 @@ extension DiscoveryPostsViewController: DataSourceProvider {
|
||||
}
|
||||
}
|
||||
|
||||
func update(status: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
viewModel.dataController.update(status: status, intent: intent)
|
||||
func update(contentStatus: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
viewModel.dataController.update(status: contentStatus, intent: intent)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
|
@ -36,8 +36,8 @@ extension HashtagTimelineViewController: DataSourceProvider {
|
||||
}
|
||||
}
|
||||
|
||||
func update(status: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
viewModel.dataController.update(status: status, intent: intent)
|
||||
func update(contentStatus: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
viewModel.dataController.update(status: contentStatus, intent: intent)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
|
@ -39,8 +39,8 @@ extension HomeTimelineViewController: DataSourceProvider {
|
||||
}
|
||||
}
|
||||
|
||||
func update(status: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
viewModel?.dataController.update(status: status, intent: intent)
|
||||
func update(contentStatus: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
viewModel?.dataController.update(status: contentStatus, intent: intent)
|
||||
}
|
||||
|
||||
private func indexPath(for cell: UITableViewCell) -> IndexPath? {
|
||||
|
@ -67,9 +67,9 @@ extension NotificationTimelineViewController: DataSourceProvider {
|
||||
}
|
||||
}
|
||||
|
||||
func update(status: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
MastodonFeedItemCacheManager.shared.addToCache(status.entity)
|
||||
if let reblog = status.entity.reblog {
|
||||
func update(contentStatus: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
MastodonFeedItemCacheManager.shared.addToCache(contentStatus.entity)
|
||||
if let reblog = contentStatus.entity.reblog {
|
||||
MastodonFeedItemCacheManager.shared.addToCache(reblog)
|
||||
}
|
||||
viewModel.reloadData()
|
||||
|
@ -36,8 +36,8 @@ extension BookmarkViewController: DataSourceProvider {
|
||||
}
|
||||
}
|
||||
|
||||
func update(status: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
viewModel.dataController.update(status: status, intent: intent)
|
||||
func update(contentStatus: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
viewModel.dataController.update(status: contentStatus, intent: intent)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
|
@ -106,7 +106,7 @@ extension FamiliarFollowersViewController: DataSourceProvider {
|
||||
}
|
||||
}
|
||||
|
||||
func update(status: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
func update(contentStatus: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
assertionFailure("Not required")
|
||||
}
|
||||
|
||||
|
@ -36,8 +36,8 @@ extension FavoriteViewController: DataSourceProvider {
|
||||
}
|
||||
}
|
||||
|
||||
func update(status: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
viewModel.dataController.update(status: status, intent: intent)
|
||||
func update(contentStatus: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
viewModel.dataController.update(status: contentStatus, intent: intent)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
|
@ -148,7 +148,7 @@ extension FollowerListViewController: DataSourceProvider {
|
||||
}
|
||||
}
|
||||
|
||||
func update(status: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
func update(contentStatus: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
assertionFailure("Not required")
|
||||
}
|
||||
|
||||
|
@ -153,7 +153,7 @@ extension FollowingListViewController: DataSourceProvider {
|
||||
}
|
||||
}
|
||||
|
||||
func update(status: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
func update(contentStatus: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
assertionFailure("Not required")
|
||||
}
|
||||
|
||||
|
@ -1030,15 +1030,15 @@ extension ProfileViewController: DataSourceProvider {
|
||||
profilePagingViewController?.reloadTables()
|
||||
}
|
||||
|
||||
func update(status: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
updateViewModelsWithDataControllers(status: status, intent: intent)
|
||||
func update(contentStatus: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
updateViewModelsWithDataControllers(status: contentStatus, intent: intent)
|
||||
}
|
||||
|
||||
func updateViewModelsWithDataControllers(status: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
|
||||
profilePagingViewController?.viewModel?.postUserTimelineViewController.update(status: status, intent: intent)
|
||||
profilePagingViewController?.viewModel?.repliesUserTimelineViewController.update(status: status, intent: intent)
|
||||
profilePagingViewController?.viewModel?.mediaUserTimelineViewController.update(status: status, intent: intent)
|
||||
profilePagingViewController?.viewModel?.postUserTimelineViewController.update(contentStatus: status, intent: intent)
|
||||
profilePagingViewController?.viewModel?.repliesUserTimelineViewController.update(contentStatus: status, intent: intent)
|
||||
profilePagingViewController?.viewModel?.mediaUserTimelineViewController.update(contentStatus: status, intent: intent)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,8 +36,8 @@ extension UserTimelineViewController: DataSourceProvider {
|
||||
}
|
||||
}
|
||||
|
||||
func update(status: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
viewModel.dataController.update(status: status, intent: intent)
|
||||
func update(contentStatus: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
viewModel.dataController.update(status: contentStatus, intent: intent)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
|
@ -36,7 +36,7 @@ extension FavoritedByViewController: DataSourceProvider {
|
||||
}
|
||||
}
|
||||
|
||||
func update(status: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
func update(contentStatus: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
assertionFailure("Not required")
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ extension RebloggedByViewController: DataSourceProvider {
|
||||
}
|
||||
}
|
||||
|
||||
func update(status: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
func update(contentStatus: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
assertionFailure("Not required")
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ extension SearchHistoryViewController: DataSourceProvider {
|
||||
}
|
||||
}
|
||||
|
||||
func update(status: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
func update(contentStatus: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
assertionFailure("Not required")
|
||||
}
|
||||
|
||||
|
@ -41,8 +41,8 @@ extension SearchResultViewController: DataSourceProvider {
|
||||
}
|
||||
}
|
||||
|
||||
func update(status: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
viewModel.dataController.update(status: status, intent: intent)
|
||||
func update(contentStatus: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
viewModel.dataController.update(status: contentStatus, intent: intent)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
|
@ -37,7 +37,7 @@ extension ThreadViewController: DataSourceProvider {
|
||||
}
|
||||
}
|
||||
|
||||
func update(status _status: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
func update(contentStatus _status: MastodonStatus, intent: MastodonStatus.UpdateIntent) {
|
||||
let status = _status.reblog ?? _status
|
||||
if case MastodonStatus.UpdateIntent.delete = intent {
|
||||
return handleDelete(status)
|
||||
|
@ -197,13 +197,13 @@ extension ThreadViewController: StatusTableViewControllerNavigateable {
|
||||
extension UINavigationController {
|
||||
func notifyChildrenAboutStatusDeletion(_ status: MastodonStatus) {
|
||||
viewControllers.compactMap { $0 as? DataSourceProvider }.forEach { provider in
|
||||
provider?.update(status: status, intent: .delete)
|
||||
provider?.update(contentStatus: status, intent: .delete)
|
||||
}
|
||||
}
|
||||
|
||||
func notifyChildrenAboutStatusEdit(_ status: MastodonStatus) {
|
||||
viewControllers.compactMap { $0 as? DataSourceProvider }.forEach { provider in
|
||||
provider?.update(status: status, intent: .edit)
|
||||
provider?.update(contentStatus: status, intent: .edit)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -119,93 +119,127 @@ final public class FeedDataController {
|
||||
@MainActor
|
||||
private func updateBookmarked(_ status: MastodonStatus, _ isBookmarked: Bool) {
|
||||
var newRecords = Array(records)
|
||||
guard let index = newRecords.firstIndex(where: { $0.id == status.id }) else {
|
||||
logger.warning("\(Self.entryNotFoundMessage)")
|
||||
return
|
||||
|
||||
let relevant = recordsContaining(statusID: status.id)
|
||||
Task {
|
||||
let refetched = await refetchStatuses(relevant)
|
||||
|
||||
for record in refetched {
|
||||
if let idx = newRecords.firstIndex(where: { $0.id == record.id }) {
|
||||
let existingRecord = newRecords[idx]
|
||||
newRecords[idx] = .fromStatus(MastodonStatus(entity: record, showDespiteContentWarning: existingRecord.status?.showDespiteContentWarning ?? false), kind: existingRecord.kind)
|
||||
} else {
|
||||
logger.warning("\(Self.entryNotFoundMessage)")
|
||||
return
|
||||
}
|
||||
}
|
||||
records = newRecords
|
||||
}
|
||||
let existingRecord = newRecords[index]
|
||||
let newStatus = status.inheritSensitivityToggled(from: existingRecord.status)
|
||||
newRecords[index] = .fromStatus(newStatus, kind: existingRecord.kind)
|
||||
records = newRecords
|
||||
}
|
||||
|
||||
@MainActor
|
||||
private func updateFavorited(_ status: MastodonStatus, _ isFavorited: Bool) {
|
||||
var newRecords = Array(records)
|
||||
if let index = newRecords.firstIndex(where: { $0.id == status.id }) {
|
||||
// Replace old status entity
|
||||
let existingRecord = newRecords[index]
|
||||
let newStatus = status.inheritSensitivityToggled(from: existingRecord.status).withOriginal(status: existingRecord.status?.originalStatus)
|
||||
newRecords[index] = .fromStatus(newStatus, kind: existingRecord.kind)
|
||||
} else if let index = newRecords.firstIndex(where: { $0.status?.reblog?.id == status.id }) {
|
||||
// Replace reblogged entity of old "parent" status
|
||||
let newStatus: MastodonStatus
|
||||
if let existingEntity = newRecords[index].status?.entity {
|
||||
newStatus = .fromEntity(existingEntity)
|
||||
newStatus.originalStatus = newRecords[index].status?.originalStatus
|
||||
newStatus.reblog = status
|
||||
} else {
|
||||
newStatus = status
|
||||
let relevant = recordsContaining(statusID: status.id)
|
||||
Task {
|
||||
let refetched = await refetchStatuses(relevant)
|
||||
|
||||
for record in refetched {
|
||||
if let idx = newRecords.firstIndex(where: { $0.id == record.id }) {
|
||||
let existingRecord = newRecords[idx]
|
||||
newRecords[idx] = .fromStatus(MastodonStatus(entity: record, showDespiteContentWarning: existingRecord.status?.showDespiteContentWarning ?? false), kind: existingRecord.kind)
|
||||
} else {
|
||||
logger.warning("\(Self.entryNotFoundMessage)")
|
||||
return
|
||||
}
|
||||
}
|
||||
newRecords[index] = .fromStatus(newStatus, kind: newRecords[index].kind)
|
||||
} else {
|
||||
logger.warning("\(Self.entryNotFoundMessage)")
|
||||
records = newRecords
|
||||
}
|
||||
records = newRecords
|
||||
}
|
||||
|
||||
@MainActor
|
||||
private func updateReblogged(_ status: MastodonStatus, _ isReblogged: Bool) {
|
||||
var newRecords = Array(records)
|
||||
|
||||
switch isReblogged {
|
||||
case true:
|
||||
let index: Int
|
||||
if let idx = newRecords.firstIndex(where: { $0.status?.reblog?.id == status.reblog?.id }) {
|
||||
index = idx
|
||||
} else if let idx = newRecords.firstIndex(where: { $0.id == status.reblog?.id }) {
|
||||
index = idx
|
||||
} else {
|
||||
logger.warning("\(Self.entryNotFoundMessage)")
|
||||
return
|
||||
let relevantID = isReblogged ? (status.reblog?.id ?? status.id) : status.id
|
||||
let relevant = recordsContaining(statusID: relevantID)
|
||||
Task {
|
||||
let refetched = await refetchStatuses(relevant)
|
||||
// print("found \(refetched.count) relevant statuses for \(status.id)")
|
||||
|
||||
for record in refetched {
|
||||
if let idx = newRecords.firstIndex(where: { $0.id == record.id }) {
|
||||
let existingRecord = newRecords[idx]
|
||||
// print("replacing record for \(existingRecord.status?.id) (reblog of \(existingRecord.status?.reblog))...")
|
||||
if existingRecord.status?.entity.reblogged == true || existingRecord.status?.reblog?.entity.reblogged == true {
|
||||
// print("- was reblogged by me")
|
||||
} else {
|
||||
// print("- NOT reblogged by me")
|
||||
}
|
||||
let newRecord = MastodonFeed.fromStatus(MastodonStatus(entity: record, showDespiteContentWarning: existingRecord.status?.showDespiteContentWarning ?? false), kind: existingRecord.kind)
|
||||
newRecords[idx] = newRecord
|
||||
// print("replaced with \(newRecord.status?.id) (reblog of \(newRecord.status?.reblog?.id))")
|
||||
if newRecord.status?.entity.reblogged == true || newRecord.status?.reblog?.entity.reblogged == true {
|
||||
// print("- was reblogged by me")
|
||||
} else {
|
||||
// print("- NOT reblogged by me")
|
||||
}
|
||||
} else {
|
||||
logger.warning("\(Self.entryNotFoundMessage)")
|
||||
return
|
||||
}
|
||||
}
|
||||
let existingRecord = newRecords[index]
|
||||
newRecords[index] = .fromStatus(status.withOriginal(status: existingRecord.status), kind: existingRecord.kind)
|
||||
case false:
|
||||
let index: Int
|
||||
if let idx = newRecords.firstIndex(where: { $0.status?.reblog?.id == status.id }) {
|
||||
index = idx
|
||||
} else if let idx = newRecords.firstIndex(where: { $0.status?.id == status.id }) {
|
||||
index = idx
|
||||
} else {
|
||||
logger.warning("\(Self.entryNotFoundMessage)")
|
||||
return
|
||||
records = newRecords
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
private func updateSensitive(_ status: MastodonStatus, _ isVisible: Bool) {
|
||||
let toUpdate = recordsContaining(statusID: status.id)
|
||||
var newRecords = Array(records)
|
||||
for record in toUpdate {
|
||||
if let index = newRecords.firstIndex(where: { $0.status?.id == record.id }), let existingEntity = newRecords[index].status?.entity {
|
||||
if existingEntity.id == status.id {
|
||||
let existingRecord = newRecords[index]
|
||||
let newStatus: MastodonStatus = .fromEntity(existingEntity)
|
||||
newStatus.reblog = status
|
||||
newRecords[index] = .fromStatus(newStatus, kind: existingRecord.kind)
|
||||
} else if existingEntity.reblog?.id == status.id {
|
||||
let existingRecord = newRecords[index]
|
||||
let newStatus: MastodonStatus = .fromEntity(existingEntity)
|
||||
.inheritSensitivityToggled(from: status)
|
||||
newRecords[index] = .fromStatus(newStatus, kind: existingRecord.kind)
|
||||
} else {
|
||||
logger.warning("\(Self.entryNotFoundMessage)")
|
||||
return
|
||||
}
|
||||
}
|
||||
let existingRecord = newRecords[index]
|
||||
let newStatus = existingRecord.status?.originalStatus ?? status.inheritSensitivityToggled(from: existingRecord.status)
|
||||
newRecords[index] = .fromStatus(newStatus, kind: existingRecord.kind)
|
||||
}
|
||||
records = newRecords
|
||||
}
|
||||
|
||||
@MainActor
|
||||
private func updateSensitive(_ status: MastodonStatus, _ isVisible: Bool) {
|
||||
var newRecords = Array(records)
|
||||
if let index = newRecords.firstIndex(where: { $0.status?.reblog?.id == status.id }), let existingEntity = newRecords[index].status?.entity {
|
||||
let existingRecord = newRecords[index]
|
||||
let newStatus: MastodonStatus = .fromEntity(existingEntity)
|
||||
newStatus.reblog = status
|
||||
newRecords[index] = .fromStatus(newStatus, kind: existingRecord.kind)
|
||||
} else if let index = newRecords.firstIndex(where: { $0.id == status.id }), let existingEntity = newRecords[index].status?.entity {
|
||||
let existingRecord = newRecords[index]
|
||||
let newStatus: MastodonStatus = .fromEntity(existingEntity)
|
||||
.inheritSensitivityToggled(from: status)
|
||||
newRecords[index] = .fromStatus(newStatus, kind: existingRecord.kind)
|
||||
} else {
|
||||
logger.warning("\(Self.entryNotFoundMessage)")
|
||||
return
|
||||
private func recordsContaining(statusID: Mastodon.Entity.Status.ID) -> [MastodonFeed] {
|
||||
records.filter { feed in
|
||||
return feed.status?.id == statusID || feed.status?.reblog?.id == statusID
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
private func refetchStatuses(_ items: [MastodonFeed]) async -> [Mastodon.Entity.Status] {
|
||||
|
||||
switch kind {
|
||||
case .notificationAll, .notificationMentions, .notificationAccount:
|
||||
return []
|
||||
default:
|
||||
var refetched = [Mastodon.Entity.Status]()
|
||||
for item in items {
|
||||
if let refetchedItem = try? await APIService.shared.status(statusID: item.id, authenticationBox: authenticationBox) {
|
||||
refetched.append(refetchedItem.value)
|
||||
} else {
|
||||
}
|
||||
}
|
||||
return refetched
|
||||
}
|
||||
records = newRecords
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user