android: add back troubleshooter for non-Play builds

This commit is contained in:
Kavish Devar
2026-04-23 00:47:09 +05:30
parent fce90cf88a
commit bf6a3cac4a
6 changed files with 107 additions and 61 deletions

View File

@@ -28,7 +28,7 @@ android {
applicationId = "me.kavishdevar.librepods" applicationId = "me.kavishdevar.librepods"
minSdk = 33 minSdk = 33
targetSdk = 37 targetSdk = 37
versionCode = 27 versionCode = 28
versionName = "0.2.0" versionName = "0.2.0"
} }
buildTypes { buildTypes {

View File

@@ -144,6 +144,7 @@ import me.kavishdevar.librepods.presentation.screens.OpenSourceLicensesScreen
import me.kavishdevar.librepods.presentation.screens.PurchaseScreen import me.kavishdevar.librepods.presentation.screens.PurchaseScreen
import me.kavishdevar.librepods.presentation.screens.RenameScreen import me.kavishdevar.librepods.presentation.screens.RenameScreen
import me.kavishdevar.librepods.presentation.screens.TransparencySettingsScreen import me.kavishdevar.librepods.presentation.screens.TransparencySettingsScreen
import me.kavishdevar.librepods.presentation.screens.TroubleshootingScreen
import me.kavishdevar.librepods.presentation.screens.UpdateHearingTestScreen import me.kavishdevar.librepods.presentation.screens.UpdateHearingTestScreen
import me.kavishdevar.librepods.presentation.screens.VersionScreen import me.kavishdevar.librepods.presentation.screens.VersionScreen
import me.kavishdevar.librepods.presentation.viewmodel.AirPodsViewModel import me.kavishdevar.librepods.presentation.viewmodel.AirPodsViewModel
@@ -473,9 +474,9 @@ fun Main() {
val appSettingsViewModel: AppSettingsViewModel = viewModel() val appSettingsViewModel: AppSettingsViewModel = viewModel()
AppSettingsScreen(navController, appSettingsViewModel) AppSettingsScreen(navController, appSettingsViewModel)
} }
// composable("troubleshooting") { composable("troubleshooting") {
// TroubleshootingScreen(navController) TroubleshootingScreen(navController)
// } }
composable("head_tracking") { composable("head_tracking") {
if (airPodsViewModel != null) HeadTrackingScreen(airPodsViewModel, navController) if (airPodsViewModel != null) HeadTrackingScreen(airPodsViewModel, navController)
} }

View File

@@ -1261,7 +1261,7 @@ class AACPManager {
val start = index val start = index
// find next 0x00 byte // find next 0x00 byte
while (index < data.size && data[index] != 0x00.toByte()) index++ while (index < data.size && data[index] != 0x00.toByte()) index++
val str = data.sliceArray(start..index).decodeToString() val str = data.sliceArray(start until index).decodeToString()
strings.add(str) strings.add(str)
} }

View File

