diff --git a/app/src/main/java/eu/darken/capod/reaction/core/popup/PopUpReaction.kt b/app/src/main/java/eu/darken/capod/reaction/core/popup/PopUpReaction.kt index 88d4a024..cee6ec66 100644 --- a/app/src/main/java/eu/darken/capod/reaction/core/popup/PopUpReaction.kt +++ b/app/src/main/java/eu/darken/capod/reaction/core/popup/PopUpReaction.kt @@ -33,7 +33,7 @@ class PopUpReaction @Inject constructor( private val bluetoothManager: BluetoothManager2, ) { - private val caseCoolDowns = mutableMapOf() + private val caseCoolDowns = mutableMapOf() private fun monitorCase(): Flow = reactionSettings.showPopUpOnCaseOpen.flow .flatMapLatest { isEnabled -> @@ -56,10 +56,10 @@ class PopUpReaction @Inject constructor( } log(TAG, VERBOSE) { "previous-id=${previous?.identifier}, current-id=${current.identifier}" } - val isSameDeviceWithCaseNowOpen = - previous?.identifier == current.identifier && previous.caseLidState != current.caseLidState - val isNewDeviceWithJustOpenedCase = - previous?.identifier != current.identifier && previous?.caseLidState != current.caseLidState + val isSameDeviceOrProfile = previous?.identifier == current.identifier || + (previous?.meta?.profile?.id != null && previous.meta.profile?.id == current.meta.profile?.id) + val isSameDeviceWithCaseNowOpen = isSameDeviceOrProfile && previous?.caseLidState != current.caseLidState + val isNewDeviceWithJustOpenedCase = !isSameDeviceOrProfile && previous?.caseLidState != current.caseLidState if (!isSameDeviceWithCaseNowOpen && !isNewDeviceWithJustOpenedCase) { return@mapNotNull null @@ -69,43 +69,46 @@ class PopUpReaction @Inject constructor( throttleCasePopUps(current) } - private fun throttleCasePopUps(current: DualApplePods): Event? = when { - current.caseLidState == DualApplePods.LidState.OPEN -> { - log(TAG, INFO) { "Show popup" } + private fun throttleCasePopUps(current: DualApplePods): Event? { + val cooldownKey = current.meta.profile?.id ?: current.identifier.toString() + return when { + current.caseLidState == DualApplePods.LidState.OPEN -> { + log(TAG, INFO) { "Show popup" } - val now = Instant.now() - val lastShown = caseCoolDowns[current.identifier] ?: Instant.MIN - val sinceLastPop = Duration.between(lastShown, now) - log(TAG) { "Time since last case popup: $sinceLastPop" } + val now = Instant.now() + val lastShown = caseCoolDowns[cooldownKey] ?: Instant.MIN + val sinceLastPop = Duration.between(lastShown, now) + log(TAG) { "Time since last case popup: $sinceLastPop" } - if (sinceLastPop >= Duration.ofSeconds(10)) { - caseCoolDowns[current.identifier] = Instant.now() - Event.PopupShow(device = current) - } else { - log(TAG, INFO) { "Case popup is still on cooldown: $sinceLastPop" } - null - } - } - - current.caseLidState != DualApplePods.LidState.OPEN -> { - when (current.caseLidState) { - DualApplePods.LidState.CLOSED -> { - log(TAG, INFO) { "Lid was actively closed, resetting cooldown." } - caseCoolDowns.remove(current.identifier) - } - - else -> { - log(TAG, WARN) { "Lid was was not actively closed, refreshing cooldown." } - caseCoolDowns[current.identifier] = Instant.now() + if (sinceLastPop >= Duration.ofSeconds(10)) { + caseCoolDowns[cooldownKey] = Instant.now() + Event.PopupShow(device = current) + } else { + log(TAG, INFO) { "Case popup is still on cooldown: $sinceLastPop" } + null } } - log(TAG, INFO) { "Hide popup" } + current.caseLidState != DualApplePods.LidState.OPEN -> { + when (current.caseLidState) { + DualApplePods.LidState.CLOSED -> { + log(TAG, INFO) { "Lid was actively closed, resetting cooldown." } + caseCoolDowns.remove(cooldownKey) + } - Event.PopupHide() + else -> { + log(TAG, WARN) { "Lid was was not actively closed, refreshing cooldown." } + caseCoolDowns[cooldownKey] = Instant.now() + } + } + + log(TAG, INFO) { "Hide popup" } + + Event.PopupHide() + } + + else -> null } - - else -> null } private val connectionCoolDowns = mutableMapOf() diff --git a/app/src/main/java/eu/darken/capod/reaction/ui/popup/PopUpContent.kt b/app/src/main/java/eu/darken/capod/reaction/ui/popup/PopUpContent.kt index fe3c25af..825a9f1b 100644 --- a/app/src/main/java/eu/darken/capod/reaction/ui/popup/PopUpContent.kt +++ b/app/src/main/java/eu/darken/capod/reaction/ui/popup/PopUpContent.kt @@ -2,6 +2,7 @@ package eu.darken.capod.reaction.ui.popup import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -49,65 +50,67 @@ fun PopUpContent( ) { val context = LocalContext.current - Card( - modifier = modifier.fillMaxWidth(), - shape = RoundedCornerShape(24.dp), - elevation = CardDefaults.cardElevation(defaultElevation = 8.dp), - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 20.dp) - .padding(top = 20.dp, bottom = 16.dp), - horizontalAlignment = Alignment.CenterHorizontally, + Box(modifier = modifier.padding(start = 12.dp, top = 12.dp, end = 12.dp, bottom = 16.dp)) { + Card( + modifier = Modifier.fillMaxWidth(), + shape = RoundedCornerShape(24.dp), + elevation = CardDefaults.cardElevation(defaultElevation = 8.dp), ) { - // Header: label + signal quality - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.Center, + Column( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 20.dp) + .padding(top = 20.dp, bottom = 16.dp), + horizontalAlignment = Alignment.CenterHorizontally, ) { - Text( - text = device.getLabel(context), - style = MaterialTheme.typography.titleLarge, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - modifier = Modifier.weight(1f, fill = false), - ) - - val signalText = device.getSignalQuality(context) - if (signalText.isNotBlank()) { - Spacer(modifier = Modifier.width(4.dp)) - Icon( - imageVector = Icons.TwoTone.SignalCellularAlt, - contentDescription = null, - modifier = Modifier.size(12.dp), - ) - Spacer(modifier = Modifier.width(4.dp)) + // Header: label + signal quality + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.Center, + ) { Text( - text = signalText, - style = MaterialTheme.typography.labelSmall, + text = device.getLabel(context), + style = MaterialTheme.typography.titleLarge, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + modifier = Modifier.weight(1f, fill = false), ) + + val signalText = device.getSignalQuality(context) + if (signalText.isNotBlank()) { + Spacer(modifier = Modifier.width(4.dp)) + Icon( + imageVector = Icons.TwoTone.SignalCellularAlt, + contentDescription = null, + modifier = Modifier.size(12.dp), + ) + Spacer(modifier = Modifier.width(4.dp)) + Text( + text = signalText, + style = MaterialTheme.typography.labelSmall, + ) + } } - } - Spacer(modifier = Modifier.height(16.dp)) + Spacer(modifier = Modifier.height(16.dp)) - // Device-specific content - when (device) { - is DualPodDevice -> DualPodContent(device) - is SinglePodDevice -> SinglePodContent(device) - } + // Device-specific content + when (device) { + is DualPodDevice -> DualPodContent(device) + is SinglePodDevice -> SinglePodContent(device) + } - Spacer(modifier = Modifier.height(20.dp)) + Spacer(modifier = Modifier.height(20.dp)) - // Close button - Button( - onClick = onClose, - modifier = Modifier.fillMaxWidth(), - shape = RoundedCornerShape(24.dp), - ) { - Text(text = stringResource(R.string.general_close_action)) + // Close button + Button( + onClick = onClose, + modifier = Modifier.fillMaxWidth(), + shape = RoundedCornerShape(24.dp), + ) { + Text(text = stringResource(R.string.general_close_action)) + } } } } diff --git a/app/src/main/java/eu/darken/capod/reaction/ui/popup/PopUpWindow.kt b/app/src/main/java/eu/darken/capod/reaction/ui/popup/PopUpWindow.kt index 9bf8a824..7453dbfc 100644 --- a/app/src/main/java/eu/darken/capod/reaction/ui/popup/PopUpWindow.kt +++ b/app/src/main/java/eu/darken/capod/reaction/ui/popup/PopUpWindow.kt @@ -42,6 +42,7 @@ class PopUpWindow @Inject constructor( val dm = appContext.resources.displayMetrics val margin = (24 * dm.density).toInt() width = minOf(dm.widthPixels - margin * 2, (400 * dm.density).toInt()) + y = (8 * dm.density).toInt() } private var composeView: ComposeView? = null