From 4409ac9d44279faadfae1c2012b5483ba25935ba Mon Sep 17 00:00:00 2001 From: Anish Shanbhag Date: Sun, 12 May 2024 22:39:25 +0200 Subject: [PATCH] Add loading state and direct linking to projects --- app/components/BlurOverlay.tsx | 40 ++++++++++++++++++---- app/components/GradientMask.tsx | 6 ++++ app/components/Transitioner.tsx | 16 ++++++++- app/components/projects/ProjectContent.tsx | 9 +++-- app/utils/state.ts | 1 + 5 files changed, 63 insertions(+), 9 deletions(-) diff --git a/app/components/BlurOverlay.tsx b/app/components/BlurOverlay.tsx index de7d09a..ba34193 100644 --- a/app/components/BlurOverlay.tsx +++ b/app/components/BlurOverlay.tsx @@ -1,18 +1,46 @@ "use client"; import { useAtomValue } from "jotai"; +import { useEffect, useState } from "react"; -import { activeProjectAtom } from "../utils/state"; +import { activeProjectAtom, isLoadingAtom } from "../utils/state"; import { OPEN_ANIMATION_DURATION_CLASS } from "../utils/constants"; export default function BlurOverlay() { + const isLoading = useAtomValue(isLoadingAtom); const activeProject = useAtomValue(activeProjectAtom); + const [inFront, setInFront] = useState(true); + + useEffect(() => { + if (!isLoading) { + setTimeout(() => setInFront(false), 500); + } + }, [isLoading]); return ( -
+ <> +
+
+
+
+
+
+
+
+
+
+ ); } diff --git a/app/components/GradientMask.tsx b/app/components/GradientMask.tsx index 0d60ab6..6975381 100644 --- a/app/components/GradientMask.tsx +++ b/app/components/GradientMask.tsx @@ -3,6 +3,9 @@ import { ReactNode, useLayoutEffect, useRef } from "react"; import { Noise } from "noisejs"; import { useInView } from "react-intersection-observer"; +import { useSetAtom } from "jotai"; + +import { isLoadingAtom } from "../utils/state"; // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const noise = new Noise(Math.random()); @@ -37,9 +40,12 @@ export default function GradientMask({ const { ref, inView } = useInView(); inViewRef.current = inView; + const setIsLoading = useSetAtom(isLoadingAtom); + useLayoutEffect(() => { if (didSetupAnimation.current) return; didSetupAnimation.current = true; + setIsLoading(false); const ctx = canvas.current!.getContext("2d")!; diff --git a/app/components/Transitioner.tsx b/app/components/Transitioner.tsx index 9c563ef..a916083 100644 --- a/app/components/Transitioner.tsx +++ b/app/components/Transitioner.tsx @@ -2,10 +2,11 @@ import { useAtom, useSetAtom } from "jotai"; import { useEffect, useRef, useState } from "react"; +import { usePathname } from "next/navigation"; import { activeProjectAtom, isTransitioningAtom } from "../utils/state"; import { OPEN_ANIMATION_DURATION } from "../utils/constants"; -import { Project } from "../utils/projects"; +import { Project, projects } from "../utils/projects"; function useScrollbarWidth() { const didCompute = useRef(false); @@ -38,12 +39,16 @@ function useScrollbarWidth() { } let backListenerRegistered = false; +let checkedProject = false; export default function Transitioner() { const [oldActiveProject, setOldActiveProject] = useState( null, ); const [activeProject, setActiveProject] = useAtom(activeProjectAtom); + + const routeAfterSlash = usePathname().split("/").slice(1).join("/"); + const setIsTransitioning = useSetAtom(isTransitioningAtom); const scrollbarWidth = useScrollbarWidth(); @@ -58,6 +63,15 @@ export default function Transitioner() { }); } + if (!checkedProject) { + checkedProject = true; + for (const project of projects) { + if (routeAfterSlash === project.name) { + setActiveProject(project); + } + } + } + if (oldActiveProject !== activeProject) { setOldActiveProject(activeProject); setIsTransitioning(true); diff --git a/app/components/projects/ProjectContent.tsx b/app/components/projects/ProjectContent.tsx index ef2c13f..f8af971 100644 --- a/app/components/projects/ProjectContent.tsx +++ b/app/components/projects/ProjectContent.tsx @@ -10,7 +10,7 @@ import { OPEN_ANIMATION_DURATION, OPEN_ANIMATION_DURATION_CLASS, } from "../../utils/constants"; -import { activeProjectAtom } from "../../utils/state"; +import { activeProjectAtom, isLoadingAtom } from "../../utils/state"; import styles from "./scrollbar.module.css"; import ProjectFeatures from "./ProjectFeatures"; @@ -38,6 +38,7 @@ export const ProjectContent = memo(function ProjectContent({ const cardRef = useRef(null); const setActiveProject = useSetAtom(activeProjectAtom); + const setIsLoading = useSetAtom(isLoadingAtom); const description = useRef(null); @@ -74,6 +75,7 @@ export const ProjectContent = memo(function ProjectContent({ setTimeout(() => { setEnableTransition(true); setIsOpen(true); + setIsLoading(false); }, 0); } }, [isActive, isOpen, enableTransition]); @@ -81,7 +83,10 @@ export const ProjectContent = memo(function ProjectContent({ return ( window.history.back()} + onOutsideClick={() => { + window.history.replaceState({ isProject: false }, null, "/"); + setActiveProject(null); + }} >
(null); export const isTransitioningAtom = atom(false); +export const isLoadingAtom = atom(true);