Display favourites on current user profile

This commit is contained in:
Thomas Ricouard 2022-12-21 08:35:26 +01:00
parent 024d325291
commit f561be7d4f
5 changed files with 62 additions and 10 deletions

View File

@ -5,7 +5,7 @@ import Status
import Shimmer
import DesignSystem
public struct AccountDetailView: View {
public struct AccountDetailView: View {
@Environment(\.redactionReasons) private var reasons
@EnvironmentObject private var client: Client
@StateObject private var viewModel: AccountDetailViewModel
@ -30,8 +30,20 @@ public struct AccountDetailView: View {
} content: {
LazyVStack {
headerView
Divider()
if isCurrentUser {
Picker("", selection: $viewModel.selectedTab) {
ForEach(AccountDetailViewModel.Tab.allCases, id: \.self) { tab in
Text(tab.title).tag(tab)
}
}
.pickerStyle(.segmented)
.padding(.horizontal, DS.Constants.layoutPadding)
.offset(y: -20)
} else {
Divider()
.offset(y: -20)
}
StatusesListView(fetcher: viewModel)
}
}

View File

@ -11,12 +11,33 @@ class AccountDetailViewModel: ObservableObject, StatusesFetcher {
enum State {
case loading, data(account: Account), error(error: Error)
}
enum Tab: Int, CaseIterable {
case statuses, favourites
var title: String {
switch self {
case .statuses: return "Posts"
case .favourites: return "Favourites"
}
}
}
@Published var state: State = .loading
@Published var statusesState: StatusesState = .loading
@Published var title: String = ""
@Published var relationship: Relationshionship?
@Published var favourites: [Status] = []
@Published var selectedTab = Tab.statuses {
didSet {
switch selectedTab {
case .statuses:
statusesState = .display(statuses: statuses, nextPageState: .hasNextPage)
case .favourites:
statusesState = .display(statuses: favourites, nextPageState: .none)
}
}
}
private var account: Account?
@ -54,7 +75,13 @@ class AccountDetailViewModel: ObservableObject, StatusesFetcher {
do {
statusesState = .loading
statuses = try await client.get(endpoint: Accounts.statuses(id: accountId, sinceId: nil))
statusesState = .display(statuses: statuses, nextPageState: .hasNextPage)
favourites = try await client.get(endpoint: Accounts.favourites(sinceId: nil))
switch selectedTab {
case .statuses:
statusesState = .display(statuses: statuses, nextPageState: .hasNextPage)
case .favourites:
statusesState = .display(statuses: favourites, nextPageState: .none)
}
} catch {
statusesState = .error(error: error)
}
@ -63,11 +90,16 @@ class AccountDetailViewModel: ObservableObject, StatusesFetcher {
func fetchNextPage() async {
guard let client else { return }
do {
guard let lastId = statuses.last?.id else { return }
statusesState = .display(statuses: statuses, nextPageState: .loadingNextPage)
let newStatuses: [Status] = try await client.get(endpoint: Accounts.statuses(id: accountId, sinceId: lastId))
statuses.append(contentsOf: newStatuses)
statusesState = .display(statuses: statuses, nextPageState: .hasNextPage)
switch selectedTab {
case .statuses:
guard let lastId = statuses.last?.id else { return }
statusesState = .display(statuses: statuses, nextPageState: .loadingNextPage)
let newStatuses: [Status] = try await client.get(endpoint: Accounts.statuses(id: accountId, sinceId: lastId))
statuses.append(contentsOf: newStatuses)
statusesState = .display(statuses: statuses, nextPageState: .hasNextPage)
case .favourites:
break
}
} catch {
statusesState = .error(error: error)
}

View File

@ -2,6 +2,7 @@ import Foundation
public enum Accounts: Endpoint {
case accounts(id: String)
case favourites(sinceId: String?)
case verifyCredentials
case statuses(id: String, sinceId: String?)
case relationships(id: String)
@ -12,6 +13,8 @@ public enum Accounts: Endpoint {
switch self {
case .accounts(let id):
return "accounts/\(id)"
case .favourites:
return "favourites"
case .verifyCredentials:
return "accounts/verify_credentials"
case .statuses(let id, _):
@ -30,6 +33,9 @@ public enum Accounts: Endpoint {
case .statuses(_, let sinceId):
guard let sinceId else { return nil }
return [.init(name: "max_id", value: sinceId)]
case .favourites(let sinceId):
guard let sinceId else { return nil }
return [.init(name: "max_id", value: sinceId)]
case let .relationships(id):
return [.init(name: "id", value: id)]
default:

View File

@ -3,7 +3,7 @@ import Models
public enum StatusesState {
public enum PagingState {
case hasNextPage, loadingNextPage
case hasNextPage, loadingNextPage, none
}
case loading
case display(statuses: [Status], nextPageState: StatusesState.PagingState)

View File

@ -40,6 +40,8 @@ public struct StatusesListView<Fetcher>: View where Fetcher: StatusesFetcher {
}
case .loadingNextPage:
loadingRow
case .none:
EmptyView()
}
}
}