Skip to content

Commit 5ed5367

Browse files
Streamline profile loading
Avoid getting stuck when hitting errors fetching accounts and relationships. Do a minimal update when fetching the relationship. Contributes to #1560
1 parent 0bf1024 commit 5ed5367

3 files changed

Lines changed: 78 additions & 63 deletions

File tree

Mastodon/In Progress New Layout and Datamodel/MastodonNavigationRouter.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -233,9 +233,12 @@ enum MastodonNavigationDestination {
233233
Task {
234234
let relationshipFetchID = account.id
235235
if let authBox = AuthenticationServiceProvider.shared.currentActiveUser.value {
236-
Task {
237-
guard let relationship = try await APIService.shared.relationship(forAccountIds: [relationshipFetchID], authenticationBox: authBox).value.first else { return }
238-
viewModel.set(account: account, relationship: .isNotMe(MastodonAccount.RelationshipInfo(relationship, fetchedAt: .now)), navigator: self)
236+
do {
237+
let relationship = try await APIService.shared.relationship(forAccountIds: [relationshipFetchID], authenticationBox: authBox).value.first
238+
guard let relationship else { return }
239+
viewModel.updateRelationship(.isNotMe(MastodonAccount.RelationshipInfo(relationship, fetchedAt: .now)))
240+
} catch {
241+
didReceiveError(error)
239242
}
240243
}
241244
}

Mastodon/In Progress New Layout and Datamodel/Profile/ProfileView.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1197,7 +1197,7 @@ extension ProfileViewModel: FeedCoordinatorUpdatable {
11971197
switch update {
11981198
case .relationship(let updatedRelationship):
11991199
if let relationship = relationshipViewModel.relationship, updatedRelationship.refersToSameAccount(as: relationship) {
1200-
relationshipViewModel.prepareForDisplay(relationship: updatedRelationship, theirAccountIsLocked: account?.locked ?? false)
1200+
updateRelationship(updatedRelationship)
12011201
}
12021202
case .deletedPost, .hashtag, .post:
12031203
break
@@ -1207,6 +1207,10 @@ extension ProfileViewModel: FeedCoordinatorUpdatable {
12071207
}
12081208
}
12091209
}
1210+
1211+
func updateRelationship(_ updatedRelationship: MastodonAccount.Relationship) {
1212+
relationshipViewModel.prepareForDisplay(relationship: updatedRelationship, theirAccountIsLocked: account?.locked ?? false)
1213+
}
12101214
}
12111215

12121216
struct VerticalPositionKey: PreferenceKey {

Mastodon/In Progress New Layout and Datamodel/Timeline/TimelineListViewController.swift

Lines changed: 67 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,7 @@ enum MastodonTimelineSheet {
817817
@Observable class TimelineListViewModel {
818818

819819
private(set) var authenticatedUser: MastodonAuthenticationBox? = AuthenticationServiceProvider.shared.currentActiveUser.value
820+
private weak var navigator: MastodonNavigationRouter?
820821

821822
var unreadCount: Int = 0
822823
private(set) var waitingReplacementItems: [TimelineItem]?
@@ -1148,6 +1149,7 @@ enum MastodonTimelineSheet {
11481149
init(timeline: MastodonTimelineType, navigator: MastodonNavigationRouter, asyncRefreshViewModel: AsyncRefreshViewModel?) {
11491150
self._asyncRefreshViewModel = asyncRefreshViewModel
11501151
self._timeline = timeline
1152+
self.navigator = navigator
11511153

11521154
self.instanceConfigurationUpdateSubscription = AuthenticationServiceProvider.shared.instanceConfigurationUpdates
11531155
.receive(on: DispatchQueue.main)
@@ -1684,75 +1686,81 @@ extension TimelineListViewModel {
16841686

16851687
guard let authenticatedUser else { return }
16861688
Task {
1687-
let fetchedAccounts = try await APIService.shared.accountsInfo(userIDs: Array(_accountsToFetch), authenticationBox: authenticatedUser)
1688-
let fetchedRelationships = try await feedLoader.fetchRelationships(Array(_relationshipsToFetch))
16891689

1690-
@MainActor
1691-
func updateCollectionModel(_ collectionModel: CollectionViewModel) {
1692-
if let account = fetchedAccounts.first(where: { $0.id == collectionModel.collection.accountId }) {
1693-
collectionModel.updateAuthorAccount(MastodonAccount.fromEntity(account, authenticatedDomain: authenticatedUser.domain))
1694-
}
1695-
if let relationship = fetchedRelationships.first(where: { $0.info?.id == collectionModel.collection.accountId }) {
1696-
collectionModel.prepareForDisplay(withRelationship: relationship)
1697-
}
1698-
collectionModel.updateAvatarUrls(fetchedAccounts)
1690+
defer {
1691+
currentlyPreparingForDisplay = nil
1692+
completion?()
16991693
}
17001694

1701-
for postModel in toPrep {
1702-
if postModel.fullPost?.actionablePost?.metaData.author.id == authenticatedUser.userID {
1703-
postModel.prepareForDisplay(relationship: .isMe, theirAccountIsLocked: postModel.fullPost?.actionablePost?.metaData.author.locked ?? false)
1704-
} else {
1705-
let relationship = fetchedRelationships.first(where: {
1706-
$0.info?.id == postModel.initialDisplayInfo.actionableAuthorId
1707-
}) ?? feedLoader.myRelationship(to: postModel.initialDisplayInfo.actionableAuthorId)
1708-
1709-
postModel.prepareForDisplay(relationship: relationship, theirAccountIsLocked: postModel.fullPost?.actionablePost?.metaData.author.locked ?? false)
1710-
}
1711-
if let collectionViewModel = postModel.collectionViewModel {
1712-
updateCollectionModel(collectionViewModel)
1695+
do {
1696+
let fetchedAccounts = try await APIService.shared.accountsInfo(userIDs: Array(_accountsToFetch), authenticationBox: authenticatedUser)
1697+
let fetchedRelationships = try await feedLoader.fetchRelationships(Array(_relationshipsToFetch))
1698+
1699+
@MainActor
1700+
func updateCollectionModel(_ collectionModel: CollectionViewModel) {
1701+
if let account = fetchedAccounts.first(where: { $0.id == collectionModel.collection.accountId }) {
1702+
collectionModel.updateAuthorAccount(MastodonAccount.fromEntity(account, authenticatedDomain: authenticatedUser.domain))
1703+
}
1704+
if let relationship = fetchedRelationships.first(where: { $0.info?.id == collectionModel.collection.accountId }) {
1705+
collectionModel.prepareForDisplay(withRelationship: relationship)
1706+
}
1707+
collectionModel.updateAvatarUrls(fetchedAccounts)
17131708
}
1714-
postModel.displayPrepStatus = .donePreparing
1715-
}
1716-
1717-
for item in batch {
1718-
switch item {
1719-
case .notification(let notificationViewModel):
1720-
let accountRelatingTo = notificationViewModel.needsRelationshipTo
1721-
if let relationship = fetchedRelationships.first(where: { fetched in
1722-
guard let fetchedID = fetched.info?.id else { return false }
1723-
return fetchedID == accountRelatingTo?.id
1724-
}) {
1725-
notificationViewModel.prepareForDisplay(relationship: relationship, theirAccountIsLocked: accountRelatingTo?.locked ?? false)
1709+
1710+
for postModel in toPrep {
1711+
if postModel.fullPost?.actionablePost?.metaData.author.id == authenticatedUser.userID {
1712+
postModel.prepareForDisplay(relationship: .isMe, theirAccountIsLocked: postModel.fullPost?.actionablePost?.metaData.author.locked ?? false)
1713+
} else {
1714+
let relationship = fetchedRelationships.first(where: {
1715+
$0.info?.id == postModel.initialDisplayInfo.actionableAuthorId
1716+
}) ?? feedLoader.myRelationship(to: postModel.initialDisplayInfo.actionableAuthorId)
1717+
1718+
postModel.prepareForDisplay(relationship: relationship, theirAccountIsLocked: postModel.fullPost?.actionablePost?.metaData.author.locked ?? false)
17261719
}
1727-
notificationViewModel.actionHandler = self
1728-
notificationViewModel.displayPrepStatus = .donePreparing
1729-
if let collectionModel = notificationViewModel.inlineCollectionViewModel {
1730-
updateCollectionModel(collectionModel)
1720+
if let collectionViewModel = postModel.collectionViewModel {
1721+
updateCollectionModel(collectionViewModel)
17311722
}
1732-
case .account(let accountViewModel):
1733-
if let relationship = fetchedRelationships.first(where: { $0.info?.id == accountViewModel.id }) {
1734-
if accountViewModel.actionHandler == nil {
1735-
accountViewModel.actionHandler = self
1723+
postModel.displayPrepStatus = .donePreparing
1724+
}
1725+
1726+
for item in batch {
1727+
switch item {
1728+
case .notification(let notificationViewModel):
1729+
let accountRelatingTo = notificationViewModel.needsRelationshipTo
1730+
if let relationship = fetchedRelationships.first(where: { fetched in
1731+
guard let fetchedID = fetched.info?.id else { return false }
1732+
return fetchedID == accountRelatingTo?.id
1733+
}) {
1734+
notificationViewModel.prepareForDisplay(relationship: relationship, theirAccountIsLocked: accountRelatingTo?.locked ?? false)
1735+
}
1736+
notificationViewModel.actionHandler = self
1737+
notificationViewModel.displayPrepStatus = .donePreparing
1738+
if let collectionModel = notificationViewModel.inlineCollectionViewModel {
1739+
updateCollectionModel(collectionModel)
1740+
}
1741+
case .account(let accountViewModel):
1742+
if let relationship = fetchedRelationships.first(where: { $0.info?.id == accountViewModel.id }) {
1743+
if accountViewModel.actionHandler == nil {
1744+
accountViewModel.actionHandler = self
1745+
}
1746+
accountViewModel.prepareForDisplay(withRelationship: relationship)
1747+
} else if accountViewModel.id == AuthenticationServiceProvider.shared.currentActiveUser.value?.userID {
1748+
accountViewModel.prepareForDisplay(withRelationship: .isMe)
17361749
}
1737-
accountViewModel.prepareForDisplay(withRelationship: relationship)
1738-
} else if accountViewModel.id == AuthenticationServiceProvider.shared.currentActiveUser.value?.userID {
1739-
accountViewModel.prepareForDisplay(withRelationship: .isMe)
1750+
case .post, .pinnedPosts:
1751+
// handled above
1752+
break
1753+
case .hashtag:
1754+
break
1755+
case .collection(let collectionViewModel):
1756+
updateCollectionModel(collectionViewModel)
1757+
case .heading, .filteredNotificationsInfo, .loadingIndicator, .noItem:
1758+
break
17401759
}
1741-
case .post, .pinnedPosts:
1742-
// handled above
1743-
break
1744-
case .hashtag:
1745-
break
1746-
case .collection(let collectionViewModel):
1747-
updateCollectionModel(collectionViewModel)
1748-
case .heading, .filteredNotificationsInfo, .loadingIndicator, .noItem:
1749-
break
17501760
}
1761+
} catch {
1762+
navigator?.didReceiveError(error)
17511763
}
1752-
1753-
currentlyPreparingForDisplay = nil
1754-
1755-
completion?()
17561764
}
17571765
}
17581766
}

0 commit comments

Comments
 (0)