mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-12-23 07:36:48 +00:00
Timeline tab: Quick accounts switcher + new filter menu
This commit is contained in:
parent
975a403c49
commit
b324c87ae1
3 changed files with 73 additions and 9 deletions
|
@ -3,8 +3,11 @@ import Timeline
|
||||||
import Env
|
import Env
|
||||||
import Network
|
import Network
|
||||||
import Combine
|
import Combine
|
||||||
|
import DesignSystem
|
||||||
|
|
||||||
struct TimelineTab: View {
|
struct TimelineTab: View {
|
||||||
|
@EnvironmentObject private var appAccounts: AppAccountsManager
|
||||||
|
@EnvironmentObject private var theme: Theme
|
||||||
@EnvironmentObject private var currentAccount: CurrentAccount
|
@EnvironmentObject private var currentAccount: CurrentAccount
|
||||||
@EnvironmentObject private var client: Client
|
@EnvironmentObject private var client: Client
|
||||||
@StateObject private var routeurPath = RouterPath()
|
@StateObject private var routeurPath = RouterPath()
|
||||||
|
@ -12,6 +15,7 @@ struct TimelineTab: View {
|
||||||
@State private var timeline: TimelineFilter = .home
|
@State private var timeline: TimelineFilter = .home
|
||||||
@State private var scrollToTopSignal: Int = 0
|
@State private var scrollToTopSignal: Int = 0
|
||||||
@State private var isAddAccountSheetDisplayed = false
|
@State private var isAddAccountSheetDisplayed = false
|
||||||
|
@State private var accountsViewModel: [AppAccountViewModel] = []
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationStack(path: $routeurPath.path) {
|
NavigationStack(path: $routeurPath.path) {
|
||||||
|
@ -19,11 +23,14 @@ struct TimelineTab: View {
|
||||||
.withAppRouteur()
|
.withAppRouteur()
|
||||||
.withSheetDestinations(sheetDestinations: $routeurPath.presentedSheet)
|
.withSheetDestinations(sheetDestinations: $routeurPath.presentedSheet)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
|
ToolbarItem(placement: .principal) {
|
||||||
|
timelineFilterButton
|
||||||
|
}
|
||||||
if client.isAuth {
|
if client.isAuth {
|
||||||
statusEditorToolbarItem(routeurPath: routeurPath)
|
|
||||||
ToolbarItem(placement: .navigationBarLeading) {
|
ToolbarItem(placement: .navigationBarLeading) {
|
||||||
timelineFilterButton
|
accountButton
|
||||||
}
|
}
|
||||||
|
statusEditorToolbarItem(routeurPath: routeurPath)
|
||||||
} else {
|
} else {
|
||||||
ToolbarItem(placement: .navigationBarTrailing) {
|
ToolbarItem(placement: .navigationBarTrailing) {
|
||||||
addAccountButton
|
addAccountButton
|
||||||
|
@ -32,6 +39,9 @@ struct TimelineTab: View {
|
||||||
}
|
}
|
||||||
.id(currentAccount.account?.id)
|
.id(currentAccount.account?.id)
|
||||||
}
|
}
|
||||||
|
.sheet(isPresented: $isAddAccountSheetDisplayed) {
|
||||||
|
AddAccountView()
|
||||||
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
routeurPath.client = client
|
routeurPath.client = client
|
||||||
timeline = client.isAuth ? .home : .pub
|
timeline = client.isAuth ? .home : .pub
|
||||||
|
@ -51,7 +61,7 @@ struct TimelineTab: View {
|
||||||
|
|
||||||
private var timelineFilterButton: some View {
|
private var timelineFilterButton: some View {
|
||||||
Menu {
|
Menu {
|
||||||
ForEach(TimelineFilter.availableTimeline(), id: \.self) { timeline in
|
ForEach(TimelineFilter.availableTimeline(client: client), id: \.self) { timeline in
|
||||||
Button {
|
Button {
|
||||||
self.timeline = timeline
|
self.timeline = timeline
|
||||||
} label: {
|
} label: {
|
||||||
|
@ -59,8 +69,62 @@ struct TimelineTab: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} label: {
|
} label: {
|
||||||
Image(systemName: "line.3.horizontal.decrease.circle")
|
HStack {
|
||||||
|
Text(timeline.title())
|
||||||
|
Image(systemName: "chevron.down")
|
||||||
|
.resizable()
|
||||||
|
.aspectRatio(contentMode: .fit)
|
||||||
|
.frame(width: 12)
|
||||||
|
.offset(y: 2)
|
||||||
|
}
|
||||||
|
.font(.headline)
|
||||||
|
.foregroundColor(theme.labelColor)
|
||||||
}
|
}
|
||||||
|
.menuStyle(.button)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var accountButton: some View {
|
||||||
|
Button {
|
||||||
|
if let account = currentAccount.account {
|
||||||
|
routeurPath.navigate(to: .accountDetailWithAccount(account: account))
|
||||||
|
}
|
||||||
|
} label: {
|
||||||
|
if let avatar = currentAccount.account?.avatar {
|
||||||
|
AvatarView(url: avatar, size: .badge)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onAppear {
|
||||||
|
if accountsViewModel.isEmpty || appAccounts.availableAccounts.count != accountsViewModel.count {
|
||||||
|
accountsViewModel = []
|
||||||
|
for account in appAccounts.availableAccounts {
|
||||||
|
let viewModel: AppAccountViewModel = .init(appAccount: account)
|
||||||
|
accountsViewModel.append(viewModel)
|
||||||
|
Task {
|
||||||
|
await viewModel.fetchAccount()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.contextMenu {
|
||||||
|
ForEach(accountsViewModel, id: \.appAccount.id) { viewModel in
|
||||||
|
Button {
|
||||||
|
appAccounts.currentAccount = viewModel.appAccount
|
||||||
|
} label: {
|
||||||
|
HStack {
|
||||||
|
if viewModel.account?.id == currentAccount.account?.id {
|
||||||
|
Image(systemName: "checkmark.circle.fill")
|
||||||
|
}
|
||||||
|
Text("\(viewModel.account?.displayName ?? "")")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
isAddAccountSheetDisplayed = true
|
||||||
|
} label: {
|
||||||
|
Label("Add Account", systemImage: "person.badge.plus")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private var addAccountButton: some View {
|
private var addAccountButton: some View {
|
||||||
|
@ -69,8 +133,5 @@ struct TimelineTab: View {
|
||||||
} label: {
|
} label: {
|
||||||
Image(systemName: "person.badge.plus")
|
Image(systemName: "person.badge.plus")
|
||||||
}
|
}
|
||||||
.sheet(isPresented: $isAddAccountSheetDisplayed) {
|
|
||||||
AddAccountView()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,10 @@ public enum TimelineFilter: Hashable, Equatable {
|
||||||
hasher.combine(title())
|
hasher.combine(title())
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func availableTimeline() -> [TimelineFilter] {
|
public static func availableTimeline(client: Client) -> [TimelineFilter] {
|
||||||
|
if !client.isAuth {
|
||||||
|
return [.pub, .local]
|
||||||
|
}
|
||||||
return [.pub, .local, .home]
|
return [.pub, .local, .home]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ For contributors and myself, here is a todo list of features that could be added
|
||||||
- [X] Light theme
|
- [X] Light theme
|
||||||
- [ ] More themes
|
- [ ] More themes
|
||||||
- [ ] Honor & display server side features (filter, default visibility, etc...)
|
- [ ] Honor & display server side features (filter, default visibility, etc...)
|
||||||
- [ ] Open remote status locally
|
- [X] Open remote status locally
|
||||||
- [ ] More context menu everywhere
|
- [ ] More context menu everywhere
|
||||||
- [ ] Support pinned posts
|
- [ ] Support pinned posts
|
||||||
- [ ] Support IceCubesApp://any mastodon links
|
- [ ] Support IceCubesApp://any mastodon links
|
||||||
|
|
Loading…
Reference in a new issue