Infintie scrolling
This commit is contained in:
parent
2d040a6313
commit
4b640c76a0
|
@ -18,19 +18,31 @@ struct AccountView: View {
|
|||
@State private var isFollowing: Bool = false
|
||||
@State private var accountFollows: Bool = false
|
||||
|
||||
@State private var loadingStatuses: Bool = false
|
||||
@State private var statuses: [Status]?
|
||||
@State private var statusesPinned: [Status]?
|
||||
@State private var lastSeen: Int?
|
||||
|
||||
private let animPicCurve = Animation.smooth(duration: 0.25, extraBounce: 0.0)
|
||||
|
||||
var body: some View {
|
||||
if isCurrent {
|
||||
if accountManager.getClient() != nil {
|
||||
NavigationStack(path: $navigator.path) {
|
||||
accountView
|
||||
.withSheets(sheetDestination: $navigator.presentedSheet)
|
||||
.onAppear {
|
||||
account = accountManager.forceAccount()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ZStack {
|
||||
Color.appBackground
|
||||
|
||||
ProgressView()
|
||||
.progressViewStyle(.circular)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
accountView
|
||||
}
|
||||
|
@ -85,8 +97,10 @@ struct AccountView: View {
|
|||
account = ref
|
||||
|
||||
await updateRelationship()
|
||||
loadingStatuses = true
|
||||
statuses = try? await client.get(endpoint: Accounts.statuses(id: account.id, sinceId: nil, tag: nil, onlyMedia: nil, excludeReplies: nil, pinned: nil))
|
||||
statusesPinned = try? await client.get(endpoint: Accounts.statuses(id: account.id, sinceId: nil, tag: nil, onlyMedia: nil, excludeReplies: nil, pinned: true))
|
||||
loadingStatuses = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -138,8 +152,6 @@ struct AccountView: View {
|
|||
let client = accountManager.getClient()
|
||||
navigator.presentedSheet = .post(content: "@\(account.username)@\(client?.server ?? "???")")
|
||||
}
|
||||
|
||||
|
||||
} label: {
|
||||
HStack {
|
||||
Spacer()
|
||||
|
@ -170,7 +182,7 @@ struct AccountView: View {
|
|||
}
|
||||
|
||||
var statusesList: some View {
|
||||
VStack {
|
||||
LazyVStack {
|
||||
if statuses != nil {
|
||||
if !(statusesPinned?.isEmpty ?? true) {
|
||||
ForEach(statusesPinned!, id: \.id) { status in
|
||||
|
@ -180,6 +192,9 @@ struct AccountView: View {
|
|||
if !statuses!.isEmpty {
|
||||
ForEach(statuses!, id: \.id) { status in
|
||||
CompactPostView(status: status, navigator: navigator)
|
||||
.onDisappear() {
|
||||
lastSeen = statuses!.firstIndex(where: { $0.id == status.id })
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -191,12 +206,26 @@ struct AccountView: View {
|
|||
if statuses == nil {
|
||||
if let client = accountManager.getClient() {
|
||||
Task {
|
||||
loadingStatuses = true
|
||||
statuses = try await client.get(endpoint: Accounts.statuses(id: account.id, sinceId: nil, tag: nil, onlyMedia: nil, excludeReplies: nil, pinned: nil))
|
||||
statusesPinned = try await client.get(endpoint: Accounts.statuses(id: account.id, sinceId: nil, tag: nil, onlyMedia: nil, excludeReplies: nil, pinned: true))
|
||||
loadingStatuses = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: lastSeen ?? 0) { _, new in
|
||||
guard statuses != nil && new >= statuses!.count - 6 && !loadingStatuses else { return }
|
||||
if let client = accountManager.getClient(), let lastStatus = statuses!.last {
|
||||
Task {
|
||||
loadingStatuses = true
|
||||
if let newStatuses: [Status] = try await client.get(endpoint: Accounts.statuses(id: account.id, sinceId: lastStatus.id, tag: nil, onlyMedia: nil, excludeReplies: nil, pinned: nil)) {
|
||||
statuses?.append(contentsOf: newStatuses)
|
||||
}
|
||||
loadingStatuses = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func followAccount() async {
|
||||
|
|
|
@ -11,7 +11,9 @@ struct TimelineView: View {
|
|||
@State private var timeline: TimelineFilter = .home
|
||||
@State private var timelines: [TimelineFilter] = [.trending, .home]
|
||||
|
||||
@State private var loadingStatuses: Bool = false
|
||||
@State private var statuses: [Status]?
|
||||
@State private var lastSeen: Int?
|
||||
|
||||
@State var timelineModel: FetchTimeline // home timeline by default
|
||||
|
||||
|
@ -54,18 +56,32 @@ struct TimelineView: View {
|
|||
// }
|
||||
|
||||
ForEach(statuses!, id: \.id) { status in
|
||||
VStack(spacing: 2) {
|
||||
LazyVStack(alignment: .leading, spacing: 2) {
|
||||
CompactPostView(status: status, navigator: navigator)
|
||||
.onDisappear {
|
||||
guard statuses != nil else { return }
|
||||
lastSeen = statuses!.firstIndex(where: { $0.id == status.id })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.refreshable {
|
||||
if let client = accountManager.getClient() {
|
||||
Task {
|
||||
statuses = try? await client.get(endpoint: Timelines.home(sinceId: nil, maxId: nil, minId: nil))
|
||||
loadingStatuses = true
|
||||
statuses = await timelineModel.fetch(client: client)
|
||||
loadingStatuses = false
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: lastSeen ?? 0) { _, new in
|
||||
guard !loadingStatuses else { return }
|
||||
Task {
|
||||
loadingStatuses = true
|
||||
statuses = await timelineModel.addStatuses(lastStatusIndex: new)
|
||||
loadingStatuses = false
|
||||
}
|
||||
}
|
||||
.padding(.top)
|
||||
.background(Color.appBackground)
|
||||
.withAppRouter(navigator)
|
||||
|
@ -91,7 +107,7 @@ struct TimelineView: View {
|
|||
}
|
||||
.scrollDisabled(true)
|
||||
.background(Color.appBackground)
|
||||
.frame(height: 150)
|
||||
.frame(height: 200)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -101,7 +117,7 @@ struct TimelineView: View {
|
|||
.onAppear {
|
||||
if let client = accountManager.getClient() {
|
||||
Task {
|
||||
statuses = try? await client.get(endpoint: Timelines.home(sinceId: nil, maxId: nil, minId: nil))
|
||||
statuses = await timelineModel.fetch(client: client)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue