From bf4ad7886c3e17deee3eb0368fbc6ac328f4eb43 Mon Sep 17 00:00:00 2001 From: darken Date: Mon, 29 Aug 2022 17:34:34 +0200 Subject: [PATCH] Improve wear os overview screen --- .../eu/darken/capod/main/core/MonitorMode.kt | 3 + app-common/src/main/res/values/strings.xml | 3 +- app-wear/src/main/java/eu/darken/capod/App.kt | 7 + .../capod/wear/ui/overview/OverviewAdapter.kt | 4 +- .../wear/ui/overview/OverviewFragmentVM.kt | 15 +- .../{SettingsVH.kt => SettingsButtonVH.kt} | 4 +- .../overview/cards/pods/SinglePodsCardVH.kt | 2 - .../cards/pods/UnknownPodDeviceCardVH.kt | 48 -- .../src/main/res/layout/main_fragment.xml | 2 + .../overview_bluetooth_disabled_item.xml | 7 +- .../res/layout/overview_nomaindevice_item.xml | 9 +- .../res/layout/overview_permission_item.xml | 10 +- .../res/layout/overview_pods_dual_item.xml | 525 +++++++++--------- .../res/layout/overview_pods_single_item.xml | 107 ++-- .../res/layout/overview_pods_unknown_item.xml | 116 ---- .../res/layout/overview_settings_item.xml | 5 +- .../main/ui/overview/OverviewFragmentVM.kt | 2 +- .../monitor/core/worker/MonitorWorker.kt | 2 +- 18 files changed, 332 insertions(+), 539 deletions(-) rename app-wear/src/main/java/eu/darken/capod/wear/ui/overview/cards/{SettingsVH.kt => SettingsButtonVH.kt} (89%) delete mode 100644 app-wear/src/main/java/eu/darken/capod/wear/ui/overview/cards/pods/UnknownPodDeviceCardVH.kt delete mode 100644 app-wear/src/main/res/layout/overview_pods_unknown_item.xml diff --git a/app-common/src/main/java/eu/darken/capod/main/core/MonitorMode.kt b/app-common/src/main/java/eu/darken/capod/main/core/MonitorMode.kt index 2ee4fc9c..c1fa7ac2 100644 --- a/app-common/src/main/java/eu/darken/capod/main/core/MonitorMode.kt +++ b/app-common/src/main/java/eu/darken/capod/main/core/MonitorMode.kt @@ -18,4 +18,7 @@ enum class MonitorMode( @Json(name = "monitor.mode.always") ALWAYS( R.string.settings_monitor_mode_always_label ), + @Json(name = "monitor.mode.periodically") PERIODICALLY( + R.string.settings_monitor_mode_periodically_label + ), } \ No newline at end of file diff --git a/app-common/src/main/res/values/strings.xml b/app-common/src/main/res/values/strings.xml index 0f20c880..6df35481 100644 --- a/app-common/src/main/res/values/strings.xml +++ b/app-common/src/main/res/values/strings.xml @@ -1,4 +1,4 @@ - + CAPod CAPod Pro CAPod FOSS @@ -44,6 +44,7 @@ When app is open When device is connected Always + Periodically Monitor mode Under which circumstances this app monitors Bluetooth data. Scanner mode diff --git a/app-wear/src/main/java/eu/darken/capod/App.kt b/app-wear/src/main/java/eu/darken/capod/App.kt index cca42e34..ba896430 100644 --- a/app-wear/src/main/java/eu/darken/capod/App.kt +++ b/app-wear/src/main/java/eu/darken/capod/App.kt @@ -5,10 +5,12 @@ import androidx.hilt.work.HiltWorkerFactory import androidx.work.Configuration import com.getkeepsafe.relinker.ReLinker import dagger.hilt.android.HiltAndroidApp +import eu.darken.capod.common.bluetooth.ScannerMode import eu.darken.capod.common.coroutine.AppScope import eu.darken.capod.common.debug.autoreport.AutoReporting import eu.darken.capod.common.debug.logging.* import eu.darken.capod.main.core.GeneralSettings +import eu.darken.capod.main.core.MonitorMode import kotlinx.coroutines.CoroutineScope import javax.inject.Inject @@ -28,6 +30,11 @@ open class App : Application(), Configuration.Provider { .log { message -> log(TAG) { "ReLinker: $message" } } .loadLibrary(this, "bugsnag-plugin-android-anr") + generalSettings.apply { + monitorMode.value = MonitorMode.PERIODICALLY + scannerMode.value = ScannerMode.BALANCED + } + autoReporting.setup() log(TAG) { "onCreate() done! ${Exception().asLog()}" } diff --git a/app-wear/src/main/java/eu/darken/capod/wear/ui/overview/OverviewAdapter.kt b/app-wear/src/main/java/eu/darken/capod/wear/ui/overview/OverviewAdapter.kt index 1515639d..7b6ee75a 100644 --- a/app-wear/src/main/java/eu/darken/capod/wear/ui/overview/OverviewAdapter.kt +++ b/app-wear/src/main/java/eu/darken/capod/wear/ui/overview/OverviewAdapter.kt @@ -14,7 +14,6 @@ import eu.darken.capod.common.lists.modular.mods.TypedVHCreatorMod import eu.darken.capod.wear.ui.overview.cards.* import eu.darken.capod.wear.ui.overview.cards.pods.DualPodsCardVH import eu.darken.capod.wear.ui.overview.cards.pods.SinglePodsCardVH -import eu.darken.capod.wear.ui.overview.cards.pods.UnknownPodDeviceCardVH import javax.inject.Inject class OverviewAdapter @Inject constructor() : @@ -26,13 +25,12 @@ class OverviewAdapter @Inject constructor() : init { modules.add(DataBinderMod(data)) modules.add(TypedVHCreatorMod({ data[it] is AppTitleVH.Item }) { AppTitleVH(it) }) - modules.add(TypedVHCreatorMod({ data[it] is SettingsVH.Item }) { SettingsVH(it) }) + modules.add(TypedVHCreatorMod({ data[it] is SettingsButtonVH.Item }) { SettingsButtonVH(it) }) modules.add(TypedVHCreatorMod({ data[it] is PermissionCardVH.Item }) { PermissionCardVH(it) }) modules.add(TypedVHCreatorMod({ data[it] is DualPodsCardVH.Item }) { DualPodsCardVH(it) }) modules.add(TypedVHCreatorMod({ data[it] is SinglePodsCardVH.Item }) { SinglePodsCardVH(it) }) modules.add(TypedVHCreatorMod({ data[it] is MissingMainDeviceVH.Item }) { MissingMainDeviceVH(it) }) modules.add(TypedVHCreatorMod({ data[it] is BluetoothDisabledVH.Item }) { BluetoothDisabledVH(it) }) - modules.add(TypedVHCreatorMod({ data[it] is UnknownPodDeviceCardVH.Item }) { UnknownPodDeviceCardVH(it) }) } override fun getItemCount(): Int = data.size diff --git a/app-wear/src/main/java/eu/darken/capod/wear/ui/overview/OverviewFragmentVM.kt b/app-wear/src/main/java/eu/darken/capod/wear/ui/overview/OverviewFragmentVM.kt index 02b13c40..34d983b0 100644 --- a/app-wear/src/main/java/eu/darken/capod/wear/ui/overview/OverviewFragmentVM.kt +++ b/app-wear/src/main/java/eu/darken/capod/wear/ui/overview/OverviewFragmentVM.kt @@ -1,6 +1,5 @@ package eu.darken.capod.wear.ui.overview -import android.app.Activity import androidx.lifecycle.LiveData import androidx.lifecycle.SavedStateHandle import dagger.hilt.android.lifecycle.HiltViewModel @@ -21,7 +20,6 @@ import eu.darken.capod.pods.core.SinglePodDevice import eu.darken.capod.wear.ui.overview.cards.* import eu.darken.capod.wear.ui.overview.cards.pods.DualPodsCardVH import eu.darken.capod.wear.ui.overview.cards.pods.SinglePodsCardVH -import eu.darken.capod.wear.ui.overview.cards.pods.UnknownPodDeviceCardVH import kotlinx.coroutines.delay import kotlinx.coroutines.flow.* import kotlinx.coroutines.isActive @@ -39,8 +37,6 @@ class OverviewFragmentVM @Inject constructor( private val bluetoothManager: BluetoothManager2, ) : ViewModel3(dispatcherProvider = dispatcherProvider) { - val launchUpgradeFlow = SingleLiveEvent<(Activity) -> Unit>() - private val updateTicker = channelFlow { while (isActive) { trySend(Unit) @@ -97,7 +93,7 @@ class OverviewFragmentVM @Inject constructor( } if (permissions.isEmpty() && isBluetoothEnabled) { - pods.map { + pods.mapNotNull { val now = Instant.now() when (it) { is DualPodDevice -> DualPodsCardVH.Item( @@ -112,18 +108,13 @@ class OverviewFragmentVM @Inject constructor( showDebug = isDebugMode, isMainPod = it == mainPod, ) - else -> UnknownPodDeviceCardVH.Item( - now = now, - device = it, - showDebug = isDebugMode, - isMainPod = it == mainPod, - ) + else -> null } }.run { items.addAll(this) } } items.add(0, AppTitleVH.Item()) - SettingsVH.Item( + SettingsButtonVH.Item( onClick = { OverviewFragmentDirections.actionOverviewFragmentToSettingsFragment().navVia(this@OverviewFragmentVM) } diff --git a/app-wear/src/main/java/eu/darken/capod/wear/ui/overview/cards/SettingsVH.kt b/app-wear/src/main/java/eu/darken/capod/wear/ui/overview/cards/SettingsButtonVH.kt similarity index 89% rename from app-wear/src/main/java/eu/darken/capod/wear/ui/overview/cards/SettingsVH.kt rename to app-wear/src/main/java/eu/darken/capod/wear/ui/overview/cards/SettingsButtonVH.kt index 572ea638..196c91d0 100644 --- a/app-wear/src/main/java/eu/darken/capod/wear/ui/overview/cards/SettingsVH.kt +++ b/app-wear/src/main/java/eu/darken/capod/wear/ui/overview/cards/SettingsButtonVH.kt @@ -7,8 +7,8 @@ import eu.darken.capod.common.lists.differ.DifferItem import eu.darken.capod.databinding.OverviewSettingsItemBinding import eu.darken.capod.wear.ui.overview.OverviewAdapter -class SettingsVH(parent: ViewGroup) : - OverviewAdapter.BaseVH( +class SettingsButtonVH(parent: ViewGroup) : + OverviewAdapter.BaseVH( R.layout.overview_settings_item, parent ) { diff --git a/app-wear/src/main/java/eu/darken/capod/wear/ui/overview/cards/pods/SinglePodsCardVH.kt b/app-wear/src/main/java/eu/darken/capod/wear/ui/overview/cards/pods/SinglePodsCardVH.kt index b9bd2ec9..2bb8c01f 100644 --- a/app-wear/src/main/java/eu/darken/capod/wear/ui/overview/cards/pods/SinglePodsCardVH.kt +++ b/app-wear/src/main/java/eu/darken/capod/wear/ui/overview/cards/pods/SinglePodsCardVH.kt @@ -31,8 +31,6 @@ class SinglePodsCardVH(parent: ViewGroup) : lastSeen.text = device.lastSeenFormatted(item.now) - reception.text = item.getReceptionText() - // Battery level device.apply { batteryLabel.text = getBatteryLevelHeadset(context) diff --git a/app-wear/src/main/java/eu/darken/capod/wear/ui/overview/cards/pods/UnknownPodDeviceCardVH.kt b/app-wear/src/main/java/eu/darken/capod/wear/ui/overview/cards/pods/UnknownPodDeviceCardVH.kt deleted file mode 100644 index 7cb3f64e..00000000 --- a/app-wear/src/main/java/eu/darken/capod/wear/ui/overview/cards/pods/UnknownPodDeviceCardVH.kt +++ /dev/null @@ -1,48 +0,0 @@ -package eu.darken.capod.wear.ui.overview.cards.pods - -import android.graphics.Typeface -import android.view.ViewGroup -import eu.darken.capod.R -import eu.darken.capod.common.lists.binding -import eu.darken.capod.databinding.OverviewPodsUnknownItemBinding -import eu.darken.capod.pods.core.PodDevice -import eu.darken.capod.pods.core.apple.ApplePods -import eu.darken.capod.pods.core.lastSeenFormatted -import java.time.Instant - -class UnknownPodDeviceCardVH(parent: ViewGroup) : - PodDeviceVH( - R.layout.overview_pods_unknown_item, - parent - ) { - - override val viewBinding = lazy { - OverviewPodsUnknownItemBinding.bind(itemView) - } - - override val onBindData = binding(payload = true) { item -> - val device = item.device - name.apply { - text = device.getLabel(context) - if (item.isMainPod) setTypeface(typeface, Typeface.BOLD) - else setTypeface(typeface, Typeface.NORMAL) - } - - lastSeen.text = device.lastSeenFormatted(item.now) - reception.text = item.getReceptionText() - - details.text = when (item.device) { - is ApplePods -> getString(R.string.pods_unknown_contact_dev) - else -> getString(R.string.pods_unknown_label) - } - - rawdata.text = device.rawDataHex.joinToString("\n") - } - - data class Item( - override val now: Instant, - override val device: PodDevice, - override val showDebug: Boolean = false, - override val isMainPod: Boolean = false, - ) : PodDeviceVH.Item -} \ No newline at end of file diff --git a/app-wear/src/main/res/layout/main_fragment.xml b/app-wear/src/main/res/layout/main_fragment.xml index 938edb4a..99014d53 100644 --- a/app-wear/src/main/res/layout/main_fragment.xml +++ b/app-wear/src/main/res/layout/main_fragment.xml @@ -11,6 +11,8 @@ android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" + android:paddingBottom="48dp" + android:clipToPadding="false" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" tools:listitem="@layout/overview_pods_dual_item" /> diff --git a/app-wear/src/main/res/layout/overview_bluetooth_disabled_item.xml b/app-wear/src/main/res/layout/overview_bluetooth_disabled_item.xml index 90f01d59..964ed9fe 100644 --- a/app-wear/src/main/res/layout/overview_bluetooth_disabled_item.xml +++ b/app-wear/src/main/res/layout/overview_bluetooth_disabled_item.xml @@ -2,11 +2,12 @@ @@ -15,8 +16,6 @@ style="@style/TextAppearance.MaterialComponents.Body1" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginHorizontal="16dp" - android:layout_marginTop="16dp" android:text="@string/overview_bluetooth_disabled_label" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -27,9 +26,7 @@ style="@style/TextAppearance.MaterialComponents.Body2" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginHorizontal="16dp" android:layout_marginTop="4dp" - android:layout_marginBottom="16dp" android:text="@string/overview_bluetooth_disabled_description" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" diff --git a/app-wear/src/main/res/layout/overview_nomaindevice_item.xml b/app-wear/src/main/res/layout/overview_nomaindevice_item.xml index 6983ebb0..bda1a29c 100644 --- a/app-wear/src/main/res/layout/overview_nomaindevice_item.xml +++ b/app-wear/src/main/res/layout/overview_nomaindevice_item.xml @@ -3,12 +3,11 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginHorizontal="8dp" - android:layout_marginVertical="8dp"> + android:layout_margin="8dp"> + android:layout_margin="8dp"> - - - - - - - - - + xmlns:tools="http://schemas.android.com/tools" + android:layout_margin="8dp"> + android:layout_margin="8dp"> - - - - - - + app:layout_constraintTop_toTopOf="parent" + app:srcCompat="@drawable/ic_airpod_both_24" /> + + + android:layout_marginBottom="4dp" + android:gravity="center_horizontal" + android:maxLines="2" + android:ellipsize="end" + app:layout_constraintBottom_toTopOf="@id/barrier_top" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/name" /> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + app:layout_constraintTop_toBottomOf="@id/barrier_bottom" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/app-wear/src/main/res/layout/overview_pods_single_item.xml b/app-wear/src/main/res/layout/overview_pods_single_item.xml index 620114ac..7972f1b2 100644 --- a/app-wear/src/main/res/layout/overview_pods_single_item.xml +++ b/app-wear/src/main/res/layout/overview_pods_single_item.xml @@ -4,102 +4,69 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginHorizontal="8dp" - android:layout_marginVertical="8dp"> + android:layout_margin="8dp"> + android:layout_margin="8dp"> - - - - + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/name" + tools:text="Music Active, Case Closed" /> + app:barrierDirection="bottom" + app:constraint_referenced_ids="status" /> + app:layout_constraintVertical_bias="0.20"> + app:barrierDirection="top" + app:constraint_referenced_ids="last_seen" /> + tools:text="3s ago" /> - + \ No newline at end of file diff --git a/app-wear/src/main/res/layout/overview_pods_unknown_item.xml b/app-wear/src/main/res/layout/overview_pods_unknown_item.xml deleted file mode 100644 index de3ed140..00000000 --- a/app-wear/src/main/res/layout/overview_pods_unknown_item.xml +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/app-wear/src/main/res/layout/overview_settings_item.xml b/app-wear/src/main/res/layout/overview_settings_item.xml index 9d258ac3..e6eef54a 100644 --- a/app-wear/src/main/res/layout/overview_settings_item.xml +++ b/app-wear/src/main/res/layout/overview_settings_item.xml @@ -2,15 +2,14 @@ + android:layout_height="wrap_content" + android:layout_margin="8dp"> false + MonitorMode.PERIODICALLY, MonitorMode.MANUAL -> false MonitorMode.AUTOMATIC -> bluetoothManager.connectedDevices().first().isNotEmpty() MonitorMode.ALWAYS -> true } diff --git a/app/src/main/java/eu/darken/capod/monitor/core/worker/MonitorWorker.kt b/app/src/main/java/eu/darken/capod/monitor/core/worker/MonitorWorker.kt index 73261de0..0a34725a 100644 --- a/app/src/main/java/eu/darken/capod/monitor/core/worker/MonitorWorker.kt +++ b/app/src/main/java/eu/darken/capod/monitor/core/worker/MonitorWorker.kt @@ -127,7 +127,7 @@ class MonitorWorker @AssistedInject constructor( .flatMapLatest { (monitorMode, devices) -> log(TAG) { "Monitor mode: $monitorMode" } when (monitorMode) { - MonitorMode.MANUAL -> flow { + MonitorMode.PERIODICALLY, MonitorMode.MANUAL -> flow { // Cancel worker, ui scans manually workerScope.coroutineContext.cancelChildren() }