fix: androidtv ui bugs and crash

closes #443
This commit is contained in:
Zane Schepke 2024-11-16 23:22:25 -05:00
parent c7a45845d6
commit 72bf0a1979
5 changed files with 19 additions and 16 deletions

View File

@ -5,10 +5,8 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Bolt import androidx.compose.material.icons.rounded.Bolt
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
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.focus.FocusRequester
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@ -19,12 +17,10 @@ import com.zaneschepke.wireguardautotunnel.ui.common.ExpandingRowListItem
import com.zaneschepke.wireguardautotunnel.ui.common.button.ScaledSwitch import com.zaneschepke.wireguardautotunnel.ui.common.button.ScaledSwitch
import com.zaneschepke.wireguardautotunnel.ui.theme.SilverTree import com.zaneschepke.wireguardautotunnel.ui.theme.SilverTree
import com.zaneschepke.wireguardautotunnel.util.extensions.isRunningOnTv import com.zaneschepke.wireguardautotunnel.util.extensions.isRunningOnTv
import com.zaneschepke.wireguardautotunnel.util.extensions.scaledHeight
@Composable @Composable
fun AutoTunnelRowItem(appUiState: AppUiState, onToggle: () -> Unit) { fun AutoTunnelRowItem(appUiState: AppUiState, onToggle: () -> Unit) {
val context = LocalContext.current val context = LocalContext.current
val itemFocusRequester = remember { FocusRequester() }
ExpandingRowListItem( ExpandingRowListItem(
leading = { leading = {
val icon = Icons.Rounded.Bolt val icon = Icons.Rounded.Bolt
@ -33,7 +29,7 @@ fun AutoTunnelRowItem(appUiState: AppUiState, onToggle: () -> Unit) {
icon.name, icon.name,
modifier = modifier =
Modifier Modifier
.size(16.dp.scaledHeight()).scale(1.5f), .size(16.dp).scale(1.5f),
tint = tint =
if (!appUiState.autoTunnelActive) { if (!appUiState.autoTunnelActive) {
Color.Gray Color.Gray
@ -53,7 +49,7 @@ fun AutoTunnelRowItem(appUiState: AppUiState, onToggle: () -> Unit) {
}, },
onClick = { onClick = {
if (context.isRunningOnTv()) { if (context.isRunningOnTv()) {
itemFocusRequester.requestFocus() onToggle()
} }
}, },
isExpanded = false, isExpanded = false,

View File

@ -33,7 +33,6 @@ import com.zaneschepke.wireguardautotunnel.ui.common.navigation.LocalNavControll
import com.zaneschepke.wireguardautotunnel.ui.common.snackbar.SnackbarController import com.zaneschepke.wireguardautotunnel.ui.common.snackbar.SnackbarController
import com.zaneschepke.wireguardautotunnel.util.extensions.asColor import com.zaneschepke.wireguardautotunnel.util.extensions.asColor
import com.zaneschepke.wireguardautotunnel.util.extensions.isRunningOnTv import com.zaneschepke.wireguardautotunnel.util.extensions.isRunningOnTv
import com.zaneschepke.wireguardautotunnel.util.extensions.scaledHeight
@Composable @Composable
fun TunnelRowItem( fun TunnelRowItem(
@ -56,20 +55,19 @@ fun TunnelRowItem(
val itemFocusRequester = remember { FocusRequester() } val itemFocusRequester = remember { FocusRequester() }
ExpandingRowListItem( ExpandingRowListItem(
leading = { leading = {
val circleIcon = Icons.Rounded.Circle
val icon = val icon =
if (tunnel.isPrimaryTunnel) { if (tunnel.isPrimaryTunnel) {
Icons.Rounded.Star Icons.Rounded.Star
} else if (tunnel.isMobileDataTunnel) { } else if (tunnel.isMobileDataTunnel) {
Icons.Rounded.Smartphone Icons.Rounded.Smartphone
} else { } else {
circleIcon Icons.Rounded.Circle
} }
Icon( Icon(
icon, icon,
icon.name, icon.name,
tint = leadingIconColor, tint = leadingIconColor,
modifier = Modifier.size(16.dp.scaledHeight()), modifier = Modifier.size(16.dp),
) )
}, },
text = tunnel.name, text = tunnel.name,

View File

@ -8,6 +8,8 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
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.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Edit import androidx.compose.material.icons.outlined.Edit
import androidx.compose.material.icons.outlined.NetworkPing import androidx.compose.material.icons.outlined.NetworkPing
@ -80,6 +82,7 @@ fun OptionsScreen(optionsViewModel: OptionsViewModel = hiltViewModel(), appUiSta
Modifier Modifier
.fillMaxSize() .fillMaxSize()
.padding(it) .padding(it)
.verticalScroll(rememberScrollState())
.padding(top = 24.dp.scaledHeight()) .padding(top = 24.dp.scaledHeight())
.padding(horizontal = 24.dp.scaledWidth()), .padding(horizontal = 24.dp.scaledWidth()),
) { ) {

View File

@ -1,10 +1,11 @@
package com.zaneschepke.wireguardautotunnel.ui.screens.support package com.zaneschepke.wireguardautotunnel.ui.screens.support
import android.os.Build
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.AttachMoney import androidx.compose.material.icons.filled.AttachMoney
import androidx.compose.material.icons.filled.Book import androidx.compose.material.icons.filled.Book
@ -48,6 +49,7 @@ fun SupportScreen() {
Modifier Modifier
.fillMaxSize() .fillMaxSize()
.padding(top = topPadding) .padding(top = topPadding)
.verticalScroll(rememberScrollState())
.padding(horizontal = 24.dp.scaledWidth()), .padding(horizontal = 24.dp.scaledWidth()),
) { ) {
GroupLabel(stringResource(R.string.thank_you)) GroupLabel(stringResource(R.string.thank_you))
@ -129,7 +131,8 @@ fun SupportScreen() {
title = { title = {
Text( Text(
stringResource(R.string.open_issue), stringResource(R.string.open_issue),
style = MaterialTheme.typography.bodyMedium.copy(MaterialTheme.colorScheme.onSurface)) style = MaterialTheme.typography.bodyMedium.copy(MaterialTheme.colorScheme.onSurface),
)
}, },
trailing = { trailing = {
ForwardButton { ForwardButton {
@ -157,7 +160,7 @@ fun SupportScreen() {
context.launchSupportEmail() context.launchSupportEmail()
}, },
), ),
) ),
) )
if (BuildConfig.FLAVOR == "fdroid") { if (BuildConfig.FLAVOR == "fdroid") {
add( add(
@ -180,7 +183,7 @@ fun SupportScreen() {
), ),
) )
} }
} },
) )
VersionLabel() VersionLabel()
} }

View File

@ -22,6 +22,7 @@ import com.zaneschepke.wireguardautotunnel.util.Constants
private const val BASELINE_HEIGHT = 2201 private const val BASELINE_HEIGHT = 2201
private const val BASELINE_WIDTH = 1080 private const val BASELINE_WIDTH = 1080
private const val BASELINE_DENSITY = 2.625 private const val BASELINE_DENSITY = 2.625
private const val ANDROID_TV_SIZE_MULTIPLIER = 1.5f
fun Context.openWebUrl(url: String): Result<Unit> { fun Context.openWebUrl(url: String): Result<Unit> {
return kotlin.runCatching { return kotlin.runCatching {
@ -47,7 +48,8 @@ val Context.actionBarSize
fun Context.resizeHeight(dp: Dp): Dp { fun Context.resizeHeight(dp: Dp): Dp {
val displayMetrics = resources.displayMetrics val displayMetrics = resources.displayMetrics
val density = displayMetrics.density val density = displayMetrics.density
val height = displayMetrics.heightPixels - this.actionBarSize val height = (displayMetrics.heightPixels - this.actionBarSize) *
(if (isRunningOnTv()) ANDROID_TV_SIZE_MULTIPLIER else 1f)
val resizeHeightPercentage = val resizeHeightPercentage =
(height.toFloat() / BASELINE_HEIGHT) * (BASELINE_DENSITY.toFloat() / density) (height.toFloat() / BASELINE_HEIGHT) * (BASELINE_DENSITY.toFloat() / density)
return dp * resizeHeightPercentage return dp * resizeHeightPercentage
@ -56,7 +58,8 @@ fun Context.resizeHeight(dp: Dp): Dp {
fun Context.resizeHeight(textUnit: TextUnit): TextUnit { fun Context.resizeHeight(textUnit: TextUnit): TextUnit {
val displayMetrics = resources.displayMetrics val displayMetrics = resources.displayMetrics
val density = displayMetrics.density val density = displayMetrics.density
val height = displayMetrics.heightPixels - actionBarSize val height = (displayMetrics.heightPixels - actionBarSize) *
(if (isRunningOnTv()) ANDROID_TV_SIZE_MULTIPLIER else 1f)
val resizeHeightPercentage = val resizeHeightPercentage =
(height.toFloat() / BASELINE_HEIGHT) * (BASELINE_DENSITY.toFloat() / density) (height.toFloat() / BASELINE_HEIGHT) * (BASELINE_DENSITY.toFloat() / density)
return textUnit * resizeHeightPercentage * 1.1 return textUnit * resizeHeightPercentage * 1.1