mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 00:02:31 +00:00
Hide desktop theme imports from paired web clients (#20015)
* Hide Ghostty import from paired web clients - Ghostty import now respects showDesktopOnlySettings, matching Warp behavior - Consolidates desktop-only theme imports under a single showDesktopThemeImports flag - Adds showGhosttyImport option to control visibility across settings UI and search * Hide desktop theme imports from web clients Consolidate Warp and Ghostty import visibility behind a single `showDesktopThemeImports` flag. These theme import flows are desktop-only and should not appear on paired web clients. --------- Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local> Co-authored-by: m4air <m4air@Mac.localdomain>
This commit is contained in:
@@ -147,7 +147,9 @@ export function AppearancePane({
|
||||
]
|
||||
const terminalSearchEntries = [
|
||||
{ title: terminalTitle },
|
||||
...getTerminalAppearanceSearchEntries({ showWarpImport: !isWebClient })
|
||||
...getTerminalAppearanceSearchEntries({
|
||||
showDesktopThemeImports: !isWebClient
|
||||
})
|
||||
]
|
||||
const windowSearchEntries = [
|
||||
{
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<string | null>(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}
|
||||
|
||||
<GhosttyImportModal
|
||||
open={ghostty.open}
|
||||
onOpenChange={ghostty.handleOpenChange}
|
||||
preview={ghostty.preview}
|
||||
loading={ghostty.loading}
|
||||
onApply={ghostty.handleApply}
|
||||
applied={ghostty.applied}
|
||||
applyError={ghostty.applyError}
|
||||
/>
|
||||
{showWarpThemeImport ? (
|
||||
<WarpThemeImportModal
|
||||
open={warpThemes.open}
|
||||
mode={warpThemes.mode}
|
||||
preview={warpThemes.preview}
|
||||
loading={warpThemes.loading}
|
||||
desktopOnly={warpThemes.desktopOnly}
|
||||
applyError={warpThemes.applyError}
|
||||
selectedThemeIds={warpThemes.selectedThemeIds}
|
||||
handlePreviewSource={warpThemes.handlePreviewSource}
|
||||
handleToggleTheme={warpThemes.handleToggleTheme}
|
||||
handleToggleAll={warpThemes.handleToggleAll}
|
||||
handleApply={warpThemes.handleApply}
|
||||
handleOpenChange={warpThemes.handleOpenChange}
|
||||
/>
|
||||
{showDesktopThemeImports ? (
|
||||
<>
|
||||
<GhosttyImportModal
|
||||
open={ghostty.open}
|
||||
onOpenChange={ghostty.handleOpenChange}
|
||||
preview={ghostty.preview}
|
||||
loading={ghostty.loading}
|
||||
onApply={ghostty.handleApply}
|
||||
applied={ghostty.applied}
|
||||
applyError={ghostty.applyError}
|
||||
/>
|
||||
<WarpThemeImportModal
|
||||
open={warpThemes.open}
|
||||
mode={warpThemes.mode}
|
||||
preview={warpThemes.preview}
|
||||
loading={warpThemes.loading}
|
||||
desktopOnly={warpThemes.desktopOnly}
|
||||
applyError={warpThemes.applyError}
|
||||
selectedThemeIds={warpThemes.selectedThemeIds}
|
||||
handlePreviewSource={warpThemes.handlePreviewSource}
|
||||
handleToggleTheme={warpThemes.handleToggleTheme}
|
||||
handleToggleAll={warpThemes.handleToggleAll}
|
||||
handleApply={warpThemes.handleApply}
|
||||
handleOpenChange={warpThemes.handleOpenChange}
|
||||
/>
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -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
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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 })
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -26,7 +26,7 @@ export function buildInterfaceSettingsSections({
|
||||
),
|
||||
icon: Palette,
|
||||
searchEntries: getAppearancePaneSearchEntries({
|
||||
showWarpImport: showDesktopOnlySettings,
|
||||
showDesktopThemeImports: showDesktopOnlySettings,
|
||||
showSystemTray: showDesktopOnlySettings && isWindows,
|
||||
showMenuBarIcon: showDesktopOnlySettings && isMac
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user