diff options
Diffstat (limited to 'app/ui')
-rw-r--r-- | app/ui/listing.php | 27 | ||||
-rw-r--r-- | app/ui/lyrics.php | 134 | ||||
-rw-r--r-- | app/ui/navigation.php | 12 | ||||
-rw-r--r-- | app/ui/settings.php | 11 | ||||
-rw-r--r-- | app/ui/stella.php | 2 | ||||
-rw-r--r-- | app/ui/video.php | 7 |
6 files changed, 133 insertions, 60 deletions
diff --git a/app/ui/listing.php b/app/ui/listing.php index 29a1bce..fdef674 100644 --- a/app/ui/listing.php +++ b/app/ui/listing.php @@ -37,9 +37,9 @@ if (!$presetList) { } } -if (!isset($onlyStella)) $onlyStella = false; +if (!isset($onlyStella)) $onlyStella = 0; -if ($onlyStella) { +if ($onlyStella === 1) { $hasAlbum = false; $list = $songs; @@ -56,6 +56,23 @@ if ($onlyStella) { $list = array_filter($list, function ($i) { return file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/content/" . $i . ".stella"); }, ARRAY_FILTER_USE_KEY); +} elseif ($onlyStella === 2) { + $hasAlbum = false; + $list = $songs; + + foreach ($albums as $id => $album) { + foreach ($album["tracks"] as $track) { + $list[$track]["_albumID"] = $id; + } + } + + uasort($list, function ($a, $b) { + return strcmp($a["title"], $b["title"]); + }); + + $list = array_filter($list, function ($i) { + return file_exists($_SERVER['DOCUMENT_ROOT'] . "/assets/content/" . $i . ".webm"); + }, ARRAY_FILTER_USE_KEY); } ?> @@ -76,8 +93,10 @@ if ($onlyStella) { Favorites <?php elseif ($hasAlbum): ?> <?= $albums[$_GET["a"]]["title"] ?> - <?php elseif ($onlyStella): ?> + <?php elseif ($onlyStella === 1): ?> Mist Stella + <?php elseif ($onlyStella === 2): ?> + Music videos <?php else: ?> Songs <?php endif; ?> @@ -97,7 +116,7 @@ if ($onlyStella) { <div id="ui-back-button" onclick="history.back();" style="display: flex; align-items: center; justify-content: center; text-align: center;<?php if (!$hasAlbum): ?>pointer-events: none; opacity: 0;<?php endif; ?>"> <img src="/assets/icons/back.svg" alt="Back" class="icon"> </div> - <div style="display: flex; align-items: center; justify-content: center; text-align: center;"><b><?php if (!$hasAlbum && !isset($favoritesList) && !$onlyStella): ?>Songs<?php elseif ($onlyStella): ?>Mist Stella<?php endif; ?></b></div> + <div style="display: flex; align-items: center; justify-content: center; text-align: center;"><b><?php if (!$hasAlbum && !isset($favoritesList) && $onlyStella === 0): ?>Songs<?php elseif ($onlyStella === 1): ?>Mist Stella<?php elseif ($onlyStella === 2): ?>Music videos<?php endif; ?></b></div> <?php if (!$hasAlbum): ?> <div> <input placeholder="Filter" id="filter" class="form-control" style="width: 256px;height: 32px;border-top: none;" onchange="updateFilter();" onkeyup="updateFilter();"> diff --git a/app/ui/lyrics.php b/app/ui/lyrics.php index 274ff93..103167c 100644 --- a/app/ui/lyrics.php +++ b/app/ui/lyrics.php @@ -46,7 +46,10 @@ <body style="background-color: transparent;"> <script src="/assets/js/common.js"></script> <div id="lyrics-outer"> - <div id="not-playing" style="position: fixed; inset: 16px; display: flex; align-items: center; justify-content: center; opacity: .5; text-align: center;"> + <div id="not-playing" style="display: none; position: fixed; inset: 16px; align-items: center; justify-content: center; opacity: .5; text-align: center;"> + Lyrics and music videos will appear here when you start playing a song. If supported, lyrics will also scroll as the song plays. + </div> + <div id="not-playing-2" style="display: none; position: fixed; inset: 16px; align-items: center; justify-content: center; opacity: .5; text-align: center;"> Lyrics will appear here when you start playing a song. If supported, they will also scroll as the song plays. </div> @@ -58,94 +61,119 @@ Loading lyrics... </div> + <video id="video" style="width: 100%; height: 100%; display: none; position: fixed; inset: 0; background-color: black;"></video> + <div id="lyrics-unsynced" style="display: none; position: fixed; inset: 16px; overflow: auto;"></div> <div id="lyrics-synced" style="text-align: center; display: none; position: fixed; left: 16px; right: 16px; top: 0; bottom: 0; z-index: 5;"></div> <div id="lyrics-synced-fade" style="display: none; position: fixed; inset: 0; z-index: 10; background-image: linear-gradient(180deg, rgba(255,0,0,0) 25%, rgba(255,255,255,1) 100%);"></div> </div> <script> + let lastID = null; let lastTimestamp = null; window.lyrics = {}; setInterval(async () => { + if (!window.delays) window.delays = await (await fetch("/assets/delays.json")).json(); + if (window.parent.currentSongID !== lastID) { lastID = window.parent.currentSongID; if (lastID === null) { document.getElementById("lyrics-synced").style.display = "none"; + document.getElementById("video").style.display = "none"; document.getElementById("lyrics-synced-fade").style.display = "none"; document.getElementById("lyrics-unsynced").style.display = "none"; document.getElementById("not-available").style.display = "none"; document.getElementById("loading").style.display = "none"; - document.getElementById("not-playing").style.display = "flex"; + document.getElementById(localStorage.getItem("data-saving") === "true" ? "not-playing-2" : "not-playing").style.display = "flex"; } else { document.getElementById("lyrics-synced").style.display = "none"; + document.getElementById("video").style.display = "none"; document.getElementById("lyrics-synced-fade").style.display = "none"; document.getElementById("lyrics-unsynced").style.display = "none"; document.getElementById("not-available").style.display = "none"; document.getElementById("loading").style.display = "flex"; - document.getElementById("not-playing").style.display = "none"; - - if (!window.lyrics[lastID]) { - window.lyricsLoadTimeout = setTimeout(() => { - location.reload(); - }, 10000); - - try { - window.lyrics[lastID] = await (await fetch("/api/lyrics.php?id=" + lastID)).json() - } catch (e) { - window.lyrics[lastID] = { - synced: false, - payload: null + document.getElementById(localStorage.getItem("data-saving") === "true" ? "not-playing-2" : "not-playing").style.display = "none"; + + window.hasVideo = await (await fetch("/api/hasVideo.php?id=" + lastID)).json(); + + if (window.hasVideo && !window.parent.document.getElementById("lyrics-page").classList.contains("mobile-show") && localStorage.getItem("data-saving") !== "true") { + document.getElementById("lyrics-synced").style.display = "none"; + document.getElementById("lyrics-synced-fade").style.display = "none"; + document.getElementById("lyrics-unsynced").style.display = "none"; + document.getElementById("video").style.display = "block"; + document.getElementById("not-available").style.display = "none"; + document.getElementById("loading").style.display = "none"; + document.getElementById(localStorage.getItem("data-saving") === "true" ? "not-playing-2" : "not-playing").style.display = "none"; + + document.getElementById("video").src = "/assets/content/" + lastID + ".webm"; + } else { + if (!window.lyrics[lastID]) { + window.lyricsLoadTimeout = setTimeout(() => { + location.reload(); + }, 10000); + + try { + window.lyrics[lastID] = await (await fetch("/api/lyrics.php?id=" + lastID)).json(); + } catch (e) { + window.lyrics[lastID] = { + synced: false, + payload: null + } } - } - clearTimeout(window.lyricsLoadTimeout); + clearTimeout(window.lyricsLoadTimeout); - if (window.lyrics[lastID] && window.lyrics[lastID].payload) { - if (window.lyrics[lastID].synced) { - document.getElementById("lyrics-synced").style.display = ""; - document.getElementById("lyrics-synced-fade").style.display = ""; - document.getElementById("lyrics-unsynced").style.display = "none"; - document.getElementById("not-available").style.display = "none"; - document.getElementById("loading").style.display = "none"; - document.getElementById("not-playing").style.display = "none"; + if (window.lyrics[lastID] && window.lyrics[lastID].payload) { + if (window.lyrics[lastID].synced) { + document.getElementById("video").style.display = "none"; + document.getElementById("lyrics-synced").style.display = ""; + document.getElementById("lyrics-synced-fade").style.display = ""; + document.getElementById("lyrics-unsynced").style.display = "none"; + document.getElementById("not-available").style.display = "none"; + document.getElementById("loading").style.display = "none"; + document.getElementById(localStorage.getItem("data-saving") === "true" ? "not-playing-2" : "not-playing").style.display = "none"; - document.getElementById("lyrics-synced").style.top = "0px"; - document.getElementById("lyrics-synced").innerHTML = "<div style='height: 16px;'></div>" + window.lyrics[lastID].payload.map(i => ` + document.getElementById("lyrics-synced").style.top = "0px"; + document.getElementById("lyrics-synced").innerHTML = "<div style='height: 16px;'></div>" + window.lyrics[lastID].payload.map(i => ` <div class="synced-lyrics-item" id="synced-lyrics-${i.startTimeMs}">${i.words}</div> `).join("") + "<div style='height: 16px;'></div>"; + } else { + document.getElementById("video").style.display = "none"; + document.getElementById("lyrics-synced").style.display = "none"; + document.getElementById("lyrics-synced-fade").style.display = "none"; + document.getElementById("lyrics-unsynced").style.display = ""; + document.getElementById("not-available").style.display = "none"; + document.getElementById("loading").style.display = "none"; + document.getElementById(localStorage.getItem("data-saving") === "true" ? "not-playing-2" : "not-playing").style.display = "none"; + + document.getElementById("lyrics-unsynced").scrollTop = false; + document.getElementById("lyrics-unsynced").innerText = window.lyrics[lastID].payload.replaceAll("\n\n\n", "\n"); + } } else { + document.getElementById("video").style.display = "none"; document.getElementById("lyrics-synced").style.display = "none"; document.getElementById("lyrics-synced-fade").style.display = "none"; - document.getElementById("lyrics-unsynced").style.display = ""; - document.getElementById("not-available").style.display = "none"; + document.getElementById("lyrics-unsynced").style.display = "none"; + document.getElementById("not-available").style.display = "flex"; document.getElementById("loading").style.display = "none"; - document.getElementById("not-playing").style.display = "none"; - - document.getElementById("lyrics-unsynced").scrollTop = false; - document.getElementById("lyrics-unsynced").innerText = window.lyrics[lastID].payload.replaceAll("\n\n\n", "\n"); + document.getElementById(localStorage.getItem("data-saving") === "true" ? "not-playing-2" : "not-playing").style.display = "none"; } - } else { - document.getElementById("lyrics-synced").style.display = "none"; - document.getElementById("lyrics-synced-fade").style.display = "none"; - document.getElementById("lyrics-unsynced").style.display = "none"; - document.getElementById("not-available").style.display = "flex"; - document.getElementById("loading").style.display = "none"; - document.getElementById("not-playing").style.display = "none"; } } } } if (window.lyrics[lastID] && window.lyrics[lastID].synced) { + document.getElementById("video").style.display = "none"; document.getElementById("lyrics-synced").style.display = ""; document.getElementById("lyrics-synced-fade").style.display = ""; document.getElementById("lyrics-unsynced").style.display = "none"; document.getElementById("not-available").style.display = "none"; document.getElementById("loading").style.display = "none"; - document.getElementById("not-playing").style.display = "none"; + document.getElementById(localStorage.getItem("data-saving") === "true" ? "not-playing-2" : "not-playing").style.display = "none"; for (let item of [...window.lyrics[lastID].payload].reverse()) { if (parseInt(item.startTimeMs) / 1000 <= window.parent.document.getElementById("player").contentDocument.getElementById("player-audio").currentTime) { @@ -161,6 +189,30 @@ } } }, 100); + + window.updateVideo = () => { + if (window.hasVideo && !window.parent.document.getElementById("lyrics-page").classList.contains("mobile-show") && localStorage.getItem("data-saving") !== "true") { + document.getElementById("video").currentTime = window.parent.playerDocument.getElementById("player-audio").currentTime + (window.delays[window.parent.currentSongID] ?? 0); + + if (window.parent.playerDocument.getElementById("player-audio").paused) { + document.getElementById("video").pause(); + } else { + document.getElementById("video").play(); + } + } + } + + document.onvisibilitychange = () => { + window.updateVideo(); + } + + setInterval(() => { + if (Math.abs(window.parent.playerDocument.getElementById("player-audio").currentTime - document.getElementById("video").currentTime) > 0.5 + Math.abs((window.delays[window.parent.currentSongID] ?? 0))) { + window.updateVideo(); + } + }, 1000); + + document.getElementById(localStorage.getItem("data-saving") === "true" ? "not-playing-2" : "not-playing").style.display = "flex"; </script> </body> </html>
\ No newline at end of file diff --git a/app/ui/navigation.php b/app/ui/navigation.php index 0125418..617bc63 100644 --- a/app/ui/navigation.php +++ b/app/ui/navigation.php @@ -39,6 +39,12 @@ <div id="home" class="navigation-item" onclick="window.parent.openUI('home');"> <img class="icon" alt="" src="/assets/icons/home.svg" style="vertical-align: middle; width: 32px;"><span style="vertical-align: middle; margin-left: 5px;" class="navigation-desktop">Home</span> </div> + <div id="lyrics" class="navigation-item" onclick="window.parent.showLyrics();"> + <img class="icon" alt="" src="/assets/icons/now.svg" style="vertical-align: middle; width: 32px;"><span style="vertical-align: middle; margin-left: 5px;" class="navigation-desktop">Now playing</span> + </div> + <div id="queue" class="navigation-item" onclick="window.parent.openUI('queue');"> + <img class="icon" alt="" src="/assets/icons/playlist.svg" style="vertical-align: middle; width: 32px;"><span style="vertical-align: middle; margin-left: 5px;" class="navigation-desktop">Queue</span> + </div> <div id="library" class="navigation-item-mobile navigation-item" onclick="window.parent.openUI('library');"> <img class="icon" alt="" src="/assets/icons/library.svg" style="vertical-align: middle; width: 32px;"><span style="vertical-align: middle; margin-left: 5px;" class="navigation-desktop">Library</span> </div> @@ -51,12 +57,6 @@ <div id="favorites" class="navigation-item-desktop navigation-item" onclick="window.parent.openUI('favorites');"> <img class="icon" alt="" src="/assets/icons/favorites.svg" style="vertical-align: middle; width: 32px;"><span style="vertical-align: middle; margin-left: 5px;" class="navigation-desktop">Favorites</span> </div> - <div id="lyrics" class="navigation-item" onclick="window.parent.showLyrics();"> - <img class="icon" alt="" src="/assets/icons/lyrics.svg" style="vertical-align: middle; width: 32px;"><span style="vertical-align: middle; margin-left: 5px;" class="navigation-desktop">Lyrics</span> - </div> - <div id="queue" class="navigation-item" onclick="window.parent.openUI('queue');"> - <img class="icon" alt="" src="/assets/icons/playlist.svg" style="vertical-align: middle; width: 32px;"><span style="vertical-align: middle; margin-left: 5px;" class="navigation-desktop">Queue</span> - </div> <div id="settings" class="navigation-item" onclick="window.parent.openUI('settings');"> <img class="icon" alt="" src="/assets/icons/settings.svg" style="vertical-align: middle; width: 32px;"><span style="vertical-align: middle; margin-left: 5px;" class="navigation-desktop">Settings</span> </div> diff --git a/app/ui/settings.php b/app/ui/settings.php index 4897f06..d4cb6f2 100644 --- a/app/ui/settings.php +++ b/app/ui/settings.php @@ -33,7 +33,7 @@ <input onchange="saveDS();" class="form-check-input" type="checkbox" role="switch" id="data-saving"> <label class="form-check-label" for="data-saving"> Enable data saving - <div class="text-muted small">Data saving disables playing lossless and high-resolution audio. Instead, you will get 256 kbps AAC-encoded audio, which is highly efficient. If you use Bluetooth headphones, the difference should be unnoticeable.</div> + <div class="text-muted small">Data saving disables playing lossless and high-resolution audio, as well as music videos. Instead, you will get 256 kbps AAC-encoded audio, which is highly efficient. If you use Bluetooth headphones, the difference should be unnoticeable.</div> </label> </div> <script> @@ -251,16 +251,11 @@ <hr> <?php if (str_contains($_SERVER['HTTP_USER_AGENT'], "MistNative/")): ?> - <a onclick="window.parent.MistNative.about();" href="#">About Mist</a><span id="studio" style="display: none;"> · <a onclick="window.parent.MistNative.studio();" href="#">Switch to Mist Studio</a></span> - <script> - if (window.parent.MistNative.studio) { - document.getElementById("studio").style.display = ""; - } - </script> + <a onclick="window.parent.MistNative.about();" href="#">About Mist</a> <?php else: ?> <div class="text-muted"> <img class="icon" src="/assets/logo-transparent.svg" style="vertical-align: middle; filter: grayscale(1) invert(1); width: 32px; height: 32px;" alt=""> - <span style="vertical-align: middle;">Mist version <?= str_replace("|", " ", file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/version")) ?> (build <?= trim(file_exists("/opt/spotify/build.txt") ? file_get_contents("/opt/spotify/build.txt") : "trunk") ?>)<span id="copyright-separator-desktop"> · </span><span id="copyright-separator-mobile"><br></span>© <?= date('Y') ?> Equestria.dev</span> + <span style="vertical-align: middle;">Mist version <?= str_replace("|", " ", file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/version")) ?> (build <?= trim(file_exists($_SERVER['DOCUMENT_ROOT'] . "/build.txt") ? file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/build.txt") : (file_exists("/opt/spotify/build.txt") ? file_get_contents("/opt/spotify/build.txt") : "trunk")) ?>)<span id="copyright-separator-desktop"> · </span><span id="copyright-separator-mobile"><br></span>© <?= date('Y') ?> Equestria.dev</span> </div> <style> @media (min-width: 768px) { diff --git a/app/ui/stella.php b/app/ui/stella.php index 143a172..c0f1fc6 100644 --- a/app/ui/stella.php +++ b/app/ui/stella.php @@ -2,6 +2,6 @@ header("X-Frame-Options: SAMEORIGIN"); unset($_GET["a"]); -$onlyStella = true; +$onlyStella = 1; global $onlyStella; require_once "./listing.php";
\ No newline at end of file diff --git a/app/ui/video.php b/app/ui/video.php new file mode 100644 index 0000000..fa11e6c --- /dev/null +++ b/app/ui/video.php @@ -0,0 +1,7 @@ +<?php + +header("X-Frame-Options: SAMEORIGIN"); +unset($_GET["a"]); +$onlyStella = 2; +global $onlyStella; +require_once "./listing.php";
\ No newline at end of file |