StatusDataController: update to fresh statuses data on user profile

This commit is contained in:
Thomas Ricouard 2023-03-01 19:27:56 +01:00
parent 43a4551d9b
commit a9e935016f
4 changed files with 38 additions and 18 deletions

View file

@ -65,7 +65,9 @@ public struct AccountDetailView: View {
if viewModel.selectedTab == .statuses { if viewModel.selectedTab == .statuses {
pinnedPostsView pinnedPostsView
} }
StatusesListView(fetcher: viewModel, client: client, routerPath: routerPath) StatusesListView(fetcher: viewModel,
client: client,
routerPath: routerPath)
case .followedTags: case .followedTags:
tagsListView tagsListView
case .lists: case .lists:

View file

@ -157,6 +157,7 @@ class AccountDetailViewModel: ObservableObject, StatusesFetcher {
onlyMedia: selectedTab == .media ? true : nil, onlyMedia: selectedTab == .media ? true : nil,
excludeReplies: selectedTab == .statuses && !isCurrentUser ? true : nil, excludeReplies: selectedTab == .statuses && !isCurrentUser ? true : nil,
pinned: nil)) pinned: nil))
StatusDataControllerProvider.shared.updateDataControllers(for: statuses, client: client)
if selectedTab == .statuses { if selectedTab == .statuses {
pinned = pinned =
try await client.get(endpoint: Accounts.statuses(id: accountId, try await client.get(endpoint: Accounts.statuses(id: accountId,
@ -165,10 +166,13 @@ class AccountDetailViewModel: ObservableObject, StatusesFetcher {
onlyMedia: nil, onlyMedia: nil,
excludeReplies: nil, excludeReplies: nil,
pinned: true)) pinned: true))
StatusDataControllerProvider.shared.updateDataControllers(for: pinned, client: client)
} }
if isCurrentUser { if isCurrentUser {
(favorites, favoritesNextPage) = try await client.getWithLink(endpoint: Accounts.favorites(sinceId: nil)) (favorites, favoritesNextPage) = try await client.getWithLink(endpoint: Accounts.favorites(sinceId: nil))
(bookmarks, bookmarksNextPage) = try await client.getWithLink(endpoint: Accounts.bookmarks(sinceId: nil)) (bookmarks, bookmarksNextPage) = try await client.getWithLink(endpoint: Accounts.bookmarks(sinceId: nil))
StatusDataControllerProvider.shared.updateDataControllers(for: favorites, client: client)
StatusDataControllerProvider.shared.updateDataControllers(for: bookmarks, client: client)
} }
reloadTabState() reloadTabState()
} catch { } catch {
@ -191,6 +195,7 @@ class AccountDetailViewModel: ObservableObject, StatusesFetcher {
excludeReplies: selectedTab == .statuses && !isCurrentUser ? true : nil, excludeReplies: selectedTab == .statuses && !isCurrentUser ? true : nil,
pinned: nil)) pinned: nil))
statuses.append(contentsOf: newStatuses) statuses.append(contentsOf: newStatuses)
StatusDataControllerProvider.shared.updateDataControllers(for: newStatuses, client: client)
tabState = .statuses(statusesState: .display(statuses: statuses, tabState = .statuses(statusesState: .display(statuses: statuses,
nextPageState: newStatuses.count < 20 ? .none : .hasNextPage)) nextPageState: newStatuses.count < 20 ? .none : .hasNextPage))
case .favorites: case .favorites:
@ -198,11 +203,13 @@ class AccountDetailViewModel: ObservableObject, StatusesFetcher {
let newFavorites: [Status] let newFavorites: [Status]
(newFavorites, favoritesNextPage) = try await client.getWithLink(endpoint: Accounts.favorites(sinceId: nextPageId)) (newFavorites, favoritesNextPage) = try await client.getWithLink(endpoint: Accounts.favorites(sinceId: nextPageId))
favorites.append(contentsOf: newFavorites) favorites.append(contentsOf: newFavorites)
StatusDataControllerProvider.shared.updateDataControllers(for: newFavorites, client: client)
tabState = .statuses(statusesState: .display(statuses: favorites, nextPageState: .hasNextPage)) tabState = .statuses(statusesState: .display(statuses: favorites, nextPageState: .hasNextPage))
case .bookmarks: case .bookmarks:
guard let nextPageId = bookmarksNextPage?.maxId else { return } guard let nextPageId = bookmarksNextPage?.maxId else { return }
let newBookmarks: [Status] let newBookmarks: [Status]
(newBookmarks, bookmarksNextPage) = try await client.getWithLink(endpoint: Accounts.bookmarks(sinceId: nextPageId)) (newBookmarks, bookmarksNextPage) = try await client.getWithLink(endpoint: Accounts.bookmarks(sinceId: nextPageId))
StatusDataControllerProvider.shared.updateDataControllers(for: newBookmarks, client: client)
bookmarks.append(contentsOf: newBookmarks) bookmarks.append(contentsOf: newBookmarks)
tabState = .statuses(statusesState: .display(statuses: bookmarks, nextPageState: .hasNextPage)) tabState = .statuses(statusesState: .display(statuses: bookmarks, nextPageState: .hasNextPage))
case .followedTags, .lists: case .followedTags, .lists:

View file

@ -38,6 +38,14 @@ public final class StatusDataControllerProvider {
cache[key] = controller cache[key] = controller
return controller return controller
} }
public func updateDataControllers(for statuses: [Status], client: Client) {
for status in statuses {
let realStatus: AnyStatus = status.reblog ?? status
let controller = dataController(for: realStatus, client: client)
controller.updateFrom(status: realStatus, publishUpdate: false)
}
}
} }
@MainActor @MainActor

