diff options
author | Isidro Henoch <imhenoch@protonmail.com> | 2022-01-12 18:10:01 -0600 |
---|---|---|
committer | Isidro Henoch <imhenoch@protonmail.com> | 2022-01-12 18:10:01 -0600 |
commit | 8b9f4d7d7c1cebd380a617d25f7f580353f24535 (patch) | |
tree | 2f64529e1be83c896a47774876ea1bd514f1c719 | |
parent | f528b208dd4bcd9cf3cf881ea93ead71b9322240 (diff) | |
parent | 88972a0e0d42c355fbed65d7ada3bcbdaad76287 (diff) | |
download | etbsa-trackermap-mobile-8b9f4d7d7c1cebd380a617d25f7f580353f24535.tar.gz etbsa-trackermap-mobile-8b9f4d7d7c1cebd380a617d25f7f580353f24535.tar.bz2 etbsa-trackermap-mobile-8b9f4d7d7c1cebd380a617d25f7f580353f24535.zip |
Merge branch 'user_information'
14 files changed, 432 insertions, 150 deletions
diff --git a/androidApp/src/main/AndroidManifest.xml b/androidApp/src/main/AndroidManifest.xml index 5d56847..6501532 100644 --- a/androidApp/src/main/AndroidManifest.xml +++ b/androidApp/src/main/AndroidManifest.xml @@ -26,5 +26,8 @@ <activity android:name=".details.DetailsActivity" android:exported="false"/> + <activity + android:name=".session.UserInformationActivity" + android:exported="false"/> </application> </manifest>
\ No newline at end of file diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/TrackerApp.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/TrackerApp.kt index 1563534..cdb7102 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/TrackerApp.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/TrackerApp.kt @@ -6,6 +6,7 @@ import mx.trackermap.TrackerMap.android.details.commands.UnitCommandsViewModel import mx.trackermap.TrackerMap.android.details.information.UnitInformationViewModel import mx.trackermap.TrackerMap.android.details.reports.UnitReportsViewModel import mx.trackermap.TrackerMap.android.session.LoginViewModel +import mx.trackermap.TrackerMap.android.session.UserInformationViewModel import mx.trackermap.TrackerMap.android.units.UnitsViewModel import mx.trackermap.TrackerMap.client.apis.* import mx.trackermap.TrackerMap.controllers.GeofencesController @@ -25,21 +26,22 @@ class TrackerApp : Application() { val appModule = module { single { "https://etbsa.net/api" } - single { SessionApi(get()) } - single { DevicesApi(get()) } - single { PositionsApi(get()) } - single { CommandsApi(get()) } - single { ReportsApi(get()) } - single { GeofencesApi(get()) } + factory { SessionApi(get()) } + factory { DevicesApi(get()) } + factory { PositionsApi(get()) } + factory { CommandsApi(get()) } + factory { ReportsApi(get()) } + factory { GeofencesApi(get()) } - single { UnitsController(get(), get()) } - single { GeofencesController(get()) } + factory { UnitsController(get(), get()) } + factory { GeofencesController(get()) } viewModel { LoginViewModel(get(), get()) } viewModel { UnitInformationViewModel(get()) } viewModel { UnitCommandsViewModel(get()) } - single { UnitsViewModel(get()) } + viewModel { UnitsViewModel(get()) } viewModel { UnitReportsViewModel(get(), get()) } + viewModel { UserInformationViewModel(get()) } } startKoin { diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesFragment.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesFragment.kt index bd3ab67..6bee413 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesFragment.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesFragment.kt @@ -11,18 +11,17 @@ import androidx.recyclerview.widget.LinearLayoutManager import kotlinx.coroutines.DelicateCoroutinesApi import mx.trackermap.TrackerMap.android.databinding.DevicesFragmentBinding import mx.trackermap.TrackerMap.android.details.DetailsActivity +import mx.trackermap.TrackerMap.android.units.UnitFragment import mx.trackermap.TrackerMap.android.units.UnitsViewModel import mx.trackermap.TrackerMap.client.models.UnitInformation import org.koin.androidx.viewmodel.ext.android.viewModel @DelicateCoroutinesApi -class DevicesFragment : Fragment() { +class DevicesFragment(private val unitsViewModel: UnitsViewModel) : UnitFragment(unitsViewModel) { private var _binding: DevicesFragmentBinding? = null private val binding get() = _binding!! - private val unitsViewModel: UnitsViewModel by viewModel() - override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -42,9 +41,20 @@ class DevicesFragment : Fragment() { super.onViewCreated(view, savedInstanceState) setupList() + } + + override fun onResume() { + super.onResume() + setupObservers() } + override fun onPause() { + super.onPause() + + removeObservers() + } + private fun setupList() { binding.devicesList.layoutManager = LinearLayoutManager( context, LinearLayoutManager.VERTICAL, @@ -65,6 +75,11 @@ class DevicesFragment : Fragment() { } } + private fun removeObservers() { + Log.d("DevicesFragment", "removeObservers()") + unitsViewModel.units.removeObservers(viewLifecycleOwner) + } + private fun itemAction(unit: UnitInformation, action: Action) { when (action) { Action.DETAILS, Action.REPORTS, Action.COMMANDS -> { diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/UnitMapFragment.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/UnitMapFragment.kt index fc417a0..30e3cea 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/UnitMapFragment.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/UnitMapFragment.kt @@ -1,29 +1,23 @@ package mx.trackermap.TrackerMap.android.map import android.content.Intent -import android.graphics.Color import android.os.Bundle import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.fragment.app.Fragment import kotlinx.coroutines.DelicateCoroutinesApi import mx.trackermap.TrackerMap.android.R import mx.trackermap.TrackerMap.android.databinding.UnitMapFragmentBinding import mx.trackermap.TrackerMap.android.details.DetailsActivity import mx.trackermap.TrackerMap.android.devices.Action import mx.trackermap.TrackerMap.android.devices.UnitRenderData +import mx.trackermap.TrackerMap.android.units.UnitFragment import mx.trackermap.TrackerMap.android.units.UnitsViewModel import mx.trackermap.TrackerMap.client.models.UnitInformation -import mx.trackermap.TrackerMap.utils.Formatter -import mx.trackermap.TrackerMap.utils.SpeedUnit -import org.koin.androidx.viewmodel.ext.android.viewModel @DelicateCoroutinesApi -class UnitMapFragment : Fragment() { - - private val unitsViewModel: UnitsViewModel by viewModel() +class UnitMapFragment(private val unitsViewModel: UnitsViewModel) : UnitFragment(unitsViewModel) { private var _binding: UnitMapFragmentBinding? = null private val binding get() = _binding!! @@ -42,9 +36,20 @@ class UnitMapFragment : Fragment() { super.onViewCreated(view, savedInstanceState) initializeMap() + } + + override fun onResume() { + super.onResume() + setupObservers() } + override fun onPause() { + super.onPause() + + removeObservers() + } + private fun initializeMap() { unitsMapFragment = childFragmentManager.findFragmentById(R.id.unitsMap) as MapFragment unitsMapFragment.markerCallback = unitsViewModel::selectUnitWith @@ -93,6 +98,13 @@ class UnitMapFragment : Fragment() { } } + private fun removeObservers() { + Log.d("MapFragment", "removeObservers()") + unitsViewModel.units.removeObservers(viewLifecycleOwner) + unitsViewModel.selectedUnit.removeObservers(viewLifecycleOwner) + unitsViewModel.geofences.removeObservers(viewLifecycleOwner) + } + private fun itemAction(unit: UnitInformation, action: Action) { when (action) { Action.DETAILS, Action.REPORTS, Action.COMMANDS -> { diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/UserInformationActivity.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/UserInformationActivity.kt new file mode 100644 index 0000000..da1c0d5 --- /dev/null +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/UserInformationActivity.kt @@ -0,0 +1,78 @@ +package mx.trackermap.TrackerMap.android.session + +import android.content.Intent +import android.os.Bundle +import android.view.View +import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import mx.trackermap.TrackerMap.android.databinding.UserInformationActivityBinding +import mx.trackermap.TrackerMap.client.models.User +import org.koin.androidx.viewmodel.ext.android.viewModel + +class UserInformationActivity : AppCompatActivity() { + + private var _binding: UserInformationActivityBinding? = null + private val binding get() = _binding!! + private val userInformationViewModel: UserInformationViewModel by viewModel() + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + _binding = UserInformationActivityBinding.inflate(layoutInflater) + setContentView(binding.root) + + initialize() + } + + private fun initialize() { + setupObservers() + setupEvents() + + userInformationViewModel.fetchUserInfo() + } + + private fun setupObservers() { + userInformationViewModel.userInformation.observe(this) { userInformation -> + when (userInformation) { + UserInformationViewModel.InformationState.Loading -> setLoading(true) + UserInformationViewModel.InformationState.Failure -> failure() + is UserInformationViewModel.InformationState.Success -> display(userInformation.user) + UserInformationViewModel.InformationState.Signout -> signout() + } + } + } + + private fun setupEvents() { + binding.signoutButton.setOnClickListener { userInformationViewModel.signout() } + } + + private fun setLoading(isLoading: Boolean) { + binding.infoLoading.visibility = if (isLoading) View.VISIBLE else View.GONE + binding.userInfoCard.visibility = if (isLoading) View.GONE else View.VISIBLE + } + + private fun failure() { + setLoading(false) + + Toast.makeText(this, "Something went wrong...", Toast.LENGTH_LONG).show() + } + + private fun display(user: User) { + setLoading(false) + + binding.apply { + usernameInfo.text = user.name ?: "" + emailInfo.text = user.email ?: "" + idInfo.text = "${user.id ?: "--"}" + deviceLimitInfo.text = "${user.deviceLimit ?: "--"}" + adminInfo.text = "${user.administrator}" + } + } + + private fun signout() { + val intent = Intent(applicationContext, LoginActivity::class.java) + intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + startActivity(intent) + finish() + } + +}
\ No newline at end of file diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/UserInformationViewModel.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/UserInformationViewModel.kt new file mode 100644 index 0000000..b2379fc --- /dev/null +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/UserInformationViewModel.kt @@ -0,0 +1,44 @@ +package mx.trackermap.TrackerMap.android.session + +import android.util.Log +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.launch +import mx.trackermap.TrackerMap.client.apis.SessionApi +import mx.trackermap.TrackerMap.client.models.User + +class UserInformationViewModel(private val sessionApi: SessionApi) : ViewModel() { + + sealed class InformationState { + object Loading: InformationState() + object Failure: InformationState() + class Success(val user: User) : InformationState() + object Signout: InformationState() + } + + var userInformation = MutableLiveData<InformationState>(InformationState.Loading) + + init { + Log.d("UserInformationVM", "Initializing User Information View Model") + } + + fun fetchUserInfo() { + viewModelScope.launch { + userInformation.postValue(InformationState.Loading) + try { + userInformation.postValue(InformationState.Success(sessionApi.sessionGet())) + } catch (e: Exception) { + userInformation.postValue(InformationState.Failure) + } + } + } + + fun signout() { + viewModelScope.launch { + userInformation.postValue(InformationState.Loading) + sessionApi.sessionDelete() + userInformation.postValue(InformationState.Signout) + } + } +}
\ No newline at end of file diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitFragment.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitFragment.kt new file mode 100644 index 0000000..ab3afc1 --- /dev/null +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitFragment.kt @@ -0,0 +1,8 @@ +package mx.trackermap.TrackerMap.android.units + +import androidx.fragment.app.Fragment +import kotlinx.coroutines.DelicateCoroutinesApi + +open class UnitFragment @DelicateCoroutinesApi constructor( + private val unitsViewModel: UnitsViewModel +) : Fragment()
\ No newline at end of file diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsActivity.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsActivity.kt index 409919a..e198ce0 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsActivity.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsActivity.kt @@ -1,5 +1,6 @@ package mx.trackermap.TrackerMap.android.units +import android.content.Intent import android.os.Bundle import android.util.Log import android.view.Gravity @@ -12,6 +13,8 @@ import mx.trackermap.TrackerMap.android.R import mx.trackermap.TrackerMap.android.databinding.UnitsActivityBinding import mx.trackermap.TrackerMap.android.devices.DevicesFragment import mx.trackermap.TrackerMap.android.map.UnitMapFragment +import mx.trackermap.TrackerMap.android.session.LoginActivity +import mx.trackermap.TrackerMap.android.session.UserInformationActivity import org.koin.androidx.viewmodel.ext.android.viewModel @DelicateCoroutinesApi @@ -21,6 +24,12 @@ class UnitsActivity : AppCompatActivity() { private val binding get() = _binding!! private val unitsViewModel: UnitsViewModel by viewModel() + private val mapFragment: UnitMapFragment by lazy { + UnitMapFragment(unitsViewModel) + } + private val devicesFragment: DevicesFragment by lazy { + DevicesFragment(unitsViewModel) + } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -38,28 +47,9 @@ class UnitsActivity : AppCompatActivity() { } private fun setupEvents() { - binding.drawerButton.setOnClickListener { - binding.drawerLayout.openDrawer(binding.navigationView) - } - binding.navigationView.setNavigationItemSelectedListener { - when (it.itemId) { - R.id.nav_account -> { - Toast.makeText(this, "Account button tapped!", Toast.LENGTH_SHORT).show() - binding.drawerLayout.closeDrawers() - false - } - R.id.nav_about -> { - Toast.makeText(this, "About button tapped!", Toast.LENGTH_SHORT).show() - binding.drawerLayout.closeDrawers() - false - } - R.id.nav_logout -> { - Toast.makeText(this, "Logout button tapped!", Toast.LENGTH_SHORT).show() - binding.drawerLayout.closeDrawers() - false - } - else -> false - } + binding.userButton.setOnClickListener { + val intent = Intent(applicationContext, UserInformationActivity::class.java) + startActivity(intent) } binding.displayModeToggle.setOnClickListener { unitsViewModel.toggleDisplayMode() @@ -89,9 +79,8 @@ class UnitsActivity : AppCompatActivity() { val newFragment = when (displayMode) { - UnitsViewModel.UnitsDisplayMode.LIST -> DevicesFragment() - UnitsViewModel.UnitsDisplayMode.MAP -> UnitMapFragment() - else -> DevicesFragment() + UnitsViewModel.UnitsDisplayMode.LIST -> devicesFragment + UnitsViewModel.UnitsDisplayMode.MAP -> mapFragment } supportFragmentManager.commit { replace(R.id.displayContainer, newFragment) diff --git a/androidApp/src/main/res/layout/units_activity.xml b/androidApp/src/main/res/layout/units_activity.xml index fb39ebe..bc8d94a 100644 --- a/androidApp/src/main/res/layout/units_activity.xml +++ b/androidApp/src/main/res/layout/units_activity.xml @@ -1,87 +1,74 @@ <?xml version="1.0" encoding="utf-8"?> -<androidx.drawerlayout.widget.DrawerLayout +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" android:id="@+id/drawerLayout" android:layout_width="match_parent" - android:layout_height="match_parent" - tools:openDrawer="start"> - - <androidx.constraintlayout.widget.ConstraintLayout - android:layout_width="match_parent" - android:layout_height="match_parent"> - <FrameLayout - android:id="@+id/displayContainer" - android:layout_width="0dp" - android:layout_height="0dp" - android:layout_marginTop="@dimen/fab_margin" - app:layout_constraintTop_toBottomOf="@id/displayModeToggle" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintBottom_toBottomOf="parent"/> + android:layout_height="match_parent"> - <com.google.android.material.floatingactionbutton.FloatingActionButton - android:id="@+id/drawerButton" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - app:layout_constraintTop_toTopOf="parent" - app:layout_constraintStart_toStartOf="parent" - android:backgroundTint="@android:color/white" - app:borderWidth="0dp" - app:fabSize="mini" - android:layout_marginStart="@dimen/fab_margin" - android:layout_marginTop="@dimen/fab_margin" - app:elevation="@dimen/fab_elevation" - android:src="@drawable/icon_menu" - android:contentDescription="@string/open_drawer"/> + <FrameLayout + android:id="@+id/displayContainer" + android:layout_width="0dp" + android:layout_height="0dp" + android:layout_marginTop="@dimen/fab_margin" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/displayModeToggle" /> - <com.google.android.material.card.MaterialCardView - android:layout_width="0dp" - android:layout_height="0dp" - app:layout_constraintTop_toTopOf="@id/displayModeToggle" - app:layout_constraintStart_toEndOf="@id/drawerButton" - app:layout_constraintEnd_toStartOf="@id/displayModeToggle" - app:layout_constraintBottom_toBottomOf="@id/displayModeToggle" - android:layout_marginVertical="@dimen/search_vertical_margin" - android:layout_marginHorizontal="@dimen/search_horizontal_margin" - app:cardCornerRadius="@dimen/card_border_radius" - app:cardElevation="@dimen/card_elevation"> - - <com.google.android.material.textfield.TextInputEditText - android:id="@+id/searchInput" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:hint="@string/units_search" - android:paddingHorizontal="16dp" - android:background="@null" - android:inputType="text" - android:lines="1" - android:imeOptions="actionSearch" /> + <com.google.android.material.floatingactionbutton.FloatingActionButton + android:id="@+id/userButton" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/fab_margin" + android:layout_marginTop="@dimen/fab_margin" + android:backgroundTint="@android:color/white" + android:contentDescription="@string/open_drawer" + android:src="@drawable/device_contact" + app:borderWidth="0dp" + app:elevation="@dimen/fab_elevation" + app:fabSize="mini" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> - </com.google.android.material.card.MaterialCardView> + <com.google.android.material.card.MaterialCardView + android:layout_width="0dp" + android:layout_height="0dp" + android:layout_marginHorizontal="@dimen/search_horizontal_margin" + android:layout_marginVertical="@dimen/search_vertical_margin" + app:cardCornerRadius="@dimen/card_border_radius" + app:cardElevation="@dimen/card_elevation" + app:layout_constraintBottom_toBottomOf="@id/displayModeToggle" + app:layout_constraintEnd_toStartOf="@id/displayModeToggle" + app:layout_constraintStart_toEndOf="@id/userButton" + app:layout_constraintTop_toTopOf="@id/displayModeToggle"> - <com.google.android.material.floatingactionbutton.FloatingActionButton - android:id="@+id/displayModeToggle" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - app:layout_constraintTop_toTopOf="parent" - app:layout_constraintEnd_toEndOf="parent" - android:backgroundTint="@android:color/white" - app:borderWidth="0dp" - app:fabSize="mini" - android:layout_marginEnd="@dimen/fab_margin" - android:layout_marginTop="@dimen/fab_margin" - app:elevation="@dimen/fab_elevation" - tools:ignore="ContentDescription" /> + <com.google.android.material.textfield.TextInputEditText + android:id="@+id/searchInput" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@null" + android:hint="@string/units_search" + android:imeOptions="actionSearch" + android:inputType="text" + android:lines="1" + android:paddingHorizontal="16dp" /> - </androidx.constraintlayout.widget.ConstraintLayout> + </com.google.android.material.card.MaterialCardView> - <com.google.android.material.navigation.NavigationView - android:id="@+id/navigationView" + <com.google.android.material.floatingactionbutton.FloatingActionButton + android:id="@+id/displayModeToggle" android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_gravity="start" - app:menu="@menu/navigation_menu" /> + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/fab_margin" + android:layout_marginEnd="@dimen/fab_margin" + android:backgroundTint="@android:color/white" + app:borderWidth="0dp" + app:elevation="@dimen/fab_elevation" + app:fabSize="mini" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" + tools:ignore="ContentDescription" /> -</androidx.drawerlayout.widget.DrawerLayout>
\ No newline at end of file +</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file diff --git a/androidApp/src/main/res/layout/user_information_activity.xml b/androidApp/src/main/res/layout/user_information_activity.xml new file mode 100644 index 0000000..8bb994a --- /dev/null +++ b/androidApp/src/main/res/layout/user_information_activity.xml @@ -0,0 +1,156 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <ProgressBar + android:id="@+id/infoLoading" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + android:visibility="gone"/> + + <androidx.cardview.widget.CardView + android:id="@+id/userInfoCard" + android:layout_margin="@dimen/card_margin" + android:layout_width="0dp" + android:layout_height="wrap_content" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:contentPadding="@dimen/card_padding" + app:cardCornerRadius="@dimen/card_border_radius" + app:cardElevation="@dimen/card_elevation"> + + <androidx.constraintlayout.widget.ConstraintLayout + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <TextView + android:id="@+id/usernameLabel" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:text="@string/username" + app:layout_constraintBottom_toTopOf="@id/usernameInfo" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintVertical_chainStyle="spread_inside" /> + + <TextView + android:id="@+id/usernameInfo" + android:layout_width="0dp" + android:layout_height="wrap_content" + app:layout_constraintBottom_toTopOf="@id/emailLabel" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/usernameLabel" + tools:text="Username" /> + + <TextView + android:id="@+id/emailLabel" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/fields_spacing" + android:text="@string/email" + app:layout_constraintBottom_toTopOf="@id/emailInfo" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/usernameInfo" /> + + <TextView + android:id="@+id/emailInfo" + android:layout_width="0dp" + android:layout_height="wrap_content" + app:layout_constraintBottom_toTopOf="@id/idLabel" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/emailLabel" + tools:text="Email" /> + + <TextView + android:id="@+id/idLabel" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/fields_spacing" + android:text="@string/unique_id" + app:layout_constraintBottom_toTopOf="@id/idInfo" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/emailInfo" /> + + <TextView + android:id="@+id/idInfo" + android:layout_width="0dp" + android:layout_height="wrap_content" + app:layout_constraintBottom_toTopOf="@id/deviceLimitLabel" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/idLabel" + tools:text="Unique ID" /> + + <TextView + android:id="@+id/deviceLimitLabel" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/fields_spacing" + android:text="@string/device_limit" + app:layout_constraintBottom_toTopOf="@id/deviceLimitInfo" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/idInfo" /> + + <TextView + android:id="@+id/deviceLimitInfo" + android:layout_width="0dp" + android:layout_height="wrap_content" + app:layout_constraintBottom_toTopOf="@id/adminLabel" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/deviceLimitLabel" + tools:text="Device Limit" /> + + <TextView + android:id="@+id/adminLabel" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/fields_spacing" + android:text="@string/admin" + app:layout_constraintBottom_toTopOf="@id/adminInfo" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/deviceLimitInfo" /> + + <TextView + android:id="@+id/adminInfo" + android:layout_width="0dp" + android:layout_height="wrap_content" + app:layout_constraintBottom_toTopOf="@id/signoutButton" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/adminLabel" + tools:text="Admin" /> + + <com.google.android.material.button.MaterialButton + android:id="@+id/signoutButton" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/fields_spacing" + android:text="@string/sign_out" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/adminInfo" /> + + </androidx.constraintlayout.widget.ConstraintLayout> + + </androidx.cardview.widget.CardView> + +</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file diff --git a/androidApp/src/main/res/menu/navigation_menu.xml b/androidApp/src/main/res/menu/navigation_menu.xml deleted file mode 100644 index 2713776..0000000 --- a/androidApp/src/main/res/menu/navigation_menu.xml +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<menu xmlns:android="http://schemas.android.com/apk/res/android"> - - <group - android:id="@+id/group_1" - android:checkableBehavior="single"> - <item - android:id="@+id/nav_account" - android:icon="@drawable/device_contact" - android:title="@string/menu_account" /> - <item - android:id="@+id/nav_about" - android:icon="@drawable/icon_about" - android:title="@string/menu_about" /> - </group> - - <group - android:id="@+id/group_2" - android:checkableBehavior="single"> - <item - android:id="@+id/nav_logout" - android:icon="@drawable/icon_logout" - android:title="@string/menu_logout" /> - </group> - -</menu>
\ No newline at end of file diff --git a/androidApp/src/main/res/values/dimen.xml b/androidApp/src/main/res/values/dimen.xml index 8acc9a3..25d0e98 100644 --- a/androidApp/src/main/res/values/dimen.xml +++ b/androidApp/src/main/res/values/dimen.xml @@ -20,4 +20,7 @@ <!-- Floating Button --> <dimen name="fab_margin">12dp</dimen> <dimen name="fab_elevation">8dp</dimen> + + <!-- User Information --> + <dimen name="fields_spacing">8dp</dimen> </resources>
\ No newline at end of file diff --git a/androidApp/src/main/res/values/strings.xml b/androidApp/src/main/res/values/strings.xml index 13ac79d..6901a37 100644 --- a/androidApp/src/main/res/values/strings.xml +++ b/androidApp/src/main/res/values/strings.xml @@ -86,4 +86,12 @@ <string name="event_text_message">Text message received</string> <string name="event_driver_changed">Driver changed</string> <string name="event_unknown">Unknown event</string> + + <!-- User Information --> + <string name="username">Username</string> + <string name="email">Email</string> + <string name="unique_id">Unique ID</string> + <string name="device_limit">Device Limit</string> + <string name="admin">Administrator</string> + <string name="sign_out">Sign out</string> </resources> diff --git a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/apis/SessionApi.kt b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/apis/SessionApi.kt index 4344de0..417a818 100644 --- a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/apis/SessionApi.kt +++ b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/apis/SessionApi.kt @@ -25,7 +25,6 @@ class SessionApi(basePath: kotlin.String = "https://demo.traccar.org/api") : Api * @return void */ suspend fun sessionDelete(): Unit { - val localVariableConfig = RequestConfig( RequestMethod.DELETE, "/session" @@ -35,7 +34,10 @@ class SessionApi(basePath: kotlin.String = "https://demo.traccar.org/api") : Api ) return when (response.responseType) { - ResponseType.Success -> Unit + ResponseType.Success -> { + val settings = Settings() + settings.remove(ACCESS_TOKEN_KEY) + } ResponseType.Informational -> TODO() ResponseType.Redirection -> TODO() ResponseType.ClientError -> throw ClientException( @@ -54,11 +56,12 @@ class SessionApi(basePath: kotlin.String = "https://demo.traccar.org/api") : Api * @return User */ @Suppress("UNCHECKED_CAST") - suspend fun sessionGet(token: kotlin.String? = null): User { - val localVariableQuery: MultiValueMap = mapOf("token" to listOf("$token")) + suspend fun sessionGet(token: String? = null): User { + val query: MutableMap<String, List<String>> = mutableMapOf() + token?.let { query["userId"] = listOf(it) } val localVariableConfig = RequestConfig( RequestMethod.GET, - "/session", query = localVariableQuery + "/session", query = query ) val response = request<User>( localVariableConfig |