Some checks are pending
E2E / Playwright e2e (push) Waiting to run
- Introduced turbopack alias for canvas in next.config.mjs. - Updated package.json scripts for development and branding tasks. - Added new dependencies for Tiptap extensions. - Implemented new demo layouts for agenda, contacts, drive, and mail applications. - Enhanced globals.css for improved theming and splash screen animations. - Added OAuth callback handling for drive mounts. - Updated layout components to integrate new demo shells and improve structure.
133 lines
4.2 KiB
TypeScript
133 lines
4.2 KiB
TypeScript
"use client"
|
|
|
|
import { useEffect, useLayoutEffect, useState } from "react"
|
|
import { usePathname } from "next/navigation"
|
|
import { UltiMailLogo } from "@/components/ultimail-logo"
|
|
import {
|
|
markSuiteSplashSeen,
|
|
shouldShowSuiteSplash,
|
|
suiteSplashAppFromPath,
|
|
SUITE_SPLASH_CONFIG,
|
|
type SuiteSplashApp,
|
|
} from "@/lib/suite/suite-app-splash"
|
|
import { suitePublicAsset } from "@/lib/suite/suite-public-asset"
|
|
import { cn } from "@/lib/utils"
|
|
|
|
const SPLASH_VISIBLE_MS = 1750
|
|
const SPLASH_EXIT_MS = 500
|
|
|
|
export function FirstLaunchSplash({
|
|
children,
|
|
}: {
|
|
children: React.ReactNode
|
|
}) {
|
|
const pathname = usePathname()
|
|
const [activeApp, setActiveApp] = useState<SuiteSplashApp | null>(() =>
|
|
typeof window === "undefined"
|
|
? null
|
|
: shouldShowSuiteSplash(window.location.pathname)
|
|
)
|
|
const [isHiding, setIsHiding] = useState(false)
|
|
const [isComplete, setIsComplete] = useState(() => activeApp === null)
|
|
|
|
useLayoutEffect(() => {
|
|
const nextApp = shouldShowSuiteSplash(pathname)
|
|
const root = document.documentElement
|
|
root.dataset.splashApp = suiteSplashAppFromPath(pathname) ?? ""
|
|
root.dataset.splashSeen = nextApp ? "0" : "1"
|
|
setActiveApp(nextApp)
|
|
setIsComplete(nextApp === null)
|
|
setIsHiding(false)
|
|
}, [pathname])
|
|
|
|
useEffect(() => {
|
|
if (!activeApp) return
|
|
|
|
const hideTimer = window.setTimeout(() => {
|
|
setIsHiding(true)
|
|
}, SPLASH_VISIBLE_MS)
|
|
|
|
const completeTimer = window.setTimeout(() => {
|
|
markSuiteSplashSeen(activeApp)
|
|
document.documentElement.dataset.splashSeen = "1"
|
|
setActiveApp(null)
|
|
setIsComplete(true)
|
|
}, SPLASH_VISIBLE_MS + SPLASH_EXIT_MS)
|
|
|
|
return () => {
|
|
window.clearTimeout(hideTimer)
|
|
window.clearTimeout(completeTimer)
|
|
}
|
|
}, [activeApp])
|
|
|
|
const config = activeApp ? SUITE_SPLASH_CONFIG[activeApp] : null
|
|
|
|
return (
|
|
<>
|
|
{children}
|
|
{!isComplete && config ? (
|
|
<div
|
|
className={cn("app-first-launch-splash", isHiding && "app-first-launch-splash--hide")}
|
|
role="status"
|
|
aria-live="polite"
|
|
aria-label={config.ariaLabel}
|
|
data-suite-splash={activeApp}
|
|
>
|
|
<div className="app-first-launch-splash__aurora" aria-hidden />
|
|
<div className="app-first-launch-splash__grain" aria-hidden />
|
|
<div className="app-first-launch-splash__content">
|
|
<div className="app-first-launch-splash__pill">{config.pill}</div>
|
|
{activeApp === "mail" ? (
|
|
<UltiMailLogo href={null} className="app-first-launch-splash__logo" />
|
|
) : config.markDark ? (
|
|
<>
|
|
<img
|
|
src={suitePublicAsset(config.mark)}
|
|
alt=""
|
|
className={cn(
|
|
"app-first-launch-splash__mark dark:hidden",
|
|
config.spinMark && "app-first-launch-splash__mark--spin"
|
|
)}
|
|
width={56}
|
|
height={56}
|
|
decoding="async"
|
|
draggable={false}
|
|
/>
|
|
<img
|
|
src={suitePublicAsset(config.markDark)}
|
|
alt=""
|
|
className={cn(
|
|
"app-first-launch-splash__mark hidden dark:block",
|
|
config.spinMark && "app-first-launch-splash__mark--spin"
|
|
)}
|
|
width={56}
|
|
height={56}
|
|
decoding="async"
|
|
draggable={false}
|
|
/>
|
|
</>
|
|
) : (
|
|
<img
|
|
src={suitePublicAsset(config.mark)}
|
|
alt=""
|
|
className={cn(
|
|
"app-first-launch-splash__mark",
|
|
config.spinMark && "app-first-launch-splash__mark--spin"
|
|
)}
|
|
width={56}
|
|
height={56}
|
|
decoding="async"
|
|
draggable={false}
|
|
/>
|
|
)}
|
|
<p className="app-first-launch-splash__subtitle">{config.subtitle}</p>
|
|
<div className="app-first-launch-splash__loader" aria-hidden>
|
|
<span />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
) : null}
|
|
</>
|
|
)
|
|
}
|