Skip to content

feat: Glass icon buttons & Reddit feed content fix#10

Merged
devohmycode merged 1 commit intomasterfrom
0.6.2
Feb 27, 2026
Merged

feat: Glass icon buttons & Reddit feed content fix#10
devohmycode merged 1 commit intomasterfrom
0.6.2

Conversation

@devohmycode
Copy link
Copy Markdown
Owner

@devohmycode devohmycode commented Feb 27, 2026

Summary

  • Glass icon buttons: Replace plain action buttons with 3D glass-effect GlassIconButton component across SourcePanel, FeedPanel, BookmarkPanel, and NotePanel
  • Reddit feed fix: Atom feeds (Reddit) were only showing title + comments — post body text was stripped because getTextContent() was used on <content type="html"> elements. Added getHtmlContent() to properly decode HTML content from Atom feeds
  • Minor: Remove Ctrl+K hint from mode tab bar, fix amoled theme on blob cards

Test plan

  • Open a Reddit feed — verify post body text now renders in the reader
  • Verify glass icon buttons display correctly in all panels (Flux, Signets, Notes)
  • Check amoled theme on card view
  • Verify YouTube and standard RSS feeds still parse correctly

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced modern glass-effect button styling across interface panels for improved visual consistency.
    • Enhanced HTML content extraction from RSS and Atom feeds for better content rendering.
  • UI/UX Improvements

    • Restyled action buttons with updated glass-icon aesthetic in bookmark, feed, note, and source panels.
    • Expanded dark and AMOLED theme support for comprehensive interface coverage.
    • Improved spacing and visual hierarchy in panel action groups.

- Replace plain buttons with 3D glass icon buttons (GlassIconButton) across
  SourcePanel, FeedPanel, BookmarkPanel, and NotePanel
- Fix Reddit/Atom feeds not rendering post body text by adding getHtmlContent()
  that properly handles type="html" and type="xhtml" Atom content elements
- Remove Ctrl+K hint from mode tab bar
- Fix amoled theme for blob cards

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 27, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8a8a631 and 907c32f.

📒 Files selected for processing (8)
  • src/components/BookmarkPanel.tsx
  • src/components/FeedPanel.tsx
  • src/components/GlassIconButton.tsx
  • src/components/GlassIcons.tsx
  • src/components/NotePanel.tsx
  • src/components/SourcePanel.tsx
  • src/index.css
  • src/services/rssService.ts

📝 Walkthrough

Walkthrough

The changes introduce a new GlassIconButton component and refactor multiple panels (Bookmark, Feed, Note, Source) to use stylized glassy buttons for header actions, replacing standard buttons. CSS styling provides the glass aesthetic with layered effects and hover animations. An RSS service improvement enhances Atom content extraction.

Changes

Cohort / File(s) Summary
Glass Button Components
src/components/GlassIconButton.tsx, src/components/GlassIcons.tsx
New reusable glassy button component with gradient backgrounds and layering effects. GlassIconButton provides single icon buttons with color/active state support; GlassIcons renders responsive grids of interactive buttons.
Panel UI Refactoring
src/components/BookmarkPanel.tsx, src/components/FeedPanel.tsx, src/components/NotePanel.tsx, src/components/SourcePanel.tsx
Migrated header action buttons from standard HTML buttons to GlassIconButton components. Maintains existing functionality while consolidating styling through component props (color, icon, active state). Removed textual labels in favor of icon-based actions.
Styling & Theme
src/index.css
Added comprehensive glass-button aesthetic with layered spans, gradient backgrounds, hover animations, and active ring states. Increased panel action spacing (gap 2px→10px). Extended dark/AMOLED theming to feed blob card components. Adjusted body padding and overflow handling.
Service Enhancement
src/services/rssService.ts
Introduced getHtmlContent helper function for improved Atom feed content extraction, handling type-specific encodings (html, xhtml) with proper decoding and serialization fallbacks.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🥕 Buttons shimmer with frosted glass,
A glassy gleam that came to pass,
Icons dance in gradient light,
Panels shine, so smooth and bright!
Feed and feeds now look divine,
UI magic—simply fine!

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 0.6.2

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.

@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Replace plain action buttons with 3D glass-effect GlassIconButton component across all panels
• Fix Reddit/Atom feeds not rendering post body text by adding getHtmlContent() function
• Improve spacing and styling for glass icon buttons in mode tab bar
• Fix amoled theme styling for blob cards and remove Ctrl+K hint
Diagram
flowchart LR
  A["RSS Service"] -->|"getHtmlContent()"| B["Atom Feed Parser"]
  B -->|"Properly decode HTML content"| C["Feed Items with Body Text"]
  D["Plain Buttons"] -->|"Replace with"| E["GlassIconButton Component"]
  E -->|"Applied to"| F["SourcePanel, FeedPanel, BookmarkPanel, NotePanel"]
  G["CSS Updates"] -->|"Add glass effect styles"| E
  G -->|"Fix amoled theme"| H["Blob Cards"]
Loading

Grey Divider

File Changes

