Skip to content

Commit fe42206

Browse files
committed
Code cleanup and minimization
* Deduplicated and simplified a lot of code * Fixed ``invalidSeekConditions`` so that it's possible to seek while the player is loading (like currently the case)
1 parent dac47d9 commit fe42206

11 files changed

Lines changed: 185 additions & 477 deletions

File tree

app/src/main/java/org/schabi/newpipe/player/Player.java

Lines changed: 28 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@
5151

5252
import android.animation.Animator;
5353
import android.animation.AnimatorListenerAdapter;
54-
import android.animation.ObjectAnimator;
55-
import android.animation.PropertyValuesHolder;
5654
import android.animation.ValueAnimator;
5755
import android.annotation.SuppressLint;
5856
import android.content.BroadcastReceiver;
@@ -189,8 +187,7 @@
189187
import org.schabi.newpipe.util.external_communication.KoreUtils;
190188
import org.schabi.newpipe.util.external_communication.ShareUtils;
191189
import org.schabi.newpipe.views.ExpandableSurfaceView;
192-
import org.schabi.newpipe.views.player.CircleClipTapView;
193-
import org.schabi.newpipe.views.player.PlayerSeekOverlay;
190+
import org.schabi.newpipe.views.player.PlayerFastSeekOverlay;
194191

195192
import java.io.IOException;
196193
import java.util.ArrayList;
@@ -454,6 +451,8 @@ public void setupFromView(@NonNull final PlayerBinding playerBinding) {
454451
initPlayer(true);
455452
}
456453
initListeners();
454+
455+
setupPlayerSeekOverlay();
457456
}
458457

459458
private void initViews(@NonNull final PlayerBinding playerBinding) {
@@ -530,12 +529,6 @@ private void initListeners() {
530529
binding.resizeTextView.setOnClickListener(this);
531530
binding.playbackLiveSync.setOnClickListener(this);
532531

533-
playerGestureListener = new PlayerGestureListener(this, service);
534-
gestureDetector = new GestureDetectorCompat(context, playerGestureListener);
535-
//noinspection ClickableViewAccessibility
536-
binding.getRoot().setOnTouchListener(playerGestureListener);
537-
setupPlayerSeekOverlay();
538-
539532
binding.queueButton.setOnClickListener(this);
540533
binding.segmentsButton.setOnClickListener(this);
541534
binding.repeatButton.setOnClickListener(this);
@@ -586,26 +579,26 @@ public void onChange(final boolean selfChange) {
586579
v.getPaddingBottom()));
587580
}
588581

