basicly complete pattern detail presentation.
This commit is contained in:
		| @@ -3,15 +3,58 @@ | ||||
|     flex: 2; | ||||
|     border-radius: calc(var(--border-radius) * 2); | ||||
|     background-color: var(--color-surface-container); | ||||
|     padding: calc(var(--spacing) * 2) calc(var(--spacing) * 2); | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     align-items: stretch; | ||||
|     gap: calc(var(--spacing) * 2); | ||||
|     .control_panel { | ||||
|       display: flex; | ||||
|       flex-direction: column; | ||||
|       gap: calc(var(--spacing) * 2); | ||||
|       .button_row { | ||||
|         display: flex; | ||||
|         flex-direction: row; | ||||
|         align-items: center; | ||||
|         gap: calc(var(--spacing) * 2); | ||||
|       } | ||||
|     } | ||||
|     .detail_panel { | ||||
|       flex: 1; | ||||
|       display: flex; | ||||
|       flex-direction: column; | ||||
|       gap: calc(var(--spacing) * 2); | ||||
|       .detail_row { | ||||
|         display: flex; | ||||
|         flex-direction: row; | ||||
|         align-items: center; | ||||
|         gap: calc(var(--spacing) * 2); | ||||
|         .detail_unit { | ||||
|           display: flex; | ||||
|           flex-direction: row; | ||||
|           align-items: center; | ||||
|           gap: calc(var(--spacing)); | ||||
|           label { | ||||
|             min-width: 8em; | ||||
|             flex: 0 0 8em; | ||||
|             text-align: right; | ||||
|           } | ||||
|           .content { | ||||
|             flex: 1 1; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     .preview_panel { | ||||
|       min-height: 140px; | ||||
|       flex: 0 0; | ||||
|     } | ||||
|   } | ||||
|   .empty_promption { | ||||
|     flex: 2; | ||||
|     border-radius: calc(var(--border-radius) * 2); | ||||
|     background-color: var(--color-surface-container); | ||||
|     padding: calc(var(--spacing) * 2) calc(var(--spacing) * 2); | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     align-items: stretch; | ||||
|   | ||||
| @@ -1,6 +1,17 @@ | ||||
| import { useAtomValue } from 'jotai'; | ||||
| import { FC } from 'react'; | ||||
| import { CurrentPatternAtom, Pattern } from '../../context/Patterns'; | ||||
| import { invoke } from '@tauri-apps/api/core'; | ||||
| import { ask } from '@tauri-apps/plugin-dialog'; | ||||
| import dayjs from 'dayjs'; | ||||
| import { useAtomValue, useSetAtom } from 'jotai'; | ||||
| import { FC, useCallback, useMemo } from 'react'; | ||||
| import { NotificationType, useNotification } from '../../components/Notifications'; | ||||
| import PatternPreview from '../../components/PatternPreview'; | ||||
| import { | ||||
|   CurrentPatternAtom, | ||||
|   Pattern, | ||||
|   PatternsAtom, | ||||
|   SelectedPatternIdAtom, | ||||
|   totalDuration, | ||||
| } from '../../context/Patterns'; | ||||
| import styles from './PatternDetail.module.css'; | ||||
|  | ||||
| const EmptyPromption: FC = () => { | ||||
| @@ -15,11 +26,80 @@ const EmptyPromption: FC = () => { | ||||
| }; | ||||
|  | ||||
| const Detail: FC<{ pattern: Pattern }> = ({ pattern }) => { | ||||
|   const { showToast } = useNotification(); | ||||
|   const refreshPatterns = useSetAtom(PatternsAtom); | ||||
|   const resetSelected = useSetAtom(SelectedPatternIdAtom); | ||||
|   const patternDuration = useMemo(() => totalDuration(pattern), [pattern]); | ||||
|   const createTime = useMemo( | ||||
|     () => dayjs(pattern.createdAt).format('YYYY-MM-DD HH:mm:ss'), | ||||
|     [pattern], | ||||
|   ); | ||||
|  | ||||
|   const handleDeleteAction = useCallback(async () => { | ||||
|     try { | ||||
|       const answer = await ask( | ||||
|         `The pattern ${pattern.name} will be deleted, and cannot be revoked. Are you sure?`, | ||||
|         { | ||||
|           title: 'Confirm action', | ||||
|           kind: 'warning', | ||||
|         }, | ||||
|       ); | ||||
|       if (answer) { | ||||
|         await invoke('remove_pattern', { patternId: pattern.id }); | ||||
|         showToast(NotificationType.SUCCESS, 'Pattern deleted.'); | ||||
|         refreshPatterns(); | ||||
|         resetSelected(null); | ||||
|       } | ||||
|     } catch (e) { | ||||
|       console.error('[delete pattern]', e); | ||||
|       showToast(NotificationType.ERROR, 'Failed to delete pattern. Please try again.'); | ||||
|     } | ||||
|   }, [pattern]); | ||||
|  | ||||
|   return ( | ||||
|     <div className={styles.pattern_detail}> | ||||
|       <div></div> | ||||
|       <div></div> | ||||
|       <div></div> | ||||
|       <div className={styles.control_panel}> | ||||
|         <div className={styles.button_row}> | ||||
|           <button className="tonal">Edit Pattern</button> | ||||
|           <button className="tonal danger" onClick={handleDeleteAction}> | ||||
|             Delete Pattern | ||||
|           </button> | ||||
|         </div> | ||||
|         <div className={styles.button_row}> | ||||
|           <button className="tonal warn">Test Run</button> | ||||
|         </div> | ||||
|         <div className={styles.button_row}> | ||||
|           <button className="tonal secondary">Add to Channel A Playlist</button> | ||||
|           <button className="tonal secondary">Add to Channel B Playlist</button> | ||||
|         </div> | ||||
|       </div> | ||||
|       <hr className="dotted" /> | ||||
|       <div className={styles.detail_panel}> | ||||
|         <div className={styles.detail_row}> | ||||
|           <div className={styles.detail_unit}> | ||||
|             <label>Created At</label> | ||||
|             <div className={styles.content}>{createTime}</div> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div className={styles.detail_row}> | ||||
|           <div className={styles.detail_unit}> | ||||
|             <label>Duration</label> | ||||
|             <div className={styles.content}>{(patternDuration / 1000).toFixed(2)} s</div> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div className={styles.detail_row}> | ||||
|           <div className={styles.detail_unit}> | ||||
|             <label> </label> | ||||
|             <div className={styles.content}> | ||||
|               {pattern.pulses.length} key frame{pattern.pulses.length > 1 && 's'} | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|       <hr className="dotted" /> | ||||
|       <div className={styles.preview_panel}> | ||||
|         <PatternPreview /> | ||||
|       </div> | ||||
|     </div> | ||||
|   ); | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user