diff --git a/src/renderer/src/components/settings/AppearancePane.tsx b/src/renderer/src/components/settings/AppearancePane.tsx index 3c460b32694..24bb19f278a 100644 --- a/src/renderer/src/components/settings/AppearancePane.tsx +++ b/src/renderer/src/components/settings/AppearancePane.tsx @@ -147,7 +147,9 @@ export function AppearancePane({ ] const terminalSearchEntries = [ { title: terminalTitle }, - ...getTerminalAppearanceSearchEntries({ showWarpImport: !isWebClient }) + ...getTerminalAppearanceSearchEntries({ + showDesktopThemeImports: !isWebClient + }) ] const windowSearchEntries = [ { diff --git a/src/renderer/src/components/settings/TerminalAppearanceSection.ghostty.test.ts b/src/renderer/src/components/settings/TerminalAppearanceSection.ghostty.test.ts index d5f2c28f73a..b8162992118 100644 --- a/src/renderer/src/components/settings/TerminalAppearanceSection.ghostty.test.ts +++ b/src/renderer/src/components/settings/TerminalAppearanceSection.ghostty.test.ts @@ -524,8 +524,36 @@ describe('TerminalAppearanceSection ghostty import wiring', () => { expect(findTerminalThemeCatalogSection(element)?.props.showThemeImport).toBe(false) expect(findWarpThemeImportModal(element)).toBeNull() + expect(findButtons(element).some((button) => button.text === 'Import from Ghostty')).toBe(false) + expect(findGhosttyImportModal(element)).toBeNull() }) + it.each([false, true])( + 'hides Ghostty search results on web clients with forceVisiblePrimary=%s', + (forceVisiblePrimary) => { + vi.stubGlobal('window', { __ORCA_WEB_CLIENT__: true }) + mockSettingsSearchQuery = 'ghostty' + + const element = TerminalAppearanceSection({ + settings: {} as never, + updateSettings: () => {}, + systemPrefersDark: true, + terminalFontSuggestions: [], + ghostty: ghosttyMock, + warpThemes: warpThemesMock, + forceVisiblePrimary + }) + + expect(findButtons(element).some((button) => button.text === 'Import from Ghostty')).toBe( + false + ) + expect(findGhosttyImportModal(element)).toBeNull() + if (!forceVisiblePrimary) { + expect(findComponentByTypeName(element, 'SettingsSubsectionHeader')).toBeNull() + } + } + ) + it('passes hook state to GhosttyImportModal', () => { const element = TerminalAppearanceSection({ settings: {} as never, diff --git a/src/renderer/src/components/settings/TerminalAppearanceSection.tsx b/src/renderer/src/components/settings/TerminalAppearanceSection.tsx index b13f535a83a..bf482ed373b 100644 --- a/src/renderer/src/components/settings/TerminalAppearanceSection.tsx +++ b/src/renderer/src/components/settings/TerminalAppearanceSection.tsx @@ -34,7 +34,7 @@ import { GhosttyImportModal } from './GhosttyImportModal' import type { UseGhosttyImportReturn } from './useGhosttyImport' import { WarpThemeImportModal } from './WarpThemeImportModal' import type { UseWarpThemeImportReturn } from './useWarpThemeImport' -import { isWebClientLocation } from '@/hooks/useSettingsNavigationMetadata' +import { isWebClientLocation } from '@/lib/web-client-location' import ghosttyIcon from '../../../../../resources/ghostty.svg' import { translate } from '@/i18n/i18n' @@ -83,7 +83,7 @@ export function TerminalAppearanceSection({ const isSearching = normalizeSettingsSearchQuery(searchQuery).length > 0 const [themeSearch, setThemeSearch] = useState('') const [previewFontFamily, setPreviewFontFamily] = useState(null) - const showWarpThemeImport = !isWebClientLocation() + const showDesktopThemeImports = !isWebClientLocation() const darkThemeSearchEntries = getTerminalDarkThemeSearchEntries() const lightThemeSearchEntries = getTerminalLightThemeSearchEntries() const terminalTypographyEntries = getTerminalTypographySearchEntries() @@ -92,7 +92,7 @@ export function TerminalAppearanceSection({ ...getTerminalThemeTargetSearchEntries(), ...darkThemeSearchEntries, ...lightThemeSearchEntries, - ...(showWarpThemeImport + ...(showDesktopThemeImports ? [...getTerminalWarpImportSearchEntries(), ...getTerminalYamlImportSearchEntries()] : []) ] @@ -116,14 +116,16 @@ export function TerminalAppearanceSection({ searchQuery, terminalTypographyEntries.slice(0, 2) ) - const ghosttyImportMatches = matchesSettingsSearch(searchQuery, ghosttyImportEntries) + const ghosttyImportMatches = + showDesktopThemeImports && matchesSettingsSearch(searchQuery, ghosttyImportEntries) const showPrimaryTypography = !isSearching || forceVisiblePrimary || primaryTypographyMatches || typographyMatches || ghosttyImportMatches - const showGhosttyImport = !isSearching || forceVisiblePrimary || ghosttyImportMatches + const showGhosttyImport = + showDesktopThemeImports && (!isSearching || forceVisiblePrimary || ghosttyImportMatches) const showTypographyAdvancedDisclosure = !isSearching || typographyMatches const advancedGroups = [ @@ -259,36 +261,38 @@ export function TerminalAppearanceSection({ previewFontFamily={previewFontFamily} importedHighlightSignal={warpThemes.importSignal} warpThemes={warpThemes} - showThemeImport={showWarpThemeImport} + showThemeImport={showDesktopThemeImports} preferredTarget={preferredThemeTarget} advancedContent={previewAdvancedContent} /> ) : null} - - {showWarpThemeImport ? ( - + {showDesktopThemeImports ? ( + <> + + + ) : null} ) diff --git a/src/renderer/src/components/settings/appearance-search.ts b/src/renderer/src/components/settings/appearance-search.ts index 726ecaa1b01..09685358145 100644 --- a/src/renderer/src/components/settings/appearance-search.ts +++ b/src/renderer/src/components/settings/appearance-search.ts @@ -223,13 +223,13 @@ const getAppearanceSectionEntries = createLocalizedCatalog((): SettingsSearchEnt ]) type AppearancePaneSearchOptions = { - showWarpImport?: boolean + showDesktopThemeImports?: boolean showSystemTray?: boolean showMenuBarIcon?: boolean } -function buildAppearancePaneSearchEntries( - options: AppearancePaneSearchOptions +export function getAppearancePaneSearchEntries( + options: AppearancePaneSearchOptions = {} ): SettingsSearchEntry[] { return [ ...getAppearanceSectionEntries(), @@ -247,13 +247,3 @@ function buildAppearancePaneSearchEntries( ...getMenuBarIconEntries(options) ] } - -export function getAppearancePaneSearchEntries( - options: AppearancePaneSearchOptions = {} -): SettingsSearchEntry[] { - return buildAppearancePaneSearchEntries({ - showWarpImport: options.showWarpImport ?? true, - showSystemTray: options.showSystemTray, - showMenuBarIcon: options.showMenuBarIcon - }) -} diff --git a/src/renderer/src/components/settings/terminal-search.test.ts b/src/renderer/src/components/settings/terminal-search.test.ts index b9d1ac76969..f86bcfa3f2c 100644 --- a/src/renderer/src/components/settings/terminal-search.test.ts +++ b/src/renderer/src/components/settings/terminal-search.test.ts @@ -156,14 +156,17 @@ describe('getTerminalPaneSearchEntries', () => { expect(matchesSettingsSearch(query, getAppearancePaneSearchEntries())).toBe(true) }) - it('omits the Warp import appearance entry when desktop-only controls are hidden', () => { - const desktopEntries = getAppearancePaneSearchEntries({ showWarpImport: true }) - const webEntries = getAppearancePaneSearchEntries({ showWarpImport: false }) + it.each(['ghostty', 'warp', 'yaml'])( + 'omits desktop-only %s search results on web clients', + (query) => { + const desktopEntries = getAppearancePaneSearchEntries() + const webEntries = getAppearancePaneSearchEntries({ showDesktopThemeImports: false }) - expect(desktopEntries.some((entry) => entry.title === 'Import from Warp')).toBe(true) - expect(webEntries.some((entry) => entry.title === 'Import from Warp')).toBe(false) - expect(webEntries.some((entry) => entry.title === 'Import from Ghostty')).toBe(true) - }) + expect(matchesSettingsSearch(query, desktopEntries)).toBe(true) + expect(matchesSettingsSearch(query, webEntries)).toBe(false) + expect(matchesSettingsSearch('font size', webEntries)).toBe(true) + } + ) it('includes the system tray appearance entry only when desktop tray controls are shown', () => { const desktopEntries = getAppearancePaneSearchEntries({ showSystemTray: true }) diff --git a/src/renderer/src/components/settings/terminal-search.ts b/src/renderer/src/components/settings/terminal-search.ts index 2a460bd64a1..39a66d65e51 100644 --- a/src/renderer/src/components/settings/terminal-search.ts +++ b/src/renderer/src/components/settings/terminal-search.ts @@ -63,10 +63,10 @@ export { } from './terminal-window-setup-search' type TerminalAppearanceSearchOptions = { - showWarpImport?: boolean + showDesktopThemeImports?: boolean } -const getTerminalAppearanceSearchEntriesWithoutWarp = createLocalizedCatalog( +const getTerminalAppearanceSearchEntriesWithoutImports = createLocalizedCatalog( (): SettingsSearchEntry[] => [ ...getTerminalTypographySearchEntries(), ...getTerminalCursorSearchEntries(), @@ -74,16 +74,15 @@ const getTerminalAppearanceSearchEntriesWithoutWarp = createLocalizedCatalog( ...getTerminalThemeTargetSearchEntries(), ...getTerminalDarkThemeSearchEntries(), ...getTerminalLightThemeSearchEntries(), - ...getTerminalWindowSearchEntries(), - ...getTerminalGhosttyImportSearchEntries() + ...getTerminalWindowSearchEntries() ] ) -// Why: compose rather than filter — entry titles are localized, so matching on -// an English title would leak the Warp entry back in under non-English locales. -const getTerminalAppearanceSearchEntriesWithWarp = createLocalizedCatalog( +// Compose catalogs because translated titles cannot reliably identify desktop-only entries. +const getTerminalAppearanceSearchEntriesWithImports = createLocalizedCatalog( (): SettingsSearchEntry[] => [ - ...getTerminalAppearanceSearchEntriesWithoutWarp(), + ...getTerminalAppearanceSearchEntriesWithoutImports(), + ...getTerminalGhosttyImportSearchEntries(), ...getTerminalWarpImportSearchEntries(), ...getTerminalYamlImportSearchEntries() ] @@ -92,9 +91,9 @@ const getTerminalAppearanceSearchEntriesWithWarp = createLocalizedCatalog( export function getTerminalAppearanceSearchEntries( options: TerminalAppearanceSearchOptions = {} ): SettingsSearchEntry[] { - return (options.showWarpImport ?? true) - ? getTerminalAppearanceSearchEntriesWithWarp() - : getTerminalAppearanceSearchEntriesWithoutWarp() + return (options.showDesktopThemeImports ?? true) + ? getTerminalAppearanceSearchEntriesWithImports() + : getTerminalAppearanceSearchEntriesWithoutImports() } export function getTerminalPaneSearchEntries(platform: { diff --git a/src/renderer/src/hooks/settings-navigation-interface-sections.ts b/src/renderer/src/hooks/settings-navigation-interface-sections.ts index 0208dd1f526..35d51532315 100644 --- a/src/renderer/src/hooks/settings-navigation-interface-sections.ts +++ b/src/renderer/src/hooks/settings-navigation-interface-sections.ts @@ -26,7 +26,7 @@ export function buildInterfaceSettingsSections({ ), icon: Palette, searchEntries: getAppearancePaneSearchEntries({ - showWarpImport: showDesktopOnlySettings, + showDesktopThemeImports: showDesktopOnlySettings, showSystemTray: showDesktopOnlySettings && isWindows, showMenuBarIcon: showDesktopOnlySettings && isMac }),