Skip to content

Add “Open in Reader” button to open generated RSS feeds in feed readers#31

Closed
DisabledAbel wants to merge 4 commits into
mainfrom
codex/add-button-to-open-rss-feed
Closed

Add “Open in Reader” button to open generated RSS feeds in feed readers#31
DisabledAbel wants to merge 4 commits into
mainfrom
codex/add-button-to-open-rss-feed

Conversation

@DisabledAbel

@DisabledAbel DisabledAbel commented May 14, 2026

Copy link
Copy Markdown
Owner

Motivation

  • Provide a quick action so users can open the generated RSS feed directly in an RSS reader or trigger a registered feed:// handler.

Description

  • Added an openInReader client-side helper that converts http:///https:// feed URLs into feed:// where possible and opens them with window.open.
  • Added an Open in Reader action button and event wiring next to the existing copy action for the selected feed in the UI.
  • Introduced .open-reader-btn styling to keep the new action visually aligned with the existing controls.
  • Applied these changes consistently to api/index.html, index.html, and templates/index.html so all served frontends behave the same.

Testing

  • Ran python -m py_compile api/app.py rss_scanner.py which completed successfully.
  • Performed a Flask test-client smoke check that GET / returned 200 and the served HTML contains Open in Reader and function openInReader, which succeeded.

Codex Task


Open in Devin Review

Summary by CodeRabbit

  • New Features
    • Added an "Open in Reader" button to open selected RSS feeds in external reader applications
    • Automatically converts feed URLs to a format compatible with RSS reader apps
    • Opens feeds in a new browser tab for seamless integration

Review Change Stack

@vercel

vercel Bot commented May 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
you-tube-rss-feed-scanner Ready Ready Preview, Comment May 14, 2026 6:41pm

@coderabbitai

coderabbitai Bot commented May 14, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@DisabledAbel has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 48 minutes and 42 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fba63ab8-5a26-48b3-b38b-dbc6fe1cb295

📥 Commits

Reviewing files that changed from the base of the PR and between fbcfd66 and d1e9d91.

📒 Files selected for processing (6)
  • README.md
  • api/index.html
  • index.html
  • scripts/run_terminal_reader.sh
  • scripts/terminal_reader.py
  • templates/index.html
📝 Walkthrough

Walkthrough

This pull request adds an "Open in Reader" feature to three HTML files (api, index, and templates versions). The feature enables users to open selected YouTube RSS feeds in external reader applications by converting http(s) protocol URLs to feed:// protocol and opening them in a new browser tab.

Changes

Open in Reader Feature

Layer / File(s) Summary
Button styling
api/index.html, index.html, templates/index.html
CSS class .open-reader-btn added to all three files with layout, spacing, sizing, and background color properties to style the new button.
Feed URL conversion function
api/index.html, index.html, templates/index.html
openInReader() function implemented across all three files to decode encoded URLs, rewrite http(s):// to feed:// protocol, and open the result in a new tab with noopener,noreferrer security flags.
UI integration and event handling
api/index.html, index.html, templates/index.html
"Open in Reader" button markup added alongside the existing "Copy Selected RSS" button; click handlers wired to call openInReader() with the selected feed URL; event listeners added for programmatic interaction.

Possibly related PRs

  • DisabledAbel/YouTube-RSS-Feed-Scanner#24: Modifies the same "Selected RSS Feed" rendering logic in index.html/templates/index.html to change what the copy button outputs, sharing the same selected-feed value/encoded data infrastructure.
  • DisabledAbel/YouTube-RSS-Feed-Scanner#1: Establishes the initial RSS feed URL generation and display UI that the new "Open in Reader" button and its URL conversion helper directly integrate with.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 Hop along, dear reader, to feeds far and wide,
No more tabs to juggle—just open with pride!
Feed protocol magic, three homes, one delight,
RSS reading flows smooth, from morning to night! 🌾

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding an 'Open in Reader' button to enable users to open generated RSS feeds in feed readers.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/add-button-to-open-rss-feed

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

devin-ai-integration[bot]

This comment was marked as resolved.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (4)
api/index.html (2)

183-192: ⚡ Quick win

Consider error handling for popup blockers.

The window.open call may be blocked by popup blockers or fail if no feed:// protocol handler is registered. Users won't receive feedback in these cases.

