mirror of
https://github.com/DeveloLongScript/MHSF.git
synced 2026-05-07 16:05:00 -05:00
feat: add new embeds
This commit is contained in:
parent
bdf5b9b52e
commit
ddea87ccf8
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Ignore everything for IntelliJ except for project essential code-styles
|
||||||
|
*
|
||||||
|
|
||||||
|
!copyright/*
|
||||||
|
!codeStyles/*
|
||||||
|
!.gitignore
|
||||||
|
|
||||||
|
!*/
|
||||||
7
.idea/codeStyles/Project.xml
generated
Normal file
7
.idea/codeStyles/Project.xml
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<code_scheme name="Project" version="173">
|
||||||
|
<JSCodeStyleSettings version="0">
|
||||||
|
<option name="SPACES_WITHIN_IMPORTS" value="true" />
|
||||||
|
</JSCodeStyleSettings>
|
||||||
|
</code_scheme>
|
||||||
|
</component>
|
||||||
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<state>
|
||||||
|
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||||
|
</state>
|
||||||
|
</component>
|
||||||
6
.vscode/.gitignore
vendored
Normal file
6
.vscode/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Ignore everything for VSCode except for project essential code-styles
|
||||||
|
*
|
||||||
|
|
||||||
|
!extensions.json
|
||||||
|
!settings.json
|
||||||
|
!.gitignore
|
||||||
5
.vscode/extensions.json
vendored
Normal file
5
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"recommendations": [
|
||||||
|
"sarfrajansari.copyright-header-injector"
|
||||||
|
]
|
||||||
|
}
|
||||||
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"copyright-header-injector.copyrightText": "/*\n * MHSF, Minehut Server List\n * All external content is rather licensed under the ECA Agreement\n * located here: https://mhsf.app/docs/legal/external-content-agreement\n *\n * All code under MHSF is licensed under the MIT License\n * by open source contributors\n *\n * Copyright (c) 2024 dvelo\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */"
|
||||||
|
}
|
||||||
@ -25,6 +25,7 @@
|
|||||||
"@radix-ui/react-icons": "^1.3.0",
|
"@radix-ui/react-icons": "^1.3.0",
|
||||||
"@radix-ui/react-menubar": "^1.1.1",
|
"@radix-ui/react-menubar": "^1.1.1",
|
||||||
"@radix-ui/react-primitive": "^2.0.0",
|
"@radix-ui/react-primitive": "^2.0.0",
|
||||||
|
"@radix-ui/react-select": "^2.1.2",
|
||||||
"@radix-ui/react-switch": "^1.1.0",
|
"@radix-ui/react-switch": "^1.1.0",
|
||||||
"@unocss/eslint-plugin": "^0.61.5",
|
"@unocss/eslint-plugin": "^0.61.5",
|
||||||
"@unocss/postcss": "^0.61.5",
|
"@unocss/postcss": "^0.61.5",
|
||||||
@ -105,7 +106,7 @@
|
|||||||
"react-markdown": "^9.0.1",
|
"react-markdown": "^9.0.1",
|
||||||
"react-resizable-panels": "^2.0.23",
|
"react-resizable-panels": "^2.0.23",
|
||||||
"recharts": "^2.12.7",
|
"recharts": "^2.12.7",
|
||||||
"shiki": "^1.22.2",
|
"shiki": "^1.23.0",
|
||||||
"tailwindcss": "^3.4.1",
|
"tailwindcss": "^3.4.1",
|
||||||
"typescript": "^5",
|
"typescript": "^5",
|
||||||
"vaul": "^0.9.1",
|
"vaul": "^0.9.1",
|
||||||
|
|||||||
39
src/app/(embeds)/embed/[server]/page.tsx
Normal file
39
src/app/(embeds)/embed/[server]/page.tsx
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* MHSF, Minehut Server List
|
||||||
|
* All external content is rather licensed under the ECA Agreement
|
||||||
|
* located here: https://mhsf.app/docs/legal/external-content-agreement
|
||||||
|
*
|
||||||
|
* All code under MHSF is licensed under the MIT License
|
||||||
|
* by open source contributors
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024 dvelo
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
* deal in the Software without restriction, including without limitation the
|
||||||
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
* sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Embed from "@/components/feat/Embed";
|
||||||
|
|
||||||
|
export default function EmbedPage({
|
||||||
|
params,
|
||||||
|
}: {
|
||||||
|
params: { server: string };
|
||||||
|
}) {
|
||||||
|
return <Embed params={params} />;
|
||||||
|
}
|
||||||
58
src/app/(embeds)/layout.tsx
Normal file
58
src/app/(embeds)/layout.tsx
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* MHSF, Minehut Server List
|
||||||
|
* All external content is rather licensed under the ECA Agreement
|
||||||
|
* located here: https://mhsf.app/docs/legal/external-content-agreement
|
||||||
|
*
|
||||||
|
* All code under MHSF is licensed under the MIT License
|
||||||
|
* by open source contributors
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024 dvelo
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
* deal in the Software without restriction, including without limitation the
|
||||||
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
* sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||||
|
import "../globals.css";
|
||||||
|
import { ThemeProvider } from "@/components/ThemeProvider";
|
||||||
|
import { useSearchParams } from "next/navigation";
|
||||||
|
|
||||||
|
export default function RootLayout({
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode;
|
||||||
|
}) {
|
||||||
|
const searchParams = useSearchParams();
|
||||||
|
const search = searchParams?.get("theme") || "light";
|
||||||
|
return (
|
||||||
|
<html lang="en">
|
||||||
|
<body>
|
||||||
|
<ThemeProvider
|
||||||
|
attribute="class"
|
||||||
|
disableTransitionOnChange
|
||||||
|
forcedTheme={search}
|
||||||
|
>
|
||||||
|
<TooltipProvider>{children}</TooltipProvider>
|
||||||
|
</ThemeProvider>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -33,11 +33,8 @@ import Banner from "@/components/Banner";
|
|||||||
import ColorProvider from "@/components/ColorProvider";
|
import ColorProvider from "@/components/ColorProvider";
|
||||||
import ServerView from "@/components/ServerView";
|
import ServerView from "@/components/ServerView";
|
||||||
import TabServer from "@/components/misc/TabServer";
|
import TabServer from "@/components/misc/TabServer";
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { Separator } from "@/components/ui/separator";
|
import { Separator } from "@/components/ui/separator";
|
||||||
import { CornerDownLeft } from "lucide-react";
|
|
||||||
import type { Metadata, ResolvingMetadata } from "next";
|
import type { Metadata, ResolvingMetadata } from "next";
|
||||||
import Link from "next/link";
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
params: { server: string };
|
params: { server: string };
|
||||||
@ -45,7 +42,7 @@ type Props = {
|
|||||||
|
|
||||||
export async function generateMetadata(
|
export async function generateMetadata(
|
||||||
{ params }: Props,
|
{ params }: Props,
|
||||||
parent: ResolvingMetadata,
|
parent: ResolvingMetadata
|
||||||
): Promise<Metadata> {
|
): Promise<Metadata> {
|
||||||
// read route params
|
// read route params
|
||||||
const { server } = params;
|
const { server } = params;
|
||||||
@ -135,12 +132,6 @@ export default function ServerPage({ params }: { params: { server: string } }) {
|
|||||||
<ColorProvider server={params.server}>
|
<ColorProvider server={params.server}>
|
||||||
<div className={"pt-16"}>
|
<div className={"pt-16"}>
|
||||||
<Banner server={params.server} />
|
<Banner server={params.server} />
|
||||||
<Link href="/">
|
|
||||||
<Button variant="link" className="text-muted-foreground text-sm">
|
|
||||||
<CornerDownLeft size={16} className="mr-2" /> Go back to the
|
|
||||||
server list
|
|
||||||
</Button>
|
|
||||||
</Link>
|
|
||||||
<TabServer server={params.server} tabDef="general" />
|
<TabServer server={params.server} tabDef="general" />
|
||||||
<div className="pt-8">
|
<div className="pt-8">
|
||||||
<ServerView server={params.server} />
|
<ServerView server={params.server} />
|
||||||
|
|||||||
@ -36,9 +36,8 @@ import {
|
|||||||
MinehutIcon,
|
MinehutIcon,
|
||||||
getIndexFromRarity,
|
getIndexFromRarity,
|
||||||
getMinehutIcons,
|
getMinehutIcons,
|
||||||
rarityIndex,
|
|
||||||
} from "@/lib/types/server-icon";
|
} from "@/lib/types/server-icon";
|
||||||
import { Copy, Info } from "lucide-react";
|
import { Copy, ExternalLink, Info } from "lucide-react";
|
||||||
import { useTheme } from "next-themes";
|
import { useTheme } from "next-themes";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import FadeIn from "react-fade-in/lib/FadeIn";
|
import FadeIn from "react-fade-in/lib/FadeIn";
|
||||||
@ -55,6 +54,8 @@ import {
|
|||||||
CardTitle,
|
CardTitle,
|
||||||
} from "./ui/card";
|
} from "./ui/card";
|
||||||
import { Tooltip, TooltipContent, TooltipTrigger } from "./ui/tooltip";
|
import { Tooltip, TooltipContent, TooltipTrigger } from "./ui/tooltip";
|
||||||
|
import { Drawer, DrawerContent, DrawerHeader, DrawerTitle } from "./ui/drawer";
|
||||||
|
import EmbedSelector from "./feat/EmbedSelector";
|
||||||
|
|
||||||
export default function AfterServerView({ server }: { server: string }) {
|
export default function AfterServerView({ server }: { server: string }) {
|
||||||
const [description, setDescription] = useState("");
|
const [description, setDescription] = useState("");
|
||||||
@ -64,11 +65,12 @@ export default function AfterServerView({ server }: { server: string }) {
|
|||||||
const { resolvedTheme } = useTheme();
|
const { resolvedTheme } = useTheme();
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [view, setView] = useState(
|
const [view, setView] = useState(
|
||||||
description !== "" || discord !== "" ? "desc" : "extra",
|
description !== "" || discord !== "" ? "desc" : "extra"
|
||||||
);
|
);
|
||||||
const [serverObject, setServerObject] = useState<ServerResponse | undefined>(
|
const [serverObject, setServerObject] = useState<ServerResponse | undefined>(
|
||||||
undefined,
|
undefined
|
||||||
);
|
);
|
||||||
|
const [embedOpened, setEmbedOpened] = useState(false);
|
||||||
const [copied, setCopied] = useState(false);
|
const [copied, setCopied] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -82,7 +84,7 @@ export default function AfterServerView({ server }: { server: string }) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
fetch("https://api.minehut.com/server/" + server + "?byName=true").then(
|
fetch("https://api.minehut.com/server/" + server + "?byName=true").then(
|
||||||
(c) => c.json().then((n) => setServerObject(n.server)),
|
(c) => c.json().then((n) => setServerObject(n.server))
|
||||||
);
|
);
|
||||||
getMinehutIcons().then((i) => {
|
getMinehutIcons().then((i) => {
|
||||||
setIcons(i);
|
setIcons(i);
|
||||||
@ -94,9 +96,17 @@ export default function AfterServerView({ server }: { server: string }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<Drawer open={embedOpened} onOpenChange={setEmbedOpened}>
|
||||||
|
<DrawerContent className="max-w-md w-full mx-auto rounded-t-[10px]">
|
||||||
|
<DrawerHeader>
|
||||||
|
<DrawerTitle>Embed Creator</DrawerTitle>
|
||||||
|
</DrawerHeader>
|
||||||
|
<EmbedSelector server={server} />
|
||||||
|
</DrawerContent>
|
||||||
|
</Drawer>
|
||||||
<FadeIn>
|
<FadeIn>
|
||||||
<div className="grid sm:grid-cols-6 h-full pl-4 pr-4 ">
|
<div className="grid sm:grid-cols-6 h-full pl-4 pr-4 ">
|
||||||
<div className="ml-5 mb-2 flex items-center sm:hidden">
|
<div className="ml-5 mb-2 flex items-center sm:hidden overflow-auto w-[calc(100vw-5rem)]">
|
||||||
{(description != "" || discord != "") && (
|
{(description != "" || discord != "") && (
|
||||||
<Button
|
<Button
|
||||||
variant={view == "desc" ? undefined : "ghost"}
|
variant={view == "desc" ? undefined : "ghost"}
|
||||||
@ -125,6 +135,10 @@ export default function AfterServerView({ server }: { server: string }) {
|
|||||||
>
|
>
|
||||||
Purchased Icons
|
Purchased Icons
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button variant="ghost" onClick={() => setEmbedOpened(true)}>
|
||||||
|
Embed Creator
|
||||||
|
<ExternalLink className="h-[1.2rem] w-[1.2rem] ml-1" />
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div className="max-sm:hidden">
|
<div className="max-sm:hidden">
|
||||||
<div className="grid">
|
<div className="grid">
|
||||||
@ -154,6 +168,10 @@ export default function AfterServerView({ server }: { server: string }) {
|
|||||||
>
|
>
|
||||||
Purchased Icons
|
Purchased Icons
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button variant="ghost" onClick={() => setEmbedOpened(true)}>
|
||||||
|
Embed Creator
|
||||||
|
<ExternalLink className="h-[1.2rem] w-[1.2rem] ml-1" />
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -349,11 +367,11 @@ export default function AfterServerView({ server }: { server: string }) {
|
|||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
minehut: serverObject,
|
minehut: serverObject,
|
||||||
mhsf: mhsf.getMHSF(),
|
mhsf: mhsf.getMHSF(),
|
||||||
}),
|
})
|
||||||
);
|
);
|
||||||
} catch {
|
} catch {
|
||||||
toast.error(
|
toast.error(
|
||||||
"Clipboard is inaccessible. Cannot copy",
|
"Clipboard is inaccessible. Cannot copy"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
toast.success(
|
toast.success(
|
||||||
@ -366,7 +384,7 @@ export default function AfterServerView({ server }: { server: string }) {
|
|||||||
}).substring(0, 36)}
|
}).substring(0, 36)}
|
||||||
...
|
...
|
||||||
</code>
|
</code>
|
||||||
</div>,
|
</div>
|
||||||
);
|
);
|
||||||
setTimeout(() => setCopied(false), 1000);
|
setTimeout(() => setCopied(false), 1000);
|
||||||
}}
|
}}
|
||||||
@ -438,9 +456,7 @@ export default function AfterServerView({ server }: { server: string }) {
|
|||||||
className="pt-4"
|
className="pt-4"
|
||||||
style={{
|
style={{
|
||||||
color: getIndexFromRarity(
|
color: getIndexFromRarity(
|
||||||
icons
|
icons?.find((c) => c._id === icon)?.rank.toLowerCase()
|
||||||
?.find((c) => c._id === icon)
|
|
||||||
?.rank.toLowerCase(),
|
|
||||||
).text,
|
).text,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -457,7 +473,7 @@ export default function AfterServerView({ server }: { server: string }) {
|
|||||||
backgroundColor: getIndexFromRarity(
|
backgroundColor: getIndexFromRarity(
|
||||||
icons
|
icons
|
||||||
?.find((c) => c._id === icon)
|
?.find((c) => c._id === icon)
|
||||||
?.rank.toLowerCase(),
|
?.rank.toLowerCase()
|
||||||
).bg,
|
).bg,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -430,7 +430,6 @@ export function ServerCommandBar() {
|
|||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
{owned && (
|
{owned && (
|
||||||
<h2 className="flex items-center text-muted-foreground">
|
<h2 className="flex items-center text-muted-foreground">
|
||||||
<CheckIcon />
|
<CheckIcon />
|
||||||
|
|||||||
@ -30,7 +30,6 @@
|
|||||||
|
|
||||||
"use client";
|
"use client";
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { Spinner } from "./ui/spinner";
|
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
CardContent,
|
CardContent,
|
||||||
@ -108,7 +107,7 @@ export default function ServerView(props: { server: string }) {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{single.grabOnline() == undefined && (
|
{single.grabOnline() == undefined && !single.grabOffline()?.online && (
|
||||||
<div className="grid pl-4 pr-4">
|
<div className="grid pl-4 pr-4">
|
||||||
<div
|
<div
|
||||||
className=" rounded p-2"
|
className=" rounded p-2"
|
||||||
@ -130,7 +129,8 @@ export default function ServerView(props: { server: string }) {
|
|||||||
<Card className="sm:col-span-2">
|
<Card className="sm:col-span-2">
|
||||||
<BetterHeader>
|
<BetterHeader>
|
||||||
<CardTitle className="flex items-center">
|
<CardTitle className="flex items-center">
|
||||||
{single.grabOnline() == undefined ? (
|
{single.grabOnline() == undefined &&
|
||||||
|
!single.grabOffline()?.online ? (
|
||||||
<div
|
<div
|
||||||
className="items-center mr-1"
|
className="items-center mr-1"
|
||||||
style={{
|
style={{
|
||||||
|
|||||||
168
src/components/feat/Embed.tsx
Normal file
168
src/components/feat/Embed.tsx
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
/*
|
||||||
|
* MHSF, Minehut Server List
|
||||||
|
* All external content is rather licensed under the ECA Agreement
|
||||||
|
* located here: https://mhsf.app/docs/legal/external-content-agreement
|
||||||
|
*
|
||||||
|
* All code under MHSF is licensed under the MIT License
|
||||||
|
* by open source contributors
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024 dvelo
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
* deal in the Software without restriction, including without limitation the
|
||||||
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
* sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use client";
|
||||||
|
import IconDisplay from "@/components/IconDisplay";
|
||||||
|
import { Badge } from "@/components/ui/badge";
|
||||||
|
import { Spinner } from "@/components/ui/spinner";
|
||||||
|
import type { ServerResponse } from "@/lib/types/mh-server";
|
||||||
|
import { Copy, ExternalLink, ServerCrash } from "lucide-react";
|
||||||
|
import { notFound, useSearchParams } from "next/navigation";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { Button } from "../ui/button";
|
||||||
|
import { CheckmarkIcon } from "react-hot-toast";
|
||||||
|
import useClipboard from "@/lib/useClipboard";
|
||||||
|
import { Tooltip, TooltipTrigger, TooltipContent } from "../ui/tooltip";
|
||||||
|
|
||||||
|
export default function Embed({ params }: { params: { server: string } }) {
|
||||||
|
const [serverFound, setServerFound] = useState(true);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [copied, setCopied] = useState(false);
|
||||||
|
const [serverObject, setServerObject] = useState<ServerResponse | null>(null);
|
||||||
|
const searchParams = useSearchParams();
|
||||||
|
const staticMode = searchParams?.get("static") === "true";
|
||||||
|
const noShowBranding = searchParams?.get("branding") === "false";
|
||||||
|
const clipboard = useClipboard();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
const serverFoundResponse = await fetch(
|
||||||
|
"https://api.minehut.com/server/" + params.server + "?byName=true"
|
||||||
|
);
|
||||||
|
const stream = await serverFoundResponse.json();
|
||||||
|
|
||||||
|
if (stream.server == null) setServerFound(false);
|
||||||
|
else setServerObject(stream.server);
|
||||||
|
setLoading(false);
|
||||||
|
})();
|
||||||
|
}, [params]);
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return <Spinner />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!serverFound) {
|
||||||
|
notFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="rounded w-[390px] h-[145px] bg-muted">
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
"flex items-center text-sm cursor-pointer border-b p-2" +
|
||||||
|
(staticMode ? "" : " group")
|
||||||
|
}
|
||||||
|
onClick={() =>
|
||||||
|
window.open("/server/" + params.server, "_blank")?.focus()
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<ServerCrash
|
||||||
|
size={16}
|
||||||
|
className="group-hover:text-white p-[4px] group-hover:p-[3px] w-[24px] h-[24px] transition-all bg-gradient-to-r group-hover:from-blue-600 group-hover:to-purple-500 group-hover:rounded"
|
||||||
|
/>
|
||||||
|
<span className="transition-colors ml-2 group-hover:bg-clip-text group-hover:text-transparent bg-gradient-to-r group-hover:from-blue-600 group-hover:to-purple-500">
|
||||||
|
Powered by MHSF
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="px-4 pt-2 flex items-center group overflow-hidden">
|
||||||
|
<div className={staticMode ? "block" : "group-hover:block hidden"}>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
className="mb-1"
|
||||||
|
onClick={() => {
|
||||||
|
setCopied(true);
|
||||||
|
clipboard.writeText(params.server + ".mhsf.minehut.gg");
|
||||||
|
setTimeout(() => setCopied(false), 1000);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{copied ? <CheckmarkIcon /> : <Copy size={16} />}
|
||||||
|
</Button>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>Copy this server IP</TooltipContent>
|
||||||
|
</Tooltip>{" "}
|
||||||
|
<br />
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
onClick={() => {
|
||||||
|
window.open("/server/" + params.server, "_blank")?.focus();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ExternalLink size={16} />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<IconDisplay
|
||||||
|
server={serverObject}
|
||||||
|
className={
|
||||||
|
"flex items-center mr-2" +
|
||||||
|
(staticMode ? " mb-1 ml-1" : " group-hover:mb-1 group-hover:ml-1")
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<div className={"block" + (staticMode ? " mb-1" : " group-hover:mb-1")}>
|
||||||
|
<strong className="text-lg">{params.server}</strong>{" "}
|
||||||
|
{!noShowBranding && <Badge variant="blue">on Minehut</Badge>}
|
||||||
|
<br />
|
||||||
|
<span className="text-sm">Joined {serverObject?.joins} times</span>
|
||||||
|
<br />
|
||||||
|
{serverObject?.online && (
|
||||||
|
<span className="flex items-center">
|
||||||
|
{serverObject.playerCount === 0 ? (
|
||||||
|
<div
|
||||||
|
className="items-center border"
|
||||||
|
style={{
|
||||||
|
width: ".5rem",
|
||||||
|
height: ".5rem",
|
||||||
|
borderRadius: "9999px",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div
|
||||||
|
className="items-center"
|
||||||
|
style={{
|
||||||
|
backgroundColor: "#0cce6b",
|
||||||
|
width: ".5rem",
|
||||||
|
height: ".5rem",
|
||||||
|
borderRadius: "9999px",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<span className="text-sm ml-1">
|
||||||
|
{serverObject.playerCount} player(s) online
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
306
src/components/feat/EmbedSelector.tsx
Normal file
306
src/components/feat/EmbedSelector.tsx
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
/*
|
||||||
|
* MHSF, Minehut Server List
|
||||||
|
* All external content is rather licensed under the ECA Agreement
|
||||||
|
* located here: https://mhsf.app/docs/legal/external-content-agreement
|
||||||
|
*
|
||||||
|
* All code under MHSF is licensed under the MIT License
|
||||||
|
* by open source contributors
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024 dvelo
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
* deal in the Software without restriction, including without limitation the
|
||||||
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
* sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import { TabsContent } from "@radix-ui/react-tabs";
|
||||||
|
import { Button } from "../ui/button";
|
||||||
|
import { DrawerFooter, DrawerTrigger } from "../ui/drawer";
|
||||||
|
import { Tabs, TabsList, TabsTrigger } from "../ui/tabs";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { codeToHtml } from "shiki";
|
||||||
|
import { useTheme } from "next-themes";
|
||||||
|
import { Asterisk, Copy } from "lucide-react";
|
||||||
|
import useClipboard from "@/lib/useClipboard";
|
||||||
|
import toast from "react-hot-toast";
|
||||||
|
import { Checkbox } from "../ui/checkbox";
|
||||||
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectItem,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from "../ui/select";
|
||||||
|
|
||||||
|
export default function EmbedSelector({ server }: { server: string }) {
|
||||||
|
const { theme, systemTheme, resolvedTheme } = useTheme();
|
||||||
|
|
||||||
|
const [embedTheme, setEmbedTheme] = useState("");
|
||||||
|
const [embedStatic, setEmbedStatic] = useState(false);
|
||||||
|
const [highlightedHtml, setHighlightedHtml] = useState("");
|
||||||
|
const [highlightedJsx, setHighlightedJsx] = useState("");
|
||||||
|
const [selectedCodeType, setSelectedCodeType] = useState("jsx");
|
||||||
|
const [noMinehutBranding, setNoMinehutBranding] = useState(false);
|
||||||
|
const clipboard = useClipboard();
|
||||||
|
const [url, setURL] = useState(`https://mhsf.app/embed/${server}?`);
|
||||||
|
const [jsxCode, setJsxCode] = useState(`<iframe
|
||||||
|
src="${url}"
|
||||||
|
width={390}
|
||||||
|
height={145}
|
||||||
|
style={{ borderRadius: 0.25 }}
|
||||||
|
allow="clipboard-write"
|
||||||
|
frameBorder={0}
|
||||||
|
sandbox="allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts"
|
||||||
|
/>`);
|
||||||
|
const [htmlCode, setHtmlCode] = useState(`<iframe
|
||||||
|
src="${url}"
|
||||||
|
width="390"
|
||||||
|
height="145"
|
||||||
|
style="border-radius: 0.25rem;"
|
||||||
|
allow="clipboard-write"
|
||||||
|
frameborder="0"
|
||||||
|
sandbox="allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts"
|
||||||
|
></iframe>`);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setHtmlCode(`<iframe
|
||||||
|
src="${url}"
|
||||||
|
width="390"
|
||||||
|
height="145"
|
||||||
|
style="border-radius: 0.25rem;"
|
||||||
|
allow="clipboard-write"
|
||||||
|
frameborder="0"
|
||||||
|
sandbox="allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts"
|
||||||
|
></iframe>`);
|
||||||
|
setJsxCode(`<iframe
|
||||||
|
src="${url}"
|
||||||
|
width={390}
|
||||||
|
height={145}
|
||||||
|
style={{ borderRadius: 0.25 }}
|
||||||
|
allow="clipboard-write"
|
||||||
|
frameBorder={0}
|
||||||
|
sandbox="allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts"
|
||||||
|
/>`);
|
||||||
|
|
||||||
|
const currentTheme = theme === "system" ? systemTheme : theme;
|
||||||
|
const selectedTheme =
|
||||||
|
currentTheme === "dark" ? "vitesse-dark" : "vitesse-light";
|
||||||
|
|
||||||
|
async function highlightCode() {
|
||||||
|
const jsx = await codeToHtml(jsxCode, {
|
||||||
|
lang: "jsx",
|
||||||
|
theme: selectedTheme,
|
||||||
|
});
|
||||||
|
const html = await codeToHtml(htmlCode, {
|
||||||
|
lang: "html",
|
||||||
|
theme: selectedTheme,
|
||||||
|
});
|
||||||
|
setHighlightedHtml(html);
|
||||||
|
setHighlightedJsx(jsx);
|
||||||
|
}
|
||||||
|
|
||||||
|
highlightCode();
|
||||||
|
}, [
|
||||||
|
theme,
|
||||||
|
systemTheme,
|
||||||
|
jsxCode,
|
||||||
|
htmlCode,
|
||||||
|
embedStatic,
|
||||||
|
noMinehutBranding,
|
||||||
|
url,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const renderCode = (code: string, highlighted: string) => {
|
||||||
|
if (highlighted) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="h-full overflow-auto bg-background font-mono text-xs [&>pre]:h-full [&>pre]:!bg-transparent [&>pre]:p-4 [&_code]:break-all"
|
||||||
|
dangerouslySetInnerHTML={{ __html: highlighted }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<pre className="h-full overflow-auto break-all bg-background p-4 font-mono text-xs text-foreground">
|
||||||
|
{code}
|
||||||
|
</pre>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="p-4">
|
||||||
|
<div className="px-2 pb-8">
|
||||||
|
<div className="items-top flex space-x-2">
|
||||||
|
<Checkbox
|
||||||
|
id="static"
|
||||||
|
checked={embedStatic}
|
||||||
|
onCheckedChange={(c) => {
|
||||||
|
setEmbedStatic(c == "indeterminate" ? true : c);
|
||||||
|
setURL(
|
||||||
|
`https://mhsf.app/embed/${server}?${c ? "&static=true" : ""}${
|
||||||
|
noMinehutBranding ? "&branding=false" : ""
|
||||||
|
}&theme=${embedTheme}`
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div className="grid gap-1.5 leading-none">
|
||||||
|
<label
|
||||||
|
htmlFor="static"
|
||||||
|
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||||
|
>
|
||||||
|
Make embed static
|
||||||
|
</label>
|
||||||
|
<p className="text-sm text-muted-foreground">
|
||||||
|
Interactions with the embed take less resources but will be less
|
||||||
|
interactive.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<div className="items-top flex space-x-2">
|
||||||
|
<Checkbox
|
||||||
|
id="static"
|
||||||
|
checked={noMinehutBranding}
|
||||||
|
onCheckedChange={(c) => {
|
||||||
|
setNoMinehutBranding(c == "indeterminate" ? true : c);
|
||||||
|
setURL(
|
||||||
|
`https://mhsf.app/embed/${server}?${embedStatic ? "&static=true" : ""}${
|
||||||
|
c ? "&branding=false" : ""
|
||||||
|
}&theme=${embedTheme}`
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div className="grid gap-1.5 leading-none">
|
||||||
|
<label
|
||||||
|
htmlFor="static"
|
||||||
|
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||||
|
>
|
||||||
|
Remove Minehut branding
|
||||||
|
</label>
|
||||||
|
<p className="text-sm text-muted-foreground">
|
||||||
|
Enabling this will remove the "on Minehut" tag on the embed.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<div>
|
||||||
|
<label
|
||||||
|
htmlFor="theme"
|
||||||
|
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||||
|
>
|
||||||
|
Theme
|
||||||
|
</label>
|
||||||
|
<Select
|
||||||
|
name="theme"
|
||||||
|
value={embedTheme}
|
||||||
|
onValueChange={(c) => {
|
||||||
|
setEmbedTheme(c);
|
||||||
|
setURL(
|
||||||
|
`https://mhsf.app/embed/${server}?${embedStatic ? "&static=true" : ""}${
|
||||||
|
noMinehutBranding ? "&branding=false" : ""
|
||||||
|
}&theme=${c}`
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SelectTrigger className="w-[180px]">
|
||||||
|
<SelectValue placeholder="Light" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectItem value="light">Light</SelectItem>
|
||||||
|
<SelectItem value="dark">Dark</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Tabs defaultValue="preview" className="relative mr-auto w-full">
|
||||||
|
<TabsList className="w-full justify-start rounded-none border-b bg-transparent p-0">
|
||||||
|
<TabsTrigger
|
||||||
|
value="preview"
|
||||||
|
className="relative h-9 rounded-none border-b-2 border-b-transparent bg-transparent px-4 pb-3 pt-2 font-semibold text-muted-foreground shadow-none transition-none data-[state=active]:border-b-primary data-[state=active]:text-foreground data-[state=active]:shadow-none"
|
||||||
|
>
|
||||||
|
Preview
|
||||||
|
</TabsTrigger>
|
||||||
|
<TabsTrigger
|
||||||
|
value="code"
|
||||||
|
className="relative h-9 rounded-none border-b-2 border-b-transparent bg-transparent px-4 pb-3 pt-2 font-semibold text-muted-foreground shadow-none transition-none data-[state=active]:border-b-primary data-[state=active]:text-foreground data-[state=active]:shadow-none"
|
||||||
|
>
|
||||||
|
Code
|
||||||
|
</TabsTrigger>
|
||||||
|
</TabsList>
|
||||||
|
<TabsContent value="preview">
|
||||||
|
<iframe
|
||||||
|
src={`/embed/${server}?${embedStatic ? "&static=true" : ""}${
|
||||||
|
noMinehutBranding ? "&branding=false" : ""
|
||||||
|
}&theme=${embedTheme}`}
|
||||||
|
width={390}
|
||||||
|
height={145}
|
||||||
|
className="justify-center m-1"
|
||||||
|
style={{ borderRadius: "0.25rem" }}
|
||||||
|
allow="clipboard-write"
|
||||||
|
frameBorder={0}
|
||||||
|
sandbox="allow-forms allow-scripts"
|
||||||
|
/>
|
||||||
|
</TabsContent>
|
||||||
|
<TabsContent value="code">
|
||||||
|
<div className="bg-secondary h-[43px] px-3 py-1 rounded-b">
|
||||||
|
<div className="w-[130px] grid grid-cols-2">
|
||||||
|
<Button
|
||||||
|
size="icon"
|
||||||
|
className="h-8 w-16 justify-end"
|
||||||
|
variant="ghost"
|
||||||
|
onClick={() => {
|
||||||
|
if (selectedCodeType === "jsx") setSelectedCodeType("html");
|
||||||
|
else setSelectedCodeType("jsx");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Asterisk size={16} className="mr-1" />
|
||||||
|
{selectedCodeType === "jsx" ? <>JSX</> : <>HTML</>}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
size="icon"
|
||||||
|
className="h-8 w-8 justify-end"
|
||||||
|
variant="ghost"
|
||||||
|
onClick={() => {
|
||||||
|
clipboard.writeText(
|
||||||
|
selectedCodeType === "jsx" ? jsxCode : htmlCode
|
||||||
|
);
|
||||||
|
toast.success("Copied!");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Copy size={16} />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{renderCode(
|
||||||
|
selectedCodeType === "jsx" ? jsxCode : htmlCode,
|
||||||
|
selectedCodeType === "jsx" ? highlightedJsx : highlightedHtml
|
||||||
|
)}
|
||||||
|
</TabsContent>
|
||||||
|
</Tabs>
|
||||||
|
</div>
|
||||||
|
<DrawerFooter>
|
||||||
|
<DrawerTrigger asChild>
|
||||||
|
<Button>Close</Button>
|
||||||
|
</DrawerTrigger>
|
||||||
|
</DrawerFooter>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -32,7 +32,7 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Tabs, TabsList, TabsTrigger } from "../ui/tabs";
|
import { Tabs, TabsList, TabsTrigger } from "../ui/tabs";
|
||||||
import { useRouter } from "@/lib/useRouter";
|
import { useRouter } from "@/lib/useRouter";
|
||||||
import { Database, Home, Paintbrush } from "lucide-react";
|
import { CornerDownLeft, Database, Home, Paintbrush } from "lucide-react";
|
||||||
|
|
||||||
export default function TabServer({
|
export default function TabServer({
|
||||||
server,
|
server,
|
||||||
@ -45,7 +45,7 @@ export default function TabServer({
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full flex justify-center">
|
<div className="w-full px-4">
|
||||||
<Tabs
|
<Tabs
|
||||||
value={tab}
|
value={tab}
|
||||||
onValueChange={(tac) => {
|
onValueChange={(tac) => {
|
||||||
@ -53,23 +53,40 @@ export default function TabServer({
|
|||||||
if (tac == "customize") router.push(`/server/${server}/customize`);
|
if (tac == "customize") router.push(`/server/${server}/customize`);
|
||||||
if (tac == "statistics") router.push(`/server/${server}/statistics`);
|
if (tac == "statistics") router.push(`/server/${server}/statistics`);
|
||||||
if (tac == "general") router.push(`/server/${server}`);
|
if (tac == "general") router.push(`/server/${server}`);
|
||||||
|
if (tac == "server-list") router.push("/");
|
||||||
}}
|
}}
|
||||||
className="sm:w-[500px] max-sm:w-[200px]"
|
|
||||||
>
|
>
|
||||||
<TabsList className="grid w-full grid-cols-3 max-sm:min-h-[50px]">
|
<TabsList className="border-b bg-transparent p-0 rounded-none w-full justify-start">
|
||||||
<TabsTrigger value="general" className="">
|
<TabsTrigger
|
||||||
|
value="general"
|
||||||
|
className="relative h-9 rounded-none border-b-2 border-b-transparent bg-transparent px-4 pb-3 pt-2 font-semibold text-muted-foreground shadow-none transition-none data-[state=active]:border-b-primary data-[state=active]:text-foreground data-[state=active]:shadow-none"
|
||||||
|
>
|
||||||
{" "}
|
{" "}
|
||||||
<div className="max-sm:hidden">General Information</div>
|
<div className="max-sm:hidden">General Information</div>
|
||||||
<Home className="sm:hidden" size={18} />
|
<Home className="sm:hidden" size={18} />
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
<TabsTrigger value="statistics">
|
<TabsTrigger
|
||||||
|
value="statistics"
|
||||||
|
className="relative h-9 rounded-none border-b-2 border-b-transparent bg-transparent px-4 pb-3 pt-2 font-semibold text-muted-foreground shadow-none transition-none data-[state=active]:border-b-primary data-[state=active]:text-foreground data-[state=active]:shadow-none"
|
||||||
|
>
|
||||||
<div className="max-sm:hidden">Statistics</div>
|
<div className="max-sm:hidden">Statistics</div>
|
||||||
<Database className="sm:hidden" size={18} />
|
<Database className="sm:hidden" size={18} />
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
<TabsTrigger value="customize">
|
<TabsTrigger
|
||||||
|
value="customize"
|
||||||
|
className="relative h-9 rounded-none border-b-2 border-b-transparent bg-transparent px-4 pb-3 pt-2 font-semibold text-muted-foreground shadow-none transition-none data-[state=active]:border-b-primary data-[state=active]:text-foreground data-[state=active]:shadow-none"
|
||||||
|
>
|
||||||
<div className="max-sm:hidden">Customization</div>
|
<div className="max-sm:hidden">Customization</div>
|
||||||
<Paintbrush className="sm:hidden" size={18} />
|
<Paintbrush className="sm:hidden" size={18} />
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
|
|
||||||
|
<TabsTrigger
|
||||||
|
value="server-list"
|
||||||
|
className="relative h-9 rounded-none border-b-2 border-b-transparent bg-transparent px-4 pb-3 pt-2 font-semibold text-muted-foreground shadow-none transition-none data-[state=active]:border-b-primary data-[state=active]:text-foreground data-[state=active]:shadow-none"
|
||||||
|
>
|
||||||
|
<CornerDownLeft size={16} className="mr-2" />
|
||||||
|
<div className="max-sm:hidden">Back to server list</div>
|
||||||
|
</TabsTrigger>
|
||||||
</TabsList>
|
</TabsList>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
158
src/components/ui/select.tsx
Normal file
158
src/components/ui/select.tsx
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import * as SelectPrimitive from "@radix-ui/react-select"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "@radix-ui/react-icons"
|
||||||
|
|
||||||
|
const Select = SelectPrimitive.Root
|
||||||
|
|
||||||
|
const SelectGroup = SelectPrimitive.Group
|
||||||
|
|
||||||
|
const SelectValue = SelectPrimitive.Value
|
||||||
|
|
||||||
|
const SelectTrigger = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SelectPrimitive.Trigger>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
|
||||||
|
>(({ className, children, ...props }, ref) => (
|
||||||
|
<SelectPrimitive.Trigger
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
<SelectPrimitive.Icon asChild>
|
||||||
|
<ChevronDownIcon className="h-4 w-4 opacity-50" />
|
||||||
|
</SelectPrimitive.Icon>
|
||||||
|
</SelectPrimitive.Trigger>
|
||||||
|
))
|
||||||
|
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName
|
||||||
|
|
||||||
|
const SelectScrollUpButton = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<SelectPrimitive.ScrollUpButton
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex cursor-default items-center justify-center py-1",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<ChevronUpIcon className="h-4 w-4" />
|
||||||
|
</SelectPrimitive.ScrollUpButton>
|
||||||
|
))
|
||||||
|
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName
|
||||||
|
|
||||||
|
const SelectScrollDownButton = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<SelectPrimitive.ScrollDownButton
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex cursor-default items-center justify-center py-1",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<ChevronDownIcon className="h-4 w-4" />
|
||||||
|
</SelectPrimitive.ScrollDownButton>
|
||||||
|
))
|
||||||
|
SelectScrollDownButton.displayName =
|
||||||
|
SelectPrimitive.ScrollDownButton.displayName
|
||||||
|
|
||||||
|
const SelectContent = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SelectPrimitive.Content>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
|
||||||
|
>(({ className, children, position = "popper", ...props }, ref) => (
|
||||||
|
<SelectPrimitive.Portal>
|
||||||
|
<SelectPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||||
|
position === "popper" &&
|
||||||
|
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
position={position}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<SelectScrollUpButton />
|
||||||
|
<SelectPrimitive.Viewport
|
||||||
|
className={cn(
|
||||||
|
"p-1",
|
||||||
|
position === "popper" &&
|
||||||
|
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</SelectPrimitive.Viewport>
|
||||||
|
<SelectScrollDownButton />
|
||||||
|
</SelectPrimitive.Content>
|
||||||
|
</SelectPrimitive.Portal>
|
||||||
|
))
|
||||||
|
SelectContent.displayName = SelectPrimitive.Content.displayName
|
||||||
|
|
||||||
|
const SelectLabel = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SelectPrimitive.Label>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<SelectPrimitive.Label
|
||||||
|
ref={ref}
|
||||||
|
className={cn("px-2 py-1.5 text-sm font-semibold", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
SelectLabel.displayName = SelectPrimitive.Label.displayName
|
||||||
|
|
||||||
|
const SelectItem = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SelectPrimitive.Item>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
|
||||||
|
>(({ className, children, ...props }, ref) => (
|
||||||
|
<SelectPrimitive.Item
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<span className="absolute right-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||||
|
<SelectPrimitive.ItemIndicator>
|
||||||
|
<CheckIcon className="h-4 w-4" />
|
||||||
|
</SelectPrimitive.ItemIndicator>
|
||||||
|
</span>
|
||||||
|
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
|
||||||
|
</SelectPrimitive.Item>
|
||||||
|
))
|
||||||
|
SelectItem.displayName = SelectPrimitive.Item.displayName
|
||||||
|
|
||||||
|
const SelectSeparator = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SelectPrimitive.Separator>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<SelectPrimitive.Separator
|
||||||
|
ref={ref}
|
||||||
|
className={cn("-mx-1 my-1 h-px bg-muted", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
SelectSeparator.displayName = SelectPrimitive.Separator.displayName
|
||||||
|
|
||||||
|
export {
|
||||||
|
Select,
|
||||||
|
SelectGroup,
|
||||||
|
SelectValue,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectContent,
|
||||||
|
SelectLabel,
|
||||||
|
SelectItem,
|
||||||
|
SelectSeparator,
|
||||||
|
SelectScrollUpButton,
|
||||||
|
SelectScrollDownButton,
|
||||||
|
}
|
||||||
@ -73,6 +73,7 @@ export const allFolders: DocsFolder[] = [
|
|||||||
name: "Legal",
|
name: "Legal",
|
||||||
docs: [
|
docs: [
|
||||||
{ title: "ECA Agreement", url: "/docs/legal/external-content-agreement" },
|
{ title: "ECA Agreement", url: "/docs/legal/external-content-agreement" },
|
||||||
|
{ title: "Email List", url: "/docs/legal/email-list" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@ -41,7 +41,10 @@ const User = ({ user }: { user: string }) => (
|
|||||||
const FeatureList = ({
|
const FeatureList = ({
|
||||||
features,
|
features,
|
||||||
title,
|
title,
|
||||||
}: { features: (string | ReactNode)[]; title: ReactNode }) => {
|
}: {
|
||||||
|
features: (string | ReactNode)[];
|
||||||
|
title: ReactNode;
|
||||||
|
}) => {
|
||||||
return (
|
return (
|
||||||
<ul>
|
<ul>
|
||||||
{title}
|
{title}
|
||||||
@ -54,6 +57,25 @@ const FeatureList = ({
|
|||||||
|
|
||||||
export const version = "1.4.0";
|
export const version = "1.4.0";
|
||||||
export const changelog: { name: string; id: string; changelog: ReactNode }[] = [
|
export const changelog: { name: string; id: string; changelog: ReactNode }[] = [
|
||||||
|
{
|
||||||
|
id: "r9swempc7kaqd2j84nutv5",
|
||||||
|
name: "v1.5.0",
|
||||||
|
changelog: (
|
||||||
|
<FeatureList
|
||||||
|
features={[
|
||||||
|
"New embeds",
|
||||||
|
"More mobile friendly elements",
|
||||||
|
"Better tabs in the server",
|
||||||
|
"Fixed issue where some servers due to their age were not loading",
|
||||||
|
]}
|
||||||
|
title={
|
||||||
|
<strong className="flex items-center">
|
||||||
|
Version 1.5.0 (November 16th 2024)
|
||||||
|
</strong>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: "ywvhtcs4k9rqjfp57x",
|
id: "ywvhtcs4k9rqjfp57x",
|
||||||
name: "v1.4.5",
|
name: "v1.4.5",
|
||||||
|
|||||||
@ -60,6 +60,9 @@ export default class ServerSingle {
|
|||||||
if (this.online == true && skipOnline != true) {
|
if (this.online == true && skipOnline != true) {
|
||||||
fetch("https://api.minehut.com/servers").then((l) =>
|
fetch("https://api.minehut.com/servers").then((l) =>
|
||||||
l.json().then((o) => {
|
l.json().then((o) => {
|
||||||
|
if (o.servers.find((j: OnlineServer) => j.name == this.name) == undefined) {
|
||||||
|
g(true);
|
||||||
|
}
|
||||||
o.servers.forEach((j: OnlineServer) => {
|
o.servers.forEach((j: OnlineServer) => {
|
||||||
if (j.name == this.name) {
|
if (j.name == this.name) {
|
||||||
this.onlineObj = j;
|
this.onlineObj = j;
|
||||||
|
|||||||
118
yarn.lock
118
yarn.lock
@ -1747,6 +1747,33 @@
|
|||||||
"@radix-ui/react-use-callback-ref" "1.1.0"
|
"@radix-ui/react-use-callback-ref" "1.1.0"
|
||||||
"@radix-ui/react-use-layout-effect" "1.1.0"
|
"@radix-ui/react-use-layout-effect" "1.1.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-select@^2.1.2":
|
||||||
|
version "2.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-select/-/react-select-2.1.2.tgz#2346e118966db793940f6a866fd4cc5db2cc275e"
|
||||||
|
integrity sha512-rZJtWmorC7dFRi0owDmoijm6nSJH1tVw64QGiNIZ9PNLyBDtG+iAq+XGsya052At4BfarzY/Dhv9wrrUr6IMZA==
|
||||||
|
dependencies:
|
||||||
|
"@radix-ui/number" "1.1.0"
|
||||||
|
"@radix-ui/primitive" "1.1.0"
|
||||||
|
"@radix-ui/react-collection" "1.1.0"
|
||||||
|
"@radix-ui/react-compose-refs" "1.1.0"
|
||||||
|
"@radix-ui/react-context" "1.1.1"
|
||||||
|
"@radix-ui/react-direction" "1.1.0"
|
||||||
|
"@radix-ui/react-dismissable-layer" "1.1.1"
|
||||||
|
"@radix-ui/react-focus-guards" "1.1.1"
|
||||||
|
"@radix-ui/react-focus-scope" "1.1.0"
|
||||||
|
"@radix-ui/react-id" "1.1.0"
|
||||||
|
"@radix-ui/react-popper" "1.2.0"
|
||||||
|
"@radix-ui/react-portal" "1.1.2"
|
||||||
|
"@radix-ui/react-primitive" "2.0.0"
|
||||||
|
"@radix-ui/react-slot" "1.1.0"
|
||||||
|
"@radix-ui/react-use-callback-ref" "1.1.0"
|
||||||
|
"@radix-ui/react-use-controllable-state" "1.1.0"
|
||||||
|
"@radix-ui/react-use-layout-effect" "1.1.0"
|
||||||
|
"@radix-ui/react-use-previous" "1.1.0"
|
||||||
|
"@radix-ui/react-visually-hidden" "1.1.0"
|
||||||
|
aria-hidden "^1.1.1"
|
||||||
|
react-remove-scroll "2.6.0"
|
||||||
|
|
||||||
"@radix-ui/react-separator@^1.1.0":
|
"@radix-ui/react-separator@^1.1.0":
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-separator/-/react-separator-1.1.0.tgz#ee0f4d86003b0e3ea7bc6ccab01ea0adee32663e"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-separator/-/react-separator-1.1.0.tgz#ee0f4d86003b0e3ea7bc6ccab01ea0adee32663e"
|
||||||
@ -1969,39 +1996,39 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@sapphire/snowflake/-/snowflake-3.5.3.tgz#0c102aa2ec5b34f806e9bc8625fc6a5e1d0a0c6a"
|
resolved "https://registry.yarnpkg.com/@sapphire/snowflake/-/snowflake-3.5.3.tgz#0c102aa2ec5b34f806e9bc8625fc6a5e1d0a0c6a"
|
||||||
integrity sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==
|
integrity sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==
|
||||||
|
|
||||||
"@shikijs/core@1.22.2":
|
"@shikijs/core@1.23.0":
|
||||||
version "1.22.2"
|
version "1.23.0"
|
||||||
resolved "https://registry.yarnpkg.com/@shikijs/core/-/core-1.22.2.tgz#9c22bd4cc8a4d6c062461cfd35e1faa6c617ca25"
|
resolved "https://registry.yarnpkg.com/@shikijs/core/-/core-1.23.0.tgz#6504882c7cafc1176b2443e87609b68fbdf10096"
|
||||||
integrity sha512-bvIQcd8BEeR1yFvOYv6HDiyta2FFVePbzeowf5pPS1avczrPK+cjmaxxh0nx5QzbON7+Sv0sQfQVciO7bN72sg==
|
integrity sha512-J4Fo22oBlfRHAXec+1AEzcowv+Qdf4ZQkuP/X/UHYH9+KA9LvyFXSXyS+HxuBRFfon+u7bsmKdRBjoZlbDVRkQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@shikijs/engine-javascript" "1.22.2"
|
"@shikijs/engine-javascript" "1.23.0"
|
||||||
"@shikijs/engine-oniguruma" "1.22.2"
|
"@shikijs/engine-oniguruma" "1.23.0"
|
||||||
"@shikijs/types" "1.22.2"
|
"@shikijs/types" "1.23.0"
|
||||||
"@shikijs/vscode-textmate" "^9.3.0"
|
"@shikijs/vscode-textmate" "^9.3.0"
|
||||||
"@types/hast" "^3.0.4"
|
"@types/hast" "^3.0.4"
|
||||||
hast-util-to-html "^9.0.3"
|
hast-util-to-html "^9.0.3"
|
||||||
|
|
||||||
"@shikijs/engine-javascript@1.22.2":
|
"@shikijs/engine-javascript@1.23.0":
|
||||||
version "1.22.2"
|
version "1.23.0"
|
||||||
resolved "https://registry.yarnpkg.com/@shikijs/engine-javascript/-/engine-javascript-1.22.2.tgz#62e90dbd2ed1d78b972ad7d0a1f8ffaaf5e43279"
|
resolved "https://registry.yarnpkg.com/@shikijs/engine-javascript/-/engine-javascript-1.23.0.tgz#51728dd9d68e4ddc123734f816874aded38a1f11"
|
||||||
integrity sha512-iOvql09ql6m+3d1vtvP8fLCVCK7BQD1pJFmHIECsujB0V32BJ0Ab6hxk1ewVSMFA58FI0pR2Had9BKZdyQrxTw==
|
integrity sha512-CcrppseWShG+8Efp1iil9divltuXVdCaU4iu+CKvzTGZO5RmXyAiSx668M7VbX8+s/vt1ZKu75Vn/jWi8O3G/Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@shikijs/types" "1.22.2"
|
"@shikijs/types" "1.23.0"
|
||||||
"@shikijs/vscode-textmate" "^9.3.0"
|
"@shikijs/vscode-textmate" "^9.3.0"
|
||||||
oniguruma-to-js "0.4.3"
|
oniguruma-to-es "0.1.2"
|
||||||
|
|
||||||
"@shikijs/engine-oniguruma@1.22.2":
|
"@shikijs/engine-oniguruma@1.23.0":
|
||||||
version "1.22.2"
|
version "1.23.0"
|
||||||
resolved "https://registry.yarnpkg.com/@shikijs/engine-oniguruma/-/engine-oniguruma-1.22.2.tgz#b12a44e3faf486e19fbcf8952f4b56b9b9b8d9b8"
|
resolved "https://registry.yarnpkg.com/@shikijs/engine-oniguruma/-/engine-oniguruma-1.23.0.tgz#c32610bdfe0850e54b10d9e1f5a689f63e681c91"
|
||||||
integrity sha512-GIZPAGzQOy56mGvWMoZRPggn0dTlBf1gutV5TdceLCZlFNqWmuc7u+CzD0Gd9vQUTgLbrt0KLzz6FNprqYAxlA==
|
integrity sha512-gS8bZLqVvmZXX+E5JUMJICsBp+kx6gj79MH/UEpKHKIqnUzppgbmEn6zLa6mB5D+sHse2gFei3YYJxQe1EzZXQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@shikijs/types" "1.22.2"
|
"@shikijs/types" "1.23.0"
|
||||||
"@shikijs/vscode-textmate" "^9.3.0"
|
"@shikijs/vscode-textmate" "^9.3.0"
|
||||||
|
|
||||||
"@shikijs/types@1.22.2":
|
"@shikijs/types@1.23.0":
|
||||||
version "1.22.2"
|
version "1.23.0"
|
||||||
resolved "https://registry.yarnpkg.com/@shikijs/types/-/types-1.22.2.tgz#695a283f19963fe0638fc2646862ba5cfc4623a8"
|
resolved "https://registry.yarnpkg.com/@shikijs/types/-/types-1.23.0.tgz#860635725176d8b0cd07cda418fb319fc7a068da"
|
||||||
integrity sha512-NCWDa6LGZqTuzjsGfXOBWfjS/fDIbDdmVDug+7ykVe1IKT4c1gakrvlfFYp5NhAXH/lyqLM8wsAPo5wNy73Feg==
|
integrity sha512-HiwzsihRao+IbPk7FER/EQT/D0dEEK3n5LAtHDzL5iRT+JMblA7y9uitUnjEnHeLkKigNM+ZplrP7MuEyyc5kA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@shikijs/vscode-textmate" "^9.3.0"
|
"@shikijs/vscode-textmate" "^9.3.0"
|
||||||
"@types/hast" "^3.0.4"
|
"@types/hast" "^3.0.4"
|
||||||
@ -3460,6 +3487,11 @@ eastasianwidth@^0.2.0:
|
|||||||
resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz"
|
resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz"
|
||||||
integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==
|
integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==
|
||||||
|
|
||||||
|
emoji-regex-xs@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/emoji-regex-xs/-/emoji-regex-xs-1.0.0.tgz#e8af22e5d9dbd7f7f22d280af3d19d2aab5b0724"
|
||||||
|
integrity sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==
|
||||||
|
|
||||||
emoji-regex@^8.0.0:
|
emoji-regex@^8.0.0:
|
||||||
version "8.0.0"
|
version "8.0.0"
|
||||||
resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz"
|
resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz"
|
||||||
@ -6506,12 +6538,14 @@ onetime@^6.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
mimic-fn "^4.0.0"
|
mimic-fn "^4.0.0"
|
||||||
|
|
||||||
oniguruma-to-js@0.4.3:
|
oniguruma-to-es@0.1.2:
|
||||||
version "0.4.3"
|
version "0.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/oniguruma-to-js/-/oniguruma-to-js-0.4.3.tgz#8d899714c21f5c7d59a3c0008ca50e848086d740"
|
resolved "https://registry.yarnpkg.com/oniguruma-to-es/-/oniguruma-to-es-0.1.2.tgz#157a34f2c6a469c053a5deecf3065f4163279cd4"
|
||||||
integrity sha512-X0jWUcAlxORhOqqBREgPMgnshB7ZGYszBNspP+tS9hPD3l13CdaXcHbgImoHUHlrvGx/7AvFEkTRhAGYh+jzjQ==
|
integrity sha512-sBYKVJlIMB0WPO+tSu/NNB1ytSFeHyyJZ3Ayxfx3f/QUuXu0lvZk0VB4K7npmdlHSC0ldqanzh/sUSlAbgCTfw==
|
||||||
dependencies:
|
dependencies:
|
||||||
regex "^4.3.2"
|
emoji-regex-xs "^1.0.0"
|
||||||
|
regex "^4.4.0"
|
||||||
|
regex-recursion "^4.1.0"
|
||||||
|
|
||||||
oo-ascii-tree@^1.84.0:
|
oo-ascii-tree@^1.84.0:
|
||||||
version "1.102.0"
|
version "1.102.0"
|
||||||
@ -7028,7 +7062,19 @@ regenerator-runtime@^0.14.0:
|
|||||||
resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz"
|
resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz"
|
||||||
integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==
|
integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==
|
||||||
|
|
||||||
regex@^4.3.2:
|
regex-recursion@^4.1.0:
|
||||||
|
version "4.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/regex-recursion/-/regex-recursion-4.2.1.tgz#024ee28593b8158e568307b99bf1b7a3d5ea31e9"
|
||||||
|
integrity sha512-QHNZyZAeKdndD1G3bKAbBEKOSSK4KOHQrAJ01N1LJeb0SoH4DJIeFhp0uUpETgONifS4+P3sOgoA1dhzgrQvhA==
|
||||||
|
dependencies:
|
||||||
|
regex-utilities "^2.3.0"
|
||||||
|
|
||||||
|
regex-utilities@^2.3.0:
|
||||||
|
version "2.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/regex-utilities/-/regex-utilities-2.3.0.tgz#87163512a15dce2908cf079c8960d5158ff43280"
|
||||||
|
integrity sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==
|
||||||
|
|
||||||
|
regex@^4.4.0:
|
||||||
version "4.4.0"
|
version "4.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/regex/-/regex-4.4.0.tgz#cb731e2819f230fad69089e1bd854fef7569e90a"
|
resolved "https://registry.yarnpkg.com/regex/-/regex-4.4.0.tgz#cb731e2819f230fad69089e1bd854fef7569e90a"
|
||||||
integrity sha512-uCUSuobNVeqUupowbdZub6ggI5/JZkYyJdDogddJr60L764oxC2pMZov1fQ3wM9bdyzUILDG+Sqx6NAKAz9rKQ==
|
integrity sha512-uCUSuobNVeqUupowbdZub6ggI5/JZkYyJdDogddJr60L764oxC2pMZov1fQ3wM9bdyzUILDG+Sqx6NAKAz9rKQ==
|
||||||
@ -7314,15 +7360,15 @@ shebang-regex@^3.0.0:
|
|||||||
resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz"
|
resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz"
|
||||||
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
|
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
|
||||||
|
|
||||||
shiki@^1.22.2:
|
shiki@^1.23.0:
|
||||||
version "1.22.2"
|
version "1.23.0"
|
||||||
resolved "https://registry.yarnpkg.com/shiki/-/shiki-1.22.2.tgz#ed109a3d0850504ad5a1edf8496470a2121c5b7b"
|
resolved "https://registry.yarnpkg.com/shiki/-/shiki-1.23.0.tgz#83e6a2b71d0faf9fa1679b045266ba5de711b4c6"
|
||||||
integrity sha512-3IZau0NdGKXhH2bBlUk4w1IHNxPh6A5B2sUpyY+8utLu2j/h1QpFkAaUA1bAMxOWWGtTWcAh531vnS4NJKS/lA==
|
integrity sha512-xfdu9DqPkIpExH29cmiTlgo0/jBki5la1Tkfhsv+Wu5TT3APLNHslR1acxuKJOCWqVdSc+pIbs/2ozjVRGppdg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@shikijs/core" "1.22.2"
|
"@shikijs/core" "1.23.0"
|
||||||
"@shikijs/engine-javascript" "1.22.2"
|
"@shikijs/engine-javascript" "1.23.0"
|
||||||
"@shikijs/engine-oniguruma" "1.22.2"
|
"@shikijs/engine-oniguruma" "1.23.0"
|
||||||
"@shikijs/types" "1.22.2"
|
"@shikijs/types" "1.23.0"
|
||||||
"@shikijs/vscode-textmate" "^9.3.0"
|
"@shikijs/vscode-textmate" "^9.3.0"
|
||||||
"@types/hast" "^3.0.4"
|
"@types/hast" "^3.0.4"
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user