diff --git a/Manager/app/src/main/kotlin/com/meowarex/rlmobile/patcher/steps/patch/SmaliPatchStep.kt b/Manager/app/src/main/kotlin/com/meowarex/rlmobile/patcher/steps/patch/SmaliPatchStep.kt index 6e76762..0f5a914 100644 --- a/Manager/app/src/main/kotlin/com/meowarex/rlmobile/patcher/steps/patch/SmaliPatchStep.kt +++ b/Manager/app/src/main/kotlin/com/meowarex/rlmobile/patcher/steps/patch/SmaliPatchStep.kt @@ -42,6 +42,8 @@ class SmaliPatchStep( val patches = mutableListOf() val localsBumps = mutableMapOf, Int>() val disabledFiles = options.disabledPatchFiles() + val knownExtensionFiles = options.knownExtensionFiles() + val enabledExtensionFiles = options.enabledExtensionFiles() // Load and parse all the patches from the smali archive. container.log("Loading patches from smali patch archive: ${patchesZip.absolutePath}") @@ -54,6 +56,11 @@ class SmaliPatchStep( if (patchFile.endsWith(".smali") && patchFile.startsWith("extension/")) { val relative = patchFile.removePrefix("extension/") + if (relative in knownExtensionFiles && relative !in enabledExtensionFiles) { + container.log("Skipping disabled extension smali: $relative") + continue + } + val out = smaliDir.resolve(relative) // Guard against zip-slip: a crafted entry could otherwise escape smaliDir. val baseCanonical = smaliDir.canonicalPath + File.separator diff --git a/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/previews/screens/PatchOptionsScreenPreview.kt b/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/previews/screens/PatchOptionsScreenPreview.kt index 2e9d038..95afaaf 100644 --- a/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/previews/screens/PatchOptionsScreenPreview.kt +++ b/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/previews/screens/PatchOptionsScreenPreview.kt @@ -40,6 +40,8 @@ private fun PatchOptionsScreenPreview( patchLockState = { PatchLock.Free }, variantIndex = { 0 }, onSelectVariant = { _, _ -> }, + isSubOptionEnabled = { _, _ -> true }, + onToggleSubOption = { _, _, _ -> }, isConfigValid = parameters.isConfigValid, onInstall = {}, ) diff --git a/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/KnownPatch.kt b/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/KnownPatch.kt index 1471ed6..43c37a0 100644 --- a/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/KnownPatch.kt +++ b/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/KnownPatch.kt @@ -8,12 +8,23 @@ import com.meowarex.rlmobile.ui.screens.patchopts.PatchDefault.Enabled data class PatchVariant( @StringRes val titleRes: Int, val fileNames: List, + val extensionFileNames: List = emptyList(), +) + +data class PatchSubOption( + val key: String, + @StringRes val titleRes: Int, + @StringRes val descRes: Int, + val fileNames: List, + val default: PatchDefault, + val extensionFileNames: List = emptyList(), ) enum class KnownPatch( val order: Int, // Patch order in the UI List (lower = higher up) [Main Patches: multiples of 10 | Sub Patches: multiples of 1] val fileNames: List, + val extensionFileNames: List = emptyList(), @StringRes val titleRes: Int, @StringRes val descRes: Int, val default: PatchDefault, // Default state of the patch in the UI List (enabled/disabled) @@ -21,6 +32,7 @@ enum class KnownPatch( val disables: List = emptyList(), val variants: List = emptyList(), val defaultVariantIndex: Int = 0, + val subOptions: List = emptyList(), ) { LyricsDisableCover( order = 41, @@ -135,6 +147,36 @@ enum class KnownPatch( ), ), ), + MiniPlayerGestures( + order = 52, + fileNames = listOf("mini-player-gestures.patch"), + extensionFileNames = listOf( + "radiant/MiniPlayerGestures.smali", + "radiant/MiniPlayerGestures\$Gesture.smali", + "radiant/MiniPlayerGestures\$RootGesture.smali", + "radiant/MiniPlayerGestures\$ApplyPending.smali", + ), + titleRes = R.string.patch_mini_player_gestures_title, + descRes = R.string.patch_mini_player_gestures_desc, + default = Enabled, + subOptions = listOf( + PatchSubOption( + key = "MiniPlayerGestures.LeftRight", + titleRes = R.string.patch_mini_player_left_right_gestures_title, + descRes = R.string.patch_mini_player_left_right_gestures_desc, + fileNames = listOf("mini-player-gestures-left-right.patch"), + default = Disabled, + extensionFileNames = listOf( + "radiant/MiniPlayerTrackGestures.smali", + "radiant/MiniPlayerTrackGestures\$Gesture.smali", + "radiant/MiniPlayerTrackGestures\$OffsetLayer.smali", + "radiant/MiniPlayerTrackGestures\$ResetAnimator.smali", + "radiant/MiniPlayerTrackGestures\$TextDraw.smali", + "com/tidal/android/feature/appscaffold/ui/q\$c.smali", + ), + ), + ), + ), EnableLegacyUi( order = 10, fileNames = listOf("enable-legacy-ui.patch"), @@ -152,6 +194,7 @@ enum class KnownPatch( QualityBadgeColors, LyricsProgressPill, CoverEverywhere, + MiniPlayerGestures, ), ); diff --git a/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/PatchOptions.kt b/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/PatchOptions.kt index 36955a2..7a7f5ac 100644 --- a/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/PatchOptions.kt +++ b/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/PatchOptions.kt @@ -40,6 +40,9 @@ data class PatchOptions( fun isEnabled(patch: KnownPatch): Boolean = patchStates[patch.name] ?: patch.default.isEnabled + fun isEnabled(subOption: PatchSubOption): Boolean = + patchStates[subOption.key] ?: subOption.default.isEnabled + fun disabledPatchFiles(): Set = buildSet { for (patch in KnownPatch.All) { val enabled = isEnabled(patch) @@ -52,6 +55,35 @@ data class PatchOptions( if (!enabled || index != selected) addAll(variant.fileNames) } } + for (subOption in patch.subOptions) { + if (!enabled || !isEnabled(subOption)) addAll(subOption.fileNames) + } + } + } + + fun knownExtensionFiles(): Set = buildSet { + for (patch in KnownPatch.All) { + addAll(patch.extensionFileNames) + patch.variants.forEach { addAll(it.extensionFileNames) } + patch.subOptions.forEach { addAll(it.extensionFileNames) } + } + } + + fun enabledExtensionFiles(): Set = buildSet { + for (patch in KnownPatch.All) { + if (!isEnabled(patch)) continue + + addAll(patch.extensionFileNames) + + if (patch.variants.isNotEmpty()) { + val selected = (selectedVariants[patch.name] ?: patch.defaultVariantIndex) + .coerceIn(0, patch.variants.lastIndex) + addAll(patch.variants[selected].extensionFileNames) + } + + for (subOption in patch.subOptions) { + if (isEnabled(subOption)) addAll(subOption.extensionFileNames) + } } } diff --git a/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/PatchOptionsModel.kt b/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/PatchOptionsModel.kt index 78b90fd..ab28588 100644 --- a/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/PatchOptionsModel.kt +++ b/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/PatchOptionsModel.kt @@ -60,6 +60,14 @@ class PatchOptionsModel( fun isPatchEnabled(patch: KnownPatch): Boolean = patchStates[patch.name] ?: patch.default.isEnabled + fun isSubOptionEnabled(patch: KnownPatch, subOption: PatchSubOption): Boolean = + isPatchEnabled(patch) && (patchStates[subOption.key] ?: subOption.default.isEnabled) + + fun setSubOptionEnabled(patch: KnownPatch, subOption: PatchSubOption, enabled: Boolean) { + if (subOption !in patch.subOptions) return + patchStates = patchStates + (subOption.key to enabled) + } + fun setPatchEnabled(patch: KnownPatch, enabled: Boolean) { fun closure(seed: KnownPatch, step: (KnownPatch) -> List): Set = buildSet { diff --git a/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/PatchOptionsScreen.kt b/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/PatchOptionsScreen.kt index bd3eb26..0b4a0f3 100644 --- a/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/PatchOptionsScreen.kt +++ b/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/PatchOptionsScreen.kt @@ -66,6 +66,8 @@ class PatchOptionsScreen( patchLockState = model::lockState, variantIndex = model::variantIndex, onSelectVariant = model::selectVariant, + isSubOptionEnabled = model::isSubOptionEnabled, + onToggleSubOption = model::setSubOptionEnabled, isConfigValid = model.isConfigValid, onInstall = { @@ -102,6 +104,8 @@ fun PatchOptionsScreenContent( patchLockState: (KnownPatch) -> PatchLock, variantIndex: (KnownPatch) -> Int, onSelectVariant: (KnownPatch, Int) -> Unit, + isSubOptionEnabled: (KnownPatch, PatchSubOption) -> Boolean, + onToggleSubOption: (KnownPatch, PatchSubOption, Boolean) -> Unit, isConfigValid: Boolean, onInstall: () -> Unit, @@ -171,6 +175,8 @@ fun PatchOptionsScreenContent( lockState = patchLockState, variantIndex = variantIndex, onSelectVariant = onSelectVariant, + isSubOptionEnabled = isSubOptionEnabled, + onToggleSubOption = onToggleSubOption, modifier = Modifier.padding(top = 4.dp), ) diff --git a/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/components/PatchSelectionAccordion.kt b/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/components/PatchSelectionAccordion.kt index c706022..99d66f0 100644 --- a/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/components/PatchSelectionAccordion.kt +++ b/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/components/PatchSelectionAccordion.kt @@ -24,6 +24,7 @@ import androidx.compose.ui.unit.dp import com.meowarex.rlmobile.R import com.meowarex.rlmobile.ui.screens.patchopts.KnownPatch import com.meowarex.rlmobile.ui.screens.patchopts.PatchLock +import com.meowarex.rlmobile.ui.screens.patchopts.PatchSubOption private data class LockInfo(val patch: KnownPatch, val lock: PatchLock) @@ -36,6 +37,8 @@ fun PatchSelectionAccordion( lockState: (KnownPatch) -> PatchLock, variantIndex: (KnownPatch) -> Int, onSelectVariant: (KnownPatch, Int) -> Unit, + isSubOptionEnabled: (KnownPatch, PatchSubOption) -> Boolean, + onToggleSubOption: (KnownPatch, PatchSubOption, Boolean) -> Unit, modifier: Modifier = Modifier, ) { var expanded by rememberSaveable { mutableStateOf(false) } @@ -131,6 +134,29 @@ fun PatchSelectionAccordion( } } } + + if (patch.subOptions.isNotEmpty()) { + AnimatedVisibility(visible = checked) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(start = 12.dp, end = 4.dp, top = 4.dp, bottom = 4.dp), + ) { + for (subOption in patch.subOptions) key(subOption) { + PatchSwitchRow( + title = stringResource(subOption.titleRes), + description = stringResource(subOption.descRes), + checked = isSubOptionEnabled(patch, subOption), + lock = PatchLock.Free, + onCheckedChange = { + onToggleSubOption(patch, subOption, it) + }, + onLockedTap = {}, + ) + } + } + } + } } } } diff --git a/Manager/app/src/main/res/values/strings.xml b/Manager/app/src/main/res/values/strings.xml index abe8cef..dee85e4 100644 --- a/Manager/app/src/main/res/values/strings.xml +++ b/Manager/app/src/main/res/values/strings.xml @@ -289,6 +289,10 @@ Redesigned Mini-Player Integrates the Seekbar into the control panel at the bottom of the screen. + Mini-Player Gestures + Swipe up on the mini-player to open the full player. + Next/Previous Gestures + Swipe left or right on the mini-player to skip tracks. Floating Grey Black diff --git a/patches/data.json b/patches/data.json index cd58bee..d4af060 100644 --- a/patches/data.json +++ b/patches/data.json @@ -1,5 +1,5 @@ { "tidalVersionCode": 9090, "tidalApkUrl": "https://github.com/meowarex/rl-mobile/releases/download/latest/tidal-stock.apk", - "patchesVersion": "0.9.10" + "patchesVersion": "0.9.12" } diff --git a/patches/extension/com/tidal/android/feature/appscaffold/ui/q$c.smali b/patches/extension/com/tidal/android/feature/appscaffold/ui/q$c.smali new file mode 100644 index 0000000..2b3b99d --- /dev/null +++ b/patches/extension/com/tidal/android/feature/appscaffold/ui/q$c.smali @@ -0,0 +1,74 @@ +.class public final Lcom/tidal/android/feature/appscaffold/ui/q$c; +.super Lcom/tidal/android/feature/appscaffold/ui/q; +.source "SourceFile" + +# Synthetic mini-player event used by right swipe (previous/rewind). +# TIDAL already exposes q$a for next in this path + +# annotations +.annotation system Ldalvik/annotation/EnclosingClass; + value = Lcom/tidal/android/feature/appscaffold/ui/q; +.end annotation + +.annotation system Ldalvik/annotation/InnerClass; + accessFlags = 0x19 + name = "c" +.end annotation + + +# static fields +.field public static final a:Lcom/tidal/android/feature/appscaffold/ui/q$c; + + +# direct methods +.method static constructor ()V + .locals 1 + + new-instance v0, Lcom/tidal/android/feature/appscaffold/ui/q$c; + + invoke-direct {v0}, Lcom/tidal/android/feature/appscaffold/ui/q;->()V + + sput-object v0, Lcom/tidal/android/feature/appscaffold/ui/q$c;->a:Lcom/tidal/android/feature/appscaffold/ui/q$c; + + return-void +.end method + + +# virtual methods +.method public final equals(Ljava/lang/Object;)Z + .locals 1 + + const/4 v0, 0x1 + + if-ne p0, p1, :cond_0 + + return v0 + + :cond_0 + instance-of p1, p1, Lcom/tidal/android/feature/appscaffold/ui/q$c; + + if-nez p1, :cond_1 + + const/4 p1, 0x0 + + return p1 + + :cond_1 + return v0 +.end method + +.method public final hashCode()I + .locals 1 + + const v0, -0x5d6a0f8 + + return v0 +.end method + +.method public final toString()Ljava/lang/String; + .locals 1 + + const-string v0, "PreviousButtonClicked" + + return-object v0 +.end method diff --git a/patches/extension/radiant/MiniPlayerGestures$ApplyPending.smali b/patches/extension/radiant/MiniPlayerGestures$ApplyPending.smali new file mode 100644 index 0000000..d54eaaf --- /dev/null +++ b/patches/extension/radiant/MiniPlayerGestures$ApplyPending.smali @@ -0,0 +1,62 @@ +.class public final Lradiant/MiniPlayerGestures$ApplyPending; +.super Ljava/lang/Object; +.implements Ljava/lang/Runnable; + +# annotations +.annotation system Ldalvik/annotation/EnclosingClass; + value = Lradiant/MiniPlayerGestures; +.end annotation + +.annotation system Ldalvik/annotation/InnerClass; + accessFlags = 0x19 + name = "ApplyPending" +.end annotation + + +# instance fields +.field public final a:Landroidx/compose/material3/SheetState; + +.field public final b:I + + +# direct methods +.method public constructor (Landroidx/compose/material3/SheetState;I)V + .locals 0 + + invoke-direct {p0}, Ljava/lang/Object;->()V + + iput-object p1, p0, Lradiant/MiniPlayerGestures$ApplyPending;->a:Landroidx/compose/material3/SheetState; + + iput p2, p0, Lradiant/MiniPlayerGestures$ApplyPending;->b:I + + return-void +.end method + + +# virtual methods +# Apply once, then re schedule if there is still pending movement +# -> Sheet anchors can appear one (or more) frames after opening the player, so this keeps applying the latest drag until no delta remains +.method public final run()V + .locals 3 + + iget-object v0, p0, Lradiant/MiniPlayerGestures$ApplyPending;->a:Landroidx/compose/material3/SheetState; + + invoke-static {v0}, Lradiant/MiniPlayerGestures;->applyPendingDrag(Landroidx/compose/material3/SheetState;)V + + iget v1, p0, Lradiant/MiniPlayerGestures$ApplyPending;->b:I + + add-int/lit8 v1, v1, -0x1 + + if-lez v1, :done + + invoke-static {v0}, Lradiant/MiniPlayerGestures;->needsApply(Landroidx/compose/material3/SheetState;)Z + + move-result v2 + + if-eqz v2, :done + + invoke-static {v0, v1}, Lradiant/MiniPlayerGestures;->scheduleApply(Landroidx/compose/material3/SheetState;I)V + + :done + return-void +.end method diff --git a/patches/extension/radiant/MiniPlayerGestures$Gesture.smali b/patches/extension/radiant/MiniPlayerGestures$Gesture.smali new file mode 100644 index 0000000..f7b00e2 --- /dev/null +++ b/patches/extension/radiant/MiniPlayerGestures$Gesture.smali @@ -0,0 +1,408 @@ +.class public final Lradiant/MiniPlayerGestures$Gesture; +.super Ljava/lang/Object; +.implements Lyl0/l; + +# annotations +.annotation system Ldalvik/annotation/EnclosingClass; + value = Lradiant/MiniPlayerGestures; +.end annotation + +.annotation system Ldalvik/annotation/InnerClass; + accessFlags = 0x19 + name = "Gesture" +.end annotation + + +# instance fields +.field public final a:Lyl0/l; + +# Y at ACTION_DOWN +.field public b:F + +# Last Y seen (on this pointer stream) +.field public c:F + +# True while this listener owns an active pointer stream +.field public d:Z + +# True when sheet drag has started +.field public e:Z + +.field public final f:Landroidx/compose/material3/SheetState; + +.field public g:F + +# X at ACTION_DOWN +.field public i:F + +# True once horizontal movement wins (prevents later vertical start) +.field public j:Z + + +# direct methods +.method public constructor (Lyl0/l;Landroidx/compose/material3/SheetState;)V + .locals 0 + + invoke-direct {p0}, Ljava/lang/Object;->()V + + iput-object p1, p0, Lradiant/MiniPlayerGestures$Gesture;->a:Lyl0/l; + + iput-object p2, p0, Lradiant/MiniPlayerGestures$Gesture;->f:Landroidx/compose/material3/SheetState; + + return-void +.end method + +.method private static dp(F)F + .locals 1 + + invoke-static {}, Landroid/content/res/Resources;->getSystem()Landroid/content/res/Resources; + + move-result-object v0 + + invoke-virtual {v0}, Landroid/content/res/Resources;->getDisplayMetrics()Landroid/util/DisplayMetrics; + + move-result-object v0 + + iget v0, v0, Landroid/util/DisplayMetrics;->density:F + + mul-float/2addr p0, v0 + + return p0 +.end method + +.method private dragSheet(FJ)V + .locals 1 + + iget-object v0, p0, Lradiant/MiniPlayerGestures$Gesture;->f:Landroidx/compose/material3/SheetState; + + invoke-static {v0, p1, p2, p3}, Lradiant/MiniPlayerGestures;->updateDragTimed(Landroidx/compose/material3/SheetState;FJ)V + + return-void +.end method + +.method private finishSheet(F)V + .locals 2 + + iget-object v0, p0, Lradiant/MiniPlayerGestures$Gesture;->f:Landroidx/compose/material3/SheetState; + + iget-object v1, p0, Lradiant/MiniPlayerGestures$Gesture;->a:Lyl0/l; + + invoke-static {v0, v1, p1}, Lradiant/MiniPlayerGestures;->finishDrag(Landroidx/compose/material3/SheetState;Lyl0/l;F)V + + return-void +.end method + +.method private openPlayer()V + .locals 2 + + iget-object v0, p0, Lradiant/MiniPlayerGestures$Gesture;->a:Lyl0/l; + + sget-object v1, Lcom/tidal/android/feature/appscaffold/ui/b$b;->a:Lcom/tidal/android/feature/appscaffold/ui/b$b; + + invoke-interface {v0, v1}, Lyl0/l;->invoke(Ljava/lang/Object;)Ljava/lang/Object; + + return-void +.end method + +.method private reset()V + .locals 1 + + const/4 v0, 0x0 + + iput-boolean v0, p0, Lradiant/MiniPlayerGestures$Gesture;->d:Z + + iput-boolean v0, p0, Lradiant/MiniPlayerGestures$Gesture;->e:Z + + iput-boolean v0, p0, Lradiant/MiniPlayerGestures$Gesture;->j:Z + + const/4 v0, 0x0 + + iput v0, p0, Lradiant/MiniPlayerGestures$Gesture;->i:F + + iput v0, p0, Lradiant/MiniPlayerGestures$Gesture;->g:F + + return-void +.end method + +.method private startSheet(FJ)V + .locals 2 + + # empty player guard + invoke-static {}, Lradiant/MiniPlayerGestures;->hasMiniPlayerMedia()Z + + move-result v0 + + if-nez v0, :start_guard + + return-void + + :start_guard + + # avoid starting twice + iget-boolean v0, p0, Lradiant/MiniPlayerGestures$Gesture;->e:Z + + if-eqz v0, :start + + return-void + + :start + const/4 v0, 0x1 + + iput-boolean v0, p0, Lradiant/MiniPlayerGestures$Gesture;->e:Z + + iget-object v1, p0, Lradiant/MiniPlayerGestures$Gesture;->f:Landroidx/compose/material3/SheetState; + + iget v0, p0, Lradiant/MiniPlayerGestures$Gesture;->b:F + + invoke-static {v1, p1, v0, p2, p3}, Lradiant/MiniPlayerGestures;->beginDrag(Landroidx/compose/material3/SheetState;FFJ)V + + invoke-direct {p0}, Lradiant/MiniPlayerGestures$Gesture;->openPlayer()V + + return-void +.end method + + +# virtual methods +# Listens for MotionEvents +.method public final invoke(Landroid/view/MotionEvent;)Lkotlin/u; + .locals 11 + + invoke-virtual {p1}, Landroid/view/MotionEvent;->getActionMasked()I + + move-result v0 + + if-eqz v0, :down + + const/4 v1, 0x1 + + if-eq v0, v1, :up + + const/4 v1, 0x2 + + if-eq v0, v1, :move + + const/4 v1, 0x3 + + if-eq v0, v1, :cancel + + goto :done + + # ACTION_DOWN + :down + invoke-static {p1}, Lradiant/MiniPlayerGestures;->beginMotion(Landroid/view/MotionEvent;)V + + invoke-virtual {p1}, Landroid/view/MotionEvent;->getRawY()F + + move-result v0 + + iput v0, p0, Lradiant/MiniPlayerGestures$Gesture;->b:F + + iput v0, p0, Lradiant/MiniPlayerGestures$Gesture;->c:F + + const/4 v0, 0x1 + + iput-boolean v0, p0, Lradiant/MiniPlayerGestures$Gesture;->d:Z + + const/4 v0, 0x0 + + iput-boolean v0, p0, Lradiant/MiniPlayerGestures$Gesture;->e:Z + + const/4 v0, 0x0 + + iput v0, p0, Lradiant/MiniPlayerGestures$Gesture;->g:F + + invoke-virtual {p1}, Landroid/view/MotionEvent;->getRawX()F + + move-result v0 + + iput v0, p0, Lradiant/MiniPlayerGestures$Gesture;->i:F + + const/4 v0, 0x0 + + iput-boolean v0, p0, Lradiant/MiniPlayerGestures$Gesture;->j:Z + + goto :done + + # ACTION_MOVE + :move + iget-boolean v0, p0, Lradiant/MiniPlayerGestures$Gesture;->d:Z + + if-eqz v0, :done + + invoke-static {p1}, Lradiant/MiniPlayerGestures;->trackMotion(Landroid/view/MotionEvent;)V + + invoke-virtual {p1}, Landroid/view/MotionEvent;->getRawY()F + + move-result v0 + + invoke-virtual {p1}, Landroid/view/MotionEvent;->getEventTime()J + + move-result-wide v5 + + iget v1, p0, Lradiant/MiniPlayerGestures$Gesture;->c:F + + sub-float v1, v0, v1 + + iput v1, p0, Lradiant/MiniPlayerGestures$Gesture;->g:F + + iget v2, p0, Lradiant/MiniPlayerGestures$Gesture;->b:F + + sub-float v2, v0, v2 + + iget-boolean v3, p0, Lradiant/MiniPlayerGestures$Gesture;->e:Z + + if-eqz v3, :maybe_start + + invoke-direct {p0, v2, v5, v6}, Lradiant/MiniPlayerGestures$Gesture;->dragSheet(FJ)V + + goto :store_last + + :maybe_start + iget-boolean v3, p0, Lradiant/MiniPlayerGestures$Gesture;->j:Z + + if-eqz v3, :axis_check + + goto :store_last + + :axis_check + invoke-virtual {p1}, Landroid/view/MotionEvent;->getRawX()F + + move-result v7 + + iget v8, p0, Lradiant/MiniPlayerGestures$Gesture;->i:F + + sub-float/2addr v7, v8 + + invoke-static {v7}, Ljava/lang/Math;->abs(F)F + + move-result v7 + + invoke-static {v2}, Ljava/lang/Math;->abs(F)F + + move-result v8 + + const/high16 v9, 0x41800000 # 16.0f + + invoke-static {v9}, Lradiant/MiniPlayerGestures$Gesture;->dp(F)F + + move-result v9 + + cmpg-float v10, v7, v9 + + if-gez v10, :vertical_check + + const/high16 v10, 0x3fc00000 # 1.5f + + mul-float/2addr v10, v8 + + cmpl-float v10, v7, v10 + + if-lez v10, :vertical_check + + const/4 v10, 0x1 + + iput-boolean v10, p0, Lradiant/MiniPlayerGestures$Gesture;->j:Z + + goto :store_last + + # At least 16dp up to open the player + :vertical_check + neg-float v9, v9 + + cmpg-float v10, v2, v9 + + if-lez v10, :vertical_dominance + + goto :store_last + + :vertical_dominance + const/high16 v10, 0x3fc00000 # 1.5f -> has to dominate horizontal mov. by 1.5x + + mul-float/2addr v7, v10 + + cmpl-float v10, v8, v7 + + if-gtz v10, :begin + + goto :store_last + + :begin + invoke-direct {p0, v2, v5, v6}, Lradiant/MiniPlayerGestures$Gesture;->startSheet(FJ)V + + invoke-direct {p0, v2, v5, v6}, Lradiant/MiniPlayerGestures$Gesture;->dragSheet(FJ)V + + + :store_last + iput v0, p0, Lradiant/MiniPlayerGestures$Gesture;->c:F + + goto :done + + # ACTION_UP + :up + iget-boolean v0, p0, Lradiant/MiniPlayerGestures$Gesture;->d:Z + + if-eqz v0, :done + + iget-boolean v0, p0, Lradiant/MiniPlayerGestures$Gesture;->e:Z + + if-eqz v0, :finish + + invoke-static {p1}, Lradiant/MiniPlayerGestures;->trackMotion(Landroid/view/MotionEvent;)V + + invoke-virtual {p1}, Landroid/view/MotionEvent;->getRawY()F + + move-result v0 + + invoke-virtual {p1}, Landroid/view/MotionEvent;->getEventTime()J + + move-result-wide v5 + + iget-object v1, p0, Lradiant/MiniPlayerGestures$Gesture;->f:Landroidx/compose/material3/SheetState; + + invoke-static {v1, v0, v5, v6}, Lradiant/MiniPlayerGestures;->updateDragToYTimed(Landroidx/compose/material3/SheetState;FJ)V + + invoke-static {v1}, Lradiant/MiniPlayerGestures;->releaseVelocity(Landroidx/compose/material3/SheetState;)F + + move-result v0 + + invoke-direct {p0, v0}, Lradiant/MiniPlayerGestures$Gesture;->finishSheet(F)V + + + :finish + invoke-direct {p0}, Lradiant/MiniPlayerGestures$Gesture;->reset()V + + goto :done + + # ACTION_CANCEL + :cancel + iget-boolean v0, p0, Lradiant/MiniPlayerGestures$Gesture;->e:Z + + if-eqz v0, :cancel_reset + + iget-object v0, p0, Lradiant/MiniPlayerGestures$Gesture;->f:Landroidx/compose/material3/SheetState; + + iget-object v1, p0, Lradiant/MiniPlayerGestures$Gesture;->a:Lyl0/l; + + invoke-static {v0, v1}, Lradiant/MiniPlayerGestures;->cancelDrag(Landroidx/compose/material3/SheetState;Lyl0/l;)V + + :cancel_reset + invoke-direct {p0}, Lradiant/MiniPlayerGestures$Gesture;->reset()V + + + :done + sget-object p1, Lkotlin/u;->a:Lkotlin/u; + + return-object p1 +.end method + +.method public bridge synthetic invoke(Ljava/lang/Object;)Ljava/lang/Object; + .locals 0 + + check-cast p1, Landroid/view/MotionEvent; + + invoke-virtual {p0, p1}, Lradiant/MiniPlayerGestures$Gesture;->invoke(Landroid/view/MotionEvent;)Lkotlin/u; + + move-result-object p1 + + return-object p1 +.end method diff --git a/patches/extension/radiant/MiniPlayerGestures$RootGesture.smali b/patches/extension/radiant/MiniPlayerGestures$RootGesture.smali new file mode 100644 index 0000000..27b0319 --- /dev/null +++ b/patches/extension/radiant/MiniPlayerGestures$RootGesture.smali @@ -0,0 +1,129 @@ +.class public final Lradiant/MiniPlayerGestures$RootGesture; +.super Ljava/lang/Object; +.implements Lyl0/l; + + +# annotations +.annotation system Ldalvik/annotation/EnclosingClass; + value = Lradiant/MiniPlayerGestures; +.end annotation + +.annotation system Ldalvik/annotation/InnerClass; + accessFlags = 0x19 + name = "RootGesture" +.end annotation + + +# instance fields +.field public final a:Lyl0/l; + +.field public final b:Landroidx/compose/material3/SheetState; + + +# direct methods +.method public constructor (Lyl0/l;Landroidx/compose/material3/SheetState;)V + .locals 0 + + invoke-direct {p0}, Ljava/lang/Object;->()V + + iput-object p1, p0, Lradiant/MiniPlayerGestures$RootGesture;->a:Lyl0/l; + + iput-object p2, p0, Lradiant/MiniPlayerGestures$RootGesture;->b:Landroidx/compose/material3/SheetState; + + return-void +.end method + + +# virtual methods +.method public final invoke(Landroid/view/MotionEvent;)Lkotlin/u; + .locals 6 + + iget-object v0, p0, Lradiant/MiniPlayerGestures$RootGesture;->b:Landroidx/compose/material3/SheetState; + + invoke-static {v0}, Lradiant/MiniPlayerGestures;->isDragging(Landroidx/compose/material3/SheetState;)Z + + move-result v1 + + if-eqz v1, :done + + invoke-virtual {p1}, Landroid/view/MotionEvent;->getActionMasked()I + + move-result v1 + + const/4 v2, 0x1 + + if-eq v1, v2, :up + + const/4 v2, 0x2 + + if-eq v1, v2, :move + + const/4 v2, 0x3 + + if-eq v1, v2, :cancel + + goto :done + + # ACTION_MOVE + :move + invoke-static {p1}, Lradiant/MiniPlayerGestures;->trackMotion(Landroid/view/MotionEvent;)V + + invoke-virtual {p1}, Landroid/view/MotionEvent;->getRawY()F + + move-result v2 + + invoke-virtual {p1}, Landroid/view/MotionEvent;->getEventTime()J + + move-result-wide v4 + + invoke-static {v0, v2, v4, v5}, Lradiant/MiniPlayerGestures;->updateDragToYTimed(Landroidx/compose/material3/SheetState;FJ)V + + goto :done + + # ACTION_UP + :up + invoke-static {p1}, Lradiant/MiniPlayerGestures;->trackMotion(Landroid/view/MotionEvent;)V + + invoke-virtual {p1}, Landroid/view/MotionEvent;->getRawY()F + + move-result v1 + + invoke-virtual {p1}, Landroid/view/MotionEvent;->getEventTime()J + + move-result-wide v4 + + invoke-static {v0, v1, v4, v5}, Lradiant/MiniPlayerGestures;->updateDragToYTimed(Landroidx/compose/material3/SheetState;FJ)V + + invoke-static {v0}, Lradiant/MiniPlayerGestures;->releaseVelocity(Landroidx/compose/material3/SheetState;)F + + move-result v1 + + iget-object v2, p0, Lradiant/MiniPlayerGestures$RootGesture;->a:Lyl0/l; + + invoke-static {v0, v2, v1}, Lradiant/MiniPlayerGestures;->finishDrag(Landroidx/compose/material3/SheetState;Lyl0/l;F)V + + goto :done + + # ACTION_CANCEL + :cancel + iget-object v2, p0, Lradiant/MiniPlayerGestures$RootGesture;->a:Lyl0/l; + + invoke-static {v0, v2}, Lradiant/MiniPlayerGestures;->cancelDrag(Landroidx/compose/material3/SheetState;Lyl0/l;)V + + :done + sget-object p1, Lkotlin/u;->a:Lkotlin/u; + + return-object p1 +.end method + +.method public bridge synthetic invoke(Ljava/lang/Object;)Ljava/lang/Object; + .locals 0 + + check-cast p1, Landroid/view/MotionEvent; + + invoke-virtual {p0, p1}, Lradiant/MiniPlayerGestures$RootGesture;->invoke(Landroid/view/MotionEvent;)Lkotlin/u; + + move-result-object p1 + + return-object p1 +.end method diff --git a/patches/extension/radiant/MiniPlayerGestures.smali b/patches/extension/radiant/MiniPlayerGestures.smali new file mode 100644 index 0000000..2be4df3 --- /dev/null +++ b/patches/extension/radiant/MiniPlayerGestures.smali @@ -0,0 +1,1057 @@ +.class public final Lradiant/MiniPlayerGestures; +.super Ljava/lang/Object; + + +# static fields +.field private static a:Landroidx/compose/material3/SheetState; + +# True while a swipe up drag owns the sheet +.field private static b:Z + +# Current drag offset (relative Y) +.field private static c:F + +# Amount of drag already dispatched to AnchoredDraggableState +.field private static d:F + +# Y where the swipe up drag started +.field private static e:F + +# Fallback Y velocity +.field private static f:F + +.field private static g:Landroidx/compose/material3/SheetState; + +# Material3 settle lambda +.field private static h:Lyl0/l; + +# Latest MotionEvent eventTime for drag updates +.field private static i:J + +# Previous drag offset for fallback velocity +.field private static j:F + +# Previous eventTime for fallback velocity +.field private static k:J + +# Fallback X velocity (used to prevent horizontal swipe triggering drag) +.field private static l:F + +# Previous X for fallback velocity +.field private static m:F + +# Latest X seen by the drag tracker +.field private static n:F + +.field private static o:Landroid/view/VelocityTracker; + +.field private static p:I + +# Mini player media state +.field private static r:Z + + +# direct methods +.method private constructor ()V + .locals 0 + + invoke-direct {p0}, Ljava/lang/Object;->()V + + return-void +.end method + +.method public static applyPendingDrag(Landroidx/compose/material3/SheetState;)V + .locals 5 + + sget-boolean v0, Lradiant/MiniPlayerGestures;->b:Z + + if-eqz v0, :done + + sget-object v0, Lradiant/MiniPlayerGestures;->a:Landroidx/compose/material3/SheetState; + + if-ne v0, p0, :done + + invoke-virtual {p0}, Landroidx/compose/material3/SheetState;->getHasExpandedState()Z + + move-result v0 + + if-eqz v0, :done + + invoke-virtual {p0}, Landroidx/compose/material3/SheetState;->getAnchoredDraggableState$material3_release()Landroidx/compose/material3/internal/AnchoredDraggableState; + + move-result-object p0 + + invoke-virtual {p0}, Landroidx/compose/material3/internal/AnchoredDraggableState;->getAnchors()Landroidx/compose/material3/internal/DraggableAnchors; + + move-result-object v4 + + invoke-interface {v4}, Landroidx/compose/material3/internal/DraggableAnchors;->maxAnchor()F + + move-result v4 + + # targetOffset = startRawY + dragOffset - hiddenAnchor. + sget v0, Lradiant/MiniPlayerGestures;->e:F + + sget v1, Lradiant/MiniPlayerGestures;->c:F + + add-float/2addr v0, v1 + + sub-float/2addr v0, v4 + + sget v1, Lradiant/MiniPlayerGestures;->d:F + + sub-float v2, v0, v1 + + const/4 v3, 0x0 + + cmpl-float v3, v2, v3 + + if-eqz v3, :done + + invoke-virtual {p0, v2}, Landroidx/compose/material3/internal/AnchoredDraggableState;->dispatchRawDelta(F)F + + move-result v2 + + sget v0, Lradiant/MiniPlayerGestures;->d:F + + add-float/2addr v0, v2 + + sput v0, Lradiant/MiniPlayerGestures;->d:F + + :done + return-void +.end method + +.method private static addRawMovement(Landroid/view/VelocityTracker;Landroid/view/MotionEvent;)V + .locals 4 + + invoke-static {p1}, Landroid/view/MotionEvent;->obtain(Landroid/view/MotionEvent;)Landroid/view/MotionEvent; + + move-result-object v0 + + invoke-virtual {p1}, Landroid/view/MotionEvent;->getRawX()F + + move-result v1 + + invoke-virtual {p1}, Landroid/view/MotionEvent;->getX()F + + move-result v2 + + sub-float/2addr v1, v2 + + invoke-virtual {p1}, Landroid/view/MotionEvent;->getRawY()F + + move-result v2 + + invoke-virtual {p1}, Landroid/view/MotionEvent;->getY()F + + move-result v3 + + sub-float/2addr v2, v3 + + invoke-virtual {v0, v1, v2}, Landroid/view/MotionEvent;->offsetLocation(FF)V + + invoke-virtual {p0, v0}, Landroid/view/VelocityTracker;->addMovement(Landroid/view/MotionEvent;)V + + invoke-virtual {v0}, Landroid/view/MotionEvent;->recycle()V + + return-void +.end method + +.method public static beginDrag(Landroidx/compose/material3/SheetState;FFJ)V + .locals 1 + + sput-object p0, Lradiant/MiniPlayerGestures;->a:Landroidx/compose/material3/SheetState; + + const/4 v0, 0x1 + + sput-boolean v0, Lradiant/MiniPlayerGestures;->b:Z + + sput p1, Lradiant/MiniPlayerGestures;->c:F + + const/4 v0, 0x0 + + sput-object v0, Lradiant/MiniPlayerGestures;->g:Landroidx/compose/material3/SheetState; + + sput-object v0, Lradiant/MiniPlayerGestures;->h:Lyl0/l; + + sput v0, Lradiant/MiniPlayerGestures;->d:F + + sput p2, Lradiant/MiniPlayerGestures;->e:F + + sput v0, Lradiant/MiniPlayerGestures;->f:F + + sput p1, Lradiant/MiniPlayerGestures;->j:F + + sput v0, Lradiant/MiniPlayerGestures;->l:F + + sget v0, Lradiant/MiniPlayerGestures;->n:F + + sput v0, Lradiant/MiniPlayerGestures;->m:F + + sput-wide p3, Lradiant/MiniPlayerGestures;->i:J + + sput-wide p3, Lradiant/MiniPlayerGestures;->k:J + + # Try immediately then retry because anchors can be created one frame later + invoke-static {p0}, Lradiant/MiniPlayerGestures;->applyPendingDrag(Landroidx/compose/material3/SheetState;)V + + const/16 v0, 0xa + + invoke-static {p0, v0}, Lradiant/MiniPlayerGestures;->scheduleApply(Landroidx/compose/material3/SheetState;I)V + + return-void +.end method + +.method public static beginMotion(Landroid/view/MotionEvent;)V + .locals 2 + + sget-object v0, Lradiant/MiniPlayerGestures;->o:Landroid/view/VelocityTracker; + + if-eqz v0, :obtain + + invoke-virtual {v0}, Landroid/view/VelocityTracker;->recycle()V + + :obtain + invoke-static {}, Landroid/view/VelocityTracker;->obtain()Landroid/view/VelocityTracker; + + move-result-object v0 + + sput-object v0, Lradiant/MiniPlayerGestures;->o:Landroid/view/VelocityTracker; + + const/4 v1, 0x0 + + invoke-virtual {p0, v1}, Landroid/view/MotionEvent;->getPointerId(I)I + + move-result v1 + + sput v1, Lradiant/MiniPlayerGestures;->p:I + + invoke-static {v0, p0}, Lradiant/MiniPlayerGestures;->addRawMovement(Landroid/view/VelocityTracker;Landroid/view/MotionEvent;)V + + invoke-virtual {p0}, Landroid/view/MotionEvent;->getRawX()F + + move-result v1 + + sput v1, Lradiant/MiniPlayerGestures;->n:F + + return-void +.end method + +.method public static endDrag(Landroidx/compose/material3/SheetState;)V + .locals 3 + + sget-object v0, Lradiant/MiniPlayerGestures;->a:Landroidx/compose/material3/SheetState; + + if-ne v0, p0, :done + + const/4 v0, 0x0 + + sput-boolean v0, Lradiant/MiniPlayerGestures;->b:Z + + sput v0, Lradiant/MiniPlayerGestures;->c:F + + sput v0, Lradiant/MiniPlayerGestures;->d:F + + sput v0, Lradiant/MiniPlayerGestures;->e:F + + sput v0, Lradiant/MiniPlayerGestures;->f:F + + sput v0, Lradiant/MiniPlayerGestures;->j:F + + sput v0, Lradiant/MiniPlayerGestures;->l:F + + sput v0, Lradiant/MiniPlayerGestures;->m:F + + sput v0, Lradiant/MiniPlayerGestures;->n:F + + sget-object v2, Lradiant/MiniPlayerGestures;->o:Landroid/view/VelocityTracker; + + if-eqz v2, :motion_recycled + + invoke-virtual {v2}, Landroid/view/VelocityTracker;->recycle()V + + const/4 v2, 0x0 + + sput-object v2, Lradiant/MiniPlayerGestures;->o:Landroid/view/VelocityTracker; + + :motion_recycled + + const/4 v1, 0x0 + + sput-object v1, Lradiant/MiniPlayerGestures;->a:Landroidx/compose/material3/SheetState; + + const-wide/16 v0, 0x0 + + sput-wide v0, Lradiant/MiniPlayerGestures;->k:J + + :done + return-void +.end method + +.method public static cancelDrag(Landroidx/compose/material3/SheetState;Lyl0/l;)V + .locals 1 + + invoke-static {p0}, Lradiant/MiniPlayerGestures;->isDragging(Landroidx/compose/material3/SheetState;)Z + + move-result v0 + + if-eqz v0, :done + + invoke-static {p0}, Lradiant/MiniPlayerGestures;->endDrag(Landroidx/compose/material3/SheetState;)V + + sget-object p0, Lcom/tidal/android/feature/appscaffold/ui/b$a;->a:Lcom/tidal/android/feature/appscaffold/ui/b$a; + + invoke-interface {p1, p0}, Lyl0/l;->invoke(Ljava/lang/Object;)Ljava/lang/Object; + + :done + return-void +.end method + +.method public static finishDrag(Landroidx/compose/material3/SheetState;Lyl0/l;F)V + .locals 6 + + invoke-static {p0}, Lradiant/MiniPlayerGestures;->isDragging(Landroidx/compose/material3/SheetState;)Z + + move-result v0 + + if-eqz v0, :done + + sget-object v0, Lradiant/MiniPlayerGestures;->g:Landroidx/compose/material3/SheetState; + + if-ne v0, p0, :fallback_snap + + sget-object v0, Lradiant/MiniPlayerGestures;->h:Lyl0/l; + + if-eqz v0, :fallback_snap + + invoke-static {p0, p2}, Lradiant/MiniPlayerGestures;->prepareSettleVelocity(Landroidx/compose/material3/SheetState;F)F + + move-result p2 + + :native_settle + + invoke-static {p0}, Lradiant/MiniPlayerGestures;->endDrag(Landroidx/compose/material3/SheetState;)V + + invoke-static {p2}, Ljava/lang/Float;->valueOf(F)Ljava/lang/Float; + + move-result-object p0 + + invoke-interface {v0, p0}, Lyl0/l;->invoke(Ljava/lang/Object;)Ljava/lang/Object; + + goto/16 :done + + :fallback_snap + + invoke-virtual {p0}, Landroidx/compose/material3/SheetState;->getAnchoredDraggableState$material3_release()Landroidx/compose/material3/internal/AnchoredDraggableState; + + move-result-object v0 + + invoke-virtual {v0}, Landroidx/compose/material3/internal/AnchoredDraggableState;->getAnchors()Landroidx/compose/material3/internal/DraggableAnchors; + + move-result-object v1 + + const/4 v5, 0x0 + + cmpl-float v3, p2, v5 + + if-gtz v3, :target_hidden + + cmpg-float v3, p2, v5 + + if-ltz v3, :target_expanded + + invoke-virtual {v0}, Landroidx/compose/material3/internal/AnchoredDraggableState;->getOffset()F + + move-result v4 + + invoke-interface {v1}, Landroidx/compose/material3/internal/DraggableAnchors;->minAnchor()F + + move-result v5 + + invoke-interface {v1}, Landroidx/compose/material3/internal/DraggableAnchors;->maxAnchor()F + + move-result p2 + + add-float/2addr v5, p2 + + const/high16 p2, 0x40000000 # 2.0f + + div-float/2addr v5, p2 + + cmpg-float p2, v4, v5 + + if-ltz p2, :target_expanded + + goto :target_hidden + + :target_hidden + sget-object v2, Landroidx/compose/material3/SheetValue;->Hidden:Landroidx/compose/material3/SheetValue; + + goto :target + + :target_expanded + + sget-object v2, Landroidx/compose/material3/SheetValue;->Expanded:Landroidx/compose/material3/SheetValue; + + :target + invoke-interface {v1, v2}, Landroidx/compose/material3/internal/DraggableAnchors;->hasAnchorFor(Ljava/lang/Object;)Z + + move-result p2 + + if-eqz p2, :close + + invoke-interface {v1, v2}, Landroidx/compose/material3/internal/DraggableAnchors;->positionOf(Ljava/lang/Object;)F + + move-result v3 + + invoke-virtual {v0}, Landroidx/compose/material3/internal/AnchoredDraggableState;->getOffset()F + + move-result v4 + + invoke-static {v4}, Ljava/lang/Float;->isNaN(F)Z + + move-result v5 + + if-eqz v5, :have_current + + const/4 v4, 0x0 + + :have_current + sub-float/2addr v3, v4 + + invoke-virtual {v0, v3}, Landroidx/compose/material3/internal/AnchoredDraggableState;->dispatchRawDelta(F)F + + invoke-static {v0, v2}, Landroidx/compose/material3/internal/AnchoredDraggableState;->access$setCurrentValue(Landroidx/compose/material3/internal/AnchoredDraggableState;Ljava/lang/Object;)V + + invoke-static {v0, v2}, Landroidx/compose/material3/internal/AnchoredDraggableState;->access$setDragTarget(Landroidx/compose/material3/internal/AnchoredDraggableState;Ljava/lang/Object;)V + + const/4 v3, 0x0 + + invoke-static {v0, v3}, Landroidx/compose/material3/internal/AnchoredDraggableState;->access$setLastVelocity(Landroidx/compose/material3/internal/AnchoredDraggableState;F)V + + invoke-static {p0}, Lradiant/MiniPlayerGestures;->endDrag(Landroidx/compose/material3/SheetState;)V + + sget-object v3, Landroidx/compose/material3/SheetValue;->Hidden:Landroidx/compose/material3/SheetValue; + + if-ne v2, v3, :done + + :close + invoke-static {p0}, Lradiant/MiniPlayerGestures;->endDrag(Landroidx/compose/material3/SheetState;)V + + sget-object p0, Lcom/tidal/android/feature/appscaffold/ui/b$a;->a:Lcom/tidal/android/feature/appscaffold/ui/b$a; + + invoke-interface {p1, p0}, Lyl0/l;->invoke(Ljava/lang/Object;)Ljava/lang/Object; + + :done + return-void +.end method + +.method public static isDragging(Landroidx/compose/material3/SheetState;)Z + .locals 1 + + sget-boolean v0, Lradiant/MiniPlayerGestures;->b:Z + + if-eqz v0, :no + + sget-object v0, Lradiant/MiniPlayerGestures;->a:Landroidx/compose/material3/SheetState; + + if-ne v0, p0, :no + + const/4 v0, 0x1 + + return v0 + + :no + const/4 v0, 0x0 + + return v0 +.end method + +.method public static isAnyDragging()Z + .locals 1 + + sget-boolean v0, Lradiant/MiniPlayerGestures;->b:Z + + return v0 +.end method + +.method public static hasMiniPlayerMedia()Z + .locals 1 + + sget-boolean v0, Lradiant/MiniPlayerGestures;->r:Z + + return v0 +.end method + +.method public static setHasMiniPlayerMedia(Z)V + .locals 0 + + sput-boolean p0, Lradiant/MiniPlayerGestures;->r:Z + + return-void +.end method + +.method private static clampReleaseVelocity(F)F + .locals 4 + + invoke-static {p0}, Ljava/lang/Math;->abs(F)F + + move-result v0 + + invoke-static {}, Lradiant/MiniPlayerGestures;->minFlingVelocity()F + + move-result v1 + + cmpg-float v2, v0, v1 + + if-gez v2, :check_max + + const/4 p0, 0x0 + + return p0 + + :check_max + const v1, 0x469c4000 # 20000.0f + + cmpl-float v2, v0, v1 + + if-lez v2, :return_velocity + + const/4 v2, 0x0 + + cmpl-float v3, p0, v2 + + if-lez v3, :negative + + move p0, v1 + + return p0 + + :negative + neg-float p0, v1 + + :return_velocity + return p0 +.end method + +.method public static modifier(Landroidx/compose/ui/Modifier;Lyl0/l;Landroidx/compose/material3/SheetState;)Landroidx/compose/ui/Modifier; + .locals 1 + + new-instance v0, Lradiant/MiniPlayerGestures$Gesture; + + invoke-direct {v0, p1, p2}, Lradiant/MiniPlayerGestures$Gesture;->(Lyl0/l;Landroidx/compose/material3/SheetState;)V + + invoke-static {p0, v0}, Landroidx/compose/ui/input/pointer/PointerInteropFilter_androidKt;->motionEventSpy(Landroidx/compose/ui/Modifier;Lyl0/l;)Landroidx/compose/ui/Modifier; + + move-result-object p0 + + return-object p0 +.end method + +.method private static minFlingVelocity()F + .locals 2 + + invoke-static {}, Landroid/content/res/Resources;->getSystem()Landroid/content/res/Resources; + + move-result-object v0 + + invoke-virtual {v0}, Landroid/content/res/Resources;->getDisplayMetrics()Landroid/util/DisplayMetrics; + + move-result-object v0 + + iget v0, v0, Landroid/util/DisplayMetrics;->density:F + + const/high16 v1, 0x42480000 # 50.0f + + mul-float/2addr v0, v1 + + return v0 +.end method + +.method private static prepareSettleVelocity(Landroidx/compose/material3/SheetState;F)F + .locals 7 + + invoke-virtual {p0}, Landroidx/compose/material3/SheetState;->getAnchoredDraggableState$material3_release()Landroidx/compose/material3/internal/AnchoredDraggableState; + + move-result-object p0 + + const/4 v6, 0x0 + + cmpl-float v0, p1, v6 + + if-gtz v0, :target_hidden + + cmpg-float v0, p1, v6 + + if-ltz v0, :target_expanded + + invoke-virtual {p0}, Landroidx/compose/material3/internal/AnchoredDraggableState;->getAnchors()Landroidx/compose/material3/internal/DraggableAnchors; + + move-result-object v0 + + invoke-virtual {p0}, Landroidx/compose/material3/internal/AnchoredDraggableState;->getOffset()F + + move-result v1 + + invoke-interface {v0}, Landroidx/compose/material3/internal/DraggableAnchors;->minAnchor()F + + move-result v2 + + invoke-interface {v0}, Landroidx/compose/material3/internal/DraggableAnchors;->maxAnchor()F + + move-result v3 + + add-float/2addr v2, v3 + + const/high16 v3, 0x40000000 # 2.0f + + div-float/2addr v2, v3 + + cmpg-float v0, v1, v2 + + if-ltz v0, :target_expanded + + goto :target_hidden + + :target_expanded + sget-object v0, Landroidx/compose/material3/SheetValue;->Hidden:Landroidx/compose/material3/SheetValue; + + invoke-static {p0, v0}, Landroidx/compose/material3/internal/AnchoredDraggableState;->access$setCurrentValue(Landroidx/compose/material3/internal/AnchoredDraggableState;Ljava/lang/Object;)V + + invoke-static {p0, v0}, Landroidx/compose/material3/internal/AnchoredDraggableState;->access$setDragTarget(Landroidx/compose/material3/internal/AnchoredDraggableState;Ljava/lang/Object;)V + + invoke-static {p1}, Ljava/lang/Math;->abs(F)F + + move-result p1 + + const v0, 0x453b8000 # 3000.0f + + cmpg-float v1, p1, v0 + + if-gez v1, :open_have_min + + move p1, v0 + + :open_have_min + neg-float p1, p1 + + invoke-static {p0, p1}, Landroidx/compose/material3/internal/AnchoredDraggableState;->access$setLastVelocity(Landroidx/compose/material3/internal/AnchoredDraggableState;F)V + + return p1 + + :target_hidden + sget-object v0, Landroidx/compose/material3/SheetValue;->Expanded:Landroidx/compose/material3/SheetValue; + + invoke-static {p0, v0}, Landroidx/compose/material3/internal/AnchoredDraggableState;->access$setCurrentValue(Landroidx/compose/material3/internal/AnchoredDraggableState;Ljava/lang/Object;)V + + invoke-static {p0, v0}, Landroidx/compose/material3/internal/AnchoredDraggableState;->access$setDragTarget(Landroidx/compose/material3/internal/AnchoredDraggableState;Ljava/lang/Object;)V + + invoke-static {p1}, Ljava/lang/Math;->abs(F)F + + move-result p1 + + const v0, 0x453b8000 # 3000.0f + + cmpg-float v1, p1, v0 + + if-gez v1, :hidden_have_min + + move p1, v0 + + :hidden_have_min + invoke-static {p0, p1}, Landroidx/compose/material3/internal/AnchoredDraggableState;->access$setLastVelocity(Landroidx/compose/material3/internal/AnchoredDraggableState;F)V + + return p1 +.end method + +.method public static releaseVelocity(Landroidx/compose/material3/SheetState;)F + .locals 6 + + invoke-static {p0}, Lradiant/MiniPlayerGestures;->isDragging(Landroidx/compose/material3/SheetState;)Z + + move-result p0 + + if-eqz p0, :zero + + sget-object v0, Lradiant/MiniPlayerGestures;->o:Landroid/view/VelocityTracker; + + if-eqz v0, :sampled_velocity + + const/16 v1, 0x3e8 + + const v2, 0x469c4000 # 20000.0f + + invoke-virtual {v0, v1, v2}, Landroid/view/VelocityTracker;->computeCurrentVelocity(IF)V + + sget v1, Lradiant/MiniPlayerGestures;->p:I + + invoke-virtual {v0, v1}, Landroid/view/VelocityTracker;->getYVelocity(I)F + + move-result p0 + + invoke-static {p0}, Lradiant/MiniPlayerGestures;->clampReleaseVelocity(F)F + + move-result p0 + + sget v1, Lradiant/MiniPlayerGestures;->p:I + + invoke-virtual {v0, v1}, Landroid/view/VelocityTracker;->getXVelocity(I)F + + move-result v0 + + invoke-static {v0}, Lradiant/MiniPlayerGestures;->clampReleaseVelocity(F)F + + move-result v0 + + goto :have_velocity + + :sampled_velocity + sget p0, Lradiant/MiniPlayerGestures;->f:F + + invoke-static {p0}, Lradiant/MiniPlayerGestures;->clampReleaseVelocity(F)F + + move-result p0 + + sget v0, Lradiant/MiniPlayerGestures;->l:F + + invoke-static {v0}, Lradiant/MiniPlayerGestures;->clampReleaseVelocity(F)F + + move-result v0 + + :have_velocity + + const/4 v3, 0x0 + + cmpl-float v1, p0, v3 + + if-lez v1, :return_done + + invoke-static {v0}, Ljava/lang/Math;->abs(F)F + + move-result v0 + + invoke-static {p0}, Ljava/lang/Math;->abs(F)F + + move-result v1 + + cmpl-float v2, v0, v1 + + if-lez v2, :return_done + + const/4 p0, 0x0 + + :return_done + + return p0 + + :zero + const/4 p0, 0x0 + + return p0 +.end method + +.method public static rootModifier(Landroidx/compose/ui/Modifier;Lyl0/l;Landroidx/compose/material3/SheetState;)Landroidx/compose/ui/Modifier; + .locals 1 + + new-instance v0, Lradiant/MiniPlayerGestures$RootGesture; + + invoke-direct {v0, p1, p2}, Lradiant/MiniPlayerGestures$RootGesture;->(Lyl0/l;Landroidx/compose/material3/SheetState;)V + + invoke-static {p0, v0}, Landroidx/compose/ui/input/pointer/PointerInteropFilter_androidKt;->motionEventSpy(Landroidx/compose/ui/Modifier;Lyl0/l;)Landroidx/compose/ui/Modifier; + + move-result-object p0 + + return-object p0 +.end method + +.method public static setSettleCallback(Landroidx/compose/material3/SheetState;Lyl0/l;)V + .locals 0 + + sput-object p0, Lradiant/MiniPlayerGestures;->g:Landroidx/compose/material3/SheetState; + + sput-object p1, Lradiant/MiniPlayerGestures;->h:Lyl0/l; + + return-void +.end method + +.method public static trackMotion(Landroid/view/MotionEvent;)V + .locals 2 + + sget-object v0, Lradiant/MiniPlayerGestures;->o:Landroid/view/VelocityTracker; + + if-nez v0, :have_tracker + + invoke-static {}, Landroid/view/VelocityTracker;->obtain()Landroid/view/VelocityTracker; + + move-result-object v0 + + sput-object v0, Lradiant/MiniPlayerGestures;->o:Landroid/view/VelocityTracker; + + :have_tracker + invoke-static {v0, p0}, Lradiant/MiniPlayerGestures;->addRawMovement(Landroid/view/VelocityTracker;Landroid/view/MotionEvent;)V + + invoke-virtual {p0}, Landroid/view/MotionEvent;->getRawX()F + + move-result v1 + + sput v1, Lradiant/MiniPlayerGestures;->n:F + + return-void +.end method + +.method public static needsApply(Landroidx/compose/material3/SheetState;)Z + .locals 3 + + sget-boolean v0, Lradiant/MiniPlayerGestures;->b:Z + + if-eqz v0, :no + + sget-object v0, Lradiant/MiniPlayerGestures;->a:Landroidx/compose/material3/SheetState; + + if-ne v0, p0, :no + + sget v0, Lradiant/MiniPlayerGestures;->c:F + + sget v1, Lradiant/MiniPlayerGestures;->d:F + + sub-float/2addr v0, v1 + + invoke-static {v0}, Ljava/lang/Math;->abs(F)F + + move-result v0 + + const/high16 v1, 0x3f000000 # 0.5f + + cmpl-float v2, v0, v1 + + if-lez v2, :no + + const/4 v0, 0x1 + + return v0 + + :no + const/4 v0, 0x0 + + return v0 +.end method + +.method public static scheduleApply(Landroidx/compose/material3/SheetState;I)V + .locals 4 + + if-lez p1, :done + + new-instance v0, Landroid/os/Handler; + + invoke-static {}, Landroid/os/Looper;->getMainLooper()Landroid/os/Looper; + + move-result-object v1 + + invoke-direct {v0, v1}, Landroid/os/Handler;->(Landroid/os/Looper;)V + + new-instance v1, Lradiant/MiniPlayerGestures$ApplyPending; + + invoke-direct {v1, p0, p1}, Lradiant/MiniPlayerGestures$ApplyPending;->(Landroidx/compose/material3/SheetState;I)V + + const-wide/16 v2, 0x10 + + invoke-virtual {v0, v1, v2, v3}, Landroid/os/Handler;->postDelayed(Ljava/lang/Runnable;J)Z + + :done + return-void +.end method + +.method public static updateDragTimed(Landroidx/compose/material3/SheetState;FJ)V + .locals 8 + + sget-boolean v0, Lradiant/MiniPlayerGestures;->b:Z + + if-eqz v0, :done + + sget-object v0, Lradiant/MiniPlayerGestures;->a:Landroidx/compose/material3/SheetState; + + if-ne v0, p0, :done + + sget v0, Lradiant/MiniPlayerGestures;->c:F + + sub-float v0, p1, v0 + + const/4 v1, 0x0 + + cmpl-float v1, v0, v1 + + if-eqz v1, :no_movement + + sput-wide p2, Lradiant/MiniPlayerGestures;->i:J + + sput p1, Lradiant/MiniPlayerGestures;->c:F + + sget-wide v1, Lradiant/MiniPlayerGestures;->k:J + + sub-long v1, p2, v1 + + const-wide/16 v3, 0x28 + + cmp-long v5, v1, v3 + + if-gez v5, :apply + + :sample_velocity + sget v0, Lradiant/MiniPlayerGestures;->j:F + + sub-float v0, p1, v0 + + long-to-float v1, v1 + + const/high16 v2, 0x447a0000 # 1000.0f + + sget v6, Lradiant/MiniPlayerGestures;->n:F + + sget v7, Lradiant/MiniPlayerGestures;->m:F + + sub-float v6, v6, v7 + + mul-float/2addr v6, v2 + + div-float/2addr v6, v1 + + mul-float/2addr v0, v2 + + div-float/2addr v0, v1 + + const v1, 0x469c4000 # 20000.0f + + cmpl-float v2, v0, v1 + + if-lez v2, :check_min_velocity + + move v0, v1 + + goto :store_velocity + + :check_min_velocity + + const v1, -0x3963c000 # -20000.0f + + cmpg-float v2, v0, v1 + + if-gez v2, :store_velocity + + move v0, v1 + + :store_velocity + sput v0, Lradiant/MiniPlayerGestures;->f:F + + const v1, 0x469c4000 # 20000.0f + + cmpl-float v2, v6, v1 + + if-lez v2, :check_min_x_velocity + + move v6, v1 + + goto :store_x_velocity + + :check_min_x_velocity + + const v1, -0x3963c000 # -20000.0f + + cmpg-float v2, v6, v1 + + if-gez v2, :store_x_velocity + + move v6, v1 + + :store_x_velocity + sput v6, Lradiant/MiniPlayerGestures;->l:F + + sput p1, Lradiant/MiniPlayerGestures;->j:F + + sget v6, Lradiant/MiniPlayerGestures;->n:F + + sput v6, Lradiant/MiniPlayerGestures;->m:F + + sput-wide p2, Lradiant/MiniPlayerGestures;->k:J + + goto :apply + + :no_movement + sget-wide v1, Lradiant/MiniPlayerGestures;->k:J + + sub-long v1, p2, v1 + + const-wide/16 v3, 0x50 + + cmp-long v5, v1, v3 + + if-gtz v5, :reset_velocity + + goto :apply + + :reset_velocity + + const/4 v0, 0x0 + + sput v0, Lradiant/MiniPlayerGestures;->f:F + + sput v0, Lradiant/MiniPlayerGestures;->l:F + + sput p1, Lradiant/MiniPlayerGestures;->j:F + + sget v0, Lradiant/MiniPlayerGestures;->n:F + + sput v0, Lradiant/MiniPlayerGestures;->m:F + + sput-wide p2, Lradiant/MiniPlayerGestures;->k:J + + :apply + + invoke-static {p0}, Lradiant/MiniPlayerGestures;->applyPendingDrag(Landroidx/compose/material3/SheetState;)V + + const/4 v0, 0x3 + + invoke-static {p0, v0}, Lradiant/MiniPlayerGestures;->scheduleApply(Landroidx/compose/material3/SheetState;I)V + + :done + return-void +.end method + +.method public static updateDragToYTimed(Landroidx/compose/material3/SheetState;FJ)V + .locals 1 + + sget v0, Lradiant/MiniPlayerGestures;->e:F + + sub-float/2addr p1, v0 + + invoke-static {p0, p1, p2, p3}, Lradiant/MiniPlayerGestures;->updateDragTimed(Landroidx/compose/material3/SheetState;FJ)V + + return-void +.end method + +.method public static suppressAutoShow(Landroidx/compose/material3/SheetState;)Z + .locals 1 + + sget-boolean v0, Lradiant/MiniPlayerGestures;->b:Z + + if-eqz v0, :no + + sget-object v0, Lradiant/MiniPlayerGestures;->a:Landroidx/compose/material3/SheetState; + + if-ne v0, p0, :no + + invoke-static {p0}, Lradiant/MiniPlayerGestures;->applyPendingDrag(Landroidx/compose/material3/SheetState;)V + + const/4 v0, 0x5 + + invoke-static {p0, v0}, Lradiant/MiniPlayerGestures;->scheduleApply(Landroidx/compose/material3/SheetState;I)V + + const/4 v0, 0x1 + + return v0 + + :no + const/4 v0, 0x0 + + return v0 +.end method diff --git a/patches/extension/radiant/MiniPlayerTrackGestures$Gesture.smali b/patches/extension/radiant/MiniPlayerTrackGestures$Gesture.smali new file mode 100644 index 0000000..433ef45 --- /dev/null +++ b/patches/extension/radiant/MiniPlayerTrackGestures$Gesture.smali @@ -0,0 +1,150 @@ +.class public final Lradiant/MiniPlayerTrackGestures$Gesture; +.super Ljava/lang/Object; +.implements Lyl0/l; + + +# annotations +.annotation system Ldalvik/annotation/EnclosingClass; + value = Lradiant/MiniPlayerTrackGestures; +.end annotation + +.annotation system Ldalvik/annotation/InnerClass; + accessFlags = 0x19 + name = "Gesture" +.end annotation + + +# instance fields +.field public final a:Lyl0/l; + + +# direct methods +.method public constructor (Lyl0/l;)V + .locals 0 + + invoke-direct {p0}, Ljava/lang/Object;->()V + + iput-object p1, p0, Lradiant/MiniPlayerTrackGestures$Gesture;->a:Lyl0/l; + + return-void +.end method + +.method private nextTrack()V + .locals 2 + + iget-object v0, p0, Lradiant/MiniPlayerTrackGestures$Gesture;->a:Lyl0/l; + + sget-object v1, Lcom/tidal/android/feature/appscaffold/ui/q$a;->a:Lcom/tidal/android/feature/appscaffold/ui/q$a; # Tidal's built-in next track mini-player event + + invoke-interface {v0, v1}, Lyl0/l;->invoke(Ljava/lang/Object;)Ljava/lang/Object; + + return-void +.end method + +.method private previousTrack()V + .locals 2 + + iget-object v0, p0, Lradiant/MiniPlayerTrackGestures$Gesture;->a:Lyl0/l; + + sget-object v1, Lcom/tidal/android/feature/appscaffold/ui/q$c;->a:Lcom/tidal/android/feature/appscaffold/ui/q$c; # Our synthetic previous track event + + invoke-interface {v0, v1}, Lyl0/l;->invoke(Ljava/lang/Object;)Ljava/lang/Object; + + return-void +.end method + + +# virtual methods +.method public final invoke(Landroid/view/MotionEvent;)Lkotlin/u; + .locals 3 + + invoke-virtual {p1}, Landroid/view/MotionEvent;->getActionMasked()I + + move-result v0 + + if-eqz v0, :down + + const/4 v1, 0x1 + + if-eq v0, v1, :up + + const/4 v1, 0x2 + + if-eq v0, v1, :move + + const/4 v1, 0x3 + + if-eq v0, v1, :cancel + + goto :done + + # ACTION_DOWN + :down + invoke-virtual {p1}, Landroid/view/MotionEvent;->getRawX()F + + move-result v0 + invoke-virtual {p1}, Landroid/view/MotionEvent;->getRawY()F + + move-result v1 + invoke-static {v0, v1}, Lradiant/MiniPlayerTrackGestures;->beginDrag(FF)V + goto :done + + # ACTION_MOVE + :move + invoke-virtual {p1}, Landroid/view/MotionEvent;->getRawX()F + + move-result v0 + invoke-virtual {p1}, Landroid/view/MotionEvent;->getRawY()F + + move-result v1 + invoke-static {v0, v1}, Lradiant/MiniPlayerTrackGestures;->moveDrag(FF)V + goto :done + + # ACTION_UP + :up + invoke-virtual {p1}, Landroid/view/MotionEvent;->getRawX()F + + move-result v0 + invoke-virtual {p1}, Landroid/view/MotionEvent;->getRawY()F + + move-result v1 + invoke-static {v0, v1}, Lradiant/MiniPlayerTrackGestures;->finishDrag(FF)I + + move-result v0 + + if-eqz v0, :done + + # Negative result = swipe left -> next. Positive result = swipe right -> previous + if-gez v0, :previous + + invoke-static {}, Lradiant/MiniPlayerTrackGestures;->suppressTapOpen()V + invoke-direct {p0}, Lradiant/MiniPlayerTrackGestures$Gesture;->nextTrack()V + goto :done + + :previous + + invoke-static {}, Lradiant/MiniPlayerTrackGestures;->suppressTapOpen()V + invoke-direct {p0}, Lradiant/MiniPlayerTrackGestures$Gesture;->previousTrack()V + goto :done + + # ACTION_CANCEL + :cancel + invoke-static {}, Lradiant/MiniPlayerTrackGestures;->cancelDrag()V + + :done + sget-object p1, Lkotlin/u;->a:Lkotlin/u; + + return-object p1 +.end method + +.method public bridge synthetic invoke(Ljava/lang/Object;)Ljava/lang/Object; + .locals 0 + + check-cast p1, Landroid/view/MotionEvent; + + invoke-virtual {p0, p1}, Lradiant/MiniPlayerTrackGestures$Gesture;->invoke(Landroid/view/MotionEvent;)Lkotlin/u; + + move-result-object p1 + + return-object p1 +.end method diff --git a/patches/extension/radiant/MiniPlayerTrackGestures$OffsetLayer.smali b/patches/extension/radiant/MiniPlayerTrackGestures$OffsetLayer.smali new file mode 100644 index 0000000..97bc03f --- /dev/null +++ b/patches/extension/radiant/MiniPlayerTrackGestures$OffsetLayer.smali @@ -0,0 +1,70 @@ +.class public final Lradiant/MiniPlayerTrackGestures$OffsetLayer; +.super Ljava/lang/Object; +.implements Lyl0/l; + + +# annotations +.annotation system Ldalvik/annotation/EnclosingClass; + value = Lradiant/MiniPlayerTrackGestures; +.end annotation + +.annotation system Ldalvik/annotation/InnerClass; + accessFlags = 0x19 + name = "OffsetLayer" +.end annotation + + +# static fields +.field public static final INSTANCE:Lradiant/MiniPlayerTrackGestures$OffsetLayer; + + +# direct methods +.method static constructor ()V + .locals 1 + + new-instance v0, Lradiant/MiniPlayerTrackGestures$OffsetLayer; + + invoke-direct {v0}, Lradiant/MiniPlayerTrackGestures$OffsetLayer;->()V + + sput-object v0, Lradiant/MiniPlayerTrackGestures$OffsetLayer;->INSTANCE:Lradiant/MiniPlayerTrackGestures$OffsetLayer; + + return-void +.end method + +.method private constructor ()V + .locals 0 + + invoke-direct {p0}, Ljava/lang/Object;->()V + + return-void +.end method + + +# virtual methods +.method public final invoke(Landroidx/compose/ui/graphics/GraphicsLayerScope;)Lkotlin/u; + .locals 1 + + sget-object v0, Lradiant/MiniPlayerTrackGestures;->b:Landroidx/compose/runtime/MutableFloatState; + + invoke-interface {v0}, Landroidx/compose/runtime/MutableFloatState;->getFloatValue()F + + move-result v0 + + invoke-interface {p1, v0}, Landroidx/compose/ui/graphics/GraphicsLayerScope;->setTranslationX(F)V + + sget-object p1, Lkotlin/u;->a:Lkotlin/u; + + return-object p1 +.end method + +.method public bridge synthetic invoke(Ljava/lang/Object;)Ljava/lang/Object; + .locals 0 + + check-cast p1, Landroidx/compose/ui/graphics/GraphicsLayerScope; + + invoke-virtual {p0, p1}, Lradiant/MiniPlayerTrackGestures$OffsetLayer;->invoke(Landroidx/compose/ui/graphics/GraphicsLayerScope;)Lkotlin/u; + + move-result-object p1 + + return-object p1 +.end method diff --git a/patches/extension/radiant/MiniPlayerTrackGestures$ResetAnimator.smali b/patches/extension/radiant/MiniPlayerTrackGestures$ResetAnimator.smali new file mode 100644 index 0000000..2f839b0 --- /dev/null +++ b/patches/extension/radiant/MiniPlayerTrackGestures$ResetAnimator.smali @@ -0,0 +1,60 @@ +.class public final Lradiant/MiniPlayerTrackGestures$ResetAnimator; +.super Ljava/lang/Object; +.implements Landroid/animation/ValueAnimator$AnimatorUpdateListener; + + +# annotations +.annotation system Ldalvik/annotation/EnclosingClass; + value = Lradiant/MiniPlayerTrackGestures; +.end annotation + +.annotation system Ldalvik/annotation/InnerClass; + accessFlags = 0x19 + name = "ResetAnimator" +.end annotation + + +# direct methods +.method public constructor ()V + .locals 0 + + invoke-direct {p0}, Ljava/lang/Object;->()V + + return-void +.end method + + +# virtual methods +.method public final onAnimationUpdate(Landroid/animation/ValueAnimator;)V + .locals 3 + + move-object v0, p1 + + invoke-virtual {p1}, Landroid/animation/ValueAnimator;->getAnimatedValue()Ljava/lang/Object; + + move-result-object v1 + + check-cast v1, Ljava/lang/Float; + + invoke-virtual {v1}, Ljava/lang/Float;->floatValue()F + + move-result v1 + + invoke-static {v1}, Lradiant/MiniPlayerTrackGestures;->setDragOffsetDirect(F)V + + invoke-virtual {v0}, Landroid/animation/ValueAnimator;->getAnimatedFraction()F + + move-result v1 + + const/high16 v2, 0x3f800000 # 1.0f + + cmpg-float v1, v1, v2 + + if-gez v1, :done + + invoke-static {v0}, Lradiant/MiniPlayerTrackGestures;->clearResetAnimator(Landroid/animation/ValueAnimator;)V + + :done + + return-void +.end method diff --git a/patches/extension/radiant/MiniPlayerTrackGestures$TextDraw.smali b/patches/extension/radiant/MiniPlayerTrackGestures$TextDraw.smali new file mode 100644 index 0000000..876a36e --- /dev/null +++ b/patches/extension/radiant/MiniPlayerTrackGestures$TextDraw.smali @@ -0,0 +1,128 @@ +.class public final Lradiant/MiniPlayerTrackGestures$TextDraw; +.super Ljava/lang/Object; +.implements Lyl0/l; + + +# annotations +.annotation system Ldalvik/annotation/EnclosingClass; + value = Lradiant/MiniPlayerTrackGestures; +.end annotation + +.annotation system Ldalvik/annotation/InnerClass; + accessFlags = 0x19 + name = "TextDraw" +.end annotation + + +# static fields +.field public static final INSTANCE:Lradiant/MiniPlayerTrackGestures$TextDraw; + + +# direct methods +.method static constructor ()V + .locals 1 + + new-instance v0, Lradiant/MiniPlayerTrackGestures$TextDraw; + + invoke-direct {v0}, Lradiant/MiniPlayerTrackGestures$TextDraw;->()V + + sput-object v0, Lradiant/MiniPlayerTrackGestures$TextDraw;->INSTANCE:Lradiant/MiniPlayerTrackGestures$TextDraw; + + return-void +.end method + +.method private constructor ()V + .locals 0 + + invoke-direct {p0}, Ljava/lang/Object;->()V + + return-void +.end method + + +# virtual methods +.method public final invoke(Landroidx/compose/ui/graphics/drawscope/ContentDrawScope;)Lkotlin/u; + .locals 12 + + sget-object v0, Lradiant/MiniPlayerTrackGestures;->b:Landroidx/compose/runtime/MutableFloatState; + + invoke-interface {v0}, Landroidx/compose/runtime/MutableFloatState;->getFloatValue()F + + move-result v10 + + invoke-interface {p1}, Landroidx/compose/ui/graphics/drawscope/DrawScope;->getDrawContext()Landroidx/compose/ui/graphics/drawscope/DrawContext; + + move-result-object v7 + + invoke-interface {v7}, Landroidx/compose/ui/graphics/drawscope/DrawContext;->getSize-NH-jbRc()J + + move-result-wide v8 + + const/16 v0, 0x20 + + shr-long v1, v8, v0 + + long-to-int v1, v1 + + invoke-static {v1}, Ljava/lang/Float;->intBitsToFloat(I)F + + move-result v4 + + invoke-interface {v7}, Landroidx/compose/ui/graphics/drawscope/DrawContext;->getCanvas()Landroidx/compose/ui/graphics/Canvas; + + move-result-object v0 + + invoke-interface {v0}, Landroidx/compose/ui/graphics/Canvas;->save()V + + :try_start_0 + sget-object v0, Landroidx/compose/ui/graphics/ClipOp;->Companion:Landroidx/compose/ui/graphics/ClipOp$Companion; + + invoke-virtual {v0}, Landroidx/compose/ui/graphics/ClipOp$Companion;->getIntersect-rtfAjoo()I + + move-result v6 + + invoke-interface {v7}, Landroidx/compose/ui/graphics/drawscope/DrawContext;->getTransform()Landroidx/compose/ui/graphics/drawscope/DrawTransform; + + move-result-object v1 + + const v2, -0x800001 # -Float.MAX_VALUE -> unbounded left + + const v3, -0x800001 # -Float.MAX_VALUE -> unbounded top + + const v5, 0x7f7fffff # Float.MAX_VALUE -> unbounded bottom + + invoke-interface/range {v1 .. v6}, Landroidx/compose/ui/graphics/drawscope/DrawTransform;->clipRect-N_I0leg(FFFFI)V + + const/4 v0, 0x0 + + invoke-interface {v1, v10, v0}, Landroidx/compose/ui/graphics/drawscope/DrawTransform;->translate(FF)V + + invoke-interface {p1}, Landroidx/compose/ui/graphics/drawscope/ContentDrawScope;->drawContent()V + :try_end_0 + .catchall {:try_start_0 .. :try_end_0} :catchall_0 + + invoke-static {v7, v8, v9}, Landroidx/compose/animation/i;->b(Landroidx/compose/ui/graphics/drawscope/DrawContext;J)V + + sget-object p1, Lkotlin/u;->a:Lkotlin/u; + + return-object p1 + + :catchall_0 + move-exception v0 + + invoke-static {v7, v8, v9}, Landroidx/compose/animation/i;->b(Landroidx/compose/ui/graphics/drawscope/DrawContext;J)V + + throw v0 +.end method + +.method public bridge synthetic invoke(Ljava/lang/Object;)Ljava/lang/Object; + .locals 0 + + check-cast p1, Landroidx/compose/ui/graphics/drawscope/ContentDrawScope; + + invoke-virtual {p0, p1}, Lradiant/MiniPlayerTrackGestures$TextDraw;->invoke(Landroidx/compose/ui/graphics/drawscope/ContentDrawScope;)Lkotlin/u; + + move-result-object p1 + + return-object p1 +.end method diff --git a/patches/extension/radiant/MiniPlayerTrackGestures.smali b/patches/extension/radiant/MiniPlayerTrackGestures.smali new file mode 100644 index 0000000..5cfa1ff --- /dev/null +++ b/patches/extension/radiant/MiniPlayerTrackGestures.smali @@ -0,0 +1,564 @@ +.class public final Lradiant/MiniPlayerTrackGestures; +.super Ljava/lang/Object; + + +# static fields +.field private static a:J + +.field public static b:Landroidx/compose/runtime/MutableFloatState; + +.field private static c:Landroid/animation/ValueAnimator; + +.field private static d:Ljava/lang/Object; + +# X at ACTION_DOWN +.field private static e:F + +# Y at ACTION_DOWN +.field private static f:F + +.field private static g:Z + +.field private static h:Z + + +# direct methods +.method static constructor ()V + .locals 1 + + const/4 v0, 0x0 + + invoke-static {v0}, Landroidx/compose/runtime/PrimitiveSnapshotStateKt;->mutableFloatStateOf(F)Landroidx/compose/runtime/MutableFloatState; + + move-result-object v0 + + sput-object v0, Lradiant/MiniPlayerTrackGestures;->b:Landroidx/compose/runtime/MutableFloatState; + + return-void +.end method + +.method private constructor ()V + .locals 0 + + invoke-direct {p0}, Ljava/lang/Object;->()V + + return-void +.end method + +.method public static animateReset()V + .locals 7 + + sget-object v0, Lradiant/MiniPlayerTrackGestures;->c:Landroid/animation/ValueAnimator; + + if-eqz v0, :read_offset + + invoke-virtual {v0}, Landroid/animation/ValueAnimator;->cancel()V + + const/4 v0, 0x0 + + sput-object v0, Lradiant/MiniPlayerTrackGestures;->c:Landroid/animation/ValueAnimator; + + :read_offset + sget-object v0, Lradiant/MiniPlayerTrackGestures;->b:Landroidx/compose/runtime/MutableFloatState; + + invoke-interface {v0}, Landroidx/compose/runtime/MutableFloatState;->getFloatValue()F + + move-result v0 + + invoke-static {v0}, Ljava/lang/Math;->abs(F)F + + move-result v1 + + const/4 v3, 0x0 + + const/high16 v2, 0x3f000000 # 0.5f + + cmpg-float v1, v1, v2 + + if-lez v1, :snap_zero + + const/4 v1, 0x2 + + new-array v1, v1, [F + + const/4 v2, 0x0 + + aput v0, v1, v2 + + const/4 v0, 0x1 + + aput v3, v1, v0 + + invoke-static {v1}, Landroid/animation/ValueAnimator;->ofFloat([F)Landroid/animation/ValueAnimator; + + move-result-object v1 + + const-wide/16 v4, 0xb4 # 180ms + + invoke-virtual {v1, v4, v5}, Landroid/animation/ValueAnimator;->setDuration(J)Landroid/animation/ValueAnimator; + + new-instance v0, Landroid/view/animation/DecelerateInterpolator; + + const/high16 v4, 0x3fc00000 # 1.5f + + invoke-direct {v0, v4}, Landroid/view/animation/DecelerateInterpolator;->(F)V + + invoke-virtual {v1, v0}, Landroid/animation/ValueAnimator;->setInterpolator(Landroid/animation/TimeInterpolator;)V + + new-instance v0, Lradiant/MiniPlayerTrackGestures$ResetAnimator; + + invoke-direct {v0}, Lradiant/MiniPlayerTrackGestures$ResetAnimator;->()V + + invoke-virtual {v1, v0}, Landroid/animation/ValueAnimator;->addUpdateListener(Landroid/animation/ValueAnimator$AnimatorUpdateListener;)V + + sput-object v1, Lradiant/MiniPlayerTrackGestures;->c:Landroid/animation/ValueAnimator; + + invoke-virtual {v1}, Landroid/animation/ValueAnimator;->start()V + + return-void + + :snap_zero + invoke-static {v3}, Lradiant/MiniPlayerTrackGestures;->setDragOffsetDirect(F)V + + return-void +.end method + +.method public static beginDrag(FF)V + .locals 2 + + sput p0, Lradiant/MiniPlayerTrackGestures;->e:F + + sput p1, Lradiant/MiniPlayerTrackGestures;->f:F + + const/4 v0, 0x1 + + sput-boolean v0, Lradiant/MiniPlayerTrackGestures;->g:Z + + const/4 v0, 0x0 + + sput-boolean v0, Lradiant/MiniPlayerTrackGestures;->h:Z + + sget-object v0, Lradiant/MiniPlayerTrackGestures;->c:Landroid/animation/ValueAnimator; + + if-eqz v0, :zero + + invoke-virtual {v0}, Landroid/animation/ValueAnimator;->cancel()V + + const/4 v0, 0x0 + + sput-object v0, Lradiant/MiniPlayerTrackGestures;->c:Landroid/animation/ValueAnimator; + + :zero + const/4 v0, 0x0 + + invoke-static {v0}, Lradiant/MiniPlayerTrackGestures;->setDragOffsetDirect(F)V + + return-void +.end method + +.method public static cancelDrag()V + .locals 1 + + const/4 v0, 0x0 + + sput-boolean v0, Lradiant/MiniPlayerTrackGestures;->g:Z + + sput-boolean v0, Lradiant/MiniPlayerTrackGestures;->h:Z + + invoke-static {}, Lradiant/MiniPlayerTrackGestures;->animateReset()V + + return-void +.end method + +.method public static clearResetAnimator(Landroid/animation/ValueAnimator;)V + .locals 1 + + sget-object v0, Lradiant/MiniPlayerTrackGestures;->c:Landroid/animation/ValueAnimator; + + if-ne v0, p0, :done + + const/4 v0, 0x0 + + sput-object v0, Lradiant/MiniPlayerTrackGestures;->c:Landroid/animation/ValueAnimator; + + :done + return-void +.end method + +.method public static finishDrag(FF)I + .locals 5 + + sget-boolean v0, Lradiant/MiniPlayerTrackGestures;->g:Z + + if-nez v0, :active + + const/4 v0, 0x0 + + return v0 + + :active + const/4 v0, 0x0 + + sput-boolean v0, Lradiant/MiniPlayerTrackGestures;->g:Z + + sget-boolean v1, Lradiant/MiniPlayerTrackGestures;->h:Z + + sput-boolean v0, Lradiant/MiniPlayerTrackGestures;->h:Z + + sget v2, Lradiant/MiniPlayerTrackGestures;->e:F + + sub-float/2addr p0, v2 + + sget v2, Lradiant/MiniPlayerTrackGestures;->f:F + + sub-float/2addr p1, v2 + + if-eqz v1, :reset + + invoke-static {}, Lradiant/MiniPlayerTrackGestures;->suppressTapOpen()V + + :reset + invoke-static {}, Lradiant/MiniPlayerTrackGestures;->animateReset()V + + invoke-static {p0}, Ljava/lang/Math;->abs(F)F + + move-result v1 + + const/high16 v2, 0x42400000 # 48.0f -> at least 48dp horizontal swipe + + invoke-static {v2}, Lradiant/MiniPlayerTrackGestures;->dp(F)F + + move-result v2 + + cmpg-float v3, v1, v2 + + if-gez v3, :check_axis + + return v0 + + :check_axis + invoke-static {p1}, Ljava/lang/Math;->abs(F)F + + move-result p1 + + const/high16 v2, 0x3fc00000 # 1.5f -> horizontal distance must dominate vertical mov. by 1.5x + + mul-float/2addr p1, v2 + + cmpg-float v1, v1, p1 + + if-lez v1, :no_swipe + + const/4 p1, 0x0 + + cmpg-float p0, p0, p1 + + if-ltz p0, :next + + const/4 v0, 0x1 + + return v0 + + :next + const/4 v0, -0x1 + + return v0 + + :no_swipe + return v0 +.end method + +.method public static moveDrag(FF)V + .locals 6 + + sget-boolean v0, Lradiant/MiniPlayerTrackGestures;->g:Z + + if-eqz v0, :done + + invoke-static {}, Lradiant/MiniPlayerGestures;->isAnyDragging()Z + + move-result v0 + + if-eqz v0, :move_continue + + const/4 v0, 0x0 + + sput-boolean v0, Lradiant/MiniPlayerTrackGestures;->g:Z + + sput-boolean v0, Lradiant/MiniPlayerTrackGestures;->h:Z + + invoke-static {}, Lradiant/MiniPlayerTrackGestures;->animateReset()V + + goto :done + + :move_continue + sget v0, Lradiant/MiniPlayerTrackGestures;->e:F + + sub-float/2addr p0, v0 + + sget v0, Lradiant/MiniPlayerTrackGestures;->f:F + + sub-float/2addr p1, v0 + + invoke-static {p0}, Ljava/lang/Math;->abs(F)F + + move-result v0 + + invoke-static {p1}, Ljava/lang/Math;->abs(F)F + + move-result v1 + + sget-boolean v2, Lradiant/MiniPlayerTrackGestures;->h:Z + + if-nez v2, :publish + + const/high16 v2, 0x40c00000 # 6.0f dp dead zone + + invoke-static {v2}, Lradiant/MiniPlayerTrackGestures;->dp(F)F + + move-result v2 + + cmpg-float v3, v0, v2 + + if-gez v3, :move_axis + + goto :done + + :move_axis + const v2, 0x3f8ccccd # 1.1f horizontal dominance while dragging + + mul-float/2addr v1, v2 + + cmpg-float v2, v0, v1 + + if-gez v2, :accept + + goto :done + + :accept + const/4 v2, 0x1 + + sput-boolean v2, Lradiant/MiniPlayerTrackGestures;->h:Z + + :publish + invoke-static {}, Lradiant/MiniPlayerTrackGestures;->suppressTapOpen()V + + invoke-static {p0}, Lradiant/MiniPlayerTrackGestures;->setDragOffset(F)V + + :done + return-void +.end method + +.method private static dp(F)F + .locals 1 + + invoke-static {}, Landroid/content/res/Resources;->getSystem()Landroid/content/res/Resources; + + move-result-object v0 + + invoke-virtual {v0}, Landroid/content/res/Resources;->getDisplayMetrics()Landroid/util/DisplayMetrics; + + move-result-object v0 + + iget v0, v0, Landroid/util/DisplayMetrics;->density:F + + mul-float/2addr p0, v0 + + return p0 +.end method + +.method public static feedbackModifier(Landroidx/compose/ui/Modifier;)Landroidx/compose/ui/Modifier; + .locals 2 + + const/high16 v0, 0x3f800000 # 1.0f + + invoke-static {p0, v0}, Landroidx/compose/ui/ZIndexModifierKt;->zIndex(Landroidx/compose/ui/Modifier;F)Landroidx/compose/ui/Modifier; + + move-result-object p0 + + sget-object v0, Lradiant/MiniPlayerTrackGestures$OffsetLayer;->INSTANCE:Lradiant/MiniPlayerTrackGestures$OffsetLayer; + + invoke-static {p0, v0}, Landroidx/compose/ui/graphics/GraphicsLayerModifierKt;->graphicsLayer(Landroidx/compose/ui/Modifier;Lyl0/l;)Landroidx/compose/ui/Modifier; + + move-result-object p0 + + return-object p0 +.end method + +.method public static textFeedbackModifier(Landroidx/compose/ui/Modifier;)Landroidx/compose/ui/Modifier; + .locals 1 + + sget-object v0, Lradiant/MiniPlayerTrackGestures$TextDraw;->INSTANCE:Lradiant/MiniPlayerTrackGestures$TextDraw; # text clip on right only + + invoke-static {p0, v0}, Landroidx/compose/ui/draw/DrawModifierKt;->drawWithContent(Landroidx/compose/ui/Modifier;Lyl0/l;)Landroidx/compose/ui/Modifier; + + move-result-object p0 + + return-object p0 +.end method + +.method public static onRenderedItem(Ljava/lang/Object;)V + .locals 2 + + sget-object v0, Lradiant/MiniPlayerTrackGestures;->d:Ljava/lang/Object; + + if-eqz v0, :store_initial + + invoke-virtual {v0, p0}, Ljava/lang/Object;->equals(Ljava/lang/Object;)Z + + move-result v1 + + if-nez v1, :done + + sput-object p0, Lradiant/MiniPlayerTrackGestures;->d:Ljava/lang/Object; + + invoke-static {}, Lradiant/MiniPlayerTrackGestures;->animateReset()V + + return-void + + :store_initial + sput-object p0, Lradiant/MiniPlayerTrackGestures;->d:Ljava/lang/Object; + + :done + return-void +.end method + +.method public static consumeTapOpenSuppression()Z + .locals 5 + + sget-wide v0, Lradiant/MiniPlayerTrackGestures;->a:J + + const-wide/16 v2, 0x0 + + cmp-long v4, v0, v2 + + if-nez v4, :check_time + + const/4 v0, 0x0 + + return v0 + + :check_time + sput-wide v2, Lradiant/MiniPlayerTrackGestures;->a:J + + invoke-static {}, Landroid/os/SystemClock;->uptimeMillis()J + + move-result-wide v2 + + cmp-long v4, v2, v0 + + if-lez v4, :yes + + const/4 v0, 0x0 + + return v0 + + :yes + const/4 v0, 0x1 + + return v0 +.end method + +.method public static suppressTapOpen()V + .locals 4 + + invoke-static {}, Landroid/os/SystemClock;->uptimeMillis()J + + move-result-wide v0 + + const-wide/16 v2, 0x258 + + add-long/2addr v0, v2 + + sput-wide v0, Lradiant/MiniPlayerTrackGestures;->a:J + + return-void +.end method + +.method public static setDragOffset(F)V + .locals 5 + + sget-object v0, Lradiant/MiniPlayerTrackGestures;->c:Landroid/animation/ValueAnimator; + + if-eqz v0, :rubber_band + + invoke-virtual {v0}, Landroid/animation/ValueAnimator;->cancel()V + + const/4 v0, 0x0 + + sput-object v0, Lradiant/MiniPlayerTrackGestures;->c:Landroid/animation/ValueAnimator; + + :rubber_band + invoke-static {p0}, Ljava/lang/Math;->abs(F)F + + move-result v0 + + const/high16 v1, 0x42800000 # 64.0f dp free travel + + invoke-static {v1}, Lradiant/MiniPlayerTrackGestures;->dp(F)F + + move-result v1 + + cmpg-float v2, v0, v1 + + if-lez v2, :publish + + sub-float/2addr v0, v1 + + const/high16 v2, 0x3e800000 # 0.25f resistance after 64dp + + mul-float/2addr v0, v2 + + const v2, 0x3eb33333 # 0.35f max extra travel + + mul-float/2addr v2, v1 + + invoke-static {v0, v2}, Ljava/lang/Math;->min(FF)F + + move-result v0 + + add-float/2addr v0, v1 + + const/4 v1, 0x0 + + cmpg-float v2, p0, v1 + + if-gez v2, :positive + + neg-float p0, v0 + + goto :publish + + :positive + move p0, v0 + + + :publish + invoke-static {p0}, Lradiant/MiniPlayerTrackGestures;->setDragOffsetDirect(F)V + + return-void +.end method + +.method public static setDragOffsetDirect(F)V + .locals 1 + + sget-object v0, Lradiant/MiniPlayerTrackGestures;->b:Landroidx/compose/runtime/MutableFloatState; + + invoke-interface {v0, p0}, Landroidx/compose/runtime/MutableFloatState;->setFloatValue(F)V + + return-void +.end method + +.method public static trackModifier(Landroidx/compose/ui/Modifier;Lyl0/l;)Landroidx/compose/ui/Modifier; + .locals 1 + + new-instance v0, Lradiant/MiniPlayerTrackGestures$Gesture; + + invoke-direct {v0, p1}, Lradiant/MiniPlayerTrackGestures$Gesture;->(Lyl0/l;)V + + invoke-static {p0, v0}, Landroidx/compose/ui/input/pointer/PointerInteropFilter_androidKt;->motionEventSpy(Landroidx/compose/ui/Modifier;Lyl0/l;)Landroidx/compose/ui/Modifier; + + move-result-object p0 + + return-object p0 +.end method diff --git a/patches/mini-player-gestures-left-right.patch b/patches/mini-player-gestures-left-right.patch new file mode 100644 index 0000000..6e9be1a --- /dev/null +++ b/patches/mini-player-gestures-left-right.patch @@ -0,0 +1,106 @@ +--- a/com/tidal/android/feature/appscaffold/ui/composable/MiniPlayerKt.smali ++++ b/com/tidal/android/feature/appscaffold/ui/composable/MiniPlayerKt.smali +@@ -1746,6 +1746,10 @@ + invoke-static {v9, v10, v15, v6, v8}, Landroidx/compose/foundation/layout/PaddingKt;->padding-qDBjuR0(Landroidx/compose/ui/Modifier;FFFF)Landroidx/compose/ui/Modifier; + + move-result-object v6 ++ ++ invoke-static {v6, v1}, Lradiant/MiniPlayerTrackGestures;->trackModifier(Landroidx/compose/ui/Modifier;Lyl0/l;)Landroidx/compose/ui/Modifier; # attach horizontal swipe listener ++ ++ move-result-object v6 + + .line 38 + sget-object v21, Landroidx/compose/ui/Alignment;->Companion:Landroidx/compose/ui/Alignment$Companion; +@@ -1884,5 +1888,5 @@ + .line 56 + iget-object v6, v0, Lcom/tidal/android/feature/appscaffold/ui/s;->b:Lcom/tidal/android/feature/appscaffold/ui/p; +- ++ invoke-static {v6}, Lradiant/MiniPlayerTrackGestures;->onRenderedItem(Ljava/lang/Object;)V # reset stale drag offset if track metadata changes mid-gesture + .line 57 + invoke-virtual/range {v16 .. v16}, Lcom/squareup/ui/market/core/theme/MarketStylesheet;->getBorderRadii()Lcom/squareup/ui/market/core/theme/MarketStylesheet$b; +@@ -1919,5 +1923,6 @@ + invoke-static {v5, v4}, Landroidx/compose/foundation/layout/SizeKt;->size-3ABfNKs(Landroidx/compose/ui/Modifier;F)Landroidx/compose/ui/Modifier; +- + move-result-object v4 +- ++ invoke-static {v4}, Lradiant/MiniPlayerTrackGestures;->feedbackModifier(Landroidx/compose/ui/Modifier;)Landroidx/compose/ui/Modifier; # move the whole cover container with horizontal swipe ++ move-result-object v4 ++ + .line 63 +@@ -2032,3 +2038,5 @@ + move-result-object v4 +- ++ invoke-static {v4}, Lradiant/MiniPlayerTrackGestures;->textFeedbackModifier(Landroidx/compose/ui/Modifier;)Landroidx/compose/ui/Modifier; # move title/artist ++ move-result-object v4 ++ + .line 72 +--- a/com/tidal/android/feature/appscaffold/ui/MiniPlayerViewModel.smali ++++ b/com/tidal/android/feature/appscaffold/ui/MiniPlayerViewModel.smali +@@ -816,10 +816,10 @@ + .line 111 + .line 112 + .line 113 +- move-result p1 ++ move-result v0 + + .line 114 +- if-eqz p1, :cond_f ++ if-eqz v0, :cond_f + + .line 115 + .line 116 +@@ -997,11 +997,32 @@ + :cond_e + return-void + +- .line 195 + :cond_f ++ sget-object v0, Lcom/tidal/android/feature/appscaffold/ui/q$c;->a:Lcom/tidal/android/feature/appscaffold/ui/q$c; ++ ++ invoke-virtual {p1, v0}, Ljava/lang/Object;->equals(Ljava/lang/Object;)Z ++ ++ move-result p1 ++ ++ if-eqz p1, :unknown_event ++ ++ invoke-interface {v3}, Lei/e;->canSkipToPreviousOrRewind()Z ++ ++ move-result p1 ++ ++ if-eqz p1, :previous_done ++ ++ const/4 p1, 0x0 ++ ++ invoke-interface {v3, p1}, Lei/e;->h(Z)V # false = previous/rewind ++ ++ :previous_done ++ return-void ++ ++ :unknown_event + invoke-static {}, Landroidx/compose/ui/graphics/y;->b()V + + .line 196 + .line 197 + .line 198 + return-void +--- a/com/tidal/android/feature/appscaffold/ui/composable/e.smali ++++ b/com/tidal/android/feature/appscaffold/ui/composable/e.smali +@@ -75,6 +75,18 @@ + .line 22 + :pswitch_0 ++ invoke-static {}, Lradiant/MiniPlayerTrackGestures;->consumeTapOpenSuppression()Z # prevent tap open after horizontal swipe ++ ++ move-result v0 ++ ++ if-eqz v0, :continue_open ++ ++ sget-object v0, Lkotlin/u;->a:Lkotlin/u; ++ ++ return-object v0 ++ ++ :continue_open ++ + iget-object v0, p0, Lcom/tidal/android/feature/appscaffold/ui/composable/e;->b:Ljava/lang/Object; + + .line 23 + .line 24 diff --git a/patches/mini-player-gestures.patch b/patches/mini-player-gestures.patch new file mode 100644 index 0000000..b9af323 --- /dev/null +++ b/patches/mini-player-gestures.patch @@ -0,0 +1,114 @@ +--- a/com/tidal/android/feature/appscaffold/ui/composable/i.smali ++++ b/com/tidal/android/feature/appscaffold/ui/composable/i.smali +@@ -2832,27 +2832,5 @@ +- .line 150 +- sget-object v8, Lkotlin/u;->a:Lkotlin/u; +- +- .line 151 +- invoke-interface {v15}, Landroidx/compose/runtime/Composer;->rememberedValue()Ljava/lang/Object; +- +- move-result-object v10 +- +- .line 152 +- invoke-virtual/range {v22 .. v22}, Landroidx/compose/runtime/Composer$Companion;->getEmpty()Ljava/lang/Object; +- +- move-result-object v11 +- +- if-ne v10, v11, :cond_48 +- +- .line 153 +- sget-object v10, Lcom/tidal/android/feature/appscaffold/ui/composable/AppScaffoldKt$AppScaffold$3$2$1$1;->a:Lcom/tidal/android/feature/appscaffold/ui/composable/AppScaffoldKt$AppScaffold$3$2$1$1; +- +- invoke-interface {v15, v10}, Landroidx/compose/runtime/Composer;->updateRememberedValue(Ljava/lang/Object;)V +- +- .line 154 +- :cond_48 +- check-cast v10, Landroidx/compose/ui/input/pointer/PointerInputEventHandler; +- +- invoke-static {v0, v8, v10}, Landroidx/compose/ui/input/pointer/SuspendingPointerInputFilterKt;->pointerInput(Landroidx/compose/ui/Modifier;Ljava/lang/Object;Landroidx/compose/ui/input/pointer/PointerInputEventHandler;)Landroidx/compose/ui/Modifier; ++ move-object/from16 v8, v25 # SheetState from AppScaffold ++ ++ invoke-static {v0, v6, v8}, Lradiant/MiniPlayerGestures;->modifier(Landroidx/compose/ui/Modifier;Lyl0/l;Landroidx/compose/material3/SheetState;)Landroidx/compose/ui/Modifier; # attach swipe up listener + + move-result-object v0 +@@ -2427,6 +2406,12 @@ + move-object/from16 v16, v9 + + .line 99 ++ move-object/from16 v9, v25 # same SheetState used by the modal sheet ++ ++ invoke-static {v5, v6, v9}, Lradiant/MiniPlayerGestures;->rootModifier(Landroidx/compose/ui/Modifier;Lyl0/l;Landroidx/compose/material3/SheetState;)Landroidx/compose/ui/Modifier; # continue drag after player recomposition ++ ++ move-result-object v5 ++ + invoke-static {v15, v5}, Landroidx/compose/ui/ComposedModifierKt;->materializeModifier(Landroidx/compose/runtime/Composer;Landroidx/compose/ui/Modifier;)Landroidx/compose/ui/Modifier; + + move-result-object v9 + +--- a/com/tidal/android/feature/appscaffold/ui/composable/MiniPlayerKt.smali ++++ b/com/tidal/android/feature/appscaffold/ui/composable/MiniPlayerKt.smali +@@ -1243,5 +1243,21 @@ + invoke-virtual {v0}, Ljava/lang/Object;->getClass()Ljava/lang/Class; + + iget-object v3, v0, Lcom/tidal/android/feature/appscaffold/ui/s;->c:Lcom/tidal/android/feature/appscaffold/ui/MiniPlayerContract$PlayState; ++ ++ iget-object v5, v0, Lcom/tidal/android/feature/appscaffold/ui/s;->a:Lcom/tidal/android/feature/appscaffold/ui/MiniPlayerContract$ItemType; # currently rendered mini player media type ++ ++ sget-object v6, Lcom/tidal/android/feature/appscaffold/ui/MiniPlayerContract$ItemType;->Unknown:Lcom/tidal/android/feature/appscaffold/ui/MiniPlayerContract$ItemType; # Unknown = no media playing. other media types : Track, Video. ++ ++ if-ne v5, v6, :rl_has_media # used to prevent swipe up when nothing is playing ++ ++ const/4 v5, 0x0 ++ ++ goto :rl_set_media ++ ++ :rl_has_media ++ const/4 v5, 0x1 ++ ++ :rl_set_media ++ invoke-static {v5}, Lradiant/MiniPlayerGestures;->setHasMiniPlayerMedia(Z)V + + invoke-virtual {v1}, Ljava/lang/Object;->getClass()Ljava/lang/Class; + +--- a/androidx/compose/material3/ModalBottomSheetKt$ModalBottomSheet$4$1.smali ++++ b/androidx/compose/material3/ModalBottomSheetKt$ModalBottomSheet$4$1.smali +@@ -210,8 +210,10 @@ + .line 22 + .line 23 + .line 24 + iget-object p1, p0, Landroidx/compose/material3/ModalBottomSheetKt$ModalBottomSheet$4$1;->$sheetState:Landroidx/compose/material3/SheetState; +- ++ invoke-static {p1}, Lradiant/MiniPlayerGestures;->suppressAutoShow(Landroidx/compose/material3/SheetState;)Z # avoid Material3 show() taking over manual drag ++ move-result v1 ++ if-nez v1, :skip_show + .line 25 + .line 26 + iput v2, p0, Landroidx/compose/material3/ModalBottomSheetKt$ModalBottomSheet$4$1;->label:I +@@ -231,7 +233,7 @@ + .line 33 + .line 34 + return-object v0 +- ++ :skip_show + .line 35 + :cond_2 + :goto_0 +--- a/androidx/compose/material3/ModalBottomSheetKt.smali ++++ b/androidx/compose/material3/ModalBottomSheetKt.smali +@@ -1370,3 +1370,6 @@ + .line 34 + :cond_47 ++ move-object v14, v12 ++ check-cast v14, Lyl0/l; ++ invoke-static {v13, v14}, Lradiant/MiniPlayerGestures;->setSettleCallback(Landroidx/compose/material3/SheetState;Lyl0/l;)V # reuse native settle animation on release + move-object/from16 v32, v12 +--- a/androidx/compose/material3/SheetDefaultsKt.smali ++++ b/androidx/compose/material3/SheetDefaultsKt.smali +@@ -100,6 +100,5 @@ + .line 16 +- const/16 v3, 0x12c +- ++ const/16 v3, 0x64 # 100ms + .line 17 + .line 18 + const/4 v4, 0x0