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

Configure Feed

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

fix eslint issues

Luna 979749a6 dc5f54a6

+102 -92
+7 -6
app/(dynamic-assets)/favicon.ico/route.ts
··· 1 + import sharp from "sharp"; 2 + 1 3 import { getUser } from "@/lib/discord/user"; 2 - import sharp from "sharp"; 3 4 4 5 export async function GET() { 5 6 const user = await getUser(process.env.CLIENT_ID!); ··· 8 9 ? user.avatarUrl + "?size=64" 9 10 : "https://cdn.discordapp.com/embed/avatars/5.png" 10 11 ) 11 - .then(r => r.arrayBuffer()) 12 + .then((r) => r.arrayBuffer()); 12 13 13 14 const { data, info } = await sharp(Buffer.from(avatar)) 14 15 .resize(64, 64) ··· 23 24 const icon = await sharp(data) 24 25 .composite([{ 25 26 input: Buffer.from(svgCircle), 26 - blend: 'dest-in' 27 + blend: "dest-in" 27 28 }]) 28 29 .toFormat("png") 29 30 .toBuffer(); ··· 33 34 icon, 34 35 { 35 36 headers: { 36 - 'Content-Type': 'image/png' 37 + "Content-Type": "image/png" 37 38 } 38 39 } 39 - ) 40 - } 40 + ); 41 + }
+1 -1
app/(dynamic-assets)/luna.webp/route.ts
··· 7 7 ? user.avatarUrl + "?size=1024" 8 8 : "https://cdn.discordapp.com/embed/avatars/5.png" 9 9 ); 10 - } 10 + }
+1 -1
app/(dynamic-assets)/waya-v3.webp/route.ts
··· 7 7 ? user.avatarUrl + "?size=1024" 8 8 : "https://cdn.discordapp.com/embed/avatars/5.png" 9 9 ); 10 - } 10 + }
+2 -2
app/(home)/debug/page.tsx
··· 7 7 import { ServerButton } from "@/components/server-button"; 8 8 import { Shiggy } from "@/components/shiggy"; 9 9 import { getBaseUrl, getCanonicalUrl } from "@/utils/urls"; 10 + 10 11 import Panel from "./panel.component"; 11 12 12 13 export const generateMetadata = async (): Promise<Metadata> => { ··· 138 139 <Shiggy className="mt-auto h-52" /> 139 140 </div> 140 141 ); 141 - } 142 - 142 + }
+1 -1
app/(home)/debug/panel.component.tsx
··· 36 36 37 37 {children} 38 38 </div> 39 - ) 39 + ); 40 40 }
+1 -1
app/(home)/debug/row.component.tsx
··· 24 24 25 25 {children} 26 26 </div> 27 - ) 27 + ); 28 28 }
+1 -1
app/(home)/faq.component.tsx
··· 163 163 </Accordion> 164 164 </div> 165 165 ); 166 - } 166 + }
+1 -1
app/(home)/privacy/page.tsx
··· 1 1 import { Metadata } from "next"; 2 2 import React from "react"; 3 3 4 - import BeautifyMarkdown from "@/components/markdown"; 5 4 import { CopyToClipboardButton } from "@/components/copy-to-clipboard"; 5 + import BeautifyMarkdown from "@/components/markdown"; 6 6 import { getBaseUrl, getCanonicalUrl } from "@/utils/urls"; 7 7 8 8 export const generateMetadata = async (): Promise<Metadata> => {
+1 -1
app/(home)/terms/page.tsx
··· 1 1 import { Metadata } from "next"; 2 2 import React from "react"; 3 3 4 - import BeautifyMarkdown from "@/components/markdown"; 5 4 import { CopyToClipboardButton } from "@/components/copy-to-clipboard"; 5 + import BeautifyMarkdown from "@/components/markdown"; 6 6 import { getBaseUrl, getCanonicalUrl } from "@/utils/urls"; 7 7 8 8 export const generateMetadata = async (): Promise<Metadata> => {
+12 -11
app/ai-gallery/generate/page.tsx
··· 2 2 3 3 import { Button, Image, Spinner } from "@nextui-org/react"; 4 4 import NextImage from "next/image"; 5 + import { useRouter, useSearchParams } from "next/navigation"; 6 + import { useCookies } from "next-client-cookies"; 7 + import { useEffect, useState } from "react"; 8 + import { HiPrinter } from "react-icons/hi"; 5 9 6 10 import DumbTextInput from "@/components/inputs/dumb-text-input"; 7 - import { useEffect, useState } from "react"; 8 - import { useRouter, useSearchParams } from "next/navigation"; 11 + import LinkTag from "@/components/link-tag"; 9 12 import Notice from "@/components/notice"; 10 - import UploadButton from "./upload.component"; 11 - import { HiPrinter } from "react-icons/hi"; 13 + import cn from "@/utils/cn"; 14 + 12 15 import Time from "./time.component"; 13 - import LinkTag from "@/components/link-tag"; 14 - import cn from "@/utils/cn"; 15 - import { useCookies } from "next-client-cookies"; 16 + import UploadButton from "./upload.component"; 16 17 17 18 enum State { 18 19 Idle = 0, ··· 21 22 22 23 export default function Home() { 23 24 const cookies = useCookies(); 24 - const search = useSearchParams() 25 + const search = useSearchParams(); 25 26 const router = useRouter(); 26 27 27 28 const imageUrl = search.get("image_url"); ··· 40 41 .then((res) => res.json() as Promise<{ gpu: string }>) 41 42 .then((res) => { 42 43 setError(null); 43 - setGpu(res.gpu || null) 44 + setGpu(res.gpu || null); 44 45 }) 45 46 .catch((err) => { 46 - setError(`Could not fetch local GPU instance (${err.toString()})`) 47 + setError(`Could not fetch local GPU instance (${err.toString()})`); 47 48 }); 48 49 }, [baseUrl]); 49 50 ··· 55 56 router.push(`?${params.toString()}`, { scroll: false }); 56 57 57 58 const reqparams = new URLSearchParams({ 58 - prompt: prompt, 59 + prompt: prompt 59 60 }); 60 61 61 62 const res = await fetch(`${baseUrl}/generate/image/${model}?${reqparams.toString()}`)
+2 -2
app/ai-gallery/generate/time.component.tsx
··· 14 14 if (loading === previousLoading) return; 15 15 16 16 if (!previousLoading && loading) setEstimatedTime(0); 17 - setPreviousLoading(loading) 17 + setPreviousLoading(loading); 18 18 19 19 if (!loading) { 20 20 if (intervalRef.current) clearInterval(intervalRef.current); ··· 30 30 <span className="inline"> 31 31 {(estimatedTime / 1000).toFixed(1)}s 32 32 </span> 33 - ) 33 + ); 34 34 }
+4 -4
app/ai-gallery/generate/upload.component.tsx
··· 1 1 "use client"; 2 2 3 3 import { Button, Checkbox } from "@nextui-org/react"; 4 + import { useSearchParams } from "next/navigation"; 4 5 import { useCookies } from "next-client-cookies"; 5 - 6 6 import { useEffect, useState } from "react"; 7 - import { useSearchParams } from "next/navigation"; 7 + import { HiCloudUpload } from "react-icons/hi"; 8 + 8 9 import { ApiV1UploadGetResponse } from "@/typings"; 9 - import { HiCloudUpload } from "react-icons/hi"; 10 10 import cn from "@/utils/cn"; 11 11 12 12 enum State { ··· 22 22 model: string; 23 23 prompt: string; 24 24 }) { 25 - const search = useSearchParams() 25 + const search = useSearchParams(); 26 26 const cookies = useCookies(); 27 27 28 28 const imageUrl = search.get("image_url");
app/dashboard/[guildId]/dailyposts/page.tsx

This is a binary file and will not be displayed.

+1 -1
app/dashboard/[guildId]/greeting/welcome/page.tsx
··· 16 16 import SelectMenu from "@/components/inputs/select-menu"; 17 17 import Switch from "@/components/inputs/switch"; 18 18 import Notice from "@/components/notice"; 19 - import { ApiV1GuildsModulesWelcomeGetResponse, RouteErrorResponse } from "@/typings"; 20 19 import { Section } from "@/components/section"; 20 + import { ApiV1GuildsModulesWelcomeGetResponse, RouteErrorResponse } from "@/typings"; 21 21 22 22 export default function Home() { 23 23 const guild = guildStore((g) => g);
+1 -1
app/dashboard/[guildId]/notifications/channel-selector.component.tsx
··· 156 156 157 157 </div> 158 158 </div> 159 - ) 159 + ); 160 160 }
+2 -2
app/dashboard/[guildId]/notifications/page.tsx
··· 1 1 "use client"; 2 2 3 + import { Button } from "@nextui-org/react"; 3 4 import Image from "next/image"; 5 + import Link from "next/link"; 4 6 import { useParams, usePathname, useRouter, useSearchParams } from "next/navigation"; 5 7 import { useCallback } from "react"; 6 8 import { HiArrowLeft, HiChat, HiExternalLink, HiViewGridAdd } from "react-icons/hi"; ··· 16 18 import { ApiV1GuildsModulesNotificationsGetResponse } from "@/typings"; 17 19 18 20 import { ChannelSelector } from "./channel-selector.component"; 19 - import { Button } from "@nextui-org/react"; 20 - import Link from "next/link"; 21 21 22 22 export default function Home() { 23 23 const guild = guildStore((g) => g);
+1 -1
app/profile/rank/card-style.component.tsx
··· 199 199 width={64} 200 200 /> 201 201 ); 202 - } 202 + }
+4 -3
app/profile/rank/leaderboard-style.component.tsx
··· 1 + import { useState } from "react"; 2 + 1 3 import { userStore } from "@/common/user"; 2 4 import { User } from "@/common/user"; 3 - import { ApiError, ApiV1UsersMeGetResponse, ApiV1UsersGetResponse } from "@/typings"; 5 + import { ApiError,ApiV1UsersMeGetResponse } from "@/typings"; 4 6 import cn from "@/utils/cn"; 5 7 import { deepMerge } from "@/utils/deepMerge"; 6 - import { useState } from "react"; 7 8 8 9 export default function LeaderboardStyle() { 9 10 const user = userStore((s) => s); ··· 98 99 <div key={i} className="flex gap-2"> 99 100 <div 100 101 className={cn( 101 - `duration-200 h-4 w-4 aspect-square rounded-full`, 102 + "duration-200 h-4 w-4 aspect-square rounded-full", 102 103 !user?.extended?.rank?.useLeaderboardList 103 104 ? "dark:bg-neutral-700/90 dark:group-hover:bg-neutral-400/60 bg-neutral-300/90 group-hover:bg-neutral-600/60" 104 105 : "dark:bg-violet-400/50 dark:group-hover:bg-violet-400/70 bg-violet-600/50 group-hover:bg-violet-600/70"
+4 -2
app/user/[userId]/layout.tsx
··· 1 - import ImageReduceMotion from "@/components/image-reduce-motion"; 2 1 import { Image } from "@nextui-org/react"; 3 - import { getUser } from "./api"; 2 + 3 + import ImageReduceMotion from "@/components/image-reduce-motion"; 4 4 import paintPic from "@/public/paint.webp"; 5 + 6 + import { getUser } from "./api"; 5 7 import Side from "./side.component"; 6 8 7 9 interface Props {
+2 -2
app/user/[userId]/page.tsx
··· 7 7 export const revalidate = 60 * 60; 8 8 9 9 export default async function Home({ 10 - params, 10 + params 11 11 }: Props) { 12 12 const user = await getUser(params.userId); 13 13 ··· 15 15 <> 16 16 <i>User has no bio yet</i> 17 17 </> 18 - ) 18 + ); 19 19 }
+5 -4
app/user/[userId]/side.component.tsx
··· 1 1 "use client"; 2 2 3 - import { ClientCountUp } from "@/components/counter"; 4 - import { ApiV1UsersGetResponse, RouteErrorResponse } from "@/typings"; 5 3 import { Accordion, AccordionItem, Skeleton } from "@nextui-org/react"; 6 4 import { useCookies } from "next-client-cookies"; 7 5 import { HiAnnotation, HiLink, HiVolumeUp } from "react-icons/hi"; 6 + 7 + import { ClientCountUp } from "@/components/counter"; 8 + import { ApiV1UsersGetResponse, RouteErrorResponse } from "@/typings"; 8 9 9 10 export default function Side({ 10 11 user ··· 62 63 } 63 64 </div> 64 65 </div> 65 - ) 66 + ); 66 67 } 67 68 68 69 return ( ··· 86 87 </AccordionItem> 87 88 </Accordion> 88 89 </div> 89 - ) 90 + ); 90 91 }
+1 -1
components/copy-to-clipboard.tsx
··· 30 30 31 31 if (timeoutRef.current) clearInterval(timeoutRef.current); 32 32 timeoutRef.current = setTimeout(() => setSaved(false), 1000 * 2); 33 - }; 33 + } 34 34 35 35 return ( 36 36 <ButtonGroup
+8 -6
components/discord/markdown.tsx
··· 4 4 import { renderToString } from "react-dom/server"; 5 5 import ReactMarkdown from "react-markdown"; 6 6 import rehypeRaw from "rehype-raw"; 7 + 8 + import cn from "@/utils/cn"; 9 + 10 + import Channel from "../markdown/channel"; 7 11 import Emoji from "../markdown/emoji"; 8 12 import User from "../markdown/user"; 9 - import Channel from "../markdown/channel"; 10 - import cn from "@/utils/cn"; 11 13 12 14 interface Props { 13 15 text: string; ··· 31 33 <span 32 34 className={cn( 33 35 mode === "DARK" ? "bg-wamellow text-neutral-200" : "bg-wamellow-100 text-neutral-800", 34 - 'border-1 border-violet-400 px-[3px] rounded-md font-light' 36 + "border-1 border-violet-400 px-[3px] rounded-md font-light" 35 37 )} 36 38 > 37 39 {match.slice(1, -1)} ··· 48 50 }) 49 51 .replace(/<(#!?)\d{15,21}>/g, () => { 50 52 return renderToString(<Channel name="some-channel" />); 51 - }) 53 + }); 52 54 } 53 55 54 56 if (!discord) return ( ··· 91 93 <div 92 94 className={cn( 93 95 mode === "DARK" ? "bg-neutral-900" : "bg-neutral-200", 94 - 'px-4 py-3 text-sm rounded-md min-w-full max-w-full my-2 break-all' 96 + "px-4 py-3 text-sm rounded-md min-w-full max-w-full my-2 break-all" 95 97 )} 96 98 > 97 99 {children} ··· 110 112 </code> 111 113 ); 112 114 }, 113 - p: (props) => <p className="mb-4" {...props} />, 115 + p: (props) => <p className="mb-4" {...props} /> 114 116 }} 115 117 > 116 118 {parseDiscordMarkdown(text)}
+1 -1
components/discord/message-embed.tsx
··· 36 36 footer, 37 37 mode 38 38 }: Props) { 39 - console.log(children) 39 + console.log(children); 40 40 if (!title && !image && !footer?.text && (!children || children.toString() === ",false" || (Array.isArray(children) && !children.filter(Boolean).length))) return <></>; 41 41 42 42 return (
-1
components/discord/message.tsx
··· 103 103 </div> 104 104 </div> 105 105 106 - 107 106 </div> 108 107 ); 109 108 }
+1 -1
components/inputs/request.ts
··· 37 37 const response = await res?.json() 38 38 .catch(() => null); 39 39 40 - onError((response as unknown as RouteErrorResponse | null)?.message || "unknown server error") 40 + onError((response as unknown as RouteErrorResponse | null)?.message || "unknown server error"); 41 41 }
+2 -2
components/inputs/slider-input.tsx
··· 2 2 import { useState } from "react"; 3 3 import { TailSpin } from "react-loading-icons"; 4 4 5 - import { RouteErrorResponse } from "@/typings"; 6 5 import cn from "@/utils/cn"; 6 + 7 7 import { request } from "./request"; 8 8 9 9 enum State { ··· 43 43 44 44 url, 45 45 dataName, 46 - defaultState, 46 + defaultState 47 47 }: Props) { 48 48 const [state, setState] = useState<State>(State.Idle); 49 49 const [error, setError] = useState<string | null>(null);
+6 -6
components/list.tsx
··· 3 3 import { Tab, Tabs } from "@nextui-org/react"; 4 4 import { usePathname, useRouter, useSearchParams } from "next/navigation"; 5 5 import React, { useEffect, useRef, useState } from "react"; 6 + import { HiChevronLeft, HiChevronRight } from "react-icons/hi"; 6 7 7 8 import decimalToRgb from "@/utils/decimalToRgb"; 8 - import { HiChevronLeft, HiChevronRight } from "react-icons/hi"; 9 9 10 10 interface ListProps { 11 11 tabs: { ··· 51 51 left: direction === "right" 52 52 ? ref.current.clientWidth - position 53 53 : -position, 54 - behavior: 'smooth', 54 + behavior: "smooth" 55 55 }); 56 - }; 56 + } 57 57 58 58 function setScrollPosition() { 59 59 if (!ref.current) return; 60 60 const { scrollLeft } = ref.current; 61 61 setPosition(scrollLeft); 62 - }; 62 + } 63 63 64 64 useEffect(() => { 65 65 if (!ref.current) return; 66 66 67 - ref.current.addEventListener('scroll', setScrollPosition); 67 + ref.current.addEventListener("scroll", setScrollPosition); 68 68 setScrollPosition(); 69 69 70 70 return () => { 71 - ref.current?.removeEventListener('scroll', setScrollPosition); 71 + ref.current?.removeEventListener("scroll", setScrollPosition); 72 72 }; 73 73 }, []); 74 74
+2 -2
components/markdown/channel.tsx
··· 7 7 <span className='bg-blurple/25 hover:bg-blurple/50 p-1 rounded-md dark:text-neutral-100 text-neutral-900 font-light text-sx duration-200 cursor-pointer'> 8 8 #{name} 9 9 </span> 10 - ) 11 - }; 10 + ); 11 + }
+1 -1
components/markdown/emoji.tsx
··· 9 9 className='rounded-md inline h-5 w-5' 10 10 src={`https://cdn.discordapp.com/emojis/${emojiId}.webp?size=40&quality=lossless`} 11 11 /> 12 - ) 12 + ); 13 13 }
+11 -10
components/markdown/index.tsx
··· 1 1 /* eslint-disable @typescript-eslint/no-unused-vars */ 2 - import { getBaseUrl } from "@/utils/urls"; 3 2 import { Code } from "@nextui-org/react"; 4 3 import Link from "next/link"; 4 + import { ReactNode } from "react"; 5 5 import { HiExternalLink } from "react-icons/hi"; 6 6 import ReactMarkdown from "react-markdown"; 7 7 import rehypeRaw from "rehype-raw"; 8 - import Notice, { NoticeType } from "../notice"; 9 8 10 9 import { getUser } from "@/lib/discord/user"; 10 + import cn from "@/utils/cn"; 11 11 import { filterDuplicates } from "@/utils/filter-duplicates"; 12 - import cn from "@/utils/cn"; 12 + import { getBaseUrl } from "@/utils/urls"; 13 + 14 + import Notice, { NoticeType } from "../notice"; 15 + import Channel from "./channel"; 13 16 import Emoji from "./emoji"; 17 + import Timestamp from "./timestamp"; 14 18 import User from "./user"; 15 - import Channel from "./channel"; 16 - import { ReactNode } from "react"; 17 - import Timestamp from "./timestamp"; 18 19 19 20 const ALLOWED_IFRAMES = [ 20 21 "https://www.youtube.com/embed/", ··· 65 66 format={format.slice(1, -1)} 66 67 /> 67 68 ); 68 - }) 69 + }); 69 70 } 70 71 71 72 function createHId(text: ReactNode) { ··· 138 139 <img alt={alt} className="rounded-md" loading="lazy" {...props} /> 139 140 {alt && alt !== "emoji" && <span aria-hidden="true" className="text-neutral-500 font-medium relative bottom-1">{alt}</span>} 140 141 </span> 141 - ) 142 + ); 142 143 }, 143 144 a: ({ href, children, ...props }) => ( 144 145 <Link ··· 167 168 )} 168 169 {...props} 169 170 /> 170 - ) 171 + ); 171 172 } 172 173 173 174 return ( ··· 177 178 message={`Iframe from "${props.src?.split("/")[2]}" is not allowed`} 178 179 /> 179 180 </div> 180 - ) 181 + ); 181 182 }, 182 183 183 184 ol: ({ ordered, ...props }) => <ol className="list-decimal list-inside space-y-1 marker:text-neutral-300/40 my-1" {...props} />,
+3 -3
components/markdown/timestamp.tsx
··· 7 7 unix: number; 8 8 format: string; 9 9 }) { 10 - const date = new Date(unix * 1000) 10 + const date = new Date(unix * 1000); 11 11 const str = getDateString(date, format); 12 12 13 13 return ( 14 14 <span className='bg-neutral-300/10 hover:bg-neutral-300/25 p-1 rounded-md dark:text-neutral-100 text-neutral-900 font-light text-sx duration-200 cursor-pointer'> 15 15 {str} 16 16 </span> 17 - ) 18 - }; 17 + ); 18 + }
+2 -2
components/markdown/user.tsx
··· 7 7 <span className='bg-blurple/25 hover:bg-blurple/50 p-1 rounded-md dark:text-neutral-100 text-neutral-900 font-light text-sx duration-200 cursor-pointer'> 8 8 @{username} 9 9 </span> 10 - ) 11 - }; 10 + ); 11 + }
+2 -1
components/section.tsx
··· 1 + import { Divider } from "@nextui-org/react"; 2 + 1 3 import cn from "@/utils/cn"; 2 - import { Divider } from "@nextui-org/react"; 3 4 4 5 export function Section({ 5 6 title,
+5 -5
postcss.config.js
··· 1 1 module.exports = { 2 - plugins: { 3 - tailwindcss: {}, 4 - autoprefixer: {}, 5 - }, 6 - } 2 + plugins: { 3 + tailwindcss: {}, 4 + autoprefixer: {} 5 + } 6 + };
+1 -1
utils/time.ts
··· 1 1 export function convertMonthToName(monthNumber: number) { 2 2 const months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; 3 3 return months[monthNumber]; 4 - }; 4 + } 5 5 6 6 export function convertDayToName(dayNumber: number) { 7 7 const days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];