diff --git a/src/App.tsx b/src/App.tsx index 40ca6c9..44433a2 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -9,13 +9,38 @@ import './index.css'; export function App() { useEffect(() => { - const hash = window.location.hash.substring(1); - if (hash) { - const element = document.getElementById(hash); - if (element) { - element.scrollIntoView({ behavior: 'smooth' }); + // 초기 로드 시 hash에 맞게 스크롤 + const scrollToHash = () => { + const hash = window.location.hash.substring(1); + if (hash) { + const element = document.getElementById(hash); + if (element) { + setTimeout(() => { + element.scrollIntoView({ behavior: "smooth" }); + }, 100); // 브라우저가 레이아웃을 그릴 시간을 줌 + } } - } + }; + scrollToHash(); + + // 스크롤 시 hash 업데이트 로직 + const sections = document.querySelectorAll(".section"); + const observer = new IntersectionObserver( + (entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + window.history.replaceState(null, "", `#${entry.target.id}`); + } + }); + }, + { threshold: 0.6 } // 60% 보이면 활성화 + ); + + sections.forEach(section => observer.observe(section)); + + return () => { + sections.forEach(section => observer.unobserve(section)); + }; }, []); return ( diff --git a/src/components/BottomBar.tsx b/src/components/BottomBar.tsx index 458ed9f..6c3b55e 100644 --- a/src/components/BottomBar.tsx +++ b/src/components/BottomBar.tsx @@ -1,6 +1,5 @@ import { useState, useEffect } from "react"; import { Send, AlignJustify, BadgeCheck, House, CircleHelp, ChartGantt, PhoneCall } from "lucide-react"; - import { DropdownMenu, DropdownMenuContent, @@ -8,27 +7,25 @@ import { DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, - } from "@/components/ui/dropdown-menu" - +} from "@/components/ui/dropdown-menu"; export default function BottomBar() { const [email, setEmail] = useState('me@imnya.ng'); const [hash, setHash] = useState(window.location.hash); + const [accessKeyCombo, setAccessKeyCombo] = useState("Alt"); useEffect(() => { - const emaillist = ['me', 'mail', 'not', 'cat', 'neko', 'meow', 'heart'] - const domainlist = ['imnya.ng', 'al-1s.kr'] + const emaillist = ['me', 'mail', 'not', 'cat', 'neko', 'meow', 'heart']; + const domainlist = ['imnya.ng', 'al-1s.kr']; - // furry is 0.001% const randomEmail = () => { const random = Math.floor(Math.random() * 1000); if (random === 0) { setEmail(`furry@${domainlist[Math.floor(Math.random() * domainlist.length)]}`); - } - else { + } else { setEmail(`${emaillist[Math.floor(Math.random() * emaillist.length)]}@${domainlist[Math.floor(Math.random() * domainlist.length)]}`); } - } + }; randomEmail(); const handleHashChange = () => { @@ -42,6 +39,25 @@ export default function BottomBar() { }; }, []); + useEffect(() => { + const ua = navigator.userAgent; + let keyCombo = "Alt"; + + if (/Mac/i.test(ua)) { + keyCombo = "Control + Option"; + } else if (/Linux/i.test(ua)) { + keyCombo = "Alt"; + if (/Firefox/i.test(ua)) { + keyCombo = "Alt + Shift"; + } + } else if (/Windows/i.test(ua)) { + if (/Firefox/i.test(ua)) { + keyCombo = "Alt + Shift"; + } + } + + setAccessKeyCombo(keyCombo); + }, []); return (
@@ -49,11 +65,14 @@ export default function BottomBar() {
{email}
- - - - - + {["top", "about", "project", "timeline", "contact"].map((section, index) => ( + + ))}
@@ -61,76 +80,25 @@ export default function BottomBar() { - - -
- {hash === "#top" ? ( - - ) : ( - - )} - Home -
- -

Alt + 1

-
-
- - -
- {hash === "#about" ? ( - - ) : ( - - )} - About -
- -

Alt + 2

-
-
- - -
- {hash === "#project" ? ( - - ) : ( - - )} - Project -
- -

Alt + 3

-
-
- - -
- {hash === "#timeline" ? ( - - ) : ( - - )} - Timeline -
- -

Alt + 4

-
-
- - -
- {hash === "#contact" ? ( - - ) : ( - - )} - Contact -
- -

Alt + 5

-
-
+ {["top", "about", "project", "timeline", "contact"].map((section, index) => { + const icons = [House, CircleHelp, ChartGantt, ChartGantt, PhoneCall]; + const Icon = icons[index]; + return ( + + +
+ {hash === `#${section}` ? ( + + ) : ( + + )} + {section.charAt(0).toUpperCase() + section.slice(1)} +
+

{accessKeyCombo} + {index + 1}

+
+
+ ); + })} © 2021-2025 imnyang
@@ -139,5 +107,5 @@ export default function BottomBar() {
- ) -} \ No newline at end of file + ); +} diff --git a/src/components/Home/Contact.tsx b/src/components/Home/Contact.tsx index 596b158..dfa4ba9 100644 --- a/src/components/Home/Contact.tsx +++ b/src/components/Home/Contact.tsx @@ -1,45 +1,91 @@ import { Github, Instagram, Rss } from "lucide-react"; import { - Tooltip, - TooltipContent, - TooltipProvider, - TooltipTrigger, - } from "@/components/ui/tooltip"; + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip"; +import { Button } from "../ui/button"; export default function Contact() { - return ( -
-
-
- - - - - - Github - - - - 𝕏 - - 𝕏 - - - - - - Instagram - - - - - - Blog - - -
-