Add trending as a timeline

This commit is contained in:
Thomas Ricouard 2023-01-01 14:28:15 +01:00
parent b324c87ae1
commit 9f009376f5
4 changed files with 24 additions and 9 deletions

View File

@ -69,7 +69,7 @@ class ExploreViewModel: ObservableObject {
do {
async let suggestedAccounts: [Account] = client.get(endpoint: Accounts.suggestions)
async let trendingTags: [Tag] = client.get(endpoint: Trends.tags)
async let trendingStatuses: [Status] = client.get(endpoint: Trends.statuses)
async let trendingStatuses: [Status] = client.get(endpoint: Trends.statuses(offset: nil))
async let trendingLinks: [Card] = client.get(endpoint: Trends.links)
self.suggestedAccounts = try await suggestedAccounts

View File

@ -2,7 +2,7 @@ import Foundation
public enum Trends: Endpoint {
case tags
case statuses
case statuses(offset: Int?)
case links
public func path() -> String {
@ -18,6 +18,11 @@ public enum Trends: Endpoint {
public func queryItems() -> [URLQueryItem]? {
switch self {
case let .statuses(offset):
if let offset {
return [.init(name: "offset", value: String(offset))]
}
return nil
default:
return nil
}

View File

@ -3,7 +3,7 @@ import Models
import Network
public enum TimelineFilter: Hashable, Equatable {
case pub, local, home
case pub, local, home, trending
case hashtag(tag: String, accountId: String?)
public func hash(into hasher: inout Hasher) {
@ -12,9 +12,9 @@ public enum TimelineFilter: Hashable, Equatable {
public static func availableTimeline(client: Client) -> [TimelineFilter] {
if !client.isAuth {
return [.pub, .local]
return [.pub, .local, .trending]
}
return [.pub, .local, .home]
return [.pub, .local, .trending, .home]
}
public func title() -> String {
@ -23,6 +23,8 @@ public enum TimelineFilter: Hashable, Equatable {
return "Federated"
case .local:
return "Local"
case .trending:
return "Trending"
case .home:
return "Home"
case let .hashtag(tag, _):
@ -36,6 +38,8 @@ public enum TimelineFilter: Hashable, Equatable {
return "globe.americas"
case .local:
return "person.3"
case .trending:
return "chart.line.uptrend.xyaxis"
case .home:
return "house"
default:
@ -43,11 +47,12 @@ public enum TimelineFilter: Hashable, Equatable {
}
}
public func endpoint(sinceId: String?, maxId: String?, minId: String?) -> Endpoint {
public func endpoint(sinceId: String?, maxId: String?, minId: String?, offset: Int?) -> Endpoint {
switch self {
case .pub: return Timelines.pub(sinceId: sinceId, maxId: maxId, minId: minId, local: false)
case .local: return Timelines.pub(sinceId: sinceId, maxId: maxId, minId: minId, local: true)
case .home: return Timelines.home(sinceId: sinceId, maxId: maxId, minId: minId)
case .trending: return Trends.statuses(offset: offset)
case let .hashtag(tag, accountId):
if let accountId {
return Accounts.statuses(id: accountId, sinceId: nil, tag: tag, onlyMedia: nil, excludeReplies: nil)

View File

@ -71,7 +71,10 @@ class TimelineViewModel: ObservableObject, StatusesFetcher {
if statuses.isEmpty {
pendingStatuses = []
statusesState = .loading
statuses = try await client.get(endpoint: timeline.endpoint(sinceId: nil, maxId: nil, minId: nil))
statuses = try await client.get(endpoint: timeline.endpoint(sinceId: nil,
maxId: nil,
minId: nil,
offset: statuses.count))
statusesState = .display(statuses: statuses, nextPageState: statuses.count < 20 ? .none : .hasNextPage)
} else if let first = statuses.first {
var newStatuses: [Status] = await fetchNewPages(minId: first.id, maxPages: 10)
@ -103,7 +106,8 @@ class TimelineViewModel: ObservableObject, StatusesFetcher {
do {
while let newStatuses: [Status] = try await client.get(endpoint: timeline.endpoint(sinceId: nil,
maxId: nil,
minId: latestMinId)),
minId: latestMinId,
offset: statuses.count)),
!newStatuses.isEmpty,
pagesLoaded < maxPages {
pagesLoaded += 1
@ -123,7 +127,8 @@ class TimelineViewModel: ObservableObject, StatusesFetcher {
statusesState = .display(statuses: statuses, nextPageState: .loadingNextPage)
let newStatuses: [Status] = try await client.get(endpoint: timeline.endpoint(sinceId: nil,
maxId: lastId,
minId: nil))
minId: nil,
offset: statuses.count))
statuses.append(contentsOf: newStatuses)
statusesState = .display(statuses: statuses, nextPageState: .hasNextPage)
} catch {