diff --git a/Manager/app/src/main/assets/patches-manifest.json b/Manager/app/src/main/assets/patches-manifest.json index d9ebef9..8a8f2e4 100644 --- a/Manager/app/src/main/assets/patches-manifest.json +++ b/Manager/app/src/main/assets/patches-manifest.json @@ -471,25 +471,27 @@ "radiant/swipe/SuggestionsResolver.smali" ], "title": "Swipe to Queue", - "description": "Swipe on tracks/albums/playlists to add them to the play queue", + "description": "Swipe on tracks/albums/playlists to add them to the play queue (and more actions)", "default": false, "advancedOptions": [ { "type": "choice", "key": "left_action", "title": "Left Swipe Action", - "description": "Choose the action for a left swipe", "entries": [ "Disabled", "Play next", - "Add to queue" + "Add to queue", + "Add to playlist" ], "values": [ "0x0", "0x1", - "0x2" + "0x2", + "0x3" ], "defaultIndex": 2, + "inline": true, "distinctFrom": "right_action", "token": "RL_SWIPE_TO_QUEUE_LEFT_ACTION" }, @@ -497,18 +499,20 @@ "type": "choice", "key": "right_action", "title": "Right Swipe Action", - "description": "Choose the action for a right swipe", "entries": [ "Disabled", "Play next", - "Add to queue" + "Add to queue", + "Add to playlist" ], "values": [ "0x0", "0x1", - "0x2" + "0x2", + "0x3" ], "defaultIndex": 0, + "inline": true, "distinctFrom": "left_action", "token": "RL_SWIPE_TO_QUEUE_RIGHT_ACTION" }, @@ -516,11 +520,10 @@ "type": "choice", "key": "remove_direction", "title": "Remove Track from Queue", - "description": "Choose the swipe direction used to remove items from the play queue", "entries": [ "Left swipe", "Right swipe", - "Both" + "Both directions" ], "values": [ "0x4", @@ -528,6 +531,8 @@ "0xc" ], "defaultIndex": 0, + "forceDropdown": true, + "inline": true, "token": "RL_SWIPE_TO_QUEUE_REMOVE_DIRECTION" }, { @@ -543,6 +548,13 @@ "title": "Play Next Color", "default": -14408663, "token": "RL_SWIPE_TO_QUEUE_PLAY_NEXT_COLOR" + }, + { + "type": "color", + "key": "add_to_playlist_color", + "title": "Add to Playlist Color", + "default": -14408663, + "token": "RL_SWIPE_TO_QUEUE_ADD_TO_PLAYLIST_COLOR" } ] }, diff --git a/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/components/radiant/RadiantInputs.kt b/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/components/radiant/RadiantInputs.kt index ac57eba..69ba90d 100644 --- a/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/components/radiant/RadiantInputs.kt +++ b/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/components/radiant/RadiantInputs.kt @@ -3,26 +3,49 @@ package com.meowarex.rlmobile.ui.components.radiant import androidx.compose.animation.animateColorAsState import androidx.compose.animation.core.animateDpAsState import androidx.compose.animation.core.animateFloatAsState +import androidx.compose.animation.core.FastOutSlowInEasing +import androidx.compose.animation.core.MutableTransitionState +import androidx.compose.animation.core.animateFloat +import androidx.compose.animation.core.rememberTransition +import androidx.compose.animation.core.tween import androidx.compose.foundation.background import androidx.compose.foundation.border +import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.collectIsFocusedAsState import androidx.compose.foundation.layout.* +import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.BasicTextField +import androidx.compose.foundation.verticalScroll import androidx.compose.material3.* import androidx.compose.runtime.* +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.clip +import androidx.compose.ui.draw.rotate import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.graphics.graphicsLayer +import androidx.compose.ui.layout.onSizeChanged +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.res.painterResource import androidx.compose.ui.semantics.Role +import androidx.compose.ui.semantics.role +import androidx.compose.ui.semantics.selected +import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.input.VisualTransformation +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Popup +import androidx.compose.ui.window.PopupProperties +import com.meowarex.rlmobile.R import com.meowarex.rlmobile.ui.theme.* /** @@ -113,6 +136,151 @@ fun RadiantTextField( } } +/** + * Dropdown + */ +@Composable +fun RadiantDropdown( + options: List, + selectedIndex: Int, + onSelect: (Int) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + disabledIndices: Set = emptySet(), +) { + var expanded by rememberSaveable { mutableStateOf(false) } + val visibilityState = remember { MutableTransitionState(false) } + visibilityState.targetState = expanded + val transition = rememberTransition(visibilityState, label = "Dropdown") + val progress by transition.animateFloat( + transitionSpec = { tween(durationMillis = 160, easing = FastOutSlowInEasing) }, + label = "DropdownProgress", + ) { + if (it) 1f else 0f + } + val scheme = MaterialTheme.colorScheme + val selectedLabel = options.getOrNull(selectedIndex).orEmpty() + val shape = if (radiantStyle.native) MaterialTheme.shapes.extraSmall else RoundedCornerShape(16.dp) + var anchorWidthPx by remember { mutableIntStateOf(0) } + val anchorWidth = with(LocalDensity.current) { anchorWidthPx.toDp() } + val positionProvider = MenuDefaults.rememberDropdownMenuPopupPositionProvider( + dropdownMenuAnchorPosition = MenuAnchorPosition.Below, + offset = DpOffset(0.dp, 6.dp), + ) + Box(modifier = modifier.fillMaxWidth()) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(12.dp), + modifier = Modifier + .fillMaxWidth() + .onSizeChanged { anchorWidthPx = it.width } + .background(scheme.surfaceContainerLowest.copy(alpha = 0.8f), shape) + .then( + if (radiantStyle.native) Modifier.border(1.dp, scheme.outline, shape) + else Modifier.border( + RadiantDesign.Hairline, + hairlineBrush(scheme.onSurface, RadiantDesign.BORDER_ALPHA * 1.5f), + shape, + ) + ) + .clip(shape) + .clickable(enabled = enabled, role = Role.Button) { expanded = !expanded } + .alpha(if (enabled) 1f else 0.45f) + .heightIn(min = 52.dp) + .padding(horizontal = 16.dp, vertical = 10.dp), + ) { + Text( + text = selectedLabel, + style = MaterialTheme.typography.bodyLarge, + color = scheme.onSurface, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + modifier = Modifier.weight(1f), + ) + Icon( + painter = painterResource(R.drawable.ic_arrow_down_small), + contentDescription = null, + modifier = Modifier.rotate(180f * progress), + ) + } + + if ( + anchorWidthPx > 0 && + (visibilityState.currentState || visibilityState.targetState || transition.isRunning) + ) { + Popup( + popupPositionProvider = positionProvider, + onDismissRequest = { expanded = false }, + properties = PopupProperties(focusable = true), + ) { + Surface( + modifier = Modifier + .width(anchorWidth) + .graphicsLayer { + alpha = progress + scaleX = 0.92f + 0.08f * progress + scaleY = 0.92f + 0.08f * progress + transformOrigin = positionProvider.transformOrigin + }, + shape = shape, + color = scheme.surfaceContainer, + tonalElevation = 0.dp, + shadowElevation = 8.dp, + border = BorderStroke( + RadiantDesign.Hairline, + scheme.onSurface.copy(alpha = RadiantDesign.BORDER_ALPHA * 2f), + ), + ) { + Column( + modifier = Modifier + .heightIn(max = 320.dp) + .verticalScroll(rememberScrollState()) + .padding(vertical = 6.dp), + ) { + options.forEachIndexed { index, option -> + val selected = index == selectedIndex + val itemEnabled = enabled && index !in disabledIndices + DropdownMenuItem( + text = { + Text( + text = option, + style = MaterialTheme.typography.bodyLarge, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + }, + trailingIcon = { + RadiantRadio( + selected = selected, + onClick = null, + enabled = itemEnabled, + ) + }, + enabled = itemEnabled, + onClick = { + onSelect(index) + expanded = false + }, + modifier = Modifier + .padding(horizontal = 6.dp, vertical = 2.dp) + .clip(RoundedCornerShape(12.dp)) + .semantics { + this.selected = selected + role = Role.RadioButton + } + .then( + if (selected) Modifier.background(scheme.primary.copy(alpha = 0.1f)) + else Modifier + ), + ) + } + } + } + } + } + } +} + /** * Slider. (i prefer the old on tbh so i reverted it back <3) */ diff --git a/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/legacy/screens/patchopts/components/PatchAdvancedOptionsSheet.kt b/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/legacy/screens/patchopts/components/PatchAdvancedOptionsSheet.kt index 93a348c..1a53860 100644 --- a/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/legacy/screens/patchopts/components/PatchAdvancedOptionsSheet.kt +++ b/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/legacy/screens/patchopts/components/PatchAdvancedOptionsSheet.kt @@ -33,11 +33,13 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.meowarex.rlmobile.R +import com.meowarex.rlmobile.ui.components.radiant.RadiantDropdown import com.meowarex.rlmobile.ui.legacy.components.ResetToDefaultButton import com.meowarex.rlmobile.ui.screens.patchopts.OptionLock import com.meowarex.rlmobile.ui.screens.patchopts.OptionSpec import com.meowarex.rlmobile.ui.screens.patchopts.PatchOptionState import com.meowarex.rlmobile.ui.screens.patchopts.hiddenForVariant +import com.meowarex.rlmobile.ui.screens.patchopts.isInline import com.meowarex.rlmobile.ui.screens.patchopts.optionLock import com.meowarex.rlmobile.ui.screens.patchopts.PatchSpec import kotlinx.coroutines.launch @@ -103,12 +105,12 @@ fun PatchAdvancedOptionsSheet( val parentKeys = patch.advancedOptions .filterIsInstance() - .filter { !it.inline } + .filter { !it.isInline } .map { it.key } .toSet() val sheetOptions = patch.advancedOptions.filter { option -> when { - option is OptionSpec.Toggle && option.inline -> false + option.isInline -> false option is OptionSpec.Toggle && option.requiresOption in parentKeys -> false // Options belonging to another variant are hidden, not greyed out. option.hiddenForVariant(selectedVariant) -> false @@ -121,7 +123,7 @@ fun PatchAdvancedOptionsSheet( is OptionSpec.Toggle -> { val toggleOn = state.toggle(patch, option) val gatedChoices = patch.advancedOptions.filterIsInstance() - .filter { it.requiresOption == option.key } + .filter { it.requiresOption == option.key && !it.isInline } val gatedToggles = patch.advancedOptions.filterIsInstance() .filter { it.requiresOption == option.key && !it.inline } val hasSubOptions = gatedChoices.isNotEmpty() || gatedToggles.isNotEmpty() @@ -164,6 +166,7 @@ fun PatchAdvancedOptionsSheet( key(choice.key) { ChoiceOptionRow( title = choice.title, + description = choice.description, entries = choice.entries, selectedIndex = state.choice(patch, choice), forceDropdown = choice.forceDropdown, @@ -208,6 +211,7 @@ fun PatchAdvancedOptionsSheet( if (option.requiresOption == null) { ChoiceOptionRow( title = option.title, + description = option.description, entries = option.entries, selectedIndex = state.choice(patch, option), forceDropdown = option.forceDropdown, @@ -387,11 +391,12 @@ private fun snapToNearestStep( } @Composable -private fun ChoiceOptionRow( +internal fun ChoiceOptionRow( entries: List, selectedIndex: Int, onSelect: (Int) -> Unit, title: String = "", + description: String = "", forceDropdown: Boolean = false, disabledIndices: Set = emptySet(), modifier: Modifier = Modifier, @@ -399,48 +404,28 @@ private fun ChoiceOptionRow( Column( modifier = modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(6.dp), - horizontalAlignment = Alignment.CenterHorizontally, + horizontalAlignment = Alignment.Start, ) { if (title.isNotEmpty()) { Text( text = title, - style = MaterialTheme.typography.labelMedium, + style = MaterialTheme.typography.titleSmall, + ) + } + if (description.isNotEmpty()) { + Text( + text = description, + style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant, - textAlign = TextAlign.Center, ) } if (forceDropdown || entries.size > 3) { - var expanded by rememberSaveable { mutableStateOf(false) } - val selectedLabel = entries.getOrNull(selectedIndex).orEmpty() - - Box(modifier = Modifier.fillMaxWidth()) { - OutlinedButton( - onClick = { expanded = true }, - modifier = Modifier.fillMaxWidth(), - ) { - Text( - text = selectedLabel, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - } - DropdownMenu( - expanded = expanded, - onDismissRequest = { expanded = false }, - modifier = Modifier.fillMaxWidth(), - ) { - entries.forEachIndexed { index, entry -> - DropdownMenuItem( - text = { Text(entry) }, - enabled = index !in disabledIndices, - onClick = { - onSelect(index) - expanded = false - }, - ) - } - } - } + RadiantDropdown( + options = entries, + selectedIndex = selectedIndex, + onSelect = onSelect, + disabledIndices = disabledIndices, + ) return@Column } SingleChoiceSegmentedButtonRow(modifier = Modifier.fillMaxWidth()) { diff --git a/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/legacy/screens/patchopts/components/PatchSelectionAccordion.kt b/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/legacy/screens/patchopts/components/PatchSelectionAccordion.kt index 0704461..4d4d296 100644 --- a/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/legacy/screens/patchopts/components/PatchSelectionAccordion.kt +++ b/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/legacy/screens/patchopts/components/PatchSelectionAccordion.kt @@ -36,6 +36,8 @@ import com.meowarex.rlmobile.ui.screens.patchopts.PatchOptions import com.meowarex.rlmobile.ui.screens.patchopts.PatchSpec import com.meowarex.rlmobile.ui.screens.patchopts.effectiveVariants import com.meowarex.rlmobile.ui.screens.patchopts.resolveVariantIndex +import com.meowarex.rlmobile.ui.screens.patchopts.conflictingChoices +import com.meowarex.rlmobile.ui.screens.patchopts.isInline private data class LockInfo(val patch: PatchSpec, val lock: PatchLock) @@ -131,11 +133,9 @@ fun PatchSelectionAccordion( val checked = isEnabled(patch) val lock = lockState(patch) - val inlineToggles = patch.advancedOptions - .filterIsInstance() - .filter { it.inline } - val hasSheetOptions = patch.advancedOptions.any { it !is OptionSpec.Toggle || !it.inline } - val hasSettings = patch.variants.isNotEmpty() || inlineToggles.isNotEmpty() || hasSheetOptions + val inlineOptions = patch.advancedOptions.filter { it.isInline } + val hasSheetOptions = patch.advancedOptions.any { !it.isInline } + val hasSettings = patch.variants.isNotEmpty() || inlineOptions.isNotEmpty() || hasSheetOptions // When a patch is enabled and has settings show a carded view of the settings val carded = checked && hasSettings @@ -191,16 +191,41 @@ fun PatchSelectionAccordion( ) } - for (option in inlineToggles) key(option.key) { - val show = option.requiresVariant == null || - option.requiresVariant == resolvedVariant - if (show) { - InlineToggleRow( - title = option.title, - description = option.description, - checked = optionState.toggle(patch, option), - onCheckedChange = { optionState.setToggle(patch, option, it) }, - ) + for (option in inlineOptions) key(option.key) { + when (option) { + is OptionSpec.Toggle -> { + val show = option.requiresVariant == null || + option.requiresVariant == resolvedVariant + if (show) { + InlineToggleRow( + title = option.title, + description = option.description, + checked = optionState.toggle(patch, option), + onCheckedChange = { optionState.setToggle(patch, option, it) }, + ) + } + } + is OptionSpec.Choice -> { + val requiredToggle = option.requiresOption?.let { key -> + patch.advancedOptions.filterIsInstance() + .firstOrNull { it.key == key } + } + if (requiredToggle == null || optionState.toggle(patch, requiredToggle)) { + ChoiceOptionRow( + title = option.title, + description = option.description, + entries = option.entries, + selectedIndex = optionState.choice(patch, option), + forceDropdown = option.forceDropdown, + disabledIndices = patch.conflictingChoices(option) + .map { optionState.choice(patch, it) } + .filter { it != 0 } + .toSet(), + onSelect = { optionState.setChoice(patch, option, it) }, + ) + } + } + else -> Unit } } 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 80a7e50..e94dd65 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 @@ -195,10 +195,9 @@ class PatchOptionsModel( } fun isAdvancedModified(spec: PatchSpec): Boolean = spec.advancedOptions.any { option -> + if (option.isInline) return@any false when (option) { - // inline toggles sit next to the variant picker, not in the sheet, so they - // must not light up the sheet's "modified" dot - is OptionSpec.Toggle -> !option.inline && toggleValue(spec, option) != option.default + is OptionSpec.Toggle -> toggleValue(spec, option) != option.default is OptionSpec.Slider -> sliderValue(spec, option) != option.default is OptionSpec.Choice -> choiceValue(spec, option) != option.defaultIndex is OptionSpec.Color -> colorValue(spec, option) != option.default @@ -206,12 +205,17 @@ class PatchOptionsModel( } fun resetAdvanced(spec: PatchSpec) { - val prefix = "${spec.id}/" - optionBools = optionBools.filterKeys { !it.startsWith(prefix) } - optionFloats = optionFloats.filterKeys { !it.startsWith(prefix) } + val advancedOptions = spec.advancedOptions.filter { !it.isInline } + val boolKeys = advancedOptions.filterIsInstance().map { keyOf(spec, it) }.toSet() + val floatKeys = advancedOptions.filterIsInstance().map { keyOf(spec, it) }.toSet() + val intKeys = advancedOptions.filter { it is OptionSpec.Choice || it is OptionSpec.Color } + .map { keyOf(spec, it) } + .toSet() + optionBools = optionBools.filterKeys { it !in boolKeys } + optionFloats = optionFloats.filterKeys { it !in floatKeys } optionInts = normalizeChoiceSelections( specs = listOf(spec), - values = optionInts.filterKeys { !it.startsWith(prefix) }, + values = optionInts.filterKeys { it !in intKeys }, ) } diff --git a/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/PatchSpec.kt b/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/PatchSpec.kt index 879327e..120b382 100644 --- a/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/PatchSpec.kt +++ b/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/PatchSpec.kt @@ -126,6 +126,8 @@ sealed interface OptionSpec { val values: List = emptyList(), val requiresOption: String? = null, val forceDropdown: Boolean = false, + /** Render inline in the patch card instead of inside the advanced sheet */ + val inline: Boolean = false, val distinctFrom: String? = null, val token: String? = null, ) : OptionSpec @@ -143,6 +145,13 @@ sealed interface OptionSpec { ) : OptionSpec } +val OptionSpec.isInline: Boolean + get() = when (this) { + is OptionSpec.Toggle -> inline + is OptionSpec.Choice -> inline + is OptionSpec.Slider, is OptionSpec.Color -> false + } + @Serializable enum class EncodeKind { @SerialName("floatBits") diff --git a/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/components/PatchAdvancedOptionsSheet.kt b/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/components/PatchAdvancedOptionsSheet.kt index cb5f7b0..328f85a 100644 --- a/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/components/PatchAdvancedOptionsSheet.kt +++ b/Manager/app/src/main/kotlin/com/meowarex/rlmobile/ui/screens/patchopts/components/PatchAdvancedOptionsSheet.kt @@ -32,6 +32,7 @@ import androidx.compose.ui.unit.dp import com.meowarex.rlmobile.R import com.meowarex.rlmobile.ui.components.radiant.RadiantButton import com.meowarex.rlmobile.ui.components.radiant.RadiantDialog +import com.meowarex.rlmobile.ui.components.radiant.RadiantDropdown import com.meowarex.rlmobile.ui.components.radiant.RadiantButtonSize import com.meowarex.rlmobile.ui.components.radiant.RadiantButtonStyle import com.meowarex.rlmobile.ui.components.radiant.RadiantIconButton @@ -45,6 +46,7 @@ import com.meowarex.rlmobile.ui.screens.patchopts.OptionSpec import com.meowarex.rlmobile.ui.screens.patchopts.PatchOptionState import com.meowarex.rlmobile.ui.screens.patchopts.conflictingChoices import com.meowarex.rlmobile.ui.screens.patchopts.hiddenForVariant +import com.meowarex.rlmobile.ui.screens.patchopts.isInline import com.meowarex.rlmobile.ui.screens.patchopts.optionLock import com.meowarex.rlmobile.ui.screens.patchopts.PatchSpec import kotlinx.coroutines.launch @@ -110,12 +112,12 @@ fun PatchAdvancedOptionsSheet( val parentKeys = patch.advancedOptions .filterIsInstance() - .filter { !it.inline } + .filter { !it.isInline } .map { it.key } .toSet() val sheetOptions = patch.advancedOptions.filter { option -> when { - option is OptionSpec.Toggle && option.inline -> false + option.isInline -> false option is OptionSpec.Toggle && option.requiresOption in parentKeys -> false // Options belonging to another variant are hidden, not greyed out. option.hiddenForVariant(selectedVariant) -> false @@ -128,7 +130,7 @@ fun PatchAdvancedOptionsSheet( is OptionSpec.Toggle -> { val toggleOn = state.toggle(patch, option) val gatedChoices = patch.advancedOptions.filterIsInstance() - .filter { it.requiresOption == option.key } + .filter { it.requiresOption == option.key && !it.isInline } val gatedToggles = patch.advancedOptions.filterIsInstance() .filter { it.requiresOption == option.key && !it.inline } val hasSubOptions = gatedChoices.isNotEmpty() || gatedToggles.isNotEmpty() @@ -171,6 +173,7 @@ fun PatchAdvancedOptionsSheet( key(choice.key) { ChoiceOptionRow( title = choice.title, + description = choice.description, entries = choice.entries, selectedIndex = state.choice(patch, choice), forceDropdown = choice.forceDropdown, @@ -215,6 +218,7 @@ fun PatchAdvancedOptionsSheet( if (option.requiresOption == null) { ChoiceOptionRow( title = option.title, + description = option.description, entries = option.entries, selectedIndex = state.choice(patch, option), forceDropdown = option.forceDropdown, @@ -388,11 +392,12 @@ private fun snapToNearestStep( } @Composable -private fun ChoiceOptionRow( +internal fun ChoiceOptionRow( entries: List, selectedIndex: Int, onSelect: (Int) -> Unit, title: String = "", + description: String = "", forceDropdown: Boolean = false, disabledIndices: Set = emptySet(), modifier: Modifier = Modifier, @@ -400,44 +405,28 @@ private fun ChoiceOptionRow( Column( modifier = modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(6.dp), - horizontalAlignment = Alignment.CenterHorizontally, + horizontalAlignment = Alignment.Start, ) { if (title.isNotEmpty()) { Text( text = title, - style = MaterialTheme.typography.labelMedium, + style = MaterialTheme.typography.titleSmall, + ) + } + if (description.isNotEmpty()) { + Text( + text = description, + style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant, - textAlign = TextAlign.Center, ) } if (forceDropdown || entries.size > 3) { - var expanded by rememberSaveable { mutableStateOf(false) } - val selectedLabel = entries.getOrNull(selectedIndex).orEmpty() - - Box(modifier = Modifier.fillMaxWidth()) { - RadiantButton( - text = selectedLabel, - onClick = { expanded = true }, - style = RadiantButtonStyle.Ghost, - fillWidth = true, - ) - DropdownMenu( - expanded = expanded, - onDismissRequest = { expanded = false }, - modifier = Modifier.fillMaxWidth(), - ) { - entries.forEachIndexed { index, entry -> - DropdownMenuItem( - text = { Text(entry) }, - enabled = index !in disabledIndices, - onClick = { - onSelect(index) - expanded = false - }, - ) - } - } - } + RadiantDropdown( + options = entries, + selectedIndex = selectedIndex, + onSelect = onSelect, + disabledIndices = disabledIndices, + ) return@Column } RadiantSegmented( 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 c745918..0bcde3a 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 @@ -33,6 +33,8 @@ import com.meowarex.rlmobile.ui.components.radiant.RadiantDialog import com.meowarex.rlmobile.ui.theme.radiantSurface import com.meowarex.rlmobile.ui.theme.glassSurface import com.meowarex.rlmobile.ui.screens.patchopts.OptionSpec +import com.meowarex.rlmobile.ui.screens.patchopts.conflictingChoices +import com.meowarex.rlmobile.ui.screens.patchopts.isInline import com.meowarex.rlmobile.ui.screens.patchopts.PatchLock import com.meowarex.rlmobile.ui.screens.patchopts.PatchOptionState import com.meowarex.rlmobile.ui.screens.patchopts.PatchOptions @@ -134,11 +136,9 @@ fun PatchSelectionAccordion( val checked = isEnabled(patch) val lock = lockState(patch) - val inlineToggles = patch.advancedOptions - .filterIsInstance() - .filter { it.inline } - val hasSheetOptions = patch.advancedOptions.any { it !is OptionSpec.Toggle || !it.inline } - val hasSettings = patch.variants.isNotEmpty() || inlineToggles.isNotEmpty() || hasSheetOptions + val inlineOptions = patch.advancedOptions.filter { it.isInline } + val hasSheetOptions = patch.advancedOptions.any { !it.isInline } + val hasSettings = patch.variants.isNotEmpty() || inlineOptions.isNotEmpty() || hasSheetOptions // When a patch is enabled and has settings show a carded view of the settings val carded = checked && hasSettings @@ -189,16 +189,41 @@ fun PatchSelectionAccordion( ) } - for (option in inlineToggles) key(option.key) { - val show = option.requiresVariant == null || - option.requiresVariant == resolvedVariant - if (show) { - InlineToggleRow( - title = option.title, - description = option.description, - checked = optionState.toggle(patch, option), - onCheckedChange = { optionState.setToggle(patch, option, it) }, - ) + for (option in inlineOptions) key(option.key) { + when (option) { + is OptionSpec.Toggle -> { + val show = option.requiresVariant == null || + option.requiresVariant == resolvedVariant + if (show) { + InlineToggleRow( + title = option.title, + description = option.description, + checked = optionState.toggle(patch, option), + onCheckedChange = { optionState.setToggle(patch, option, it) }, + ) + } + } + is OptionSpec.Choice -> { + val requiredToggle = option.requiresOption?.let { key -> + patch.advancedOptions.filterIsInstance() + .firstOrNull { it.key == key } + } + if (requiredToggle == null || optionState.toggle(patch, requiredToggle)) { + ChoiceOptionRow( + title = option.title, + description = option.description, + entries = option.entries, + selectedIndex = optionState.choice(patch, option), + forceDropdown = option.forceDropdown, + disabledIndices = patch.conflictingChoices(option) + .map { optionState.choice(patch, it) } + .filter { it != 0 } + .toSet(), + onSelect = { optionState.setChoice(patch, option, it) }, + ) + } + } + else -> Unit } } diff --git a/patches/extension/radiant/SwipeToQueue.smali b/patches/extension/radiant/SwipeToQueue.smali index ec60872..1cf175b 100644 --- a/patches/extension/radiant/SwipeToQueue.smali +++ b/patches/extension/radiant/SwipeToQueue.smali @@ -12,6 +12,10 @@ .field private final addIcon:Landroid/graphics/drawable/Drawable; +.field private final addToPlaylistBackground:Landroid/graphics/drawable/ColorDrawable; + +.field private final addToPlaylistIcon:Landroid/graphics/drawable/Drawable; + .field private final playNextBackground:Landroid/graphics/drawable/ColorDrawable; .field private final playNextIcon:Landroid/graphics/drawable/Drawable; @@ -81,6 +85,14 @@ iput-object v1, p0, Lradiant/SwipeToQueue;->playNextBackground:Landroid/graphics/drawable/ColorDrawable; + new-instance v1, Landroid/graphics/drawable/ColorDrawable; + + const v2, __RL_SWIPE_TO_QUEUE_ADD_TO_PLAYLIST_COLOR__ + + invoke-direct {v1, v2}, Landroid/graphics/drawable/ColorDrawable;->(I)V + + iput-object v1, p0, Lradiant/SwipeToQueue;->addToPlaylistBackground:Landroid/graphics/drawable/ColorDrawable; + sget v1, Lcom/aspiro/wamp/R$drawable;->ic_add_to_queue_last:I invoke-virtual {v0, v1}, Landroid/content/Context;->getDrawable(I)Landroid/graphics/drawable/Drawable; @@ -123,6 +135,29 @@ :store_play_next_icon iput-object v0, p0, Lradiant/SwipeToQueue;->playNextIcon:Landroid/graphics/drawable/Drawable; + invoke-virtual {p1}, Landroid/view/View;->getContext()Landroid/content/Context; + + move-result-object v0 + + sget v1, Lcom/aspiro/wamp/R$drawable;->ic_add_to_playlist:I + + invoke-virtual {v0, v1}, Landroid/content/Context;->getDrawable(I)Landroid/graphics/drawable/Drawable; + + move-result-object v0 + + if-eqz v0, :store_add_to_playlist_icon + + invoke-virtual {v0}, Landroid/graphics/drawable/Drawable;->mutate()Landroid/graphics/drawable/Drawable; + + move-result-object v0 + + const/4 v1, -0x1 + + invoke-virtual {v0, v1}, Landroid/graphics/drawable/Drawable;->setTint(I)V + + :store_add_to_playlist_icon + iput-object v0, p0, Lradiant/SwipeToQueue;->addToPlaylistIcon:Landroid/graphics/drawable/Drawable; + return-void .end method @@ -343,6 +378,15 @@ goto :background_ready :add_background + const/4 v9, 0x3 + + if-ne v8, v9, :add_to_queue_background + + iget-object v6, p0, Lradiant/SwipeToQueue;->addToPlaylistBackground:Landroid/graphics/drawable/ColorDrawable; + + goto :background_ready + + :add_to_queue_background iget-object v6, p0, Lradiant/SwipeToQueue;->addBackground:Landroid/graphics/drawable/ColorDrawable; :background_ready @@ -474,6 +518,15 @@ goto :icon_ready :draw_add_icon + const/4 v9, 0x3 + + if-ne v8, v9, :draw_add_to_queue_icon + + iget-object v6, p0, Lradiant/SwipeToQueue;->addToPlaylistIcon:Landroid/graphics/drawable/Drawable; + + goto :icon_ready + + :draw_add_to_queue_icon iget-object v6, p0, Lradiant/SwipeToQueue;->addIcon:Landroid/graphics/drawable/Drawable; :icon_ready diff --git a/patches/extension/radiant/swipe/AlbumItemQueueAction.smali b/patches/extension/radiant/swipe/AlbumItemQueueAction.smali index d575081..9988ddd 100644 --- a/patches/extension/radiant/swipe/AlbumItemQueueAction.smali +++ b/patches/extension/radiant/swipe/AlbumItemQueueAction.smali @@ -50,6 +50,10 @@ iget-object v2, p0, Lradiant/swipe/AlbumItemQueueAction;->moduleId:Ljava/lang/String; + const/4 v3, 0x3 + + if-eq p1, v3, :active_queue + invoke-static {}, Lradiant/swipe/QueueExecutor;->hasActiveQueue()Z move-result v3 @@ -168,12 +172,21 @@ const/4 v8, 0x1 - if-ne p1, v8, :append_track + if-ne p1, v8, :check_add_to_playlist invoke-static {v3, v7, v5, v6}, Lradiant/swipe/QueueExecutor;->playNextTrack(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)Z goto :done + :check_add_to_playlist + const/4 v8, 0x3 + + if-ne p1, v8, :append_track + + invoke-static {v3, v7, v5, v6}, Lradiant/swipe/QueueExecutor;->addToPlaylistTrack(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)V + + goto :done + :append_track invoke-static {v3, v7, v5, v6}, Lradiant/swipe/QueueExecutor;->track(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)Z diff --git a/patches/extension/radiant/swipe/ArtistTrackCreditsQueue.smali b/patches/extension/radiant/swipe/ArtistTrackCreditsQueue.smali index 380603a..8022129 100644 --- a/patches/extension/radiant/swipe/ArtistTrackCreditsQueue.smali +++ b/patches/extension/radiant/swipe/ArtistTrackCreditsQueue.smali @@ -158,12 +158,21 @@ const/4 v2, 0x1 - if-ne v0, v2, :append + if-ne v0, v2, :check_add_to_playlist invoke-static {v1, v7, v8, v9}, Lradiant/swipe/QueueExecutor;->playNextTrack(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)Z goto :done + :check_add_to_playlist + const/4 v2, 0x3 + + if-ne v0, v2, :append + + invoke-static {v1, v7, v8, v9}, Lradiant/swipe/QueueExecutor;->addToPlaylistTrack(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)V + + goto :done + :append invoke-static {v1, v7, v8, v9}, Lradiant/swipe/QueueExecutor;->track(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)Z diff --git a/patches/extension/radiant/swipe/ArtistTrackCreditsQueueAction.smali b/patches/extension/radiant/swipe/ArtistTrackCreditsQueueAction.smali index 655da85..b7b236d 100644 --- a/patches/extension/radiant/swipe/ArtistTrackCreditsQueueAction.smali +++ b/patches/extension/radiant/swipe/ArtistTrackCreditsQueueAction.smali @@ -44,6 +44,10 @@ iget-wide v1, p0, Lradiant/swipe/ArtistTrackCreditsQueueAction;->trackId:J + const/4 v0, 0x3 + + if-eq p1, v0, :active_queue + invoke-static {}, Lradiant/swipe/QueueExecutor;->hasActiveQueue()Z move-result v0 diff --git a/patches/extension/radiant/swipe/CompactGridMediaQueueAction.smali b/patches/extension/radiant/swipe/CompactGridMediaQueueAction.smali index c5ce95e..93e54c0 100644 --- a/patches/extension/radiant/swipe/CompactGridMediaQueueAction.smali +++ b/patches/extension/radiant/swipe/CompactGridMediaQueueAction.smali @@ -173,6 +173,10 @@ if-eqz v5, :done + const/4 v1, 0x3 + + if-eq p1, v1, :queue_event + const/4 v1, 0x4 if-ne v5, v1, :queue_event diff --git a/patches/extension/radiant/swipe/ComposeSearchQueue.smali b/patches/extension/radiant/swipe/ComposeSearchQueue.smali index ee0c6c1..0f6e46d 100644 --- a/patches/extension/radiant/swipe/ComposeSearchQueue.smali +++ b/patches/extension/radiant/swipe/ComposeSearchQueue.smali @@ -17,7 +17,7 @@ if-lt v0, v1, :done - const/4 v1, 0x2 + const/4 v1, 0x3 if-gt v0, v1, :done @@ -168,12 +168,19 @@ check-cast v3, Lh40/p; + iget v0, p1, Lradiant/swipe/ComposeSearchQueueEvent;->action:I + + const/4 v1, 0x3 + + if-eq v0, v1, :queue_track + invoke-static {}, Lradiant/swipe/QueueExecutor;->hasActiveQueue()Z move-result v0 if-eqz v0, :play_track + :queue_track invoke-static {v3}, Lie0/i;->a(Lh40/p;)Lcom/aspiro/wamp/model/Track; move-result-object v9 @@ -212,12 +219,21 @@ const/4 v1, 0x1 - if-ne v0, v1, :append_track + if-ne v0, v1, :check_add_track_to_playlist invoke-static {v8, v9, v7, v4}, Lradiant/swipe/QueueExecutor;->playNextTrack(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)Z goto :done + :check_add_track_to_playlist + const/4 v1, 0x3 + + if-ne v0, v1, :append_track + + invoke-static {v8, v9, v7, v4}, Lradiant/swipe/QueueExecutor;->addToPlaylistTrack(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)V + + goto :done + :append_track invoke-static {v8, v9, v7, v4}, Lradiant/swipe/QueueExecutor;->track(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)Z @@ -262,12 +278,21 @@ const/4 v1, 0x1 - if-ne v0, v1, :append_album + if-ne v0, v1, :check_add_album_to_playlist invoke-static {v8, v9, v7, v5, v6}, Lradiant/swipe/QueueExecutor;->playNextAlbum(Landroid/content/Context;Lcom/aspiro/wamp/model/Album;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)Lio/reactivex/disposables/Disposable; goto :done + :check_add_album_to_playlist + const/4 v1, 0x3 + + if-ne v0, v1, :append_album + + invoke-static {v8, v9, v7, v5, v6}, Lradiant/swipe/QueueExecutor;->addToPlaylistAlbum(Landroid/content/Context;Lcom/aspiro/wamp/model/Album;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)V + + goto :done + :append_album invoke-static {v8, v9, v7, v5, v6}, Lradiant/swipe/QueueExecutor;->album(Landroid/content/Context;Lcom/aspiro/wamp/model/Album;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)Lio/reactivex/disposables/Disposable; @@ -288,12 +313,21 @@ const/4 v1, 0x1 - if-ne v0, v1, :append_playlist + if-ne v0, v1, :check_add_playlist_to_playlist invoke-static {v8, v9, v7, v5}, Lradiant/swipe/QueueExecutor;->playNextPlaylist(Landroid/content/Context;Lcom/aspiro/wamp/model/Playlist;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;)V goto :done + :check_add_playlist_to_playlist + const/4 v1, 0x3 + + if-ne v0, v1, :append_playlist + + invoke-static {v8, v9, v7, v5}, Lradiant/swipe/QueueExecutor;->addToPlaylistPlaylist(Landroid/content/Context;Lcom/aspiro/wamp/model/Playlist;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;)V + + goto :done + :append_playlist invoke-static {v8, v9, v7, v5}, Lradiant/swipe/QueueExecutor;->playlist(Landroid/content/Context;Lcom/aspiro/wamp/model/Playlist;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;)V @@ -310,12 +344,21 @@ const/4 v1, 0x1 - if-ne v0, v1, :append_mix + if-ne v0, v1, :check_add_mix_to_playlist invoke-static {v8, v9, v7, v5, v6}, Lradiant/swipe/QueueExecutor;->playNextMix(Landroid/content/Context;Lcom/aspiro/wamp/mix/model/Mix;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)Lio/reactivex/disposables/Disposable; goto :done + :check_add_mix_to_playlist + const/4 v1, 0x3 + + if-ne v0, v1, :append_mix + + invoke-static {v8, v9, v7, v5, v6}, Lradiant/swipe/QueueExecutor;->addToPlaylistMix(Landroid/content/Context;Lcom/aspiro/wamp/mix/model/Mix;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)V + + goto :done + :append_mix invoke-static {v8, v9, v7, v5, v6}, Lradiant/swipe/QueueExecutor;->mix(Landroid/content/Context;Lcom/aspiro/wamp/mix/model/Mix;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)Lio/reactivex/disposables/Disposable; diff --git a/patches/extension/radiant/swipe/ComposeSwipeState$Draw.smali b/patches/extension/radiant/swipe/ComposeSwipeState$Draw.smali index 3398b27..f0a4975 100644 --- a/patches/extension/radiant/swipe/ComposeSwipeState$Draw.smali +++ b/patches/extension/radiant/swipe/ComposeSwipeState$Draw.smali @@ -119,6 +119,15 @@ goto :color_ready :add_color + const/4 v12, 0x3 + + if-ne v11, v12, :add_to_queue_color + + const v11, __RL_SWIPE_TO_QUEUE_ADD_TO_PLAYLIST_COLOR__ + + goto :color_ready + + :add_to_queue_color const v11, __RL_SWIPE_TO_QUEUE_ADD_COLOR__ :color_ready @@ -138,6 +147,15 @@ goto :icon_ready :add_icon + const/4 v12, 0x3 + + if-ne v11, v12, :add_to_queue_icon + + iget-object v11, v5, Lradiant/swipe/ComposeSwipeState;->addToPlaylistIcon:Landroid/graphics/drawable/Drawable; + + goto :icon_ready + + :add_to_queue_icon iget-object v11, v5, Lradiant/swipe/ComposeSwipeState;->addIcon:Landroid/graphics/drawable/Drawable; :icon_ready diff --git a/patches/extension/radiant/swipe/ComposeSwipeState.smali b/patches/extension/radiant/swipe/ComposeSwipeState.smali index 19adcd5..1f10a10 100644 --- a/patches/extension/radiant/swipe/ComposeSwipeState.smali +++ b/patches/extension/radiant/swipe/ComposeSwipeState.smali @@ -33,6 +33,8 @@ .field addIcon:Landroid/graphics/drawable/Drawable; +.field addToPlaylistIcon:Landroid/graphics/drawable/Drawable; + .field playNextIcon:Landroid/graphics/drawable/Drawable; @@ -659,6 +661,25 @@ :store_play_next_icon iput-object v1, p0, Lradiant/swipe/ComposeSwipeState;->playNextIcon:Landroid/graphics/drawable/Drawable; + sget v1, Lcom/aspiro/wamp/R$drawable;->ic_add_to_playlist:I + + invoke-virtual {v0, v1}, Landroid/content/Context;->getDrawable(I)Landroid/graphics/drawable/Drawable; + + move-result-object v1 + + if-eqz v1, :store_add_to_playlist_icon + + invoke-virtual {v1}, Landroid/graphics/drawable/Drawable;->mutate()Landroid/graphics/drawable/Drawable; + + move-result-object v1 + + const/4 v2, -0x1 + + invoke-virtual {v1, v2}, Landroid/graphics/drawable/Drawable;->setTint(I)V + + :store_add_to_playlist_icon + iput-object v1, p0, Lradiant/swipe/ComposeSwipeState;->addToPlaylistIcon:Landroid/graphics/drawable/Drawable; + :context_ready if-eqz p1, :enabled_ready diff --git a/patches/extension/radiant/swipe/DynamicMediaQueue.smali b/patches/extension/radiant/swipe/DynamicMediaQueue.smali index d363405..72098ab 100644 --- a/patches/extension/radiant/swipe/DynamicMediaQueue.smali +++ b/patches/extension/radiant/swipe/DynamicMediaQueue.smali @@ -17,7 +17,7 @@ if-lt v4, v5, :done - const/4 v5, 0x2 + const/4 v5, 0x3 if-gt v4, v5, :done @@ -186,12 +186,21 @@ const/4 v1, 0x1 - if-ne v0, v1, :append_album + if-ne v0, v1, :check_add_album_to_playlist invoke-static {v5, v12, v10, v9, v6}, Lradiant/swipe/QueueExecutor;->playNextAlbum(Landroid/content/Context;Lcom/aspiro/wamp/model/Album;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)Lio/reactivex/disposables/Disposable; goto :done + :check_add_album_to_playlist + const/4 v1, 0x3 + + if-ne v0, v1, :append_album + + invoke-static {v5, v12, v10, v9, v6}, Lradiant/swipe/QueueExecutor;->addToPlaylistAlbum(Landroid/content/Context;Lcom/aspiro/wamp/model/Album;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)V + + goto :done + :append_album invoke-static {v5, v12, v10, v9, v6}, Lradiant/swipe/QueueExecutor;->album(Landroid/content/Context;Lcom/aspiro/wamp/model/Album;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)Lio/reactivex/disposables/Disposable; @@ -218,12 +227,21 @@ const/4 v1, 0x1 - if-ne v0, v1, :append_mix + if-ne v0, v1, :check_add_mix_to_playlist invoke-static {v5, v12, v10, v9, v6}, Lradiant/swipe/QueueExecutor;->playNextMix(Landroid/content/Context;Lcom/aspiro/wamp/mix/model/Mix;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)Lio/reactivex/disposables/Disposable; goto :done + :check_add_mix_to_playlist + const/4 v1, 0x3 + + if-ne v0, v1, :append_mix + + invoke-static {v5, v12, v10, v9, v6}, Lradiant/swipe/QueueExecutor;->addToPlaylistMix(Landroid/content/Context;Lcom/aspiro/wamp/mix/model/Mix;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)V + + goto :done + :append_mix invoke-static {v5, v12, v10, v9, v6}, Lradiant/swipe/QueueExecutor;->mix(Landroid/content/Context;Lcom/aspiro/wamp/mix/model/Mix;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)Lio/reactivex/disposables/Disposable; @@ -244,12 +262,21 @@ const/4 v1, 0x1 - if-ne v0, v1, :append_playlist + if-ne v0, v1, :check_add_playlist_to_playlist invoke-static {v5, v12, v10, v9}, Lradiant/swipe/QueueExecutor;->playNextPlaylist(Landroid/content/Context;Lcom/aspiro/wamp/model/Playlist;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;)V goto :done + :check_add_playlist_to_playlist + const/4 v1, 0x3 + + if-ne v0, v1, :append_playlist + + invoke-static {v5, v12, v10, v9}, Lradiant/swipe/QueueExecutor;->addToPlaylistPlaylist(Landroid/content/Context;Lcom/aspiro/wamp/model/Playlist;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;)V + + goto :done + :append_playlist invoke-static {v5, v12, v10, v9}, Lradiant/swipe/QueueExecutor;->playlist(Landroid/content/Context;Lcom/aspiro/wamp/model/Playlist;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;)V @@ -283,12 +310,21 @@ const/4 v1, 0x1 - if-ne v0, v1, :append_track + if-ne v0, v1, :check_add_track_to_playlist invoke-static {v5, v12, v10, v11}, Lradiant/swipe/QueueExecutor;->playNextTrack(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)Z goto :done + :check_add_track_to_playlist + const/4 v1, 0x3 + + if-ne v0, v1, :append_track + + invoke-static {v5, v12, v10, v11}, Lradiant/swipe/QueueExecutor;->addToPlaylistTrack(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)V + + goto :done + :append_track invoke-static {v5, v12, v10, v11}, Lradiant/swipe/QueueExecutor;->track(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)Z @@ -309,7 +345,7 @@ if-lt v0, v1, :done - const/4 v1, 0x2 + const/4 v1, 0x3 if-gt v0, v1, :done @@ -430,12 +466,21 @@ const/4 v1, 0x1 - if-ne v0, v1, :append_playlist + if-ne v0, v1, :check_add_playlist_to_playlist invoke-static {v6, v4, v8, v7}, Lradiant/swipe/QueueExecutor;->playNextPlaylist(Landroid/content/Context;Lcom/aspiro/wamp/model/Playlist;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;)V goto :done + :check_add_playlist_to_playlist + const/4 v1, 0x3 + + if-ne v0, v1, :append_playlist + + invoke-static {v6, v4, v8, v7}, Lradiant/swipe/QueueExecutor;->addToPlaylistPlaylist(Landroid/content/Context;Lcom/aspiro/wamp/model/Playlist;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;)V + + goto :done + :append_playlist invoke-static {v6, v4, v8, v7}, Lradiant/swipe/QueueExecutor;->playlist(Landroid/content/Context;Lcom/aspiro/wamp/model/Playlist;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;)V @@ -456,7 +501,7 @@ if-lt v4, v5, :done - const/4 v5, 0x2 + const/4 v5, 0x3 if-gt v4, v5, :done @@ -625,12 +670,21 @@ const/4 v1, 0x1 - if-ne v0, v1, :append_album + if-ne v0, v1, :check_add_album_to_playlist invoke-static {v5, v12, v10, v9, v6}, Lradiant/swipe/QueueExecutor;->playNextAlbum(Landroid/content/Context;Lcom/aspiro/wamp/model/Album;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)Lio/reactivex/disposables/Disposable; goto :done + :check_add_album_to_playlist + const/4 v1, 0x3 + + if-ne v0, v1, :append_album + + invoke-static {v5, v12, v10, v9, v6}, Lradiant/swipe/QueueExecutor;->addToPlaylistAlbum(Landroid/content/Context;Lcom/aspiro/wamp/model/Album;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)V + + goto :done + :append_album invoke-static {v5, v12, v10, v9, v6}, Lradiant/swipe/QueueExecutor;->album(Landroid/content/Context;Lcom/aspiro/wamp/model/Album;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)Lio/reactivex/disposables/Disposable; @@ -657,12 +711,21 @@ const/4 v1, 0x1 - if-ne v0, v1, :append_mix + if-ne v0, v1, :check_add_mix_to_playlist invoke-static {v5, v12, v10, v9, v6}, Lradiant/swipe/QueueExecutor;->playNextMix(Landroid/content/Context;Lcom/aspiro/wamp/mix/model/Mix;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)Lio/reactivex/disposables/Disposable; goto :done + :check_add_mix_to_playlist + const/4 v1, 0x3 + + if-ne v0, v1, :append_mix + + invoke-static {v5, v12, v10, v9, v6}, Lradiant/swipe/QueueExecutor;->addToPlaylistMix(Landroid/content/Context;Lcom/aspiro/wamp/mix/model/Mix;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)V + + goto :done + :append_mix invoke-static {v5, v12, v10, v9, v6}, Lradiant/swipe/QueueExecutor;->mix(Landroid/content/Context;Lcom/aspiro/wamp/mix/model/Mix;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)Lio/reactivex/disposables/Disposable; @@ -683,12 +746,21 @@ const/4 v1, 0x1 - if-ne v0, v1, :append_playlist + if-ne v0, v1, :check_add_playlist_to_playlist invoke-static {v5, v12, v10, v9}, Lradiant/swipe/QueueExecutor;->playNextPlaylist(Landroid/content/Context;Lcom/aspiro/wamp/model/Playlist;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;)V goto :done + :check_add_playlist_to_playlist + const/4 v1, 0x3 + + if-ne v0, v1, :append_playlist + + invoke-static {v5, v12, v10, v9}, Lradiant/swipe/QueueExecutor;->addToPlaylistPlaylist(Landroid/content/Context;Lcom/aspiro/wamp/model/Playlist;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;)V + + goto :done + :append_playlist invoke-static {v5, v12, v10, v9}, Lradiant/swipe/QueueExecutor;->playlist(Landroid/content/Context;Lcom/aspiro/wamp/model/Playlist;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;)V @@ -722,12 +794,21 @@ const/4 v1, 0x1 - if-ne v0, v1, :append_track + if-ne v0, v1, :check_add_track_to_playlist invoke-static {v5, v12, v10, v11}, Lradiant/swipe/QueueExecutor;->playNextTrack(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)Z goto :done + :check_add_track_to_playlist + const/4 v1, 0x3 + + if-ne v0, v1, :append_track + + invoke-static {v5, v12, v10, v11}, Lradiant/swipe/QueueExecutor;->addToPlaylistTrack(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)V + + goto :done + :append_track invoke-static {v5, v12, v10, v11}, Lradiant/swipe/QueueExecutor;->track(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)Z diff --git a/patches/extension/radiant/swipe/DynamicTrackQueue.smali b/patches/extension/radiant/swipe/DynamicTrackQueue.smali index 5dc629d..b6fd5a9 100644 --- a/patches/extension/radiant/swipe/DynamicTrackQueue.smali +++ b/patches/extension/radiant/swipe/DynamicTrackQueue.smali @@ -166,12 +166,21 @@ const/4 v2, 0x1 - if-ne v0, v2, :append + if-ne v0, v2, :check_add_to_playlist invoke-static {v1, v7, v8, v9}, Lradiant/swipe/QueueExecutor;->playNextTrack(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)Z goto :done + :check_add_to_playlist + const/4 v2, 0x3 + + if-ne v0, v2, :append + + invoke-static {v1, v7, v8, v9}, Lradiant/swipe/QueueExecutor;->addToPlaylistTrack(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)V + + goto :done + :append invoke-static {v1, v7, v8, v9}, Lradiant/swipe/QueueExecutor;->track(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)Z diff --git a/patches/extension/radiant/swipe/DynamicTrackQueueAction.smali b/patches/extension/radiant/swipe/DynamicTrackQueueAction.smali index d4a8b8b..a13a6ed 100644 --- a/patches/extension/radiant/swipe/DynamicTrackQueueAction.smali +++ b/patches/extension/radiant/swipe/DynamicTrackQueueAction.smali @@ -44,6 +44,10 @@ iget-wide v1, p0, Lradiant/swipe/DynamicTrackQueueAction;->trackId:J + const/4 v0, 0x3 + + if-eq p1, v0, :active_queue + invoke-static {}, Lradiant/swipe/QueueExecutor;->hasActiveQueue()Z move-result v0 diff --git a/patches/extension/radiant/swipe/DynamicTrackResolver.smali b/patches/extension/radiant/swipe/DynamicTrackResolver.smali index c6f1cdc..512c0b2 100644 --- a/patches/extension/radiant/swipe/DynamicTrackResolver.smali +++ b/patches/extension/radiant/swipe/DynamicTrackResolver.smali @@ -525,6 +525,10 @@ if-eqz v1, :done + const/4 v2, 0x3 + + if-eq v8, v2, :append + invoke-static {}, Lradiant/swipe/QueueExecutor;->hasActiveQueue()Z move-result v2 @@ -626,12 +630,21 @@ const/4 v0, 0x1 - if-ne v8, v0, :append_track + if-ne v8, v0, :check_add_to_playlist invoke-static {v5, v1, v3, v4}, Lradiant/swipe/QueueExecutor;->playNextTrack(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)Z goto :done + :check_add_to_playlist + const/4 v0, 0x3 + + if-ne v8, v0, :append_track + + invoke-static {v5, v1, v3, v4}, Lradiant/swipe/QueueExecutor;->addToPlaylistTrack(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)V + + goto :done + :append_track invoke-static {v5, v1, v3, v4}, Lradiant/swipe/QueueExecutor;->track(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)Z diff --git a/patches/extension/radiant/swipe/FeedResolver.smali b/patches/extension/radiant/swipe/FeedResolver.smali index 70def93..54d7b36 100644 --- a/patches/extension/radiant/swipe/FeedResolver.smali +++ b/patches/extension/radiant/swipe/FeedResolver.smali @@ -410,6 +410,10 @@ check-cast v7, Lcom/aspiro/wamp/model/Playlist; + const/4 v0, 0x3 + + if-eq p0, v0, :add_to_playlist_playlist + const/4 v0, 0x1 if-ne p0, v0, :append_playlist @@ -423,6 +427,11 @@ goto :done + :add_to_playlist_playlist + invoke-static {v3, v7, p1, v5}, Lradiant/swipe/QueueExecutor;->addToPlaylistPlaylist(Landroid/content/Context;Lcom/aspiro/wamp/model/Playlist;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;)V + + goto :done + :collection iget-object v6, v2, La80/c;->b:Lx40/a; @@ -438,6 +447,10 @@ check-cast v7, Lcom/aspiro/wamp/model/Album; + const/4 v0, 0x3 + + if-eq p0, v0, :add_to_playlist_album + const/4 v0, 0x1 if-ne p0, v0, :append_album @@ -455,9 +468,18 @@ goto :retain + :add_to_playlist_album + invoke-static {v3, v7, p1, v5, v6}, Lradiant/swipe/QueueExecutor;->addToPlaylistAlbum(Landroid/content/Context;Lcom/aspiro/wamp/model/Album;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)V + + goto :done + :queue_mix check-cast v7, Lcom/aspiro/wamp/mix/model/Mix; + const/4 v0, 0x3 + + if-eq p0, v0, :add_to_playlist_mix + const/4 v0, 0x1 if-ne p0, v0, :append_mix @@ -473,6 +495,13 @@ move-result-object v7 + goto :retain + + :add_to_playlist_mix + invoke-static {v3, v7, p1, v5, v6}, Lradiant/swipe/QueueExecutor;->addToPlaylistMix(Landroid/content/Context;Lcom/aspiro/wamp/mix/model/Mix;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)V + + goto :done + :retain if-eqz v7, :done diff --git a/patches/extension/radiant/swipe/MyAlbumsResolver.smali b/patches/extension/radiant/swipe/MyAlbumsResolver.smali index 2f0f60c..70292bf 100644 --- a/patches/extension/radiant/swipe/MyAlbumsResolver.smali +++ b/patches/extension/radiant/swipe/MyAlbumsResolver.smali @@ -162,6 +162,10 @@ iget-object p0, v1, Lfd/c;->c:Lcom/tidal/android/navigation/NavigationInfo; + const/4 v1, 0x3 + + if-eq v6, v1, :add_to_playlist + const/4 v1, 0x1 if-ne v6, v1, :append @@ -177,6 +181,13 @@ move-result-object p1 + goto :retain + + :add_to_playlist + invoke-static {v3, v4, v5, p0, v2}, Lradiant/swipe/QueueExecutor;->addToPlaylistAlbum(Landroid/content/Context;Lcom/aspiro/wamp/model/Album;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)V + + goto :done + :retain if-eqz p1, :done diff --git a/patches/extension/radiant/swipe/MyMixesAndRadioResolver.smali b/patches/extension/radiant/swipe/MyMixesAndRadioResolver.smali index d2c651e..58751f3 100644 --- a/patches/extension/radiant/swipe/MyMixesAndRadioResolver.smali +++ b/patches/extension/radiant/swipe/MyMixesAndRadioResolver.smali @@ -198,6 +198,10 @@ iget-object p0, v1, Lpe/f;->b:Lcom/tidal/android/navigation/NavigationInfo; + const/4 v1, 0x3 + + if-eq v7, v1, :add_to_playlist + const/4 v1, 0x1 if-ne v7, v1, :append @@ -213,6 +217,13 @@ move-result-object p1 + goto :retain + + :add_to_playlist + invoke-static {v3, v4, v5, p0, v2}, Lradiant/swipe/QueueExecutor;->addToPlaylistMix(Landroid/content/Context;Lcom/aspiro/wamp/mix/model/Mix;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)V + + goto :done + :retain if-eqz p1, :done diff --git a/patches/extension/radiant/swipe/MyPlaylistsResolver.smali b/patches/extension/radiant/swipe/MyPlaylistsResolver.smali index 26733d7..ce6b0a6 100644 --- a/patches/extension/radiant/swipe/MyPlaylistsResolver.smali +++ b/patches/extension/radiant/swipe/MyPlaylistsResolver.smali @@ -189,6 +189,10 @@ iget-object p0, v1, Lhf/c;->d:Lcom/tidal/android/navigation/NavigationInfo; + const/4 v0, 0x3 + + if-eq v5, v0, :add_to_playlist + const/4 v0, 0x1 if-ne v5, v0, :append @@ -200,6 +204,11 @@ :append invoke-static {v2, v3, v4, p0}, Lradiant/swipe/QueueExecutor;->playlist(Landroid/content/Context;Lcom/aspiro/wamp/model/Playlist;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;)V + goto :done + + :add_to_playlist + invoke-static {v2, v3, v4, p0}, Lradiant/swipe/QueueExecutor;->addToPlaylistPlaylist(Landroid/content/Context;Lcom/aspiro/wamp/model/Playlist;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;)V + :done return-void .end method diff --git a/patches/extension/radiant/swipe/PlaylistItemsResolver.smali b/patches/extension/radiant/swipe/PlaylistItemsResolver.smali index cbfe02e..9e52236 100644 --- a/patches/extension/radiant/swipe/PlaylistItemsResolver.smali +++ b/patches/extension/radiant/swipe/PlaylistItemsResolver.smali @@ -260,10 +260,15 @@ check-cast v2, Lcom/aspiro/wamp/playlist/ui/items/PlaylistItemCollectionView; if-eqz v2, :done + const/4 v3, 0x3 + + if-eq v8, v3, :build_source + invoke-static {}, Lradiant/swipe/QueueExecutor;->hasActiveQueue()Z move-result v3 if-eqz v3, :play + :build_source instance-of v3, v0, Lcom/aspiro/wamp/playlist/viewmodel/item/SuggestedTrackViewModel; if-eqz v3, :append_member @@ -303,6 +308,10 @@ :append invoke-virtual {v2}, Landroid/view/View;->getContext()Landroid/content/Context; move-result-object v3 + const/4 v0, 0x3 + + if-eq v8, v0, :add_to_playlist + const/4 v0, 0x1 if-ne v8, v0, :append_track @@ -315,6 +324,10 @@ invoke-static {v3, v1, v6, v7}, Lradiant/swipe/QueueExecutor;->track(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)Z goto :done + :add_to_playlist + invoke-static {v3, v1, v6, v7}, Lradiant/swipe/QueueExecutor;->addToPlaylistTrack(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)V + goto :done + :play iget-object v3, v2, Lcom/aspiro/wamp/playlist/ui/items/PlaylistItemCollectionView;->c:Lcom/aspiro/wamp/playlist/ui/items/a; if-eqz v3, :done diff --git a/patches/extension/radiant/swipe/QueueExecutor.smali b/patches/extension/radiant/swipe/QueueExecutor.smali index 5d74e8b..d5ce7f9 100644 --- a/patches/extension/radiant/swipe/QueueExecutor.smali +++ b/patches/extension/radiant/swipe/QueueExecutor.smali @@ -39,6 +39,132 @@ return-object p0 .end method +.method public static addToPlaylistAlbum(Landroid/content/Context;Lcom/aspiro/wamp/model/Album;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)V + .locals 2 + + if-eqz p1, :done + + if-eqz p2, :done + + if-eqz p4, :done + + invoke-static {p0}, Lradiant/swipe/QueueExecutor;->activity(Landroid/content/Context;)Landroidx/fragment/app/FragmentActivity; + + move-result-object p0 + + if-eqz p0, :done + + iget-object v0, p4, Lh4/a;->b:Lo3/a$a; + + if-eqz v0, :done + + invoke-interface {v0, p1, p2, p3}, Lo3/a$a;->a(Lcom/aspiro/wamp/model/Album;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;)Lo3/a; + + move-result-object v0 + + if-eqz v0, :done + + iget-object v0, v0, Lo3/a;->l:Lcom/aspiro/wamp/module/album/AlbumProvider; + + if-eqz v0, :done + + new-instance v1, Lc3/h; + + invoke-direct {v1, p1, v0, p2, p3}, Lc3/h;->(Lcom/aspiro/wamp/model/Album;Lcom/aspiro/wamp/module/album/AlbumProvider;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;)V + + invoke-virtual {v1, p0}, Lc3/h;->b(Landroidx/fragment/app/FragmentActivity;)V + + :done + return-void +.end method + +.method public static addToPlaylistMix(Landroid/content/Context;Lcom/aspiro/wamp/mix/model/Mix;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)V + .locals 1 + + if-eqz p1, :done + + if-eqz p2, :done + + if-eqz p4, :done + + invoke-static {p0}, Lradiant/swipe/QueueExecutor;->activity(Landroid/content/Context;)Landroidx/fragment/app/FragmentActivity; + + move-result-object p0 + + if-eqz p0, :done + + iget-object v0, p4, Lh4/a;->h:Lu3/a$a; + + if-eqz v0, :done + + invoke-interface {v0, p1, p2, p3}, Lu3/a$a;->a(Lcom/aspiro/wamp/mix/model/Mix;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;)Lu3/a; + + move-result-object v0 + + if-eqz v0, :done + + iget-object v0, v0, Lu3/a;->j:Lj3/k$a; + + if-eqz v0, :done + + invoke-interface {v0, p1, p2, p3}, Lj3/k$a;->a(Lcom/aspiro/wamp/mix/model/Mix;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;)Lj3/k; + + move-result-object v0 + + if-eqz v0, :done + + invoke-virtual {v0, p0}, Lj3/k;->b(Landroidx/fragment/app/FragmentActivity;)V + + :done + return-void +.end method + +.method public static addToPlaylistPlaylist(Landroid/content/Context;Lcom/aspiro/wamp/model/Playlist;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;)V + .locals 1 + + if-eqz p1, :done + + if-eqz p2, :done + + invoke-static {p0}, Lradiant/swipe/QueueExecutor;->activity(Landroid/content/Context;)Landroidx/fragment/app/FragmentActivity; + + move-result-object p0 + + if-eqz p0, :done + + new-instance v0, Lcom/aspiro/wamp/contextmenu/item/playlist/f; + + invoke-direct {v0, p1, p2, p3}, Lcom/aspiro/wamp/contextmenu/item/playlist/f;->(Lcom/aspiro/wamp/model/Playlist;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;)V + + invoke-virtual {v0, p0}, Lcom/aspiro/wamp/contextmenu/item/playlist/f;->b(Landroidx/fragment/app/FragmentActivity;)V + + :done + return-void +.end method + +.method public static addToPlaylistTrack(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)V + .locals 1 + + if-eqz p1, :done + + if-eqz p2, :done + + invoke-static {p0}, Lradiant/swipe/QueueExecutor;->activity(Landroid/content/Context;)Landroidx/fragment/app/FragmentActivity; + + move-result-object p0 + + if-eqz p0, :done + + new-instance v0, Lm3/d; + + invoke-direct {v0, p1, p2, p3}, Lm3/d;->(Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)V + + invoke-virtual {v0, p0}, Lm3/d;->b(Landroidx/fragment/app/FragmentActivity;)V + + :done + return-void +.end method + .method public static album(Landroid/content/Context;Lcom/aspiro/wamp/model/Album;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)Lio/reactivex/disposables/Disposable; .locals 8 diff --git a/patches/extension/radiant/swipe/QueueRequest.smali b/patches/extension/radiant/swipe/QueueRequest.smali index 4b9d9a6..dfeb02a 100644 --- a/patches/extension/radiant/swipe/QueueRequest.smali +++ b/patches/extension/radiant/swipe/QueueRequest.smali @@ -9,6 +9,8 @@ .field public static final ACTION_ADD_TO_QUEUE:I = 0x2 +.field public static final ACTION_ADD_TO_PLAYLIST:I = 0x3 + # instance fields .field public action:I diff --git a/patches/extension/radiant/swipe/SearchAlbumsResolver.smali b/patches/extension/radiant/swipe/SearchAlbumsResolver.smali index 75766cb..eba723b 100644 --- a/patches/extension/radiant/swipe/SearchAlbumsResolver.smali +++ b/patches/extension/radiant/swipe/SearchAlbumsResolver.smali @@ -162,6 +162,10 @@ iget-object p0, v1, Lld/c;->c:Lcom/tidal/android/navigation/NavigationInfo; + const/4 v1, 0x3 + + if-eq v6, v1, :add_to_playlist + const/4 v1, 0x1 if-ne v6, v1, :append @@ -177,6 +181,13 @@ move-result-object p1 + goto :retain + + :add_to_playlist + invoke-static {v3, v4, v5, p0, v2}, Lradiant/swipe/QueueExecutor;->addToPlaylistAlbum(Landroid/content/Context;Lcom/aspiro/wamp/model/Album;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)V + + goto :done + :retain if-eqz p1, :done diff --git a/patches/extension/radiant/swipe/SearchPlaylistsResolver.smali b/patches/extension/radiant/swipe/SearchPlaylistsResolver.smali index f5e496e..1099ed2 100644 --- a/patches/extension/radiant/swipe/SearchPlaylistsResolver.smali +++ b/patches/extension/radiant/swipe/SearchPlaylistsResolver.smali @@ -193,6 +193,10 @@ iget-object p0, v1, Lzf/c;->c:Lcom/tidal/android/navigation/NavigationInfo; + const/4 v0, 0x3 + + if-eq v6, v0, :add_to_playlist + const/4 v0, 0x1 if-ne v6, v0, :append @@ -204,6 +208,11 @@ :append invoke-static {v2, v3, v4, p0}, Lradiant/swipe/QueueExecutor;->playlist(Landroid/content/Context;Lcom/aspiro/wamp/model/Playlist;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;)V + goto :done + + :add_to_playlist + invoke-static {v2, v3, v4, p0}, Lradiant/swipe/QueueExecutor;->addToPlaylistPlaylist(Landroid/content/Context;Lcom/aspiro/wamp/model/Playlist;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;)V + :done return-void .end method diff --git a/patches/extension/radiant/swipe/SuggestionsResolver.smali b/patches/extension/radiant/swipe/SuggestionsResolver.smali index 599c249..e10af9b 100644 --- a/patches/extension/radiant/swipe/SuggestionsResolver.smali +++ b/patches/extension/radiant/swipe/SuggestionsResolver.smali @@ -319,6 +319,10 @@ iget v2, p1, Lradiant/swipe/QueueRequest;->action:I + const/4 v3, 0x3 + + if-eq v2, v3, :track_action + const/4 v3, 0x1 if-ne v2, v3, :default_action @@ -329,6 +333,7 @@ if-eqz v2, :default_action + :track_action invoke-virtual {v0}, Lcom/aspiro/wamp/model/SuggestedMediaItem$SuggestedTrack;->getMediaItem()Lcom/aspiro/wamp/model/Track; move-result-object v2 @@ -375,10 +380,21 @@ move-result-object v0 + iget p1, p1, Lradiant/swipe/QueueRequest;->action:I + + const/4 v3, 0x3 + + if-eq p1, v3, :add_to_playlist + invoke-static {v0, v2, v4, v6}, Lradiant/swipe/QueueExecutor;->playNextTrack(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)Z goto :done + :add_to_playlist + invoke-static {v0, v2, v4, v6}, Lradiant/swipe/QueueExecutor;->addToPlaylistTrack(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)V + + goto :done + :default_action iget p1, p1, Lradiant/swipe/QueueRequest;->position:I diff --git a/patches/extension/radiant/swipe/UnifiedSearchResolver.smali b/patches/extension/radiant/swipe/UnifiedSearchResolver.smali index 8fbaa22..c9fcebe 100644 --- a/patches/extension/radiant/swipe/UnifiedSearchResolver.smali +++ b/patches/extension/radiant/swipe/UnifiedSearchResolver.smali @@ -237,6 +237,8 @@ move-object v5, v0 check-cast v5, Lbm/k; iget-object v6, v5, Lbm/k;->a:Lcom/aspiro/wamp/model/Track; + const/4 v7, 0x3 + if-eq v8, v7, :append_track invoke-static {}, Lradiant/swipe/QueueExecutor;->hasActiveQueue()Z move-result v7 if-nez v7, :append_track @@ -273,6 +275,10 @@ invoke-virtual {p1, v6}, Lcom/aspiro/wamp/playqueue/source/model/Source;->addSourceItem(Lcom/aspiro/wamp/model/MediaItem;)V invoke-virtual {v1}, Landroidx/fragment/app/Fragment;->getContext()Landroid/content/Context; move-result-object v0 + const/4 v2, 0x3 + + if-eq v8, v2, :add_to_playlist_track + const/4 v2, 0x1 if-ne v8, v2, :queue_append_track @@ -285,6 +291,10 @@ invoke-static {v0, v6, v3, p1}, Lradiant/swipe/QueueExecutor;->track(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)Z goto :done + :add_to_playlist_track + invoke-static {v0, v6, v3, p1}, Lradiant/swipe/QueueExecutor;->addToPlaylistTrack(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)V + goto :done + :album instance-of v5, v0, Lbm/a; if-eqz v5, :playlist @@ -296,6 +306,10 @@ iget-object v6, v0, Lbm/a;->a:Lcom/aspiro/wamp/model/Album; invoke-virtual {v1}, Landroidx/fragment/app/Fragment;->getContext()Landroid/content/Context; move-result-object v7 + const/4 v0, 0x3 + + if-eq v8, v0, :add_to_playlist_album + const/4 v0, 0x1 if-ne v8, v0, :append_album @@ -312,6 +326,10 @@ invoke-virtual {v1, v0}, Lio/reactivex/disposables/CompositeDisposable;->add(Lio/reactivex/disposables/Disposable;)Z goto :done + :add_to_playlist_album + invoke-static {v7, v6, v3, v4, v5}, Lradiant/swipe/QueueExecutor;->addToPlaylistAlbum(Landroid/content/Context;Lcom/aspiro/wamp/model/Album;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)V + goto :done + :playlist instance-of v5, v0, Lbm/g; if-eqz v5, :mix @@ -319,6 +337,10 @@ iget-object v5, v0, Lbm/g;->a:Lcom/aspiro/wamp/model/Playlist; invoke-virtual {v1}, Landroidx/fragment/app/Fragment;->getContext()Landroid/content/Context; move-result-object v6 + const/4 v0, 0x3 + + if-eq v8, v0, :add_to_playlist_playlist + const/4 v0, 0x1 if-ne v8, v0, :append_playlist @@ -331,6 +353,10 @@ invoke-static {v6, v5, v3, v4}, Lradiant/swipe/QueueExecutor;->playlist(Landroid/content/Context;Lcom/aspiro/wamp/model/Playlist;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;)V goto :done + :add_to_playlist_playlist + invoke-static {v6, v5, v3, v4}, Lradiant/swipe/QueueExecutor;->addToPlaylistPlaylist(Landroid/content/Context;Lcom/aspiro/wamp/model/Playlist;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;)V + goto :done + :mix instance-of v5, v0, Lbm/f; if-eqz v5, :done @@ -342,6 +368,10 @@ iget-object v6, v0, Lbm/f;->a:Lcom/aspiro/wamp/mix/model/Mix; invoke-virtual {v1}, Landroidx/fragment/app/Fragment;->getContext()Landroid/content/Context; move-result-object v7 + const/4 v0, 0x3 + + if-eq v8, v0, :add_to_playlist_mix + const/4 v0, 0x1 if-ne v8, v0, :append_mix @@ -357,6 +387,11 @@ iget-object v1, v1, Lcom/aspiro/wamp/search/v2/UnifiedSearchView;->g:Lio/reactivex/disposables/CompositeDisposable; invoke-virtual {v1, v0}, Lio/reactivex/disposables/CompositeDisposable;->add(Lio/reactivex/disposables/Disposable;)Z + goto :done + + :add_to_playlist_mix + invoke-static {v7, v6, v3, v4, v5}, Lradiant/swipe/QueueExecutor;->addToPlaylistMix(Landroid/content/Context;Lcom/aspiro/wamp/mix/model/Mix;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/tidal/android/navigation/NavigationInfo;Lh4/a;)V + :done return-void .end method diff --git a/patches/extension/radiant/swipe/VerticalMediaQueueAction.smali b/patches/extension/radiant/swipe/VerticalMediaQueueAction.smali index bd8cd53..9229b4f 100644 --- a/patches/extension/radiant/swipe/VerticalMediaQueueAction.smali +++ b/patches/extension/radiant/swipe/VerticalMediaQueueAction.smali @@ -213,6 +213,10 @@ if-eqz v5, :done + const/4 v1, 0x3 + + if-eq p1, v1, :queue_event + const/4 v1, 0x4 if-ne v5, v1, :queue_event diff --git a/patches/extension/radiant/swipe/ViewAllTrackQueue.smali b/patches/extension/radiant/swipe/ViewAllTrackQueue.smali index c38d57f..07e4ef1 100644 --- a/patches/extension/radiant/swipe/ViewAllTrackQueue.smali +++ b/patches/extension/radiant/swipe/ViewAllTrackQueue.smali @@ -103,12 +103,21 @@ const/4 v0, 0x1 - if-ne p4, v0, :append + if-ne p4, v0, :check_add_to_playlist invoke-static {p1, v3, v4, v9}, Lradiant/swipe/QueueExecutor;->playNextTrack(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)Z goto :done + :check_add_to_playlist + const/4 v0, 0x3 + + if-ne p4, v0, :append + + invoke-static {p1, v3, v4, v9}, Lradiant/swipe/QueueExecutor;->addToPlaylistTrack(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)V + + goto :done + :append invoke-static {p1, v3, v4, v9}, Lradiant/swipe/QueueExecutor;->track(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)Z diff --git a/patches/extension/radiant/swipe/ViewAllTrackQueueAction.smali b/patches/extension/radiant/swipe/ViewAllTrackQueueAction.smali index 9dfa506..82e6a74 100644 --- a/patches/extension/radiant/swipe/ViewAllTrackQueueAction.smali +++ b/patches/extension/radiant/swipe/ViewAllTrackQueueAction.smali @@ -40,12 +40,17 @@ iget-wide v1, p0, Lradiant/swipe/ViewAllTrackQueueAction;->trackId:J + const/4 v3, 0x3 + + if-eq p1, v3, :queue_event + invoke-static {}, Lradiant/swipe/QueueExecutor;->hasActiveQueue()Z move-result v3 if-eqz v3, :play_existing + :queue_event iget-object v3, p0, Lradiant/swipe/ViewAllTrackQueueAction;->context:Landroid/content/Context; if-eqz v3, :done diff --git a/patches/manifest.json b/patches/manifest.json index d9ebef9..8a8f2e4 100644 --- a/patches/manifest.json +++ b/patches/manifest.json @@ -471,25 +471,27 @@ "radiant/swipe/SuggestionsResolver.smali" ], "title": "Swipe to Queue", - "description": "Swipe on tracks/albums/playlists to add them to the play queue", + "description": "Swipe on tracks/albums/playlists to add them to the play queue (and more actions)", "default": false, "advancedOptions": [ { "type": "choice", "key": "left_action", "title": "Left Swipe Action", - "description": "Choose the action for a left swipe", "entries": [ "Disabled", "Play next", - "Add to queue" + "Add to queue", + "Add to playlist" ], "values": [ "0x0", "0x1", - "0x2" + "0x2", + "0x3" ], "defaultIndex": 2, + "inline": true, "distinctFrom": "right_action", "token": "RL_SWIPE_TO_QUEUE_LEFT_ACTION" }, @@ -497,18 +499,20 @@ "type": "choice", "key": "right_action", "title": "Right Swipe Action", - "description": "Choose the action for a right swipe", "entries": [ "Disabled", "Play next", - "Add to queue" + "Add to queue", + "Add to playlist" ], "values": [ "0x0", "0x1", - "0x2" + "0x2", + "0x3" ], "defaultIndex": 0, + "inline": true, "distinctFrom": "left_action", "token": "RL_SWIPE_TO_QUEUE_RIGHT_ACTION" }, @@ -516,11 +520,10 @@ "type": "choice", "key": "remove_direction", "title": "Remove Track from Queue", - "description": "Choose the swipe direction used to remove items from the play queue", "entries": [ "Left swipe", "Right swipe", - "Both" + "Both directions" ], "values": [ "0x4", @@ -528,6 +531,8 @@ "0xc" ], "defaultIndex": 0, + "forceDropdown": true, + "inline": true, "token": "RL_SWIPE_TO_QUEUE_REMOVE_DIRECTION" }, { @@ -543,6 +548,13 @@ "title": "Play Next Color", "default": -14408663, "token": "RL_SWIPE_TO_QUEUE_PLAY_NEXT_COLOR" + }, + { + "type": "color", + "key": "add_to_playlist_color", + "title": "Add to Playlist Color", + "default": -14408663, + "token": "RL_SWIPE_TO_QUEUE_ADD_TO_PLAYLIST_COLOR" } ] }, diff --git a/patches/swipe-to-queue.patch b/patches/swipe-to-queue.patch index 3eedd77..38aef33 100644 --- a/patches/swipe-to-queue.patch +++ b/patches/swipe-to-queue.patch @@ -1,6 +1,6 @@ --- a/com/aspiro/wamp/mycollection/subpages/favoritetracks/FavoriteTracksFragment.smali +++ b/com/aspiro/wamp/mycollection/subpages/favoritetracks/FavoriteTracksFragment.smali -@@ -107,6 +107,143 @@ +@@ -107,6 +107,154 @@ .end method @@ -102,6 +102,10 @@ + + move-object v2, p2 + ++ const/4 p1, 0x3 ++ ++ if-eq p3, p1, :rl_favorite_add_to_playlist ++ + const/4 p1, 0x1 + + if-ne p3, p1, :rl_favorite_append @@ -123,6 +127,13 @@ + + move-result v0 + ++ goto :rl_favorite_result ++ ++ :rl_favorite_add_to_playlist ++ invoke-static {v1, v2, v3, v4}, Lradiant/swipe/QueueExecutor;->addToPlaylistTrack(Landroid/content/Context;Lcom/aspiro/wamp/model/Track;Lcom/aspiro/wamp/eventtracking/model/ContextualMetadata;Lcom/aspiro/wamp/playqueue/source/model/Source;)V ++ ++ goto :done ++ + :rl_favorite_result + + if-nez v0, :done @@ -144,7 +155,7 @@ # virtual methods .method public final M()Ln8/b; .locals 1 -@@ -2265,9 +2437,16 @@ +@@ -2265,9 +2448,16 @@ iput-object p0, p1, Lo4/g;->e:Lo4/g$e; .line 224