Loading packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt +18 −13 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.graphics.drawable.Animatable import android.service.quicksettings.Tile.STATE_ACTIVE import android.service.quicksettings.Tile.STATE_INACTIVE import android.text.TextUtils import android.util.Log import androidx.appcompat.content.res.AppCompatResources import androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi import androidx.compose.animation.graphics.res.animatedVectorResource Loading Loading @@ -81,7 +82,6 @@ import com.android.systemui.common.ui.compose.Icon import com.android.systemui.common.ui.compose.load import com.android.systemui.plugins.qs.QSTile import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel import com.android.systemui.qs.panels.ui.viewmodel.TileUiState import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel import com.android.systemui.qs.panels.ui.viewmodel.toUiState import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor Loading @@ -91,7 +91,6 @@ import com.android.systemui.res.R import java.util.function.Supplier import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.delay import kotlinx.coroutines.flow.mapLatest object TileType Loading @@ -103,29 +102,27 @@ fun Tile( showLabels: Boolean = false, modifier: Modifier, ) { val state: TileUiState by tile.state .mapLatest { it.toUiState() } .collectAsStateWithLifecycle(tile.currentState.toUiState()) val colors = TileDefaults.getColorForState(state.state) val state by tile.state.collectAsStateWithLifecycle(tile.currentState) val uiState = remember(state) { state.toUiState() } val colors = TileDefaults.getColorForState(uiState.state) TileContainer( colors = colors, showLabels = showLabels, label = state.label.toString(), label = uiState.label, iconOnly = iconOnly, clickEnabled = true, onClick = tile::onClick, onLongClick = tile::onLongClick, modifier = modifier, ) { val icon = getTileIcon(icon = state.icon) val icon = getTileIcon(icon = uiState.icon) if (iconOnly) { TileIcon(icon = icon, color = colors.icon, modifier = Modifier.align(Alignment.Center)) } else { LargeTileContent( label = state.label.toString(), secondaryLabel = state.secondaryLabel.toString(), label = uiState.label, secondaryLabel = uiState.secondaryLabel, icon = icon, colors = colors, clickEnabled = true, Loading Loading @@ -234,19 +231,26 @@ private fun LargeTileContent( Text( label, color = colors.label, modifier = Modifier.basicMarquee(), modifier = Modifier.tileMarquee(), ) if (!TextUtils.isEmpty(secondaryLabel)) { Text( secondaryLabel ?: "", color = colors.secondaryLabel, modifier = Modifier.basicMarquee(), modifier = Modifier.tileMarquee(), ) } } } } private fun Modifier.tileMarquee(): Modifier { return basicMarquee( iterations = 1, initialDelayMillis = 200, ) } @Composable fun TileLazyGrid( modifier: Modifier = Modifier, Loading Loading @@ -452,6 +456,7 @@ private fun TileIcon( animateToEnd: Boolean = false, modifier: Modifier = Modifier, ) { Log.d("Fabian", "Recomposing tile icon") val iconModifier = modifier.size(dimensionResource(id = R.dimen.qs_icon_size)) val context = LocalContext.current val loadedDrawable = Loading packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModel.kt +18 −8 Original line number Diff line number Diff line Loading @@ -26,8 +26,8 @@ import com.android.systemui.qs.pipeline.shared.TileSpec import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.mapLatest Loading @@ -54,14 +54,24 @@ constructor( quickQuickSettingsRowInteractor.defaultRows ) val tileViewModels: Flow<List<SizedTile<TileViewModel>>> = columns.flatMapLatest { columns -> val tileViewModels: StateFlow<List<SizedTile<TileViewModel>>> = columns .flatMapLatest { columns -> tilesInteractor.currentTiles.combine(rows, ::Pair).mapLatest { (tiles, rows) -> tiles .map { SizedTile(TileViewModel(it.tile, it.spec), it.spec.width) } .let { splitInRowsSequence(it, columns).take(rows).toList().flatten() } } } .stateIn( applicationScope, SharingStarted.WhileSubscribed(), tilesInteractor.currentTiles.value .map { SizedTile(TileViewModel(it.tile, it.spec), it.spec.width) } .let { splitInRowsSequence(it, columns.value).take(rows.value).toList().flatten() } ) private val TileSpec.width: Int get() = if (iconTilesViewModel.isIconTile(this)) 1 else 2 Loading packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiState.kt +6 −4 Original line number Diff line number Diff line Loading @@ -16,20 +16,22 @@ package com.android.systemui.qs.panels.ui.viewmodel import androidx.compose.runtime.Immutable import com.android.systemui.plugins.qs.QSTile import java.util.function.Supplier @Immutable data class TileUiState( val label: CharSequence, val secondaryLabel: CharSequence, val label: String, val secondaryLabel: String, val state: Int, val icon: Supplier<QSTile.Icon>, ) fun QSTile.State.toUiState(): TileUiState { return TileUiState( label ?: "", secondaryLabel ?: "", label?.toString() ?: "", secondaryLabel?.toString() ?: "", state, icon?.let { Supplier { icon } } ?: iconSupplier, ) Loading packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileViewModel.kt +2 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.qs.panels.ui.viewmodel import androidx.compose.runtime.Immutable import com.android.systemui.animation.Expandable import com.android.systemui.plugins.qs.QSTile import com.android.systemui.qs.pipeline.shared.TileSpec Loading @@ -25,6 +26,7 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.onStart @Immutable class TileViewModel(private val tile: QSTile, val spec: TileSpec) { val state: Flow<QSTile.State> = conflatedCallbackFlow { Loading Loading
packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt +18 −13 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.graphics.drawable.Animatable import android.service.quicksettings.Tile.STATE_ACTIVE import android.service.quicksettings.Tile.STATE_INACTIVE import android.text.TextUtils import android.util.Log import androidx.appcompat.content.res.AppCompatResources import androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi import androidx.compose.animation.graphics.res.animatedVectorResource Loading Loading @@ -81,7 +82,6 @@ import com.android.systemui.common.ui.compose.Icon import com.android.systemui.common.ui.compose.load import com.android.systemui.plugins.qs.QSTile import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel import com.android.systemui.qs.panels.ui.viewmodel.TileUiState import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel import com.android.systemui.qs.panels.ui.viewmodel.toUiState import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor Loading @@ -91,7 +91,6 @@ import com.android.systemui.res.R import java.util.function.Supplier import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.delay import kotlinx.coroutines.flow.mapLatest object TileType Loading @@ -103,29 +102,27 @@ fun Tile( showLabels: Boolean = false, modifier: Modifier, ) { val state: TileUiState by tile.state .mapLatest { it.toUiState() } .collectAsStateWithLifecycle(tile.currentState.toUiState()) val colors = TileDefaults.getColorForState(state.state) val state by tile.state.collectAsStateWithLifecycle(tile.currentState) val uiState = remember(state) { state.toUiState() } val colors = TileDefaults.getColorForState(uiState.state) TileContainer( colors = colors, showLabels = showLabels, label = state.label.toString(), label = uiState.label, iconOnly = iconOnly, clickEnabled = true, onClick = tile::onClick, onLongClick = tile::onLongClick, modifier = modifier, ) { val icon = getTileIcon(icon = state.icon) val icon = getTileIcon(icon = uiState.icon) if (iconOnly) { TileIcon(icon = icon, color = colors.icon, modifier = Modifier.align(Alignment.Center)) } else { LargeTileContent( label = state.label.toString(), secondaryLabel = state.secondaryLabel.toString(), label = uiState.label, secondaryLabel = uiState.secondaryLabel, icon = icon, colors = colors, clickEnabled = true, Loading Loading @@ -234,19 +231,26 @@ private fun LargeTileContent( Text( label, color = colors.label, modifier = Modifier.basicMarquee(), modifier = Modifier.tileMarquee(), ) if (!TextUtils.isEmpty(secondaryLabel)) { Text( secondaryLabel ?: "", color = colors.secondaryLabel, modifier = Modifier.basicMarquee(), modifier = Modifier.tileMarquee(), ) } } } } private fun Modifier.tileMarquee(): Modifier { return basicMarquee( iterations = 1, initialDelayMillis = 200, ) } @Composable fun TileLazyGrid( modifier: Modifier = Modifier, Loading Loading @@ -452,6 +456,7 @@ private fun TileIcon( animateToEnd: Boolean = false, modifier: Modifier = Modifier, ) { Log.d("Fabian", "Recomposing tile icon") val iconModifier = modifier.size(dimensionResource(id = R.dimen.qs_icon_size)) val context = LocalContext.current val loadedDrawable = Loading
packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModel.kt +18 −8 Original line number Diff line number Diff line Loading @@ -26,8 +26,8 @@ import com.android.systemui.qs.pipeline.shared.TileSpec import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.mapLatest Loading @@ -54,14 +54,24 @@ constructor( quickQuickSettingsRowInteractor.defaultRows ) val tileViewModels: Flow<List<SizedTile<TileViewModel>>> = columns.flatMapLatest { columns -> val tileViewModels: StateFlow<List<SizedTile<TileViewModel>>> = columns .flatMapLatest { columns -> tilesInteractor.currentTiles.combine(rows, ::Pair).mapLatest { (tiles, rows) -> tiles .map { SizedTile(TileViewModel(it.tile, it.spec), it.spec.width) } .let { splitInRowsSequence(it, columns).take(rows).toList().flatten() } } } .stateIn( applicationScope, SharingStarted.WhileSubscribed(), tilesInteractor.currentTiles.value .map { SizedTile(TileViewModel(it.tile, it.spec), it.spec.width) } .let { splitInRowsSequence(it, columns.value).take(rows.value).toList().flatten() } ) private val TileSpec.width: Int get() = if (iconTilesViewModel.isIconTile(this)) 1 else 2 Loading
packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiState.kt +6 −4 Original line number Diff line number Diff line Loading @@ -16,20 +16,22 @@ package com.android.systemui.qs.panels.ui.viewmodel import androidx.compose.runtime.Immutable import com.android.systemui.plugins.qs.QSTile import java.util.function.Supplier @Immutable data class TileUiState( val label: CharSequence, val secondaryLabel: CharSequence, val label: String, val secondaryLabel: String, val state: Int, val icon: Supplier<QSTile.Icon>, ) fun QSTile.State.toUiState(): TileUiState { return TileUiState( label ?: "", secondaryLabel ?: "", label?.toString() ?: "", secondaryLabel?.toString() ?: "", state, icon?.let { Supplier { icon } } ?: iconSupplier, ) Loading
packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileViewModel.kt +2 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.qs.panels.ui.viewmodel import androidx.compose.runtime.Immutable import com.android.systemui.animation.Expandable import com.android.systemui.plugins.qs.QSTile import com.android.systemui.qs.pipeline.shared.TileSpec Loading @@ -25,6 +26,7 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.onStart @Immutable class TileViewModel(private val tile: QSTile, val spec: TileSpec) { val state: Flow<QSTile.State> = conflatedCallbackFlow { Loading