mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-11-29 11:41:01 +00:00
Account: Added filter for accounts status
This commit is contained in:
parent
a06386c1da
commit
a592341768
5 changed files with 58 additions and 23 deletions
|
@ -41,19 +41,15 @@ public struct AccountDetailView: View {
|
||||||
featuredTagsView
|
featuredTagsView
|
||||||
.offset(y: -36)
|
.offset(y: -36)
|
||||||
Group {
|
Group {
|
||||||
if isCurrentUser {
|
Picker("", selection: $viewModel.selectedTab) {
|
||||||
Picker("", selection: $viewModel.selectedTab) {
|
ForEach(isCurrentUser ? AccountDetailViewModel.Tab.currentAccountTabs : AccountDetailViewModel.Tab.accountTabs,
|
||||||
ForEach(AccountDetailViewModel.Tab.allCases, id: \.self) { tab in
|
id: \.self) { tab in
|
||||||
Text(tab.title).tag(tab)
|
Text(tab.title).tag(tab)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.pickerStyle(.segmented)
|
|
||||||
.padding(.horizontal, DS.Constants.layoutPadding)
|
|
||||||
.offset(y: -20)
|
|
||||||
} else {
|
|
||||||
Divider()
|
|
||||||
.offset(y: -20)
|
|
||||||
}
|
}
|
||||||
|
.pickerStyle(.segmented)
|
||||||
|
.padding(.horizontal, DS.Constants.layoutPadding)
|
||||||
|
.offset(y: -20)
|
||||||
}
|
}
|
||||||
.id("status")
|
.id("status")
|
||||||
|
|
||||||
|
|
|
@ -14,14 +14,24 @@ class AccountDetailViewModel: ObservableObject, StatusesFetcher {
|
||||||
case loading, data(account: Account), error(error: Error)
|
case loading, data(account: Account), error(error: Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Tab: Int, CaseIterable {
|
enum Tab: Int {
|
||||||
case statuses, favourites, followedTags
|
case statuses, favourites, followedTags, postsAndReplies, media
|
||||||
|
|
||||||
|
static var currentAccountTabs: [Tab] {
|
||||||
|
[.statuses, .favourites, .followedTags]
|
||||||
|
}
|
||||||
|
|
||||||
|
static var accountTabs: [Tab] {
|
||||||
|
[.statuses, .postsAndReplies, .media]
|
||||||
|
}
|
||||||
|
|
||||||
var title: String {
|
var title: String {
|
||||||
switch self {
|
switch self {
|
||||||
case .statuses: return "Posts"
|
case .statuses: return "Posts"
|
||||||
case .favourites: return "Favourites"
|
case .favourites: return "Favourites"
|
||||||
case .followedTags: return "Followed Tags"
|
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 familliarFollowers: [Account] = []
|
||||||
@Published var selectedTab = Tab.statuses {
|
@Published var selectedTab = Tab.statuses {
|
||||||
didSet {
|
didSet {
|
||||||
reloadTabState()
|
switch selectedTab {
|
||||||
|
case .statuses, .postsAndReplies, .media:
|
||||||
|
tabTask?.cancel()
|
||||||
|
tabTask = Task {
|
||||||
|
await fetchStatuses()
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
reloadTabState()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var account: Account?
|
private var account: Account?
|
||||||
|
private var tabTask: Task<Void, Never>?
|
||||||
|
|
||||||
private(set) var statuses: [Status] = []
|
private(set) var statuses: [Status] = []
|
||||||
|
|
||||||
|
@ -109,7 +128,12 @@ class AccountDetailViewModel: ObservableObject, StatusesFetcher {
|
||||||
guard let client else { return }
|
guard let client else { return }
|
||||||
do {
|
do {
|
||||||
tabState = .statuses(statusesState: .loading)
|
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 {
|
if isCurrentUser {
|
||||||
(favourites, favouritesNextPage) = try await client.getWithLink(endpoint: Accounts.favourites(sinceId: nil))
|
(favourites, favouritesNextPage) = try await client.getWithLink(endpoint: Accounts.favourites(sinceId: nil))
|
||||||
}
|
}
|
||||||
|
@ -123,10 +147,15 @@ class AccountDetailViewModel: ObservableObject, StatusesFetcher {
|
||||||
guard let client else { return }
|
guard let client else { return }
|
||||||
do {
|
do {
|
||||||
switch selectedTab {
|
switch selectedTab {
|
||||||
case .statuses:
|
case .statuses, .postsAndReplies, .media:
|
||||||
guard let lastId = statuses.last?.id else { return }
|
guard let lastId = statuses.last?.id else { return }
|
||||||
tabState = .statuses(statusesState: .display(statuses: statuses, nextPageState: .loadingNextPage))
|
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)
|
statuses.append(contentsOf: newStatuses)
|
||||||
tabState = .statuses(statusesState: .display(statuses: statuses,
|
tabState = .statuses(statusesState: .display(statuses: statuses,
|
||||||
nextPageState: newStatuses.count < 20 ? .none : .hasNextPage))
|
nextPageState: newStatuses.count < 20 ? .none : .hasNextPage))
|
||||||
|
@ -164,7 +193,7 @@ class AccountDetailViewModel: ObservableObject, StatusesFetcher {
|
||||||
|
|
||||||
private func reloadTabState() {
|
private func reloadTabState() {
|
||||||
switch selectedTab {
|
switch selectedTab {
|
||||||
case .statuses:
|
case .statuses, .postsAndReplies, .media:
|
||||||
tabState = .statuses(statusesState: .display(statuses: statuses, nextPageState: statuses.count < 20 ? .none : .hasNextPage))
|
tabState = .statuses(statusesState: .display(statuses: statuses, nextPageState: statuses.count < 20 ? .none : .hasNextPage))
|
||||||
case .favourites:
|
case .favourites:
|
||||||
tabState = .statuses(statusesState: .display(statuses: favourites,
|
tabState = .statuses(statusesState: .display(statuses: favourites,
|
||||||
|
|
|
@ -6,7 +6,7 @@ public enum Accounts: Endpoint {
|
||||||
case followedTags
|
case followedTags
|
||||||
case featuredTags(id: String)
|
case featuredTags(id: String)
|
||||||
case verifyCredentials
|
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 relationships(ids: [String])
|
||||||
case follow(id: String)
|
case follow(id: String)
|
||||||
case unfollow(id: String)
|
case unfollow(id: String)
|
||||||
|
@ -27,7 +27,7 @@ public enum Accounts: Endpoint {
|
||||||
return "accounts/\(id)/featured_tags"
|
return "accounts/\(id)/featured_tags"
|
||||||
case .verifyCredentials:
|
case .verifyCredentials:
|
||||||
return "accounts/verify_credentials"
|
return "accounts/verify_credentials"
|
||||||
case .statuses(let id, _, _):
|
case .statuses(let id, _, _, _, _):
|
||||||
return "accounts/\(id)/statuses"
|
return "accounts/\(id)/statuses"
|
||||||
case .relationships:
|
case .relationships:
|
||||||
return "accounts/relationships"
|
return "accounts/relationships"
|
||||||
|
@ -48,7 +48,7 @@ public enum Accounts: Endpoint {
|
||||||
|
|
||||||
public func queryItems() -> [URLQueryItem]? {
|
public func queryItems() -> [URLQueryItem]? {
|
||||||
switch self {
|
switch self {
|
||||||
case .statuses(_, let sinceId, let tag):
|
case .statuses(_, let sinceId, let tag, let onlyMedia, let excludeReplies):
|
||||||
var params: [URLQueryItem] = []
|
var params: [URLQueryItem] = []
|
||||||
if let tag {
|
if let tag {
|
||||||
params.append(.init(name: "tagged", value: tag))
|
params.append(.init(name: "tagged", value: tag))
|
||||||
|
@ -56,6 +56,12 @@ public enum Accounts: Endpoint {
|
||||||
if let sinceId {
|
if let sinceId {
|
||||||
params.append(.init(name: "max_id", value: 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
|
return params
|
||||||
case let .relationships(ids):
|
case let .relationships(ids):
|
||||||
return ids.map {
|
return ids.map {
|
||||||
|
|
|
@ -47,7 +47,7 @@ public enum TimelineFilter: Hashable, Equatable {
|
||||||
case .home: return Timelines.home(sinceId: sinceId, maxId: maxId, minId: minId)
|
case .home: return Timelines.home(sinceId: sinceId, maxId: maxId, minId: minId)
|
||||||
case let .hashtag(tag, accountId):
|
case let .hashtag(tag, accountId):
|
||||||
if let 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 {
|
} else {
|
||||||
return Timelines.hashtag(tag: tag, maxId: maxId)
|
return Timelines.hashtag(tag: tag, maxId: maxId)
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ For contributors and myself, here is a todo list of features that could be added
|
||||||
- [ ] Editor: Post image alts
|
- [ ] Editor: Post image alts
|
||||||
- [ ] Editor: Add / Edit polls
|
- [ ] Editor: Add / Edit polls
|
||||||
- [ ] Editor: Support video types
|
- [ ] Editor: Support video types
|
||||||
- [ ] Editor: Open camera
|
- [ ] Editor: Add photos from camera
|
||||||
- [X] Editor: Autocomplete for mentions / hashtags
|
- [X] Editor: Autocomplete for mentions / hashtags
|
||||||
- [ ] Better settings tab
|
- [ ] Better settings tab
|
||||||
- [ ] Edit profile
|
- [ ] 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
|
- [ ] Open remote status locally
|
||||||
- [ ] More context menu everywhere
|
- [ ] More context menu everywhere
|
||||||
- [ ] Support pinned posts
|
- [ ] 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.
|
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.
|
||||||
|
|
Loading…
Reference in a new issue