password fill

This commit is contained in:
shipovnikaaa 2025-02-19 12:14:38 +03:00
parent 8cdf504893
commit 52b4723ca9
8 changed files with 57 additions and 12 deletions

View File

@ -1,6 +1,6 @@
package ru.myitschool.work.core package ru.myitschool.work.core
// БЕРИТЕ И ИЗМЕНЯЙТЕ ХОСТ ТОЛЬКО ЗДЕСЬ И НЕ БЕРИТЕ ИЗ ДРУГИХ МЕСТ. ФАЙЛ ПЕРЕМЕЩАТЬ НЕЛЬЗЯ // БЕРИТЕ И ИЗМЕНЯЙТЕ ХОСТ ТОЛЬКО ЗДЕСЬ И НЕ БЕРИТЕ ИЗ ДРУГИХ МЕСТ. ФАЙЛ ПЕРЕМЕЩАТЬ НЕЛЬЗЯ
object Constants { object Constants {
const val SERVER_ADDRESS = "http://localhost:8090/api/" const val SERVER_ADDRESS = "http://10.0.2.2:8090/api/"
//const val SERVER_ADDRESS = "http://192.168.1.73:8080/api/" //const val SERVER_ADDRESS = "http://192.168.1.73:8080/api/"
} }

View File

@ -37,11 +37,21 @@ object AppModule {
@Singleton @Singleton
class DataStoreManager @Inject constructor(@ApplicationContext appContext: Context) { class DataStoreManager @Inject constructor(@ApplicationContext appContext: Context) {
private val settingsDataStore = appContext.dataStore private val settingsDataStore = appContext.dataStore
private val lastUsernameKey = stringPreferencesKey("last_username") private val lastUsernameKey = stringPreferencesKey("last_username")
private val lastPasswordKey = stringPreferencesKey("last_password")
val lastUsername: Flow<String> val lastUsername: Flow<String>
get() = settingsDataStore.data.map { it[lastUsernameKey].orEmpty() } get() = settingsDataStore.data.map { it[lastUsernameKey].orEmpty() }
val lastPassword: Flow<String>
get() = settingsDataStore.data.map { it[lastPasswordKey].orEmpty() }
suspend fun setLastUsername(username: String) = suspend fun setLastUsername(username: String) =
settingsDataStore.edit { it[lastUsernameKey] = username } settingsDataStore.edit { it[lastUsernameKey] = username }
suspend fun setLastPassword(username: String) =
settingsDataStore.edit { it[lastPasswordKey] = username }
} }
} }

View File

@ -27,12 +27,12 @@ class LoginFragment : Fragment(R.layout.fragment_login) {
subscribe() subscribe()
viewModel.initialize() viewModel.initialize()
binding.login.setOnClickListener { binding.login.setOnClickListener {
login(binding.username.text.toString()) login(binding.username.text.toString(), binding.password.text.toString())
} }
} }
private fun login(username: String) { private fun login(username: String, password : String) {
viewModel.tryLogin(username) { viewModel.tryLogin(username, password) {
findNavController().apply { findNavController().apply {
popBackStack<LoginDestination>(true) popBackStack<LoginDestination>(true)
navigate(MainDestination(username)) navigate(MainDestination(username))
@ -51,8 +51,10 @@ class LoginFragment : Fragment(R.layout.fragment_login) {
} }
} }
viewModel.savedUsername.collectWhenStarted(this) { username -> viewModel.savedUsername.collectWhenStarted(this) { username ->
if (!username.isNullOrBlank()) { viewModel.savedPassword.collectWhenStarted(this) { password ->
login(username) if (!username.isNullOrBlank() && !password.isNullOrBlank()) {
login(username, password)
}
} }
} }
} }

View File

@ -3,3 +3,7 @@ package ru.myitschool.work.ui.login
data class LoginState( data class LoginState(
val isLoginEnabled: Boolean = false, val error: String? = null val isLoginEnabled: Boolean = false, val error: String? = null
) )
data class PasswordState(
val isPasswordEnabled: Boolean = false, val error: String? = null
)

View File

@ -30,20 +30,31 @@ class LoginViewModel @Inject constructor(
private val _savedUsername = MutableStateFlow<String?>(null) private val _savedUsername = MutableStateFlow<String?>(null)
val savedUsername = _savedUsername.asStateFlow() val savedUsername = _savedUsername.asStateFlow()
private val _stateP = MutableStateFlow(PasswordState())
val stateP = _stateP.asStateFlow()
private val _savedPassword = MutableStateFlow<String?>(null)
val savedPassword = _savedPassword.asStateFlow()
fun initialize() { fun initialize() {
viewModelScope.launch { viewModelScope.launch {
dataStoreManager.lastUsername.distinctUntilChanged().collect { lastUsername -> dataStoreManager.lastUsername.distinctUntilChanged().collect { lastUsername ->
if (lastUsername.isNotEmpty()) { dataStoreManager.lastPassword.distinctUntilChanged().collect { lastpassword ->
_savedUsername.update { lastUsername } if (lastUsername.isNotEmpty() && lastpassword.isNotEmpty()) {
} else { _savedUsername.update { lastUsername }
_savedUsername.update { null } _savedPassword.update { lastpassword }
_state.update { LoginState() } } else {
_savedUsername.update { null }
_savedPassword.update { null }
_state.update { LoginState() }
_stateP.update { PasswordState() }
}
} }
} }
} }
} }
fun tryLogin(username: String, onSuccess: () -> Unit) { fun tryLogin(username: String, password : String, onSuccess: () -> Unit) {
viewModelScope.launch { viewModelScope.launch {
try { try {
val resp = api.auth(username) val resp = api.auth(username)
@ -52,6 +63,7 @@ class LoginViewModel @Inject constructor(
} }
Log.d("LoginViewModel", "Login success for $username") Log.d("LoginViewModel", "Login success for $username")
dataStoreManager.setLastUsername(username) dataStoreManager.setLastUsername(username)
dataStoreManager.setLastPassword(password)
onSuccess() onSuccess()
} catch (httpExc: HttpException) { } catch (httpExc: HttpException) {
Log.e("LoginViewModel", "Login failed for $username", httpExc) Log.e("LoginViewModel", "Login failed for $username", httpExc)

View File

@ -17,6 +17,17 @@
android:inputType="text" android:inputType="text"
android:visibility="visible" /> android:visibility="visible" />
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="96dp"
android:layout_marginTop="16dp"
android:autofillHints=""
android:ems="16"
android:hint="@string/password_label"
android:inputType="text"
android:visibility="visible" />
<Button <Button
android:id="@+id/login" android:id="@+id/login"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -82,4 +82,9 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/scan" /> app:layout_constraintTop_toBottomOf="@+id/scan" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"></LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -2,4 +2,5 @@
<string name="app_name" translatable="false">NTO Pass</string> <string name="app_name" translatable="false">NTO Pass</string>
<string name="login_button">Login</string> <string name="login_button">Login</string>
<string name="username_label">Username</string> <string name="username_label">Username</string>
<string name="password_label">password</string>
</resources> </resources>