Merge pull request #1176 from Bnyro/master

load feed in background
This commit is contained in:
Bnyro 2022-08-26 18:32:36 +02:00 committed by GitHub
commit 8e065fc44b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 131 additions and 117 deletions

View File

@ -28,7 +28,7 @@ class LibraryFragment : BaseFragment() {
lateinit var token: String
private lateinit var binding: FragmentLibraryBinding
val playerViewModel: PlayerViewModel by activityViewModels()
private val playerViewModel: PlayerViewModel by activityViewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -88,7 +88,7 @@ class LibraryFragment : BaseFragment() {
}
}
fun updateFABMargin() {
private fun updateFABMargin() {
// optimize CreatePlaylistFab bottom margin if miniPlayer active
val bottomMargin = if (playerViewModel.isMiniPlayerVisible.value == true) 180 else 64
val layoutParams = binding.createPlaylist.layoutParams as ViewGroup.MarginLayoutParams

View File

@ -1,47 +1,31 @@
package com.github.libretube.fragments
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import com.github.libretube.R
import com.github.libretube.adapters.LegacySubscriptionAdapter
import com.github.libretube.adapters.SubscriptionChannelAdapter
import com.github.libretube.adapters.TrendingAdapter
import com.github.libretube.api.RetrofitInstance
import com.github.libretube.api.SubscriptionHelper
import com.github.libretube.databinding.FragmentSubscriptionsBinding
import com.github.libretube.extensions.BaseFragment
import com.github.libretube.extensions.TAG
import com.github.libretube.obj.StreamItem
import com.github.libretube.models.SubscriptionsViewModel
import com.github.libretube.preferences.PreferenceHelper
import com.github.libretube.preferences.PreferenceKeys
import com.github.libretube.util.toID
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import retrofit2.HttpException
import java.io.IOException
class SubscriptionsFragment : BaseFragment() {
private lateinit var binding: FragmentSubscriptionsBinding
private val viewModel: SubscriptionsViewModel by activityViewModels()
lateinit var token: String
private var isLoaded = false
private var subscriptionAdapter: TrendingAdapter? = null
private var feed: List<StreamItem> = listOf()
private var sortOrder = "most_recent"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@ -53,7 +37,6 @@ class SubscriptionsFragment : BaseFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
token = PreferenceHelper.getToken()
binding.subRefresh.isEnabled = true
@ -63,12 +46,22 @@ class SubscriptionsFragment : BaseFragment() {
PreferenceKeys.GRID_COLUMNS,
resources.getInteger(R.integer.grid_items).toString()
)
binding.subFeed.layoutManager = GridLayoutManager(view.context, grid.toInt())
fetchFeed()
if (viewModel.videoFeed.value == null) viewModel.fetchFeed()
viewModel.videoFeed.observe(viewLifecycleOwner) {
if (it != null) showFeed()
}
viewModel.subscriptions.observe(viewLifecycleOwner) {
if (it != null) showSubscriptions()
}
binding.subRefresh.setOnRefreshListener {
fetchChannels()
fetchFeed()
viewModel.fetchSubscriptions()
viewModel.fetchFeed()
}
binding.sortTV.setOnClickListener {
@ -76,14 +69,14 @@ class SubscriptionsFragment : BaseFragment() {
}
binding.toggleSubs.visibility = View.VISIBLE
var loadedSubbedChannels = false
binding.toggleSubs.setOnClickListener {
if (!binding.subChannelsContainer.isVisible) {
if (!loadedSubbedChannels) {
binding.subChannels.layoutManager = LinearLayoutManager(context)
fetchChannels()
loadedSubbedChannels = true
if (viewModel.subscriptions.value == null) {
viewModel.fetchSubscriptions()
} else {
showSubscriptions()
}
binding.subChannelsContainer.visibility = View.VISIBLE
binding.subFeedContainer.visibility = View.GONE
@ -99,14 +92,13 @@ class SubscriptionsFragment : BaseFragment() {
== (binding.scrollviewSub.height + binding.scrollviewSub.scrollY)
) {
// scroll view is at bottom
if (isLoaded) {
if (viewModel.videoFeed.value == null) return@addOnScrollChangedListener
binding.subRefresh.isRefreshing = true
subscriptionAdapter?.updateItems()
binding.subRefresh.isRefreshing = false
}
}
}
}
private fun showSortDialog() {
val sortOptions = resources.getStringArray(R.array.sortOptions)
@ -122,45 +114,9 @@ class SubscriptionsFragment : BaseFragment() {
.show()
}
private fun fetchFeed() {
fun run() {
lifecycleScope.launchWhenCreated {
feed = try {
if (token != "") {
RetrofitInstance.authApi.getFeed(token)
} else {
RetrofitInstance.authApi.getUnauthenticatedFeed(
SubscriptionHelper.getFormattedLocalSubscriptions()
)
}
} catch (e: IOException) {
Log.e(TAG(), e.toString())
Log.e(TAG(), "IOException, you might not have internet connection")
return@launchWhenCreated
} catch (e: HttpException) {
Log.e(TAG(), "HttpException, unexpected response")
return@launchWhenCreated
} finally {
binding.subRefresh.isRefreshing = false
}
if (feed.isNotEmpty()) {
// save the last recent video to the prefs for the notification worker
PreferenceHelper.setLatestVideoId(feed[0].url.toID())
// show the feed
showFeed()
} else {
runOnUiThread {
binding.emptyFeed.visibility = View.VISIBLE
}
}
binding.subProgress.visibility = View.GONE
isLoaded = true
}
}
run()
}
private fun showFeed() {
binding.subRefresh.isRefreshing = false
val feed = viewModel.videoFeed.value!!
// sort the feed
val sortedFeed = when (sortOrder) {
"most_recent" -> feed
@ -171,32 +127,13 @@ class SubscriptionsFragment : BaseFragment() {
"channel_name_za" -> feed.sortedBy { it.uploaderName }.reversed()
else -> feed
}
binding.subProgress.visibility = View.GONE
subscriptionAdapter = TrendingAdapter(sortedFeed, childFragmentManager, false)
binding.subFeed.adapter = subscriptionAdapter
}
private fun fetchChannels() {
fun run() {
lifecycleScope.launchWhenCreated {
val response = try {
if (token != "") {
RetrofitInstance.authApi.subscriptions(token)
} else {
RetrofitInstance.authApi.unauthenticatedSubscriptions(
SubscriptionHelper.getFormattedLocalSubscriptions()
)
}
} catch (e: IOException) {
Log.e(TAG(), e.toString())
Log.e(TAG(), "IOException, you might not have internet connection")
return@launchWhenCreated
} catch (e: HttpException) {
Log.e(TAG(), "HttpException, unexpected response")
return@launchWhenCreated
} finally {
private fun showSubscriptions() {
binding.subRefresh.isRefreshing = false
}
if (response.isNotEmpty()) {
binding.subChannels.adapter =
if (PreferenceHelper.getBoolean(
PreferenceKeys.LEGACY_SUBSCRIPTIONS,
@ -210,15 +147,13 @@ class SubscriptionsFragment : BaseFragment() {
"4"
).toInt()
)
LegacySubscriptionAdapter(response)
LegacySubscriptionAdapter(
viewModel.subscriptions.value!!
)
} else {
SubscriptionChannelAdapter(response.toMutableList())
SubscriptionChannelAdapter(
viewModel.subscriptions.value!!.toMutableList()
)
}
} else {
Toast.makeText(context, R.string.subscribeIsEmpty, Toast.LENGTH_SHORT).show()
}
}
}
run()
}
}

View File

@ -0,0 +1,79 @@
package com.github.libretube.models
import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.github.libretube.api.RetrofitInstance
import com.github.libretube.api.SubscriptionHelper
import com.github.libretube.extensions.TAG
import com.github.libretube.obj.StreamItem
import com.github.libretube.obj.Subscription
import com.github.libretube.preferences.PreferenceHelper
import com.github.libretube.util.toID
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import retrofit2.HttpException
import java.io.IOException
class SubscriptionsViewModel : ViewModel() {
var videoFeed = MutableLiveData<List<StreamItem>?>().apply {
value = null
}
var subscriptions = MutableLiveData<List<Subscription>?>().apply {
value = null
}
fun fetchFeed() {
CoroutineScope(Dispatchers.IO).launch {
val videoFeed = try {
if (PreferenceHelper.getToken() != "") {
RetrofitInstance.authApi.getFeed(
PreferenceHelper.getToken()
)
} else {
RetrofitInstance.authApi.getUnauthenticatedFeed(
SubscriptionHelper.getFormattedLocalSubscriptions()
)
}
} catch (e: IOException) {
Log.e(TAG(), e.toString())
Log.e(TAG(), "IOException, you might not have internet connection")
return@launch
} catch (e: HttpException) {
Log.e(TAG(), "HttpException, unexpected response")
return@launch
}
this@SubscriptionsViewModel.videoFeed.postValue(videoFeed)
if (videoFeed.isNotEmpty()) {
// save the last recent video to the prefs for the notification worker
PreferenceHelper.setLatestVideoId(videoFeed[0].url.toID())
}
}
}
fun fetchSubscriptions() {
CoroutineScope(Dispatchers.IO).launch {
val subscriptions = try {
if (PreferenceHelper.getToken() != "") {
RetrofitInstance.authApi.subscriptions(
PreferenceHelper.getToken()
)
} else {
RetrofitInstance.authApi.unauthenticatedSubscriptions(
SubscriptionHelper.getFormattedLocalSubscriptions()
)
}
} catch (e: IOException) {
Log.e(TAG(), e.toString())
Log.e(TAG(), "IOException, you might not have internet connection")
return@launch
} catch (e: HttpException) {
Log.e(TAG(), "HttpException, unexpected response")
return@launch
}
this@SubscriptionsViewModel.subscriptions.postValue(subscriptions)
}
}
}