mirror of
https://github.com/metabolist/metatext.git
synced 2024-11-22 00:01:00 +00:00
Timeline selection
This commit is contained in:
parent
c8b2defbb8
commit
e5d7b0a12b
4 changed files with 101 additions and 26 deletions
|
@ -38,3 +38,6 @@
|
|||
"status.visibility.public" = "Public";
|
||||
"status.visibility.unlisted" = "Unlisted";
|
||||
"status.visibility.private" = "Private";
|
||||
"timelines.home" = "Home";
|
||||
"timelines.local" = "Local";
|
||||
"timelines.federated" = "Federated";
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
enum Timeline {
|
||||
enum Timeline: Identifiable {
|
||||
case home
|
||||
case local
|
||||
case federated
|
||||
|
|
|
@ -6,7 +6,8 @@ import Combine
|
|||
class TabNavigationViewModel: ObservableObject {
|
||||
@Published private(set) var identity: Identity
|
||||
@Published private(set) var recentIdentities = [Identity]()
|
||||
@Published private(set) var timelineViewModel: StatusListViewModel
|
||||
@Published private(set) var timeline = Timeline.home
|
||||
@Published private(set) var timelinesAndLists = TabNavigationViewModel.timelines
|
||||
@Published var presentingSecondaryNavigation = false
|
||||
@Published var alertItem: AlertItem?
|
||||
var selectedTab: Tab? = .timelines
|
||||
|
@ -17,7 +18,6 @@ class TabNavigationViewModel: ObservableObject {
|
|||
init(identityService: IdentityService) {
|
||||
self.identityService = identityService
|
||||
identity = identityService.identity
|
||||
timelineViewModel = StatusListViewModel(statusListService: identityService.service(timeline: .home))
|
||||
identityService.$identity.dropFirst().assign(to: &$identity)
|
||||
|
||||
identityService.recentIdentitiesObservation()
|
||||
|
@ -27,6 +27,37 @@ class TabNavigationViewModel: ObservableObject {
|
|||
}
|
||||
|
||||
extension TabNavigationViewModel {
|
||||
var timelineSubtitle: String {
|
||||
switch timeline {
|
||||
case .home, .list:
|
||||
return identity.handle
|
||||
case .local, .federated:
|
||||
return identity.instance?.uri ?? ""
|
||||
}
|
||||
}
|
||||
|
||||
func title(timeline: Timeline) -> String {
|
||||
switch timeline {
|
||||
case .home:
|
||||
return NSLocalizedString("timelines.home", comment: "")
|
||||
case .local:
|
||||
return NSLocalizedString("timelines.local", comment: "")
|
||||
case .federated:
|
||||
return NSLocalizedString("timelines.federated", comment: "")
|
||||
case let .list(list):
|
||||
return list.title
|
||||
}
|
||||
}
|
||||
|
||||
func systemImageName(timeline: Timeline) -> String {
|
||||
switch timeline {
|
||||
case .home: return "house"
|
||||
case .local: return "person.3"
|
||||
case .federated: return "globe"
|
||||
case .list: return "scroll"
|
||||
}
|
||||
}
|
||||
|
||||
func refreshIdentity() {
|
||||
if identityService.isAuthorized {
|
||||
identityService.verifyCredentials()
|
||||
|
@ -51,6 +82,18 @@ extension TabNavigationViewModel {
|
|||
func secondaryNavigationViewModel() -> SecondaryNavigationViewModel {
|
||||
SecondaryNavigationViewModel(identityService: identityService)
|
||||
}
|
||||
|
||||
func viewModel(timeline: Timeline) -> StatusListViewModel {
|
||||
StatusListViewModel(statusListService: identityService.service(timeline: timeline))
|
||||
}
|
||||
|
||||
func select(timeline: Timeline) {
|
||||
self.timeline = timeline
|
||||
}
|
||||
}
|
||||
|
||||
private extension TabNavigationViewModel {
|
||||
static let timelines: [Timeline] = [.home, .local, .federated]
|
||||
}
|
||||
|
||||
extension TabNavigationViewModel {
|
||||
|
|
|
@ -40,36 +40,65 @@ private extension TabNavigationView {
|
|||
func view(tab: TabNavigationViewModel.Tab) -> some View {
|
||||
switch tab {
|
||||
case .timelines:
|
||||
StatusListView(viewModel: viewModel.timelineViewModel)
|
||||
StatusListView(viewModel: viewModel.viewModel(timeline: viewModel.timeline))
|
||||
.id(viewModel.timeline.id)
|
||||
.edgesIgnoringSafeArea(.all)
|
||||
.navigationBarTitle(viewModel.identity.handle, displayMode: .inline)
|
||||
.navigationBarTitle(viewModel.title(timeline: viewModel.timeline), displayMode: .inline)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .principal) {
|
||||
VStack {
|
||||
Text(viewModel.title(timeline: viewModel.timeline))
|
||||
.font(.headline)
|
||||
Text(viewModel.timelineSubtitle)
|
||||
.font(.footnote)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationBarItems(
|
||||
leading: Button {
|
||||
viewModel.presentingSecondaryNavigation.toggle()
|
||||
leading: secondaryNavigationButton,
|
||||
trailing: Menu {
|
||||
ForEach(viewModel.timelinesAndLists) { timeline in
|
||||
Button {
|
||||
viewModel.select(timeline: timeline)
|
||||
} label: {
|
||||
Label(viewModel.title(timeline: timeline),
|
||||
systemImage: viewModel.systemImageName(timeline: timeline))
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
KFImage(viewModel.identity.image,
|
||||
options: .downsampled(dimension: 28, scaleFactor: displayScale))
|
||||
.placeholder { Image(systemName: "gear") }
|
||||
.renderingMode(.original)
|
||||
.contextMenu(ContextMenu {
|
||||
ForEach(viewModel.recentIdentities) { recentIdentity in
|
||||
Button {
|
||||
rootViewModel.newIdentitySelected(id: recentIdentity.id)
|
||||
} label: {
|
||||
Label(
|
||||
title: { Text(recentIdentity.handle) },
|
||||
icon: {
|
||||
KFImage(recentIdentity.image,
|
||||
options: .downsampled(dimension: 28, scaleFactor: displayScale))
|
||||
.renderingMode(.original)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
Image(systemName: viewModel.systemImageName(timeline: viewModel.timeline))
|
||||
})
|
||||
default: Text(tab.title)
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
var secondaryNavigationButton: some View {
|
||||
Button {
|
||||
viewModel.presentingSecondaryNavigation.toggle()
|
||||
} label: {
|
||||
KFImage(viewModel.identity.image,
|
||||
options: .downsampled(dimension: 28, scaleFactor: displayScale))
|
||||
.placeholder { Image(systemName: "gear") }
|
||||
.renderingMode(.original)
|
||||
.contextMenu(ContextMenu {
|
||||
ForEach(viewModel.recentIdentities) { recentIdentity in
|
||||
Button {
|
||||
rootViewModel.newIdentitySelected(id: recentIdentity.id)
|
||||
} label: {
|
||||
Label(
|
||||
title: { Text(recentIdentity.handle) },
|
||||
icon: {
|
||||
KFImage(recentIdentity.image,
|
||||
options: .downsampled(dimension: 28, scaleFactor: displayScale))
|
||||
.renderingMode(.original)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
|
|
Loading…
Reference in a new issue