Skip to content

Commit

Permalink
feat: add close event for modals
Browse files Browse the repository at this point in the history
  • Loading branch information
remvze committed Apr 24, 2024
1 parent f81ea9e commit af92b1e
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 24 deletions.
72 changes: 53 additions & 19 deletions src/components/menu/menu.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState } from 'react';
import { useState, useMemo, useCallback } from 'react';
import { IoMenu, IoClose } from 'react-icons/io5/index';
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
import { useHotkeys } from 'react-hotkeys-hook';
Expand All @@ -20,22 +20,52 @@ import { Notepad, Pomodoro } from '@/components/toolbox';
import { fade, mix, slideY } from '@/lib/motion';

import styles from './menu.module.css';
import { useCloseListener } from '@/hooks/use-close-listener';

export function Menu() {
const [isOpen, setIsOpen] = useState(false);

const [showPresets, setShowPresets] = useState(false);
const [showShareLink, setShowShareLink] = useState(false);
const [showNotepad, setShowNotepad] = useState(false);
const [showPomodoro, setShowPomodoro] = useState(false);
const initial = useMemo(
() => ({
notepad: false,
pomodoro: false,
presets: false,
shareLink: false,
}),
[],
);

const variants = mix(fade(), slideY());
const [modals, setModals] = useState<{
notepad: boolean;
pomodoro: boolean;
presets: boolean;
shareLink: boolean;
}>(initial);

const close = useCallback((name: string) => {
setModals(prev => ({ ...prev, [name]: false }));
}, []);

const closeAll = useCallback(() => setModals(initial), [initial]);

const open = useCallback(
(name: string) => {
closeAll();
setIsOpen(false);
setModals(prev => ({ ...prev, [name]: true }));
},
[closeAll],
);

useHotkeys('shift+m', () => setIsOpen(prev => !prev));
useHotkeys('shift+n', () => setShowNotepad(prev => !prev));
useHotkeys('shift+p', () => setShowPomodoro(prev => !prev));
useHotkeys('shift+alt+p', () => setShowPresets(prev => !prev));
useHotkeys('shift+s', () => setShowShareLink(prev => !prev));
useHotkeys('shift+n', () => open('notepad'));
useHotkeys('shift+p', () => open('pomodoro'));
useHotkeys('shift+alt+p', () => open('presets'));
useHotkeys('shift+s', () => open('shareLink'));

useCloseListener(closeAll);

const variants = mix(fade(), slideY());

return (
<>
Expand Down Expand Up @@ -64,12 +94,12 @@ export function Menu() {
initial="hidden"
variants={variants}
>
<PresetsItem open={() => setShowPresets(true)} />
<ShareItem open={() => setShowShareLink(true)} />
<PresetsItem open={() => open('presets')} />
<ShareItem open={() => open('shareLink')} />
<ShuffleItem />
<Divider />
<NotepadItem open={() => setShowNotepad(true)} />
<PomodoroItem open={() => setShowPomodoro(true)} />
<NotepadItem open={() => open('notepad')} />
<PomodoroItem open={() => open('pomodoro')} />
<Divider />
<DonateItem />
<SourceItem />
Expand All @@ -82,12 +112,16 @@ export function Menu() {
</div>

<ShareLinkModal
show={showShareLink}
onClose={() => setShowShareLink(false)}
show={modals.shareLink}
onClose={() => close('shareLink')}
/>
<PresetsModal show={modals.presets} onClose={() => close('presets')} />
<Notepad show={modals.notepad} onClose={() => close('notepad')} />
<Pomodoro
open={() => open('pomodoro')}
show={modals.pomodoro}
onClose={() => close('pomodoro')}
/>
<PresetsModal show={showPresets} onClose={() => setShowPresets(false)} />
<Notepad show={showNotepad} onClose={() => setShowNotepad(false)} />
<Pomodoro show={showPomodoro} onClose={() => setShowPomodoro(false)} />
</>
);
}
4 changes: 2 additions & 2 deletions src/components/modal/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ export function Modal({

useEffect(() => {
function keyListener(e: KeyboardEvent) {
if (e.key === 'escape') {
if (show && e.key === 'Escape') {
onClose();
}
}

document.addEventListener('keydown', keyListener);

return () => document.removeEventListener('keydown', keyListener);
}, [onClose]);
}, [onClose, show]);

return (
<Portal>
Expand Down
3 changes: 3 additions & 0 deletions src/components/modals/shared/shared.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Modal } from '@/components/modal';

import { useSoundStore } from '@/store';
import { useSnackbar } from '@/contexts/snackbar';
import { useCloseListener } from '@/hooks/use-close-listener';
import { cn } from '@/helpers/styles';
import { sounds } from '@/data/sounds';

Expand Down Expand Up @@ -77,6 +78,8 @@ export function SharedModal() {
showSnackbar('Done! You can now play the new selection.');
};

useCloseListener(() => setIsOpen(false));

return (
<Modal show={isOpen} onClose={() => setIsOpen(false)}>
<h1 className={styles.heading}>New sound mix detected!</h1>
Expand Down
14 changes: 11 additions & 3 deletions src/components/toolbox/pomodoro/pomodoro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ import styles from './pomodoro.module.css';

interface PomodoroProps {
onClose: () => void;
open: () => void;
show: boolean;
}

export function Pomodoro({ onClose, show }: PomodoroProps) {
export function Pomodoro({ onClose, open, show }: PomodoroProps) {
const [showSetting, setShowSetting] = useState(false);

const [selectedTab, setSelectedTab] = useState('pomodoro');
Expand Down Expand Up @@ -125,7 +126,10 @@ export function Pomodoro({ onClose, show }: PomodoroProps) {
<Button
icon={<IoMdSettings />}
tooltip="Change Times"
onClick={() => setShowSetting(true)}
onClick={() => {
onClose();
setShowSetting(true);
}}
/>
</div>
</header>
Expand Down Expand Up @@ -157,10 +161,14 @@ export function Pomodoro({ onClose, show }: PomodoroProps) {
<Setting
show={showSetting}
times={times}
onClose={() => setShowSetting(false)}
onChange={times => {
setShowSetting(false);
setTimes(times);
open();
}}
onClose={() => {
setShowSetting(false);
open();
}}
/>
</>
Expand Down
11 changes: 11 additions & 0 deletions src/hooks/use-close-listener.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { useEffect } from 'react';

import { onCloseModal } from '@/lib/modal';

export function useCloseListener(listener: () => void) {
useEffect(() => {
const unsubscribe = onCloseModal(listener);

return unsubscribe;
}, [listener]);
}
13 changes: 13 additions & 0 deletions src/lib/event.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export function dispatch(eventName: string) {
const event = new Event(eventName);

document.dispatchEvent(event);
}

export function subscribe(eventName: string, listener: () => void) {
document.addEventListener(eventName, listener);
}

export function unsubscribe(eventName: string, listener: () => void) {
document.removeEventListener(eventName, listener);
}
11 changes: 11 additions & 0 deletions src/lib/modal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { dispatch, subscribe, unsubscribe } from './event';

export function closeModals() {
dispatch('closeModals');
}

export function onCloseModal(listener: () => void) {
subscribe('closeModals', listener);

return () => unsubscribe('closeModals', listener);
}

0 comments on commit af92b1e

Please sign in to comment.