From 41aad20b7ebe24f318476c7f3fdb6be744dd5b9d Mon Sep 17 00:00:00 2001 From: Iván Ávalos Date: Sun, 16 Jan 2022 14:09:38 -0600 Subject: Fixed focusOn not respecting max zoom, and added zoom level 21 to MapCalculus --- .../TrackerMap/android/map/MapFragment.kt | 27 +++++++++++++--------- .../mx/trackermap/TrackerMap/utils/MapCalculus.kt | 1 + 2 files changed, 17 insertions(+), 11 deletions(-) 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 f577613..cfb59a0 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 @@ -65,7 +65,7 @@ class MapFragment : GlobeMapFragment() { val tmpInfo = RemoteTileInfoNew(layer[0], layer[1].toInt(), layer[2].toInt()) tileInfo = tileInfoSetCacheDir(layer[0], tmpInfo) tileInfo?.let { - setZoomLimits(it.minZoom, it.maxZoom) + setZoomLimits(layer[1].toInt(), layer[2].toInt()) } } @@ -92,7 +92,7 @@ class MapFragment : GlobeMapFragment() { userMotion: Boolean ) { super.mapDidStopMoving(mapControl, corners, userMotion) - Log.d("MapFragment", "Height: ${mapControl?.height}") + Log.d("MapFragment", "Height: %7.7f".format(mapControl?.height)) } override fun userDidSelect( @@ -320,17 +320,22 @@ class MapFragment : GlobeMapFragment() { fun focusOn( latitude: Double, longitude: Double, - height: Double? = 0.00001, + height: Double = 0.00001, animated: Boolean = true ) { - val lat = latitude * Math.PI / 180 - val lon = longitude * Math.PI / 180 - // Ensure height is equal or higher than bottom limit - val z = mapControl.zoomLimitMin.coerceAtLeast(height ?: 0.0) - if (animated) { - mapControl.animatePositionGeo(lon, lat, z, 0.2) - } else { - mapControl.setPositionGeo(lon, lat, z) + mapControl?.addPostSurfaceRunnable { + val lat = latitude * Math.PI / 180 + val lon = longitude * Math.PI / 180 + // Ensure height is equal or higher than bottom limit + Log.d("MapFragment", "Target: %7.7f".format(height)) + Log.d("MapFragment", "Min: %7.7f".format(mapControl.zoomLimitMin)) + val z = height.coerceAtLeast(mapControl.zoomLimitMin) + Log.d("MapFragment", "Final: %7.7f".format(z)) + if (animated) { + mapControl.animatePositionGeo(lon, lat, z, 0.2) + } else { + mapControl.setPositionGeo(lon, lat, z) + } } } diff --git a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/utils/MapCalculus.kt b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/utils/MapCalculus.kt index 118c117..b1a6444 100644 --- a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/utils/MapCalculus.kt +++ b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/utils/MapCalculus.kt @@ -31,6 +31,7 @@ class MapCalculus { 19 -> 1066.36479193 20 -> 533.182395965 21 -> 266.5911979825 + 22 -> 133.29559899125 else -> null } } -- cgit v1.2.3 From 484c64d1682f65ad0741228963bdefda87b935ab Mon Sep 17 00:00:00 2001 From: Iván Ávalos Date: Sun, 16 Jan 2022 14:23:04 -0600 Subject: Fixed NullPointerException and device not getting centered after selected from list view --- .../java/mx/trackermap/TrackerMap/android/map/MapFragment.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) 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 cfb59a0..b8ce350 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 @@ -81,9 +81,9 @@ class MapFragment : GlobeMapFragment() { loader = QuadImageLoader(params, tileInfo, baseControl) loader?.setImageFormat(RenderController.ImageFormat.MaplyImageUShort565) - val latitude = 23.191 - val longitude = -100.36 - focusOn(latitude, longitude, height = 0.4, animated = false) + val latitude = 23.191 * Math.PI / 180 + val longitude = -100.36 * Math.PI / 180 + mapControl.setPositionGeo(latitude, longitude, 0.4) } override fun mapDidStopMoving( @@ -235,9 +235,9 @@ class MapFragment : GlobeMapFragment() { } mbr.expandByFraction(0.1) - mapControl.addPostSurfaceRunnable { - val zoom = mapControl.zoomLimitMax.coerceAtLeast( - mapControl.findHeightToViewBounds(mbr, mbr.middle())) + mapControl?.addPostSurfaceRunnable { + val zoom = mapControl.findHeightToViewBounds(mbr, mbr.middle()) + .coerceAtLeast(mapControl.zoomLimitMin) mapControl.setPositionGeo(mbr.middle(), zoom) } } -- cgit v1.2.3 From 16b614d6f3fcc88924e79ac3a1bffef538b09e8b Mon Sep 17 00:00:00 2001 From: Iván Ávalos Date: Sun, 16 Jan 2022 16:11:47 -0600 Subject: Added hourmeter field --- .../android/details/information/UnitInformationFragment.kt | 8 ++++++++ .../TrackerMap/android/devices/UnitRenderData.kt | 14 ++++++++++++++ androidApp/src/main/res/drawable/position_hourmeter.xml | 10 ++++++++++ androidApp/src/main/res/values-es-rMX/strings.xml | 1 + androidApp/src/main/res/values/strings.xml | 1 + .../kotlin/mx/trackermap/TrackerMap/utils/Formatter.kt | 5 ++++- 6 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 androidApp/src/main/res/drawable/position_hourmeter.xml diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/information/UnitInformationFragment.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/information/UnitInformationFragment.kt index 0c3577e..6c15ae4 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/information/UnitInformationFragment.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/information/UnitInformationFragment.kt @@ -13,6 +13,7 @@ import androidx.core.widget.TextViewCompat import androidx.fragment.app.Fragment import com.google.android.material.button.MaterialButton import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.serialization.json.longOrNull import mx.trackermap.TrackerMap.android.R import mx.trackermap.TrackerMap.android.databinding.UnitDetailsInformationBinding import mx.trackermap.TrackerMap.android.details.UnitDetailsAdapter @@ -94,6 +95,13 @@ class UnitInformationFragment : Fragment() { unit.position?.address?.let { address -> details.add(getString(R.string.unit_info_address) to address) } + unit.position?.attributes?.get("hours")?.longOrNull?.let { + if (it > 0) { + details.add( + getString(R.string.unit_hourmeter) to Formatter.formatHours(it) + ) + } + } unit.position?.protocol?.let { protocol -> details.add(getString(R.string.unit_info_protocol) to protocol) } diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/UnitRenderData.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/UnitRenderData.kt index beeba6f..c7999de 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/UnitRenderData.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/UnitRenderData.kt @@ -12,6 +12,7 @@ import android.widget.TextView import androidx.cardview.widget.CardView import androidx.core.content.ContextCompat import com.zerobranch.layout.SwipeLayout +import kotlinx.serialization.json.longOrNull import mx.trackermap.TrackerMap.android.R import mx.trackermap.TrackerMap.android.map.MarkerTransformations import mx.trackermap.TrackerMap.client.models.UnitInformation @@ -128,6 +129,19 @@ class UnitRenderData { ) } + /* Hourmeter */ + position.attributes["hours"]?.longOrNull?.let { + if (it > 0) { + details.add( + Triple( + R.drawable.position_hourmeter, + Formatter.formatHours(it), + context.getString(R.string.unit_hourmeter) + ) + ) + } + } + /* Date time */ position.fixTime?.let { fixTime -> details.add( diff --git a/androidApp/src/main/res/drawable/position_hourmeter.xml b/androidApp/src/main/res/drawable/position_hourmeter.xml new file mode 100644 index 0000000..52ff427 --- /dev/null +++ b/androidApp/src/main/res/drawable/position_hourmeter.xml @@ -0,0 +1,10 @@ + + + diff --git a/androidApp/src/main/res/values-es-rMX/strings.xml b/androidApp/src/main/res/values-es-rMX/strings.xml index 5e41768..f843c29 100644 --- a/androidApp/src/main/res/values-es-rMX/strings.xml +++ b/androidApp/src/main/res/values-es-rMX/strings.xml @@ -31,6 +31,7 @@ Nombre del conductor Velocidad Dirección de la última posición + Horómetro Fecha y hora de la última posición Animal diff --git a/androidApp/src/main/res/values/strings.xml b/androidApp/src/main/res/values/strings.xml index 11c914f..60547d3 100644 --- a/androidApp/src/main/res/values/strings.xml +++ b/androidApp/src/main/res/values/strings.xml @@ -44,6 +44,7 @@ Driver name Speed Last position address + Hourmeter Last position datetime Animal diff --git a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/utils/Formatter.kt b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/utils/Formatter.kt index 878418e..c113bef 100644 --- a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/utils/Formatter.kt +++ b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/utils/Formatter.kt @@ -1,7 +1,6 @@ package mx.trackermap.TrackerMap.utils import kotlinx.datetime.* -import kotlin.math.round class Formatter { companion object { @@ -25,5 +24,9 @@ class Formatter { } } } + + fun formatHours(millis: Long): String { + return "${millis / (1000 * 60 * 60)} hr" + } } } \ No newline at end of file -- cgit v1.2.3 From e2a836e7a82892c13d67f0767070c99007394186 Mon Sep 17 00:00:00 2001 From: Iván Ávalos Date: Sun, 16 Jan 2022 16:28:24 -0600 Subject: Added fake close button to unit_map_fragment.xml --- androidApp/src/main/res/drawable/icon_close.xml | 10 +++++ .../src/main/res/layout/unit_map_fragment.xml | 45 ++++++++++++++++------ androidApp/src/main/res/values-es-rMX/strings.xml | 3 +- androidApp/src/main/res/values/strings.xml | 1 + 4 files changed, 46 insertions(+), 13 deletions(-) create mode 100644 androidApp/src/main/res/drawable/icon_close.xml diff --git a/androidApp/src/main/res/drawable/icon_close.xml b/androidApp/src/main/res/drawable/icon_close.xml new file mode 100644 index 0000000..16d6d37 --- /dev/null +++ b/androidApp/src/main/res/drawable/icon_close.xml @@ -0,0 +1,10 @@ + + + diff --git a/androidApp/src/main/res/layout/unit_map_fragment.xml b/androidApp/src/main/res/layout/unit_map_fragment.xml index 8395013..e2bee95 100644 --- a/androidApp/src/main/res/layout/unit_map_fragment.xml +++ b/androidApp/src/main/res/layout/unit_map_fragment.xml @@ -30,20 +30,25 @@ app:contentPaddingTop="@dimen/card_padding" app:contentPaddingLeft="@dimen/card_padding" app:contentPaddingRight="@dimen/card_padding" - android:visibility="gone"> + android:animateLayoutChanges="true" + android:visibility="gone" + tools:visibility="visible"> - + android:orientation="vertical"> + android:orientation="horizontal" + app:layout_constraintEnd_toStartOf="@+id/closeButton" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> + + + android:layout_width="0dp" + android:layout_height="wrap_content" + app:layout_constraintTop_toBottomOf="@id/titleLayout" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" /> + android:visibility="visible" + app:layout_constraintTop_toBottomOf="@id/gridLayout" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintBottom_toBottomOf="parent"> - + diff --git a/androidApp/src/main/res/values-es-rMX/strings.xml b/androidApp/src/main/res/values-es-rMX/strings.xml index f843c29..d228c28 100644 --- a/androidApp/src/main/res/values-es-rMX/strings.xml +++ b/androidApp/src/main/res/values-es-rMX/strings.xml @@ -2,7 +2,8 @@ OK - Cancel + Cancelar + Cerrar Nombre de usuario diff --git a/androidApp/src/main/res/values/strings.xml b/androidApp/src/main/res/values/strings.xml index 60547d3..d2c6148 100644 --- a/androidApp/src/main/res/values/strings.xml +++ b/androidApp/src/main/res/values/strings.xml @@ -16,6 +16,7 @@ OK Cancel + Close Username -- cgit v1.2.3 From f5355cf5b6281c8475a06061ac5fc80f7b9cdedf Mon Sep 17 00:00:00 2001 From: Iván Ávalos Date: Sun, 16 Jan 2022 16:39:00 -0600 Subject: Moved stuff to shared package --- .../android/details/reports/UnitReportsFragment.kt | 2 +- .../TrackerMap/android/devices/DevicesAdapter.kt | 8 +- .../TrackerMap/android/devices/DevicesFragment.kt | 11 +- .../TrackerMap/android/devices/UnitRenderData.kt | 218 -------------------- .../TrackerMap/android/map/MapFragment.kt | 1 + .../android/map/MarkerTransformations.kt | 142 ------------- .../TrackerMap/android/map/UnitMapFragment.kt | 14 +- .../android/shared/MarkerTransformations.kt | 143 +++++++++++++ .../TrackerMap/android/shared/UnitRenderData.kt | 221 +++++++++++++++++++++ 9 files changed, 382 insertions(+), 378 deletions(-) delete mode 100644 androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/UnitRenderData.kt delete mode 100644 androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/MarkerTransformations.kt create mode 100644 androidApp/src/main/java/mx/trackermap/TrackerMap/android/shared/MarkerTransformations.kt create mode 100644 androidApp/src/main/java/mx/trackermap/TrackerMap/android/shared/UnitRenderData.kt diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/reports/UnitReportsFragment.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/reports/UnitReportsFragment.kt index 20d2a48..3b3570b 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/reports/UnitReportsFragment.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/reports/UnitReportsFragment.kt @@ -22,7 +22,7 @@ import mx.trackermap.TrackerMap.android.R import mx.trackermap.TrackerMap.android.databinding.UnitDetailsReportsBinding import mx.trackermap.TrackerMap.android.details.UnitDetailsAdapter import mx.trackermap.TrackerMap.android.map.MapFragment -import mx.trackermap.TrackerMap.android.map.MarkerTransformations +import mx.trackermap.TrackerMap.android.shared.MarkerTransformations import mx.trackermap.TrackerMap.client.models.EventInformation import mx.trackermap.TrackerMap.client.models.Position import mx.trackermap.TrackerMap.client.models.Stop 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 344907c..b1854a9 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,19 +1,15 @@ package mx.trackermap.TrackerMap.android.devices -import android.util.TypedValue import android.view.LayoutInflater import android.view.ViewGroup -import android.widget.FrameLayout import androidx.core.view.updateLayoutParams import androidx.recyclerview.widget.RecyclerView import mx.trackermap.TrackerMap.android.R import mx.trackermap.TrackerMap.android.databinding.UnitItemBinding +import mx.trackermap.TrackerMap.android.shared.ActionCallback +import mx.trackermap.TrackerMap.android.shared.UnitRenderData import mx.trackermap.TrackerMap.client.models.UnitInformation -enum class Action { - CLICK, DETAILS, REPORTS, COMMANDS -} - class DevicesAdapter( private val units: List, private val actionCallback: ActionCallback? 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 96d4696..b1a3663 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 @@ -6,12 +6,11 @@ import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.view.ViewTreeObserver -import android.widget.Toast 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.shared.UnitRenderData import mx.trackermap.TrackerMap.android.units.UnitFragment import mx.trackermap.TrackerMap.android.units.UnitsViewModel import mx.trackermap.TrackerMap.client.models.UnitInformation @@ -82,9 +81,11 @@ class DevicesFragment(private val unitsViewModel: UnitsViewModel) : UnitFragment unitsViewModel.units.removeObservers(viewLifecycleOwner) } - private fun itemAction(unit: UnitInformation, action: Action) { + private fun itemAction(unit: UnitInformation, action: UnitRenderData.Action) { when (action) { - Action.DETAILS, Action.REPORTS, Action.COMMANDS -> { + UnitRenderData.Action.DETAILS, + UnitRenderData.Action.REPORTS, + UnitRenderData.Action.COMMANDS -> { Log.d("DevicesFragment", "Action: $action - Unit: $unit") val activity = requireActivity() val intent = Intent(activity.applicationContext, DetailsActivity::class.java) @@ -93,7 +94,7 @@ class DevicesFragment(private val unitsViewModel: UnitsViewModel) : UnitFragment intent.putExtra(DetailsActivity.ACTION_EXTRA, action) startActivity(intent) } - Action.CLICK -> { + UnitRenderData.Action.CLICK -> { unitsViewModel.selectUnit(unit) } } diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/UnitRenderData.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/UnitRenderData.kt deleted file mode 100644 index c7999de..0000000 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/UnitRenderData.kt +++ /dev/null @@ -1,218 +0,0 @@ -package mx.trackermap.TrackerMap.android.devices - -import android.content.Context -import android.graphics.Color -import android.util.TypedValue -import android.view.Gravity -import android.view.View -import android.widget.Button -import android.widget.GridLayout -import android.widget.ImageView -import android.widget.TextView -import androidx.cardview.widget.CardView -import androidx.core.content.ContextCompat -import com.zerobranch.layout.SwipeLayout -import kotlinx.serialization.json.longOrNull -import mx.trackermap.TrackerMap.android.R -import mx.trackermap.TrackerMap.android.map.MarkerTransformations -import mx.trackermap.TrackerMap.client.models.UnitInformation -import mx.trackermap.TrackerMap.utils.Formatter -import mx.trackermap.TrackerMap.utils.SpeedUnit - -typealias ActionCallback = (unit: UnitInformation, action: Action) -> Unit - -class UnitRenderData { - data class UnitRenderViewHolder( - val unitName: TextView, - val unitIcon: ImageView? = null, - val statusIcon: ImageView, - val engineStopIcon: ImageView, - val gridLayout: GridLayout, - val detailsButton: Button? = null, - val reportsButton: Button? = null, - val commandsButton: Button? = null, - val unitCard: CardView? = null, - val swipeLayout: SwipeLayout? = null - ) - - companion object { - fun render( - viewHolder: UnitRenderViewHolder, - context: Context, - unit: UnitInformation, - actionCallback: ActionCallback? - ) { - viewHolder.apply { - val details: MutableList> = mutableListOf() - - /* Device name */ - unitName.text = unit.device.name - - /* Device icon */ - unitIcon?.setImageResource( - MarkerTransformations.categoryToResourceId(unit.device.category) - ) - unitIcon?.contentDescription = context.getString( - MarkerTransformations.categoryToStringId(unit.device.category) - ) - - /* Contact */ - unit.device.contact?.let { contact -> - if (contact.isNotEmpty()) { - details.add( - Triple( - R.drawable.device_contact, - contact, - context.getString(R.string.unit_driver_name) - ) - ) - } - } - - statusIcon.visibility = View.GONE - engineStopIcon.visibility = View.GONE - - unit.position?.let { position -> - /* Status icon */ - statusIcon.visibility = View.VISIBLE - position.speed?.let { speed -> - if (speed >= 2) { - statusIcon.setColorFilter( - ContextCompat.getColor(context, R.color.colorOnline) - ) - } else { - statusIcon.setColorFilter( - ContextCompat.getColor(context, R.color.colorOffline) - ) - } - } ?: run { - statusIcon.setColorFilter(Color.GRAY) - } - - /* Engine stop */ - val attributes = position.attributes - if (attributes["out1"].toString() != "null") { - engineStopIcon.visibility = View.VISIBLE - engineStopIcon.setImageResource( - when (attributes["out1"].toString()) { - "true" -> R.drawable.device_unlocked - "false" -> R.drawable.device_locked - else -> R.drawable.device_locked - } - ) - engineStopIcon.contentDescription = when (attributes["out1"].toString()) { - "true" -> context.getString(R.string.unit_lock_on) - "false" -> context.getString(R.string.unit_lock_off) - else -> context.getString(R.string.unit_lock_on) - } - } - - /* Speed */ - position.speed?.let { speed -> - details.add( - Triple( - R.drawable.position_speed, - Formatter.formatSpeed(speed, SpeedUnit.KMH), - context.getString(R.string.unit_speed) - ) - ) - } - - /* Address */ - position.address?.let { address -> - details.add( - Triple( - R.drawable.position_address, - address, - context.getString(R.string.unit_last_address) - ) - ) - } - - /* Hourmeter */ - position.attributes["hours"]?.longOrNull?.let { - if (it > 0) { - details.add( - Triple( - R.drawable.position_hourmeter, - Formatter.formatHours(it), - context.getString(R.string.unit_hourmeter) - ) - ) - } - } - - /* Date time */ - position.fixTime?.let { fixTime -> - details.add( - Triple( - R.drawable.position_datetime, - Formatter.formatDate(fixTime), - context.getString(R.string.unit_last_date) - ) - ) - } - } - - gridLayout.removeAllViewsInLayout() - val metrics = context.resources.displayMetrics - details.forEachIndexed { i, detail -> - /* Property icon */ - val imageView = ImageView(gridLayout.context) - imageView.setImageResource(detail.first) - imageView.contentDescription = detail.third - imageView.setColorFilter( - ContextCompat.getColor( - context, - androidx.appcompat.R.color.secondary_text_default_material_light - ) - ) - - val imageLayout = GridLayout.LayoutParams() - imageLayout.width = GridLayout.LayoutParams.WRAP_CONTENT - imageLayout.height = GridLayout.LayoutParams.WRAP_CONTENT - imageLayout.marginEnd = - TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 6f, metrics).toInt() - imageLayout.rowSpec = GridLayout.spec(i) - imageLayout.columnSpec = GridLayout.spec(0) - imageView.layoutParams = imageLayout - - /* Property text */ - val textView = TextView(gridLayout.context) - textView.text = detail.second - - val textLayout = GridLayout.LayoutParams() - textLayout.width = 0 - textLayout.height = GridLayout.LayoutParams.MATCH_PARENT - textLayout.rowSpec = GridLayout.spec(i) - textLayout.columnSpec = GridLayout.spec(1, 1, 5f) - textView.layoutParams = textLayout - - gridLayout.addView(imageView) - gridLayout.addView(textView) - - imageLayout.setGravity(Gravity.CENTER) - } - - actionCallback?.let { callback -> - unitCard?.setOnClickListener { - swipeLayout?.close() - callback(unit, Action.CLICK) - } - detailsButton?.setOnClickListener { - swipeLayout?.close() - callback(unit, Action.DETAILS) - } - reportsButton?.setOnClickListener { - swipeLayout?.close() - callback(unit, Action.REPORTS) - } - commandsButton?.setOnClickListener { - swipeLayout?.close() - callback(unit, Action.COMMANDS) - } - } - } - } - } -} \ 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 b8ce350..6a80f95 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 @@ -17,6 +17,7 @@ import mil.nga.sf.util.SFException import mil.nga.sf.wkt.GeometryReader import java.io.File import mx.trackermap.TrackerMap.android.R +import mx.trackermap.TrackerMap.android.shared.MarkerTransformations import mx.trackermap.TrackerMap.client.models.Geofence import mx.trackermap.TrackerMap.client.models.MapLayer import mx.trackermap.TrackerMap.utils.MapCalculus diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/MarkerTransformations.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/MarkerTransformations.kt deleted file mode 100644 index 933cd8a..0000000 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/MarkerTransformations.kt +++ /dev/null @@ -1,142 +0,0 @@ -package mx.trackermap.TrackerMap.android.map - -import android.util.Log -import mx.trackermap.TrackerMap.android.R -import mx.trackermap.TrackerMap.client.models.Position -import mx.trackermap.TrackerMap.client.models.Stop -import mx.trackermap.TrackerMap.client.models.UnitInformation -import mx.trackermap.TrackerMap.utils.MarkerType - -object MarkerTransformations { - fun unitToMarker(unit: UnitInformation): MapFragment.Marker? { - if (unit.position == null || unit.position!!.latitude == null || unit.position!!.longitude == null) { - return null - } - - return MapFragment.Marker( - unit.position!!.id!!, - unit.device.name, - unit.position!!.latitude!!, - unit.position!!.longitude!!, - categoryToMarkerType(unit.device.category ?: "") - ) - } - - fun positionToMarker(position: Position): MapFragment.Marker? { - if (position.latitude == null || position.longitude == null) { - return null - } - - return MapFragment.Marker( - position.id!!, - "", - position.latitude!!, - position.longitude!! - ) - } - - fun stopToMarker(stop: Stop): MapFragment.Marker? { - Log.d("MarkerTransformations", "stopToMarker($stop)") - if (stop.latitude == null || stop.longitude == null) { - return null - } - - return MapFragment.Marker( - stop.deviceId!!, - stop.deviceName!!, - stop.latitude!!, - stop.longitude!! - ) - } - - private fun categoryToMarkerType(category: String?): MarkerType { - return when (category?.lowercase()) { - "animal" -> MarkerType.ANIMAL - "bicycle" -> MarkerType.BICYCLE - "boat" -> MarkerType.BOAT - "bus" -> MarkerType.BUS - "car" -> MarkerType.CAR - "crane" -> MarkerType.CRANE - "helicopter" -> MarkerType.HELICOPTER - "motorcycle" -> MarkerType.MOTORCYCLE - "offroad" -> MarkerType.OFFROAD - "person" -> MarkerType.PERSON - "pickup" -> MarkerType.PICKUP - "plane" -> MarkerType.PLANE - "scooter" -> MarkerType.SCOOTER - "ship" -> MarkerType.SHIP - "tractor" -> MarkerType.TRACTOR - "train" -> MarkerType.TRAIN - "tram" -> MarkerType.TRAM - "trolleybus" -> MarkerType.TROLLEYBUS - "truck" -> MarkerType.TRUCK - "van" -> MarkerType.VAN - else -> MarkerType.DEFAULT - } - } - - fun markerTypeToResourceId(markerType: MarkerType): Int { - return when (markerType) { - MarkerType.ANIMAL -> R.drawable.map_animal - MarkerType.BICYCLE -> R.drawable.map_bicycle - MarkerType.BOAT -> R.drawable.map_boat - MarkerType.BUS -> R.drawable.map_bus - MarkerType.CAR -> R.drawable.map_car - MarkerType.CRANE -> R.drawable.map_crane - MarkerType.DEFAULT -> R.drawable.map_default - MarkerType.HELICOPTER -> R.drawable.map_helicopter - MarkerType.MOTORCYCLE -> R.drawable.map_motorcycle - MarkerType.OFFROAD -> R.drawable.map_offroad - MarkerType.PERSON -> R.drawable.map_person - MarkerType.PICKUP -> R.drawable.map_pickup - MarkerType.PLANE -> R.drawable.map_plane - MarkerType.SCOOTER -> R.drawable.map_scooter - MarkerType.SHIP -> R.drawable.map_ship - MarkerType.TRACTOR -> R.drawable.map_tractor - MarkerType.TRAIN -> R.drawable.map_train - MarkerType.TRAM -> R.drawable.map_tram - MarkerType.TROLLEYBUS -> R.drawable.map_trolleybus - MarkerType.TRUCK -> R.drawable.map_truck - MarkerType.VAN -> R.drawable.map_van - - MarkerType.REPORT_POSITION -> R.drawable.map_report_position - MarkerType.REPORT_START -> R.drawable.map_report_start - MarkerType.REPORT_END -> R.drawable.map_report_end - } - } - - fun markerTypeToStringId(markerType: MarkerType): Int { - return when (markerType) { - MarkerType.ANIMAL -> R.string.unit_category_animal - MarkerType.BICYCLE -> R.string.unit_category_bicycle - MarkerType.BOAT -> R.string.unit_category_boat - MarkerType.BUS -> R.string.unit_category_bus - MarkerType.CAR -> R.string.unit_category_car - MarkerType.CRANE -> R.string.unit_category_crane - MarkerType.DEFAULT -> R.string.unit_category_default - MarkerType.HELICOPTER -> R.string.unit_category_helicopter - MarkerType.MOTORCYCLE -> R.string.unit_category_motorcycle - MarkerType.OFFROAD -> R.string.unit_category_offroad - MarkerType.PERSON -> R.string.unit_category_person - MarkerType.PICKUP -> R.string.unit_category_pickup - MarkerType.PLANE -> R.string.unit_category_plane - MarkerType.SCOOTER -> R.string.unit_category_scooter - MarkerType.SHIP -> R.string.unit_category_ship - MarkerType.TRACTOR -> R.string.unit_category_tractor - MarkerType.TRAIN -> R.string.unit_category_train - MarkerType.TRAM -> R.string.unit_category_tram - MarkerType.TROLLEYBUS -> R.string.unit_category_trolleybus - MarkerType.TRUCK -> R.string.unit_category_truck - MarkerType.VAN -> R.string.unit_category_van - else -> R.string.unit_category_default - } - } - - fun categoryToResourceId(category: String?): Int { - return markerTypeToResourceId(categoryToMarkerType(category)) - } - - fun categoryToStringId(category: String?): Int { - return markerTypeToResourceId(categoryToMarkerType(category)) - } -} \ No newline at end of file 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 6f6596f..6ea5f82 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 @@ -11,8 +11,8 @@ 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.shared.MarkerTransformations +import mx.trackermap.TrackerMap.android.shared.UnitRenderData import mx.trackermap.TrackerMap.android.units.UnitFragment import mx.trackermap.TrackerMap.android.units.UnitsViewModel import mx.trackermap.TrackerMap.client.models.UnitInformation @@ -117,10 +117,12 @@ class UnitMapFragment(private val unitsViewModel: UnitsViewModel) : UnitFragment unitsViewModel.geofences.removeObservers(viewLifecycleOwner) } - private fun itemAction(unit: UnitInformation, action: Action) { + private fun itemAction(unit: UnitInformation, action: UnitRenderData.Action) { when (action) { - Action.DETAILS, Action.REPORTS, Action.COMMANDS -> { - Log.d("DevicesFragment", "Action: $action - Unit: $unit") + UnitRenderData.Action.DETAILS, + UnitRenderData.Action.REPORTS, + UnitRenderData.Action.COMMANDS -> { + Log.d("UnitMapFragment", "Action: $action - Unit: $unit") val activity = requireActivity() val intent = Intent(activity.applicationContext, DetailsActivity::class.java) intent.putExtra(DetailsActivity.DEVICE_ID_EXTRA, unit.device.id) @@ -128,7 +130,7 @@ class UnitMapFragment(private val unitsViewModel: UnitsViewModel) : UnitFragment intent.putExtra(DetailsActivity.ACTION_EXTRA, action) startActivity(intent) } - Action.CLICK -> { + UnitRenderData.Action.CLICK -> { unitsViewModel.selectUnit(unit) } } diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/shared/MarkerTransformations.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/shared/MarkerTransformations.kt new file mode 100644 index 0000000..660b436 --- /dev/null +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/shared/MarkerTransformations.kt @@ -0,0 +1,143 @@ +package mx.trackermap.TrackerMap.android.shared + +import android.util.Log +import mx.trackermap.TrackerMap.android.R +import mx.trackermap.TrackerMap.android.map.MapFragment +import mx.trackermap.TrackerMap.client.models.Position +import mx.trackermap.TrackerMap.client.models.Stop +import mx.trackermap.TrackerMap.client.models.UnitInformation +import mx.trackermap.TrackerMap.utils.MarkerType + +object MarkerTransformations { + fun unitToMarker(unit: UnitInformation): MapFragment.Marker? { + if (unit.position == null || unit.position!!.latitude == null || unit.position!!.longitude == null) { + return null + } + + return MapFragment.Marker( + unit.position!!.id!!, + unit.device.name, + unit.position!!.latitude!!, + unit.position!!.longitude!!, + categoryToMarkerType(unit.device.category ?: "") + ) + } + + fun positionToMarker(position: Position): MapFragment.Marker? { + if (position.latitude == null || position.longitude == null) { + return null + } + + return MapFragment.Marker( + position.id!!, + "", + position.latitude!!, + position.longitude!! + ) + } + + fun stopToMarker(stop: Stop): MapFragment.Marker? { + Log.d("MarkerTransformations", "stopToMarker($stop)") + if (stop.latitude == null || stop.longitude == null) { + return null + } + + return MapFragment.Marker( + stop.deviceId!!, + stop.deviceName!!, + stop.latitude!!, + stop.longitude!! + ) + } + + private fun categoryToMarkerType(category: String?): MarkerType { + return when (category?.lowercase()) { + "animal" -> MarkerType.ANIMAL + "bicycle" -> MarkerType.BICYCLE + "boat" -> MarkerType.BOAT + "bus" -> MarkerType.BUS + "car" -> MarkerType.CAR + "crane" -> MarkerType.CRANE + "helicopter" -> MarkerType.HELICOPTER + "motorcycle" -> MarkerType.MOTORCYCLE + "offroad" -> MarkerType.OFFROAD + "person" -> MarkerType.PERSON + "pickup" -> MarkerType.PICKUP + "plane" -> MarkerType.PLANE + "scooter" -> MarkerType.SCOOTER + "ship" -> MarkerType.SHIP + "tractor" -> MarkerType.TRACTOR + "train" -> MarkerType.TRAIN + "tram" -> MarkerType.TRAM + "trolleybus" -> MarkerType.TROLLEYBUS + "truck" -> MarkerType.TRUCK + "van" -> MarkerType.VAN + else -> MarkerType.DEFAULT + } + } + + fun markerTypeToResourceId(markerType: MarkerType): Int { + return when (markerType) { + MarkerType.ANIMAL -> R.drawable.map_animal + MarkerType.BICYCLE -> R.drawable.map_bicycle + MarkerType.BOAT -> R.drawable.map_boat + MarkerType.BUS -> R.drawable.map_bus + MarkerType.CAR -> R.drawable.map_car + MarkerType.CRANE -> R.drawable.map_crane + MarkerType.DEFAULT -> R.drawable.map_default + MarkerType.HELICOPTER -> R.drawable.map_helicopter + MarkerType.MOTORCYCLE -> R.drawable.map_motorcycle + MarkerType.OFFROAD -> R.drawable.map_offroad + MarkerType.PERSON -> R.drawable.map_person + MarkerType.PICKUP -> R.drawable.map_pickup + MarkerType.PLANE -> R.drawable.map_plane + MarkerType.SCOOTER -> R.drawable.map_scooter + MarkerType.SHIP -> R.drawable.map_ship + MarkerType.TRACTOR -> R.drawable.map_tractor + MarkerType.TRAIN -> R.drawable.map_train + MarkerType.TRAM -> R.drawable.map_tram + MarkerType.TROLLEYBUS -> R.drawable.map_trolleybus + MarkerType.TRUCK -> R.drawable.map_truck + MarkerType.VAN -> R.drawable.map_van + + MarkerType.REPORT_POSITION -> R.drawable.map_report_position + MarkerType.REPORT_START -> R.drawable.map_report_start + MarkerType.REPORT_END -> R.drawable.map_report_end + } + } + + fun markerTypeToStringId(markerType: MarkerType): Int { + return when (markerType) { + MarkerType.ANIMAL -> R.string.unit_category_animal + MarkerType.BICYCLE -> R.string.unit_category_bicycle + MarkerType.BOAT -> R.string.unit_category_boat + MarkerType.BUS -> R.string.unit_category_bus + MarkerType.CAR -> R.string.unit_category_car + MarkerType.CRANE -> R.string.unit_category_crane + MarkerType.DEFAULT -> R.string.unit_category_default + MarkerType.HELICOPTER -> R.string.unit_category_helicopter + MarkerType.MOTORCYCLE -> R.string.unit_category_motorcycle + MarkerType.OFFROAD -> R.string.unit_category_offroad + MarkerType.PERSON -> R.string.unit_category_person + MarkerType.PICKUP -> R.string.unit_category_pickup + MarkerType.PLANE -> R.string.unit_category_plane + MarkerType.SCOOTER -> R.string.unit_category_scooter + MarkerType.SHIP -> R.string.unit_category_ship + MarkerType.TRACTOR -> R.string.unit_category_tractor + MarkerType.TRAIN -> R.string.unit_category_train + MarkerType.TRAM -> R.string.unit_category_tram + MarkerType.TROLLEYBUS -> R.string.unit_category_trolleybus + MarkerType.TRUCK -> R.string.unit_category_truck + MarkerType.VAN -> R.string.unit_category_van + else -> R.string.unit_category_default + } + } + + fun categoryToResourceId(category: String?): Int { + return markerTypeToResourceId(categoryToMarkerType(category)) + } + + fun categoryToStringId(category: String?): Int { + return markerTypeToResourceId(categoryToMarkerType(category)) + } +} \ No newline at end of file diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/shared/UnitRenderData.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/shared/UnitRenderData.kt new file mode 100644 index 0000000..e8a4bd6 --- /dev/null +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/shared/UnitRenderData.kt @@ -0,0 +1,221 @@ +package mx.trackermap.TrackerMap.android.shared + +import android.content.Context +import android.graphics.Color +import android.util.TypedValue +import android.view.Gravity +import android.view.View +import android.widget.Button +import android.widget.GridLayout +import android.widget.ImageView +import android.widget.TextView +import androidx.cardview.widget.CardView +import androidx.core.content.ContextCompat +import com.zerobranch.layout.SwipeLayout +import kotlinx.serialization.json.longOrNull +import mx.trackermap.TrackerMap.android.R +import mx.trackermap.TrackerMap.client.models.UnitInformation +import mx.trackermap.TrackerMap.utils.Formatter +import mx.trackermap.TrackerMap.utils.SpeedUnit + +typealias ActionCallback = (unit: UnitInformation, action: UnitRenderData.Action) -> Unit + +class UnitRenderData { + data class UnitRenderViewHolder( + val unitName: TextView, + val unitIcon: ImageView? = null, + val statusIcon: ImageView, + val engineStopIcon: ImageView, + val gridLayout: GridLayout, + val detailsButton: Button? = null, + val reportsButton: Button? = null, + val commandsButton: Button? = null, + val unitCard: CardView? = null, + val swipeLayout: SwipeLayout? = null + ) + + enum class Action { + CLICK, DETAILS, REPORTS, COMMANDS + } + + companion object { + fun render( + viewHolder: UnitRenderViewHolder, + context: Context, + unit: UnitInformation, + actionCallback: ActionCallback? + ) { + viewHolder.apply { + val details: MutableList> = mutableListOf() + + /* Device name */ + unitName.text = unit.device.name + + /* Device icon */ + unitIcon?.setImageResource( + MarkerTransformations.categoryToResourceId(unit.device.category) + ) + unitIcon?.contentDescription = context.getString( + MarkerTransformations.categoryToStringId(unit.device.category) + ) + + /* Contact */ + unit.device.contact?.let { contact -> + if (contact.isNotEmpty()) { + details.add( + Triple( + R.drawable.device_contact, + contact, + context.getString(R.string.unit_driver_name) + ) + ) + } + } + + statusIcon.visibility = View.GONE + engineStopIcon.visibility = View.GONE + + unit.position?.let { position -> + /* Status icon */ + statusIcon.visibility = View.VISIBLE + position.speed?.let { speed -> + if (speed >= 2) { + statusIcon.setColorFilter( + ContextCompat.getColor(context, R.color.colorOnline) + ) + } else { + statusIcon.setColorFilter( + ContextCompat.getColor(context, R.color.colorOffline) + ) + } + } ?: run { + statusIcon.setColorFilter(Color.GRAY) + } + + /* Engine stop */ + val attributes = position.attributes + if (attributes["out1"].toString() != "null") { + engineStopIcon.visibility = View.VISIBLE + engineStopIcon.setImageResource( + when (attributes["out1"].toString()) { + "true" -> R.drawable.device_unlocked + "false" -> R.drawable.device_locked + else -> R.drawable.device_locked + } + ) + engineStopIcon.contentDescription = when (attributes["out1"].toString()) { + "true" -> context.getString(R.string.unit_lock_on) + "false" -> context.getString(R.string.unit_lock_off) + else -> context.getString(R.string.unit_lock_on) + } + } + + /* Speed */ + position.speed?.let { speed -> + details.add( + Triple( + R.drawable.position_speed, + Formatter.formatSpeed(speed, SpeedUnit.KMH), + context.getString(R.string.unit_speed) + ) + ) + } + + /* Address */ + position.address?.let { address -> + details.add( + Triple( + R.drawable.position_address, + address, + context.getString(R.string.unit_last_address) + ) + ) + } + + /* Hourmeter */ + position.attributes["hours"]?.longOrNull?.let { + if (it > 0) { + details.add( + Triple( + R.drawable.position_hourmeter, + Formatter.formatHours(it), + context.getString(R.string.unit_hourmeter) + ) + ) + } + } + + /* Date time */ + position.fixTime?.let { fixTime -> + details.add( + Triple( + R.drawable.position_datetime, + Formatter.formatDate(fixTime), + context.getString(R.string.unit_last_date) + ) + ) + } + } + + gridLayout.removeAllViewsInLayout() + val metrics = context.resources.displayMetrics + details.forEachIndexed { i, detail -> + /* Property icon */ + val imageView = ImageView(gridLayout.context) + imageView.setImageResource(detail.first) + imageView.contentDescription = detail.third + imageView.setColorFilter( + ContextCompat.getColor( + context, + androidx.appcompat.R.color.secondary_text_default_material_light + ) + ) + + val imageLayout = GridLayout.LayoutParams() + imageLayout.width = GridLayout.LayoutParams.WRAP_CONTENT + imageLayout.height = GridLayout.LayoutParams.WRAP_CONTENT + imageLayout.marginEnd = + TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 6f, metrics).toInt() + imageLayout.rowSpec = GridLayout.spec(i) + imageLayout.columnSpec = GridLayout.spec(0) + imageView.layoutParams = imageLayout + + /* Property text */ + val textView = TextView(gridLayout.context) + textView.text = detail.second + + val textLayout = GridLayout.LayoutParams() + textLayout.width = 0 + textLayout.height = GridLayout.LayoutParams.MATCH_PARENT + textLayout.rowSpec = GridLayout.spec(i) + textLayout.columnSpec = GridLayout.spec(1, 1, 5f) + textView.layoutParams = textLayout + + gridLayout.addView(imageView) + gridLayout.addView(textView) + + imageLayout.setGravity(Gravity.CENTER) + } + + actionCallback?.let { callback -> + unitCard?.setOnClickListener { + swipeLayout?.close() + callback(unit, Action.CLICK) + } + detailsButton?.setOnClickListener { + swipeLayout?.close() + callback(unit, Action.DETAILS) + } + reportsButton?.setOnClickListener { + swipeLayout?.close() + callback(unit, Action.REPORTS) + } + commandsButton?.setOnClickListener { + swipeLayout?.close() + callback(unit, Action.COMMANDS) + } + } + } + } + } +} \ No newline at end of file -- cgit v1.2.3 From 22fcedc76d998cba6f8281829ba6c4f120cef691 Mon Sep 17 00:00:00 2001 From: Iván Ávalos Date: Sun, 16 Jan 2022 16:40:31 -0600 Subject: Removed import of missing class and fixed imports after moving classes to shared --- .../trackermap/TrackerMap/android/details/DetailsActivity.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/DetailsActivity.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/DetailsActivity.kt index f66a760..aaf7ecb 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/DetailsActivity.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/DetailsActivity.kt @@ -12,7 +12,7 @@ import com.google.android.material.tabs.TabLayoutMediator import kotlinx.coroutines.DelicateCoroutinesApi import mx.trackermap.TrackerMap.android.R import mx.trackermap.TrackerMap.android.databinding.DetailsActivityBinding -import mx.trackermap.TrackerMap.android.devices.Action +import mx.trackermap.TrackerMap.android.shared.UnitRenderData @DelicateCoroutinesApi class DetailsActivity : AppCompatActivity() { @@ -47,7 +47,7 @@ class DetailsActivity : AppCompatActivity() { private fun initialize() { deviceId = intent.getIntExtra(DEVICE_ID_EXTRA, 0) deviceName = intent.getStringExtra(DEVICE_NAME_EXTRA) ?: "" - val initialSection = intent.getSerializableExtra(ACTION_EXTRA) as Action + val initialSection = intent.getSerializableExtra(ACTION_EXTRA) as UnitRenderData.Action Log.d("DetailsActivity", "Device ID - $deviceId") Log.d("DetailsActivity", "Initial Section - $initialSection") @@ -62,14 +62,14 @@ class DetailsActivity : AppCompatActivity() { }.attach() binding.detailsPager.setCurrentItem( when (initialSection) { - Action.DETAILS -> 0 - Action.REPORTS -> 1 + UnitRenderData.Action.DETAILS -> 0 + UnitRenderData.Action.REPORTS -> 1 else -> 2 }, false ) binding.detailsPager.isUserInputEnabled = when (initialSection) { - Action.DETAILS -> true - Action.REPORTS -> false + UnitRenderData.Action.DETAILS -> true + UnitRenderData.Action.REPORTS -> false else -> true } binding.detailsTabs.addOnTabSelectedListener(object: TabLayout.OnTabSelectedListener { -- cgit v1.2.3 From 41e222e22f6cf67248ae40161f69cc1d2753f6a2 Mon Sep 17 00:00:00 2001 From: Iván Ávalos Date: Sun, 16 Jan 2022 17:18:22 -0600 Subject: Added close button to DetailsActivity, updated strings and layouts --- .../TrackerMap/android/details/DetailsActivity.kt | 3 +++ .../details/commands/UnitCommandsFragment.kt | 2 +- .../android/session/UserInformationActivity.kt | 2 +- .../src/main/res/layout/details_activity.xml | 26 +++++++++++++++++----- .../main/res/layout/user_information_activity.xml | 8 +++---- androidApp/src/main/res/values-es-rMX/strings.xml | 3 ++- androidApp/src/main/res/values/strings.xml | 3 ++- androidApp/src/main/res/values/styles.xml | 6 +++++ 8 files changed, 40 insertions(+), 13 deletions(-) diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/DetailsActivity.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/DetailsActivity.kt index aaf7ecb..c6d260b 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/DetailsActivity.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/DetailsActivity.kt @@ -84,6 +84,9 @@ class DetailsActivity : AppCompatActivity() { override fun onTabUnselected(tab: TabLayout.Tab?) {} override fun onTabReselected(tab: TabLayout.Tab?) {} }) + binding.closeButton.setOnClickListener { + finish() + } requestPermission {} } diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/commands/UnitCommandsFragment.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/commands/UnitCommandsFragment.kt index b56a403..822d351 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/commands/UnitCommandsFragment.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/commands/UnitCommandsFragment.kt @@ -75,7 +75,7 @@ class UnitCommandsFragment: Fragment() { setPositiveButton(R.string.shared_cancel) { dialogInterface, _ -> dialogInterface.dismiss() } - setNegativeButton(R.string.send_command) { dialogInterface, _ -> + setNegativeButton(R.string.shared_send) { dialogInterface, _ -> unitCommandsViewModel.sendCommand() dialogInterface.dismiss() } 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 index b0a4482..13deed0 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/UserInformationActivity.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/session/UserInformationActivity.kt @@ -69,7 +69,7 @@ class UserInformationActivity : AppCompatActivity() { } private fun setupEvents() { - binding.backButton.setOnClickListener { onBackPressed() } + binding.closeButton.setOnClickListener { onBackPressed() } binding.signoutButton.setOnClickListener { userInformationViewModel.signOut(PreferenceManager .getDefaultSharedPreferences(this) diff --git a/androidApp/src/main/res/layout/details_activity.xml b/androidApp/src/main/res/layout/details_activity.xml index f79ea69..37d3b15 100644 --- a/androidApp/src/main/res/layout/details_activity.xml +++ b/androidApp/src/main/res/layout/details_activity.xml @@ -5,13 +5,28 @@ android:layout_width="match_parent" android:layout_height="match_parent"> + + + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintStart_toEndOf="@id/closeButton" + app:layout_constraintBottom_toTopOf="@id/detailsPager" + app:tabTextAppearance="@style/SmallTabText" /> + android:layout_marginTop="@dimen/fab_margin" + app:layout_constraintTop_toBottomOf="@id/closeButton" /> \ 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 index c409e98..bc81b20 100644 --- a/androidApp/src/main/res/layout/user_information_activity.xml +++ b/androidApp/src/main/res/layout/user_information_activity.xml @@ -7,13 +7,13 @@ android:layout_height="match_parent"> diff --git a/androidApp/src/main/res/values-es-rMX/strings.xml b/androidApp/src/main/res/values-es-rMX/strings.xml index d228c28..835f342 100644 --- a/androidApp/src/main/res/values-es-rMX/strings.xml +++ b/androidApp/src/main/res/values-es-rMX/strings.xml @@ -4,6 +4,7 @@ OK Cancelar Cerrar + Enviar Nombre de usuario @@ -76,7 +77,7 @@ Enviar comando - ¿Está seguro de que desea enviar el comando a la unidad %1$s? + El comando se enviará a la unidad %1$s. ¿Continuar? diff --git a/androidApp/src/main/res/values/strings.xml b/androidApp/src/main/res/values/strings.xml index d2c6148..62963fa 100644 --- a/androidApp/src/main/res/values/strings.xml +++ b/androidApp/src/main/res/values/strings.xml @@ -17,6 +17,7 @@ OK Cancel Close + Send Username @@ -89,7 +90,7 @@ Send Command - Are you sure you want to send the command to device %1$s? + Command will be sent to device %1$s. Continue? diff --git a/androidApp/src/main/res/values/styles.xml b/androidApp/src/main/res/values/styles.xml index 4a51239..dc40450 100644 --- a/androidApp/src/main/res/values/styles.xml +++ b/androidApp/src/main/res/values/styles.xml @@ -6,4 +6,10 @@ @color/colorAccent + + \ No newline at end of file -- cgit v1.2.3 From f030f9cc2327fa3825964a9b06430ae5881ebcba Mon Sep 17 00:00:00 2001 From: Iván Ávalos Date: Sun, 16 Jan 2022 17:21:23 -0600 Subject: Reduced top margin for login button --- androidApp/src/main/res/layout/login.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/androidApp/src/main/res/layout/login.xml b/androidApp/src/main/res/layout/login.xml index 35c9410..7c79e5c 100644 --- a/androidApp/src/main/res/layout/login.xml +++ b/androidApp/src/main/res/layout/login.xml @@ -91,7 +91,7 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintHorizontal_bias="0.5" - android:layout_marginTop="40dp" + android:layout_marginTop="24dp" android:text="@string/login_login"/> -- cgit v1.2.3 From 21e16e27f047053582d8b0c722feedf3c8badebe Mon Sep 17 00:00:00 2001 From: Iván Ávalos Date: Sun, 16 Jan 2022 17:57:14 -0600 Subject: Refactored report types into commonMain, added support for event report types in controller and API --- .../android/details/reports/UnitReportsFragment.kt | 42 ++++++------ .../details/reports/UnitReportsViewModel.kt | 20 +++++- .../TrackerMap/client/apis/ReportsApi.kt | 10 ++- .../TrackerMap/client/models/EventInformation.kt | 79 +++++++++++++++++++++- .../TrackerMap/controllers/ReportController.kt | 14 ++-- 5 files changed, 136 insertions(+), 29 deletions(-) diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/reports/UnitReportsFragment.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/reports/UnitReportsFragment.kt index 3b3570b..4c87b31 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/reports/UnitReportsFragment.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/reports/UnitReportsFragment.kt @@ -205,26 +205,28 @@ class UnitReportsFragment : Fragment() { datetimeText.text = Formatter.formatDate(it) } event.event.type?.let { - eventText.text = getString(when (it) { - "deviceOnline" -> R.string.event_device_online - "deviceUnknown" -> R.string.event_device_unknown - "deviceOffline" -> R.string.event_device_offline - "deviceInactive" -> R.string.event_device_inactive - "deviceMoving" -> R.string.event_device_moving - "deviceStopped" -> R.string.event_device_stopped - "deviceOverspeed" -> R.string.event_device_overspeed - "deviceFuelDrop" -> R.string.event_device_fuel_drop - "commandResult" -> R.string.event_command_result - "geofenceEnter" -> R.string.event_geofence_enter - "geofenceExit" -> R.string.event_geofence_exit - "alarm" -> R.string.event_alarm - "ignitionOn" -> R.string.event_ignition_on - "ignitionOff" -> R.string.event_ignition_off - "maintenance" -> R.string.event_maintenance - "textMessage" -> R.string.event_text_message - "driverChanged" -> R.string.event_driver_changed - else -> R.string.event_unknown - }) + eventText.text = getString( + when (EventInformation.stringToReportType(it)) { + EventInformation.Type.DEVICE_ONLINE -> R.string.event_device_online + EventInformation.Type.DEVICE_UNKNOWN -> R.string.event_device_unknown + EventInformation.Type.DEVICE_OFFLINE -> R.string.event_device_offline + EventInformation.Type.DEVICE_INACTIVE -> R.string.event_device_inactive + EventInformation.Type.DEVICE_MOVING -> R.string.event_device_moving + EventInformation.Type.DEVICE_STOPPED -> R.string.event_device_stopped + EventInformation.Type.DEVICE_OVERSPEED -> R.string.event_device_overspeed + EventInformation.Type.DEVICE_FUEL_DROP -> R.string.event_device_fuel_drop + EventInformation.Type.COMMAND_RESULT -> R.string.event_command_result + EventInformation.Type.GEOFENCE_ENTER -> R.string.event_geofence_enter + EventInformation.Type.GEOFENCE_EXIT -> R.string.event_geofence_exit + EventInformation.Type.ALARM -> R.string.event_alarm + EventInformation.Type.IGNITION_ON -> R.string.event_ignition_on + EventInformation.Type.IGNITION_OFF -> R.string.event_ignition_off + EventInformation.Type.MAINTENANCE -> R.string.event_maintenance + EventInformation.Type.TEXT_MESSAGE -> R.string.event_text_message + EventInformation.Type.DRIVER_CHANGED -> R.string.event_driver_changed + EventInformation.Type.UNKNOWN -> R.string.event_unknown + else -> R.string.event_unknown + }) } event.geofence?.let { geofenceText.text = it.name diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/reports/UnitReportsViewModel.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/reports/UnitReportsViewModel.kt index 865f096..62ac4f2 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/reports/UnitReportsViewModel.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/reports/UnitReportsViewModel.kt @@ -4,6 +4,7 @@ import androidx.lifecycle.* import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch +import mx.trackermap.TrackerMap.client.models.EventInformation import mx.trackermap.TrackerMap.controllers.ReportController import mx.trackermap.TrackerMap.utils.ReportDates import org.koin.core.component.KoinComponent @@ -84,7 +85,24 @@ class UnitReportsViewModel( deviceId = id, reportType = _reportType.value, reportPeriod = _reportPeriod.value, - xlsx = xlsx + xlsx = xlsx, + eventTypes = arrayOf( + EventInformation.Type.DEVICE_INACTIVE, + EventInformation.Type.DEVICE_MOVING, + EventInformation.Type.DEVICE_STOPPED, + EventInformation.Type.DEVICE_OVERSPEED, + EventInformation.Type.DEVICE_FUEL_DROP, + EventInformation.Type.COMMAND_RESULT, + EventInformation.Type.GEOFENCE_ENTER, + EventInformation.Type.GEOFENCE_EXIT, + EventInformation.Type.ALARM, + EventInformation.Type.IGNITION_ON, + EventInformation.Type.IGNITION_OFF, + EventInformation.Type.MAINTENANCE, + EventInformation.Type.TEXT_MESSAGE, + EventInformation.Type.DRIVER_CHANGED, + EventInformation.Type.UNKNOWN + ) ) } } diff --git a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/apis/ReportsApi.kt b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/apis/ReportsApi.kt index b4d6f74..3765207 100644 --- a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/apis/ReportsApi.kt +++ b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/apis/ReportsApi.kt @@ -36,12 +36,14 @@ class ReportsApi(basePath: String = "https://demo.traccar.org/api") : ApiClient( from: String, to: String, deviceId: Int, + type: String = "%", xlsx: Boolean = false ): Any { val localVariableQuery: MultiValueMap = mapOf( "deviceId" to toMultiValue(listOf(deviceId), "multi"), "from" to listOf(from), - "to" to listOf(to) + "to" to listOf(to), + "type" to listOf(type) ) val localVariableHeaders = mutableMapOf() if (xlsx) { @@ -79,18 +81,20 @@ class ReportsApi(basePath: String = "https://demo.traccar.org/api") : ApiClient( suspend fun reportsEventsGet( from: String, to: String, + type: String = "%", deviceId: Int, ): Array { - return reportsEventsGetBase(from, to, deviceId, false) as Array + return reportsEventsGetBase(from, to, deviceId, type, false) as Array } @Suppress("UNCHECKED_CAST") suspend fun reportsEventsGetXlsx( from: String, to: String, + type: String = "%", deviceId: Int, ): ByteArray { - return reportsEventsGetBase(from, to, deviceId, true) as ByteArray + return reportsEventsGetBase(from, to, deviceId, type, true) as ByteArray } /** diff --git a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/models/EventInformation.kt b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/models/EventInformation.kt index c4f91fe..befd8f1 100644 --- a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/models/EventInformation.kt +++ b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/models/EventInformation.kt @@ -4,4 +4,81 @@ data class EventInformation( val event: Event, val position: Position?, val geofence: Geofence? -) +) { + enum class Type { + ALL, + DEVICE_ONLINE, + DEVICE_UNKNOWN, + DEVICE_OFFLINE, + DEVICE_INACTIVE, + DEVICE_MOVING, + DEVICE_STOPPED, + DEVICE_OVERSPEED, + DEVICE_FUEL_DROP, + COMMAND_RESULT, + GEOFENCE_ENTER, + GEOFENCE_EXIT, + ALARM, + IGNITION_ON, + IGNITION_OFF, + MAINTENANCE, + TEXT_MESSAGE, + DRIVER_CHANGED, + UNKNOWN + } + + companion object { + fun reportTypeToString(t: Type) = + when (t) { + Type.ALL -> "%" + Type.DEVICE_ONLINE -> "deviceOnline" + Type.DEVICE_UNKNOWN -> "deviceUnknown" + Type.DEVICE_OFFLINE -> "deviceOffline" + Type.DEVICE_INACTIVE -> "deviceInactive" + Type.DEVICE_MOVING -> "deviceMoving" + Type.DEVICE_STOPPED -> "deviceStopped" + Type.DEVICE_OVERSPEED -> "deviceOverspeed" + Type.DEVICE_FUEL_DROP -> "deviceFuelDrop" + Type.COMMAND_RESULT -> "commandResult" + Type.GEOFENCE_ENTER -> "geofenceEnter" + Type.GEOFENCE_EXIT -> "geofenceExit" + Type.ALARM -> "alarm" + Type.IGNITION_ON -> "ignitionOn" + Type.IGNITION_OFF -> "ignitionOff" + Type.MAINTENANCE -> "maintenance" + Type.TEXT_MESSAGE -> "textMessage" + Type.DRIVER_CHANGED -> "driverChanged" + Type.UNKNOWN -> "unknown" + } + + fun reportTypesToString(t: Array) = + if (t.isEmpty() || t.contains(Type.ALL)) { + reportTypeToString(Type.ALL) + } else { + t.joinToString(",", transform = this::reportTypeToString) + } + + fun stringToReportType(s: String) = + when (s) { + "deviceOnline" -> Type.DEVICE_ONLINE + "deviceUnknown" -> Type.DEVICE_UNKNOWN + "deviceOffline" -> Type.DEVICE_OFFLINE + "deviceInactive" -> Type.DEVICE_INACTIVE + "deviceMoving" -> Type.DEVICE_MOVING + "deviceStopped" -> Type.DEVICE_STOPPED + "deviceOverspeed" -> Type.DEVICE_OVERSPEED + "deviceFuelDrop" -> Type.DEVICE_FUEL_DROP + "commandResult" -> Type.COMMAND_RESULT + "geofenceEnter" -> Type.GEOFENCE_ENTER + "geofenceExit" -> Type.GEOFENCE_EXIT + "alarm" -> Type.ALARM + "ignitionOn" -> Type.IGNITION_ON + "ignitionOff" -> Type.IGNITION_OFF + "maintenance" -> Type.MAINTENANCE + "textMessage" -> Type.TEXT_MESSAGE + "driverChanged" -> Type.DRIVER_CHANGED + "unknown" -> Type.UNKNOWN + else -> Type.UNKNOWN + } + } +} diff --git a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/controllers/ReportController.kt b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/controllers/ReportController.kt index 2151331..8a7f527 100644 --- a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/controllers/ReportController.kt +++ b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/controllers/ReportController.kt @@ -36,7 +36,8 @@ class ReportController( deviceId: Int, reportType: ReportType?, reportPeriod: ReportDates.ReportPeriod?, - xlsx: Boolean = false + xlsx: Boolean = false, + eventTypes: Array = arrayOf() ) { if (reportType == null || reportPeriod == null) { return @@ -54,7 +55,7 @@ class ReportController( GlobalScope.launch { when (reportType) { ReportType.POSITIONS -> fetchPositions(deviceId, previousDate, currentDate, xlsx) - ReportType.EVENTS -> fetchEvents(deviceId, previousDate, currentDate, xlsx) + ReportType.EVENTS -> fetchEvents(deviceId, previousDate, currentDate, eventTypes, xlsx) ReportType.STOPS -> fetchStops(deviceId, previousDate, currentDate, xlsx) } } @@ -84,13 +85,16 @@ class ReportController( deviceId: Int, from: String, to: String, + types: Array, xlsx: Boolean ) { Log.d("UnitReportsVM", "Fetching events") if (!xlsx) { val positionsResult = reportsApi.reportsRouteGet(from, to, deviceId) - val eventsResult = reportsApi.reportsEventsGet(from, to, deviceId) + val eventsResult = reportsApi.reportsEventsGet( + from, to, EventInformation.reportTypesToString(types), deviceId + ) val geofencesResult = geofencesApi.geofencesGet(all = true) val result = mutableListOf() @@ -105,7 +109,9 @@ class ReportController( Log.d("UnitReportsVM", "Events report: $result") reportFlow.value = Report.EventsReport(result.toTypedArray()) } else { - val result = reportsApi.reportsEventsGetXlsx(from, to, deviceId) + val result = reportsApi.reportsEventsGetXlsx( + from, to, EventInformation.reportTypesToString(types), deviceId + ) Log.d("UnitReportsVM", "Events report: $result") reportFlow.value = Report.XlsxReport(result) -- cgit v1.2.3