commit 27356c5db4baa5202d967e5de1ebf69444782317
parent 00c576c75b4a7bc15b47ff3ef702197b600e94d3
Author: Nirmal Kumar R <tildezero@gmail.com>
Date: Sun, 19 May 2024 19:58:52 +0530
Enhance with Recents playlist
Diffstat:
M | emptyfm.js | | | 221 | +++++++++++++++++++++++++++++++++++++++++++++++-------------------------------- |
M | index.html | | | 45 | ++++++++++++++++++++++++++++++++++++++++----- |
2 files changed, 172 insertions(+), 94 deletions(-)
diff --git a/emptyfm.js b/emptyfm.js
@@ -1,112 +1,155 @@
let player;
-
-// document.addEventListener('DOMContentLoaded', function () {
-// player = videojs('emptyfm');
-// player.play();
-// });
+let recents;
async function fetchFMStations() {
- let countrySelect = document.getElementById("countryCode");
- let countryCode = countrySelect.value;
-
- let languagesSelect = document.getElementById("languages");
- let langCode = languagesSelect.value;
-
- let queryParams;
-
- if (!countryCode && !langCode) {
- alert("You must choose either country or language, or both if you wish.");
- return;
- }
- else if (!countryCode) {
- queryParams = "language=" + langCode + "&hidebroken=true&order=clickcount&reverse=true"
- }
- else if (!langCode) {
- queryParams = "countrycode=" + countryCode + "&hidebroken=true&order=clickcount&reverse=true"
- }
- else {
- queryParams = "countrycode=" + countryCode + "&language=" + langCode + "&hidebroken=true&order=clickcount&reverse=true"
- }
-
- const response = await fetch("https://de1.api.radio-browser.info/json/stations/search?" + queryParams);
- const stations = await response.json();
-
- let fmList = document.getElementById("fmlist");
-
- fmList.innerHTML = "";
- for (var k in stations) {
- let atag = document.createElement("a");
- atag.className = "fmitem";
- atag.href = stations[k].url;
- atag.innerText = stations[k].name;
- atag.onclick = (e) => {
- e.preventDefault();
- changeSource(atag.href);
+ let countrySelect = document.getElementById("countryCode");
+ let countryCode = countrySelect.value;
+
+ let languagesSelect = document.getElementById("languages");
+ let langCode = languagesSelect.value;
+
+ let queryParams;
+
+ if (!countryCode && !langCode) {
+ alert("You must choose either country or language, or both if you wish.");
+ return;
+ } else if (!countryCode) {
+ queryParams = "language=" + langCode + "&hidebroken=true&order=clickcount&reverse=true"
+ } else if (!langCode) {
+ queryParams = "countrycode=" + countryCode + "&hidebroken=true&order=clickcount&reverse=true"
+ } else {
+ queryParams = "countrycode=" + countryCode + "&language=" + langCode + "&hidebroken=true&order=clickcount&reverse=true"
}
- fmList.appendChild(atag);
- }
+ const response = await fetch("https://de1.api.radio-browser.info/json/stations/search?" + queryParams);
+ const stations = await response.json();
+
+ let fmList = document.getElementById("fmlist");
+
+ fmList.innerHTML = "";
+ for (var k in stations) {
+ let atag = document.createElement("a");
+ atag.className = "fmitem";
+ atag.href = stations[k].url;
+ atag.innerText = stations[k].name;
+ atag.onclick = (e) => {
+ e.preventDefault();
+ let found = recents.find(({
+ name
+ }) => name === atag.innerText);
+ if (!found) {
+ addToRecents(recents, atag.innerText, atag.href);
+ }
+
+ changeSource(atag.href);
+ }
+
+ fmList.appendChild(atag);
+ }
+}
+
+function populateRecents() {
+ let saved = localStorage.getItem('emptyfm') ?? '{ "recents": [] }';
+ let savedObj = JSON.parse(saved);
+ recents = savedObj["recents"];
+
+ for (recent of recents) {
+ constructRecentEl(recent.name, recent.url);
+ }
+}
+
+function constructRecentEl(name, url) {
+ let recentsEl = document.getElementById("recentList");
+ let litag = document.createElement("li");
+ let atag = document.createElement("a");
+ atag.href = url;
+ atag.innerText = name;
+ atag.onclick = (e) => {
+ e.preventDefault();
+ changeSource(atag.href);
+ };
+
+ litag.appendChild(atag);
+ recentsEl.appendChild(litag);
+}
+
+function addToRecents(savedObj, name, url) {
+ let recentObj = {
+ name: name,
+ url: url
+ };
+
+ recents.push(recentObj);
+
+ let recentsStr = JSON.stringify({ recents: recents });
+ localStorage.setItem('emptyfm', recentsStr);
+
+ constructRecentEl(name, url);
}
function changeSource(url) {
- player = videojs('emptyfm');
- mediaType = fetchMediaType(url);
- player.src({ type: mediaType, src: url });
- player.play();
+ player = videojs('emptyfm');
+ mediaType = fetchMediaType(url);
+ player.src({
+ type: mediaType,
+ src: url
+ });
+ player.play();
}
function fetchMediaType(url) {
- last = url.split("/").pop();
- switch (last) {
- case "stream":
- return "audio/mpeg";
- default:
- ext = last.split(".").pop();
- switch (ext) {
- case "m3u8":
- return "application/x-mpegURL";
+ last = url.split("/").pop();
+ switch (last) {
+ case "stream":
+ return "audio/mpeg";
default:
- return "audio/mpeg";
- }
- }
+ ext = last.split(".").pop();
+ switch (ext) {
+ case "m3u8":
+ return "application/x-mpegURL";
+ default:
+ return "audio/mpeg";
+ }
+ }
}
function listCountries() {
- fetch('./iso-3166-1-alpha2-countrycode.json')
- .then((response) => response.json())
- .then((json) => {
- let selectElem = document.getElementById("countryCode");
-
- for (var k in json) {
- if (json.hasOwnProperty(k)) {
- let option = document.createElement("option");
- option.text = json[k];
- option.value = k;
-
- selectElem.appendChild(option);
- }
- }
- })
+ fetch('./iso-3166-1-alpha2-countrycode.json')
+ .then((response) => response.json())
+ .then((json) => {
+ let selectElem = document.getElementById("countryCode");
+
+ for (var k in json) {
+ if (json.hasOwnProperty(k)) {
+ let option = document.createElement("option");
+ option.text = json[k];
+ option.value = k;
+
+ selectElem.appendChild(option);
+ }
+ }
+ })
}
function listLanguages() {
- fetch('./iso-639-lang.json')
- .then((response) => response.json())
- .then((json) => {
- let selectElem = document.getElementById("languages");
-
- for (var k in json) {
- if (json.hasOwnProperty(k)) {
- let option = document.createElement("option");
- option.text = json[k];
- option.value = k;
-
- selectElem.appendChild(option);
- }
- }
- })
+ fetch('./iso-639-lang.json')
+ .then((response) => response.json())
+ .then((json) => {
+ let selectElem = document.getElementById("languages");
+
+ for (var k in json) {
+ if (json.hasOwnProperty(k)) {
+ let option = document.createElement("option");
+ option.text = json[k];
+ option.value = k;
+
+ selectElem.appendChild(option);
+ }
+ }
+ })
}
+populateRecents();
listCountries();
listLanguages();
diff --git a/index.html b/index.html
@@ -24,13 +24,13 @@
}
body {
- font-size: 14px;
+ font-size: 17px;
line-height: 1.5;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
padding: 0 2em;
- margin: 3em auto;
+ margin: 2em auto;
background-color: var(--bg);
color: var(--fg);
font-family: 'JetBrains Mono', monospace;
@@ -40,6 +40,7 @@
.logo {
display: block;
+ font-size: 1.2rem;
margin-bottom: 2em;
}
@@ -50,16 +51,22 @@
text-decoration-thickness: 1px
}
+ h3 {
+ font-size: 1rem;
+ }
+
select,
button {
width: 100%;
height: 32px;
- font-size: 14px;
+ font-size: 1rem;
box-sizing: border-box;
margin-bottom: 1em;
}
button {
+ font-family: 'JetBrains Mono', monospace;
+ font-size: 1.2rem;
padding: 0 1em;
background: #15C;
border: 1px solid var(--fg);
@@ -89,6 +96,30 @@
z-index: 1;
}
+ .recents {
+ background: #efefef;
+ margin: 0 0 2rem;
+ }
+
+ .recents ul {
+ max-height: 14em;
+ overflow-x: hidden;
+ overflow-y: auto;
+ margin: 0;
+ }
+
+ .recents li {
+ margin: 1em 0;
+ }
+
+ .recents h3 {
+ background: #666;
+ color: white;
+ margin: 0;
+ padding: 0 0.7em;
+ font-size: 1rem;
+ }
+
.video-js {
background: transparent;
}
@@ -119,6 +150,11 @@
<a class="logo" href="/">emptyfm</a>
<header>
+ <div class="recents">
+ <h3>Recents</h3>
+ <ul id="recentList"></ul>
+ </div>
+
<div class="form-item">
<label for="countryCode">Choose a country:</label>
<select name="country_code" id="countryCode">
@@ -149,4 +185,4 @@
<script src="emptyfm.js"></script>
</body>
-</html>
-\ No newline at end of file
+</html>