582+
/**
583+
* Initializes the Fast-For/Backward overlay.
584+
*/
589585
private void setupPlayerSeekOverlay() {
590-
binding.seekOverlay.showCircle(true)
591-
.circleBackgroundColorInt(CircleClipTapView.COLOR_DARK_TRANSPARENT)
586+
playerGestureListener = new PlayerGestureListener(this, service);
587+
gestureDetector = new GestureDetectorCompat(context, playerGestureListener);
588+
binding.getRoot().setOnTouchListener(playerGestureListener);
589+
590+
binding.fastSeekOverlay
592591
.seekSeconds((int) (retrieveSeekDurationFromPreferences(this) / 1000.0f))
593-
.performListener(new PlayerSeekOverlay.PerformListener() {
592+
.performListener(new PlayerFastSeekOverlay.PerformListener() {
594593

595594
@Override
596-
public void onPrepare() {
597-
if (invalidSeekConditions()) {
598-
playerGestureListener.endMultiDoubleTap();
599-
return;
600-
}
601-
binding.seekOverlay.arcSize(
602-
CircleClipTapView.Companion.calculateArcSize(getSurfaceView())
603-
);
595+
public void onDoubleTabStart() {
596+
// TODO
604597
}
605598

606599
@Override
607-
public void onAnimationStart() {
608-
animate(binding.seekOverlay, true, SEEK_OVERLAY_DURATION);
600+
public void onDoubleTab() {
601+
animate(binding.fastSeekOverlay, true, SEEK_OVERLAY_DURATION);
609602
animate(binding.playbackControlsShadow,
610603
!simpleExoPlayer.getPlayWhenReady(), SEEK_OVERLAY_DURATION);
611604
animate(binding.playerTopShadow, false, SEEK_OVERLAY_DURATION);
@@ -615,8 +608,8 @@ public void onAnimationStart() {
615608
}
616609

617610
@Override
618-
public void onAnimationEnd() {
619-
animate(binding.seekOverlay, false, SEEK_OVERLAY_DURATION);
611+
public void onDoubleTabEnd() {
612+
animate(binding.fastSeekOverlay, false, SEEK_OVERLAY_DURATION);
620613
if (!simpleExoPlayer.getPlayWhenReady()) {
621614
showControls(SEEK_OVERLAY_DURATION);
622615
} else {
@@ -629,6 +622,7 @@ public Boolean shouldFastForward(@NonNull final DisplayPortion portion) {
629622
// Null indicates an invalid area or condition e.g. the middle portion
630623
// or video start or end was reached during double tap seeking
631624
if (invalidSeekConditions()) {
625+
playerGestureListener.endMultiDoubleTap();
632626
return null;
633627
}
634628
if (portion == DisplayPortion.LEFT
@@ -637,9 +631,9 @@ public Boolean shouldFastForward(@NonNull final DisplayPortion portion) {
637631
return false;
638632
} else if (portion == DisplayPortion.RIGHT) {
639633
return true;
640-
} else /* portion == DisplayPortion.MIDDLE */ {
641-
return null;
642634
}
635+
/* portion == DisplayPortion.MIDDLE */
636+
return null;
643637
}
644638

645639
@Override
@@ -653,12 +647,13 @@ public void seek(final boolean forward) {
653647
}
654648

655649
private boolean invalidSeekConditions() {
656-
return simpleExoPlayer.getCurrentPosition() == simpleExoPlayer.getDuration()
657-
|| currentState == STATE_COMPLETED
658-
|| !isPrepared;
650+
return exoPlayerIsNull()
651+
|| simpleExoPlayer.getPlaybackState() == SimpleExoPlayer.STATE_ENDED
652+
|| simpleExoPlayer.getCurrentPosition() >= simpleExoPlayer.getDuration()
653+
|| currentState == STATE_COMPLETED;
659654
}
660655
});
661-
playerGestureListener.doubleTapControls(binding.seekOverlay);
656+
playerGestureListener.doubleTapControls(binding.fastSeekOverlay);
662657
}
663658

664659
//endregion
@@ -1879,71 +1874,6 @@ public boolean isControlsVisible() {
18791874
return binding != null && binding.playbackControlRoot.getVisibility() == View.VISIBLE;
18801875
}
18811876

1882-
/**
1883-
* Show a animation, and depending on goneOnEnd, will stay on the screen or be gone.
1884-
*
1885-
* @param drawableId the drawable that will be used to animate,
1886-
* pass -1 to clear any animation that is visible
1887-
* @param goneOnEnd will set the animation view to GONE on the end of the animation
1888-
*/
1889-
public void showAndAnimateControl(final int drawableId, final boolean goneOnEnd) {
1890-
if (DEBUG) {
1891-
Log.d(TAG, "showAndAnimateControl() called with: "
1892-
+ "drawableId = [" + drawableId + "], goneOnEnd = [" + goneOnEnd + "]");
1893-
}
1894-
if (controlViewAnimator != null && controlViewAnimator.isRunning()) {
1895-
if (DEBUG) {
1896-
Log.d(TAG, "showAndAnimateControl: controlViewAnimator.isRunning");
1897-
}
1898-
controlViewAnimator.end();
1899-
}
1900-
1901-
if (drawableId == -1) {
1902-
if (binding.controlAnimationView.getVisibility() == View.VISIBLE) {
1903-
controlViewAnimator = ObjectAnimator.ofPropertyValuesHolder(
1904-
binding.controlAnimationView,
1905-
PropertyValuesHolder.ofFloat(View.ALPHA, 1.0f, 0.0f),
1906-
PropertyValuesHolder.ofFloat(View.SCALE_X, 1.4f, 1.0f),
1907-
PropertyValuesHolder.ofFloat(View.SCALE_Y, 1.4f, 1.0f)
1908-
).setDuration(DEFAULT_CONTROLS_DURATION);
1909-
controlViewAnimator.addListener(new AnimatorListenerAdapter() {
1910-
@Override
1911-
public void onAnimationEnd(final Animator animation) {
1912-
binding.controlAnimationView.setVisibility(View.GONE);
1913-
}
1914-
});
1915-
controlViewAnimator.start();
1916-
}
1917-
return;
1918-
}
1919-
1920-
final float scaleFrom = goneOnEnd ? 1f : 1f;
1921-
final float scaleTo = goneOnEnd ? 1.8f : 1.4f;
1922-
final float alphaFrom = goneOnEnd ? 1f : 0f;
1923-
final float alphaTo = goneOnEnd ? 0f : 1f;
1924-
1925-
1926-
controlViewAnimator = ObjectAnimator.ofPropertyValuesHolder(
1927-
binding.controlAnimationView,
1928-
PropertyValuesHolder.ofFloat(View.ALPHA, alphaFrom, alphaTo),
1929-
PropertyValuesHolder.ofFloat(View.SCALE_X, scaleFrom, scaleTo),
1930-
PropertyValuesHolder.ofFloat(View.SCALE_Y, scaleFrom, scaleTo)
1931-
);
1932-
controlViewAnimator.setDuration(goneOnEnd ? 1000 : 500);
1933-
controlViewAnimator.addListener(new AnimatorListenerAdapter() {
1934-
@Override
1935-
public void onAnimationEnd(final Animator animation) {
1936-
binding.controlAnimationView.setVisibility(goneOnEnd ? View.GONE : View.VISIBLE);
1937-
}
1938-
});
1939-
1940-
1941-
binding.controlAnimationView.setVisibility(View.VISIBLE);
1942-
binding.controlAnimationView.setImageDrawable(
1943-
AppCompatResources.getDrawable(context, drawableId));
1944-
controlViewAnimator.start();
1945-
}
1946-
19471877
public void showControlsThenHide() {
19481878
if (DEBUG) {
19491879
Log.d(TAG, "showControlsThenHide() called");
@@ -2214,8 +2144,6 @@ private void onPlaying() {
22142144

22152145
updateStreamRelatedViews();
22162146

2217-
showAndAnimateControl(-1, true);
2218-
22192147
binding.playbackSeekBar.setEnabled(true);
22202148
binding.playbackSeekBar.getThumb()
22212149
.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_IN));
@@ -2295,7 +2223,6 @@ private void onPausedSeek() {
22952223
if (DEBUG) {
22962224
Log.d(TAG, "onPausedSeek() called");
22972225
}
2298-
showAndAnimateControl(-1, true);
22992226

23002227
animatePlayButtons(false, 100);
23012228
binding.getRoot().setKeepScreenOn(true);
@@ -4364,8 +4291,8 @@ public TextView getCurrentDisplaySeek() {
43644291
return binding.currentDisplaySeek;
43654292
}
43664293

4367-
public PlayerSeekOverlay getSeekOverlay() {
4368-
return binding.seekOverlay;
4294+
public PlayerFastSeekOverlay getFastSeekOverlay() {
4295+
return binding.fastSeekOverlay;
43694296
}
43704297

43714298
@Nullable

app/src/main/java/org/schabi/newpipe/player/event/BasePlayerGestureListener.kt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ abstract class BasePlayerGestureListener(
411411
var doubleTapControls: DoubleTapListener? = null
412412
private set
413413

414-
val isDoubleTapEnabled: Boolean
414+
private val isDoubleTapEnabled: Boolean
415415
get() = doubleTapDelay > 0
416416

417417
var isDoubleTapping = false
@@ -459,10 +459,6 @@ abstract class BasePlayerGestureListener(
459459
doubleTapControls?.onDoubleTapFinished()
460460
}
461461

462-
fun enableMultiDoubleTap(enable: Boolean) = apply {
463-
doubleTapDelay = if (enable) DOUBLE_TAP_DELAY else 0
464-
}
465-
466462
// ///////////////////////////////////////////////////////////////////
467463
// Utils
468464
// ///////////////////////////////////////////////////////////////////

app/src/main/java/org/schabi/newpipe/player/event/PlayerGestureListener.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,11 +230,10 @@ public void onPopupResizingStart() {
230230
if (DEBUG) {
231231
Log.d(TAG, "onPopupResizingStart called");
232232
}
233-
player.showAndAnimateControl(-1, true);
234233
player.getLoadingPanel().setVisibility(View.GONE);
235234

236235
player.hideControls(0, 0);
237-
animate(player.getSeekOverlay(), false, 0);
236+
animate(player.getFastSeekOverlay(), false, 0);
238237
animate(player.getCurrentDisplaySeek(), false, 0, ALPHA, 0);
239238
}
240239

app/src/main/java/org/schabi/newpipe/views/player/CircleClipTapView.kt

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,9 @@ import android.graphics.Paint
66
import android.graphics.Path
77
import android.util.AttributeSet
88
import android.view.View
9-
import org.schabi.newpipe.player.event.DisplayPortion
109

1110
class CircleClipTapView(context: Context?, attrs: AttributeSet) : View(context, attrs) {
1211

13-
companion object {
14-
const val COLOR_DARK = 0x45000000
15-
const val COLOR_DARK_TRANSPARENT = 0x30000000
16-
const val COLOR_LIGHT_TRANSPARENT = 0x25EEEEEE
17-
18-
fun calculateArcSize(view: View): Float = view.height / 11.4f
19-
}
20-
2112
private var backgroundPaint = Paint()
2213

2314
private var widthPx = 0
@@ -26,6 +17,7 @@ class CircleClipTapView(context: Context?, attrs: AttributeSet) : View(context,
2617
// Background
2718

2819
private var shapePath = Path()
20+
private var arcSize: Float = 80f
2921
private var isLeft = true
3022

3123
init {
@@ -34,7 +26,7 @@ class CircleClipTapView(context: Context?, attrs: AttributeSet) : View(context,
3426
backgroundPaint.apply {
3527
style = Paint.Style.FILL
3628
isAntiAlias = true
37-
color = COLOR_LIGHT_TRANSPARENT
29+
color = 0x30000000
3830
}
3931

4032
val dm = context.resources.displayMetrics
@@ -44,24 +36,15 @@ class CircleClipTapView(context: Context?, attrs: AttributeSet) : View(context,
4436
updatePathShape()
4537
}
4638

47-
var arcSize: Float = 80f
48-
set(value) {
49-
field = value
39+
fun updateArcSize(baseView: View) {
40+
val newArcSize = baseView.height / 11.4f
41+
if (arcSize != newArcSize) {
42+
arcSize = newArcSize
5043
updatePathShape()
5144
}
45+
}
5246

53-
var circleBackgroundColor: Int
54-
get() = backgroundPaint.color
55-
set(value) {
56-
backgroundPaint.color = value
57-
}
58-
59-
/*
60-
Background
61-
*/
62-
63-
fun updatePosition(portion: DisplayPortion) {
64-
val newIsLeft = portion == DisplayPortion.LEFT
47+
fun updatePosition(newIsLeft: Boolean) {
6548
if (isLeft != newIsLeft) {
6649
isLeft = newIsLeft
6750
updatePathShape()

0 commit comments

Comments
 (0)