Skip to content

Refactor/bottom sheet refactor#6241

Open
SeniorZhai wants to merge 2 commits intomasterfrom
refactor/bottom-sheet-refactor
Open

Refactor/bottom sheet refactor#6241
SeniorZhai wants to merge 2 commits intomasterfrom
refactor/bottom-sheet-refactor

Conversation

@SeniorZhai
Copy link
Member

No description provided.

@SeniorZhai SeniorZhai requested a review from Copilot March 20, 2026 06:31
@SeniorZhai SeniorZhai marked this pull request as ready for review March 20, 2026 06:31
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors several Compose ModalBottomSheetLayout usages into dedicated MixinComposeBottomSheetDialogFragment bottom sheets, and wires back-press/expand behavior between fragments and Compose screens.

Changes:

  • Replaces Compose modal bottom sheets in Alert edit and PIN quiz flows with MixinComposeBottomSheetDialogFragment implementations.
  • Introduces an address-book bottom sheet dialog and updates transfer destination flow to open it via a callback.
  • Adds expansion/back handling for the wallet asset dashboard overlay.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
app/src/main/java/one/mixin/android/ui/wallet/components/AssetDashboardScreen.kt Adds Compose BackHandler and new parameters to close the expanded dashboard.
app/src/main/java/one/mixin/android/ui/wallet/alert/AlertSelectionBottomSheetDialogFragment.kt New bottom sheet dialog for selecting alert type/frequency.
app/src/main/java/one/mixin/android/ui/wallet/alert/AlertFragment.kt Uses the new alert selection bottom sheet dialog from the edit route.
app/src/main/java/one/mixin/android/ui/wallet/alert/AlertEditPage.kt Removes ModalBottomSheetLayout; delegates selection UI to fragment-provided callbacks.
app/src/main/java/one/mixin/android/ui/wallet/WalletListBottomSheetDialogFragment.kt Adjusts wallet list layout sizing inside the bottom sheet.
app/src/main/java/one/mixin/android/ui/wallet/WalletFragment.kt Tracks dashboard expanded state and closes it via back press.
app/src/main/java/one/mixin/android/ui/landing/components/QuizResultBottomSheetDialogFragment.kt New quiz result bottom sheet dialog.
app/src/main/java/one/mixin/android/ui/landing/components/QuizPage.kt Removes Compose modal sheet; triggers a fragment bottom sheet via callback.
app/src/main/java/one/mixin/android/ui/landing/SetupPinFragment.kt Shows QuizResultBottomSheetDialogFragment from the quiz page callback.
app/src/main/java/one/mixin/android/ui/address/page/TransferDestinationInputPage.kt Removes Compose modal address book; uses onShowAddressBook callback.
app/src/main/java/one/mixin/android/ui/address/page/AddressSearchBottomSheet.kt Updates bottom sheet content to use onDismiss and simplifies back handling.
app/src/main/java/one/mixin/android/ui/address/TransferDestinationInputFragment.kt Shows the new address search bottom sheet dialog fragment.
app/src/main/java/one/mixin/android/ui/address/AddressSearchBottomSheetDialogFragment.kt New bottom sheet dialog fragment hosting AddressSearchBottomSheet.
Comments suppressed due to low confidence (1)

app/src/main/java/one/mixin/android/ui/address/page/AddressSearchBottomSheet.kt:87

  • The computed actionBarHeight value is unused, and scope/kotlinx.coroutines.launch are no longer referenced after removing the modal sheet state logic. Please remove these unused variables/imports to avoid lint/ktlint failures and keep the file minimal.
    val scope = rememberCoroutineScope()
    val filteredAddresses = remember(searchText, addresses) {
        if (searchText.isBlank()) {
            addresses
        } else {
            addresses.filter { address ->
                address.label.contains(searchText, ignoreCase = true) ||
                    address.destination.contains(searchText, ignoreCase = true)
            }
        }
    }
    BackHandler(enabled = true) {
        if (isDeleteMode) isDeleteMode = false
        else onDismiss()
    }

    val actionBarHeight = with(LocalDensity.current) {
        val attrs = intArrayOf(android.R.attr.actionBarSize)
        val typedArray = LocalContext.current.obtainStyledAttributes(attrs)
        val height = typedArray.getDimensionPixelSize(0, 0)
        typedArray.recycle()
        height.toDp()
    }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 17 to 20
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.ModalBottomSheetLayout
import androidx.compose.material.ModalBottomSheetValue
import androidx.compose.material.RadioButton
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After removing the ModalBottomSheetLayout/coroutine-scope logic, kotlinx.coroutines.launch is no longer used in this file. Please remove the unused import to avoid lint/ktlint failures.

