Keep current player when clicking on timestamp#12254
Conversation
24c2560 to
61432a2
Compare
|
| @Parcelize | ||
| enum class PlayerIntentType : Parcelable { | ||
| Enqueue, | ||
| EnqueueNext, | ||
| TimestampChange, | ||
| AllOthers | ||
| } |
There was a problem hiding this comment.
Enums are serializable, so they can be passed to/retrieved from intents/bundles as serializable objects.
There was a problem hiding this comment.
what’s the difference? I don’t see any.
There was a problem hiding this comment.
I added some suggestions with the relevant changes, so the Parcelable implementation can be removed for this enum.
There was a problem hiding this comment.
| @Parcelize | |
| enum class PlayerIntentType : Parcelable { | |
| Enqueue, | |
| EnqueueNext, | |
| TimestampChange, | |
| AllOthers | |
| } | |
| enum class PlayerIntentType { | |
| Enqueue, | |
| EnqueueNext, | |
| TimestampChange, | |
| AllOthers | |
| } |
There was a problem hiding this comment.
but why? I don’t see a big difference and like Parcellable more than Serializable
| // by long pressing the video detail fragment, playlist or channel controls | ||
| return getPlayerIntent(context, targetClazz, playQueue, false) | ||
| .putExtra(Player.ENQUEUE, true); | ||
| intent.putExtra(Player.PLAYER_INTENT_TYPE, (Parcelable) PlayerIntentType.TimestampChange); |
There was a problem hiding this comment.
| intent.putExtra(Player.PLAYER_INTENT_TYPE, (Parcelable) PlayerIntentType.TimestampChange); | |
| intent.putExtra(Player.PLAYER_INTENT_TYPE, PlayerIntentType.TimestampChange); |
| final String queueCache = intent.getStringExtra(PLAY_QUEUE_KEY); | ||
| if (queueCache == null) { | ||
|
|
||
| final PlayerIntentType playerIntentType = intent.getParcelableExtra(PLAYER_INTENT_TYPE); |
There was a problem hiding this comment.
| final PlayerIntentType playerIntentType = intent.getParcelableExtra(PLAYER_INTENT_TYPE); | |
| final var playerIntentType = IntentCompat.getSerializableExtra(intent, PLAYER_INTENT_TYPE, PlayerIntentType.class); |
| return; | ||
| } | ||
| case TimestampChange -> { | ||
| final TimestampChangeData dat = intent.getParcelableExtra(PLAYER_INTENT_DATA); |
There was a problem hiding this comment.
| final TimestampChangeData dat = intent.getParcelableExtra(PLAYER_INTENT_DATA); | |
| final var dat = IntentCompat.getParcelableExtra(intent, PLAYER_INTENT_DATA, TimestampChangeData.class); |
61432a2 to
2e92fb1
Compare
The only use of the key was removed in commit 2a2c82e but the handling logic stayed around. So let’s get rid of it.
cf966a7 to
0485817
Compare
Funnily enough, I’m pretty sure that whole comment will be not necessary, because we never check `resumePlayback` on handling the intent anyway.
Okay, so this is the … only? branch in this if-chain that will conditionally fire if `playQueue` *is* `null`, sometimes. This is why the unconditional `initPlayback` in `else` is not passed a `null` in many cases … because `RESUME_PLAYBACK` is `true` and `playQueue` is `null`. It’s gonna be hard to figure out which parts of that are intentional, I say.
We can do this, because:
1. if `playQueue` is not null, we return early
2. if `playQueue` is null and we need to enqueue:
- the only “proper” case that could be triggered is
the `RESUME_PLAYBACK` case, which is never `true` for the queuing
intents, see the comment in `NavigationHelper.enqueueOnPlayer`
- the generic `else` case is degenerate, because it would crash on
`playQueue` being `null`.
This makes some sense, because there is no way to trigger the
enqueueing logic via the UI currently if there is no video playing
yet, in which case `playQueue` is not `null`.
So we need to transform this whole if desaster into a big switch.
The goal here is to convert all player intents to use a single enum with extra data for each case. The queue ones are pretty easy, they don’t carry any extra data. We fall through for everything else for now.
They are just read from the player preferences and don’t influence the branching, no need to read them in the intent parsing logic.
Instead of implicitely reconstructing whether the intent was intended (lol) to be a timestamp change, we create a new kind of intent that *only* sets the data we need to switch to a new timestamp. This means that the logic of what to do (opening a popup player) gets moved from `InternalUrlsHandler.playOnPopup` to the `Player.handleIntent` method, we only pass that we want to jump to a new timestamp. Thus, the stream is now loaded *after* sending the intent instead of before sending. This is somewhat messy right now and still does not fix the issue of queue deletion, but from now on the queue logic should get more straightforward to implement. In the end, everything should be a giant switch. Thus we don’t fall-through anymore, but run the post-setup code manually by calling `handeIntentPost` and then returning.
Fixes #11013 We finally are at the point where we can have good logic around clicking on timestamps. This is pretty straightforward: 1) if we are already playing the stream (usual case), we skip to the correct second directly 2) If we don’t have a queue yet, create a trivial one with the stream 3) If we have a queue, we insert the video as next item and start playing it. The skipping logic in 1) is similar to the one further down in the old optimization block, but will always correctly fire for timestamps now. I copied it because it’s not quite the same code, and moving into a separate method at this stage would complicate the code too much.
In 063dcd4 I falsely claimed that the fallthrough case is always degenerate, but it kinda somehow still worked because if you long-click on e.g. the popup button, it would call enqueue, but if nothing was running yet it would fallthrough to the very last case and start the player with the video. So let’s return to that and add a TODO for further refactoring in the future.
We always need to handleIntentPost otherwise the VideoDetailFragment is not setup correctly.
0485817 to
2937943
Compare
This was always a bit weird, that clicking a timestamp would unconditionally switch to the popup player. With the new enum, it’s trivial to change it to always stay at the selected player now ;)
2937943 to
1723bf0
Compare



one extra commit on top of #12252
What is it?
Description of the changes in your PR
Makes the player stay the same when a timestamp is pressed instead of always opening the popup player.
Before/After Screenshots/Screen Record
newpipe_timestamp_always_opens_popup_player.mp4
newpipe_player_timestamp_stays_the_same.mp4
Fixes the following issue(s)
Relies on the following changes
#12252
APK testing
The APK can be found by going to the "Checks" tab below the title. On the left pane, click on "CI", scroll down to "artifacts" and click "app" to download the zip file which contains the debug APK of this PR. You can find more info and a video demonstration on this wiki page.
Due diligence