From cac8a8fde4f338c31428d5947e22c69d1fdb9fb6 Mon Sep 17 00:00:00 2001 From: Kai Date: Thu, 10 Jul 2025 09:30:42 -0500 Subject: [PATCH] add back button when in channel shorts hide refresh button when in channel shorts prevent main player being open when viewing shorts show info toast when long pressing refresh button switch bottom bar button ids back to their original values Changelog: changed --- .../platformplayer/activities/MainActivity.kt | 4 - .../bottombar/MenuBottomBarFragment.kt | 8 +- .../fragment/mainactivity/main/ShortView.kt | 193 ++++++------------ .../mainactivity/main/ShortsFragment.kt | 10 +- .../main/res/layout/view_short_overlay.xml | 40 ++++ app/src/stable/assets/sources/dailymotion | 2 +- 6 files changed, 118 insertions(+), 139 deletions(-) diff --git a/app/src/main/java/com/futo/platformplayer/activities/MainActivity.kt b/app/src/main/java/com/futo/platformplayer/activities/MainActivity.kt index ec89eac1..6d68bb18 100644 --- a/app/src/main/java/com/futo/platformplayer/activities/MainActivity.kt +++ b/app/src/main/java/com/futo/platformplayer/activities/MainActivity.kt @@ -353,10 +353,6 @@ class MainActivity : AppCompatActivity, IWithResultLauncher { _fragBrowser = BrowserFragment.newInstance(); - _fragShorts.onShownEvent.subscribe { - _fragVideoDetail.closeVideoDetails() - }; - //Overlays _fragVideoDetail = VideoDetailFragment.newInstance(); //Overlay Init diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/bottombar/MenuBottomBarFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/bottombar/MenuBottomBarFragment.kt index b69082ae..f6e57c26 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/bottombar/MenuBottomBarFragment.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/bottombar/MenuBottomBarFragment.kt @@ -392,13 +392,13 @@ class MenuBottomBarFragment : MainActivityFragment() { ButtonDefinition(2, R.drawable.ic_creators, R.drawable.ic_creators_filled, R.string.creators, canToggle = false, { it.currentMain is CreatorsFragment }, { it.navigate(withHistory = false) }), ButtonDefinition(3, R.drawable.ic_sources, R.drawable.ic_sources_filled, R.string.sources, canToggle = false, { it.currentMain is SourcesFragment }, { it.navigate(withHistory = false) }), ButtonDefinition(4, R.drawable.ic_playlist, R.drawable.ic_playlist_filled, R.string.playlists, canToggle = false, { it.currentMain is PlaylistsFragment }, { it.navigate(withHistory = false) }), - ButtonDefinition(5, R.drawable.ic_smart_display, R.drawable.ic_smart_display_filled, R.string.shorts, canToggle = true, { it.currentMain is ShortsFragment && !(it.currentMain as ShortsFragment).isChannelShortsMode }, { it.navigate(withHistory = false) }), - ButtonDefinition(6, R.drawable.ic_history, R.drawable.ic_history, R.string.history, canToggle = false, { it.currentMain is HistoryFragment }, { it.navigate(withHistory = false) }), - ButtonDefinition(7, R.drawable.ic_download, R.drawable.ic_download, R.string.downloads, canToggle = false, { it.currentMain is DownloadsFragment }, { it.navigate(withHistory = false) }), + ButtonDefinition(11, R.drawable.ic_smart_display, R.drawable.ic_smart_display_filled, R.string.shorts, canToggle = true, { it.currentMain is ShortsFragment && !(it.currentMain as ShortsFragment).isChannelShortsMode }, { it.navigate(withHistory = false) }), + ButtonDefinition(5, R.drawable.ic_history, R.drawable.ic_history, R.string.history, canToggle = false, { it.currentMain is HistoryFragment }, { it.navigate(withHistory = false) }), + ButtonDefinition(6, R.drawable.ic_download, R.drawable.ic_download, R.string.downloads, canToggle = false, { it.currentMain is DownloadsFragment }, { it.navigate(withHistory = false) }), ButtonDefinition(8, R.drawable.ic_chat, R.drawable.ic_chat_filled, R.string.comments, canToggle = true, { it.currentMain is CommentsFragment }, { it.navigate(withHistory = false) }), ButtonDefinition(9, R.drawable.ic_subscriptions, R.drawable.ic_subscriptions_filled, R.string.subscription_group_menu, canToggle = true, { it.currentMain is SubscriptionGroupListFragment }, { it.navigate(withHistory = false) }), ButtonDefinition(10, R.drawable.ic_help_square, R.drawable.ic_help_square_fill, R.string.tutorials, canToggle = true, { it.currentMain is TutorialFragment }, { it.navigate(withHistory = false) }), - ButtonDefinition(11, R.drawable.ic_settings, R.drawable.ic_settings_filled, R.string.settings, canToggle = false, { false }, { + ButtonDefinition(7, R.drawable.ic_settings, R.drawable.ic_settings_filled, R.string.settings, canToggle = false, { false }, { val c = it.context ?: return@ButtonDefinition; Logger.i(TAG, "settings preventPictureInPicture()"); it.requireFragment().preventPictureInPicture(); diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/ShortView.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/ShortView.kt index d107f388..4db612ca 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/ShortView.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/ShortView.kt @@ -21,6 +21,7 @@ import android.widget.FrameLayout import android.widget.ImageView import android.widget.LinearLayout import android.widget.TextView +import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.graphics.drawable.toDrawable import androidx.core.net.toUri import androidx.lifecycle.lifecycleScope @@ -122,6 +123,9 @@ class ShortView : FrameLayout { private val videoTitle: TextView private val platformIndicator: PlatformIndicator + private val backButton: MaterialButton + private val backButtonContainer: ConstraintLayout + private val likeContainer: FrameLayout private val dislikeContainer: FrameLayout private val likeButton: MaterialButton @@ -132,6 +136,7 @@ class ShortView : FrameLayout { private val commentsButton: MaterialButton private val shareButton: MaterialButton private val refreshButton: MaterialButton + private val refreshButtonContainer: View private val qualityButton: MaterialButton private val playPauseOverlay: FrameLayout @@ -180,129 +185,7 @@ class ShortView : FrameLayout { dislikeCount.text = value.toString() } - // Required constructor for XML inflation - constructor(context: Context) : super(context) { - inflate(context, R.layout.view_short, this) - player = findViewById(R.id.short_player) - - channelInfo = findViewById(R.id.channel_info) - creatorThumbnail = findViewById(R.id.creator_thumbnail) - channelName = findViewById(R.id.channel_name) - videoTitle = findViewById(R.id.video_title) - platformIndicator = findViewById(R.id.short_platform_indicator) - - likeContainer = findViewById(R.id.like_container) - dislikeContainer = findViewById(R.id.dislike_container) - likeButton = findViewById(R.id.like_button) - likeCount = findViewById(R.id.like_count) - dislikeButton = findViewById(R.id.dislike_button) - dislikeCount = findViewById(R.id.dislike_count) - - commentsButton = findViewById(R.id.comments_button) - shareButton = findViewById(R.id.share_button) - refreshButton = findViewById(R.id.refresh_button) - qualityButton = findViewById(R.id.quality_button) - - playPauseOverlay = findViewById(R.id.play_pause_overlay) - playPauseIcon = findViewById(R.id.play_pause_icon) - - overlayLoading = findViewById(R.id.short_view_loading_overlay) - overlayLoadingSpinner = findViewById(R.id.short_view_loader) - - init() - } - - // Required constructor for XML inflation with attributes - constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { - inflate(context, R.layout.view_short, this) - player = findViewById(R.id.short_player) - - channelInfo = findViewById(R.id.channel_info) - creatorThumbnail = findViewById(R.id.creator_thumbnail) - channelName = findViewById(R.id.channel_name) - videoTitle = findViewById(R.id.video_title) - platformIndicator = findViewById(R.id.short_platform_indicator) - - likeContainer = findViewById(R.id.like_container) - dislikeContainer = findViewById(R.id.dislike_container) - likeButton = findViewById(R.id.like_button) - likeCount = findViewById(R.id.like_count) - dislikeButton = findViewById(R.id.dislike_button) - dislikeCount = findViewById(R.id.dislike_count) - - commentsButton = findViewById(R.id.comments_button) - shareButton = findViewById(R.id.share_button) - refreshButton = findViewById(R.id.refresh_button) - qualityButton = findViewById(R.id.quality_button) - - playPauseOverlay = findViewById(R.id.play_pause_overlay) - playPauseIcon = findViewById(R.id.play_pause_icon) - - overlayLoading = findViewById(R.id.short_view_loading_overlay) - overlayLoadingSpinner = findViewById(R.id.short_view_loader) - - init() - } - - // Required constructor for XML inflation with attributes and style - constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { - inflate(context, R.layout.view_short, this) - player = findViewById(R.id.short_player) - - channelInfo = findViewById(R.id.channel_info) - creatorThumbnail = findViewById(R.id.creator_thumbnail) - channelName = findViewById(R.id.channel_name) - videoTitle = findViewById(R.id.video_title) - platformIndicator = findViewById(R.id.short_platform_indicator) - - likeContainer = findViewById(R.id.like_container) - dislikeContainer = findViewById(R.id.dislike_container) - likeButton = findViewById(R.id.like_button) - likeCount = findViewById(R.id.like_count) - dislikeButton = findViewById(R.id.dislike_button) - dislikeCount = findViewById(R.id.dislike_count) - - commentsButton = findViewById(R.id.comments_button) - shareButton = findViewById(R.id.share_button) - refreshButton = findViewById(R.id.refresh_button) - qualityButton = findViewById(R.id.quality_button) - - playPauseOverlay = findViewById(R.id.play_pause_overlay) - playPauseIcon = findViewById(R.id.play_pause_icon) - - overlayLoading = findViewById(R.id.short_view_loading_overlay) - overlayLoadingSpinner = findViewById(R.id.short_view_loader) - - init() - } - - constructor(inflater: LayoutInflater, fragment: MainFragment, overlayQualityContainer: FrameLayout) : super(inflater.context) { - inflater.inflate(R.layout.view_short, this, true) - player = findViewById(R.id.short_player) - - channelInfo = findViewById(R.id.channel_info) - creatorThumbnail = findViewById(R.id.creator_thumbnail) - channelName = findViewById(R.id.channel_name) - videoTitle = findViewById(R.id.video_title) - platformIndicator = findViewById(R.id.short_platform_indicator) - - likeContainer = findViewById(R.id.like_container) - dislikeContainer = findViewById(R.id.dislike_container) - likeButton = findViewById(R.id.like_button) - likeCount = findViewById(R.id.like_count) - dislikeButton = findViewById(R.id.dislike_button) - dislikeCount = findViewById(R.id.dislike_count) - - commentsButton = findViewById(R.id.comments_button) - shareButton = findViewById(R.id.share_button) - refreshButton = findViewById(R.id.refresh_button) - qualityButton = findViewById(R.id.quality_button) - - playPauseOverlay = findViewById(R.id.play_pause_overlay) - playPauseIcon = findViewById(R.id.play_pause_icon) - - overlayLoading = findViewById(R.id.short_view_loading_overlay) - overlayLoadingSpinner = findViewById(R.id.short_view_loader) + constructor(inflater: LayoutInflater, fragment: MainFragment, overlayQualityContainer: FrameLayout) : this(inflater.context) { this.overlayQualityContainer = overlayQualityContainer layoutParams = LayoutParams( @@ -311,11 +194,46 @@ class ShortView : FrameLayout { this.mainFragment = fragment bottomSheet.mainFragment = fragment - - init() } - private fun init() { + // Required constructor for XML inflation + constructor(context: Context) : this(context, null, null) + + // Required constructor for XML inflation with attributes + constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, null) + + // Required constructor for XML inflation with attributes and style + constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int? = null) : super( + context, attrs, defStyleAttr ?: 0 + ) { + // Inflate the layout once here + inflate(context, R.layout.view_short, this) + + // Initialize all val properties using findViewById + player = findViewById(R.id.short_player) + channelInfo = findViewById(R.id.channel_info) + creatorThumbnail = findViewById(R.id.creator_thumbnail) + channelName = findViewById(R.id.channel_name) + videoTitle = findViewById(R.id.video_title) + platformIndicator = findViewById(R.id.short_platform_indicator) + backButton = findViewById(R.id.back_button) + backButtonContainer = findViewById(R.id.back_button_container) + likeContainer = findViewById(R.id.like_container) + dislikeContainer = findViewById(R.id.dislike_container) + likeButton = findViewById(R.id.like_button) + likeCount = findViewById(R.id.like_count) + dislikeButton = findViewById(R.id.dislike_button) + dislikeCount = findViewById(R.id.dislike_count) + commentsButton = findViewById(R.id.comments_button) + shareButton = findViewById(R.id.share_button) + refreshButton = findViewById(R.id.refresh_button) + refreshButtonContainer = findViewById(R.id.refresh_button_container) + qualityButton = findViewById(R.id.quality_button) + playPauseOverlay = findViewById(R.id.play_pause_overlay) + playPauseIcon = findViewById(R.id.play_pause_icon) + overlayLoading = findViewById(R.id.short_view_loading_overlay) + overlayLoadingSpinner = findViewById(R.id.short_view_loader) + player.setOnClickListener { if (player.activelyPlaying) { player.pause() @@ -344,6 +262,11 @@ class ShortView : FrameLayout { channelName.text = it?.author?.name } + backButton.setOnClickListener { + playSoundEffect(SoundEffectConstants.CLICK) + mainFragment.closeSegment() + } + channelInfo.setOnClickListener { playSoundEffect(SoundEffectConstants.CLICK) mainFragment.navigate(video?.author) @@ -378,6 +301,11 @@ class ShortView : FrameLayout { onResetTriggered.emit() } + refreshButton.setOnLongClickListener { + UIDialogs.toast(context, "Reload all platform shorts pagers") + false + } + qualityButton.setOnClickListener { playSoundEffect(SoundEffectConstants.CLICK) showVideoSettings() @@ -692,12 +620,23 @@ class ShortView : FrameLayout { this.overlayQualityContainer = overlayQualityContainer } - fun changeVideo(video: IPlatformVideo) { + fun changeVideo(video: IPlatformVideo, isChannelShortsMode: Boolean) { if (this.video?.url == video.url) { return } this.video = video + refreshButtonContainer.visibility = if (isChannelShortsMode) { + GONE + } else { + VISIBLE + } + backButtonContainer.visibility = if (isChannelShortsMode) { + VISIBLE + } else { + GONE + } + loadVideo(video.url) } diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/ShortsFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/ShortsFragment.kt index 6b00c3b7..153986c7 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/ShortsFragment.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/ShortsFragment.kt @@ -14,6 +14,7 @@ import androidx.recyclerview.widget.RecyclerView import androidx.viewpager2.widget.ViewPager2 import com.futo.platformplayer.R import com.futo.platformplayer.UIDialogs +import com.futo.platformplayer.activities.MainActivity import com.futo.platformplayer.api.media.models.video.IPlatformVideo import com.futo.platformplayer.api.media.structures.IPager import com.futo.platformplayer.constructs.Event0 @@ -58,6 +59,7 @@ class ShortsFragment : MainFragment() { // we just completely reset the data structure so we want to tell the adapter that @SuppressLint("NotifyDataSetChanged") override fun onShownWithView(parameter: Any?, isBack: Boolean) { + (activity as MainActivity?)?.getFragment()?.closeVideoDetails() super.onShownWithView(parameter, isBack) if (parameter is Triple<*, *, *>) { @@ -114,7 +116,7 @@ class ShortsFragment : MainFragment() { Logger.i(TAG, "Creating adapter") val customViewAdapter = - CustomViewAdapter(currentShorts, layoutInflater, this@ShortsFragment, overlayQualityContainer) { + CustomViewAdapter(currentShorts, layoutInflater, this@ShortsFragment, overlayQualityContainer, { isChannelShortsMode }) { if (!currentShortsPager!!.hasMorePages()) { return@CustomViewAdapter } @@ -288,6 +290,7 @@ class ShortsFragment : MainFragment() { private val inflater: LayoutInflater, private val fragment: MainFragment, private val overlayQualityContainer: FrameLayout, + private val isChannelShortsMode: () -> Boolean, private val onNearEnd: () -> Unit, ) : RecyclerView.Adapter() { val onResetTriggered = Event0() @@ -297,7 +300,8 @@ class ShortsFragment : MainFragment() { @OptIn(UnstableApi::class) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder { - val shortView = ShortView(inflater, fragment, overlayQualityContainer) + val shortView = + ShortView(inflater, fragment, overlayQualityContainer) shortView.onResetTriggered.subscribe { onResetTriggered.emit() } @@ -306,7 +310,7 @@ class ShortsFragment : MainFragment() { @OptIn(UnstableApi::class) override fun onBindViewHolder(holder: CustomViewHolder, position: Int) { - holder.shortView.changeVideo(videos[position]) + holder.shortView.changeVideo(videos[position], isChannelShortsMode()) if (position == itemCount - 1) { onNearEnd() diff --git a/app/src/main/res/layout/view_short_overlay.xml b/app/src/main/res/layout/view_short_overlay.xml index 2806c69d..b55e49e0 100644 --- a/app/src/main/res/layout/view_short_overlay.xml +++ b/app/src/main/res/layout/view_short_overlay.xml @@ -10,6 +10,45 @@ android:layout_width="match_parent" android:layout_height="match_parent"> + + + + + + + +