Copilot uses AI. Check for mistakes.
Comment on lines 88 to +92
toWallet: (String?) -> Unit,
onSend: (String) -> Unit,
onDeleteAddress: (Address) -> Unit,
onAddressClick: (Address) -> Unit,
onShowAddressBook: () -> Unit,
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

toAddAddress, onDeleteAddress, and onAddressClick are still declared as parameters but are no longer used inside TransferDestinationInputPage after moving address-book UI to onShowAddressBook(). Consider removing these parameters (and updating call sites) to keep the composable API minimal and avoid unused-parameter lint warnings.

Copilot uses AI. Check for mistakes.
Comment on lines +491 to +494
onShowAddressBook = {
val chainId = token?.chainId ?: web3Token?.chainId ?: return@TransferDestinationInputPage
AddressSearchBottomSheetDialogFragment.newInstance(chainId).apply {
onAddressClick = { address ->
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

onShowAddressBook directly calls show(...) on a new AddressSearchBottomSheetDialogFragment instance. Since this callback can be triggered both from a user tap and from LaunchedEffect(addressShown) in the composable, it’s possible to attempt to show the dialog multiple times (or after state is saved), leading to overlapping dialogs or IllegalStateException. Consider guarding with parentFragmentManager.findFragmentByTag(TAG) == null and/or checking !parentFragmentManager.isStateSaved before showing.

Copilot uses AI. Check for mistakes.
Comment on lines +46 to +48
private val mode by lazy { requireArguments().getString(ARGS_MODE).orEmpty() }
private val selectedType by lazy { AlertType.values().first { it.value == requireArguments().getString(ARGS_SELECTED_TYPE) } }
private val selectedFrequency by lazy { AlertFrequency.values().first { it.value == requireArguments().getString(ARGS_SELECTED_FREQUENCY) } }
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mode is read with orEmpty() and anything other than MODE_TYPE falls into the frequency branch. If the fragment is ever created with missing/invalid args (e.g., ARGS_MODE absent, or an unknown value), this will attempt to read ARGS_SELECTED_FREQUENCY and first { ... } will throw, crashing the app. Consider validating mode/args (use firstOrNull, provide a safe default, or dismiss early) instead of assuming the arguments are always present and correct.

Suggested change
private val mode by lazy { requireArguments().getString(ARGS_MODE).orEmpty() }
private val selectedType by lazy { AlertType.values().first { it.value == requireArguments().getString(ARGS_SELECTED_TYPE) } }
private val selectedFrequency by lazy { AlertFrequency.values().first { it.value == requireArguments().getString(ARGS_SELECTED_FREQUENCY) } }
private val mode by lazy {
when (val argMode = requireArguments().getString(ARGS_MODE)) {
MODE_TYPE, MODE_FREQUENCY -> argMode
else -> MODE_TYPE
}
}
private val selectedType by lazy {
val selected = requireArguments().getString(ARGS_SELECTED_TYPE)
AlertType.values().firstOrNull { it.value == selected } ?: AlertType.values().first()
}
private val selectedFrequency by lazy {
val selected = requireArguments().getString(ARGS_SELECTED_FREQUENCY)
AlertFrequency.values().firstOrNull { it.value == selected } ?: AlertFrequency.values().first()
}

Copilot uses AI. Check for mistakes.
Comment on lines +247 to +253
Column(
modifier = Modifier
.fillMaxWidth()
.height(
LocalConfiguration.current.screenHeightDp.dp - GetActionBarHeight() - GetStatusBarHeightValue()
)
) {
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WalletListScreen hard-codes its own height using LocalConfiguration.screenHeightDp - GetActionBarHeight() - GetStatusBarHeightValue(), but the hosting WalletListBottomSheetDialogFragment.getBottomSheetHeight() already constrains the sheet height (and resolveBottomSheetPeekHeight accounts for insets). This can double-subtract system bars/action bar and leave unused space or truncate content. Prefer Modifier.fillMaxSize() (or weight(1f) inside the sheet) and let the bottom sheet height/insets be handled by the fragment/base bottom sheet utilities.

Copilot uses AI. Check for mistakes.
Comment on lines +112 to 115
if (searchText.isNotEmpty() || isDeleteMode) {
Text(
text = stringResource(R.string.Cancel),
color = MixinAppTheme.colors.textBlue,
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "Cancel" action is now only shown when searchText is non-empty or isDeleteMode is true. In the default state (no search / no delete), users lose the obvious in-UI affordance to dismiss/close the bottom sheet (they can only use system back). Consider always showing a dismiss action (e.g., always render Cancel or show a close icon) and have it call onDismiss() when neither search nor delete mode is active.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants