From a52c436d6a2de444a7aaf3288aff95113dfd5acf Mon Sep 17 00:00:00 2001 From: Calibrain Date: Mon, 24 Aug 2026 05:56:04 +0000 Subject: [PATCH] fix(search): let manual search switch media type under forced combined search MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Manual search browses release sources directly, one media type at a time, so the combined (both) flow never applied to it — yet FORCE_COMBINED_SEARCH locked the content-type selector onto both, pinning manual search to ebook sources with no way to reach audiobook sources (no Audiobay tab). Treat a manual search target as combined-exempt in the search bar: present a plain, switchable Books/Audiobooks selector (unlocked, no combined toggle), even when combined search is forced on for metadata targets. Metadata search behavior is unchanged. Fixes #1256 --- src/frontend/src/components/SearchBar.tsx | 38 +++++++++++++++-------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/frontend/src/components/SearchBar.tsx b/src/frontend/src/components/SearchBar.tsx index bfd74ed..4b960fa 100644 --- a/src/frontend/src/components/SearchBar.tsx +++ b/src/frontend/src/components/SearchBar.tsx @@ -223,6 +223,14 @@ export const SearchBar = forwardRef( ); const showActiveTargetLabel = queryTargets.length > 0 && activeTarget.source !== 'general'; + // Manual search browses release sources directly, one media type at a time — the + // combined ("both") flow doesn't apply. Present a plain, switchable Books/Audiobooks + // choice for it, even when combined search is forced on for metadata targets. + const isManualTarget = activeTarget?.source === 'manual'; + const combinedSelectionActive = combinedMode && !isManualTarget; + const combinedSelectorLocked = combinedModeLocked && !isManualTarget; + const combinedToggleAvailable = !!onCombinedModeChange && !isManualTarget; + useDismiss(isSelectorOpen, [selectorRef], () => setIsSelectorOpen(false)); useDismiss(isSelectOpen, [selectPanelRef, selectTriggerRef], () => setIsSelectOpen(false)); useDismiss(isAutocompleteOpen, [autocompletePanelRef, inputRef], () => @@ -356,7 +364,7 @@ export const SearchBar = forwardRef( contentType, activeTarget, placeholder, - combinedMode, + combinedSelectionActive, ); const effectiveInputAriaLabel = activeTarget ? `${inputAriaLabel}: ${activeTarget.label}` @@ -537,7 +545,7 @@ export const SearchBar = forwardRef( let selectorContentTypeLabel = 'audiobooks'; let selectorIcon = ; - if (combinedMode) { + if (combinedSelectionActive) { selectorContentTypeLabel = 'books and audiobooks'; selectorIcon = ; } else if (contentType === 'ebook') { @@ -665,7 +673,7 @@ export const SearchBar = forwardRef(
{showContentTypeSelector && (
@@ -712,34 +720,38 @@ export const SearchBar = forwardRef( type="button" onClick={() => handleContentTypeSelect('ebook')} className={`flex items-center gap-2 rounded-xl border px-3 py-2 text-sm font-medium transition-colors ${ - contentType === 'ebook' || combinedMode + contentType === 'ebook' || combinedSelectionActive ? 'bg-emerald-600 text-white' : 'hover-surface' }`} style={ - contentType === 'ebook' || combinedMode + contentType === 'ebook' || combinedSelectionActive ? { borderColor: 'rgb(16 185 129 / 0.7)' } : { color: 'var(--text)', borderColor: 'var(--border-muted)' } } > - {contentType === 'ebook' || combinedMode ? : } + {contentType === 'ebook' || combinedSelectionActive ? ( + + ) : ( + + )} Books
- {onCombinedModeChange && + {combinedToggleAvailable && (() => { - const lineColor = combinedMode + const lineColor = combinedSelectionActive ? 'bg-emerald-500' : 'bg-(--border-muted) group-hover:bg-zinc-400 dark:group-hover:bg-zinc-500'; return ( @@ -787,7 +799,7 @@ export const SearchBar = forwardRef( {/* Chain icon centered at bottom */}
( stroke="currentColor" aria-hidden="true" > - {combinedModeLocked ? ( + {combinedSelectorLocked ? (