💡 Add error handling and user feedback
 function openInReader(encodedText) {
     const feedUrl = decodeURIComponent(encodedText);
     const feedProtocolUrl = feedUrl.startsWith('https://')
         ? 'feed://' + feedUrl.slice('https://'.length)
         : feedUrl.startsWith('http://')
             ? 'feed://' + feedUrl.slice('http://'.length)
             : feedUrl;
 
-    window.open(feedProtocolUrl, '_blank', 'noopener,noreferrer');
+    const opened = window.open(feedProtocolUrl, '_blank', 'noopener,noreferrer');
+    if (!opened || opened.closed || typeof opened.closed === 'undefined') {
+        showToast('Could not open feed reader. Please check your popup blocker or install a feed reader app.', true);
+    }
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@api/index.html` around lines 183 - 192, The openInReader function currently
calls window.open(feedProtocolUrl, '_blank', 'noopener,noreferrer') without
handling failures; update openInReader to catch exceptions and check the return
value (popup window handle) from window.open, and if it is null or an exception
occurs show user feedback (e.g., call a UI helper like showErrorToast or alert)
explaining the open failed and provide a fallback (copy feedProtocolUrl to
clipboard or display the decoded feedUrl so the user can manually open it);
ensure you reference the existing symbols openInReader, feedProtocolUrl and the
window.open call when implementing the checks and fallback.

242-243: ⚡ Quick win

Inconsistent event handling pattern.

These lines use inline onclick handlers, but the file already has event delegation for copy buttons (lines 292-299) using data-encoded attributes. Line 253 also uses data-encoded for official feeds. This inconsistency makes the code harder to maintain.

♻️ Refactor to use consistent event delegation pattern

Change the HTML generation to use data-encoded attributes:

-html += '<button class="copy-btn" onclick="copyEncodedText(\'' + encodeURIComponent((data.selected_feed || data.youtube_rss)) + '\')">Copy Selected RSS</button>';
-html += '<button class="open-reader-btn" onclick="openInReader(\'' + encodeURIComponent((data.selected_feed || data.youtube_rss)) + '\')">Open in Reader</button></div>';
+html += '<button class="copy-btn" data-encoded="' + encodeURIComponent((data.selected_feed || data.youtube_rss)) + '">Copy Selected RSS</button>';
+html += '<button class="open-reader-btn" data-encoded="' + encodeURIComponent((data.selected_feed || data.youtube_rss)) + '">Open in Reader</button></div>';

Add event delegation for open-reader-btn (after line 299):

// Event delegation for dynamically added open reader buttons
document.addEventListener('click', function(e) {
    if (e.target && e.target.classList.contains('open-reader-btn')) {
        const encoded = e.target.getAttribute('data-encoded');
        if (encoded) {
            openInReader(encoded);
        }
    }
});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@api/index.html` around lines 242 - 243, The generated buttons use inline
onclick handlers instead of the existing data-driven delegation pattern; update
the HTML string that builds the buttons to set data-encoded="..." on both the
copy and open buttons (remove the onclick attributes) and keep the classes
'copy-btn' and 'open-reader-btn', then add an event-delegation listener that
detects clicks on elements with class 'open-reader-btn', reads the data-encoded
value and calls openInReader(encoded) (mirror the existing delegation used for
copy buttons which calls copyEncodedText). Ensure you reference the same
attribute name 'data-encoded' and the functions copyEncodedText and openInReader
so behavior remains identical.
index.html (1)

179-187: ⚡ Quick win

Consider error handling for popup blockers.

The window.open call may be blocked by popup blockers or fail if no feed:// protocol handler is registered.

💡 Add error handling and user feedback
 function openInReader(feedUrl) {
     const feedProtocolUrl = feedUrl.startsWith('https://')
         ? 'feed://' + feedUrl.slice('https://'.length)
         : feedUrl.startsWith('http://')
             ? 'feed://' + feedUrl.slice('http://'.length)
             : feedUrl;
 
-    window.open(feedProtocolUrl, '_blank', 'noopener,noreferrer');
+    const opened = window.open(feedProtocolUrl, '_blank', 'noopener,noreferrer');
+    if (!opened || opened.closed || typeof opened.closed === 'undefined') {
+        showToast('Could not open feed reader. Please check your popup blocker or install a feed reader app.', true);
+    }
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@index.html` around lines 179 - 187, The openInReader function needs
popup-block and failure handling: after building feedProtocolUrl, call
window.open and check its return value (the opened window reference) and wrap
the call in try/catch; if window.open returns null/undefined or throws, show
user feedback (e.g., display an in-page message or alert) explaining the open
failed and provide a fallback link or instructions to copy the feed URL (use the
feedProtocolUrl string). Ensure you reference the feedProtocolUrl and
window.open call inside openInReader and surface a clear, user-friendly error
message.
templates/index.html (1)

178-189: ⚡ Quick win

Consider error handling for popup blockers.

The window.open call may be blocked by popup blockers or fail if no feed:// protocol handler is registered.

💡 Add error handling and user feedback
 function openInReader(encodedText) {
     const feedUrl = decodeURIComponent(encodedText);
     // Many desktop/mobile feed apps register the feed:// protocol.
     // Convert https:// URLs to feed:// where possible to trigger RSS readers.
     const feedProtocolUrl = feedUrl.startsWith('https://')
         ? 'feed://' + feedUrl.slice('https://'.length)
         : feedUrl.startsWith('http://')
             ? 'feed://' + feedUrl.slice('http://'.length)
             : feedUrl;
 
-    window.open(feedProtocolUrl, '_blank', 'noopener,noreferrer');
+    const opened = window.open(feedProtocolUrl, '_blank', 'noopener,noreferrer');
+    if (!opened || opened.closed || typeof opened.closed === 'undefined') {
+        showToast('Could not open feed reader. Please check your popup blocker or install a feed reader app.', true);
+    }
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@templates/index.html` around lines 178 - 189, The openInReader function
should handle failures from window.open (popup blockers or missing feed://
handler): wrap the window.open call in a try/catch and check its return value;
if window.open returns null or an exception is thrown, fallback by attempting to
open the original feedUrl (e.g., set window.location.href) or show a user-facing
message/alert via your app’s UI indicating the reader could not be launched and
suggesting manual subscription; reference openInReader, feedProtocolUrl and
feedUrl when adding these checks and the fallback/user-feedback path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@api/index.html`:
- Around line 183-192: The openInReader function currently calls
window.open(feedProtocolUrl, '_blank', 'noopener,noreferrer') without handling
failures; update openInReader to catch exceptions and check the return value
(popup window handle) from window.open, and if it is null or an exception occurs
show user feedback (e.g., call a UI helper like showErrorToast or alert)
explaining the open failed and provide a fallback (copy feedProtocolUrl to
clipboard or display the decoded feedUrl so the user can manually open it);
ensure you reference the existing symbols openInReader, feedProtocolUrl and the
window.open call when implementing the checks and fallback.
- Around line 242-243: The generated buttons use inline onclick handlers instead
of the existing data-driven delegation pattern; update the HTML string that
builds the buttons to set data-encoded="..." on both the copy and open buttons
(remove the onclick attributes) and keep the classes 'copy-btn' and
'open-reader-btn', then add an event-delegation listener that detects clicks on
elements with class 'open-reader-btn', reads the data-encoded value and calls
openInReader(encoded) (mirror the existing delegation used for copy buttons
which calls copyEncodedText). Ensure you reference the same attribute name
'data-encoded' and the functions copyEncodedText and openInReader so behavior
remains identical.

In `@index.html`:
- Around line 179-187: The openInReader function needs popup-block and failure
handling: after building feedProtocolUrl, call window.open and check its return
value (the opened window reference) and wrap the call in try/catch; if
window.open returns null/undefined or throws, show user feedback (e.g., display
an in-page message or alert) explaining the open failed and provide a fallback
link or instructions to copy the feed URL (use the feedProtocolUrl string).
Ensure you reference the feedProtocolUrl and window.open call inside
openInReader and surface a clear, user-friendly error message.

In `@templates/index.html`:
- Around line 178-189: The openInReader function should handle failures from
window.open (popup blockers or missing feed:// handler): wrap the window.open
call in a try/catch and check its return value; if window.open returns null or
an exception is thrown, fallback by attempting to open the original feedUrl
(e.g., set window.location.href) or show a user-facing message/alert via your
app’s UI indicating the reader could not be launched and suggesting manual
subscription; reference openInReader, feedProtocolUrl and feedUrl when adding
these checks and the fallback/user-feedback path.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 872d1452-5d04-41aa-b669-ce5c18c88958

📥 Commits

Reviewing files that changed from the base of the PR and between 554b8a5 and fbcfd66.

📒 Files selected for processing (3)
  • api/index.html
  • index.html
  • templates/index.html

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@DisabledAbel DisabledAbel deleted the codex/add-button-to-open-rss-feed branch May 14, 2026 20:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant