Add "Trending posts" (statuses) feed (#4007)
Add "Trending posts" (statuses) feed. This feed is a good source of interesting accounts to follow and, personally, a sort of "Front page of the Fediverse". Since #3908 and #3910 (which would provide a more thorough, albeit complex, access to trending things) won't get merged, I'd like to address this missing feed by simply adding another tab/feed. ~~If desired, I can move the second commit (fixing lint) to another PR.~~ ## Screenshots ### Tab <img src="https://github.com/tuskyapp/Tusky/assets/1063155/6a71a97e-673e-44c7-b67d-9b1df0bed4f5" width=320 /> <img src="https://github.com/tuskyapp/Tusky/assets/1063155/9bf60b23-d2f3-4dd8-8af6-e96647b02121" width=320 /> ### Activity <img src="https://github.com/tuskyapp/Tusky/assets/1063155/4e07dea3-d97f-42c6-8551-492a3116fcfa" width=320 /> <img src="https://github.com/tuskyapp/Tusky/assets/1063155/ad00a134-d622-43f4-8305-84cfa7fed706" width=320 />
This commit is contained in:
parent
bb1868fd67
commit
fa80a0123a
12 changed files with 148 additions and 11 deletions
|
|
@ -540,7 +540,8 @@ class TimelineFragment :
|
|||
when (kind) {
|
||||
TimelineViewModel.Kind.HOME,
|
||||
TimelineViewModel.Kind.PUBLIC_FEDERATED,
|
||||
TimelineViewModel.Kind.PUBLIC_LOCAL -> adapter.refresh()
|
||||
TimelineViewModel.Kind.PUBLIC_LOCAL,
|
||||
TimelineViewModel.Kind.PUBLIC_TRENDING_STATUSES -> adapter.refresh()
|
||||
TimelineViewModel.Kind.USER,
|
||||
TimelineViewModel.Kind.USER_WITH_REPLIES -> if (status.account.id == viewModel.id) {
|
||||
adapter.refresh()
|
||||
|
|
|
|||
|
|
@ -33,6 +33,14 @@ class NetworkTimelineRemoteMediator(
|
|||
private val viewModel: NetworkTimelineViewModel
|
||||
) : RemoteMediator<String, StatusViewData>() {
|
||||
|
||||
private val statusIds = mutableSetOf<String>()
|
||||
|
||||
init {
|
||||
if (viewModel.kind == TimelineViewModel.Kind.PUBLIC_TRENDING_STATUSES) {
|
||||
statusIds.addAll(viewModel.statusData.map { it.id })
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun load(
|
||||
loadType: LoadType,
|
||||
state: PagingState<String, StatusViewData>
|
||||
|
|
@ -88,6 +96,10 @@ class NetworkTimelineRemoteMediator(
|
|||
false
|
||||
}
|
||||
|
||||
if (viewModel.kind == TimelineViewModel.Kind.PUBLIC_TRENDING_STATUSES) {
|
||||
statusIds.addAll(data.map { it.id })
|
||||
}
|
||||
|
||||
viewModel.statusData.addAll(0, data)
|
||||
|
||||
if (insertPlaceholder) {
|
||||
|
|
@ -96,11 +108,22 @@ class NetworkTimelineRemoteMediator(
|
|||
} else {
|
||||
val linkHeader = statusResponse.headers()["Link"]
|
||||
val links = HttpHeaderLink.parse(linkHeader)
|
||||
val nextId = HttpHeaderLink.findByRelationType(links, "next")?.uri?.getQueryParameter("max_id")
|
||||
val next = HttpHeaderLink.findByRelationType(links, "next")
|
||||
|
||||
viewModel.nextKey = nextId
|
||||
var filteredData = data
|
||||
if (viewModel.kind == TimelineViewModel.Kind.PUBLIC_TRENDING_STATUSES) {
|
||||
// Trending statuses use offset for paging, not IDs. If a new status has been added to the remote
|
||||
// feed after we performed the initial fetch, then the feed will have moved, but our offset won't.
|
||||
// As a result, we'd get repeat statuses. This addresses that.
|
||||
filteredData = data.filter { !statusIds.contains(it.id) }
|
||||
statusIds.addAll(filteredData.map { it.id })
|
||||
|
||||
viewModel.statusData.addAll(data)
|
||||
viewModel.nextKey = next?.uri?.getQueryParameter("offset")
|
||||
} else {
|
||||
viewModel.nextKey = next?.uri?.getQueryParameter("max_id")
|
||||
}
|
||||
|
||||
viewModel.statusData.addAll(filteredData)
|
||||
}
|
||||
|
||||
viewModel.currentSource?.invalidate()
|
||||
|
|
|
|||
|
|
@ -308,6 +308,7 @@ class NetworkTimelineViewModel @Inject constructor(
|
|||
Kind.FAVOURITES -> api.favourites(fromId, uptoId, limit)
|
||||
Kind.BOOKMARKS -> api.bookmarks(fromId, uptoId, limit)
|
||||
Kind.LIST -> api.listTimeline(id!!, fromId, uptoId, limit)
|
||||
Kind.PUBLIC_TRENDING_STATUSES -> api.trendingStatuses(limit = limit, offset = fromId)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -321,12 +321,12 @@ abstract class TimelineViewModel(
|
|||
}
|
||||
|
||||
enum class Kind {
|
||||
HOME, PUBLIC_LOCAL, PUBLIC_FEDERATED, TAG, USER, USER_PINNED, USER_WITH_REPLIES, FAVOURITES, LIST, BOOKMARKS;
|
||||
HOME, PUBLIC_LOCAL, PUBLIC_FEDERATED, TAG, USER, USER_PINNED, USER_WITH_REPLIES, FAVOURITES, LIST, BOOKMARKS, PUBLIC_TRENDING_STATUSES;
|
||||
|
||||
fun toFilterKind(): Filter.Kind {
|
||||
return when (valueOf(name)) {
|
||||
HOME, LIST -> Filter.Kind.HOME
|
||||
PUBLIC_FEDERATED, PUBLIC_LOCAL, TAG, FAVOURITES -> Filter.Kind.PUBLIC
|
||||
PUBLIC_FEDERATED, PUBLIC_LOCAL, TAG, FAVOURITES, PUBLIC_TRENDING_STATUSES -> Filter.Kind.PUBLIC
|
||||
USER, USER_WITH_REPLIES, USER_PINNED -> Filter.Kind.ACCOUNT
|
||||
else -> Filter.Kind.PUBLIC
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue