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.
This commit is contained in:
Takumi Mori
2025-09-01 00:55:13 +09:00
parent e5709d71e0
commit 975e4b04a6
5 changed files with 125 additions and 12 deletions

View File

@@ -37,6 +37,7 @@ function MainContent({
sendMessage,
messages,
isMobile,
isPWA,
onMenuClick,
isLoading,
onInputFocusChange,
@@ -152,10 +153,13 @@ function MainContent({
<div className="h-full flex flex-col">
{/* Header with menu button for mobile */}
{isMobile && (
<div className="bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 p-3 sm:p-4 flex-shrink-0">
<div
className="bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 p-3 sm:p-4 pwa-header-safe flex-shrink-0"
style={isPWA && isMobile ? { paddingTop: '56px' } : {}}
>
<button
onClick={onMenuClick}
className="p-1.5 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white rounded-md hover:bg-gray-100 dark:hover:bg-gray-700"
className="p-1.5 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white rounded-md hover:bg-gray-100 dark:hover:bg-gray-700 pwa-menu-button"
>
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" />
@@ -188,10 +192,13 @@ function MainContent({
<div className="h-full flex flex-col">
{/* Header with menu button for mobile */}
{isMobile && (
<div className="bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 p-3 sm:p-4 flex-shrink-0">
<div
className="bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 p-3 sm:p-4 pwa-header-safe flex-shrink-0"
style={isPWA && isMobile ? { paddingTop: '56px' } : {}}
>
<button
onClick={onMenuClick}
className="p-1.5 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white rounded-md hover:bg-gray-100 dark:hover:bg-gray-700"
className="p-1.5 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white rounded-md hover:bg-gray-100 dark:hover:bg-gray-700 pwa-menu-button"
>
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" />
@@ -224,7 +231,10 @@ function MainContent({
return (
<div className="h-full flex flex-col">
{/* Header with tabs */}
<div className="bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 p-3 sm:p-4 flex-shrink-0">
<div
className="bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 p-3 sm:p-4 pwa-header-safe flex-shrink-0"
style={isPWA && isMobile ? { paddingTop: '56px' } : {}}
>
<div className="flex items-center justify-between">
<div className="flex items-center space-x-2 sm:space-x-3">
{isMobile && (
@@ -234,7 +244,7 @@ function MainContent({
e.preventDefault();
onMenuClick();
}}
className="p-2.5 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white rounded-md hover:bg-gray-100 dark:hover:bg-gray-700 touch-manipulation active:scale-95"
className="p-2.5 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white rounded-md hover:bg-gray-100 dark:hover:bg-gray-700 touch-manipulation active:scale-95 pwa-menu-button"
>
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" />

View File

@@ -54,7 +54,9 @@ function Sidebar({
updateAvailable,
latestVersion,
currentVersion,
onShowVersionModal
onShowVersionModal,
isPWA,
isMobile
}) {
const [expandedProjects, setExpandedProjects] = useState(new Set());
const [editingProject, setEditingProject] = useState(null);
@@ -434,7 +436,10 @@ function Sidebar({
};
return (
<div className="h-full flex flex-col bg-card md:select-none">
<div
className="h-full flex flex-col bg-card md:select-none"
style={isPWA && isMobile ? { paddingTop: '44px' } : {}}
>
{/* Header */}
<div className="md:p-4 md:border-b md:border-border">
{/* Desktop Header */}
@@ -479,7 +484,10 @@ function Sidebar({
</div>
{/* Mobile Header */}
<div className="md:hidden p-3 border-b border-border">
<div
className="md:hidden p-3 border-b border-border"
style={isPWA && isMobile ? { paddingTop: '16px' } : {}}
>
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="w-8 h-8 bg-primary rounded-lg flex items-center justify-center">