View file

@ -7,19 +7,22 @@ import SwiftUI
public struct StatusesListView<Fetcher>: View where Fetcher: StatusesFetcher { public struct StatusesListView<Fetcher>: View where Fetcher: StatusesFetcher {
@EnvironmentObject private var theme: Theme @EnvironmentObject private var theme: Theme
@ObservedObject private var fetcher: Fetcher @ObservedObject private var fetcher: Fetcher
private let isRemote: Bool private let isRemote: Bool
private let routerPath: RouterPath private let routerPath: RouterPath
private let client: Client private let client: Client
public init(fetcher: Fetcher, client: Client, routerPath: RouterPath, isRemote: Bool = false) { public init(fetcher: Fetcher,
client: Client,
routerPath: RouterPath,
isRemote: Bool = false) {
self.fetcher = fetcher self.fetcher = fetcher
self.isRemote = isRemote self.isRemote = isRemote
self.client = client self.client = client
self.routerPath = routerPath self.routerPath = routerPath
} }
public var body: some View { public var body: some View {
switch fetcher.statusesState { switch fetcher.statusesState {
case .loading: case .loading:
@ -35,24 +38,24 @@ public struct StatusesListView<Fetcher>: View where Fetcher: StatusesFetcher {
await fetcher.fetchNewestStatuses() await fetcher.fetchNewestStatuses()
} }
} }
.listRowBackground(theme.primaryBackgroundColor) .listRowBackground(theme.primaryBackgroundColor)
.listRowSeparator(.hidden) .listRowSeparator(.hidden)
case let .display(statuses, nextPageState): case let .display(statuses, nextPageState):
ForEach(statuses, id: \.viewId) { status in ForEach(statuses, id: \.viewId) { status in
StatusRowView(viewModel: { StatusRowViewModel(status: status, StatusRowView(viewModel: { StatusRowViewModel(status: status,
client: client, client: client,
routerPath: routerPath, routerPath: routerPath,
isRemote: isRemote) isRemote: isRemote)
}) })
.id(status.id) .id(status.id)
.onAppear { .onAppear {
fetcher.statusDidAppear(status: status) fetcher.statusDidAppear(status: status)
} }
.onDisappear { .onDisappear {
fetcher.statusDidDisappear(status: status) fetcher.statusDidDisappear(status: status)
} }
} }
switch nextPageState { switch nextPageState {
case .hasNextPage: case .hasNextPage:
@ -69,7 +72,7 @@ public struct StatusesListView<Fetcher>: View where Fetcher: StatusesFetcher {
} }
} }
} }
private var loadingRow: some View { private var loadingRow: some View {
HStack { HStack {
Spacer() Spacer()