1. src/services/rssService.ts 🐞 Bug fix +19/-1

Add HTML content extraction for Atom feeds

• Added getHtmlContent() function to properly handle Atom feed content elements with type="html"
 and type="xhtml" attributes
• Function decodes HTML-encoded text content and serializes XHTML child nodes correctly
• Updated parseAtomFeed() to use getHtmlContent() for content field, falling back to text
 content and summary

src/services/rssService.ts


2. src/index.css ✨ Enhancement +111/-9

Add glass button styles and fix amoled theme

• Added comprehensive .glass-icon-btn styles with 3D perspective, tilted background, and frosted
 glass overlay effects
• Updated mode tab bar spacing and added glass icon button sizing rules
• Fixed amoled theme styling for blob cards by adding .amoled selectors alongside .dark
 selectors
• Increased gap spacing in bookmark, note, and feed panel action containers from 2px to 10px

src/index.css


3. src/components/GlassIconButton.tsx ✨ Enhancement +37/-0

New GlassIconButton component with 3D effects

• New component implementing 3D glass-effect icon buttons with colored gradient backgrounds
• Supports color prop with predefined gradient mappings (blue, purple, red, indigo, orange, green)
• Includes active state styling and hover 3D transform effects
• Accepts standard button HTML attributes and ReactNode icons

src/components/GlassIconButton.tsx


View more (5)
4. src/components/GlassIcons.tsx ✨ Enhancement +71/-0

New GlassIcons grid display component

• New utility component for displaying grid of glass icon buttons with labels
• Provides reusable interface for glass icon collections with hover animations
• Includes gradient mapping and custom styling support

src/components/GlassIcons.tsx


5. src/components/BookmarkPanel.tsx ✨ Enhancement +29/-23

Replace buttons with glass icon buttons

• Replaced plain filter and view mode buttons with GlassIconButton components
• Added color-coded buttons (blue, indigo, orange, green, purple) for different actions
• Imported GlassIconButton component and updated button styling to use active prop

src/components/BookmarkPanel.tsx


6. src/components/FeedPanel.tsx ✨ Enhancement +38/-32

Replace feed panel buttons with glass icons

• Replaced all plain action buttons with GlassIconButton components
• Added color-coded buttons for digest, translate, mark read, view modes, and close actions
• Imported GlassIconButton and updated button structure to use icon and active props
• Maintained spinner and SVG icon support within glass buttons

src/components/FeedPanel.tsx


7. src/components/NotePanel.tsx ✨ Enhancement +11/-10

Replace note panel buttons with glass icons

• Replaced plain view mode buttons with GlassIconButton components
• Added color-coded buttons (orange for cards, indigo for board view)
• Imported GlassIconButton and updated button structure

src/components/NotePanel.tsx


8. src/components/SourcePanel.tsx ✨ Enhancement +12/-11

Replace mode tabs with glass icon buttons

• Replaced mode tab buttons with GlassIconButton components
• Added color prop to each mode tab (blue, green, orange, purple, indigo)
• Updated locked state to use red color instead of CSS class
• Removed Ctrl+K hint span from mode tab bar
• Imported GlassIconButton component

src/components/SourcePanel.tsx


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review bot commented Feb 27, 2026

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Atom HTML XSS risk 🐞 Bug ⛨ Security
Description
Atom <content> is now treated as HTML (including serialized XHTML) and flows into
dangerouslySetInnerHTML rendering without sanitization. With the current Tauri CSP allowing
unsafe-inline/unsafe-eval, a malicious feed can inject scriptable markup (e.g., event handlers)
into the WebView.
Code

src/services/rssService.ts[R152-156]

      description: getTextContent(entry, 'summary'),
      pubDate: getTextContent(entry, 'published') || getTextContent(entry, 'updated'),
      author: entry.querySelector('author name')?.textContent || '',
-      content: getTextContent(entry, 'content') || getTextContent(entry, 'summary'),
+      content: getHtmlContent(entry, 'content') || getTextContent(entry, 'content') || getTextContent(entry, 'summary'),
      guid: getTextContent(entry, 'id') || link,
Evidence
parseAtomFeed() now prefers getHtmlContent() for entry content, which can return raw markup; the
Reader renders item.content via dangerouslySetInnerHTML; the app’s CSP explicitly allows
inline/eval scripts, increasing impact of any injection.

src/services/rssService.ts[36-52]
src/services/rssService.ts[141-167]
src/components/ReaderPanel.tsx[1175-1180]
src-tauri/tauri.conf.json[27-29]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Atom feed parsing now returns HTML markup (`getHtmlContent`) that is rendered with `dangerouslySetInnerHTML` in the Reader. Since feed content is untrusted and the Tauri CSP allows inline/eval scripts, this can enable XSS via event-handler attributes or other scriptable HTML.

## Issue Context
- Atom entries can provide `content` as `type=&quot;html&quot;` or `type=&quot;xhtml&quot;`; the new helper serializes/returns markup.
- The reader injects this HTML into the DOM.

