From 0183a36058b75632b0ff9591b1ec3746f109e97f Mon Sep 17 00:00:00 2001 From: Evgeny Date: Sat, 19 Sep 2026 14:16:39 +0100 Subject: [PATCH] ui: update text about badges (#7544) * ui: update text about badges * update * update * update * update * update * update * update kotlin --------- Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com> --- .../Views/Badges/BadgesHowItWorksView.swift | 9 ++++---- .../Views/Badges/BadgesRedeemCodeView.swift | 2 +- .../Badges/BadgesSupportSimplexView.swift | 4 ++-- .../Views/Badges/BadgesYourBadgeView.swift | 2 +- .../Views/Badges/BadgesYourLevelView.swift | 2 +- .../Views/Badges/SupportSimpleXBanner.swift | 2 +- .../Shared/Views/ChatList/ChatListView.swift | 6 +++--- .../views/badges/BadgesHowItWorksView.kt | 3 ++- .../commonMain/resources/MR/base/strings.xml | 21 ++++++++++--------- blog/20260919-simplex-supporter-badges.md | 2 +- 10 files changed, 28 insertions(+), 25 deletions(-) diff --git a/apps/ios/Shared/Views/Badges/BadgesHowItWorksView.swift b/apps/ios/Shared/Views/Badges/BadgesHowItWorksView.swift index bca1f7da40..5758ceb12c 100644 --- a/apps/ios/Shared/Views/Badges/BadgesHowItWorksView.swift +++ b/apps/ios/Shared/Views/Badges/BadgesHowItWorksView.swift @@ -14,7 +14,7 @@ struct BadgesHowItWorksView: View { var body: some View { VStack(alignment: .leading) { - Text("How private badges work") + Text("How badges protect your privacy") .font(.largeTitle) .bold() .foregroundColor(theme.colors.primary) @@ -22,9 +22,10 @@ struct BadgesHowItWorksView: View { .padding(.bottom, 16) ScrollView { VStack(alignment: .leading, spacing: 12) { - Text("A badge is not an account. It is a signed credential stored on your device. It does not identify you, and no one keeps a record of who holds which badge.") - Text("Your contacts see the badge and its expiry date, and nothing else. The badge carries no identifier, so it cannot be used to find out who you are or to match you across chats.") - Text("Payment and badge are kept apart. Paying is one step; the badge is issued in another, under a key that exists only for that badge. Whoever handles the payment cannot see where the badge ends up.") + Text("A badge is an anonymous credential stored in your profile on your device. This credential is never sent to anyone.") + Text("To prove to a contact or a server that you have a badge, the app generates a new proof that reveals only the badge type and the expiry date, rounded to a week.") + Text("Nobody can link two different proofs to each other or to the purchase.") + ExternalLink("Read more in our blog.", destination: URL(string: "https://simplex.chat/blog/20260919-simplex-supporter-badges.html")!) } .lineLimit(nil) .fixedSize(horizontal: false, vertical: true) diff --git a/apps/ios/Shared/Views/Badges/BadgesRedeemCodeView.swift b/apps/ios/Shared/Views/Badges/BadgesRedeemCodeView.swift index 16e1796e96..6ea0c58edb 100644 --- a/apps/ios/Shared/Views/Badges/BadgesRedeemCodeView.swift +++ b/apps/ios/Shared/Views/Badges/BadgesRedeemCodeView.swift @@ -80,7 +80,7 @@ struct BadgesRedeemCodeView: View { .multilineTextAlignment(.center) .fixedSize(horizontal: false, vertical: true) - Text("Paste the code from your receipt.") + Text("Paste the code you received.") .font(.body) .multilineTextAlignment(.center) .fixedSize(horizontal: false, vertical: true) diff --git a/apps/ios/Shared/Views/Badges/BadgesSupportSimplexView.swift b/apps/ios/Shared/Views/Badges/BadgesSupportSimplexView.swift index 2fc904197d..55d05f2615 100644 --- a/apps/ios/Shared/Views/Badges/BadgesSupportSimplexView.swift +++ b/apps/ios/Shared/Views/Badges/BadgesSupportSimplexView.swift @@ -29,7 +29,7 @@ struct BadgesSupportSimplexView: View { .multilineTextAlignment(.center) .fixedSize(horizontal: false, vertical: true) - Text("SimpleX doesn't sell ads or data. It's funded by its users and by investors who share the mission. You can support the project and show a badge on your profile.") + Text("Get a badge to send larger files (2-5GB) that stay available longer (7-21 days), and to show it on your profile.") .font(.body) .multilineTextAlignment(.center) .fixedSize(horizontal: false, vertical: true) @@ -110,7 +110,7 @@ struct BadgesSupportSimplexView: View { Button { howItWorksActive = true } label: { HStack(spacing: 4) { Image(systemName: "info.circle") - Text("How private badges work").fontWeight(.medium) + Text("How badges protect your privacy").fontWeight(.medium) } .font(.body) } diff --git a/apps/ios/Shared/Views/Badges/BadgesYourBadgeView.swift b/apps/ios/Shared/Views/Badges/BadgesYourBadgeView.swift index 59eeba7eac..5654d6e5aa 100644 --- a/apps/ios/Shared/Views/Badges/BadgesYourBadgeView.swift +++ b/apps/ios/Shared/Views/Badges/BadgesYourBadgeView.swift @@ -48,7 +48,7 @@ struct BadgesYourBadgeView: View { .modifier(ThemedBackground()) } label: { settingsRow("info.circle", color: theme.colors.secondary) { - Text("How private badges work") + Text("How badges protect your privacy") } } } diff --git a/apps/ios/Shared/Views/Badges/BadgesYourLevelView.swift b/apps/ios/Shared/Views/Badges/BadgesYourLevelView.swift index eb2396c655..d47bcaa0a7 100644 --- a/apps/ios/Shared/Views/Badges/BadgesYourLevelView.swift +++ b/apps/ios/Shared/Views/Badges/BadgesYourLevelView.swift @@ -162,7 +162,7 @@ struct BadgesYourLevelView: View { } label: { HStack(spacing: 4) { Image(systemName: "info.circle") - Text("How private badges work").fontWeight(.medium) + Text("How badges protect your privacy").fontWeight(.medium) } .font(.body) } diff --git a/apps/ios/Shared/Views/Badges/SupportSimpleXBanner.swift b/apps/ios/Shared/Views/Badges/SupportSimpleXBanner.swift index dad3bb1b0a..c2f6136d31 100644 --- a/apps/ios/Shared/Views/Badges/SupportSimpleXBanner.swift +++ b/apps/ios/Shared/Views/Badges/SupportSimpleXBanner.swift @@ -13,7 +13,7 @@ struct SupportSimpleXBanner: View { @EnvironmentObject var theme: AppTheme @Environment(\.colorScheme) var colorScheme: ColorScheme var title: LocalizedStringKey = "Support SimpleX" - var subtitle: LocalizedStringKey = "Get badge + files up to 5GB" + var subtitle: LocalizedStringKey = "Get badge + better files" let onTap: () -> Void let onDismiss: () -> Void diff --git a/apps/ios/Shared/Views/ChatList/ChatListView.swift b/apps/ios/Shared/Views/ChatList/ChatListView.swift index 61f29485a7..ab3ffdd191 100644 --- a/apps/ios/Shared/Views/ChatList/ChatListView.swift +++ b/apps/ios/Shared/Views/ChatList/ChatListView.swift @@ -387,7 +387,7 @@ struct ChatListView: View { } private func showSupportEndedDismissAlert() { - showAlert(NSLocalizedString("Support ended", comment: "alert title")) { + showAlert(NSLocalizedString("Your badge expired", comment: "alert title")) { [ UIAlertAction(title: NSLocalizedString("Remind me later", comment: "alert button"), style: .default) { _ in Task { await ackBadgeAlert(snooze: true) } @@ -464,8 +464,8 @@ struct ChatListView: View { // one slot: a badge the user paid for ending outranks the pitch to get one if supportEnded, let alert = badgeModel.alert { SupportSimpleXBanner( - title: "Support ended", - subtitle: "Your support ended on \(alert.dateText).", + title: "Your badge expired", + subtitle: "Your badge expired on \(alert.dateText).", onTap: { showBadgesSheet = true }, onDismiss: showSupportEndedDismissAlert ) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/badges/BadgesHowItWorksView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/badges/BadgesHowItWorksView.kt index 7c16bee763..cb300b183d 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/badges/BadgesHowItWorksView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/badges/BadgesHowItWorksView.kt @@ -10,9 +10,9 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import dev.icerock.moko.resources.compose.stringResource import chat.simplex.common.platform.ColumnWithScrollBar +import chat.simplex.common.views.onboarding.ReadableTextWithLink import chat.simplex.res.MR -// TODO [badges]: replace lorem ipsum with the real copy once the badge protocol and privacy properties are documented. @Composable fun BadgesHowItWorksView() { ColumnWithScrollBar( @@ -30,5 +30,6 @@ fun BadgesHowItWorksView() { Text(stringResource(MR.strings.badges_how_it_works_p1), style = MaterialTheme.typography.body1) Text(stringResource(MR.strings.badges_how_it_works_p2), style = MaterialTheme.typography.body1) Text(stringResource(MR.strings.badges_how_it_works_p3), style = MaterialTheme.typography.body1) + ReadableTextWithLink(MR.strings.badges_how_it_works_read_more_with_link, "https://simplex.chat/blog/20260919-simplex-supporter-badges.html") } } diff --git a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml index e310834fda..f305ffc13f 100644 --- a/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml +++ b/apps/multiplatform/common/src/commonMain/resources/MR/base/strings.xml @@ -3159,19 +3159,20 @@ Ends on %1$s. Your level Support SimpleX - SimpleX doesn\'t sell ads or data. It\'s funded by its users and by investors who share the mission. You can support the project and show a badge on your profile. + Get a badge to send larger files (2-5GB) that stay available longer (7-21 days), and to show it on your profile. Why SimpleX is built. Choose your level Redeem badge code Continue - How private badges work - How private badges work - A badge is not an account. It is a signed credential stored on your device. It does not identify you, and no one keeps a record of who holds which badge. - Your contacts see the badge and its expiry date, and nothing else. The badge carries no identifier, so it cannot be used to find out who you are or to match you across chats. - Payment and badge are kept apart. Paying is one step; the badge is issued in another, under a key that exists only for that badge. Whoever handles the payment cannot see where the badge ends up. + How badges protect your privacy + How badges protect your privacy + A badge is an anonymous credential stored in your profile on your device. This credential is never sent to anyone. + To prove to a contact or a server that you have a badge, the app generates a new proof that reveals only the badge type and the expiry date, rounded to a week. + Nobody can link two different proofs to each other or to the purchase. + our blog.]]> My nickname Support SimpleX - Get badge + files up to 5GB + Get badge + better files You can support SimpleX later in Settings. Purchase successful Purchase pending @@ -3179,7 +3180,7 @@ Purchase error Get your code Redeem code - Paste the code from your receipt. + Paste the code you received. SB-XXXXX-XXXXX-XXXXX-XXXXX Redeem Cannot redeem code @@ -3197,12 +3198,12 @@ The code could not be redeemed. The code you scanned is not a badge code. Your badge - Support ended + Your badge expired shown on your profile Ends Prepaid months have no billing date. The badge is reissued each month from the balance you already paid for, and ends when it runs out. Investor - Your support ended on %1$s. + Your badge expired on %1$s. Remind me later Dismiss Credential diff --git a/blog/20260919-simplex-supporter-badges.md b/blog/20260919-simplex-supporter-badges.md index bd2774404b..ebe19ef431 100644 --- a/blog/20260919-simplex-supporter-badges.md +++ b/blog/20260919-simplex-supporter-badges.md @@ -20,7 +20,7 @@ You can now support SimpleX Chat and get a supporter badge, larger files and lon A supporter badge is shown on your profile to your contacts, group members and channel subscribers. With a badge you can send files up to 2GB, or 5GB with a legend badge, instead of 1GB, and servers keep your files for longer — 7 days with a supporter badge and 21 days with a legend badge. -A badge is a credential stored in your profile on your device. The credential itself is not sent to anyone: to show the badge to a contact or to present it to a server, the app generates a new zero-knowledge proof that reveals only the badge type and the expiry date, and no two proofs can be linked to each other or to the purchase, by the badge service, your contacts or servers. Credentials are issued for one month at a time, and all badges expire on the same day of the week, so a badge places you among all supporters of that week and nothing more. +A badge is an anonymous credential stored in your profile on your device. The credential itself is not sent to anyone: to show the badge to a contact or to present it to a server, the app generates a new zero-knowledge proof that reveals only the badge type and the expiry date, and no two proofs can be linked to each other or to the purchase, by the badge service, your contacts or servers. Credentials are issued for one month at a time, and all badges expire on the same day of the week, so a badge places you among all supporters of that week and nothing more. This is only possible because the network has no user identifiers — in other messengers a paid feature is attached to the account, so the operator knows who paid and what they do with the feature.