update not found page

This commit is contained in:
Nomi Nonsense (Nonszy) 2025-10-06 14:05:15 +07:00
parent b3c03e0c41
commit f8195aa401
12 changed files with 178 additions and 12 deletions

BIN
public/images/coralz_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

BIN
public/images/coralz_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

BIN
public/sound/poke.wav Normal file

Binary file not shown.

BIN
public/sound/squeak.wav Normal file

Binary file not shown.

View File

@ -7,6 +7,17 @@
--primary: #F48120;
}
@keyframes click-bounce {
0%, 100% {
transform: scale(1, 1);
/* animation-timing-function: linear(0.2, 0.8, 1); */
}
30% {
transform: scale(1.18, 0.9);
/* animation-timing-function: cubic-bezier(0.8, 0, 1, 1); */
}
}
@keyframes silly-bounce {
0%, 100% {
transform: translate(0px, 0px) scale(0.9, 1.1);

View File

@ -1,4 +1,6 @@
import WobblingImage from "@/components/wobbling-image";
import type { Metadata } from "next";
import Link from "@/components/link";
export const metadata: Metadata = {
title: "Wep wep",
@ -8,12 +10,19 @@ export default function NotFound() {
return (
<main className="flex items-center h-screen pt-16 md:pt-32 pb-12 px-8 md:px-0">
<div className="mx-auto w-[380px]">
<header className="mb-8 -ms-5 text-center">
<h1 className="font-bold text-8xl">404</h1>
</header>
<div className="">
Oh you lost, you know there&apos;s nothing here...
</div>
<noscript>
<header className="mb-8 -ms-5 text-center">
<h1 className="font-bold text-8xl">404</h1>
</header>
<div className="">
Oh you lost, you know there&apos;s nothing here...
</div>
</noscript>
<WobblingImage
img1="/images/coralz_0.png"
img2="/images/coralz_1.png"
/>
<Link target="_blank" href="https://x.com/JoelGuerraC/status/1840178999546319101">Source</Link>
</div>
</main>
);

View File

@ -3,9 +3,8 @@ import { NolaGlitchClientOnly } from "@/components/nola-glitch";
import { Sosmed } from "@/components/sosmed";
import HomeText from "@/components/home-text.mdx"
import Link from "next/link";
import Link from "@/components/link";
import { FakeWindow, HomeWindows } from "@/components/windows";
import Taskbar from "@/components/taskbar";
import { WindowManagerProvider } from "@/hooks/window-manager";
export default function Home() {
@ -28,12 +27,12 @@ export default function Home() {
<HomeText />
</article>
<section className="my-8">
<p> Powered with <Link href="https://www.cloudflare.com/" target="_blank" className="text-primary underline">Cloudflare</Link> </p>
<p> Powered with <Link href="https://www.cloudflare.com/" target="_blank">Cloudflare</Link> </p>
</section>
<footer className="mt-20 text-center">
<p>&copy; <span className="text-sm">2025 Nomi Nonszy</span></p>
<p className="text-sm">
<Link href={"/terms"} className="text-primary underline">Terms</Link> and <Link href={"/privacy"} className="text-primary underline">Privacy</Link>
<Link href={"/terms"}>Terms</Link> and <Link href={"/privacy"}>Privacy</Link>
</p>
</footer>
</FakeWindow>

14
src/components/link.tsx Normal file
View File

@ -0,0 +1,14 @@
import clsx from "clsx";
import NextLink from "next/link"
function Link({ className, ...props }: React.ComponentProps<typeof NextLink>) {
return (
<NextLink
className={clsx("text-primary underline", className)}
{...props}
/>
)
}
export default Link;

View File

@ -15,7 +15,7 @@ export const SimpleArticle = ({
Back
</ButtonPrimary>
</Link>
<article className="space-y-5 [&_p]:leading-relaxed relative [&_h1]:text-2xl [&_h2]:text-xl">
<article className="space-y-5 [&_p]:leading-relaxed [&_p]:text-sm [&_li]:text-sm relative [&_h1]:text-2xl [&_h2]:text-xl">
{children}
</article>
</div>

View File

@ -1,5 +1,5 @@
# Privacy Policy
This website ("nonszy.space") fully respects the privacy of its visitors. This document explains how we handle visitor information. The short answer is: **we do not collect, track, or store your personal information**.
This website ("nonszy.space") fully respects the privacy of its visitors. This page explains how we handle visitor information. The short answer is: **we do not collect, track, or store your personal information**.
However, future feature additions will update the privacy policy.

View File

@ -0,0 +1,132 @@
'use client'
import clsx from "clsx";
import Image from "next/image";
import { useCallback, useEffect, useRef, useState } from "react"
interface WobblingImageInterface {
img1: string
img2?: string
}
function WobblingImage ({
img1, img2
}: WobblingImageInterface) {
const size = 400;
const [isAnimating, setIsAnimating] = useState(false);
const audioPath = "/sound/poke.wav";
const audioContextRef = useRef<AudioContext | null>(null);
const [audioBuffer, setAudioBuffer] = useState<AudioBuffer | null>(null);
const [audioLoaded, setAudioLoaded] = useState(false);
const [dummyAudio, setDummyAudio] = useState<HTMLAudioElement | null>(null);
useEffect(() => {
if (typeof Audio !== undefined) setDummyAudio(new Audio(audioPath))
return () => {
if (dummyAudio) dummyAudio.pause();
}
}, [])
const initializeAudioContext = useCallback((): AudioContext => {
if (!audioContextRef.current) {
audioContextRef.current = new (window.AudioContext || (window as any).webkitAudioContext)();
}
return audioContextRef.current;
}, []);
const loadAudio = useCallback(async (url: string): Promise<AudioBuffer> => {
const response = await fetch(url);
const arrayBuffer = await response.arrayBuffer();
const context = initializeAudioContext();
return await context.decodeAudioData(arrayBuffer);
}, [initializeAudioContext]);
const initializeAudio = useCallback(async (): Promise<void> => {
if (audioBuffer) return;
setAudioLoaded(false);
try {
const buffer = await loadAudio(audioPath);
setAudioBuffer(buffer);
} catch (error) {
console.error('Failed to load audio:', error);
}
finally {
setAudioLoaded(true);
}
}, [audioBuffer, loadAudio]);
const playRandomPitch = useCallback(async (): Promise<void> => {
await initializeAudio();
if (!audioBuffer || !audioContextRef.current) return;
const context = audioContextRef.current;
const changeToLowPitch = Math.floor(Math.random() * 10);
const randomPitch = Math.random() * 0.2 + (changeToLowPitch == 1 ? 0.25 : 0.85);
const source = context.createBufferSource();
source.buffer = audioBuffer;
source.playbackRate.value = randomPitch;
source.connect(context.destination);
source.start(0);
source.onended = () => {
source.disconnect();
};
}, [audioBuffer, initializeAudio]);
function handleClick() {
setIsAnimating(false);
requestAnimationFrame(() => setIsAnimating(true));
playRandomPitch();
if (dummyAudio && !audioLoaded) {
dummyAudio.currentTime = 0;
dummyAudio.play();
}
}
function handleAnimationEnd() {
setIsAnimating(false);
}
return (
<div className="">
<div
className={clsx(
"relative mx-auto cursor-grab h-[400px] select-none",
isAnimating && "animate-[click-bounce_150ms_ease-out]"
)}
onClick={handleClick}
onAnimationEnd={handleAnimationEnd}
role="button"
tabIndex={0}
onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); handleClick(); } }}
onMouseDown={(e) => e.preventDefault()}
onPointerDown={(e) => e.preventDefault()}
>
<Image
className={clsx("absolute left-1/2 -translate-x-1/2 top-0 pointer-events-none", isAnimating ? "opacity-0" : "opacity-100")}
alt="clip1"
src={img1}
width={size}
height={size}
draggable={false}
/>
<Image
className={clsx("absolute left-1/2 -translate-x-1/2 top-0 pointer-events-none", isAnimating ? "opacity-100" : "opacity-0")}
alt="clip2"
src={img2 || img1}
width={size}
height={size}
draggable={false}
/>
</div>
</div>
)
}
export default WobblingImage;

View File

@ -24,6 +24,7 @@ const config: Config = {
},
animation: {
"silly-bouncing": 'silly-bounce 0.8s infinite',
"click-bouncing": 'click-bounce 200ms',
'window-popup': 'window-popup 1s',
'window-popdown': 'window-popdown 1s'
},