diff --git a/_locales/en/messages.json b/_locales/en/messages.json
index 797fa4c337..51a22146e8 100644
--- a/_locales/en/messages.json
+++ b/_locales/en/messages.json
@@ -8902,14 +8902,30 @@
"messageformat": "Thank you for supporting Signal. Your contribution helps fuel the mission of protecting free expression and enabling secure global communication for millions around the world, through open source privacy technology. If you’re a resident of the United States, please retain this receipt for your tax records. Signal Technology Foundation is a tax-exempt nonprofit organization in the United States under section 501c3 of the Internal Revenue Code. Our Federal Tax ID is 82-4506840.",
"description": "Footer text shown on donation receipts explaining tax deductibility and Signal's mission"
},
+ "icu:Donations__Toast__Cancelled": {
+ "messageformat": "Donation cancelled",
+ "description": "Toast shown when a donation was manually cancelled by the user"
+ },
"icu:Donations__Toast__Completed": {
"messageformat": "Donation completed",
"description": "Toast shown when a donation started processing after resuming on startup, and it completed successfully when the user is not on the Preferences/Donations screen"
},
+ "icu:Donations__Toast__Error": {
+ "messageformat": "Error processing donation",
+ "description": "Toast shown when a donation fails when the user is not on the Preferences/Donations screen"
+ },
"icu:Donations__Toast__Processing": {
"messageformat": "Processing donation",
"description": "Toast shown when a donation starts processing again after resuming on startup"
},
+ "icu:Donations__Toast__VerificationFailed": {
+ "messageformat": "Verification failed",
+ "description": "Shown when the user is not on the Preferences/Donations screen, and for some reason their attempt to complete verification failed"
+ },
+ "icu:Donations__Toast__VerificationNeeded": {
+ "messageformat": "You have a donation in progress that needs additional verification.",
+ "description": "Shown when the user is not on the Preferences/Donations screen, and donation verification is needed. Like when resuming from startup."
+ },
"icu:Donations__PaymentMethodDeclined": {
"messageformat": "Payment method declined",
"description": "Title of the dialog shown with the user's provided payment method has not worked"
@@ -8918,14 +8934,6 @@
"messageformat": "Try another payment method or contact your bank for more information.",
"description": "An explanation for the 'payment declined' dialog"
},
- "icu:Donations__ErrorProcessingDonation": {
- "messageformat": "Error processing donation",
- "description": "Title of the dialog shown when a user's donation didn't seem to complete"
- },
- "icu:Donations__ErrorProcessingDonation__Description": {
- "messageformat": "Try another payment method or contact your bank for more information.",
- "description": "An explanation for the 'error processing' dialog"
- },
"icu:Donations__Failed3dsValidation": {
"messageformat": "Verification Failed",
"description": "Title of the dialog shown when something went wrong processing a user's 3ds verification with their bank"
@@ -8958,6 +8966,10 @@
"messageformat": "Additional verification required",
"description": "Title of the dialog shown when the user's payment method requires a redirect to a verification website"
},
+ "icu:Donations__3dsValidationNeeded--waiting": {
+ "messageformat": "Waiting for verification",
+ "description": "Title of the dialog shown when the user's payment method requires a redirect to a verification website"
+ },
"icu:Donations__3dsValidationNeeded__Description": {
"messageformat": "Your credit card issuer requires an additional verification step in a web browser.",
"description": "An explanation for the 'verification required' dialog"
@@ -8966,6 +8978,14 @@
"messageformat": "Open browser",
"description": "When external payment method validation is required, this button will open that external verification website"
},
+ "icu:Donations__3dsValidationNeeded__OpenBrowser--opened": {
+ "messageformat": "Re-open browser",
+ "description": "When the user has started external payment method validation, the button switches to this text. It allows them to kick off the process again if necessary."
+ },
+ "icu:Donations__3dsValidationNeeded__CancelDonation": {
+ "messageformat": "Cancel donation",
+ "description": "When external payment method validation is required, this button will open that external verification website"
+ },
"icu:WhatsNew__bugfixes": {
"messageformat": "This version contains a number of small tweaks and bug fixes to keep Signal running smoothly.",
"description": "Release notes for releases that only include bug fixes",
diff --git a/stylesheets/components/DonationVerificationModal.scss b/stylesheets/components/DonationVerificationModal.scss
index cb4c5b645d..e2adda0629 100644
--- a/stylesheets/components/DonationVerificationModal.scss
+++ b/stylesheets/components/DonationVerificationModal.scss
@@ -11,3 +11,7 @@
.module-Modal__title.DonationVerificationModal__title {
@include mixins.font-title-medium;
}
+
+.DonationVerificationModal__body_inner {
+ @include mixins.font-body-2;
+}
diff --git a/ts/components/DonationError.stories.tsx b/ts/components/DonationError.stories.tsx
index 6e66d0b6ae..09102ce374 100644
--- a/ts/components/DonationError.stories.tsx
+++ b/ts/components/DonationError.stories.tsx
@@ -21,15 +21,6 @@ const defaultProps = {
onClose: action('onClose'),
};
-export function DonationProcessingError(): JSX.Element {
- return (
-
- );
-}
-
export function Failed3dsValidation(): JSX.Element {
return (
{i18n('icu:Confirmation--confirm')}
}
- hasXButton
moduleClassName="DonationErrorModal"
modalName="DonationErrorModal"
+ noMouseClose
onClose={onClose}
title={title}
>
diff --git a/ts/components/DonationProgressModal.stories.tsx b/ts/components/DonationProgressModal.stories.tsx
index 1c25531c69..1f3b301399 100644
--- a/ts/components/DonationProgressModal.stories.tsx
+++ b/ts/components/DonationProgressModal.stories.tsx
@@ -17,7 +17,7 @@ export default {
const defaultProps = {
i18n,
- onClose: action('onClose'),
+ onWaitedTooLong: action('onWaitedTooLong'),
};
export function Default(): JSX.Element {
diff --git a/ts/components/DonationProgressModal.tsx b/ts/components/DonationProgressModal.tsx
index 6f0797a464..9e99e2a803 100644
--- a/ts/components/DonationProgressModal.tsx
+++ b/ts/components/DonationProgressModal.tsx
@@ -1,26 +1,41 @@
// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
-import React from 'react';
+import React, { useEffect } from 'react';
import type { LocalizerType } from '../types/Util';
import { Modal } from './Modal';
import { SpinnerV2 } from './SpinnerV2';
+import { SECOND } from '../util/durations';
export type PropsType = {
i18n: LocalizerType;
- onClose: () => void;
+ onWaitedTooLong: () => void;
};
export function DonationProgressModal(props: PropsType): JSX.Element {
- const { i18n, onClose } = props;
+ const { i18n, onWaitedTooLong } = props;
+
+ useEffect(() => {
+ let timeout: NodeJS.Timeout | undefined = setTimeout(() => {
+ timeout = undefined;
+ onWaitedTooLong();
+ }, SECOND * 30);
+
+ return () => {
+ if (timeout) {
+ clearTimeout(timeout);
+ }
+ };
+ }, [onWaitedTooLong]);
return (
undefined}
>