Introduce ApplePods.Flags and UI for key status

This commit introduces a new `Flags` data class within `ApplePods` to store boolean flags related to the device, specifically `isIRKMatch`.

This flag is now passed during the creation of `ApplePods` instances in all `ApplePodsFactory` implementations and the central `AppleFactory`.

The UI has been updated to display a key icon in the overview cards (`DualPodsCardVH` and `SinglePodsCardVH`):
- The icon is only visible if `flags.isIRKMatch` is true.
- The icon changes to a filled key (`ic_key_24`) if `payload.private` is not null (indicating successful decryption), otherwise an outline key (`ic_key_outline_24`) is shown.
- Minor layout adjustments were made in `overview_pods_single_item.xml` and `overview_pods_dual_item.xml` to accommodate the new key icon.
This commit is contained in:
darken
2025-06-06 06:03:41 +02:00
committed by Matthias Urhahn
parent eab0296125
commit ffe8a58746
31 changed files with 198 additions and 84 deletions
@@ -4,6 +4,7 @@ import android.graphics.Typeface
import android.view.ViewGroup
import androidx.core.view.isGone
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import eu.darken.capod.R
import eu.darken.capod.common.lists.binding
import eu.darken.capod.databinding.OverviewPodsDualItemBinding
@@ -14,6 +15,7 @@ import eu.darken.capod.pods.core.HasDualMicrophone
import eu.darken.capod.pods.core.HasEarDetectionDual
import eu.darken.capod.pods.core.HasPodStyle
import eu.darken.capod.pods.core.HasStateDetection
import eu.darken.capod.pods.core.apple.ApplePods
import eu.darken.capod.pods.core.apple.DualApplePods
import eu.darken.capod.pods.core.apple.DualApplePods.LidState
import eu.darken.capod.pods.core.firstSeenFormatted
@@ -62,6 +64,17 @@ class DualPodsCardVH(parent: ViewGroup) :
reception.text = item.getReceptionText()
keyIcon.apply {
isVisible = device is ApplePods && device.flags.isIRKMatch
if (device !is ApplePods) return@apply
setImageResource(
when {
device.payload.private != null -> R.drawable.ic_key_24
else -> R.drawable.ic_key_outline_24
}
)
}
// Pods battery state
device.apply {
podLeftBatteryIcon.setImageResource(getBatteryDrawable(batteryLeftPodPercent))
@@ -4,10 +4,17 @@ import android.graphics.Typeface
import android.view.ViewGroup
import androidx.core.view.isGone
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import eu.darken.capod.R
import eu.darken.capod.common.lists.binding
import eu.darken.capod.databinding.OverviewPodsSingleItemBinding
import eu.darken.capod.pods.core.*
import eu.darken.capod.pods.core.HasChargeDetection
import eu.darken.capod.pods.core.HasEarDetection
import eu.darken.capod.pods.core.SinglePodDevice
import eu.darken.capod.pods.core.apple.ApplePods
import eu.darken.capod.pods.core.getBatteryDrawable
import eu.darken.capod.pods.core.getBatteryLevelHeadset
import eu.darken.capod.pods.core.lastSeenFormatted
import java.time.Instant
class SinglePodsCardVH(parent: ViewGroup) :
@@ -33,6 +40,17 @@ class SinglePodsCardVH(parent: ViewGroup) :
reception.text = item.getReceptionText()
keyIcon.apply {
isVisible = device is ApplePods && device.flags.isIRKMatch
if (device !is ApplePods) return@apply
setImageResource(
when {
device.payload.private != null -> R.drawable.ic_key_24
else -> R.drawable.ic_key_outline_24
}
)
}
// Battery level
device.apply {
batteryLabel.text = getBatteryLevelHeadset(context)
@@ -17,10 +17,10 @@
<ImageView
android:id="@+id/device_icon"
style="@style/PodInfoItemIcon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="16dp"
style="@style/PodInfoItemIcon"
app:layout_constraintBottom_toBottomOf="@id/name"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/name"
@@ -71,13 +71,13 @@
style="@style/TextAppearance.Material3.LabelMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="@id/name"
app:layout_constraintBottom_toBottomOf="@id/key_icon"
app:layout_constraintEnd_toStartOf="@id/reception_icon"
app:layout_constraintStart_toEndOf="@id/name"
app:layout_constraintTop_toTopOf="@+id/name"
app:layout_constraintTop_toTopOf="@+id/reception_icon"
tools:text="Yours (RSSI -61)" />
<ImageView
@@ -87,15 +87,25 @@
android:layout_height="16dp"
android:layout_marginHorizontal="16dp"
android:layout_marginStart="4dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="@+id/reception"
app:layout_constraintBottom_toTopOf="@id/key_icon"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/reception"
app:layout_constraintTop_toTopOf="@+id/reception"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_baseline_settings_input_antenna_24"
tools:text="Yours (RSSI -61)" />
<ImageView
android:id="@+id/key_icon"
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/ic_key_outline_24"
app:layout_constraintEnd_toEndOf="@id/reception_icon"
app:layout_constraintStart_toStartOf="@id/reception_icon"
app:layout_constraintTop_toBottomOf="@id/reception_icon" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier_top"
android:layout_width="wrap_content"
@@ -17,9 +17,9 @@
<ImageView
android:id="@+id/device_icon"
style="@style/PodInfoItemIcon"
android:layout_width="24dp"
android:layout_height="24dp"
style="@style/PodInfoItemIcon"
android:layout_marginStart="16dp"
app:layout_constraintBottom_toBottomOf="@id/name"
app:layout_constraintStart_toStartOf="parent"
@@ -59,13 +59,13 @@
style="@style/TextAppearance.Material3.LabelMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="@id/name"
app:layout_constraintBottom_toBottomOf="@id/key_icon"
app:layout_constraintEnd_toStartOf="@id/reception_icon"
app:layout_constraintStart_toEndOf="@id/name"
app:layout_constraintTop_toTopOf="@+id/name"
app:layout_constraintTop_toTopOf="@+id/reception_icon"
tools:text="Yours (RSSI -61)" />
<ImageView
@@ -73,17 +73,26 @@
style="@style/TextAppearance.Material3.LabelMedium"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginHorizontal="16dp"
android:layout_marginStart="4dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="@+id/reception"
app:layout_constraintBottom_toTopOf="@id/key_icon"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/reception"
app:layout_constraintTop_toTopOf="@+id/reception"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_baseline_settings_input_antenna_24"
tools:text="Yours (RSSI -61)" />
<ImageView
android:id="@+id/key_icon"
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/ic_key_outline_24"
app:layout_constraintEnd_toEndOf="@id/reception_icon"
app:layout_constraintStart_toStartOf="@id/reception_icon"
app:layout_constraintTop_toBottomOf="@id/reception_icon" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier_top"
android:layout_width="wrap_content"