Skip to content

Commit

Permalink
fix(YouTube): Fix player button fade out animations (#4469)
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcaDian authored Feb 19, 2025
1 parent 048a4f3 commit bf8e775
Show file tree
Hide file tree
Showing 10 changed files with 256 additions and 264 deletions.
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
package app.revanced.extension.youtube.sponsorblock.ui;

import static app.revanced.extension.shared.Utils.getResourceIdentifier;

import android.view.View;
import android.widget.ImageView;

import java.lang.ref.WeakReference;
import androidx.annotation.Nullable;

import java.util.Objects;

import app.revanced.extension.youtube.patches.VideoInformation;
import app.revanced.extension.youtube.settings.Settings;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.youtube.videoplayer.PlayerControlButton;
import app.revanced.extension.youtube.patches.VideoInformation;
import app.revanced.extension.youtube.settings.Settings;
import app.revanced.extension.youtube.videoplayer.PlayerControlTopButton;

// Edit: This should be a subclass of PlayerControlButton
public class CreateSegmentButtonController {
private static WeakReference<ImageView> buttonReference = new WeakReference<>(null);
private static boolean isShowing;
public class CreateSegmentButtonController extends PlayerControlTopButton {
@Nullable
private static CreateSegmentButtonController instance;

public static void hideControls() {
if (instance != null) instance.hide();
}

/**
* injection point
Expand All @@ -27,10 +29,7 @@ public static void initialize(View youtubeControlsLayout) {
Logger.printDebug(() -> "initializing new segment button");
ImageView imageView = Objects.requireNonNull(Utils.getChildViewByResourceName(
youtubeControlsLayout, "revanced_sb_create_segment_button"));
imageView.setVisibility(View.GONE);
imageView.setOnClickListener(v -> SponsorBlockViewController.toggleNewSegmentLayoutVisibility());

buttonReference = new WeakReference<>(imageView);
instance = new CreateSegmentButtonController(imageView);
} catch (Exception ex) {
Logger.printException(() -> "initialize failure", ex);
}
Expand All @@ -40,72 +39,22 @@ public static void initialize(View youtubeControlsLayout) {
* injection point
*/
public static void changeVisibilityImmediate(boolean visible) {
if (visible) {
// Fix button flickering, by pushing this call to the back of
// the main thread and letting other layout code run first.
Utils.runOnMainThread(() -> setVisibility(true, false));
} else {
setVisibility(false, false);
}
if (instance != null) instance.setVisibilityImmediate(visible);
}

/**
* injection point
*/
public static void changeVisibility(boolean visible, boolean animated) {
// Ignore this call, otherwise with full screen thumbnails the buttons are visible while seeking.
if (visible && !animated) return;

setVisibility(visible, animated);
if (instance != null) instance.setVisibility(visible, animated);
}

private static void setVisibility(boolean visible, boolean animated) {
try {
if (isShowing == visible) return;
isShowing = visible;

ImageView iView = buttonReference.get();
if (iView == null) return;

if (visible) {
iView.clearAnimation();
if (!shouldBeShown()) {
return;
}
if (animated) {
iView.startAnimation(PlayerControlButton.getButtonFadeIn());
}
iView.setVisibility(View.VISIBLE);
return;
}

if (iView.getVisibility() == View.VISIBLE) {
iView.clearAnimation();
if (animated) {
iView.startAnimation(PlayerControlButton.getButtonFadeOut());
}
iView.setVisibility(View.GONE);
}
} catch (Exception ex) {
Logger.printException(() -> "changeVisibility failure", ex);
}
private CreateSegmentButtonController(ImageView imageView) {
super(imageView, v -> SponsorBlockViewController.toggleNewSegmentLayoutVisibility());
}

private static boolean shouldBeShown() {
protected boolean shouldBeShown() {
return Settings.SB_ENABLED.get() && Settings.SB_CREATE_NEW_SEGMENT.get()
&& !VideoInformation.isAtEndOfVideo();
}

public static void hide() {
if (!isShowing) {
return;
}
Utils.verifyOnMainThread();
View v = buttonReference.get();
if (v == null) {
return;
}
v.setVisibility(View.GONE);
isShowing = false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import app.revanced.extension.youtube.settings.Settings;
import app.revanced.extension.youtube.shared.PlayerType;
import app.revanced.extension.youtube.sponsorblock.objects.SponsorSegment;
import app.revanced.extension.youtube.videoplayer.PlayerControlTopButton;
import kotlin.Unit;

public class SponsorBlockViewController {
Expand Down Expand Up @@ -238,8 +239,8 @@ public static void endOfVideoReached() {
// but if buttons are showing when the end of the video is reached then they need
// to be forcefully hidden
if (!Settings.AUTO_REPEAT.get()) {
CreateSegmentButtonController.hide();
VotingButtonController.hide();
CreateSegmentButtonController.hideControls();
VotingButtonController.hideControls();
}
} catch (Exception ex) {
Logger.printException(() -> "endOfVideoReached failure", ex);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
package app.revanced.extension.youtube.sponsorblock.ui;

import static app.revanced.extension.shared.Utils.getResourceIdentifier;

import android.view.View;
import android.widget.ImageView;

import java.lang.ref.WeakReference;
import androidx.annotation.Nullable;

import java.util.Objects;

import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.youtube.patches.VideoInformation;
import app.revanced.extension.youtube.settings.Settings;
import app.revanced.extension.youtube.sponsorblock.SegmentPlaybackController;
import app.revanced.extension.youtube.sponsorblock.SponsorBlockUtils;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.youtube.videoplayer.PlayerControlButton;
import app.revanced.extension.youtube.videoplayer.PlayerControlTopButton;

// Edit: This should be a subclass of PlayerControlButton
public class VotingButtonController {
private static WeakReference<ImageView> buttonReference = new WeakReference<>(null);
private static boolean isShowing;
public class VotingButtonController extends PlayerControlTopButton {
@Nullable
private static VotingButtonController instance;

public static void hideControls() {
if (instance != null) instance.hide();
}

/**
* injection point
Expand All @@ -29,10 +31,7 @@ public static void initialize(View youtubeControlsLayout) {
Logger.printDebug(() -> "initializing voting button");
ImageView imageView = Objects.requireNonNull(Utils.getChildViewByResourceName(
youtubeControlsLayout, "revanced_sb_voting_button"));
imageView.setVisibility(View.GONE);
imageView.setOnClickListener(v -> SponsorBlockUtils.onVotingClicked(v.getContext()));

buttonReference = new WeakReference<>(imageView);
instance = new VotingButtonController(imageView);
} catch (Exception ex) {
Logger.printException(() -> "initialize failure", ex);
}
Expand All @@ -42,75 +41,22 @@ public static void initialize(View youtubeControlsLayout) {
* injection point
*/
public static void changeVisibilityImmediate(boolean visible) {
if (visible) {
// Fix button flickering, by pushing this call to the back of
// the main thread and letting other layout code run first.
Utils.runOnMainThread(() -> setVisibility(true, false));
} else {
setVisibility(false, false);
}
if (instance != null) instance.setVisibilityImmediate(visible);
}

/**
* injection point
*/
public static void changeVisibility(boolean visible, boolean animated) {
// Ignore this call, otherwise with full screen thumbnails the buttons are visible while seeking.
if (visible && !animated) return;

setVisibility(visible, animated);
if (instance != null) instance.setVisibility(visible, animated);
}

/**
* injection point
*/
private static void setVisibility(boolean visible, boolean animated) {
try {
if (isShowing == visible) return;
isShowing = visible;

ImageView iView = buttonReference.get();
if (iView == null) return;

if (visible) {
iView.clearAnimation();
if (!shouldBeShown()) {
return;
}
if (animated) {
iView.startAnimation(PlayerControlButton.getButtonFadeIn());
}
iView.setVisibility(View.VISIBLE);
return;
}

if (iView.getVisibility() == View.VISIBLE) {
iView.clearAnimation();
if (animated) {
iView.startAnimation(PlayerControlButton.getButtonFadeOut());
}
iView.setVisibility(View.GONE);
}
} catch (Exception ex) {
Logger.printException(() -> "changeVisibility failure", ex);
}
private VotingButtonController(ImageView imageView) {
super(imageView, v -> SponsorBlockUtils.onVotingClicked(v.getContext()));
}

private static boolean shouldBeShown() {
protected boolean shouldBeShown() {
return Settings.SB_ENABLED.get() && Settings.SB_VOTING_BUTTON.get()
&& SegmentPlaybackController.videoHasSegments() && !VideoInformation.isAtEndOfVideo();
}

public static void hide() {
if (!isShowing) {
return;
}
Utils.verifyOnMainThread();
View v = buttonReference.get();
if (v == null) {
return;
}
v.setVisibility(View.GONE);
isShowing = false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import app.revanced.extension.shared.Logger;

@SuppressWarnings("unused")
public class CopyVideoUrlButton extends PlayerControlButton {
public class CopyVideoUrlButton extends PlayerControlBottomButton {
@Nullable
private static CopyVideoUrlButton instance;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import app.revanced.extension.shared.Logger;

@SuppressWarnings("unused")
public class CopyVideoUrlTimestampButton extends PlayerControlButton {
public class CopyVideoUrlTimestampButton extends PlayerControlBottomButton {
@Nullable
private static CopyVideoUrlTimestampButton instance;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import app.revanced.extension.youtube.settings.Settings;

@SuppressWarnings("unused")
public class ExternalDownloadButton extends PlayerControlButton {
public class ExternalDownloadButton extends PlayerControlBottomButton {
@Nullable
private static ExternalDownloadButton instance;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import app.revanced.extension.shared.Logger;

@SuppressWarnings("unused")
public class PlaybackSpeedDialogButton extends PlayerControlButton {
public class PlaybackSpeedDialogButton extends PlayerControlBottomButton {
@Nullable
private static PlaybackSpeedDialogButton instance;

Expand Down
Loading

0 comments on commit bf8e775

Please sign in to comment.