Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
.claude/
.agent/
.gemini/
_/
GEMINI.md
AGENT.md

Expand Down
4 changes: 2 additions & 2 deletions biome.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "https://biomejs.dev/schemas/2.4.12/schema.json",
"$schema": "https://biomejs.dev/schemas/2.5.7/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
Expand All @@ -18,7 +18,7 @@
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"preset": "recommended",
"correctness": {
"useExhaustiveDependencies": "warn",
"useJsxKeyInIterable": "error"
Expand Down
1 change: 0 additions & 1 deletion components/Copyright.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ const Copyright = () => {
fontWeight: '400',
fontSize: '1.4rem',
lineHeight: '2.4rem',
color: 'white',
gap: '1rem',
}}
>
Expand Down
5 changes: 5 additions & 0 deletions next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ const nextConfig = {
// Enable standalone output for optimized Docker builds
output: 'standalone',

// Keep Turbopack scoped to this repository when parent directories contain lockfiles.
turbopack: {
root: import.meta.dirname,
},

// Security headers configuration
async headers() {
return [
Expand Down
32 changes: 16 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "luddy.dance",
"version": "0.1.0",
"private": true,
"packageManager": "pnpm@11.1.3",
"packageManager": "pnpm@11.20.0",
"engines": {
"node": ">=22"
},
Expand All @@ -22,27 +22,27 @@
},
"dependencies": {
"logan-logger": "^1.1.16",
"next": "16.2.6",
"react": "^19.2.6",
"react-dom": "^19.2.6"
"next": "16.3.0",
"react": "^19.2.8",
"react-dom": "^19.2.8"
},
"devDependencies": {
"@biomejs/biome": "^2.4.15",
"@next/bundle-analyzer": "^16.2.6",
"@tailwindcss/postcss": "^4.3.0",
"@biomejs/biome": "^2.5.7",
"@next/bundle-analyzer": "^16.3.0",
"@tailwindcss/postcss": "^4.3.3",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
"@types/node": "^25.9.0",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^6.0.2",
"@vitest/ui": "^4.1.6",
"@types/react": "^19.2.18",
"@types/react-dom": "^19.2.4",
"@vitejs/plugin-react": "^6.0.5",
"@vitest/ui": "^4.1.10",
"jsdom": "^29.1.1",
"postcss": "^8.5.14",
"sharp": "^0.34.5",
"tailwindcss": "^4.3.0",
"postcss": "8.5.25",
"sharp": "^0.35.3",
"tailwindcss": "^4.3.3",
"typescript": "^6.0.3",
"vite": "^8.0.13",
"vitest": "^4.1.6"
"vite": "^8.2.0",
"vitest": "^4.1.10"
}
}
24 changes: 18 additions & 6 deletions pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ import Image from 'next/image';
import { useEffect, useRef, useState } from 'react';
import { log, reportError, setUserContext, trackPerformance } from '@/lib/logger';

const VIDEO_URL = 'https://www.youtube.com/embed/L3Ucukzbp6k';

export default function Component() {
const [isIframeLoaded, setIframeLoaded] = useState(false);
const [shouldLoadIframe, setShouldLoadIframe] = useState(false);
const iframeRef = useRef<HTMLIFrameElement>(null);
const iframeLoadStartedAtRef = useRef<number | null>(null);

useEffect(() => {
// Set user context on page load
Expand All @@ -23,6 +26,7 @@ export default function Component() {
const [entry] = entries;
if (entry.isIntersecting) {
const startTime = performance.now();
iframeLoadStartedAtRef.current = startTime;
setShouldLoadIframe(true);
trackPerformance('iframe_intersection', performance.now() - startTime);
log.componentMount('VideoIframe');
Expand Down Expand Up @@ -69,24 +73,32 @@ export default function Component() {
<iframe
ref={iframeRef}
className="absolute top-0 left-0 w-full h-auto border-0"
src={shouldLoadIframe ? 'https://www.youtube.com/embed/L3Ucukzbp6k' : undefined}
src={shouldLoadIframe ? VIDEO_URL : undefined}
title="10 hours of Ludwig doing the Luddy dance - YouTube video player"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
loading="lazy"
onLoad={() => {
const loadTime = performance.now();
onLoad={(event) => {
const iframeLoadStartedAt = iframeLoadStartedAtRef.current;
if (
!shouldLoadIframe ||
event.currentTarget.getAttribute('src') !== VIDEO_URL ||
iframeLoadStartedAt === null
) {
return;
}

iframeLoadStartedAtRef.current = null;
setIframeLoaded(true);
trackPerformance('iframe_load', loadTime);
trackPerformance('iframe_load', performance.now() - iframeLoadStartedAt);
log.componentMount('VideoIframeContent');
}}
onError={(e) => {
reportError(new Error('iframe failed to load'), {
src: shouldLoadIframe ? 'https://www.youtube.com/embed/L3Ucukzbp6k' : 'undefined',
src: shouldLoadIframe ? VIDEO_URL : 'undefined',
event: e.type,
});
}}
role="application"
aria-label="Embedded YouTube video: 10 hours of Ludwig doing the Luddy dance"
style={{
aspectRatio: '16 / 9',
Expand Down
Loading
Loading