mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 15:25:46 +00:00
0e88e8a5cd
### Audio - Replay Gain support (track + album mode, configurable pre-gain, hard limiter) - Crossfade between tracks (configurable duration 1–10 s) - Gapless preloading ⚠️ experimental/alpha — enable in Settings → Playback - Atomic sink swap: old track plays until new one is decoded, then stops cleanly ### UI / UX - Settings redesigned with tab navigation (General, Playback, About) - Changelog viewer in Settings → About with collapsible version entries - Download Folder Modal: choose folder + "remember" checkbox per-download - EQ popup now accessible directly from the Player Bar - "Also Featured On" section on Artist pages for non-album appearances ### Fixes - Bundle identifier changed from dev.psysonic.app → dev.psysonic.player (fixes macOS warning) - Version sync: all four version files (package.json, Cargo.toml, tauri.conf.json, PKGBUILD) now at 1.6.0 ### Known Issues - FLAC seeking via waveform seekbar does not work (MP3/OGG unaffected) — under investigation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
57 lines
2.2 KiB
TypeScript
57 lines
2.2 KiB
TypeScript
import { FolderOpen } from 'lucide-react';
|
|
import { open as openDialog } from '@tauri-apps/plugin-dialog';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { useDownloadModalStore } from '../store/downloadModalStore';
|
|
import { useAuthStore } from '../store/authStore';
|
|
|
|
export default function DownloadFolderModal() {
|
|
const { isOpen, folder, remember, setFolder, setRemember, confirm, cancel } = useDownloadModalStore();
|
|
const setDownloadFolder = useAuthStore(s => s.setDownloadFolder);
|
|
const { t } = useTranslation();
|
|
|
|
const handleBrowse = async () => {
|
|
const selected = await openDialog({ directory: true, multiple: false, title: t('common.chooseDownloadFolder') });
|
|
if (selected && typeof selected === 'string') setFolder(selected);
|
|
};
|
|
|
|
if (!isOpen) return null;
|
|
|
|
return (
|
|
<>
|
|
<div className="eq-popup-backdrop" onClick={cancel} style={{ zIndex: 210 }} />
|
|
<div className="eq-popup" style={{ zIndex: 211, width: 'min(480px, 92vw)', gap: 0 }}>
|
|
<div className="eq-popup-header">
|
|
<span className="eq-popup-title">{t('common.chooseDownloadFolder')}</span>
|
|
</div>
|
|
|
|
<div style={{ padding: '16px 0 12px' }}>
|
|
<div className="download-folder-pick-row">
|
|
<span className="download-folder-path">
|
|
{folder || t('common.noFolderSelected')}
|
|
</span>
|
|
<button className="btn btn-ghost" onClick={handleBrowse} style={{ flexShrink: 0 }}>
|
|
<FolderOpen size={15} /> {t('settings.pickFolder')}
|
|
</button>
|
|
</div>
|
|
|
|
<label className="download-remember-row">
|
|
<input type="checkbox" checked={remember} onChange={e => setRemember(e.target.checked)} />
|
|
<span>{t('common.rememberDownloadFolder')}</span>
|
|
</label>
|
|
</div>
|
|
|
|
<div className="download-modal-actions">
|
|
<button className="btn btn-ghost" onClick={cancel}>{t('common.cancel')}</button>
|
|
<button
|
|
className="btn btn-primary"
|
|
onClick={() => confirm(setDownloadFolder)}
|
|
disabled={!folder}
|
|
>
|
|
{t('common.download')}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|