@@ -2,18 +2,23 @@ package com.ismartcoding.plain.ui.page.root.components
22
33import androidx.compose.foundation.ExperimentalFoundationApi
44import androidx.compose.foundation.background
5+ import androidx.compose.foundation.combinedClickable
56import androidx.compose.foundation.layout.Box
67import androidx.compose.foundation.layout.Column
78import androidx.compose.foundation.layout.Row
9+ import androidx.compose.foundation.layout.fillMaxSize
810import androidx.compose.foundation.layout.fillMaxWidth
911import androidx.compose.foundation.layout.padding
1012import androidx.compose.foundation.layout.size
13+ import androidx.compose.foundation.layout.wrapContentSize
1114import androidx.compose.foundation.shape.CircleShape
1215import androidx.compose.material3.Icon
1316import androidx.compose.material3.MaterialTheme
1417import androidx.compose.material3.Surface
1518import androidx.compose.material3.Text
1619import androidx.compose.runtime.Composable
20+ import androidx.compose.runtime.mutableStateOf
21+ import androidx.compose.runtime.remember
1722import androidx.compose.ui.Alignment
1823import androidx.compose.ui.Modifier
1924import androidx.compose.ui.draw.clip
@@ -29,7 +34,10 @@ import com.ismartcoding.plain.db.DMessageImages
2934import com.ismartcoding.plain.db.DMessageText
3035import com.ismartcoding.plain.db.DMessageType
3136import com.ismartcoding.plain.extensions.timeAgo
37+ import com.ismartcoding.plain.ui.base.PDropdownMenu
38+ import com.ismartcoding.plain.ui.base.PDropdownMenuItem
3239import com.ismartcoding.plain.ui.base.VerticalSpace
40+ import com.ismartcoding.plain.ui.helpers.DialogHelper
3341import com.ismartcoding.plain.ui.theme.green
3442import com.ismartcoding.plain.ui.theme.grey
3543import com.ismartcoding.plain.ui.theme.listItemSubtitle
@@ -45,78 +53,125 @@ fun PeerListItem(
4553 icon : Int ,
4654 online : Boolean? = null,
4755 latestChat : DChat ? = null,
56+ peerId : String? = null,
57+ onDelete : ((String ) -> Unit )? = null,
58+ onClick : () -> Unit = {},
4859) {
60+ val showContextMenu = remember { mutableStateOf(false ) }
61+ val deleteText = stringResource(id = R .string.delete)
62+ val deleteWarningText = stringResource(id = R .string.delete_peer_warning)
63+ val cancelText = stringResource(id = R .string.cancel)
64+
4965 Surface (
50- modifier =
51- modifier,
66+ modifier = modifier.combinedClickable(
67+ onClick = onClick,
68+ onLongClick = {
69+ if (peerId != null && onDelete != null ) {
70+ showContextMenu.value = true
71+ }
72+ }
73+ ),
5274 color = Color .Unspecified ,
5375 ) {
54- Row (
55- modifier =
56- Modifier
76+ Box {
77+ Row (
78+ modifier = Modifier
5779 .fillMaxWidth()
5880 .padding(4 .dp, 8 .dp, 8 .dp, 8 .dp),
59- verticalAlignment = Alignment .CenterVertically ,
60- ) {
61- Box (
62- modifier = Modifier
63- .padding(end = 8 .dp)
64- .size(40 .dp)
65- .padding(2 .dp),
66- contentAlignment = Alignment .Center
81+ verticalAlignment = Alignment .CenterVertically ,
6782 ) {
68- Icon (
69- painter = painterResource(icon),
70- contentDescription = title,
71- modifier = Modifier .size(24 .dp),
72- tint = MaterialTheme .colorScheme.primary
73- )
74- if (online != null ) {
75- Box (
76- modifier = Modifier
77- .size(10 .dp)
78- .clip(CircleShape )
79- .background(MaterialTheme .colorScheme.surface)
80- .padding(1 .dp)
81- .clip(CircleShape )
82- .background(
83- if (online)
84- MaterialTheme .colorScheme.green
85- else
86- MaterialTheme .colorScheme.grey
87- )
88- .align(Alignment .BottomEnd )
83+ Box (
84+ modifier = Modifier
85+ .padding(end = 8 .dp)
86+ .size(40 .dp)
87+ .padding(2 .dp),
88+ contentAlignment = Alignment .Center
89+ ) {
90+ Icon (
91+ painter = painterResource(icon),
92+ contentDescription = title,
93+ modifier = Modifier .size(24 .dp),
94+ tint = MaterialTheme .colorScheme.primary
8995 )
96+ if (online != null ) {
97+ Box (
98+ modifier = Modifier
99+ .size(10 .dp)
100+ .clip(CircleShape )
101+ .background(MaterialTheme .colorScheme.surface)
102+ .padding(1 .dp)
103+ .clip(CircleShape )
104+ .background(
105+ if (online)
106+ MaterialTheme .colorScheme.green
107+ else
108+ MaterialTheme .colorScheme.grey
109+ )
110+ .align(Alignment .BottomEnd )
111+ )
112+ }
90113 }
91- }
92- Column (
93- modifier = Modifier
94- .weight(1f )
95- .padding(vertical = 8 .dp)
96- ) {
97- Row (
98- modifier = Modifier .fillMaxWidth(),
99- verticalAlignment = Alignment .CenterVertically
114+ Column (
115+ modifier = Modifier
116+ .weight(1f )
117+ .padding(vertical = 8 .dp)
100118 ) {
119+ Row (
120+ modifier = Modifier .fillMaxWidth(),
121+ verticalAlignment = Alignment .CenterVertically
122+ ) {
123+ Text (
124+ text = title,
125+ style = MaterialTheme .typography.listItemTitle(),
126+ modifier = Modifier .weight(1f )
127+ )
128+ latestChat?.let { chat ->
129+ Text (
130+ text = chat.createdAt.timeAgo(),
131+ style = MaterialTheme .typography.listItemSubtitle(),
132+ )
133+ }
134+ }
135+ VerticalSpace (dp = 8 .dp)
101136 Text (
102- text = title,
103- style = MaterialTheme .typography.listItemTitle(),
104- modifier = Modifier .weight(1f )
137+ text = latestChat?.let { getMessagePreview(it) } ? : desc,
138+ style = MaterialTheme .typography.listItemSubtitle(),
139+ maxLines = 1 ,
140+ overflow = TextOverflow .Ellipsis
105141 )
106- latestChat?.let { chat ->
107- Text (
108- text = chat.createdAt.timeAgo(),
109- style = MaterialTheme .typography.listItemSubtitle(),
142+ }
143+ }
144+
145+ // Context menu for peer items
146+ if (peerId != null && onDelete != null ) {
147+ Box (
148+ modifier = Modifier
149+ .fillMaxSize()
150+ .padding(top = 32 .dp)
151+ .wrapContentSize(Alignment .Center ),
152+ ) {
153+ PDropdownMenu (
154+ expanded = showContextMenu.value,
155+ onDismissRequest = {
156+ showContextMenu.value = false
157+ },
158+ ) {
159+ PDropdownMenuItem (
160+ text = { Text (deleteText) },
161+ onClick = {
162+ showContextMenu.value = false
163+ DialogHelper .showConfirmDialog(
164+ title = deleteText,
165+ message = deleteWarningText,
166+ confirmButton = Pair (deleteText) {
167+ onDelete(peerId)
168+ },
169+ dismissButton = Pair (cancelText) {}
170+ )
171+ },
110172 )
111173 }
112174 }
113- VerticalSpace (dp = 8 .dp)
114- Text (
115- text = latestChat?.let { getMessagePreview(it) } ? : desc,
116- style = MaterialTheme .typography.listItemSubtitle(),
117- maxLines = 1 ,
118- overflow = TextOverflow .Ellipsis
119- )
120175 }
121176 }
122177 }
0 commit comments