diff --git a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/activities/NoiseControlWidgetConfigurationActivity.kt b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/activities/NoiseControlWidgetConfigurationActivity.kt index 1cfb3ba48..b6e91076f 100644 --- a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/activities/NoiseControlWidgetConfigurationActivity.kt +++ b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/activities/NoiseControlWidgetConfigurationActivity.kt @@ -147,7 +147,7 @@ class NoiseControlWidgetConfigurationActivity: ComponentActivity() { ) } ?: run { Text( - text = "Service not available. Please ensure LibrePods is running and try again.", + text = stringResource(R.string.widget_service_not_available), style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurface ) @@ -179,7 +179,7 @@ private fun WidgetDevicePickerContent( Spacer(modifier = Modifier.size(topPadding)) if (devices.isEmpty()) { Text( - text = "No devices found. Please ensure a compatible device is paired with your phone and try again.", + text = stringResource(R.string.widget_no_devices_found), style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurface ) @@ -188,7 +188,7 @@ private fun WidgetDevicePickerContent( onClick = onCancelClicked ) { Text( - text = "Cancel", + text = stringResource(R.string.cancel), style = MaterialTheme.typography.bodyMedium, ) } @@ -232,7 +232,7 @@ private fun WidgetDevicePickerContent( enabled = pickedDevice != null ) { Text( - text = "Done", + text = stringResource(R.string.done), style = MaterialTheme.typography.bodyMedium, ) } diff --git a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/components/apple/BatteryView.kt b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/components/apple/BatteryView.kt index 6da1a3210..b48aa9849 100644 --- a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/components/apple/BatteryView.kt +++ b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/components/apple/BatteryView.kt @@ -81,7 +81,7 @@ fun BatteryView( ) { Image( bitmap = ImageBitmap.imageResource(primaryImageRes), - contentDescription = "Headset", + contentDescription = stringResource(R.string.headset), modifier = Modifier.fillMaxWidth() ) diff --git a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/components/apple/PressAndHoldSettings.kt b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/components/apple/PressAndHoldSettings.kt index 1a78f2e66..06cb0c24d 100644 --- a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/components/apple/PressAndHoldSettings.kt +++ b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/components/apple/PressAndHoldSettings.kt @@ -34,13 +34,13 @@ fun PressAndHoldSettings( ) { val leftActionText = when (leftAction) { StemAction.CYCLE_listening_mode_MODES -> stringResource(R.string.listening_mode) - StemAction.DIGITAL_ASSISTANT -> "Digital Assistant" + StemAction.DIGITAL_ASSISTANT -> stringResource(R.string.digital_assistant) else -> "INVALID!!" } val rightActionText = when (rightAction) { StemAction.CYCLE_listening_mode_MODES -> stringResource(R.string.listening_mode) - StemAction.DIGITAL_ASSISTANT -> "Digital Assistant" + StemAction.DIGITAL_ASSISTANT -> stringResource(R.string.digital_assistant) else -> "INVALID!!" } diff --git a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/components/primitives/StyledConfirmationDialog.kt b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/components/primitives/StyledConfirmationDialog.kt index f162eec2e..12cc3f50a 100644 --- a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/components/primitives/StyledConfirmationDialog.kt +++ b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/components/primitives/StyledConfirmationDialog.kt @@ -48,6 +48,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.luminance +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.window.DialogProperties @@ -57,6 +58,7 @@ import com.kyant.backdrop.drawBackdrop import com.kyant.backdrop.effects.blur import com.kyant.backdrop.effects.lens import com.kyant.backdrop.effects.vibrancy +import me.kavishdevar.librepods.R import me.kavishdevar.librepods.data.app.DesignSystem import me.kavishdevar.librepods.presentation.design.LocalDesign @@ -66,8 +68,8 @@ fun StyledConfirmationDialog( showDialog: MutableState, title: String, message: String, - confirmText: String = "Enable", - dismissText: String = "Cancel", + confirmText: String = stringResource(R.string.enable), + dismissText: String = stringResource(R.string.cancel), onConfirm: () -> Unit, onDismiss: () -> Unit = { showDialog.value = false }, backdrop: LayerBackdrop, diff --git a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/components/primitives/StyledInputField.kt b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/components/primitives/StyledInputField.kt index 9e7da9000..4f14d53d7 100644 --- a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/components/primitives/StyledInputField.kt +++ b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/components/primitives/StyledInputField.kt @@ -35,8 +35,10 @@ import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import me.kavishdevar.librepods.R import me.kavishdevar.librepods.data.app.DesignSystem import me.kavishdevar.librepods.presentation.design.LocalDesign import me.kavishdevar.librepods.presentation.icons.LocalIcons @@ -148,7 +150,7 @@ fun StyledInputField( ) { Icon( imageVector = LocalIcons.current.CloseCircle, - contentDescription = "Clear text", + contentDescription = stringResource(R.string.clear_text), tint = MaterialTheme.colorScheme.onBackground.copy(alpha = 0.6f), modifier = Modifier.size(16.dp) ) diff --git a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/components/primitives/StyledScaffold.kt b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/components/primitives/StyledScaffold.kt index 2ac5afc68..867b9d19d 100644 --- a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/components/primitives/StyledScaffold.kt +++ b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/components/primitives/StyledScaffold.kt @@ -77,6 +77,7 @@ import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.LocalWindowInfo +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.Dp @@ -86,6 +87,7 @@ import dev.chrisbanes.haze.HazeInput import dev.chrisbanes.haze.blur.hazeBlur import dev.chrisbanes.haze.hazeSource import dev.chrisbanes.haze.rememberHazeState +import me.kavishdevar.librepods.R import me.kavishdevar.librepods.data.app.ColorStyle import me.kavishdevar.librepods.data.app.DesignSystem import me.kavishdevar.librepods.presentation.design.LocalDesign @@ -343,7 +345,7 @@ fun StyledScaffold( ) { Icon( imageVector = LocalIcons.current.ArrowBack, - contentDescription = "Back", + contentDescription = stringResource(R.string.back), modifier = Modifier.size(16.dp), tint = MaterialTheme.colorScheme.onBackground, ) diff --git a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/DeviceListScreen.kt b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/DeviceListScreen.kt index e4e78b4ff..2d40686fb 100644 --- a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/DeviceListScreen.kt +++ b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/DeviceListScreen.kt @@ -110,7 +110,7 @@ fun DeviceListScreen( ) { Icon( imageVector = Icons.Outlined.Settings, - contentDescription = "settings", + contentDescription = stringResource(R.string.settings), modifier = Modifier.size(IconButtonDefaults.mediumIconSize), ) } @@ -121,7 +121,7 @@ fun DeviceListScreen( ) { Icon( imageVector = LocalIcons.current.Settings, - contentDescription = "Settings", + contentDescription = stringResource(R.string.settings), tint = MaterialTheme.colorScheme.onBackground, modifier = Modifier.size(IconButtonDefaults.mediumIconSize) ) diff --git a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/apple/HeadTrackingScreen.kt b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/apple/HeadTrackingScreen.kt index 61389e25f..da6c1376b 100644 --- a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/apple/HeadTrackingScreen.kt +++ b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/apple/HeadTrackingScreen.kt @@ -139,7 +139,7 @@ fun HeadTrackingScreen( ) { Icon( imageVector = if (state.headTrackingState == BuddyState.ACTIVE) MaterialIcons.Pause else Icons.Default.PlayArrow, - contentDescription = "Play/Pause", + contentDescription = stringResource(R.string.play_pause), modifier = Modifier.size(IconButtonDefaults.mediumIconSize), ) } @@ -151,7 +151,7 @@ fun HeadTrackingScreen( ) { Icon( imageVector = if (state.headTrackingState == BuddyState.ACTIVE) LocalIcons.current.Pause else LocalIcons.current.Play, - contentDescription = "Play/Pause", + contentDescription = stringResource(R.string.play_pause), modifier = Modifier.size(16.dp), tint = MaterialTheme.colorScheme.onBackground ) @@ -194,7 +194,7 @@ fun HeadTrackingScreen( } StyledToggle( - label = "Head Gestures", + label = stringResource(R.string.head_gestures), checked = settings.headGesturesEnabled, onCheckedChange = { viewModel.setHeadGesturesEnabled(it) }, enabled = uiState.isPremium || settings.headGesturesEnabled, @@ -204,7 +204,7 @@ fun HeadTrackingScreen( Spacer(modifier = Modifier.height(16.dp)) Text( - "Velocity", + stringResource(R.string.velocity), style = MaterialTheme.typography.labelSmallEmphasized, modifier = Modifier.padding(vertical = 8.dp) ) @@ -224,11 +224,13 @@ fun HeadTrackingScreen( } } val gestureTextValue = stringResource(R.string.shake_your_head_or_nod) + val yesDetectedText = stringResource(R.string.head_gesture_yes_detected) + val noDetectedText = stringResource(R.string.head_gesture_no_detected) StyledButton( onClick = { gestureText = gestureTextValue coroutineScope.launch { - viewModel.detectHeadGestures { gestureText = if (it) "\"Yes\" gesture detected." else "\"No\" gesture detected." } + viewModel.detectHeadGestures { gestureText = if (it) yesDetectedText else noDetectedText } } }, backdrop = backdrop, @@ -238,7 +240,7 @@ fun HeadTrackingScreen( materialButtonStyle = MaterialButtonStyle.Outlined ) { Text( - "Test Head Gestures", + stringResource(R.string.test_head_gestures), style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.primary ) @@ -340,6 +342,9 @@ private fun Plot() { .padding(16.dp) ) { val onBackground = MaterialTheme.colorScheme.onBackground + // the Canvas draw scope is not composable, so resolve the legend labels here + val horizontalLabel = stringResource(R.string.horizontal) + val verticalLabel = stringResource(R.string.vertical) Canvas( modifier = Modifier.fillMaxSize() ) { @@ -422,7 +427,7 @@ private fun Plot() { textSize = 12.sp.toPx() textAlign = Paint.Align.LEFT } - drawText("Horizontal", width - 140.dp.toPx(), textOffsetY, paint) + drawText(horizontalLabel, width - 140.dp.toPx(), textOffsetY, paint) } drawCircle(verticalColor, 5.dp.toPx(), Offset(width - 70.dp.toPx(), legendY)) @@ -432,7 +437,7 @@ private fun Plot() { textSize = 12.sp.toPx() textAlign = Paint.Align.LEFT } - drawText("Vertical", width - 60.dp.toPx(), textOffsetY, paint) + drawText(verticalLabel, width - 60.dp.toPx(), textOffsetY, paint) } } } diff --git a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/apple/HearingAidScreen.kt b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/apple/HearingAidScreen.kt index 8259bdb71..82a30dae2 100644 --- a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/apple/HearingAidScreen.kt +++ b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/apple/HearingAidScreen.kt @@ -189,10 +189,10 @@ fun HearingAidScreen( StyledConfirmationDialog( showDialog = showDialog, - title = "Enable Hearing Aid", - message = "Enabling Hearing Aid will disable Headphone Accommodation and Customized Transparency Mode.", - confirmText = "Enable", - dismissText = "Cancel", + title = stringResource(R.string.enable_hearing_aid), + message = stringResource(R.string.enable_hearing_aid_description), + confirmText = stringResource(R.string.enable), + dismissText = stringResource(R.string.cancel), onConfirm = { showDialog.value = false val enrolled = state.controlStates[ControlCommandIdentifier.HEARING_AID]?.getOrNull(0) == 0x01.toByte() diff --git a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/apple/HeartRateScreen.kt b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/apple/HeartRateScreen.kt index 5bc3ce414..41711d378 100644 --- a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/apple/HeartRateScreen.kt +++ b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/apple/HeartRateScreen.kt @@ -124,7 +124,7 @@ fun HeartRateScreen( ) { Icon( imageVector = it, - contentDescription = "Start/Stop", + contentDescription = stringResource(R.string.start_stop), modifier = Modifier.size(IconButtonDefaults.mediumIconSize), ) } @@ -139,7 +139,7 @@ fun HeartRateScreen( ) { Icon( imageVector = it, - contentDescription = "Start/Stop", + contentDescription = stringResource(R.string.start_stop), modifier = Modifier.size(16.dp), tint = MaterialTheme.colorScheme.onBackground ) @@ -257,7 +257,7 @@ fun HeartRateScreen( ) { Icon( imageVector = LocalIcons.current.VitalSigns, - contentDescription = "vital signs", + contentDescription = stringResource(R.string.heart_rate), modifier = Modifier.size(24.dp), tint = MaterialTheme.colorScheme.onPrimaryContainer ) @@ -287,7 +287,7 @@ fun HeartRateScreen( ) { Icon( imageVector = LocalIcons.current.VitalSigns, - contentDescription = "vital signs", + contentDescription = stringResource(R.string.heart_rate), modifier = Modifier.size(24.dp), tint = MaterialTheme.colorScheme.onSurface ) diff --git a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/apple/RecordingScreen.kt b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/apple/RecordingScreen.kt index e4fd0fdd7..de0af292b 100644 --- a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/apple/RecordingScreen.kt +++ b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/apple/RecordingScreen.kt @@ -254,8 +254,8 @@ fun RecordingScreen( ) { Text( text = if (state.recordingState.isRecording) { - "Stop Recording" - } else "Start Recording", + stringResource(R.string.stop_recording) + } else stringResource(R.string.start_recording), style = MaterialTheme.typography.labelMedium ) } diff --git a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/apple/TransparencySettingsScreen.kt b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/apple/TransparencySettingsScreen.kt index ec1bb6b8c..6dc148a99 100644 --- a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/apple/TransparencySettingsScreen.kt +++ b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/apple/TransparencySettingsScreen.kt @@ -303,8 +303,11 @@ fun TransparencySettingsScreen( newEQ[i] = eqValue.floatValue eq.value = newEQ }, + // weight, not fillMaxWidth(0.9f): the band label after the slider + // only got the leftover width and was clipped in wider scripts modifier = Modifier - .fillMaxWidth(0.9f) + .weight(1f) + .padding(horizontal = 8.dp) .height(36.dp), colors = SliderDefaults.colors( thumbColor = thumbColor, diff --git a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/onboarding/OnboardingScreen.kt b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/onboarding/OnboardingScreen.kt index f7a3a8734..a0acb0641 100644 --- a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/onboarding/OnboardingScreen.kt +++ b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/onboarding/OnboardingScreen.kt @@ -171,7 +171,7 @@ fun OnboardingScreen( ) { Icon( Icons.AutoMirrored.Default.ArrowForward, - contentDescription = "forward", + contentDescription = stringResource(R.string.next), modifier = Modifier.size(IconButtonDefaults.largeIconSize), ) } diff --git a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/onboarding/PermissionsPage.kt b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/onboarding/PermissionsPage.kt index 7b85037fc..e6520e46c 100644 --- a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/onboarding/PermissionsPage.kt +++ b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/onboarding/PermissionsPage.kt @@ -181,7 +181,7 @@ fun PermissionsPage( ) { Icon( imageVector = MaterialIcons.Bluetooth, - contentDescription = "bluetooth", + contentDescription = stringResource(R.string.bluetooth), modifier = Modifier.size(24.dp), tint = animatedBluetoothIconColor ) @@ -228,7 +228,7 @@ fun PermissionsPage( ) { Icon( imageVector = MaterialIcons.Notifications, - contentDescription = "notifications", + contentDescription = stringResource(R.string.notifications), modifier = Modifier.size(24.dp), tint = animatedNotificationsIconColor ) @@ -258,7 +258,7 @@ fun PermissionsPage( ) { Icon( imageVector = MaterialIcons.Call, - contentDescription = "call", + contentDescription = stringResource(R.string.phone), modifier = Modifier.size(24.dp), tint = animatedPhoneIconColor ) @@ -292,7 +292,7 @@ fun PermissionsPage( ) { Icon( imageVector = MaterialIcons.VitalSigns, - contentDescription = "vital signs", + contentDescription = stringResource(R.string.heart_rate), modifier = Modifier.size(24.dp), tint = animatedHealthConnectIconColor ) @@ -330,7 +330,7 @@ fun PermissionsPage( ) { Icon( imageVector = MaterialIcons.Overlay, - contentDescription = "overlay", + contentDescription = stringResource(R.string.permission_overlay), modifier = Modifier.size(24.dp), tint = animatedOverlayIconColor ) @@ -353,7 +353,7 @@ fun PermissionsPage( ) { Icon( Icons.AutoMirrored.Default.ArrowBack, - contentDescription = "backward", + contentDescription = stringResource(R.string.back), modifier = Modifier.size(IconButtonDefaults.mediumIconSize), ) } @@ -372,7 +372,7 @@ fun PermissionsPage( enabled = !bluetoothPermissionsState.allPermissionsGranted || !notificationPermissionState.status.isGranted || !phonePermissionState.allPermissionsGranted || !canDrawOverlays.value ) { Text( - text = "Grant all", + text = stringResource(R.string.grant_all), style = MaterialTheme.typography.labelMedium ) } @@ -388,7 +388,7 @@ fun PermissionsPage( ) { Icon( Icons.AutoMirrored.Default.ArrowForward, - contentDescription = "forward", + contentDescription = stringResource(R.string.next), modifier = Modifier.size(IconButtonDefaults.mediumIconSize), ) } diff --git a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/settings/AppAccessibilitySettingsScreen.kt b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/settings/AppAccessibilitySettingsScreen.kt index 5dd43eec4..b2f92585b 100644 --- a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/settings/AppAccessibilitySettingsScreen.kt +++ b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/settings/AppAccessibilitySettingsScreen.kt @@ -90,20 +90,19 @@ fun AppAccessibilitySettingsScreen( ) } - // TODO: extract strings - StyledList(title = "Glass effects") { + StyledList(title = stringResource(R.string.glass_effects)) { styledToggle( - label = "Reduce transparency", + label = stringResource(R.string.reduce_transparency), checked = reduceTransparency, onCheckedChange = onReduceTransparencyChanged ) styledToggle( - label = "Increase contrast", + label = stringResource(R.string.increase_contrast), checked = increaseContrast, onCheckedChange = onIncreaseContrastChanged ) styledToggle( - label = "Show borders", + label = stringResource(R.string.show_borders), checked = showBorders, onCheckedChange = onShowBordersChanged ) diff --git a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/settings/AppSettingsScreen.kt b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/settings/AppSettingsScreen.kt index ff2bbdcf3..3a54bba67 100644 --- a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/settings/AppSettingsScreen.kt +++ b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/settings/AppSettingsScreen.kt @@ -483,7 +483,7 @@ fun AppSettingsScreen( ) { Icon( imageVector = LocalIcons.current.Close, - contentDescription = "Close", + contentDescription = stringResource(R.string.close), tint = MaterialTheme.colorScheme.onBackground ) } @@ -527,7 +527,7 @@ fun AppSettingsScreen( ) { Icon( imageVector = LocalIcons.current.Send, - contentDescription = "Send", + contentDescription = stringResource(R.string.send), tint = if (subjectState.text.isNotEmpty() && descriptionState.text.isNotEmpty()) Color.White else Color.Gray ) } diff --git a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/settings/island/IslandSettingsScreen.kt b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/settings/island/IslandSettingsScreen.kt index d848ea474..73b9420ed 100644 --- a/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/settings/island/IslandSettingsScreen.kt +++ b/android/app/src/main/kotlin/me/kavishdevar/librepods/presentation/screens/settings/island/IslandSettingsScreen.kt @@ -233,7 +233,7 @@ fun IslandSettingsScreen( verticalArrangement = Arrangement.spacedBy(16.dp) ) { StyledList( - title = "Compact" + title = stringResource(R.string.compact) ) { styledListItem( contentText = stringResource(R.string.size_and_position), diff --git a/android/app/src/main/kotlin/me/kavishdevar/librepods/services/AirPodsQSService.kt b/android/app/src/main/kotlin/me/kavishdevar/librepods/services/AirPodsQSService.kt index a5777a57c..f3723ebff 100644 --- a/android/app/src/main/kotlin/me/kavishdevar/librepods/services/AirPodsQSService.kt +++ b/android/app/src/main/kotlin/me/kavishdevar/librepods/services/AirPodsQSService.kt @@ -171,7 +171,7 @@ class AirPodsQSService : TileService() { } else { tile.state = Tile.STATE_UNAVAILABLE tile.label = "AirPods" - tile.subtitle = "Disconnected" + tile.subtitle = getString(R.string.disconnected) tile.icon = Icon.createWithResource(this, R.drawable.ic_airpods) } @@ -210,11 +210,11 @@ class AirPodsQSService : TileService() { private fun getModeLabel(mode: Int): String { return when (mode) { - NoiseControlMode.OFF.ordinal + 1 -> "Off" - NoiseControlMode.TRANSPARENCY.ordinal + 1 -> "Transparency" - NoiseControlMode.ADAPTIVE.ordinal + 1 -> "Adaptive" - NoiseControlMode.NOISE_CANCELLATION.ordinal + 1 -> "Noise Cancellation" - else -> "Unknown" + NoiseControlMode.OFF.ordinal + 1 -> getString(R.string.off) + NoiseControlMode.TRANSPARENCY.ordinal + 1 -> getString(R.string.transparency) + NoiseControlMode.ADAPTIVE.ordinal + 1 -> getString(R.string.adaptive) + NoiseControlMode.NOISE_CANCELLATION.ordinal + 1 -> getString(R.string.noise_cancellation) + else -> getString(R.string.unknown) } } diff --git a/android/app/src/main/kotlin/me/kavishdevar/librepods/services/LibrePodsService.kt b/android/app/src/main/kotlin/me/kavishdevar/librepods/services/LibrePodsService.kt index 7409d9897..4319e941d 100644 --- a/android/app/src/main/kotlin/me/kavishdevar/librepods/services/LibrePodsService.kt +++ b/android/app/src/main/kotlin/me/kavishdevar/librepods/services/LibrePodsService.kt @@ -1058,7 +1058,7 @@ class LibrePodsService: Service() { NotificationCompat.Builder(this, "device_${device.macAddress}") .setSmallIcon(R.drawable.ic_airpods) .setContentTitle(device.metadata.value.name) - .setContentText(device.state.value.battery.joinToString(" ") { "${it.component.name[0]}: ${it.level}%" }) + .setContentText(device.state.value.battery.joinToString(" ") { "${batteryShortLabel(it.component)}: ${it.level}%" }) .setContentIntent(pendingIntent) .setCategory(Notification.CATEGORY_STATUS) .setPriority(NotificationCompat.PRIORITY_LOW) @@ -1280,6 +1280,15 @@ class LibrePodsService: Service() { appWidgetManager.updateAppWidget(widgetIds, remoteViews) } + private fun batteryShortLabel(component: BatteryComponent): String = getString( + when (component) { + BatteryComponent.LEFT -> R.string.battery_short_left + BatteryComponent.RIGHT -> R.string.battery_short_right + BatteryComponent.CASE -> R.string.battery_short_case + BatteryComponent.HEADSET -> R.string.battery_short_headset + } + ) + private fun processComponentStateChange( device: Device<*, *, *>, previousComponentState: Set, diff --git a/android/app/src/main/res/values-zh-rCN/strings.xml b/android/app/src/main/res/values-zh-rCN/strings.xml index aacb63742..793cc57af 100644 --- a/android/app/src/main/res/values-zh-rCN/strings.xml +++ b/android/app/src/main/res/values-zh-rCN/strings.xml @@ -55,7 +55,7 @@ 开发者 打开 AirPods 设置 管理 AirPods 功能与偏好 - 自动人耳检测 + 自动入耳检测 自动播放 自动暂停 故障排查 @@ -337,10 +337,155 @@ 已接听来电 正在等待… 服务运行中 - 没什么用的通知,点它即可关闭。 + 没什么用的通知,点击即可关闭。 前台服务状态 你的心率已超过设定阈值。(当前:%d bpm) 心率过高 此提醒目前不会考虑运动或体力活动的影响,仅供参考,不构成医疗建议。 提醒已关闭,直到重新连接或重新开启心率监测为止。 + 测试 + + 由于 Android 蓝牙协议栈的限制,许多设备暂不受支持。 + \n在这些设备上,需要 Root 权限和 Xposed 框架才能使用完整功能。 + \n\n较新的 Android 版本已解决这一限制。以下设备配置可以直接运行本应用: + \n• 运行 Android 16 三月更新及更高版本,并已安装最新 Play 系统更新的 Google Pixel® + \n• 运行 Android 17 Beta 3 及更高版本的 Google Pixel® + \n• 运行 OxygenOS 16 或更高版本的一加设备 + \n• 运行 ColorOS 16 或更高版本的 OPPO 设备 + \n\n详情请参阅项目文档。 + + 不以颜色区分 + 字体 + 字体 + 字体缩放 + 字体缩放 + 灵动岛设置 + 相机控制和可交互的灵动岛弹窗 + 大小与位置 + 按住 + 自定义 + 打开 %s + 点按以展开 + 点按以打开 %s + 展开 + 保持显示紧凑式灵动岛 + 灵动岛显示在状态栏时,需要无障碍服务才能与其交互。 + 无障碍服务 + 可用 + 不可用 + 电池样式 + 不显示 + 圆环 + 文字 + 两者 + 隐藏灵动岛 + 显示灵动岛 + 边框宽度 + 圆角半径 + 水平偏移 + 垂直偏移 + 高度 + 宽度 + 聆听模式控制 + 长按以打开 %s + 字号 + 默认样式 + 展开式 + 紧凑式 + 不透明度 + 单色 + 图标 + 图片 + 取消 + 重置应用设置 + 所有应用设置(外观、交互、辅助功能、灵动岛等)都将被重置。 + 重置灵动岛设置 + 通话中可能无法通过 AirPods 上的控制将麦克风静音或取消静音。这是 Android 的已知问题,LibrePods 无法修复。 + 已跳过兼容性检查。你确定你的设备兼容吗? + 你的设备目前不兼容。请更新设备后继续。 + 由于 Android 的限制,需要较新版本的 Android 才能使用 LibrePods。 + \n• Google Pixel 设备需要 Android 16 三月更新或更高版本,并安装最新的 Google Play 系统更新 + \n• 一加和 OPPO 设备需要 Android 16 + \n• 其他所有设备需要 Android 17(OneUI 9、MagicOS 11、Nothing OS 5.0 等) + + 低 + 中 + 高 + 完成 + 启用 + 关闭 + 发送 + 清除文本 + 耳机 + 未连接 + 未知 + 速度 + 测试头部动作 + 水平 + 垂直 + 启用助听 + 启用助听后,耳机调节和自定义通透模式将被停用。 + 开始录音 + 停止录音 + 全部授予 + 服务不可用。请确认 LibrePods 正在运行,然后重试。 + 未找到设备。请确认已有兼容的设备与手机配对,然后重试。 + 左 + 右 + 盒 + 耳机 + 检测到点头。 + 检测到摇头。 + 播放/暂停 + 开始/停止 + 下一步 + 调整 AirPods 播放声音效果的提示声音量。当前的声音比推荐的默认音量更响。 + 应用颜色 + 壁纸 + 图标 + 模糊样式 + 超薄 + 薄 + 常规 + 厚 + 超厚 + 顶栏使用渐进式模糊 + 颜色 + 模糊与玻璃效果 + 模糊顶栏后方的内容 + 纯黑背景 + 调色板样式 + 暂无电池信息 + 未连接 + 色相 + 饱和度 + 亮度 + 对比度 + 连接 + 显示卡片 + 隐藏卡片 + 播放循环视频 + 靠近弹窗 + 在手机附近打开充电盒时显示弹窗。 + 显示连接按钮 + 悬浮窗 + 灵动岛弹窗 + 佩戴 AirPods 时显示。你可以选择在佩戴期间一直显示,或在几秒后隐藏。 + 更多设置 + 自定义悬浮窗的大小、位置、外观和行为。 + 未连接其他设备时自动连接 + 启用后,当 AirPods 没有连接其他设备时,应用会自动连接 AirPods。 + 通话规则 + 选择何时自动将通话音频切换到 AirPods。 + 媒体音频规则 + 选择何时自动将音乐、视频等媒体音频切换到 AirPods。 + 未连接任何设备 + 已连接其他设备,但处于空闲 + 已连接正在播放媒体的其他设备 + 配置自动连接 + 两只 AirPods 都在充电盒内时才显示 + 玻璃效果 + 降低透明度 + 增强对比度 + 显示边框 diff --git a/android/app/src/main/res/values-zh-rTW/strings.xml b/android/app/src/main/res/values-zh-rTW/strings.xml index 807c7c30e..d9ae383e6 100644 --- a/android/app/src/main/res/values-zh-rTW/strings.xml +++ b/android/app/src/main/res/values-zh-rTW/strings.xml @@ -240,4 +240,253 @@ 你確定你的裝置原生支援或已啟用 Xposed 模組嗎? 不支援 您的應用程式已更新為 Google Play 版本,進階功能將在 %1$d 天後停用。請從您的原始安裝來源更新以繼續使用 FOSS 版本,或等待此期限結束後直接購買升級;如果您已是支持者,請點按此處申請促銷代碼。 + 測試 + 彈出視窗動畫 + 底部彈出視窗 + 連接 AirPods 時,在底部顯示 iOS 風格的彈出視窗。 + 動態島彈出視窗 + 在頂部以動態島樣式顯示連線與接管事件的彈出視窗。 + + 由於 Android 藍牙堆疊的限制,許多裝置目前尚不支援。 + \n在這些裝置上,需要 Root 權限與 Xposed 框架才能使用完整功能。 + \n\n較新的 Android 版本已解決此限制。以下裝置設定可以原生執行本應用程式: + \n• 執行 Android 16 三月更新或更新版本,並已安裝最新 Play 系統更新的 Google Pixel® + \n• 執行 Android 17 Beta 3 或以上版本的 Google Pixel® + \n• 執行 OxygenOS 16 或更新版本的 OnePlus 裝置 + \n• 執行 ColorOS 16 或更新版本的 OPPO 裝置 + \n\n詳情請參閱專案說明文件。 + + (價格由你決定) + + 由於平台限制,此裝置可能不受支援,需要使用 Xposed 框架。請勾選下方的核取方塊並輸入 OK 以繼續。 + + 輸入「%s」以繼續 + 繼續 + 我已閱讀相容性需求。 + 裝置資訊 + 建置 ID + 製造商 + 免費功能 + 進階功能 + 長按啟動語音助理 + 按住 AirPods Pro 耳機柄時啟動語音助理。 + 無法使用自訂功能。請至少連接 AirPods 一次後再使用。 + Xposed 可用 + 已在 Xposed 中啟用應用程式 + 主旨 + 描述你遇到的問題 + 最佳化充電上限 + AirPods 可以學習你的每日使用習慣,決定何時充電至最佳化上限、何時允許充滿電。此上限會依據你的每日使用情況調整,長期下來可延長電池壽命。\n此設定對不支援的 AirPods 或韌體版本較舊的 AirPods 可能無效。 + 請更新你的裝置,或在 Xposed 中啟用 LibrePods 並重新開啟應用程式以繼續。 + 自訂 + 建議 + 外觀 + Material 3 Expressive + LibrePods 現已支援以 Material 3 Expressive 為基礎的全新外觀,包括更新的字體排版與自適應配色。\n你可以在應用程式設定中切換回 Apple 外觀。 + 僅適用於最新的 AirPods Beta 韌體。安裝 Beta 韌體需要一台執行 OS 27 版本的 Apple 裝置。 + 新功能 + 正在重新連線 + 輕觸以重新連線 + 權限 + 隱私權政策 + 我同意 + 錄音 + 錄音檔 + 使用 AirPods 的高品質麥克風錄製音訊。 + 心率 + 跟隨系統 + 淺色 + 深色 + 設計風格 + Apple + Apple + 正在連線 + 裝置 + 設定小工具 + 歡迎使用 + 直接向開發者尋求協助。回覆可能需要一些時間,這個專案只有我一個人在做 :) + 向社群尋求協助。 + 在 GitHub 儲存庫中建立 issue。僅在你要提出功能建議,或確定發現 bug 時使用。開 issue 之前請先向社群詢問。 + 無法開啟 Discord 邀請連結 + 無法開啟 GitHub 連結 + 掃描模式 + BLE 設定 + 除非你清楚自己在做什麼,否則請勿變更這些設定! + 低功耗 + 耗電量最少 + 平衡 + 在掃描頻率與耗電量之間取得良好平衡 + 低延遲 + 掃描頻率最高 + 啟用偵錯模式 + 大於 0 的值會啟用批次回報。 + 回報延遲(毫秒) + 間隔 + 兩次心率量測之間的間隔 + 沒有心率資料 + 1 秒 + 1 分鐘 + 將心率寫入「健康資料同步」 + 允許應用程式將心率資料寫入 Android 的「健康資料同步」平台。 + 必要權限 + 藍牙 + 與 AirPods 通訊所必需。 + 選用權限 + 通知 + 顯示電池狀態、心率過高警示(支援的型號)等。 + 使用頭部手勢接聽或拒接來電。 + 顯示在其他應用程式上層 + 當 AirPods 在附近或音訊切換到 AirPods 時顯示彈出視窗。 + 在任意位置滑動即可返回 + 使用裝置支援的最高更新率 + 顯示額外的資訊與設定。 + 互動 + 心率監測 + 心率超過閾值時傳送通知。會增加耗電量。 + 心率警示 + 警示閾值 + 已拒接來電 + 已接聽來電 + 正在等待… + 服務執行中 + 沒什麼用的通知,點一下即可關閉。 + 前景服務狀態 + 你的心率已超過設定的閾值。(目前:%d bpm) + 心率過高 + 此警示目前不會考慮運動或體能活動的影響,僅供參考,不構成醫療建議。 + 警示已停用,直到重新連線或重新啟用心率監測為止。 + 不以顏色區分 + 字型 + 字型 + 字型縮放 + 字型縮放 + 動態島設定 + 相機控制與可互動的動態島彈出視窗 + 大小與位置 + 按住 + 自訂 + 開啟 %s + 輕觸以展開 + 輕觸以開啟 %s + 展開 + 持續顯示精簡式動態島 + 動態島顯示在狀態列時,需要無障礙服務才能與其互動。 + 無障礙服務 + 可用 + 無法使用 + 電池樣式 + 不顯示 + 圓環 + 文字 + 兩者 + 隱藏動態島 + 顯示動態島 + 邊框寬度 + 圓角半徑 + 水平偏移 + 垂直偏移 + 高度 + 寬度 + 聽覺模式控制 + 長按以開啟 %s + 字型大小 + 預設樣式 + 展開式 + 精簡式 + 不透明度 + 單色 + 圖示 + 圖片 + 取消 + 重設應用程式設定 + 所有應用程式設定(外觀、互動、輔助使用、動態島等)都將重設。 + 重設動態島設定 + 通話中可能無法使用 AirPods 上的控制將麥克風靜音或取消靜音。這是 Android 的已知問題,LibrePods 無法修正。 + 已略過相容性檢查。你確定你的裝置相容嗎? + 你的裝置目前不相容。請更新裝置以繼續。 + 由於 Android 的限制,需要較新版本的 Android 才能使用 LibrePods。 + \n• Google Pixel 裝置需要 Android 16 三月更新或更新版本,並安裝最新的 Google Play 系統更新 + \n• OnePlus 與 OPPO 裝置需要 Android 16 + \n• 其他所有裝置需要 Android 17(OneUI 9、MagicOS 11、Nothing OS 5.0 等) + + 低 + 中 + 高 + 完成 + 啟用 + 關閉 + 傳送 + 清除文字 + 耳機 + 未連線 + 未知 + 速度 + 測試頭部手勢 + 水平 + 垂直 + 啟用助聽器 + 啟用助聽器後,耳機調節和自訂通透模式將會停用。 + 開始錄音 + 停止錄音 + 全部授權 + 服務無法使用。請確認 LibrePods 正在執行,然後再試一次。 + 找不到裝置。請確認已有相容的裝置與手機配對,然後再試一次。 + 左 + 右 + 盒 + 耳機 + 偵測到點頭。 + 偵測到搖頭。 + 播放/暫停 + 開始/停止 + 下一步 + 調整 AirPods 播放音效的提示音音量。目前的聲音比建議的預設音量更大聲。 + 應用程式顏色 + 桌布 + 圖示 + 模糊樣式 + 超薄 + 薄 + 標準 + 厚 + 超厚 + 頂部列使用漸進式模糊 + 顏色 + 模糊與玻璃效果 + 模糊頂部列後方的內容 + 純黑背景 + 調色盤樣式 + 沒有可用的電池資訊 + 未連線 + 色相 + 飽和度 + 亮度 + 對比 + 連線 + 顯示卡片 + 隱藏卡片 + 播放循環影片 + 靠近彈出視窗 + 在手機附近打開充電盒時顯示彈出視窗。 + 顯示連線按鈕 + 浮動視窗 + 動態島彈出視窗 + 配戴 AirPods 時顯示。你可以選擇在配戴期間持續顯示,或在幾秒後隱藏。 + 更多設定 + 自訂浮動視窗的大小、位置、外觀與行為。 + 未連接其他裝置時自動連線 + 啟用後,當 AirPods 沒有連接其他裝置時,應用程式會自動連接 AirPods。 + 通話規則 + 選擇何時自動將通話音訊切換到 AirPods。 + 媒體音訊規則 + 選擇何時自動將音樂、影片等媒體音訊切換到 AirPods。 + 未連接任何裝置 + 已連接其他裝置,但處於閒置 + 已連接正在播放媒體的其他裝置 + 設定自動連線 + 兩只 AirPods 都在充電盒內時才顯示 + 玻璃效果 + 降低透明度 + 增加對比 + 顯示邊框 diff --git a/android/app/src/main/res/values/arrays.xml b/android/app/src/main/res/values/arrays.xml index dc69d9b43..8e4d6472f 100644 --- a/android/app/src/main/res/values/arrays.xml +++ b/android/app/src/main/res/values/arrays.xml @@ -4,12 +4,12 @@ @array/com_google_android_gms_fonts_certs_dev @array/com_google_android_gms_fonts_certs_prod - + MIIEqDCCA5CgAwIBAgIJANWFuGx90071MA0GCSqGSIb3DQEBBAUAMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAeFw0wODA0MTUyMzM2NTZaFw0zNTA5MDEyMzM2NTZaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBANbOLggKv+IxTdGNs8/TGFy0PTP6DHThvbbR24kT9ixcOd9W+EaBPWW+wPPKQmsHxajtWjmQwWfna8mZuSeJS48LIgAZlKkpFeVyxW0qMBujb8X8ETrWy550NaFtI6t9+u7hZeTfHwqNvacKhp1RbE6dBRGWynwMVX8XW8N1+UjFaq6GCJukT4qmpN2afb8sCjUigq0GuMwYXrFVee74bQgLHWGJwPmvmLHC69EH6kWr22ijx4OKXlSIx2xT1AsSHee70w5iDBiK4aph27yH3TxkXy9V89TDdexAcKk/cVHYNnDBapcavl7y0RiQ4biu8ymM8Ga/nmzhRKya6G0cGw8CAQOjgfwwgfkwHQYDVR0OBBYEFI0cxb6VTEM8YYY6FbBMvAPyT+CyMIHJBgNVHSMEgcEwgb6AFI0cxb6VTEM8YYY6FbBMvAPyT+CyoYGapIGXMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbYIJANWFuGx90071MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADggEBABnTDPEF+3iSP0wNfdIjIz1AlnrPzgAIHVvXxunW7SBrDhEglQZBbKJEk5kT0mtKoOD1JMrSu1xuTKEBahWRbqHsXclaXjoBADb0kkjVEJu/Lh5hgYZnOjvlba8Ld7HCKePCVePoTJBdI4fvugnL8TsgK05aIskyY0hKI9L8KfqfGTl1lzOv2KoWD0KWwtAWPoGChZxmQ+nBli+gwYMzM1vAkP+aayLe0a1EQimlOalO762r0GXO0ks+UeXde2Z4e+8S/pf7pITEI/tP+MxJTALw9QUWEv9lKTk+jkbqxbsh8nfBUapfKqYn0eidpwq2AzVp3juYl7//fKnaPhJD9gs= - + MIIEQzCCAyugAwIBAgIJAMLgh0ZkSjCNMA0GCSqGSIb3DQEBBAUAMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDAeFw0wODA4MjEyMzEzMzRaFw0zNjAxMDcyMzEzMzRaMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBAKtWLgDYO6IIrgqWbxJOKdoR8qtW0I9Y4sypEwPpt1TTcvZApxsdyxMJZ2JORland2qSGT2y5b+3JKkedxiLDmpHpDsz2WCbdxgxRczfey5YZnTJ4VZbH0xqWVW/8lGmPav5xVwnIiJS6HXk+BVKZF+JcWjAsb/GEuq/eFdpuzSqeYTcfi6idkyugwfYwXFU1+5fZKUaRKYCwkkFQVfcAs1fXA5V+++FGfvjJ/CxURaSxaBvGdGDhfXE28LWuT9ozCl5xw4Yq5OGazvV24mZVSoOO0yZ31j7kYvtwYK6NeADwbSxDdJEqO4k//0zOHKrUiGYXtqw/A0LFFtqoZKFjnkCAQOjgdkwgdYwHQYDVR0OBBYEFMd9jMIhF1Ylmn/Tgt9r45jk14alMIGmBgNVHSMEgZ4wgZuAFMd9jMIhF1Ylmn/Tgt9r45jk14aloXikdjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLR29vZ2xlIEluYy4xEDAOBgNVBAsTB0FuZHJvaWQxEDAOBgNVBAMTB0FuZHJvaWSCCQDC4IdGZEowjTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4IBAQBt0lLO74UwLDYKqs6Tm8/yzKkEu116FmH4rkaymUIE0P9KaMftGlMexFlaYjzmB2OxZyl6euNXEsQH8gjwyxCUKRJNexBiGcCEyj6z+a1fuHHvkiaai+KL8W1EyNmgjmyy8AW7P+LLlkR+ho5zEHatRbM/YAnqGcFh5iZBqpknHf1SKMXFh4dd239FJ1jWYfbMDMy3NS5CTMQ2XFI1MvcyUTdZPErjQfTbQe3aDQsQcafEQPD+nqActifKZ0Np0IS9L9kR/wbNvyz6ENwPiTrjV2KRkEjH78ZMcUQXg0L3BYHJ3lc69Vs5Ddf9uUGGMYldX3WfMBEmh/9iFBDAaTCK diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index d557ec166..70222565e 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -358,9 +358,9 @@ Differentiate without color Font Font - Inter - Roboto Flex (Expressive) - Roboto Flex + Inter + Roboto Flex (Expressive) + Roboto Flex Font scale Font scale Island settings @@ -418,7 +418,7 @@ App color Wallpaper Icons - Material Symbols + Material Symbols Blur style Ultra thin Thin @@ -460,4 +460,37 @@ Connected to another device playing media Configure automatic connections Require both AirPods in case to show + Done + Enable + Close + Send + Clear text + Headset + Disconnected + Unknown + Velocity + Test Head Gestures + Horizontal + Vertical + Enable Hearing Aid + Enabling Hearing Aid will disable Headphone Accommodation and Customized Transparency Mode. + Start Recording + Stop Recording + Grant all + Service not available. Please ensure LibrePods is running and try again. + No devices found. Please ensure a compatible device is paired with your phone and try again. + + L + R + C + H + \"Yes\" gesture detected. + \"No\" gesture detected. + Play/Pause + Start/Stop + Next + Glass effects + Reduce transparency + Increase contrast + Show borders