diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 6e96622..b0bfb57 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -47,6 +47,10 @@ dependencies { implementation("androidx.constraintlayout:constraintlayout:2.1.4") kapt ("com.github.bumptech.glide:compiler:4.15.1") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0") + implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.5.1") + defaultLibrary() implementation(Dependencies.AndroidX.activity) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7d4881e..2a9c5ce 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,8 @@ + xmlns:tools="http://schemas.android.com/tools"> + + @@ -22,9 +24,6 @@ android:supportsRtl="true" android:theme="@style/Theme.Default" tools:targetApi="34"> - diff --git a/app/src/main/java/ru/myitschool/work/SessionManager.kt b/app/src/main/java/ru/myitschool/work/SessionManager.kt index 699b478..4f43031 100644 --- a/app/src/main/java/ru/myitschool/work/SessionManager.kt +++ b/app/src/main/java/ru/myitschool/work/SessionManager.kt @@ -1,5 +1,12 @@ package ru.myitschool.work object SessionManager { - var userLogin: String = "" + var userLogin: String? = null // Логин пользователя + var userRole: String? = null // Роль пользователя + + // Метод для очистки данных сессии + fun clearSession() { + userLogin = null + userRole = null + } } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/api/ApiModule.kt b/app/src/main/java/ru/myitschool/work/api/ApiModule.kt index a13ebd5..1b02705 100644 --- a/app/src/main/java/ru/myitschool/work/api/ApiModule.kt +++ b/app/src/main/java/ru/myitschool/work/api/ApiModule.kt @@ -4,9 +4,9 @@ import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent +import okhttp3.OkHttpClient import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory -import ru.myitschool.work.api.ApiService import ru.myitschool.work.core.Constants import javax.inject.Singleton @@ -16,9 +16,20 @@ object ApiModule { @Provides @Singleton - fun provideRetrofit(): Retrofit { + fun provideOkHttpClient(): OkHttpClient { + val username = "pivanov" // Замените на ваш логин + val password = "password123" // Замените на ваш пароль + return OkHttpClient.Builder() + .addInterceptor(AuthInterceptor(username, password)) + .build() + } + + @Provides + @Singleton + fun provideRetrofit(client: OkHttpClient): Retrofit { return Retrofit.Builder() .baseUrl(Constants.SERVER_ADDRESS) + .client(client) .addConverterFactory(GsonConverterFactory.create()) .build() } diff --git a/app/src/main/java/ru/myitschool/work/api/ApiService.kt b/app/src/main/java/ru/myitschool/work/api/ApiService.kt index f8b780a..cd239ad 100644 --- a/app/src/main/java/ru/myitschool/work/api/ApiService.kt +++ b/app/src/main/java/ru/myitschool/work/api/ApiService.kt @@ -3,22 +3,56 @@ package ru.myitschool.work.api import retrofit2.Response import retrofit2.http.Body import retrofit2.http.GET -import retrofit2.http.Header import retrofit2.http.PATCH +import retrofit2.http.POST import retrofit2.http.Path +import retrofit2.http.Query interface ApiService { - @GET("api/{login}/auth") + // Метод для аутентификации + @GET("/api/auth") // Используем GET для аутентификации suspend fun authenticate( - @Path("login") login: String, - @Header("Authorization") authorization: String // Добавляем заголовок Authorization - ): Response + @Query("login") login: String, // Передаем логин как параметр запроса + @Query("password") password: String // Передаем пароль как параметр запроса + ): Response // Возвращаем JSON как объект UserAuthResponse - @GET("api/{login}/info") - suspend fun getUserInfo(@Path("login") login: String): Response> // Возвращаем Map вместо UserInfo + // Другие методы... + @GET("/api/{login}/info") // Получение информации о пользователе + suspend fun getUserInfo(@Path("login") login: String): Response> - @PATCH("api/{login}/open") - suspend fun openDoor(@Path("login") login: String, @Body body: OpenDoorRequest): Response + @GET("/api/employee/{login}") // Получение информации о сотруднике + suspend fun getEmployeeInfo(@Path("login") login: String): Response + + @PATCH("/api/open") // Открыть дверь + suspend fun openDoor(@Body request: OpenDoorRequest): Response + + @POST("/api/employee/toggleAccess") // Метод для блокировки/разблокировки доступа + suspend fun toggleAccess(@Body request: ToggleAccessRequest): Response + + @GET("/api/workers") // Получить всех сотрудников + suspend fun getAllWorkers(): Response> } -data class OpenDoorRequest(val value: String) \ No newline at end of file +// Модель данных для ответа аутентификации +data class UserAuthResponse( + val role: String // Добавляем поле для роли +) + +// Модель данных для информации о сотруднике +data class EmployeeData( + val name: String, + val position: String, + val lastVisit: String +) + +// Модель данных для запроса блокировки/разблокировки доступа +data class ToggleAccessRequest( + val login: String, // Логин сотрудника + val action: String // Действие: "block" или "unblock" +) + +// Модель данных для запроса открытия двери +data class OpenDoorRequest( + val login: String, // Логин сотрудника + val value: Long // Код для открытия двери +) \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/api/AuthInterceptor.kt b/app/src/main/java/ru/myitschool/work/api/AuthInterceptor.kt new file mode 100644 index 0000000..2e635b1 --- /dev/null +++ b/app/src/main/java/ru/myitschool/work/api/AuthInterceptor.kt @@ -0,0 +1,16 @@ +package ru.myitschool.work.api + +import okhttp3.Interceptor +import okhttp3.Response +import java.util.Base64 + +class AuthInterceptor(private val username: String, private val password: String) : Interceptor { + override fun intercept(chain: Interceptor.Chain): Response { + val originalRequest = chain.request() + val credential = Base64.getEncoder().encodeToString("$username:$password".toByteArray()) + val newRequest = originalRequest.newBuilder() + .addHeader("Authorization", "Basic $credential") + .build() + return chain.proceed(newRequest) + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/core/Constants.kt b/app/src/main/java/ru/myitschool/work/core/Constants.kt index f24b5bb..235327b 100644 --- a/app/src/main/java/ru/myitschool/work/core/Constants.kt +++ b/app/src/main/java/ru/myitschool/work/core/Constants.kt @@ -1,5 +1,5 @@ package ru.myitschool.work.core // БЕРИТЕ И ИЗМЕНЯЙТЕ ХОСТ ТОЛЬКО ЗДЕСЬ И НЕ БЕРИТЕ ИЗ ДРУГИХ МЕСТ. ФАЙЛ ПЕРЕМЕЩАТЬ НЕЛЬЗЯ object Constants { - const val SERVER_ADDRESS = "const val SERVER_ADDRESS = \"http://localhost:8090\"\n" + const val SERVER_ADDRESS = "http://192.168.1.131:8080" } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/Main/AdminFragment.kt b/app/src/main/java/ru/myitschool/work/ui/Main/AdminFragment.kt index ab9e2e4..d9f6dd3 100644 --- a/app/src/main/java/ru/myitschool/work/ui/Main/AdminFragment.kt +++ b/app/src/main/java/ru/myitschool/work/ui/Main/AdminFragment.kt @@ -1,21 +1,108 @@ package ru.myitschool.work.ui.Main import android.os.Bundle -import androidx.activity.enableEdgeToEdge -import androidx.appcompat.app.AppCompatActivity -import androidx.core.view.ViewCompat -import androidx.core.view.WindowInsetsCompat +import android.view.View +import android.widget.Toast +import androidx.fragment.app.Fragment +import androidx.lifecycle.lifecycleScope +import kotlinx.coroutines.launch +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory import ru.myitschool.work.R +import ru.myitschool.work.api.ApiService +import ru.myitschool.work.api.EmployeeData +import ru.myitschool.work.api.ToggleAccessRequest +import ru.myitschool.work.core.Constants +import ru.myitschool.work.databinding.FragmentAdminBinding -class AdminFragment : AppCompatActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - enableEdgeToEdge() - setContentView(R.layout.fragment_admin) - ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -> - val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) - v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) - insets +class AdminFragment : Fragment(R.layout.fragment_admin) { + private var _binding: FragmentAdminBinding? = null + private val binding get() = _binding!! + + private val apiService: ApiService by lazy { + Retrofit.Builder() + .baseUrl(Constants.SERVER_ADDRESS) + .addConverterFactory(GsonConverterFactory.create()) + .build() + .create(ApiService::class.java) + } + + private var isAccessBlocked: Boolean = false // Переменная для отслеживания состояния доступа + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + _binding = FragmentAdminBinding.bind(view) + + setupUI() + } + + private fun setupUI() { + binding.viewEmployeeInfo.setOnClickListener { + val login = binding.employeeLogin.text.toString() + if (login.isNotEmpty()) { + fetchEmployeeInfo(login) + } else { + Toast.makeText(requireContext(), "Введите логин сотрудника", Toast.LENGTH_SHORT).show() + } + } + + binding.toggleAccess.setOnClickListener { + val login = binding.employeeLogin.text.toString() + if (login.isNotEmpty()) { + // Определяем действие на основе текущего состояния доступа + val action = if (isAccessBlocked) "unblock" else "block" + toggleEmployeeAccess(login, action) + } else { + Toast.makeText(requireContext(), "Введите логин сотрудника", Toast.LENGTH_SHORT).show() + } } } + + private fun fetchEmployeeInfo(login: String) { + lifecycleScope.launch { + try { + val response = apiService.getEmployeeInfo(login) + if (response.isSuccessful) { + val employeeData = response.body() + employeeData?.let { + binding.employeeInfo.text = "Имя: ${it.name}, Должность: ${it.position}, Последний визит: ${it.lastVisit}" + binding.employeeInfo.visibility = View.VISIBLE + binding.toggleAccess.visibility = View.VISIBLE + // Здесь можно установить состояние доступа, если оно доступно + isAccessBlocked = false // Предположим, что доступ не заблокирован по умолчанию + } + } else { + Toast.makeText(requireContext(), "Ошибка получения данных", Toast.LENGTH_SHORT).show() + } + } catch (e: Exception) { + e.printStackTrace() + Toast.makeText(requireContext(), "Ошибка сети", Toast.LENGTH_SHORT).show() + } + } + } + + private fun toggleEmployeeAccess(login: String, action: String) { + val request = ToggleAccessRequest(login, action) + + lifecycleScope.launch { + try { + val response = apiService.toggleAccess(request) + if (response.isSuccessful) { + isAccessBlocked = !isAccessBlocked // Переключаем состояние доступа + val message = if (action == "block") "Доступ заблокирован" else "Доступ разблокирован" + Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show() + } else { + Toast.makeText(requireContext(), "Ошибка изменения доступа", Toast.LENGTH_SHORT).show() + } + } catch (e: Exception) { + e.printStackTrace() + Toast.makeText(requireContext(), "Ошибка сети", Toast.LENGTH_SHORT).show() + } + } + } + + override fun onDestroyView() { + _binding = null // Освобождаем binding, когда представление уничтожается + super.onDestroyView() + } } \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/Main/MainFragment.kt b/app/src/main/java/ru/myitschool/work/ui/Main/MainFragment.kt index 351e58f..1524b9c 100644 --- a/app/src/main/java/ru/myitschool/work/ui/Main/MainFragment.kt +++ b/app/src/main/java/ru/myitschool/work/ui/Main/MainFragment.kt @@ -10,7 +10,6 @@ import androidx.fragment.app.setFragmentResultListener import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -47,11 +46,24 @@ class MainFragment : Fragment(R.layout.fragment_main) { setupUI() fetchUserData() + checkAdminAccess() // Проверяем доступ администратора // Проверяем, есть ли результат QR checkQrResult() } + private fun checkAdminAccess() { + // Проверяем, является ли пользователь администратором + if (SessionManager.userRole == "admin") { + binding.adminPanel.visibility = View.VISIBLE // Показываем кнопку AdminPanel + binding.adminPanel.setOnClickListener { + findNavController().navigate(R.id.adminFragment) // Переход на экран администратора + } + } else { + binding.adminPanel.visibility = View.GONE // Скрываем кнопку для обычных пользователей + } + } + private fun checkQrResult() { // Слушаем результат QR сканирования setFragmentResultListener(QrScanDestination.REQUEST_KEY) { _, bundle -> @@ -81,25 +93,28 @@ class MainFragment : Fragment(R.layout.fragment_main) { lifecycleScope.launch { showError(null) // Скрыть ошибку, если она была try { - val response = apiService.getUserInfo(SessionManager.userLogin) // Получаем данные пользователя - if (response.isSuccessful) { - response.body()?.let { data -> - // Извлекаем значения из Map - val fullName = data["name"] as? String ?: "Неизвестно" - val position = data["position"] as? String ?: "Неизвестно" - val lastVisit = data["lastVisit"] as? String ?: "Неизвестно" - val photoUrl = data["photo"] as? String ?: "" + val response = + SessionManager.userLogin?.let { apiService.getUserInfo(it) } // Получаем данные пользователя + if (response != null) { + if (response.isSuccessful) { + response.body()?.let { data -> + // Извлекаем значения из Map + val fullName = data["name"] as? String ?: "Неизвестно" + val position = data["position"] as? String ?: "Неизвестно" + val lastVisit = data["lastVisit"] as? String ?: "Неизвестно" + val photoUrl = data["photo"] as? String ?: "" - // Обновляем UI - updateUI(fullName, position, lastVisit, photoUrl) + // Обновляем UI + updateUI(fullName, position, lastVisit, photoUrl) - // Здесь вы можете добавить данные проходов в список - // Пример: - accessLogs.add(AccessLog("2024-02-31 08:31", "Считыватель 1", "карта")) - accessLogAdapter.notifyDataSetChanged() // Обновляем адаптер + // Здесь вы можете добавить данные проходов в список + // Пример: + accessLogs.add(AccessLog("2024-02-31 08:31", "Считыватель 1", "карта")) + accessLogAdapter.notifyDataSetChanged() // Обновляем адаптер + } + } else { + showError(getString(R.string.error_loading_data)) // Показываем ошибку, если данные не загрузились } - } else { - showError(getString(R.string.error_loading_data)) // Показываем ошибку, если данные не загрузились } } catch (e: Exception) { showError(e.localizedMessage) // Показываем ошибку при исключении diff --git a/app/src/main/java/ru/myitschool/work/ui/login/LoginFragment.kt b/app/src/main/java/ru/myitschool/work/ui/login/LoginFragment.kt index bd2f510..5d79f87 100644 --- a/app/src/main/java/ru/myitschool/work/ui/login/LoginFragment.kt +++ b/app/src/main/java/ru/myitschool/work/ui/login/LoginFragment.kt @@ -10,15 +10,17 @@ import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels +import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController import dagger.hilt.android.AndroidEntryPoint import ru.myitschool.work.R +import ru.myitschool.work.SessionManager +import ru.myitschool.work.api.UserAuthResponse import ru.myitschool.work.databinding.FragmentLoginBinding import ru.myitschool.work.utils.collectWhenStarted import ru.myitschool.work.utils.visibleOrGone import ru.myitschool.work.utils.AuthPreferences import kotlinx.coroutines.launch -import androidx.lifecycle.lifecycleScope @AndroidEntryPoint class LoginFragment : Fragment(R.layout.fragment_login) { @@ -57,6 +59,7 @@ class LoginFragment : Fragment(R.layout.fragment_login) { performLogin(username, password) // Передаем пароль в метод performLogin } + // Изначально скрываем индикаторы binding.loading.visibleOrGone(false) binding.error.visibleOrGone(false) } @@ -76,30 +79,35 @@ class LoginFragment : Fragment(R.layout.fragment_login) { private fun performLogin(username: String, password: String) { lifecycleScope.launch { + binding.loading.visibleOrGone(true) // Показываем индикатор загрузки viewModel.authenticate(username, password) // Передаем пароль в метод authenticate } } private fun subscribe() { - viewModel.state.collectWhenStarted(this) { state -> - binding.loading.visibleOrGone(false) + lifecycleScope.launch { + viewModel.state.collect { state -> + binding.loading.visibleOrGone(false) - try { if (state.maintenance) { showMaintenanceDialog() // Показываем диалог о техработах - } else if (state.error != null) { - binding.error.text = state.error - binding.error.visibility = View.VISIBLE } else if (state.success) { binding.error.visibility = View.GONE authPreferences.saveLoginState(true) authPreferences.saveLogin(binding.username.text.toString()) // Сохраняем логин + + // Сохраняем роль пользователя в SessionManager + val userAuthResponse: UserAuthResponse? = state.userAuthResponse + userAuthResponse?.let { + SessionManager.userRole = it.role // Сохраняем роль + } + Toast.makeText(context, "Авторизация прошла успешно", Toast.LENGTH_SHORT).show() - navigateToMainScreen() + navigateToMainScreen() // Перенаправление на следующий экран + } else if (state.error != null) { + binding.error.text = state.error + binding.error.visibility = View.VISIBLE } - } catch (e: Exception) { - Log.e("LoginFragment", "Ошибка при обработке состояния", e) - Toast.makeText(context, "Произошла ошибка. Пожалуйста, попробуйте снова.", Toast.LENGTH_SHORT).show() } } } @@ -108,7 +116,7 @@ class LoginFragment : Fragment(R.layout.fragment_login) { AlertDialog.Builder(requireContext()) .setTitle("Технические работы") .setMessage("Проводятся техработы, пожалуйста, подождите.") - .setPositiveButton("ОК") { dialog, _ -> dialog.dismiss() } + .setPositiveButton("ОК ") { dialog, _ -> dialog.dismiss() } .setCancelable(false) .show() } diff --git a/app/src/main/java/ru/myitschool/work/ui/login/LoginViewModel.kt b/app/src/main/java/ru/myitschool/work/ui/login/LoginViewModel.kt index 6ea460d..25dcb8a 100644 --- a/app/src/main/java/ru/myitschool/work/ui/login/LoginViewModel.kt +++ b/app/src/main/java/ru/myitschool/work/ui/login/LoginViewModel.kt @@ -1,52 +1,48 @@ package ru.myitschool.work.ui.login -import android.content.Context +import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel -import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch -import okhttp3.Credentials -import retrofit2.Retrofit -import retrofit2.converter.gson.GsonConverterFactory import ru.myitschool.work.SessionManager import ru.myitschool.work.api.ApiService -import ru.myitschool.work.core.Constants +import ru.myitschool.work.api.UserAuthResponse import javax.inject.Inject @HiltViewModel class LoginViewModel @Inject constructor( - @ApplicationContext private val context: Context, + private val apiService: ApiService ) : ViewModel() { - private val _state = MutableStateFlow(LoginState()) - val state = _state.asStateFlow() - private val apiService: ApiService by lazy { - Retrofit.Builder() - .baseUrl(Constants.SERVER_ADDRESS) - .addConverterFactory(GsonConverterFactory.create()) - .build() - .create(ApiService::class.java) - } + private val _state = MutableStateFlow(LoginState()) + val state: StateFlow get() = _state fun authenticate(username: String, password: String) { if (isValidUsername(username)) { viewModelScope.launch { try { - val credentials = Credentials.basic(username, password) // Создаем Basic Auth заголовок - val response = apiService.authenticate(username, credentials) // Передаем заголовок в запрос + val response = apiService.authenticate(username, password) + Log.d("LoginViewModel", "Response code: ${response.code()}") + if (response.isSuccessful) { - SessionManager.userLogin = username - _state.value = LoginState(success = true) - } else if (response.code() == 503) { // Пример кода для техработ - _state.value = LoginState(maintenance = true) + val userAuthResponse = response.body() // Получаем JSON-ответ + Log.d("LoginViewModel", "User Auth Response: $userAuthResponse") // Логируем ответ + + // Обработка JSON-ответа + if (userAuthResponse != null) { + SessionManager.userLogin = username + SessionManager.userRole = userAuthResponse.role // Сохраняем роль + _state.value = LoginState(success = true) // Успешная авторизация + } else { + _state.value = LoginState(error = "Ошибка авторизации: Неверные учетные данные.") + } } else { - _state.value = LoginState(error = "Ошибка авторизации") + _state.value = LoginState(error = "Ошибка авторизации: ${response.message()}") } } catch (e: Exception) { - // Логирование ошибки e.printStackTrace() _state.value = LoginState(error = "Ошибка сети. Проверьте подключение к интернету.") } @@ -57,8 +53,14 @@ class LoginViewModel @Inject constructor( } private fun isValidUsername(username: String): Boolean { - return username.length >= 3 && !username.first().isDigit() && username.all { it.isLetterOrDigit() } + return username.isNotEmpty() // Пример проверки логина } +} - data class LoginState(val success: Boolean = false, val error: String? = null, val maintenance: Boolean = false) -} \ No newline at end of file +// Состояние аутентификации +data class LoginState( + val success: Boolean = false, // Успешность аутентификации + val userAuthResponse: UserAuthResponse? = null, // Ответ с информацией о пользователе + val error: String? = null, // Сообщение об ошибке + val maintenance: Boolean = false // Состояние техобслуживания +) \ No newline at end of file diff --git a/app/src/main/java/ru/myitschool/work/ui/qr/result/QrResult.kt b/app/src/main/java/ru/myitschool/work/ui/qr/result/QrResult.kt index f607c58..327e9ad 100644 --- a/app/src/main/java/ru/myitschool/work/ui/qr/result/QrResult.kt +++ b/app/src/main/java/ru/myitschool/work/ui/qr/result/QrResult.kt @@ -55,11 +55,19 @@ class QrResult : Fragment(R.layout.fragment_qr_scan_result) { private fun sendRequestToServer(qrData: String) { lifecycleScope.launch { try { - val response = apiService.openDoor(SessionManager.userLogin, OpenDoorRequest(qrData)) - if (response.isSuccessful) { - binding.result.text = "Успешно/Success" + // Проверяем, что userLogin не равен null + val login = SessionManager.userLogin + if (login != null) { + // Создаем объект OpenDoorRequest с логином и кодом + val openDoorRequest = OpenDoorRequest(login, qrData.toLong()) // Преобразуем qrData в Long, если это необходимо + val response = apiService.openDoor(openDoorRequest) // Теперь передаем только openDoorRequest + if (response.isSuccessful) { + binding.result.text = "Успешно/Success" + } else { + binding.result.text = "Что-то пошло не так/Something wrong" + } } else { - binding.result.text = "Что-то пошло не так/Something wrong" + binding.result.text = "Пользователь не авторизован/Unauthorized user" } } catch (e: Exception) { binding.result.text = "Что-то пошло не так/Something wrong" diff --git a/app/src/main/java/utils/Extensions.kt b/app/src/main/java/utils/Extensions.kt new file mode 100644 index 0000000..529280f --- /dev/null +++ b/app/src/main/java/utils/Extensions.kt @@ -0,0 +1,24 @@ +package ru.myitschool.work.utils + +import android.view.View +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.launch + +// Функция для сбора данных из Flow, когда жизненный цикл находится в состоянии STARTED +fun Flow.collectWhenStarted(lifecycleOwner: LifecycleOwner, collector: (T) -> Unit) { + lifecycleOwner.lifecycleScope.launch { + lifecycleOwner.lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { + collect { value -> collector(value) } + } + } +} + +// Функция для управления видимостью View +fun View?.visibleOrGone(isVisible: Boolean) { + this?.visibility = if (isVisible) View.VISIBLE else View.GONE +} \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml index 2aa9683..99a2164 100644 --- a/app/src/main/res/layout/fragment_main.xml +++ b/app/src/main/res/layout/fragment_main.xml @@ -15,7 +15,7 @@ android:text="@string/fullname_label" android:textSize="18sp" android:layout_marginBottom="5dp" - android:visibility="visible" /> + android:visibility="gone" /> + android:visibility="gone" /> + android:visibility="gone" /> + android:visibility="gone" />