huh?
This commit is contained in:
65
static/html/album.html
Normal file
65
static/html/album.html
Normal file
@@ -0,0 +1,65 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Album Viewer - 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/queue/queue.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/main/icons.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/album/album.css') }}" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-container">
|
||||
<div id="album-header" class="content-header hidden">
|
||||
<!-- Album Image -->
|
||||
<img id="album-image" class="header-image" alt="Album cover" onerror="this.src='/static/images/placeholder.jpg'">
|
||||
|
||||
<!-- Album Info -->
|
||||
<div id="album-info" class="header-info">
|
||||
<h1 id="album-name" class="header-title"></h1>
|
||||
<p id="album-artist" class="header-subtitle"></p>
|
||||
<p id="album-stats" class="header-subtitle"></p>
|
||||
<p id="album-copyright" class="album-copyright"></p>
|
||||
|
||||
<!-- Download Button -->
|
||||
<div class="header-actions">
|
||||
<button id="downloadAlbumBtn" class="download-btn btn-primary">
|
||||
<img src="{{ url_for('static', filename='images/download.svg') }}" alt="Download">
|
||||
Download Full Album
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="tracks-container" class="hidden">
|
||||
<h2 class="section-title">Tracks</h2>
|
||||
<div id="tracks-list" class="tracks-list"></div>
|
||||
</div>
|
||||
|
||||
<!-- Loading and Error states -->
|
||||
<div id="loading" class="loading">
|
||||
<div class="loading-indicator">Loading...</div>
|
||||
</div>
|
||||
<div id="error" class="error hidden">Error loading album</div>
|
||||
</div>
|
||||
|
||||
<!-- Fixed floating buttons for home and queue -->
|
||||
<button id="homeButton" class="btn-icon home-btn floating-icon settings-icon" aria-label="Return to home">
|
||||
<img src="{{ url_for('static', filename='images/home.svg') }}" alt="Home">
|
||||
</button>
|
||||
|
||||
<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 Icon">
|
||||
</button>
|
||||
|
||||
<script type="module" src="{{ url_for('static', filename='js/album.js') }}"></script>
|
||||
</body>
|
||||
</html>
|
||||
65
static/html/artist.html
Normal file
65
static/html/artist.html
Normal file
@@ -0,0 +1,65 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Artist Viewer - 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/queue/queue.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/main/icons.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/artist/artist.css') }}" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-container">
|
||||
<!-- Artist header container -->
|
||||
<div id="artist-header" class="content-header hidden">
|
||||
<!-- Artist Image -->
|
||||
<img id="artist-image" class="header-image" alt="Artist image" onerror="this.src='/static/images/placeholder.jpg'">
|
||||
|
||||
<!-- Artist Info -->
|
||||
<div id="artist-info" class="header-info">
|
||||
<h1 id="artist-name" class="header-title"></h1>
|
||||
<p id="artist-stats" class="header-subtitle"></p>
|
||||
|
||||
<!-- Download Button -->
|
||||
<div class="header-actions">
|
||||
<button id="downloadArtistBtn" class="download-btn btn-primary">
|
||||
<img src="{{ url_for('static', filename='images/download.svg') }}" alt="Download">
|
||||
Download All Discography
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Albums container -->
|
||||
<div id="albums-container" class="hidden">
|
||||
<!-- This container will hold one section per album type -->
|
||||
<div id="album-groups" class="album-groups"></div>
|
||||
</div>
|
||||
|
||||
<!-- Loading and Error states -->
|
||||
<div id="loading" class="loading">
|
||||
<div class="loading-indicator">Loading...</div>
|
||||
</div>
|
||||
<div id="error" class="error hidden">Error loading artist info</div>
|
||||
</div>
|
||||
|
||||
<!-- Fixed floating buttons for home and queue -->
|
||||
<button id="homeButton" class="btn-icon home-btn floating-icon settings-icon" aria-label="Return to home">
|
||||
<img src="{{ url_for('static', filename='images/home.svg') }}" alt="Home">
|
||||
</button>
|
||||
|
||||
<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 Icon">
|
||||
</button>
|
||||
|
||||
<script type="module" src="{{ url_for('static', filename='js/artist.js') }}"></script>
|
||||
</body>
|
||||
</html>
|
||||
287
static/html/config.html
Normal file
287
static/html/config.html
Normal file
@@ -0,0 +1,287 @@
|
||||
<!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>
|
||||
</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 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</option>
|
||||
<option value="%album%">%album% - Album name</option>
|
||||
<option value="%ar_album%">%ar_album% - Album artist</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</option>
|
||||
<option value="%album%">%album% - Album name</option>
|
||||
<option value="%ar_album%">%ar_album% - Album artist</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 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>
|
||||
</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="/" 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>
|
||||
|
||||
<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>
|
||||
BIN
static/html/favicon.ico
Executable file
BIN
static/html/favicon.ico
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
78
static/html/main.html
Executable file
78
static/html/main.html
Executable file
@@ -0,0 +1,78 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>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/main/main.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') }}">
|
||||
<script>
|
||||
// Helper function to handle image loading errors
|
||||
function handleImageError(img) {
|
||||
img.src = '/static/images/placeholder.jpg';
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-container">
|
||||
<div class="search-header">
|
||||
<div class="search-input-container">
|
||||
<input
|
||||
type="text"
|
||||
class="search-input"
|
||||
placeholder="Search tracks, albums, playlists or artists... (Or paste in a spotify url)"
|
||||
id="searchInput"
|
||||
/>
|
||||
<select class="search-type" id="searchType">
|
||||
<option value="track">Tracks</option>
|
||||
<option value="album">Albums</option>
|
||||
<option value="playlist">Playlists</option>
|
||||
<option value="artist">Artists</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button class="search-button btn-primary" id="searchButton" aria-label="Search">
|
||||
<img src="{{ url_for('static', filename='images/search.svg') }}" alt="" />
|
||||
Search
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Results container -->
|
||||
<div id="resultsContainer" class="results-grid"></div>
|
||||
|
||||
<!-- Empty state when there are no results -->
|
||||
<div id="emptyState" class="empty-state">
|
||||
<div class="empty-state-content">
|
||||
<img src="{{ url_for('static', filename='images/music.svg') }}" alt="Music" class="empty-state-icon" />
|
||||
<h2>Search for music</h2>
|
||||
<p>Find and download your favorite tracks, albums, playlists or artists</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Loading indicator -->
|
||||
<div id="loadingResults" class="loading hidden">
|
||||
<div class="loading-indicator">Searching...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Fixed floating buttons for settings and queue -->
|
||||
<a href="/config" class="btn-icon settings-icon floating-icon" aria-label="Settings">
|
||||
<img src="{{ url_for('static', filename='images/settings.svg') }}" alt="Settings" 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="" onerror="handleImageError(this)"/>
|
||||
</button>
|
||||
|
||||
<script type="module" src="{{ url_for('static', filename='js/main.js') }}"></script>
|
||||
</body>
|
||||
</html>
|
||||
69
static/html/playlist.html
Normal file
69
static/html/playlist.html
Normal file
@@ -0,0 +1,69 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Playlist Viewer - 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/queue/queue.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/main/icons.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/playlist/playlist.css') }}" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-container">
|
||||
<div id="playlist-header" class="content-header hidden">
|
||||
<!-- Playlist Image -->
|
||||
<img id="playlist-image" class="header-image" alt="Playlist cover" onerror="this.src='/static/images/placeholder.jpg'">
|
||||
|
||||
<!-- Playlist Info -->
|
||||
<div id="playlist-info" class="header-info">
|
||||
<h1 id="playlist-name" class="header-title"></h1>
|
||||
<p id="playlist-owner" class="header-subtitle"></p>
|
||||
<p id="playlist-stats" class="header-subtitle"></p>
|
||||
<p id="playlist-description" class="playlist-description"></p>
|
||||
|
||||
<!-- Download Buttons -->
|
||||
<div class="header-actions">
|
||||
<button id="downloadPlaylistBtn" class="download-btn btn-primary">
|
||||
<img src="{{ url_for('static', filename='images/download.svg') }}" alt="Download">
|
||||
Download Whole Playlist
|
||||
</button>
|
||||
<button id="downloadAlbumsBtn" class="download-btn">
|
||||
<img src="{{ url_for('static', filename='images/album.svg') }}" alt="Albums">
|
||||
Download Playlist's Albums
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="tracks-container" class="hidden">
|
||||
<h2 class="section-title">Tracks</h2>
|
||||
<div id="tracks-list" class="tracks-list"></div>
|
||||
</div>
|
||||
|
||||
<!-- Loading and Error states -->
|
||||
<div id="loading" class="loading">
|
||||
<div class="loading-indicator">Loading...</div>
|
||||
</div>
|
||||
<div id="error" class="error hidden">Error loading playlist</div>
|
||||
</div>
|
||||
|
||||
<!-- Fixed floating buttons for home and queue -->
|
||||
<button id="homeButton" class="btn-icon home-btn floating-icon settings-icon" aria-label="Return to home">
|
||||
<img src="{{ url_for('static', filename='images/home.svg') }}" alt="Home">
|
||||
</button>
|
||||
|
||||
<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 Icon">
|
||||
</button>
|
||||
|
||||
<script type="module" src="{{ url_for('static', filename='js/playlist.js') }}"></script>
|
||||
</body>
|
||||
</html>
|
||||
65
static/html/track.html
Normal file
65
static/html/track.html
Normal file
@@ -0,0 +1,65 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Track Viewer - 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/queue/queue.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/main/icons.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/track/track.css') }}">
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-container">
|
||||
<div id="track-header" class="content-header hidden">
|
||||
<!-- Album Image -->
|
||||
<img id="track-album-image" class="header-image" alt="Album cover" onerror="this.src='/static/images/placeholder.jpg'">
|
||||
|
||||
<!-- Track Info -->
|
||||
<div id="track-info" class="header-info">
|
||||
<h1 id="track-name" class="header-title"></h1>
|
||||
<p id="track-artist" class="header-subtitle"></p>
|
||||
<p id="track-album" class="header-subtitle"></p>
|
||||
|
||||
<div class="track-details">
|
||||
<span id="track-duration" class="track-detail-item"></span>
|
||||
<span id="track-explicit" class="track-detail-item"></span>
|
||||
</div>
|
||||
|
||||
<!-- Download Button moved here for better mobile layout -->
|
||||
<div class="header-actions">
|
||||
<button id="downloadTrackBtn" class="download-btn btn-primary">
|
||||
<img src="{{ url_for('static', filename='images/download.svg') }}" alt="Download">
|
||||
Download Track
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Loading and Error states -->
|
||||
<div id="loading" class="loading">
|
||||
<div class="loading-indicator">Loading...</div>
|
||||
</div>
|
||||
<div id="error" class="error hidden">Error loading track</div>
|
||||
</div>
|
||||
|
||||
<!-- Fixed floating buttons for home and queue -->
|
||||
<button id="homeButton" class="btn-icon home-btn floating-icon settings-icon" aria-label="Return to home">
|
||||
<img src="{{ url_for('static', filename='images/home.svg') }}" alt="Home">
|
||||
</button>
|
||||
|
||||
<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 Icon">
|
||||
</button>
|
||||
|
||||
<!-- The download queue container will be inserted by queue.js -->
|
||||
<script type="module" src="{{ url_for('static', filename='js/track.js') }}"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user