refactor shorts code

Changelog: changed
This commit is contained in:
Kai 2025-04-08 17:58:31 -05:00
parent bd87a47551
commit a1c2d19daf
No known key found for this signature in database
11 changed files with 545 additions and 802 deletions

View File

@ -16,11 +16,11 @@ import com.futo.platformplayer.R
import com.futo.platformplayer.api.media.models.video.IPlatformVideo
import com.futo.platformplayer.api.media.structures.IPager
import com.futo.platformplayer.constructs.Event0
import com.futo.platformplayer.logging.Logger
import com.futo.platformplayer.states.StatePlatform
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@ -43,9 +43,6 @@ class ShortsFragment : MainFragment() {
private lateinit var overlayLoadingSpinner: ImageView
private lateinit var overlayQualityContainer: FrameLayout
private lateinit var customViewAdapter: CustomViewAdapter
private val urls = listOf(
"https://youtube.com/shorts/fHU6dfPHT-o?si=TVCYnt_mvAxWYACZ", "https://youtube.com/shorts/j9LQ0c4MyGk?si=FVlr90UD42y1ZIO0", "https://youtube.com/shorts/Q8LndW9YZvQ?si=mDrSsm-3Uq7IEXAT", "https://www.youtube.com/watch?v=MXHSS-7XcBc", "https://youtube.com/shorts/OIS5qHDOOzs?si=RGYeaAH9M-TRuZSr", "https://youtube.com/shorts/1Cp6EbLWVnI?si=N4QqytC48CTnfJra", "https://youtube.com/shorts/fHU6dfPHT-o?si=TVCYnt_mvAxWYACZ", "https://youtube.com/shorts/j9LQ0c4MyGk?si=FVlr90UD42y1ZIO0", "https://youtube.com/shorts/Q8LndW9YZvQ?si=mDrSsm-3Uq7IEXAT", "https://youtube.com/shorts/OIS5qHDOOzs?si=RGYeaAH9M-TRuZSr", "https://youtube.com/shorts/1Cp6EbLWVnI?si=N4QqytC48CTnfJra"
)
init {
loadPager()
@ -60,10 +57,10 @@ class ShortsFragment : MainFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewPager = view.findViewById(R.id.viewPager)
viewPager = view.findViewById(R.id.view_pager)
overlayLoading = view.findViewById(R.id.short_view_loading_overlay)
overlayLoadingSpinner = view.findViewById(R.id.short_view_loader)
overlayQualityContainer = view.findViewById(R.id.videodetail_quality_overview)
overlayQualityContainer = view.findViewById(R.id.shorts_quality_overview)
setLoading(true)
@ -72,7 +69,9 @@ class ShortsFragment : MainFragment() {
}
loadPagerJob!!.invokeOnCompletion {
customViewAdapter = CustomViewAdapter(videos, layoutInflater, this@ShortsFragment, overlayQualityContainer) {
Logger.i(TAG, "Creating adapter")
customViewAdapter =
CustomViewAdapter(videos, layoutInflater, this@ShortsFragment, overlayQualityContainer) {
if (!shortsPager!!.hasMorePages()) {
return@CustomViewAdapter
}
@ -88,7 +87,6 @@ class ShortsFragment : MainFragment() {
val viewPager = viewPager!!
viewPager.adapter = customViewAdapter
// TODO something is laggy sometimes when swiping between videos
viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
@OptIn(UnstableApi::class)
override fun onPageSelected(position: Int) {
@ -96,7 +94,8 @@ class ShortsFragment : MainFragment() {
adapter.previousShownView?.stop()
adapter.previousShownView = null
// viewPager.post {
// the post prevents lag when swiping
viewPager.post {
val recycler = (viewPager.getChildAt(0) as RecyclerView)
val viewHolder =
recycler.findViewHolderForAdapterPosition(position) as CustomViewHolder?
@ -108,10 +107,8 @@ class ShortsFragment : MainFragment() {
focusedView.play()
adapter.previousShownView = focusedView
}
// }
}
}
})
setLoading(false)
}
@ -154,12 +151,9 @@ class ShortsFragment : MainFragment() {
viewPager?.currentItem = 0
loadPagerJob = CoroutineScope(Dispatchers.Main).launch {
// delay(5000)
val pager = try {
withContext(Dispatchers.IO) {
StatePlatform.instance.getShorts()
// StatePlatform.instance.getHome()
// as IPager<IPlatformVideo>
}
} catch (_: CancellationException) {
return@launch

View File

@ -19,7 +19,9 @@ class WebviewOverlay : LinearLayout {
inflate(context, R.layout.overlay_webview, this)
_topbar = findViewById(R.id.topbar);
_webview = findViewById(R.id.webview);
if (!isInEditMode){
_webview.settings.javaScriptEnabled = true;
}
_topbar.onClose.subscribe(this, onClose::emit);
}

View File

@ -2,28 +2,25 @@ package com.futo.platformplayer.views.video
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Bitmap
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.animation.LinearInterpolator
import androidx.annotation.OptIn
import androidx.media3.common.C
import androidx.media3.common.PlaybackParameters
import androidx.media3.common.Player
import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.DefaultLoadControl
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.exoplayer.upstream.DefaultAllocator
import androidx.media3.ui.DefaultTimeBar
import androidx.media3.ui.PlayerView
import androidx.media3.ui.TimeBar
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
import com.futo.platformplayer.R
import com.futo.platformplayer.Settings
import com.futo.platformplayer.api.media.models.video.IPlatformVideoDetails
import com.futo.platformplayer.helpers.VideoHelper
import com.futo.platformplayer.logging.Logger
import com.futo.platformplayer.states.StatePlayer
import com.futo.platformplayer.video.PlayerManager
@UnstableApi
class FutoShortPlayer(context: Context, attrs: AttributeSet? = null) :
@ -35,23 +32,9 @@ class FutoShortPlayer(context: Context, attrs: AttributeSet? = null) :
}
private var playerAttached = false
// private set;
private val videoView: PlayerView
private val progressBar: DefaultTimeBar
private val loadArtwork = object : CustomTarget<Bitmap>() {
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
setArtwork(BitmapDrawable(resources, resource))
}
override fun onLoadCleared(placeholder: Drawable?) {
setArtwork(null)
}
}
private val player = StatePlayer.instance.getShortPlayerOrCreate(context)
private lateinit var player: PlayerManager
private var progressAnimator: ValueAnimator = createProgressBarAnimator()
private var playerEventListener = object : Player.Listener {
@ -69,8 +52,7 @@ class FutoShortPlayer(context: Context, attrs: AttributeSet? = null) :
if (player.isPlaying) {
if (progressAnimator.isPaused) {
progressAnimator.resume()
}
else if (!progressAnimator.isStarted) {
} else if (!progressAnimator.isStarted) {
progressAnimator.start()
}
} else {
@ -84,10 +66,13 @@ class FutoShortPlayer(context: Context, attrs: AttributeSet? = null) :
init {
LayoutInflater.from(context).inflate(R.layout.view_short_player, this, true)
videoView = findViewById(R.id.video_player)
progressBar = findViewById(R.id.video_player_progress_bar)
videoView = findViewById(R.id.short_player_view)
progressBar = findViewById(R.id.short_player_progress_bar)
if (!isInEditMode) {
player = StatePlayer.instance.getShortPlayerOrCreate(context)
player.player.repeatMode = Player.REPEAT_MODE_ONE
}
progressBar.addListener(object : TimeBar.OnScrubListener {
override fun onScrubStart(timeBar: TimeBar, position: Long) {
@ -148,30 +133,6 @@ class FutoShortPlayer(context: Context, attrs: AttributeSet? = null) :
player.detach()
}
fun setPreview(video: IPlatformVideoDetails) {
if (video.live != null) {
setSource(video.live, null, play = true, keepSubtitles = false)
} else {
val videoSource =
VideoHelper.selectBestVideoSource(video.video, Settings.instance.playback.getPreferredPreviewQualityPixelCount(), PREFERED_VIDEO_CONTAINERS)
val audioSource =
VideoHelper.selectBestAudioSource(video.video, PREFERED_AUDIO_CONTAINERS, Settings.instance.playback.getPrimaryLanguage(context))
if (videoSource == null && audioSource != null) {
val thumbnail = video.thumbnails.getHQThumbnail()
if (!thumbnail.isNullOrBlank()) {
Glide.with(videoView).asBitmap().load(thumbnail).into(loadArtwork)
} else {
Glide.with(videoView).clear(loadArtwork)
setArtwork(null)
}
} else {
Glide.with(videoView).clear(loadArtwork)
}
setSource(videoSource, audioSource, play = true, keepSubtitles = false)
}
}
@OptIn(UnstableApi::class)
fun setArtwork(drawable: Drawable?) {
if (drawable != null) {
@ -194,9 +155,4 @@ class FutoShortPlayer(context: Context, attrs: AttributeSet? = null) :
val param = PlaybackParameters(playbackRate)
exoPlayer?.playbackParameters = param
}
// TODO remove stub
fun hideControls(stub: Boolean) {
}
}

View File

@ -72,7 +72,7 @@ import kotlin.math.abs
abstract class FutoVideoPlayerBase : ConstraintLayout {
private val TAG = "FutoVideoPlayerBase"
private val TEMP_DIRECTORY = StateApp.instance.getTempDirectory();
// private val TEMP_DIRECTORY = StateApp.instance.getTempDirectory();
private var _mediaSource: MediaSource? = null;

View File

@ -5,7 +5,7 @@
android:layout_height="match_parent">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager"
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" />
@ -29,7 +29,7 @@
</FrameLayout>
<FrameLayout
android:id="@+id/videodetail_quality_overview"
android:id="@+id/shorts_quality_overview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:elevation="100dp"

View File

@ -15,13 +15,8 @@
android:layout_height="wrap_content"
android:paddingBottom="0dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:id="@+id/contentContainer"
android:id="@+id/content_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
@ -60,7 +55,7 @@
android:layout_marginEnd="10dp"
android:fontFamily="@font/inter_medium"
android:textColor="@color/white"
android:textSize="17dp"
android:textSize="17sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/layout_title_right"
app:layout_constraintTop_toTopOf="parent"
@ -73,7 +68,7 @@
android:layout_marginEnd="10dp"
android:fontFamily="@font/inter_regular"
android:textColor="#ACACAC"
android:textSize="10dp"
android:textSize="11sp"
app:layout_constraintLeft_toLeftOf="@id/videodetail_title"
app:layout_constraintRight_toLeftOf="@id/layout_title_right"
app:layout_constraintTop_toBottomOf="@id/videodetail_title"
@ -112,17 +107,18 @@
android:id="@+id/image_like_icon"
android:layout_width="14dp"
android:layout_height="14dp"
android:contentDescription="@string/cd_image_like_icon"
app:srcCompat="@drawable/ic_thumb_up"
app:tint="#ACACAC" />
<TextView
android:id="@+id/text_likes"
android:layout_width="wrap_content"
android:layout_height="18dp"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:gravity="center_vertical"
android:textColor="#ACACAC"
android:textSize="10dp"
android:textSize="11sp"
tools:text="500K" />
</LinearLayout>
@ -136,17 +132,18 @@
android:layout_width="14dp"
android:layout_height="14dp"
android:layout_marginTop="2dp"
android:contentDescription="@string/cd_image_dislike_icon"
app:srcCompat="@drawable/ic_thumb_down"
app:tint="#ACACAC" />
<TextView
android:id="@+id/text_dislikes"
android:layout_width="wrap_content"
android:layout_height="18dp"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:gravity="center_vertical"
android:textColor="#ACACAC"
android:textSize="10dp"
android:textSize="11sp"
tools:text="500K" />
</LinearLayout>
</LinearLayout>
@ -156,24 +153,15 @@
</LinearLayout>
<!--Channel/Subscribe Segment-->
<androidx.constraintlayout.widget.ConstraintLayout
<LinearLayout
android:id="@+id/videodetail_channel_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="14dp"
android:layout_marginTop="10dp"
android:layout_marginTop="17dp"
android:layout_marginRight="14dp"
android:layout_marginBottom="10dp">
<LinearLayout
android:id="@+id/videodetail_channel_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="7dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/button_subscribe"
app:layout_constraintTop_toTopOf="parent">
android:layout_marginBottom="10dp"
android:orientation="horizontal">
<com.futo.platformplayer.views.others.CreatorThumbnail
android:id="@+id/creator_thumbnail"
@ -196,8 +184,8 @@
android:layout_gravity="center"
android:ellipsize="end"
android:maxLines="1"
android:paddingEnd="10dp"
android:textColor="@color/white"
android:textSize="11sp"
tools:text="Channel Name" />
<TextView
@ -205,26 +193,15 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:textColor="#ACACAC"
android:textSize="9sp"
android:textSize="11sp"
tools:text="" />
</LinearLayout>
</LinearLayout>
<com.futo.platformplayer.views.subscriptions.SubscribeButton
android:id="@+id/button_subscribe"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!--Description-->
<LinearLayout
android:id="@+id/videodetail_description_container"
@ -234,6 +211,7 @@
android:layout_marginRight="14dp"
android:animateLayoutChanges="true"
android:background="@drawable/background_videodetail_description"
android:gravity="center"
android:orientation="vertical"
android:paddingLeft="12dp"
android:paddingTop="3dp"
@ -242,15 +220,16 @@
<com.futo.platformplayer.views.behavior.NonScrollingTextView
android:id="@+id/videodetail_description"
android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:background="@color/transparent"
android:fontFamily="@font/inter_light"
android:isScrollContainer="false"
android:maxWidth="500dp"
android:maxLines="3"
android:textColor="@color/white"
android:textSize="11dp"
android:textSize="11sp"
tools:text="@string/lorem_ipsum" />
<TextView
@ -262,8 +241,8 @@
android:fontFamily="@font/inter_regular"
android:text="@string/click_to_read_more"
android:textAlignment="center"
android:textColor="#585656"
android:textSize="12dp" />
android:textColor="#838181"
android:textSize="12sp" />
</LinearLayout>
<com.futo.platformplayer.views.MonetizationView
@ -271,24 +250,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<com.futo.platformplayer.views.videometa.UpNextView
android:id="@+id/up_next"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="15dp"
android:text="@string/live_chat" />
</LinearLayout>
<LinearLayout
android:id="@+id/layout_change_bottom_section"
android:layout_width="match_parent"
@ -298,59 +259,37 @@
android:layout_marginRight="14dp"
android:layout_marginBottom="10dp"
android:background="@drawable/background_videodetail_description"
android:gravity="center"
android:orientation="horizontal">
<Button
android:id="@+id/button_polycentric"
android:layout_width="0dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="90dp"
android:background="?android:attr/selectableItemBackground"
android:ellipsize="marquee"
android:lines="1"
android:maxWidth="100dp"
android:padding="10dp"
android:text="Polycentric"
android:text="@string/polycentric"
android:textColor="#fff"
android:textSize="10dp" />
android:textSize="11sp" />
<Button
android:id="@+id/button_platform"
android:layout_width="0dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="?android:attr/selectableItemBackground"
android:ellipsize="marquee"
android:lines="1"
android:maxWidth="100dp"
android:padding="10dp"
android:text="Platform"
android:text="@string/platform"
android:textColor="#fff"
android:textSize="10dp" />
<Button
android:id="@+id/button_recommended"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="?android:attr/selectableItemBackground"
android:ellipsize="marquee"
android:lines="1"
android:padding="10dp"
android:text="Recommended"
android:textColor="#fff"
android:textSize="10dp"
android:visibility="gone" />
android:textSize="11sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/layout_recommended"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:gravity="center_horizontal"
android:orientation="vertical"
android:visibility="gone"></LinearLayout>
<com.futo.platformplayer.views.comments.AddCommentView
android:id="@+id/add_comment_view"
android:layout_width="match_parent"
@ -361,7 +300,6 @@
android:layout_marginBottom="12dp" />
</LinearLayout>
<com.futo.platformplayer.views.segments.CommentsList
android:id="@+id/comments_list"
android:layout_width="match_parent"
@ -378,24 +316,12 @@
android:layout_height="match_parent"
android:visibility="gone" />
<com.futo.platformplayer.views.overlays.LiveChatOverlay
android:id="@+id/videodetail_container_livechat"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
<com.futo.platformplayer.views.overlays.WebviewOverlay
android:id="@+id/videodetail_container_webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
<com.futo.platformplayer.views.overlays.QueueEditorOverlay
android:id="@+id/videodetail_container_queue"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
<com.futo.platformplayer.views.overlays.RepliesOverlay
android:id="@+id/videodetail_container_replies"
android:layout_width="match_parent"
@ -409,4 +335,3 @@
android:visibility="gone" />
</FrameLayout>
</LinearLayout>
</LinearLayout>

View File

@ -16,18 +16,20 @@
app:layout_constraintTop_toTopOf="parent" />
<androidx.compose.ui.platform.ComposeView
android:id="@+id/compose_view_test_button"
android:id="@+id/shorts_overlay_content_compose_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:elevation="1dp"
app:layout_constraintBottom_toBottomOf="parent" />
<!-- make the overlay clickable to intercept touches-->
<FrameLayout
android:id="@+id/short_view_loading_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#77000000"
android:elevation="4dp"
android:clickable="true"
android:visibility="gone">
<ImageView

View File

@ -3,12 +3,12 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.media3.ui.PlayerView
android:id="@+id/video_player"
android:id="@+id/short_player_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@color/black"
app:default_artwork="@drawable/placeholder_video_thumbnail"
app:layout_constraintBottom_toTopOf="@id/video_player_progress_bar"
app:layout_constraintBottom_toTopOf="@id/short_player_progress_bar"
app:layout_constraintTop_toTopOf="parent"
app:resize_mode="fit"
app:show_buffering="when_playing"
@ -16,7 +16,7 @@
app:use_controller="false" />
<androidx.media3.ui.DefaultTimeBar
android:id="@+id/video_player_progress_bar"
android:id="@+id/short_player_progress_bar"
android:layout_width="match_parent"
android:layout_height="6dp"
app:bar_height="6dp"

View File

@ -172,6 +172,7 @@
<string name="copy">Copy</string>
<string name="copy_your_identity_to_clipboard">Copy your identity to clipboard</string>
<string name="polycentric">Polycentric</string>
<string name="platform">Platform</string>
<string name="profile_name">Profile Name</string>
<string name="this_will_be_visible_to_other_users">This will be visible to other users</string>
<string name="create_profile">Create Profile</string>

View File

@ -49,7 +49,7 @@
</style>
<style name="Custom.BottomSheet.Modal.Style" parent="Widget.MaterialComponents.BottomSheet.Modal">
<item name="shapeAppearanceOverlay">@style/Custom.BottomSheet.ShapeAppearance</item>
<!-- force black background while grayjay only has a dark theme-->
<!-- force black background while grayjay only has a dark theme TODO remove when adding support for light mode-->
<item name="backgroundTint">@color/black</item>
</style>
<style name="Custom.BottomSheetDialog.Theme" parent="@style/ThemeOverlay.Material3.BottomSheetDialog">