From 92abdde69eb385b66bc246ae85f28fd986c5651d Mon Sep 17 00:00:00 2001 From: Stanislav Dmitrenko <7953703+avently@users.noreply.github.com> Date: Tue, 30 Aug 2022 20:37:44 +0300 Subject: [PATCH] android: start direct chat button inside MemberInfo (#987) * Start direct chat button inside GroupInfo * More code for better understanding --- .../java/chat/simplex/app/model/ChatModel.kt | 1 + .../chat/simplex/app/views/chat/ChatView.kt | 34 ++++++------- .../app/views/chat/group/GroupChatInfoView.kt | 6 +-- .../views/chat/group/GroupMemberInfoView.kt | 48 ++++++++++++++++++- .../app/src/main/res/values-ru/strings.xml | 1 + .../app/src/main/res/values/strings.xml | 1 + 6 files changed, 71 insertions(+), 20 deletions(-) diff --git a/apps/android/app/src/main/java/chat/simplex/app/model/ChatModel.kt b/apps/android/app/src/main/java/chat/simplex/app/model/ChatModel.kt index 918a6a30e4..8593d903bd 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/model/ChatModel.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/model/ChatModel.kt @@ -67,6 +67,7 @@ class ChatModel(val controller: ChatController) { fun hasChat(id: String): Boolean = chats.firstOrNull { it.id == id } != null fun getChat(id: String): Chat? = chats.firstOrNull { it.id == id } + fun getContactChat(contactId: Long): Chat? = chats.firstOrNull { it.chatInfo is ChatInfo.Direct && it.chatInfo.apiId == contactId } private fun getChatIndex(id: String): Int = chats.indexOfFirst { it.id == id } fun addChat(chat: Chat) = chats.add(index = 0, chat) diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatView.kt index 26b0e86636..c6744f1361 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatView.kt @@ -32,8 +32,7 @@ import chat.simplex.app.R import chat.simplex.app.model.* import chat.simplex.app.ui.theme.* import chat.simplex.app.views.call.* -import chat.simplex.app.views.chat.group.AddGroupMembersView -import chat.simplex.app.views.chat.group.GroupChatInfoView +import chat.simplex.app.views.chat.group.* import chat.simplex.app.views.chat.item.ChatItemView import chat.simplex.app.views.chat.item.ItemAction import chat.simplex.app.views.chatlist.* @@ -135,12 +134,17 @@ fun ChatView(chatModel: ChatModel) { } } }, - openDirectChat = { contactId -> - val c = chatModel.chats.firstOrNull { - it.chatInfo is ChatInfo.Direct && it.chatInfo.contact.contactId == contactId - } - if (c != null) { - withApi { openChat(c.chatInfo, chatModel) } + showMemberInfo = { groupInfo: GroupInfo, member: GroupMember -> + withApi { + val stats = chatModel.controller.apiGroupMemberInfo(groupInfo.groupId, member.groupMemberId) + ModalManager.shared.showCustomModal { close -> + ModalView( + close = close, modifier = Modifier, + background = if (isInDarkTheme()) MaterialTheme.colors.background else SettingsBackgroundLight + ) { + GroupMemberInfoView(groupInfo, member, stats, chatModel, close, close) + } + } } }, loadPrevMessages = { cInfo -> @@ -238,7 +242,7 @@ fun ChatLayout( chatModelIncognito: Boolean, back: () -> Unit, info: () -> Unit, - openDirectChat: (Long) -> Unit, + showMemberInfo: (GroupInfo, GroupMember) -> Unit, loadPrevMessages: (ChatInfo) -> Unit, deleteMessage: (Long, CIDeleteMode) -> Unit, receiveFile: (Long) -> Unit, @@ -281,7 +285,7 @@ fun ChatLayout( BoxWithConstraints(Modifier.fillMaxHeight().padding(contentPadding)) { ChatItemsList( user, chat, unreadCount, composeState, chatItems, searchValue, - useLinkPreviews, chatModelIncognito, openDirectChat, loadPrevMessages, deleteMessage, + useLinkPreviews, chatModelIncognito, showMemberInfo, loadPrevMessages, deleteMessage, receiveFile, joinGroup, acceptCall, markRead, setFloatingButton ) } @@ -423,7 +427,7 @@ fun BoxWithConstraintsScope.ChatItemsList( searchValue: State, useLinkPreviews: Boolean, chatModelIncognito: Boolean, - openDirectChat: (Long) -> Unit, + showMemberInfo: (GroupInfo, GroupMember) -> Unit, loadPrevMessages: (ChatInfo) -> Unit, deleteMessage: (Long, CIDeleteMode) -> Unit, receiveFile: (Long) -> Unit, @@ -510,9 +514,7 @@ fun BoxWithConstraintsScope.ChatItemsList( Modifier .clip(CircleShape) .clickable { - openDirectChat(contactId) - // Scroll to first unread message when direct chat will be loaded - shouldAutoScroll = true + showMemberInfo(chat.chatInfo.groupInfo, member) } ) { MemberImage(member) @@ -826,7 +828,7 @@ fun PreviewChatLayout() { chatModelIncognito = false, back = {}, info = {}, - openDirectChat = {}, + showMemberInfo = {_, _ -> }, loadPrevMessages = { _ -> }, deleteMessage = { _, _ -> }, receiveFile = {}, @@ -883,7 +885,7 @@ fun PreviewGroupChatLayout() { chatModelIncognito = false, back = {}, info = {}, - openDirectChat = {}, + showMemberInfo = {_, _ -> }, loadPrevMessages = { _ -> }, deleteMessage = { _, _ -> }, receiveFile = {}, diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chat/group/GroupChatInfoView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chat/group/GroupChatInfoView.kt index 0d1208f191..84250861da 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chat/group/GroupChatInfoView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chat/group/GroupChatInfoView.kt @@ -59,12 +59,12 @@ fun GroupChatInfoView(chatModel: ChatModel, close: () -> Unit) { showMemberInfo = { member -> withApi { val stats = chatModel.controller.apiGroupMemberInfo(groupInfo.groupId, member.groupMemberId) - ModalManager.shared.showCustomModal { close -> + ModalManager.shared.showCustomModal { closeCurrent -> ModalView( - close = close, modifier = Modifier, + close = closeCurrent, modifier = Modifier, background = if (isInDarkTheme()) MaterialTheme.colors.background else SettingsBackgroundLight ) { - GroupMemberInfoView(groupInfo, member, stats, chatModel, close) + GroupMemberInfoView(groupInfo, member, stats, chatModel, closeCurrent) { closeCurrent(); close() } } } } diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chat/group/GroupMemberInfoView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chat/group/GroupMemberInfoView.kt index 5aa06861d7..53a19528fe 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chat/group/GroupMemberInfoView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chat/group/GroupMemberInfoView.kt @@ -24,6 +24,7 @@ import chat.simplex.app.R import chat.simplex.app.model.* import chat.simplex.app.ui.theme.* import chat.simplex.app.views.chat.SimplexServers +import chat.simplex.app.views.chatlist.openChat import chat.simplex.app.views.helpers.* @Composable @@ -32,7 +33,8 @@ fun GroupMemberInfoView( member: GroupMember, connStats: ConnectionStats?, chatModel: ChatModel, - close: () -> Unit + close: () -> Unit, + closeAll: () -> Unit, // Close all open windows up to ChatView ) { BackHandler(onBack = close) val chat = chatModel.chats.firstOrNull { it.id == chatModel.chatId.value } @@ -43,6 +45,22 @@ fun GroupMemberInfoView( member, connStats, developerTools, + openDirectChat = { + withApi { + val oldChat = chatModel.getContactChat(member.memberContactId ?: return@withApi) + if (oldChat != null) { + openChat(oldChat.chatInfo, chatModel) + } else { + var newChat = chatModel.controller.apiGetChat(ChatType.Direct, member.memberContactId) ?: return@withApi + // TODO it's not correct to blindly set network status to connected - we should manage network status in model / backend + newChat = newChat.copy(serverInfo = Chat.ServerInfo(networkStatus = Chat.NetworkStatus.Connected())) + chatModel.addChat(newChat) + chatModel.chatItems.clear() + chatModel.chatId.value = newChat.id + } + closeAll() + } + }, removeMember = { removeMemberDialog(groupInfo, member, chatModel, close) } ) } @@ -71,6 +89,7 @@ fun GroupMemberInfoLayout( member: GroupMember, connStats: ConnectionStats?, developerTools: Boolean, + openDirectChat: () -> Unit, removeMember: () -> Unit, ) { Column( @@ -87,6 +106,13 @@ fun GroupMemberInfoLayout( } SectionSpacer() + SectionView { + SectionItemView { + OpenChatButton(openDirectChat) + } + } + SectionSpacer() + SectionView(title = stringResource(R.string.member_info_section_title_member)) { InfoRow(stringResource(R.string.info_row_group), groupInfo.displayName) val conn = member.activeConn @@ -181,6 +207,25 @@ fun RemoveMemberButton(removeMember: () -> Unit) { } } +@Composable +fun OpenChatButton(onClick: () -> Unit) { + Row( + Modifier + .fillMaxSize() + .clickable { onClick() }, + verticalAlignment = Alignment.CenterVertically + ) { + Icon( + Icons.Outlined.Message, + stringResource(R.string.button_send_direct_message), + Modifier.padding(top = 5.dp), + tint = MaterialTheme.colors.primary + ) + Spacer(Modifier.size(8.dp)) + Text(stringResource(R.string.button_send_direct_message), color = MaterialTheme.colors.primary) + } +} + @Preview @Composable fun PreviewGroupMemberInfoLayout() { @@ -190,6 +235,7 @@ fun PreviewGroupMemberInfoLayout() { member = GroupMember.sampleData, connStats = null, developerTools = false, + openDirectChat = {}, removeMember = {} ) } diff --git a/apps/android/app/src/main/res/values-ru/strings.xml b/apps/android/app/src/main/res/values-ru/strings.xml index 023e067f1c..960e274fa5 100644 --- a/apps/android/app/src/main/res/values-ru/strings.xml +++ b/apps/android/app/src/main/res/values-ru/strings.xml @@ -614,6 +614,7 @@ Удалить члена группы + Отправить сообщение Член группы будет удален - это действие нельзя отменить! Удалить ЧЛЕН ГРУППЫ diff --git a/apps/android/app/src/main/res/values/strings.xml b/apps/android/app/src/main/res/values/strings.xml index cf21338f7a..5ce4e0556f 100644 --- a/apps/android/app/src/main/res/values/strings.xml +++ b/apps/android/app/src/main/res/values/strings.xml @@ -615,6 +615,7 @@ Remove member + Send direct message Member will be removed from group - this cannot be undone! Remove MEMBER