mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-03-30 20:45:49 +00:00
ui: add swipe/menu actions to member contact requests (#6138)
* ios: add swipe actions to member contact requests * kotlin * padding
This commit is contained in:
@@ -27,13 +27,13 @@ struct ContextMemberContactActionsView: View {
|
||||
.frame(maxWidth: .infinity, minHeight: 60)
|
||||
} else {
|
||||
HStack(spacing: 0) {
|
||||
Button(role: .destructive, action: showRejectRequestAlert) {
|
||||
Button(role: .destructive, action: { showRejectMemberContactRequestAlert(contact) }) {
|
||||
Label("Reject", systemImage: "multiply")
|
||||
}
|
||||
.frame(maxWidth: .infinity, minHeight: 60)
|
||||
|
||||
Button {
|
||||
acceptRequest()
|
||||
acceptMemberContactRequest(contact, inProgress: $inProgress)
|
||||
} label: {
|
||||
Label("Accept", systemImage: "checkmark")
|
||||
}
|
||||
@@ -61,44 +61,44 @@ struct ContextMemberContactActionsView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func showRejectRequestAlert() {
|
||||
showAlert(
|
||||
NSLocalizedString("Reject contact request", comment: "alert title"),
|
||||
message: NSLocalizedString("The sender will NOT be notified", comment: "alert message"),
|
||||
actions: {[
|
||||
UIAlertAction(title: NSLocalizedString("Reject", comment: "alert action"), style: .destructive) { _ in
|
||||
deleteContact()
|
||||
},
|
||||
cancelAlertAction
|
||||
]}
|
||||
)
|
||||
}
|
||||
func showRejectMemberContactRequestAlert(_ contact: Contact) {
|
||||
showAlert(
|
||||
NSLocalizedString("Reject contact request", comment: "alert title"),
|
||||
message: NSLocalizedString("The sender will NOT be notified", comment: "alert message"),
|
||||
actions: {[
|
||||
UIAlertAction(title: NSLocalizedString("Reject", comment: "alert action"), style: .destructive) { _ in
|
||||
deleteContact(contact)
|
||||
},
|
||||
cancelAlertAction
|
||||
]}
|
||||
)
|
||||
}
|
||||
|
||||
func deleteContact() {
|
||||
Task {
|
||||
do {
|
||||
let _ct = try await apiDeleteContact(id: contact.contactId, chatDeleteMode: .full(notify: false))
|
||||
await MainActor.run {
|
||||
ChatModel.shared.removeChat(contact.id)
|
||||
ChatModel.shared.chatId = nil
|
||||
}
|
||||
} catch let error {
|
||||
logger.error("apiDeleteContact: \(responseError(error))")
|
||||
await MainActor.run {
|
||||
showAlert(
|
||||
NSLocalizedString("Error deleting chat!", comment: "alert title"),
|
||||
message: responseError(error)
|
||||
)
|
||||
}
|
||||
private func deleteContact(_ contact: Contact) {
|
||||
Task {
|
||||
do {
|
||||
_ = try await apiDeleteContact(id: contact.contactId, chatDeleteMode: .full(notify: false))
|
||||
await MainActor.run {
|
||||
ChatModel.shared.removeChat(contact.id)
|
||||
ChatModel.shared.chatId = nil
|
||||
}
|
||||
} catch let error {
|
||||
logger.error("apiDeleteContact: \(responseError(error))")
|
||||
await MainActor.run {
|
||||
showAlert(
|
||||
NSLocalizedString("Error deleting chat!", comment: "alert title"),
|
||||
message: responseError(error)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func acceptRequest() {
|
||||
Task {
|
||||
await acceptMemberContact(contactId: contact.contactId, inProgress: $inProgress)
|
||||
}
|
||||
func acceptMemberContactRequest(_ contact: Contact, inProgress: Binding<Bool>? = nil) {
|
||||
Task {
|
||||
await acceptMemberContact(contactId: contact.contactId, inProgress: inProgress)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -130,26 +130,54 @@ struct ChatListNavLink: View {
|
||||
}
|
||||
}
|
||||
.swipeActions(edge: .trailing, allowsFullSwipe: true) {
|
||||
if contact.nextAcceptContactRequest,
|
||||
let contactRequestId = contact.contactRequestId {
|
||||
Button {
|
||||
Task { await acceptContactRequest(incognito: false, contactRequestId: contactRequestId) }
|
||||
} label: { SwipeLabel(NSLocalizedString("Accept", comment: "swipe action"), systemImage: "checkmark", inverted: oneHandUI) }
|
||||
.tint(theme.colors.primary)
|
||||
if !ChatModel.shared.addressShortLinkDataSet {
|
||||
if contact.nextAcceptContactRequest {
|
||||
if let contactRequestId = contact.contactRequestId {
|
||||
Button {
|
||||
Task { await acceptContactRequest(incognito: true, contactRequestId: contactRequestId) }
|
||||
} label: {
|
||||
SwipeLabel(NSLocalizedString("Accept incognito", comment: "swipe action"), systemImage: "theatermasks.fill", inverted: oneHandUI)
|
||||
Task { await acceptContactRequest(incognito: false, contactRequestId: contactRequestId) }
|
||||
} label: { SwipeLabel(NSLocalizedString("Accept", comment: "swipe action"), systemImage: "checkmark", inverted: oneHandUI) }
|
||||
.tint(theme.colors.primary)
|
||||
if !ChatModel.shared.addressShortLinkDataSet {
|
||||
Button {
|
||||
Task { await acceptContactRequest(incognito: true, contactRequestId: contactRequestId) }
|
||||
} label: {
|
||||
SwipeLabel(NSLocalizedString("Accept incognito", comment: "swipe action"), systemImage: "theatermasks.fill", inverted: oneHandUI)
|
||||
}
|
||||
.tint(.indigo)
|
||||
}
|
||||
.tint(.indigo)
|
||||
Button {
|
||||
AlertManager.shared.showAlert(rejectContactRequestAlert(contactRequestId))
|
||||
} label: {
|
||||
SwipeLabel(NSLocalizedString("Reject", comment: "swipe action"), systemImage: "multiply", inverted: oneHandUI)
|
||||
}
|
||||
.tint(.red)
|
||||
} else if let groupDirectInv = contact.groupDirectInv, !groupDirectInv.memberRemoved {
|
||||
Button {
|
||||
acceptMemberContactRequest(contact)
|
||||
} label: {
|
||||
Label("Accept", systemImage: "checkmark")
|
||||
}
|
||||
.tint(theme.colors.primary)
|
||||
Button {
|
||||
showRejectMemberContactRequestAlert(contact)
|
||||
} label: {
|
||||
Label("Reject", systemImage: "multiply")
|
||||
}
|
||||
.tint(.red)
|
||||
} else {
|
||||
Button {
|
||||
deleteContactDialog(
|
||||
chat,
|
||||
contact,
|
||||
dismissToChatList: false,
|
||||
showAlert: { alert = $0 },
|
||||
showActionSheet: { actionSheet = $0 },
|
||||
showSheetContent: { sheet = $0 }
|
||||
)
|
||||
} label: {
|
||||
deleteLabel
|
||||
}
|
||||
.tint(.red)
|
||||
}
|
||||
Button {
|
||||
AlertManager.shared.showAlert(rejectContactRequestAlert(contactRequestId))
|
||||
} label: {
|
||||
SwipeLabel(NSLocalizedString("Reject", comment: "swipe action"), systemImage: "multiply", inverted: oneHandUI)
|
||||
}
|
||||
.tint(.red)
|
||||
} else {
|
||||
tagChatButton(chat)
|
||||
if !chat.chatItems.isEmpty {
|
||||
|
||||
@@ -87,8 +87,10 @@ struct ContactListNavLink: View {
|
||||
if let contactRequestId = contact.contactRequestId {
|
||||
Button {
|
||||
Task { await acceptContactRequest(incognito: false, contactRequestId: contactRequestId) }
|
||||
} label: { Label("Accept", systemImage: "checkmark") }
|
||||
.tint(theme.colors.primary)
|
||||
} label: {
|
||||
Label("Accept", systemImage: "checkmark")
|
||||
}
|
||||
.tint(theme.colors.primary)
|
||||
if !ChatModel.shared.addressShortLinkDataSet {
|
||||
Button {
|
||||
Task { await acceptContactRequest(incognito: true, contactRequestId: contactRequestId) }
|
||||
@@ -103,6 +105,19 @@ struct ContactListNavLink: View {
|
||||
Label("Reject", systemImage: "multiply")
|
||||
}
|
||||
.tint(.red)
|
||||
} else if let groupDirectInv = contact.groupDirectInv, !groupDirectInv.memberRemoved {
|
||||
Button {
|
||||
acceptMemberContactRequest(contact)
|
||||
} label: {
|
||||
Label("Accept", systemImage: "checkmark")
|
||||
}
|
||||
.tint(theme.colors.primary)
|
||||
Button {
|
||||
showRejectMemberContactRequestAlert(contact)
|
||||
} label: {
|
||||
Label("Reject", systemImage: "multiply")
|
||||
}
|
||||
.tint(.red)
|
||||
} else {
|
||||
Button {
|
||||
deleteContactDialog(
|
||||
|
||||
@@ -14,6 +14,7 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.platform.chatModel
|
||||
import chat.simplex.common.ui.theme.DEFAULT_PADDING_HALF
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.res.MR
|
||||
import dev.icerock.moko.resources.compose.painterResource
|
||||
@@ -59,7 +60,8 @@ fun ComposeContextMemberContactActionsView(
|
||||
if (groupDirectInv.memberRemoved) {
|
||||
Row(
|
||||
Modifier
|
||||
.fillMaxSize(),
|
||||
.fillMaxSize()
|
||||
.padding(horizontal = DEFAULT_PADDING_HALF),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally)
|
||||
) {
|
||||
@@ -149,7 +151,7 @@ private fun deleteMemberContact(rhId: Long?, contact: Contact) {
|
||||
fun acceptMemberContact(
|
||||
rhId: Long?,
|
||||
contactId: Long,
|
||||
close: ((chat: Chat) -> Unit)? = null, // currently unused, can pass function to open chat if reused in other views (e.g. see onRequestAccepted)
|
||||
close: ((chat: Chat) -> Unit)? = null,
|
||||
inProgress: MutableState<Boolean>? = null
|
||||
) {
|
||||
withBGApi {
|
||||
|
||||
@@ -271,8 +271,14 @@ suspend fun setGroupMembers(rhId: Long?, groupInfo: GroupInfo, chatModel: ChatMo
|
||||
|
||||
@Composable
|
||||
fun ContactMenuItems(chat: Chat, contact: Contact, chatModel: ChatModel, showMenu: MutableState<Boolean>, showMarkRead: Boolean) {
|
||||
if (contact.nextAcceptContactRequest && contact.contactRequestId != null) {
|
||||
ContactRequestMenuItems(chat.remoteHostId, contactRequestId = contact.contactRequestId, chatModel, showMenu)
|
||||
if (contact.nextAcceptContactRequest) {
|
||||
if (contact.contactRequestId != null) {
|
||||
ContactRequestMenuItems(chat.remoteHostId, contactRequestId = contact.contactRequestId, chatModel, showMenu)
|
||||
} else if (contact.groupDirectInv != null && !contact.groupDirectInv.memberRemoved) {
|
||||
MemberContactRequestMenuItems(chat.remoteHostId, contact, showMenu)
|
||||
} else {
|
||||
DeleteContactAction(chat, chatModel, showMenu)
|
||||
}
|
||||
} else {
|
||||
if (contact.activeConn != null) {
|
||||
if (showMarkRead) {
|
||||
@@ -545,6 +551,28 @@ fun ContactRequestMenuItems(rhId: Long?, contactRequestId: Long, chatModel: Chat
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun MemberContactRequestMenuItems(rhId: Long?, contact: Contact, showMenu: MutableState<Boolean>, onSuccess: ((chat: Chat) -> Unit)? = null) {
|
||||
ItemAction(
|
||||
stringResource(MR.strings.accept_contact_button),
|
||||
painterResource(MR.images.ic_check),
|
||||
color = MaterialTheme.colors.onBackground,
|
||||
onClick = {
|
||||
acceptMemberContact(rhId, contact.contactId, onSuccess)
|
||||
showMenu.value = false
|
||||
}
|
||||
)
|
||||
ItemAction(
|
||||
stringResource(MR.strings.reject_contact_button),
|
||||
painterResource(MR.images.ic_close),
|
||||
onClick = {
|
||||
showRejectMemberContactRequestAlert(rhId, contact)
|
||||
showMenu.value = false
|
||||
},
|
||||
color = Color.Red
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ContactConnectionMenuItems(rhId: Long?, chatInfo: ChatInfo.ContactConnection, chatModel: ChatModel, showMenu: MutableState<Boolean>) {
|
||||
ItemAction(
|
||||
|
||||
@@ -73,14 +73,25 @@ fun ContactListNavLinkView(chat: Chat, nextChatSelected: State<Boolean>, showDel
|
||||
},
|
||||
dropdownMenuItems = {
|
||||
tryOrShowError("${chat.id}ContactListNavLinkDropdown", error = {}) {
|
||||
if (contactType == ContactType.CONTACT_WITH_REQUEST && chat.chatInfo.contact.contactRequestId != null) {
|
||||
ContactRequestMenuItems(
|
||||
rhId = chat.remoteHostId,
|
||||
contactRequestId = chat.chatInfo.contact.contactRequestId,
|
||||
chatModel = chatModel,
|
||||
showMenu = showMenu,
|
||||
onSuccess = { onRequestAccepted(it) }
|
||||
)
|
||||
if (contactType == ContactType.CONTACT_WITH_REQUEST) {
|
||||
if (chat.chatInfo.contact.contactRequestId != null) {
|
||||
ContactRequestMenuItems(
|
||||
rhId = chat.remoteHostId,
|
||||
contactRequestId = chat.chatInfo.contact.contactRequestId,
|
||||
chatModel = chatModel,
|
||||
showMenu = showMenu,
|
||||
onSuccess = { onRequestAccepted(it) }
|
||||
)
|
||||
} else if (chat.chatInfo.contact.groupDirectInv != null && !chat.chatInfo.contact.groupDirectInv.memberRemoved) {
|
||||
MemberContactRequestMenuItems(
|
||||
rhId = chat.remoteHostId,
|
||||
contact = chat.chatInfo.contact,
|
||||
showMenu = showMenu,
|
||||
onSuccess = { onRequestAccepted(it) }
|
||||
)
|
||||
} else {
|
||||
DeleteContactAction(chat, chatModel, showMenu)
|
||||
}
|
||||
} else {
|
||||
DeleteContactAction(chat, chatModel, showMenu)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user