/** * TrackerMap * Copyright (C) 2021-2022 Iván Ávalos , Henoch Ojeda * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ package mx.trackermap.TrackerMap.android.session import android.content.* import android.os.Bundle import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Toast import androidx.fragment.app.Fragment import androidx.localbroadcastmanager.content.LocalBroadcastManager import androidx.preference.PreferenceManager import com.zhuinden.liveevent.observe import kotlinx.coroutines.DelicateCoroutinesApi import mx.trackermap.TrackerMap.android.R import mx.trackermap.TrackerMap.android.databinding.LoginBinding import mx.trackermap.TrackerMap.android.units.UnitsActivity import mx.trackermap.TrackerMap.controllers.SessionController import org.koin.androidx.viewmodel.ext.android.viewModel import kotlin.time.ExperimentalTime @DelicateCoroutinesApi @ExperimentalTime class LoginFragment : Fragment() { private var _binding: LoginBinding? = null private val binding get() = _binding!! private val loginViewModel: LoginViewModel by viewModel() private lateinit var broadcastManager: LocalBroadcastManager override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { _binding = LoginBinding.inflate(inflater, container, false) return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setupEvents() setupObservers() broadcastManager = LocalBroadcastManager.getInstance(requireActivity()) binding.urlEditText.setText( PreferenceManager .getDefaultSharedPreferences(requireActivity()) .getString( PREFERENCE_SERVER_URL, getString(R.string.default_server_url) ) ?: getString(R.string.default_server_url) ) } override fun onStart() { super.onStart() val intentFilter = IntentFilter(EVENT_TOKEN) broadcastManager.registerReceiver(broadcastReceiver, intentFilter) } override fun onStop() { super.onStop() broadcastManager.unregisterReceiver(broadcastReceiver) } override fun onDestroyView() { super.onDestroyView() _binding = null } private fun setupEvents() { binding.signinButton.setOnClickListener { loginViewModel.login( binding.usernameEditText.text.toString(), binding.passwordEditText.text.toString(), binding.urlEditText.text.toString(), PreferenceManager .getDefaultSharedPreferences(requireActivity()) .getString(PREFERENCE_TOKEN, null) ) } } private fun setupObservers() { loginViewModel.networkAvailable.observe(viewLifecycleOwner) { available -> Log.d("LoginFragment", "available = $available, session = ${loginViewModel.hasSession}") binding.offlineBanner.root.visibility = if (available == true) View.GONE else View.VISIBLE binding.infoLoading.root.visibility = when (available) { null -> View.VISIBLE true -> if (loginViewModel.hasSession) { loginViewModel.restoreSession() View.VISIBLE } else View.GONE false -> if (loginViewModel.hasSession) { View.VISIBLE } else { View.GONE } } } loginViewModel.loginState.observe(viewLifecycleOwner) { result -> Log.d("LoginFragment", result.toString()) when (result) { SessionController.LoginState.Nothing -> { binding.infoLoading.root.visibility = View.GONE } SessionController.LoginState.Loading -> { binding.infoLoading.root.visibility = View.VISIBLE } SessionController.LoginState.UrlMissing -> { binding.infoLoading.root.visibility = View.GONE Toast.makeText(context, getString(R.string.login_url_missing), Toast.LENGTH_SHORT).show() } SessionController.LoginState.EmailMissing -> { binding.infoLoading.root.visibility = View.GONE Toast.makeText(context, getString(R.string.login_username_missing), Toast.LENGTH_SHORT).show() } SessionController.LoginState.PasswordMissing -> { binding.infoLoading.root.visibility = View.GONE Toast.makeText(context, getString(R.string.login_password_missing), Toast.LENGTH_SHORT).show() } SessionController.LoginState.Failure -> { binding.infoLoading.root.visibility = View.GONE Toast.makeText(context, getString(R.string.login_login_failed), Toast.LENGTH_SHORT).show() } SessionController.LoginState.Success -> { PreferenceManager .getDefaultSharedPreferences(requireActivity()) .edit() .putString(PREFERENCE_SERVER_URL, binding.urlEditText.text.toString()) .apply() broadcastManager.sendBroadcast(Intent(EVENT_LOGIN)) val activity = requireActivity() val intent = Intent(activity.applicationContext, UnitsActivity::class.java) intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK startActivity(intent) activity.finish() } else -> {} } } } private val broadcastReceiver = object : BroadcastReceiver() { override fun onReceive(p0: Context?, p1: Intent?) { p1?.getStringExtra(KEY_TOKEN)?.let { token -> PreferenceManager .getDefaultSharedPreferences(requireActivity()) .edit() .putString(PREFERENCE_TOKEN, token) .apply() } } } companion object { const val EVENT_LOGIN = "eventLogin" const val EVENT_TOKEN = "eventToken" const val KEY_TOKEN = "keyToken" const val PREFERENCE_SERVER_URL = "server_url" const val PREFERENCE_TOKEN = "token" } }