Improvements to key list activity (#2030)
This commit is contained in:
parent
6d0bff144c
commit
9c5e9c8e43
8 changed files with 117 additions and 15 deletions
|
@ -76,6 +76,7 @@ dependencies {
|
||||||
implementation(libs.androidx.recyclerviewSelection)
|
implementation(libs.androidx.recyclerviewSelection)
|
||||||
implementation(libs.androidx.security)
|
implementation(libs.androidx.security)
|
||||||
implementation(libs.androidx.swiperefreshlayout)
|
implementation(libs.androidx.swiperefreshlayout)
|
||||||
|
implementation(libs.compose.ui.tooling)
|
||||||
implementation(libs.dagger.hilt.android)
|
implementation(libs.dagger.hilt.android)
|
||||||
|
|
||||||
implementation(libs.kotlin.coroutines.android)
|
implementation(libs.kotlin.coroutines.android)
|
||||||
|
|
|
@ -9,11 +9,12 @@ import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import app.passwordstore.crypto.GpgIdentifier
|
import app.passwordstore.crypto.GpgIdentifier
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
public fun KeyList(
|
fun KeyList(
|
||||||
identifiers: List<GpgIdentifier>,
|
identifiers: List<GpgIdentifier>,
|
||||||
onItemClick: (identifier: GpgIdentifier) -> Unit,
|
onItemClick: (identifier: GpgIdentifier) -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
@ -37,3 +38,16 @@ private fun KeyItem(
|
||||||
}
|
}
|
||||||
Box(modifier = modifier.padding(16.dp).fillMaxWidth()) { Text(text = label) }
|
Box(modifier = modifier.padding(16.dp).fillMaxWidth()) { Text(text = label) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
private fun KeyListPreview() {
|
||||||
|
KeyList(
|
||||||
|
identifiers =
|
||||||
|
listOfNotNull(
|
||||||
|
GpgIdentifier.fromString("john.doe@example.com"),
|
||||||
|
GpgIdentifier.fromString("0xB950AE2813841585")
|
||||||
|
),
|
||||||
|
onItemClick = {}
|
||||||
|
)
|
||||||
|
}
|
|
@ -6,10 +6,17 @@ import androidx.activity.compose.setContent
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import app.passwordstore.R
|
||||||
|
import app.passwordstore.ui.APSAppBar
|
||||||
import app.passwordstore.ui.compose.theme.APSTheme
|
import app.passwordstore.ui.compose.theme.APSTheme
|
||||||
|
import app.passwordstore.ui.compose.theme.decideColorScheme
|
||||||
import app.passwordstore.util.viewmodel.PGPKeyListViewModel
|
import app.passwordstore.util.viewmodel.PGPKeyListViewModel
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
|
||||||
|
@ -22,8 +29,18 @@ class PGPKeyListActivity : ComponentActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContent {
|
setContent {
|
||||||
APSTheme {
|
val context = LocalContext.current
|
||||||
Scaffold { paddingValues ->
|
APSTheme(colors = decideColorScheme(context)) {
|
||||||
|
Scaffold(
|
||||||
|
topBar = {
|
||||||
|
APSAppBar(
|
||||||
|
title = stringResource(R.string.activity_label_pgp_key_manager),
|
||||||
|
navigationIcon = painterResource(R.drawable.ic_arrow_back_black_24dp),
|
||||||
|
onNavigationIconClick = { finish() },
|
||||||
|
backgroundColor = MaterialTheme.colorScheme.surface,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
) { paddingValues ->
|
||||||
PGPKeyList(viewModel = viewModel, modifier = Modifier.padding(paddingValues))
|
PGPKeyList(viewModel = viewModel, modifier = Modifier.padding(paddingValues))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
15
app/src/main/res/drawable/ic_arrow_back_black_24dp.xml
Normal file
15
app/src/main/res/drawable/ic_arrow_back_black_24dp.xml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<!--
|
||||||
|
~ Copyright © 2014-2021 The Android Password Store Authors. All Rights Reserved.
|
||||||
|
~ SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
-->
|
||||||
|
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="?attr/colorControlNormal"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFFFF"
|
||||||
|
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z" />
|
||||||
|
</vector>
|
|
@ -20,5 +20,4 @@ dependencies {
|
||||||
api(libs.compose.foundation.layout)
|
api(libs.compose.foundation.layout)
|
||||||
api(libs.compose.material3)
|
api(libs.compose.material3)
|
||||||
api(libs.compose.ui.core)
|
api(libs.compose.ui.core)
|
||||||
implementation(projects.cryptoPgpainless)
|
|
||||||
}
|
}
|
||||||
|
|
36
ui-compose/src/main/kotlin/app/passwordstore/ui/APSAppBar.kt
Normal file
36
ui-compose/src/main/kotlin/app/passwordstore/ui/APSAppBar.kt
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
package app.passwordstore.ui
|
||||||
|
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.SmallTopAppBar
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.painter.Painter
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
public fun APSAppBar(
|
||||||
|
title: String,
|
||||||
|
backgroundColor: Color,
|
||||||
|
navigationIcon: Painter?,
|
||||||
|
onNavigationIconClick: (() -> Unit)?,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
|
SmallTopAppBar(
|
||||||
|
title = { Text(text = title) },
|
||||||
|
navigationIcon = {
|
||||||
|
if (navigationIcon != null) {
|
||||||
|
IconButton(onClick = { onNavigationIconClick?.invoke() }) {
|
||||||
|
Icon(
|
||||||
|
painter = navigationIcon,
|
||||||
|
contentDescription = null,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
colors = TopAppBarDefaults.smallTopAppBarColors(containerColor = backgroundColor),
|
||||||
|
modifier = modifier,
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,12 +1,12 @@
|
||||||
package app.passwordstore.ui.compose.theme
|
package app.passwordstore.ui.compose.theme
|
||||||
|
|
||||||
import androidx.compose.foundation.isSystemInDarkTheme
|
import androidx.compose.material3.ColorScheme
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.darkColorScheme
|
import androidx.compose.material3.darkColorScheme
|
||||||
import androidx.compose.material3.lightColorScheme
|
import androidx.compose.material3.lightColorScheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
|
||||||
private val LightThemeColors =
|
internal val LightThemeColors =
|
||||||
lightColorScheme(
|
lightColorScheme(
|
||||||
primary = md_theme_light_primary,
|
primary = md_theme_light_primary,
|
||||||
onPrimary = md_theme_light_onPrimary,
|
onPrimary = md_theme_light_onPrimary,
|
||||||
|
@ -34,7 +34,7 @@ private val LightThemeColors =
|
||||||
inverseOnSurface = md_theme_light_inverseOnSurface,
|
inverseOnSurface = md_theme_light_inverseOnSurface,
|
||||||
inverseSurface = md_theme_light_inverseSurface,
|
inverseSurface = md_theme_light_inverseSurface,
|
||||||
)
|
)
|
||||||
private val DarkThemeColors =
|
internal val DarkThemeColors =
|
||||||
darkColorScheme(
|
darkColorScheme(
|
||||||
primary = md_theme_dark_primary,
|
primary = md_theme_dark_primary,
|
||||||
onPrimary = md_theme_dark_onPrimary,
|
onPrimary = md_theme_dark_onPrimary,
|
||||||
|
@ -65,15 +65,8 @@ private val DarkThemeColors =
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
public fun APSTheme(
|
public fun APSTheme(
|
||||||
useDarkTheme: Boolean = isSystemInDarkTheme(),
|
colors: ColorScheme,
|
||||||
content: @Composable () -> Unit,
|
content: @Composable () -> Unit,
|
||||||
) {
|
) {
|
||||||
val colors =
|
|
||||||
if (!useDarkTheme) {
|
|
||||||
LightThemeColors
|
|
||||||
} else {
|
|
||||||
DarkThemeColors
|
|
||||||
}
|
|
||||||
|
|
||||||
MaterialTheme(colorScheme = colors, typography = AppTypography, content = content)
|
MaterialTheme(colorScheme = colors, typography = AppTypography, content = content)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package app.passwordstore.ui.compose.theme
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
|
import androidx.compose.material3.ColorScheme
|
||||||
|
import androidx.compose.material3.dynamicDarkColorScheme
|
||||||
|
import androidx.compose.material3.dynamicLightColorScheme
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
public fun decideColorScheme(context: Context): ColorScheme {
|
||||||
|
val isDarkTheme = isSystemInDarkTheme()
|
||||||
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
|
if (isDarkTheme) {
|
||||||
|
dynamicDarkColorScheme(context)
|
||||||
|
} else {
|
||||||
|
dynamicLightColorScheme(context)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isDarkTheme) {
|
||||||
|
DarkThemeColors
|
||||||
|
} else {
|
||||||
|
LightThemeColors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue