import React, { useState } from 'react'; import ClickAwayListener from 'react-click-away-listener'; import { Center, Flex, Text } from '@chakra-ui/react'; import { Icon } from '../Icon/Icon'; import { useThingtime } from './useThingtime'; export const SettingsMenu = (props) => { const [show, setShow] = useState(false); const hideRef = React.useRef(null); const [opacity, setOpacity] = React.useState(props?.opacity === 0 ? 0 : 1); const [pinStatus, setPinStatus] = React.useState(false); const stateRef = React.useRef({ pinStatus }); React.useEffect(() => { stateRef.current.pinStatus = pinStatus; }, [pinStatus]); const { thingtime, events } = useThingtime(); const opacityRef = React.useRef(null); const waitTime = 1555; const [uuid, setUuid] = React.useState(null); React.useEffect(() => { setUuid(Math.random().toString(36).substring(7)); }, []); React.useEffect(() => { const subscription = events.subscribe((event) => { if (event?.type === 'settings-menu-hide' && event?.uuid !== uuid) { if (!stateRef?.current?.pinStatus || event?.force) { setShow(false); setOpacity(0); } } }); return () => { subscription?.unsubscribe?.(); }; }, [events, uuid]); React.useEffect(() => { clearInterval(opacityRef?.current); if (props?.opacity) { setOpacity(props?.opacity); } else { opacityRef.current = setInterval(() => { if (!stateRef?.current?.pinStatus) { setOpacity(props?.opacity); setShow(false); } }, waitTime); } }, [props?.opacity]); React.useEffect(() => { if (show || props?.opacity) { clearInterval(hideRef?.current); events.next({ type: 'settings-menu-hide', uuid }); } else if (!show) { setPinStatus(false); } }, [show, props?.opacity, events, uuid]); const maybeHide = React.useCallback(() => { clearInterval(hideRef?.current); hideRef.current = setTimeout(() => { if (!stateRef?.current?.pinStatus) { setShow(false); setOpacity(0); } }, waitTime); }, []); const showMenu = React.useCallback(() => { clearInterval(hideRef?.current); setShow(true); }, []); const hideMenu = React.useCallback(() => { setShow(false); }, []); const basePadding = React.useMemo(() => { return 4; }, []); const types = React.useMemo(() => { const baseTypes = thingtime?.settings?.types?.javascript || {}; const baseTypeKeys = Object.keys(baseTypes); const customTypes = thingtime?.settings?.types?.custom || {}; const customTypeKeysRaw = Object.keys(customTypes); const customTypeKeys = customTypeKeysRaw?.filter((key) => { return !baseTypeKeys?.includes?.(key); }); const types = [ ...(baseTypeKeys?.map?.((key) => { return { ...baseTypes?.[key], key }; }) || []), ...(customTypeKeys?.map?.((key) => { return { ...customTypes?.[key], key }; }) || []) ]; return types; }, [thingtime?.settings?.types?.javascript, thingtime?.settings?.types?.custom]); const onType = React.useCallback( (args) => { props?.onType?.(args); }, [props?.onType] ); const onDelete = React.useCallback( (type) => { props?.onDelete?.(); }, [props?.onDelete] ); const childIconSize = 10; const iconSize = props?.iconSize || 7; return (
setPinStatus((prev) => !prev)} title={`Pin Options`} > {show === true && } {/* edit mode menu item */} Toggle Edit Mode {!props?.readonly && ( Types )} {!props?.readonly && types.map((type, idx) => { const ret = ( div': { background: 'greys.light' } }} cursor="pointer" onClick={() => onType({ type })} paddingY={1} > {type?.label || type?.key || type} {type?.wrap && ( { e?.preventDefault?.(); e?.stopPropagation?.(); // cancel bubble e?.nativeEvent?.stopImmediatePropagation?.(); onType({ type, wrap: true }); }} > )} ); return ret; })} {!props?.readonly && props?.onDelete && ( Recycle )}
); };