@@ -31,7 +31,6 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
@@ -40,8 +39,10 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.scale import androidx.compose.ui.draw.scale
import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.Font import androidx.compose.ui.text.font.Font
@@ -53,6 +54,7 @@ import androidx.compose.ui.unit.sp
import me.kavishdevar.librepods.R import me.kavishdevar.librepods.R
import me.kavishdevar.librepods.data.BatteryStatus import me.kavishdevar.librepods.data.BatteryStatus
import kotlin.math.cos import kotlin.math.cos
import kotlin.math.min
import kotlin.math.sin import kotlin.math.sin
import kotlin.math.sqrt import kotlin.math.sqrt
@@ -66,8 +68,8 @@ fun BatteryIndicator(
val isDarkTheme = isSystemInDarkTheme() val isDarkTheme = isSystemInDarkTheme()
val backgroundColor = if (isDarkTheme) Color.Black else Color(0xFFF2F2F7) val backgroundColor = if (isDarkTheme) Color.Black else Color(0xFFF2F2F7)
val batteryTextColor = if (isDarkTheme) Color.White else Color.Black val batteryTextColor = if (isDarkTheme) Color.White else Color.Black
val batteryFillColor = if (batteryPercentage > 25) val batteryFillColor =
if (isDarkTheme) Color(0xFF2ED158) else Color(0xFF35C759) if (batteryPercentage > 25) if (isDarkTheme) Color(0xFF2ED158) else Color(0xFF35C759)
else if (isDarkTheme) Color(0xFFFC4244) else Color(0xFFfe373C) else if (isDarkTheme) Color(0xFFFC4244) else Color(0xFFfe373C)
val initialScale = if (previousCharging) 1f else 0f val initialScale = if (previousCharging) 1f else 0f
@@ -80,27 +82,57 @@ fun BatteryIndicator(
} }
Column( Column(
modifier = Modifier modifier = Modifier.background(backgroundColor).padding(4.dp), // just for haze to work
.background(backgroundColor), // just for haze to work
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
) { ) {
Box( Box(
modifier = Modifier.padding(bottom = 4.dp), modifier = Modifier.padding(bottom = 4.dp), contentAlignment = Alignment.Center
contentAlignment = Alignment.Center
) { ) {
val strokeWidthPx = with(LocalDensity.current) { 4.dp.toPx() } val strokeWidthPx = with(LocalDensity.current) { 4.dp.toPx() }
val gapFromCenterPx = with(LocalDensity.current) { 8.sp.toPx() } val gapFromCenterPx = with(LocalDensity.current) { 8.sp.toPx() }
if (status == BatteryStatus.OPTIMIZED_CHARGING) { val trackColor = if (isDarkTheme) Color(0xFF272728) else Color(0xFFE3E3E8)
Canvas(modifier = Modifier.size(40.dp)) { val optimizedLimit = 0.8f
val radius = size.minDimension / 2 val progress = batteryPercentage / 100f
val progress = batteryPercentage / 100f
val angleDeg = -90f + 360f * progress Canvas(modifier = Modifier.size(34.dp)) {
val startAngle = -90f
val stroke = Stroke(width = strokeWidthPx, cap = StrokeCap.Round)
val inset = strokeWidthPx / 2
Rect(
left = inset,
top = inset,
right = size.width - inset,
bottom = size.height - inset
)
val radius = size.minDimension / 2
if (status == BatteryStatus.OPTIMIZED_CHARGING) {
drawArc(
color = trackColor,
startAngle = startAngle,
sweepAngle = 360f * optimizedLimit,
useCenter = false,
style = stroke
)
val sweep = 360f * min(progress, optimizedLimit)
drawArc(
color = batteryFillColor,
startAngle = startAngle,
sweepAngle = sweep,
useCenter = false,
style = stroke
)
// ---- PILL MARKER AT 80% ----
val angleDeg = startAngle + 360f * optimizedLimit
val angleRad = Math.toRadians(angleDeg.toDouble()) val angleRad = Math.toRadians(angleDeg.toDouble())
val outerX = center.x + (radius - strokeWidthPx) * cos(angleRad).toFloat() val arcRadius = radius - strokeWidthPx
val outerY = center.y + (radius - strokeWidthPx) * sin(angleRad).toFloat()
val outerX = center.x + arcRadius * cos(angleRad).toFloat()
val outerY = center.y + arcRadius * sin(angleRad).toFloat()
val dirX = center.x - outerX val dirX = center.x - outerX
val dirY = center.y - outerY val dirY = center.y - outerY
@@ -116,34 +148,38 @@ fun BatteryIndicator(
val endY = center.y - normY * gapFromCenterPx val endY = center.y - normY * gapFromCenterPx
drawLine( drawLine(
color = batteryFillColor, color = if (batteryPercentage >= 80) batteryFillColor else trackColor,
start = Offset(startX, startY), start = Offset(startX, startY),
end = Offset(endX, endY), end = Offset(endX, endY),
strokeWidth = strokeWidthPx, strokeWidth = strokeWidthPx,
cap = StrokeCap.Round cap = StrokeCap.Round
) )
} else {
drawArc(
color = trackColor,
startAngle = 0f,
sweepAngle = 360f,
useCenter = false,
style = stroke
)
drawArc(
color = batteryFillColor,
startAngle = startAngle,
sweepAngle = 360f * progress,
useCenter = false,
style = stroke
)
} }
} }
CircularProgressIndicator(
progress = { batteryPercentage / 100f },
modifier = Modifier.size(40.dp),
color = batteryFillColor,
gapSize = 0.dp,
strokeCap = StrokeCap.Round,
strokeWidth = 4.dp,
trackColor = if (isDarkTheme) Color(0xFF0E0E0F) else Color(0xFFE3E3E8)
)
Text( Text(
text = "\uDBC0\uDEE6", text = "\uDBC0\uDEE6", style = TextStyle(
style = TextStyle( fontSize = 14.sp,
fontSize = 12.sp,
fontFamily = FontFamily(Font(R.font.sf_pro)), fontFamily = FontFamily(Font(R.font.sf_pro)),
color = batteryFillColor, color = batteryFillColor,
textAlign = TextAlign.Center textAlign = TextAlign.Center
), ), modifier = Modifier.scale(scaleAnim.value)
modifier = Modifier.scale(scaleAnim.value)
) )
} }
@@ -153,7 +189,7 @@ fun BatteryIndicator(
text = "$prefix $batteryPercentage%", text = "$prefix $batteryPercentage%",
color = batteryTextColor, color = batteryTextColor,
style = TextStyle( style = TextStyle(
fontSize = 16.sp, fontSize = 14.sp,
fontFamily = FontFamily(Font(R.font.sf_pro)), fontFamily = FontFamily(Font(R.font.sf_pro)),
textAlign = TextAlign.Center textAlign = TextAlign.Center
), ),
@@ -168,6 +204,11 @@ fun BatteryIndicatorPreview() {
Box( Box(
modifier = Modifier.background(bg) modifier = Modifier.background(bg)
) { ) {
BatteryIndicator(batteryPercentage = 80, status = BatteryStatus.CHARGING, prefix = "\uDBC6\uDCE5", previousCharging = false) BatteryIndicator(
batteryPercentage = 50,
status = BatteryStatus.OPTIMIZED_CHARGING,
prefix = "\uDBC6\uDCE5",
previousCharging = false
)
} }
} }

View File

@@ -500,23 +500,25 @@ fun AirPodsSettingsScreen(viewModel: AirPodsViewModel, navController: NavControl
} }
Spacer(Modifier.height(32.dp)) Spacer(Modifier.height(32.dp))
// StyledButton( if (!BuildConfig.PLAY_BUILD) {
// onClick = { navController.navigate("troubleshooting") }, StyledButton(
// backdrop = backdrop, onClick = { navController.navigate("troubleshooting") },
// modifier = Modifier backdrop = backdrop,
// .fillMaxWidth(0.9f) modifier = Modifier
// ) { .fillMaxWidth(0.9f)
// Text( ) {
// text = stringResource(R.string.troubleshooting), Text(
// style = TextStyle( text = stringResource(R.string.troubleshooting),
// fontSize = 16.sp, style = TextStyle(
// fontWeight = FontWeight.Medium, fontSize = 16.sp,
// fontFamily = FontFamily(Font(R.font.sf_pro)), fontWeight = FontWeight.Medium,
// color = if (isSystemInDarkTheme()) Color.White else Color.Black fontFamily = FontFamily(Font(R.font.sf_pro)),
// ) color = if (isSystemInDarkTheme()) Color.White else Color.Black
// ) )
// } )
// Spacer(Modifier.height(16.dp)) }
Spacer(Modifier.height(16.dp))
}
StyledButton( StyledButton(
onClick = { onClick = {
viewModel.reconnectFromSavedMac() viewModel.reconnectFromSavedMac()

View File

@@ -382,13 +382,15 @@ fun AppSettingsScreen(
} }
// NavigationButton( if (!BuildConfig.PLAY_BUILD) {
// to = "troubleshooting", NavigationButton(
// name = stringResource(R.string.troubleshooting), to = "troubleshooting",
// navController = navController, name = stringResource(R.string.troubleshooting),
// independent = true, navController = navController,
// description = stringResource(R.string.troubleshooting_description) independent = true,
// ) description = stringResource(R.string.troubleshooting_description)
)
}
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))