Fix favorited post might lose repost header (IOS-206)

This commit is contained in:
Marcus Kida 2023-12-07 15:16:13 +01:00
parent c30fb73922
commit 1754375644
No known key found for this signature in database
GPG Key ID: 19FF64E08013CA40
4 changed files with 29 additions and 126 deletions

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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)