feat: add header

This commit is contained in:
Hewston Fox
2026-03-21 19:50:29 +02:00
parent 4aa0291176
commit 2a1115b66f
21 changed files with 401 additions and 100 deletions

View File

@@ -22,7 +22,7 @@ import menuIcon from "./assets/menu.svg";
import rouletteIcon from "./assets/roulette.svg";
import tasksIcon from "./assets/tasks.svg";
import earningsIcon from "./assets/earnings.svg";
import tg from "@/tg";
import tg, { useTelegramViewportValue } from "@/tg";
const ANIMATION_DURATION = 0.2;
const SPRING_ANIMATION = {
@@ -62,33 +62,34 @@ type BarProps = {
function NavBar({ labelKey, icon, active, entranceDelay, onClick }: BarProps) {
const { t } = useTranslation();
const isInitial = useRef(true);
useEffect(() => {
isInitial.current = false;
}, []);
const [isReady, setIsReady] = useState(false);
const height = active ? ACTIVE_BAR_HEIGHT : BAR_HEIGHT;
const safeAreaBottom = useTelegramViewportValue("safeAreaInsetBottom");
const safeContentBottom = useTelegramViewportValue("contentSafeAreaInsetBottom");
const height = (active ? ACTIVE_BAR_HEIGHT : BAR_HEIGHT) + safeAreaBottom + safeContentBottom;
const offscreenOffset = height * 0.3;
return (
<GlassSurface
className={[classes.bar, active && classes.active]}
variants={{
hidden: {
translateY: ACTIVE_BAR_HEIGHT + OFFSCREEN_BAR_OFFSET,
translateY: height + offscreenOffset,
height,
},
visible: {
translateY: OFFSCREEN_BAR_OFFSET,
height: height + OFFSCREEN_BAR_OFFSET,
translateY: offscreenOffset,
height: height + offscreenOffset,
transition: { ...SPRING_ANIMATION, delay: entranceDelay },
},
ready: {
translateY: OFFSCREEN_BAR_OFFSET,
height: height + OFFSCREEN_BAR_OFFSET,
translateY: offscreenOffset,
height: height + offscreenOffset,
transition: SPRING_ANIMATION,
},
}}
onAnimationComplete={(variant) => variant === "visible" && setIsReady(true)}
initial="hidden"
animate={isInitial.current ? "visible" : "ready"}
animate={isReady ? "ready" : "visible"}
whileTap={{ scale: 0.95 }}
onClick={onClick}
>
@@ -110,34 +111,37 @@ type MenuBarProps = {
const MENU_BAR_WIDTH = 94;
const ACTIVE_MENU_BAR_WIDTH = 104;
const OFFSCREEN_MENU_BAR_OFFSET = 20;
function MenuBar({ labelKey, icon, delay, active, onClick }: MenuBarProps) {
const { t } = useTranslation();
const [isReady, setIsReady] = useState(false);
const width = active ? ACTIVE_MENU_BAR_WIDTH : MENU_BAR_WIDTH;
const safeAreaRight = useTelegramViewportValue("safeAreaInsetRight");
const safeContentRight = useTelegramViewportValue("contentSafeAreaInsetRight");
const width =
(active ? ACTIVE_MENU_BAR_WIDTH : MENU_BAR_WIDTH) + safeAreaRight + safeContentRight;
const offscreenOffset = width * 0.3;
return (
<GlassSurface
className={[classes.menuBar, active && classes.active]}
variants={{
hidden: {
translateX: width + OFFSCREEN_MENU_BAR_OFFSET,
translateX: width + offscreenOffset,
width,
},
visible: {
translateX: OFFSCREEN_MENU_BAR_OFFSET,
translateX: offscreenOffset,
transition: { ...SPRING_ANIMATION, delay: delay },
width,
},
ready: {
translateX: OFFSCREEN_MENU_BAR_OFFSET,
translateX: offscreenOffset,
transition: SPRING_ANIMATION,
width,
},
exit: {
translateX: width + OFFSCREEN_MENU_BAR_OFFSET + 10,
translateX: width + offscreenOffset,
transition: { ...SPRING_ANIMATION, delay: delay },
width,
},