mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-09 09:23:51 +00:00
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:
@@ -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));
|
||||
});
|
||||
@@ -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'
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user