fix(ui): align sidebar hamburger in macOS fullscreen (#9257)
Signed-off-by: Cole McIntosh <colemcintosh6@gmail.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
|
import { IpcRendererEvent } from 'electron';
|
||||||
import { Outlet, useLocation } from 'react-router-dom';
|
import { Outlet, useLocation } from 'react-router-dom';
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
import { Menu } from 'lucide-react';
|
import { Menu } from 'lucide-react';
|
||||||
@@ -37,6 +38,21 @@ const AppLayoutContent: React.FC<AppLayoutContentProps> = ({ activeSessions }) =
|
|||||||
const chatContext = useChatContext();
|
const chatContext = useChatContext();
|
||||||
const isOnPairRoute = location.pathname === '/pair';
|
const isOnPairRoute = location.pathname === '/pair';
|
||||||
|
|
||||||
|
const [isFullScreen, setIsFullScreen] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!safeIsMacOS) return;
|
||||||
|
window.electron
|
||||||
|
.getIsFullScreen()
|
||||||
|
.then(setIsFullScreen)
|
||||||
|
.catch(() => {});
|
||||||
|
const handler = (_event: IpcRendererEvent, ...args: unknown[]) => {
|
||||||
|
setIsFullScreen(Boolean(args[0]));
|
||||||
|
};
|
||||||
|
window.electron.on('fullscreen-change', handler);
|
||||||
|
return () => window.electron.off('fullscreen-change', handler);
|
||||||
|
}, [safeIsMacOS]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isNavExpanded,
|
isNavExpanded,
|
||||||
setIsNavExpanded,
|
setIsNavExpanded,
|
||||||
@@ -146,8 +162,9 @@ const AppLayoutContent: React.FC<AppLayoutContentProps> = ({ activeSessions }) =
|
|||||||
};
|
};
|
||||||
}, [isPushTopNav]);
|
}, [isPushTopNav]);
|
||||||
|
|
||||||
const headerPadding = safeIsMacOS ? 'pl-[96px]' : 'pl-4';
|
const needsTrafficLightInset = safeIsMacOS && !isFullScreen;
|
||||||
const headerTop = safeIsMacOS ? 'top-[15px]' : 'top-[11px]';
|
const headerPadding = needsTrafficLightInset ? 'pl-[96px]' : 'pl-4';
|
||||||
|
const headerTop = needsTrafficLightInset ? 'top-[15px]' : 'top-[11px]';
|
||||||
|
|
||||||
// Determine flex direction based on navigation position (for push mode)
|
// Determine flex direction based on navigation position (for push mode)
|
||||||
const getLayoutClass = () => {
|
const getLayoutClass = () => {
|
||||||
|
|||||||
@@ -1118,6 +1118,14 @@ const createChat = async (app: App, options: CreateChatOptions = {}) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const broadcastFullScreenState = () => {
|
||||||
|
if (!mainWindow.isDestroyed()) {
|
||||||
|
mainWindow.webContents.send('fullscreen-change', mainWindow.isFullScreen());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
mainWindow.on('enter-full-screen', broadcastFullScreenState);
|
||||||
|
mainWindow.on('leave-full-screen', broadcastFullScreenState);
|
||||||
|
|
||||||
// Handle mouse back button (button 3)
|
// Handle mouse back button (button 3)
|
||||||
// Use type assertion for non-standard Electron event
|
// Use type assertion for non-standard Electron event
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
@@ -1792,6 +1800,11 @@ ipcMain.handle('is-any-window-focused', () => {
|
|||||||
return BrowserWindow.getFocusedWindow() !== null;
|
return BrowserWindow.getFocusedWindow() !== null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcMain.handle('get-is-fullscreen', (event) => {
|
||||||
|
const win = BrowserWindow.fromWebContents(event.sender);
|
||||||
|
return win?.isFullScreen() ?? false;
|
||||||
|
});
|
||||||
|
|
||||||
// Add file/directory selection handler
|
// Add file/directory selection handler
|
||||||
ipcMain.handle('select-file-or-directory', async (_event, defaultPath?: string) => {
|
ipcMain.handle('select-file-or-directory', async (_event, defaultPath?: string) => {
|
||||||
const dialogOptions: OpenDialogOptions = {
|
const dialogOptions: OpenDialogOptions = {
|
||||||
|
|||||||
@@ -149,6 +149,7 @@ type ElectronAPI = {
|
|||||||
getSpellcheckState: () => Promise<boolean>;
|
getSpellcheckState: () => Promise<boolean>;
|
||||||
openNotificationsSettings: () => Promise<boolean>;
|
openNotificationsSettings: () => Promise<boolean>;
|
||||||
isAnyWindowFocused: () => Promise<boolean>;
|
isAnyWindowFocused: () => Promise<boolean>;
|
||||||
|
getIsFullScreen: () => Promise<boolean>;
|
||||||
onMouseBackButtonClicked: (callback: () => void) => void;
|
onMouseBackButtonClicked: (callback: () => void) => void;
|
||||||
offMouseBackButtonClicked: (callback: () => void) => void;
|
offMouseBackButtonClicked: (callback: () => void) => void;
|
||||||
on: (
|
on: (
|
||||||
@@ -273,6 +274,7 @@ const electronAPI: ElectronAPI = {
|
|||||||
getSpellcheckState: () => ipcRenderer.invoke('get-spellcheck-state'),
|
getSpellcheckState: () => ipcRenderer.invoke('get-spellcheck-state'),
|
||||||
openNotificationsSettings: () => ipcRenderer.invoke('open-notifications-settings'),
|
openNotificationsSettings: () => ipcRenderer.invoke('open-notifications-settings'),
|
||||||
isAnyWindowFocused: () => ipcRenderer.invoke('is-any-window-focused'),
|
isAnyWindowFocused: () => ipcRenderer.invoke('is-any-window-focused'),
|
||||||
|
getIsFullScreen: () => ipcRenderer.invoke('get-is-fullscreen'),
|
||||||
onMouseBackButtonClicked: (callback: () => void) => {
|
onMouseBackButtonClicked: (callback: () => void) => {
|
||||||
// Wrapper that ignores the event parameter.
|
// Wrapper that ignores the event parameter.
|
||||||
const wrappedCallback = (_event: Electron.IpcRendererEvent) => callback();
|
const wrappedCallback = (_event: Electron.IpcRendererEvent) => callback();
|
||||||
|
|||||||
@@ -87,5 +87,8 @@ Object.defineProperty(window, 'electron', {
|
|||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}),
|
}),
|
||||||
showMessageBox: vi.fn(() => Promise.resolve({ response: 0 })),
|
showMessageBox: vi.fn(() => Promise.resolve({ response: 0 })),
|
||||||
|
getIsFullScreen: vi.fn(() => Promise.resolve(false)),
|
||||||
|
on: vi.fn(),
|
||||||
|
off: vi.fn(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user