mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-08-14 13:40:32 +00:00
wip
This commit is contained in:
@@ -53,7 +53,7 @@ struct BadgesPayView: View {
|
||||
|
||||
Text(level.tagline)
|
||||
.font(.body)
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
.foregroundColor(theme.colors.onBackground)
|
||||
.multilineTextAlignment(.center)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.padding(.top, 4)
|
||||
@@ -66,15 +66,17 @@ struct BadgesPayView: View {
|
||||
|
||||
Spacer(minLength: 20)
|
||||
|
||||
payButton()
|
||||
|
||||
Text(billingFooter)
|
||||
.font(.footnote)
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
.multilineTextAlignment(.center)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.padding(.top, 4)
|
||||
.padding(.bottom, g.safeAreaInsets.bottom == 0 ? 20 : 0)
|
||||
VStack(spacing: 10) {
|
||||
payButton()
|
||||
.padding(.vertical, 10)
|
||||
Text(billingFooter)
|
||||
.font(.footnote)
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
.multilineTextAlignment(.center)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.frame(height: 22)
|
||||
}
|
||||
.padding(.bottom, g.safeAreaInsets.bottom == 0 ? 20 : 0)
|
||||
}
|
||||
.padding(.horizontal, 25)
|
||||
.padding(.top, 8)
|
||||
|
||||
@@ -14,7 +14,7 @@ import SimpleXChat
|
||||
struct BadgesSupportSimplexView: View {
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@Environment(\.colorScheme) var colorScheme: ColorScheme
|
||||
@State private var showWhySimpleX = false
|
||||
@State private var whyBuiltActive = false
|
||||
@State private var chooseLevelActive = false
|
||||
@State private var redeemCodeActive = false
|
||||
|
||||
@@ -34,10 +34,7 @@ struct BadgesSupportSimplexView: View {
|
||||
.multilineTextAlignment(.center)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
|
||||
Button { showWhySimpleX = true } label: {
|
||||
Label("Why SimpleX is built.", systemImage: "info.circle")
|
||||
.font(.headline)
|
||||
}
|
||||
whyBuiltButton()
|
||||
|
||||
Spacer(minLength: 0)
|
||||
|
||||
@@ -47,11 +44,14 @@ struct BadgesSupportSimplexView: View {
|
||||
|
||||
Spacer(minLength: 0)
|
||||
|
||||
chooseLevelButton()
|
||||
|
||||
redeemCodeButton()
|
||||
.padding(.top, 4)
|
||||
.padding(.bottom, g.safeAreaInsets.bottom == 0 ? 20 : 0)
|
||||
// Onboarding pattern: nested VStack(spacing: 10) + action button vertical padding 10.
|
||||
VStack(spacing: 10) {
|
||||
chooseLevelButton()
|
||||
.padding(.vertical, 10)
|
||||
redeemCodeButton()
|
||||
.frame(height: 22)
|
||||
}
|
||||
.padding(.bottom, g.safeAreaInsets.bottom == 0 ? 20 : 0)
|
||||
}
|
||||
.padding(.horizontal, 25)
|
||||
.padding(.top, 28)
|
||||
@@ -63,8 +63,22 @@ struct BadgesSupportSimplexView: View {
|
||||
.frame(maxHeight: .infinity)
|
||||
.modifier(ThemedBackground())
|
||||
.navigationBarHidden(true)
|
||||
.sheet(isPresented: $showWhySimpleX) {
|
||||
WhySimpleX(onboarding: false, titleColor: theme.colors.primary, createProfileNavLinkActive: .constant(false))
|
||||
}
|
||||
|
||||
private func whyBuiltButton() -> some View {
|
||||
ZStack {
|
||||
Button { whyBuiltActive = true } label: {
|
||||
Label("Why SimpleX is built.", systemImage: "info.circle")
|
||||
.font(.headline)
|
||||
}
|
||||
NavigationLink(isActive: $whyBuiltActive) {
|
||||
WhySimpleX(onboarding: false, titleColor: theme.colors.primary, createProfileNavLinkActive: .constant(false))
|
||||
.modifier(ThemedBackground())
|
||||
} label: {
|
||||
EmptyView()
|
||||
}
|
||||
.frame(width: 1, height: 1)
|
||||
.hidden()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -113,11 +113,13 @@ struct BadgesYourLevelView: View {
|
||||
|
||||
Spacer(minLength: 20)
|
||||
|
||||
continueButton()
|
||||
|
||||
howItWorksButton()
|
||||
.padding(.top, 4)
|
||||
.padding(.bottom, g.safeAreaInsets.bottom == 0 ? 20 : 0)
|
||||
VStack(spacing: 10) {
|
||||
continueButton()
|
||||
.padding(.vertical, 10)
|
||||
howItWorksButton()
|
||||
.frame(height: 22)
|
||||
}
|
||||
.padding(.bottom, g.safeAreaInsets.bottom == 0 ? 20 : 0)
|
||||
}
|
||||
.padding(.horizontal, 25)
|
||||
.padding(.top, 8)
|
||||
|
||||
@@ -53,7 +53,8 @@ struct SupportSimpleXBanner: View {
|
||||
}
|
||||
.padding(.leading, cardLeadingPadding)
|
||||
.padding(.trailing, cardTrailingPadding)
|
||||
.frame(height: cardHeight)
|
||||
.padding(.vertical, 12)
|
||||
.frame(minHeight: cardHeight)
|
||||
.background(gradientBackground())
|
||||
.clipShape(RoundedRectangle(cornerRadius: cardCornerRadius))
|
||||
}
|
||||
|
||||
+18
-13
@@ -46,7 +46,7 @@ fun BadgesPayView(level: BadgeLevel) {
|
||||
var selectedPeriod by remember { mutableStateOf(BadgePeriod.Subscribe) }
|
||||
|
||||
ColumnWithScrollBar(
|
||||
Modifier.padding(horizontal = 25.dp).padding(top = 8.dp, bottom = 20.dp),
|
||||
Modifier.background(MaterialTheme.colors.background).padding(horizontal = 25.dp).padding(top = 8.dp, bottom = 20.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
maxIntrinsicSize = true,
|
||||
@@ -65,7 +65,7 @@ fun BadgesPayView(level: BadgeLevel) {
|
||||
Text(
|
||||
stringResource(level.tagline),
|
||||
style = MaterialTheme.typography.body1,
|
||||
color = MaterialTheme.colors.secondary,
|
||||
color = MaterialTheme.colors.onBackground,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 4.dp)
|
||||
)
|
||||
@@ -80,15 +80,20 @@ fun BadgesPayView(level: BadgeLevel) {
|
||||
|
||||
Spacer(Modifier.weight(1f).heightIn(min = 20.dp))
|
||||
|
||||
PayButton(level, selectedPeriod)
|
||||
|
||||
Text(
|
||||
stringResource(billingFooter(selectedPeriod)),
|
||||
style = MaterialTheme.typography.body2,
|
||||
color = MaterialTheme.colors.secondary,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 4.dp)
|
||||
)
|
||||
// Plain Text (not TextButtonBelowOnboardingButton) because the billing footer is informational,
|
||||
// not an action — using TextButtonBelowOnboardingButton would force a Medium-weight bold look.
|
||||
// 15.5dp top padding matches the visual gap the TextButtonBelowOnboardingButton produces on
|
||||
// the other two badges views (7.5dp Modifier + 8dp TextButton chip inner padding).
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
PayButton(level, selectedPeriod)
|
||||
Text(
|
||||
stringResource(billingFooter(selectedPeriod)),
|
||||
style = MaterialTheme.typography.body2,
|
||||
color = MaterialTheme.colors.secondary,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth().padding(top = 15.5.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +108,7 @@ private fun PeriodCard(period: BadgePeriod, selectedPeriod: BadgePeriod, modifie
|
||||
.background(MaterialTheme.colors.background.mixWith(MaterialTheme.colors.onBackground, 0.97f), shape)
|
||||
.border(2.dp, borderColor, shape)
|
||||
.clickable { onSelect(period) }
|
||||
.padding(vertical = 20.dp),
|
||||
.padding(vertical = 20.dp, horizontal = 12.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp)
|
||||
) {
|
||||
@@ -113,7 +118,7 @@ private fun PeriodCard(period: BadgePeriod, selectedPeriod: BadgePeriod, modifie
|
||||
tint = if (isSelected) MaterialTheme.colors.primary else MaterialTheme.colors.secondary,
|
||||
modifier = Modifier.size(32.dp)
|
||||
)
|
||||
Text(stringResource(period.label), style = MaterialTheme.typography.h3, fontWeight = FontWeight.Bold)
|
||||
Text(stringResource(period.label), style = MaterialTheme.typography.h3, fontWeight = FontWeight.Bold, textAlign = TextAlign.Center)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+9
-17
@@ -27,6 +27,7 @@ import chat.simplex.common.views.newchat.gradientPoints
|
||||
import chat.simplex.common.views.newchat.lightStops
|
||||
import chat.simplex.common.views.onboarding.HowItWorks
|
||||
import chat.simplex.common.views.onboarding.OnboardingActionButton
|
||||
import chat.simplex.common.views.onboarding.TextButtonBelowOnboardingButton
|
||||
import chat.simplex.res.MR
|
||||
|
||||
// Entry point for badges management. Subsequent screens push via ModalManager; the enclosing
|
||||
@@ -35,7 +36,7 @@ import chat.simplex.res.MR
|
||||
fun BadgesSupportSimplexView() {
|
||||
// TODO [badges] gate on user badge status (no badge → this view, active → "Manage your badge")
|
||||
ColumnWithScrollBar(
|
||||
Modifier.padding(horizontal = 25.dp).padding(top = 28.dp, bottom = 20.dp),
|
||||
Modifier.background(MaterialTheme.colors.background).padding(horizontal = 25.dp).padding(top = 28.dp, bottom = 20.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
maxIntrinsicSize = true,
|
||||
@@ -72,9 +73,13 @@ fun BadgesSupportSimplexView() {
|
||||
|
||||
Spacer(Modifier.weight(1f))
|
||||
|
||||
ChooseLevelButton()
|
||||
|
||||
RedeemCodeButton(Modifier.padding(top = 4.dp))
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
ChooseLevelButton()
|
||||
TextButtonBelowOnboardingButton(
|
||||
text = stringResource(MR.strings.badges_redeem_code_button),
|
||||
onClick = { ModalManager.start.showModal { BadgesRedeemCodeView() } }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,19 +95,6 @@ private fun ChooseLevelButton() {
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RedeemCodeButton(modifier: Modifier = Modifier) {
|
||||
TextButton(
|
||||
onClick = { ModalManager.start.showModal { BadgesRedeemCodeView() } },
|
||||
modifier = modifier
|
||||
) {
|
||||
Text(
|
||||
stringResource(MR.strings.badges_redeem_code_button),
|
||||
color = MaterialTheme.colors.primary,
|
||||
fontWeight = FontWeight.Medium
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Hero image reused across badges views and WhatsNewView v7.1. Fallback (no SIMPLEX_ASSETS) is a
|
||||
// gradient card carrying the small supporter badge glyph.
|
||||
|
||||
+16
-20
@@ -20,6 +20,7 @@ import chat.simplex.common.platform.*
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.common.views.onboarding.OnboardingActionButton
|
||||
import chat.simplex.common.views.onboarding.TextButtonBelowOnboardingButton
|
||||
import chat.simplex.res.MR
|
||||
|
||||
// Draft levels used by the badges UI while the API/state machine is still being designed. TODO [badges]:
|
||||
@@ -88,7 +89,7 @@ fun BadgesYourLevelView() {
|
||||
var selectedLevel by remember { mutableStateOf(BadgeLevel.Supporter) }
|
||||
|
||||
ColumnWithScrollBar(
|
||||
Modifier.padding(horizontal = 25.dp).padding(top = 8.dp, bottom = 20.dp),
|
||||
Modifier.background(MaterialTheme.colors.background).padding(horizontal = 25.dp).padding(top = 8.dp, bottom = 20.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
maxIntrinsicSize = true,
|
||||
@@ -120,9 +121,16 @@ fun BadgesYourLevelView() {
|
||||
|
||||
Spacer(Modifier.weight(1f).heightIn(min = 20.dp))
|
||||
|
||||
ContinueButton(selectedLevel)
|
||||
|
||||
HowItWorksButton(Modifier.padding(top = 4.dp))
|
||||
// Nested Column with no spacing so the TextButtonBelowOnboardingButton sits directly under
|
||||
// the action button (matches onboarding pattern where its own 7.5dp top padding is the gap).
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
ContinueButton(selectedLevel)
|
||||
TextButtonBelowOnboardingButton(
|
||||
text = stringResource(MR.strings.badges_how_it_works_button),
|
||||
icon = painterResource(MR.images.ic_info),
|
||||
onClick = { ModalManager.start.showModal { BadgesHowItWorksView() } }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +145,7 @@ private fun LevelCard(level: BadgeLevel, selectedLevel: BadgeLevel, modifier: Mo
|
||||
.background(MaterialTheme.colors.background.mixWith(MaterialTheme.colors.onBackground, 0.97f), shape)
|
||||
.border(2.dp, borderColor, shape)
|
||||
.clickable { onSelect(level) }
|
||||
.padding(vertical = 20.dp),
|
||||
.padding(vertical = 20.dp, horizontal = 12.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp)
|
||||
) {
|
||||
@@ -147,9 +155,9 @@ private fun LevelCard(level: BadgeLevel, selectedLevel: BadgeLevel, modifier: Mo
|
||||
contentScale = ContentScale.Fit,
|
||||
modifier = Modifier.size(60.dp)
|
||||
)
|
||||
Text(stringResource(level.title), style = MaterialTheme.typography.h3, fontWeight = FontWeight.Bold)
|
||||
Text(stringResource(level.filesDescription), style = MaterialTheme.typography.body2, color = MaterialTheme.colors.secondary)
|
||||
Text(stringResource(level.monthlyPrice), style = MaterialTheme.typography.body1)
|
||||
Text(stringResource(level.title), style = MaterialTheme.typography.h3, fontWeight = FontWeight.Bold, textAlign = TextAlign.Center)
|
||||
Text(stringResource(level.filesDescription), style = MaterialTheme.typography.body2, color = MaterialTheme.colors.secondary, textAlign = TextAlign.Center)
|
||||
Text(stringResource(level.monthlyPrice), style = MaterialTheme.typography.body1, textAlign = TextAlign.Center)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,15 +173,3 @@ private fun ContinueButton(selectedLevel: BadgeLevel) {
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun HowItWorksButton(modifier: Modifier = Modifier) {
|
||||
TextButton(
|
||||
onClick = { ModalManager.start.showModal { BadgesHowItWorksView() } },
|
||||
modifier = modifier
|
||||
) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(6.dp)) {
|
||||
Icon(painterResource(MR.images.ic_info), null, tint = MaterialTheme.colors.primary)
|
||||
Text(stringResource(MR.strings.badges_how_it_works_button), color = MaterialTheme.colors.primary, fontWeight = FontWeight.Medium)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+63
-52
@@ -32,9 +32,10 @@ import chat.simplex.res.MR
|
||||
@Composable
|
||||
fun SupportSimpleXBanner(onTap: () -> Unit, onDismiss: () -> Unit) {
|
||||
val cardCornerRadius = 16.dp
|
||||
// grows with system font but never shrinks below the default so small-font users see the same
|
||||
// banner as today; hero image stays fixed so its above-card overhang shrinks at very large fonts
|
||||
val cardHeight = (72.dp * fontSizeSqrtMultiplier).coerceAtLeast(72.dp)
|
||||
// grows linearly with system font but never shrinks below the default so small-font users see the
|
||||
// same baseline; the card Row uses heightIn(min = cardHeight) and grows further when 2-line text
|
||||
// wraps at very large fonts. Hero stays fixed so its above-card overhang shrinks at very large fonts.
|
||||
val cardHeight = (72.dp * fontSizeMultiplier).coerceAtLeast(72.dp)
|
||||
// matches OneHandUICard's segment icon leading so the text aligns with it in the list
|
||||
val cardLeadingPadding = 16.dp
|
||||
val cardTrailingPadding = 8.dp
|
||||
@@ -49,36 +50,66 @@ fun SupportSimpleXBanner(onTap: () -> Unit, onDismiss: () -> Unit) {
|
||||
var cardSize by remember { mutableStateOf(IntSize.Zero) }
|
||||
val brush = remember(isDark, cardSize) { gradientBrush(isDark, cardSize) }
|
||||
|
||||
// Root Box is sized to the card; hero and X are children so they can render outside the card's
|
||||
// rounded-corner clip. Hero anchors bottom-end and its 108dp height extends 36dp above the card top.
|
||||
Box(Modifier.fillMaxWidth().height(cardHeight)) {
|
||||
Row(
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.clip(RoundedCornerShape(cardCornerRadius))
|
||||
.background(brush)
|
||||
.clickable(onClick = onTap)
|
||||
.onSizeChanged { cardSize = it }
|
||||
.padding(start = cardLeadingPadding, end = cardTrailingPadding + heroWidth + heroTrailingPadding + textToHeroGap),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
|
||||
Text(
|
||||
generalGetString(MR.strings.badges_banner_title),
|
||||
style = MaterialTheme.typography.body1,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = MaterialTheme.colors.primary,
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
Text(
|
||||
generalGetString(MR.strings.badges_banner_subtitle),
|
||||
style = MaterialTheme.typography.body2,
|
||||
color = MaterialTheme.colors.onBackground,
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
// Two-Box structure so text can grow (2-line wrapping at large fonts) while X stays anchored to
|
||||
// the card's top-right, not the outer wrapper's top-right (which would drift up into hero overhang).
|
||||
// Outer Box takes max(inner card, hero); inner Box wraps the card Row + X together and aligns to
|
||||
// Outer bottom so hero overhangs above.
|
||||
Box(Modifier.fillMaxWidth(), contentAlignment = Alignment.BottomStart) {
|
||||
Box(Modifier.fillMaxWidth()) {
|
||||
Row(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.heightIn(min = cardHeight)
|
||||
.clip(RoundedCornerShape(cardCornerRadius))
|
||||
.background(brush)
|
||||
.clickable(onClick = onTap)
|
||||
.onSizeChanged { cardSize = it }
|
||||
.padding(
|
||||
start = cardLeadingPadding,
|
||||
end = cardTrailingPadding + heroWidth + heroTrailingPadding + textToHeroGap,
|
||||
top = 12.dp,
|
||||
bottom = 12.dp
|
||||
),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
|
||||
Text(
|
||||
generalGetString(MR.strings.badges_banner_title),
|
||||
style = MaterialTheme.typography.body1,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = MaterialTheme.colors.primary,
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
Text(
|
||||
generalGetString(MR.strings.badges_banner_subtitle),
|
||||
style = MaterialTheme.typography.body2,
|
||||
color = MaterialTheme.colors.onBackground,
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Same X pattern as OneHandUICard: circle-clipped clickable region with inner padding for hit area.
|
||||
Icon(
|
||||
painterResource(MR.images.ic_close),
|
||||
contentDescription = generalGetString(MR.strings.icon_descr_close_button),
|
||||
tint = MaterialTheme.colors.secondary,
|
||||
modifier = Modifier
|
||||
.align(Alignment.TopEnd)
|
||||
.padding(end = 4.dp, top = 4.dp)
|
||||
.clip(CircleShape)
|
||||
.clickable {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
title = generalGetString(MR.strings.badges_banner_title),
|
||||
text = generalGetString(MR.strings.badges_banner_dismiss_message),
|
||||
onConfirm = onDismiss
|
||||
)
|
||||
}
|
||||
.padding(8.dp)
|
||||
.size(16.dp)
|
||||
)
|
||||
}
|
||||
|
||||
HeroThumbnail(
|
||||
@@ -88,26 +119,6 @@ fun SupportSimpleXBanner(onTap: () -> Unit, onDismiss: () -> Unit) {
|
||||
trailingPadding = heroTrailingPadding,
|
||||
modifier = Modifier.align(Alignment.BottomEnd)
|
||||
)
|
||||
|
||||
// Same X pattern as OneHandUICard: circle-clipped clickable region with inner padding for hit area.
|
||||
Icon(
|
||||
painterResource(MR.images.ic_close),
|
||||
contentDescription = generalGetString(MR.strings.icon_descr_close_button),
|
||||
tint = MaterialTheme.colors.secondary,
|
||||
modifier = Modifier
|
||||
.align(Alignment.TopEnd)
|
||||
.padding(end = 4.dp, top = 4.dp)
|
||||
.clip(CircleShape)
|
||||
.clickable {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
title = generalGetString(MR.strings.badges_banner_title),
|
||||
text = generalGetString(MR.strings.badges_banner_dismiss_message),
|
||||
onConfirm = onDismiss
|
||||
)
|
||||
}
|
||||
.padding(8.dp)
|
||||
.size(16.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user