-
Notifications
You must be signed in to change notification settings - Fork 26
migrate to m3e list item #1651
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
migrate to m3e list item #1651
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -38,12 +38,12 @@ import androidx.compose.runtime.Composable | |||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.runtime.CompositionLocalProvider | ||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.runtime.DisposableEffect | ||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.runtime.LaunchedEffect | ||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.runtime.derivedStateOf | ||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.runtime.getValue | ||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.runtime.mutableStateOf | ||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.runtime.remember | ||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.runtime.rememberCoroutineScope | ||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.runtime.rememberUpdatedState | ||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.runtime.retain.retain | ||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.Alignment | ||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.Modifier | ||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.draw.clip | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -114,32 +114,30 @@ internal fun HomeScreen(afterInit: () -> Unit) { | |||||||||||||||||||||||||||||||||||||||||
| val wideNavigationRailState = rememberWideNavigationRailState() | ||||||||||||||||||||||||||||||||||||||||||
| state.tabs | ||||||||||||||||||||||||||||||||||||||||||
| .onSuccess { tabs -> | ||||||||||||||||||||||||||||||||||||||||||
| val topLevelBackStack by producePresenter( | ||||||||||||||||||||||||||||||||||||||||||
| key = "home_top_level_back_stack_${tabs.all.first().key}", | ||||||||||||||||||||||||||||||||||||||||||
| useImmediateClock = true, | ||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||
| TopLevelBackStack<Route>( | ||||||||||||||||||||||||||||||||||||||||||
| getDirection(tabs.all.first()), | ||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| fun navigate(route: Route) { | ||||||||||||||||||||||||||||||||||||||||||
| topLevelBackStack.addTopLevel(route) | ||||||||||||||||||||||||||||||||||||||||||
| scope.launch { | ||||||||||||||||||||||||||||||||||||||||||
| wideNavigationRailState.collapse() | ||||||||||||||||||||||||||||||||||||||||||
| val topLevelBackStack = | ||||||||||||||||||||||||||||||||||||||||||
| retain( | ||||||||||||||||||||||||||||||||||||||||||
| "home_top_level_back_stack_${tabs.all.first().key}", | ||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||
| TopLevelBackStack( | ||||||||||||||||||||||||||||||||||||||||||
| getDirection(tabs.all.first()), | ||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| val currentRoute by remember { | ||||||||||||||||||||||||||||||||||||||||||
| derivedStateOf { | ||||||||||||||||||||||||||||||||||||||||||
| topLevelBackStack.topLevelKey | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| val accountType by remember { | ||||||||||||||||||||||||||||||||||||||||||
| derivedStateOf { | ||||||||||||||||||||||||||||||||||||||||||
| currentRoute.accountTypeOr(AccountType.Active) | ||||||||||||||||||||||||||||||||||||||||||
| val topLevelBackStackState by rememberUpdatedState(topLevelBackStack) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| val navigate = | ||||||||||||||||||||||||||||||||||||||||||
| remember(topLevelBackStack, wideNavigationRailState) { | ||||||||||||||||||||||||||||||||||||||||||
| { route: Route -> | ||||||||||||||||||||||||||||||||||||||||||
| topLevelBackStack.addTopLevel(route) | ||||||||||||||||||||||||||||||||||||||||||
| scope.launch { | ||||||||||||||||||||||||||||||||||||||||||
| wideNavigationRailState.collapse() | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| Unit | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+126
to
+135
|
||||||||||||||||||||||||||||||||||||||||||
| val topLevelBackStackState by rememberUpdatedState(topLevelBackStack) | |
| val navigate = | |
| remember(topLevelBackStack, wideNavigationRailState) { | |
| { route: Route -> | |
| topLevelBackStack.addTopLevel(route) | |
| scope.launch { | |
| wideNavigationRailState.collapse() | |
| } | |
| Unit | |
| val topLevelBackStackState = rememberUpdatedState(topLevelBackStack) | |
| val wideNavigationRailStateState = rememberUpdatedState(wideNavigationRailState) | |
| val navigate: (Route) -> Unit = | |
| remember { | |
| { route: Route -> | |
| topLevelBackStackState.value.addTopLevel(route) | |
| scope.launch { | |
| wideNavigationRailStateState.value.collapse() | |
| } |
Copilot
AI
Jan 5, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "by remember { derivedStateOf { ... } }" pattern has been replaced with direct property access, removing the derived state optimization. This means currentRoute and accountType will now be recalculated on every recomposition instead of only when topLevelBackStack.topLevelKey changes. This could lead to unnecessary recalculations and recompositions of dependent composables.
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -12,6 +12,7 @@ import androidx.compose.foundation.lazy.rememberLazyListState | |||||
| import androidx.compose.material3.ExperimentalMaterial3Api | ||||||
| import androidx.compose.material3.IconButton | ||||||
| import androidx.compose.material3.ListItem | ||||||
| import androidx.compose.material3.ListItemDefaults | ||||||
| import androidx.compose.material3.Switch | ||||||
| import androidx.compose.material3.Text | ||||||
| import androidx.compose.material3.TopAppBarDefaults | ||||||
|
|
@@ -51,6 +52,7 @@ import dev.dimension.flare.ui.screen.settings.EditTabDialog | |||||
| import dev.dimension.flare.ui.screen.settings.TabAddBottomSheet | ||||||
| import dev.dimension.flare.ui.screen.settings.TabCustomItem | ||||||
| import dev.dimension.flare.ui.theme.screenHorizontalPadding | ||||||
| import dev.dimension.flare.ui.theme.segmentedShapes2 | ||||||
| import kotlinx.collections.immutable.toImmutableList | ||||||
| import kotlinx.coroutines.CoroutineScope | ||||||
| import kotlinx.coroutines.flow.map | ||||||
|
|
@@ -129,7 +131,7 @@ internal fun TabSettingScreen( | |||||
| modifier = | ||||||
| Modifier | ||||||
| .padding(horizontal = screenHorizontalPadding), | ||||||
| verticalArrangement = Arrangement.spacedBy(2.dp), | ||||||
| verticalArrangement = Arrangement.spacedBy(ListItemDefaults.SegmentedGap), | ||||||
| ) { | ||||||
| state.enableMixedTimeline.onSuccess { enabled -> | ||||||
| if (state.currentTabs.size > 1) { | ||||||
|
|
@@ -166,6 +168,7 @@ internal fun TabSettingScreen( | |||||
| itemsIndexed(state.currentTabs, key = { _, item -> item.key }) { index, item -> | ||||||
| TabCustomItem( | ||||||
| item = item, | ||||||
| shapes = ListItemDefaults.segmentedShapes2(index, state.currentTabs.size), | ||||||
| deleteTab = { | ||||||
| if (it is TimelineTabItem) { | ||||||
| state.deleteTab(item) | ||||||
|
|
@@ -178,12 +181,6 @@ internal fun TabSettingScreen( | |||||
| }, | ||||||
| reorderableLazyColumnState = reorderableLazyColumnState, | ||||||
| canSwipeToDelete = state.canSwipeToDelete, | ||||||
| modifier = | ||||||
| Modifier | ||||||
| .listCard( | ||||||
| index = index, | ||||||
| totalCount = state.currentTabs.size, | ||||||
| ), | ||||||
| ) | ||||||
| } | ||||||
| } | ||||||
|
|
@@ -243,7 +240,7 @@ private fun presenter( | |||||
| object { | ||||||
| val currentTabs = cacheTabs | ||||||
| val allTabsState = allTabsState | ||||||
| val canSwipeToDelete = cacheTabs.size > 1 | ||||||
| val canSwipeToDelete = true | ||||||
|
||||||
| val canSwipeToDelete = true | |
| val enableSwipeToDelete = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using "retain" here instead of "producePresenter" changes the lifecycle management of the TopLevelBackStack. The "retain" function appears to bypass the presenter's clock and composition lifecycle, which could lead to stale state not being properly cleaned up when the composition is disposed. This needs verification that the retained object is properly released when no longer needed.