Skip to content

fix(settings): show labelled Add/Remove buttons in podcast search (#109) - #195

Merged
chhoumann merged 2 commits into
masterfrom
chhoumann/109-ipad-add-button
Jun 16, 2026
Merged

chhoumann merged 2 commits into
masterfrom
chhoumann/109-ipad-add-button

Conversation

@chhoumann

@chhoumann chhoumann commented Jun 16, 2026 •

Copy link
Copy Markdown
Owner

Summary

Closes #109.

On iPad, users could not find the Add controls in PodNotes settings. The podcast search result cards — and the "add playlist" button — used icon-only Obsidian buttons (setIcon("plus") / setIcon("trash")), and on iPad the icon glyph rendered as an empty box: an invisible, unrecognisable tap target. Both reporters' screenshots show this (an empty rounded rectangle where the add control should be; on a light theme, nothing visible at all).

This replaces the icon-only buttons with Obsidian's native call-to-action / warning buttons carrying visible text labels — Add (cta) and Remove (warning). A text label always renders (it is textContent, not an icon glyph), reads unambiguously, and is sized appropriately per platform (Obsidian renders larger buttons on mobile/iPad via --input-height). The aria-label is preserved.

Before (iPad, from #109) After
Empty box / no visible add control A clearly-labelled accent Add button (and Remove for saved feeds)

Root cause

  • The settings podcast view was redesigned in 2.13.0 to use compact icon-only buttons; the iPad reports ([bug]can’t find an “add” button when searching for podcasts in iPad #109, Sep 2024) started right after.
  • On iPad the lucide glyph inside Obsidian's ButtonComponent did not paint, so the button was an empty box. Obsidian's own toolbar icons rendered fine on the same device — so an icon-only affordance is fragile here, while a text label is guaranteed to render.
  • The control was also only ~30×30px with no text, just an aria-label.

Changes

  • src/ui/settings/PodcastResultCard.svelte — icon-only → text="Add" cta / text="Remove" warning; aria-label kept. The control is now a native cta/warning button that supplies its own padding/radius/hover, so the previous custom :global(.podcast-actions button) block is removed (a deliberate, minor desktop visual change to native button styling).
  • src/ui/settings/PlaylistManager.svelte — the "add playlist" button had the same icon-only failure mode and no aria-label (so it was also invisible to screen readers). Changed <Button icon="plus" cta /> → <Button text="Add" cta ariaLabel="Add playlist" />.
  • src/ui/settings/PodcastResultCard.test.ts + src/ui/settings/PlaylistManager.test.ts (new) — Testing-Library regression tests asserting a visible Add/Remove text label, mod-cta/mod-warning, an accessible name, and that no action renders without a visible label.
  • vitest.setup.ts — minimal Element.prototype.animate (Web Animations API) mock so transition:fade components can render under jsdom in component tests; documented its known fidelity gaps.

Verification

  • Gates (Node 22), all green: lint, format:check, typecheck, check:a11y (0 errors / 0 warnings), test (375 passing), build.
  • Real Obsidian app (isolated e2e vault): searched podcasts and inspected the playlist manager; both add controls now render an "Add" button with the accent (mod-cta) background rgb(138, 92, 245) and intact aria-labels ("Add … podcast", "Add playlist").

Notes / caveats

  • The iPad-only empty-glyph could not be reproduced on desktop (the icon renders fine there). The root cause was confirmed from the two reporters' screenshots + the markup, and the fix targets the failure mode directly: a guaranteed-visible text label with native per-platform sizing.
  • The new unit tests assert mod-cta/mod-warning + visible text via the obsidian test mock, not real Obsidian CSS/glyph rendering — they guard against re-introducing a label-less button, while the real-app e2e check validates the visible-label fix.
  • No enforced 44px touch target by design: Obsidian sizes buttons via --input-height (larger on mobile/iPad); native cta/warning sizing is correct per-platform.

Possible follow-up (out of scope)

The PlaylistItem delete button (src/ui/settings/PlaylistItem.svelte) still uses the icon-only setIcon glyph path that is the #109 root cause, so it could also render as an empty box on iPad. It already has an aria-label (so it is not screen-reader-invisible), and its stateful trash → confirm-check behaviour makes converting it a larger change. Left out of this add-scoped fix; worth a separate issue.

On iPad the icon-only "+"/trash buttons in podcast search results
rendered as empty boxes — the icon glyph did not paint, leaving an
invisible, unrecognisable tap target, so users could not find the add
control. Replace the icon-only buttons with Obsidian's native
call-to-action / warning buttons carrying visible "Add"/"Remove" text
labels, which always render and are sized appropriately per platform
(Obsidian renders larger buttons on mobile/iPad). The aria-label is
preserved.

The control is now a native cta/warning button that supplies its own
padding, radius and hover, so the previous custom
:global(.podcast-actions button) styling is removed (a deliberate,
minor desktop visual change to native button styling).

Also add a PodcastResultCard regression test guarding the visible text
label, and mock the Web Animations API in the vitest setup so
transition-bearing Svelte components can be rendered in component tests.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 16, 2026 •

Copy link
Copy Markdown

Deploying podnotes with  Cloudflare Pages  Cloudflare Pages

Latest commit: 316f114
Status: ✅  Deploy successful!
Preview URL: https://1ee62b31.podnotes.pages.dev
Branch Preview URL: https://chhoumann-109-ipad-add-butto.podnotes.pages.dev

View logs

The "add playlist" control in PlaylistManager used the same icon-only
"+" button as the podcast search results — on iPad the glyph did not
paint, leaving an empty box, and it had no aria-label, so it was also
invisible to screen readers. Give it a visible "Add" text label and an
"Add playlist" aria-label, matching the podcast-search fix, and add a
regression test.
@chhoumann
chhoumann merged commit 33399f5 into master Jun 16, 2026
2 checks passed
@chhoumann
chhoumann deleted the chhoumann/109-ipad-add-button branch June 16, 2026 06:16
github-actions Bot pushed a commit that referenced this pull request Jun 22, 2026
# [2.17.0](2.16.0...2.17.0) (2026-06-22)

### Bug Fixes

* behavioral-audit logic and robustness fixes (back-end, 1/2) ([#213](#213)) ([4e2845d](4e2845d))
* **download:** default per-episode download path and migrate empty default ([#183](#183)) ([#186](#186)) ([46a6486](46a6486))
* **download:** prevent Android crash and create missing folders on download ([#178](#178)) ([ecd09d5](ecd09d5)), closes [#113](#113) [#86](#86) [#113](#113) [#86](#86)
* **lifecycle:** defer mobile podcast view startup ([#208](#208)) ([8bf9ce4](8bf9ce4))
* **notes:** cap note path length and harden folder creation ([#22](#22), [#87](#87)) ([#192](#192)) ([858e280](858e280)), closes [#87-class](#87)
* **playback:** persist listened time during playback ([#33](#33)) ([#190](#190)) ([e3433c2](e3433c2)), closes [#191](#191) [#108](#108) [#163](#163) [#183](#183)
* **playback:** play local files and downloads on iOS via resource path ([#100](#100)) ([#184](#184)) ([12c503a](12c503a))
* **player:** clear progress on episode switch to stop end-of-playback glitch ([#94](#94)) ([#194](#194)) ([59dccb3](59dccb3))
* **player:** reveal PodNotes view on Play with PodNotes so local files play ([#84](#84)) ([#198](#198)) ([5953625](5953625))
* **settings:** show labelled Add/Remove buttons in podcast search ([#109](#109)) ([#195](#195)) ([33399f5](33399f5))
* show downloaded episodes in the Local Files playlist ([#176](#176)) ([#177](#177)) ([184188c](184188c))
* **timestamps:** capture into the cursor's table cell without breaking the row ([#165](#165)) ([#203](#203)) ([964e342](964e342))
* **transcription:** always transcribe the currently playing episode ([#182](#182)) ([62b488a](62b488a)), closes [#107](#107)
* **uri:** preserve '+' in episode titles and paths for timestamp links ([#181](#181)) ([8ad7aa5](8ad7aa5)), closes [#164](#164)
* **view:** reliably reveal PodNotes view via command + ribbon icon ([#55](#55)) ([#199](#199)) ([fa1d708](fa1d708))

### Features

* add podcast segment links ([#205](#205)) ([d97e59e](d97e59e))
* **api:** expose generated episode transcripts ([e264465](e264465)), closes [#105](#105)
* behavioral-audit UI and interaction fixes (front-end, 2/2) ([#215](#215)) ([894d93d](894d93d))
* **commands:** add playback rate and media timestamp controls ([#206](#206)) ([a8bb44a](a8bb44a))
* **devx:** isolated per-worktree Obsidian E2E vault wrapper ([#188](#188)) ([a8b7a4a](a8b7a4a))
* **episodes:** add a setting to control the Latest Episodes list length ([#114](#114)) ([#200](#200)) ([7b3e3c6](7b3e3c6))
* **notes:** add {{episodelink}} template tag to resume an episode from its note ([#35](#35)) ([#193](#193)) ([8c1ddd6](8c1ddd6))
* **notes:** add podcast feed-level notes ([#163](#163)) ([#187](#187)) ([db0de47](db0de47)), closes [#161](#161) [#160](#160)
* **notes:** ship a Bases-friendly default episode note template ([#160](#160)) ([#201](#201)) ([209431d](209431d)), closes [#163](#163) [#183](#183)
* **player:** scale episode title font size to its length ([#81](#81)) ([#202](#202)) ([659b6b8](659b6b8))
* **player:** support video episode playback ([#209](#209)) ([f92a91f](f92a91f))
* **queue:** add setting to disable queue auto-population and auto-advance ([#108](#108)) ([#185](#185)) ([cf3d73c](cf3d73c))
* **queue:** allow reordering the playback queue ([#80](#80)) ([#179](#179)) ([d994d61](d994d61)), closes [#173](#173)
* **settings:** import/export settings & templates ([#180](#180)) ([a27d23d](a27d23d)), closes [#162](#162) [#162](#162)
* **templates:** add {{currentDate}}, {{episodeNumber}}, {{duration}} template variables ([#189](#189)) ([ec573eb](ec573eb)), closes [#75](#75) [#34](#34) [#88](#88) [163/#186](#186)
* **templates:** add episode chapters tag ([#207](#207)) ([9c98863](9c98863))
* **transcripts:** opt-in speaker diarization for transcripts ([#168](#168)) ([#204](#204)) ([a96e12f](a96e12f))
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 2.17.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

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.

[bug]can’t find an “add” button when searching for podcasts in iPad

1 participant