diff --git a/apps/www/src/app/(main)/server/v2/minehut/[server]/page.tsx b/apps/www/src/app/(main)/server/v2/minehut/[server]/page.tsx index 954e707..2cda2db 100644 --- a/apps/www/src/app/(main)/server/v2/minehut/[server]/page.tsx +++ b/apps/www/src/app/(main)/server/v2/minehut/[server]/page.tsx @@ -1,5 +1,5 @@ import { ServerProvider } from "@/components/feat/server-page/server-provider"; -import { ServerResponse } from "@/lib/types/mh-server"; +import type { ServerResponse } from "@/lib/types/mh-server"; import type { Metadata } from "next"; import { notFound } from "next/navigation"; diff --git a/apps/www/src/app/(sl-modification-frame)/servers/embedded/sl-modification-frame/files/page.tsx b/apps/www/src/app/(sl-modification-frame)/servers/embedded/sl-modification-frame/files/page.tsx index b5a7af6..93e83cf 100644 --- a/apps/www/src/app/(sl-modification-frame)/servers/embedded/sl-modification-frame/files/page.tsx +++ b/apps/www/src/app/(sl-modification-frame)/servers/embedded/sl-modification-frame/files/page.tsx @@ -46,7 +46,6 @@ import { ArrowLeft, Braces, EllipsisVertical, - File, FileCode, Pencil, Trash, @@ -76,7 +75,7 @@ export default function ServerListModificationFrame() { {files.map((c, i) => ( @@ -88,7 +87,7 @@ export default function ServerListModificationFrame() { + diff --git a/apps/www/src/components/feat/server-list/server-list.tsx b/apps/www/src/components/feat/server-list/server-list.tsx index 8d56e3e..4340aa9 100644 --- a/apps/www/src/components/feat/server-list/server-list.tsx +++ b/apps/www/src/components/feat/server-list/server-list.tsx @@ -36,13 +36,14 @@ import { Separator } from "@/components/ui/separator"; import { Statistics } from "./statistics"; import InfiniteScroll from "react-infinite-scroll-component"; import { useInfiniteScrolling } from "@/lib/hooks/use-infinite-scrolling"; -import { useMHSFServer } from "@/lib/hooks/use-mhsf-multiple"; import { ModificationButton } from "./modification/modification-button"; import { useFilters } from "@/lib/hooks/use-filters"; +import { ServerTestModeSelector } from "./server-test-mode-selector"; export function ServerList() { const { servers, loading, serverCount, playerCount } = useServers(); - const { filteredData } = useFilters(servers); + const { filteredData, testModeEnabled, testModeLoading, testModeStatus } = + useFilters(servers); const { itemsLength, fetchMoreData, hasMoreData, data } = useInfiniteScrolling(filteredData); @@ -67,7 +68,14 @@ export function ServerList() {

Servers

- +
+ + +
+ + + + + + + Test mode was enabled. + + + + ); + + return null; +} diff --git a/apps/www/src/components/ui/animated-text.tsx b/apps/www/src/components/ui/animated-text.tsx index be10d5c..50fdd01 100644 --- a/apps/www/src/components/ui/animated-text.tsx +++ b/apps/www/src/components/ui/animated-text.tsx @@ -6,9 +6,10 @@ import { cn } from "@/lib/utils"; interface AnimatedTextProps { text: string; className?: string; + glimmer?: boolean; } -export function AnimatedText({ text, className }: AnimatedTextProps) { +export function AnimatedText({ text, className, glimmer }: AnimatedTextProps) { const [currentText, setCurrentText] = useState(text); useEffect(() => { @@ -24,7 +25,9 @@ export function AnimatedText({ text, className }: AnimatedTextProps) { animate={{ y: 0, opacity: 1 }} exit={{ y: -20, opacity: 0 }} transition={{ duration: 0.3 }} - className={cn("absolute left-0", className)} + className={cn("absolute left-0", className, { + "loading-shimmer": glimmer, + })} > {currentText} diff --git a/apps/www/src/lib/hooks/use-filters.tsx b/apps/www/src/lib/hooks/use-filters.tsx index d2bc0a7..6d143b9 100644 --- a/apps/www/src/lib/hooks/use-filters.tsx +++ b/apps/www/src/lib/hooks/use-filters.tsx @@ -39,6 +39,8 @@ export function useFilters(data: OnlineServer[]) { const [filteredData, setFilteredData] = useState(data); const [t] = useQueryState("tm"); const [testModeEnabled, setTestModeEnabled] = useState(false); + const [testModeStatus, setTestModeStatus] = useState("Haven't connected thread yet (if stuck, select the other tab, and come back)"); + const [testModeLoading, setTestModeLoading] = useState(true); useEffect(() => { if (filteredData.length === 0) setFilteredData(data); @@ -54,68 +56,91 @@ export function useFilters(data: OnlineServer[]) { setTestModeEnabled(true); const code = atob(t); (async () => { - toast.info("Transpiling TypeScript..."); + setTestModeStatus("Transpiling TypeScript..."); const startTime = Date.now(); const { error, data: transpiledCode } = await tryCatch( (async () => transpileTypeScript(code))() ); if (error) { - toast.error( + setTestModeStatus( "Failed to transpile TypeScript! Error: " + error.message ); + setTestModeLoading(false); return; } if (transpiledCode === null) { - toast.error("Cannot continue."); + setTestModeStatus("Cannot continue."); + setTestModeLoading(false); return; } console.log( "[MHSF Filters] Transpiled TypeScript:", transpiledCode ?? "" ); - toast.info("Generating function..."); - const functionBody = transpiledCode.match( - /function\s+filter\s*\([^)]*\)\s*\{([\s\S]*)\}/ - )?.[1]; + setTestModeStatus("Generating function..."); + if ( + !transpiledCode.includes("export default") && + !transpiledCode.includes("export") + ) { + setTestModeStatus( + "Transpiled code does not contain any export statements." + ); + setTestModeLoading(false); + return; + } + const functionBody = transpiledCode + .replace(/export default(?!.*[;])/g, "") // Avoid replacing if followed by a semicolon + .replace(/export(?!.*[;])/g, ""); // Avoid replacing if followed by a semicolon const { error: filterErr, data: filterFunc } = await tryCatch( - (async () => new Function("server", functionBody as string))() + (async () => + new Function( + "server", + `${functionBody} + + return filter(server)` + ))() ); if (filterErr) { - toast.error( + setTestModeStatus( `Failed to generate function! Error: ${filterErr.message}` ); + setTestModeLoading(false); return; } if (typeof filterFunc === "function") { - toast.success("Compiled in " + (Date.now() - startTime) + "ms"); + setTestModeStatus( + "Compiled in " + (Date.now() - startTime) + "ms" + ); toast.promise( async () => { let newServers = []; newServers = data.filter((c) => filterFunc(c)); - toast.info( + setTestModeStatus( "Server count " + data.length + " -> " + newServers.length ); setFilteredData(() => [...newServers]); + setTestModeLoading(false); }, { loading: "Manipulating data...", success: "Manipulated data; test mode finished!", error: (e) => - `Error while manipulating data; go back to your editor and run again. ${es}`, + `Error while manipulating data; go back to your editor and run again. ${e}`, } ); } else { - toast.error( + setTestModeStatus( "Code doesn't have a 'filter' function. Cannot be tested." ); - toast.error(typeof filterFunc); + setTestModeLoading(false); } })(); } }); }, [t, data]); - console.log(filteredData); + console.log(filteredData, testModeStatus); - return { filteredData, testModeEnabled }; + return { filteredData, testModeEnabled, testModeLoading, testModeStatus }; } + \ No newline at end of file diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..3270c88 --- /dev/null +++ b/biome.json @@ -0,0 +1,12 @@ +{ + "$schema": "./node_modules/@biomejs/biome/configuration_schema.json", + "linter": { + "rules": { + "style": { + "useImportType": { + "level": "warn" + } + } + } + } +}