// ==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)
})()