From b1fd20e00552271ec49fa578ac656d07064659c9 Mon Sep 17 00:00:00 2001 From: Nik Clayton Date: Fri, 1 Sep 2023 19:06:56 +0200 Subject: [PATCH] feat: Support "Trending posts" - Implement the trending posts API - Display trending statuses as a new Timeline kind - Allow the user to add trending statuses to a dedicated tab - Always show the "Trending" option in the navigation menu --- app/src/main/java/com/keylesspalace/tusky/TabData.kt | 7 +++++++ .../com/keylesspalace/tusky/TabPreferenceActivity.kt | 3 +++ .../tusky/components/timeline/TimelineFragment.kt | 4 +++- .../timeline/viewmodel/NetworkTimelineViewModel.kt | 1 + .../components/timeline/viewmodel/TimelineViewModel.kt | 2 +- .../tusky/components/trending/TrendingActivity.kt | 10 +++++++--- .../com/keylesspalace/tusky/network/MastodonApi.kt | 3 +++ app/src/main/res/values/strings.xml | 6 ++++-- 8 files changed, 29 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/keylesspalace/tusky/TabData.kt b/app/src/main/java/com/keylesspalace/tusky/TabData.kt index 1a57599dd..3739d53fb 100644 --- a/app/src/main/java/com/keylesspalace/tusky/TabData.kt +++ b/app/src/main/java/com/keylesspalace/tusky/TabData.kt @@ -36,6 +36,7 @@ const val FEDERATED = "Federated" const val DIRECT = "Direct" const val TRENDING_TAGS = "TrendingTags" const val TRENDING_LINKS = "TrendingLinks" +const val TRENDING_STATUSES = "TrendingStatuses" const val HASHTAG = "Hashtag" const val LIST = "List" const val BOOKMARKS = "Bookmarks" @@ -107,6 +108,12 @@ fun createTabDataFromId(id: String, arguments: List = emptyList()): TabD icon = R.drawable.ic_trending_up_24px, fragment = { TrendingLinksFragment.newInstance() } ) + TRENDING_STATUSES -> TabData( + id = TRENDING_STATUSES, + text = R.string.title_public_trending_statuses, + icon = R.drawable.ic_trending_up_24px, + fragment = { TimelineFragment.newInstance(TimelineViewModel.Kind.TRENDING_STATUSES) } + ) HASHTAG -> TabData( id = HASHTAG, text = R.string.hashtags, diff --git a/app/src/main/java/com/keylesspalace/tusky/TabPreferenceActivity.kt b/app/src/main/java/com/keylesspalace/tusky/TabPreferenceActivity.kt index d44dcbcd7..92a1dc348 100644 --- a/app/src/main/java/com/keylesspalace/tusky/TabPreferenceActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/TabPreferenceActivity.kt @@ -386,6 +386,9 @@ class TabPreferenceActivity : BaseActivity(), Injectable, ItemInteractionListene if (!currentTabs.contains(trendingLinksTab)) { addableTabs.add(trendingLinksTab) } + createTabDataFromId(TRENDING_STATUSES).apply { + currentTabs.contains(this) || addableTabs.add(this) + } val bookmarksTab = createTabDataFromId(BOOKMARKS) if (!currentTabs.contains(trendingTagsTab)) { addableTabs.add(bookmarksTab) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/timeline/TimelineFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/timeline/TimelineFragment.kt index ef5d9085d..a68fc4acd 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/timeline/TimelineFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/timeline/TimelineFragment.kt @@ -549,7 +549,8 @@ class TimelineFragment : TimelineViewModel.Kind.FAVOURITES, TimelineViewModel.Kind.LIST, TimelineViewModel.Kind.BOOKMARKS, - TimelineViewModel.Kind.USER_PINNED -> return + TimelineViewModel.Kind.USER_PINNED, + TimelineViewModel.Kind.TRENDING_STATUSES -> return } } @@ -562,6 +563,7 @@ class TimelineFragment : return viewModel.kind != TimelineViewModel.Kind.TAG && viewModel.kind != TimelineViewModel.Kind.FAVOURITES && viewModel.kind != TimelineViewModel.Kind.BOOKMARKS && + viewModel.kind != TimelineViewModel.Kind.TRENDING_STATUSES && activity is ActionButtonActivity } diff --git a/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/NetworkTimelineViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/NetworkTimelineViewModel.kt index f32443aee..9feaace43 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/NetworkTimelineViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/NetworkTimelineViewModel.kt @@ -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.TRENDING_STATUSES -> api.trendingStatuses() } } diff --git a/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/TimelineViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/TimelineViewModel.kt index adab92b33..9bca68ba0 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/TimelineViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/TimelineViewModel.kt @@ -321,7 +321,7 @@ 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, TRENDING_STATUSES; fun toFilterKind(): Filter.Kind { return when (valueOf(name)) { diff --git a/app/src/main/java/com/keylesspalace/tusky/components/trending/TrendingActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/trending/TrendingActivity.kt index 7fa54bcdc..d101d2854 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/trending/TrendingActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/trending/TrendingActivity.kt @@ -30,8 +30,10 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity import androidx.viewpager2.adapter.FragmentStateAdapter import com.google.android.material.tabs.TabLayoutMediator -import com.keylesspalace.tusky.BaseActivity +import com.keylesspalace.tusky.BottomSheetActivity import com.keylesspalace.tusky.R +import com.keylesspalace.tusky.components.timeline.TimelineFragment +import com.keylesspalace.tusky.components.timeline.viewmodel.TimelineViewModel import com.keylesspalace.tusky.databinding.ActivityTrendingBinding import com.keylesspalace.tusky.util.reduceSwipeSensitivity import com.keylesspalace.tusky.util.viewBinding @@ -39,7 +41,7 @@ import dagger.android.DispatchingAndroidInjector import dagger.android.HasAndroidInjector import javax.inject.Inject -class TrendingActivity : BaseActivity(), HasAndroidInjector, MenuProvider { +class TrendingActivity : BottomSheetActivity(), HasAndroidInjector, MenuProvider { @Inject lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector @@ -93,12 +95,13 @@ class TrendingActivity : BaseActivity(), HasAndroidInjector, MenuProvider { } class TrendingFragmentAdapter(val activity: FragmentActivity) : FragmentStateAdapter(activity) { - override fun getItemCount() = 2 + override fun getItemCount() = 3 override fun createFragment(position: Int): Fragment { return when (position) { 0 -> TrendingTagsFragment.newInstance() 1 -> TrendingLinksFragment.newInstance() + 2 -> TimelineFragment.newInstance(TimelineViewModel.Kind.TRENDING_STATUSES) else -> throw IllegalStateException() } } @@ -107,6 +110,7 @@ class TrendingFragmentAdapter(val activity: FragmentActivity) : FragmentStateAda return when (position) { 0 -> activity.getString(R.string.title_tab_public_trending_hashtags) 1 -> activity.getString(R.string.title_tab_public_trending_links) + 2 -> activity.getString(R.string.title_tab_public_trending_statuses) else -> throw IllegalStateException() } } diff --git a/app/src/main/java/com/keylesspalace/tusky/network/MastodonApi.kt b/app/src/main/java/com/keylesspalace/tusky/network/MastodonApi.kt index a751c1536..9d7d4e85a 100644 --- a/app/src/main/java/com/keylesspalace/tusky/network/MastodonApi.kt +++ b/app/src/main/java/com/keylesspalace/tusky/network/MastodonApi.kt @@ -789,4 +789,7 @@ interface MastodonApi { @GET("api/v1/trends/links") suspend fun trendingLinks(): NetworkResult> + + @GET("api/v1/trends/statuses") + suspend fun trendingStatuses(): Response> } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0dd9b3534..d96dc5327 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -53,10 +53,12 @@ Notifications Local Trending - Trending Hashtags - Trending Links + Trending hashtags + Trending links + Trending posts Hashtags Links + Posts Federated Direct messages Tabs