Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions frontend/app/components/ui/CountdownTimer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@ const styles = StyleSheet.create({
paddingHorizontal: 4,
paddingTop: 28,
},
tabularNums: {
fontVariant: ['tabular-nums'],
},
});

// Component for a single flip digit showing full value with flip animation
Expand Down
31 changes: 29 additions & 2 deletions frontend/app/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
Play,
Plus,
} from 'lucide-react-native';
import React, { useEffect, useRef, useState } from 'react';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import {
Alert,
Animated,
Expand Down Expand Up @@ -49,6 +49,8 @@
const [loading, setLoading] = useState(false);
const [showInfoSheet, setShowInfoSheet] = useState(false);
const [showVideo, setShowVideo] = useState(false);
const [cooldownSeconds, setCooldownSeconds] = useState(0);
const cooldownRef = useRef<ReturnType<typeof setInterval> | null>(null);
const [direction, setDirection] = useState<'forward' | 'backward'>('forward');

// Animation refs for splash elements
Expand Down Expand Up @@ -217,7 +219,29 @@
markOnboardingVideoAsShown();
};

const startCooldown = useCallback(() => {
setCooldownSeconds(15);
cooldownRef.current = setInterval(() => {
setCooldownSeconds((prev) => {
if (prev <= 1) {
clearInterval(cooldownRef.current!);

Check warning on line 227 in frontend/app/home.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

This assertion is unnecessary since the receiver accepts the original type of the expression.

See more on https://sonarcloud.io/project/issues?id=cornell-dti_redi&issues=AZ1kK2J0zeXJidPvv571&open=AZ1kK2J0zeXJidPvv571&pullRequest=120
cooldownRef.current = null;
return 0;
}
return prev - 1;
});
}, 1000);
}, []);

useEffect(() => {
return () => {
if (cooldownRef.current) clearInterval(cooldownRef.current);
};
}, []);

const handleSendPasswordlessLink = async () => {
if (cooldownSeconds > 0) return;

if (!email) {
Alert.alert('Missing Information', 'Please enter your email address');
return;
Expand All @@ -235,6 +259,7 @@
try {
await sendPasswordlessSignInLink(email);
showToast({ label: 'Sign-in link sent! Check your email.' });
startCooldown();
// Keep the email in case user needs to resend
} catch (error) {
Alert.alert(
Expand Down Expand Up @@ -366,9 +391,11 @@
) : (
<View style={styles.buttonContainer}>
<Button
title="Send Sign-In Link"
title={cooldownSeconds > 0 ? `Resend in ${cooldownSeconds}s` : 'Send Sign-In Link'}
Copy link
Copy Markdown
Collaborator

@clementroze clementroze Apr 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really minor, but to prevent flickering of the numbers + the label changing width, do u wanna try adding the font-variant-numeric: tabular-nums; CSS property?

See this SO post for more details

onPress={handleSendPasswordlessLink}
variant="primary"
disabled={cooldownSeconds > 0}
textStyle={{ fontVariant: ['tabular-nums'] }}
/>

<Button
Expand Down
Loading