Add juicy on-load animation to logo in app header
This commit is contained in:
@ -10,11 +10,18 @@ Please do not fill this up with junk.
|
||||
|
||||
interface AppState {
|
||||
isStreamReady: boolean
|
||||
/**
|
||||
* Saves if the app has loaded already across route navigations.
|
||||
* Used by the ProjectSidebarMenu component to determine if it should
|
||||
* perform a fancy animation, which is only on the first render.
|
||||
*/
|
||||
hasRenderedOnce: boolean
|
||||
setAppState: (newAppState: Partial<AppState>) => void
|
||||
}
|
||||
|
||||
const AppStateContext = createContext<AppState>({
|
||||
isStreamReady: false,
|
||||
hasRenderedOnce: false,
|
||||
setAppState: () => {},
|
||||
})
|
||||
|
||||
@ -23,6 +30,7 @@ export const useAppState = () => useContext(AppStateContext)
|
||||
export const AppStateProvider = ({ children }: { children: ReactNode }) => {
|
||||
const [appState, _setAppState] = useState<AppState>({
|
||||
isStreamReady: false,
|
||||
hasRenderedOnce: false,
|
||||
setAppState: () => {},
|
||||
})
|
||||
const setAppState = (newAppState: Partial<AppState>) =>
|
||||
@ -32,6 +40,7 @@ export const AppStateProvider = ({ children }: { children: ReactNode }) => {
|
||||
<AppStateContext.Provider
|
||||
value={{
|
||||
isStreamReady: appState.isStreamReady,
|
||||
hasRenderedOnce: appState.hasRenderedOnce,
|
||||
setAppState,
|
||||
}}
|
||||
>
|
||||
|
||||
@ -4,7 +4,7 @@ import { type IndexLoaderData } from 'lib/types'
|
||||
import { PATHS } from 'lib/paths'
|
||||
import { isDesktop } from '../lib/isDesktop'
|
||||
import { Link, useLocation, useNavigate } from 'react-router-dom'
|
||||
import { Fragment, useMemo } from 'react'
|
||||
import { Fragment, useEffect, useMemo } from 'react'
|
||||
import { Logo } from './Logo'
|
||||
import { APP_NAME } from 'lib/constants'
|
||||
import { useCommandsContext } from 'hooks/useCommandsContext'
|
||||
@ -15,6 +15,7 @@ import { machineManager } from 'lib/machineManager'
|
||||
import usePlatform from 'hooks/usePlatform'
|
||||
import { useAbsoluteFilePath } from 'hooks/useAbsoluteFilePath'
|
||||
import Tooltip from './Tooltip'
|
||||
import { useAppState } from 'AppState'
|
||||
|
||||
const ProjectSidebarMenu = ({
|
||||
project,
|
||||
@ -54,34 +55,56 @@ const ProjectSidebarMenu = ({
|
||||
function AppLogoLink({
|
||||
project,
|
||||
file,
|
||||
className = '',
|
||||
}: {
|
||||
project?: IndexLoaderData['project']
|
||||
file?: IndexLoaderData['file']
|
||||
className?: string
|
||||
}) {
|
||||
const { hasRenderedOnce, setAppState } = useAppState()
|
||||
const { onProjectClose } = useLspContext()
|
||||
const wrapperClassName =
|
||||
"relative h-full grid place-content-center group p-1.5 before:block before:content-[''] before:absolute before:inset-0 before:bottom-2.5 before:z-[-1] before:bg-primary before:rounded-b-sm"
|
||||
const logoClassName = 'w-auto h-4 text-chalkboard-10'
|
||||
|
||||
return isDesktop() ? (
|
||||
<Link
|
||||
data-testid="app-logo"
|
||||
onClick={() => {
|
||||
onProjectClose(file || null, project?.path || null, false)
|
||||
// Clear the scene and end the session.
|
||||
engineCommandManager.endSession()
|
||||
}}
|
||||
to={PATHS.HOME}
|
||||
className={wrapperClassName + ' hover:before:brightness-110'}
|
||||
useEffect(() => {
|
||||
if (!hasRenderedOnce) {
|
||||
setAppState({ hasRenderedOnce: true })
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<Transition
|
||||
show={true}
|
||||
appear={!hasRenderedOnce}
|
||||
as={Fragment}
|
||||
enter="transition-transform ease-out duration-500 delay-200"
|
||||
enterFrom="-translate-y-12"
|
||||
enterTo="translate-y-0"
|
||||
>
|
||||
<Logo className={logoClassName} />
|
||||
<span className="sr-only">{APP_NAME}</span>
|
||||
</Link>
|
||||
) : (
|
||||
<div className={wrapperClassName} data-testid="app-logo">
|
||||
<Logo className={logoClassName} />
|
||||
<span className="sr-only">{APP_NAME}</span>
|
||||
</div>
|
||||
{isDesktop() ? (
|
||||
<Link
|
||||
data-testid="app-logo"
|
||||
onClick={() => {
|
||||
onProjectClose(file || null, project?.path || null, false)
|
||||
// Clear the scene and end the session.
|
||||
engineCommandManager.endSession()
|
||||
}}
|
||||
to={PATHS.HOME}
|
||||
className={
|
||||
wrapperClassName + ' hover:before:brightness-110 ' + className
|
||||
}
|
||||
>
|
||||
<Logo className={logoClassName} />
|
||||
<span className="sr-only">{APP_NAME}</span>
|
||||
</Link>
|
||||
) : (
|
||||
<div className={wrapperClassName} data-testid="app-logo">
|
||||
<Logo className={logoClassName} />
|
||||
<span className="sr-only">{APP_NAME}</span>
|
||||
</div>
|
||||
)}
|
||||
</Transition>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user