// Copyright 2024 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import type { UIEvent } from 'react'; import React, { useEffect, useMemo, useRef, useState } from 'react'; import uuid from 'uuid'; import type { LocalizerType } from '../types/I18N'; import { Modal } from './Modal'; import { Button, ButtonVariant } from './Button'; import { useReducedMotion } from '../hooks/useReducedMotion'; export type SafetyTipsModalProps = Readonly<{ i18n: LocalizerType; onClose(): void; }>; export function SafetyTipsModal({ i18n, onClose, }: SafetyTipsModalProps): JSX.Element { const pages = useMemo(() => { return [ { key: 'crypto', title: i18n('icu:SafetyTipsModal__TipTitle--Crypto'), description: i18n('icu:SafetyTipsModal__TipDescription--Crypto'), imageUrl: 'images/safety-tips/safety-tip-crypto.png', }, { key: 'vague', title: i18n('icu:SafetyTipsModal__TipTitle--Vague'), description: i18n('icu:SafetyTipsModal__TipDescription--Vague'), imageUrl: 'images/safety-tips/safety-tip-vague.png', }, { key: 'links', title: i18n('icu:SafetyTipsModal__TipTitle--Links'), description: i18n('icu:SafetyTipsModal__TipDescription--Links'), imageUrl: 'images/safety-tips/safety-tip-links.png', }, { key: 'business', title: i18n('icu:SafetyTipsModal__TipTitle--Business'), description: i18n('icu:SafetyTipsModal__TipDescription--Business'), imageUrl: 'images/safety-tips/safety-tip-business.png', }, ]; }, [i18n]); const [modalId] = useState(() => uuid()); const [cardWrapperId] = useState(() => uuid()); function getCardIdForPage(pageIndex: number) { return `${cardWrapperId}_${pages[pageIndex].key}`; } const maxPageIndex = pages.length - 1; const [pageIndex, setPageIndexInner] = useState(0); const reducedMotion = useReducedMotion(); const scrollEndTimer = useRef(null); const [hasPageIndexChanged, setHasPageIndexChanged] = useState(false); function setPageIndex(nextPageIndex: number) { setPageIndexInner(nextPageIndex); setHasPageIndexChanged(true); } function clearScrollEndTimer() { if (scrollEndTimer.current != null) { clearTimeout(scrollEndTimer.current); scrollEndTimer.current = null; } } useEffect(() => { return () => { clearScrollEndTimer(); }; }, []); function scrollToPageIndex(nextPageIndex: number) { clearScrollEndTimer(); setPageIndex(nextPageIndex); document.getElementById(getCardIdForPage(nextPageIndex))?.scrollIntoView({ inline: 'center', behavior: reducedMotion ? 'instant' : 'smooth', }); } function handleScroll(event: UIEvent) { clearScrollEndTimer(); const { scrollWidth, scrollLeft, clientWidth } = event.currentTarget; const maxScrollLeft = scrollWidth - clientWidth; const absScrollLeft = Math.abs(scrollLeft); const percentScrolled = absScrollLeft / maxScrollLeft; const scrolledPageIndex = Math.round(percentScrolled * maxPageIndex); scrollEndTimer.current = setTimeout(() => { setPageIndex(scrolledPageIndex); }, 100); } return ( {pageIndex < maxPageIndex ? ( ) : ( )} } >

{i18n('icu:SafetyTipsModal__Description')}

{pages.map((page, index) => { const isCurrentPage = pageIndex === index; return (

{page.title}

{page.description}

); })}
{pages.map((page, index) => { const isCurrentPage = pageIndex === index; return ( ); })}
); }