aboutsummaryrefslogtreecommitdiff
path: root/androidApp/src
diff options
context:
space:
mode:
Diffstat (limited to 'androidApp/src')
-rw-r--r--androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesAdapter.kt15
-rw-r--r--androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesFragment.kt23
-rw-r--r--androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/MapFragment.kt45
-rw-r--r--androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsActivity.kt14
-rw-r--r--androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsViewModel.kt36
-rw-r--r--androidApp/src/main/res/drawable/ic_baseline_menu_24.xml10
-rw-r--r--androidApp/src/main/res/layout/units_activity.xml8
-rw-r--r--androidApp/src/main/res/values-es-rMX/strings.xml8
-rw-r--r--androidApp/src/main/res/values/strings.xml7
9 files changed, 114 insertions, 52 deletions
diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesAdapter.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesAdapter.kt
index 6a01e33..b38b20b 100644
--- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesAdapter.kt
+++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesAdapter.kt
@@ -1,21 +1,17 @@
package mx.trackermap.TrackerMap.android.devices
import android.graphics.Color
-import android.graphics.ColorFilter
-import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import android.view.ViewStructure
-import androidx.core.content.res.ResourcesCompat
import androidx.recyclerview.widget.RecyclerView
-import kotlinx.serialization.json.JsonNull
import mx.trackermap.TrackerMap.android.R
import mx.trackermap.TrackerMap.android.databinding.UnitItemBinding
+import mx.trackermap.TrackerMap.utils.Formatter
import mx.trackermap.TrackerMap.client.models.UnitInformation
enum class Action {
- DETAILS, REPORTS, COMMANDS
+ CLICK, DETAILS, REPORTS, COMMANDS
}
typealias ActionCallback = (unit: UnitInformation, action: Action) -> Unit
@@ -73,8 +69,11 @@ class DevicesAdapter(
driverName.text = unit.device.contact
unitSpeed.text = context.getString(R.string.unit_speed_format, unit.position?.speed?.toInt() ?: 0)
lastAddress.text = unit.position?.address
- lastDate.text = unit.position?.deviceTime
+ unit.position?.fixTime?.let {
+ lastDate.text = Formatter.formatDate(it)
+ }
actionCallback?.let { callback ->
+ unitCard.setOnClickListener { callback(unit, Action.CLICK) }
detailsButton.setOnClickListener { callback(unit, Action.DETAILS) }
reportsButton.setOnClickListener { callback(unit, Action.REPORTS) }
commandsButton.setOnClickListener { callback(unit, Action.COMMANDS) }
@@ -85,4 +84,4 @@ class DevicesAdapter(
override fun getItemCount(): Int = units.size
inner class ViewHolder(val binding: UnitItemBinding) : RecyclerView.ViewHolder(binding.root)
-} \ No newline at end of file
+}
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 a8782cc..bd3ab67 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
@@ -28,6 +28,7 @@ class DevicesFragment : Fragment() {
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
+ super.onCreateView(inflater, container, savedInstanceState)
_binding = DevicesFragmentBinding.inflate(inflater, container, false)
return binding.root
}
@@ -54,7 +55,8 @@ class DevicesFragment : Fragment() {
@DelicateCoroutinesApi
private fun setupObservers() {
- unitsViewModel.units.observe(this) { units ->
+ Log.d("DevicesFragment", "setupObservers()")
+ unitsViewModel.units.observe(viewLifecycleOwner) { units ->
Log.d("DevicesFragment", "Success $units")
binding.devicesList.swapAdapter(
DevicesAdapter(units, this::itemAction),
@@ -64,11 +66,18 @@ class DevicesFragment : Fragment() {
}
private fun itemAction(unit: UnitInformation, action: Action) {
- Log.d("DevicesFragment", "Action: $action - Unit: $unit")
- val activity = requireActivity()
- val intent = Intent(activity.applicationContext, DetailsActivity::class.java)
- intent.putExtra(DetailsActivity.DEVICE_ID_EXTRA, unit.device.id)
- intent.putExtra(DetailsActivity.ACTION_EXTRA, action)
- startActivity(intent)
+ when (action) {
+ Action.DETAILS, Action.REPORTS, Action.COMMANDS -> {
+ Log.d("DevicesFragment", "Action: $action - Unit: $unit")
+ val activity = requireActivity()
+ val intent = Intent(activity.applicationContext, DetailsActivity::class.java)
+ intent.putExtra(DetailsActivity.DEVICE_ID_EXTRA, unit.device.id)
+ intent.putExtra(DetailsActivity.ACTION_EXTRA, action)
+ startActivity(intent)
+ }
+ Action.CLICK -> {
+ unitsViewModel.selectUnit(unit)
+ }
+ }
}
} \ No newline at end of file
diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/MapFragment.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/MapFragment.kt
index f3d7cac..8dbd26c 100644
--- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/MapFragment.kt
+++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/MapFragment.kt
@@ -1,28 +1,25 @@
package mx.trackermap.TrackerMap.android.map
import android.graphics.BitmapFactory
-import android.graphics.Point
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.mousebird.maply.*
-import io.ktor.util.*
import kotlinx.coroutines.DelicateCoroutinesApi
import mx.trackermap.TrackerMap.android.R
-import mx.trackermap.TrackerMap.android.databinding.MapFragmentBinding
import mx.trackermap.TrackerMap.android.units.UnitsViewModel
import org.koin.androidx.viewmodel.ext.android.viewModel
import java.io.File
@DelicateCoroutinesApi
class MapFragment: GlobeMapFragment() {
- private var _binding: MapFragmentBinding? = null
- private val binding get() = _binding!!
private val unitsViewModel: UnitsViewModel by viewModel()
+ private val markers = mutableListOf<Pair<ScreenMarker, ComponentObject>>()
+
override fun chooseDisplayType(): MapDisplayType {
return MapDisplayType.Map
}
@@ -58,12 +55,7 @@ class MapFragment: GlobeMapFragment() {
val latitude = 23.191 * Math.PI / 180
val longitude = -100.36 * Math.PI / 180
val zoom = 0.4
- mapControl.animatePositionGeo(longitude, latitude, zoom, 1.0)
- }
-
- override fun onDestroyView() {
- super.onDestroyView()
- _binding = null
+ mapControl.setPositionGeo(longitude, latitude, zoom)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -74,13 +66,18 @@ class MapFragment: GlobeMapFragment() {
@DelicateCoroutinesApi
private fun setupObservers() {
- unitsViewModel.units.observe(this) { units ->
+ Log.d("MapFragment", "setupObservers()")
+ unitsViewModel.units.observe(viewLifecycleOwner) { units ->
+ /* Remove all markers */
+ markers.forEach {
+ mapControl.removeObject(it.second, ThreadMode.ThreadAny)
+ }
+ markers.clear()
+
+ /* Reinsert markers from units */
units.forEach { unit ->
unit.position?.let { position ->
if (position.longitude != null && position.longitude != null) {
-
- /* Add marker */
- val markerInfo = MarkerInfo()
val icon =
BitmapFactory.decodeResource(
activity!!.resources,
@@ -109,18 +106,32 @@ class MapFragment: GlobeMapFragment() {
else -> R.drawable.map_default
}
)
- val markerSize = Point2d(144.0, 144.0)
val marker = ScreenMarker()
+ val markerSize = Point2d(144.0, 144.0)
+
marker.loc = Point2d.FromDegrees(position.longitude!!, position.latitude!!)
marker.image = icon
marker.size = markerSize
marker.userObject = unit
- mapControl.addScreenMarker(marker, markerInfo, ThreadMode.ThreadAny)
+ /* Add marker to map */
+ val markerInfo = MarkerInfo()
+ val componentObject = mapControl.addScreenMarker(marker, markerInfo, ThreadMode.ThreadAny)
+ markers.add(marker to componentObject)
}
}
}
}
+ unitsViewModel.selectedUnit.observe(viewLifecycleOwner) {
+ it?.let { unit ->
+ unit.position?.let { position ->
+ val latitude = position.latitude!! * Math.PI / 180
+ val longitude = position.longitude!! * Math.PI / 180
+ val zoom = 0.000008
+ mapControl.setPositionGeo(longitude, latitude, zoom)
+ }
+ }
+ }
}
} \ 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 ea40d91..8a6f699 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
@@ -45,12 +45,7 @@ class UnitsActivity : AppCompatActivity() {
}
binding.searchInput.doAfterTextChanged {
Log.d("UnitsActivity", "Search changed to ${it.toString()}")
- unitsViewModel.searchQuery.value = it.toString()
- }
- binding.searchInput.setOnEditorActionListener { _, _, _ ->
- Log.d("UnitsActivity", "Search key tapped")
- unitsViewModel.search()
- true
+ unitsViewModel.search(it.toString())
}
}
@@ -63,6 +58,13 @@ class UnitsActivity : AppCompatActivity() {
else -> R.drawable.ic_baseline_map_24
}
)
+ binding.displayModeToggle.contentDescription = getString(
+ when (displayMode) {
+ UnitsViewModel.UnitsDisplayMode.LIST -> R.string.toggle_map
+ UnitsViewModel.UnitsDisplayMode.MAP -> R.string.toggle_list
+ else -> R.string.toggle_map
+ }
+ )
val newFragment =
when (displayMode) {
diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsViewModel.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsViewModel.kt
index bcb0818..d8d7ea1 100644
--- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsViewModel.kt
+++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsViewModel.kt
@@ -1,10 +1,7 @@
package mx.trackermap.TrackerMap.android.units
import android.util.Log
-import androidx.lifecycle.MutableLiveData
-import androidx.lifecycle.SavedStateHandle
-import androidx.lifecycle.ViewModel
-import androidx.lifecycle.viewModelScope
+import androidx.lifecycle.*
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
@@ -24,9 +21,15 @@ class UnitsViewModel(
private val unitsController: UnitsController by inject()
- var searchQuery = savedStateHandle.getLiveData("searchQuery", "")
- var unitsDisplayMode = MutableLiveData(UnitsDisplayMode.LIST)
- var units = MutableLiveData<List<UnitInformation>>()
+ private var _searchQuery = savedStateHandle.getLiveData("searchQuery", "")
+ private var _unitsDisplayMode = MutableLiveData(UnitsDisplayMode.LIST)
+ private var _units = MutableLiveData<List<UnitInformation>>()
+ private var _selectedUnit = MutableLiveData<UnitInformation?>()
+
+ val searchQuery: LiveData<String> get() = _searchQuery
+ val unitsDisplayMode: LiveData<UnitsDisplayMode> get() = _unitsDisplayMode
+ val units: LiveData<List<UnitInformation>> get() = _units
+ val selectedUnit: LiveData<UnitInformation?> get() = _selectedUnit
init {
Log.d("UnitsViewModel", "Initializing Units View Model")
@@ -38,10 +41,21 @@ class UnitsViewModel(
private suspend fun setupObservers() {
Log.d("UnitsViewModel", "Setup observers")
unitsController.displayedUnitsFlow.collect { units ->
- this.units.value = units
+ this._units.value = units
}
}
+ fun selectUnit(unit: UnitInformation) {
+ Log.d("UnitsViewModel", "Selecting unit ${unit.device.name}")
+ _selectedUnit.postValue(unit)
+ setDisplayMode(UnitsDisplayMode.MAP)
+ }
+
+ fun setDisplayMode(displayMode: UnitsDisplayMode) {
+ Log.d("UnitsViewModel", "Setting Display mode to $displayMode")
+ _unitsDisplayMode.postValue(displayMode)
+ }
+
fun toggleDisplayMode() {
Log.d("UnitsViewModel", "Toggling Display mode")
val newDisplayMode =
@@ -50,10 +64,10 @@ class UnitsViewModel(
} else {
UnitsDisplayMode.MAP
}
- unitsDisplayMode.postValue(newDisplayMode)
+ _unitsDisplayMode.postValue(newDisplayMode)
}
- fun search() {
- unitsController.search(searchQuery.value!!)
+ fun search(query: String) {
+ unitsController.search(query)
}
} \ No newline at end of file
diff --git a/androidApp/src/main/res/drawable/ic_baseline_menu_24.xml b/androidApp/src/main/res/drawable/ic_baseline_menu_24.xml
new file mode 100644
index 0000000..4350ba9
--- /dev/null
+++ b/androidApp/src/main/res/drawable/ic_baseline_menu_24.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="?attr/colorControlNormal">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M3,18h18v-2L3,16v2zM3,13h18v-2L3,11v2zM3,6v2h18L21,6L3,6z"/>
+</vector>
diff --git a/androidApp/src/main/res/layout/units_activity.xml b/androidApp/src/main/res/layout/units_activity.xml
index f0d80ab..bff3789 100644
--- a/androidApp/src/main/res/layout/units_activity.xml
+++ b/androidApp/src/main/res/layout/units_activity.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
@@ -26,7 +27,9 @@
app:fabSize="mini"
android:layout_marginStart="@dimen/fab_margin"
android:layout_marginTop="@dimen/fab_margin"
- app:elevation="@dimen/fab_elevation"/>
+ app:elevation="@dimen/fab_elevation"
+ android:src="@drawable/ic_baseline_menu_24"
+ android:contentDescription="@string/open_drawer"/>
<com.google.android.material.card.MaterialCardView
android:layout_width="0dp"
@@ -64,6 +67,7 @@
app:fabSize="mini"
android:layout_marginEnd="@dimen/fab_margin"
android:layout_marginTop="@dimen/fab_margin"
- app:elevation="@dimen/fab_elevation"/>
+ app:elevation="@dimen/fab_elevation"
+ tools:ignore="ContentDescription" />
</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/androidApp/src/main/res/values-es-rMX/strings.xml b/androidApp/src/main/res/values-es-rMX/strings.xml
index 0da9947..69ca1a8 100644
--- a/androidApp/src/main/res/values-es-rMX/strings.xml
+++ b/androidApp/src/main/res/values-es-rMX/strings.xml
@@ -7,6 +7,11 @@
<string name="login_password">Contraseña</string>
<string name="login_login">Iniciar sesión</string>
+ <!-- UnitsActivity -->
+ <string name="toggle_list">Cambiar a lista de dispositivos</string>
+ <string name="toggle_map">Cambiar a mapa</string>
+ <string name="open_drawer">Abrir menú lateral</string>
+
<!-- Unit Item -->
<string name="unit_status_on">Estatus encendido</string>
<string name="unit_status_off">Estatus apagado</string>
@@ -23,4 +28,7 @@
<string name="unit_reports">Reportes</string>
<string name="unit_commands">Comandos</string>
<string name="units_search">Escribe para buscar</string>
+
+ <string name="key">Key</string>
+ <string name="value">Value</string>
</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 7333a1e..453bc16 100644
--- a/androidApp/src/main/res/values/strings.xml
+++ b/androidApp/src/main/res/values/strings.xml
@@ -7,6 +7,11 @@
<string name="login_password">Password</string>
<string name="login_login">Login</string>
+ <!-- UnitsActivity -->
+ <string name="toggle_list">Switch to device list</string>
+ <string name="toggle_map">Switch to map</string>
+ <string name="open_drawer">Open drawer menu</string>
+
<!-- Unit Item -->
<string name="unit_status_on">Status on</string>
<string name="unit_status_off">Status off</string>
@@ -41,4 +46,4 @@
<string name="select_period">Select</string>
<string name="table_event">Event</string>
<string name="table_datetime">Datetime</string>
-</resources> \ No newline at end of file
+</resources>