Basic working data display in wear-app

This commit is contained in:
darken
2022-09-14 18:00:18 +02:00
committed by Matthias Urhahn
parent 2eb3f70e0c
commit 1d51c207f4
225 changed files with 606 additions and 860 deletions
+3
View File
@@ -93,5 +93,8 @@ dependencies {
addBaseWorkManager()
addNavigation()
addTesting()
implementation("com.bugsnag:bugsnag-android:5.9.2")
}
@@ -1,22 +0,0 @@
package eu.darken.capod
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.*
import org.junit.Test
import org.junit.runner.RunWith
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("eu.darken.capod.test", appContext.packageName)
}
}
@@ -1,16 +0,0 @@
package eu.darken.capod
import org.junit.Assert.assertEquals
import org.junit.Test
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}
@@ -13,9 +13,9 @@ import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.test.*
import org.junit.jupiter.api.Test
import testhelper.BaseTest
import testhelper.coroutine.runTest2
import testhelper.flow.test
import testhelpers.BaseTest
import testhelpers.coroutine.runTest2
import testhelpers.flow.test
import java.io.IOException
import java.lang.Thread.sleep
import kotlin.concurrent.thread
@@ -28,7 +28,7 @@ class DynamicStateFlowTest : BaseTest() {
fun `exceptions on initialization are rethrown`() {
val testScope =
createTestCoroutineScope(TestCoroutineDispatcher() + TestCoroutineExceptionHandler() + EmptyCoroutineContext)
val hotData = DynamicStateFlow<String>(
val hotData = eu.darken.capod.common.flow.DynamicStateFlow<String>(
loggingTag = "tag",
parentScope = testScope,
coroutineContext = Dispatchers.Unconfined,
@@ -53,7 +53,7 @@ class DynamicStateFlowTest : BaseTest() {
val valueProvider = mockk<suspend CoroutineScope.() -> String>()
coEvery { valueProvider.invoke(any()) } returns "Test"
val hotData = DynamicStateFlow(
val hotData = eu.darken.capod.common.flow.DynamicStateFlow(
loggingTag = "tag",
parentScope = testScope,
coroutineContext = Dispatchers.Unconfined,
@@ -76,7 +76,7 @@ class DynamicStateFlowTest : BaseTest() {
val valueProvider = mockk<suspend CoroutineScope.() -> Long>()
coEvery { valueProvider.invoke(any()) } returns 1
val hotData = DynamicStateFlow(
val hotData = eu.darken.capod.common.flow.DynamicStateFlow(
loggingTag = "tag",
parentScope = testScope,
startValueProvider = valueProvider,
@@ -113,10 +113,11 @@ class DynamicStateFlowTest : BaseTest() {
fun `check multi threading value updates with more complex data`() {
val testScope =
createTestCoroutineScope(TestCoroutineDispatcher() + TestCoroutineExceptionHandler() + EmptyCoroutineContext)
val valueProvider = mockk<suspend CoroutineScope.() -> Map<String, TestData>>()
coEvery { valueProvider.invoke(any()) } returns mapOf("data" to TestData())
val valueProvider =
mockk<suspend CoroutineScope.() -> Map<String, eu.darken.capod.common.flow.DynamicStateFlowTest.TestData>>()
coEvery { valueProvider.invoke(any()) } returns mapOf("data" to eu.darken.capod.common.flow.DynamicStateFlowTest.TestData())
val hotData = DynamicStateFlow(
val hotData = eu.darken.capod.common.flow.DynamicStateFlow(
loggingTag = "tag",
parentScope = testScope,
startValueProvider = valueProvider,
@@ -152,7 +153,7 @@ class DynamicStateFlowTest : BaseTest() {
val testScope =
createTestCoroutineScope(TestCoroutineDispatcher() + TestCoroutineExceptionHandler() + EmptyCoroutineContext)
val hotData = DynamicStateFlow(
val hotData = eu.darken.capod.common.flow.DynamicStateFlow(
loggingTag = "tag",
parentScope = testScope,
startValueProvider = { "1" },
@@ -177,7 +178,7 @@ class DynamicStateFlowTest : BaseTest() {
val valueProvider = mockk<suspend CoroutineScope.() -> String>()
coEvery { valueProvider.invoke(any()) } returns "Test"
val hotData = DynamicStateFlow(
val hotData = eu.darken.capod.common.flow.DynamicStateFlow(
loggingTag = "tag",
parentScope = this,
startValueProvider = valueProvider,
@@ -209,7 +210,7 @@ class DynamicStateFlowTest : BaseTest() {
val valueProvider = mockk<suspend CoroutineScope.() -> Long>()
coEvery { valueProvider.invoke(any()) } returns 1
val hotData = DynamicStateFlow(
val hotData = eu.darken.capod.common.flow.DynamicStateFlow(
loggingTag = "tag",
parentScope = this,
coroutineContext = this.coroutineContext,
@@ -248,7 +249,7 @@ class DynamicStateFlowTest : BaseTest() {
fun `blocking update is actually blocking`() = runBlocking {
val testScope =
createTestCoroutineScope(TestCoroutineDispatcher() + TestCoroutineExceptionHandler() + EmptyCoroutineContext)
val hotData = DynamicStateFlow(
val hotData = eu.darken.capod.common.flow.DynamicStateFlow(
loggingTag = "tag",
parentScope = testScope,
coroutineContext = testScope.coroutineContext,
@@ -279,7 +280,7 @@ class DynamicStateFlowTest : BaseTest() {
fun `blocking update rethrows error`() = runBlocking {
val testScope =
createTestCoroutineScope(TestCoroutineDispatcher() + TestCoroutineExceptionHandler() + EmptyCoroutineContext)
val hotData = DynamicStateFlow(
val hotData = eu.darken.capod.common.flow.DynamicStateFlow(
loggingTag = "tag",
parentScope = testScope,
coroutineContext = testScope.coroutineContext,
@@ -308,7 +309,7 @@ class DynamicStateFlowTest : BaseTest() {
@Test
fun `async updates error handler`() = runTest2(expectedError = IOException::class) {
val hotData = DynamicStateFlow(
val hotData = eu.darken.capod.common.flow.DynamicStateFlow(
loggingTag = "tag",
parentScope = this,
startValueProvider = { 1 },
@@ -327,7 +328,7 @@ class DynamicStateFlowTest : BaseTest() {
val testScope =
createTestCoroutineScope(TestCoroutineDispatcher() + TestCoroutineExceptionHandler() + EmptyCoroutineContext)
val hotData = DynamicStateFlow(
val hotData = eu.darken.capod.common.flow.DynamicStateFlow(
loggingTag = "tag",
parentScope = testScope,
startValueProvider = { 1 },
@@ -357,7 +358,7 @@ class DynamicStateFlowTest : BaseTest() {
var onReleaseValue: String? = null
val hotData = DynamicStateFlow(
val hotData = eu.darken.capod.common.flow.DynamicStateFlow(
loggingTag = "tag",
parentScope = testScope,
coroutineContext = Dispatchers.Unconfined,
@@ -7,8 +7,8 @@ import io.kotest.matchers.shouldBe
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.runBlockingTest
import org.junit.jupiter.api.Test
import testhelper.BaseTest
import testhelper.json.toComparableJson
import testhelpers.BaseTest
import testhelpers.json.toComparableJson
import testhelpers.preferences.MockSharedPreferences
class FlowPreferenceMoshiTest : BaseTest() {
@@ -4,7 +4,7 @@ import io.kotest.matchers.shouldBe
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.runBlockingTest
import org.junit.jupiter.api.Test
import testhelper.BaseTest
import testhelpers.BaseTest
import testhelpers.preferences.MockSharedPreferences
class FlowPreferenceTest : BaseTest() {
@@ -9,7 +9,7 @@ import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.mockkObject
import org.junit.jupiter.api.BeforeEach
import testhelper.BaseTest
import testhelpers.BaseTest
import javax.inject.Singleton
abstract class BaseAirPodsTest : BaseTest() {
@@ -1,4 +1,4 @@
package testhelper
package testhelpers
import eu.darken.capod.common.debug.logging.Logging
import eu.darken.capod.common.debug.logging.Logging.Priority.VERBOSE
@@ -1,4 +1,4 @@
package testhelper.coroutine
package testhelpers.coroutine
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -1,4 +1,4 @@
package testhelper.coroutine
package testhelpers.coroutine
import eu.darken.capod.common.coroutine.DispatcherProvider
import kotlinx.coroutines.CoroutineScope
@@ -1,4 +1,4 @@
package testhelper.coroutine
package testhelpers.coroutine
import eu.darken.capod.common.debug.logging.asLog
import kotlinx.coroutines.CancellationException
@@ -1,4 +1,4 @@
package testhelper.flow
package testhelpers.flow
import eu.darken.capod.common.debug.logging.Logging.Priority.WARN
import eu.darken.capod.common.debug.logging.asLog
@@ -1,4 +1,4 @@
package testhelper.json
package testhelpers.json
import com.squareup.moshi.JsonReader
import com.squareup.moshi.Moshi
@@ -1,4 +1,4 @@
package testhelper.livedata
package testhelpers.livedata
import androidx.arch.core.executor.ArchTaskExecutor
import androidx.arch.core.executor.TaskExecutor
@@ -1,10 +1,9 @@
package testhelper.preferences
package testhelpers.preferences
import androidx.core.content.edit
import io.kotest.matchers.shouldBe
import org.junit.jupiter.api.Test
import testhelper.BaseTest
import testhelpers.preferences.MockSharedPreferences
import testhelpers.BaseTest
class MockSharedPreferencesTest : BaseTest() {
-19
View File
@@ -118,25 +118,6 @@ android {
"-opt-in=kotlin.RequiresOptIn"
)
}
testOptions {
unitTests {
isIncludeAndroidResources = true
}
tasks.withType<Test> {
useJUnitPlatform()
}
}
sourceSets {
getByName("test") {
java.srcDir("$projectDir/src/testShared/java")
}
getByName("androidTest") {
java.srcDir("$projectDir/src/testShared/java")
assets.srcDirs(files("$projectDir/schemas"))
}
}
}
dependencies {
+1 -1
View File
@@ -32,7 +32,7 @@
android:label="@string/app_name"
android:supportsRtl="true"
android:name=".App"
android:theme="@android:style/Theme.DeviceDefault">
android:theme="@style/AppTheme">
<uses-library
android:name="com.google.android.wearable"
android:required="true" />
@@ -8,6 +8,7 @@ import dagger.hilt.android.HiltAndroidApp
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 kotlinx.coroutines.CoroutineScope
import javax.inject.Inject
@@ -16,6 +17,7 @@ open class App : Application(), Configuration.Provider {
@Inject lateinit var workerFactory: HiltWorkerFactory
@Inject lateinit var autoReporting: AutoReporting
@Inject lateinit var generalSettings: GeneralSettings
@Inject @AppScope lateinit var appScope: CoroutineScope
override fun onCreate() {
@@ -2,7 +2,7 @@ package eu.darken.capod.wear.ui
import android.os.Bundle
import androidx.activity.viewModels
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.wear.widget.SwipeDismissFrameLayout
import dagger.hilt.android.AndroidEntryPoint
import eu.darken.capod.R
import eu.darken.capod.common.navigation.findNavController
@@ -17,11 +17,16 @@ class MainActivity : Activity2() {
private val navController by lazy { supportFragmentManager.findNavController(R.id.nav_host) }
override fun onCreate(savedInstanceState: Bundle?) {
installSplashScreen()
super.onCreate(savedInstanceState)
ui = MainActivityBinding.inflate(layoutInflater)
setContentView(ui.root)
ui.swipeWrapper.addCallback(object : SwipeDismissFrameLayout.Callback() {
override fun onDismissed(layout: SwipeDismissFrameLayout?) {
if (!navController.popBackStack()) finish()
super.onDismissed(layout)
}
})
}
}
@@ -11,9 +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.wear.ui.overview.cards.BluetoothDisabledVH
import eu.darken.capod.wear.ui.overview.cards.MissingMainDeviceVH
import eu.darken.capod.wear.ui.overview.cards.PermissionCardVH
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
@@ -27,6 +25,8 @@ 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 PermissionCardVH.Item }) { PermissionCardVH(it) })
modules.add(TypedVHCreatorMod({ data[it] is DualPodsCardVH.Item }) { DualPodsCardVH(it) })
modules.add(TypedVHCreatorMod({ data[it] is SinglePodsCardVH.Item }) { SinglePodsCardVH(it) })
@@ -4,21 +4,17 @@ import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.Settings
import android.text.SpannableStringBuilder
import android.view.View
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.fragment.app.viewModels
import dagger.hilt.android.AndroidEntryPoint
import eu.darken.capod.BuildConfig
import eu.darken.capod.R
import eu.darken.capod.common.colorString
import eu.darken.capod.common.debug.logging.log
import eu.darken.capod.common.lists.differ.update
import eu.darken.capod.common.lists.setupDefaults
import eu.darken.capod.common.permissions.Permission
import eu.darken.capod.common.uix.Fragment3
import eu.darken.capod.common.upgrade.UpgradeRepo
import eu.darken.capod.common.viewbinding.viewBinding
import eu.darken.capod.databinding.MainFragmentBinding
import javax.inject.Inject
@@ -48,37 +44,10 @@ class OverviewFragment : Fragment3(R.layout.main_fragment) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
ui.apply {
list.setupDefaults(adapter, dividers = false)
list.setupDefaults(adapter)
}
ui.toolbar.apply {
// setOnMenuItemClickListener {
// when (it.itemId) {
// R.id.menu_item_settings -> {
// vm.goToSettings()
// true
// }
// R.id.menu_item_donate -> {
// vm.onUpgrade()
// true
// }
// R.id.menu_item_upgrade -> {
// vm.onUpgrade()
// true
// }
// else -> false
// }
// }
}
vm.listItems.observe2(ui) {
if (BuildConfig.DEBUG) toolbar.subtitle = "${it.size} items"
adapter.update(it)
}
vm.workerAutolaunch.observe2 {
// While UI is active, subscribe to the autolaunch routine
}
vm.listItems.observe2(ui) { adapter.update(it) }
vm.requestPermissionEvent.observe2(ui) {
when (it) {
@@ -106,47 +75,6 @@ class OverviewFragment : Fragment3(R.layout.main_fragment) {
}
}
vm.upgradeState.observe2(ui) { info ->
// val gplay = toolbar.menu.findItem(R.id.menu_item_upgrade)
// val donate = toolbar.menu.findItem(R.id.menu_item_donate)
// gplay.isVisible = false
// donate.isVisible = false
//
// val baseTitle = when (info.type) {
// UpgradeRepo.Type.GPLAY -> {
// if (info.isPro) {
// getString(R.string.app_name_pro)
// } else {
// gplay.isVisible = true
// getString(R.string.app_name)
// }
// }
// UpgradeRepo.Type.FOSS -> {
// if (info.isPro) {
// getString(R.string.app_name_foss)
// } else {
// donate.isVisible = true
// getString(R.string.app_name)
// }
// }
// }.split(" ".toRegex())
// .dropLastWhile { it.isEmpty() }
// .toTypedArray()
//
// toolbar.title = if (baseTitle.size == 2) {
// val builder = SpannableStringBuilder(baseTitle[0] + " ")
// val color = when (info.type) {
// UpgradeRepo.Type.FOSS -> R.color.brand_secondary
// else -> R.color.brand_tertiary
// }
// builder.append(colorString(requireContext(), color, baseTitle[1]))
// } else {
// getString(R.string.app_name)
// }
}
vm.launchUpgradeFlow.observe2 {
it(requireActivity())
}
super.onViewCreated(view, savedInstanceState)
}
@@ -7,23 +7,18 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import eu.darken.capod.common.bluetooth.BluetoothManager2
import eu.darken.capod.common.coroutine.DispatcherProvider
import eu.darken.capod.common.debug.autoreport.DebugSettings
import eu.darken.capod.common.debug.logging.log
import eu.darken.capod.common.flow.combine
import eu.darken.capod.common.livedata.SingleLiveEvent
import eu.darken.capod.common.navigation.navVia
import eu.darken.capod.common.permissions.Permission
import eu.darken.capod.common.uix.ViewModel3
import eu.darken.capod.common.upgrade.UpgradeRepo
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.monitor.core.PodMonitor
import eu.darken.capod.pods.core.DualPodDevice
import eu.darken.capod.pods.core.PodDevice
import eu.darken.capod.pods.core.SinglePodDevice
import eu.darken.capod.wear.ui.overview.cards.BluetoothDisabledVH
import eu.darken.capod.wear.ui.overview.cards.MissingMainDeviceVH
import eu.darken.capod.wear.ui.overview.cards.PermissionCardVH
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
@@ -37,16 +32,13 @@ import javax.inject.Inject
class OverviewFragmentVM @Inject constructor(
@Suppress("UNUSED_PARAMETER") handle: SavedStateHandle,
dispatcherProvider: DispatcherProvider,
// private val monitorControl: MonitorControl,
private val podMonitor: PodMonitor,
private val permissionTool: PermissionTool,
private val generalSettings: GeneralSettings,
debugSettings: DebugSettings,
private val upgradeRepo: UpgradeRepo,
private val bluetoothManager: BluetoothManager2,
) : ViewModel3(dispatcherProvider = dispatcherProvider) {
val upgradeState = upgradeRepo.upgradeInfo.asLiveData2()
val launchUpgradeFlow = SingleLiveEvent<(Activity) -> Unit>()
private val updateTicker = channelFlow<Unit> {
@@ -56,26 +48,6 @@ class OverviewFragmentVM @Inject constructor(
}
}
val workerAutolaunch: LiveData<Unit> = permissionTool.missingPermissions
.onEach {
if (it.isNotEmpty()) {
log(TAG) { "Missing permissions: $it" }
return@onEach
}
val shouldStartMonitor = when (generalSettings.monitorMode.value) {
MonitorMode.MANUAL -> false
MonitorMode.AUTOMATIC -> bluetoothManager.connectedDevices().first().isNotEmpty()
MonitorMode.ALWAYS -> true
}
if (shouldStartMonitor) {
log(TAG) { "Starting monitor" }
// monitorControl.startMonitor()
}
}
.map { }
.asLiveData2()
val requestPermissionEvent = SingleLiveEvent<Permission>()
private val pods: Flow<List<PodDevice>> = permissionTool.missingPermissions
@@ -150,6 +122,13 @@ class OverviewFragmentVM @Inject constructor(
}.run { items.addAll(this) }
}
items.add(0, AppTitleVH.Item())
SettingsVH.Item(
onClick = {
OverviewFragmentDirections.actionOverviewFragmentToSettingsFragment().navVia(this@OverviewFragmentVM)
}
).run { items.add(this) }
items
}
.catch { errorEvents.postValue(it) }
@@ -158,16 +137,4 @@ class OverviewFragmentVM @Inject constructor(
fun onPermissionResult(granted: Boolean) {
if (granted) permissionTool.recheck()
}
fun goToSettings() = launch {
OverviewFragmentDirections.actionOverviewFragmentToSettingsFragment().navVia(this@OverviewFragmentVM)
}
fun onUpgrade() = launch {
val call: (Activity) -> Unit = {
upgradeRepo.launchBillingFlow(it)
}
launchUpgradeFlow.postValue(call)
}
}
@@ -0,0 +1,36 @@
package eu.darken.capod.wear.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.common.upgrade.UpgradeRepo
import eu.darken.capod.databinding.OverviewApptitleItemBinding
import eu.darken.capod.wear.ui.overview.OverviewAdapter
class AppTitleVH(parent: ViewGroup) :
OverviewAdapter.BaseVH<AppTitleVH.Item, OverviewApptitleItemBinding>(
R.layout.overview_apptitle_item,
parent
) {
override val viewBinding = lazy {
OverviewApptitleItemBinding.bind(itemView)
}
override val onBindData: OverviewApptitleItemBinding.(
item: Item,
payloads: List<Any>
) -> Unit = binding(payload = true) { item ->
}
data class Item(
val upgradeInfo: UpgradeRepo.Info? = null
) : 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 }
}
}
@@ -0,0 +1,36 @@
package eu.darken.capod.wear.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.OverviewSettingsItemBinding
import eu.darken.capod.wear.ui.overview.OverviewAdapter
class SettingsVH(parent: ViewGroup) :
OverviewAdapter.BaseVH<SettingsVH.Item, OverviewSettingsItemBinding>(
R.layout.overview_settings_item,
parent
) {
override val viewBinding = lazy {
OverviewSettingsItemBinding.bind(itemView)
}
override val onBindData: OverviewSettingsItemBinding.(
item: Item,
payloads: List<Any>
) -> Unit = binding(payload = true) { item ->
settingsButton.setOnClickListener { item.onClick() }
}
data class Item(
val isEnabled: Boolean = true,
val onClick: () -> 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 }
}
}
@@ -9,8 +9,6 @@ import eu.darken.capod.common.lists.binding
import eu.darken.capod.databinding.OverviewPodsDualItemBinding
import eu.darken.capod.pods.core.*
import eu.darken.capod.pods.core.apple.DualAirPods
import eu.darken.capod.pods.core.apple.DualAirPods.LidState
import java.time.Duration
import java.time.Instant
class DualPodsCardVH(parent: ViewGroup) :
@@ -41,10 +39,7 @@ class DualPodsCardVH(parent: ViewGroup) :
deviceIcon.setImageResource(device.iconRes)
lastSeen.text = context.getString(R.string.last_seen_x, device.lastSeenFormatted(item.now))
firstSeen.text = context.getString(R.string.first_seen_x, device.firstSeenFormatted(item.now))
firstSeen.isGone = Duration.between(device.seenFirstAt, device.seenLastAt).toMinutes() < 1
reception.text = item.getReceptionText()
// reception.text = item.getReceptionText()
// Pods battery state
device.apply {
@@ -59,16 +54,12 @@ class DualPodsCardVH(parent: ViewGroup) :
device.apply {
if (this is HasChargeDetectionDual) {
podLeftChargingIcon.isInvisible = !isLeftPodCharging
podLeftChargingLabel.isInvisible = !isLeftPodCharging
podRightChargingIcon.isInvisible = !isRightPodCharging
podRightChargingLabel.isInvisible = !isRightPodCharging
} else {
podLeftChargingIcon.isGone = true
podLeftChargingLabel.isGone = true
podRightChargingIcon.isGone = true
podRightChargingLabel.isGone = true
}
}
@@ -76,16 +67,12 @@ class DualPodsCardVH(parent: ViewGroup) :
device.apply {
if (this is HasDualMicrophone) {
podLeftMicrophoneIcon.isInvisible = !isLeftPodMicrophone
podLeftMicrophoneLabel.isInvisible = !isLeftPodMicrophone
podRightMicrophoneIcon.isInvisible = !isRightPodMicrophone
podRightMicrophoneLabel.isInvisible = !isRightPodMicrophone
} else {
podLeftMicrophoneIcon.isGone = true
podLeftMicrophoneLabel.isGone = true
podRightMicrophoneIcon.isGone = true
podRightMicrophoneLabel.isGone = true
}
}
@@ -93,16 +80,12 @@ class DualPodsCardVH(parent: ViewGroup) :
device.apply {
if (this is HasEarDetectionDual) {
podLeftWearIcon.isInvisible = !isLeftPodInEar
podLeftWearLabel.isInvisible = !isLeftPodInEar
podRightWearIcon.isInvisible = !isRightPodInEar
podRightWearLabel.isInvisible = !isRightPodInEar
} else {
podLeftWearIcon.isGone = true
podLeftWearLabel.isGone = true
podRightWearIcon.isGone = true
podRightWearLabel.isGone = true
}
}
@@ -114,33 +97,31 @@ class DualPodsCardVH(parent: ViewGroup) :
podCaseBatteryLabel.text = getBatteryLevelCase(context)
podCaseChargingIcon.isInvisible = !isCaseCharging
podCaseChargingLabel.isInvisible = !isCaseCharging
} else {
podCaseBatteryIcon.isGone = true
podCaseBatteryLabel.isGone = true
podCaseChargingIcon.isGone = true
podCaseChargingLabel.isGone = true
}
}
// Case lid state
device.apply {
if (this is DualAirPods) {
podCaseLidLabel.text = when (caseLidState) {
LidState.OPEN -> context.getString(R.string.pods_case_status_open_label)
LidState.CLOSED -> context.getString(R.string.pods_case_status_closed_label)
else -> context.getString(R.string.pods_case_unknown_state)
}
val hideInfo = !listOf(LidState.OPEN, LidState.CLOSED).contains(caseLidState)
podCaseLidIcon.isInvisible = hideInfo
podCaseLidLabel.isInvisible = hideInfo
} else {
podCaseLidIcon.isGone = true
podCaseLidLabel.isGone = true
}
}
// // Case lid state
// device.apply {
// if (this is DualAirPods) {
// podCaseLidLabel.text = when (caseLidState) {
// LidState.OPEN -> context.getString(R.string.pods_case_status_open_label)
// LidState.CLOSED -> context.getString(R.string.pods_case_status_closed_label)
// else -> context.getString(R.string.pods_case_unknown_state)
// }
//
// val hideInfo = !listOf(LidState.OPEN, LidState.CLOSED).contains(caseLidState)
// podCaseLidIcon.isInvisible = hideInfo
// podCaseLidLabel.isInvisible = hideInfo
// } else {
// podCaseLidIcon.isGone = true
// podCaseLidLabel.isGone = true
// }
// }
// Connection state
device.apply {
@@ -0,0 +1,24 @@
package eu.darken.capod.wear.ui.settings
import android.os.Bundle
import android.view.View
import androidx.fragment.app.viewModels
import dagger.hilt.android.AndroidEntryPoint
import eu.darken.capod.R
import eu.darken.capod.common.BuildConfigWrap
import eu.darken.capod.common.uix.Fragment3
import eu.darken.capod.common.viewbinding.viewBinding
import eu.darken.capod.databinding.SettingsFragmentBinding
@AndroidEntryPoint
class SettingsFragment : Fragment3(R.layout.settings_fragment) {
override val vm: SettingsFragmentVM by viewModels()
override val ui: SettingsFragmentBinding by viewBinding()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
ui.appVersion.text = BuildConfigWrap.VERSION_DESCRIPTION_TINY
super.onViewCreated(view, savedInstanceState)
}
}
@@ -0,0 +1,13 @@
package eu.darken.capod.wear.ui.settings
import androidx.lifecycle.SavedStateHandle
import dagger.hilt.android.lifecycle.HiltViewModel
import eu.darken.capod.common.coroutine.DispatcherProvider
import eu.darken.capod.common.uix.ViewModel3
import javax.inject.Inject
@HiltViewModel
class SettingsFragmentVM @Inject constructor(
@Suppress("UNUSED_PARAMETER") handle: SavedStateHandle,
dispatcherProvider: DispatcherProvider,
) : ViewModel3(dispatcherProvider = dispatcherProvider)
+13 -6
View File
@@ -7,16 +7,23 @@
android:orientation="vertical"
tools:context=".wear.ui.MainActivity">
<fragment
android:id="@+id/nav_host"
android:name="androidx.navigation.fragment.NavHostFragment"
<androidx.wear.widget.SwipeDismissFrameLayout
android:id="@+id/swipe_wrapper"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/nav_graph" />
app:layout_constraintTop_toTopOf="parent">
<fragment
android:id="@+id/nav_host"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
</androidx.wear.widget.SwipeDismissFrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
+4 -14
View File
@@ -1,19 +1,9 @@
<?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="match_parent"
xmlns:tools="http://schemas.android.com/tools">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
style="@style/Widget.MaterialComponents.Toolbar.Primary"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:title="@string/app_name" />
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list"
@@ -21,8 +11,8 @@
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:listitem="@layout/overview_pods_dual_item"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar" />
app:layout_constraintTop_toTopOf="parent"
tools:listitem="@layout/overview_pods_dual_item" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -0,0 +1,23 @@
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/bluetooth_description"
style="@style/TextAppearance.Material3.HeadlineMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?colorPrimary"
android:gravity="center"
android:paddingHorizontal="16dp"
android:paddingVertical="8dp"
android:text="@string/app_name"
android:textColor="?colorOnPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -1,8 +1,8 @@
<?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"
android:id="@+id/card"
android:layout_width="match_parent"
android:layout_marginHorizontal="8dp"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
@@ -1,9 +1,10 @@
<?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"
android:id="@+id/card"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="8dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/container"
@@ -2,9 +2,9 @@
<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"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/container"
@@ -16,8 +16,8 @@
style="@style/TextAppearance.MaterialComponents.Caption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="16dp"
android:text="@string/permission_required_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
@@ -39,9 +39,9 @@
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"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="4dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/permission_label"
@@ -51,10 +51,10 @@
android:id="@+id/privacy_policy"
style="@style/TextAppearance.MaterialComponents.Tooltip"
android:layout_width="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="4dp"
android:layout_marginBottom="8dp"
android:text="@string/settings_privacy_policy_label"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/permission_description" />
@@ -63,10 +63,10 @@
android:id="@+id/grant_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_marginHorizontal="16dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="8dp"
android:text="@string/general_grant_permission_action"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
@@ -1,445 +1,281 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
<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:id="@+id/card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="8dp">
android:layout_margin="8dp"
tools:context=".wear.ui.MainActivity">
<ImageView
android:id="@+id/device_icon"
android:layout_width="24dp"
android:layout_height="24dp"
app:layout_constraintBottom_toTopOf="@+id/name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_airpod_both_24" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/name"
style="@style/TextAppearance.Material3.BodyMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
app:layout_constraintBottom_toTopOf="@+id/status"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/device_icon"
tools:text="Apple AirPods Pro" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/status"
style="@style/TextAppearance.Material3.BodySmall"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
android:gravity="center_horizontal"
android:lines="2"
android:paddingBottom="4dp"
app:layout_constraintBottom_toTopOf="@id/barrier_top"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/name"
tools:text="Music Active, Case Closed" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="status" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/card_content"
android:layout_width="match_parent"
android:id="@+id/pod_left_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingBottom="16dp">
android:layout_marginStart="4dp"
android:layout_marginEnd="4dp"
app:layout_constraintBottom_toTopOf="@id/barrier_bottom"
app:layout_constraintEnd_toStartOf="@id/pod_case_container"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/barrier_top"
app:layout_constraintVertical_bias="0.2">
<ImageView
android:id="@+id/device_icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="16dp"
app:layout_constraintBottom_toBottomOf="@id/name"
android:id="@+id/pod_left_icon"
style="@style/PodInfoItemIcon"
android:layout_marginHorizontal="2dp"
android:contentDescription="@string/pods_dual_left_label"
android:src="@drawable/ic_airpod_left_24"
app:layout_constraintEnd_toStartOf="@+id/pod_left_wear_icon"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/name"
app:srcCompat="@drawable/ic_airpod_both_24" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/name"
style="@style/TextAppearance.MaterialComponents.Body2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginStart="4dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
android:gravity="center_vertical"
app:layout_constraintBottom_toTopOf="@+id/last_seen"
app:layout_constraintEnd_toStartOf="@id/reception"
app:layout_constraintStart_toEndOf="@id/device_icon"
app:layout_constraintTop_toTopOf="parent"
tools:text="Apple AirPods Pro" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/last_seen"
style="@style/TextAppearance.MaterialComponents.Caption"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@id/first_seen"
app:layout_constraintEnd_toEndOf="@id/name"
app:layout_constraintStart_toStartOf="@id/name"
app:layout_constraintTop_toBottomOf="@id/name"
app:layout_goneMarginBottom="8dp"
tools:text="Last seen: 3s ago" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/first_seen"
style="@style/TextAppearance.MaterialComponents.Caption"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="@id/barrier_top"
app:layout_constraintEnd_toEndOf="@id/name"
app:layout_constraintStart_toStartOf="@id/name"
app:layout_constraintTop_toBottomOf="@id/last_seen"
tools:text="First seen: 3s ago" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/reception"
style="@style/TextAppearance.MaterialComponents.Caption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginStart="8dp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="@id/name"
app:layout_constraintEnd_toStartOf="@id/reception_icon"
app:layout_constraintStart_toEndOf="@id/name"
app:layout_constraintTop_toTopOf="@+id/name"
tools:text="Yours (RSSI -61)" />
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/reception_icon"
style="@style/TextAppearance.MaterialComponents.Caption"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginHorizontal="16dp"
android:layout_marginStart="4dp"
android:layout_marginEnd="16dp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="@+id/reception"
android:id="@+id/pod_left_wear_icon"
style="@style/PodInfoItemIcon"
android:layout_marginHorizontal="2dp"
android:src="@drawable/ic_baseline_hearing_24"
app:layout_constraintBottom_toBottomOf="@id/pod_left_icon"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/reception"
app:layout_constraintTop_toTopOf="@+id/reception"
app:srcCompat="@drawable/ic_baseline_settings_input_antenna_24"
tools:text="Yours (RSSI -61)" />
app:layout_constraintStart_toEndOf="@id/pod_left_icon"
app:layout_constraintTop_toTopOf="@id/pod_left_icon" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="top"
app:constraint_referenced_ids="pod_left_container,pod_case_container,pod_right_container" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/pod_left_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="4dp"
app:layout_constraintBottom_toTopOf="@id/barrier_bottom"
app:layout_constraintEnd_toStartOf="@id/pod_case_container"
<ImageView
android:id="@+id/pod_left_battery_icon"
style="@style/PodInfoItemIcon"
android:layout_marginTop="4dp"
android:src="@drawable/ic_baseline_battery_unknown_24"
app:layout_constraintBottom_toTopOf="@id/pod_left_battery_label"
app:layout_constraintEnd_toStartOf="@+id/pod_left_charging_icon"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/barrier_top"
app:layout_constraintVertical_bias="0.0">
app:layout_constraintTop_toBottomOf="@id/pod_left_icon" />
<ImageView
android:id="@+id/pod_left_icon"
style="@style/PodInfoItemIcon"
android:contentDescription="@string/pods_dual_left_label"
android:src="@drawable/ic_airpod_left_24"
app:layout_constraintBottom_toBottomOf="@id/pod_left_label"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/pod_left_label" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/pod_left_label"
style="@style/PodInfoItemText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="@string/pods_dual_left_label"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/pod_left_icon"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/pod_left_battery_icon"
style="@style/PodInfoItemIcon"
android:src="@drawable/ic_baseline_battery_unknown_24"
app:layout_constraintBottom_toBottomOf="@id/pod_left_battery_label"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/pod_left_battery_label" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/pod_left_battery_label"
style="@style/PodInfoItemText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="2dp"
android:text="@string/general_value_not_available_label"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/pod_left_battery_icon"
app:layout_constraintTop_toBottomOf="@id/pod_left_label" />
<ImageView
android:id="@+id/pod_left_charging_icon"
style="@style/PodInfoItemIcon"
android:src="@drawable/ic_baseline_power_24"
app:layout_constraintBottom_toBottomOf="@id/pod_left_charging_label"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/pod_left_charging_label" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/pod_left_charging_label"
style="@style/PodInfoItemText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="2dp"
android:text="@string/pods_charging_label"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/pod_left_charging_icon"
app:layout_constraintTop_toBottomOf="@id/pod_left_battery_label" />
<ImageView
android:id="@+id/pod_left_microphone_icon"
style="@style/PodInfoItemIcon"
android:src="@drawable/ic_baseline_keyboard_voice_24"
app:layout_constraintBottom_toBottomOf="@id/pod_left_microphone_label"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/pod_left_microphone_label" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/pod_left_microphone_label"
style="@style/PodInfoItemText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="2dp"
android:text="@string/pods_microphone_label"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/pod_left_microphone_icon"
app:layout_constraintTop_toBottomOf="@id/pod_left_charging_label" />
<ImageView
android:id="@+id/pod_left_wear_icon"
style="@style/PodInfoItemIcon"
android:src="@drawable/ic_baseline_hearing_24"
app:layout_constraintBottom_toBottomOf="@id/pod_left_wear_label"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/pod_left_wear_label" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/pod_left_wear_label"
style="@style/PodInfoItemText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="2dp"
android:text="@string/pods_inear_label"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/pod_left_wear_icon"
app:layout_constraintTop_toBottomOf="@id/pod_left_microphone_label" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/pod_case_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="4dp"
app:layout_constraintBottom_toTopOf="@id/barrier_bottom"
app:layout_constraintEnd_toStartOf="@id/pod_right_container"
app:layout_constraintStart_toEndOf="@id/pod_left_container"
app:layout_constraintTop_toBottomOf="@id/barrier_top"
app:layout_constraintVertical_bias="0.0">
<ImageView
android:id="@+id/pod_case_icon"
style="@style/PodInfoItemIcon"
android:src="@drawable/ic_airpod_case_24"
app:layout_constraintBottom_toBottomOf="@id/pod_case_label"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/pod_case_label" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/pod_case_label"
style="@style/PodInfoItemText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="@string/pods_case_label"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/pod_case_icon"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/pod_case_battery_icon"
style="@style/PodInfoItemIcon"
android:src="@drawable/ic_baseline_battery_unknown_24"
app:layout_constraintBottom_toBottomOf="@id/pod_case_battery_label"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/pod_case_battery_label" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/pod_case_battery_label"
style="@style/PodInfoItemText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="2dp"
android:text="@string/general_value_not_available_label"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/pod_case_battery_icon"
app:layout_constraintTop_toBottomOf="@id/pod_case_label" />
<ImageView
android:id="@+id/pod_case_charging_icon"
style="@style/PodInfoItemIcon"
android:src="@drawable/ic_baseline_power_24"
app:layout_constraintBottom_toBottomOf="@id/pod_case_charging_label"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/pod_case_charging_label" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/pod_case_charging_label"
style="@style/PodInfoItemText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="2dp"
android:text="@string/pods_charging_label"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/pod_case_charging_icon"
app:layout_constraintTop_toBottomOf="@id/pod_case_battery_label" />
<ImageView
android:id="@+id/pod_case_lid_icon"
style="@style/PodInfoItemIcon"
android:src="@drawable/ic_baseline_grid_view_24"
app:layout_constraintBottom_toBottomOf="@id/pod_case_lid_label"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/pod_case_lid_label" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/pod_case_lid_label"
style="@style/PodInfoItemText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="2dp"
android:text="@string/pods_case_status_closed_label"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/pod_case_lid_icon"
app:layout_constraintTop_toBottomOf="@id/pod_case_charging_label" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/pod_right_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginEnd="16dp"
app:layout_constraintBottom_toTopOf="@id/barrier_bottom"
<ImageView
android:id="@+id/pod_left_charging_icon"
style="@style/PodInfoItemIcon"
android:src="@drawable/ic_baseline_power_24"
app:layout_constraintBottom_toBottomOf="@id/pod_left_battery_icon"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/pod_case_container"
app:layout_constraintTop_toBottomOf="@id/barrier_top"
app:layout_constraintVertical_bias="0.0">
<ImageView
android:id="@+id/pod_right_icon"
style="@style/PodInfoItemIcon"
android:contentDescription="@string/pods_dual_right_label"
android:src="@drawable/ic_airpod_right_24"
app:layout_constraintBottom_toBottomOf="@id/pod_right_label"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/pod_right_label" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/pod_right_label"
style="@style/PodInfoItemText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="@string/pods_dual_right_label"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/pod_right_icon"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/pod_right_battery_icon"
style="@style/PodInfoItemIcon"
android:src="@drawable/ic_baseline_battery_unknown_24"
app:layout_constraintBottom_toBottomOf="@id/pod_right_battery_label"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/pod_right_battery_label" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/pod_right_battery_label"
style="@style/PodInfoItemText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="2dp"
android:text="@string/general_value_not_available_label"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/pod_right_battery_icon"
app:layout_constraintTop_toBottomOf="@id/pod_right_label" />
<ImageView
android:id="@+id/pod_right_charging_icon"
style="@style/PodInfoItemIcon"
android:src="@drawable/ic_baseline_power_24"
app:layout_constraintBottom_toBottomOf="@id/pod_right_charging_label"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/pod_right_charging_label" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/pod_right_charging_label"
style="@style/PodInfoItemText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="2dp"
android:text="@string/pods_charging_label"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/pod_right_charging_icon"
app:layout_constraintTop_toBottomOf="@id/pod_right_battery_label" />
<ImageView
android:id="@+id/pod_right_microphone_icon"
style="@style/PodInfoItemIcon"
android:src="@drawable/ic_baseline_keyboard_voice_24"
app:layout_constraintBottom_toBottomOf="@id/pod_right_microphone_label"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/pod_right_microphone_label" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/pod_right_microphone_label"
style="@style/PodInfoItemText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="2dp"
android:text="@string/pods_microphone_label"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/pod_right_microphone_icon"
app:layout_constraintTop_toBottomOf="@id/pod_right_charging_label" />
<ImageView
android:id="@+id/pod_right_wear_icon"
style="@style/PodInfoItemIcon"
android:src="@drawable/ic_baseline_hearing_24"
app:layout_constraintBottom_toBottomOf="@id/pod_right_wear_label"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/pod_right_wear_label" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/pod_right_wear_label"
style="@style/PodInfoItemText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="2dp"
android:text="@string/pods_inear_label"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/pod_right_wear_icon"
app:layout_constraintTop_toBottomOf="@id/pod_right_microphone_label" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="pod_left_container,pod_case_container,pod_right_container" />
app:layout_constraintStart_toEndOf="@id/pod_left_battery_icon"
app:layout_constraintTop_toTopOf="@id/pod_left_battery_icon" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/status"
style="@style/TextAppearance.MaterialComponents.Body2"
android:id="@+id/pod_left_battery_label"
style="@style/PodInfoItemText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="8dp"
android:gravity="center_vertical"
android:layout_marginTop="4dp"
android:text="@string/general_value_not_available_label"
app:layout_constraintEnd_toEndOf="@id/pod_left_charging_icon"
app:layout_constraintStart_toStartOf="@id/pod_left_battery_icon"
app:layout_constraintTop_toBottomOf="@id/pod_left_battery_icon" />
<ImageView
android:id="@+id/pod_left_microphone_icon"
style="@style/PodInfoItemIcon"
android:layout_marginHorizontal="2dp"
android:layout_marginTop="4dp"
android:src="@drawable/ic_baseline_keyboard_voice_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.85"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/barrier_bottom"
tools:text="Music Active, Case Closed" />
app:layout_constraintTop_toBottomOf="@id/pod_left_battery_label" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/pod_case_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="4dp"
app:layout_constraintBottom_toBottomOf="@id/pod_left_container"
app:layout_constraintEnd_toStartOf="@id/pod_right_container"
app:layout_constraintStart_toEndOf="@id/pod_left_container"
app:layout_constraintTop_toTopOf="@id/pod_left_container"
app:layout_constraintVertical_bias="0.0">
<ImageView
android:id="@+id/pod_case_icon"
style="@style/PodInfoItemIcon"
android:src="@drawable/ic_airpod_case_24"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/pod_case_battery_icon"
style="@style/PodInfoItemIcon"
android:layout_marginTop="4dp"
android:src="@drawable/ic_baseline_battery_unknown_24"
app:layout_constraintBottom_toTopOf="@id/pod_case_battery_label"
app:layout_constraintEnd_toStartOf="@+id/pod_case_charging_icon"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/pod_case_icon" />
<ImageView
android:id="@+id/pod_case_charging_icon"
style="@style/PodInfoItemIcon"
android:src="@drawable/ic_baseline_power_24"
app:layout_constraintBottom_toBottomOf="@id/pod_case_battery_icon"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/pod_case_battery_icon"
app:layout_constraintTop_toTopOf="@id/pod_case_battery_icon" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/pod_case_battery_label"
style="@style/PodInfoItemText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="@string/general_value_not_available_label"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/pod_case_battery_icon" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/pod_right_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginEnd="4dp"
app:layout_constraintBottom_toTopOf="@id/barrier_bottom"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/pod_case_container"
app:layout_constraintTop_toBottomOf="@id/barrier_top"
app:layout_constraintVertical_bias="0.2">
<ImageView
android:id="@+id/pod_right_icon"
style="@style/PodInfoItemIcon"
android:layout_marginHorizontal="2dp"
android:contentDescription="@string/pods_dual_right_label"
android:src="@drawable/ic_airpod_right_24"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toEndOf="@+id/pod_right_wear_icon"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/pod_right_wear_icon"
style="@style/PodInfoItemIcon"
android:layout_marginHorizontal="2dp"
android:src="@drawable/ic_baseline_hearing_24"
app:layout_constraintBottom_toBottomOf="@id/pod_right_icon"
app:layout_constraintEnd_toStartOf="@id/pod_right_icon"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/pod_right_icon" />
<ImageView
android:id="@+id/pod_right_battery_icon"
style="@style/PodInfoItemIcon"
android:layout_marginTop="4dp"
android:src="@drawable/ic_baseline_battery_unknown_24"
app:layout_constraintBottom_toTopOf="@id/pod_right_battery_label"
app:layout_constraintEnd_toStartOf="@+id/pod_right_charging_icon"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/pod_right_icon" />
<ImageView
android:id="@+id/pod_right_charging_icon"
style="@style/PodInfoItemIcon"
android:src="@drawable/ic_baseline_power_24"
app:layout_constraintBottom_toBottomOf="@id/pod_right_battery_icon"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/pod_right_battery_icon"
app:layout_constraintTop_toTopOf="@id/pod_right_battery_icon" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/pod_right_battery_label"
style="@style/PodInfoItemText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="@string/general_value_not_available_label"
app:layout_constraintEnd_toEndOf="@id/pod_right_charging_icon"
app:layout_constraintStart_toStartOf="@id/pod_right_battery_icon"
app:layout_constraintTop_toBottomOf="@id/pod_right_battery_icon" />
<ImageView
android:id="@+id/pod_right_microphone_icon"
style="@style/PodInfoItemIcon"
android:layout_marginHorizontal="2dp"
android:layout_marginTop="4dp"
android:src="@drawable/ic_baseline_keyboard_voice_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.15"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/pod_right_battery_label" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="top"
app:constraint_referenced_ids="last_seen" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/last_seen"
style="@style/TextAppearance.Material3.BodySmall"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="8dp"
android:gravity="center"
app:drawableStartCompat="@drawable/ic_baseline_watch_later_12"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/barrier_bottom"
tools:text="3s ago" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -2,9 +2,9 @@
<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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="8dp">
<androidx.constraintlayout.widget.ConstraintLayout
@@ -2,7 +2,7 @@
<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"
android:layout_marginHorizontal="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
@@ -0,0 +1,24 @@
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.button.MaterialButton
android:id="@+id/settings_button"
style="@style/Widget.Material3.Button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="48dp"
android:gravity="center"
android:padding="16dp"
android:text="@string/settings_label"
app:icon="@drawable/ic_baseline_settings_24"
app:iconGravity="textStart"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView 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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?colorPrimary"
android:gravity="center"
android:orientation="vertical"
android:paddingHorizontal="8dp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_baseline_settings_24"
app:tint="?colorOnPrimary" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/app_version"
style="@style/TextAppearance.Material3.LabelMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:maxLines="1"
android:textColor="?colorOnPrimary"
tools:text="v1.0.0" />
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
@@ -17,7 +17,7 @@
<fragment
android:id="@+id/settingsFragment"
android:name="eu.darken.capod.main.ui.settings.SettingsFragment"
android:name="eu.darken.capod.wear.ui.settings.SettingsFragment"
android:label="SettingsFragment"
tools:layout="@layout/settings_fragment" />
@@ -1,32 +0,0 @@
<resources>
<style name="AppTheme" parent="Theme.Material3.Dark.NoActionBar">
<item name="colorPrimary">@color/md_theme_dark_primary</item>
<item name="colorOnPrimary">@color/md_theme_dark_onPrimary</item>
<item name="colorPrimaryContainer">@color/md_theme_dark_primaryContainer</item>
<item name="colorOnPrimaryContainer">@color/md_theme_dark_onPrimaryContainer</item>
<item name="colorSecondary">@color/md_theme_dark_secondary</item>
<item name="colorOnSecondary">@color/md_theme_dark_onSecondary</item>
<item name="colorSecondaryContainer">@color/md_theme_dark_secondaryContainer</item>
<item name="colorOnSecondaryContainer">@color/md_theme_dark_onSecondaryContainer</item>
<item name="colorTertiary">@color/md_theme_dark_tertiary</item>
<item name="colorOnTertiary">@color/md_theme_dark_onTertiary</item>
<item name="colorTertiaryContainer">@color/md_theme_dark_tertiaryContainer</item>
<item name="colorOnTertiaryContainer">@color/md_theme_dark_onTertiaryContainer</item>
<item name="colorError">@color/md_theme_dark_error</item>
<item name="colorErrorContainer">@color/md_theme_dark_errorContainer</item>
<item name="colorOnError">@color/md_theme_dark_onError</item>
<item name="colorOnErrorContainer">@color/md_theme_dark_onErrorContainer</item>
<item name="android:colorBackground">@color/md_theme_dark_background</item>
<item name="colorOnBackground">@color/md_theme_dark_onBackground</item>
<item name="colorSurface">@color/md_theme_dark_surface</item>
<item name="colorOnSurface">@color/md_theme_dark_onSurface</item>
<item name="colorSurfaceVariant">@color/md_theme_dark_surfaceVariant</item>
<item name="colorOnSurfaceVariant">@color/md_theme_dark_onSurfaceVariant</item>
<item name="colorOutline">@color/md_theme_dark_outline</item>
<item name="colorOnSurfaceInverse">@color/md_theme_dark_inverseOnSurface</item>
<item name="colorSurfaceInverse">@color/md_theme_dark_inverseSurface</item>
<item name="colorPrimaryInverse">@color/md_theme_dark_primaryInverse</item>
</style>
</resources>
+7 -34
View File
@@ -1,36 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="md_theme_light_primary">#3F7AFF</color>
<color name="md_theme_light_onPrimary">#FFFFFF</color>
<color name="md_theme_light_primaryContainer">#DAE2FF</color>
<color name="md_theme_light_onPrimaryContainer">#00174B</color>
<color name="md_theme_light_secondary">#715C00</color>
<color name="md_theme_light_onSecondary">#FFFFFF</color>
<color name="md_theme_light_secondaryContainer">#FFE16C</color>
<color name="md_theme_light_onSecondaryContainer">#231B00</color>
<color name="md_theme_light_tertiary">#006D39</color>
<color name="md_theme_light_onTertiary">#FFFFFF</color>
<color name="md_theme_light_tertiaryContainer">#5CFFA0</color>
<color name="md_theme_light_onTertiaryContainer">#00210D</color>
<color name="md_theme_light_error">#BA1B1B</color>
<color name="md_theme_light_errorContainer">#FFDAD4</color>
<color name="md_theme_light_onError">#FFFFFF</color>
<color name="md_theme_light_onErrorContainer">#410001</color>
<color name="md_theme_light_background">#FEFBFF</color>
<color name="md_theme_light_onBackground">#1B1B1F</color>
<color name="md_theme_light_surface">#FEFBFF</color>
<color name="md_theme_light_onSurface">#1B1B1F</color>
<color name="md_theme_light_surfaceVariant">#E2E2EC</color>
<color name="md_theme_light_onSurfaceVariant">#44464E</color>
<color name="md_theme_light_outline">#75767F</color>
<color name="md_theme_light_inverseOnSurface">#F2F0F5</color>
<color name="md_theme_light_inverseSurface">#303033</color>
<color name="md_theme_light_primaryInverse">#B1C5FF</color>
<color name="md_theme_dark_primary">#3F7AFF</color>
<color name="md_theme_dark_onPrimary">#002A78</color>
<color name="md_theme_dark_onPrimary">#FEFBFF</color>
<color name="md_theme_dark_primaryContainer">#003EA7</color>
<color name="md_theme_dark_onPrimaryContainer">#DAE2FF</color>
<color name="md_theme_dark_onPrimaryContainer">#FEFBFF</color>
<color name="md_theme_dark_secondary">#E9C426</color>
<color name="md_theme_dark_onSecondary">#3B2F00</color>
<color name="md_theme_dark_secondaryContainer">#564500</color>
@@ -43,15 +16,15 @@
<color name="md_theme_dark_errorContainer">#930006</color>
<color name="md_theme_dark_onError">#680003</color>
<color name="md_theme_dark_onErrorContainer">#FFDAD4</color>
<color name="md_theme_dark_background">#1B1B1F</color>
<color name="md_theme_dark_onBackground">#E3E1E6</color>
<color name="md_theme_dark_surface">#1B1B1F</color>
<color name="md_theme_dark_onSurface">#E3E1E6</color>
<color name="md_theme_dark_background">#000000</color>
<color name="md_theme_dark_onBackground">#FEFBFF</color>
<color name="md_theme_dark_surface">#000000</color>
<color name="md_theme_dark_onSurface">#FEFBFF</color>
<color name="md_theme_dark_surfaceVariant">#44464E</color>
<color name="md_theme_dark_onSurfaceVariant">#C6C6D0</color>
<color name="md_theme_dark_outline">#8F909A</color>
<color name="md_theme_dark_inverseOnSurface">#1B1B1F</color>
<color name="md_theme_dark_inverseSurface">#E3E1E6</color>
<color name="md_theme_dark_inverseSurface">#FEFBFF</color>
<color name="md_theme_dark_primaryInverse">#0054D9</color>
<color name="seed">#3F7AFF</color>
+2 -2
View File
@@ -1,4 +1,4 @@
<resources>
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
<string name="wear_service_label">CAPod for WearOS</string>
<string name="wear_service_description">View details about your AirPood devices on your WearOS device.</string>
<string name="wear_service_description">Details about AirPods</string>
</resources>
+27 -43
View File
@@ -1,48 +1,32 @@
<resources>
<style name="AppTheme" parent="Theme.Material3.Light.NoActionBar">
<item name="colorPrimary">@color/md_theme_light_primary</item>
<item name="colorOnPrimary">@color/md_theme_light_onPrimary</item>
<item name="colorPrimaryContainer">@color/md_theme_light_primaryContainer</item>
<item name="colorOnPrimaryContainer">@color/md_theme_light_onPrimaryContainer</item>
<item name="colorSecondary">@color/md_theme_light_secondary</item>
<item name="colorOnSecondary">@color/md_theme_light_onSecondary</item>
<item name="colorSecondaryContainer">@color/md_theme_light_secondaryContainer</item>
<item name="colorOnSecondaryContainer">@color/md_theme_light_onSecondaryContainer</item>
<item name="colorTertiary">@color/md_theme_light_tertiary</item>
<item name="colorOnTertiary">@color/md_theme_light_onTertiary</item>
<item name="colorTertiaryContainer">@color/md_theme_light_tertiaryContainer</item>
<item name="colorOnTertiaryContainer">@color/md_theme_light_onTertiaryContainer</item>
<item name="colorError">@color/md_theme_light_error</item>
<item name="colorErrorContainer">@color/md_theme_light_errorContainer</item>
<item name="colorOnError">@color/md_theme_light_onError</item>
<item name="colorOnErrorContainer">@color/md_theme_light_onErrorContainer</item>
<item name="android:colorBackground">@color/md_theme_light_background</item>
<item name="colorOnBackground">@color/md_theme_light_onBackground</item>
<item name="colorSurface">@color/md_theme_light_surface</item>
<item name="colorOnSurface">@color/md_theme_light_onSurface</item>
<item name="colorSurfaceVariant">@color/md_theme_light_surfaceVariant</item>
<item name="colorOnSurfaceVariant">@color/md_theme_light_onSurfaceVariant</item>
<item name="colorOutline">@color/md_theme_light_outline</item>
<item name="colorOnSurfaceInverse">@color/md_theme_light_inverseOnSurface</item>
<item name="colorSurfaceInverse">@color/md_theme_light_inverseSurface</item>
<item name="colorPrimaryInverse">@color/md_theme_light_primaryInverse</item>
</style>
<style name="AppThemeFloating" parent="AppTheme">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowIsFloating">true</item>
<item name="android:backgroundDimEnabled">true</item>
</style>
<style name="AppThemeSplash" parent="Theme.SplashScreen">
<item name="windowSplashScreenBackground">#3f7aff</item>
<item name="windowSplashScreenAnimatedIcon">@drawable/splash_screen</item>
<item name="postSplashScreenTheme">@style/AppTheme</item>
<style name="AppTheme" parent="Theme.Material3.Dark.NoActionBar">
<item name="colorPrimary">@color/md_theme_dark_primary</item>
<item name="colorOnPrimary">@color/md_theme_dark_onPrimary</item>
<item name="colorPrimaryContainer">@color/md_theme_dark_primaryContainer</item>
<item name="colorOnPrimaryContainer">@color/md_theme_dark_onPrimaryContainer</item>
<item name="colorSecondary">@color/md_theme_dark_secondary</item>
<item name="colorOnSecondary">@color/md_theme_dark_onSecondary</item>
<item name="colorSecondaryContainer">@color/md_theme_dark_secondaryContainer</item>
<item name="colorOnSecondaryContainer">@color/md_theme_dark_onSecondaryContainer</item>
<item name="colorTertiary">@color/md_theme_dark_tertiary</item>
<item name="colorOnTertiary">@color/md_theme_dark_onTertiary</item>
<item name="colorTertiaryContainer">@color/md_theme_dark_tertiaryContainer</item>
<item name="colorOnTertiaryContainer">@color/md_theme_dark_onTertiaryContainer</item>
<item name="colorError">@color/md_theme_dark_error</item>
<item name="colorErrorContainer">@color/md_theme_dark_errorContainer</item>
<item name="colorOnError">@color/md_theme_dark_onError</item>
<item name="colorOnErrorContainer">@color/md_theme_dark_onErrorContainer</item>
<item name="android:colorBackground">@color/md_theme_dark_background</item>
<item name="colorOnBackground">@color/md_theme_dark_onBackground</item>
<item name="colorSurface">@color/md_theme_dark_surface</item>
<item name="colorOnSurface">@color/md_theme_dark_onSurface</item>
<item name="colorSurfaceVariant">@color/md_theme_dark_surfaceVariant</item>
<item name="colorOnSurfaceVariant">@color/md_theme_dark_onSurfaceVariant</item>
<item name="colorOutline">@color/md_theme_dark_outline</item>
<item name="colorOnSurfaceInverse">@color/md_theme_dark_inverseOnSurface</item>
<item name="colorSurfaceInverse">@color/md_theme_dark_inverseSurface</item>
<item name="colorPrimaryInverse">@color/md_theme_dark_primaryInverse</item>
</style>
</resources>
+5 -18
View File
@@ -125,16 +125,6 @@ android {
useJUnitPlatform()
}
}
sourceSets {
getByName("test") {
java.srcDir("$projectDir/src/testShared/java")
}
getByName("androidTest") {
java.srcDir("$projectDir/src/testShared/java")
assets.srcDirs(files("$projectDir/schemas"))
}
}
}
dependencies {
@@ -153,18 +143,15 @@ dependencies {
addBaseAndroid()
addBaseAndroidUi()
implementation("androidx.core:core-splashscreen:1.0.0-alpha02")
addNavigation()
implementation("androidx.navigation:navigation-fragment-ktx:2.5.0")
implementation("androidx.navigation:navigation-ui-ktx:2.5.0")
addBaseWorkManager()
// Debugging
implementation("com.bugsnag:bugsnag-android:5.9.2")
implementation("com.getkeepsafe.relinker:relinker:1.4.3")
addTesting()
implementation("com.bugsnag:bugsnag-android:5.9.2")
implementation("com.getkeepsafe.relinker:relinker:1.4.3")
"gplayImplementation"("com.android.billingclient:billing:4.0.0")
}

Some files were not shown because too many files have changed in this diff Show More