-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
166 lines (145 loc) · 10.7 KB
/
index.html
File metadata and controls
166 lines (145 loc) · 10.7 KB
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
<!DOCTYPE html>
<html lang="en" data-theme="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="google-site-verification" content="5lwKBMVGBS8nrFsa5iLmmwrM7x8Orb-syCvl4pvGG30" />
<title>Advanced Local Player</title>
<link rel="icon" href="https://avatars.githubusercontent.com/u/105863400">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsmediatags/3.9.5/jsmediatags.min.js"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="mobileBlocker">
<div>
<svg viewBox="0 0 24 24" width="64" height="64" fill="#ff4444" style="margin-bottom: 16px;"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/></svg>
<h2>Made for PC Only</h2>
<p>Mobile browsers strictly block websites from accessing your local folder directories due to sandbox security. Please open this application on a desktop or laptop.</p>
</div>
</div>
<div id="toast">Message</div>
<div class="app-core">
<aside class="panel sidebar-section" id="sidebar">
<div class="nav-item active" id="navAllSongs">
<svg viewBox="0 0 24 24"><path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/></svg> All Songs
</div>
<div class="nav-item" id="navSettings">
<svg viewBox="0 0 24 24"><path d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.06-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94L14.4 2.81c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41L9.25 5.35C8.66 5.59 8.12 5.92 7.63 6.29L5.24 5.33c-.22-.08-.47 0-.59.22L2.73 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.06.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .43-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.49-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/></svg> Settings
</div>
<div class="sidebar-header" style="position:relative; margin-top: 30px;">
Library Sources
<button class="action-btn" id="addSourceBtn" title="Add Music" onclick="toggleAddMenu(event)"><svg viewBox="0 0 24 24" width="16" height="16"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg></button>
<div id="addSourceMenu" class="dropdown-menu">
<div class="nav-item" onclick="addLocalFolder()">📁 Add Entire Folder</div>
<div class="nav-item" onclick="addLocalFiles()">🎵 Add Specific Files</div>
</div>
</div>
<button class="btn-small btn-restore hidden" id="restoreBtn">↻ Restore Session</button>
<div id="folderSidebarList" style="margin-bottom: 10px;"></div>
<div class="sidebar-header">
Playlists
<button class="action-btn" id="newPlaylistBtn" title="Create Playlist"><svg viewBox="0 0 24 24" width="16" height="16"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg></button>
</div>
<div class="sidebar-scroll" id="playlistSidebarList"></div>
<input type="file" id="fallbackFolderInput" webkitdirectory directory multiple accept="audio/*" class="hidden">
<input type="file" id="fallbackFileInput" multiple accept="audio/*" class="hidden">
<input type="file" id="importBackupInput" accept=".json" class="hidden">
</aside>
<div class="resizer" id="dragResizer"></div>
<main class="panel center-section">
<div class="center-header">
<div class="header-top">
<div class="header-text">
<h1><span id="viewTitle">All Songs</span></h1>
<p id="viewSubtitle">0 Tracks</p>
</div>
<div class="top-right-controls">
<button class="action-btn" id="openManualBtn" title="Manual & Shortcuts" style="background: var(--bg-hover);">
<svg viewBox="0 0 24 24" width="18" height="18"><path d="M11 7h2v2h-2zm0 4h2v6h-2zm1-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></svg>
</button>
<select id="themeDropdown" class="theme-dropdown" title="Change Visual Theme">
<option value="dark">Dark Mode</option> <option value="light">Clean Light</option> <option value="dracula">Dracula</option>
<option value="nord">Nord Blue</option> <option value="synthwave">Synthwave</option> <option value="matcha">Matcha Green</option>
<option value="solarized">Solarized</option> <option value="ocean">Deep Ocean</option> <option value="midnight">Midnight OLED</option>
<option value="random">Random Theme</option>
</select>
</div>
</div>
<div class="main-search-container" id="mainSearchContainer">
<div class="main-search-bar">
<svg viewBox="0 0 24 24"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/></svg>
<input type="text" id="searchInput" placeholder="Filter current view by song name...">
</div>
</div>
</div>
<div class="track-list-container">
<div class="track-list" id="centerTrackList">
<div style="color: var(--text-muted); text-align: center; padding: 60px 0;">No music loaded. Click the "+" next to Library Sources.</div>
</div>
<div id="batchActionBar">
<span id="batchCountText" style="font-weight: 600; font-size: 14px;">0 selected</span>
<select id="batchPlaylistSelect"><option value="">Add selected to...</option></select>
<button class="btn-small action-btn-danger hidden" id="batchRemoveBtn" style="margin:0; border:none; padding:8px 16px;">Remove</button>
<button class="action-btn" onclick="clearSelection()" title="Clear Selection" style="background: rgba(255,255,255,0.1);"><svg viewBox="0 0 24 24" width="16" height="16" fill="var(--text-main)"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg></button>
</div>
</div>
</main>
</div>
<footer class="playback-bar">
<div class="footer-left">
<div class="footer-art" id="footerArt">🎵</div>
<div class="footer-info">
<div class="footer-title" id="footerTitle">--</div>
<div class="footer-artist" id="footerArtist">--</div>
</div>
</div>
<div class="footer-center">
<div class="control-buttons">
<button class="btn-icon" id="shuffleBtn" title="Weighted Shuffle"><svg viewBox="0 0 24 24"><path d="M10.59 9.17L5.41 4 4 5.41l5.17 5.17 1.42-1.41zM14.5 4l2.04 2.04L4 18.59 5.41 20 17.96 7.46 20 9.5V4h-5.5zm.33 9.41l-1.41 1.41 3.13 3.13L14.5 20H20v-5.5l-2.04 2.04-3.13-3.13z"/></svg></button>
<button class="btn-icon" id="prevBtn" title="Previous (Ctrl+Left)"><svg viewBox="0 0 24 24"><path d="M6 6h2v12H6zm3.5 6l8.5 6V6z"/></svg></button>
<button class="btn-icon play-pause" id="playBtn" title="Play/Pause (Space)">
<svg id="playIcon" viewBox="0 0 24 24"><path d="M8 5v14l11-7z"/></svg>
<svg id="pauseIcon" viewBox="0 0 24 24" class="hidden"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>
</button>
<button class="btn-icon" id="nextBtn" title="Next (Ctrl+Right)"><svg viewBox="0 0 24 24"><path d="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z"/></svg></button>
<button class="btn-icon" id="repeatBtn" title="Repeat All"><svg viewBox="0 0 24 24"><path d="M7 7h10v3l4-4-4-4v3H5v6h2V7zm10 10H7v-3l-4 4 4 4v-3h12v-6h-2v4z"/></svg></button>
</div>
<div class="progress-container">
<span id="currentTime">0:00</span>
<input type="range" id="progressBar" min="0" max="100" value="0">
<span id="totalTime">0:00</span>
</div>
</div>
<div class="footer-right">
<button class="btn-icon" id="muteBtn" title="Mute (M)"><svg viewBox="0 0 24 24"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/></svg></button>
<input type="range" id="volumeSlider" min="0" max="1" step="0.01" value="1" style="width: 100px;">
</div>
</footer>
<audio id="audioPlayer"></audio>
<div class="modal-overlay hidden" id="manualModal">
<div class="modal-content">
<h2><svg viewBox="0 0 24 24" width="28" height="28" fill="var(--accent)"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/></svg> Welcome to Local Player</h2>
<p>Your entire music library, stored securely inside your browser cache. Zero uploads required.</p>
<h3 style="color: var(--text-main); margin-bottom: 8px; margin-top: 16px;">Quick Start</h3>
<ul style="margin-left: 20px; line-height: 1.6; color: var(--text-muted);">
<li>Click the <b>+</b> next to Library Sources to load a local folder or files.</li>
<li>Hover over a song and click the trash icon to remove it from your library or playlist.</li>
<li>Due to browser security, you must click <b>↻ Restore Session</b> when refreshing the page.</li>
</ul>
<h3 style="color: var(--text-main); margin-bottom: 8px; margin-top: 16px;">Keyboard Shortcuts</h3>
<ul style="margin-left: 20px; line-height: 1.6; color: var(--text-muted);">
<li><b>Spacebar:</b> Play / Pause</li>
<li><b>Ctrl + Right Arrow:</b> Next Track</li>
<li><b>Ctrl + Left Arrow:</b> Previous Track</li>
<li><b>Shift + Right/Left Arrow:</b> Seek forward/backward 5 seconds</li>
<li><b>M:</b> Mute / Unmute</li>
</ul>
<div style="text-align: right; margin-top: 20px;">
<button class="btn-small" id="closeManualBtn" style="background: var(--accent); color: var(--bg-base); border: none; font-size: 14px; padding: 10px 20px;">Got it!</button>
</div>
</div>
</div>
<script src="app.js"></script>
</body>
</html>