Thread
#compose
    z

    zoha131

    1 year ago
    is there any way to change two different state at the same time without recomposing?
    Adam Powell

    Adam Powell

    1 year ago
    withMutableSnapshot
    will let you commit several snapshot state changes atomically and compose will see it as a single change. In some cases it's redundant or overkill though, what's your use case?
    z

    zoha131

    1 year ago
    I am using
    ModalBottomSheetLayout
    and I have to show different
    BottomSheet
    based on user action. Now if i change the
    bottomSheetState
    first then I can’t get the updated other state inside the
    sheetBlock
    sealed class StudentEditSheet{
        object Email: StudentEditSheet()
        object Gender: StudentEditSheet()
        object Department: StudentEditSheet()
        object Level: StudentEditSheet()
        object Term: StudentEditSheet()
        object None: StudentEditSheet()
    }
    
    @ExperimentalComposeApi
    @OptIn(ExperimentalMaterialApi::class)
    @Composable
    fun StudentEditScreen(
        viewModel: StudentEditViewModel,
        onBackPress: (() -> Unit)?,
        onNavigateToHome: () -> Unit
    ) {
        val sheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
        var studentEditSheet by remember { mutableStateOf<StudentEditSheet>(StudentEditSheet.None) }
    
        ModalBottomSheetLayout(
            sheetState = sheetState,
            sheetContent = {
                when (studentEditSheet) {
                    StudentEditSheet.Gender -> {
                        ListBottomSheet(
                            title = stringResource(id = R.string.select_your_department),
                            icon = Icons.Outlined.DepartureBoard,
                            onClose = { studentEditSheet = StudentEditSheet.None },
                            list = (0..9).toList(),
                            onItemClick = { }
                        )
                    }
    
                    else -> {
                        Box(modifier = Modifier.size(100.dp))
                    }
                }
            }
        ) {
            StudentEditScreenContent(
                stateFlow = viewModel.state,
                onFullNameChange = viewModel::changeFullName,
                onDiuIdChange = viewModel::changeDiuId,
                selectGender = {
                    withMutableSnapshot {
                        sheetState.show()
                        studentEditSheet = StudentEditSheet.Gender
                    }
                },
                onEmailClick = { studentEditSheet = StudentEditSheet.Email },
                onPhoneChange = viewModel::changePhoneNumber,
                selectDepartment = { studentEditSheet = StudentEditSheet.Department },
                selectLevel = { studentEditSheet = StudentEditSheet.Level },
                selectTerm = { studentEditSheet = StudentEditSheet.Term },
                changeImage = {},
                saveStudentProfile = viewModel::saveProfile,
                onBackPress = onBackPress
            )
        }
    }
    I think I am doing it wrong….
    Adam Powell

    Adam Powell

    1 year ago
    I'd have to give it a closer look than I can spare tonight to see what exactly is amiss, but I doubt it has to do with snapshot atomicity. Compose user input events all dispatch on the android main thread and compose will coalesce updates no more often than every
    Choreographer
    frame synced to the device's vsync interval; if you make two changes in the same event handler it's basically as good as putting it inside a
    withMutableSnapshot
    block anyway
    (since
    Choreographer
    work also happens on the same thread as the event callbacks; they cannot run concurrently)
    z

    zoha131

    1 year ago
    i have also tried reorganizing the state changes.
    studentEditSheet = StudentEditSheet.Gender
    sheetState.show()
    but I have the same effect. It ignores the first tap.
    Adam Powell

    Adam Powell

    1 year ago
    hmm, can you file an issue on the bug tracker and we'll take a look after the holidays? If you have an isolated repro it seems worth looking into
    z

    zoha131

    1 year ago
    ok. I will file a but with an isolated repro.
    József Szilvási

    József Szilvási

    1 year ago
    @zoha131 can you please link the issue you filed? thanks
    z

    zoha131

    1 year ago
    i didn’t file any issue. I was unable to reproduce this in a fresh project. But somehow it is not working in my project.