Miniflux Extension

An extension for Miniflux RSS reader

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey, Greasemonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Userscripts.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een gebruikersscriptbeheerder nodig.

(Ik heb al een user script manager, laat me het downloaden!)

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

(Ik heb al een beheerder - laat me doorgaan met de installatie!)

// ==UserScript==
// @name                 Miniflux Extension
// @name:zh-CN           Miniflux Extension
// @namespace            https://github.com/utags/miniflux-extension
// @homepage             https://github.com/utags/miniflux-extension#readme
// @supportURL           https://github.com/utags/miniflux-extension/issues
// @version              0.0.2
// @description          An extension for Miniflux RSS reader
// @description:zh-CN    Miniflux RSS 阅读器扩展
// @icon                 https://miniflux.app/favicon.ico
// @author               Pipecraft
// @license              MIT
// @match                https://reader.miniflux.app/*
// @match                https://miniflux.pipecraft.net/*
// @grant                GM_addElement
// @grant                GM_addStyle
// ==/UserScript==
//
//// Recent Updates
//// - 0.0.2 2023.04.26
////    - Add reader.miniflux.app as match site
////    - Automatically update categories every 10 minutes
////
;(() => {
  "use strict"
  var doc = document
  var $ = (element, selectors) =>
    element && typeof element === "object"
      ? element.querySelector(selectors)
      : doc.querySelector(element)
  var createElement = (tagName, attributes) =>
    setAttributes(doc.createElement(tagName), attributes)
  var addEventListener = (element, type, listener, options) => {
    if (!element) {
      return
    }
    if (typeof type === "object") {
      for (const type1 in type) {
        if (Object.hasOwn(type, type1)) {
          element.addEventListener(type1, type[type1])
        }
      }
    } else if (typeof type === "string" && typeof listener === "function") {
      element.addEventListener(type, listener, options)
    }
  }
  var setAttribute = (element, name, value) =>
    element ? element.setAttribute(name, value) : void 0
  var setAttributes = (element, attributes) => {
    if (element && attributes) {
      for (const name in attributes) {
        if (Object.hasOwn(attributes, name)) {
          const value = attributes[name]
          if (value === void 0) {
            continue
          }
          if (/^(value|textContent|innerText|innerHTML)$/.test(name)) {
            element[name] = value
          } else if (name === "style") {
            setStyle(element, value, true)
          } else if (/on\w+/.test(name)) {
            const type = name.slice(2)
            addEventListener(element, type, value)
          } else {
            setAttribute(element, name, value)
          }
        }
      }
    }
    return element
  }
  var setStyle = (element, values, overwrite) => {
    if (!element) {
      return
    }
    const style = element.style
    if (typeof values === "string") {
      style.cssText = overwrite ? values : style.cssText + ";" + values
      return
    }
    if (overwrite) {
      style.cssText = ""
    }
    for (const key in values) {
      if (Object.hasOwn(values, key)) {
        style[key] = values[key].replace("!important", "")
      }
    }
  }
  if (typeof Object.hasOwn !== "function") {
    Object.hasOwn = (instance, prop) =>
      Object.prototype.hasOwnProperty.call(instance, prop)
  }
  var addElement = (parentNode, tagName, attributes) => {
    if (typeof parentNode === "string" || typeof tagName === "string") {
      const element = GM_addElement(parentNode, tagName, attributes)
      setAttributes(element, attributes)
      return element
    }
    setAttributes(tagName, attributes)
    parentNode.append(tagName)
    return tagName
  }
  var addStyle = (styleText) => GM_addStyle(styleText)
  var content_default =
    "[data-miniflux_ext] #left_section{position:fixed;top:0;left:0;padding:20px;overflow:auto;height:100%}"
  var config = {
    matches: [
      "https://reader.miniflux.app/*",
      "https://miniflux.pipecraft.net/*",
    ],
  }
  var m1 = 1e3 * 60
  var storageKey = "extension.miniflux.cache"
  function getCategoriesFromCache() {
    const categoriesText = localStorage.getItem(storageKey)
    return categoriesText
      ? createElement("div", {
          class: "items",
          innerHTML: categoriesText,
        })
      : null
  }
  async function updateCategories() {
    const response = await fetch("/categories")
    if (response.status === 200) {
      const text = await response.text()
      const div = createElement("div")
      div.innerHTML = text
      const categories = $(div, ".items")
      if (categories == null ? void 0 : categories.innerHTML) {
        const categoriesText = localStorage.getItem(storageKey)
        if (categoriesText !== categories.innerHTML) {
          localStorage.setItem(storageKey, categories.innerHTML)
          return true
        }
      }
    }
    return false
  }
  var appendCategories = () => {
    const container = $("[data-miniflux_ext] #left_section")
    if (!container) {
      return
    }
    let categories = $("[data-miniflux_ext] #left_section .items")
    if (categories) {
      categories.remove()
    }
    categories = getCategoriesFromCache()
    if (categories) {
      container.append(categories)
    }
  }
  async function autoUpdateCategories() {
    if (await updateCategories()) {
      appendCategories()
      setTimeout(autoUpdateCategories, 3 * m1)
    } else {
      setTimeout(autoUpdateCategories, 10 * m1)
    }
  }
  async function main() {
    if (!document.body || $("[data-miniflux_ext] #left_section")) {
      return
    }
    addStyle(content_default)
    document.body.dataset.miniflux_ext = "1"
    addElement(document.body, "section", {
      id: "left_section",
      innerHTML: `<section class="page-header"><h1>Categories</h1></section>`,
    })
    appendCategories()
    setTimeout(autoUpdateCategories, 1e3)
  }
  main()
  addEventListener(document, "DOMContentLoaded", main)
})()