mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-21 04:29:45 +01:00
Merge pull request #4259 from nextcloud/password_improvement
Password improvement
This commit is contained in:
commit
0354501b41
@ -20,25 +20,31 @@ import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.result.ActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
@ -48,6 +54,7 @@ import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Switch
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.runtime.Composable
|
||||
@ -55,7 +62,7 @@ import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
@ -67,9 +74,11 @@ import androidx.compose.ui.platform.LocalView
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import autodagger.AutoInjector
|
||||
@ -436,6 +445,8 @@ fun RoomCreationOptions(conversationCreationViewModel: ConversationCreationViewM
|
||||
.isConversationAvailableForRegisteredUsers.value
|
||||
val isOpenForGuestAppUsers = conversationCreationViewModel.openForGuestAppUsers.value
|
||||
|
||||
val isPasswordSet = conversationCreationViewModel.isPasswordEnabled.value
|
||||
|
||||
Text(
|
||||
text = stringResource(id = R.string.nc_new_conversation_visibility).uppercase(),
|
||||
fontSize = 14.sp,
|
||||
@ -452,15 +463,21 @@ fun RoomCreationOptions(conversationCreationViewModel: ConversationCreationViewM
|
||||
}
|
||||
)
|
||||
},
|
||||
showDialog = false,
|
||||
conversationCreationViewModel = conversationCreationViewModel
|
||||
)
|
||||
|
||||
if (isGuestsAllowed) {
|
||||
if (isGuestsAllowed && !isPasswordSet) {
|
||||
ConversationOptions(
|
||||
icon = R.drawable.baseline_lock_open_24,
|
||||
text = R.string.nc_set_password,
|
||||
conversationCreationViewModel = conversationCreationViewModel
|
||||
)
|
||||
}
|
||||
|
||||
if (isGuestsAllowed && isPasswordSet) {
|
||||
ConversationOptions(
|
||||
icon = R.drawable.ic_lock_grey600_24px,
|
||||
text = R.string.nc_set_password,
|
||||
showDialog = true,
|
||||
text = R.string.nc_change_password,
|
||||
conversationCreationViewModel = conversationCreationViewModel
|
||||
)
|
||||
}
|
||||
@ -476,7 +493,6 @@ fun RoomCreationOptions(conversationCreationViewModel: ConversationCreationViewM
|
||||
}
|
||||
)
|
||||
},
|
||||
showDialog = false,
|
||||
conversationCreationViewModel = conversationCreationViewModel
|
||||
)
|
||||
|
||||
@ -491,7 +507,6 @@ fun RoomCreationOptions(conversationCreationViewModel: ConversationCreationViewM
|
||||
}
|
||||
)
|
||||
},
|
||||
showDialog = false,
|
||||
conversationCreationViewModel = conversationCreationViewModel
|
||||
)
|
||||
}
|
||||
@ -502,19 +517,23 @@ fun ConversationOptions(
|
||||
icon: Int? = null,
|
||||
text: Int,
|
||||
switch: @Composable (() -> Unit)? = null,
|
||||
showDialog: Boolean,
|
||||
conversationCreationViewModel: ConversationCreationViewModel
|
||||
) {
|
||||
var showPasswordDialog by remember { mutableStateOf(false) }
|
||||
var showPasswordDialog by rememberSaveable { mutableStateOf(false) }
|
||||
var showPasswordChangeDialog by rememberSaveable { mutableStateOf(false) }
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 16.dp, end = 16.dp, bottom = 8.dp)
|
||||
.then(
|
||||
if (showDialog) {
|
||||
if (!conversationCreationViewModel.isPasswordEnabled.value) {
|
||||
Modifier.clickable {
|
||||
showPasswordDialog = true
|
||||
}
|
||||
} else if (conversationCreationViewModel.isPasswordEnabled.value) {
|
||||
Modifier.clickable {
|
||||
showPasswordChangeDialog = true
|
||||
}
|
||||
} else {
|
||||
Modifier
|
||||
}
|
||||
@ -545,24 +564,99 @@ fun ConversationOptions(
|
||||
conversationCreationViewModel = conversationCreationViewModel
|
||||
)
|
||||
}
|
||||
if (showPasswordChangeDialog) {
|
||||
ShowChangePassword(
|
||||
onDismiss = {
|
||||
showPasswordChangeDialog = false
|
||||
},
|
||||
conversationCreationViewModel = conversationCreationViewModel
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ShowChangePassword(onDismiss: () -> Unit, conversationCreationViewModel: ConversationCreationViewModel) {
|
||||
var changedPassword by rememberSaveable { mutableStateOf("") }
|
||||
Dialog(onDismissRequest = {
|
||||
onDismiss()
|
||||
}) {
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(375.dp)
|
||||
.padding(32.dp)
|
||||
.clip(RoundedCornerShape(16.dp))
|
||||
.background(color = colorResource(id = R.color.appbar))
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(vertical = 16.dp, horizontal = 16.dp),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.nc_set_new_password), fontWeight = FontWeight.SemiBold)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
OutlinedTextField(
|
||||
value = changedPassword,
|
||||
onValueChange = {
|
||||
changedPassword = it
|
||||
},
|
||||
label = { Text(text = stringResource(id = R.string.nc_password)) },
|
||||
singleLine = true
|
||||
)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.padding(vertical = 8.dp),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
TextButton(
|
||||
onClick = {
|
||||
conversationCreationViewModel.updatePassword(changedPassword)
|
||||
conversationCreationViewModel.isPasswordEnabled.value = true
|
||||
onDismiss()
|
||||
},
|
||||
enabled = changedPassword.isNotEmpty() && changedPassword.isNotBlank(),
|
||||
contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp)
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.nc_change_password))
|
||||
}
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
TextButton(
|
||||
onClick = {
|
||||
conversationCreationViewModel.isPasswordEnabled.value = false
|
||||
onDismiss()
|
||||
},
|
||||
contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp)
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.nc_remove_password),
|
||||
color = colorResource(id = R.color.nc_darkRed)
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
TextButton(
|
||||
onClick = { onDismiss() },
|
||||
contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp)
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.nc_cancel))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ShowPasswordDialog(onDismiss: () -> Unit, conversationCreationViewModel: ConversationCreationViewModel) {
|
||||
var password by remember { mutableStateOf("") }
|
||||
|
||||
var password by rememberSaveable { mutableStateOf("") }
|
||||
AlertDialog(
|
||||
containerColor = colorResource(id = R.color.dialog_background),
|
||||
onDismissRequest = onDismiss,
|
||||
confirmButton = {
|
||||
Button(onClick = {
|
||||
conversationCreationViewModel.updatePassword(password)
|
||||
onDismiss()
|
||||
}) {
|
||||
Text(text = stringResource(id = R.string.save))
|
||||
}
|
||||
},
|
||||
title = { Text(text = stringResource(id = R.string.nc_set_password)) },
|
||||
text = {
|
||||
TextField(
|
||||
@ -573,8 +667,20 @@ fun ShowPasswordDialog(onDismiss: () -> Unit, conversationCreationViewModel: Con
|
||||
label = { Text(text = stringResource(id = R.string.nc_guest_access_password_dialog_hint)) }
|
||||
)
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
if (password.isNotEmpty() && password.isNotBlank()) {
|
||||
conversationCreationViewModel.updatePassword(password)
|
||||
conversationCreationViewModel.isPasswordEnabled(true)
|
||||
}
|
||||
}
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.save))
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
Button(onClick = { onDismiss() }) {
|
||||
TextButton(onClick = { onDismiss() }) {
|
||||
Text(text = stringResource(id = R.string.nc_cancel))
|
||||
}
|
||||
}
|
||||
|
@ -38,14 +38,20 @@ class ConversationCreationViewModel @Inject constructor(
|
||||
private val _currentUser = userManager.currentUser.blockingGet()
|
||||
val currentUser: User = _currentUser
|
||||
|
||||
private val _isPasswordEnabled = mutableStateOf(false)
|
||||
val isPasswordEnabled = _isPasswordEnabled
|
||||
|
||||
fun updateSelectedParticipants(participants: List<AutocompleteUser>) {
|
||||
_selectedParticipants.value = participants
|
||||
}
|
||||
|
||||
fun isPasswordEnabled(value: Boolean) {
|
||||
_isPasswordEnabled.value = value
|
||||
}
|
||||
|
||||
fun updateSelectedImageUri(uri: Uri?) {
|
||||
_selectedImageUri.value = uri
|
||||
}
|
||||
|
||||
private val _roomName = MutableStateFlow("")
|
||||
val roomName: StateFlow<String> = _roomName
|
||||
private val _password = MutableStateFlow("")
|
||||
|
18
app/src/main/res/drawable/baseline_lock_open_24.xml
Normal file
18
app/src/main/res/drawable/baseline_lock_open_24.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<!--
|
||||
~ Nextcloud Talk - Android Client
|
||||
~
|
||||
~ SPDX-FileCopyrightText: 2024 Google LLC
|
||||
~ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:tint="#000000"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24"
|
||||
android:width="24dp">
|
||||
|
||||
<path android:fillColor="@android:color/white"
|
||||
android:pathData="M12,17c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6h1.9c0,-1.71 1.39,-3.1 3.1,-3.1 1.71,0 3.1,1.39 3.1,3.1v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM18,20L6,20L6,10h12v10z"/>
|
||||
|
||||
</vector>
|
@ -434,6 +434,10 @@ How to translate with transifex:
|
||||
<string name="nc_guest_access_allow_summary">Allow guests to share a public link to join this conversation.</string>
|
||||
<string name="nc_guest_access_allow_failed">Cannot enable/disable guest access.</string>
|
||||
<string name="nc_set_password">Set Password</string>
|
||||
<string name="nc_password">Password</string>
|
||||
<string name="nc_change_password">Change Password</string>
|
||||
<string name="nc_remove_password">Remove Password</string>
|
||||
<string name="nc_set_new_password">Set new password</string>
|
||||
<string name="nc_guest_access_password_title">Password protection</string>
|
||||
<string name="nc_guest_access_password_summary">Set a password to restrict who can use the public link.</string>
|
||||
<string name="nc_guest_access_password_dialog_title">Guest access password</string>
|
||||
|
Loading…
Reference in New Issue
Block a user