improve bottom nav bar on home

This commit is contained in:
Yogesh Choudhary Paliyal
2025-05-18 15:34:54 +05:30
parent a918b295a2
commit 7ae95ac8b9
22 changed files with 168 additions and 189 deletions

View File

@@ -17,11 +17,11 @@ class MyApplication : CommonMyApplication() {
private var timeToLaunchActivity : Long? = null
fun activityLaunchTriggered() {
fun knownActivityLaunchTriggered() {
timeToLaunchActivity = SystemClock.uptimeMillis()
}
fun isActivityLaunchTriggered() : Boolean {
fun isKnownActivityLaunchTriggered() : Boolean {
val mTimeToLaunchActivity = timeToLaunchActivity ?: return false
timeToLaunchActivity = null
return SystemClock.uptimeMillis() - mTimeToLaunchActivity < 1000

View File

@@ -30,11 +30,13 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
@@ -47,6 +49,7 @@ import com.yogeshpaliyal.common.utils.openLink
import com.yogeshpaliyal.keypass.BuildConfig
import com.yogeshpaliyal.keypass.R
import com.yogeshpaliyal.keypass.ui.commonComponents.DefaultBottomAppBar
import com.yogeshpaliyal.keypass.ui.commonComponents.DefaultTopAppBar
import com.yogeshpaliyal.keypass.ui.commonComponents.PreferenceItem
import com.yogeshpaliyal.keypass.ui.redux.actions.Action
import com.yogeshpaliyal.keypass.ui.redux.actions.GoBackAction
@@ -54,15 +57,12 @@ import org.reduxkotlin.compose.rememberTypedDispatcher
@Composable
fun AboutScreen() {
val dispatchAction = rememberTypedDispatcher<Action>()
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
Scaffold(
bottomBar = {
// Add back button to bottom bar
DefaultBottomAppBar(
showBackButton = true
)
}
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
DefaultTopAppBar(title = R.string.app_name, scrollBehavior = scrollBehavior)
},
) { contentPadding ->
Surface(
modifier = Modifier
@@ -98,9 +98,11 @@ private fun MainContent() {
horizontalAlignment = Alignment.CenterHorizontally
) {
// App Info Card
ElevatedCard(
Card(
modifier = Modifier.fillMaxWidth(),
elevation = CardDefaults.elevatedCardElevation(defaultElevation = 2.dp),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surfaceContainerLow
),
shape = RoundedCornerShape(16.dp)
) {
Column(
@@ -124,13 +126,13 @@ private fun MainContent() {
Spacer(modifier = Modifier.height(16.dp))
// App Name
Text(
text = stringResource(id = R.string.app_name),
style = MaterialTheme.typography.headlineMedium,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.primary
)
// // App Name
// Text(
// text = stringResource(id = R.string.app_name),
// style = MaterialTheme.typography.headlineMedium,
// fontWeight = FontWeight.Bold,
// color = MaterialTheme.colorScheme.primary
// )
Spacer(modifier = Modifier.height(4.dp))
@@ -203,9 +205,11 @@ private fun MainContent() {
textAlign = TextAlign.Start
)
ElevatedCard(
Card(
modifier = Modifier.fillMaxWidth(),
elevation = CardDefaults.elevatedCardElevation(defaultElevation = 2.dp),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surfaceContainerLow
),
shape = RoundedCornerShape(16.dp)
) {
Column(modifier = Modifier.fillMaxWidth()) {

View File

@@ -15,7 +15,7 @@ class KeyPassBackupDirectoryPick : ActivityResultContracts.OpenDocument() {
Intent.FLAG_GRANT_WRITE_URI_PERMISSION or
Intent.FLAG_GRANT_READ_URI_PERMISSION
)
(context.applicationContext as? MyApplication)?.activityLaunchTriggered()
(context.applicationContext as? MyApplication)?.knownActivityLaunchTriggered()
return intent
}

View File

@@ -197,11 +197,13 @@ fun BackupImporter(state: BackupImporterState, mViewModel: DashboardViewModel =
@Composable
private fun ImportOptionCard(option: ImportOption, onClick: () -> Unit) {
val desc = option.importer.getImporterDesc()
ElevatedCard(
Card(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp),
elevation = CardDefaults.elevatedCardElevation(defaultElevation = 1.dp),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surfaceContainerLow
),
onClick = onClick,
shape = RoundedCornerShape(12.dp)
) {

View File

@@ -1,10 +1,6 @@
package com.yogeshpaliyal.keypass.ui.changeDefaultPasswordLength
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
@@ -12,25 +8,17 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.ArrowBackIosNew
import androidx.compose.material.icons.rounded.Done
import androidx.compose.material.icons.rounded.Info
import androidx.compose.material3.BottomAppBar
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.derivedStateOf
@@ -50,6 +38,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.yogeshpaliyal.keypass.R
import com.yogeshpaliyal.keypass.ui.commonComponents.DefaultTopAppBar
import com.yogeshpaliyal.keypass.ui.generate.ui.components.PasswordLengthInput
import com.yogeshpaliyal.keypass.ui.redux.actions.Action
import com.yogeshpaliyal.keypass.ui.redux.actions.GoBackAction
@@ -66,7 +55,13 @@ fun ChangeDefaultPasswordLengthScreen(
val state by viewModel.viewState.collectAsState()
Scaffold(
bottomBar = { BottomBar(dispatchAction, viewModel) }
topBar = {
DefaultTopAppBar(
title = R.string.choose_default_password_length,
subtitle = R.string.choose_default_password_length_desc
)
},
floatingActionButton = { FloatingActionButton(dispatchAction, viewModel) }
) { contentPadding ->
Surface(
modifier = Modifier
@@ -97,16 +92,11 @@ private fun ChangeDefaultPasswordLengthContent(
) {
// Password length input with improved UI
Text(
text = stringResource(R.string.choose_default_password_length),
style = MaterialTheme.typography.headlineSmall,
fontWeight = FontWeight.SemiBold,
textAlign = TextAlign.Start
)
ElevatedCard(
Card(
modifier = Modifier.fillMaxWidth(),
elevation = CardDefaults.elevatedCardElevation(defaultElevation = 1.dp)
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surfaceContainerLow
)
) {
Column(
modifier = Modifier.padding(16.dp),
@@ -130,38 +120,6 @@ private fun ChangeDefaultPasswordLengthContent(
}
Spacer(modifier = Modifier.height(8.dp))
// Information card
InfoCard()
}
}
@Composable
private fun InfoCard() {
Card(
modifier = Modifier.fillMaxWidth(),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.secondaryContainer.copy(alpha = 0.7f)
)
) {
Row(
modifier = Modifier.padding(16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
imageVector = Icons.Rounded.Info,
contentDescription = null,
tint = MaterialTheme.colorScheme.onSecondaryContainer,
modifier = Modifier.size(24.dp)
)
Text(
text = "This length will be used as default when generating new passwords. " +
"Longer passwords provide better security.",
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSecondaryContainer,
modifier = Modifier.padding(start = 12.dp)
)
}
}
}
@@ -231,44 +189,29 @@ private fun PasswordStrengthIndicator(strength: PasswordStrength) {
}
@Composable
private fun BottomBar(
private fun FloatingActionButton(
dispatchAction: TypedDispatcher<Action>,
viewModel: ChangeDefaultPasswordLengthViewModel
) {
val context = LocalContext.current
BottomAppBar(
actions = {
// Add back button on the left side
IconButton(
onClick = { dispatchAction(GoBackAction) }
) {
Icon(
painter = rememberVectorPainter(image = Icons.Rounded.ArrowBackIosNew),
contentDescription = "Cancel",
tint = MaterialTheme.colorScheme.onSurfaceVariant
)
FloatingActionButton(
modifier = Modifier.testTag("save"),
onClick = {
// Save new password length
viewModel.updatePasswordLength(context) {
// Close screen
dispatchAction(GoBackAction)
}
},
floatingActionButton = {
FloatingActionButton(
modifier = Modifier.testTag("save"),
onClick = {
// Save new password length
viewModel.updatePasswordLength(context) {
// Close screen
dispatchAction(GoBackAction)
}
},
containerColor = MaterialTheme.colorScheme.primaryContainer
) {
Icon(
painter = rememberVectorPainter(image = Icons.Rounded.Done),
contentDescription = "Save Changes",
tint = MaterialTheme.colorScheme.onPrimaryContainer
)
}
}
)
containerColor = MaterialTheme.colorScheme.primaryContainer
) {
Icon(
painter = rememberVectorPainter(image = Icons.Rounded.Done),
contentDescription = "Save Changes",
tint = MaterialTheme.colorScheme.onPrimaryContainer
)
}
}
@Preview(name = "ChangeDefaultPasswordLength", showBackground = true, showSystemUi = true)

View File

@@ -149,7 +149,7 @@ fun ChangePassword(state: ChangeAppPasswordState) {
Card(
modifier = Modifier.fillMaxWidth(),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.secondaryContainer
containerColor = MaterialTheme.colorScheme.surfaceContainerLow
)
) {
Column(
@@ -176,7 +176,10 @@ fun ChangePassword(state: ChangeAppPasswordState) {
// Password input fields in a card
Card(
modifier = Modifier.fillMaxWidth()
modifier = Modifier.fillMaxWidth(),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surfaceContainerLow
)
) {
Column(
modifier = Modifier

View File

@@ -9,9 +9,11 @@ import androidx.compose.material3.IconButton
import androidx.compose.material3.LargeFlexibleTopAppBar
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.res.stringResource
import com.yogeshpaliyal.keypass.ui.redux.actions.Action
@@ -36,12 +38,11 @@ fun DefaultTopAppBar(
text = stringResource(id = subtitle),
)
}
}, title = {
}, colors = TopAppBarDefaults.topAppBarColors(containerColor = Color.Unspecified, scrolledContainerColor = MaterialTheme.colorScheme.surface),
title = {
Text(
text = stringResource(id = title),
)
}, actions = {
extraAction?.invoke(this)
}, navigationIcon = {

View File

@@ -33,6 +33,7 @@ import com.yogeshpaliyal.common.constants.ScannerType
import com.yogeshpaliyal.common.utils.TOTPHelper
import com.yogeshpaliyal.keypass.R
import com.yogeshpaliyal.keypass.ui.detail.components.BottomBar
import com.yogeshpaliyal.keypass.ui.detail.components.FABAddAccount
import com.yogeshpaliyal.keypass.ui.detail.components.Fields
import com.yogeshpaliyal.keypass.ui.redux.actions.CopyToClipboard
import com.yogeshpaliyal.keypass.ui.redux.actions.GoBackAction
@@ -104,7 +105,7 @@ fun AccountDetailPage(
}
}
Scaffold(
bottomBar = {
topBar = {
BottomBar(
accountModel,
backPressed = goBack,
@@ -120,7 +121,10 @@ fun AccountDetailPage(
openPasswordConfiguration = {
dispatchAction(NavigationAction(PasswordGeneratorState()))
}
) {
)
},
floatingActionButton = {
FABAddAccount{
viewModel.insertOrUpdate(accountModel, goBack)
}
}

View File

@@ -20,7 +20,7 @@ class QRScanner : ActivityResultContract<Int, QRScannerResult>() {
} else {
null
}
(context.applicationContext as? MyApplication)?.activityLaunchTriggered()
(context.applicationContext as? MyApplication)?.knownActivityLaunchTriggered()
return intentIntegration?.setPrompt("")?.createScanIntent() ?: Intent()
}

View File

@@ -7,18 +7,24 @@ import androidx.compose.material.icons.rounded.ArrowBackIosNew
import androidx.compose.material.icons.rounded.Delete
import androidx.compose.material.icons.rounded.Done
import androidx.compose.material3.BottomAppBar
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LargeFlexibleTopAppBar
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import com.yogeshpaliyal.common.data.AccountModel
import com.yogeshpaliyal.keypass.R
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun BottomBar(
accountModel: AccountModel,
@@ -26,12 +32,17 @@ fun BottomBar(
onDeleteAccount: () -> Unit,
generateQrCodeClicked: () -> Unit,
openPasswordConfiguration: () -> Unit,
onSaveClicked: () -> Unit
) {
val openDialog = remember { mutableStateOf(false) }
BottomAppBar(
actions = {
LargeFlexibleTopAppBar(
title = {
Text(
text = stringResource(if (accountModel.id == null) R.string.create_account else R.string.edit_account),
color = MaterialTheme.colorScheme.onSurface
)
},
navigationIcon = {
IconButton(onClick = backPressed) {
Icon(
painter = rememberVectorPainter(image = Icons.Rounded.ArrowBackIosNew),
@@ -39,6 +50,8 @@ fun BottomBar(
tint = MaterialTheme.colorScheme.onSurface
)
}
},
actions = {
IconButton(
modifier = Modifier.testTag("action_configure_password"),
@@ -73,14 +86,6 @@ fun BottomBar(
)
}
}
},
floatingActionButton = {
FloatingActionButton(modifier = Modifier.testTag("save"), onClick = onSaveClicked) {
Icon(
painter = rememberVectorPainter(image = Icons.Rounded.Done),
contentDescription = "Save Changes"
)
}
}
)
@@ -92,3 +97,13 @@ fun BottomBar(
onDeleteAccount
)
}
@Composable
fun FABAddAccount(onSaveClicked: () -> Unit) {
FloatingActionButton(modifier = Modifier.testTag("save"), onClick = onSaveClicked) {
Icon(
painter = rememberVectorPainter(image = Icons.Rounded.Done),
contentDescription = "Save Changes"
)
}
}

View File

@@ -41,7 +41,7 @@ class BottomNavViewModel @Inject constructor(
private fun postListUpdate() {
val newList = if (tagsList.isNullOrEmpty().not()) {
NavigationModel.navigationMenuItems + NavigationModelItem.NavDivider("Tags") + (
mutableListOf<NavigationModelItem>() + NavigationModelItem.NavDivider("Tags", true) + (
tagsList?.filter { it != null }
?.map { NavigationModelItem.NavTagItem(it) } ?: listOf()
)

View File

@@ -112,7 +112,7 @@ class DashboardComposeActivity : AppCompatActivity() {
}
@Composable
fun Dashboard() {
fun Dashboard(viewModel: BottomNavViewModel = androidx.lifecycle.viewmodel.compose.viewModel()) {
val systemBackPress by selectState<KeyPassState, Boolean> { this.systemBackPress }
val context = LocalContext.current
@@ -124,7 +124,7 @@ fun Dashboard() {
// Call this like any other SideEffect in your composable
LifecycleEventEffect(Lifecycle.Event.ON_PAUSE) {
if (userSettings.autoLockEnabled == true &&
(context.applicationContext as? MyApplication)?.isActivityLaunchTriggered() == false) {
(context.applicationContext as? MyApplication)?.isKnownActivityLaunchTriggered() == false) {
dispatch(NavigationAction(AuthState.Login))
}
}
@@ -142,12 +142,12 @@ fun Dashboard() {
onDispose { dispatch(UpdateContextAction(null)) }
}
Scaffold(bottomBar = { KeyPassBottomBar() }, modifier = Modifier.safeDrawingPadding()) {
Scaffold(bottomBar = { KeyPassBottomBar(viewModel) }, modifier = Modifier.safeDrawingPadding()) {
paddingValues ->
Surface(modifier = Modifier.padding(paddingValues)) {
CurrentPage()
DashboardBottomSheet()
DashboardBottomSheet(viewModel)
}
}
}

View File

@@ -1,6 +1,7 @@
package com.yogeshpaliyal.keypass.ui.nav
import com.yogeshpaliyal.keypass.R
import com.yogeshpaliyal.keypass.ui.nav.NavigationModelItem.NavMenuItem
import com.yogeshpaliyal.keypass.ui.redux.actions.IntentNavigation
import com.yogeshpaliyal.keypass.ui.redux.actions.NavigationAction
import com.yogeshpaliyal.keypass.ui.redux.states.HomeState
@@ -11,20 +12,20 @@ object NavigationModel {
const val GENERATE_PASSWORD = 1
const val ADD_TOPT = 2
var navigationMenuItems = mutableListOf(
NavigationModelItem.NavMenuItem(
id = HOME,
icon = R.drawable.ic_twotone_home_24,
titleRes = R.string.home,
checked = false,
action = NavigationAction(HomeState(), true)
),
NavigationModelItem.NavMenuItem(
id = GENERATE_PASSWORD,
icon = R.drawable.ic_twotone_vpn_key_24,
titleRes = R.string.generate_password,
checked = false,
action = IntentNavigation.GeneratePassword
)
var navigationMenuItems = mutableListOf<NavMenuItem>(
// NavigationModelItem.NavMenuItem(
// id = HOME,
// icon = R.drawable.ic_twotone_home_24,
// titleRes = R.string.home,
// checked = false,
// action = NavigationAction(HomeState(), true)
// ),
// NavigationModelItem.NavMenuItem(
// id = GENERATE_PASSWORD,
// icon = R.drawable.ic_twotone_vpn_key_24,
// titleRes = R.string.generate_password,
// checked = false,
// action = IntentNavigation.GeneratePassword
// )
)
}

View File

@@ -18,7 +18,7 @@ sealed class NavigationModelItem {
* A class which is used to show a section divider (a subtitle and underline) between
* sections of different NavigationModelItem types.
*/
data class NavDivider(val title: String) : NavigationModelItem()
data class NavDivider(val title: String, val hideDivider: Boolean = false) : NavigationModelItem()
data class NavTagItem(val tag: String) : NavigationModelItem()
}

View File

@@ -21,19 +21,19 @@ import org.reduxkotlin.compose.rememberDispatcher
import org.reduxkotlin.compose.selectState
@Composable
fun DashboardBottomSheet() {
fun DashboardBottomSheet(viewModel: BottomNavViewModel) {
val bottomSheetState by selectState<KeyPassState, BottomSheetState?> { this.bottomSheet }
if (bottomSheetState?.isBottomSheetOpen != true) {
return
}
OptionBottomBar()
OptionBottomBar(viewModel)
}
@Composable
fun OptionBottomBar(
viewModel: BottomNavViewModel = androidx.lifecycle.viewmodel.compose.viewModel()
viewModel: BottomNavViewModel
) {
val dispatchAction = rememberDispatcher()

View File

@@ -1,13 +1,11 @@
package com.yogeshpaliyal.keypass.ui.nav.components
import androidx.compose.foundation.selection.selectable
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Home
import androidx.compose.material.icons.outlined.Menu
import androidx.compose.material.icons.outlined.Settings
import androidx.compose.material.icons.outlined.VpnKey
import androidx.compose.material.icons.rounded.Add
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
@@ -16,11 +14,14 @@ import androidx.compose.material3.IconToggleButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.platform.testTag
import com.yogeshpaliyal.keypass.ui.commonComponents.DefaultBottomAppBar
import com.yogeshpaliyal.keypass.ui.nav.BottomNavViewModel
import com.yogeshpaliyal.keypass.ui.redux.actions.BottomSheetAction
import com.yogeshpaliyal.keypass.ui.redux.actions.IntentNavigation
import com.yogeshpaliyal.keypass.ui.redux.actions.NavigationAction
import com.yogeshpaliyal.keypass.ui.redux.states.AccountDetailState
import com.yogeshpaliyal.keypass.ui.redux.states.HomeState
@@ -34,10 +35,11 @@ import org.reduxkotlin.compose.selectState
@Composable
fun KeyPassBottomBar() {
fun KeyPassBottomBar(viewModel: BottomNavViewModel) {
val currentScreen: ScreenState by selectState<KeyPassState, ScreenState> { this.currentScreen }
val showMainBottomAppBar = currentScreen.showMainBottomAppBar
val dispatchAction = rememberDispatcher()
val navigationItems by viewModel.navigationList.observeAsState()
if (!showMainBottomAppBar) {
return
@@ -59,15 +61,27 @@ fun KeyPassBottomBar() {
}
IconButton(onClick = {
dispatchAction(BottomSheetAction.HomeNavigationMenu(true))
dispatchAction(IntentNavigation.GeneratePassword)
}) {
Icon(
painter = rememberVectorPainter(image = Icons.Outlined.Menu),
contentDescription = "Menu",
painter = rememberVectorPainter(image = Icons.Outlined.VpnKey),
contentDescription = "Generate Password",
tint = MaterialTheme.colorScheme.onSurface
)
}
if (navigationItems?.isNotEmpty() == true) {
IconButton(onClick = {
dispatchAction(BottomSheetAction.HomeNavigationMenu(true))
}) {
Icon(
painter = rememberVectorPainter(image = Icons.Outlined.Menu),
contentDescription = "Menu",
tint = MaterialTheme.colorScheme.onSurface
)
}
}
IconToggleButton(colors = IconButtonDefaults.iconToggleButtonColors(
checkedContainerColor = MaterialTheme.colorScheme.primaryContainer,
checkedContentColor = MaterialTheme.colorScheme.onPrimaryContainer

View File

@@ -18,12 +18,13 @@ import java.util.Locale
@Composable
fun NavItemSection(divider: NavigationModelItem.NavDivider) {
Column(modifier = Modifier.padding(16.dp)) {
Divider()
Spacer(modifier = Modifier.height(32.dp))
if (!divider.hideDivider) {
Divider()
Spacer(modifier = Modifier.height(32.dp))
}
Text(
text = divider.title.uppercase(Locale.getDefault()),
style = MaterialTheme.typography.labelMedium,
fontSize = TextUnit(12f, TextUnitType.Sp)
style = MaterialTheme.typography.titleLarge
)
}
}

View File

@@ -40,6 +40,7 @@ import androidx.compose.ui.unit.dp
import com.yogeshpaliyal.common.utils.setPasswordHint
import com.yogeshpaliyal.keypass.R
import com.yogeshpaliyal.keypass.ui.commonComponents.DefaultBottomAppBar
import com.yogeshpaliyal.keypass.ui.commonComponents.DefaultTopAppBar
import com.yogeshpaliyal.keypass.ui.commonComponents.KeyPassInputField
import com.yogeshpaliyal.keypass.ui.nav.LocalUserSettings
import com.yogeshpaliyal.keypass.ui.redux.actions.Action
@@ -61,10 +62,8 @@ fun PasswordHintScreen() {
var showInfoDialog by remember { mutableStateOf(false) }
Scaffold(
bottomBar = {
DefaultBottomAppBar(
showBackButton = true
)
topBar = {
DefaultTopAppBar(title = R.string.app_password_hint, subtitle = R.string.app_password_hint_desc)
}
) { contentPadding ->
Surface(
@@ -78,26 +77,13 @@ fun PasswordHintScreen() {
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
// Title and Description
Text(
text = stringResource(id = R.string.app_password_hint),
style = MaterialTheme.typography.headlineMedium,
fontWeight = FontWeight.Bold
)
Text(
text = "A password hint helps you remember your password if you forget it. " +
"Make sure it's a hint only you would understand.",
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
Spacer(modifier = Modifier.height(8.dp))
// Input Card
ElevatedCard(
Card(
modifier = Modifier.fillMaxWidth(),
elevation = CardDefaults.elevatedCardElevation(defaultElevation = 2.dp)
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surfaceContainerLow
)
) {
Column(
modifier = Modifier.padding(16.dp),

View File

@@ -2,6 +2,7 @@ package com.yogeshpaliyal.keypass.ui.redux.middlewares
import android.content.Intent
import com.yogeshpaliyal.keypass.BuildConfig
import com.yogeshpaliyal.keypass.MyApplication
import com.yogeshpaliyal.keypass.R
import com.yogeshpaliyal.keypass.ui.generate.GeneratePasswordActivity
import com.yogeshpaliyal.keypass.ui.redux.actions.BatchActions
@@ -29,11 +30,13 @@ val intentNavigationMiddleware = middleware<KeyPassState> { store, next, action
private fun Store<KeyPassState>.handleAction(action: Any, state: KeyPassState) {
when (action) {
is IntentNavigation.GeneratePassword -> {
(state.context?.applicationContext as? MyApplication)?.knownActivityLaunchTriggered()
val intent = Intent(state.context, GeneratePasswordActivity::class.java)
state.context?.startActivity(intent)
}
is IntentNavigation.ShareApp -> {
(state.context?.applicationContext as? MyApplication)?.knownActivityLaunchTriggered()
val sendIntent = Intent()
sendIntent.action = Intent.ACTION_SEND
sendIntent.putExtra(

View File

@@ -11,7 +11,6 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
@@ -25,7 +24,6 @@ import androidx.compose.material.icons.rounded.Share
import androidx.compose.material.icons.filled.Search
import androidx.compose.material.icons.filled.KeyboardArrowDown
import androidx.compose.material.icons.filled.KeyboardArrowUp
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.OutlinedTextField
@@ -339,7 +337,7 @@ fun MySettingCompose() {
PreferenceType.AUTO_FILL -> {
val autoFillClick = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
{
(context.applicationContext as? MyApplication)?.activityLaunchTriggered()
(context.applicationContext as? MyApplication)?.knownActivityLaunchTriggered()
context.enableAutoFillService()
}
} else null

View File

@@ -18,7 +18,7 @@ class OpenKeyPassBackup<T : AccountsImporter>(val importer: T?) : ActivityResult
Intent.FLAG_GRANT_READ_URI_PERMISSION
)
(context.applicationContext as? MyApplication)?.activityLaunchTriggered()
(context.applicationContext as? MyApplication)?.knownActivityLaunchTriggered()
return intent
}

View File

@@ -50,6 +50,8 @@
<string name="backup_desc">Backups are encrypted with a passphrase and stored on your device</string>
<string name="yes">Yes</string>
<string name="create_backup">Create Backup</string>
<string name="create_account">Create Account</string>
<string name="edit_account">Edit Account</string>
<string name="alert">Alert</string>
<string name="copy_keypharse_msg">Copy This Key Phrase this will be used to recover this backup, this will not be provided by KeyPass Again, have you copied or written down?</string>
<string name="help">Help</string>
@@ -94,6 +96,7 @@
<string name="change_app_hint">Change Hint</string>
<string name="remove_app_hint">Remove Hint</string>
<string name="app_password_hint">App Password Hint</string>
<string name="app_password_hint_desc">A password hint helps you remember your password if you forget it. Make sure it\'s a hint only you would understand.</string>
<string name="set_app_password_hint">Set App Password Hint</string>
<string name="change_app_password_hint">Change App Password Hint</string>
<string name="old_password">Old Password</string>
@@ -144,6 +147,7 @@
<string name="contact_developer">Contact Developer</string>
<string name="contact_via_email">Send an email for support, feedback, or suggestions</string>
<string name="choose_default_password_length">Choose Default Password Length</string>
<string name="choose_default_password_length_desc">This length will be used as default when generating new passwords. Longer passwords provide better security.</string>
</resources>