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 43a4d638c9..3f4278bf08 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 @@ -139,8 +139,9 @@ fun ChatView(chatId: String, chatModel: ChatModel, onComposed: () -> Unit) { } } else if (chat.chatInfo is ChatInfo.Group) { setGroupMembers(chat.chatInfo.groupInfo, chatModel) + var groupLink = chatModel.controller.apiGetGroupLink(chat.chatInfo.groupInfo.groupId) ModalManager.shared.showModalCloseable(true) { close -> - GroupChatInfoView(chatModel, close) + GroupChatInfoView(chatModel, groupLink, { groupLink = it }, close) } } } 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 6bf43a8d03..874c0db684 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 @@ -34,7 +34,7 @@ import chat.simplex.app.views.helpers.* import chat.simplex.app.views.usersettings.* @Composable -fun GroupChatInfoView(chatModel: ChatModel, close: () -> Unit) { +fun GroupChatInfoView(chatModel: ChatModel, groupLink: String?, onGroupLinkUpdated: (String?) -> Unit, close: () -> Unit) { BackHandler(onBack = close) val chat = chatModel.chats.firstOrNull { it.id == chatModel.chatId.value } val developerTools = chatModel.controller.appPrefs.developerTools.get() @@ -47,6 +47,7 @@ fun GroupChatInfoView(chatModel: ChatModel, close: () -> Unit) { .filter { it.memberStatus != GroupMemberStatus.MemLeft && it.memberStatus != GroupMemberStatus.MemRemoved } .sortedBy { it.displayName.lowercase() }, developerTools, + groupLink, addMembers = { withApi { setGroupMembers(groupInfo, chatModel) @@ -95,8 +96,7 @@ fun GroupChatInfoView(chatModel: ChatModel, close: () -> Unit) { leaveGroup = { leaveGroupDialog(groupInfo, chatModel, close) }, manageGroupLink = { withApi { - val groupLink = chatModel.controller.apiGetGroupLink(groupInfo.groupId) - ModalManager.shared.showModal { GroupLinkView(chatModel, groupInfo, groupLink) } + ModalManager.shared.showModal { GroupLinkView(chatModel, groupInfo, groupLink, onGroupLinkUpdated) } } } ) @@ -145,6 +145,7 @@ fun GroupChatInfoLayout( groupInfo: GroupInfo, members: List, developerTools: Boolean, + groupLink: String?, addMembers: () -> Unit, showMemberInfo: (GroupMember) -> Unit, editGroupProfile: () -> Unit, @@ -181,7 +182,11 @@ fun GroupChatInfoLayout( SectionView(title = String.format(generalGetString(R.string.group_info_section_title_num_members), members.count() + 1)) { if (groupInfo.canAddMembers) { SectionItemView(manageGroupLink) { - GroupLinkButton() + if (groupLink == null) { + CreateGroupLinkButton() + } else { + GroupLinkButton() + } } SectionDivider() val onAddMembersClick = if (chat.chatInfo.incognito) ::cantInviteIncognitoAlert else addMembers @@ -350,7 +355,24 @@ private fun GroupLinkButton() { } @Composable -private fun EditGroupProfileButton() { +private fun CreateGroupLinkButton() { + Row( + Modifier + .fillMaxSize(), + verticalAlignment = Alignment.CenterVertically + ) { + Icon( + Icons.Outlined.AddLink, + stringResource(R.string.create_group_link), + tint = HighOrLowlight + ) + Spacer(Modifier.size(8.dp)) + Text(stringResource(R.string.create_group_link)) + } +} + +@Composable +fun EditGroupProfileButton() { Row( Modifier .fillMaxSize(), @@ -411,6 +433,7 @@ fun PreviewGroupChatInfoLayout() { groupInfo = GroupInfo.sampleData, members = listOf(GroupMember.sampleData, GroupMember.sampleData, GroupMember.sampleData), developerTools = false, + groupLink = null, addMembers = {}, showMemberInfo = {}, editGroupProfile = {}, openPreferences = {}, deleteGroup = {}, clearChat = {}, leaveGroup = {}, manageGroupLink = {}, ) } diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chat/group/GroupLinkView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chat/group/GroupLinkView.kt index 86c884478c..40296db1d6 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chat/group/GroupLinkView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chat/group/GroupLinkView.kt @@ -5,6 +5,7 @@ import androidx.compose.material.Text import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.* import androidx.compose.runtime.* +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -21,16 +22,27 @@ import chat.simplex.app.views.helpers.* import chat.simplex.app.views.newchat.QRCode @Composable -fun GroupLinkView(chatModel: ChatModel, groupInfo: GroupInfo, connReqContact: String?) { - var groupLink by remember { mutableStateOf(connReqContact) } +fun GroupLinkView(chatModel: ChatModel, groupInfo: GroupInfo, connReqContact: String?, onGroupLinkUpdated: (String?) -> Unit) { + var groupLink by rememberSaveable { mutableStateOf(connReqContact) } + var creatingLink by rememberSaveable { mutableStateOf(false) } val cxt = LocalContext.current + fun createLink() { + creatingLink = true + withApi { + groupLink = chatModel.controller.apiCreateGroupLink(groupInfo.groupId) + onGroupLinkUpdated(groupLink) + creatingLink = false + } + } + LaunchedEffect(Unit) { + if (groupLink == null && !creatingLink) { + createLink() + } + } GroupLinkLayout( groupLink = groupLink, - createLink = { - withApi { - groupLink = chatModel.controller.apiCreateGroupLink(groupInfo.groupId) - } - }, + creatingLink, + createLink = ::createLink, share = { shareText(cxt, groupLink ?: return@GroupLinkLayout) }, deleteLink = { AlertManager.shared.showAlertMsg( @@ -42,6 +54,7 @@ fun GroupLinkView(chatModel: ChatModel, groupInfo: GroupInfo, connReqContact: St val r = chatModel.controller.apiDeleteGroupLink(groupInfo.groupId) if (r) { groupLink = null + onGroupLinkUpdated(null) } } } @@ -53,6 +66,7 @@ fun GroupLinkView(chatModel: ChatModel, groupInfo: GroupInfo, connReqContact: St @Composable fun GroupLinkLayout( groupLink: String?, + creatingLink: Boolean, createLink: () -> Unit, share: () -> Unit, deleteLink: () -> Unit @@ -74,7 +88,7 @@ fun GroupLinkLayout( verticalArrangement = Arrangement.SpaceEvenly ) { if (groupLink == null) { - SimpleButton(stringResource(R.string.button_create_group_link), icon = Icons.Outlined.AddLink, click = createLink) + SimpleButton(stringResource(R.string.button_create_group_link), icon = Icons.Outlined.AddLink, disabled = creatingLink, click = createLink) } else { QRCode(groupLink, Modifier.weight(1f, fill = false).aspectRatio(1f)) Row( diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/helpers/SimpleButton.kt b/apps/android/app/src/main/java/chat/simplex/app/views/helpers/SimpleButton.kt index d898126fef..5068dd837f 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/helpers/SimpleButton.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/helpers/SimpleButton.kt @@ -28,6 +28,22 @@ fun SimpleButton(text: String, icon: ImageVector, } } +@Composable +fun SimpleButton( + text: String, icon: ImageVector, + color: Color = MaterialTheme.colors.primary, + disabled: Boolean, + click: () -> Unit +) { + SimpleButtonFrame(click, disabled = disabled) { + Icon( + icon, text, tint = if (disabled) HighOrLowlight else color, + modifier = Modifier.padding(end = 8.dp) + ) + Text(text, style = MaterialTheme.typography.caption, color = if (disabled) HighOrLowlight else color) + } +} + @Composable fun SimpleButtonIconEnded( text: String, diff --git a/apps/android/app/src/main/res/values/strings.xml b/apps/android/app/src/main/res/values/strings.xml index afa07daeb0..c38fa57242 100644 --- a/apps/android/app/src/main/res/values/strings.xml +++ b/apps/android/app/src/main/res/values/strings.xml @@ -879,6 +879,7 @@ Leave group Edit group profile Group link + Create group link Create link Delete link? Delete link