From 6d2360fdd85cc8d82ad624e17b094fdc917b3a39 Mon Sep 17 00:00:00 2001
From: SansGuidon <sansguidon@noreply.gitea.zoemp.be>
Date: Tue, 22 Apr 2025 21:52:44 +0000
Subject: [PATCH] feat(miniflux) distinct duration filters

---
 miniflux_scripts/entries_duration_filter.js | 81 +++++++++++++++++++++
 miniflux_scripts/shorter_entries_filter.js  | 59 ---------------
 2 files changed, 81 insertions(+), 59 deletions(-)
 create mode 100644 miniflux_scripts/entries_duration_filter.js
 delete mode 100644 miniflux_scripts/shorter_entries_filter.js

diff --git a/miniflux_scripts/entries_duration_filter.js b/miniflux_scripts/entries_duration_filter.js
new file mode 100644
index 0000000..f3a24b3
--- /dev/null
+++ b/miniflux_scripts/entries_duration_filter.js
@@ -0,0 +1,81 @@
+(function () {
+  'use strict';
+
+  const SHORT_MAX = 2;     // ≤ 2 minutes
+  const LONG_MIN = 11;     // ≥ 11 minutes
+
+  function parseMinutes(el) {
+    if (!el) return null;
+    const m = el.textContent.match(/(\d+)\s*minute/);
+    return m ? parseInt(m[1], 10) : null;
+  }
+
+  function stylize(entry, opts) {
+    Object.assign(entry.style, {
+      backgroundColor: opts.bg,
+      border: `1px solid ${opts.border}`,
+      borderRadius: '4px',
+      padding: '5px',
+      transition: 'border-color .5s ease, box-shadow .5s ease',
+    });
+    entry.addEventListener('mouseover', () => {
+      entry.style.borderColor = opts.hoverBorder;
+      entry.style.boxShadow = `0 0 10px ${opts.hoverGlow}`;
+    });
+    entry.addEventListener('mouseout', () => {
+      entry.style.borderColor = opts.border;
+      entry.style.boxShadow = 'none';
+    });
+  }
+
+  document.querySelectorAll('article.item.entry-item').forEach(entry => {
+    const mins = parseMinutes(entry.querySelector('.item-meta-info-reading-time span'));
+    if (mins !== null) {
+      if (mins <= SHORT_MAX) {
+        stylize(entry, {
+          bg: 'rgb(37, 44, 39)',
+          border: 'rgb(79, 194, 20)',
+          hoverBorder: 'rgb(129, 255, 50)',
+          hoverGlow: 'rgba(129, 255, 50, .8)',
+        });
+        entry.dataset.readCategory = 'short';
+      } else if (mins >= LONG_MIN) {
+        stylize(entry, {
+          bg: 'rgb(44, 39, 37)',
+          border: 'rgb(194, 79, 20)',
+          hoverBorder: 'rgb(255, 129, 50)',
+          hoverGlow: 'rgba(255, 129, 50, .8)',
+        });
+        entry.dataset.readCategory = 'long';
+      }
+    }
+  });
+
+  function addFilter(label, category) {
+    const nav = document.querySelector('.page-header nav ul');
+    if (!nav) return;
+    const btn = document.createElement('button');
+    btn.textContent = `Filter: ${label}`;
+    Object.assign(btn.style, {
+      marginLeft: '10px',
+      padding: '5px 10px',
+      border: '1px solid rgb(79, 194, 20)',
+      borderRadius: '5px',
+      backgroundColor: 'rgb(37, 44, 39)',
+      color: '#fff',
+      cursor: 'pointer',
+    });
+    btn.onclick = () => {
+      document.querySelectorAll('article.item.entry-item').forEach(e => {
+        e.style.display = (category === 'all' || e.dataset.readCategory === category) ? '' : 'none';
+      });
+    };
+    nav.appendChild(btn);
+  }
+
+  document.addEventListener('DOMContentLoaded', () => {
+    addFilter('Short Reads', 'short');
+    addFilter('Long Reads', 'long');
+    addFilter('All', 'all');
+  });
+})();
diff --git a/miniflux_scripts/shorter_entries_filter.js b/miniflux_scripts/shorter_entries_filter.js
deleted file mode 100644
index 6b013e8..0000000
--- a/miniflux_scripts/shorter_entries_filter.js
+++ /dev/null
@@ -1,59 +0,0 @@
-(function() {
-    'use strict';
-
-    // Style and animate short reading time entries
-    document.querySelectorAll('article.item.entry-item').forEach(entry => {
-        const readingTimeElement = entry.querySelector('.item-meta-info-reading-time span');
-        if (readingTimeElement && (readingTimeElement.textContent.includes('1 minute') || readingTimeElement.textContent.includes('2 minutes'))) {
-            entry.style.backgroundColor = 'rgb(37, 44, 39)'; // Base dark muted greenish-gray
-            entry.style.border = '1px solid rgb(79, 194, 20)'; // Subtle green border
-            entry.style.borderRadius = '4px'; // Rounded corners
-            entry.style.padding = '5px'; // Comfortable padding
-            entry.style.transition = 'border-color 0.5s ease, box-shadow 0.5s ease'; // Smooth animation for border & shadow
-
-            // Add hover effect for geeky animation
-            entry.addEventListener('mouseover', () => {
-                entry.style.borderColor = 'rgb(129, 255, 50)'; // Brighter green on hover
-                entry.style.boxShadow = '0 0 10px rgba(129, 255, 50, 0.8)'; // Neon glow effect
-            });
-
-            entry.addEventListener('mouseout', () => {
-                entry.style.borderColor = 'rgb(79, 194, 20)'; // Reset border color
-                entry.style.boxShadow = 'none'; // Remove glow
-            });
-        }
-    });
-
-    // Add a filter for short reading times
-    function addShortReadingTimeFilter() {
-        const pageHeader = document.querySelector('.page-header nav ul');
-        if (!pageHeader) return;
-
-        const filterButton = document.createElement('button');
-        filterButton.textContent = 'Filter: Short Reads';
-        filterButton.style.marginLeft = '10px';
-        filterButton.style.padding = '5px 10px';
-        filterButton.style.border = '1px solid rgb(79, 194, 20)';
-        filterButton.style.borderRadius = '5px';
-        filterButton.style.backgroundColor = 'rgb(37, 44, 39)';
-        filterButton.style.color = '#fff';
-        filterButton.style.cursor = 'pointer';
-
-        filterButton.onclick = () => {
-            document.querySelectorAll('article.item.entry-item').forEach(entry => {
-                const readingTimeElement = entry.querySelector('.item-meta-info-reading-time span');
-                if (readingTimeElement && 
-                    (readingTimeElement.textContent.includes('1 minute') || readingTimeElement.textContent.includes('2 minutes'))) {
-                    entry.style.display = ''; // Show entry
-                } else {
-                    entry.style.display = 'none'; // Hide non-matching entries
-                }
-            });
-        };
-
-        pageHeader.appendChild(filterButton);
-    }
-
-    // Add the filter button after DOM is fully loaded
-    document.addEventListener('DOMContentLoaded', addShortReadingTimeFilter);
-})();
\ No newline at end of file