fix: code review findings - @Stable on FeedPost, derivedStateOf, deduplicate dismiss logic

This commit is contained in:
Paweł Orzech 2026-03-19 14:54:30 +01:00
parent f3ab562a6c
commit c91ccd0afb
No known key found for this signature in database
3 changed files with 17 additions and 23 deletions

View file

@ -2,7 +2,7 @@ package com.swoosh.microblog.data.model
import androidx.room.Entity
import androidx.room.PrimaryKey
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.Stable
import com.google.gson.annotations.SerializedName
// --- API Response/Request Models ---
@ -107,7 +107,7 @@ enum class QueueStatus {
// --- UI Display Model ---
@Immutable
@Stable
data class FeedPost(
val localId: Long? = null,
val ghostId: String? = null,
@ -133,7 +133,7 @@ data class FeedPost(
val queueStatus: QueueStatus = QueueStatus.NONE
)
@Immutable
@Stable
data class LinkPreview(
val url: String,
val title: String?,

View file

@ -68,8 +68,10 @@ fun ComposerScreen(
var showAltTextDialog by remember { mutableStateOf(false) }
var linkInput by remember { mutableStateOf("") }
var showSendMenu by remember { mutableStateOf(false) }
var fullScreenImageUri by remember { mutableStateOf<Uri?>(null) }
var fullScreenImageIndex by remember { mutableIntStateOf(-1) }
val fullScreenImageUri = if (fullScreenImageIndex >= 0 && fullScreenImageIndex < state.imageUris.size)
state.imageUris[fullScreenImageIndex] else null
val dismissFullScreen = { fullScreenImageIndex = -1 }
// Focus requester for auto-focus on text field
val focusRequester = remember { FocusRequester() }
@ -103,7 +105,9 @@ fun ComposerScreen(
}
}
val canSubmit = !state.isSubmitting && (state.text.isNotBlank() || state.imageUris.isNotEmpty())
val canSubmit by remember {
derivedStateOf { !state.isSubmitting && (state.text.isNotBlank() || state.imageUris.isNotEmpty()) }
}
Scaffold(
topBar = {
@ -389,8 +393,7 @@ fun ComposerScreen(
imageUris = state.imageUris,
onRemoveImage = viewModel::removeImage,
onAddMore = { multiImagePickerLauncher.launch("image/*") },
onImageClick = { index, uri ->
fullScreenImageUri = uri
onImageClick = { index, _ ->
fullScreenImageIndex = index
}
)
@ -623,8 +626,7 @@ fun ComposerScreen(
if (fullScreenImageUri != null) {
Dialog(
onDismissRequest = {
fullScreenImageUri = null
fullScreenImageIndex = -1
dismissFullScreen()
},
properties = DialogProperties(usePlatformDefaultWidth = false)
) {
@ -644,10 +646,7 @@ fun ComposerScreen(
// Close button at top-left
IconButton(
onClick = {
fullScreenImageUri = null
fullScreenImageIndex = -1
},
onClick = { dismissFullScreen() },
modifier = Modifier
.align(Alignment.TopStart)
.padding(16.dp),
@ -665,8 +664,7 @@ fun ComposerScreen(
if (fullScreenImageIndex >= 0) {
viewModel.removeImage(fullScreenImageIndex)
}
fullScreenImageUri = null
fullScreenImageIndex = -1
dismissFullScreen()
},
modifier = Modifier
.align(Alignment.BottomCenter)
@ -778,22 +776,19 @@ fun ScheduleDateTimePicker(
onConfirm: (LocalDateTime) -> Unit,
onDismiss: () -> Unit
) {
val today = remember { java.time.LocalDate.now() }
val todayMillis = remember {
java.time.LocalDate.now()
.atStartOfDay(ZoneId.systemDefault())
.toInstant()
.toEpochMilli()
today.atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli()
}
val currentYear = remember { today.year }
val datePickerState = rememberDatePickerState(
selectableDates = object : SelectableDates {
override fun isSelectableDate(utcTimeMillis: Long): Boolean {
// Allow today and future dates only
return utcTimeMillis >= todayMillis
}
override fun isSelectableYear(year: Int): Boolean {
return year >= java.time.LocalDate.now().year
return year >= currentYear
}
}
)

View file

@ -19,7 +19,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.font.FontWeight
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost