chat.sad.ovh/src/routes/app/+page.svelte

111 lines
3.6 KiB
Svelte

<script lang="ts">
import { Status, type OverviewData,
GroupID, UserID, ServerID,
type GroupId, type ServerId, type UserId,
type OverviewUser, type OverviewGroup, type OverviewServer } from "$lib";
import type { PageServerData } from './$types';
import AppSidebar from "$lib/components/app-sidebar.svelte";
import * as Sidebar from "$lib/components/ui/sidebar/index.js";
import { onMount } from "svelte";
let { data }: { data: PageServerData } = $props();
let currentPageID: (UserId|GroupId|ServerId)|null = $state(null);
let currentPage: OverviewUser | OverviewGroup | OverviewServer | undefined = $state();
const overview_data: OverviewData = $state({
friends: [],
groups: [],
servers: []
});
console.log(data, overview_data)
$effect(() => {
if (currentPageID) {
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 = undefined;
}
});
onMount(()=>{
async function run() {
overview_data.servers = data.user.servers.map(z => {
return {
id: ServerID.parse(z.id),
name: z.name,
ownerId: z.ownerId,
image: "https://api.dicebear.com/7.x/pixel-art/svg?seed=" + z.name,
};
})
overview_data.groups = data.user.groups.map(z => {
return {
id: GroupID.parse(z.id),
name: z.name,
ownerId: z.ownerId,
members: z.members,
image: "https://api.dicebear.com/7.x/pixel-art/svg?seed=" + z.name,
};
})
overview_data.friends = await Promise.all(
data.user.friends.map(async (friend) => {
const res = await fetch(`/api/status/${friend.id}`);
if (!res.ok) {
throw new Error(`Failed to fetch status for ${friend.id}`);
}
const status = await res.json();
return {
id: UserID.parse(friend.id),
username: friend.username,
status: status.status,
customStatus: status.customStatus,
image: "https://api.dicebear.com/7.x/pixel-art/svg?seed=" + friend.username
};
})
);
}
run();
});
</script>
<Sidebar.Provider>
<AppSidebar bind:currentPage={currentPageID} data={overview_data} />
<Sidebar.Inset>
<header class="flex h-16 shrink-0 items-center gap-2 border-b px-4">
<Sidebar.Trigger class="-ms-1" />
{#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 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 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>
</Sidebar.Provider>