diff --git a/app/src/main/java/com/github/libretube/fragments/LibraryFragment.kt b/app/src/main/java/com/github/libretube/fragments/LibraryFragment.kt index 0db99547b..2e73b6c50 100644 --- a/app/src/main/java/com/github/libretube/fragments/LibraryFragment.kt +++ b/app/src/main/java/com/github/libretube/fragments/LibraryFragment.kt @@ -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 diff --git a/app/src/main/java/com/github/libretube/fragments/SubscriptionsFragment.kt b/app/src/main/java/com/github/libretube/fragments/SubscriptionsFragment.kt index 53abbd033..a373de840 100644 --- a/app/src/main/java/com/github/libretube/fragments/SubscriptionsFragment.kt +++ b/app/src/main/java/com/github/libretube/fragments/SubscriptionsFragment.kt @@ -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 = 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 + binding.subChannels.layoutManager = LinearLayoutManager(context) + if (viewModel.subscriptions.value == null) { + viewModel.fetchSubscriptions() + } else { + showSubscriptions() } binding.subChannelsContainer.visibility = View.VISIBLE binding.subFeedContainer.visibility = View.GONE @@ -99,11 +92,10 @@ class SubscriptionsFragment : BaseFragment() { == (binding.scrollviewSub.height + binding.scrollviewSub.scrollY) ) { // scroll view is at bottom - if (isLoaded) { - binding.subRefresh.isRefreshing = true - subscriptionAdapter?.updateItems() - binding.subRefresh.isRefreshing = false - } + if (viewModel.videoFeed.value == null) return@addOnScrollChangedListener + binding.subRefresh.isRefreshing = true + subscriptionAdapter?.updateItems() + binding.subRefresh.isRefreshing = false } } } @@ -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,54 +127,33 @@ 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 { - binding.subRefresh.isRefreshing = false - } - if (response.isNotEmpty()) { - binding.subChannels.adapter = - if (PreferenceHelper.getBoolean( - PreferenceKeys.LEGACY_SUBSCRIPTIONS, - false - ) - ) { - binding.subChannels.layoutManager = GridLayoutManager( - context, - PreferenceHelper.getString( - PreferenceKeys.LEGACY_SUBSCRIPTIONS_COLUMNS, - "4" - ).toInt() - ) - LegacySubscriptionAdapter(response) - } else { - SubscriptionChannelAdapter(response.toMutableList()) - } - } else { - Toast.makeText(context, R.string.subscribeIsEmpty, Toast.LENGTH_SHORT).show() - } + private fun showSubscriptions() { + binding.subRefresh.isRefreshing = false + binding.subChannels.adapter = + if (PreferenceHelper.getBoolean( + PreferenceKeys.LEGACY_SUBSCRIPTIONS, + false + ) + ) { + binding.subChannels.layoutManager = GridLayoutManager( + context, + PreferenceHelper.getString( + PreferenceKeys.LEGACY_SUBSCRIPTIONS_COLUMNS, + "4" + ).toInt() + ) + LegacySubscriptionAdapter( + viewModel.subscriptions.value!! + ) + } else { + SubscriptionChannelAdapter( + viewModel.subscriptions.value!!.toMutableList() + ) } - } - run() } } diff --git a/app/src/main/java/com/github/libretube/models/SubscriptionsViewModel.kt b/app/src/main/java/com/github/libretube/models/SubscriptionsViewModel.kt new file mode 100644 index 000000000..44fedd4fb --- /dev/null +++ b/app/src/main/java/com/github/libretube/models/SubscriptionsViewModel.kt @@ -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?>().apply { + value = null + } + + var subscriptions = MutableLiveData?>().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) + } + } +}