Files
spotizerr-dev/static/html/config.html
2025-06-03 22:37:45 -06:00

387 lines
20 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Configuration - Spotizerr</title>
<!-- Add the new base.css first -->
<link rel="stylesheet" href="{{ url_for('static', filename='css/main/base.css') }}" />
<link rel="stylesheet" href="{{ url_for('static', filename='css/config/config.css') }}" />
<link rel="stylesheet" href="{{ url_for('static', filename='css/main/icons.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/queue/queue.css') }}">
</head>
<body>
<div class="app-container">
<div class="config-container">
<header class="config-header">
<h1 class="header-title">Configuration</h1>
<span class="version-text">Set on build</span>
</header>
<div class="account-config card">
<h2 class="section-title">Download Settings</h2>
<!-- Default service selection - new element -->
<div class="config-item">
<label>Default Service:</label>
<select id="defaultServiceSelect" class="form-select">
<option value="spotify">Spotify</option>
</select>
<div class="setting-description">
The default service to use for downloads when not explicitly specified
</div>
</div>
<!-- Your account config section remains unchanged -->
<div class="config-item spotify-specific">
<label>Active Spotify Account:</label>
<select id="spotifyAccountSelect" class="form-select"></select>
<div id="spotifyAccountMessage" style="display: none; color: #888; margin-top: 5px;"></div>
</div>
<div class="config-item spotify-specific">
<label>Spotify Quality:</label>
<select id="spotifyQualitySelect" class="form-select">
<option value="NORMAL">OGG 96</option>
<option value="HIGH">OGG 160</option>
<option value="VERY_HIGH">OGG 320 (premium)</option>
</select>
</div>
<div class="config-item deezer-specific">
<label>Active Deezer Account:</label>
<select id="deezerAccountSelect" class="form-select"></select>
<div id="deezerAccountMessage" style="display: none; color: #888; margin-top: 5px;"></div>
</div>
<div class="config-item deezer-specific">
<label>Deezer Quality:</label>
<select id="deezerQualitySelect" class="form-select">
<option value="MP3_128">MP3 128</option>
<option value="MP3_320">MP3 320 (sometimes premium)</option>
<option value="FLAC">FLAC (premium)</option>
</select>
</div>
<!-- Explicit Filter Status -->
<div class="config-item">
<label>Explicit Content Filter:</label>
<div class="env-controlled-setting">
<span id="explicitFilterStatus" class="env-controlled-value">Loading...</span>
<div class="env-controlled-badge">ENV</div>
</div>
<div class="setting-description">
Filter explicit content. Controlled by environment variable EXPLICIT_FILTER.
</div>
</div>
<div class="config-item">
<label>Download Fallback:</label>
<label class="switch">
<input type="checkbox" id="fallbackToggle" />
<span class="slider"></span>
</label>
</div>
<div class="config-item">
<label>Real time downloading:</label>
<label class="switch">
<input type="checkbox" id="realTimeToggle" />
<span class="slider"></span>
</label>
</div>
<div class="config-item">
<label for="maxConcurrentDownloads">Max Concurrent Downloads:</label>
<input type="number" id="maxConcurrentDownloads" min="1" value="3" class="form-input">
</div>
<!-- New Conversion Options -->
<h2 class="section-title">Conversion Settings</h2>
<div class="config-item">
<label for="convertToSelect">Convert To Format:</label>
<select id="convertToSelect" class="form-select">
<option value="">No Conversion</option>
<option value="MP3">MP3</option>
<option value="AAC">AAC</option>
<option value="OGG">OGG</option>
<option value="OPUS">OPUS</option>
<option value="FLAC">FLAC</option>
<option value="WAV">WAV</option>
<option value="ALAC">ALAC</option>
</select>
<div class="setting-description">
Select a format to convert downloaded files to. "No Conversion" keeps the original format.
</div>
</div>
<div class="config-item">
<label for="bitrateSelect">Bitrate:</label>
<select id="bitrateSelect" class="form-select" disabled>
<!-- Options will be populated by JavaScript -->
<option value="">N/A</option>
</select>
<div class="setting-description">
Select the bitrate for the chosen format. Only applicable for lossy formats.
</div>
</div>
<!-- New Retry Options -->
<h2 class="section-title">Retry Options</h2>
<div class="config-item">
<label for="maxRetries">Max Retry Attempts:</label>
<input type="number" id="maxRetries" min="0" max="10" value="3" class="form-input">
</div>
<div class="config-item">
<label for="retryDelaySeconds">Initial Retry Delay (seconds):</label>
<input type="number" id="retryDelaySeconds" min="1" value="5" class="form-input">
</div>
<div class="config-item">
<label for="retryDelayIncrease">Retry Delay Increase (seconds):</label>
<input type="number" id="retryDelayIncrease" min="0" value="5" class="form-input">
<div class="setting-description">
The amount of additional delay to add for each retry attempt
</div>
</div>
<!-- New Formatting Options -->
<h2 class="section-title">Formatting Options</h2>
<div class="config-item">
<label>Custom Directory Format:</label>
<input
type="text"
id="customDirFormat"
placeholder="e.g. %artist%/%album%"
class="form-input"
/>
<div class="format-help">
<select id="dirFormatHelp" class="format-selector">
<option value="">-- Select placeholder --</option>
<optgroup label="Common">
<option value="%music%">%music% - Track title</option>
<option value="%artist%">%artist% - Track artist. If multiple artists, use %artist_1%, %artist_2%, etc. to select a specific one.</option>
<option value="%album%">%album% - Album name</option>
<option value="%ar_album%">%ar_album% - Album artist. If multiple album artists, use %ar_album_1%, %ar_album_2%, etc. to select a specific one.</option>
<option value="%tracknum%">%tracknum% - Track number</option>
<option value="%year%">%year% - Year of release</option>
</optgroup>
<optgroup label="Additional">
<option value="%discnum%">%discnum% - Disc number</option>
<option value="%date%">%date% - Release date</option>
<option value="%genre%">%genre% - Music genre</option>
<option value="%isrc%">%isrc% - International Standard Recording Code</option>
<option value="%explicit%">%explicit% - Explicit content flag</option>
<option value="%duration%">%duration% - Track duration (seconds)</option>
</optgroup>
<optgroup label="Metadata">
<option value="%publisher%">%publisher% - Publisher information</option>
<option value="%composer%">%composer% - Track composer</option>
<option value="%copyright%">%copyright% - Copyright information</option>
<option value="%author%">%author% - Author information</option>
<option value="%lyricist%">%lyricist% - Lyricist information</option>
<option value="%version%">%version% - Version information</option>
<option value="%comment%">%comment% - Comment field</option>
</optgroup>
<optgroup label="Other">
<option value="%encodedby%">%encodedby% - Encoded by information</option>
<option value="%language%">%language% - Language information</option>
<option value="%lyrics%">%lyrics% - Track lyrics</option>
<option value="%mood%">%mood% - Mood information</option>
<option value="%rating%">%rating% - Track rating</option>
<option value="%website%">%website% - Website information</option>
</optgroup>
<optgroup label="ReplayGain">
<option value="%replaygain_album_gain%">%replaygain_album_gain% - Album gain</option>
<option value="%replaygain_album_peak%">%replaygain_album_peak% - Album peak</option>
<option value="%replaygain_track_gain%">%replaygain_track_gain% - Track gain</option>
<option value="%replaygain_track_peak%">%replaygain_track_peak% - Track peak</option>
</optgroup>
</select>
</div>
</div>
<div class="config-item">
<label>Custom Track Format:</label>
<input
type="text"
id="customTrackFormat"
placeholder="e.g. %tracknum% - %music%"
class="form-input"
/>
<div class="format-help">
<select id="trackFormatHelp" class="format-selector">
<option value="">-- Select placeholder --</option>
<optgroup label="Common">
<option value="%music%">%music% - Track title</option>
<option value="%artist%">%artist% - Track artist. If multiple artists, use %artist_1%, %artist_2%, etc. to select a specific one.</option>
<option value="%album%">%album% - Album name</option>
<option value="%ar_album%">%ar_album% - Album artist. If multiple album artists, use %ar_album_1%, %ar_album_2%, etc. to select a specific one.</option>
<option value="%tracknum%">%tracknum% - Track number</option>
<option value="%year%">%year% - Year of release</option>
</optgroup>
<optgroup label="Additional">
<option value="%discnum%">%discnum% - Disc number</option>
<option value="%date%">%date% - Release date</option>
<option value="%genre%">%genre% - Music genre</option>
<option value="%isrc%">%isrc% - International Standard Recording Code</option>
<option value="%explicit%">%explicit% - Explicit content flag</option>
<option value="%duration%">%duration% - Track duration (seconds)</option>
</optgroup>
<optgroup label="Metadata">
<option value="%publisher%">%publisher% - Publisher information</option>
<option value="%composer%">%composer% - Track composer</option>
<option value="%copyright%">%copyright% - Copyright information</option>
<option value="%author%">%author% - Author information</option>
<option value="%lyricist%">%lyricist% - Lyricist information</option>
<option value="%version%">%version% - Version information</option>
<option value="%comment%">%comment% - Comment field</option>
</optgroup>
<optgroup label="Other">
<option value="%encodedby%">%encodedby% - Encoded by information</option>
<option value="%language%">%language% - Language information</option>
<option value="%lyrics%">%lyrics% - Track lyrics</option>
<option value="%mood%">%mood% - Mood information</option>
<option value="%rating%">%rating% - Track rating</option>
<option value="%website%">%website% - Website information</option>
<option value="%quality%">%quality% - Quality of the track</option>
</optgroup>
<optgroup label="ReplayGain">
<option value="%replaygain_album_gain%">%replaygain_album_gain% - Album gain</option>
<option value="%replaygain_album_peak%">%replaygain_album_peak% - Album peak</option>
<option value="%replaygain_track_gain%">%replaygain_track_gain% - Track gain</option>
<option value="%replaygain_track_peak%">%replaygain_track_peak% - Track peak</option>
</optgroup>
</select>
</div>
<div class="setting-description">
Note that these placeholder depend on the metadata of the track, if one entry is not available in a track, the placeholder will be replaced with an empty string.
</div>
</div>
<!-- New Track Number Padding Toggle -->
<div class="config-item">
<label>Track Number Padding:</label>
<label class="switch">
<input type="checkbox" id="tracknumPaddingToggle" />
<span class="slider"></span>
</label>
<div class="setting-description">
When enabled: "01. Track" - When disabled: "1. Track"
</div>
</div>
<!-- New Save Cover Art Toggle -->
<div class="config-item">
<label>Save Cover Art:</label>
<label class="switch">
<input type="checkbox" id="saveCoverToggle" />
<span class="slider"></span>
</label>
<div class="setting-description">
When enabled, cover art will saved as cover.jpg in the same directory as the track.
</div>
</div>
</div>
<div class="watch-options-config card">
<h2 class="section-title">Watch Options</h2>
<div class="config-item">
<label>Enable Watch Feature:</label>
<label class="switch">
<input type="checkbox" id="watchEnabledToggle" />
<span class="slider"></span>
</label>
<div class="setting-description">
Enable or disable the entire watch feature (monitoring playlists and artists for new content).
</div>
</div>
<div id="watchEnabledWarning" class="config-item urgent-warning-message" style="display: none;">
<svg class="warning-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="24px" height="24px"><path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/></svg>
Warning: Enable "Real time downloading" in the Download Settings to avoid rate-limiting issues. If you don't, you WILL (pretty much immediately) encounter API rate limits, and the watch feature WILL break.
</div>
<div class="config-item">
<label for="watchedArtistAlbumGroup">Artist Page - Album Groups to Watch:</label>
<div id="watchedArtistAlbumGroupChecklist" class="checklist-container">
<div class="checklist-item">
<input type="checkbox" id="albumGroup-album" name="watchedArtistAlbumGroup" value="album">
<label for="albumGroup-album">Album</label>
</div>
<div class="checklist-item">
<input type="checkbox" id="albumGroup-single" name="watchedArtistAlbumGroup" value="single">
<label for="albumGroup-single">Single</label>
</div>
<div class="checklist-item">
<input type="checkbox" id="albumGroup-compilation" name="watchedArtistAlbumGroup" value="compilation">
<label for="albumGroup-compilation">Compilation</label>
</div>
<div class="checklist-item">
<input type="checkbox" id="albumGroup-appears_on" name="watchedArtistAlbumGroup" value="appears_on">
<label for="albumGroup-appears_on">Appears On</label>
</div>
</div>
<div class="setting-description">
Select which album groups to monitor on watched artist pages.
</div>
</div>
<div class="config-item">
<label for="watchPollIntervalSeconds">Watch Poll Interval (seconds):</label>
<input type="number" id="watchPollIntervalSeconds" min="60" value="3600" class="form-input">
<div class="setting-description">
How often to check watched items for updates (e.g., new playlist tracks, new artist albums).
</div>
</div>
</div>
<div class="accounts-section">
<div class="service-tabs">
<button class="tab-button active" data-service="spotify">Spotify</button>
<button class="tab-button" data-service="deezer">Deezer</button>
</div>
<!-- Wrapper for the list and the add button -->
<div class="credentials-list-wrapper card">
<div class="credentials-list-items">
<!-- Dynamic credential items will be rendered here by JavaScript -->
<!-- "No credentials" message will also be rendered here -->
</div>
<div class="add-account-item">
<button id="showAddAccountFormBtn" class="btn-add-account-styled" type="button">
<img src="{{ url_for('static', filename='images/plus-circle.svg') }}" alt="Add" /> Add New Account
</button>
</div>
</div>
<div class="credentials-form card">
<h2 id="formTitle" class="section-title">Add New Spotify Account</h2>
<form id="credentialForm">
<div class="config-item">
<label>Name:</label>
<input type="text" id="credentialName" class="form-input" required />
</div>
<div id="serviceFields"></div>
<div id="searchFields" style="display: none;"></div>
<button type="submit" id="submitCredentialBtn" class="btn btn-primary save-btn">Save Account</button>
<button type="button" id="cancelAddAccountBtn" class="btn btn-secondary cancel-btn btn-cancel-icon" style="margin-left: 10px;" title="Cancel">
<img src="{{ url_for('static', filename='images/cross.svg') }}" alt="Cancel" />
</button>
</form>
<div id="configSuccess" class="success"></div>
<div id="configError" class="error"></div>
</div>
</div>
</div>
</div>
<!-- Fixed floating buttons for back and queue -->
<a href="/history" class="btn-icon history-nav-btn floating-icon settings-icon" aria-label="Download History" title="Go to Download History">
<img src="{{ url_for('static', filename='images/history.svg') }}" alt="History" onerror="handleImageError(this)"/>
</a>
<a href="/" class="back-button floating-icon settings-icon" aria-label="Back to app">
<img src="{{ url_for('static', filename='images/arrow-left.svg') }}" alt="Back" />
</a>
<a id="watchlistButton" href="/watchlist" class="btn-icon watchlist-icon floating-icon hidden" aria-label="Watchlist" title="Go to Watchlist">
<img src="{{ url_for('static', filename='images/binoculars.svg') }}" alt="Watchlist" onerror="handleImageError(this)"/>
</a>
<button
id="queueIcon"
class="btn-icon queue-icon floating-icon"
aria-label="Download queue"
aria-controls="downloadQueue"
aria-expanded="false"
>
<img src="{{ url_for('static', filename='images/queue.svg') }}" alt="Queue" />
</button>
<!-- Load config.js as a module so you can import queue.js -->
<script type="module" src="{{ url_for('static', filename='js/config.js') }}"></script>
</body>
</html>