import React, { MouseEventHandler, useCallback, useMemo, useState } from 'react'; import FocusTrap from 'focus-trap-react'; import { Dialog, Overlay, OverlayCenter, OverlayBackdrop, Header, config, Box, Text, IconButton, Icon, Icons, color, Button, Spinner, Chip, PopOut, RectCords, } from 'folds'; import { Direction, MatrixError } from 'matrix-js-sdk'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; import { stopPropagation } from '../../../utils/keyboard'; import { useAlive } from '../../../hooks/useAlive'; import { useStateEvent } from '../../../hooks/useStateEvent'; import { useRoom } from '../../../hooks/useRoom'; import { StateEvent } from '../../../../types/matrix/room'; import { getToday, getYesterday, timeDayMonthYear, timeHourMinute } from '../../../utils/time'; import { DatePicker, TimePicker } from '../../../components/time-date'; import { useSetting } from '../../../state/hooks/settings'; import { settingsAtom } from '../../../state/settings'; type JumpToTimeProps = { onCancel: () => void; onSubmit: (eventId: string) => void; }; export function JumpToTime({ onCancel, onSubmit }: JumpToTimeProps) { const mx = useMatrixClient(); const room = useRoom(); const alive = useAlive(); const createStateEvent = useStateEvent(room, StateEvent.RoomCreate); const todayTs = getToday(); const yesterdayTs = getYesterday(); const createTs = useMemo(() => createStateEvent?.getTs() ?? 0, [createStateEvent]); const [ts, setTs] = useState(() => Date.now()); const [hour24Clock] = useSetting(settingsAtom, 'hour24Clock'); const [timePickerCords, setTimePickerCords] = useState(); const [datePickerCords, setDatePickerCords] = useState(); const handleTimePicker: MouseEventHandler = (evt) => { setTimePickerCords(evt.currentTarget.getBoundingClientRect()); }; const handleDatePicker: MouseEventHandler = (evt) => { setDatePickerCords(evt.currentTarget.getBoundingClientRect()); }; const handleToday = () => { setTs(todayTs < createTs ? createTs : todayTs); }; const handleYesterday = () => { setTs(yesterdayTs < createTs ? createTs : yesterdayTs); }; const handleBeginning = () => setTs(createTs); const [timestampState, timestampToEvent] = useAsyncCallback( useCallback( async (newTs) => { const result = await mx.timestampToEvent(room.roomId, newTs, Direction.Forward); return result.event_id; }, [mx, room] ) ); const handleSubmit = () => { timestampToEvent(ts).then((eventId) => { if (alive()) { onSubmit(eventId); } }); }; return ( }>
Jump to Time
Time } onClick={handleTimePicker} > {timeHourMinute(ts, hour24Clock)} setTimePickerCords(undefined), clickOutsideDeactivates: true, isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown' || evt.key === 'ArrowRight', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp' || evt.key === 'ArrowLeft', escapeDeactivates: stopPropagation, }} >
} /> Date } onClick={handleDatePicker} > {timeDayMonthYear(ts)} setDatePickerCords(undefined), clickOutsideDeactivates: true, isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown' || evt.key === 'ArrowRight', isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp' || evt.key === 'ArrowLeft', escapeDeactivates: stopPropagation, }} > } /> Preset {createTs < todayTs && ( Today )} {createTs < yesterdayTs && ( Yesterday )} Beginning {timestampState.status === AsyncStatus.Error && ( {timestampState.error.message} )}
); }