mirror of
https://github.com/signalapp/Signal-Desktop.git
synced 2025-12-24 20:26:24 +00:00
Fix donations processing dialog on retry and add onEnter handler to form inputs
This commit is contained in:
@@ -36,7 +36,6 @@ export function DonationProgressModal(props: PropsType): JSX.Element {
|
||||
modalName="DonationProgressModal"
|
||||
noEscapeClose
|
||||
noMouseClose
|
||||
onClose={() => undefined}
|
||||
>
|
||||
<SpinnerV2 size={58} strokeWidth={8} />
|
||||
<div className="DonationProgressModal__text">
|
||||
|
||||
@@ -614,22 +614,45 @@ function CardForm({
|
||||
setCardCvcError(formResult.cardCvc.error ?? null);
|
||||
|
||||
const cardDetail = cardFormToCardDetail(formResult);
|
||||
if (cardDetail == null) {
|
||||
if (
|
||||
cardDetail == null ||
|
||||
formResult.cardNumber.error ||
|
||||
formResult.cardExpiration.error ||
|
||||
formResult.cardCvc.error
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
onSubmit(cardDetail);
|
||||
}, [cardCvc, cardExpiration, cardNumber, onSubmit]);
|
||||
|
||||
const isDonateDisabled =
|
||||
disabled ||
|
||||
!isOnline ||
|
||||
cardNumber === '' ||
|
||||
cardExpiration === '' ||
|
||||
cardCvc === '' ||
|
||||
cardNumberError != null ||
|
||||
cardExpirationError != null ||
|
||||
cardCvcError != null;
|
||||
const isDonateDisabled = useMemo(
|
||||
() =>
|
||||
disabled ||
|
||||
!isOnline ||
|
||||
cardNumber === '' ||
|
||||
cardExpiration === '' ||
|
||||
cardCvc === '' ||
|
||||
cardNumberError != null ||
|
||||
cardExpirationError != null ||
|
||||
cardCvcError != null,
|
||||
[
|
||||
cardCvc,
|
||||
cardCvcError,
|
||||
cardExpiration,
|
||||
cardExpirationError,
|
||||
cardNumber,
|
||||
cardNumberError,
|
||||
disabled,
|
||||
isOnline,
|
||||
]
|
||||
);
|
||||
|
||||
const handleInputEnterKey = useCallback(() => {
|
||||
if (!isDonateDisabled) {
|
||||
handleDonateClicked();
|
||||
}
|
||||
}, [handleDonateClicked, isDonateDisabled]);
|
||||
|
||||
const donateButton = (
|
||||
<Button
|
||||
@@ -674,6 +697,7 @@ function CardForm({
|
||||
onValueChange={handleCardNumberChange}
|
||||
maxInputLength={cardFormSettings.cardNumber.maxInputLength}
|
||||
onBlur={handleCardNumberBlur}
|
||||
onEnter={handleInputEnterKey}
|
||||
/>
|
||||
{cardNumberError != null && (
|
||||
<div className="DonationCardForm_FieldError">
|
||||
@@ -697,6 +721,7 @@ function CardForm({
|
||||
value={cardExpiration}
|
||||
onValueChange={handleCardExpirationChange}
|
||||
onBlur={handleCardExpirationBlur}
|
||||
onEnter={handleInputEnterKey}
|
||||
/>
|
||||
{cardExpirationError && (
|
||||
<div className="DonationCardForm_FieldError">
|
||||
@@ -720,6 +745,7 @@ function CardForm({
|
||||
onValueChange={handleCardCvcChange}
|
||||
maxInputLength={cardFormSettings.cardCvc.maxInputLength}
|
||||
onBlur={handleCardCvcBlur}
|
||||
onEnter={handleInputEnterKey}
|
||||
/>
|
||||
{cardCvcError && (
|
||||
<div className="DonationCardForm_FieldError">
|
||||
|
||||
@@ -597,7 +597,7 @@ export function PreferencesDonations({
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!workflow || lastError) {
|
||||
if (lastError) {
|
||||
setIsSubmitted(false);
|
||||
}
|
||||
|
||||
@@ -636,6 +636,7 @@ export function PreferencesDonations({
|
||||
errorType={lastError}
|
||||
i18n={i18n}
|
||||
onClose={() => {
|
||||
setIsSubmitted(false);
|
||||
updateLastError(undefined);
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -14,6 +14,7 @@ export default {
|
||||
onValueChange: action('onValueChange'),
|
||||
maxInputLength: 3,
|
||||
onBlur: action('onBlur'),
|
||||
onEnter: action('onEnter'),
|
||||
},
|
||||
} satisfies ComponentMeta<DonateInputCardCvcProps>;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright 2025 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
import type { FormEvent } from 'react';
|
||||
import type { FormEvent, KeyboardEvent } from 'react';
|
||||
import React, { memo, useCallback, useRef } from 'react';
|
||||
import { CC_CVC_FORMATTER, useInputMask } from '../../../hooks/useInputMask';
|
||||
import type { LocalizerType } from '../../../types/I18N';
|
||||
@@ -30,12 +30,13 @@ export type DonateInputCardCvcProps = Readonly<{
|
||||
onValueChange: (newValue: string) => void;
|
||||
maxInputLength: number;
|
||||
onBlur?: () => void;
|
||||
onEnter?: () => void;
|
||||
}>;
|
||||
|
||||
export const DonateInputCardCvc = memo(function DonateInputCardCvc(
|
||||
props: DonateInputCardCvcProps
|
||||
) {
|
||||
const { onValueChange } = props;
|
||||
const { onEnter, onValueChange } = props;
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
useInputMask(inputRef, CC_CVC_FORMATTER);
|
||||
@@ -47,6 +48,15 @@ export const DonateInputCardCvc = memo(function DonateInputCardCvc(
|
||||
[onValueChange]
|
||||
);
|
||||
|
||||
const handleKeyDown = useCallback(
|
||||
(event: KeyboardEvent) => {
|
||||
if (onEnter && event.key === 'Enter') {
|
||||
onEnter();
|
||||
}
|
||||
},
|
||||
[onEnter]
|
||||
);
|
||||
|
||||
return (
|
||||
<input
|
||||
ref={inputRef}
|
||||
@@ -59,6 +69,7 @@ export const DonateInputCardCvc = memo(function DonateInputCardCvc(
|
||||
value={props.value}
|
||||
onInput={handleInput}
|
||||
onBlur={props.onBlur}
|
||||
onKeyDown={handleKeyDown}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -13,6 +13,7 @@ export default {
|
||||
value: '',
|
||||
onValueChange: action('onValueChange'),
|
||||
onBlur: action('onBlur'),
|
||||
onEnter: action('onEnter'),
|
||||
},
|
||||
} satisfies ComponentMeta<DonateInputCardExpProps>;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright 2025 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
import type { FormEvent } from 'react';
|
||||
import type { FormEvent, KeyboardEvent } from 'react';
|
||||
import React, { memo, useCallback, useRef } from 'react';
|
||||
import { CC_EXP_FORMATTER, useInputMask } from '../../../hooks/useInputMask';
|
||||
import { CardExpirationError } from '../../../types/DonationsCardForm';
|
||||
@@ -40,12 +40,13 @@ export type DonateInputCardExpProps = Readonly<{
|
||||
value: string;
|
||||
onValueChange: (newValue: string) => void;
|
||||
onBlur?: () => void;
|
||||
onEnter?: () => void;
|
||||
}>;
|
||||
|
||||
export const DonateInputCardExp = memo(function DonateInputCardExp(
|
||||
props: DonateInputCardExpProps
|
||||
) {
|
||||
const { onValueChange } = props;
|
||||
const { onEnter, onValueChange } = props;
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
useInputMask(inputRef, CC_EXP_FORMATTER);
|
||||
@@ -57,6 +58,15 @@ export const DonateInputCardExp = memo(function DonateInputCardExp(
|
||||
[onValueChange]
|
||||
);
|
||||
|
||||
const handleKeyDown = useCallback(
|
||||
(event: KeyboardEvent) => {
|
||||
if (onEnter && event.key === 'Enter') {
|
||||
onEnter();
|
||||
}
|
||||
},
|
||||
[onEnter]
|
||||
);
|
||||
|
||||
return (
|
||||
<input
|
||||
ref={inputRef}
|
||||
@@ -68,6 +78,7 @@ export const DonateInputCardExp = memo(function DonateInputCardExp(
|
||||
value={props.value}
|
||||
onInput={handleInput}
|
||||
onBlur={props.onBlur}
|
||||
onKeyDown={handleKeyDown}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -13,6 +13,7 @@ export default {
|
||||
value: '',
|
||||
onValueChange: action('onValueChange'),
|
||||
onBlur: action('onBlur'),
|
||||
onEnter: action('onEnter'),
|
||||
maxInputLength: 19,
|
||||
},
|
||||
} satisfies ComponentMeta<DonateInputCardNumberProps>;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright 2025 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
import type { FormEvent } from 'react';
|
||||
import type { FormEvent, KeyboardEvent } from 'react';
|
||||
import React, { memo, useCallback, useRef } from 'react';
|
||||
import { CC_NUMBER_FORMATTER, useInputMask } from '../../../hooks/useInputMask';
|
||||
import type { LocalizerType } from '../../../types/I18N';
|
||||
@@ -28,12 +28,13 @@ export type DonateInputCardNumberProps = Readonly<{
|
||||
onValueChange: (newValue: string) => void;
|
||||
maxInputLength: number;
|
||||
onBlur?: () => void;
|
||||
onEnter?: () => void;
|
||||
}>;
|
||||
|
||||
export const DonateInputCardNumber = memo(function DonateInputCardNumber(
|
||||
props: DonateInputCardNumberProps
|
||||
) {
|
||||
const { onValueChange } = props;
|
||||
const { onEnter, onValueChange } = props;
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
useInputMask(inputRef, CC_NUMBER_FORMATTER);
|
||||
@@ -45,6 +46,15 @@ export const DonateInputCardNumber = memo(function DonateInputCardNumber(
|
||||
[onValueChange]
|
||||
);
|
||||
|
||||
const handleKeyDown = useCallback(
|
||||
(event: KeyboardEvent) => {
|
||||
if (onEnter && event.key === 'Enter') {
|
||||
onEnter();
|
||||
}
|
||||
},
|
||||
[onEnter]
|
||||
);
|
||||
|
||||
return (
|
||||
<input
|
||||
ref={inputRef}
|
||||
@@ -57,6 +67,7 @@ export const DonateInputCardNumber = memo(function DonateInputCardNumber(
|
||||
value={props.value}
|
||||
onInput={handleInput}
|
||||
onBlur={props.onBlur}
|
||||
onKeyDown={handleKeyDown}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user