bump: 0.8.0

This commit is contained in:
dvelo 2024-08-11 22:14:36 -05:00
parent 0a620523c4
commit b33191bdaa
10 changed files with 275 additions and 106 deletions

BIN
public/imgs/badge1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 739 B

@ -69,7 +69,7 @@ export default function ServerPage({ params }: { params: { server: string } }) {
<ColorProvider server={params.server}>
<div className={"pt-16"}>
<Banner server={params.server} />
<TabServer server={params.server} tabDef="historical" />
<TabServer server={params.server} tabDef="statistics" />
<div className="pt-8">
<ServerView server={params.server} />
<div className="p-4 gap-4">

@ -9,15 +9,17 @@ import {
CommandSeparator,
CommandShortcut,
} from "@/components/ui/command";
import { TagShower } from "./ServerList";
import { useState } from "react";
import { useEffect, useState } from "react";
import { OnlineServer } from "@/lib/types/mh-server";
import events from "@/lib/commandEvent";
import { useHotkeys } from "react-hotkeys-hook";
import {
ArrowDown01,
ArrowLeft,
Calendar,
CheckIcon,
CommandIcon,
Database,
LinkIcon,
Server,
Settings,
@ -27,7 +29,10 @@ import { useEffectOnce } from "@/lib/useEffectOnce";
import { useClerk, useUser } from "@clerk/nextjs";
import { useRouter } from "@/lib/useRouter";
import type { SVGProps } from "react";
import { getAccountFavorites } from "@/lib/api";
import { favoriteServer, getAccountFavorites } from "@/lib/api";
import IconDisplay from "./IconDisplay";
import ServerSingle from "@/lib/single";
import toast from "react-hot-toast";
export function SearchCommandBar() {
const [serverList, setServerList] = useState<OnlineServer[]>([]);
@ -58,23 +63,46 @@ export function SearchCommandBar() {
<CommandInput
placeholder="Search for a server (offline or online)"
onValueChange={(c) => {
if (c != "") {
fetch("https://api.minehut.com/server/" + c + "?byName=true").then(
(l) => {
if (l.ok) {
console.log("found!");
l.json().then((m: any) => {
setSearchRes(m.server);
console.log(searchRes);
});
} else {
setSearchRes(undefined);
}
}
);
}
}}
/>
<CommandList>
<CommandGroup heading="">
<CommandGroup heading="Popular Servers">
{serverList.map((b: OnlineServer) => (
<CommandItem
key={b.name}
onSelect={() => {
if (!backEnabled)
events.emit("cmd-server", {
serverName: b.name,
serverObject: b,
});
if (backEnabled)
events.emit("cmd-server-vb", {
serverName: b.name,
serverObject: b,
});
setOpen(false);
}}
>
<IconDisplay server={b} className="mr-2" />
{b.name}
</CommandItem>
))}
</CommandGroup>
<CommandGroup heading="Hierarchy">
<CommandItem
onSelect={() => {
setOpen(false);
@ -86,51 +114,148 @@ export function SearchCommandBar() {
<span>Go back</span>
</CommandItem>
</CommandGroup>
<CommandEmpty>
No results found. (Minehut deleted legacy servers)
</CommandEmpty>
{searchRes == undefined ? (
""
) : (
<CommandGroup heading="Search Results">
</CommandList>
</CommandDialog>
);
}
export function ServerCommandBar() {
const [open, setOpen] = useState(false);
const [serverName, setServerName] = useState("");
const [obj, setObj] = useState<OnlineServer | object>({});
const [vb, setVB] = useState(false);
const router = useRouter();
const [owned, setOwned] = useState(false);
const [serverSingle, setSingle] = useState<ServerSingle>(
new ServerSingle(serverName)
);
useEffect(() => {
events.on("cmd-server", (info) => {
serverSingle.setName(info.serverName);
if (serverSingle != undefined)
(serverSingle as ServerSingle).init(true).then(() => {
setServerName(info.serverName);
setObj(info.serverObject);
setOpen(true);
serverSingle.isCustomized().then((b) => setOwned(true));
});
});
events.on("cmd-server-vb", (info) => {
serverSingle.setName(info.serverName);
setVB(true);
if (serverSingle != undefined)
(serverSingle as ServerSingle).init(true).then(() => {
setServerName(info.serverName);
setObj(info.serverObject);
setOpen(true);
});
});
}, []);
return (
<CommandDialog open={open} onOpenChange={setOpen}>
<CommandInput placeholder="Type a command or search..." />
<CommandList>
{Object.keys(obj).length != 0 && (
<div className="m-4 dark:bg-ring min-h-[150px] rounded p-4 dark:text-white">
<h1 className="font-bold text-2xl">
<IconDisplay server={obj} />
{serverName}
</h1>
<h1 className="text-muted-foreground">
by {(obj as OnlineServer).author}
</h1>
<h2 className="flex items-center text-muted-foreground pt-[15px] pl-1.5">
<span className="relative flex h-[10px] w-[10px]">
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-black dark:bg-[#0cce6b] opacity-75" />
<span className="relative inline-flex rounded-full h-[10px] w-[10px] bg-black dark:bg-[#0cce6b]" />
</span>{" "}
<span className="pl-1.5 text-[16px]">
{(obj as OnlineServer).playerData.playerCount} online currently
</span>
</h2>
<h2 className="flex items-center text-muted-foreground">
<Calendar />
<span className="pl-1.5 text-[16px]">
Created in{" "}
{timeConverter(
(serverSingle as ServerSingle).grabOffline()?.creation
)}
</span>
</h2>
{owned && (
<h2 className="flex items-center text-muted-foreground">
<CheckIcon />
<span className="pl-1.5 text-[16px]">
Is customized by a MHSF User
</span>
</h2>
)}
</div>
)}
<CommandGroup heading="Server Actions">
<CommandItem
onSelect={() => {
router.push("/server/" + searchRes.name);
onClick={() => router.push("/server/" + serverName + "/")}
>
<Server className="mr-2 h-4 w-4" />
Open Server Page
</CommandItem>
<CommandItem
onClick={() => {
favoriteServer(serverName).then(() => toast.success("Done!"));
}}
>
<div className="block">
<span className="font-medium">{searchRes.name}</span> <br />
<code className="text-gray-500 text-[14px]">
{searchRes.joins} total joins {" "}
{searchRes.online ? "Online" : "Offline"}
</code>
</div>
<Star className="mr-2 h-4 w-4" />
Favorite Server
</CommandItem>
<CommandItem
onClick={() => router.push("/server/" + serverName + "/statistics")}
>
<Database className="mr-2 h-4 w-4" />
See Statistics
</CommandItem>
</CommandGroup>
)}
<CommandSeparator />
<CommandGroup heading="Popular Servers">
{serverList.map((b: OnlineServer) => (
<CommandGroup heading="Hierarchy">
<CommandItem
key={b.name}
onSelect={() => {
router.push("/server/" + b.name);
setOpen(false);
if (vb) events.emit("search-request-event-back");
if (!vb) events.emit("search-request-event");
}}
>
<div className="block">
<span className="font-medium">{b.name}</span> <br />
<code className="text-gray-500 text-[14px]">
<TagShower server={b} />
</code>
</div>
<ArrowLeft className="mr-2 h-4 w-4" />
Go back
</CommandItem>
))}
{vb && (
<CommandItem
onSelect={() => {
setOpen(false);
events.emit("cmd-event");
}}
>
<ArrowLeft className="mr-2 h-4 w-4" />
Back to main
</CommandItem>
)}
</CommandGroup>
</CommandList>
</CommandDialog>
);
}
function timeConverter(UNIX_timestamp: any) {
var a = new Date(UNIX_timestamp);
var months = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"];
var year = a.getFullYear();
var month = months[a.getMonth()];
var date = a.getDate();
var time = month + "/" + date + "/" + year;
return time;
}
export function CommandBar() {
const [open, setOpen] = useState(false);
const clerk = useClerk();
@ -327,6 +452,7 @@ export function CommandBarer() {
<SubLinkCommandBar />
<CommandBar />
<SearchCommandBar />
<ServerCommandBar />
</>
);
}

@ -7,18 +7,24 @@ import {
} from "@/components/ui/tooltip";
import { useState, useEffect } from "react";
export default function IconDisplay(props: { server: any }) {
export default function IconDisplay(props: {
server: any;
className?: string;
}) {
return (
<Tooltip>
<TooltipTrigger>
<div>
<i
className={
props.server.icon != null
(props.server.icon != null
? "icon-minecraft icon-minecraft-" +
props.server.icon.replaceAll("_", "-").toLowerCase()
: "icon-minecraft icon-minecraft-oak-sign"
props.server.icon.replaceAll("_", "-").toLowerCase() +
" "
: "icon-minecraft icon-minecraft-oak-sign ") + props.className
}
/>
</div>
</TooltipTrigger>
<TooltipContent>
<div className="font-mono">

@ -699,7 +699,11 @@ export default function ServerList() {
);
}
export function TagShower(props: { server: OnlineServer; className?: string }) {
export function TagShower(props: {
server: OnlineServer;
className?: string;
unclickable?: boolean;
}) {
const [loading, setLoading] = useState(true);
const [compatiableTags, setCompatiableTags] = useState<
Array<{
@ -757,6 +761,12 @@ export function TagShower(props: { server: OnlineServer; className?: string }) {
<>
{compatiableTags.map((t) => (
<>
{props.unclickable && (
<Badge variant={t.role} className={props.className}>
{t.name}
</Badge>
)}
{!props.unclickable && (
<Dialog key={t.name}>
<DialogTrigger>
<Tooltip>
@ -789,6 +799,7 @@ export function TagShower(props: { server: OnlineServer; className?: string }) {
</DialogHeader>
</DialogContent>
</Dialog>
)}
</>
))}
</>

@ -12,7 +12,6 @@ export default function TabServer({
tabDef: string;
}) {
const [tab, setTab] = useState(tabDef);
const [tabLoading, setTabLoading] = useState(false);
const router = useRouter();
return (
@ -21,9 +20,8 @@ export default function TabServer({
value={tab}
onValueChange={(tac) => {
setTab(tac);
setTabLoading(true);
if (tac == "customize") router.push(`/server/${server}/customize`);
if (tac == "historical") router.push(`/server/${server}/short-term`);
if (tac == "statistics") router.push(`/server/${server}/statistics`);
if (tac == "general") router.push(`/server/${server}`);
}}
className="sm:w-[500px] max-sm:w-[200px]"
@ -34,8 +32,8 @@ export default function TabServer({
<div className="max-sm:hidden">General Information</div>
<Home className="sm:hidden" size={18} />
</TabsTrigger>
<TabsTrigger value="historical">
<div className="max-sm:hidden">Short Term</div>
<TabsTrigger value="statistics">
<div className="max-sm:hidden">Statistics</div>
<Database className="sm:hidden" size={18} />
</TabsTrigger>
<TabsTrigger value="customize">

@ -6,15 +6,15 @@ class CommandEvents {
}
// Method to emit events
emit(eventName: string) {
const event = new CustomEvent(eventName);
emit(eventName: string, info?: any) {
const event = new CustomEvent(eventName, { detail: info });
this.eventTarget.dispatchEvent(event);
}
// Method to listen for events
on(eventName: string, callback: () => void) {
this.eventTarget.addEventListener(eventName, () => {
callback();
on(eventName: string, callback: (info?: any) => void) {
this.eventTarget.addEventListener(eventName, (infoF?: any) => {
callback(infoF.detail);
});
}
}

@ -1,3 +1,4 @@
import { serverOwned } from "./api";
import { OnlineServer, ServerResponse } from "./types/mh-server";
import toast from "react-hot-toast";
@ -10,7 +11,15 @@ export default class ServerSingle {
constructor(name: string) {
this.name = name;
}
init(): Promise<boolean> {
setName(newName: string) {
this.name = newName;
}
isCustomized(): Promise<boolean> {
return serverOwned(this.name);
}
init(skipOnline?: boolean): Promise<boolean> {
return new Promise<boolean>((g, bc) => {
fetch("https://api.minehut.com/server/" + this.name + "?byName=true")
.then((d) => {
@ -18,7 +27,7 @@ export default class ServerSingle {
d.json().then((m) => {
this.online = m.server.online;
this.offlineObj = m.server;
if (this.online == true) {
if (this.online == true && skipOnline != true) {
fetch("https://api.minehut.com/servers").then((l) =>
l.json().then((o) => {
o.servers.forEach((j: OnlineServer) => {

@ -1,4 +1,7 @@
export const version = "b-0.7.2";
import Image from "next/image";
import Link from "next/link";
export const version = "b-0.8.0";
const User = ({ user }: { user: string }) => (
<span className="cursor-pointer bg-[rgba(255,165,0,0.25);] rounded p-[2.5px]">
@ -41,6 +44,16 @@ export const Changelog = () => (
</code>
</div>
<br />
<div>
<strong className="flex items-center">
Version b-0.8.0 (August 11th 2024)
</strong>
<ul>
<li> Fixing up command bar</li>
<li> Renaming "Short Term" to "Statistics"</li>
</ul>
</div>
<br />
<div>
<strong className="flex items-center">
Version b-0.7.2 (August 7th 2024)
@ -118,5 +131,11 @@ export const Changelog = () => (
<li> Inital release!</li>
</ul>
</div>
<br />
<div className="w-full justify-center">
<Link href="https://dvelo.vercel.app">
<Image src="/imgs/badge1.png" alt="cool badge" width={88} height={31} />
</Link>
</div>
</>
);