mirror of
https://github.com/pawelorzech/Swoosh.git
synced 2026-03-31 20:15:41 +00:00
fix: code review findings - @Stable on FeedPost, derivedStateOf, deduplicate dismiss logic
This commit is contained in:
parent
f3ab562a6c
commit
c91ccd0afb
3 changed files with 17 additions and 23 deletions
|
|
@ -2,7 +2,7 @@ package com.swoosh.microblog.data.model
|
||||||
|
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Stable
|
||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
// --- API Response/Request Models ---
|
// --- API Response/Request Models ---
|
||||||
|
|
@ -107,7 +107,7 @@ enum class QueueStatus {
|
||||||
|
|
||||||
// --- UI Display Model ---
|
// --- UI Display Model ---
|
||||||
|
|
||||||
@Immutable
|
@Stable
|
||||||
data class FeedPost(
|
data class FeedPost(
|
||||||
val localId: Long? = null,
|
val localId: Long? = null,
|
||||||
val ghostId: String? = null,
|
val ghostId: String? = null,
|
||||||
|
|
@ -133,7 +133,7 @@ data class FeedPost(
|
||||||
val queueStatus: QueueStatus = QueueStatus.NONE
|
val queueStatus: QueueStatus = QueueStatus.NONE
|
||||||
)
|
)
|
||||||
|
|
||||||
@Immutable
|
@Stable
|
||||||
data class LinkPreview(
|
data class LinkPreview(
|
||||||
val url: String,
|
val url: String,
|
||||||
val title: String?,
|
val title: String?,
|
||||||
|
|
|
||||||
|
|
@ -68,8 +68,10 @@ fun ComposerScreen(
|
||||||
var showAltTextDialog by remember { mutableStateOf(false) }
|
var showAltTextDialog by remember { mutableStateOf(false) }
|
||||||
var linkInput by remember { mutableStateOf("") }
|
var linkInput by remember { mutableStateOf("") }
|
||||||
var showSendMenu by remember { mutableStateOf(false) }
|
var showSendMenu by remember { mutableStateOf(false) }
|
||||||
var fullScreenImageUri by remember { mutableStateOf<Uri?>(null) }
|
|
||||||
var fullScreenImageIndex by remember { mutableIntStateOf(-1) }
|
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
|
// Focus requester for auto-focus on text field
|
||||||
val focusRequester = remember { FocusRequester() }
|
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(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
|
|
@ -389,8 +393,7 @@ fun ComposerScreen(
|
||||||
imageUris = state.imageUris,
|
imageUris = state.imageUris,
|
||||||
onRemoveImage = viewModel::removeImage,
|
onRemoveImage = viewModel::removeImage,
|
||||||
onAddMore = { multiImagePickerLauncher.launch("image/*") },
|
onAddMore = { multiImagePickerLauncher.launch("image/*") },
|
||||||
onImageClick = { index, uri ->
|
onImageClick = { index, _ ->
|
||||||
fullScreenImageUri = uri
|
|
||||||
fullScreenImageIndex = index
|
fullScreenImageIndex = index
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -623,8 +626,7 @@ fun ComposerScreen(
|
||||||
if (fullScreenImageUri != null) {
|
if (fullScreenImageUri != null) {
|
||||||
Dialog(
|
Dialog(
|
||||||
onDismissRequest = {
|
onDismissRequest = {
|
||||||
fullScreenImageUri = null
|
dismissFullScreen()
|
||||||
fullScreenImageIndex = -1
|
|
||||||
},
|
},
|
||||||
properties = DialogProperties(usePlatformDefaultWidth = false)
|
properties = DialogProperties(usePlatformDefaultWidth = false)
|
||||||
) {
|
) {
|
||||||
|
|
@ -644,10 +646,7 @@ fun ComposerScreen(
|
||||||
|
|
||||||
// Close button at top-left
|
// Close button at top-left
|
||||||
IconButton(
|
IconButton(
|
||||||
onClick = {
|
onClick = { dismissFullScreen() },
|
||||||
fullScreenImageUri = null
|
|
||||||
fullScreenImageIndex = -1
|
|
||||||
},
|
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.align(Alignment.TopStart)
|
.align(Alignment.TopStart)
|
||||||
.padding(16.dp),
|
.padding(16.dp),
|
||||||
|
|
@ -665,8 +664,7 @@ fun ComposerScreen(
|
||||||
if (fullScreenImageIndex >= 0) {
|
if (fullScreenImageIndex >= 0) {
|
||||||
viewModel.removeImage(fullScreenImageIndex)
|
viewModel.removeImage(fullScreenImageIndex)
|
||||||
}
|
}
|
||||||
fullScreenImageUri = null
|
dismissFullScreen()
|
||||||
fullScreenImageIndex = -1
|
|
||||||
},
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.align(Alignment.BottomCenter)
|
.align(Alignment.BottomCenter)
|
||||||
|
|
@ -778,22 +776,19 @@ fun ScheduleDateTimePicker(
|
||||||
onConfirm: (LocalDateTime) -> Unit,
|
onConfirm: (LocalDateTime) -> Unit,
|
||||||
onDismiss: () -> Unit
|
onDismiss: () -> Unit
|
||||||
) {
|
) {
|
||||||
|
val today = remember { java.time.LocalDate.now() }
|
||||||
val todayMillis = remember {
|
val todayMillis = remember {
|
||||||
java.time.LocalDate.now()
|
today.atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli()
|
||||||
.atStartOfDay(ZoneId.systemDefault())
|
|
||||||
.toInstant()
|
|
||||||
.toEpochMilli()
|
|
||||||
}
|
}
|
||||||
|
val currentYear = remember { today.year }
|
||||||
|
|
||||||
val datePickerState = rememberDatePickerState(
|
val datePickerState = rememberDatePickerState(
|
||||||
selectableDates = object : SelectableDates {
|
selectableDates = object : SelectableDates {
|
||||||
override fun isSelectableDate(utcTimeMillis: Long): Boolean {
|
override fun isSelectableDate(utcTimeMillis: Long): Boolean {
|
||||||
// Allow today and future dates only
|
|
||||||
return utcTimeMillis >= todayMillis
|
return utcTimeMillis >= todayMillis
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isSelectableYear(year: Int): Boolean {
|
override fun isSelectableYear(year: Int): Boolean {
|
||||||
return year >= java.time.LocalDate.now().year
|
return year >= currentYear
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import androidx.navigation.NavDestination.Companion.hierarchy
|
|
||||||
import androidx.navigation.NavGraph.Companion.findStartDestination
|
import androidx.navigation.NavGraph.Companion.findStartDestination
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue