diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatListView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatListView.kt index f8501afbe..86647a0ef 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatListView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ChatListView.kt @@ -208,7 +208,7 @@ private fun ChatListToolbar(chatModel: ChatModel, drawerState: DrawerState, user } else if (chatModel.users.isEmpty()) { NavigationButtonMenu { scope.launch { if (drawerState.isOpen) drawerState.close() else drawerState.open() } } } else { - val users by remember { derivedStateOf { chatModel.users.toList() } } + val users by remember { derivedStateOf { chatModel.users.filter { u -> u.user.activeUser || !u.user.hidden } } } val allRead = users .filter { u -> !u.user.activeUser && !u.user.hidden } .all { u -> u.unreadCount == 0 } @@ -247,7 +247,7 @@ private fun ChatListToolbar(chatModel: ChatModel, drawerState: DrawerState, user } @Composable -private fun UserProfileButton(image: String?, allRead: Boolean, onButtonClicked: () -> Unit) { +fun UserProfileButton(image: String?, allRead: Boolean, onButtonClicked: () -> Unit) { IconButton(onClick = onButtonClicked) { Box { ProfileImage( diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ShareListView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ShareListView.kt index 8c8b20fc1..bd97135c4 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ShareListView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/ShareListView.kt @@ -24,12 +24,15 @@ import chat.simplex.app.model.* import chat.simplex.app.ui.theme.HighOrLowlight import chat.simplex.app.ui.theme.Indigo import chat.simplex.app.views.helpers.* +import kotlinx.coroutines.flow.MutableStateFlow @Composable fun ShareListView(chatModel: ChatModel, stopped: Boolean) { var searchInList by rememberSaveable { mutableStateOf("") } + val userPickerState by rememberSaveable(stateSaver = AnimatedViewState.saver()) { mutableStateOf(MutableStateFlow(AnimatedViewState.GONE)) } + val switchingUsers = rememberSaveable { mutableStateOf(false) } Scaffold( - topBar = { Column { ShareListToolbar(chatModel, stopped) { searchInList = it.trim() } } }, + topBar = { Column { ShareListToolbar(chatModel, userPickerState, stopped) { searchInList = it.trim() } } }, ) { Box(Modifier.padding(it)) { Column( @@ -45,23 +48,41 @@ fun ShareListView(chatModel: ChatModel, stopped: Boolean) { } } } + UserPicker(chatModel, userPickerState, switchingUsers, showSettings = false, showCancel = true, cancelClicked = { + chatModel.sharedContent.value = null + }) } @Composable private fun EmptyList() { - Box { - Text(stringResource(R.string.you_have_no_chats), Modifier.align(Alignment.Center), color = HighOrLowlight) + Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { + Text(stringResource(R.string.you_have_no_chats), color = HighOrLowlight) } } @Composable -private fun ShareListToolbar(chatModel: ChatModel, stopped: Boolean, onSearchValueChanged: (String) -> Unit) { +private fun ShareListToolbar(chatModel: ChatModel, userPickerState: MutableStateFlow, stopped: Boolean, onSearchValueChanged: (String) -> Unit) { var showSearch by rememberSaveable { mutableStateOf(false) } val hideSearchOnBack = { onSearchValueChanged(""); showSearch = false } if (showSearch) { BackHandler(onBack = hideSearchOnBack) } val barButtons = arrayListOf<@Composable RowScope.() -> Unit>() + val users by remember { derivedStateOf { chatModel.users.filter { u -> u.user.activeUser || !u.user.hidden } } } + val navButton: @Composable RowScope.() -> Unit = { + when { + showSearch -> NavigationButtonBack(hideSearchOnBack) + users.size > 1 -> { + val allRead = users + .filter { u -> !u.user.activeUser && !u.user.hidden } + .all { u -> u.unreadCount == 0 } + UserProfileButton(chatModel.currentUser.value?.profile?.image, allRead) { + userPickerState.value = AnimatedViewState.VISIBLE + } + } + else -> NavigationButtonBack { chatModel.sharedContent.value = null } + } + } if (chatModel.chats.size >= 8) { barButtons.add { IconButton({ showSearch = true }) { @@ -87,7 +108,7 @@ private fun ShareListToolbar(chatModel: ChatModel, stopped: Boolean, onSearchVal } DefaultTopAppBar( - navigationButton = { if (showSearch) NavigationButtonBack(hideSearchOnBack) else NavigationButtonBack { chatModel.sharedContent.value = null } }, + navigationButton = navButton, title = { Row(verticalAlignment = Alignment.CenterVertically) { Text( diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/UserPicker.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/UserPicker.kt index b7d3185e3..5d3769561 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/UserPicker.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chatlist/UserPicker.kt @@ -34,7 +34,15 @@ import kotlinx.coroutines.launch import kotlin.math.roundToInt @Composable -fun UserPicker(chatModel: ChatModel, userPickerState: MutableStateFlow, switchingUsers: MutableState, openSettings: () -> Unit) { +fun UserPicker( + chatModel: ChatModel, + userPickerState: MutableStateFlow, + switchingUsers: MutableState, + showSettings: Boolean = true, + showCancel: Boolean = false, + cancelClicked: () -> Unit = {}, + settingsClicked: () -> Unit = {}, +) { val scope = rememberCoroutineScope() var newChat by remember { mutableStateOf(userPickerState.value) } val users by remember { @@ -101,12 +109,12 @@ fun UserPicker(chatModel: ChatModel, userPickerState: MutableStateFlow UserProfilePickerItem(u.user, u.unreadCount, openSettings = { - openSettings() + settingsClicked() userPickerState.value = AnimatedViewState.GONE }) { userPickerState.value = AnimatedViewState.HIDING @@ -126,9 +134,17 @@ fun UserPicker(chatModel: ChatModel, userPickerState: MutableStateFlow Unit) { Icon(Icons.Outlined.Settings, text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground) } } + +@Composable +private fun CancelPickerItem(onClick: () -> Unit) { + SectionItemViewSpaceBetween(onClick, minHeight = 68.dp) { + val text = generalGetString(R.string.cancel_verb) + Text( + text, + color = MaterialTheme.colors.onBackground, + ) + Icon(Icons.Outlined.Close, text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground) + } +} diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/UserProfilesView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/UserProfilesView.kt index 54885ac73..960da1a88 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/UserProfilesView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/UserProfilesView.kt @@ -216,12 +216,12 @@ private fun UserView( }) } if (user.showNtfs) { - ItemAction(stringResource(R.string.user_mute), Icons.Outlined.Notifications, onClick = { + ItemAction(stringResource(R.string.user_mute), Icons.Outlined.NotificationsOff, onClick = { showDropdownMenu = false muteUser(user) }) } else { - ItemAction(stringResource(R.string.user_unmute), Icons.Outlined.NotificationsOff, onClick = { + ItemAction(stringResource(R.string.user_unmute), Icons.Outlined.Notifications, onClick = { showDropdownMenu = false unmuteUser(user) }) diff --git a/apps/ios/Shared/Views/ChatList/ChatListView.swift b/apps/ios/Shared/Views/ChatList/ChatListView.swift index 0b2a3f1a9..78ed48ed2 100644 --- a/apps/ios/Shared/Views/ChatList/ChatListView.swift +++ b/apps/ios/Shared/Views/ChatList/ChatListView.swift @@ -71,7 +71,7 @@ struct ChatListView: View { .toolbar { ToolbarItem(placement: .navigationBarLeading) { Button { - if chatModel.users.count > 1 { + if chatModel.users.filter { u in u.user.activeUser || !u.user.hidden }.count > 1 { withAnimation { userPickerVisible.toggle() }