add zero state for shorts tab

Changelog: changed
This commit is contained in:
Kai 2025-07-10 10:40:52 -05:00
commit 7aa8b6bc14
No known key found for this signature in database
3 changed files with 82 additions and 3 deletions

View file

@ -4,10 +4,12 @@ import android.annotation.SuppressLint
import android.graphics.drawable.Animatable import android.graphics.drawable.Animatable
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.SoundEffectConstants
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.ImageView import android.widget.ImageView
import android.widget.LinearLayout
import androidx.annotation.OptIn import androidx.annotation.OptIn
import androidx.media3.common.util.UnstableApi import androidx.media3.common.util.UnstableApi
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
@ -22,6 +24,7 @@ import com.futo.platformplayer.constructs.TaskHandler
import com.futo.platformplayer.logging.Logger import com.futo.platformplayer.logging.Logger
import com.futo.platformplayer.states.StateApp import com.futo.platformplayer.states.StateApp
import com.futo.platformplayer.states.StatePlatform import com.futo.platformplayer.states.StatePlatform
import com.futo.platformplayer.views.buttons.BigButton
@UnstableApi @UnstableApi
class ShortsFragment : MainFragment() { class ShortsFragment : MainFragment() {
@ -47,6 +50,8 @@ class ShortsFragment : MainFragment() {
get() = channelShortsPager != null get() = channelShortsPager != null
private var viewPager: ViewPager2? = null private var viewPager: ViewPager2? = null
private lateinit var zeroState: LinearLayout
private lateinit var sourcesButton: BigButton
private lateinit var overlayLoading: FrameLayout private lateinit var overlayLoading: FrameLayout
private lateinit var overlayLoadingSpinner: ImageView private lateinit var overlayLoadingSpinner: ImageView
private lateinit var overlayQualityContainer: FrameLayout private lateinit var overlayQualityContainer: FrameLayout
@ -108,10 +113,17 @@ class ShortsFragment : MainFragment() {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
viewPager = view.findViewById(R.id.view_pager) viewPager = view.findViewById(R.id.view_pager)
zeroState = view.findViewById(R.id.zero_state)
sourcesButton = view.findViewById(R.id.sources_button)
overlayLoading = view.findViewById(R.id.short_view_loading_overlay) overlayLoading = view.findViewById(R.id.short_view_loading_overlay)
overlayLoadingSpinner = view.findViewById(R.id.short_view_loader) overlayLoadingSpinner = view.findViewById(R.id.short_view_loader)
overlayQualityContainer = view.findViewById(R.id.shorts_quality_overview) overlayQualityContainer = view.findViewById(R.id.shorts_quality_overview)
sourcesButton.setOnClickListener {
sourcesButton.playSoundEffect(SoundEffectConstants.CLICK)
navigate<SourcesFragment>()
}
setLoading(true) setLoading(true)
Logger.i(TAG, "Creating adapter") Logger.i(TAG, "Creating adapter")
@ -140,9 +152,11 @@ class ShortsFragment : MainFragment() {
loadPagerTask!!.success { loadPagerTask!!.success {
setLoading(false) setLoading(false)
updateZeroState()
} }
} else { } else {
setLoading(false) setLoading(false)
updateZeroState()
} }
viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
@ -186,6 +200,14 @@ class ShortsFragment : MainFragment() {
}) })
} }
private fun updateZeroState() {
if (mainShorts.isEmpty()) {
zeroState.visibility = View.VISIBLE
} else {
zeroState.visibility = View.GONE
}
}
private fun nextPage() { private fun nextPage() {
nextPageTask?.cancel() nextPageTask?.cancel()
@ -290,7 +312,7 @@ class ShortsFragment : MainFragment() {
private val inflater: LayoutInflater, private val inflater: LayoutInflater,
private val fragment: MainFragment, private val fragment: MainFragment,
private val overlayQualityContainer: FrameLayout, private val overlayQualityContainer: FrameLayout,
private val isChannelShortsMode: () -> Boolean, private val isChannelShortsMode: () -> Boolean,
private val onNearEnd: () -> Unit, private val onNearEnd: () -> Unit,
) : RecyclerView.Adapter<CustomViewHolder>() { ) : RecyclerView.Adapter<CustomViewHolder>() {
val onResetTriggered = Event0() val onResetTriggered = Event0()
@ -300,8 +322,7 @@ class ShortsFragment : MainFragment() {
@OptIn(UnstableApi::class) @OptIn(UnstableApi::class)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
val shortView = val shortView = ShortView(inflater, fragment, overlayQualityContainer)
ShortView(inflater, fragment, overlayQualityContainer)
shortView.onResetTriggered.subscribe { shortView.onResetTriggered.subscribe {
onResetTriggered.emit() onResetTriggered.emit()
} }

View file

@ -28,6 +28,62 @@
app:srcCompat="@drawable/ic_loader_animated" /> app:srcCompat="@drawable/ic_loader_animated" />
</FrameLayout> </FrameLayout>
<!-- zero state -->
<LinearLayout
android:id="@+id/zero_state"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginHorizontal="24dp"
android:orientation="vertical"
android:visibility="gone">
<ImageView
android:id="@+id/icon"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginBottom="10dp"
android:importantForAccessibility="no"
android:scaleType="fitCenter"
android:src="@drawable/ic_help" />
<TextView
android:id="@+id/text_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:fontFamily="@font/inter_bold"
android:gravity="center"
android:text="@string/no_results"
android:textColor="@color/white"
android:textSize="22dp" />
<TextView
android:id="@+id/text_centered"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="10dp"
android:fontFamily="@font/inter_regular"
android:gravity="center"
android:text="@string/no_results_shorts"
android:textColor="@color/gray_ac"
android:textSize="13dp" />
<com.futo.platformplayer.views.buttons.BigButton
android:id="@+id/sources_button"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:buttonIcon="@drawable/ic_creators"
app:buttonSubText="Go to the sources tab"
app:buttonText="Sources" />
</LinearLayout>
<FrameLayout <FrameLayout
android:id="@+id/shorts_quality_overview" android:id="@+id/shorts_quality_overview"
android:layout_width="match_parent" android:layout_width="match_parent"

View file

@ -87,6 +87,8 @@
<string name="these_creators_not_in_group">These creators are not in this group.</string> <string name="these_creators_not_in_group">These creators are not in this group.</string>
<string name="disabled">Disabled</string> <string name="disabled">Disabled</string>
<string name="watch_later">Watch Later</string> <string name="watch_later">Watch Later</string>
<string name="no_results">Nothing to see here</string>
<string name="no_results_shorts">The enabled sources do not have any short video results.</string>
<string name="create">Create</string> <string name="create">Create</string>
<string name="ok">OK</string> <string name="ok">OK</string>
<string name="yes">Yes</string> <string name="yes">Yes</string>