fun SpeakersScreen()

in shared/src/commonMain/kotlin/org/jetbrains/kotlinconf/screens/SpeakersScreen.kt [56:186]


fun SpeakersScreen(
    onSpeaker: (SpeakerId) -> Unit,
    viewModel: SpeakersViewModel = koinViewModel(),
) {
    var searchState by rememberSaveable { mutableStateOf(MainHeaderContainerState.Title) }
    var searchText by rememberSaveable { mutableStateOf("") }

    val uiState = viewModel.speakers.collectAsStateWithLifecycle().value

    val gridState = rememberLazyGridState()

    LaunchedEffect(searchState, searchText) {
        if (searchState == MainHeaderContainerState.Search) {
            if (gridState.firstVisibleItemIndex > 1) {
                gridState.scrollToItem(0)
            } else {
                gridState.animateScrollToItem(0)
            }
        }
        viewModel.setSearchText(searchText)
    }

    Column(Modifier.fillMaxSize().background(color = KotlinConfTheme.colors.mainBackground)) {
        MainHeaderContainer(
            state = searchState,
            titleContent = {
                MainHeaderTitleBar(
                    title = stringResource(Res.string.speakers_title),
                    endContent = {
                        TopMenuButton(
                            icon = UiRes.drawable.search_24,
                            onClick = { searchState = MainHeaderContainerState.Search },
                            contentDescription = stringResource(UiRes.string.main_header_search_hint)
                        )
                    }
                )
            },
            searchContent = {
                NavigationBackHandler(
                    state = rememberNavigationEventState(NavigationEventInfo.None),
                    isBackEnabled = true,
                    onBackCompleted = {
                        searchState = MainHeaderContainerState.Title
                        searchText = ""
                    },
                )

                MainHeaderSearchBar(
                    searchValue = searchText,
                    onSearchValueChange = { searchText = it },
                    onClose = {
                        searchState = MainHeaderContainerState.Title
                        searchText = ""
                    },
                    onClear = { searchText = "" },
                )
            }
        )

        Divider(1.dp, KotlinConfTheme.colors.strokePale)

        AnimatedContent(
            uiState,
            modifier = Modifier.fillMaxSize().clipToBounds(),
            contentKey = {
                when (uiState) {
                    is SpeakersUiState.Content -> 1
                    SpeakersUiState.Error, SpeakersUiState.Loading -> 2
                }
            },
            transitionSpec = { FadingAnimationSpec }
        ) { targetState ->
            when (targetState) {
                is SpeakersUiState.Content -> {
                    ScrollToTopHandler(gridState)
                    HideKeyboardOnDragHandler(gridState)

                    val speakers = targetState.speakers
                    LazyVerticalGrid(
                        state = gridState,
                        columns = GridCells.Adaptive(300.dp),
                        modifier = Modifier.fillMaxSize(),
                    ) {
                        if (searchState == MainHeaderContainerState.Search) {
                            item(span = { GridItemSpan(maxLineSpan) }, key = "number-of-speakers") {
                                Text(
                                    text = pluralStringResource(
                                        Res.plurals.speakers_number_of_results,
                                        speakers.size,
                                        speakers.size
                                    ),
                                    color = KotlinConfTheme.colors.secondaryText,
                                    style = KotlinConfTheme.typography.text2,
                                    modifier = Modifier
                                        .animateItem()
                                        .padding(horizontal = 12.dp)
                                        .padding(top = 12.dp, bottom = 4.dp)
                                        .semantics { liveRegion = LiveRegionMode.Polite }
                                )
                            }
                        }
                        items(speakers, key = { it.speaker.id.id }) { speakerWithHighlights ->
                            val speaker = speakerWithHighlights.speaker
                            SpeakerCard(
                                name = speaker.name,
                                nameHighlights = speakerWithHighlights.nameHighlights,
                                title = speaker.position,
                                titleHighlights = speakerWithHighlights.titleHighlights,
                                photoUrl = speaker.photoUrl,
                                modifier = Modifier
                                    .animateItem()
                                    .fillMaxWidth()
                                    .padding(12.dp),
                                onClick = { onSpeaker(speaker.id) },
                            )
                        }
                    }
                }

                SpeakersUiState.Error, SpeakersUiState.Loading -> {
                    NormalErrorWithLoading(
                        message = stringResource(Res.string.speakers_error_no_data),
                        isLoading = uiState is SpeakersUiState.Loading,
                        modifier = Modifier.fillMaxSize(),
                        onRetry = { viewModel.refresh() },
                    )
                }
            }
        }
    }
}