mirror of
https://github.com/revanced/revanced-integrations.git
synced 2025-02-06 09:06:47 +01:00
fix(youtube/sponsorblock): fix toast shown when scrubbing thru a paused video (#401)
This commit is contained in:
parent
fc2ad5fa76
commit
7da56738a1
@ -15,7 +15,7 @@ import app.revanced.integrations.shared.PlayerOverlays;
|
|||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class PlayerOverlaysHookPatch {
|
public class PlayerOverlaysHookPatch {
|
||||||
/**
|
/**
|
||||||
* Hook into YouTubePlayerOverlaysLayout.onFinishInflate() method
|
* Injection point.
|
||||||
*
|
*
|
||||||
* @param thisRef reference to the view
|
* @param thisRef reference to the view
|
||||||
* @smali YouTubePlayerOverlaysLayout_onFinishInflateHook(Ljava / lang / Object ;)V
|
* @smali YouTubePlayerOverlaysLayout_onFinishInflateHook(Ljava / lang / Object ;)V
|
||||||
|
@ -3,32 +3,25 @@ package app.revanced.integrations.patches;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import app.revanced.integrations.shared.PlayerType;
|
import app.revanced.integrations.shared.PlayerType;
|
||||||
import app.revanced.integrations.utils.LogHelper;
|
import app.revanced.integrations.shared.VideoState;
|
||||||
|
|
||||||
/**
|
|
||||||
* Hook receiver class for 'player-type-hook' patch
|
|
||||||
*
|
|
||||||
* @usedBy app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch
|
|
||||||
* @smali Lapp/revanced/integrations/patches/PlayerTypeHookPatch;
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class PlayerTypeHookPatch {
|
public class PlayerTypeHookPatch {
|
||||||
/**
|
/**
|
||||||
* Hook into YouTubePlayerOverlaysLayout.updatePlayerLayout() method
|
* Injection point.
|
||||||
*
|
|
||||||
* @param type the new player type
|
|
||||||
* @smali YouTubePlayerOverlaysLayout_updatePlayerTypeHookEX(Ljava/lang/Object;)V
|
|
||||||
*/
|
*/
|
||||||
public static void YouTubePlayerOverlaysLayout_updatePlayerTypeHookEX(@Nullable Object type) {
|
public static void setPlayerType(@Nullable Enum<?> youTubePlayerType) {
|
||||||
if (type == null) return;
|
if (youTubePlayerType == null) return;
|
||||||
|
|
||||||
// update current player type
|
PlayerType.setFromString(youTubePlayerType.name());
|
||||||
final PlayerType newType = PlayerType.safeParseFromString(type.toString());
|
}
|
||||||
if (newType == null) {
|
|
||||||
LogHelper.printException(() -> "Unknown PlayerType encountered: " + type);
|
/**
|
||||||
} else {
|
* Injection point.
|
||||||
PlayerType.setCurrent(newType);
|
*/
|
||||||
LogHelper.printDebug(() -> "PlayerType was updated to: " + newType);
|
public static void setVideoState(@Nullable Enum<?> youTubeVideoState) {
|
||||||
}
|
if (youTubeVideoState == null) return;
|
||||||
|
|
||||||
|
VideoState.setFromString(youTubeVideoState.name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import java.lang.reflect.Method;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import app.revanced.integrations.patches.playback.speed.RememberPlaybackSpeedPatch;
|
import app.revanced.integrations.patches.playback.speed.RememberPlaybackSpeedPatch;
|
||||||
|
import app.revanced.integrations.shared.VideoState;
|
||||||
import app.revanced.integrations.utils.LogHelper;
|
import app.revanced.integrations.utils.LogHelper;
|
||||||
import app.revanced.integrations.utils.ReVancedUtils;
|
import app.revanced.integrations.utils.ReVancedUtils;
|
||||||
|
|
||||||
@ -183,7 +184,12 @@ public final class VideoInformation {
|
|||||||
* @return If the playback is at the end of the video.
|
* @return If the playback is at the end of the video.
|
||||||
*
|
*
|
||||||
* If video is playing in the background with no video visible,
|
* If video is playing in the background with no video visible,
|
||||||
* this always returns false (even if the video is actually at the end)
|
* this always returns false (even if the video is actually at the end).
|
||||||
|
*
|
||||||
|
* This is equivalent to checking for {@link VideoState#ENDED},
|
||||||
|
* but can give a more up to date result for code calling from some hooks.
|
||||||
|
*
|
||||||
|
* @see VideoState
|
||||||
*/
|
*/
|
||||||
public static boolean isAtEndOfVideo() {
|
public static boolean isAtEndOfVideo() {
|
||||||
return videoTime > 0 && videoLength > 0 && videoTime >= videoLength;
|
return videoTime > 0 && videoLength > 0 && videoTime >= videoLength;
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package app.revanced.integrations.shared
|
package app.revanced.integrations.shared
|
||||||
|
|
||||||
import app.revanced.integrations.utils.Event
|
import app.revanced.integrations.utils.Event
|
||||||
|
import app.revanced.integrations.utils.LogHelper
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WatchWhile player type
|
* WatchWhile player type
|
||||||
*/
|
*/
|
||||||
@Suppress("unused")
|
|
||||||
enum class PlayerType {
|
enum class PlayerType {
|
||||||
/**
|
/**
|
||||||
* Includes Shorts and Stories playback.
|
* Includes Shorts and Stories playback.
|
||||||
@ -40,15 +40,15 @@ enum class PlayerType {
|
|||||||
|
|
||||||
private val nameToPlayerType = values().associateBy { it.name }
|
private val nameToPlayerType = values().associateBy { it.name }
|
||||||
|
|
||||||
/**
|
|
||||||
* safely parse from a string
|
|
||||||
*
|
|
||||||
* @param name the name to find
|
|
||||||
* @return the enum constant, or null if not found
|
|
||||||
*/
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun safeParseFromString(name: String): PlayerType? {
|
fun setFromString(enumName: String) {
|
||||||
return nameToPlayerType[name]
|
val newType = nameToPlayerType[enumName]
|
||||||
|
if (newType == null) {
|
||||||
|
LogHelper.printException { "Unknown PlayerType encountered: $enumName" }
|
||||||
|
} else if (current != newType) {
|
||||||
|
LogHelper.printDebug { "PlayerType changed to: $newType" }
|
||||||
|
current = newType
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -57,7 +57,7 @@ enum class PlayerType {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
var current
|
var current
|
||||||
get() = currentPlayerType
|
get() = currentPlayerType
|
||||||
set(value) {
|
private set(value) {
|
||||||
currentPlayerType = value
|
currentPlayerType = value
|
||||||
onChange(currentPlayerType)
|
onChange(currentPlayerType)
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ enum class PlayerType {
|
|||||||
* although can return false positive if the player is minimized.
|
* although can return false positive if the player is minimized.
|
||||||
*
|
*
|
||||||
* @return If nothing, a Short, a Story,
|
* @return If nothing, a Short, a Story,
|
||||||
* or a regular minimized video is sliding off screen to a dismissed or hidden state.
|
* or a regular video is minimized video or sliding off screen to a dismissed or hidden state.
|
||||||
*/
|
*/
|
||||||
fun isNoneHiddenOrMinimized(): Boolean {
|
fun isNoneHiddenOrMinimized(): Boolean {
|
||||||
return this == NONE || this == HIDDEN
|
return this == NONE || this == HIDDEN
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
package app.revanced.integrations.shared
|
||||||
|
|
||||||
|
import app.revanced.integrations.utils.LogHelper
|
||||||
|
import app.revanced.integrations.patches.VideoInformation
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VideoState playback state.
|
||||||
|
*/
|
||||||
|
enum class VideoState {
|
||||||
|
NEW,
|
||||||
|
PLAYING,
|
||||||
|
PAUSED,
|
||||||
|
RECOVERABLE_ERROR,
|
||||||
|
UNRECOVERABLE_ERROR,
|
||||||
|
/**
|
||||||
|
* @see [VideoInformation.isAtEndOfVideo]
|
||||||
|
*/
|
||||||
|
ENDED;
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
private val nameToVideoState = values().associateBy { it.name }
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun setFromString(enumName: String) {
|
||||||
|
val state = nameToVideoState[enumName]
|
||||||
|
if (state == null) {
|
||||||
|
LogHelper.printException { "Unknown VideoState encountered: $enumName" }
|
||||||
|
} else if (currentVideoState != state) {
|
||||||
|
LogHelper.printDebug { "VideoState changed to: $state" }
|
||||||
|
currentVideoState = state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Depending on which hook this is called from,
|
||||||
|
* this value may not be up to date with the actual playback state.
|
||||||
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
var current: VideoState?
|
||||||
|
get() = currentVideoState
|
||||||
|
private set(value) {
|
||||||
|
currentVideoState = value
|
||||||
|
}
|
||||||
|
|
||||||
|
private var currentVideoState : VideoState? = null
|
||||||
|
}
|
||||||
|
}
|
@ -20,6 +20,7 @@ import java.util.Objects;
|
|||||||
import app.revanced.integrations.patches.VideoInformation;
|
import app.revanced.integrations.patches.VideoInformation;
|
||||||
import app.revanced.integrations.settings.SettingsEnum;
|
import app.revanced.integrations.settings.SettingsEnum;
|
||||||
import app.revanced.integrations.shared.PlayerType;
|
import app.revanced.integrations.shared.PlayerType;
|
||||||
|
import app.revanced.integrations.shared.VideoState;
|
||||||
import app.revanced.integrations.sponsorblock.objects.CategoryBehaviour;
|
import app.revanced.integrations.sponsorblock.objects.CategoryBehaviour;
|
||||||
import app.revanced.integrations.sponsorblock.objects.SegmentCategory;
|
import app.revanced.integrations.sponsorblock.objects.SegmentCategory;
|
||||||
import app.revanced.integrations.sponsorblock.objects.SponsorSegment;
|
import app.revanced.integrations.sponsorblock.objects.SponsorSegment;
|
||||||
@ -522,6 +523,7 @@ public class SegmentPlaybackController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final boolean videoIsPaused = VideoState.getCurrent() == VideoState.PAUSED;
|
||||||
if (!userManuallySkipped) {
|
if (!userManuallySkipped) {
|
||||||
// check for any smaller embedded segments, and count those as autoskipped
|
// check for any smaller embedded segments, and count those as autoskipped
|
||||||
final boolean showSkipToast = SettingsEnum.SB_TOAST_ON_SKIP.getBoolean();
|
final boolean showSkipToast = SettingsEnum.SB_TOAST_ON_SKIP.getBoolean();
|
||||||
@ -532,7 +534,10 @@ public class SegmentPlaybackController {
|
|||||||
if (otherSegment == segmentToSkip ||
|
if (otherSegment == segmentToSkip ||
|
||||||
(otherSegment.category != SegmentCategory.HIGHLIGHT && segmentToSkip.containsSegment(otherSegment))) {
|
(otherSegment.category != SegmentCategory.HIGHLIGHT && segmentToSkip.containsSegment(otherSegment))) {
|
||||||
otherSegment.didAutoSkipped = true;
|
otherSegment.didAutoSkipped = true;
|
||||||
if (showSkipToast) {
|
// Do not show a toast if the user is scrubbing thru a paused video.
|
||||||
|
// Cannot do this video state check in setTime or earlier in this method, as the video state may not be up to date.
|
||||||
|
// So instead, only hide toasts because all other skip logic done while paused causes no harm.
|
||||||
|
if (showSkipToast && !videoIsPaused) {
|
||||||
showSkippedSegmentToast(otherSegment);
|
showSkippedSegmentToast(otherSegment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -542,7 +547,7 @@ public class SegmentPlaybackController {
|
|||||||
if (segmentToSkip.category == SegmentCategory.UNSUBMITTED) {
|
if (segmentToSkip.category == SegmentCategory.UNSUBMITTED) {
|
||||||
removeUnsubmittedSegments();
|
removeUnsubmittedSegments();
|
||||||
SponsorBlockUtils.setNewSponsorSegmentPreviewed();
|
SponsorBlockUtils.setNewSponsorSegmentPreviewed();
|
||||||
} else {
|
} else if (!videoIsPaused) {
|
||||||
SponsorBlockUtils.sendViewRequestAsync(segmentToSkip);
|
SponsorBlockUtils.sendViewRequestAsync(segmentToSkip);
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user