diff --git a/client/src/app/context/settingsAtom.js b/client/src/app/context/settingsAtom.js new file mode 100644 index 000000000..c49055d5b --- /dev/null +++ b/client/src/app/context/settingsAtom.js @@ -0,0 +1,34 @@ +const { atom } = require('jotai'); + +const PATH = 'option-gen'; +const initialValue = { + cursor: 'locked', +}; + +export const settingsAtom = atom( + (get) => { + const storedOptions = localStorage.getItem(PATH); + if (storedOptions == null) return initialValue; + + return JSON.parse(storedOptions); + }, + (get, set, newValues) => { + set(settingsAtom, newValues); + localStorage.setItem(PATH, JSON.stringify(newValues)); + } +); + +// get a single option, if it exists +export const SelectSetting = (setting) => { + return atom((get) => get(settingsAtom)[setting]); +}; + +// change a single item in object +export const HandleOptions = atom(null, (get, set, payload) => { + const updatedVal = { + ...get(settingsAtom), + ...payload, + }; + set(settingsAtom, updatedVal); + localStorage.setItem(PATH, JSON.stringify(updatedVal)); +}); diff --git a/client/src/features/editors/list/EventList.jsx b/client/src/features/editors/list/EventList.jsx index 51c582c90..8b43078fa 100644 --- a/client/src/features/editors/list/EventList.jsx +++ b/client/src/features/editors/list/EventList.jsx @@ -1,18 +1,23 @@ import style from './List.module.css'; -import { Fragment, useEffect, useState } from 'react'; +import { createRef, Fragment, useEffect, useMemo, useState } from 'react'; import { useSocket } from 'app/context/socketContext'; import tinykeys from 'tinykeys'; import Empty from 'common/state/Empty'; import EventListItem from './EventListItem'; import { AnimatePresence, motion } from 'framer-motion'; import { DragDropContext, Droppable } from 'react-beautiful-dnd'; +import { useAtom } from 'jotai'; +import { SelectSetting } from 'app/context/settingsAtom'; export default function EventList(props) { const { events, eventsHandler } = props; const socket = useSocket(); const [selected, setSelected] = useState(null); const [next, setNext] = useState(null); - const [cursor, setCursor] = useState(null); + const [cursor, setCursor] = useState(0); + const [cursorSettings] = useAtom(useMemo(() => SelectSetting('cursor'), [])); + + const cursorRef = createRef(); // Handle keyboard shortcuts useEffect(() => { @@ -70,6 +75,21 @@ export default function EventList(props) { }; }, [socket]); + // attach scroll to cursor + useEffect(() => { + if (cursor == null || cursorRef.current == null) return; + + cursorRef.current.scrollIntoView({ + behavior: 'smooth', + block: 'nearest', + inline: 'start', + }); + }, [cursor, cursorRef]); + + useEffect(() => { + if (cursorSettings !== 'locked') return; + }, [selected]); + if (events.length < 1) { return ; } @@ -114,6 +134,7 @@ export default function EventList(props) { {cursor === -1 && ( {cursor === index && ( { - const buttonProps = { - size: 'sm', - variant: 'outline', - colorScheme: 'whiteAlpha', - backgroundColor: '#ffffff05', - _hover: { bg: 'blue.800' }, - _expanded: { bg: 'blue.400' }, - _focus: { boxShadow: 'none' }, - }; - - const menuStyle = { - color: 'initial', - backgroundColor: 'rgba(255,255,255,0.67)', - }; + const [cursorSettings] = useAtom(useMemo(() => SelectSetting('cursor'), [])); + const [, SetOption] = useAtom(HandleOptions); const actionHandler = (action) => { switch (action) { @@ -41,6 +23,13 @@ const EventListMenu = ({ eventsHandler }) => { case 'block': eventsHandler('add', { type: action, order: 0 }); break; + case 'togglelock': + let newSet = 'locked'; + if (cursorSettings === 'locked') { + newSet = 'unlocked'; + } + SetOption({ cursor: newSet }); + break; default: break; } @@ -48,36 +37,18 @@ const EventListMenu = ({ eventsHandler }) => { return (
- - - - - - - - - Upload Excel - Upload CSV - - - - - - - - - - - Download Excel - Download CSV - - - eventsHandler('collapseall')} /> eventsHandler('expandall')} /> + + actionHandler('togglelock')} + active={cursorSettings === 'locked'} + /> +
);