The content type segmented picker rendered as a Liquid-Glass pill instead
of a native macOS segmented control. Wrapping a `.segmented` Picker in
`.opacity`/`.disabled`/`.accessibilityHidden`/`.fixedSize` (used to keep
toolbar items mounted-but-invisible for stable layout) inserts a hosting
layer that makes the toolbar fall back to the pill rendering.
- SearchView: filters button and content type picker are now always
visible on macOS, rendered bare so `.segmented` keeps native styling.
- SearchView: don't reset the content type to .video on submit on macOS,
so a pre-selected type (e.g. Playlists) is preserved (iOS unchanged).
- InstanceBrowseView: same pill fix, rendering the tab / content type
pickers bare via conditional `if` instead of opacity-masking.
- ViewOptionsSheet / MediaBrowserViewOptionsSheet: use `.formStyle(.grouped)`
for native macOS form styling in the options popover.
Place the view options control on the leading (`.navigation`) edge on
macOS so it is consistently the first/leftmost toolbar button across all
views, instead of sitting on the right next to the search field in
search views and on the left in non-search views.
Each affected view gains a computed `viewOptionsPlacement` (`.navigation`
on macOS, `.primaryAction` elsewhere) so iOS/iPadOS/tvOS keep the
button trailing. Search-style views (Search, InstanceBrowse) declare the
view options item first so it renders left of the search-filters button;
their flexible spacer is kept to right-pin the search field. Channel's
fixed spacer between view options and the channel menu is now iOS-only.
Tapping a recent search (or suggestion, or opening a query deep link) mutates
the searchable text, which fires the onChange handler that clears results and
re-fetches suggestions. That raced against the search Task started by the same
tap: on Sequoia the onChange settled last, cancelling the in-flight search and
leaving suggestions visible instead of results.
Suppress the onChange-driven suggestion fetch for the single programmatic text
mutation via a one-shot flag, so the execute paths go straight to results
regardless of onChange-vs-Task ordering. Manual typing is unaffected.
Plain-Form sheets rendered as columns-style content floating inside
oversized fixed frames on macOS. Anchor these panels to their toolbar
buttons as popovers instead, sized to content; iOS/tvOS keep sheets.
- Search and PeerTube explore filters apply live (Cancel never
reverted anything anyway) and dismiss on outside click
- Subscriptions/Manage Channels "Subscriptions Data" opens as a sheet
from the popover's onDisappear via a pending flag, since presenting
while the popover dismisses gets swallowed
- Media browser view options drop navigation chrome on macOS
Relocate the funnel filter button and the content-type picker
(All/Videos/Playlists/Channels) from the inline results strip into the
window toolbar on macOS. The inline strip remains iOS-only.
Like on iOS, the controls appear only after a search is submitted
(gated on hasSearched). To keep the toolbar stable:
- Items stay in the toolbar permanently but are invisible and inert
before a search, so the search field keeps a constant size; their
liquid-glass backgrounds are suppressed with
sharedBackgroundVisibility(.hidden) (macOS 26, with a conditional
fallback on macOS 15).
- A flexible ToolbarSpacer pins the view-options button and search
field to the trailing edge so they no longer shift when items
appear.
The filters type onChange handler moved from the strip to the shared
iOS/macOS branch so both the strip and the toolbar picker reuse it.
These views rendered video thumbnails without passing watchProgress, so the
progress bar was silently missing. Apply the existing pattern from
SubscriptionsView: maintain a watchEntriesMap and forward watchProgress(for:)
to VideoRowView/VideoCardView at each call site.
Add macOS-only minimum frame sizing to sheets that wrap a
NavigationStack/Form without intrinsic size, so they render properly
instead of collapsing to just the toolbar. Affects Customize Home,
subscription/channel view options, playlist create/edit, search
filters, media browser options, instance picker, log filters, preset
editor, and legacy data import result.
- Disable scroll clipping so focused source/channel/playlist cards show full halo
- Remove rounded clip on source picker row that cut the Menu focus effect
- Replace tappable recents header Button with a plain label on tvOS
- Add vertical spacing between recent search items
- Widen recent channel and playlist cards and reserve space for two-line titles
- Increase horizontal spacing between cards so focus halos don't collide
Match iOS behavior by gating the type switcher and filters menus on an
active query, and drop the .caption font so they render with the same
default button font as View Options.
The backgroundStyle.ignoresSafeArea().overlay(ScrollView) pattern
clips the tvOS focus effect at the overlay boundary. On tvOS, render
the ScrollView directly so focus highlights can extend naturally.
Reorganize the tvOS search UI into a single header row with search
field, type filter menu, combined filters menu (sort/date/duration
with reset), and view options button. Removes the separate filter
strip between search and results on tvOS.
Unifies the filter strip on tvOS so all filters (sort, date, duration,
content type) use the same inline Menu style instead of mixing menus
with a segmented picker.
The filters sheet is too small and awkward on tvOS. Replace the filter
button with inline Menu pickers for Sort By, Upload Date, and Duration
directly in the filter strip. Applied to both SearchView and
InstanceBrowseView.
Use inline TextField with focusSection instead of .searchable() on tvOS
to prevent keyboard/navigation title overlap. Remove clipShape on recent
search items so tvOS focus effect is not cut off.
- Fix BGTaskScheduler assertion crash on Mac Catalyst by guarding all
iOS background task APIs with isMacCatalystApp check
- Fix iPad popover crash in UIPopoverPresentationController by adding
.presentationCompactAdaptation(.sheet) to all 27 confirmationDialogs
- Fix SwiftData assertion crash when accessing deleted Bookmark model
properties during SwiftUI hit testing in BookmarkRowView
- Fix UICollectionView invalid item count crash on queue swipe-to-delete
by using ID-based removal with withAnimation instead of stale index
- Fix Range crash in storyboard download when storyboardCount is zero
On tvOS, ContentUnavailableView inside a Group doesn't expand to fill
available space — it sizes to content and aligns top-leading. Add
.frame(maxWidth: .infinity, maxHeight: .infinity) to all instances
so they center correctly in their parent containers.