Skip to content

Creating Subreddit Widget ​

This guide explains step-by-step how to create a subreddit page. The example code provided below aims to fetch an RSS feed from a subreddit and display it on the page.

HTML Structure ​

First, we create the basic HTML structure. This structure defines the skeleton of the page and specifies where the necessary elements will be located.

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>r-programming</title>
    <link rel="stylesheet" href="./styles.css" />
  </head>

  <body>
    <div id="message">
      <span> Getting information...</span>
      <div id="loading"></div>
    </div>
    <main>
      <h1 id="header">
        <img
          src="./reddit.png"
          title="reddit logo"
          width="24px"
          height="24px"
        />/programming
      </h1>
      <section id="container">
        <article id="item">
          <div id="title">title goes here</div>
          <div>
            <p id="pubDate">published date goes here</p>
            <div id="author" rel="noopener noreferrer">
             author username goes here
            </div>
          </div>
        </article>
      </section>
      <div id="scrollTopButton">Scroll Top</div>
    </main>
    <script src="./script.js"></script>
  </body>
</html>

JavaScript Code ​

JavaScript code necessary for dynamically updating the page:

javascript
// Define an asynchronous function to fetch data and update the UI
async function fetchDataAndUpdateUI() {
  // Define a function to update the UI
  function updateUI() {
    // Hide the message and loading elements
    document.getElementById("message").style.display = "none";
    document.getElementById("loading").style.display = "none";
    // Get the main element
    const main = document.getElementsByTagName("main")[0];
    // Display the main element
    main.style.display = "flex";
    // Iterate over each item in the data
    data.items.forEach((element) => {
      // Clone the container element
      const node = document.getElementById("container").cloneNode(true);
      // Display the item and container elements
      node.querySelector("#item").style.display = "flex";
      node.style.display = "flex";
      // Set the title of the item
      node.querySelector("#title").textContent = element.title;
      // Add an event listener to open the link when the title is clicked
      node.querySelector("#title").addEventListener("click", () => {
        window.electronAPI.openExternal(element.link);
      });
      // Format the publication date
      const pubDate = new Date(element.pubDate);
      node.querySelector("#pubDate").textContent = pubDate.toLocaleString();
      // Create a link to the author's profile
      const userLink = "https://www.reddit.com/" + element.author;
      // Set the author of the item
      node.querySelector("#author").textContent = element.author;
      // Add an event listener to open the author's profile when the author is clicked
      node.querySelector("#author").addEventListener("click", () => {
        window.electronAPI.openExternal(userLink);
      });
      // Append the new node to the main element
      main.appendChild(node);
    });
  }

  // Fetch the RSS feed data
  const data = await window.electronAPI.getRSSFeed(
    "https://www.reddit.com/r/programming.rss"
  );
  // Log the data
  console.log(data);
  // If data exists, update the UI
  if (data) updateUI();
  // Set an interval to reload the widget every hour
  setInterval(
    () => window.electronAPI.reloadWidget("r-programming"),
    1000 * 60 * 60 // reload every hour
  );
}

// Add an event listener for the scroll event
window.onscroll = function () {
  scrollFunction();
};

// Define a function to handle the scroll event
function scrollFunction() {
  // Get the scrollTopButton element
  const scrollTopButton = document.getElementById("scrollTopButton");
  // If the scroll position is greater than 50, display the scrollTopButton
  if (document.body.scrollTop > 50 || document.documentElement.scrollTop > 50) {
    scrollTopButton.style.display = "block";
  } else {
    // Otherwise, hide the scrollTopButton
    scrollTopButton.style.display = "none";
  }
}

// Add an event listener to the scrollTopButton to scroll to the top when clicked
document
  .getElementById("scrollTopButton")
  .addEventListener("click", function () {
    document.body.scrollTop = 0; // For Safari
    document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera
  });

// Try to fetch data and update the UI
try {
  fetchDataAndUpdateUI();
} catch (error) {
  // If an error occurs, log it
  console.error(error);
  // Get the message element
  const messageElement = document.getElementById("message");
  // Hide the loading element
  document.getElementById("loading").style.display = "none";
  // If the message element exists, display the error message
  if (messageElement) {
    messageElement.textContent = "An error occurred: " + error.message;
  }
}

Explanations ​

  1. HTML and CSS: The HTML file defines the structure of the page. The CSS file (styles.css) sets the style of the page. The page includes sections for the main header, content container, and a loading message.

  2. JavaScript: When the page loads, the fetchDataAndUpdateUI function runs. This function fetches the RSS feed from the subreddit and dynamically updates the page.

    • Fetching RSS Feed: The window.electronAPI.getRSSFeed function is used to fetch the RSS feed.(or you can use my reddit rss api 😃
    • Updating the UI: The UI is updated with the fetched data, and each item is added to the page.
    • Automatic Reload: The widget automatically reloads every hour.
    • Scroll Functionality: When the page is scrolled, the 'Scroll Top' button becomes visible after a certain position, and clicking it scrolls the page back to the top.

This guide explains how to create a subreddit page and update it with dynamic data. The example code fetches the RSS feed from Reddit and displays the data on the page.