mirror of
https://github.com/d4rken-org/capod.git
synced 2026-09-14 18:26:11 -04:00
Improve "UnknownDevice" and "NoPairedDeviceConnected" cards
This commit is contained in:
@@ -11,6 +11,7 @@ import eu.darken.capod.common.lists.differ.setupDiffer
|
||||
import eu.darken.capod.common.lists.modular.ModularAdapter
|
||||
import eu.darken.capod.common.lists.modular.mods.DataBinderMod
|
||||
import eu.darken.capod.common.lists.modular.mods.TypedVHCreatorMod
|
||||
import eu.darken.capod.main.ui.overview.cards.NoPairedDeviceCardVH
|
||||
import eu.darken.capod.main.ui.overview.cards.PermissionCardVH
|
||||
import eu.darken.capod.main.ui.overview.cards.pods.BasicSingleApplePodsCardVH
|
||||
import eu.darken.capod.main.ui.overview.cards.pods.DualApplePodsCardVH
|
||||
@@ -31,6 +32,7 @@ class OverviewAdapter @Inject constructor() :
|
||||
modules.add(TypedVHCreatorMod({ data[it] is SingleApplePodsCardVH.Item }) { SingleApplePodsCardVH(it) })
|
||||
modules.add(TypedVHCreatorMod({ data[it] is BasicSingleApplePodsCardVH.Item }) { BasicSingleApplePodsCardVH(it) })
|
||||
modules.add(TypedVHCreatorMod({ data[it] is UnknownPodDeviceCardVH.Item }) { UnknownPodDeviceCardVH(it) })
|
||||
modules.add(TypedVHCreatorMod({ data[it] is NoPairedDeviceCardVH.Item }) { NoPairedDeviceCardVH(it) })
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = data.size
|
||||
|
||||
@@ -13,11 +13,9 @@ import eu.darken.capod.common.uix.ViewModel3
|
||||
import eu.darken.capod.main.core.GeneralSettings
|
||||
import eu.darken.capod.main.core.MonitorMode
|
||||
import eu.darken.capod.main.core.PermissionTool
|
||||
import eu.darken.capod.main.ui.overview.cards.NoPairedDeviceCardVH
|
||||
import eu.darken.capod.main.ui.overview.cards.PermissionCardVH
|
||||
import eu.darken.capod.main.ui.overview.cards.pods.BasicSingleApplePodsCardVH
|
||||
import eu.darken.capod.main.ui.overview.cards.pods.DualApplePodsCardVH
|
||||
import eu.darken.capod.main.ui.overview.cards.pods.SingleApplePodsCardVH
|
||||
import eu.darken.capod.main.ui.overview.cards.pods.UnknownPodDeviceCardVH
|
||||
import eu.darken.capod.main.ui.overview.cards.pods.*
|
||||
import eu.darken.capod.monitor.core.PodMonitor
|
||||
import eu.darken.capod.monitor.core.worker.MonitorControl
|
||||
import eu.darken.capod.pods.core.PodDevice
|
||||
@@ -90,7 +88,8 @@ class OverviewFragmentVM @Inject constructor(
|
||||
requiredPermissions,
|
||||
pods,
|
||||
debugSettings.isDebugModeEnabled.flow,
|
||||
) { tick, permissions, pods, isDebugMode ->
|
||||
generalSettings.showAll.flow,
|
||||
) { tick, permissions, pods, isDebugMode, showAll ->
|
||||
val items = mutableListOf<OverviewAdapter.Item>()
|
||||
|
||||
val now = Instant.now()
|
||||
@@ -129,6 +128,12 @@ class OverviewFragmentVM @Inject constructor(
|
||||
}
|
||||
.run { items.addAll(this) }
|
||||
|
||||
if (!showAll && items.none { it is PodDeviceVH.Item }) {
|
||||
NoPairedDeviceCardVH.Item {
|
||||
generalSettings.showAll.value = true
|
||||
}.run { items.add(this) }
|
||||
}
|
||||
|
||||
items
|
||||
}
|
||||
.catch { errorEvents.postValue(it) }
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package eu.darken.capod.main.ui.overview.cards
|
||||
|
||||
import android.view.ViewGroup
|
||||
import eu.darken.capod.R
|
||||
import eu.darken.capod.common.lists.binding
|
||||
import eu.darken.capod.common.lists.differ.DifferItem
|
||||
import eu.darken.capod.databinding.OverviewNopaireddeviceItemBinding
|
||||
import eu.darken.capod.main.ui.overview.OverviewAdapter
|
||||
|
||||
class NoPairedDeviceCardVH(parent: ViewGroup) :
|
||||
OverviewAdapter.BaseVH<NoPairedDeviceCardVH.Item, OverviewNopaireddeviceItemBinding>(
|
||||
R.layout.overview_nopaireddevice_item,
|
||||
parent
|
||||
) {
|
||||
|
||||
override val viewBinding = lazy {
|
||||
OverviewNopaireddeviceItemBinding.bind(itemView)
|
||||
}
|
||||
|
||||
override val onBindData: OverviewNopaireddeviceItemBinding.(
|
||||
item: Item,
|
||||
payloads: List<Any>
|
||||
) -> Unit = binding(payload = true) { item ->
|
||||
showAllAction.setOnClickListener { item.onShowAll() }
|
||||
}
|
||||
|
||||
data class Item(
|
||||
val onShowAll: () -> Unit
|
||||
) : OverviewAdapter.Item {
|
||||
override val stableId: Long = Item::class.hashCode().toLong()
|
||||
|
||||
override val payloadProvider: ((DifferItem, DifferItem) -> DifferItem?)
|
||||
get() = { old, new -> if (new::class.isInstance(old)) new else null }
|
||||
}
|
||||
}
|
||||
@@ -5,20 +5,20 @@ import eu.darken.capod.R
|
||||
import eu.darken.capod.common.lists.binding
|
||||
import eu.darken.capod.common.lists.differ.DifferItem
|
||||
import eu.darken.capod.common.permissions.Permission
|
||||
import eu.darken.capod.databinding.MainPermissionItemBinding
|
||||
import eu.darken.capod.databinding.OverviewPermissionItemBinding
|
||||
import eu.darken.capod.main.ui.overview.OverviewAdapter
|
||||
|
||||
class PermissionCardVH(parent: ViewGroup) :
|
||||
OverviewAdapter.BaseVH<PermissionCardVH.Item, MainPermissionItemBinding>(
|
||||
R.layout.main_permission_item,
|
||||
OverviewAdapter.BaseVH<PermissionCardVH.Item, OverviewPermissionItemBinding>(
|
||||
R.layout.overview_permission_item,
|
||||
parent
|
||||
) {
|
||||
|
||||
override val viewBinding = lazy {
|
||||
MainPermissionItemBinding.bind(itemView)
|
||||
OverviewPermissionItemBinding.bind(itemView)
|
||||
}
|
||||
|
||||
override val onBindData: MainPermissionItemBinding.(
|
||||
override val onBindData: OverviewPermissionItemBinding.(
|
||||
item: Item,
|
||||
payloads: List<Any>
|
||||
) -> Unit = binding(payload = true) { item ->
|
||||
|
||||
+2
-2
@@ -13,12 +13,12 @@ import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class KnownDevices @Inject constructor(
|
||||
class PairedDevices @Inject constructor(
|
||||
@AppScope private val scope: CoroutineScope,
|
||||
private val bluetoothManager2: BluetoothManager2,
|
||||
) {
|
||||
|
||||
fun currentKnownDevices(): Flow<List<BluetoothDevice2>> = bluetoothManager2
|
||||
fun connectedDevices(): Flow<List<BluetoothDevice2>> = bluetoothManager2
|
||||
.isBluetoothEnabled
|
||||
.flatMapLatest { bluetoothManager2.connectedDevices() }
|
||||
.map { devices ->
|
||||
@@ -17,12 +17,12 @@ import javax.inject.Inject
|
||||
@Reusable
|
||||
class PodReactions @Inject constructor(
|
||||
private val podMonitor: PodMonitor,
|
||||
private val knownDevices: KnownDevices,
|
||||
private val pairedDevices: PairedDevices,
|
||||
private val generalSettings: GeneralSettings,
|
||||
private val mediaControl: MediaControl,
|
||||
) {
|
||||
|
||||
fun podReactions() = knownDevices.currentKnownDevices()
|
||||
fun podReactions() = pairedDevices.connectedDevices()
|
||||
.flatMapLatest {
|
||||
if (it.isEmpty()) {
|
||||
log(TAG) { "No known devices connected." }
|
||||
|
||||
@@ -34,7 +34,7 @@ class MonitorWorker @AssistedInject constructor(
|
||||
private val notificationManager: NotificationManager,
|
||||
private val generalSettings: GeneralSettings,
|
||||
private val permissionTool: PermissionTool,
|
||||
private val knownDevices: KnownDevices,
|
||||
private val pairedDevices: PairedDevices,
|
||||
private val podMonitor: PodMonitor,
|
||||
private val podReactions: PodReactions,
|
||||
) : CoroutineWorker(context, params) {
|
||||
@@ -105,7 +105,7 @@ class MonitorWorker @AssistedInject constructor(
|
||||
return@flatMapLatest emptyFlow()
|
||||
}
|
||||
|
||||
knownDevices.currentKnownDevices().map { knownDevices ->
|
||||
pairedDevices.connectedDevices().map { knownDevices ->
|
||||
monitorMode to knownDevices
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ class MonitorNotifications @Inject constructor(
|
||||
|
||||
fun getBuilder(device: PodDevice?): NotificationCompat.Builder {
|
||||
if (device == null) {
|
||||
builder.setContentTitle(context.getString(R.string.device_none_label))
|
||||
builder.setContentTitle(context.getString(R.string.pods_none_label_short))
|
||||
builder.setSmallIcon(R.drawable.ic_device_generic_earbuds)
|
||||
return builder
|
||||
}
|
||||
|
||||
@@ -15,10 +15,10 @@ data class UnknownAppleDevice(
|
||||
) : ApplePods {
|
||||
|
||||
override fun getLabel(context: Context): String {
|
||||
return context.getString(R.string.device_unknown_label)
|
||||
return context.getString(R.string.pods_unknown_label)
|
||||
}
|
||||
|
||||
override fun getShortStatus(context: Context): String {
|
||||
return context.getString(R.string.device_unknown_label)
|
||||
return context.getString(R.string.pods_unknown_label)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.card.MaterialCardView 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:id="@+id/card"
|
||||
style="@style/MyCardView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:context=".main.ui.MainActivity">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/permission_label"
|
||||
style="@style/TextAppearance.MaterialComponents.Body1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:text="@string/pods_none_label" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/permission_description"
|
||||
style="@style/TextAppearance.MaterialComponents.Body2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/permission_label"
|
||||
android:text="@string/pods_none_description" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/show_all_action"
|
||||
style="@style/Widget.MaterialComponents.Button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/settings_showall_label"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/permission_description" />
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
+1
-1
@@ -57,7 +57,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="Grant permission"
|
||||
android:text="@string/general_grant_permission_action"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/permission_description" />
|
||||
@@ -26,7 +26,7 @@
|
||||
app:layout_constraintEnd_toStartOf="@id/reception"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Apple AirPods Max" />
|
||||
tools:text="Unknown device" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/last_seen"
|
||||
@@ -34,7 +34,6 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/rawdata_label"
|
||||
app:layout_constraintEnd_toEndOf="@id/name"
|
||||
app:layout_constraintStart_toStartOf="@id/name"
|
||||
app:layout_constraintTop_toBottomOf="@id/name"
|
||||
@@ -70,6 +69,21 @@
|
||||
app:srcCompat="@drawable/ic_baseline_signal_cellular_alt_24"
|
||||
tools:text="Yours (RSSI -61)" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/contact_dev_hint"
|
||||
style="@style/TextAppearance.MaterialComponents.Body2"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:text="@string/pods_unknown_contact_dev"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/last_seen" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/rawdata_label"
|
||||
style="@style/TextAppearance.MaterialComponents.Caption"
|
||||
@@ -83,7 +97,7 @@
|
||||
android:text="@string/pods_unknown_raw_data_label"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/last_seen" />
|
||||
app:layout_constraintTop_toBottomOf="@id/contact_dev_hint" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/rawdata"
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<string name="general_value_unknown_label">Unknown</string>
|
||||
<string name="general_thank_you_label">Thank you</string>
|
||||
<string name="general_value_not_available_label">N/A</string>
|
||||
<string name="general_grant_permission_action">Grant permission</string>
|
||||
|
||||
<string name="debug_debuglog_size_label">Size</string>
|
||||
<string name="debug_debuglog_size_compressed_label">Compressed size</string>
|
||||
@@ -31,12 +32,14 @@
|
||||
<string name="permission_ignore_battery_optimizations_label">Disable battery optimizations</string>
|
||||
<string name="permission_ignore_battery_optimizations_description">Battery optimizations can prevent CAPod from receiving Bluetooth data while the app is in the background.</string>
|
||||
|
||||
<string name="pods_single_basic_status_short">Headphones: %1$s</string>
|
||||
<string name="pods_single_headphones_label">Headphones</string>
|
||||
<string name="pods_dual_left_label">Left pod</string>
|
||||
<string name="pods_dual_right_label">Right pod</string>
|
||||
<string name="pods_dual_case_status_short">L %1$s | C %2$s | R %3$s</string>
|
||||
<string name="pods_case_status_label">Case</string>
|
||||
<string name="pods_case_status_open_label">Open</string>
|
||||
<string name="pods_case_status_closed_label">Closed</string>
|
||||
<string name="pods_unknown_raw_data_label">Raw data</string>
|
||||
<string name="pods_reception_x_label">Reception %s</string>
|
||||
<string name="pods_device_color_white_label">White</string>
|
||||
<string name="pods_device_color_yellow_label">Yellow</string>
|
||||
@@ -57,6 +60,12 @@
|
||||
<string name="pods_connection_state_call_label">In call mode</string>
|
||||
<string name="pods_connection_state_ringing_label">Ringing</string>
|
||||
<string name="pods_connection_state_hanging_up_label">Hanging up</string>
|
||||
<string name="pods_unknown_raw_data_label">Raw data</string>
|
||||
<string name="pods_unknown_label">Unknown device</string>
|
||||
<string name="pods_unknown_contact_dev">This is an unknown device, but it is using Apple\'s message format. Let\'s add support for it, contact me :).</string>
|
||||
<string name="pods_none_label_short">No device</string>
|
||||
<string name="pods_none_label">No paired device connected.</string>
|
||||
<string name="pods_none_description">Connect a paired device or enable the \'Show all\' option.</string>
|
||||
|
||||
<string name="settings_label">Settings</string>
|
||||
<string name="settings_privacy_policy_label">Privacy policy</string>
|
||||
@@ -82,9 +91,6 @@
|
||||
<string name="settings_support_email_developer_description">Note that I can only respond in german or english.</string>
|
||||
<string name="settings_debug_autoreports_label">Automatic bug reports</string>
|
||||
<string name="settings_debug_autoreports_description">Automatically reports issues, e.g. details on an app crash so I can figure out how to fix it.</string>
|
||||
<string name="device_unknown_label">Unknown device</string>
|
||||
<string name="device_none_label">No device</string>
|
||||
<string name="pods_single_headphones_label">Headphones</string>
|
||||
<string name="settings_debug_mode_label">Debug mode</string>
|
||||
<string name="settings_debug_mode_description">Show additional information to troubleshoot issues.</string>
|
||||
<string name="settings_monitor_mode_label">Monitor mode</string>
|
||||
@@ -103,8 +109,6 @@
|
||||
<string name="settings_showall_description">Show other people\'s devices that are near you.</string>
|
||||
<string name="settings_autopplay_label">Auto play</string>
|
||||
<string name="settings_autoplay_description">Start music playback music when wearing the device (if supported).</string>
|
||||
<string name="pods_dual_case_status_short">L %1$s | C %2$s | R %3$s</string>
|
||||
<string name="pods_single_basic_status_short">Headphones: %1$s</string>
|
||||
<string name="settings_fake_data_label">Fake data</string>
|
||||
<string name="settings_fake_data_description">Show fake data, i.e. simulate device that don\'t exist.</string>
|
||||
<string name="settings_debug_label">Debug settings</string>
|
||||
|
||||
Reference in New Issue
Block a user