Account: Added filter for accounts status

This commit is contained in:
Thomas Ricouard 2023-01-01 08:22:39 +01:00
parent a06386c1da
commit a592341768
5 changed files with 58 additions and 23 deletions

View file

@ -41,19 +41,15 @@ public struct AccountDetailView: View {
featuredTagsView
.offset(y: -36)
Group {
if isCurrentUser {
Picker("", selection: $viewModel.selectedTab) {
ForEach(AccountDetailViewModel.Tab.allCases, id: \.self) { tab in
ForEach(isCurrentUser ? AccountDetailViewModel.Tab.currentAccountTabs : AccountDetailViewModel.Tab.accountTabs,
id: \.self) { tab in
Text(tab.title).tag(tab)
}
}
.pickerStyle(.segmented)
.padding(.horizontal, DS.Constants.layoutPadding)
.offset(y: -20)
} else {
Divider()
.offset(y: -20)
}
}
.id("status")

View file

@ -14,14 +14,24 @@ class AccountDetailViewModel: ObservableObject, StatusesFetcher {
case loading, data(account: Account), error(error: Error)
}
enum Tab: Int, CaseIterable {
case statuses, favourites, followedTags
enum Tab: Int {
case statuses, favourites, followedTags, postsAndReplies, media
static var currentAccountTabs: [Tab] {
[.statuses, .favourites, .followedTags]
}
static var accountTabs: [Tab] {
[.statuses, .postsAndReplies, .media]
}
var title: String {
switch self {
case .statuses: return "Posts"
case .favourites: return "Favourites"
case .followedTags: return "Followed Tags"
case .postsAndReplies: return "Posts & Replies"
case .media: return "Media"
}
}
}
@ -55,11 +65,20 @@ class AccountDetailViewModel: ObservableObject, StatusesFetcher {
@Published var familliarFollowers: [Account] = []
@Published var selectedTab = Tab.statuses {
didSet {
switch selectedTab {
case .statuses, .postsAndReplies, .media:
tabTask?.cancel()
tabTask = Task {
await fetchStatuses()
}
default:
reloadTabState()
}
}
}
private var account: Account?
private var tabTask: Task<Void, Never>?
private(set) var statuses: [Status] = []
@ -109,7 +128,12 @@ class AccountDetailViewModel: ObservableObject, StatusesFetcher {
guard let client else { return }
do {
tabState = .statuses(statusesState: .loading)
statuses = try await client.get(endpoint: Accounts.statuses(id: accountId, sinceId: nil, tag: nil))
statuses =
try await client.get(endpoint: Accounts.statuses(id: accountId,
sinceId: nil,
tag: nil,
onlyMedia: selectedTab == .media ? true : nil,
excludeReplies: selectedTab == .statuses && !isCurrentUser ? true : nil))
if isCurrentUser {
(favourites, favouritesNextPage) = try await client.getWithLink(endpoint: Accounts.favourites(sinceId: nil))
}
@ -123,10 +147,15 @@ class AccountDetailViewModel: ObservableObject, StatusesFetcher {
guard let client else { return }
do {
switch selectedTab {
case .statuses:
case .statuses, .postsAndReplies, .media:
guard let lastId = statuses.last?.id else { return }
tabState = .statuses(statusesState: .display(statuses: statuses, nextPageState: .loadingNextPage))
let newStatuses: [Status] = try await client.get(endpoint: Accounts.statuses(id: accountId, sinceId: lastId, tag: nil))
let newStatuses: [Status] =
try await client.get(endpoint: Accounts.statuses(id: accountId,
sinceId: lastId,
tag: nil,
onlyMedia: selectedTab == .media ? true : nil,
excludeReplies: selectedTab == .statuses && !isCurrentUser ? true : nil))
statuses.append(contentsOf: newStatuses)
tabState = .statuses(statusesState: .display(statuses: statuses,
nextPageState: newStatuses.count < 20 ? .none : .hasNextPage))
@ -164,7 +193,7 @@ class AccountDetailViewModel: ObservableObject, StatusesFetcher {
private func reloadTabState() {
switch selectedTab {
case .statuses:
case .statuses, .postsAndReplies, .media:
tabState = .statuses(statusesState: .display(statuses: statuses, nextPageState: statuses.count < 20 ? .none : .hasNextPage))
case .favourites:
tabState = .statuses(statusesState: .display(statuses: favourites,

View file

@ -6,7 +6,7 @@ public enum Accounts: Endpoint {
case followedTags
case featuredTags(id: String)
case verifyCredentials
case statuses(id: String, sinceId: String?, tag: String?)
case statuses(id: String, sinceId: String?, tag: String?, onlyMedia: Bool?, excludeReplies: Bool?)
case relationships(ids: [String])
case follow(id: String)
case unfollow(id: String)
@ -27,7 +27,7 @@ public enum Accounts: Endpoint {
return "accounts/\(id)/featured_tags"
case .verifyCredentials:
return "accounts/verify_credentials"
case .statuses(let id, _, _):
case .statuses(let id, _, _, _, _):
return "accounts/\(id)/statuses"
case .relationships:
return "accounts/relationships"
@ -48,7 +48,7 @@ public enum Accounts: Endpoint {
public func queryItems() -> [URLQueryItem]? {
switch self {
case .statuses(_, let sinceId, let tag):
case .statuses(_, let sinceId, let tag, let onlyMedia, let excludeReplies):
var params: [URLQueryItem] = []
if let tag {
params.append(.init(name: "tagged", value: tag))
@ -56,6 +56,12 @@ public enum Accounts: Endpoint {
if let sinceId {
params.append(.init(name: "max_id", value: sinceId))
}
if let onlyMedia {
params.append(.init(name: "only_media", value: onlyMedia ? "true" : "false"))
}
if let excludeReplies {
params.append(.init(name: "exclude_replies", value: excludeReplies ? "true" : "fals"))
}
return params
case let .relationships(ids):
return ids.map {

View file

@ -47,7 +47,7 @@ public enum TimelineFilter: Hashable, Equatable {
case .home: return Timelines.home(sinceId: sinceId, maxId: maxId, minId: minId)
case let .hashtag(tag, accountId):
if let accountId {
return Accounts.statuses(id: accountId, sinceId: nil, tag: tag)
return Accounts.statuses(id: accountId, sinceId: nil, tag: tag, onlyMedia: nil, excludeReplies: nil)
} else {
return Timelines.hashtag(tag: tag, maxId: maxId)
}

View file

@ -20,7 +20,7 @@ For contributors and myself, here is a todo list of features that could be added
- [ ] Editor: Post image alts
- [ ] Editor: Add / Edit polls
- [ ] Editor: Support video types
- [ ] Editor: Open camera
- [ ] Editor: Add photos from camera
- [X] Editor: Autocomplete for mentions / hashtags
- [ ] Better settings tab
- [ ] Edit profile
@ -30,6 +30,10 @@ For contributors and myself, here is a todo list of features that could be added
- [ ] Open remote status locally
- [ ] More context menu everywhere
- [ ] Support pinned posts
- [ ] Support IceCubesApp://any mastodon links
- [ ] Add a share sheet
- [ ] Proper iPad support
- [ ] macOS support
IceCubesApp is an open source application for accessing the decentralized social network Mastodon! It's built entirely in SwiftUI, making it fast, lightweight, and easy to use.