Skip to content

Commit

Permalink
Remove main top app bar and relocate actions
Browse files Browse the repository at this point in the history
  • Loading branch information
t895 committed Nov 21, 2024
1 parent de920b6 commit 61614cf
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 76 deletions.
2 changes: 1 addition & 1 deletion app/src/main/kotlin/com/t895/dnsnet/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class MainActivity : AppCompatActivity() {
) {
App(
vm = vm,
onRefresh = ::refresh,
onRefreshHosts = ::refresh,
onLoadDefaults = {
config = Configuration()
config.save()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.TimeoutCancellationException
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeout

Expand All @@ -46,6 +48,9 @@ class RuleDatabaseUpdateWorker(
const val PERIODIC_TAG = "RuleDatabaseUpdatePeriodicWorker"

var lastErrors by atomic<MutableList<String>?>(null)

private val _isRefreshing = MutableStateFlow(false)
val isRefreshing = _isRefreshing.asStateFlow()
}

private val errors = ArrayList<String>()
Expand All @@ -65,6 +70,7 @@ class RuleDatabaseUpdateWorker(

override suspend fun doWork(): Result = withContext(Dispatchers.IO) {
logd("doWork: Begin")
_isRefreshing.value = true
val start = System.currentTimeMillis()
val jobs = mutableListOf<Deferred<Unit>>()
config.hosts.items.forEach {
Expand Down Expand Up @@ -188,6 +194,7 @@ class RuleDatabaseUpdateWorker(
.setAutoCancel(true)
notificationManager.notify(UPDATE_NOTIFICATION_ID, notificationBuilder.build())
}
_isRefreshing.value = false
}

/**
Expand Down
88 changes: 13 additions & 75 deletions app/src/main/kotlin/com/t895/dnsnet/ui/Home.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import androidx.compose.animation.core.tween
import androidx.compose.animation.scaleIn
import androidx.compose.animation.scaleOut
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.displayCutout
Expand All @@ -29,20 +28,14 @@ import androidx.compose.material.icons.automirrored.filled.DriveFileMove
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Android
import androidx.compose.material.icons.filled.Dns
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material.icons.filled.Refresh
import androidx.compose.material.icons.filled.VpnKey
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FabPosition
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteScaffold
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteType
Expand All @@ -58,7 +51,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.testTag
Expand All @@ -85,6 +77,7 @@ import com.t895.dnsnet.HostFile
import com.t895.dnsnet.HostState
import com.t895.dnsnet.R
import com.t895.dnsnet.config
import com.t895.dnsnet.db.RuleDatabaseUpdateWorker
import com.t895.dnsnet.ui.HomeDestinationIcon.Companion.toHomeDestinationIcon
import com.t895.dnsnet.ui.theme.DefaultFabSize
import com.t895.dnsnet.ui.theme.EmphasizedAccelerateEasing
Expand Down Expand Up @@ -172,7 +165,7 @@ open class TopLevelDestination {
@Composable
fun App(
vm: HomeViewModel = viewModel(),
onRefresh: () -> Unit,
onRefreshHosts: () -> Unit,
onLoadDefaults: () -> Unit,
onImport: () -> Unit,
onExport: () -> Unit,
Expand Down Expand Up @@ -351,7 +344,7 @@ fun App(
topLevelNavController = navController,
status = status,
canEditSettings = canEditSettings,
onRefresh = onRefresh,
onRefreshHosts = onRefreshHosts,
onImport = onImport,
onExport = onExport,
onShareLogcat = onShareLogcat,
Expand Down Expand Up @@ -516,7 +509,7 @@ fun EditHostDestination(
@Composable
fun AppPreview() {
App(
onRefresh = {},
onRefreshHosts = {},
onLoadDefaults = {},
onImport = {},
onExport = {},
Expand All @@ -536,7 +529,7 @@ fun HomeScreen(
topLevelNavController: NavHostController,
status: VpnStatus,
canEditSettings: Boolean,
onRefresh: () -> Unit,
onRefreshHosts: () -> Unit,
onImport: () -> Unit,
onExport: () -> Unit,
onShareLogcat: () -> Unit,
Expand Down Expand Up @@ -564,7 +557,6 @@ fun HomeScreen(
}

val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()

val displayCutout = WindowInsets.displayCutout
val localDensity = LocalDensity.current
Expand Down Expand Up @@ -605,68 +597,6 @@ fun HomeScreen(
) {
Scaffold(
contentWindowInsets = navigationSuiteScaffoldContentInsets,
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
TopAppBar(
windowInsets = navigationSuiteScaffoldTopAppBarInsets,
title = {
Text(text = stringResource(R.string.app_name))
},
actions = {
IconButton(onClick = onRefresh) {
Icon(
imageVector = Icons.Default.Refresh,
contentDescription = stringResource(R.string.action_refresh),
)
}

Box {
var expanded by rememberSaveable { mutableStateOf(false) }
IconButton(
onClick = { expanded = true },
) {
Icon(
imageVector = Icons.Default.MoreVert,
contentDescription = stringResource(R.string.more_options),
)
}

DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
) {
val item =
@Composable { text: String, enabled: Boolean, onClick: () -> Unit ->
MenuItem(
text = text,
enabled = enabled,
onClick = {
expanded = false
onClick()
}
)
}

item(
stringResource(R.string.load_defaults),
canEditSettings,
) { vm.onResetSettingsWarning() }
item(
stringResource(R.string.action_import),
canEditSettings,
onImport
)
item(stringResource(R.string.action_export), true, onExport)
item(stringResource(R.string.action_logcat), true, onShareLogcat)
item(stringResource(R.string.action_about), true) {
topLevelNavController.navigate(TopLevelDestination.About)
}
}
}
},
scrollBehavior = scrollBehavior,
)
},
floatingActionButton = {
AnimatedVisibility(
visible = (currentDestination == HomeDestinations.Hosts ||
Expand Down Expand Up @@ -798,6 +728,11 @@ fun HomeScreen(
onOpenBlockLog = {
topLevelNavController.navigate(TopLevelDestination.BlockLog)
},
onImport = onImport,
onExport = onExport,
onShareLogcat = onShareLogcat,
onResetSettings = { vm.onResetSettingsWarning() },
onOpenAbout = { topLevelNavController.navigate(TopLevelDestination.About) },
status = status,
onChangeVpnStatusClick = onTryToggleService,
)
Expand All @@ -806,6 +741,7 @@ fun HomeScreen(
var filterHosts by remember { mutableStateOf(config.hosts.enabled) }
var refreshDaily by remember { mutableStateOf(config.hosts.automaticRefresh) }
val hosts by vm.hosts.collectAsState()
val isRefreshingHosts by RuleDatabaseUpdateWorker.isRefreshing.collectAsState()
HostsScreen(
contentPadding = contentPadding + PaddingValues(ListPadding) +
PaddingValues(bottom = DefaultFabSize + FabPadding),
Expand All @@ -831,6 +767,8 @@ fun HomeScreen(
onHostStateChanged = { host ->
vm.cycleHost(host)
},
isRefreshingHosts = isRefreshingHosts,
onRefreshHosts = onRefreshHosts,
)
}

Expand Down
57 changes: 57 additions & 0 deletions app/src/main/kotlin/com/t895/dnsnet/ui/Hosts.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,20 @@ package com.t895.dnsnet.ui
import android.content.Intent
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.items
Expand All @@ -30,10 +36,12 @@ import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.AttachFile
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.Save
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExposedDropdownMenuBox
import androidx.compose.material3.ExposedDropdownMenuDefaults
import androidx.compose.material3.FilledTonalButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
Expand Down Expand Up @@ -66,6 +74,9 @@ import com.t895.dnsnet.HostState
import com.t895.dnsnet.HostState.Companion.toHostState
import com.t895.dnsnet.R
import com.t895.dnsnet.ui.theme.DnsNetTheme
import com.t895.dnsnet.ui.theme.EmphasizedAccelerateEasing
import com.t895.dnsnet.ui.theme.HideRefreshHostFilesSpinner
import com.t895.dnsnet.ui.theme.ShowRefreshHostFilesSpinner

@Composable
private fun IconText(
Expand Down Expand Up @@ -103,6 +114,8 @@ fun HostsScreen(
hosts: List<Host>,
onHostClick: (Host) -> Unit,
onHostStateChanged: (Host) -> Unit,
isRefreshingHosts: Boolean,
onRefreshHosts: () -> Unit,
) {
val itemStateStrings = stringArrayResource(R.array.item_states)
val getStateString = { state: HostState ->
Expand Down Expand Up @@ -158,6 +171,48 @@ fun HostsScreen(
onCheckedChange = { onRefreshDailyClick() },
)
}

Spacer(modifier = Modifier.padding(vertical = 4.dp))

Box(
modifier = Modifier.fillMaxWidth(),
contentAlignment = Alignment.Center,
) {
Row(
modifier = Modifier.animateContentSize(
animationSpec = tween(
durationMillis = 1,
easing = EmphasizedAccelerateEasing,
)
),
verticalAlignment = Alignment.CenterVertically,
) {
FilledTonalButton(
onClick = {
if (!isRefreshingHosts) {
onRefreshHosts()
}
},
) {
Text(text = stringResource(R.string.action_refresh))
}

AnimatedVisibility(
visible = isRefreshingHosts,
enter = ShowRefreshHostFilesSpinner,
exit = HideRefreshHostFilesSpinner,
) {
Row(
modifier = Modifier.wrapContentSize(),
verticalAlignment = Alignment.CenterVertically,
) {
Spacer(modifier = Modifier.padding(horizontal = 8.dp))
CircularProgressIndicator(modifier = Modifier.size(24.dp))
}
}
}
}

Spacer(modifier = Modifier.padding(vertical = 4.dp))
}

Expand Down Expand Up @@ -226,6 +281,8 @@ private fun HostsScreenPreview() {
hosts = items,
onHostClick = {},
onHostStateChanged = {},
isRefreshingHosts = false,
onRefreshHosts = {},
)
}
}
Expand Down
Loading

0 comments on commit 61614cf

Please sign in to comment.