fix for ssgoi hero animation

Hee Sung Son committed Nov 21, 2025 at 22:33 UTC 03e16413aabe54f3d5b612a9fd51b5716624dcc0
2 files changed +30 -35
cmd/relay-server/frontend/src/components/ServerCard.tsx
+1 -7
@@ -36,15 +36,9 @@ export function ServerCard({
36 >
37 <div
38 data-hero-key={`server-bg-${serverId}`}
39 - className="relative h-[174.5px] bg-center bg-no-repeat bg-cover rounded-xl shadow-lg hover:shadow-xl transition-shadow duration-300 cursor-pointer z-1"
39 + className="relative h-[174.5px] bg-center bg-no-repeat bg-cover rounded-xl shadow-lg hover:shadow-xl transition-shadow duration-300 cursor-pointer z-1 border border-foreground/40"
40 style={{ backgroundImage: `url(${thumbnail || defaultThumbnail})` }}
41 >
42 - {/* Hero element - just the background image */}
43 - {/* <img
44 - src={thumbnail || defaultThumbnail}
45 - alt={name}
46 - className="absolute inset-0 w-full h-full object-cover"
47 - /> */}
42 {/* Content overlay - not part of hero transition */}
43 <div className="relative h-full w-full bg-background/80 rounded-xl flex flex-col gap-4 p-4 items-start text-start">
44 <div className="w-full flex flex-1 flex-col justify-between gap-4">
cmd/relay-server/frontend/src/pages/ServerDetail.tsx
+29 -28
@@ -1,5 +1,5 @@
1 import { SsgoiTransition } from "@ssgoi/react";
2 -import { useEffect, useState } from "react";
2 +import { useEffect } from "react";
3 import { useLocation, useNavigate } from "react-router-dom";
4
5 interface ServerDetailState {
@@ -18,34 +18,41 @@ export function ServerDetail() {
18 const navigate = useNavigate();
19 const server = location.state as ServerDetailState;
20
21 - const [isPush, setIsPush] = useState(false);
22 - const [isBlocked, setIsBlocked] = useState(false);
21 + const isPush = () => localStorage.getItem("isPush") === "true";
22 +
23 + useEffect(() => {
24 + const handlePageShow = () => {
25 + if (isPush()) {
26 + localStorage.removeItem("isPush");
27 + navigate("/");
28 + }
29 + };
30 +
31 + window.addEventListener("pageshow", handlePageShow);
32 +
33 + return () => {
34 + window.removeEventListener("pageshow", handlePageShow);
35 + };
36 + }, []);
37 +
38 useEffect(() => {
24 - console.log("isPush", isPush);
25 - console.log("isBlocked", isBlocked);
26 - // If no server data, redirect to home
27 - if (!server) {
28 - navigate("/");
29 - return;
30 - }
39 + if (typeof localStorage === "undefined") return;
40
41 // Redirect to actual server URL after animation
42 const timer = setTimeout(() => {
34 - // Replace current history entry before redirecting
35 - if (isPush) {
36 - if (!isBlocked) {
37 - setIsBlocked(true);
38 - } else {
39 - navigate("/");
40 - }
43 + if (isPush()) {
44 + localStorage.removeItem("isPush");
45 + navigate("/");
46 } else {
42 - setIsPush(true);
47 + localStorage.setItem("isPush", "true");
48 window.location.href = server.serverUrl;
49 }
45 - }, 500);
50 + }, 300);
51
47 - return () => clearTimeout(timer);
48 - }, [server, isPush, setIsPush, isBlocked, setIsBlocked, navigate]);
52 + return () => {
53 + clearTimeout(timer);
54 + };
55 + }, [server, navigate]);
56
57 // If no server data, show nothing (will redirect)
58 if (!server) {
@@ -64,14 +71,8 @@ export function ServerDetail() {
71 className="fixed inset-0 bg-center bg-no-repeat bg-cover w-screen h-screen"
72 style={{ backgroundImage: `url(${thumbnail || defaultThumbnail})` }}
73 >
67 - {/* Hero element - just the background image */}
68 - {/* <img
69 - src={thumbnail || defaultThumbnail}
70 - alt={name}
71 - className="absolute inset-0 w-full h-full object-cover"
72 - /> */}
74 {/* Content overlay - not part of hero transition */}
74 - <div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-background/70 rounded-xl flex flex-col gap-4 p-4 items-start text-start z-1">
75 + <div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 h-[174.5px] w-full min-[500px]:w-[50%] md:w-[33.33%] bg-background/70 rounded-xl flex flex-col gap-4 p-4 items-start text-start z-1">
76 <div className="w-full flex flex-1 flex-col justify-between gap-4">
77 <div className="flex flex-col gap-2">
78 <div className="flex items-center gap-2">