Skip to content

Commit a12f2a5

Browse files
Add delete button to conversation screen
1 parent 02e1639 commit a12f2a5

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

app/src/main/java/org/vonderheidt/hips/ui/screens/ConversationScreen.kt

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package org.vonderheidt.hips.ui.screens
22

3+
import android.widget.Toast
34
import androidx.compose.foundation.background
45
import androidx.compose.foundation.clickable
6+
import androidx.compose.foundation.gestures.detectTapGestures
57
import androidx.compose.foundation.layout.Arrangement
68
import androidx.compose.foundation.layout.Box
79
import androidx.compose.foundation.layout.Column
@@ -21,6 +23,7 @@ import androidx.compose.material.icons.Icons
2123
import androidx.compose.material.icons.automirrored.outlined.ArrowForward
2224
import androidx.compose.material.icons.automirrored.outlined.Send
2325
import androidx.compose.material.icons.outlined.Clear
26+
import androidx.compose.material.icons.outlined.Delete
2427
import androidx.compose.material.icons.outlined.Person
2528
import androidx.compose.material3.Icon
2629
import androidx.compose.material3.IconButton
@@ -36,6 +39,9 @@ import androidx.compose.runtime.setValue
3639
import androidx.compose.ui.Alignment
3740
import androidx.compose.ui.Modifier
3841
import androidx.compose.ui.graphics.Color
42+
import androidx.compose.ui.graphics.graphicsLayer
43+
import androidx.compose.ui.input.pointer.pointerInput
44+
import androidx.compose.ui.platform.LocalContext
3945
import androidx.compose.ui.tooling.preview.Preview
4046
import androidx.compose.ui.unit.dp
4147
import androidx.compose.ui.unit.sp
@@ -60,8 +66,12 @@ fun ConversationScreen(navController: NavController, modifier: Modifier) {
6066
// Coroutines
6167
val coroutineScope = rememberCoroutineScope()
6268

69+
// Toasts
70+
val currentLocalContext = LocalContext.current
71+
6372
// State variables
6473
var messages by rememberSaveable { mutableStateOf(listOf<Message>()) }
74+
var selectedMessages by rememberSaveable { mutableStateOf(listOf<Message>()) }
6575
var newMessageContent by rememberSaveable { mutableStateOf("") }
6676
var isSender by rememberSaveable { mutableStateOf(true) }
6777

@@ -119,6 +129,37 @@ fun ConversationScreen(navController: NavController, modifier: Modifier) {
119129
text = "Demo",
120130
fontSize = 24.sp,
121131
)
132+
133+
// Profile picture and name on the left, buttons on the right
134+
Spacer(modifier = modifier.weight(1f))
135+
136+
if (selectedMessages.isNotEmpty()) {
137+
// Delete button
138+
IconButton(
139+
onClick = {
140+
// Only last messages of the conversation can be deleted, otherwise context would be corrupted
141+
if (messages.takeLast(selectedMessages.size) == selectedMessages) {
142+
// Update database
143+
// Inverse encapsulation of loop vs coroutine causes messages to not be deleted
144+
for (selectedMessage in selectedMessages) {
145+
coroutineScope.launch { db.messageDao.deleteMessage(selectedMessage) }
146+
}
147+
148+
// Update state variables
149+
messages = messages.dropLast(selectedMessages.size)
150+
selectedMessages = listOf()
151+
}
152+
else {
153+
Toast.makeText(currentLocalContext, "Only messages at the end can be deleted", Toast.LENGTH_LONG).show()
154+
}
155+
}
156+
) {
157+
Icon(
158+
imageVector = Icons.Outlined.Delete,
159+
contentDescription = "Delete selected messages"
160+
)
161+
}
162+
}
122163
}
123164

124165
Spacer(modifier = modifier.height(8.dp))
@@ -144,7 +185,26 @@ fun ConversationScreen(navController: NavController, modifier: Modifier) {
144185
color = if (message.senderID == 0) Color(0xFF2E7D32) else Color(0xFFB71C1C),
145186
shape = RoundedCornerShape(4.dp)
146187
)
188+
.graphicsLayer(
189+
alpha = if (selectedMessages.isEmpty()) { 1f }
190+
else {
191+
if (message in selectedMessages) { 1f }
192+
else { 0.25f }
193+
}
194+
)
147195
.padding(8.dp)
196+
.pointerInput(Unit) {
197+
detectTapGestures(
198+
onLongPress = {
199+
// List of selected messages has to be sorted because list of messages is sorted, otherwise couldn't be compared to its end
200+
selectedMessages += message
201+
selectedMessages = selectedMessages.sortedBy { it.timestamp }
202+
},
203+
onTap = {
204+
selectedMessages -= message
205+
}
206+
)
207+
}
148208
) {
149209
Text(
150210
text = message.content,

0 commit comments

Comments
 (0)