adjust Pulse List layout.
This commit is contained in:
		| @@ -5,14 +5,17 @@ | |||||||
|     justify-content: flex-end; |     justify-content: flex-end; | ||||||
|     align-items: center; |     align-items: center; | ||||||
|     gap: calc(var(--spacing) * 2); |     gap: calc(var(--spacing) * 2); | ||||||
|   } |     .attribute_unit { | ||||||
|   .attribute_unit { |       display: flex; | ||||||
|     display: flex; |       flex-direction: row; | ||||||
|     flex-direction: row; |       align-items: center; | ||||||
|     align-items: center; |       gap: calc(var(--spacing)); | ||||||
|     gap: calc(var(--spacing)); |       font-size: var(--body-small-font-size); | ||||||
|     label { |       line-height: var(--body-small-line-height); | ||||||
|       font-weight: bold; |       font-weight: var(--body-small-font-weight); | ||||||
|  |       label { | ||||||
|  |         font-weight: 500; | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   .pulses { |   .pulses { | ||||||
|   | |||||||
| @@ -1,39 +1,46 @@ | |||||||
| import { DndContext } from '@dnd-kit/core'; |  | ||||||
| import { Icon } from '@iconify/react/dist/iconify.js'; | import { Icon } from '@iconify/react/dist/iconify.js'; | ||||||
| import { useAtomValue } from 'jotai'; | import { useAtom, useAtomValue } from 'jotai'; | ||||||
| import { FC } from 'react'; | import { max } from 'lodash-es'; | ||||||
|  | import { FC, useCallback, useMemo } from 'react'; | ||||||
| import { ScrollArea } from '../../components/ScrollArea'; | import { ScrollArea } from '../../components/ScrollArea'; | ||||||
|  | import { addPulse, deletePulse } from '../../context/pattern-model'; | ||||||
| import { | import { | ||||||
|   CurrentPatternAtom, |   CurrentPatternAtom, | ||||||
|   CurrentPatternDuration, |   CurrentPatternDuration, | ||||||
|   PulsesInCurrentPatternAtom, |   SelectedPulseAtom, | ||||||
|  |   useSavePattern, | ||||||
| } from '../../context/Patterns'; | } from '../../context/Patterns'; | ||||||
|  | import PulseCard from './PulseCard'; | ||||||
| import styles from './PulseList.module.css'; | import styles from './PulseList.module.css'; | ||||||
|  |  | ||||||
| const PulseList: FC = () => { | const PulseList: FC = () => { | ||||||
|   const pattern = useAtomValue(CurrentPatternAtom); |   const [pattern, refreshPattern] = useAtom(CurrentPatternAtom); | ||||||
|   const pulses = useAtomValue(PulsesInCurrentPatternAtom); |  | ||||||
|   const duration = useAtomValue(CurrentPatternDuration); |   const duration = useAtomValue(CurrentPatternDuration); | ||||||
|  |   const selectedPulse = useAtomValue(SelectedPulseAtom); | ||||||
|  |   const maxPulseOrder = useMemo( | ||||||
|  |     () => max(pattern?.pulses.map((pulse) => pulse.order) ?? []), | ||||||
|  |     [pattern], | ||||||
|  |   ); | ||||||
|  |   const savePattern = useSavePattern(); | ||||||
|  |  | ||||||
|  |   const handleAddPulseAction = useCallback(async () => { | ||||||
|  |     if (!pattern) return; | ||||||
|  |     addPulse(pattern); | ||||||
|  |     await savePattern(pattern); | ||||||
|  |     refreshPattern(); | ||||||
|  |   }, [pattern]); | ||||||
|  |   const handleDeletePulseAction = useCallback(async () => { | ||||||
|  |     if (!pattern || !selectedPulse) return; | ||||||
|  |     deletePulse(pattern, selectedPulse.id); | ||||||
|  |     await savePattern(pattern); | ||||||
|  |     refreshPattern(); | ||||||
|  |   }, [pattern, selectedPulse]); | ||||||
|  |  | ||||||
|   return ( |   return ( | ||||||
|     <> |     <> | ||||||
|       <div className={styles.pulse_tools}> |  | ||||||
|         <button className="text"> |  | ||||||
|           <Icon icon="material-symbols-light:play-arrow-outline" /> |  | ||||||
|           <span>Test Run</span> |  | ||||||
|         </button> |  | ||||||
|         <button className="text"> |  | ||||||
|           <Icon icon="material-symbols-light:add" /> |  | ||||||
|           <span>Add Pulse</span> |  | ||||||
|         </button> |  | ||||||
|         <button className="text"> |  | ||||||
|           <Icon icon="material-symbols-light:delete-forever-outline" /> |  | ||||||
|           <span>Delete Selected</span> |  | ||||||
|         </button> |  | ||||||
|       </div> |  | ||||||
|       <div className={styles.pulse_tools}> |       <div className={styles.pulse_tools}> | ||||||
|         <div className={styles.attribute_unit}> |         <div className={styles.attribute_unit}> | ||||||
|           <span>{pulses.length ?? 0}</span> |           <span>{pattern?.pulses.length ?? 0}</span> | ||||||
|           <label>Key Pulses</label> |           <label>Key Pulses</label> | ||||||
|         </div> |         </div> | ||||||
|         <div className={styles.attribute_unit}> |         <div className={styles.attribute_unit}> | ||||||
| @@ -41,13 +48,43 @@ const PulseList: FC = () => { | |||||||
|           <span>{duration.toFixed(2)} s</span> |           <span>{duration.toFixed(2)} s</span> | ||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
|  |       <div className={styles.pulse_tools}> | ||||||
|  |         <button className="text" disabled> | ||||||
|  |           <Icon icon="material-symbols-light:play-arrow-outline" /> | ||||||
|  |           <span>Test Run</span> | ||||||
|  |         </button> | ||||||
|  |         <button className="text" onClick={handleAddPulseAction}> | ||||||
|  |           <Icon icon="material-symbols-light:add" /> | ||||||
|  |           <span>Add Pulse</span> | ||||||
|  |         </button> | ||||||
|  |         <button className="text" onClick={handleDeletePulseAction} disabled={!selectedPulse}> | ||||||
|  |           <Icon icon="material-symbols-light:delete-forever-outline" /> | ||||||
|  |           <span>Delete Selected</span> | ||||||
|  |         </button> | ||||||
|  |       </div> | ||||||
|  |       <div className={styles.pulse_tools}> | ||||||
|  |         <button className="text" disabled={!selectedPulse || selectedPulse.order === 1}> | ||||||
|  |           <Icon icon="material-symbols-light:arrow-upward" /> | ||||||
|  |           <span>Move Up</span> | ||||||
|  |         </button> | ||||||
|  |         <button className="text" disabled={!selectedPulse || selectedPulse.order === maxPulseOrder}> | ||||||
|  |           <Icon icon="material-symbols-light:arrow-downward" /> | ||||||
|  |           <span>Move Down</span> | ||||||
|  |         </button> | ||||||
|  |       </div> | ||||||
|       <div className={styles.pulses}> |       <div className={styles.pulses}> | ||||||
|         <ScrollArea enableY> |         <ScrollArea enableY> | ||||||
|           <DndContext> |           <div className={styles.pulse_cards}> | ||||||
|             <div className={styles.pulse_cards}> |             {pattern?.pulses.length === 0 ? ( | ||||||
|               {pulses.length === 0 && <div className="empty_prompt">No key pulses.</div>} |               <div className="empty_prompt">No key pulses.</div> | ||||||
|             </div> |             ) : ( | ||||||
|           </DndContext> |               <> | ||||||
|  |                 {pattern?.pulses.map((pulse) => ( | ||||||
|  |                   <PulseCard key={pulse.id} pulse={pulse} /> | ||||||
|  |                 ))} | ||||||
|  |               </> | ||||||
|  |             )} | ||||||
|  |           </div> | ||||||
|         </ScrollArea> |         </ScrollArea> | ||||||
|       </div> |       </div> | ||||||
|     </> |     </> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user