feat: iPad split layout for the Capacitor app (#2104)
* fix: open mobile model/agent panels on tablet-width Capacitor shells and keep composer taps from dismissing the keyboard * feat: add iPadOS-style split layout to the Capacitor app - classify the Capacitor shell as mobile in device detection so shared surfaces (draft starters, panels) stop falling into tablet branches - add isIPadApp() and useOrientation() helpers - iPad: persistent full-height sessions sidebar (mobile sessions surface inline), Changes/Files in a right sidebar with header shortcut toggles - animate sidebar open/close like the desktop sidebars and add finger-sized drag-resize with persisted widths - anchor the overflow menu and the usage/metadata popover next to their header buttons regardless of open sidebars * fix: re-anchor metadata popover on layout shifts and untangle sidebar toggle updates - recompute the iPad metadata popover anchor via a ResizeObserver on its wrapper so sidebar toggles/resizes while it is open cannot leave it misplaced - move the portrait right-panel close out of the setIpadSidebarOpen updater into plain sequential state updates
This commit is contained in:
committed by
GitHub
parent
3d32ac7989
commit
ac93a52e21
@@ -556,6 +556,16 @@ const ComposerAttachmentControls = React.memo(function ComposerAttachmentControl
|
||||
type="button"
|
||||
className={footerIconButtonClass}
|
||||
onClick={props.onOpenMobileSheet}
|
||||
// Same guard as PermissionAutoAcceptButton: keep the tap
|
||||
// from dismissing the keyboard. On Android's
|
||||
// resizes-content viewport the keyboard-close relayout
|
||||
// moves this button mid-tap and the click never lands.
|
||||
onMouseDown={(event) => event.preventDefault()}
|
||||
onPointerDownCapture={(event) => {
|
||||
if (event.pointerType === 'touch') {
|
||||
event.preventDefault();
|
||||
}
|
||||
}}
|
||||
title={t('chat.chatInput.actions.addAttachment')}
|
||||
aria-label={t('chat.chatInput.actions.addAttachment')}
|
||||
>
|
||||
@@ -4087,7 +4097,12 @@ const ChatInputComponent: React.FC<ChatInputProps> = ({ onOpenSettings, scrollTo
|
||||
}, [newSessionDraftOpen, openNewSessionDraft, currentDirectory]);
|
||||
|
||||
const openMobileAttachSheet = React.useCallback(() => {
|
||||
// Same order as handleOpenMobilePanel: mark the sheet open BEFORE the
|
||||
// blur so the collapse watcher sees an overlay when the keyboard-close
|
||||
// lands. The trigger button blocks the tap's own focus transfer, so
|
||||
// the keyboard must be dismissed explicitly here.
|
||||
setMobileAttachMenuOpen(true);
|
||||
textareaRef.current?.blur();
|
||||
}, []);
|
||||
|
||||
const mobileComposerExpandedRef = React.useRef(mobileComposerExpanded);
|
||||
|
||||
Reference in New Issue
Block a user