feat(settings): add folder selection for music and playlists

Add UI and logic to select music and playlists folders in settings using
tauri dialog plugin. Integrate @tauri-apps/plugin-dialog, plugin-fs, and
plugin-store in both frontend and backend. Update capabilities and
dependencies to support new plugins. Improve settings page with folder
selectors and info note for better user experience.
This commit is contained in:
2025-09-30 18:58:52 -04:00
parent 792e81a6cf
commit a8f8e4602a
9 changed files with 476 additions and 4 deletions

View File

@@ -95,6 +95,7 @@
flex-shrink: 0;
padding: 0;
overflow-y: auto;
background: #121212;
}
.sidebar-nav {
@@ -153,7 +154,7 @@
overflow-y: auto;
padding: 8px;
font-family: "Pixelated MS Sans Serif", Arial;
background: #121212;
}
.status-text {

View File

@@ -1,7 +1,91 @@
<script lang="ts">
import { onMount } from 'svelte';
import { settings, setMusicFolder, setPlaylistsFolder, loadSettings } from '$lib/stores/settings';
import { open } from '@tauri-apps/plugin-dialog';
let currentMusicFolder = $state<string | null>(null);
let currentPlaylistsFolder = $state<string | null>(null);
onMount(async () => {
await loadSettings();
currentMusicFolder = $settings.musicFolder;
currentPlaylistsFolder = $settings.playlistsFolder;
});
$effect(() => {
currentMusicFolder = $settings.musicFolder;
currentPlaylistsFolder = $settings.playlistsFolder;
});
async function selectMusicFolder() {
const selected = await open({
directory: true,
multiple: false,
title: 'Select Music Folder'
});
if (selected && typeof selected === 'string') {
await setMusicFolder(selected);
}
}
async function selectPlaylistsFolder() {
const selected = await open({
directory: true,
multiple: false,
title: 'Select Playlists Folder'
});
if (selected && typeof selected === 'string') {
await setPlaylistsFolder(selected);
}
}
</script>
<div>
<h2>Settings</h2>
<section class="library-content">
<h3>Library Folders</h3>
<p class="info-note">
<strong>Note:</strong> Music and Playlists folders should be in the same parent directory for playlists to work properly in other apps.
</p>
<div class="field-row-stacked">
<label for="music-folder">Music Folder</label>
<div class="folder-selector">
<input
type="text"
id="music-folder"
value={currentMusicFolder || 'No folder selected'}
readonly
class="folder-path"
/>
<button onclick={selectMusicFolder}>Browse...</button>
</div>
{#if currentMusicFolder}
<small class="help-text">Currently using: {currentMusicFolder}</small>
{:else}
<small class="help-text">No music folder selected. Click Browse to choose one.</small>
{/if}
</div>
<div class="field-row-stacked">
<label for="playlists-folder">Playlists Folder</label>
<div class="folder-selector">
<input
type="text"
id="playlists-folder"
value={currentPlaylistsFolder || 'No folder selected'}
readonly
class="folder-path"
/>
<button onclick={selectPlaylistsFolder}>Browse...</button>
</div>
{#if currentPlaylistsFolder}
<small class="help-text">Currently using: {currentPlaylistsFolder}</small>
{:else}
<small class="help-text">No playlists folder selected. Click Browse to choose one.</small>
{/if}
</div>
</section>
</div>
@@ -11,7 +95,50 @@
margin-top: 0;
}
h3 {
margin-top: 0;
margin-bottom: 12px;
font-size: 1.1em;
}
.library-content {
margin-top: 20px;
}
.info-note {
background-color: var(--button-shadow, #2a2a2a);
padding: 12px;
margin-bottom: 20px;
border-left: 3px solid var(--button-highlight, #606060);
font-size: 0.9em;
}
.info-note strong {
font-weight: bold;
}
.field-row-stacked {
display: flex;
flex-direction: column;
gap: 8px;
margin-bottom: 16px;
}
.folder-selector {
display: flex;
gap: 8px;
align-items: center;
}
.folder-path {
flex: 1;
background-color: var(--button-highlight);
cursor: not-allowed;
}
.help-text {
color: var(--text-color, #FFFFFF);
opacity: 0.7;
font-size: 0.9em;
}
</style>