Last Friday
I'd like to develop a browser-side app with pure JavaScript code without CSS and HTML. Below is my design and help me convert HTML and CSS code to JavaScript code. My original JavaScript function will be filled by myself.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Apple Podcasts Extractor</title>
<!-- FileSaver.js for saving blobs as files -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.0/FileSaver.min.js"></script>
<!-- PicoCSS for simple styling -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/picocss/1.5.10/pico.min.css">
</head>
<!-- Initialize app on page load -->
<body onload="initApp()">
<main class="container">
<!-- Podcast search section with add/remove buttons -->
<div class="grid">
<div>
<label for="podcast_id">Podcast Search Term</label>
<input type="text" id="podcast_id" name="podcast_id" value="Nutrition Facts with Dr. Greger">
</div>
</div>
<!-- CORS proxy configuration -->
<label for="cors_proxy">CORS Proxy</label>
<input type="text" id="cors_proxy" name="cors_proxy" value="https://cors-aywhere.herokuapp.com/">
<!-- Run button to fetch podcasts -->
<button onclick="run_it()">Run</button>
<!-- Display section for podcast info -->
<p>
Podcast Name: <em><span id="podcast_name"></span></em>
</p>
<!-- Container for episode listings -->
<div id="episodes"></div>
</main>
<script>
// Global variables
let proxy_api; // Stores the CORS proxy URL
let id_download; // Stores the ID of the element being downloaded
function initApp() {
run_itt();
}
async function my_backend(search) {
// I will fill the placeholder by myself
}
async function run_it() {
const podcast_id = document.getElementById("podcast_id").value;
const episodes = document.getElementById("episodes");
// Clear previous episodes
episodes.innerHTML = "";
// Show loading indicator
const episode_hint = document.createElement("div");
episodes.appendChild(episode_hint);
episode_hint.innerText = "loading...";
// Fetch podcast data
const podcast = await my_backend(podcast_id);
document.getElementById("podcast_name").innerText =
podcast[0].albumName;
// Remove loading indicator
const episode_tmp = document.querySelector("#episodes div");
episodes.removeChild(episode_tmp);
// Create episode list items
podcast.slice(1).forEach((episode) => {
// Create list item container
const episode_li = document.createElement("li");
episode_li.setAttribute("class", "grid");
// Create episode link
const episode_anchor = document.createElement("a");
episode_anchor.setAttribute("href", episode.url);
episode_anchor.setAttribute("target", "_blank");
episode_anchor.innerText = episode.title;
episode_li.appendChild(episode_anchor);
// Create date display
const episode_span = document.createElement("span");
episode_span.setAttribute("style", "color: #999;");
episode_span.innerText = episode.date;
episode_li.appendChild(episode_span);
// Create download button
const episode_button = document.createElement("button");
episode_button.setAttribute("id", episode.title);
episode_button.setAttribute(
"style",
"width: auto; margin-right: 0; margin-left: auto;"
);
// Determine file extension
let filename_with_ext = episode.title + ".m4a";
if (episode.url.includes(".mp3")) {
filename_with_ext = episode.title + ".mp3";
}
// Set download handler
episode_button.onclick = function (evt) {
downloadUsingFetch(
proxy_api + episode.url,
filename_with_ext,
evt
);
};
episode_button.innerText = "download";
episode_li.appendChild(episode_button);
episodes.appendChild(episode_li);
});
}
function progress({ loaded, total }) {
const elProgress = document.getElementById(id_download);
elProgress.innerHTML = Math.round((loaded / total) * 100) + "%";
}
async function downloadUsingFetch(FILE_URL, filename, evt) {
// I will fill the placeholder by myself
}