mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-05 06:24:37 +00:00
fix(web): keep overlays below PWA status bar (#1124)
* fix codex session import merge (#1123) 修复 Codex 会话导入合并后列表为空的问题。 Fix Codex session import merge so a session is not detected as a duplicate of itself and deleted during merge. Co-authored-by: LIUZHIRU <ryuu@fine-net.co.jp> * fix(web): keep overlays below PWA status bar Account for env(safe-area-inset-top) on fixed top banners, image preview chrome, and session action menus so installed PWA mode no longer draws controls under the OS status bar. Fixes #1066 --------- Co-authored-by: Himehane <36065996+Himehane@users.noreply.github.com> Co-authored-by: LIUZHIRU <ryuu@fine-net.co.jp>
This commit is contained in:
co-authored by
Himehane
LIUZHIRU
parent
a965b0ab21
commit
cd25660658
@@ -240,7 +240,7 @@ export function ImagePreview(props: {
|
||||
aria-modal="true"
|
||||
aria-label={props.label}
|
||||
>
|
||||
<div className="flex items-center gap-2 border-b border-white/10 bg-black/50 px-3 py-2">
|
||||
<div className="flex items-center gap-2 border-b border-white/10 bg-black/50 px-3 pb-2 pt-[calc(env(safe-area-inset-top)+0.5rem)]">
|
||||
<div className="min-w-0 flex-1 truncate text-sm font-medium">{props.fileName}</div>
|
||||
<button
|
||||
type="button"
|
||||
|
||||
@@ -10,7 +10,7 @@ export function OfflineBanner() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="fixed top-0 left-0 right-0 bg-amber-500 text-white text-center py-2 text-sm font-medium z-50">
|
||||
<div className="fixed top-0 left-0 right-0 bg-amber-500 text-white text-center pb-2 pt-[calc(env(safe-area-inset-top)+0.5rem)] text-sm font-medium z-50">
|
||||
{t('offline.message')}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -117,7 +117,9 @@ describe('PwaUpdateBanner', () => {
|
||||
</I18nProvider>,
|
||||
)
|
||||
|
||||
expect(screen.getByTestId('pwa-update-banner')).toHaveClass('top-12')
|
||||
expect(screen.getByTestId('pwa-update-banner')).toHaveClass(
|
||||
'top-[calc(env(safe-area-inset-top)+3rem)]'
|
||||
)
|
||||
})
|
||||
|
||||
it('expands the rationale section when the disclosure is opened', () => {
|
||||
|
||||
@@ -14,7 +14,9 @@ export function PwaUpdateBanner({ topClassName }: { topClassName?: string } = {}
|
||||
return null
|
||||
}
|
||||
|
||||
const topClass = topClassName ?? (isOnline ? 'top-2' : 'top-10')
|
||||
const topClass = topClassName ?? (isOnline
|
||||
? 'top-[calc(env(safe-area-inset-top)+0.5rem)]'
|
||||
: 'top-[calc(env(safe-area-inset-top)+2.5rem)]')
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -68,6 +70,10 @@ export function PwaUpdateBannerWithStatusOffset({
|
||||
Boolean(voice && voice.status === 'error' && voice.errorMessage)
|
||||
|
||||
return (
|
||||
<PwaUpdateBanner topClassName={hasTopStatusBanner ? 'top-12' : undefined} />
|
||||
<PwaUpdateBanner
|
||||
topClassName={hasTopStatusBanner
|
||||
? 'top-[calc(env(safe-area-inset-top)+3rem)]'
|
||||
: undefined}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ export function ReconnectingBanner({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="fixed top-0 left-0 right-0 bg-amber-500 text-white text-center py-2 text-sm font-medium z-50 flex items-center justify-center gap-2">
|
||||
<div className="fixed top-0 left-0 right-0 bg-amber-500 text-white text-center pb-2 pt-[calc(env(safe-area-inset-top)+0.5rem)] text-sm font-medium z-50 flex items-center justify-center gap-2">
|
||||
<span className="animate-spin h-4 w-4 border-2 border-white border-t-transparent rounded-full" />
|
||||
{t('reconnecting.message')}
|
||||
{reasonLabel ? <span className="opacity-90">({reasonLabel})</span> : null}
|
||||
|
||||
@@ -289,7 +289,7 @@ export function SessionActionMenu(props: SessionActionMenuProps) {
|
||||
|
||||
const menuStyle: CSSProperties | undefined = menuPosition
|
||||
? {
|
||||
top: menuPosition.top,
|
||||
top: `max(${menuPosition.top}px, calc(env(safe-area-inset-top) + 8px))`,
|
||||
left: menuPosition.left,
|
||||
transformOrigin: menuPosition.transformOrigin
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ export function SyncingBanner({ isSyncing }: { isSyncing: boolean }) {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="fixed top-0 left-0 right-0 bg-[var(--app-banner-bg)] text-[var(--app-banner-text)] text-center py-2 text-sm font-medium z-50 flex items-center justify-center gap-2 border-b border-[var(--app-divider)]">
|
||||
<div className="fixed top-0 left-0 right-0 bg-[var(--app-banner-bg)] text-[var(--app-banner-text)] text-center pb-2 pt-[calc(env(safe-area-inset-top)+0.5rem)] text-sm font-medium z-50 flex items-center justify-center gap-2 border-b border-[var(--app-divider)]">
|
||||
<Spinner size="sm" label={null} className="text-[var(--app-banner-text)]" />
|
||||
{t('syncing.title')}
|
||||
</div>
|
||||
|
||||
@@ -21,7 +21,7 @@ export function VoiceErrorBanner() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="fixed top-0 left-0 right-0 bg-red-500 text-white text-center py-2 text-sm font-medium z-50 flex items-center justify-center border-b border-red-600">
|
||||
<div className="fixed top-0 left-0 right-0 bg-red-500 text-white text-center pb-2 pt-[calc(env(safe-area-inset-top)+0.5rem)] text-sm font-medium z-50 flex items-center justify-center border-b border-red-600">
|
||||
{voice.errorMessage}
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user