@@ -65,6 +65,9 @@ import androidx.compose.ui.text.input.ImeAction
6565import androidx.compose.ui.unit.dp
6666import androidx.lifecycle.compose.collectAsStateWithLifecycle
6767import androidx.navigation.NavController
68+ import androidx.navigationevent.NavigationEventInfo
69+ import androidx.navigationevent.compose.NavigationBackHandler
70+ import androidx.navigationevent.compose.rememberNavigationEventState
6871import coil3.compose.AsyncImage
6972import com.daniebeler.pfpixelix.di.injectViewModel
7073import com.daniebeler.pfpixelix.domain.model.MediaAttachment
@@ -81,10 +84,13 @@ import org.jetbrains.compose.resources.stringResource
8184import org.jetbrains.compose.resources.vectorResource
8285import pixelix.app.generated.resources.Res
8386import pixelix.app.generated.resources.alt_text
87+ import pixelix.app.generated.resources.are_you_sure
8488import pixelix.app.generated.resources.cancel
89+ import pixelix.app.generated.resources.cancel_post_edit
8590import pixelix.app.generated.resources.caption
8691import pixelix.app.generated.resources.content_warning_or_spoiler_text
8792import pixelix.app.generated.resources.delete
93+ import pixelix.app.generated.resources.discard
8894import pixelix.app.generated.resources.edit_post
8995import pixelix.app.generated.resources.location
9096import pixelix.app.generated.resources.save
@@ -100,6 +106,7 @@ fun EditPostComposable(
100106 viewModel : EditPostViewModel = injectViewModel("editPostViewModel") { editPostViewModel }
101107) {
102108 val scrollBehavior = TopAppBarDefaults .pinnedScrollBehavior()
109+ var isCancelAlertOpen by remember { mutableStateOf(false ) }
103110
104111 var showSaveAlert by remember {
105112 mutableStateOf(false )
@@ -113,18 +120,31 @@ fun EditPostComposable(
113120 }
114121 val suggestionsState by viewModel.hashtagMentionsSuggestionsManager.suggestionsState.collectAsStateWithLifecycle()
115122
116- Scaffold (contentWindowInsets = WindowInsets .systemBars.only(WindowInsetsSides .Top ),
123+ NavigationBackHandler (
124+ state = rememberNavigationEventState(NavigationEventInfo .None ),
125+ isBackEnabled = viewModel.isEdited,
126+ onBackCompleted = {
127+ isCancelAlertOpen = true
128+ })
129+
130+ Scaffold (
131+ contentWindowInsets = WindowInsets .systemBars.only(WindowInsetsSides .Top ),
117132 modifier = Modifier .nestedScroll(scrollBehavior.nestedScrollConnection),
118133 topBar = {
119- TopAppBar (scrollBehavior = scrollBehavior,
134+ TopAppBar (
135+ scrollBehavior = scrollBehavior,
120136 title = {
121137 Text (
122138 text = stringResource(Res .string.edit_post), fontWeight = FontWeight .Bold
123139 )
124140 },
125141 navigationIcon = {
126142 IconButton (onClick = {
127- navController.popBackStack()
143+ if (viewModel.isEdited) {
144+ isCancelAlertOpen = true
145+ } else {
146+ navController.popBackStack()
147+ }
128148 }) {
129149 Icon (
130150 imageVector = Icons .AutoMirrored .Filled .ArrowBack ,
@@ -134,10 +154,9 @@ fun EditPostComposable(
134154 },
135155 actions = {
136156 if (viewModel.editPostState.post != null ) {
137- val mediaAttachmentsEditIds = viewModel.mediaAttachmentsEdit.map { it.id }
138- val mediaAttachmentsBeforeIds =
139- viewModel.mediaAttachmentsBefore.map { it.id }
140- if ((viewModel.mediaDescriptionItems.any { it.changed } || viewModel.caption.text != viewModel.editPostState.post!! .content || viewModel.sensitive != viewModel.editPostState.post!! .sensitive || mediaAttachmentsBeforeIds != mediaAttachmentsEditIds || viewModel.editPostState.post!! .place != viewModel.location) && viewModel.caption.text.length <= (viewModel.instance?.configuration?.statusConfig?.maxCharacters ? : Int .MAX_VALUE )) {
157+ if (viewModel.isEdited && viewModel.caption.text.length <= (viewModel.instance?.configuration?.statusConfig?.maxCharacters
158+ ? : Int .MAX_VALUE )
159+ ) {
141160 if (viewModel.editPostState.isLoading) {
142161 Button (
143162 onClick = { }, modifier = Modifier .width(120 .dp)
@@ -176,7 +195,8 @@ fun EditPostComposable(
176195 .verticalScroll(state = rememberScrollState()),
177196 verticalArrangement = Arrangement .spacedBy(12 .dp)
178197 ) {
179- ImagesPagerEditPost (viewModel.mediaAttachmentsEdit,
198+ ImagesPagerEditPost (
199+ viewModel.mediaAttachmentsEdit,
180200 viewModel.mediaDescriptionItems,
181201 { mediaDescriptionIndex, altText ->
182202
@@ -190,97 +210,16 @@ fun EditPostComposable(
190210 { index -> viewModel.moveMediaAttachmentDown(index) },
191211 { index -> viewModel.deleteMedia(index) },
192212 )
193- /* viewModel.mediaAttachmentsEdit.forEachIndexed { index, mediaAttachment ->
194- Row(
195- Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically
196- ) {
197- Box(contentAlignment = Alignment.Center) {
198-
199- if (mediaAttachment.type == "image") {
200- AsyncImage(
201- model = mediaAttachment.url,
202- contentDescription = null,
203- modifier = Modifier.width(100.dp)
204- )
205- } else {
206- //todo KMP video
207- AsyncImage(
208- model = mediaAttachment.url,
209- contentDescription = "video thumbnail",
210- modifier = Modifier.width(100.dp)
211- )
212- }
213- }
214-
215- Spacer(Modifier.width(10.dp))
216-
217- val mediaDescriptionItem =
218- viewModel.mediaDescriptionItems.find { mediaDescriptionItem -> mediaDescriptionItem.imageId == mediaAttachment.id }
219- ?: EditPostViewModel.MediaDescriptionItem(
220- mediaAttachment.id, "", false
221- )
222- val indexOfDescriptionItem =
223- viewModel.mediaDescriptionItems.indexOf(mediaDescriptionItem)
224- TextField(
225- value = mediaDescriptionItem.description,
226- onValueChange = {
227- val oldMediaAttachment =
228- viewModel.editPostState.post!!.mediaAttachments.find { it.id == mediaDescriptionItem.imageId }
229- val changed = it != (oldMediaAttachment!!.description ?: "")
230- viewModel.mediaDescriptionItems[indexOfDescriptionItem] =
231- viewModel.mediaDescriptionItems[indexOfDescriptionItem].copy(
232- description = it, changed = changed
233- )
234- },
235- modifier = Modifier.weight(1f),
236- singleLine = false,
237- placeholder = { Text(stringResource(Res.string.content_warning_or_spoiler_text)) },
238- shape = RoundedCornerShape(16.dp),
239- colors = TextFieldDefaults.colors(
240- unfocusedIndicatorColor = Color.Transparent,
241- focusedIndicatorColor = Color.Transparent,
242- ),
243- keyboardOptions = KeyboardOptions(imeAction = ImeAction.Default),
244- keyboardActions = KeyboardActions(onDone = {
245- keyboardController?.hide()
246- focusManager.clearFocus()
247- })
248- )
249-
250- if (viewModel.mediaAttachmentsEdit.size > 1) {
251- Column {
252- IconButton(onClick = { viewModel.moveMediaAttachmentUp(index) }) {
253- Icon(
254- imageVector = Icons.Outlined.ArrowUpward,
255- contentDescription = "move Imageupwards"
256- )
257- }
258- IconButton(onClick = { viewModel.moveMediaAttachmentDown(index) }) {
259- Icon(
260- imageVector = Icons.Outlined.ArrowDownward,
261- contentDescription = "move Imageupwards"
262- )
263- }
264- }
265- IconButton(onClick = {
266- viewModel.deleteMediaDialog = mediaAttachment.id
267- }) {
268- Icon(
269- imageVector = Icons.Outlined.Delete,
270- contentDescription = "delete Image",
271- tint = MaterialTheme.colorScheme.error
272- )
273- }
274- }
275- }
276- }*/
277213 if (! viewModel.editPostState.isLoading && viewModel.editPostState.post != null ) {
278214 MaxLengthTextField (
279215 value = viewModel.caption,
280216 onValueChange = { viewModel.updateCaption(it) },
281- textFieldModifier = Modifier .fillMaxWidth().onFocusChanged { focusState ->
282- viewModel.hashtagMentionsSuggestionsManager.onFocusChanged(focusState.isFocused)
283- },
217+ textFieldModifier = Modifier .fillMaxWidth()
218+ .onFocusChanged { focusState ->
219+ viewModel.hashtagMentionsSuggestionsManager.onFocusChanged(
220+ focusState.isFocused
221+ )
222+ },
284223 label = Res .string.caption,
285224 maxLength = viewModel.instance?.configuration?.statusConfig?.maxCharacters,
286225 submit = {}
@@ -292,7 +231,8 @@ fun EditPostComposable(
292231 verticalAlignment = Alignment .CenterVertically
293232 ) {
294233 Text (text = stringResource(Res .string.sensitive_nsfw_media))
295- Switch (checked = viewModel.sensitive,
234+ Switch (
235+ checked = viewModel.sensitive,
296236 onCheckedChange = { viewModel.sensitive = it })
297237 }
298238 if (viewModel.sensitive) {
@@ -306,8 +246,12 @@ fun EditPostComposable(
306246 colors = TextFieldDefaults .colors(
307247 unfocusedIndicatorColor = Color .Transparent ,
308248 focusedIndicatorColor = Color .Transparent ,
309- focusedContainerColor = MaterialTheme .colorScheme.surfaceColorAtElevation(4 .dp),
310- unfocusedContainerColor = MaterialTheme .colorScheme.surfaceColorAtElevation(4 .dp)
249+ focusedContainerColor = MaterialTheme .colorScheme.surfaceColorAtElevation(
250+ 4 .dp
251+ ),
252+ unfocusedContainerColor = MaterialTheme .colorScheme.surfaceColorAtElevation(
253+ 4 .dp
254+ )
311255 ),
312256 keyboardOptions = KeyboardOptions (imeAction = ImeAction .Default ),
313257 keyboardActions = KeyboardActions (onDone = {
@@ -331,15 +275,18 @@ fun EditPostComposable(
331275 LoadingComposable (isLoading = viewModel.editPostState.isLoading)
332276 ErrorComposableDialog (
333277 errorMessage = viewModel.editPostState.error,
334- onDismiss = { viewModel.editPostState = viewModel.editPostState.copy(error = " " ) }
278+ onDismiss = {
279+ viewModel.editPostState = viewModel.editPostState.copy(error = " " )
280+ }
335281 )
336282 }
337283 if (viewModel.hashtagMentionsSuggestionsManager.suggestionsOpen) {
338284 SuggestionsBar (
339285 state = suggestionsState, onSelected = { selected ->
340- viewModel.caption = viewModel.hashtagMentionsSuggestionsManager.selectSuggestion(
341- selected, viewModel.caption
342- )
286+ viewModel.caption =
287+ viewModel.hashtagMentionsSuggestionsManager.selectSuggestion(
288+ selected, viewModel.caption
289+ )
343290 })
344291 }
345292 }
@@ -390,6 +337,31 @@ fun EditPostComposable(
390337 }
391338 })
392339 }
340+
341+ if (isCancelAlertOpen) {
342+ AlertDialog (
343+ title = {
344+ Text (text = stringResource(Res .string.are_you_sure))
345+ },
346+ text = {
347+ Text (text = stringResource(Res .string.cancel_post_edit))
348+ }, onDismissRequest = {
349+ isCancelAlertOpen = false
350+ }, dismissButton = {
351+ TextButton (onClick = {
352+ isCancelAlertOpen = false
353+ }) {
354+ Text (stringResource(Res .string.cancel))
355+ }
356+ }, confirmButton = {
357+ TextButton (onClick = {
358+ isCancelAlertOpen = false
359+ navController.popBackStack()
360+ }) {
361+ Text (stringResource(Res .string.discard))
362+ }
363+ })
364+ }
393365}
394366
395367
0 commit comments