mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2025-06-29 04:39:53 +00:00
android: ability to change profile from share dialog, mobile: do not show profile dropdown when there is only one visible profile (#2084)
* android: ability to change profile from share dialog * icons swap
This commit is contained in:
parent
48b4b23204
commit
f5c11b8faf
5 changed files with 65 additions and 16 deletions
|
@ -208,7 +208,7 @@ private fun ChatListToolbar(chatModel: ChatModel, drawerState: DrawerState, user
|
||||||
} else if (chatModel.users.isEmpty()) {
|
} else if (chatModel.users.isEmpty()) {
|
||||||
NavigationButtonMenu { scope.launch { if (drawerState.isOpen) drawerState.close() else drawerState.open() } }
|
NavigationButtonMenu { scope.launch { if (drawerState.isOpen) drawerState.close() else drawerState.open() } }
|
||||||
} else {
|
} 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
|
val allRead = users
|
||||||
.filter { u -> !u.user.activeUser && !u.user.hidden }
|
.filter { u -> !u.user.activeUser && !u.user.hidden }
|
||||||
.all { u -> u.unreadCount == 0 }
|
.all { u -> u.unreadCount == 0 }
|
||||||
|
@ -247,7 +247,7 @@ private fun ChatListToolbar(chatModel: ChatModel, drawerState: DrawerState, user
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun UserProfileButton(image: String?, allRead: Boolean, onButtonClicked: () -> Unit) {
|
fun UserProfileButton(image: String?, allRead: Boolean, onButtonClicked: () -> Unit) {
|
||||||
IconButton(onClick = onButtonClicked) {
|
IconButton(onClick = onButtonClicked) {
|
||||||
Box {
|
Box {
|
||||||
ProfileImage(
|
ProfileImage(
|
||||||
|
|
|
@ -24,12 +24,15 @@ import chat.simplex.app.model.*
|
||||||
import chat.simplex.app.ui.theme.HighOrLowlight
|
import chat.simplex.app.ui.theme.HighOrLowlight
|
||||||
import chat.simplex.app.ui.theme.Indigo
|
import chat.simplex.app.ui.theme.Indigo
|
||||||
import chat.simplex.app.views.helpers.*
|
import chat.simplex.app.views.helpers.*
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ShareListView(chatModel: ChatModel, stopped: Boolean) {
|
fun ShareListView(chatModel: ChatModel, stopped: Boolean) {
|
||||||
var searchInList by rememberSaveable { mutableStateOf("") }
|
var searchInList by rememberSaveable { mutableStateOf("") }
|
||||||
|
val userPickerState by rememberSaveable(stateSaver = AnimatedViewState.saver()) { mutableStateOf(MutableStateFlow(AnimatedViewState.GONE)) }
|
||||||
|
val switchingUsers = rememberSaveable { mutableStateOf(false) }
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = { Column { ShareListToolbar(chatModel, stopped) { searchInList = it.trim() } } },
|
topBar = { Column { ShareListToolbar(chatModel, userPickerState, stopped) { searchInList = it.trim() } } },
|
||||||
) {
|
) {
|
||||||
Box(Modifier.padding(it)) {
|
Box(Modifier.padding(it)) {
|
||||||
Column(
|
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
|
@Composable
|
||||||
private fun EmptyList() {
|
private fun EmptyList() {
|
||||||
Box {
|
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||||
Text(stringResource(R.string.you_have_no_chats), Modifier.align(Alignment.Center), color = HighOrLowlight)
|
Text(stringResource(R.string.you_have_no_chats), color = HighOrLowlight)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ShareListToolbar(chatModel: ChatModel, stopped: Boolean, onSearchValueChanged: (String) -> Unit) {
|
private fun ShareListToolbar(chatModel: ChatModel, userPickerState: MutableStateFlow<AnimatedViewState>, stopped: Boolean, onSearchValueChanged: (String) -> Unit) {
|
||||||
var showSearch by rememberSaveable { mutableStateOf(false) }
|
var showSearch by rememberSaveable { mutableStateOf(false) }
|
||||||
val hideSearchOnBack = { onSearchValueChanged(""); showSearch = false }
|
val hideSearchOnBack = { onSearchValueChanged(""); showSearch = false }
|
||||||
if (showSearch) {
|
if (showSearch) {
|
||||||
BackHandler(onBack = hideSearchOnBack)
|
BackHandler(onBack = hideSearchOnBack)
|
||||||
}
|
}
|
||||||
val barButtons = arrayListOf<@Composable RowScope.() -> Unit>()
|
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) {
|
if (chatModel.chats.size >= 8) {
|
||||||
barButtons.add {
|
barButtons.add {
|
||||||
IconButton({ showSearch = true }) {
|
IconButton({ showSearch = true }) {
|
||||||
|
@ -87,7 +108,7 @@ private fun ShareListToolbar(chatModel: ChatModel, stopped: Boolean, onSearchVal
|
||||||
}
|
}
|
||||||
|
|
||||||
DefaultTopAppBar(
|
DefaultTopAppBar(
|
||||||
navigationButton = { if (showSearch) NavigationButtonBack(hideSearchOnBack) else NavigationButtonBack { chatModel.sharedContent.value = null } },
|
navigationButton = navButton,
|
||||||
title = {
|
title = {
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
Text(
|
Text(
|
||||||
|
|
|
@ -34,7 +34,15 @@ import kotlinx.coroutines.launch
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun UserPicker(chatModel: ChatModel, userPickerState: MutableStateFlow<AnimatedViewState>, switchingUsers: MutableState<Boolean>, openSettings: () -> Unit) {
|
fun UserPicker(
|
||||||
|
chatModel: ChatModel,
|
||||||
|
userPickerState: MutableStateFlow<AnimatedViewState>,
|
||||||
|
switchingUsers: MutableState<Boolean>,
|
||||||
|
showSettings: Boolean = true,
|
||||||
|
showCancel: Boolean = false,
|
||||||
|
cancelClicked: () -> Unit = {},
|
||||||
|
settingsClicked: () -> Unit = {},
|
||||||
|
) {
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
var newChat by remember { mutableStateOf(userPickerState.value) }
|
var newChat by remember { mutableStateOf(userPickerState.value) }
|
||||||
val users by remember {
|
val users by remember {
|
||||||
|
@ -101,12 +109,12 @@ fun UserPicker(chatModel: ChatModel, userPickerState: MutableStateFlow<AnimatedV
|
||||||
.width(IntrinsicSize.Min)
|
.width(IntrinsicSize.Min)
|
||||||
.height(IntrinsicSize.Min)
|
.height(IntrinsicSize.Min)
|
||||||
.shadow(8.dp, MaterialTheme.shapes.medium, clip = false)
|
.shadow(8.dp, MaterialTheme.shapes.medium, clip = false)
|
||||||
.background(MaterialTheme.colors.background, MaterialTheme.shapes.medium)
|
.background(if (isInDarkTheme()) MaterialTheme.colors.background.darker(-0.7f) else MaterialTheme.colors.background, MaterialTheme.shapes.medium)
|
||||||
) {
|
) {
|
||||||
Column(Modifier.weight(1f).verticalScroll(rememberScrollState())) {
|
Column(Modifier.weight(1f).verticalScroll(rememberScrollState())) {
|
||||||
users.forEach { u ->
|
users.forEach { u ->
|
||||||
UserProfilePickerItem(u.user, u.unreadCount, openSettings = {
|
UserProfilePickerItem(u.user, u.unreadCount, openSettings = {
|
||||||
openSettings()
|
settingsClicked()
|
||||||
userPickerState.value = AnimatedViewState.GONE
|
userPickerState.value = AnimatedViewState.GONE
|
||||||
}) {
|
}) {
|
||||||
userPickerState.value = AnimatedViewState.HIDING
|
userPickerState.value = AnimatedViewState.HIDING
|
||||||
|
@ -126,9 +134,17 @@ fun UserPicker(chatModel: ChatModel, userPickerState: MutableStateFlow<AnimatedV
|
||||||
if (u.user.activeUser) Divider(Modifier.requiredHeight(0.5.dp))
|
if (u.user.activeUser) Divider(Modifier.requiredHeight(0.5.dp))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SettingsPickerItem {
|
if (showSettings) {
|
||||||
openSettings()
|
SettingsPickerItem {
|
||||||
userPickerState.value = AnimatedViewState.GONE
|
settingsClicked()
|
||||||
|
userPickerState.value = AnimatedViewState.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (showCancel) {
|
||||||
|
CancelPickerItem {
|
||||||
|
cancelClicked()
|
||||||
|
userPickerState.value = AnimatedViewState.GONE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,3 +227,15 @@ private fun SettingsPickerItem(onClick: () -> Unit) {
|
||||||
Icon(Icons.Outlined.Settings, text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground)
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -216,12 +216,12 @@ private fun UserView(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (user.showNtfs) {
|
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
|
showDropdownMenu = false
|
||||||
muteUser(user)
|
muteUser(user)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
ItemAction(stringResource(R.string.user_unmute), Icons.Outlined.NotificationsOff, onClick = {
|
ItemAction(stringResource(R.string.user_unmute), Icons.Outlined.Notifications, onClick = {
|
||||||
showDropdownMenu = false
|
showDropdownMenu = false
|
||||||
unmuteUser(user)
|
unmuteUser(user)
|
||||||
})
|
})
|
||||||
|
|
|
@ -71,7 +71,7 @@ struct ChatListView: View {
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarItem(placement: .navigationBarLeading) {
|
ToolbarItem(placement: .navigationBarLeading) {
|
||||||
Button {
|
Button {
|
||||||
if chatModel.users.count > 1 {
|
if chatModel.users.filter { u in u.user.activeUser || !u.user.hidden }.count > 1 {
|
||||||
withAnimation {
|
withAnimation {
|
||||||
userPickerVisible.toggle()
|
userPickerVisible.toggle()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue