From 986b26576d716ca31a7208b640e9394de0358c5e Mon Sep 17 00:00:00 2001 From: Kentai Radiquum Date: Fri, 10 Jan 2025 20:18:55 +0500 Subject: [PATCH] feat: create a lastfm widget instead of the text --- index.html | 23 ++++-- static/fa6-brands--lastfm.svg | 1 + static/i18n/strings/ru.js | 2 +- static/material-symbols--pause.svg | 1 + static/material-symbols--play-arrow.svg | 1 + static/script.js | 100 +++++++++-------------- static/tailwind.css | 102 ++++++++++++++++++++++++ 7 files changed, 159 insertions(+), 71 deletions(-) create mode 100644 static/fa6-brands--lastfm.svg create mode 100644 static/material-symbols--pause.svg create mode 100644 static/material-symbols--play-arrow.svg diff --git a/index.html b/index.html index 2dbaecc..af26574 100644 --- a/index.html +++ b/index.html @@ -98,12 +98,23 @@ class="inline sm:hidden">. -

- Now listening to: LOADING . . - . -

+
+ + +
diff --git a/static/fa6-brands--lastfm.svg b/static/fa6-brands--lastfm.svg new file mode 100644 index 0000000..ecde7ee --- /dev/null +++ b/static/fa6-brands--lastfm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/i18n/strings/ru.js b/static/i18n/strings/ru.js index dcd6918..a439441 100644 --- a/static/i18n/strings/ru.js +++ b/static/i18n/strings/ru.js @@ -8,7 +8,7 @@ const i18n_ru = { QUICK_BIO_CODER: "Программист", QUICK_BIO_PHOTOGRAPHER: "Фотограф", QUICK_BIO_ENTHUSIAST: "Селф-Хостинг Энтузиаст", - QUICK_BIO_LASTFM: "Сейчас слушает: ", + QUICK_BIO_LASTFM: "Мой профиль", // BUTTONS BTN_ABOUT_ME: "ОБО МНЕ", diff --git a/static/material-symbols--pause.svg b/static/material-symbols--pause.svg new file mode 100644 index 0000000..272cf21 --- /dev/null +++ b/static/material-symbols--pause.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/material-symbols--play-arrow.svg b/static/material-symbols--play-arrow.svg new file mode 100644 index 0000000..85e9a8c --- /dev/null +++ b/static/material-symbols--play-arrow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/script.js b/static/script.js index 1993b20..2d864c5 100644 --- a/static/script.js +++ b/static/script.js @@ -1,6 +1,5 @@ // Animation durations in ms const SONG_CHANGE_DELAY = 180000; -const SYMBOL_DELAY = 150; const IMAGE_CHANGE_DELAY = 6000; const ARTS_CHANGE_DELAY = 6500; @@ -10,59 +9,14 @@ const IMAGE_TRANSITION_DELAY = 1000; // Header percentages const HEADER_ACTIVATION_PERCENT = 0.8; -// THIS IS NOT CONSTANTS, BUT A GLOBAL VAR FOR TIMERS IN SONG NAME CHANGE!!! -let DELETE_INTERVAL = null; -let UPDATE_INTERVAL = null; -function deletePreviousTrack(newTrackName) { - const trackName = document.getElementById("track-name"); - const prevTrackNameLen = trackName.innerHTML.length; - trackName.style.setProperty("--cursor-animation", "none"); - clearInterval(DELETE_INTERVAL); - clearInterval(UPDATE_INTERVAL); - - let removed = 0; - DELETE_INTERVAL = setInterval(() => { - removed += 1; - trackName.innerHTML = trackName.innerHTML.substring( - 0, - prevTrackNameLen - removed - ); - - if (removed == prevTrackNameLen) { - clearInterval(DELETE_INTERVAL); - updateTrack(newTrackName); - return true; - } - }, SYMBOL_DELAY); -} - -function updateTrack(newTrackName) { - const trackName = document.getElementById("track-name"); - const TrackNameLen = newTrackName.length; - clearInterval(DELETE_INTERVAL); - clearInterval(UPDATE_INTERVAL); - - let added = 0; - UPDATE_INTERVAL = setInterval(() => { - if (added < TrackNameLen) { - trackName.innerHTML += newTrackName[added]; - added += 1; - } - - if (added == TrackNameLen) { - clearInterval(UPDATE_INTERVAL); - trackName.style.setProperty("--cursor-animation", "blink"); - setTimeout(() => { - trackName.style.setProperty("--cursor-color", "transparent"); - }, SYMBOL_DELAY * 3); - return true; - } - }, SYMBOL_DELAY); -} - async function updatePlayingTrack() { - const trackName = document.getElementById("track-name"); - const prevTrackName = trackName.innerHTML; + + const images = document.querySelectorAll("#lastfm_image"); + const state = document.getElementById("lastfm_state"); + const title = document.getElementById("lastfm_title"); + const artist = document.getElementById("lastfm_artist"); + const album = document.getElementById("lastfm_album"); + const link = document.getElementById("lastfm_songlink"); fetch("https://lastfm-last-played.biancarosa.com.br/radiquum/latest-song") .then((res) => { @@ -73,21 +27,39 @@ async function updatePlayingTrack() { }) .then((data) => { if ( - prevTrackName != `${data.track.artist["#text"]} - ${data.track.name}` + title.innerHTML != data.track.name ) { - trackName.style.setProperty("--cursor-color", "#fff"); - trackName.style.setProperty("--cursor-animation", "blink"); - setTimeout(() => { - deletePreviousTrack( - `${data.track.artist["#text"]} - ${data.track.name}` - ); - }, SYMBOL_DELAY * 4); + if (!data.track) throw new Error("No track is provided"); + if (data.track.hasOwnProperty("image") && data.track.image.length > 0) { + images.forEach((img) => {img.src = data.track.image[data.track.image.length - 1]["#text"]}); + } else { + images.forEach((img) => {img.src = "https://lastfm.freetls.fastly.net/i/u/34s/2a96cbd8b46e442fc41c2b86b821562f.png"}); + } + if (data.track.hasOwnProperty("@attr") && data.track["@attr"].nowplaying) { + state.src = "./static/material-symbols--play-arrow.svg"; + state.alt = "Playing"; + } else { + state.src = "./static/material-symbols--pause.svg"; + state.alt = "Paused"; + } + if (data.track.hasOwnProperty("album")) { + album.innerHTML = data.track.album["#text"]; + } else { + album.innerHTML = ""; + } + if (data.track.hasOwnProperty("artist")) { + artist.innerHTML = data.track.artist["#text"]; + } else { + artist.innerHTML = ""; + } + title.innerHTML = data.track.name; + link.href = data.track.url } }) .catch((err) => { - deletePreviousTrack("ERROR: last.fm is not reachable"); - console.log(err); + console.log("lastfm is unreachable:", err); + return }); } @@ -235,7 +207,7 @@ function changeArtsSectionImage() { window.onload = () => { updatePlayingTrack(); - setInterval(updatePlayingTrack, 180000); + setInterval(updatePlayingTrack, SONG_CHANGE_DELAY); setPhotoSectionImagesMargin(); setInterval(changePhotoSectionImage, IMAGE_CHANGE_DELAY); setArtsSectionImagesMargin(); diff --git a/static/tailwind.css b/static/tailwind.css index 5a44644..b78dcca 100644 --- a/static/tailwind.css +++ b/static/tailwind.css @@ -730,6 +730,14 @@ video { margin-top: 0.5rem; } +.-ml-2 { + margin-left: -0.5rem; +} + +.-ml-1 { + margin-left: -0.25rem; +} + .block { display: block; } @@ -786,6 +794,10 @@ video { height: 170px; } +.h-6 { + height: 1.5rem; +} + .max-h-\[182px\] { max-height: 182px; } @@ -794,6 +806,22 @@ video { max-height: 50vh; } +.max-h-\[calc\(100\%-2px\)\] { + max-height: calc(100% - 2px); +} + +.max-h-\[calc\(100\%\+2px\)\] { + max-height: calc(100% + 2px); +} + +.max-h-\[calc\(100\%\+8px\)\] { + max-height: calc(100% + 8px); +} + +.max-h-\[calc\(100\%\+16px\)\] { + max-height: calc(100% + 16px); +} + .min-h-screen { min-height: 100vh; } @@ -839,10 +867,18 @@ video { width: max-content; } +.w-6 { + width: 1.5rem; +} + .min-w-\[170px\] { min-width: 170px; } +.min-w-\[372px\] { + min-width: 372px; +} + .max-w-\[50vw\] { max-width: 50vw; } @@ -851,6 +887,10 @@ video { max-width: 170px; } +.max-w-\[512px\] { + max-width: 512px; +} + .flex-1 { flex: 1 1 0%; } @@ -990,6 +1030,20 @@ video { scroll-behavior: smooth; } +.truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.whitespace-nowrap { + white-space: nowrap; +} + +.text-nowrap { + text-wrap: nowrap; +} + .break-words { overflow-wrap: break-word; } @@ -1203,6 +1257,22 @@ video { --tw-bg-opacity: 0.5; } +.bg-opacity-55 { + --tw-bg-opacity: 0.55; +} + +.bg-opacity-25 { + --tw-bg-opacity: 0.25; +} + +.bg-opacity-75 { + --tw-bg-opacity: 0.75; +} + +.bg-opacity-5 { + --tw-bg-opacity: 0.05; +} + .object-contain { -o-object-fit: contain; object-fit: contain; @@ -1297,6 +1367,11 @@ video { line-height: 1.75rem; } +.text-sm { + font-size: 0.875rem; + line-height: 1.25rem; +} + .font-bold { font-weight: 700; } @@ -1343,10 +1418,33 @@ video { filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); } +.invert { + --tw-invert: invert(100%); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); +} + .filter { filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); } +.backdrop-blur-md { + --tw-backdrop-blur: blur(12px); + -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); +} + +.backdrop-blur-sm { + --tw-backdrop-blur: blur(4px); + -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); +} + +.backdrop-blur-lg { + --tw-backdrop-blur: blur(16px); + -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); +} + .transition-\[border-color\] { transition-property: border-color; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); @@ -1573,6 +1671,10 @@ body { } @media (min-width: 768px) { + .md\:-z-10 { + z-index: -10; + } + .md\:order-3 { order: 3; }