i wrote puuid in typescript
This commit is contained in:
parent
8a2c3d05c9
commit
91284c242a
4 changed files with 100 additions and 45 deletions
|
|
@ -1,22 +1,40 @@
|
|||
import { definePrefix, type Puuid } from "./puuid"
|
||||
|
||||
export const UserID = definePrefix("user");
|
||||
export const GroupID = definePrefix("group");
|
||||
export const ServerID = definePrefix("srv");
|
||||
|
||||
export type UserId = Puuid<"user">;
|
||||
export type GroupId = Puuid<"group">;
|
||||
export type ServerId = Puuid<"srv">;
|
||||
|
||||
|
||||
export const Status: Record<string, 1|2|3> = {
|
||||
OFFLINE: 1,
|
||||
DND: 2,
|
||||
ONLINE: 3
|
||||
}
|
||||
|
||||
interface InnerData {
|
||||
id: string
|
||||
}
|
||||
export interface Friend extends InnerData {
|
||||
export interface User {
|
||||
id: UserId
|
||||
name: string,
|
||||
status: 1|2|3,
|
||||
image: string
|
||||
}
|
||||
export interface Group extends InnerData {
|
||||
export interface Group {
|
||||
id: GroupId
|
||||
name: string
|
||||
members: number
|
||||
}
|
||||
export interface Server extends InnerData {
|
||||
export interface Server {
|
||||
id: ServerId
|
||||
name: string
|
||||
image: string
|
||||
}
|
||||
|
||||
|
||||
export interface Data {
|
||||
friends: User[],
|
||||
groups: Group[],
|
||||
servers: Server[],
|
||||
};
|
||||
|
|
|
|||
42
src/lib/puuid.ts
Normal file
42
src/lib/puuid.ts
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
import { v4 as uuidv4 } from "uuid";
|
||||
import { v7 as uuidv7 } from "uuid";
|
||||
|
||||
type Brand<K, T> = K & { __brand: T };
|
||||
|
||||
export type Puuid<Prefix extends string> = Brand<
|
||||
string,
|
||||
{ prefix: Prefix }
|
||||
>;
|
||||
|
||||
export function definePrefix<const P extends string>(prefix: P) {
|
||||
const withPrefix = (uuid: string) =>
|
||||
`${prefix}_${uuid}` as Puuid<P>;
|
||||
|
||||
return {
|
||||
prefix,
|
||||
is(value: string): value is Puuid<P> {
|
||||
return value.startsWith(prefix + "_");
|
||||
},
|
||||
|
||||
newV7(): Puuid<P> {
|
||||
return withPrefix(uuidv7());
|
||||
},
|
||||
|
||||
newV4(): Puuid<P> {
|
||||
return withPrefix(uuidv4());
|
||||
},
|
||||
|
||||
parse(value: string): Puuid<P> {
|
||||
if (!value.startsWith(prefix + "_")) {
|
||||
throw new Error(
|
||||
`Invalid prefix, expected "${prefix}_"`
|
||||
);
|
||||
}
|
||||
return value as Puuid<P>;
|
||||
},
|
||||
|
||||
inner(id: Puuid<P>): string {
|
||||
return id.slice(prefix.length + 1);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
@ -1,47 +1,40 @@
|
|||
<script lang="ts">
|
||||
import { Status, type Server, type Group, type Friend } from "$lib";
|
||||
import { Status, type Server, type Group, type User, GroupID, UserID, ServerID, type GroupId, type ServerId, type UserId, type Data } from "$lib";
|
||||
import AppSidebar from "$lib/components/app-sidebar.svelte";
|
||||
import * as Sidebar from "$lib/components/ui/sidebar/index.js";
|
||||
|
||||
let currentPageID: string|null = $state(null);
|
||||
let currentPageType: string|null = $state(null);
|
||||
let currentPage: Friend | Group | Server | null = $state(null);
|
||||
let currentPageID: (UserId|GroupId|ServerId)|null = $state(null);
|
||||
let currentPage: User | Group | Server | undefined = $state();
|
||||
|
||||
const overview_data = {
|
||||
const overview_data: Data = {
|
||||
friends: [
|
||||
{ id: crypto.randomUUID(), name: "Alice", status: Status.OFFLINE, image: "https://placehold.co/40x40" },
|
||||
{ id: crypto.randomUUID(), name: "Bob", status: Status.DND, image: "https://placehold.co/40x40" },
|
||||
{ id: crypto.randomUUID(), name: "Charlie", status: Status.ONLINE, image: "https://placehold.co/40x40" },
|
||||
{ id: UserID.newV7(), name: "Alice", status: Status.OFFLINE, image: "https://placehold.co/40x40" },
|
||||
{ id: UserID.newV7(), name: "Bob", status: Status.DND, image: "https://placehold.co/40x40" },
|
||||
{ id: UserID.newV7(), name: "Charlie", status: Status.ONLINE, image: "https://placehold.co/40x40" },
|
||||
],
|
||||
groups: [
|
||||
{ id: crypto.randomUUID(), name: "Work Team", members: 5 },
|
||||
{ id: crypto.randomUUID(), name: "Gaming Group", members: 8 },
|
||||
{ id: GroupID.newV7(), name: "Work Team", members: 5 },
|
||||
{ id: GroupID.newV7(), name: "Gaming Group", members: 8 },
|
||||
],
|
||||
servers: [
|
||||
{ id: crypto.randomUUID(), name: "Main Server", image: "https://placehold.co/40x40" },
|
||||
{ id: crypto.randomUUID(), name: "Backup Server", image: "https://placehold.co/40x40" },
|
||||
{ id: ServerID.newV7(), name: "Main Server", image: "https://placehold.co/40x40" },
|
||||
{ id: ServerID.newV7(), name: "Backup Server", image: "https://placehold.co/40x40" },
|
||||
],
|
||||
};
|
||||
|
||||
console.log(overview_data)
|
||||
|
||||
$effect(() => {
|
||||
if (currentPageID) {
|
||||
let f = overview_data.friends.find(friend => friend.id === currentPageID);
|
||||
let g = overview_data.groups.find(group => group.id === currentPageID);
|
||||
let s = overview_data.servers.find(server => server.id === currentPageID);
|
||||
|
||||
if(f) {
|
||||
currentPageType = "friend";
|
||||
currentPage = f;
|
||||
} else if(g) {
|
||||
currentPageType = "group";
|
||||
currentPage = g;
|
||||
} else if(s) {
|
||||
currentPageType = "server";
|
||||
currentPage = s;
|
||||
if(UserID.is(currentPageID)) {
|
||||
currentPage = overview_data.friends.find(friend => friend.id === currentPageID);
|
||||
} else if(GroupID.is(currentPageID)) {
|
||||
currentPage = overview_data.groups.find(group => group.id === currentPageID);
|
||||
} else if(ServerID.is(currentPageID)) {
|
||||
currentPage = overview_data.servers.find(server => server.id === currentPageID);
|
||||
}
|
||||
} else {
|
||||
currentPage = null;
|
||||
currentPageType = null;
|
||||
currentPage = undefined;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
@ -52,23 +45,25 @@
|
|||
<Sidebar.Inset>
|
||||
<header class="flex h-16 shrink-0 items-center gap-2 border-b px-4">
|
||||
<Sidebar.Trigger class="-ms-1" />
|
||||
{#if currentPageType == "server"}
|
||||
{#if currentPageID && currentPage}
|
||||
{#if ServerID.is(currentPageID)}
|
||||
{@const server = (currentPage as Server)}
|
||||
|
||||
<img src={server!.image} alt={server!.name} class="size-6 rounded-full" />
|
||||
|
||||
<h1>{server!.name}</h1>
|
||||
{:else if currentPageType == "friend"}
|
||||
{@const friend = (currentPage as Friend)}
|
||||
{:else if UserID.is(currentPageID)}
|
||||
{@const friend = (currentPage as User)}
|
||||
|
||||
<img src={friend.image} alt={friend!.name} class="size-6 rounded-full" />
|
||||
|
||||
<h1>{friend!.name} [{friend.status == Status.ONLINE ? "Online!" : friend.status == Status.DND ? "DND" : friend.status == Status.OFFLINE ? "Offline" : "Unknown"}]</h1>
|
||||
{:else if currentPageType == "group"}
|
||||
{:else if GroupID.is(currentPageID)}
|
||||
{@const group = (currentPage as Group)}
|
||||
|
||||
<h1>{group!.name} ({group.members} member{group.members > 1 ? "s" : ""})</h1>
|
||||
{/if}
|
||||
{/if}
|
||||
</header>
|
||||
<h1> this is like lowkirkounely the content, i should put messages and shi here</h1>
|
||||
</Sidebar.Inset>
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
<div class="flex min-h-screen flex-col items-center justify-center gap-2">
|
||||
<div class='w-1/2 p-2 bg-secondary rounded-md '>
|
||||
<div class="text-center pb-2">
|
||||
<Title size="2xl"></Title>
|
||||
<Title class="text-2xl"></Title>
|
||||
</div>
|
||||
<form method="post" action="?/register">
|
||||
<Input name="username" class="mb-2" type="text" placeholder="Username"></Input>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue