@@ -51,18 +53,27 @@ function CountdownBar({ seconds, total }: { seconds: number; total: number }) {
);
}
-const COUNTDOWN_TOTAL = 30;
+// Match the bot's PAIR_TIMEOUT_MS — 5 minutes — so the pairing-window
+// timer is the single source of truth for "you have to scan by then".
+// Individual QR rotations (~5 s each from Baileys) refresh the displayed
+// QR but do NOT reset this timer — that would punish the user with a
+// constantly-resetting countdown.
+const PAIRING_WINDOW_SEC = 5 * 60;
export function PairLive({ accountId, label }: PairLiveProps) {
const router = useRouter();
const [pairingState, setPairingState] = useState({ phase: "waiting" });
- const [countdown, setCountdown] = useState(COUNTDOWN_TOTAL);
+ const [countdown, setCountdown] = useState(PAIRING_WINDOW_SEC);
const timerRef = useRef | null>(null);
+ const startedRef = useRef(false);
- // Reset and start countdown when QR arrives
+ /** Start the pairing-window countdown once. Subsequent QR refreshes do
+ * not restart this — only mount/connect/timeout/unmount touches it. */
const startCountdown = () => {
+ if (startedRef.current) return;
+ startedRef.current = true;
if (timerRef.current) clearInterval(timerRef.current);
- setCountdown(COUNTDOWN_TOTAL);
+ setCountdown(PAIRING_WINDOW_SEC);
timerRef.current = setInterval(() => {
setCountdown((c) => {
if (c <= 1) {
@@ -79,6 +90,8 @@ export function PairLive({ accountId, label }: PairLiveProps) {
if (data.accountId !== accountId) return;
// Bust the URL with the timestamp so the browser refetches each time.
setPairingState({ phase: "qr", qrUrl: `/api/qr/${accountId}?t=${data.ts}` });
+ // Idempotent — only the first QR starts the global pairing-window
+ // timer; later QR rotations leave it ticking.
startCountdown();
},
"session.connected": (data) => {
@@ -130,8 +143,10 @@ export function PairLive({ accountId, label }: PairLiveProps) {
{pairingState.phase === "qr" && (
- {/* Countdown — separate from the QR so it doesn't obstruct scanning */}
-
+ {/* Pairing-window countdown — single source of truth.
+ The QR image rotates every ~5 s but this timer keeps ticking
+ against the bot's PAIR_TIMEOUT (5 min). */}
+
{/* QR image */}
{/* eslint-disable-next-line @next/next/no-img-element */}
@@ -148,6 +163,9 @@ export function PairLive({ accountId, label }: PairLiveProps) {
Open WhatsApp → tap ⋮ → Linked Devices → Link a device
+
+ The QR rotates automatically every few seconds — scan whichever one is showing.
+