diff options
Diffstat (limited to 'androidApp')
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> |