package com.peachpasswords.ui.vault import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.gestures.detectVerticalDragGestures import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Description import androidx.compose.material.icons.outlined.Lock import androidx.compose.material.icons.outlined.Settings import androidx.compose.material.icons.rounded.Add import androidx.compose.material.icons.rounded.Search import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.em import com.peachpasswords.ui.components.PeachWordmark import com.peachpasswords.ui.theme.LocalPeachAccent import com.peachpasswords.ui.theme.PeachRadius import com.peachpasswords.ui.theme.PeachSpacing import com.peachpasswords.ui.theme.PeachType import com.peachpasswords.ui.theme.peachColors @Composable internal fun PeachVaultIdentity(section: String, modifier: Modifier = Modifier, onHome: () -> Unit) { Row( modifier.fillMaxWidth().height(64.dp), verticalAlignment = Alignment.CenterVertically, ) { Box(Modifier.clickable(onClickLabel = "Open vault") { onHome() }) { PeachWordmark() } Spacer(Modifier.width(PeachSpacing.md)) Text(section.uppercase(), color = peachColors.T2, style = PeachType.labelMono.copy(letterSpacing = 0.08.em)) } } @Composable internal fun PeachDeckBottomBar( onSearch: () -> Unit, onAdd: () -> Unit, onNotes: () -> Unit, onSettings: () -> Unit, onLock: () -> Unit, onSwipeUp: () -> Unit, notesSelected: Boolean = false, modifier: Modifier = Modifier, ) { val accent = LocalPeachAccent.current Row( modifier.fillMaxWidth() .padding(horizontal = PeachSpacing.xl, vertical = PeachSpacing.sm) .height(64.dp) .background(peachColors.S1, RoundedCornerShape(PeachRadius.Pill)) .border(1.dp, peachColors.T3, RoundedCornerShape(PeachRadius.Pill)) .pointerInput(onSwipeUp) { var opened = false detectVerticalDragGestures( onDragEnd = { opened = false }, onDragCancel = { opened = false }, ) { _, dragAmount -> if (!opened && dragAmount < -4f) { opened = true onSwipeUp() } } } .padding(horizontal = PeachSpacing.md), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically, ) { DeckAction(Icons.Rounded.Search, "search", accent, onSearch, offsetX = 1.dp) // Material's Add path has substantially less visual mass than the // outlined glyphs beside it, so it needs a larger box to read as the // same optical size. DeckAction(Icons.Rounded.Add, "new", peachColors.T0, onAdd, iconSize = 28.dp) DeckAction(Icons.Outlined.Description, "Notes", if (notesSelected) accent else peachColors.T0, onNotes) DeckAction(Icons.Outlined.Settings, "settings", peachColors.T0, onSettings) DeckAction(Icons.Outlined.Lock, "Lock vault", accent, onLock) } } @Composable private fun DeckAction( icon: ImageVector, label: String, tint: Color, onClick: () -> Unit, iconSize: androidx.compose.ui.unit.Dp = 22.dp, offsetX: androidx.compose.ui.unit.Dp = 0.dp, ) { Box( Modifier.size(48.dp).clickable(onClick = onClick), contentAlignment = Alignment.Center, ) { Icon( icon, contentDescription = label, tint = tint, modifier = Modifier.size(iconSize).offset(x = offsetX), ) } }