mirror of
https://github.com/ev-map/EVMap.git
synced 2026-04-24 16:17:15 -04:00
@@ -94,6 +94,17 @@ class ConnectorAdapter : DataBindingAdapter<ConnectorAdapter.ChargepointWithAvai
|
||||
override fun getItemViewType(position: Int): Int = R.layout.item_connector
|
||||
}
|
||||
|
||||
class ConnectorDetailsAdapter : DataBindingAdapter<ConnectorDetailsAdapter.ConnectorDetails>() {
|
||||
data class ConnectorDetails(
|
||||
val chargepoint: Chargepoint,
|
||||
val status: ChargepointStatus?,
|
||||
val evseId: String?
|
||||
) :
|
||||
Equatable
|
||||
|
||||
override fun getItemViewType(position: Int): Int = R.layout.dialog_connector_details_item
|
||||
}
|
||||
|
||||
class ChargepriceAdapter() :
|
||||
DataBindingAdapter<ChargePrice>() {
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package net.vonforst.evmap.api.availability
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Parcelable
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import net.vonforst.evmap.addDebugInterceptors
|
||||
import net.vonforst.evmap.api.RateLimitInterceptor
|
||||
import net.vonforst.evmap.api.await
|
||||
@@ -154,7 +156,8 @@ data class ChargeLocationStatus(
|
||||
val totalChargepoints = status.map { it.key.count }.sum()
|
||||
}
|
||||
|
||||
enum class ChargepointStatus {
|
||||
@Parcelize
|
||||
enum class ChargepointStatus : Parcelable {
|
||||
AVAILABLE, UNKNOWN, CHARGING, OCCUPIED, FAULTED
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package net.vonforst.evmap.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.os.BundleCompat
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import net.vonforst.evmap.adapter.ConnectorDetailsAdapter
|
||||
import net.vonforst.evmap.api.availability.ChargeLocationStatus
|
||||
import net.vonforst.evmap.api.availability.ChargepointStatus
|
||||
import net.vonforst.evmap.databinding.DialogConnectorDetailsBinding
|
||||
import net.vonforst.evmap.databinding.DialogDataSourceSelectBinding
|
||||
import net.vonforst.evmap.model.Chargepoint
|
||||
import net.vonforst.evmap.model.FILTERS_DISABLED
|
||||
import net.vonforst.evmap.storage.PreferenceDataSource
|
||||
import net.vonforst.evmap.ui.MaterialDialogFragment
|
||||
|
||||
class ConnectorDetailsDialog : MaterialDialogFragment() {
|
||||
private lateinit var binding: DialogConnectorDetailsBinding
|
||||
|
||||
companion object {
|
||||
fun getInstance(
|
||||
chargepoint: Chargepoint,
|
||||
status: List<ChargepointStatus>,
|
||||
evseIds: List<String>? = null
|
||||
): ConnectorDetailsDialog {
|
||||
val dialog = ConnectorDetailsDialog()
|
||||
dialog.arguments = Bundle().apply {
|
||||
putParcelable("chargepoint", chargepoint)
|
||||
putParcelableArrayList("status", ArrayList(status))
|
||||
putStringArrayList("evseIds", evseIds?.let { ArrayList(it) })
|
||||
}
|
||||
return dialog
|
||||
}
|
||||
}
|
||||
|
||||
override fun createView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
binding = DialogConnectorDetailsBinding.inflate(inflater, container, false)
|
||||
prefs = PreferenceDataSource(requireContext())
|
||||
return binding.root
|
||||
}
|
||||
|
||||
private lateinit var prefs: PreferenceDataSource
|
||||
|
||||
override fun initView(view: View, savedInstanceState: Bundle?) {
|
||||
val args = requireArguments()
|
||||
|
||||
val chargepoint = BundleCompat.getParcelable(args, "chargepoint", Chargepoint::class.java)!!
|
||||
val status =
|
||||
BundleCompat.getParcelableArrayList(args, "status", ChargepointStatus::class.java)
|
||||
val evseIds = args.getStringArrayList("evseIds")
|
||||
|
||||
val items = List(chargepoint.count) { i ->
|
||||
ConnectorDetailsAdapter.ConnectorDetails(chargepoint, status?.get(i), evseIds?.get(i))
|
||||
}.sortedBy { it.evseId }
|
||||
|
||||
binding.list.apply {
|
||||
adapter = ConnectorDetailsAdapter().apply {
|
||||
submitList(items)
|
||||
}
|
||||
itemAnimator = null
|
||||
layoutManager =
|
||||
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
|
||||
}
|
||||
|
||||
binding.btnClose.setOnClickListener {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -814,7 +814,20 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
}
|
||||
|
||||
binding.detailView.connectors.apply {
|
||||
adapter = ConnectorAdapter()
|
||||
adapter = ConnectorAdapter().apply {
|
||||
onClickListener = { item ->
|
||||
vm.availability.value?.data?.let {
|
||||
item.status?.let { status ->
|
||||
val dialog = ConnectorDetailsDialog.getInstance(
|
||||
item.chargepoint,
|
||||
status,
|
||||
it.evseIds?.get(item.chargepoint)
|
||||
)
|
||||
dialog.show(parentFragmentManager, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
itemAnimator = null
|
||||
layoutManager =
|
||||
LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
|
||||
|
||||
@@ -156,11 +156,21 @@ fun setImageTintAvailability(view: ImageView, available: List<ChargepointStatus>
|
||||
view.imageTintList = ColorStateList.valueOf(availabilityColor(available, view.context))
|
||||
}
|
||||
|
||||
@BindingAdapter("tintAvailability")
|
||||
fun setImageTintAvailability(view: ImageView, available: ChargepointStatus?) {
|
||||
view.imageTintList = ColorStateList.valueOf(availabilityColor(available, view.context))
|
||||
}
|
||||
|
||||
@BindingAdapter("textColorAvailability")
|
||||
fun setTextColorAvailability(view: TextView, available: List<ChargepointStatus>?) {
|
||||
view.setTextColor(availabilityColor(available, view.context))
|
||||
}
|
||||
|
||||
@BindingAdapter("textColorAvailability")
|
||||
fun setTextColorAvailability(view: TextView, available: ChargepointStatus?) {
|
||||
view.setTextColor(availabilityColor(available, view.context))
|
||||
}
|
||||
|
||||
@BindingAdapter("backgroundTintAvailability")
|
||||
fun setBackgroundTintAvailability(view: View, available: List<ChargepointStatus>?) {
|
||||
view.backgroundTintList = ColorStateList.valueOf(availabilityColor(available, view.context))
|
||||
@@ -269,6 +279,25 @@ private fun availabilityColor(
|
||||
ta.getColor(0, 0)
|
||||
}
|
||||
|
||||
private fun availabilityColor(
|
||||
status: ChargepointStatus?,
|
||||
context: Context
|
||||
): Int = when (status) {
|
||||
ChargepointStatus.UNKNOWN -> ContextCompat.getColor(context, R.color.unknown)
|
||||
ChargepointStatus.AVAILABLE -> ContextCompat.getColor(context, R.color.available)
|
||||
ChargepointStatus.FAULTED -> ContextCompat.getColor(context, R.color.unavailable)
|
||||
ChargepointStatus.OCCUPIED, ChargepointStatus.CHARGING -> ContextCompat.getColor(
|
||||
context,
|
||||
R.color.charging
|
||||
)
|
||||
|
||||
null -> {
|
||||
val ta =
|
||||
context.theme.obtainStyledAttributes(intArrayOf(androidx.appcompat.R.attr.colorControlNormal))
|
||||
ta.getColor(0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
fun availabilityText(status: List<ChargepointStatus>?): String? {
|
||||
if (status == null) return null
|
||||
|
||||
@@ -281,6 +310,18 @@ fun availabilityText(status: List<ChargepointStatus>?): String? {
|
||||
} else available.toString()
|
||||
}
|
||||
|
||||
fun availabilityText(status: ChargepointStatus?, context: Context): String? {
|
||||
if (status == null) return null
|
||||
|
||||
return when (status) {
|
||||
ChargepointStatus.UNKNOWN -> context.getString(R.string.status_unknown)
|
||||
ChargepointStatus.AVAILABLE -> context.getString(R.string.status_available)
|
||||
ChargepointStatus.CHARGING -> context.getString(R.string.status_charging)
|
||||
ChargepointStatus.OCCUPIED -> context.getString(R.string.status_occupied)
|
||||
ChargepointStatus.FAULTED -> context.getString(R.string.status_faulted)
|
||||
}
|
||||
}
|
||||
|
||||
fun flatten(it: Iterable<Iterable<ChargepointStatus>>?): List<ChargepointStatus>? {
|
||||
return it?.flatten()
|
||||
}
|
||||
|
||||
34
app/src/main/res/layout/dialog_connector_details.xml
Normal file
34
app/src/main/res/layout/dialog_connector_details.xml
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/list"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:listitem="@layout/dialog_connector_details_item" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/btnClose"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="0dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/close"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/ic_close"
|
||||
app:tint="?colorControlNormal" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
89
app/src/main/res/layout/dialog_connector_details_item.xml
Normal file
89
app/src/main/res/layout/dialog_connector_details_item.xml
Normal file
@@ -0,0 +1,89 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<data>
|
||||
|
||||
<import type="net.vonforst.evmap.adapter.ConnectorDetailsAdapter.ConnectorDetails" />
|
||||
|
||||
<import type="net.vonforst.evmap.ui.BindingAdaptersKt" />
|
||||
|
||||
<variable
|
||||
name="item"
|
||||
type="ConnectorDetails" />
|
||||
</data>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="?attr/listPreferredItemHeightSmall"
|
||||
android:layout_marginStart="?attr/dialogPreferredPadding"
|
||||
android:layout_marginEnd="?attr/dialogPreferredPadding">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:tintMode="src_in"
|
||||
android:contentDescription="@{item.chargepoint.type}"
|
||||
app:connectorIcon="@{item.chargepoint.type}"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:tintAvailability="@{item.status}"
|
||||
tools:tint="@color/available"
|
||||
tools:srcCompat="@drawable/ic_connector_typ2" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView6"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="@{item.chargepoint.formatPower()}"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:goneUnless="@{item.chargepoint.hasKnownPower()}"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="@+id/imageView"
|
||||
app:layout_constraintStart_toStartOf="@+id/imageView"
|
||||
app:layout_constraintTop_toBottomOf="@+id/imageView"
|
||||
app:textColorAvailability="@{item.status}"
|
||||
tools:text="350 kW"
|
||||
tools:textColor="@color/available" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtEvseid"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginTop="18dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="14dp"
|
||||
android:text="@{item.evseId}"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/imageView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/imageView"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="SK*IOY*E222901" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtStatus"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="14dp"
|
||||
android:text="@{BindingAdaptersKt.availabilityText(item.status, context)}"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:goneUnless="@{item.status != null}"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/txtEvseid"
|
||||
app:layout_constraintTop_toBottomOf="@+id/txtEvseid"
|
||||
tools:text="Available" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</layout>
|
||||
@@ -14,7 +14,8 @@
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackgroundBorderless">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
|
||||
@@ -368,5 +368,10 @@
|
||||
<string name="referral_tesla">Tesla</string>
|
||||
<string name="generic_connection_error">Daten konnten nicht geladen werden</string>
|
||||
<string name="copied">In Zwischenablage kopiert</string>
|
||||
<string name="status_available">Verfügbar</string>
|
||||
<string name="status_occupied">Besetzt</string>
|
||||
<string name="status_charging">Lädt</string>
|
||||
<string name="status_faulted">Defekt</string>
|
||||
<string name="status_unknown">Status unbekannt</string>
|
||||
<string name="charger_name">Ladestationsname</string>
|
||||
</resources>
|
||||
@@ -368,5 +368,10 @@
|
||||
<string name="referral_tesla">Tesla</string>
|
||||
<string name="generic_connection_error">Could not load data</string>
|
||||
<string name="copied">Copied to clipboard</string>
|
||||
<string name="status_available">Available</string>
|
||||
<string name="status_occupied">Occupied</string>
|
||||
<string name="status_charging">Charging</string>
|
||||
<string name="status_faulted">Out of order</string>
|
||||
<string name="status_unknown">Status Unknown</string>
|
||||
<string name="charger_name">Charger name</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user