PixelDroid-App-Android/app/src/main/java/org/pixeldroid/app/searchDiscover/TrendingActivity.kt

189 lines
7.2 KiB
Kotlin

package org.pixeldroid.app.searchDiscover
import android.annotation.SuppressLint
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import androidx.annotation.StringRes
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import org.pixeldroid.app.R
import org.pixeldroid.app.databinding.ActivityTrendingBinding
import org.pixeldroid.app.posts.PostActivity
import org.pixeldroid.app.posts.feeds.uncachedFeeds.accountLists.AccountViewHolder
import org.pixeldroid.app.posts.feeds.uncachedFeeds.search.HashTagViewHolder
import org.pixeldroid.app.profile.ProfilePostViewHolder
import org.pixeldroid.app.utils.BaseActivity
import org.pixeldroid.app.utils.api.PixelfedAPI
import org.pixeldroid.app.utils.api.objects.Account
import org.pixeldroid.app.utils.api.objects.Attachment
import org.pixeldroid.app.utils.api.objects.FeedContent
import org.pixeldroid.app.utils.api.objects.Status
import org.pixeldroid.app.utils.api.objects.Tag
import org.pixeldroid.app.utils.setSquareImageFromURL
class TrendingActivity : BaseActivity() {
private lateinit var binding: ActivityTrendingBinding
private lateinit var trendingAdapter : TrendingRecyclerViewAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityTrendingBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.topBar)
val recycler = binding.list
supportActionBar?.setDisplayHomeAsUpEnabled(true)
val type = intent.getSerializableExtra(TRENDING_TAG) as TrendingType? ?: TrendingType.POSTS
when (type) {
TrendingType.POSTS, TrendingType.DISCOVER -> {
// Set posts RecyclerView as a grid with 3 columns
recycler.layoutManager = GridLayoutManager(this, 3)
supportActionBar?.setTitle(
if (type == TrendingType.POSTS) {
R.string.trending_posts
} else {
R.string.discover
}
)
this.trendingAdapter = DiscoverRecyclerViewAdapter()
}
TrendingType.HASHTAGS -> {
supportActionBar?.setTitle(R.string.trending_hashtags)
this.trendingAdapter = HashtagsRecyclerViewAdapter()
}
TrendingType.ACCOUNTS -> {
supportActionBar?.setTitle(R.string.popular_accounts)
this.trendingAdapter = AccountsRecyclerViewAdapter()
}
}
recycler.adapter = this.trendingAdapter
getTrending(type)
binding.refreshLayout.setOnRefreshListener {
getTrending(type)
}
}
private fun showError(@StringRes errorText: Int = R.string.loading_toast, show: Boolean = true){
binding.motionLayout.apply {
if(show){
transitionToEnd()
binding.errorLayout.errorText.setText(errorText)
} else {
transitionToStart()
}
}
binding.refreshLayout.isRefreshing = false
binding.progressBar.visibility = View.GONE
}
private fun getTrending(type: TrendingType) {
lifecycleScope.launchWhenCreated {
try {
val api: PixelfedAPI = apiHolder.api ?: apiHolder.setToCurrentUser()
val content: List<FeedContent> = when(type) {
TrendingType.POSTS -> api.trendingPosts(Range.daily)
TrendingType.HASHTAGS -> api.trendingHashtags().map { it.copy(name = it.name.removePrefix("#")) }
TrendingType.ACCOUNTS -> api.popularAccounts()
TrendingType.DISCOVER -> api.discover().posts
}
trendingAdapter.addPosts(content)
showError(show = false)
} catch (exception: Exception) {
showError()
}
}
}
/**
* Abstract class for the different RecyclerViewAdapters used in this activity
*/
abstract class TrendingRecyclerViewAdapter: RecyclerView.Adapter<RecyclerView.ViewHolder>(){
val data: ArrayList<FeedContent?> = ArrayList()
@SuppressLint("NotifyDataSetChanged")
fun addPosts(newPosts: List<FeedContent>){
data.clear()
data.addAll(newPosts)
notifyDataSetChanged()
}
override fun getItemCount(): Int = data.size
}
/**
* [RecyclerView.Adapter] that can display a list of [Status]s' thumbnails for the discover view
*/
class DiscoverRecyclerViewAdapter: TrendingRecyclerViewAdapter() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProfilePostViewHolder =
ProfilePostViewHolder.create(parent)
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder !is ProfilePostViewHolder) return
val post = data[position] as? Status
if((post?.media_attachments?.size ?: 0) > 1) {
holder.albumIcon.visibility = View.VISIBLE
} else {
holder.albumIcon.visibility = View.GONE
if(post?.media_attachments?.getOrNull(0)?.type == Attachment.AttachmentType.video) {
holder.videoIcon.visibility = View.VISIBLE
} else holder.videoIcon.visibility = View.GONE
}
setSquareImageFromURL(holder.postView.root, post?.getPostPreviewURL(), holder.postPreview, post?.media_attachments?.firstOrNull()?.blurhash)
holder.postPreview.setOnClickListener {
val intent = Intent(holder.postView.root.context, PostActivity::class.java)
intent.putExtra(Status.POST_TAG, post)
holder.postView.root.context.startActivity(intent)
}
}
}
companion object {
const val TRENDING_TAG = "TrendingTag"
enum class TrendingType {
POSTS, HASHTAGS, ACCOUNTS, DISCOVER
}
@Suppress("EnumEntryName", "unused")
enum class Range {
daily, monthly, yearly
}
}
/**
* [RecyclerView.Adapter] that can display a list of [Tag]s for the trending view
*/
class HashtagsRecyclerViewAdapter: TrendingRecyclerViewAdapter() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HashTagViewHolder =
HashTagViewHolder.create(parent)
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val tag = data[position] as Tag
(holder as HashTagViewHolder).bind(tag)
}
}
/**
* [RecyclerView.Adapter] that can display a list of [Account]s for the popular view
*/
class AccountsRecyclerViewAdapter: TrendingRecyclerViewAdapter() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AccountViewHolder =
AccountViewHolder.create(parent)
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val account = data[position] as? Account
(holder as AccountViewHolder).bind(account)
}
}
}