You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
54 lines
1.6 KiB
54 lines
1.6 KiB
import { useEffect, useRef, useState } from 'react';
|
|
import { Pressable, StyleSheet, Text } from 'react-native';
|
|
import { colors } from '../../../src/theme';
|
|
|
|
interface Props {
|
|
disabled?: boolean;
|
|
onSend?: () => void;
|
|
seconds?: number;
|
|
}
|
|
|
|
/** 获取验证码按钮:未满足前置条件置灰;点击后倒计时 Ns */
|
|
export function CountdownButton({ disabled = false, onSend, seconds = 60 }: Props) {
|
|
const [left, setLeft] = useState(0);
|
|
const timer = useRef<ReturnType<typeof setInterval> | null>(null);
|
|
|
|
useEffect(() => () => {
|
|
if (timer.current) clearInterval(timer.current);
|
|
}, []);
|
|
|
|
const start = () => {
|
|
if (disabled || left > 0) return;
|
|
setLeft(seconds);
|
|
onSend?.();
|
|
timer.current = setInterval(() => {
|
|
setLeft((l) => {
|
|
if (l <= 1) {
|
|
if (timer.current) clearInterval(timer.current);
|
|
return 0;
|
|
}
|
|
return l - 1;
|
|
});
|
|
}, 1000);
|
|
};
|
|
|
|
const counting = left > 0;
|
|
return (
|
|
<Pressable
|
|
style={[styles.btn, (disabled || counting) && styles.btnDisabled]}
|
|
onPress={start}
|
|
disabled={disabled || counting}
|
|
>
|
|
<Text style={[styles.text, (disabled || counting) && styles.textDisabled]}>
|
|
{counting ? `${left}s 后重新获取` : '获取验证码'}
|
|
</Text>
|
|
</Pressable>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
btn: { paddingHorizontal: 14, paddingVertical: 8, borderRadius: 16, backgroundColor: colors.primaryLight },
|
|
btnDisabled: { backgroundColor: colors.borderLight },
|
|
text: { fontSize: 13, fontWeight: '600', color: colors.primaryText },
|
|
textDisabled: { color: colors.textDisabled },
|
|
});
|
|
|