diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/logs/components/LogList.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/logs/components/LogList.kt index 64af1915..67413a7d 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/logs/components/LogList.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/logs/components/LogList.kt @@ -1,10 +1,12 @@ package com.zaneschepke.wireguardautotunnel.ui.screens.settings.logs.components +import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.material3.scrollbar import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp @@ -18,7 +20,13 @@ fun LogList( ) { LazyColumn( state = lazyColumnListState, - modifier = modifier.padding(horizontal = 12.dp), + modifier = + modifier + .padding(horizontal = 12.dp) + .scrollbar( + state = lazyColumnListState.scrollIndicatorState, + orientation = Orientation.Vertical, + ), verticalArrangement = Arrangement.spacedBy(2.dp), ) { itemsIndexed(items = logs, key = { index, _ -> index }) { _, log -> LogItem(log = log) } diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/support/donate/crypto/AddressesScreen.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/support/donate/crypto/AddressesScreen.kt index 39aa716c..eb177c1b 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/support/donate/crypto/AddressesScreen.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/support/donate/crypto/AddressesScreen.kt @@ -1,10 +1,12 @@ package com.zaneschepke.wireguardautotunnel.ui.screens.support.donate.crypto +import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.scrollbar import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -13,10 +15,17 @@ import com.zaneschepke.wireguardautotunnel.ui.screens.support.donate.crypto.comp @Composable fun AddressesScreen() { + val scrollState = rememberScrollState() Column( horizontalAlignment = Alignment.Start, verticalArrangement = Arrangement.Top, - modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()), + modifier = + Modifier.fillMaxSize() + .verticalScroll(scrollState) + .scrollbar( + state = scrollState.scrollIndicatorState, + orientation = Orientation.Vertical, + ), ) { val clipboard = rememberClipboardHelper() Address.allAddresses.forEach { AddressItem(it) { address -> clipboard.copy(address) } } diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/support/license/components/LicenseList.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/support/license/components/LicenseList.kt index 4c9493d3..94537790 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/support/license/components/LicenseList.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/support/license/components/LicenseList.kt @@ -2,6 +2,7 @@ package com.zaneschepke.wireguardautotunnel.ui.screens.support.license.component import LicenseFileEntry import androidx.compose.foundation.clickable +import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -9,11 +10,13 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.outlined.Launch import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text +import androidx.compose.material3.scrollbar import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -24,8 +27,17 @@ import com.zaneschepke.wireguardautotunnel.util.extensions.openWebUrl @Composable fun LicenseList(licenses: List) { val context = LocalContext.current + val lazyListState = rememberLazyListState() - LazyColumn(modifier = Modifier.fillMaxSize()) { + LazyColumn( + modifier = + Modifier.fillMaxSize() + .scrollbar( + state = lazyListState.scrollIndicatorState, + orientation = Orientation.Vertical, + ), + state = lazyListState, + ) { items(licenses) { entry -> Row( verticalAlignment = Alignment.CenterVertically, diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunnels/components/TunnelList.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunnels/components/TunnelList.kt index b473e598..e7369a49 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunnels/components/TunnelList.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunnels/components/TunnelList.kt @@ -1,6 +1,7 @@ package com.zaneschepke.wireguardautotunnel.ui.screens.tunnels.components import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.gestures.ScrollableDefaults import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.layout.size @@ -12,6 +13,7 @@ import androidx.compose.foundation.rememberOverscrollEffect import androidx.compose.material.icons.Icons import androidx.compose.material.icons.rounded.Circle import androidx.compose.material3.Icon +import androidx.compose.material3.scrollbar import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue @@ -78,7 +80,11 @@ fun TunnelList( viewModel.clearSelectedTunnels() } } - .overscroll(rememberOverscrollEffect()), + .overscroll(rememberOverscrollEffect()) + .scrollbar( + state = lazyListState.scrollIndicatorState, + orientation = Orientation.Vertical, + ), state = lazyListState, userScrollEnabled = true, reverseLayout = false, diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunnels/settings/config/ConfigScreen.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunnels/settings/config/ConfigScreen.kt index b8513191..02c3729b 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunnels/settings/config/ConfigScreen.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunnels/settings/config/ConfigScreen.kt @@ -1,5 +1,6 @@ package com.zaneschepke.wireguardautotunnel.ui.screens.tunnels.settings.config +import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize @@ -9,6 +10,7 @@ import androidx.compose.foundation.text.selection.SelectionContainer import androidx.compose.foundation.verticalScroll import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text +import androidx.compose.material3.scrollbar import androidx.compose.runtime.Composable import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue @@ -57,6 +59,8 @@ fun ConfigScreen( var showQrModal by rememberSaveable { mutableStateOf(false) } + val scrollState = rememberScrollState() + val rawConfig by remember(liveConfig, uiState.activeConfig, uiState.tunnel?.quickConfig) { derivedStateOf { @@ -90,7 +94,13 @@ fun ConfigScreen( Column( horizontalAlignment = Alignment.Start, verticalArrangement = Arrangement.spacedBy(12.dp, Alignment.Top), - modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()), + modifier = + Modifier.fillMaxSize() + .verticalScroll(scrollState) + .scrollbar( + state = scrollState.scrollIndicatorState, + orientation = Orientation.Vertical, + ), ) { val displayText by remember(rawConfig, showKeys) { derivedStateOf { maskSensitive(rawConfig, showKeys) } } diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunnels/settings/config/edit/ConfigEditScreen.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunnels/settings/config/edit/ConfigEditScreen.kt index 559c1dc8..23efdc0d 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunnels/settings/config/edit/ConfigEditScreen.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunnels/settings/config/edit/ConfigEditScreen.kt @@ -1,5 +1,6 @@ package com.zaneschepke.wireguardautotunnel.ui.screens.tunnels.settings.config.edit +import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer @@ -12,6 +13,7 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.HdrAuto import androidx.compose.material3.Icon import androidx.compose.material3.Text +import androidx.compose.material3.scrollbar import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -49,11 +51,12 @@ fun ConfigEditScreen( val uiState by viewModel.collectAsState() if (uiState.isLoading) return - val locale = Locale.current.platformLocale var showSelectionDialog by rememberSaveable { mutableStateOf(false) } + val scrollState = rememberScrollState() + sharedViewModel.collectSideEffect { sideEffect -> when (sideEffect) { is LocalSideEffect.SaveChanges -> { @@ -104,7 +107,14 @@ fun ConfigEditScreen( Column( horizontalAlignment = Alignment.Start, verticalArrangement = Arrangement.spacedBy(16.dp, Alignment.Top), - modifier = Modifier.fillMaxSize().imePadding().verticalScroll(rememberScrollState()), + modifier = + Modifier.fillMaxSize() + .imePadding() + .verticalScroll(scrollState) + .scrollbar( + state = scrollState.scrollIndicatorState, + orientation = Orientation.Vertical, + ), ) { if (uiState.isGlobalConfig) { Column { diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunnels/sort/SortScreen.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunnels/sort/SortScreen.kt index de6ae788..f699410a 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunnels/sort/SortScreen.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunnels/sort/SortScreen.kt @@ -1,5 +1,6 @@ package com.zaneschepke.wireguardautotunnel.ui.screens.tunnels.sort +import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.gestures.ScrollableDefaults import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row @@ -17,6 +18,7 @@ import androidx.compose.material.icons.filled.ArrowUpward import androidx.compose.material.icons.filled.DragHandle import androidx.compose.material3.Icon import androidx.compose.material3.IconButton +import androidx.compose.material3.scrollbar import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -107,7 +109,11 @@ fun SortScreen(sharedViewModel: SharedAppViewModel = koinActivityViewModel()) { Modifier.pointerInput(Unit) { if (tunnelsUiState.tunnels.isEmpty()) return@pointerInput } - .overscroll(rememberOverscrollEffect()), + .overscroll(rememberOverscrollEffect()) + .scrollbar( + state = lazyListState.scrollIndicatorState, + orientation = Orientation.Vertical, + ), state = lazyListState, userScrollEnabled = true, reverseLayout = false, diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/viewmodel/SharedAppViewModel.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/viewmodel/SharedAppViewModel.kt index e368c9c4..e05994b5 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/viewmodel/SharedAppViewModel.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/viewmodel/SharedAppViewModel.kt @@ -73,13 +73,7 @@ class SharedAppViewModel( tunnelCoordinator.backendStatus, selectedTunnelsRepository.flow, ) { tunnels, backendStatus, selectedTuns -> - val activeTunnelIds = backendStatus.activeTunnels.keys - - val sortedTunnels = - tunnels.sortedWith( - compareByDescending { it.id in activeTunnelIds } - .thenBy { it.position } - ) + val sortedTunnels = tunnels.sortedBy { it.position } val displayStates = backendStatus.activeTunnels.mapValues { (_, activeTunnel) -> diff --git a/tunnel/src/main/java/com/zaneschepke/tunnel/backend/WireGuardTunnelEngine.kt b/tunnel/src/main/java/com/zaneschepke/tunnel/backend/WireGuardTunnelEngine.kt index da8a719a..c3066777 100644 --- a/tunnel/src/main/java/com/zaneschepke/tunnel/backend/WireGuardTunnelEngine.kt +++ b/tunnel/src/main/java/com/zaneschepke/tunnel/backend/WireGuardTunnelEngine.kt @@ -101,8 +101,7 @@ internal class WireGuardTunnelEngine(private val serviceHolder: ServiceHolder) : if (!peer.isStaticallyConfigured && peer.endpoint != null) { replacedWithNonRoutable = true val port = peer.endpoint!!.substringAfterLast(":") - peer.copy(endpoint = "$TEST_NET_IP:$port", - persistentKeepalive = 0) + peer.copy(endpoint = "$TEST_NET_IP:$port", persistentKeepalive = 0) } else peer } ) to replacedWithNonRoutable