import { memo, useContext, useMemo } from 'react'; import { View, type TextProps, type ViewProps } from 'react-native'; import { Text } from '../Text'; import { circleSize } from './timeUtils'; import { DisplayModeContext } from './DisplayModeContext'; import { timePickerClockHoursStyles } from './utils'; const outerRange = getHourNumbers(false, circleSize, 12, 12, 1); const innerRange = getHourNumbers(true, circleSize, 12, 12, 13); function AnalogClockHours({ is24Hour, hours }: { is24Hour: boolean; hours: number }) { const { mode } = useContext(DisplayModeContext); const { activeTextColor, outerHourRootStyle, innerHourRootStyle, innerHourTextStyle, innerHourInner, outerHourInner, } = useMemo(() => { const { outerHourRoot, outerHourInner: _outerHourInner, innerHourRoot, innerHourInner: _innerHourInner, innerHourText, } = timePickerClockHoursStyles; return { activeTextColor: timePickerClockHoursStyles.root?._activeTextColor, outerHourRootStyle: outerHourRoot, innerHourRootStyle: innerHourRoot, innerHourTextStyle: innerHourText, outerHourInner: _outerHourInner, innerHourInner: _innerHourInner, }; }, []); return ( <> {outerRange.map((a, i) => ( {/* Display 00 instead of 12 for AM hours */} {mode === 'AM' && !is24Hour && a.hourValue === 12 ? '00' : a.hourValue} ))} <> {is24Hour ? innerRange.map((a, i) => ( {a.hourValue === 24 ? '00' : a.hourValue} )) : null} ); } const HourWrapper = memo( ({ style, position, ...rest }: ViewProps & { position: { x: number; y: number }; }) => { const componentStyles = useMemo(() => { return [ style, { top: position.y || 0, left: position.x || 0, }, ]; }, [position.x, position.y, style]); return ; }, ); const HourText = memo( ({ style, children, type, index: i, hours, activeTextColor, is24Hour, ...rest }: TextProps & { type: 'outer' | 'inner'; index: number; hours: number; activeTextColor: string; is24Hour: boolean; }) => { const componentStyles = useMemo(() => { const isOuterActive = (!is24Hour && hours === 0 && hours === i - 11) || hours === i + 1; const isInnerActive = i + 13 === hours || (i + 13 === 24 && hours === 0); const isActive = type === 'outer' ? isOuterActive : isInnerActive; return [style, isActive ? { color: activeTextColor } : null]; }, [activeTextColor, hours, i, is24Hour, style, type]); return ( {children} ); }, ); function getHourNumbers( is24Hour: boolean, size: number, count: number, arrayLength: number, startsAt: number, ) { let angle = 0; const step = (2 * Math.PI) / count; const radius = size / (is24Hour ? 4 : 2.5); angle = (-90 * Math.PI) / 180 + Math.PI / 6; return Array(arrayLength) .fill(true) .map(() => { const x = Math.round(size / 2 + radius * Math.cos(angle)); const y = Math.round(size / 2 + radius * Math.sin(angle)); angle += step; return { x, y, hourValue: startsAt++ }; }); } export default memo(AnalogClockHours);