Repository: android/compose-samples
File: JetNews/app/src/main/java/com/example/jetnews/ui/interests/InterestsScreen.kt (Kotlin)

Code before:
            Tab(
                selected = selectedTabIndex == index,
                onClick = { updateSection(tabContent.section) },
                modifier = Modifier.heightIn(min = 48.dp)
            ) {
                Text(
                    text = stringResource(id = tabContent.section.titleResId),
                    color = colorText,
                    style = MaterialTheme.typography.subtitle2,
                    modifier = Modifier.paddingFromBaseline(top = 20.dp)
                )
            }
        }
    }
}

/**
 * Return state for interest sections grouped given the number of columns that fill the screen.
 * Sections are distributed to balance the number of items on each column.
 */
@Composable
private fun sectionsGroupedInColumnsAsState(
    sections: List<InterestSection>,
    columns: Int,
    defaultDispatcher: CoroutineDispatcher = Dispatchers.Default
): State<Array<MutableList<InterestSection>>> = produceState(
    initialValue = arrayOf(),
    keys = arrayOf(sections, columns)
) {
    withContext(defaultDispatcher) { // Move the execution of this logic to the background thread
        val sectionsInColumns = Array<MutableList<InterestSection>>(columns) { mutableListOf() }
        // For each section, find the column with less elements and add it there
        sections.forEach { section ->
            val shortestColumnIndex = sectionsInColumns.getIndexShortestElement()
            sectionsInColumns[shortestColumnIndex] += section
        }
        value = sectionsInColumns
    }
}

/**
 * Find the position of the array with less interests items in it
 */
private fun Array<MutableList<InterestSection>>.getIndexShortestElement(): Int {
    var (indexShortestColumn, elementsInShortestColumn) = Int.MAX_VALUE to Int.MAX_VALUE
    // For each column group, calculate the number of interests items and find the shortest
    this.forEachIndexed { index, columnsGroup ->
        val elements = columnsGroup.fold(0, { acc, section -> acc + section.interests.size })
        if (elements < elementsInShortestColumn) {
            indexShortestColumn = index
            elementsInShortestColumn = elements

Review comment (suggestion):
We should definitely avoid having a `State` with a mutable container inside of it like `MutableList` (even though we won't modify it elsewhere).

If that list were to change, Compose wouldn't be able to track it, which would cause some weirdness in the best case.

Code after:
 */
@Composable
private fun rememberItemMaxWidth(windowMaxWidth: Dp, columns: Int) =
    remember(windowMaxWidth, columns) {
        if (columns == 1) {
            // If the space available is small, fill the screen
            if (windowMaxWidth < 600.dp) Dp.Infinity else 600.dp
        } else {
            // Calculate the max width each item can take given the number of columns
            val itemMaxWidth = windowMaxWidth / columns
            // Limit the width of the item for them to not be too big given the available space
            if (windowMaxWidth < 800.dp) min(itemMaxWidth, 350.dp) else min(itemMaxWidth, 450.dp)
        }
    }

@Composable
fun rememberTabContent(
    interestsViewModel: InterestsViewModel
): List<TabContent> {
    // UiState of the InterestsScreen
    val uiState by interestsViewModel.uiState.collectAsState()

    // Describe the screen sections here since each section needs 2 states and 1 event.
    // Pass them to the stateless InterestsScreen using a tabContent.
    val topicsSection = TabContent(Sections.Topics) {
        val selectedTopics by interestsViewModel.selectedTopics.collectAsState()
        TopicList(
            topics = uiState.topics,
            selectedTopics = selectedTopics,
            onTopicSelect = { interestsViewModel.toggleTopicSelection(it) }
        )
    }

    val peopleSection = TabContent(Sections.People) {
        val selectedPeople by interestsViewModel.selectedPeople.collectAsState()
        PeopleList(
            people = uiState.people,
            selectedPeople = selectedPeople,
            onPersonSelect = { interestsViewModel.togglePersonSelected(it) }
        )
    }

    val publicationSection = TabContent(Sections.Publications) {
        val selectedPublications by interestsViewModel.selectedPublications.collectAsState()
        PublicationList(
            publications = uiState.publications,
            selectedPublications = selectedPublications,
            onPublicationSelect = { interestsViewModel.togglePublicationSelected(it) }
        )
    }