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 package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"@noriginmedia/norigin-spatial-navigation": "^3.3.0",
"@profullstack/autoblog": "https://codeload.github.com/profullstack/autoblog/tar.gz/75e54af",
"@profullstack/emailer": "^1.0.3",
"@profullstack/footer": "latest",
"@profullstack/notifications": "^0.1.4",
"@profullstack/player": "0.13.2",
"@profullstack/referrals": "^0.1.0",
Expand Down
17 changes: 17 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions src/app/invite-only/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { inviteMetadata } from '@/lib/invite-metadata';
import { Webring } from '@/components/layout/webring';
import { SiteFooter } from '@/components/layout/site-footer';

export const metadata = inviteMetadata('Invite only');

/**
* While the site is invite only, `/` answers 307 here, so this screen is the homepage
* the Profullstack ring's verifier sees: it carries the ring links, server-rendered.
* the Profullstack ring's verifier sees: it carries the site footer and its ring links, server-rendered.
*/
export default function InviteOnlyLayout({ children }: { children: React.ReactNode }): React.ReactNode {
return (
<>
{children}
<footer className="bg-bg-primary px-4 pb-6 text-center text-sm text-text-secondary">
<Webring className="webring" />
</footer>
<div className="bg-bg-primary text-text-secondary">
<SiteFooter />
</div>
</>
);
}
6 changes: 5 additions & 1 deletion src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import Script from 'next/script';
import './globals.css';
import { TvLayoutProvider } from '@/components/layout';
import { Providers } from '@/components/providers';
import { SiteFooter } from '@/components/layout/site-footer';
import { SiteFooterProvider } from '@/components/layout/site-footer-context';

const inter = Inter({
subsets: ['latin'],
Expand Down Expand Up @@ -112,7 +114,9 @@ export default function RootLayout({ children }: RootLayoutProps): React.ReactEl
<body className="min-h-screen bg-bg-primary font-sans antialiased">
<Providers>
<TvLayoutProvider>
<ReferralProvider>{children}</ReferralProvider>
<ReferralProvider>
<SiteFooterProvider footer={<SiteFooter />}>{children}</SiteFooterProvider>
</ReferralProvider>
</TvLayoutProvider>
</Providers>

Expand Down
26 changes: 6 additions & 20 deletions src/components/layout/main-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { cn } from '@/lib/utils';
import { Sidebar } from './sidebar';
import { Header } from './header';
import { useAuth } from '@/hooks/use-auth';
import { Webring } from '@/components/layout/webring';
import { useSiteFooter } from '@/components/layout/site-footer-context';

interface MainLayoutProps {
children: React.ReactNode;
Expand All @@ -23,6 +23,7 @@ interface MainLayoutProps {

export function MainLayout({ children, className }: MainLayoutProps): React.ReactElement {
const router = useRouter();
const siteFooter = useSiteFooter();
const pathname = usePathname();
const { isLoggedIn, isPremium, user, clearAuth, needsProfileSelection, isLoading, activeProfile } = useAuth();

Expand Down Expand Up @@ -72,26 +73,11 @@ export function MainLayout({ children, className }: MainLayoutProps): React.Reac
</main>

{/* Footer */}
<footer className="border-t border-border-primary px-4 py-4 text-center text-sm text-text-secondary md:px-6">
<span>&copy; {new Date().getFullYear()} Media Streamer</span>
<span className="mx-2">&middot;</span>
<a
href="mailto:support@bittorrented.com?subject=BitTorrented"
className="text-accent-primary hover:text-accent-primary/80 transition-colors"
>
Contact Us
</a>
<span className="mx-2">·</span>
<a href="/terms" className="hover:text-text-primary transition-colors">Terms</a>
<span className="mx-2">·</span>
<a href="/privacy" className="hover:text-text-primary transition-colors">Privacy</a>
<span className="mx-2">·</span>
<a href="https://github.com/profullstack/media-streamer" target="_blank" rel="noopener noreferrer" className="hover:text-text-primary transition-colors">GitHub</a>

<Webring />
<div className="text-text-secondary">
{siteFooter}

{/* Launchpadly badge */}
<div className="mt-3">
<div className="pb-4 text-center">
<a
href="https://launchpadly.co/startup/bittorrented?ref=badge"
target="_blank"
Expand All @@ -109,7 +95,7 @@ export function MainLayout({ children, className }: MainLayoutProps): React.Reac
/>
</a>
</div>
</footer>
</div>
</div>
</div>
);
Expand Down
17 changes: 17 additions & 0 deletions src/components/layout/site-footer-context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use client';

import { createContext, useContext } from 'react';

/**
* Carries the server-rendered SiteFooter (site-footer.tsx) from the root layout to
* client layouts such as MainLayout, which cannot render an async server component.
*/
const SiteFooterContext = createContext<React.ReactNode>(null);

export function SiteFooterProvider({ footer, children }: { footer: React.ReactNode; children: React.ReactNode }): React.ReactNode {
return <SiteFooterContext.Provider value={footer}>{children}</SiteFooterContext.Provider>;
}

export function useSiteFooter(): React.ReactNode {
return useContext(SiteFooterContext);
}
24 changes: 24 additions & 0 deletions src/components/layout/site-footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Footer } from '@profullstack/footer/react';

/**
* The site footer: @profullstack/footer (links, copyright and the Profullstack
* webring). An async server component: it renders on the server, where the ring's
* verifier reads it, and fetches the package's @latest template so a footer release
* reaches the site without a redeploy.
*
* MainLayout is a client component, so it cannot render this itself: the root
* layout renders it once and hands it down through SiteFooterProvider.
*/
export function SiteFooter(): React.ReactNode {
return (
<Footer
site="https://bittorrented.com/"
links={[
{ label: 'Contact Us', href: 'mailto:support@bittorrented.com?subject=BitTorrented' },
{ label: 'Terms', href: '/terms' },
{ label: 'Privacy', href: '/privacy' },
{ label: 'GitHub', href: 'https://github.com/profullstack/media-streamer' },
]}
/>
);
}
33 changes: 0 additions & 33 deletions src/components/layout/webring.tsx

This file was deleted.

Loading