mirror of
https://github.com/DeveloLongScript/MHSF.git
synced 2026-05-07 22:14:59 -05:00
bump: 0.10
This commit is contained in:
parent
2e23e9b43f
commit
8aeae0cda4
74
package.json
74
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mh-stats",
|
"name": "mh-stats",
|
||||||
"version": "0.1.0",
|
"version": "0.10.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"packageManager": "yarn@1.22.22",
|
"packageManager": "yarn@1.22.22",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@ -16,6 +16,8 @@
|
|||||||
"@babel/parser": "^7.24.7",
|
"@babel/parser": "^7.24.7",
|
||||||
"@clerk/nextjs": "^5.1.3",
|
"@clerk/nextjs": "^5.1.3",
|
||||||
"@monaco-editor/react": "^4.6.0",
|
"@monaco-editor/react": "^4.6.0",
|
||||||
|
"@radix-ui/react-icons": "^1.3.0",
|
||||||
|
"@radix-ui/react-menubar": "^1.1.1",
|
||||||
"@unocss/eslint-plugin": "^0.61.5",
|
"@unocss/eslint-plugin": "^0.61.5",
|
||||||
"@unocss/postcss": "^0.61.5",
|
"@unocss/postcss": "^0.61.5",
|
||||||
"@unocss/transformer-directives": "^0.61.5",
|
"@unocss/transformer-directives": "^0.61.5",
|
||||||
@ -43,41 +45,8 @@
|
|||||||
"unplugin-tailwindcss-mangle": "^3.0.1"
|
"unplugin-tailwindcss-mangle": "^3.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"geist": "^1.3.0",
|
|
||||||
"@hookform/resolvers": "^3.9.0",
|
|
||||||
"@types/canvas-confetti": "^1.6.4",
|
|
||||||
"@types/nprogress": "^0.2.3",
|
|
||||||
"@types/react-twemoji": "^0.4.3",
|
|
||||||
"@clerk/themes": "^2.1.19",
|
"@clerk/themes": "^2.1.19",
|
||||||
"@tailwindcss/typography": "^0.5.13",
|
"@hookform/resolvers": "^3.9.0",
|
||||||
"@types/node": "^20",
|
|
||||||
"@types/react": "^18",
|
|
||||||
"@types/react-dom": "^18",
|
|
||||||
"@unocss/eslint-config": "^0.61.5",
|
|
||||||
"@unocss/preset-uno": "^0.61.5",
|
|
||||||
"@unocss/transformer-compile-class": "^0.61.5",
|
|
||||||
"eslint": "^8",
|
|
||||||
"eslint-config-next": "14.2.3",
|
|
||||||
"mangle-css-class-webpack-plugin": "^5.1.0",
|
|
||||||
"postcss": "^8",
|
|
||||||
"tailwindcss": "^3.4.1",
|
|
||||||
"typescript": "^5",
|
|
||||||
"vaul": "^0.9.1",
|
|
||||||
"zod": "^3.23.8",
|
|
||||||
"react-hook-form": "^7.52.2",
|
|
||||||
"react-hot-toast": "^2.4.1",
|
|
||||||
"react-hotkeys-hook": "^4.5.0",
|
|
||||||
"react-infinite-scroll-component": "^6.1.0",
|
|
||||||
"react-markdown": "^9.0.1",
|
|
||||||
"react-resizable-panels": "^2.0.23",
|
|
||||||
"recharts": "^2.12.7",
|
|
||||||
"@vercel/analytics": "^1.3.1",
|
|
||||||
"@vercel/speed-insights": "^1.0.12",
|
|
||||||
"canvas-confetti": "^1.9.3",
|
|
||||||
"class-variance-authority": "^0.7.0",
|
|
||||||
"clsx": "^2.1.1",
|
|
||||||
"cmdk": "^1.0.0",
|
|
||||||
"framer-motion": "^11.3.8",
|
|
||||||
"@radix-ui/react-checkbox": "^1.0.4",
|
"@radix-ui/react-checkbox": "^1.0.4",
|
||||||
"@radix-ui/react-context-menu": "^2.1.5",
|
"@radix-ui/react-context-menu": "^2.1.5",
|
||||||
"@radix-ui/react-dialog": "^1.1.1",
|
"@radix-ui/react-dialog": "^1.1.1",
|
||||||
@ -90,6 +59,39 @@
|
|||||||
"@radix-ui/react-separator": "^1.0.3",
|
"@radix-ui/react-separator": "^1.0.3",
|
||||||
"@radix-ui/react-slot": "^1.1.0",
|
"@radix-ui/react-slot": "^1.1.0",
|
||||||
"@radix-ui/react-tabs": "^1.1.0",
|
"@radix-ui/react-tabs": "^1.1.0",
|
||||||
"@radix-ui/react-tooltip": "^1.0.7"
|
"@radix-ui/react-tooltip": "^1.0.7",
|
||||||
|
"@tailwindcss/typography": "^0.5.13",
|
||||||
|
"@types/canvas-confetti": "^1.6.4",
|
||||||
|
"@types/node": "^20",
|
||||||
|
"@types/nprogress": "^0.2.3",
|
||||||
|
"@types/react": "^18",
|
||||||
|
"@types/react-dom": "^18",
|
||||||
|
"@types/react-twemoji": "^0.4.3",
|
||||||
|
"@unocss/eslint-config": "^0.61.5",
|
||||||
|
"@unocss/preset-uno": "^0.61.5",
|
||||||
|
"@unocss/transformer-compile-class": "^0.61.5",
|
||||||
|
"@vercel/analytics": "^1.3.1",
|
||||||
|
"@vercel/speed-insights": "^1.0.12",
|
||||||
|
"canvas-confetti": "^1.9.3",
|
||||||
|
"class-variance-authority": "^0.7.0",
|
||||||
|
"clsx": "^2.1.1",
|
||||||
|
"cmdk": "^1.0.0",
|
||||||
|
"eslint": "^8",
|
||||||
|
"eslint-config-next": "14.2.3",
|
||||||
|
"framer-motion": "^11.3.8",
|
||||||
|
"geist": "^1.3.0",
|
||||||
|
"mangle-css-class-webpack-plugin": "^5.1.0",
|
||||||
|
"postcss": "^8",
|
||||||
|
"react-hook-form": "^7.52.2",
|
||||||
|
"react-hot-toast": "^2.4.1",
|
||||||
|
"react-hotkeys-hook": "^4.5.0",
|
||||||
|
"react-infinite-scroll-component": "^6.1.0",
|
||||||
|
"react-markdown": "^9.0.1",
|
||||||
|
"react-resizable-panels": "^2.0.23",
|
||||||
|
"recharts": "^2.12.7",
|
||||||
|
"tailwindcss": "^3.4.1",
|
||||||
|
"typescript": "^5",
|
||||||
|
"vaul": "^0.9.1",
|
||||||
|
"zod": "^3.23.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -100,22 +100,19 @@
|
|||||||
backdrop-filter: blur(8px) !important;
|
backdrop-filter: blur(8px) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* width */
|
/** Cool scrollbar */
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
width: 10px;
|
width: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Track */
|
|
||||||
::-webkit-scrollbar-track {
|
::-webkit-scrollbar-track {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle */
|
|
||||||
::-webkit-scrollbar-thumb {
|
::-webkit-scrollbar-thumb {
|
||||||
background: #888;
|
background: #888;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle on hover */
|
|
||||||
::-webkit-scrollbar-thumb:hover {
|
::-webkit-scrollbar-thumb:hover {
|
||||||
background: #555;
|
background: #555;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import TextFromPathname from "@/components/TextFromPathname";
|
|||||||
import { Inter as interFont } from "next/font/google";
|
import { Inter as interFont } from "next/font/google";
|
||||||
import { CommandBarer } from "@/components/CommandBar";
|
import { CommandBarer } from "@/components/CommandBar";
|
||||||
import ThemedToaster from "@/components/misc/ThemedToaster";
|
import ThemedToaster from "@/components/misc/ThemedToaster";
|
||||||
|
import UnofficalDialog from "@/components/misc/UnofficalDialog";
|
||||||
|
|
||||||
const inter = interFont({ variable: "--font-inter", subsets: ["latin"] });
|
const inter = interFont({ variable: "--font-inter", subsets: ["latin"] });
|
||||||
export default async function RootLayout({
|
export default async function RootLayout({
|
||||||
@ -68,6 +69,7 @@ export default async function RootLayout({
|
|||||||
<CommandBarer />
|
<CommandBarer />
|
||||||
<SpeedInsights />
|
<SpeedInsights />
|
||||||
<Analytics />
|
<Analytics />
|
||||||
|
<UnofficalDialog />
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
</ClerkThemeProvider>
|
</ClerkThemeProvider>
|
||||||
|
|||||||
@ -23,22 +23,29 @@ import toast from "react-hot-toast";
|
|||||||
import { allTags, allCategories } from "@/allTags";
|
import { allTags, allCategories } from "@/allTags";
|
||||||
import IconDisplay from "./IconDisplay";
|
import IconDisplay from "./IconDisplay";
|
||||||
import InfiniteScroll from "react-infinite-scroll-component";
|
import InfiniteScroll from "react-infinite-scroll-component";
|
||||||
import {
|
|
||||||
Popover,
|
|
||||||
PopoverContent,
|
|
||||||
PopoverTrigger,
|
|
||||||
} from "@/components/ui/popover";
|
|
||||||
import { Checkbox } from "@/components/ui/checkbox";
|
|
||||||
import { Spinner } from "./ui/spinner";
|
import { Spinner } from "./ui/spinner";
|
||||||
import { CommandIcon } from "lucide-react";
|
import { CommandIcon } from "lucide-react";
|
||||||
import { OnlineServer } from "@/lib/types/mh-server";
|
import { OnlineServer } from "@/lib/types/mh-server";
|
||||||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
|
||||||
import { useEffectOnce } from "@/lib/useEffectOnce";
|
import { useEffectOnce } from "@/lib/useEffectOnce";
|
||||||
import ServerCard from "./ServerCard";
|
import ServerCard from "./ServerCard";
|
||||||
import events from "@/lib/commandEvent";
|
import events from "@/lib/commandEvent";
|
||||||
import { BorderBeam } from "@/components/effects/border-beam";
|
import { BorderBeam } from "@/components/effects/border-beam";
|
||||||
import { Label } from "./ui/label";
|
|
||||||
import { useRouter } from "@/lib/useRouter";
|
import { useRouter } from "@/lib/useRouter";
|
||||||
|
import {
|
||||||
|
Menubar,
|
||||||
|
MenubarCheckboxItem,
|
||||||
|
MenubarContent,
|
||||||
|
MenubarItem,
|
||||||
|
MenubarMenu,
|
||||||
|
MenubarRadioGroup,
|
||||||
|
MenubarRadioItem,
|
||||||
|
MenubarSeparator,
|
||||||
|
MenubarShortcut,
|
||||||
|
MenubarSub,
|
||||||
|
MenubarSubContent,
|
||||||
|
MenubarSubTrigger,
|
||||||
|
MenubarTrigger,
|
||||||
|
} from "@/components/ui/menubar";
|
||||||
|
|
||||||
export default function ServerList() {
|
export default function ServerList() {
|
||||||
const [loading, setLoading]: any = useState(true);
|
const [loading, setLoading]: any = useState(true);
|
||||||
@ -62,6 +69,7 @@ export default function ServerList() {
|
|||||||
const [inErrState, setErrState] = useState(false);
|
const [inErrState, setErrState] = useState(false);
|
||||||
const [servers, setServers] = useState<Array<OnlineServer>>([]);
|
const [servers, setServers] = useState<Array<OnlineServer>>([]);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const [ipr, setIPR] = useState("4");
|
||||||
const [filters, setFilters] = useState<
|
const [filters, setFilters] = useState<
|
||||||
Array<(server: OnlineServer) => Promise<boolean>>
|
Array<(server: OnlineServer) => Promise<boolean>>
|
||||||
>([]);
|
>([]);
|
||||||
@ -200,27 +208,77 @@ export default function ServerList() {
|
|||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
<Separator />
|
<Separator />
|
||||||
<div className="mt-3 ml-3">
|
<Menubar className="mt-3 ml-2 border rounded p-2">
|
||||||
<Button
|
<MenubarMenu>
|
||||||
onClick={() => events.emit("search-request-event")}
|
<MenubarTrigger>Servers</MenubarTrigger>
|
||||||
variant="secondary"
|
<MenubarContent>
|
||||||
className="max-lg:mb-3"
|
<MenubarItem onSelect={() => events.emit("search-request-event")}>
|
||||||
>
|
Search Servers
|
||||||
Search{" "}
|
<MenubarShortcut className="flex items-center ml-3">
|
||||||
<code className="ml-2 flex items-center">
|
|
||||||
<CommandIcon size={14} />
|
<CommandIcon size={14} />
|
||||||
+Shift+K
|
+Shift+K
|
||||||
</code>
|
</MenubarShortcut>
|
||||||
</Button>
|
</MenubarItem>
|
||||||
<Popover>
|
<MenubarItem
|
||||||
<PopoverTrigger>
|
onSelect={() => {
|
||||||
<Button className="ml-3" variant="secondary">
|
setRandomData(serverList.getRandomServer());
|
||||||
Filter
|
setRandom(true);
|
||||||
<code className="ml-2">{filters.length}</code>
|
}}
|
||||||
</Button>
|
>
|
||||||
</PopoverTrigger>
|
Pick Random Server
|
||||||
<PopoverContent className="w-[390px] z-3">
|
</MenubarItem>
|
||||||
<RadioGroup
|
<MenubarSeparator />
|
||||||
|
<MenubarItem
|
||||||
|
onSelect={() => {
|
||||||
|
toast.promise(
|
||||||
|
new Promise((s, e) => {
|
||||||
|
setLoading(true);
|
||||||
|
serverList
|
||||||
|
.fetchDataAndFilter()
|
||||||
|
.then(() => {
|
||||||
|
serverList.moveListDown();
|
||||||
|
|
||||||
|
let stringList: Array<{
|
||||||
|
server: string;
|
||||||
|
motd: string;
|
||||||
|
}> = [];
|
||||||
|
let obj: any = {};
|
||||||
|
|
||||||
|
serverList.currentServers.forEach((b) => {
|
||||||
|
stringList.push({ motd: b.motd, server: b.name });
|
||||||
|
});
|
||||||
|
|
||||||
|
serverList.getMOTDs(stringList).then((c) => {
|
||||||
|
var updatedSL = motdList;
|
||||||
|
c.forEach((b: { server: string; motd: string }) => {
|
||||||
|
updatedSL[b.server] = b.motd;
|
||||||
|
});
|
||||||
|
setMotdList(updatedSL);
|
||||||
|
setServers(serverList.currentServers);
|
||||||
|
setLoading(false);
|
||||||
|
s(false);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
e();
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
success: "Succesfully refreshed servers",
|
||||||
|
loading: "Refreshing...",
|
||||||
|
error: "Error while refreshing",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Refresh
|
||||||
|
</MenubarItem>
|
||||||
|
</MenubarContent>
|
||||||
|
</MenubarMenu>
|
||||||
|
<MenubarMenu>
|
||||||
|
<MenubarTrigger>Filter</MenubarTrigger>
|
||||||
|
<MenubarContent className="max-h-[400px] overflow-auto">
|
||||||
|
<MenubarRadioGroup
|
||||||
onValueChange={(v) => {
|
onValueChange={(v) => {
|
||||||
toast.promise(
|
toast.promise(
|
||||||
new Promise((g, b) => {
|
new Promise((g, b) => {
|
||||||
@ -344,7 +402,7 @@ export default function ServerList() {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
defaultValue={(() => {
|
value={(() => {
|
||||||
if (nameFilters["smaller-tf"]) {
|
if (nameFilters["smaller-tf"]) {
|
||||||
return "smaller";
|
return "smaller";
|
||||||
} else if (nameFilters["bigger-tf"]) {
|
} else if (nameFilters["bigger-tf"]) {
|
||||||
@ -354,57 +412,38 @@ export default function ServerList() {
|
|||||||
}
|
}
|
||||||
})()}
|
})()}
|
||||||
>
|
>
|
||||||
<div className="items-top flex space-x-2">
|
<MenubarRadioItem value="smaller">
|
||||||
<RadioGroupItem id="smaller" value="smaller" />
|
<div className="block">
|
||||||
<div className="grid gap-1.5 leading-none">
|
|
||||||
<label
|
|
||||||
htmlFor="smaller"
|
|
||||||
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
|
||||||
>
|
|
||||||
Only allow smaller servers
|
Only allow smaller servers
|
||||||
</label>
|
<br />
|
||||||
<p className="text-sm text-muted-foreground">
|
<span className="text-sm text-muted-foreground">
|
||||||
Server have 15-7 players, cannot be{" "}
|
Only allow servers that have the player range 7-15, and
|
||||||
<Badge variant="secondary">Always Online</Badge>
|
cannot <br />
|
||||||
</p>
|
be Always Online.
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</MenubarRadioItem>
|
||||||
<div className="items-top flex space-x-2">
|
<MenubarRadioItem value="bigger">
|
||||||
<RadioGroupItem id="bigger" value="bigger" />
|
<div className="block">
|
||||||
<div className="grid gap-1.5 leading-none">
|
|
||||||
<label
|
|
||||||
htmlFor="bigger"
|
|
||||||
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
|
||||||
>
|
|
||||||
Only allow bigger servers
|
Only allow bigger servers
|
||||||
</label>
|
|
||||||
<p className="text-sm text-muted-foreground">
|
|
||||||
Server has 16 players or more
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="items-top flex space-x-2">
|
|
||||||
<RadioGroupItem id="none" value="none" />
|
|
||||||
<div className="grid gap-1.5 leading-none">
|
|
||||||
<label
|
|
||||||
htmlFor="none"
|
|
||||||
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
|
||||||
>
|
|
||||||
Custom/no requirements
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</RadioGroup>
|
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<span className="text-sm text-muted-foreground">
|
||||||
<strong className="pb-2">Tags</strong>
|
Only allow servers with more than 15 players.
|
||||||
<br />
|
</span>
|
||||||
|
</div>
|
||||||
|
</MenubarRadioItem>
|
||||||
|
<MenubarRadioItem value="none">
|
||||||
|
No/custom requirements
|
||||||
|
</MenubarRadioItem>
|
||||||
|
</MenubarRadioGroup>
|
||||||
|
<MenubarSeparator />
|
||||||
|
<MenubarSub>
|
||||||
|
<span className="text-sm text-muted-foreground ml-2">Tags</span>
|
||||||
|
</MenubarSub>
|
||||||
{allTags.map((tag) => (
|
{allTags.map((tag) => (
|
||||||
<div key={tag.docsName}>
|
<div key={tag.docsName}>
|
||||||
{tag.docsName && tag.__filter == undefined && (
|
{tag.docsName && tag.__filter == undefined && (
|
||||||
<div className="items-top flex space-x-2 pb-1">
|
<MenubarCheckboxItem
|
||||||
<Checkbox
|
|
||||||
disabled={templateFilter && tag.__disab != undefined}
|
disabled={templateFilter && tag.__disab != undefined}
|
||||||
id={tag.docsName}
|
id={tag.docsName}
|
||||||
checked={(() => {
|
checked={(() => {
|
||||||
@ -447,30 +486,22 @@ export default function ServerList() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
|
||||||
<div className="grid gap-1.5 leading-none">
|
|
||||||
<label
|
|
||||||
htmlFor={tag.docsName}
|
|
||||||
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
|
||||||
>
|
>
|
||||||
<Badge variant={tag.role} className="mr-1">
|
<Badge variant={tag.role} className="mr-1">
|
||||||
{tag.docsName}
|
{tag.docsName}
|
||||||
</Badge>
|
</Badge>
|
||||||
</label>
|
</MenubarCheckboxItem>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
<br />
|
<MenubarSeparator />
|
||||||
<strong>Categories</strong>
|
<MenubarSub>
|
||||||
<br />
|
<span className="text-sm text-muted-foreground ml-2">
|
||||||
|
Categories
|
||||||
|
</span>
|
||||||
|
</MenubarSub>
|
||||||
{allCategories.map((categorie) => (
|
{allCategories.map((categorie) => (
|
||||||
<div
|
<MenubarCheckboxItem
|
||||||
className="items-top flex space-x-2 pb-1"
|
|
||||||
key={categorie.name}
|
|
||||||
>
|
|
||||||
<Checkbox
|
|
||||||
id={categorie.name}
|
id={categorie.name}
|
||||||
onCheckedChange={async (b) => {
|
onCheckedChange={async (b) => {
|
||||||
var filt = nameFilters;
|
var filt = nameFilters;
|
||||||
@ -510,98 +541,49 @@ export default function ServerList() {
|
|||||||
checked={(() => {
|
checked={(() => {
|
||||||
return nameFilters["c-" + categorie.name];
|
return nameFilters["c-" + categorie.name];
|
||||||
})()}
|
})()}
|
||||||
/>
|
|
||||||
<div className="grid gap-1.5 leading-none">
|
|
||||||
<label
|
|
||||||
htmlFor={categorie.name}
|
|
||||||
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
|
||||||
>
|
>
|
||||||
<Badge variant={categorie.role} className="mr-1">
|
<Badge variant={categorie.role} className="mr-1">
|
||||||
{categorie.name}
|
{categorie.name}
|
||||||
</Badge>
|
</Badge>
|
||||||
</label>
|
</MenubarCheckboxItem>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
))}
|
||||||
</PopoverContent>
|
</MenubarContent>
|
||||||
</Popover>
|
</MenubarMenu>
|
||||||
<Popover>
|
<MenubarMenu>
|
||||||
<PopoverTrigger>
|
<MenubarTrigger>View</MenubarTrigger>
|
||||||
<Button className="ml-2" variant="secondary">
|
<MenubarContent>
|
||||||
Sort
|
<MenubarSub>
|
||||||
</Button>
|
<MenubarSubTrigger>Grid</MenubarSubTrigger>
|
||||||
</PopoverTrigger>
|
<MenubarSubContent>
|
||||||
<PopoverContent>
|
<MenubarRadioGroup value={ipr} onValueChange={setIPR}>
|
||||||
<RadioGroup
|
<MenubarRadioItem value="4">4 items per row</MenubarRadioItem>
|
||||||
defaultValue="option-one"
|
<MenubarRadioItem value="5">5 items per row</MenubarRadioItem>
|
||||||
onValueChange={() => router.push("/sort/favorites")}
|
<MenubarRadioItem value="6">6 items per row</MenubarRadioItem>
|
||||||
>
|
</MenubarRadioGroup>
|
||||||
<div className="flex items-center space-x-2">
|
</MenubarSubContent>
|
||||||
<RadioGroupItem value="option-one" id="option-one" />
|
</MenubarSub>
|
||||||
<Label htmlFor="option-one">Online Players</Label>
|
<MenubarSub>
|
||||||
</div>
|
<MenubarSubTrigger>Sort</MenubarSubTrigger>
|
||||||
<div className="flex items-center space-x-2">
|
<MenubarSubContent>
|
||||||
<RadioGroupItem value="option-two" id="option-two" />
|
<MenubarRadioGroup
|
||||||
<Label htmlFor="option-two">Favorites</Label>
|
value="joins"
|
||||||
</div>
|
onValueChange={(c) =>
|
||||||
</RadioGroup>
|
c == "favorites" && router.push("/sort/favorites")
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
<Button
|
|
||||||
variant="secondary"
|
|
||||||
className="md:ml-3 "
|
|
||||||
onClick={() => {
|
|
||||||
setRandomData(serverList.getRandomServer());
|
|
||||||
setRandom(true);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Pick Random Server
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="secondary"
|
|
||||||
className="ml-3"
|
|
||||||
onClick={() => {
|
|
||||||
toast.promise(
|
|
||||||
new Promise((s, e) => {
|
|
||||||
setLoading(true);
|
|
||||||
serverList
|
|
||||||
.fetchDataAndFilter()
|
|
||||||
.then(() => {
|
|
||||||
serverList.moveListDown();
|
|
||||||
|
|
||||||
let stringList: Array<{ server: string; motd: string }> =
|
|
||||||
[];
|
|
||||||
let obj: any = {};
|
|
||||||
|
|
||||||
serverList.currentServers.forEach((b) => {
|
|
||||||
stringList.push({ motd: b.motd, server: b.name });
|
|
||||||
});
|
|
||||||
|
|
||||||
serverList.getMOTDs(stringList).then((c) => {
|
|
||||||
var updatedSL = motdList;
|
|
||||||
c.forEach((b: { server: string; motd: string }) => {
|
|
||||||
updatedSL[b.server] = b.motd;
|
|
||||||
});
|
|
||||||
setMotdList(updatedSL);
|
|
||||||
setServers(serverList.currentServers);
|
|
||||||
setLoading(false);
|
|
||||||
s(false);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
e();
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
{
|
|
||||||
success: "Succesfully refreshed servers",
|
|
||||||
loading: "Refreshing...",
|
|
||||||
error: "Error while refreshing",
|
|
||||||
}
|
}
|
||||||
);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
Refresh
|
<MenubarRadioItem value="joins">
|
||||||
</Button>
|
Players Online
|
||||||
|
</MenubarRadioItem>
|
||||||
|
<MenubarRadioItem value="favorites">
|
||||||
|
Favorites
|
||||||
|
</MenubarRadioItem>
|
||||||
|
</MenubarRadioGroup>
|
||||||
|
</MenubarSubContent>
|
||||||
|
</MenubarSub>
|
||||||
|
</MenubarContent>
|
||||||
|
</MenubarMenu>
|
||||||
|
</Menubar>
|
||||||
|
|
||||||
<Dialog open={random} onOpenChange={setRandom}>
|
<Dialog open={random} onOpenChange={setRandom}>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
{randomData == undefined && <>No data to randomize</>}
|
{randomData == undefined && <>No data to randomize</>}
|
||||||
@ -679,7 +661,7 @@ export default function ServerList() {
|
|||||||
)}
|
)}
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</div>
|
|
||||||
<br />
|
<br />
|
||||||
<InfiniteScroll
|
<InfiniteScroll
|
||||||
dataLength={serverList.currentServers.length}
|
dataLength={serverList.currentServers.length}
|
||||||
@ -712,7 +694,7 @@ export default function ServerList() {
|
|||||||
}
|
}
|
||||||
style={{ overflow: "hidden !important", paddingLeft: 6 }}
|
style={{ overflow: "hidden !important", paddingLeft: 6 }}
|
||||||
>
|
>
|
||||||
<div className=" grid sm:grid-cols-4 gap-4">
|
<div className={" grid " + "grid-cols-" + ipr + " gap-4"}>
|
||||||
{servers.map((b: any) => (
|
{servers.map((b: any) => (
|
||||||
<>
|
<>
|
||||||
<ServerCard b={b} motd={motdList[b.name]} />
|
<ServerCard b={b} motd={motdList[b.name]} />
|
||||||
|
|||||||
47
src/components/misc/UnofficalDialog.tsx
Normal file
47
src/components/misc/UnofficalDialog.tsx
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
"use client";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogDescription,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
} from "../ui/dialog";
|
||||||
|
|
||||||
|
export default function UnofficalDialog() {
|
||||||
|
const [isOpen, setOpen] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const dialog = localStorage.getItem("unoffical-dialog-open");
|
||||||
|
|
||||||
|
if (dialog == null) {
|
||||||
|
setOpen(true);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onChangeVal = (state: boolean) => {
|
||||||
|
if (state == false) {
|
||||||
|
setOpen(false);
|
||||||
|
localStorage.setItem("unoffical-dialog-open", "true");
|
||||||
|
} else setOpen(state);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open={isOpen} onOpenChange={onChangeVal}>
|
||||||
|
<DialogContent>
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>Welcome to the Minehut Server List (MHSF)</DialogTitle>
|
||||||
|
</DialogHeader>
|
||||||
|
<DialogDescription>
|
||||||
|
MHSF is a Minehut server-list using the Minehut API to serve you
|
||||||
|
servers with filters, sorts and other helpful information when picking
|
||||||
|
a server to play.{" "}
|
||||||
|
<span className="font-bold">
|
||||||
|
Keep in mind that MHSF is not endorsed by Minehut or GamerSafer in
|
||||||
|
any way, as MHSF is a open-source unofficial project.
|
||||||
|
</span>
|
||||||
|
</DialogDescription>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
240
src/components/ui/menubar.tsx
Normal file
240
src/components/ui/menubar.tsx
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import {
|
||||||
|
CheckIcon,
|
||||||
|
ChevronRightIcon,
|
||||||
|
DotFilledIcon,
|
||||||
|
} from "@radix-ui/react-icons"
|
||||||
|
import * as MenubarPrimitive from "@radix-ui/react-menubar"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const MenubarMenu = MenubarPrimitive.Menu
|
||||||
|
|
||||||
|
const MenubarGroup = MenubarPrimitive.Group
|
||||||
|
|
||||||
|
const MenubarPortal = MenubarPrimitive.Portal
|
||||||
|
|
||||||
|
const MenubarSub = MenubarPrimitive.Sub
|
||||||
|
|
||||||
|
const MenubarRadioGroup = MenubarPrimitive.RadioGroup
|
||||||
|
|
||||||
|
const Menubar = React.forwardRef<
|
||||||
|
React.ElementRef<typeof MenubarPrimitive.Root>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Root>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<MenubarPrimitive.Root
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex h-9 items-center space-x-1 rounded-md border bg-background p-1 shadow-sm",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
Menubar.displayName = MenubarPrimitive.Root.displayName
|
||||||
|
|
||||||
|
const MenubarTrigger = React.forwardRef<
|
||||||
|
React.ElementRef<typeof MenubarPrimitive.Trigger>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Trigger>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<MenubarPrimitive.Trigger
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex cursor-default select-none items-center rounded-sm px-3 py-1 text-sm font-medium outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
MenubarTrigger.displayName = MenubarPrimitive.Trigger.displayName
|
||||||
|
|
||||||
|
const MenubarSubTrigger = React.forwardRef<
|
||||||
|
React.ElementRef<typeof MenubarPrimitive.SubTrigger>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.SubTrigger> & {
|
||||||
|
inset?: boolean
|
||||||
|
}
|
||||||
|
>(({ className, inset, children, ...props }, ref) => (
|
||||||
|
<MenubarPrimitive.SubTrigger
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
|
||||||
|
inset && "pl-8",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
<ChevronRightIcon className="ml-auto h-4 w-4" />
|
||||||
|
</MenubarPrimitive.SubTrigger>
|
||||||
|
))
|
||||||
|
MenubarSubTrigger.displayName = MenubarPrimitive.SubTrigger.displayName
|
||||||
|
|
||||||
|
const MenubarSubContent = React.forwardRef<
|
||||||
|
React.ElementRef<typeof MenubarPrimitive.SubContent>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.SubContent>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<MenubarPrimitive.SubContent
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg 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",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
MenubarSubContent.displayName = MenubarPrimitive.SubContent.displayName
|
||||||
|
|
||||||
|
const MenubarContent = React.forwardRef<
|
||||||
|
React.ElementRef<typeof MenubarPrimitive.Content>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Content>
|
||||||
|
>(
|
||||||
|
(
|
||||||
|
{ className, align = "start", alignOffset = -4, sideOffset = 8, ...props },
|
||||||
|
ref
|
||||||
|
) => (
|
||||||
|
<MenubarPrimitive.Portal>
|
||||||
|
<MenubarPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
align={align}
|
||||||
|
alignOffset={alignOffset}
|
||||||
|
sideOffset={sideOffset}
|
||||||
|
className={cn(
|
||||||
|
"z-50 min-w-[12rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in 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",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</MenubarPrimitive.Portal>
|
||||||
|
)
|
||||||
|
)
|
||||||
|
MenubarContent.displayName = MenubarPrimitive.Content.displayName
|
||||||
|
|
||||||
|
const MenubarItem = React.forwardRef<
|
||||||
|
React.ElementRef<typeof MenubarPrimitive.Item>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Item> & {
|
||||||
|
inset?: boolean
|
||||||
|
}
|
||||||
|
>(({ className, inset, ...props }, ref) => (
|
||||||
|
<MenubarPrimitive.Item
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||||
|
inset && "pl-8",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
MenubarItem.displayName = MenubarPrimitive.Item.displayName
|
||||||
|
|
||||||
|
const MenubarCheckboxItem = React.forwardRef<
|
||||||
|
React.ElementRef<typeof MenubarPrimitive.CheckboxItem>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.CheckboxItem>
|
||||||
|
>(({ className, children, checked, ...props }, ref) => (
|
||||||
|
<MenubarPrimitive.CheckboxItem
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
checked={checked}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||||
|
<MenubarPrimitive.ItemIndicator>
|
||||||
|
<CheckIcon className="h-4 w-4" />
|
||||||
|
</MenubarPrimitive.ItemIndicator>
|
||||||
|
</span>
|
||||||
|
{children}
|
||||||
|
</MenubarPrimitive.CheckboxItem>
|
||||||
|
))
|
||||||
|
MenubarCheckboxItem.displayName = MenubarPrimitive.CheckboxItem.displayName
|
||||||
|
|
||||||
|
const MenubarRadioItem = React.forwardRef<
|
||||||
|
React.ElementRef<typeof MenubarPrimitive.RadioItem>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.RadioItem>
|
||||||
|
>(({ className, children, ...props }, ref) => (
|
||||||
|
<MenubarPrimitive.RadioItem
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 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 left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||||
|
<MenubarPrimitive.ItemIndicator>
|
||||||
|
<DotFilledIcon className="h-4 w-4 fill-current" />
|
||||||
|
</MenubarPrimitive.ItemIndicator>
|
||||||
|
</span>
|
||||||
|
{children}
|
||||||
|
</MenubarPrimitive.RadioItem>
|
||||||
|
))
|
||||||
|
MenubarRadioItem.displayName = MenubarPrimitive.RadioItem.displayName
|
||||||
|
|
||||||
|
const MenubarLabel = React.forwardRef<
|
||||||
|
React.ElementRef<typeof MenubarPrimitive.Label>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Label> & {
|
||||||
|
inset?: boolean
|
||||||
|
}
|
||||||
|
>(({ className, inset, ...props }, ref) => (
|
||||||
|
<MenubarPrimitive.Label
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"px-2 py-1.5 text-sm font-semibold",
|
||||||
|
inset && "pl-8",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
MenubarLabel.displayName = MenubarPrimitive.Label.displayName
|
||||||
|
|
||||||
|
const MenubarSeparator = React.forwardRef<
|
||||||
|
React.ElementRef<typeof MenubarPrimitive.Separator>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Separator>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<MenubarPrimitive.Separator
|
||||||
|
ref={ref}
|
||||||
|
className={cn("-mx-1 my-1 h-px bg-muted", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
MenubarSeparator.displayName = MenubarPrimitive.Separator.displayName
|
||||||
|
|
||||||
|
const MenubarShortcut = ({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.HTMLAttributes<HTMLSpanElement>) => {
|
||||||
|
return (
|
||||||
|
<span
|
||||||
|
className={cn(
|
||||||
|
"ml-auto text-xs tracking-widest text-muted-foreground",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
MenubarShortcut.displayname = "MenubarShortcut"
|
||||||
|
|
||||||
|
export {
|
||||||
|
Menubar,
|
||||||
|
MenubarMenu,
|
||||||
|
MenubarTrigger,
|
||||||
|
MenubarContent,
|
||||||
|
MenubarItem,
|
||||||
|
MenubarSeparator,
|
||||||
|
MenubarLabel,
|
||||||
|
MenubarCheckboxItem,
|
||||||
|
MenubarRadioGroup,
|
||||||
|
MenubarRadioItem,
|
||||||
|
MenubarPortal,
|
||||||
|
MenubarSubContent,
|
||||||
|
MenubarSubTrigger,
|
||||||
|
MenubarGroup,
|
||||||
|
MenubarSub,
|
||||||
|
MenubarShortcut,
|
||||||
|
}
|
||||||
@ -115,7 +115,10 @@ export default function parseToHTML(m: string, tw?: boolean): Promise<string> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function objToHTML(i: Element): string {
|
function objToHTML(i: Element | string): string {
|
||||||
|
if (typeof i == "string") {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
var curClass = "";
|
var curClass = "";
|
||||||
var contents = "";
|
var contents = "";
|
||||||
if (i.extra != undefined) {
|
if (i.extra != undefined) {
|
||||||
@ -152,7 +155,7 @@ function createHTML(
|
|||||||
) {
|
) {
|
||||||
if (className == undefined) className = "";
|
if (className == undefined) className = "";
|
||||||
if (contents == undefined) contents = "";
|
if (contents == undefined) contents = "";
|
||||||
if (contents == "undefined") contents = "<br/>";
|
if (contents == "\n") contents = "<br>";
|
||||||
|
|
||||||
if (tw == false || tw == undefined) {
|
if (tw == false || tw == undefined) {
|
||||||
return (
|
return (
|
||||||
@ -189,6 +192,9 @@ function colorConvert(className: string) {
|
|||||||
if (classUnique.startsWith("text-[")) {
|
if (classUnique.startsWith("text-[")) {
|
||||||
result +=
|
result +=
|
||||||
"color: " + classUnique.substring(6, classUnique.length - 1) + "; ";
|
"color: " + classUnique.substring(6, classUnique.length - 1) + "; ";
|
||||||
|
} else {
|
||||||
|
result +=
|
||||||
|
"color: " + classUnique.substring(5, classUnique.length) + "; ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (classUnique.startsWith("font-bold")) {
|
if (classUnique.startsWith("font-bold")) {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
|
||||||
export const version = "b-0.9.0";
|
export const version = "b-0.10.0";
|
||||||
|
|
||||||
const User = ({ user }: { user: string }) => (
|
const User = ({ user }: { user: string }) => (
|
||||||
<span className="cursor-pointer bg-[rgba(255,165,0,0.25);] rounded p-[2.5px]">
|
<span className="cursor-pointer bg-[rgba(255,165,0,0.25);] rounded p-[2.5px]">
|
||||||
@ -44,6 +44,28 @@ export const Changelog = () => (
|
|||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
|
<div>
|
||||||
|
<strong className="flex items-center">
|
||||||
|
Version b-0.10.0 (August 17th 2024)
|
||||||
|
</strong>
|
||||||
|
<ul>
|
||||||
|
<li>• Revamped server list button list</li>
|
||||||
|
<li>• Added welcome dialog when first launching</li>
|
||||||
|
<li>
|
||||||
|
• Fixed an issue where servers were still able to be favorited
|
||||||
|
client-side when logged out
|
||||||
|
</li>
|
||||||
|
<li>• Improved MOTD engine</li>
|
||||||
|
</ul>
|
||||||
|
<br />
|
||||||
|
<i>👀</i>
|
||||||
|
{/** Ensure Tailwind pre-renders all grid column types */}
|
||||||
|
<span className="grid-cols-6" />
|
||||||
|
<span className="grid-cols-5" />
|
||||||
|
<span className="grid-cols-4" />
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
<div>
|
<div>
|
||||||
<strong className="flex items-center">
|
<strong className="flex items-center">
|
||||||
Version b-0.9.0 (August 15th 2024)
|
Version b-0.9.0 (August 15th 2024)
|
||||||
|
|||||||
21
yarn.lock
21
yarn.lock
@ -675,6 +675,11 @@
|
|||||||
"@radix-ui/react-primitive" "2.0.0"
|
"@radix-ui/react-primitive" "2.0.0"
|
||||||
"@radix-ui/react-use-callback-ref" "1.1.0"
|
"@radix-ui/react-use-callback-ref" "1.1.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-icons@^1.3.0":
|
||||||
|
version "1.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-icons/-/react-icons-1.3.0.tgz#c61af8f323d87682c5ca76b856d60c2312dbcb69"
|
||||||
|
integrity sha512-jQxj/0LKgp+j9BiTXz3O3sgs26RNet2iLWmsPyRz2SIcR4q/4SbazXfnYwbAr+vLYKSfc7qxzyGQA1HLlYiuNw==
|
||||||
|
|
||||||
"@radix-ui/react-id@1.0.1":
|
"@radix-ui/react-id@1.0.1":
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.1.tgz"
|
resolved "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.1.tgz"
|
||||||
@ -746,6 +751,22 @@
|
|||||||
aria-hidden "^1.1.1"
|
aria-hidden "^1.1.1"
|
||||||
react-remove-scroll "2.5.7"
|
react-remove-scroll "2.5.7"
|
||||||
|
|
||||||
|
"@radix-ui/react-menubar@^1.1.1":
|
||||||
|
version "1.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-menubar/-/react-menubar-1.1.1.tgz#e126514cb1c46e0a4f9fba7d016e578cc4e41f22"
|
||||||
|
integrity sha512-V05Hryq/BE2m+rs8d5eLfrS0jmSWSDHEbG7jEyLA5D5J9jTvWj/o3v3xDN9YsOlH6QIkJgiaNDaP+S4T1rdykw==
|
||||||
|
dependencies:
|
||||||
|
"@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.0"
|
||||||
|
"@radix-ui/react-direction" "1.1.0"
|
||||||
|
"@radix-ui/react-id" "1.1.0"
|
||||||
|
"@radix-ui/react-menu" "2.1.1"
|
||||||
|
"@radix-ui/react-primitive" "2.0.0"
|
||||||
|
"@radix-ui/react-roving-focus" "1.1.0"
|
||||||
|
"@radix-ui/react-use-controllable-state" "1.1.0"
|
||||||
|
|
||||||
"@radix-ui/react-navigation-menu@^1.1.4":
|
"@radix-ui/react-navigation-menu@^1.1.4":
|
||||||
version "1.1.4"
|
version "1.1.4"
|
||||||
resolved "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.1.4.tgz"
|
resolved "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.1.4.tgz"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user