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 5d4e8c904..a9b85c3dc 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 @@ -163,6 +163,10 @@ class ChatModel(val controller: ChatController) { val pItem = chat.chatItems.lastOrNull() if (pItem?.id == cItem.id) { chats[i] = chat.copy(chatItems = arrayListOf(cItem)) + if (pItem.isRcvNew && !cItem.isRcvNew) { + // status changed from New to Read, update counter + decreaseCounterInChat(cInfo.id) + } } res = false } else { @@ -251,6 +255,18 @@ class ChatModel(val controller: ChatController) { return markedRead } + private fun decreaseCounterInChat(chatId: ChatId) { + val chatIndex = getChatIndex(chatId) + if (chatIndex == -1) return + + val chat = chats[chatIndex] + chats[chatIndex] = chat.copy( + chatStats = chat.chatStats.copy( + unreadCount = kotlin.math.max(chat.chatStats.unreadCount - 1, 0), + ) + ) + } + // func popChat(_ id: String) { // if let i = getChatIndex(id) { // popChat_(i) diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatInfoView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatInfoView.kt index 6ed71d295..dc7deb6b3 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatInfoView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chat/ChatInfoView.kt @@ -64,42 +64,10 @@ fun ChatInfoView( }, deleteContact = { deleteContactDialog(chat.chatInfo, chatModel, close) }, clearChat = { clearChatDialog(chat.chatInfo, chatModel, close) }, - changeNtfsState = { enabled -> - changeNtfsState(enabled, chat, chatModel) - }, ) } } -fun changeNtfsState(enabled: Boolean, chat: Chat, chatModel: ChatModel) { - val newChatInfo = when(chat.chatInfo) { - is ChatInfo.Direct -> with (chat.chatInfo) { - ChatInfo.Direct(contact.copy(chatSettings = contact.chatSettings.copy(enableNtfs = enabled))) - } - is ChatInfo.Group -> with(chat.chatInfo) { - ChatInfo.Group(groupInfo.copy(chatSettings = groupInfo.chatSettings.copy(enableNtfs = enabled))) - } - else -> null - } - withApi { - val res = when (newChatInfo) { - is ChatInfo.Direct -> with(newChatInfo) { - chatModel.controller.apiSetSettings(chatType, apiId, contact.chatSettings) - } - is ChatInfo.Group -> with(newChatInfo) { - chatModel.controller.apiSetSettings(chatType, apiId, groupInfo.chatSettings) - } - else -> false - } - if (res && newChatInfo != null) { - chatModel.updateChatInfo(newChatInfo) - if (!enabled) { - chatModel.controller.ntfManager.cancelNotificationsForChat(chat.id) - } - } - } -} - fun deleteContactDialog(chatInfo: ChatInfo, chatModel: ChatModel, close: (() -> Unit)? = null) { AlertManager.shared.showAlertMsg( title = generalGetString(R.string.delete_contact_question), @@ -148,7 +116,6 @@ fun ChatInfoLayout( onLocalAliasChanged: (String) -> Unit, deleteContact: () -> Unit, clearChat: () -> Unit, - changeNtfsState: (Boolean) -> Unit, ) { Column( Modifier @@ -192,18 +159,6 @@ fun ChatInfoLayout( } SectionSpacer() } - - var ntfsEnabled by remember { mutableStateOf(chat.chatInfo.ntfsEnabled) } - SectionView(title = stringResource(R.string.settings_section_title_settings)) { - SectionItemView { - NtfsSwitch(ntfsEnabled) { - ntfsEnabled = !ntfsEnabled - changeNtfsState(ntfsEnabled) - } - } - } - SectionSpacer() - SectionView { SectionItemView { ClearChatButton(clearChat) @@ -350,38 +305,6 @@ fun SimplexServers(text: String, servers: List) { } } -@Composable -fun NtfsSwitch( - ntfsEnabled: Boolean, - toggleNtfs: (Boolean) -> Unit -) { - Row( - Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween - ) { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(8.dp) - ) { - Icon( - Icons.Outlined.Notifications, - stringResource(R.string.notifications), - tint = HighOrLowlight - ) - Text(stringResource(R.string.notifications)) - } - Switch( - checked = ntfsEnabled, - onCheckedChange = toggleNtfs, - colors = SwitchDefaults.colors( - checkedThumbColor = MaterialTheme.colors.primary, - uncheckedThumbColor = HighOrLowlight - ), - ) - } -} - @Composable fun ClearChatButton(clearChat: () -> Unit) { Row( @@ -437,7 +360,6 @@ fun PreviewChatInfoLayout() { ), Contact.sampleData, localAlias = "", - changeNtfsState = {}, developerTools = false, connStats = null, onLocalAliasChanged = {}, 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 c7c8c06d0..695a8148e 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 @@ -216,6 +216,7 @@ fun ChatView(chatModel: ChatModel) { ) } }, + changeNtfsState = { enabled, currentValue -> changeNtfsStatePerChat(enabled, currentValue, chat, chatModel) }, onSearchValueChanged = { value -> if (searchText.value == value) return@ChatLayout val c = chatModel.getChat(chat.chatInfo.id) ?: return@ChatLayout @@ -253,6 +254,7 @@ fun ChatLayout( acceptCall: (Contact) -> Unit, addMembers: (GroupInfo) -> Unit, markRead: (CC.ItemRange, unreadCountAfter: Int?) -> Unit, + changeNtfsState: (Boolean, currentValue: MutableState) -> Unit, onSearchValueChanged: (String) -> Unit, ) { Surface( @@ -279,7 +281,7 @@ fun ChatLayout( } Scaffold( - topBar = { ChatInfoToolbar(chat, back, info, startCall, addMembers, onSearchValueChanged) }, + topBar = { ChatInfoToolbar(chat, back, info, startCall, addMembers, changeNtfsState, onSearchValueChanged) }, bottomBar = composeView, modifier = Modifier.navigationBarsWithImePadding(), floatingActionButton = { floatingButton.value() }, @@ -304,8 +306,10 @@ fun ChatInfoToolbar( info: () -> Unit, startCall: (CallMediaType) -> Unit, addMembers: (GroupInfo) -> Unit, + changeNtfsState: (Boolean, currentValue: MutableState) -> Unit, onSearchValueChanged: (String) -> Unit, ) { + val scope = rememberCoroutineScope() var showMenu by rememberSaveable { mutableStateOf(false) } var showSearch by rememberSaveable { mutableStateOf(false) } val onBackClicked = { @@ -351,6 +355,23 @@ fun ChatInfoToolbar( } } } + + val ntfsEnabled = remember { mutableStateOf(chat.chatInfo.ntfsEnabled) } + menuItems.add { + ItemAction( + if (ntfsEnabled.value) stringResource(R.string.mute_chat) else stringResource(R.string.unmute_chat), + if (ntfsEnabled.value) Icons.Outlined.NotificationsOff else Icons.Outlined.Notifications, + onClick = { + showMenu = false + // Just to make a delay before changing state of ntfsEnabled, otherwise it will redraw menu item with new value before closing the menu + scope.launch { + delay(200) + changeNtfsState(!ntfsEnabled.value, ntfsEnabled) + } + } + ) + } + barButtons.add { IconButton({ showMenu = true }) { Icon(Icons.Default.MoreVert, stringResource(R.string.icon_descr_more_button), tint = MaterialTheme.colors.primary) @@ -839,6 +860,7 @@ fun PreviewChatLayout() { acceptCall = { _ -> }, addMembers = { _ -> }, markRead = { _, _ -> }, + changeNtfsState = { _, _ -> }, onSearchValueChanged = {}, ) } @@ -896,6 +918,7 @@ fun PreviewGroupChatLayout() { acceptCall = { _ -> }, addMembers = { _ -> }, markRead = { _, _ -> }, + changeNtfsState = { _, _ -> }, onSearchValueChanged = {}, ) } 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 587b3f40a..e76ef8db3 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 @@ -75,9 +75,6 @@ fun GroupChatInfoView(chatModel: ChatModel, close: () -> Unit) { deleteGroup = { deleteGroupDialog(chat.chatInfo, chatModel, close) }, clearChat = { clearChatDialog(chat.chatInfo, chatModel, close) }, leaveGroup = { leaveGroupDialog(groupInfo, chatModel, close) }, - changeNtfsState = { enabled -> - changeNtfsState(enabled, chat, chatModel) - }, ) } } @@ -127,7 +124,6 @@ fun GroupChatInfoLayout( deleteGroup: () -> Unit, clearChat: () -> Unit, leaveGroup: () -> Unit, - changeNtfsState: (Boolean) -> Unit, ) { Column( Modifier @@ -162,17 +158,6 @@ fun GroupChatInfoLayout( } SectionSpacer() - var ntfsEnabled by remember { mutableStateOf(chat.chatInfo.ntfsEnabled) } - SectionView(title = stringResource(R.string.settings_section_title_settings)) { - SectionItemView { - NtfsSwitch(ntfsEnabled) { - ntfsEnabled = !ntfsEnabled - changeNtfsState(ntfsEnabled) - } - } - } - SectionSpacer() - SectionView { if (groupInfo.canEdit) { SectionItemView { @@ -367,7 +352,6 @@ fun PreviewGroupChatInfoLayout() { members = listOf(GroupMember.sampleData, GroupMember.sampleData, GroupMember.sampleData), developerTools = false, addMembers = {}, showMemberInfo = {}, editGroupProfile = {}, deleteGroup = {}, clearChat = {}, leaveGroup = {}, - changeNtfsState = {}, ) } } diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatListNavLinkView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatListNavLinkView.kt index b8f4d8b1e..8754c098e 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatListNavLinkView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatListNavLinkView.kt @@ -168,7 +168,7 @@ fun ToggleNotificationsChatAction(chat: Chat, chatModel: ChatModel, ntfsEnabled: if (ntfsEnabled) stringResource(R.string.mute_chat) else stringResource(R.string.unmute_chat), if (ntfsEnabled) Icons.Outlined.NotificationsOff else Icons.Outlined.Notifications, onClick = { - changeNtfsState(!ntfsEnabled, chat, chatModel) + changeNtfsStatePerChat(!ntfsEnabled, mutableStateOf(ntfsEnabled), chat, chatModel) showMenu.value = false } ) @@ -424,6 +424,36 @@ fun groupInvitationAcceptedAlert() { ) } +fun changeNtfsStatePerChat(enabled: Boolean, currentState: MutableState, chat: Chat, chatModel: ChatModel) { + val newChatInfo = when(chat.chatInfo) { + is ChatInfo.Direct -> with (chat.chatInfo) { + ChatInfo.Direct(contact.copy(chatSettings = contact.chatSettings.copy(enableNtfs = enabled))) + } + is ChatInfo.Group -> with(chat.chatInfo) { + ChatInfo.Group(groupInfo.copy(chatSettings = groupInfo.chatSettings.copy(enableNtfs = enabled))) + } + else -> null + } + withApi { + val res = when (newChatInfo) { + is ChatInfo.Direct -> with(newChatInfo) { + chatModel.controller.apiSetSettings(chatType, apiId, contact.chatSettings) + } + is ChatInfo.Group -> with(newChatInfo) { + chatModel.controller.apiSetSettings(chatType, apiId, groupInfo.chatSettings) + } + else -> false + } + if (res && newChatInfo != null) { + chatModel.updateChatInfo(newChatInfo) + if (!enabled) { + chatModel.controller.ntfManager.cancelNotificationsForChat(chat.id) + } + currentState.value = enabled + } + } +} + @Composable fun ChatListNavLinkLayout( chatLinkPreview: @Composable () -> Unit, diff --git a/scripts/android/download_libs_aarch64.sh b/scripts/android/download_libs_aarch64.sh new file mode 100755 index 000000000..939ac16da --- /dev/null +++ b/scripts/android/download_libs_aarch64.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +set -e + +function readlink() { + echo $(cd $(dirname $1); pwd -P) +} + +if [ -z ${1} ]; then + echo "Job repo is unset. Provide it via first argument like: $(readlink $0)/download_libs_aarch64.sh https://something.com/job/something" + exit 1 +fi + +job_repo=$1 +arch="aarch64" +#arch="x86_64" +output_arch="arm64-v8a" +#output_arch="x86_64" + +root_dir="$(dirname $(dirname $(readlink $0)))" +output_dir="$root_dir/apps/android/app/src/main/cpp/libs/$output_arch/" + +mkdir -p "$output_dir" 2> /dev/null + +curl --location -o libsupport.zip $job_repo/simplex-chat-nix-android/$arch-android:lib:support.x86_64-linux/latest/download/1 && \ +unzip -o libsupport.zip && \ +mv libsupport.so "$output_dir" && \ +rm libsupport.zip + +curl --location -o libsimplex.zip $job_repo/simplex-chat-nix-android/$arch-android:lib:simplex-chat.x86_64-linux/latest/download/1 && \ +unzip -o libsimplex.zip && \ +mv libsimplex.so "$output_dir" && \ +rm libsimplex.zip