Skip to content

Commit e217ef3

Browse files
author
Emanuel Hiebeler
committed
Add cancel dialog to edit post
1 parent fe685b9 commit e217ef3

4 files changed

Lines changed: 87 additions & 106 deletions

File tree

app/src/commonMain/composeResources/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,4 +286,5 @@
286286
<string name="are_you_sure">Are you sure?</string>
287287
<string name="cancel_post_warning">Do you want to discard this post?</string>
288288
<string name="cancel_profile_edit">Do you want to discard the changes?</string>
289+
<string name="cancel_post_edit">Do you want to discard the changes?</string>
289290
</resources>

app/src/commonMain/kotlin/com/daniebeler/pfpixelix/ui/composables/edit_post/EditPostComposable.kt

Lines changed: 74 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ import androidx.compose.ui.text.input.ImeAction
6565
import androidx.compose.ui.unit.dp
6666
import androidx.lifecycle.compose.collectAsStateWithLifecycle
6767
import androidx.navigation.NavController
68+
import androidx.navigationevent.NavigationEventInfo
69+
import androidx.navigationevent.compose.NavigationBackHandler
70+
import androidx.navigationevent.compose.rememberNavigationEventState
6871
import coil3.compose.AsyncImage
6972
import com.daniebeler.pfpixelix.di.injectViewModel
7073
import com.daniebeler.pfpixelix.domain.model.MediaAttachment
@@ -81,10 +84,13 @@ import org.jetbrains.compose.resources.stringResource
8184
import org.jetbrains.compose.resources.vectorResource
8285
import pixelix.app.generated.resources.Res
8386
import pixelix.app.generated.resources.alt_text
87+
import pixelix.app.generated.resources.are_you_sure
8488
import pixelix.app.generated.resources.cancel
89+
import pixelix.app.generated.resources.cancel_post_edit
8590
import pixelix.app.generated.resources.caption
8691
import pixelix.app.generated.resources.content_warning_or_spoiler_text
8792
import pixelix.app.generated.resources.delete
93+
import pixelix.app.generated.resources.discard
8894
import pixelix.app.generated.resources.edit_post
8995
import pixelix.app.generated.resources.location
9096
import 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

app/src/commonMain/kotlin/com/daniebeler/pfpixelix/ui/composables/edit_post/EditPostViewModel.kt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.daniebeler.pfpixelix.ui.composables.edit_post
22

3+
import androidx.compose.runtime.derivedStateOf
34
import androidx.compose.runtime.getValue
45
import androidx.compose.runtime.mutableStateListOf
56
import androidx.compose.runtime.mutableStateOf
@@ -45,6 +46,12 @@ class EditPostViewModel @Inject constructor(
4546
var mediaDescriptionItems = mutableStateListOf<MediaDescriptionItem>()
4647
var deleteMediaDialog by mutableStateOf<String?>(null)
4748
var instance: Instance? = null
49+
val isEdited: Boolean by derivedStateOf {
50+
if (editPostState.post == null) return@derivedStateOf false
51+
val mediaAttachmentsEditIds = mediaAttachmentsEdit.map { it.id }
52+
val mediaAttachmentsBeforeIds = mediaAttachmentsBefore.map { it.id }
53+
mediaDescriptionItems.any { it.changed } || caption.text != editPostState.post!!.content || sensitive != editPostState.post!!.sensitive || mediaAttachmentsBeforeIds != mediaAttachmentsEditIds || editPostState.post!!.place != location
54+
}
4855

4956
fun loadData(postId: String) {
5057
loadPost(postId)
@@ -89,7 +96,7 @@ class EditPostViewModel @Inject constructor(
8996
}
9097

9198
is Resource.Error -> {
92-
EditPostState(error = result.message ?: "An unexpected error occurred")
99+
EditPostState(error = result.message)
93100
}
94101

95102
is Resource.Loading -> {
@@ -140,7 +147,7 @@ class EditPostViewModel @Inject constructor(
140147
}
141148

142149
is Resource.Error -> {
143-
EditPostState(error = result.message ?: "An unexpected error occurred")
150+
EditPostState(error = result.message)
144151
}
145152

146153
is Resource.Loading -> {
@@ -162,7 +169,7 @@ class EditPostViewModel @Inject constructor(
162169

163170
is Resource.Error -> {
164171
editPostState =
165-
EditPostState(error = (result.message ?: "An unexpected error occurred"))
172+
EditPostState(error = (result.message))
166173
}
167174

168175
is Resource.Loading -> {

app/src/commonMain/kotlin/com/daniebeler/pfpixelix/ui/composables/edit_profile/EditProfileViewModel.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,10 @@ class EditProfileViewModel @Inject constructor(
3333
var privateProfile by mutableStateOf(false)
3434

3535
val isEdited: Boolean by derivedStateOf {
36+
if (accountState.account == null) return@derivedStateOf false
3637
!(displayName.text == (accountState.account?.displayname
3738
?: "") && note.text == (accountState.account?.note
38-
?: "") && "https://" + website == (accountState.account?.website
39+
?: "") && "https://$website" == (accountState.account?.website
3940
?: "") && newAvatar == null && privateProfile == accountState.account?.locked)
4041
}
4142

0 commit comments

Comments
 (0)