Repository navigation
fix(settings): show labelled Add/Remove buttons in podcast search (#109) - #195
Merged
Merged
Conversation
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.
Deploying podnotes with
|
| 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 |
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.
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))
Contributor
|
🎉 This PR is included in version 2.17.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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) andRemove(warning). A text label always renders (it istextContent, not an icon glyph), reads unambiguously, and is sized appropriately per platform (Obsidian renders larger buttons on mobile/iPad via--input-height). Thearia-labelis preserved.Root cause
ButtonComponentdid 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.aria-label.Changes
src/ui/settings/PodcastResultCard.svelte— icon-only →text="Add" cta/text="Remove" warning;aria-labelkept. 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 noaria-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 visibleAdd/Removetext label,mod-cta/mod-warning, an accessible name, and that no action renders without a visible label.vitest.setup.ts— minimalElement.prototype.animate(Web Animations API) mock sotransition:fadecomponents can render under jsdom in component tests; documented its known fidelity gaps.Verification
lint,format:check,typecheck,check:a11y(0 errors / 0 warnings),test(375 passing),build.mod-cta) backgroundrgb(138, 92, 245)and intactaria-labels ("Add … podcast","Add playlist").Notes / caveats
mod-cta/mod-warning+ visible text via theobsidiantest 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.--input-height(larger on mobile/iPad); native cta/warning sizing is correct per-platform.Possible follow-up (out of scope)
The
PlaylistItemdelete button (src/ui/settings/PlaylistItem.svelte) still uses the icon-onlysetIconglyph path that is the #109 root cause, so it could also render as an empty box on iPad. It already has anaria-label(so it is not screen-reader-invisible), and its stateful trash → confirm-check behaviour makes converting it a larger change. Left out of thisadd-scoped fix; worth a separate issue.