Skip to content

Commit 839f3b8

Browse files
authored
perf: migrate LibreFitScaffold action lists to ImmutableList and stabilize action callbacks (#79)
* perf: migrate `LibreFitScaffold` action lists to `ImmutableList` and stabilize action callbacks * refactor: update `remember` key for `interactionSources`
1 parent decdf08 commit 839f3b8

13 files changed

Lines changed: 69 additions & 63 deletions

File tree

app/src/main/java/org/librefit/ui/components/LibreFitScaffold.kt

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ import androidx.compose.material3.Scaffold
2828
import androidx.compose.material3.Text
2929
import androidx.compose.material3.TopAppBar
3030
import androidx.compose.runtime.Composable
31+
import androidx.compose.runtime.getValue
3132
import androidx.compose.runtime.remember
33+
import androidx.compose.runtime.rememberUpdatedState
3234
import androidx.compose.ui.Modifier
3335
import androidx.compose.ui.graphics.painter.Painter
3436
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
@@ -37,6 +39,8 @@ import androidx.compose.ui.res.painterResource
3739
import androidx.compose.ui.res.stringResource
3840
import androidx.compose.ui.text.AnnotatedString
3941
import androidx.compose.ui.text.style.TextOverflow
42+
import kotlinx.collections.immutable.ImmutableList
43+
import kotlinx.collections.immutable.persistentListOf
4044
import org.librefit.R
4145

4246

@@ -72,11 +76,11 @@ import org.librefit.R
7276
fun LibreFitScaffold(
7377
title: AnnotatedString? = null,
7478
navigateBack: (() -> Unit)? = null,
75-
actions: List<() -> Unit> = listOf(),
76-
actionsEnabled: List<Boolean> = listOf(),
77-
actionsDescription: List<String?> = listOf(),
78-
actionsIcons: List<Painter> = listOf(),
79-
actionsElevated: List<Boolean> = listOf(),
79+
actions: ImmutableList<() -> Unit> = persistentListOf(),
80+
actionsEnabled: ImmutableList<Boolean> = persistentListOf(),
81+
actionsDescription: ImmutableList<String?> = persistentListOf(),
82+
actionsIcons: ImmutableList<Painter> = persistentListOf(),
83+
actionsElevated: ImmutableList<Boolean> = persistentListOf(),
8084
fabAction: (() -> Unit)? = null,
8185
fabIcon: Painter? = null,
8286
fabDescription: String? = null,
@@ -130,14 +134,15 @@ fun LibreFitScaffold(
130134

131135
customItem(
132136
buttonGroupContent = {
137+
val currentAction by rememberUpdatedState(action)
133138
if (icon != null) {
134139
IconButton(
135140
modifier = interactionSources.getOrNull(index)
136141
?.let { Modifier.animateWidth(it) }
137142
?: Modifier,
138143
onClick = {
139144
haptic.performHapticFeedback(HapticFeedbackType.ContextClick)
140-
action()
145+
currentAction()
141146
},
142147
shapes = IconButtonDefaults.shapes(),
143148
interactionSource = interactionSources.getOrNull(
@@ -161,7 +166,7 @@ fun LibreFitScaffold(
161166
?: Modifier,
162167
onClick = {
163168
haptic.performHapticFeedback(HapticFeedbackType.ContextClick)
164-
action()
169+
currentAction()
165170
},
166171
shapes = ButtonDefaults.shapes(),
167172
interactionSource = interactionSources.getOrNull(

app/src/main/java/org/librefit/ui/screens/MainScreen.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import androidx.compose.ui.res.painterResource
2727
import androidx.compose.ui.res.stringResource
2828
import androidx.compose.ui.text.buildAnnotatedString
2929
import androidx.navigation.NavHostController
30+
import kotlinx.collections.immutable.persistentListOf
3031
import kotlinx.coroutines.launch
3132
import org.librefit.R
3233
import org.librefit.enums.pages.MainScreenPages
@@ -72,17 +73,17 @@ fun SharedTransitionScope.MainScreen(
7273
title = buildAnnotatedString {
7374
GetAppNameInAnnotatedBuilder(MaterialTheme.typography.titleLargeEmphasized)
7475
},
75-
actions = listOf(
76+
actions = persistentListOf(
7677
{ navController.navigate(Route.SupportScreen()) { launchSingleTop = true } },
7778
{ navController.navigate(Route.AboutScreen) { launchSingleTop = true } },
7879
{ navController.navigate(Route.SettingsScreen) { launchSingleTop = true } }
7980
),
80-
actionsIcons = listOf(
81+
actionsIcons = persistentListOf(
8182
painterResource(R.drawable.ic_favorite),
8283
painterResource(R.drawable.ic_info),
8384
painterResource(R.drawable.ic_settings)
8485
),
85-
actionsElevated = listOf(true, false, false),
86+
actionsElevated = persistentListOf(true, false, false),
8687
fabAction = if (pagerState.currentPage == MainScreenPages.HOME.ordinal) fabAction else null,
8788
fabIcon = painterResource(R.drawable.ic_add),
8889
fabDescription = stringResource(R.string.create_routine),

app/src/main/java/org/librefit/ui/screens/about/TutorialScreen.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import androidx.compose.ui.unit.dp
4949
import androidx.navigation.NavHostController
5050
import androidx.navigation.compose.rememberNavController
5151
import coil3.compose.AsyncImage
52+
import kotlinx.collections.immutable.persistentListOf
5253
import kotlinx.coroutines.launch
5354
import org.librefit.R
5455
import org.librefit.enums.pages.TutorialContent
@@ -91,13 +92,13 @@ fun TutorialScreen(
9192
LibreFitScaffold(
9293
title = AnnotatedString(stringResource(R.string.tutorial)),
9394
navigateBack = navigateBack,
94-
actions = if (fromWelcomeScreen) listOf {
95+
actions = if (fromWelcomeScreen) persistentListOf({
9596
navController.navigate(Route.MainScreen) {
9697
launchSingleTop = true
9798
popUpTo(Route.TutorialScreen()) { inclusive = true }
9899
}
99-
} else emptyList(),
100-
actionsDescription = listOf(stringResource(R.string.done))
100+
}) else persistentListOf(),
101+
actionsDescription = persistentListOf(stringResource(R.string.done))
101102
) { innerPadding ->
102103
LibreFitLazyColumn(
103104
innerPadding = innerPadding,

app/src/main/java/org/librefit/ui/screens/beforeSaving/BeforeSavingScreen.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -205,15 +205,15 @@ fun SharedTransitionScope.BeforeSavingScreenContent(
205205
LibreFitScaffold(
206206
title = AnnotatedString(stringResource(R.string.overview)),
207207
navigateBack = navController::navigateUp,
208-
actions = listOf {
208+
actions = persistentListOf({
209209
saveExercisesWithWorkout()
210210
navController.navigate(Route.SuccessScreen(SuccessMessage.WORKOUT_SAVED)) {
211211
launchSingleTop = true
212212
popUpTo(Route.MainScreen) { inclusive = false }
213213
}
214-
},
215-
actionsDescription = listOf(stringResource(R.string.save)),
216-
actionsEnabled = listOf(!isTitleEmpty && !isTitleTooLong)
214+
}),
215+
actionsDescription = persistentListOf(stringResource(R.string.save)),
216+
actionsEnabled = persistentListOf(!isTitleEmpty && !isTitleTooLong)
217217
) { innerPadding ->
218218
LibreFitLazyColumn(innerPadding) {
219219
item {

app/src/main/java/org/librefit/ui/screens/editExercise/EditExerciseScreen.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
5757
import androidx.lifecycle.compose.collectAsStateWithLifecycle
5858
import androidx.navigation.NavHostController
5959
import coil3.compose.AsyncImage
60+
import kotlinx.collections.immutable.persistentListOf
6061
import org.librefit.R
6162
import org.librefit.db.entity.ExerciseDC
6263
import org.librefit.enums.SuccessMessage
@@ -176,12 +177,12 @@ private fun SharedTransitionScope.EditExerciseScreenContent(
176177
navigateBack = {
177178
showConfirmExitDialog.value = true
178179
},
179-
actions = listOf {
180+
actions = persistentListOf({
180181
saveExercise()
181182
navigateToSuccessScreen()
182-
},
183-
actionsEnabled = listOf(name.isNotEmpty()),
184-
actionsDescription = listOf(stringResource(R.string.save)),
183+
}),
184+
actionsEnabled = persistentListOf(name.isNotEmpty()),
185+
actionsDescription = persistentListOf(stringResource(R.string.save)),
185186
) { innerPadding ->
186187
LibreFitLazyColumn(
187188
innerPadding = innerPadding,

app/src/main/java/org/librefit/ui/screens/editWorkout/EditWorkoutScreen.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ private fun SharedTransitionScope.EditWorkoutScreenContent(
234234
showConfirmDialog = true
235235
}
236236
},
237-
actions = listOf {
237+
actions = persistentListOf({
238238
if (typeOfEdit == false) {
239239
navController.navigate(
240240
Route.BeforeSavingScreen(
@@ -248,12 +248,12 @@ private fun SharedTransitionScope.EditWorkoutScreenContent(
248248
popUpTo(Route.MainScreen) { inclusive = false }
249249
}
250250
}
251-
},
252-
actionsDescription = listOf(
251+
}),
252+
actionsDescription = persistentListOf(
253253
if (typeOfEdit == false) stringResource(R.string.done)
254254
else stringResource(R.string.save)
255255
),
256-
actionsEnabled = listOf(!isTitleEmpty && !isTitleTooLong && if (typeOfEdit != false) true else exercisesWithSets.isNotEmpty()),
256+
actionsEnabled = persistentListOf(!isTitleEmpty && !isTitleTooLong && if (typeOfEdit != false) true else exercisesWithSets.isNotEmpty()),
257257
fabIcon = painterResource(R.drawable.ic_add),
258258
fabAction = {
259259
navController.navigate(Route.ExercisesScreen(addExercises = true)) {

app/src/main/java/org/librefit/ui/screens/exercises/ExercisesScreen.kt

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
5757
import androidx.lifecycle.compose.collectAsStateWithLifecycle
5858
import androidx.navigation.NavHostController
5959
import coil3.compose.AsyncImage
60+
import kotlinx.collections.immutable.ImmutableList
6061
import kotlinx.collections.immutable.persistentListOf
6162
import org.librefit.R
6263
import org.librefit.db.entity.ExerciseDC
@@ -120,10 +121,10 @@ fun SharedTransitionScope.ExercisesScreen(
120121
}
121122

122123
val actions = remember {
123-
if (addExercises) listOf {
124+
if (addExercises) persistentListOf({
124125
navController.navigateUp()
125126
sharedViewModel.setSelectedExercisesList(selectedExercisesList.map { it.toEntity() })
126-
} else listOf()
127+
}) else persistentListOf()
127128
}
128129

129130

@@ -163,7 +164,7 @@ private fun SharedTransitionScope.ExercisesScreenContent(
163164
toggleSelectedExercise: (String) -> Unit,
164165
updateQuery: (String) -> Unit,
165166
updateFilter: (FilterValue) -> Unit,
166-
actions: List<() -> Unit>,
167+
actions: ImmutableList<() -> Unit>,
167168
navigateBack: () -> Unit,
168169
navigateToInfoExercise: (ExerciseDC) -> Unit,
169170
navigateToEditExercise: () -> Unit
@@ -177,8 +178,8 @@ private fun SharedTransitionScope.ExercisesScreenContent(
177178
title = AnnotatedString(stringResource(id = R.string.exercises)),
178179
navigateBack = navigateBack,
179180
actions = actions,
180-
actionsDescription = listOf(stringResource(R.string.add)),
181-
actionsEnabled = listOf(selectedExercisesIdList.isNotEmpty()),
181+
actionsDescription = persistentListOf(stringResource(R.string.add)),
182+
actionsEnabled = persistentListOf(selectedExercisesIdList.isNotEmpty()),
182183
fabAction = navigateToEditExercise,
183184
fabText = stringResource(R.string.create_exercise),
184185
fabIcon = painterResource(R.drawable.ic_add),
@@ -418,7 +419,7 @@ private fun ExercisesScreenPreview() {
418419
toggleSelectedExercise = {},
419420
updateQuery = { query = it },
420421
updateFilter = { filterValue = it },
421-
actions = listOf {},
422+
actions = persistentListOf({}),
422423
navigateBack = {},
423424
navigateToInfoExercise = {},
424425
navigateToEditExercise = {}

app/src/main/java/org/librefit/ui/screens/home/HomeScreen.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ import androidx.navigation.compose.rememberNavController
6363
import com.google.accompanist.permissions.ExperimentalPermissionsApi
6464
import com.google.accompanist.permissions.isGranted
6565
import com.google.accompanist.permissions.rememberPermissionState
66+
import kotlinx.collections.immutable.persistentListOf
6667
import org.librefit.R
6768
import org.librefit.enums.InfoMode
6869
import org.librefit.enums.pages.MainScreenPages
@@ -385,13 +386,13 @@ fun HomeScreenPreview() {
385386
title = buildAnnotatedString {
386387
GetAppNameInAnnotatedBuilder(MaterialTheme.typography.titleLargeEmphasized)
387388
},
388-
actions = listOf({ }, { }, { }),
389-
actionsIcons = listOf(
389+
actions = persistentListOf({ }, { }, { }),
390+
actionsIcons = persistentListOf(
390391
painterResource(R.drawable.ic_favorite),
391392
painterResource(R.drawable.ic_info),
392393
painterResource(R.drawable.ic_settings)
393394
),
394-
actionsElevated = listOf(true, false, false),
395+
actionsElevated = persistentListOf(true, false, false),
395396
fabAction = {},
396397
fabIcon = painterResource(R.drawable.ic_add),
397398
fabText = stringResource(R.string.create_routine),

app/src/main/java/org/librefit/ui/screens/infoExercise/InfoExerciseScreen.kt

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ private fun SharedTransitionScope.InfoExerciseScreenContent(
191191
LibreFitScaffold(
192192
navigateBack = navController::navigateUp,
193193
actions = if (exerciseDC.isCustomExercise) {
194-
listOf(
194+
persistentListOf(
195195
{
196196
navController.navigate(
197197
Route.EditExerciseScreen(
@@ -207,14 +207,17 @@ private fun SharedTransitionScope.InfoExerciseScreenContent(
207207
}
208208
)
209209
} else {
210-
emptyList()
210+
persistentListOf()
211211
},
212212
actionsIcons = if (exerciseDC.isCustomExercise) {
213-
listOf(painterResource(R.drawable.ic_edit), painterResource(R.drawable.ic_delete))
213+
persistentListOf(
214+
painterResource(R.drawable.ic_edit),
215+
painterResource(R.drawable.ic_delete)
216+
)
214217
} else {
215-
emptyList()
218+
persistentListOf()
216219
},
217-
actionsElevated = listOf(false, false)
220+
actionsElevated = persistentListOf(false, false)
218221
) { innerPadding ->
219222
BoxWithConstraints(
220223
modifier = Modifier.padding(innerPadding)

app/src/main/java/org/librefit/ui/screens/infoWorkout/InfoWorkoutScreen.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ private fun SharedTransitionScope.InfoWorkoutScreenContent(
172172
LibreFitScaffold(
173173
title = AnnotatedString(stringResource(if (isRoutine) R.string.routine else R.string.workout)),
174174
navigateBack = navController::navigateUp,
175-
actions = listOf(
175+
actions = persistentListOf(
176176
{
177177
navController.navigate(Route.EditWorkoutScreen(workoutId = workout.id)) {
178178
launchSingleTop = true
@@ -182,11 +182,11 @@ private fun SharedTransitionScope.InfoWorkoutScreenContent(
182182
showConfirmDialog = true
183183
}
184184
),
185-
actionsIcons = listOf(
185+
actionsIcons = persistentListOf(
186186
painterResource(R.drawable.ic_edit),
187187
painterResource(R.drawable.ic_delete)
188188
),
189-
actionsElevated = listOf(false, false)
189+
actionsElevated = persistentListOf(false, false)
190190
) { innerPadding ->
191191
LibreFitLazyColumn(innerPadding) {
192192
item {

0 commit comments

Comments
 (0)