mirror of
https://github.com/revanced/revanced-patches.git
synced 2025-04-30 14:44:33 +02:00
fix(YouTube): Fix player button fade out animations (#4469)
This commit is contained in:
parent
048a4f306a
commit
bf8e7759f9
@ -1,23 +1,25 @@
|
|||||||
package app.revanced.extension.youtube.sponsorblock.ui;
|
package app.revanced.extension.youtube.sponsorblock.ui;
|
||||||
|
|
||||||
import static app.revanced.extension.shared.Utils.getResourceIdentifier;
|
|
||||||
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import java.util.Objects;
|
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.Logger;
|
||||||
import app.revanced.extension.shared.Utils;
|
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 extends PlayerControlTopButton {
|
||||||
public class CreateSegmentButtonController {
|
@Nullable
|
||||||
private static WeakReference<ImageView> buttonReference = new WeakReference<>(null);
|
private static CreateSegmentButtonController instance;
|
||||||
private static boolean isShowing;
|
|
||||||
|
public static void hideControls() {
|
||||||
|
if (instance != null) instance.hide();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* injection point
|
* injection point
|
||||||
@ -27,10 +29,7 @@ public class CreateSegmentButtonController {
|
|||||||
Logger.printDebug(() -> "initializing new segment button");
|
Logger.printDebug(() -> "initializing new segment button");
|
||||||
ImageView imageView = Objects.requireNonNull(Utils.getChildViewByResourceName(
|
ImageView imageView = Objects.requireNonNull(Utils.getChildViewByResourceName(
|
||||||
youtubeControlsLayout, "revanced_sb_create_segment_button"));
|
youtubeControlsLayout, "revanced_sb_create_segment_button"));
|
||||||
imageView.setVisibility(View.GONE);
|
instance = new CreateSegmentButtonController(imageView);
|
||||||
imageView.setOnClickListener(v -> SponsorBlockViewController.toggleNewSegmentLayoutVisibility());
|
|
||||||
|
|
||||||
buttonReference = new WeakReference<>(imageView);
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Logger.printException(() -> "initialize failure", ex);
|
Logger.printException(() -> "initialize failure", ex);
|
||||||
}
|
}
|
||||||
@ -40,72 +39,22 @@ public class CreateSegmentButtonController {
|
|||||||
* injection point
|
* injection point
|
||||||
*/
|
*/
|
||||||
public static void changeVisibilityImmediate(boolean visible) {
|
public static void changeVisibilityImmediate(boolean visible) {
|
||||||
if (visible) {
|
if (instance != null) instance.setVisibilityImmediate(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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* injection point
|
* injection point
|
||||||
*/
|
*/
|
||||||
public static void changeVisibility(boolean visible, boolean animated) {
|
public static void changeVisibility(boolean visible, boolean animated) {
|
||||||
// Ignore this call, otherwise with full screen thumbnails the buttons are visible while seeking.
|
if (instance != null) instance.setVisibility(visible, animated);
|
||||||
if (visible && !animated) return;
|
|
||||||
|
|
||||||
setVisibility(visible, animated);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setVisibility(boolean visible, boolean animated) {
|
private CreateSegmentButtonController(ImageView imageView) {
|
||||||
try {
|
super(imageView, v -> SponsorBlockViewController.toggleNewSegmentLayoutVisibility());
|
||||||
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 static boolean shouldBeShown() {
|
protected boolean shouldBeShown() {
|
||||||
return Settings.SB_ENABLED.get() && Settings.SB_CREATE_NEW_SEGMENT.get()
|
return Settings.SB_ENABLED.get() && Settings.SB_CREATE_NEW_SEGMENT.get()
|
||||||
&& !VideoInformation.isAtEndOfVideo();
|
&& !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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ import app.revanced.extension.shared.Utils;
|
|||||||
import app.revanced.extension.youtube.settings.Settings;
|
import app.revanced.extension.youtube.settings.Settings;
|
||||||
import app.revanced.extension.youtube.shared.PlayerType;
|
import app.revanced.extension.youtube.shared.PlayerType;
|
||||||
import app.revanced.extension.youtube.sponsorblock.objects.SponsorSegment;
|
import app.revanced.extension.youtube.sponsorblock.objects.SponsorSegment;
|
||||||
|
import app.revanced.extension.youtube.videoplayer.PlayerControlTopButton;
|
||||||
import kotlin.Unit;
|
import kotlin.Unit;
|
||||||
|
|
||||||
public class SponsorBlockViewController {
|
public class SponsorBlockViewController {
|
||||||
@ -238,8 +239,8 @@ public class SponsorBlockViewController {
|
|||||||
// but if buttons are showing when the end of the video is reached then they need
|
// but if buttons are showing when the end of the video is reached then they need
|
||||||
// to be forcefully hidden
|
// to be forcefully hidden
|
||||||
if (!Settings.AUTO_REPEAT.get()) {
|
if (!Settings.AUTO_REPEAT.get()) {
|
||||||
CreateSegmentButtonController.hide();
|
CreateSegmentButtonController.hideControls();
|
||||||
VotingButtonController.hide();
|
VotingButtonController.hideControls();
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Logger.printException(() -> "endOfVideoReached failure", ex);
|
Logger.printException(() -> "endOfVideoReached failure", ex);
|
||||||
|
@ -1,25 +1,27 @@
|
|||||||
package app.revanced.extension.youtube.sponsorblock.ui;
|
package app.revanced.extension.youtube.sponsorblock.ui;
|
||||||
|
|
||||||
import static app.revanced.extension.shared.Utils.getResourceIdentifier;
|
|
||||||
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import java.util.Objects;
|
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.patches.VideoInformation;
|
||||||
import app.revanced.extension.youtube.settings.Settings;
|
import app.revanced.extension.youtube.settings.Settings;
|
||||||
import app.revanced.extension.youtube.sponsorblock.SegmentPlaybackController;
|
import app.revanced.extension.youtube.sponsorblock.SegmentPlaybackController;
|
||||||
import app.revanced.extension.youtube.sponsorblock.SponsorBlockUtils;
|
import app.revanced.extension.youtube.sponsorblock.SponsorBlockUtils;
|
||||||
import app.revanced.extension.shared.Logger;
|
import app.revanced.extension.youtube.videoplayer.PlayerControlTopButton;
|
||||||
import app.revanced.extension.shared.Utils;
|
|
||||||
import app.revanced.extension.youtube.videoplayer.PlayerControlButton;
|
|
||||||
|
|
||||||
// Edit: This should be a subclass of PlayerControlButton
|
public class VotingButtonController extends PlayerControlTopButton {
|
||||||
public class VotingButtonController {
|
@Nullable
|
||||||
private static WeakReference<ImageView> buttonReference = new WeakReference<>(null);
|
private static VotingButtonController instance;
|
||||||
private static boolean isShowing;
|
|
||||||
|
public static void hideControls() {
|
||||||
|
if (instance != null) instance.hide();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* injection point
|
* injection point
|
||||||
@ -29,10 +31,7 @@ public class VotingButtonController {
|
|||||||
Logger.printDebug(() -> "initializing voting button");
|
Logger.printDebug(() -> "initializing voting button");
|
||||||
ImageView imageView = Objects.requireNonNull(Utils.getChildViewByResourceName(
|
ImageView imageView = Objects.requireNonNull(Utils.getChildViewByResourceName(
|
||||||
youtubeControlsLayout, "revanced_sb_voting_button"));
|
youtubeControlsLayout, "revanced_sb_voting_button"));
|
||||||
imageView.setVisibility(View.GONE);
|
instance = new VotingButtonController(imageView);
|
||||||
imageView.setOnClickListener(v -> SponsorBlockUtils.onVotingClicked(v.getContext()));
|
|
||||||
|
|
||||||
buttonReference = new WeakReference<>(imageView);
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Logger.printException(() -> "initialize failure", ex);
|
Logger.printException(() -> "initialize failure", ex);
|
||||||
}
|
}
|
||||||
@ -42,75 +41,22 @@ public class VotingButtonController {
|
|||||||
* injection point
|
* injection point
|
||||||
*/
|
*/
|
||||||
public static void changeVisibilityImmediate(boolean visible) {
|
public static void changeVisibilityImmediate(boolean visible) {
|
||||||
if (visible) {
|
if (instance != null) instance.setVisibilityImmediate(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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* injection point
|
* injection point
|
||||||
*/
|
*/
|
||||||
public static void changeVisibility(boolean visible, boolean animated) {
|
public static void changeVisibility(boolean visible, boolean animated) {
|
||||||
// Ignore this call, otherwise with full screen thumbnails the buttons are visible while seeking.
|
if (instance != null) instance.setVisibility(visible, animated);
|
||||||
if (visible && !animated) return;
|
|
||||||
|
|
||||||
setVisibility(visible, animated);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private VotingButtonController(ImageView imageView) {
|
||||||
* injection point
|
super(imageView, v -> SponsorBlockUtils.onVotingClicked(v.getContext()));
|
||||||
*/
|
|
||||||
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 static boolean shouldBeShown() {
|
protected boolean shouldBeShown() {
|
||||||
return Settings.SB_ENABLED.get() && Settings.SB_VOTING_BUTTON.get()
|
return Settings.SB_ENABLED.get() && Settings.SB_VOTING_BUTTON.get()
|
||||||
&& SegmentPlaybackController.videoHasSegments() && !VideoInformation.isAtEndOfVideo();
|
&& 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import app.revanced.extension.youtube.settings.Settings;
|
|||||||
import app.revanced.extension.shared.Logger;
|
import app.revanced.extension.shared.Logger;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class CopyVideoUrlButton extends PlayerControlButton {
|
public class CopyVideoUrlButton extends PlayerControlBottomButton {
|
||||||
@Nullable
|
@Nullable
|
||||||
private static CopyVideoUrlButton instance;
|
private static CopyVideoUrlButton instance;
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ import app.revanced.extension.youtube.settings.Settings;
|
|||||||
import app.revanced.extension.shared.Logger;
|
import app.revanced.extension.shared.Logger;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class CopyVideoUrlTimestampButton extends PlayerControlButton {
|
public class CopyVideoUrlTimestampButton extends PlayerControlBottomButton {
|
||||||
@Nullable
|
@Nullable
|
||||||
private static CopyVideoUrlTimestampButton instance;
|
private static CopyVideoUrlTimestampButton instance;
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ import app.revanced.extension.youtube.patches.VideoInformation;
|
|||||||
import app.revanced.extension.youtube.settings.Settings;
|
import app.revanced.extension.youtube.settings.Settings;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class ExternalDownloadButton extends PlayerControlButton {
|
public class ExternalDownloadButton extends PlayerControlBottomButton {
|
||||||
@Nullable
|
@Nullable
|
||||||
private static ExternalDownloadButton instance;
|
private static ExternalDownloadButton instance;
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ import app.revanced.extension.youtube.settings.Settings;
|
|||||||
import app.revanced.extension.shared.Logger;
|
import app.revanced.extension.shared.Logger;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class PlaybackSpeedDialogButton extends PlayerControlButton {
|
public class PlaybackSpeedDialogButton extends PlayerControlBottomButton {
|
||||||
@Nullable
|
@Nullable
|
||||||
private static PlaybackSpeedDialogButton instance;
|
private static PlaybackSpeedDialogButton instance;
|
||||||
|
|
||||||
|
@ -0,0 +1,103 @@
|
|||||||
|
package app.revanced.extension.youtube.videoplayer;
|
||||||
|
|
||||||
|
import static app.revanced.extension.youtube.videoplayer.PlayerControlTopButton.fadeOutDuration;
|
||||||
|
|
||||||
|
import android.transition.Fade;
|
||||||
|
import android.transition.TransitionManager;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import app.revanced.extension.shared.Logger;
|
||||||
|
import app.revanced.extension.shared.Utils;
|
||||||
|
import app.revanced.extension.shared.settings.BooleanSetting;
|
||||||
|
|
||||||
|
public abstract class PlayerControlBottomButton {
|
||||||
|
private final WeakReference<ImageView> buttonRef;
|
||||||
|
private final BooleanSetting setting;
|
||||||
|
private boolean isVisible;
|
||||||
|
|
||||||
|
protected PlayerControlBottomButton(ViewGroup bottomControlsViewGroup, String imageViewButtonId,
|
||||||
|
BooleanSetting booleanSetting, View.OnClickListener onClickListener,
|
||||||
|
@Nullable View.OnLongClickListener longClickListener) {
|
||||||
|
Logger.printDebug(() -> "Initializing button: " + imageViewButtonId);
|
||||||
|
|
||||||
|
ImageView imageView = Objects.requireNonNull(bottomControlsViewGroup.findViewById(
|
||||||
|
Utils.getResourceIdentifier(imageViewButtonId, "id")
|
||||||
|
));
|
||||||
|
imageView.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
imageView.setOnClickListener(onClickListener);
|
||||||
|
if (longClickListener != null) {
|
||||||
|
imageView.setOnLongClickListener(longClickListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
setting = booleanSetting;
|
||||||
|
buttonRef = new WeakReference<>(imageView);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setVisibilityImmediate(boolean visible) {
|
||||||
|
private_setVisibility(visible, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setVisibility(boolean visible, boolean animated) {
|
||||||
|
// Ignore this call, otherwise with full screen thumbnails the buttons are visible while seeking.
|
||||||
|
if (visible && !animated) return;
|
||||||
|
|
||||||
|
private_setVisibility(visible, animated);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void private_setVisibility(boolean visible, boolean animated) {
|
||||||
|
try {
|
||||||
|
// If the visibility state hasn't changed, return early.
|
||||||
|
if (isVisible == visible) return;
|
||||||
|
isVisible = visible;
|
||||||
|
|
||||||
|
ImageView iView = buttonRef.get();
|
||||||
|
if (iView == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewGroup parent = (ViewGroup) iView.getParent();
|
||||||
|
if (parent == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply transition if animation is enabled.
|
||||||
|
if (animated) {
|
||||||
|
Fade fade = visible
|
||||||
|
? PlayerControlTopButton.fadeInTransition
|
||||||
|
: PlayerControlTopButton.fadeOutTransition;
|
||||||
|
TransitionManager.beginDelayedTransition(parent, fade);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the view should be visible and the setting allows it.
|
||||||
|
if (visible && setting.get()) {
|
||||||
|
// Set the view to VISIBLE.
|
||||||
|
iView.setVisibility(View.VISIBLE);
|
||||||
|
} else if (iView.getVisibility() == View.VISIBLE) {
|
||||||
|
// First, set visibility to INVISIBLE for animation.
|
||||||
|
iView.setVisibility(View.INVISIBLE);
|
||||||
|
|
||||||
|
if (animated) {
|
||||||
|
// Set the view to GONE after the fade animation ends.
|
||||||
|
Utils.runOnMainThreadDelayed(() -> {
|
||||||
|
if (!isVisible) {
|
||||||
|
iView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}, fadeOutDuration);
|
||||||
|
} else {
|
||||||
|
// If no animation, immediately set the view to GONE.
|
||||||
|
iView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Logger.printException(() -> "private_setVisibility failure", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,117 +0,0 @@
|
|||||||
package app.revanced.extension.youtube.videoplayer;
|
|
||||||
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.view.animation.Animation;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import app.revanced.extension.shared.Logger;
|
|
||||||
import app.revanced.extension.shared.Utils;
|
|
||||||
import app.revanced.extension.shared.settings.BooleanSetting;
|
|
||||||
|
|
||||||
public abstract class PlayerControlButton {
|
|
||||||
private static final Animation fadeIn;
|
|
||||||
private static final Animation fadeOut;
|
|
||||||
private static final Animation fadeOutImmediate;
|
|
||||||
|
|
||||||
private final WeakReference<ImageView> buttonRef;
|
|
||||||
protected final BooleanSetting setting;
|
|
||||||
protected boolean isVisible;
|
|
||||||
|
|
||||||
static {
|
|
||||||
// TODO: check if these durations are correct.
|
|
||||||
fadeIn = Utils.getResourceAnimation("fade_in");
|
|
||||||
fadeIn.setDuration(Utils.getResourceInteger("fade_duration_fast"));
|
|
||||||
|
|
||||||
fadeOut = Utils.getResourceAnimation("fade_out");
|
|
||||||
fadeOut.setDuration(Utils.getResourceInteger("fade_duration_scheduled"));
|
|
||||||
|
|
||||||
fadeOutImmediate = Utils.getResourceAnimation("abc_fade_out");
|
|
||||||
fadeOutImmediate.setDuration(Utils.getResourceInteger("fade_duration_fast"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public static Animation getButtonFadeIn() {
|
|
||||||
return fadeIn;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public static Animation getButtonFadeOut() {
|
|
||||||
return fadeOut;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public static Animation getButtonFadeOutImmediately() {
|
|
||||||
return fadeOutImmediate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PlayerControlButton(@NonNull ViewGroup bottomControlsViewGroup, @NonNull String imageViewButtonId,
|
|
||||||
@NonNull BooleanSetting booleanSetting, @NonNull View.OnClickListener onClickListener,
|
|
||||||
@Nullable View.OnLongClickListener longClickListener) {
|
|
||||||
Logger.printDebug(() -> "Initializing button: " + imageViewButtonId);
|
|
||||||
|
|
||||||
ImageView imageView = Objects.requireNonNull(bottomControlsViewGroup.findViewById(
|
|
||||||
Utils.getResourceIdentifier(imageViewButtonId, "id")
|
|
||||||
));
|
|
||||||
imageView.setVisibility(View.GONE);
|
|
||||||
|
|
||||||
imageView.setOnClickListener(onClickListener);
|
|
||||||
if (longClickListener != null) {
|
|
||||||
imageView.setOnLongClickListener(longClickListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
setting = booleanSetting;
|
|
||||||
buttonRef = new WeakReference<>(imageView);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVisibilityImmediate(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(() -> private_setVisibility(true, false));
|
|
||||||
} else {
|
|
||||||
private_setVisibility(false, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVisibility(boolean visible, boolean animated) {
|
|
||||||
// Ignore this call, otherwise with full screen thumbnails the buttons are visible while seeking.
|
|
||||||
if (visible && !animated) return;
|
|
||||||
|
|
||||||
private_setVisibility(visible, animated);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void private_setVisibility(boolean visible, boolean animated) {
|
|
||||||
try {
|
|
||||||
if (isVisible == visible) return;
|
|
||||||
isVisible = visible;
|
|
||||||
|
|
||||||
ImageView iView = buttonRef.get();
|
|
||||||
if (iView == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (visible && setting.get()) {
|
|
||||||
iView.clearAnimation();
|
|
||||||
if (animated) {
|
|
||||||
iView.startAnimation(PlayerControlButton.getButtonFadeIn());
|
|
||||||
}
|
|
||||||
iView.setVisibility(View.VISIBLE);
|
|
||||||
} else if (iView.getVisibility() == View.VISIBLE) {
|
|
||||||
iView.clearAnimation();
|
|
||||||
if (animated) {
|
|
||||||
iView.startAnimation(PlayerControlButton.getButtonFadeOut());
|
|
||||||
}
|
|
||||||
iView.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
} catch (Exception ex) {
|
|
||||||
Logger.printException(() -> "setVisibility failure", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,110 @@
|
|||||||
|
package app.revanced.extension.youtube.videoplayer;
|
||||||
|
|
||||||
|
import android.transition.Fade;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.animation.Animation;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
|
import app.revanced.extension.shared.Logger;
|
||||||
|
import app.revanced.extension.shared.Utils;
|
||||||
|
|
||||||
|
// Ideally this should be refactored into PlayerControlBottomButton,
|
||||||
|
// but the show/hide logic is not the same so keeping this as two classes might be simpler.
|
||||||
|
public abstract class PlayerControlTopButton {
|
||||||
|
static final int fadeInDuration;
|
||||||
|
static final int fadeOutDuration;
|
||||||
|
|
||||||
|
private static final Animation fadeInAnimation;
|
||||||
|
private static final Animation fadeOutAnimation;
|
||||||
|
|
||||||
|
static final Fade fadeInTransition;
|
||||||
|
static final Fade fadeOutTransition;
|
||||||
|
|
||||||
|
private final WeakReference<ImageView> buttonReference;
|
||||||
|
private boolean isShowing;
|
||||||
|
|
||||||
|
static {
|
||||||
|
fadeInDuration = Utils.getResourceInteger("fade_duration_fast");
|
||||||
|
fadeOutDuration = Utils.getResourceInteger("fade_duration_scheduled");
|
||||||
|
|
||||||
|
fadeInAnimation = Utils.getResourceAnimation("fade_in");
|
||||||
|
fadeInAnimation.setDuration(fadeInDuration);
|
||||||
|
|
||||||
|
fadeOutAnimation = Utils.getResourceAnimation("fade_out");
|
||||||
|
fadeOutAnimation.setDuration(fadeOutDuration);
|
||||||
|
|
||||||
|
fadeInTransition = new Fade();
|
||||||
|
fadeInTransition.setDuration(fadeInDuration);
|
||||||
|
|
||||||
|
fadeOutTransition = new Fade();
|
||||||
|
fadeOutTransition.setDuration(fadeOutDuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected PlayerControlTopButton(ImageView imageView, View.OnClickListener onClickListener) {
|
||||||
|
imageView.setVisibility(View.GONE);
|
||||||
|
imageView.setOnClickListener(onClickListener);
|
||||||
|
|
||||||
|
buttonReference = new WeakReference<>(imageView);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setVisibilityImmediate(boolean visible) {
|
||||||
|
private_setVisibility(visible, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setVisibility(boolean visible, boolean animated) {
|
||||||
|
// Ignore this call, otherwise with full screen thumbnails the buttons are visible while seeking.
|
||||||
|
if (visible && !animated) return;
|
||||||
|
|
||||||
|
private_setVisibility(visible, animated);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void private_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(fadeInAnimation);
|
||||||
|
}
|
||||||
|
iView.setVisibility(View.VISIBLE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iView.getVisibility() == View.VISIBLE) {
|
||||||
|
iView.clearAnimation();
|
||||||
|
if (animated) {
|
||||||
|
iView.startAnimation(fadeOutAnimation);
|
||||||
|
}
|
||||||
|
iView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Logger.printException(() -> "private_setVisibility failure", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract boolean shouldBeShown();
|
||||||
|
|
||||||
|
public void hide() {
|
||||||
|
if (!isShowing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Utils.verifyOnMainThread();
|
||||||
|
View v = buttonReference.get();
|
||||||
|
if (v == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
v.setVisibility(View.GONE);
|
||||||
|
isShowing = false;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user