From 975e4b04a6d2db7b2b80b142a97be035561428c8 Mon Sep 17 00:00:00 2001 From: Takumi Mori <51111242+takumi3488@users.noreply.github.com> Date: Mon, 1 Sep 2025 00:55:13 +0900 Subject: [PATCH 1/4] fix: iOS PWA status bar overlap issue on mobile devices - Add PWA detection logic to App.jsx - Apply dynamic padding to header and sidebar in PWA mode - Update viewport meta tag for better iOS compatibility - Change status bar style to black-translucent for PWA - Add CSS variables for safe area insets with fallback support This ensures menu button and sidebar content are properly visible below the iOS status bar when installed as a PWA. --- index.html | 4 +-- src/App.jsx | 34 ++++++++++++++++++ src/components/MainContent.jsx | 22 ++++++++---- src/components/Sidebar.jsx | 14 ++++++-- src/index.css | 63 +++++++++++++++++++++++++++++++++- 5 files changed, 125 insertions(+), 12 deletions(-) diff --git a/index.html b/index.html index c42257f..8ee3437 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ - + Claude Code UI @@ -12,7 +12,7 @@ - + diff --git a/src/App.jsx b/src/App.jsx index ec0278d..6c0bdae 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -77,6 +77,35 @@ function AppContent() { const [activeSessions, setActiveSessions] = useState(new Set()); // Track sessions with active conversations const { ws, sendMessage, messages } = useWebSocketContext(); + + // Detect if running as PWA + const [isPWA, setIsPWA] = useState(false); + + useEffect(() => { + // Check if running in standalone mode (PWA) + const checkPWA = () => { + const isStandalone = window.matchMedia('(display-mode: standalone)').matches || + window.navigator.standalone || + document.referrer.includes('android-app://'); + setIsPWA(isStandalone); + + // Add class to body for CSS targeting + if (isStandalone) { + document.body.classList.add('pwa-mode'); + } else { + document.body.classList.remove('pwa-mode'); + } + }; + + checkPWA(); + + // Listen for changes + window.matchMedia('(display-mode: standalone)').addEventListener('change', checkPWA); + + return () => { + window.matchMedia('(display-mode: standalone)').removeEventListener('change', checkPWA); + }; + }, []); useEffect(() => { const checkMobile = () => { @@ -561,6 +590,8 @@ function AppContent() { latestVersion={latestVersion} currentVersion={currentVersion} onShowVersionModal={() => setShowVersionModal(true)} + isPWA={isPWA} + isMobile={isMobile} /> @@ -606,6 +637,8 @@ function AppContent() { latestVersion={latestVersion} currentVersion={currentVersion} onShowVersionModal={() => setShowVersionModal(true)} + isPWA={isPWA} + isMobile={isMobile} /> @@ -622,6 +655,7 @@ function AppContent() { sendMessage={sendMessage} messages={messages} isMobile={isMobile} + isPWA={isPWA} onMenuClick={() => setSidebarOpen(true)} isLoading={isLoadingProjects} onInputFocusChange={setIsInputFocused} diff --git a/src/components/MainContent.jsx b/src/components/MainContent.jsx index 5bbbc7a..b6bd04a 100644 --- a/src/components/MainContent.jsx +++ b/src/components/MainContent.jsx @@ -37,6 +37,7 @@ function MainContent({ sendMessage, messages, isMobile, + isPWA, onMenuClick, isLoading, onInputFocusChange, @@ -152,10 +153,13 @@ function MainContent({
{/* Header with menu button for mobile */} {isMobile && ( -
+
)}
-
- {diff && diff.split('\n').map((line, index) => renderDiffLine(line, index))} +
+ {diff && }
diff --git a/src/components/MainContent.jsx b/src/components/MainContent.jsx index 645f4b4..676a83f 100644 --- a/src/components/MainContent.jsx +++ b/src/components/MainContent.jsx @@ -155,7 +155,6 @@ function MainContent({ {isMobile && (