Add long-press copy on App and Core version items
This commit is contained in:
@@ -9,9 +9,13 @@ import android.net.Uri
|
|||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.text.format.Formatter
|
import android.text.format.Formatter
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.combinedClickable
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
@@ -26,6 +30,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
|||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||||
|
import androidx.compose.material.icons.filled.ContentCopy
|
||||||
import androidx.compose.material.icons.outlined.AdminPanelSettings
|
import androidx.compose.material.icons.outlined.AdminPanelSettings
|
||||||
import androidx.compose.material.icons.outlined.Autorenew
|
import androidx.compose.material.icons.outlined.Autorenew
|
||||||
import androidx.compose.material.icons.outlined.DeleteForever
|
import androidx.compose.material.icons.outlined.DeleteForever
|
||||||
@@ -44,6 +49,8 @@ import androidx.compose.material3.Badge
|
|||||||
import androidx.compose.material3.Card
|
import androidx.compose.material3.Card
|
||||||
import androidx.compose.material3.CardDefaults
|
import androidx.compose.material3.CardDefaults
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
|
import androidx.compose.material3.DropdownMenu
|
||||||
|
import androidx.compose.material3.DropdownMenuItem
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
@@ -83,6 +90,7 @@ import io.nekohasekai.sfa.R
|
|||||||
import io.nekohasekai.sfa.compose.component.UpdateAvailableDialog
|
import io.nekohasekai.sfa.compose.component.UpdateAvailableDialog
|
||||||
import io.nekohasekai.sfa.compose.topbar.OverrideTopBar
|
import io.nekohasekai.sfa.compose.topbar.OverrideTopBar
|
||||||
import io.nekohasekai.sfa.database.Settings
|
import io.nekohasekai.sfa.database.Settings
|
||||||
|
import io.nekohasekai.sfa.ktx.clipboardText
|
||||||
import io.nekohasekai.sfa.update.UpdateCheckException
|
import io.nekohasekai.sfa.update.UpdateCheckException
|
||||||
import io.nekohasekai.sfa.update.UpdateSource
|
import io.nekohasekai.sfa.update.UpdateSource
|
||||||
import io.nekohasekai.sfa.update.UpdateState
|
import io.nekohasekai.sfa.update.UpdateState
|
||||||
@@ -99,7 +107,7 @@ import java.io.File
|
|||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import android.provider.Settings as AndroidSettings
|
import android.provider.Settings as AndroidSettings
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun AppSettingsScreen(navController: NavController) {
|
fun AppSettingsScreen(navController: NavController) {
|
||||||
OverrideTopBar {
|
OverrideTopBar {
|
||||||
@@ -142,6 +150,7 @@ fun AppSettingsScreen(navController: NavController) {
|
|||||||
var downloadJob by remember { mutableStateOf<Job?>(null) }
|
var downloadJob by remember { mutableStateOf<Job?>(null) }
|
||||||
var downloadError by remember { mutableStateOf<String?>(null) }
|
var downloadError by remember { mutableStateOf<String?>(null) }
|
||||||
var showUpdateAvailableDialog by remember { mutableStateOf(false) }
|
var showUpdateAvailableDialog by remember { mutableStateOf(false) }
|
||||||
|
var showVersionMenu by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
var notificationEnabled by remember { mutableStateOf(true) }
|
var notificationEnabled by remember { mutableStateOf(true) }
|
||||||
var dynamicNotification by remember { mutableStateOf(Settings.dynamicNotification) }
|
var dynamicNotification by remember { mutableStateOf(Settings.dynamicNotification) }
|
||||||
@@ -433,6 +442,7 @@ fun AppSettingsScreen(navController: NavController) {
|
|||||||
),
|
),
|
||||||
) {
|
) {
|
||||||
Column {
|
Column {
|
||||||
|
Box {
|
||||||
ListItem(
|
ListItem(
|
||||||
headlineContent = {
|
headlineContent = {
|
||||||
Text(
|
Text(
|
||||||
@@ -460,12 +470,42 @@ fun AppSettingsScreen(navController: NavController) {
|
|||||||
},
|
},
|
||||||
modifier =
|
modifier =
|
||||||
Modifier
|
Modifier
|
||||||
.clip(RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp)),
|
.clip(RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp))
|
||||||
|
.combinedClickable(
|
||||||
|
onClick = {},
|
||||||
|
onLongClick = { showVersionMenu = true },
|
||||||
|
),
|
||||||
colors =
|
colors =
|
||||||
ListItemDefaults.colors(
|
ListItemDefaults.colors(
|
||||||
containerColor = Color.Transparent,
|
containerColor = Color.Transparent,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
Box(modifier = Modifier.align(Alignment.BottomEnd)) {
|
||||||
|
DropdownMenu(
|
||||||
|
expanded = showVersionMenu,
|
||||||
|
onDismissRequest = { showVersionMenu = false },
|
||||||
|
) {
|
||||||
|
DropdownMenuItem(
|
||||||
|
text = { Text(stringResource(R.string.per_app_proxy_action_copy)) },
|
||||||
|
leadingIcon = {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Filled.ContentCopy,
|
||||||
|
contentDescription = null,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onClick = {
|
||||||
|
clipboardText = BuildConfig.VERSION_NAME
|
||||||
|
Toast.makeText(
|
||||||
|
context,
|
||||||
|
R.string.copied_to_clipboard,
|
||||||
|
Toast.LENGTH_SHORT,
|
||||||
|
).show()
|
||||||
|
showVersionMenu = false
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ListItem(
|
ListItem(
|
||||||
headlineContent = {
|
headlineContent = {
|
||||||
|
|||||||
@@ -5,8 +5,11 @@ import android.content.Context
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.provider.DocumentsContract
|
import android.provider.DocumentsContract
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.combinedClickable
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
@@ -18,6 +21,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
|||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||||
|
import androidx.compose.material.icons.filled.ContentCopy
|
||||||
import androidx.compose.material.icons.outlined.DeleteForever
|
import androidx.compose.material.icons.outlined.DeleteForever
|
||||||
import androidx.compose.material.icons.outlined.FolderOpen
|
import androidx.compose.material.icons.outlined.FolderOpen
|
||||||
import androidx.compose.material.icons.outlined.Info
|
import androidx.compose.material.icons.outlined.Info
|
||||||
@@ -25,6 +29,8 @@ import androidx.compose.material.icons.outlined.Storage
|
|||||||
import androidx.compose.material.icons.outlined.WarningAmber
|
import androidx.compose.material.icons.outlined.WarningAmber
|
||||||
import androidx.compose.material3.Card
|
import androidx.compose.material3.Card
|
||||||
import androidx.compose.material3.CardDefaults
|
import androidx.compose.material3.CardDefaults
|
||||||
|
import androidx.compose.material3.DropdownMenu
|
||||||
|
import androidx.compose.material3.DropdownMenuItem
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
@@ -41,6 +47,7 @@ import androidx.compose.runtime.mutableStateOf
|
|||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
@@ -52,11 +59,12 @@ import io.nekohasekai.libbox.Libbox
|
|||||||
import io.nekohasekai.sfa.R
|
import io.nekohasekai.sfa.R
|
||||||
import io.nekohasekai.sfa.compose.topbar.OverrideTopBar
|
import io.nekohasekai.sfa.compose.topbar.OverrideTopBar
|
||||||
import io.nekohasekai.sfa.database.Settings
|
import io.nekohasekai.sfa.database.Settings
|
||||||
|
import io.nekohasekai.sfa.ktx.clipboardText
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun CoreSettingsScreen(navController: NavController) {
|
fun CoreSettingsScreen(navController: NavController) {
|
||||||
OverrideTopBar {
|
OverrideTopBar {
|
||||||
@@ -77,6 +85,7 @@ fun CoreSettingsScreen(navController: NavController) {
|
|||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
var dataSize by remember { mutableStateOf("") }
|
var dataSize by remember { mutableStateOf("") }
|
||||||
val version = remember { Libbox.version() }
|
val version = remember { Libbox.version() }
|
||||||
|
var showVersionMenu by remember { mutableStateOf(false) }
|
||||||
var disableDeprecatedWarnings by remember { mutableStateOf(Settings.disableDeprecatedWarnings) }
|
var disableDeprecatedWarnings by remember { mutableStateOf(Settings.disableDeprecatedWarnings) }
|
||||||
|
|
||||||
// Calculate data size on launch
|
// Calculate data size on launch
|
||||||
@@ -114,6 +123,7 @@ fun CoreSettingsScreen(navController: NavController) {
|
|||||||
) {
|
) {
|
||||||
Column {
|
Column {
|
||||||
// Version Info
|
// Version Info
|
||||||
|
Box {
|
||||||
ListItem(
|
ListItem(
|
||||||
headlineContent = {
|
headlineContent = {
|
||||||
Text(
|
Text(
|
||||||
@@ -136,12 +146,43 @@ fun CoreSettingsScreen(navController: NavController) {
|
|||||||
tint = MaterialTheme.colorScheme.primary,
|
tint = MaterialTheme.colorScheme.primary,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
modifier = Modifier.clip(RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp)),
|
modifier = Modifier
|
||||||
|
.clip(RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp))
|
||||||
|
.combinedClickable(
|
||||||
|
onClick = {},
|
||||||
|
onLongClick = { showVersionMenu = true },
|
||||||
|
),
|
||||||
colors =
|
colors =
|
||||||
ListItemDefaults.colors(
|
ListItemDefaults.colors(
|
||||||
containerColor = Color.Transparent,
|
containerColor = Color.Transparent,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
Box(modifier = Modifier.align(Alignment.BottomEnd)) {
|
||||||
|
DropdownMenu(
|
||||||
|
expanded = showVersionMenu,
|
||||||
|
onDismissRequest = { showVersionMenu = false },
|
||||||
|
) {
|
||||||
|
DropdownMenuItem(
|
||||||
|
text = { Text(stringResource(R.string.per_app_proxy_action_copy)) },
|
||||||
|
leadingIcon = {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Filled.ContentCopy,
|
||||||
|
contentDescription = null,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onClick = {
|
||||||
|
clipboardText = version
|
||||||
|
Toast.makeText(
|
||||||
|
context,
|
||||||
|
R.string.copied_to_clipboard,
|
||||||
|
Toast.LENGTH_SHORT,
|
||||||
|
).show()
|
||||||
|
showVersionMenu = false
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Data Size
|
// Data Size
|
||||||
ListItem(
|
ListItem(
|
||||||
|
|||||||
Reference in New Issue
Block a user