list follows cursor

- add settings atom with cursor mode
- in locked mode eventlist scrolls to cursor
- cleanup unused menu items
This commit is contained in:
cv
2021-05-20 12:40:33 +02:00
parent 272458b412
commit f1538def99
3 changed files with 80 additions and 53 deletions
+34
View File
@@ -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));
});
+24 -2
View File
@@ -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 <Empty text='No Events' />;
}
@@ -114,6 +134,7 @@ export default function EventList(props) {
<AnimatePresence>
{cursor === -1 && (
<motion.div
ref={cursorRef}
className={style.cursor}
variants={cursorVariants}
initial='hidden'
@@ -149,6 +170,7 @@ export default function EventList(props) {
<AnimatePresence>
{cursor === index && (
<motion.div
ref={cursorRef}
className={style.cursor}
variants={cursorVariants}
initial='hidden'
+22 -51
View File
@@ -1,34 +1,16 @@
import { memo } from 'react';
import { FiChevronDown } from 'react-icons/fi';
import {
Button,
ButtonGroup,
Menu,
MenuButton,
MenuItem,
MenuList,
} from '@chakra-ui/react';
import { memo, useMemo } from 'react';
import { Divider } from '@chakra-ui/react';
import style from './EventListMenu.module.css';
import MenuActionButtons from '../editors/list/MenuActionButtons';
import MenuActionButtons from './MenuActionButtons';
import CollapseBtn from 'common/components/buttons/CollapseBtn';
import ExpandBtn from 'common/components/buttons/ExpandBtn';
import CurrentBtn from 'common/components/buttons/CurrentBtn';
import { SelectSetting, HandleOptions } from 'app/context/settingsAtom';
import { useAtom } from 'jotai';
import LockIconBtn from 'common/components/buttons/LockIconBtn';
const EventListMenu = ({ eventsHandler }) => {
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 (
<div className={style.headerButtons}>
<Menu className={style.menu} isLazy>
<ButtonGroup isAttached>
<Button {...buttonProps}>Upload</Button>
<MenuButton as={Button} {...buttonProps}>
<FiChevronDown />
</MenuButton>
</ButtonGroup>
<MenuList style={menuStyle}>
<MenuItem>Upload Excel</MenuItem>
<MenuItem>Upload CSV</MenuItem>
</MenuList>
</Menu>
<Menu>
<ButtonGroup isAttached>
<Button {...buttonProps}>Save</Button>
<MenuButton as={Button} {...buttonProps}>
<FiChevronDown />
</MenuButton>
</ButtonGroup>
<MenuList style={menuStyle}>
<MenuItem>Download Excel</MenuItem>
<MenuItem>Download CSV</MenuItem>
</MenuList>
</Menu>
<CurrentBtn size='sm' />
<CollapseBtn
size='sm'
clickhandler={() => eventsHandler('collapseall')}
/>
<ExpandBtn size='sm' clickhandler={() => eventsHandler('expandall')} />
<Divider orientation='vertical' />
<LockIconBtn
size='sm'
clickhandler={() => actionHandler('togglelock')}
active={cursorSettings === 'locked'}
/>
<Divider orientation='vertical' />
<MenuActionButtons actionHandler={actionHandler} size='sm' />
</div>
);