<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Geert Jan Sloos 🌎</title>
    <description>The latest articles on DEV Community by Geert Jan Sloos 🌎 (@geertjansloos).</description>
    <link>https://dev.to/geertjansloos</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F908111%2F80695803-cca4-459e-9544-e22c2d90a618.png</url>
      <title>DEV Community: Geert Jan Sloos 🌎</title>
      <link>https://dev.to/geertjansloos</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/geertjansloos"/>
    <language>en</language>
    <item>
      <title>How I build lofi.radio with only CloudFlare</title>
      <dc:creator>Geert Jan Sloos 🌎</dc:creator>
      <pubDate>Fri, 07 Jul 2023 03:42:34 +0000</pubDate>
      <link>https://dev.to/geertjansloos/how-i-build-lofiradio-with-only-cloudflare-255j</link>
      <guid>https://dev.to/geertjansloos/how-i-build-lofiradio-with-only-cloudflare-255j</guid>
      <description>&lt;h2&gt;
  
  
  How It Started
&lt;/h2&gt;

&lt;p&gt;The idea came from current lo-fi websites (and my love for lo-fi music) but most websites were complex or rely on Youtube for their music. Additionally, some had no remarkable domain names. lofi.radio stands out for its simplicity and clean page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using only CloudFlare for hosting&lt;/strong&gt;&lt;br&gt;
The biggest challenge I gave myself was to make it without hosting (php/mysql), I ended up with CloudFlare Pages &amp;amp; Cloudflare Worker (serverless) and also CloudFlare DNS/Caching + Email Routing.&lt;/p&gt;

&lt;p&gt;In daily life I am not a developer, so I had a little help from ChatGPT also used MidJourney to create the logo/icon.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faazosa9sdt8r1gd9ulg8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faazosa9sdt8r1gd9ulg8.png" alt="Lo-Fi Radio Logo"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Music Player
&lt;/h2&gt;

&lt;p&gt;The Music Player I build with &lt;a href="https://howlerjs.com/" rel="noopener noreferrer"&gt;https://howlerjs.com/&lt;/a&gt; because it has many features and it quitte simple to work with it (and even Google and Disney using it.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqo718amayu7nrbpc8af2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqo718amayu7nrbpc8af2.png" alt="Music Player"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Show the current song
&lt;/h2&gt;

&lt;p&gt;I added a simple function to showcase the current song effortlessly, while also removing any spaces to ensure it is consistently displayed in a clear and easily readable manner.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function updateSongInfo() {
  var currentSong = playlist[currentTrack];
  var songTitle = currentSong.substring(currentSong.lastIndexOf('/') + 1, currentSong.lastIndexOf('.'));
  songTitle = decodeURIComponent(songTitle.replace(/\+/g, ' '));
  document.getElementById('song-button').innerText = songTitle;
}

// Update the time and song info every second
setInterval(function() {
  updateTime();
  updateSongInfo();
}, 1000);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Show the current time
&lt;/h2&gt;

&lt;p&gt;To prevent losing track of time while being occupied, I have implemented a function that automatically refreshes the local time every minute. This way, you can stay updated with the current time without any interruptions, ensuring you stay on schedule and manage your tasks effectively.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function formatTime(date) {
  var hours = date.getHours();
  var minutes = date.getMinutes();
  return hours.toString().padStart(2, '0') + ':' + minutes.toString().padStart(2, '0');
}

function updateTime() {
  var currentTime = new Date();
  document.getElementById('time-button').innerText = formatTime(currentTime);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Show Listeners with CloudFlare Analytics
&lt;/h2&gt;

&lt;p&gt;The most challenging aspect was demonstrating how many people are tuning in to lofi.radio. I began researching solutions, but using Google Analytics, No-code, and Javascript wasn't an option.&lt;/p&gt;

&lt;p&gt;Eventually, I choose to use the CloudFlare API to gather Web Analytics data and display it using Javascript. To accomplish this, I set up a CloudFlare Worker and used GraphQL to retrieve the data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const query =
    query {
      viewer {
        zones(filter: { zoneTag: "xxxx" }) {
          httpRequests1dGroups(filter: { date: "${today}" }, limit: 1) {
            uniq {
              uniques
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkvmg8wf4ewedgq7ek08t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkvmg8wf4ewedgq7ek08t.png" alt="Listener preview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Music
&lt;/h2&gt;

&lt;p&gt;Most important is of course the music, I download the tracks from &lt;a href="https://pixabay.com/en/music/" rel="noopener noreferrer"&gt;https://pixabay.com/en/music/&lt;/a&gt; and then upload it on DigitalOcean Spaces (S3) I could have used CloudFlare for this, but since I have a lot of data transfer at DigitalOcean, streaming it there makes more sense.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2eohcd74vzm3iluhjxbp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2eohcd74vzm3iluhjxbp.png" alt="DO Spaces S3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Words
&lt;/h2&gt;

&lt;p&gt;I hope you like my post and lofi.music I still thinking to add more features like Notes, Timer, Pomodoro and Scenes, but for now I get some rest 🤗&lt;/p&gt;

&lt;p&gt;Do not forget to check out &lt;a href="https://lofi.radio" rel="noopener noreferrer"&gt;https://lofi.radio&lt;/a&gt; 👀&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>tutorial</category>
      <category>productivity</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
