mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2024-12-17 17:20:21 +01:00
profile picker modal for external shares
This commit is contained in:
+21
-14
@@ -35,7 +35,7 @@ fun ShareListView(chatModel: ChatModel, settingsState: SettingsViewState, stoppe
|
||||
topBar = {
|
||||
if (!oneHandUI.value) {
|
||||
Column {
|
||||
ShareListToolbar(chatModel, userPickerState, stopped) { searchInList = it.trim() }
|
||||
ShareListToolbar(chatModel, stopped) { searchInList = it.trim() }
|
||||
Divider()
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@ fun ShareListView(chatModel: ChatModel, settingsState: SettingsViewState, stoppe
|
||||
if (oneHandUI.value) {
|
||||
Column {
|
||||
Divider()
|
||||
ShareListToolbar(chatModel, userPickerState, stopped) { searchInList = it.trim() }
|
||||
ShareListToolbar(chatModel, stopped) { searchInList = it.trim() }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,16 +92,6 @@ fun ShareListView(chatModel: ChatModel, settingsState: SettingsViewState, stoppe
|
||||
}
|
||||
}
|
||||
}
|
||||
if (appPlatform.isAndroid) {
|
||||
tryOrShowError("UserPicker", error = {}) {
|
||||
UserPicker(
|
||||
chatModel,
|
||||
userPickerState,
|
||||
contentAlignment = if (oneHandUI.value) Alignment.BottomStart else Alignment.TopStart,
|
||||
drawerState = scaffoldState.drawerState,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun hasSimplexLink(msg: String): Boolean {
|
||||
@@ -117,7 +107,7 @@ private fun EmptyList() {
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ShareListToolbar(chatModel: ChatModel, userPickerState: MutableStateFlow<AnimatedViewState>, stopped: Boolean, onSearchValueChanged: (String) -> Unit) {
|
||||
private fun ShareListToolbar(chatModel: ChatModel, stopped: Boolean, onSearchValueChanged: (String) -> Unit) {
|
||||
var showSearch by rememberSaveable { mutableStateOf(false) }
|
||||
val hideSearchOnBack = { onSearchValueChanged(""); showSearch = false }
|
||||
if (showSearch) {
|
||||
@@ -133,7 +123,24 @@ private fun ShareListToolbar(chatModel: ChatModel, userPickerState: MutableState
|
||||
.filter { u -> !u.user.activeUser && !u.user.hidden }
|
||||
.all { u -> u.unreadCount == 0 }
|
||||
UserProfileButton(chatModel.currentUser.value?.profile?.image, allRead) {
|
||||
userPickerState.value = AnimatedViewState.VISIBLE
|
||||
if (appPlatform.isAndroid) {
|
||||
ModalManager.start.showCustomModal { close ->
|
||||
val search = rememberSaveable { mutableStateOf("") }
|
||||
ModalView(
|
||||
{ close() },
|
||||
endButtons = {
|
||||
SearchTextField(Modifier.fillMaxWidth(), placeholder = stringResource(MR.strings.search_verb), alwaysVisible = true) { search.value = it }
|
||||
},
|
||||
content = {
|
||||
ShareListUserPicker(
|
||||
chatModel = chatModel,
|
||||
search = search,
|
||||
close = close,
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> NavigationButtonBack(onButtonClicked = {
|
||||
|
||||
+81
-1
@@ -8,11 +8,13 @@ import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.interaction.collectIsHoveredAsState
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.shape.*
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.ui.*
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
@@ -32,11 +34,11 @@ import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.common.platform.*
|
||||
import chat.simplex.common.views.CreateProfile
|
||||
import chat.simplex.common.views.newchat.*
|
||||
import chat.simplex.common.views.remote.*
|
||||
import chat.simplex.common.views.usersettings.*
|
||||
import chat.simplex.common.views.usersettings.AppearanceScope.ColorModeSwitcher
|
||||
import chat.simplex.res.MR
|
||||
import dev.icerock.moko.resources.ImageResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.*
|
||||
@@ -51,6 +53,84 @@ private fun UserPickerOptionRow(icon: Painter, text: String, click: (() -> Unit)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ShareListUserPicker(
|
||||
chatModel: ChatModel,
|
||||
search: MutableState<String>,
|
||||
close: () -> Unit,
|
||||
) {
|
||||
val switchingProfile = remember { mutableStateOf(false) }
|
||||
val searchTextOrPassword = rememberSaveable { search }
|
||||
val profiles = remember {
|
||||
chatModel.users.map { it.user }.sortedBy { !it.activeUser }
|
||||
}
|
||||
val filteredProfiles by remember {
|
||||
derivedStateOf { filteredProfiles(profiles, searchTextOrPassword.value) }
|
||||
}
|
||||
|
||||
var progressByTimeout by rememberSaveable { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(switchingProfile.value) {
|
||||
progressByTimeout = if (switchingProfile.value) {
|
||||
delay(500)
|
||||
switchingProfile.value
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
BoxWithConstraints {
|
||||
Column(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.alpha(if (progressByTimeout) 0.6f else 1f)
|
||||
) {
|
||||
LazyColumnWithScrollBar(userScrollEnabled = !switchingProfile.value) {
|
||||
item {
|
||||
AppBarTitle(stringResource(MR.strings.select_chat_profile), hostDevice(chatModel.remoteHostId), bottomPadding = DEFAULT_PADDING)
|
||||
}
|
||||
|
||||
itemsIndexed(filteredProfiles) { _, p ->
|
||||
ProfilePickerOption(
|
||||
title = p.chatViewName,
|
||||
disabled = switchingProfile.value || p.activeUser,
|
||||
image = { ProfileImage(size = 42.dp, image = p.image) },
|
||||
selected = p.activeUser,
|
||||
onSelected = {
|
||||
switchingProfile.value = true
|
||||
withApi {
|
||||
try {
|
||||
controller.changeActiveUser(
|
||||
rhId = p.remoteHostId,
|
||||
toUserId = p.userId,
|
||||
viewPwd = if (p.hidden) searchTextOrPassword.value else null
|
||||
)
|
||||
|
||||
if (chatModel.currentUser.value?.userId != p.userId) {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
generalGetString(
|
||||
MR.strings.switching_profile_error_title
|
||||
),
|
||||
String.format(generalGetString(MR.strings.switching_profile_error_message), p.chatViewName)
|
||||
)
|
||||
}
|
||||
|
||||
close.invoke()
|
||||
} finally {
|
||||
switchingProfile.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (progressByTimeout) {
|
||||
DefaultProgressView("")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun UsersLayout(
|
||||
chatModel: ChatModel,
|
||||
|
||||
+2
-2
@@ -208,7 +208,7 @@ private fun RetryButton(onClick: () -> Unit) {
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ProfilePickerOption(
|
||||
fun ProfilePickerOption(
|
||||
title: String,
|
||||
selected: Boolean,
|
||||
disabled: Boolean,
|
||||
@@ -267,7 +267,7 @@ private fun ProfilePickerOption(
|
||||
)
|
||||
}
|
||||
|
||||
private fun filteredProfiles(users: List<User>, searchTextOrPassword: String): List<User> {
|
||||
fun filteredProfiles(users: List<User>, searchTextOrPassword: String): List<User> {
|
||||
val s = searchTextOrPassword.trim()
|
||||
val lower = s.lowercase()
|
||||
return users.filter { u ->
|
||||
|
||||
Reference in New Issue
Block a user