feat(ui): integrate Electron mode detection for conditional UI rendering
- Added `isElectronMode` function to determine if the app is running in Electron or a browser. - Updated `SidebarHeader`, `TabBar`, and `TabbedLayout` components to conditionally render UI elements based on the Electron mode. - Adjusted styles and settings gear icon visibility to enhance user experience in browser mode. This commit improves the application's adaptability by ensuring that Electron-specific features are only available when appropriate.
This commit is contained in:
parent
7fa2f96ed4
commit
656c9b155f
4 changed files with 32 additions and 18 deletions
|
|
@ -39,6 +39,12 @@ function getImpl(): ElectronAPI {
|
|||
* In browser: delegates to `HttpAPIClient` (created on first use).
|
||||
* In tests: delegates to whatever mock is installed on `window.electronAPI`.
|
||||
*/
|
||||
/**
|
||||
* Whether the app is running inside Electron (true) or in a browser via HTTP server (false).
|
||||
* Use this to hide Electron-only UI (settings, traffic lights, etc.) in browser mode.
|
||||
*/
|
||||
export const isElectronMode = (): boolean => !!window.electronAPI;
|
||||
|
||||
export const api: ElectronAPI = new Proxy({} as ElectronAPI, {
|
||||
get(_target, prop, receiver) {
|
||||
const impl = getImpl();
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
|
||||
import { isElectronMode } from '@renderer/api';
|
||||
import { HEADER_ROW1_HEIGHT, HEADER_ROW2_HEIGHT } from '@renderer/constants/layout';
|
||||
import { useStore } from '@renderer/store';
|
||||
import { truncateMiddle } from '@renderer/utils/stringUtils';
|
||||
|
|
@ -330,8 +331,10 @@ export const SidebarHeader = (): React.JSX.Element => {
|
|||
style={
|
||||
{
|
||||
height: `${HEADER_ROW1_HEIGHT}px`,
|
||||
paddingLeft: 'var(--macos-traffic-light-padding-left, 72px)',
|
||||
WebkitAppRegion: 'drag',
|
||||
paddingLeft: isElectronMode()
|
||||
? 'var(--macos-traffic-light-padding-left, 72px)'
|
||||
: '16px',
|
||||
WebkitAppRegion: isElectronMode() ? 'drag' : undefined,
|
||||
} as React.CSSProperties
|
||||
}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|||
|
||||
import { useDroppable } from '@dnd-kit/core';
|
||||
import { horizontalListSortingStrategy, SortableContext } from '@dnd-kit/sortable';
|
||||
import { isElectronMode } from '@renderer/api';
|
||||
import { HEADER_ROW1_HEIGHT } from '@renderer/constants/layout';
|
||||
import { useStore } from '@renderer/store';
|
||||
import { Bell, PanelLeft, Plus, RefreshCw, Search, Settings } from 'lucide-react';
|
||||
|
|
@ -250,7 +251,8 @@ export const TabBar = ({ paneId }: TabBarProps): React.JSX.Element => {
|
|||
sidebarCollapsed && isLeftmostPane
|
||||
? 'var(--macos-traffic-light-padding-left, 72px)'
|
||||
: '8px',
|
||||
WebkitAppRegion: sidebarCollapsed && isLeftmostPane ? 'drag' : undefined,
|
||||
WebkitAppRegion:
|
||||
isElectronMode() && sidebarCollapsed && isLeftmostPane ? 'drag' : undefined,
|
||||
backgroundColor: 'var(--color-surface)',
|
||||
borderBottom: '1px solid var(--color-border)',
|
||||
opacity: isFocused || paneCount === 1 ? 1 : 0.7,
|
||||
|
|
@ -382,20 +384,22 @@ export const TabBar = ({ paneId }: TabBarProps): React.JSX.Element => {
|
|||
)}
|
||||
</button>
|
||||
|
||||
{/* Settings gear icon */}
|
||||
<button
|
||||
onClick={openSettingsTab}
|
||||
onMouseEnter={() => setSettingsHover(true)}
|
||||
onMouseLeave={() => setSettingsHover(false)}
|
||||
className="rounded-md p-2 transition-colors"
|
||||
style={{
|
||||
color: settingsHover ? 'var(--color-text)' : 'var(--color-text-muted)',
|
||||
backgroundColor: settingsHover ? 'var(--color-surface-raised)' : 'transparent',
|
||||
}}
|
||||
title="Settings"
|
||||
>
|
||||
<Settings className="size-4" />
|
||||
</button>
|
||||
{/* Settings gear icon (Electron only - browser can't access native settings) */}
|
||||
{isElectronMode() && (
|
||||
<button
|
||||
onClick={openSettingsTab}
|
||||
onMouseEnter={() => setSettingsHover(true)}
|
||||
onMouseLeave={() => setSettingsHover(false)}
|
||||
className="rounded-md p-2 transition-colors"
|
||||
style={{
|
||||
color: settingsHover ? 'var(--color-text)' : 'var(--color-text-muted)',
|
||||
backgroundColor: settingsHover ? 'var(--color-surface-raised)' : 'transparent',
|
||||
}}
|
||||
title="Settings"
|
||||
>
|
||||
<Settings className="size-4" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Context menu */}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
* - Main content: PaneContainer with one or more panes, each with TabBar + content
|
||||
*/
|
||||
|
||||
import { isElectronMode } from '@renderer/api';
|
||||
import { getTrafficLightPaddingForZoom } from '@renderer/constants/layout';
|
||||
import { useKeyboardShortcuts } from '@renderer/hooks/useKeyboardShortcuts';
|
||||
import { useZoomFactor } from '@renderer/hooks/useZoomFactor';
|
||||
|
|
@ -64,7 +65,7 @@ export const TabbedLayout = (): React.JSX.Element => {
|
|||
// Enable keyboard shortcuts
|
||||
useKeyboardShortcuts();
|
||||
const zoomFactor = useZoomFactor();
|
||||
const trafficLightPadding = getTrafficLightPaddingForZoom(zoomFactor);
|
||||
const trafficLightPadding = isElectronMode() ? getTrafficLightPaddingForZoom(zoomFactor) : 0;
|
||||
|
||||
return (
|
||||
<div
|
||||
|
|
|
|||
Loading…
Reference in a new issue