import variables from 'config/variables'; import { PureComponent, memo, useState } from 'react'; import { MdChecklist, MdPushPin, MdDelete, MdPlaylistAdd, MdOutlineDragIndicator, MdPlaylistRemove, } from 'react-icons/md'; import TextareaAutosize from '@mui/material/TextareaAutosize'; import { Tooltip } from 'components/Elements'; import Checkbox from '@mui/material/Checkbox'; import { shift, useFloating } from '@floating-ui/react-dom'; import { sortableContainer, sortableElement, sortableHandle } from '@muetab/react-sortable-hoc'; import EventBus from 'utils/eventbus'; const SortableItem = sortableElement(({ value }) =>
{value}
); const SortableContainer = sortableContainer(({ children }) =>
{children}
); const SortableHandle = sortableHandle(() => ); class Todo extends PureComponent { constructor() { super(); this.state = { todo: JSON.parse(localStorage.getItem('todo')) || [], visibility: localStorage.getItem('todoPinned') === 'true' ? 'visible' : 'hidden', marginLeft: localStorage.getItem('refresh') === 'false' ? '-200px' : '-130px', showTodo: localStorage.getItem('todoPinned') === 'true', }; } setZoom() { this.setState({ zoomFontSize: Number(((localStorage.getItem('zoomNavbar') || 100) / 100) * 1.2) + 'rem', }); } componentDidMount() { EventBus.on('refresh', (data) => { if (data === 'navbar') { this.forceUpdate(); try { this.setZoom(); } catch (e) {} } }); this.setZoom(); } componentWillUnmount() { EventBus.off('refresh'); } /** * It takes an array, removes an item from it, and then inserts it at a new index. * @param {Array} array The array to move the item in. * @param {Number} oldIndex The index of the item to move. * @param {Number} newIndex The index to move the item to. * @returns The result of the splice method. */ arrayMove(array, oldIndex, newIndex) { const result = Array.from(array); const [removed] = result.splice(oldIndex, 1); result.splice(newIndex, 0, removed); return result; } onSortEnd = ({ oldIndex, newIndex }) => { this.setState({ todo: this.arrayMove(this.state.todo, oldIndex, newIndex), }); }; showTodo() { this.setState({ showTodo: true, }); } hideTodo() { this.setState({ showTodo: localStorage.getItem('todoPinned') === 'true', }); } /** * This function takes in an action, an index, and data, and then updates the todo list accordingly. * @param {String} action The action to perform. Can be 'add', 'remove', 'set', or 'done'. * @param {Number} index The index of the item to perform the action on. * @param {Object} data The data to use for the action. */ updateTodo(action, index, data) { let todo = this.state.todo; switch (action) { case 'add': todo.push({ value: '', done: false, }); break; case 'remove': todo.splice(index, 1); break; case 'set': todo[index] = { value: data.target.value, done: todo[index].done, }; break; case 'done': todo[index].done = !todo[index].done; break; default: break; } localStorage.setItem('todo', JSON.stringify(todo)); this.setState({ todo, }); this.forceUpdate(); } pin() { variables.stats.postEvent('feature', 'Todo pin'); const todoPinned = localStorage.getItem('todoPinned') === 'true'; localStorage.setItem('todoPinned', !todoPinned); this.setState({ showTodo: !todoPinned, }); } render() { return (
this.hideTodo()} onFocus={() => this.showTodo()}> {this.state.showTodo && (
{variables.getMessage('widgets.navbar.todo.title')}
{this.state.todo.length === 0 ? (
{variables.getMessage('widgets.navbar.todo.no_todos')} {variables.getMessage('modals.main.settings.sections.message.add_some')}
) : ( {this.state.todo.map((_value, index) => ( this.updateTodo('done', index)} /> this.updateTodo('set', index, data)} readOnly={this.state.todo[index].done} /> this.updateTodo('remove', index)} />
} /> ))} )}
)} ); } } function TodoWrapper() { const [reference, setReference] = useState(null); const { x, y, refs, strategy } = useFloating({ placement: 'bottom', middleware: [shift()], elements: { reference, }, }); return ( ); } const MemoizedTodoWrapper = memo(TodoWrapper); export { MemoizedTodoWrapper as default, MemoizedTodoWrapper as Todo };