From 1754375644016f974e56bcd688bc8ba511e47be6 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Thu, 7 Dec 2023 15:16:13 +0100 Subject: [PATCH] Fix favorited post might lose repost header (IOS-206) --- .../Service/API/APIService+Bookmark.swift | 30 +------- .../Service/API/APIService+Favorite.swift | 27 +------- .../Service/API/APIService+HomeTimeline.swift | 69 +------------------ .../Content/StatusView+Configuration.swift | 29 +++++++- 4 files changed, 29 insertions(+), 126 deletions(-) diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Bookmark.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Bookmark.swift index 75953c17f..c535135a6 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Bookmark.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Bookmark.swift @@ -72,35 +72,7 @@ extension APIService { authorization: authenticationBox.userAuthorization, query: query ).singleOutput() - - let managedObjectContext = self.backgroundManagedObjectContext - try await managedObjectContext.performChanges { - - guard - let me = authenticationBox.authentication.user(in: managedObjectContext) - else { - assertionFailure() - return - } - - for entity in response.value { - let result = Persistence.Status.createOrMerge( - in: managedObjectContext, - context: Persistence.Status.PersistContext( - domain: authenticationBox.domain, - entity: entity, - me: me, - statusCache: nil, - userCache: nil, - networkDate: response.networkDate - ) - ) - - result.status.update(bookmarked: true, by: me) - result.status.reblog?.update(bookmarked: true, by: me) - } // end for … in - } - + return response } // end func } diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Favorite.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Favorite.swift index 182ffea6f..104af8fed 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Favorite.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Favorite.swift @@ -70,32 +70,7 @@ extension APIService { authorization: authenticationBox.userAuthorization, query: query ).singleOutput() - - let managedObjectContext = self.backgroundManagedObjectContext - try await managedObjectContext.performChanges { - guard let me = authenticationBox.authentication.user(in: managedObjectContext) else { - assertionFailure() - return - } - - for entity in response.value { - let result = Persistence.Status.createOrMerge( - in: managedObjectContext, - context: Persistence.Status.PersistContext( - domain: authenticationBox.domain, - entity: entity, - me: me, - statusCache: nil, - userCache: nil, - networkDate: response.networkDate - ) - ) - - result.status.update(liked: true, by: me) - result.status.reblog?.update(liked: true, by: me) - } // end for … in - } - + return response } // end func } diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+HomeTimeline.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+HomeTimeline.swift index f806f856f..047fe1337 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+HomeTimeline.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+HomeTimeline.swift @@ -41,8 +41,6 @@ extension APIService { authorization: authorization ).singleOutput() - let managedObjectContext = self.backgroundManagedObjectContext - // FIXME: This is a dirty hack to make the performance-stuff work. // Problem is, that we don't persist the user on disk anymore. So we have to fetch // it when we need it to display on the home timeline. @@ -54,72 +52,7 @@ extension APIService { } NotificationCenter.default.post(name: .userFetched, object: nil) - - try await managedObjectContext.performChanges { - guard let me = authenticationBox.authentication.user(in: managedObjectContext) else { - assertionFailure() - return - } - - // persist status - var statuses: [Status] = [] - for entity in response.value { - let result = Persistence.Status.createOrMerge( - in: managedObjectContext, - context: Persistence.Status.PersistContext( - domain: domain, - entity: entity, - me: me, - statusCache: nil, // TODO: add cache - userCache: nil, // TODO: add cache - networkDate: response.networkDate - ) - ) - statuses.append(result.status) - } - - // locate anchor status - let anchorStatus: Status? = { - guard let maxID = maxID else { return nil } - let request = Status.sortedFetchRequest - request.predicate = Status.predicate(domain: domain, id: maxID) - request.fetchLimit = 1 - return try? managedObjectContext.fetch(request).first - }() - - // update hasMore flag for anchor status - let acct = Feed.Acct.mastodon(domain: authenticationBox.domain, userID: authenticationBox.userID) - if let anchorStatus = anchorStatus, - let feed = anchorStatus.feed(kind: .home, acct: acct) { - feed.update(hasMore: false) - } - - // persist Feed relationship - let sortedStatuses = statuses.sorted(by: { $0.createdAt < $1.createdAt }) - let oldestStatus = sortedStatuses.first - for status in sortedStatuses { - let _feed = status.feed(kind: .home, acct: acct) - if let feed = _feed { - feed.update(updatedAt: response.networkDate) - } else { - let feedProperty = Feed.Property( - acct: acct, - kind: .home, - hasMore: false, - createdAt: status.createdAt, - updatedAt: response.networkDate - ) - let feed = Feed.insert(into: managedObjectContext, property: feedProperty) - status.attach(feed: feed) - - // set hasMore on oldest status if is new feed - if status === oldestStatus { - feed.update(hasMore: true) - } - } - } - } - + return response } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift index 36bc4e398..cf3061c49 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+Configuration.swift @@ -86,12 +86,35 @@ extension StatusView { extension StatusView { private func configureHeader(status: MastodonStatus) { - if let _ = status.reblog { - let name = status.entity.account.displayName + if status.entity.reblogged == true, + let authenticationBox = viewModel.authContext?.mastodonAuthenticationBox, + let managedObjectContext = viewModel.context?.managedObjectContext { + + let user = MastodonUser.findOrFetch( + in: managedObjectContext, + matching: MastodonUser.predicate(domain: authenticationBox.domain, id: authenticationBox.userID) + ) + + let name = user?.displayNameWithFallback ?? authenticationBox.authentication.username + let emojis = user?.emojis ?? [] + + viewModel.header = { + let text = L10n.Common.Controls.Status.userReblogged(name) + let content = MastodonContent(content: text, emojis: emojis.asDictionary) + do { + let metaContent = try MastodonMetaContent.convert(document: content) + return .repost(info: .init(header: metaContent)) + } catch { + let metaContent = PlaintextMetaContent(string: name) + return .repost(info: .init(header: metaContent)) + } + }() + } else if status.reblog != nil { + let name = status.entity.account.displayNameWithFallback let emojis = status.entity.account.emojis ?? [] viewModel.header = { - let text = L10n.Common.Controls.Status.userReblogged(status.entity.account.displayNameWithFallback) + let text = L10n.Common.Controls.Status.userReblogged(name) let content = MastodonContent(content: text, emojis: emojis.asDictionary) do { let metaContent = try MastodonMetaContent.convert(document: content)