mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2025-09-03 00:23:49 +00:00
Refactor TimelineView
This commit is contained in:
parent
6ea4888ae5
commit
631707a798
5 changed files with 105 additions and 82 deletions
|
@ -0,0 +1,22 @@
|
||||||
|
import SwiftUI
|
||||||
|
import DesignSystem
|
||||||
|
|
||||||
|
struct TimelineHeaderView<Content: View>: View {
|
||||||
|
@Environment(Theme.self) private var theme
|
||||||
|
|
||||||
|
var content: () -> Content
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack(alignment: .leading) {
|
||||||
|
Spacer()
|
||||||
|
content()
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.listRowBackground(theme.secondaryBackgroundColor)
|
||||||
|
.listRowSeparator(.hidden)
|
||||||
|
.listRowInsets(.init(top: 8,
|
||||||
|
leading: .layoutPadding,
|
||||||
|
bottom: 8,
|
||||||
|
trailing: .layoutPadding))
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
import SwiftUI
|
||||||
|
import Models
|
||||||
|
import Env
|
||||||
|
|
||||||
|
struct TimelineTagGroupheaderView: View {
|
||||||
|
@Environment(RouterPath.self) private var routerPath
|
||||||
|
|
||||||
|
@Binding var group: TagGroup?
|
||||||
|
@Binding var timeline: TimelineFilter
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
if let group {
|
||||||
|
TimelineHeaderView {
|
||||||
|
HStack {
|
||||||
|
ScrollView(.horizontal) {
|
||||||
|
HStack(spacing: 4) {
|
||||||
|
ForEach(group.tags, id: \.self) { tag in
|
||||||
|
Button {
|
||||||
|
routerPath.navigate(to: .hashTag(tag: tag, account: nil))
|
||||||
|
} label: {
|
||||||
|
Text("#\(tag)")
|
||||||
|
.font(.scaledHeadline)
|
||||||
|
}
|
||||||
|
.buttonStyle(.plain)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.scrollIndicators(.hidden)
|
||||||
|
Button("status.action.edit") {
|
||||||
|
routerPath.presentedSheet = .editTagGroup(tagGroup: group, onSaved: { group in
|
||||||
|
timeline = .tagGroup(title: group.title, tags: group.tags)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
.buttonStyle(.bordered)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
import SwiftUI
|
||||||
|
import Models
|
||||||
|
import DesignSystem
|
||||||
|
import Env
|
||||||
|
|
||||||
|
struct TimelineTagHeaderView: View {
|
||||||
|
@Environment(CurrentAccount.self) private var account
|
||||||
|
|
||||||
|
@Binding var tag: Tag?
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
if let tag {
|
||||||
|
TimelineHeaderView {
|
||||||
|
HStack {
|
||||||
|
TagChartView(tag: tag)
|
||||||
|
.padding(.top, 12)
|
||||||
|
|
||||||
|
VStack(alignment: .leading, spacing: 4) {
|
||||||
|
Text("#\(tag.name)")
|
||||||
|
.font(.scaledHeadline)
|
||||||
|
Text("timeline.n-recent-from-n-participants \(tag.totalUses) \(tag.totalAccounts)")
|
||||||
|
.font(.scaledFootnote)
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
}
|
||||||
|
.accessibilityElement(children: .combine)
|
||||||
|
Spacer()
|
||||||
|
Button {
|
||||||
|
Task {
|
||||||
|
if tag.following {
|
||||||
|
self.tag = await account.unfollowTag(id: tag.name)
|
||||||
|
} else {
|
||||||
|
self.tag = await account.followTag(id: tag.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} label: {
|
||||||
|
Text(tag.following ? "account.follow.following" : "account.follow.follow")
|
||||||
|
}.buttonStyle(.bordered)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -48,8 +48,8 @@ public struct TimelineView: View {
|
||||||
ZStack(alignment: .top) {
|
ZStack(alignment: .top) {
|
||||||
List {
|
List {
|
||||||
scrollToTopView
|
scrollToTopView
|
||||||
tagGroupHeaderView
|
TimelineTagGroupheaderView(group: $selectedTagGroup, timeline: $viewModel.timeline)
|
||||||
tagHeaderView
|
TimelineTagHeaderView(tag: $viewModel.tag)
|
||||||
switch viewModel.timeline {
|
switch viewModel.timeline {
|
||||||
case .remoteLocal:
|
case .remoteLocal:
|
||||||
StatusesListView(fetcher: viewModel, client: client, routerPath: routerPath, isRemote: true)
|
StatusesListView(fetcher: viewModel, client: client, routerPath: routerPath, isRemote: true)
|
||||||
|
@ -157,86 +157,6 @@ public struct TimelineView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
|
||||||
private var tagHeaderView: some View {
|
|
||||||
if let tag = viewModel.tag {
|
|
||||||
headerView {
|
|
||||||
HStack {
|
|
||||||
TagChartView(tag: tag)
|
|
||||||
.padding(.top, 12)
|
|
||||||
|
|
||||||
VStack(alignment: .leading, spacing: 4) {
|
|
||||||
Text("#\(tag.name)")
|
|
||||||
.font(.scaledHeadline)
|
|
||||||
Text("timeline.n-recent-from-n-participants \(tag.totalUses) \(tag.totalAccounts)")
|
|
||||||
.font(.scaledFootnote)
|
|
||||||
.foregroundStyle(.secondary)
|
|
||||||
}
|
|
||||||
.accessibilityElement(children: .combine)
|
|
||||||
Spacer()
|
|
||||||
Button {
|
|
||||||
Task {
|
|
||||||
if tag.following {
|
|
||||||
viewModel.tag = await account.unfollowTag(id: tag.name)
|
|
||||||
} else {
|
|
||||||
viewModel.tag = await account.followTag(id: tag.name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} label: {
|
|
||||||
Text(tag.following ? "account.follow.following" : "account.follow.follow")
|
|
||||||
}.buttonStyle(.bordered)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ViewBuilder
|
|
||||||
private var tagGroupHeaderView: some View {
|
|
||||||
if let group = selectedTagGroup {
|
|
||||||
headerView {
|
|
||||||
HStack {
|
|
||||||
ScrollView(.horizontal) {
|
|
||||||
HStack(spacing: 4) {
|
|
||||||
ForEach(group.tags, id: \.self) { tag in
|
|
||||||
Button {
|
|
||||||
routerPath.navigate(to: .hashTag(tag: tag, account: nil))
|
|
||||||
} label: {
|
|
||||||
Text("#\(tag)")
|
|
||||||
.font(.scaledHeadline)
|
|
||||||
}
|
|
||||||
.buttonStyle(.plain)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.scrollIndicators(.hidden)
|
|
||||||
Button("status.action.edit") {
|
|
||||||
routerPath.presentedSheet = .editTagGroup(tagGroup: group, onSaved: { group in
|
|
||||||
viewModel.timeline = .tagGroup(title: group.title, tags: group.tags)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
.buttonStyle(.bordered)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ViewBuilder
|
|
||||||
private func headerView(
|
|
||||||
@ViewBuilder content: () -> some View
|
|
||||||
) -> some View {
|
|
||||||
VStack(alignment: .leading) {
|
|
||||||
Spacer()
|
|
||||||
content()
|
|
||||||
Spacer()
|
|
||||||
}
|
|
||||||
.listRowBackground(theme.secondaryBackgroundColor)
|
|
||||||
.listRowSeparator(.hidden)
|
|
||||||
.listRowInsets(.init(top: 8,
|
|
||||||
leading: .layoutPadding,
|
|
||||||
bottom: 8,
|
|
||||||
trailing: .layoutPadding))
|
|
||||||
}
|
|
||||||
|
|
||||||
@ToolbarContentBuilder
|
@ToolbarContentBuilder
|
||||||
private var toolbarTitleView: some ToolbarContent {
|
private var toolbarTitleView: some ToolbarContent {
|
||||||
ToolbarItem(placement: .principal) {
|
ToolbarItem(placement: .principal) {
|
Loading…
Reference in a new issue