ios pwa沉浸式状态栏
This commit is contained in:
@@ -14,6 +14,7 @@ const manifestPath = path.join(publicDir, 'manifest.json');
|
||||
const siteName = process.env.NEXT_PUBLIC_SITE_NAME || 'MoonTVPlus';
|
||||
|
||||
// manifest.json 模板
|
||||
// Apple 状态栏等配置应写在 HTML meta(layout appleWebApp),非标准 manifest 字段浏览器会忽略
|
||||
const manifestTemplate = {
|
||||
name: siteName,
|
||||
short_name: siteName,
|
||||
@@ -22,8 +23,6 @@ const manifestTemplate = {
|
||||
scope: '/',
|
||||
display: 'standalone',
|
||||
background_color: '#000000',
|
||||
'apple-mobile-web-app-capable': 'yes',
|
||||
'apple-mobile-web-app-status-bar-style': 'black',
|
||||
icons: [
|
||||
{
|
||||
src: '/icons/icon-192x192.png',
|
||||
|
||||
@@ -40,6 +40,12 @@ export async function generateMetadata(): Promise<Metadata> {
|
||||
title: siteName,
|
||||
description: '影视聚合',
|
||||
manifest: '/manifest.json',
|
||||
// iOS 添加到主屏幕:沉浸式状态栏(需配合 viewport-fit=cover + 顶部 safe-area)
|
||||
appleWebApp: {
|
||||
capable: true,
|
||||
statusBarStyle: 'black-translucent',
|
||||
title: siteName,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -2093,7 +2093,10 @@ export default function MusicClient({ children: _children }: { children?: React.
|
||||
</div>
|
||||
)}
|
||||
{/* Header */}
|
||||
<header className="fixed top-0 left-0 right-0 z-40 bg-zinc-950/95 backdrop-blur-md border-b border-white/10 px-4 md:px-6">
|
||||
<header
|
||||
className="fixed top-0 left-0 right-0 z-40 bg-zinc-950/95 backdrop-blur-md border-b border-white/10 px-4 md:px-6"
|
||||
style={{ paddingTop: 'env(safe-area-inset-top)' }}
|
||||
>
|
||||
<div className="w-full mx-auto flex items-center justify-between gap-3 md:gap-4 py-3">
|
||||
<div className="flex items-center justify-between md:justify-start md:gap-6 w-full md:w-auto">
|
||||
<div className="flex items-center gap-3">
|
||||
@@ -2118,7 +2121,7 @@ export default function MusicClient({ children: _children }: { children?: React.
|
||||
</header>
|
||||
|
||||
{/* Main Content */}
|
||||
<main className="pt-[80px] md:pt-[76px] pb-32 px-4 md:px-6">
|
||||
<main className="pt-[calc(80px+env(safe-area-inset-top))] md:pt-[calc(76px+env(safe-area-inset-top))] pb-32 px-4 md:px-6">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
{_children}
|
||||
</div>
|
||||
|
||||
@@ -15,8 +15,11 @@ interface MobileHeaderProps {
|
||||
const MobileHeader = ({ showBackButton = false }: MobileHeaderProps) => {
|
||||
const { siteName } = useSite();
|
||||
return (
|
||||
<header className='md:hidden fixed top-0 left-0 right-0 z-[999] w-full bg-white/70 backdrop-blur-xl border-b border-gray-200/50 shadow-sm dark:bg-gray-900/70 dark:border-gray-700/50'>
|
||||
<div className='h-12 flex items-center justify-between px-4'>
|
||||
<header
|
||||
className='md:hidden fixed top-0 left-0 right-0 z-[999] w-full bg-white/70 backdrop-blur-xl border-b border-gray-200/50 shadow-sm dark:bg-gray-900/70 dark:border-gray-700/50'
|
||||
style={{ paddingTop: 'env(safe-area-inset-top)' }}
|
||||
>
|
||||
<div className='relative h-12 flex items-center justify-between px-4'>
|
||||
{/* 左侧:搜索按钮、返回按钮和设置按钮 */}
|
||||
<div className='flex items-center gap-2'>
|
||||
<Link
|
||||
@@ -47,17 +50,17 @@ const MobileHeader = ({ showBackButton = false }: MobileHeaderProps) => {
|
||||
<UserMenu />
|
||||
<UpdateNotification />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 中间:Logo(绝对居中) */}
|
||||
<div className='absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2'>
|
||||
<Link
|
||||
href='/'
|
||||
prefetch={false}
|
||||
className='text-2xl font-bold text-green-600 tracking-tight hover:opacity-80 transition-opacity'
|
||||
>
|
||||
{siteName}
|
||||
</Link>
|
||||
{/* 中间:Logo(相对内容行居中,避免被 safe-area 顶偏) */}
|
||||
<div className='absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2'>
|
||||
<Link
|
||||
href='/'
|
||||
prefetch={false}
|
||||
className='text-2xl font-bold text-green-600 tracking-tight hover:opacity-80 transition-opacity'
|
||||
>
|
||||
{siteName}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
|
||||
@@ -107,7 +107,7 @@ const PageLayout = ({ children, activePath = '/', hideNavigation = false }: Page
|
||||
|
||||
{/* 主内容 */}
|
||||
<main
|
||||
className='flex-1 md:min-h-0 mb-14 md:mb-0 md:mt-0 mt-12'
|
||||
className='flex-1 md:min-h-0 mb-14 md:mb-0 md:mt-0 mt-[calc(3rem+env(safe-area-inset-top))]'
|
||||
style={{
|
||||
paddingBottom: 'calc(3.5rem + env(safe-area-inset-bottom))',
|
||||
}}
|
||||
|
||||
@@ -119,7 +119,10 @@ export default function BooksLayout({
|
||||
|
||||
return (
|
||||
<div className='min-h-screen bg-[radial-gradient(circle_at_top_left,#fce7f3_0,transparent_34rem),linear-gradient(180deg,#fff7fb_0%,#f8fafc_44%,#f8fafc_100%)] text-slate-900 dark:bg-[radial-gradient(circle_at_top_left,rgba(6,95,70,0.26)_0,transparent_32rem),linear-gradient(180deg,#050505_0%,#09090b_100%)] dark:text-gray-100'>
|
||||
<header className='fixed inset-x-0 top-0 z-40 border-b border-emerald-100/80 bg-white/85 shadow-sm shadow-emerald-950/5 backdrop-blur-xl dark:border-emerald-500/10 dark:bg-gray-950/85 dark:shadow-black/20'>
|
||||
<header
|
||||
className='fixed inset-x-0 top-0 z-40 border-b border-emerald-100/80 bg-white/85 shadow-sm shadow-emerald-950/5 backdrop-blur-xl dark:border-emerald-500/10 dark:bg-gray-950/85 dark:shadow-black/20'
|
||||
style={{ paddingTop: 'env(safe-area-inset-top)' }}
|
||||
>
|
||||
<div className='mx-auto flex h-16 max-w-6xl items-center gap-3 px-4'>
|
||||
{isRead || pathname === '/books/detail' ? (
|
||||
<Link
|
||||
@@ -240,7 +243,11 @@ export default function BooksLayout({
|
||||
</div>
|
||||
</header>
|
||||
<main
|
||||
className={`mx-auto max-w-6xl ${isRead ? 'pt-16' : 'px-4 pb-24 pt-24'}`}
|
||||
className={`mx-auto max-w-6xl ${
|
||||
isRead
|
||||
? 'pt-[calc(4rem+env(safe-area-inset-top))]'
|
||||
: 'px-4 pb-24 pt-[calc(6rem+env(safe-area-inset-top))]'
|
||||
}`}
|
||||
>
|
||||
{children}
|
||||
</main>
|
||||
|
||||
@@ -64,7 +64,10 @@ export default function MangaLayout({ children }: MangaLayoutProps) {
|
||||
|
||||
return (
|
||||
<div className='min-h-screen bg-gray-50 text-gray-900 dark:bg-black dark:text-gray-100'>
|
||||
<header className='fixed inset-x-0 top-0 z-[999] border-b border-gray-200/70 bg-white/85 backdrop-blur-xl shadow-sm dark:border-gray-800/80 dark:bg-gray-950/85'>
|
||||
<header
|
||||
className='fixed inset-x-0 top-0 z-[999] border-b border-gray-200/70 bg-white/85 backdrop-blur-xl shadow-sm dark:border-gray-800/80 dark:bg-gray-950/85'
|
||||
style={{ paddingTop: 'env(safe-area-inset-top)' }}
|
||||
>
|
||||
<div className='mx-auto flex h-14 max-w-7xl items-center gap-3 px-3 sm:h-16 sm:px-6'>
|
||||
<div className='flex min-w-0 flex-1 items-center gap-2'>
|
||||
{meta.backHref ? (
|
||||
@@ -154,7 +157,7 @@ export default function MangaLayout({ children }: MangaLayoutProps) {
|
||||
</header>
|
||||
|
||||
<main
|
||||
className={`mx-auto max-w-7xl pt-20 sm:pt-24 ${
|
||||
className={`mx-auto max-w-7xl pt-[calc(5rem+env(safe-area-inset-top))] sm:pt-[calc(6rem+env(safe-area-inset-top))] ${
|
||||
isReadingPage
|
||||
? 'px-0 pb-24 sm:px-0 sm:pb-28 lg:pb-10'
|
||||
: 'px-3 pb-[calc(5rem+env(safe-area-inset-bottom))] sm:px-6 sm:pb-[calc(5rem+env(safe-area-inset-bottom))] lg:pb-10'
|
||||
|
||||
Reference in New Issue
Block a user