mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-05 06:24:37 +00:00
fix(web): keep mobile views scrollable and new-session actions reachable (#364)
This commit is contained in:
+1
-1
@@ -347,7 +347,7 @@ function AppInner() {
|
||||
/>
|
||||
<VoiceErrorBanner />
|
||||
<OfflineBanner />
|
||||
<div className="h-full flex flex-col">
|
||||
<div className="h-full min-h-0 flex flex-col">
|
||||
<Outlet />
|
||||
</div>
|
||||
<ToastContainer />
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useState } from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { usePWAInstall } from '@/hooks/usePWAInstall'
|
||||
import { usePlatform } from '@/hooks/usePlatform'
|
||||
import { CloseIcon, ShareIcon, PlusCircleIcon } from '@/components/icons'
|
||||
@@ -9,6 +9,22 @@ export function InstallPrompt() {
|
||||
const { canInstall, canInstallIOS, promptInstall, dismissInstall, isStandalone } = usePWAInstall()
|
||||
const { isTelegram, haptic } = usePlatform()
|
||||
const [showIOSGuide, setShowIOSGuide] = useState(false)
|
||||
const showFloatingPrompt = !isTelegram && !isStandalone && ((canInstallIOS && !showIOSGuide) || canInstall)
|
||||
|
||||
useEffect(() => {
|
||||
const root = document.documentElement
|
||||
if (!root) return
|
||||
|
||||
if (showFloatingPrompt) {
|
||||
root.style.setProperty('--app-floating-bottom-offset', '112px')
|
||||
} else {
|
||||
root.style.removeProperty('--app-floating-bottom-offset')
|
||||
}
|
||||
|
||||
return () => {
|
||||
root.style.removeProperty('--app-floating-bottom-offset')
|
||||
}
|
||||
}, [showFloatingPrompt])
|
||||
|
||||
if (isTelegram || isStandalone) {
|
||||
return null
|
||||
|
||||
@@ -13,7 +13,7 @@ export function ActionButtons(props: {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<div className="flex gap-2 px-3 py-3">
|
||||
<div className="flex gap-2 px-3 pt-3 pb-[calc(env(safe-area-inset-bottom)+1rem)]">
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={props.onCancel}
|
||||
|
||||
@@ -13,7 +13,7 @@ export function AgentSelector(props: {
|
||||
<label className="text-xs font-medium text-[var(--app-hint)]">
|
||||
{t('newSession.agent')}
|
||||
</label>
|
||||
<div className="flex gap-3">
|
||||
<div className="flex flex-wrap gap-x-3 gap-y-2">
|
||||
{(['claude', 'codex', 'cursor', 'gemini', 'opencode'] as const).map((agentType) => (
|
||||
<label
|
||||
key={agentType}
|
||||
|
||||
@@ -323,7 +323,7 @@ export function SessionChat(props: {
|
||||
})
|
||||
|
||||
return (
|
||||
<div className="flex h-full flex-col">
|
||||
<div className="flex h-full min-h-0 flex-col">
|
||||
<SessionHeader
|
||||
session={props.session}
|
||||
onBack={props.onBack}
|
||||
|
||||
+4
-1
@@ -368,7 +368,10 @@ function NewSessionPage() {
|
||||
<div className="flex-1 font-semibold">{t('newSession.title')}</div>
|
||||
</div>
|
||||
|
||||
<div className="app-scroll-y flex-1 min-h-0">
|
||||
<div
|
||||
className="app-scroll-y flex-1 min-h-0"
|
||||
style={{ paddingBottom: 'calc(var(--app-floating-bottom-offset, 0px) + env(safe-area-inset-bottom))' }}
|
||||
>
|
||||
{machinesError ? (
|
||||
<div className="p-3 text-sm text-red-600">
|
||||
{machinesError}
|
||||
|
||||
@@ -196,7 +196,7 @@ export default function FilePage() {
|
||||
const diffErrorMessage = diffError ? `Diff unavailable: ${diffError}` : null
|
||||
|
||||
return (
|
||||
<div className="flex h-full flex-col">
|
||||
<div className="flex h-full min-h-0 flex-col">
|
||||
<div className="bg-[var(--app-bg)] pt-[env(safe-area-inset-top)]">
|
||||
<div className="mx-auto w-full max-w-content flex items-center gap-2 p-3 border-b border-[var(--app-border)]">
|
||||
<button
|
||||
@@ -249,7 +249,7 @@ export default function FilePage() {
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<div className="app-scroll-y flex-1">
|
||||
<div className="app-scroll-y flex-1 min-h-0">
|
||||
<div className="mx-auto w-full max-w-content p-4">
|
||||
{diffErrorMessage ? (
|
||||
<div className="mb-3 rounded-md bg-amber-500/10 p-2 text-xs text-[var(--app-hint)]">
|
||||
|
||||
@@ -306,7 +306,7 @@ export default function FilesPage() {
|
||||
}, [navigate, sessionId])
|
||||
|
||||
return (
|
||||
<div className="flex h-full flex-col">
|
||||
<div className="flex h-full min-h-0 flex-col">
|
||||
<div className="bg-[var(--app-bg)] pt-[env(safe-area-inset-top)]">
|
||||
<div className="mx-auto w-full max-w-content flex items-center gap-2 p-3 border-b border-[var(--app-border)]">
|
||||
<button
|
||||
@@ -390,7 +390,7 @@ export default function FilesPage() {
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<div className="app-scroll-y flex-1">
|
||||
<div className="app-scroll-y flex-1 min-h-0">
|
||||
<div className="mx-auto w-full max-w-content">
|
||||
{showGitErrorBanner && activeTab === 'changes' ? (
|
||||
<div className="border-b border-[var(--app-divider)] bg-amber-500/10 px-3 py-2 text-xs text-[var(--app-hint)]">
|
||||
|
||||
@@ -409,7 +409,7 @@ export default function TerminalPage() {
|
||||
: null
|
||||
|
||||
return (
|
||||
<div className="flex h-full flex-col">
|
||||
<div className="flex h-full min-h-0 flex-col">
|
||||
<div className="bg-[var(--app-bg)] pt-[env(safe-area-inset-top)]">
|
||||
<div className="mx-auto w-full max-w-content flex items-center gap-2 p-3 border-b border-[var(--app-border)]">
|
||||
<button
|
||||
@@ -452,7 +452,7 @@ export default function TerminalPage() {
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<div className="flex-1 overflow-hidden bg-[var(--app-bg)]">
|
||||
<div className="flex-1 min-h-0 overflow-hidden bg-[var(--app-bg)]">
|
||||
<div className="mx-auto h-full w-full max-w-content p-3">
|
||||
{terminalSupported ? (
|
||||
<TerminalView onMount={handleTerminalMount} onResize={handleResize} className="h-full w-full" />
|
||||
|
||||
@@ -177,7 +177,7 @@ export default function SettingsPage() {
|
||||
}, [isOpen, isAppearanceOpen, isFontOpen, isTerminalFontOpen, isVoiceOpen])
|
||||
|
||||
return (
|
||||
<div className="flex h-full flex-col">
|
||||
<div className="flex h-full min-h-0 flex-col">
|
||||
<div className="bg-[var(--app-bg)] pt-[env(safe-area-inset-top)]">
|
||||
<div className="mx-auto w-full max-w-content flex items-center gap-2 p-3 border-b border-[var(--app-border)]">
|
||||
<button
|
||||
@@ -191,7 +191,7 @@ export default function SettingsPage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="app-scroll-y flex-1">
|
||||
<div className="app-scroll-y flex-1 min-h-0">
|
||||
<div className="mx-auto w-full max-w-content">
|
||||
{/* Language section */}
|
||||
<div className="border-b border-[var(--app-divider)]">
|
||||
|
||||
Reference in New Issue
Block a user