mirror of
https://github.com/wgtunnel/android.git
synced 2026-07-03 14:07:49 +02:00
refactor: remove nav ripple on mobile, improve key ui
This commit is contained in:
+32
-23
@@ -1,5 +1,7 @@
|
||||
package com.zaneschepke.wireguardautotunnel.ui.navigation.components
|
||||
|
||||
import android.R.attr.button
|
||||
import android.R.attr.theme
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
@@ -7,11 +9,13 @@ import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.zaneschepke.wireguardautotunnel.ui.LocalIsAndroidTV
|
||||
import com.zaneschepke.wireguardautotunnel.ui.common.animations.AnimatedFloatIcon
|
||||
import com.zaneschepke.wireguardautotunnel.ui.navigation.Tab
|
||||
import com.zaneschepke.wireguardautotunnel.ui.theme.SilverTree
|
||||
@@ -19,6 +23,9 @@ import com.zaneschepke.wireguardautotunnel.ui.theme.SilverTree
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Composable
|
||||
fun BottomNavbar(isAutoTunnelActive: Boolean, currentTab: Tab, onTabSelected: (Tab) -> Unit) {
|
||||
val isTv = LocalIsAndroidTV.current
|
||||
val rippleTheme = LocalRippleConfiguration.current
|
||||
val theme = remember { if (isTv) rippleTheme else null }
|
||||
FlexibleBottomAppBar(
|
||||
containerColor = MaterialTheme.colorScheme.surface,
|
||||
contentColor = MaterialTheme.colorScheme.onSurface,
|
||||
@@ -31,29 +38,31 @@ fun BottomNavbar(isAutoTunnelActive: Boolean, currentTab: Tab, onTabSelected: (T
|
||||
val hasBadge = tab == Tab.AUTOTUNNEL && isAutoTunnelActive
|
||||
val button =
|
||||
@Stable @Composable {
|
||||
IconButton(
|
||||
onClick = { onTabSelected(tab) },
|
||||
colors =
|
||||
IconButtonDefaults.iconButtonColors(
|
||||
containerColor = Color.Transparent,
|
||||
contentColor =
|
||||
if (isSelected) {
|
||||
MaterialTheme.colorScheme.primary
|
||||
} else {
|
||||
MaterialTheme.colorScheme.onSurfaceVariant
|
||||
},
|
||||
disabledContainerColor = Color.Transparent,
|
||||
disabledContentColor =
|
||||
MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
),
|
||||
interactionSource = interactionSource,
|
||||
) {
|
||||
AnimatedFloatIcon(
|
||||
activeIcon = tab.activeIcon,
|
||||
inactiveIcon = tab.inactiveIcon,
|
||||
isSelected = isSelected,
|
||||
modifier = Modifier.size(24.dp),
|
||||
)
|
||||
CompositionLocalProvider(LocalRippleConfiguration provides theme) {
|
||||
IconButton(
|
||||
onClick = { onTabSelected(tab) },
|
||||
colors =
|
||||
IconButtonDefaults.iconButtonColors(
|
||||
containerColor = Color.Transparent,
|
||||
contentColor =
|
||||
if (isSelected) {
|
||||
MaterialTheme.colorScheme.primary
|
||||
} else {
|
||||
MaterialTheme.colorScheme.onSurfaceVariant
|
||||
},
|
||||
disabledContainerColor = Color.Transparent,
|
||||
disabledContentColor =
|
||||
MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
),
|
||||
interactionSource = interactionSource,
|
||||
) {
|
||||
AnimatedFloatIcon(
|
||||
activeIcon = tab.activeIcon,
|
||||
inactiveIcon = tab.inactiveIcon,
|
||||
isSelected = isSelected,
|
||||
modifier = Modifier.size(24.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasBadge) {
|
||||
|
||||
+5
-5
@@ -200,17 +200,17 @@ fun SettingsScreen(viewModel: SettingsViewModel = hiltViewModel()) {
|
||||
onClick = { navController.push(Route.ProxySettings) },
|
||||
)
|
||||
}
|
||||
SurfaceRow(
|
||||
leading = { Icon(Icons.Outlined.Android, null) },
|
||||
title = stringResource(R.string.android_integrations),
|
||||
onClick = { navController.push(Route.AndroidIntegrations) },
|
||||
)
|
||||
}
|
||||
Column {
|
||||
GroupLabel(
|
||||
stringResource(R.string.general),
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
)
|
||||
SurfaceRow(
|
||||
leading = { Icon(Icons.Outlined.Android, null) },
|
||||
title = stringResource(R.string.android_integrations),
|
||||
onClick = { navController.push(Route.AndroidIntegrations) },
|
||||
)
|
||||
SurfaceRow(
|
||||
leading = {
|
||||
Icon(Icons.AutoMirrored.Outlined.ViewQuilt, contentDescription = null)
|
||||
|
||||
+45
-23
@@ -1,25 +1,19 @@
|
||||
package com.zaneschepke.wireguardautotunnel.ui.screens.settings.integrations
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.outlined.Launch
|
||||
import androidx.compose.material.icons.filled.AppShortcut
|
||||
import androidx.compose.material.icons.filled.SmartToy
|
||||
import androidx.compose.material.icons.outlined.AdminPanelSettings
|
||||
import androidx.compose.material.icons.outlined.Restore
|
||||
import androidx.compose.material.icons.outlined.VpnLock
|
||||
import androidx.compose.material.icons.outlined.*
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
@@ -34,6 +28,7 @@ import com.zaneschepke.wireguardautotunnel.ui.common.button.SurfaceRow
|
||||
import com.zaneschepke.wireguardautotunnel.ui.common.functions.rememberClipboardHelper
|
||||
import com.zaneschepke.wireguardautotunnel.ui.common.label.GroupLabel
|
||||
import com.zaneschepke.wireguardautotunnel.ui.common.security.SecureScreenFromRecording
|
||||
import com.zaneschepke.wireguardautotunnel.ui.common.text.DescriptionText
|
||||
import com.zaneschepke.wireguardautotunnel.util.extensions.launchVpnSettings
|
||||
import com.zaneschepke.wireguardautotunnel.viewmodel.SettingsViewModel
|
||||
|
||||
@@ -74,6 +69,7 @@ fun AndroidIntegrationsScreen(viewModel: SettingsViewModel = hiltViewModel()) {
|
||||
onClick = {
|
||||
viewModel.setAlwaysOnVpnEnabled(!settingsState.settings.isAlwaysOnVpnEnabled)
|
||||
},
|
||||
description = { DescriptionText(stringResource(R.string.aovpn_description)) },
|
||||
)
|
||||
}
|
||||
Column {
|
||||
@@ -95,6 +91,7 @@ fun AndroidIntegrationsScreen(viewModel: SettingsViewModel = hiltViewModel()) {
|
||||
!settingsState.settings.isRestoreOnBootEnabled
|
||||
)
|
||||
},
|
||||
description = { DescriptionText(stringResource(R.string.tunnel_boot_description)) },
|
||||
)
|
||||
SurfaceRow(
|
||||
leading = { Icon(Icons.Filled.AppShortcut, contentDescription = null) },
|
||||
@@ -117,25 +114,50 @@ fun AndroidIntegrationsScreen(viewModel: SettingsViewModel = hiltViewModel()) {
|
||||
onClick = { viewModel.setRemoteEnabled(it) },
|
||||
)
|
||||
},
|
||||
description = {
|
||||
settingsState.remoteKey?.let { key ->
|
||||
AnimatedVisibility(visible = settingsState.isRemoteEnabled) {
|
||||
title = stringResource(R.string.enable_remote_app_control),
|
||||
onClick = { viewModel.setRemoteEnabled(!settingsState.isRemoteEnabled) },
|
||||
)
|
||||
AnimatedVisibility(settingsState.isRemoteEnabled) {
|
||||
settingsState.remoteKey?.let { key ->
|
||||
var passwordProtected by remember { mutableStateOf(true) }
|
||||
val keyText by
|
||||
remember(passwordProtected) {
|
||||
derivedStateOf {
|
||||
if (passwordProtected) "•".repeat(key.length) else key
|
||||
}
|
||||
}
|
||||
SurfaceRow(
|
||||
leading = { Icon(Icons.Outlined.Key, contentDescription = null) },
|
||||
title = stringResource(R.string.remote_key),
|
||||
description = {
|
||||
Text(
|
||||
text = stringResource(R.string.remote_key_template, key),
|
||||
text = keyText,
|
||||
style =
|
||||
MaterialTheme.typography.bodySmall.copy(
|
||||
color = MaterialTheme.colorScheme.outline
|
||||
),
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
modifier = Modifier.clickable { clipboard.copy(key) },
|
||||
overflow = TextOverflow.Clip,
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
title = stringResource(R.string.enable_remote_app_control),
|
||||
onClick = { viewModel.setRemoteEnabled(!settingsState.isRemoteEnabled) },
|
||||
)
|
||||
},
|
||||
trailing = {
|
||||
Row {
|
||||
IconButton(onClick = { passwordProtected = !passwordProtected }) {
|
||||
Icon(
|
||||
Icons.Outlined.RemoveRedEye,
|
||||
contentDescription = stringResource(R.string.show_password),
|
||||
)
|
||||
}
|
||||
IconButton(onClick = { clipboard.copy(key) }) {
|
||||
Icon(
|
||||
Icons.Outlined.ContentCopy,
|
||||
contentDescription = stringResource(R.string.copy),
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
<string name="unsure_how">if you are unsure how to proceed</string>
|
||||
<string name="see_the">See the</string>
|
||||
<string name="getting_started_guide">getting started guide</string>
|
||||
<string name="restart_at_boot">Restart on boot</string>
|
||||
<string name="restart_at_boot">Start on boot</string>
|
||||
<string name="vpn_denied_dialog_title">Permission Denied</string>
|
||||
<string name="vpn_settings">VPN system settings</string>
|
||||
<string name="always_on_message">VPN connection permission has been denied. Please check the</string>
|
||||
@@ -409,5 +409,8 @@
|
||||
<string name="all_services_disabled">Auto-tunnel and tunnels must be disabled to perform this action.</string>
|
||||
<string name="ddns_success_message">Dynamic DNS endpoint successfully updated.</string>
|
||||
<string name="reliability">Reliability</string>
|
||||
<string name="debounce_description">Delay between rapid changes</string>
|
||||
<string name="debounce_description">Delay between rapid network changes</string>
|
||||
<string name="aovpn_description">Allows Android to start tunnels</string>
|
||||
<string name="tunnel_boot_description">Start the default tunnel on boot</string>
|
||||
<string name="remote_key">Remote key</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user