Bubble/Threaded/Views/TimelineView.swift

146 lines
6.2 KiB
Swift
Raw Normal View History

2023-12-29 11:17:37 +01:00
//Made by Lumaa
import SwiftUI
struct TimelineView: View {
@Environment(AccountManager.self) private var accountManager: AccountManager
@State var navigator: Navigator = Navigator()
@State private var showPicker: Bool = false
@State private var stringTimeline: String = "home"
@State private var timelines: [TimelineFilter] = [.trending, .home]
2023-12-29 11:17:37 +01:00
2024-01-06 02:50:54 +01:00
@State private var loadingStatuses: Bool = false
2023-12-29 11:17:37 +01:00
@State private var statuses: [Status]?
2024-01-06 02:50:54 +01:00
@State private var lastSeen: Int?
2023-12-29 11:17:37 +01:00
@State var filter: TimelineFilter = .home
@State var showHero: Bool = true
@State var timelineModel: FetchTimeline // home timeline by default
2023-12-29 11:17:37 +01:00
init(timelineModel: FetchTimeline, filter: TimelineFilter = .home, showHero: Bool = true) {
self.timelineModel = timelineModel
self.filter = filter
self.showHero = showHero
}
2023-12-29 11:17:37 +01:00
var body: some View {
NavigationStack(path: $navigator.path) {
if statuses != nil {
2023-12-29 12:54:11 +01:00
if !statuses!.isEmpty {
ScrollView(showsIndicators: false) {
if showHero {
Button {
withAnimation(.easeInOut) {
showPicker.toggle()
}
} label: {
Image("HeroIcon")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 30)
.padding(.bottom)
}
}
// if showPicker {
// //TODO: Fix this
//
// MetaPicker(items: timelines.map { $0.rawValue }, selectedItem: $stringTimeline) { item in
// let title: String = timelines.filter{ $0.rawValue == item }.first?.localizedTitle() ?? "Unknown"
// Text("\(title)")
// }
// .padding(.bottom)
// .onChange(of: stringTimeline) { _, newTimeline in
// let loc = timelines.filter{ $0.rawValue == newTimeline }.first?.localizedTitle()
// switch (loc) {
// case "home":
// timeline = .home
// case "trending":
// timeline = .trending
// default:
// timeline = .home
// }
// }
// }
2023-12-29 12:54:11 +01:00
ForEach(statuses!, id: \.id) { status in
2024-01-06 02:50:54 +01:00
LazyVStack(alignment: .leading, spacing: 2) {
CompactPostView(status: status)
2024-01-06 02:50:54 +01:00
.onDisappear {
guard statuses != nil else { return }
lastSeen = statuses!.firstIndex(where: { $0.id == status.id })
}
2023-12-29 12:54:11 +01:00
}
}
}
.refreshable {
if let client = accountManager.getClient() {
Task {
2024-01-06 02:50:54 +01:00
loadingStatuses = true
statuses = await timelineModel.fetch(client: client)
loadingStatuses = false
}
}
}
2024-01-06 02:50:54 +01:00
.onChange(of: lastSeen ?? 0) { _, new in
guard !loadingStatuses else { return }
Task {
loadingStatuses = true
statuses = await timelineModel.addStatuses(lastStatusIndex: new)
loadingStatuses = false
}
}
2023-12-29 12:54:11 +01:00
.padding(.top)
.background(Color.appBackground)
.withAppRouter(navigator)
2023-12-29 12:54:11 +01:00
} else {
ZStack {
Color.appBackground
.ignoresSafeArea()
VStack {
Image("HeroIcon")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 50)
.padding(.bottom)
ContentUnavailableView {
Text("timeline.empty")
.bold()
} description: {
Text("timeline.empty.description")
}
.scrollDisabled(true)
2023-12-29 11:17:37 +01:00
}
2023-12-29 12:54:11 +01:00
.scrollDisabled(true)
.background(Color.appBackground)
2024-01-06 02:50:54 +01:00
.frame(height: 200)
2023-12-29 11:17:37 +01:00
}
}
} else {
ZStack {
Color.appBackground
.ignoresSafeArea()
.onAppear {
if let client = accountManager.getClient() {
Task {
2024-01-06 02:50:54 +01:00
statuses = await timelineModel.fetch(client: client)
}
2023-12-29 11:17:37 +01:00
}
}
ProgressView()
.progressViewStyle(.circular)
}
}
}
.environmentObject(navigator)
2023-12-29 11:17:37 +01:00
.background(Color.appBackground)
.toolbarBackground(Color.appBackground, for: .navigationBar)
.toolbarBackground(.visible, for: .navigationBar)
.safeAreaPadding()
}
}