import range from 'lodash/range'; import times from 'lodash/times'; import React, { useCallback, useMemo, useRef } from 'react'; import { View, Text, TouchableWithoutFeedback, ViewStyle, TextStyle, StyleSheet, } from 'react-native'; import constants from '../commons/constants'; import { buildTimeString, calcTimeByPosition, calcDateByPosition, } from './helpers/presenter'; import { buildUnavailableHoursBlocks, HOUR_BLOCK_HEIGHT, UnavailableHours, } from './Packer'; interface NewEventTime { hour: number; minutes: number; date?: string; } export interface TimelineHoursProps { start?: number; end?: number; date?: string; format24h?: boolean; onBackgroundLongPress?: (timeString: string, time: NewEventTime) => void; onBackgroundLongPressOut?: (timeString: string, time: NewEventTime) => void; unavailableHours?: UnavailableHours[]; unavailableHoursColor?: string; styles: { [key: string]: ViewStyle | TextStyle }; width: number; numberOfDays: number; timelineLeftInset?: number; } const dimensionWidth = constants.screenWidth; const EVENT_DIFF = 20; const TimelineHours = (props: TimelineHoursProps) => { const { format24h, start = 0, end = 24, date, unavailableHours, unavailableHoursColor, styles, onBackgroundLongPress, onBackgroundLongPressOut, width, numberOfDays = 1, timelineLeftInset = 0, } = props; const lastLongPressEventTime = useRef(); // const offset = this.calendarHeight / (end - start); const offset = HOUR_BLOCK_HEIGHT; const unavailableHoursBlocks = buildUnavailableHoursBlocks(unavailableHours, { dayStart: start, dayEnd: end, }); const hours = useMemo(() => { return range(start, end + 1).map((i) => { let timeText; if (i === start) { timeText = ''; } else if (i < 12) { timeText = !format24h ? `${i} AM` : `${i}:00`; } else if (i === 12) { timeText = !format24h ? `${i} PM` : `${i}:00`; } else if (i === 24) { timeText = !format24h ? '12 AM' : '23:59'; } else { timeText = !format24h ? `${i - 12} PM` : `${i}:00`; } return { timeText, time: i }; }); }, [start, end, format24h]); const handleBackgroundPress = useCallback( (event: any) => { const yPosition = event.nativeEvent.locationY; const xPosition = event.nativeEvent.locationX; const { hour, minutes } = calcTimeByPosition( yPosition, HOUR_BLOCK_HEIGHT ); const dateByPosition = calcDateByPosition( xPosition, timelineLeftInset, numberOfDays, date ); lastLongPressEventTime.current = { hour, minutes, date: dateByPosition }; const timeString = buildTimeString(hour, minutes, dateByPosition); onBackgroundLongPress?.(timeString, lastLongPressEventTime.current); }, [onBackgroundLongPress, date] ); const handlePressOut = useCallback(() => { if (lastLongPressEventTime.current) { const { hour, minutes, date } = lastLongPressEventTime.current; const timeString = buildTimeString(hour, minutes, date); onBackgroundLongPressOut?.(timeString, lastLongPressEventTime.current); lastLongPressEventTime.current = undefined; } }, [onBackgroundLongPressOut, date]); return ( <> {unavailableHoursBlocks.map((block, index) => ( ))} {hours.map(({ timeText, time }, index) => { return ( {timeText} {time === start ? null : ( )} { } ); })} {times(numberOfDays, (index) => ( ))} ); }; export default React.memo(TimelineHours);