mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-12 09:13:23 +00:00
feat(ui): modernize the quote/repost choice popup
Replace the bare row of three flat primary-coloured buttons in the boost/quote/fork popup with the same card-and-pill treatment used by the reaction and zap popups: an elevated surfaceVariant card holding pill chips, each with a coloured leading icon (repost, quote, fork) next to its label and the soft outline the zap rails use, so the three action popups read as one family. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016a27kWKUcpADUC1KhXHRpV
This commit is contained in:
@@ -44,6 +44,7 @@ import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
@@ -59,8 +60,6 @@ import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.ElevatedCard
|
||||
@@ -1618,7 +1617,6 @@ private fun BoostTypeChoicePopup(
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
@Composable
|
||||
private fun BoostTypeChoicePopup(
|
||||
baseNote: Note,
|
||||
@@ -1642,52 +1640,81 @@ private fun BoostTypeChoicePopup(
|
||||
enter = popupAnimationEnter,
|
||||
exit = popupAnimationExit,
|
||||
) {
|
||||
FlowRow {
|
||||
Button(
|
||||
modifier = Modifier.padding(horizontal = 3.dp),
|
||||
onClick = {
|
||||
if (accountViewModel.isWriteable()) {
|
||||
accountViewModel.boost(baseNote)
|
||||
visibilityState.targetState = false
|
||||
} else {
|
||||
onRepost()
|
||||
visibilityState.targetState = false
|
||||
}
|
||||
},
|
||||
shape = ButtonBorder,
|
||||
colors =
|
||||
ButtonDefaults.buttonColors(
|
||||
containerColor = MaterialTheme.colorScheme.primary,
|
||||
),
|
||||
) {
|
||||
Text(stringRes(R.string.boost), color = Color.White, textAlign = TextAlign.Center)
|
||||
}
|
||||
|
||||
Button(
|
||||
modifier = Modifier.padding(horizontal = 3.dp),
|
||||
onClick = onQuote,
|
||||
shape = ButtonBorder,
|
||||
colors =
|
||||
ButtonDefaults.buttonColors(
|
||||
containerColor = MaterialTheme.colorScheme.primary,
|
||||
),
|
||||
) {
|
||||
Text(stringRes(R.string.quote), color = Color.White, textAlign = TextAlign.Center)
|
||||
}
|
||||
|
||||
BoostTypeChoicePopupContent(
|
||||
// removes the option to fork for now because we do not have screens for
|
||||
// LongForm, Wiki and NIP posting.
|
||||
if (baseNote.event is TextNoteEvent) {
|
||||
Button(
|
||||
modifier = Modifier.padding(horizontal = 3.dp),
|
||||
showFork = baseNote.event is TextNoteEvent,
|
||||
onBoost = {
|
||||
if (accountViewModel.isWriteable()) {
|
||||
accountViewModel.boost(baseNote)
|
||||
} else {
|
||||
onRepost()
|
||||
}
|
||||
visibilityState.targetState = false
|
||||
},
|
||||
onQuote = {
|
||||
onQuote()
|
||||
visibilityState.targetState = false
|
||||
},
|
||||
onFork = {
|
||||
onFork()
|
||||
visibilityState.targetState = false
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
@Composable
|
||||
fun BoostTypeChoicePopupContent(
|
||||
showFork: Boolean,
|
||||
onBoost: () -> Unit,
|
||||
onQuote: () -> Unit,
|
||||
onFork: () -> Unit,
|
||||
) {
|
||||
Box(HalfPadding, contentAlignment = Center) {
|
||||
ElevatedCard(
|
||||
shape = SmallBorder,
|
||||
elevation = CardDefaults.elevatedCardElevation(defaultElevation = 8.dp),
|
||||
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceVariant),
|
||||
) {
|
||||
FlowRow(
|
||||
modifier = Modifier.padding(horizontal = 5.dp, vertical = 5.dp),
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
verticalArrangement = Arrangement.Center,
|
||||
itemVerticalAlignment = CenterVertically,
|
||||
) {
|
||||
BoostActionChip(
|
||||
label = stringRes(R.string.boost),
|
||||
onClick = onBoost,
|
||||
) { tint ->
|
||||
RepostedIcon(Size18Modifier, tint)
|
||||
}
|
||||
|
||||
BoostActionChip(
|
||||
label = stringRes(R.string.quote),
|
||||
onClick = onQuote,
|
||||
) { tint ->
|
||||
Icon(
|
||||
symbol = MaterialSymbols.FormatQuote,
|
||||
contentDescription = null,
|
||||
modifier = Size18Modifier,
|
||||
tint = tint,
|
||||
)
|
||||
}
|
||||
|
||||
if (showFork) {
|
||||
BoostActionChip(
|
||||
label = stringRes(R.string.fork),
|
||||
onClick = onFork,
|
||||
shape = ButtonBorder,
|
||||
colors =
|
||||
ButtonDefaults.buttonColors(
|
||||
containerColor = MaterialTheme.colorScheme.primary,
|
||||
),
|
||||
) {
|
||||
Text(stringRes(R.string.fork), color = Color.White, textAlign = TextAlign.Center)
|
||||
) { tint ->
|
||||
Icon(
|
||||
symbol = MaterialSymbols.EditNote,
|
||||
contentDescription = null,
|
||||
modifier = Size18Modifier,
|
||||
tint = tint,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1695,6 +1722,56 @@ private fun BoostTypeChoicePopup(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A single quote/repost action rendered as a pill: a coloured leading icon next
|
||||
* to its label, wrapped in the same soft-outlined surface the zap rails use so
|
||||
* the popups read as one family.
|
||||
*/
|
||||
@Composable
|
||||
private fun BoostActionChip(
|
||||
label: String,
|
||||
onClick: () -> Unit,
|
||||
icon: @Composable (Color) -> Unit,
|
||||
) {
|
||||
Surface(
|
||||
shape = ButtonBorder,
|
||||
color = MaterialTheme.colorScheme.surfaceVariant,
|
||||
border = BorderStroke(1.dp, MaterialTheme.colorScheme.outlineVariant),
|
||||
modifier = Modifier.padding(horizontal = 4.dp, vertical = 6.dp),
|
||||
) {
|
||||
Row(
|
||||
modifier =
|
||||
Modifier
|
||||
.clip(ButtonBorder)
|
||||
.clickable(onClick = onClick)
|
||||
.padding(horizontal = 12.dp, vertical = 8.dp),
|
||||
verticalAlignment = CenterVertically,
|
||||
) {
|
||||
icon(MaterialTheme.colorScheme.primary)
|
||||
Spacer(Modifier.width(6.dp))
|
||||
Text(
|
||||
text = label,
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun BoostTypeChoicePopupPreview() {
|
||||
ThemeComparisonColumn {
|
||||
BoostTypeChoicePopupContent(
|
||||
showFork = true,
|
||||
onBoost = {},
|
||||
onQuote = {},
|
||||
onFork = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val popupAnimationEnter: EnterTransition =
|
||||
slideInVertically(
|
||||
animationSpec = defaultTweenIntOffsetSpec,
|
||||
|
||||
Reference in New Issue
Block a user