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
4 changes: 0 additions & 4 deletions next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ const nextConfig: NextConfig = {
key: 'X-Content-Type-Options',
value: 'nosniff',
},
{
key: 'X-Frame-Options',
value: 'DENY',
},
{
key: 'X-XSS-Protection',
value: '1; mode=block',
Expand Down
10 changes: 10 additions & 0 deletions src/app/books/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { Metadata } from 'next';

export const metadata: Metadata = {
title: 'Books',
description: 'Browse Books on BitTorrented',
};

export default function Layout({ children }: { children: React.ReactNode }) {
return children;
}
1 change: 1 addition & 0 deletions src/app/books/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client';


/**
* Books Page
*
Expand Down
10 changes: 10 additions & 0 deletions src/app/dht/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { Metadata } from 'next';

export const metadata: Metadata = {
title: 'DHT Torrents',
description: 'Browse DHT Torrents on BitTorrented',
};

export default function Layout({ children }: { children: React.ReactNode }) {
return children;
}
1 change: 1 addition & 0 deletions src/app/dht/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client';


/**
* DHT Index Page
*
Expand Down
Binary file added src/app/favicon.ico
Binary file not shown.
10 changes: 10 additions & 0 deletions src/app/find-torrents/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { Metadata } from 'next';

export const metadata: Metadata = {
title: 'Find Torrents',
description: 'Browse Find Torrents on BitTorrented',
};

export default function Layout({ children }: { children: React.ReactNode }) {
return children;
}
1 change: 1 addition & 0 deletions src/app/find-torrents/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client';


/**
* Find Torrents Page
*
Expand Down
4 changes: 2 additions & 2 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ export const viewport: Viewport = {
themeColor: '#8b5cf6',
width: 'device-width',
initialScale: 1,
maximumScale: 1,
userScalable: false,
maximumScale: 5,
userScalable: true,
viewportFit: 'cover',
};

Expand Down
2 changes: 1 addition & 1 deletion src/app/live-tv/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default async function LiveTvPage(): Promise<React.ReactElement> {
const user = await getCurrentUser();

if (!user) {
redirect('/login?redirect=/live-tv');
redirect('/login?redirect=/live-tv&reason=live-tv');
}

return <LiveTvContent />;
Expand Down
14 changes: 13 additions & 1 deletion src/app/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* User authentication with email/password.
*/

import { useState } from 'react';
import { useState, useEffect } from 'react';
import Link from 'next/link';
import Image from 'next/image';
import { MainLayout } from '@/components/layout';
Expand All @@ -17,6 +17,12 @@ export default function LoginPage(): React.ReactElement {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [isLoading, setIsLoading] = useState(false);
const [reason, setReason] = useState<string | null>(null);

useEffect(() => {
const params = new URLSearchParams(window.location.search);
setReason(params.get('reason'));
}, []);
const [error, setError] = useState<string | null>(null);

const handleSubmit = async (e: React.FormEvent): Promise<void> => {
Expand Down Expand Up @@ -53,6 +59,12 @@ export default function LoginPage(): React.ReactElement {
<MainLayout>
<div className="flex min-h-[60vh] items-center justify-center">
<div className="w-full max-w-md">
{/* Reason message for redirects */}
{reason === 'live-tv' && (
<div className="mb-4 rounded-lg border border-accent-primary/30 bg-accent-primary/10 px-4 py-3 text-center text-sm text-text-primary">
Sign in to access Live TV — add your IPTV playlists and stream live channels.
</div>
)}
Comment on lines +62 to +67
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because this is a client component page that is still SSR'd, gating the banner on typeof window !== 'undefined' means the server render will never include the banner, but the client render can include it for ?reason=live-tv. That can trigger hydration mismatch warnings and causes a layout shift. Prefer deriving reason from searchParams in a server wrapper (and pass it as a prop), or render the banner only after mount via state set in useEffect (so the first client render matches SSR).

Copilot uses AI. Check for mistakes.
{/* Logo */}
<div className="mb-8 text-center">
<Link href="/" className="inline-block mb-4">
Expand Down
10 changes: 10 additions & 0 deletions src/app/movies/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { Metadata } from 'next';

export const metadata: Metadata = {
title: 'Movies',
description: 'Browse Movies on BitTorrented',
};

export default function Layout({ children }: { children: React.ReactNode }) {
return children;
}
1 change: 1 addition & 0 deletions src/app/movies/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client';


/**
* Movies Page
*
Expand Down
10 changes: 10 additions & 0 deletions src/app/music/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { Metadata } from 'next';

export const metadata: Metadata = {
title: 'Music',
description: 'Browse Music on BitTorrented',
};

export default function Layout({ children }: { children: React.ReactNode }) {
return children;
}
1 change: 1 addition & 0 deletions src/app/music/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client';


/**
* Music Page
*
Expand Down
10 changes: 10 additions & 0 deletions src/app/search/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { Metadata } from 'next';

export const metadata: Metadata = {
title: 'Search',
description: 'Browse Search on BitTorrented',
};

export default function Layout({ children }: { children: React.ReactNode }) {
return children;
}
1 change: 1 addition & 0 deletions src/app/search/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client';


/**
* Search Page
*
Expand Down
10 changes: 10 additions & 0 deletions src/app/trending/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { Metadata } from 'next';

export const metadata: Metadata = {
title: 'Trending',
description: 'Browse Trending on BitTorrented',
};
Comment on lines +3 to +6
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These segment titles include the site name ("— BitTorrented"), but the root metadata defines a title.template of %s | BitTorrented (src/app/layout.tsx). Next.js will apply that template to nested string titles, producing a duplicated site name (e.g., "Trending — BitTorrented | BitTorrented"). Use a bare segment title (e.g., "Trending") or set an absolute title to bypass the template.

Copilot uses AI. Check for mistakes.

export default function Layout({ children }: { children: React.ReactNode }) {
return children;
}
1 change: 1 addition & 0 deletions src/app/trending/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client';


/**
* Trending Page
*
Expand Down
10 changes: 10 additions & 0 deletions src/app/tvshows/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { Metadata } from 'next';

export const metadata: Metadata = {
title: 'TV Shows',
description: 'Browse TV Shows on BitTorrented',
};

export default function Layout({ children }: { children: React.ReactNode }) {
return children;
}
1 change: 1 addition & 0 deletions src/app/tvshows/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client';


/**
* TV Shows Page
*
Expand Down
Loading