## Fix Focus Areas
- src/services/rssService.ts[36-52]
- src/services/rssService.ts[141-167]
- src/components/ReaderPanel.tsx[1175-1180]
- src-tauri/tauri.conf.json[27-29]

## Implementation notes
- Add a small `sanitizeFeedHtml(html: string): string` utility (DOMParser-based allowlist) and apply it to `item.content` (and `item.fullContent` if also untrusted) before rendering.
- Ensure removal of `on*` attributes and `javascript:`/`data:` URLs in `href/src` as appropriate.
- If feasible, reduce CSP permissiveness (especially `unsafe-inline`/`unsafe-eval`).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Icon buttons a11y/UX 🐞 Bug ✓ Correctness
Description
GlassIconButton creates icon-only buttons where the icon is aria-hidden and there is no explicit
accessible name; callers currently rely on title, which is inconsistent across assistive tech. The
CSS also removes focus outline and keeps cursor: pointer even when disabled, making keyboard
focus and disabled state hard to perceive.
Code

src/components/GlassIconButton.tsx[R18-35]

+export default function GlassIconButton({ color, icon, active, className, ...props }: GlassIconButtonProps) {
+  const bg = gradientMapping[color] || color;
+
+  return (
+    <button
+      type="button"
+      {...props}
+      className={`glass-icon-btn group ${active ? 'active' : ''} ${className || ''}`}
+    >
+      {/* Colored background — tilted */}
+      <span className="glass-icon-bg" style={{ background: bg }} />
+      {/* Frosted glass overlay */}
+      <span className="glass-icon-front">
+        <span className="glass-icon-inner" aria-hidden="true">
+          {icon}
+        </span>
+      </span>
+    </button>
Evidence
The component hides the icon from screen readers and doesn’t set aria-label; the new CSS sets
outline: none and cursor: pointer; yet callers pass disabled (e.g., FeedPanel) so buttons can
be disabled with no visual affordance/focus ring.

src/components/GlassIconButton.tsx[18-35]
src/index.css[3551-3563]
src/components/FeedPanel.tsx[350-356]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`GlassIconButton` is used for icon-only actions across panels. Right now it hides the icon from screen readers and doesn’t provide an explicit accessible name, and CSS removes focus outline and doesn’t visually distinguish disabled buttons.

## Issue Context
Most callers provide a `title`, but relying on `title` for accessible naming is inconsistent. The component should provide consistent a11y and focus/disabled affordances by default.

## Fix Focus Areas
- src/components/GlassIconButton.tsx[18-35]
- src/index.css[3551-3563]
- src/components/FeedPanel.tsx[350-356]

## Implementation notes
- In `GlassIconButton`, set `aria-label={props[&#x27;aria-label&#x27;] ?? (typeof props.title === &#x27;string&#x27; ? props.title : undefined)}`.
- Add CSS for `.glass-icon-btn:focus-visible` (e.g., outline/ring on `.glass-icon-front`).
- Add CSS for `.glass-icon-btn:disabled` (e.g., `opacity`, `cursor: not-allowed`) and optionally suppress hover transforms when disabled.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@devohmycode devohmycode merged commit 4d1207c into master Feb 27, 2026
1 check was pending
Comment on lines 152 to 156
description: getTextContent(entry, 'summary'),
pubDate: getTextContent(entry, 'published') || getTextContent(entry, 'updated'),
author: entry.querySelector('author name')?.textContent || '',
content: getTextContent(entry, 'content') || getTextContent(entry, 'summary'),
content: getHtmlContent(entry, 'content') || getTextContent(entry, 'content') || getTextContent(entry, 'summary'),
guid: getTextContent(entry, 'id') || link,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Atom html xss risk 🐞 Bug ⛨ Security

Atom <content> is now treated as HTML (including serialized XHTML) and flows into
dangerouslySetInnerHTML rendering without sanitization. With the current Tauri CSP allowing
unsafe-inline/unsafe-eval, a malicious feed can inject scriptable markup (e.g., event handlers)
into the WebView.
Agent Prompt
## Issue description
Atom feed parsing now returns HTML markup (`getHtmlContent`) that is rendered with `dangerouslySetInnerHTML` in the Reader. Since feed content is untrusted and the Tauri CSP allows inline/eval scripts, this can enable XSS via event-handler attributes or other scriptable HTML.

## Issue Context
- Atom entries can provide `content` as `type="html"` or `type="xhtml"`; the new helper serializes/returns markup.
- The reader injects this HTML into the DOM.

## Fix Focus Areas
- src/services/rssService.ts[36-52]
- src/services/rssService.ts[141-167]
- src/components/ReaderPanel.tsx[1175-1180]
- src-tauri/tauri.conf.json[27-29]

## Implementation notes
- Add a small `sanitizeFeedHtml(html: string): string` utility (DOMParser-based allowlist) and apply it to `item.content` (and `item.fullContent` if also untrusted) before rendering.
- Ensure removal of `on*` attributes and `javascript:`/`data:` URLs in `href/src` as appropriate.
- If feasible, reduce CSP permissiveness (especially `unsafe-inline`/`unsafe-eval`).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant