The weeb for the next gen discord boat - Wamellow wamellow.com
bot discord
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 224 lines 7.0 kB view raw
1import "./globals.css"; 2import { Header } from "@/components/header"; 3import { LoginButton } from "@/components/login-button"; 4import { Button } from "@/components/ui/button"; 5import { Separator } from "@/components/ui/separator"; 6import Icon from "@/public/icon.svg"; 7import { cn } from "@/utils/cn"; 8import { getBaseUrl } from "@/utils/urls"; 9import type { Metadata, Viewport } from "next"; 10import { Lexend, Noto_Sans_JP, Outfit } from "next/font/google"; 11import { cookies } from "next/headers"; 12import Image from "next/image"; 13import Link from "next/link"; 14import Script from "next/script"; 15import { CookiesProvider } from "next-client-cookies/server"; 16 17import { Provider } from "./provider"; 18 19const outfit = Outfit({ subsets: ["latin", "latin-ext"], variable: "--font-outfit" }); 20const notosansJP = Noto_Sans_JP({ subsets: ["cyrillic", "vietnamese"], variable: "--font-noto-sans-jp" }); 21 22const lexend = Lexend({ weight: "600", subsets: ["latin"] }); 23 24// TODO: get automatically from top.gg 25const reviews = { 26 "@context": "https://schema.org", 27 "@type": "Product", 28 name: "wamellow", 29 aggregateRating: { 30 "@type": "AggregateRating", 31 ratingValue: "5", 32 reviewCount: "110", 33 bestRating: "5" 34 } 35}; 36 37export const viewport: Viewport = { 38 themeColor: "#8957ff", 39 initialScale: 0.85 40}; 41 42export const generateMetadata = (): Metadata => { 43 44 const title = "Wamellow: Next-gen of Discord Bots & Apps"; 45 const description = "Accessibility where it's needed the most: Discord Voice Chats. Social notifications to stay connected and up to date with anyone, anywhere. Simple, customizable, free, and built in public."; 46 47 return { 48 metadataBase: new URL(getBaseUrl()), 49 50 manifest: "/manifest.json", 51 appleWebApp: { 52 capable: true, 53 title: "Wamellow", 54 startupImage: "/waya-v3.webp", 55 statusBarStyle: "black-translucent" 56 }, 57 58 title: { 59 default: title, 60 template: "%s" 61 }, 62 63 description, 64 65 alternates: { 66 canonical: getBaseUrl() 67 }, 68 69 openGraph: { 70 title: { 71 default: title, 72 template: "%s on Wamellow" 73 }, 74 description, 75 type: "website", 76 url: getBaseUrl(), 77 images: `${getBaseUrl()}/waya-v3.webp?v=3` 78 }, 79 80 twitter: { 81 card: "summary", 82 site: "wamellow.com", 83 title, 84 description, 85 images: `${getBaseUrl()}/waya-v3.webp?v=3` 86 }, 87 88 other: { 89 google: "notranslate" 90 }, 91 92 creator: "Luna (shi.gg)", 93 publisher: "Luna (shi.gg)", 94 95 robots: "index, follow" 96 }; 97}; 98 99export default function RootLayout({ children }: { children: React.ReactNode; }) { 100 return ( 101 <CookiesProvider> 102 <html 103 suppressHydrationWarning 104 data-theme="dark" 105 lang="en" 106 className="dark max-w-screen overflow-x-hidden" 107 > 108 <Script 109 defer 110 data-domain="wamellow.com" 111 data-api="/api/event" 112 src="/static/analytics.js" 113 /> 114 115 <Script 116 id="reviews" 117 type="application/ld+json" 118 > 119 {JSON.stringify(reviews)} 120 </Script> 121 122 {process.env.NODE_ENV === "development" && ( 123 <Script src="https://unpkg.com/react-scan/dist/auto.global.js" /> 124 )} 125 126 <body 127 className={cn( 128 "relative top-0 w-full flex justify-center overflow-x-hidden xl:overflow-visible!", 129 outfit.variable, 130 notosansJP.variable 131 )} 132 > 133 <div id="bg" className="absolute top-0 right-0 w-screen h-screen -z-50" /> 134 <Noise /> 135 136 <div className="w-full max-w-7xl"> 137 <NavBar className="w-full" /> 138 <Provider className="w-full">{children}</Provider> 139 </div> 140 </body> 141 </html> 142 </CookiesProvider> 143 ); 144} 145 146function Noise() { 147 return ( 148 <svg 149 className="absolute top-0 left-0 w-screen h-screen -z-40 blur-[1px] saturate-0" 150 viewBox='0 0 142 158' 151 xmlns='http://www.w3.org/2000/svg' 152 > 153 <filter id='noiseFilter'> 154 <feTurbulence 155 type="fractalNoise" 156 baseFrequency="9" 157 numOctaves="1" 158 stitchTiles="stitch" 159 result="turbulence" 160 161 /> 162 <feComponentTransfer> 163 <feFuncR type="table" tableValues="-1 0.2" /> 164 <feFuncG type="table" tableValues="-1 0.2" /> 165 <feFuncB type="table" tableValues="-1 0.2" /> 166 </feComponentTransfer> 167 </filter> 168 169 <rect 170 className="w-screen h-screen" 171 filter='url(#noiseFilter)' 172 /> 173 </svg> 174 ); 175} 176 177async function NavBar({ className }: { className?: string; }) { 178 const jar = await cookies(); 179 180 return ( 181 <nav className={cn("p-4 flex items-center gap-2 text-base text-neutral-300 select-none h-20 relative", className)}> 182 <Link 183 aria-label="Go to Wamellow's homepage" 184 className={cn("font-semibold flex items-center shrink-0 group", lexend.className)} 185 href="/" 186 > 187 <Image src={Icon} alt="wamellow icon" className="size-8 shrink-0 mr-4 pt-1 group-hover:rotate-45 duration-200" /> 188 <span className="text-xl dark:text-neutral-100 text-neutral-900 hidden sm:block">Wamellow</span> 189 </Link> 190 191 <Separator 192 className="h-10 rotate-6 ml-3" 193 orientation="vertical" 194 /> 195 196 <div className="flex shrink-0"> 197 <Button 198 asChild 199 size="sm" 200 variant="ghost" 201 > 202 <Link href="/docs/index"> 203 Documentation 204 </Link> 205 </Button> 206 <Button 207 asChild 208 className="hidden sm:flex" 209 size="sm" 210 variant="ghost" 211 > 212 <Link href="/premium"> 213 Premium 214 </Link> 215 </Button> 216 </div> 217 218 {jar.get("session")?.value 219 ? <Header /> 220 : <LoginButton className="ml-auto" /> 221 } 222 </nav> 223 ); 224}