Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | import React, { useCallback } from "react"; import trackerActions from "store/features/tracker/trackerActions"; import { Button } from "ui/buttons/Button"; import { ToggleButtonGroup } from "ui/form/ToggleButtonGroup"; import { NumberField } from "ui/form/NumberField"; import { useAppDispatch, useAppSelector } from "store/hooks"; import type { MusicExportFormat } from "shared/lib/music/types"; import { downloadExportedSong } from "renderer/lib/music/exportSong"; import { FormField, FormRow } from "ui/form/layout/FormLayout"; import { StyledExportPanel } from "./style"; import { MAX_EXPORT_LOOPS, MIN_EXPORT_LOOPS } from "shared/lib/music/constants"; import l10n from "shared/lib/lang/l10n"; interface SongExportFormProps { name?: string; } const musicExportFormats: MusicExportFormat[] = ["mp3", "flac", "wav"]; const exportFormatOptions = musicExportFormats.map((format) => ({ value: format, label: format.toLocaleUpperCase(), })); const noop = () => {}; const SongExportForm = ({ name }: SongExportFormProps) => { const dispatch = useAppDispatch(); const song = useAppSelector((state) => state.trackerDocument.present.song); const exporting = useAppSelector((state) => state.tracker.exporting); const exportFormat = useAppSelector((state) => state.tracker.exportFormat); const exportLoopCount = useAppSelector( (state) => state.tracker.exportLoopCount, ); const exportSong = useCallback( async (format: MusicExportFormat, loopCount: number) => { Iif (!song) { return; } const filename = `${(name || "song").replace( /\.[^.]+$/, "", )}${loopCount > 1 ? `-loop-x${loopCount}` : ""}.${format}`; dispatch(trackerActions.setExporting(true)); try { await downloadExportedSong(song, format, loopCount, filename); } finally { dispatch(trackerActions.setExporting(false)); } }, [dispatch, name, song], ); const setMusicExportSettings = useCallback( (format: MusicExportFormat, loopCount: number) => { dispatch(trackerActions.setExportSettings({ format, loopCount })); }, [dispatch], ); const onChangeExportFormat = useCallback( (newFormat: MusicExportFormat) => { setMusicExportSettings(newFormat, exportLoopCount); }, [exportLoopCount, setMusicExportSettings], ); const onChangeExportLoopCount = useCallback( (event: React.ChangeEvent<HTMLInputElement>) => { const nextValue = parseInt(event.currentTarget.value, 10); Iif (Number.isNaN(nextValue)) { return; } setMusicExportSettings(exportFormat, nextValue); }, [exportFormat, setMusicExportSettings], ); const onSubmitExportPanel = useCallback(async () => { await exportSong(exportFormat, exportLoopCount); }, [exportFormat, exportLoopCount, exportSong]); return ( <StyledExportPanel> <FormRow> <FormField label={l10n("FIELD_FILE_FORMAT")} name={"exportFormat"}> <ToggleButtonGroup name="exportFormat" value={exportFormat} options={exportFormatOptions} onChange={onChangeExportFormat} /> </FormField> </FormRow> <FormRow> <NumberField name="exportLoopCount" label={l10n("FIELD_LOOPS")} value={exportLoopCount} min={MIN_EXPORT_LOOPS} max={MAX_EXPORT_LOOPS} onChange={onChangeExportLoopCount} /> </FormRow> <FormRow> {exporting ? ( <Button disabled onClick={noop}> {l10n("FIELD_EXPORTING")} </Button> ) : ( <Button onClick={onSubmitExportPanel}> {l10n("FIELD_EXPORT_SONG")} </Button> )} </FormRow> </StyledExportPanel> ); }; export default SongExportForm; |