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 Shimmer
import DesignSystem import DesignSystem
public struct AccountDetailView: View { public struct AccountDetailView: View {
@Environment(\.redactionReasons) private var reasons @Environment(\.redactionReasons) private var reasons
@EnvironmentObject private var client: Client @EnvironmentObject private var client: Client
@StateObject private var viewModel: AccountDetailViewModel @StateObject private var viewModel: AccountDetailViewModel
@ -30,8 +30,20 @@ public struct AccountDetailView: View {
} content: { } content: {
LazyVStack { LazyVStack {
headerView 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) .offset(y: -20)
} else {
Divider()
.offset(y: -20)
}
StatusesListView(fetcher: viewModel) StatusesListView(fetcher: viewModel)
} }
} }

View file

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

View file

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

View file

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

View file

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