diff options
| -rw-r--r-- | assets/css/custom.css | 55 | ||||
| -rw-r--r-- | layouts/_default/baseof.html | 90 |
2 files changed, 144 insertions, 1 deletions
diff --git a/assets/css/custom.css b/assets/css/custom.css index acbff4f..addb33a 100644 --- a/assets/css/custom.css +++ b/assets/css/custom.css | |||
| @@ -452,4 +452,59 @@ button#clear-search svg { | |||
| 452 | 452 | ||
| 453 | .back-to-top { | 453 | .back-to-top { |
| 454 | text-align: center; | 454 | text-align: center; |
| 455 | } | ||
| 456 | |||
| 457 | #setlist-tab { | ||
| 458 | position: fixed; | ||
| 459 | bottom: 5px; | ||
| 460 | right: 3px; | ||
| 461 | background: rgba(0, 0, 0, 0.5); /* translucent black */ | ||
| 462 | color: white; | ||
| 463 | padding: 3px 5px; | ||
| 464 | border-radius: 6px; | ||
| 465 | font-size: 14px; | ||
| 466 | cursor: pointer; | ||
| 467 | z-index: 9999; | ||
| 468 | transition: opacity 0.2s ease-in-out, background 0.2s; | ||
| 469 | opacity: 0.6; | ||
| 470 | } | ||
| 471 | |||
| 472 | #setlist-tab:hover { | ||
| 473 | background: rgba(0, 0, 0, 0.7); /* slightly darker on hover */ | ||
| 474 | opacity: 1; /* fade in */ | ||
| 475 | } | ||
| 476 | |||
| 477 | #setlist-sidebar { | ||
| 478 | position: fixed; | ||
| 479 | bottom: 50px; | ||
| 480 | right: 10px; | ||
| 481 | width: 250px; | ||
| 482 | background: #241E1A; | ||
| 483 | border: 2px solid #ccc; | ||
| 484 | padding: 12px; | ||
| 485 | border-radius: 8px; | ||
| 486 | box-shadow: 0 0 8px rgba(0,0,0,0.2); | ||
| 487 | z-index: 9998; | ||
| 488 | } | ||
| 489 | |||
| 490 | #setlist-sidebar h6{ | ||
| 491 | margin-top: 5px; | ||
| 492 | } | ||
| 493 | |||
| 494 | #setlist-sidebar.hidden { | ||
| 495 | display: none; | ||
| 496 | } | ||
| 497 | |||
| 498 | #setlist li { | ||
| 499 | display: flex; | ||
| 500 | justify-content: space-between; | ||
| 501 | margin-bottom: 6px; | ||
| 502 | } | ||
| 503 | |||
| 504 | #setlist li button { | ||
| 505 | background: none; | ||
| 506 | border: none; | ||
| 507 | color: red; | ||
| 508 | font-size: 1rem; | ||
| 509 | cursor: pointer; | ||
| 455 | } \ No newline at end of file | 510 | } \ No newline at end of file |
diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html index d505868..9dad6a7 100644 --- a/layouts/_default/baseof.html +++ b/layouts/_default/baseof.html | |||
| @@ -27,6 +27,16 @@ | |||
| 27 | </main> | 27 | </main> |
| 28 | </div> | 28 | </div> |
| 29 | 29 | ||
| 30 | |||
| 31 | <div id="setlist-tab">Setlist</div> | ||
| 32 | |||
| 33 | <div id="setlist-sidebar" class="hidden"> | ||
| 34 | <h6>Set List</h3> | ||
| 35 | <ul id="setlist"></ul> | ||
| 36 | <button id="add-to-setlist">+ Add Song</button> | ||
| 37 | </div> | ||
| 38 | |||
| 39 | |||
| 30 | </body> | 40 | </body> |
| 31 | 41 | ||
| 32 | <script> | 42 | <script> |
| @@ -113,7 +123,16 @@ document.addEventListener("DOMContentLoaded", () => { | |||
| 113 | renderChords(); | 123 | renderChords(); |
| 114 | 124 | ||
| 115 | const selector = document.getElementById('key-selector'); | 125 | const selector = document.getElementById('key-selector'); |
| 116 | const originalKey = selector?.dataset.originalKey || 'C'; | 126 | const originalKey = selector?.dataset.originalKey || 'C'; |
| 127 | |||
| 128 | // Read override from URL query | ||
| 129 | const urlParams = new URLSearchParams(window.location.search); | ||
| 130 | const selectedKey = urlParams.get('key') || selector?.value || originalKey; | ||
| 131 | |||
| 132 | // Set selector to match the query key (if present) | ||
| 133 | if (selector && selectedKey) { | ||
| 134 | selector.value = selectedKey; | ||
| 135 | } | ||
| 117 | 136 | ||
| 118 | // Trigger initial transpose to match the default selected key | 137 | // Trigger initial transpose to match the default selected key |
| 119 | transposeToKey(originalKey, selector.value); | 138 | transposeToKey(originalKey, selector.value); |
| @@ -142,6 +161,75 @@ document.addEventListener("DOMContentLoaded", () => { | |||
| 142 | document.body.classList.toggle("hide-chords", !toggle.checked); | 161 | document.body.classList.toggle("hide-chords", !toggle.checked); |
| 143 | }); | 162 | }); |
| 144 | }); | 163 | }); |
| 164 | |||
| 165 | document.addEventListener("DOMContentLoaded", () => { | ||
| 166 | const setlistTab = document.getElementById("setlist-tab"); | ||
| 167 | const setlistSidebar = document.getElementById("setlist-sidebar"); | ||
| 168 | const setlistEl = document.getElementById("setlist"); | ||
| 169 | const addButton = document.getElementById("add-to-setlist"); | ||
| 170 | |||
| 171 | // Load setlist from localStorage | ||
| 172 | let setlist = JSON.parse(localStorage.getItem("setlist")) || []; | ||
| 173 | |||
| 174 | function saveSetlist() { | ||
| 175 | localStorage.setItem("setlist", JSON.stringify(setlist)); | ||
| 176 | } | ||
| 177 | |||
| 178 | function renderSetlist() { | ||
| 179 | setlistEl.innerHTML = ""; | ||
| 180 | setlist.forEach((song) => { | ||
| 181 | const li = document.createElement("li"); | ||
| 182 | |||
| 183 | const link = document.createElement("a"); | ||
| 184 | link.href = song.url; | ||
| 185 | link.textContent = song.title; | ||
| 186 | link.style.flex = "1"; | ||
| 187 | |||
| 188 | const key = document.createElement("span"); | ||
| 189 | key.textContent = ` (${song.key})`; | ||
| 190 | key.style.marginLeft = "6px"; | ||
| 191 | key.style.color = "#555"; | ||
| 192 | |||
| 193 | const removeBtn = document.createElement("button"); | ||
| 194 | removeBtn.textContent = "−"; | ||
| 195 | removeBtn.addEventListener("click", () => { | ||
| 196 | setlist = setlist.filter((s) => s.url !== song.url); | ||
| 197 | saveSetlist(); | ||
| 198 | renderSetlist(); | ||
| 199 | }); | ||
| 200 | |||
| 201 | li.appendChild(link); | ||
| 202 | li.appendChild(key); | ||
| 203 | li.appendChild(removeBtn); | ||
| 204 | setlistEl.appendChild(li); | ||
| 205 | }); | ||
| 206 | } | ||
| 207 | |||
| 208 | // Toggle sidebar | ||
| 209 | setlistTab.addEventListener("click", () => { | ||
| 210 | setlistSidebar.classList.toggle("hidden"); | ||
| 211 | }); | ||
| 212 | |||
| 213 | // Add current song | ||
| 214 | addButton.addEventListener("click", () => { | ||
| 215 | const title = document.title.split(" | ")[0]; // Adjust to your site's title format | ||
| 216 | const url = window.location.href; | ||
| 217 | const keySelector = document.getElementById("key-selector"); | ||
| 218 | const transposedKey = keySelector?.value || "C"; | ||
| 219 | |||
| 220 | const exists = setlist.some((s) => s.url === url); | ||
| 221 | if (!exists) { | ||
| 222 | // Add ?key=E or &key=E if query already exists | ||
| 223 | const urlObj = new URL(url); | ||
| 224 | urlObj.searchParams.set("key", transposedKey); | ||
| 225 | setlist.push({ title, url: urlObj.toString(), key: transposedKey }); | ||
| 226 | saveSetlist(); | ||
| 227 | renderSetlist(); | ||
| 228 | } | ||
| 229 | }); | ||
| 230 | |||
| 231 | renderSetlist(); | ||
| 232 | }); | ||
| 145 | </script> | 233 | </script> |
| 146 | {{ end }} | 234 | {{ end }} |
| 147 | 235 | ||
