implement channels fully, implement servers fully, make dms impossible

to send if no longer friends, update overview information on
invalidation (form response recieved, friends update)
This commit is contained in:
Soph :3 2026-01-11 13:47:46 +02:00
parent 92a95cb365
commit 7af96ca084
8 changed files with 245 additions and 104 deletions

View file

@ -18,11 +18,13 @@
let {
currentPage = $bindable<string | null>(),
subPage = $bindable<string | null>(),
data,
user,
...restProps
}: {
currentPage: string | null;
subPage: string | null;
data: OverviewData;
user: SessionValidationResult['user'];
} = $props();
@ -254,6 +256,7 @@
onclick={(e) => {
e.preventDefault();
currentPage = friend.id;
subPage = null;
}}
user={friend}
></User>
@ -283,6 +286,7 @@
onclick={(e) => {
e.preventDefault();
currentPage = group.id;
subPage = null;
}}
href="##"
>
@ -309,24 +313,34 @@
<Sidebar.MenuSub>
{#each data.servers as server (server.id)}
<Sidebar.MenuSubItem>
<Sidebar.MenuSubButton>
<a
onclick={(e) => {
e.preventDefault();
currentPage = server.id;
}}
href="##"
class="flex items-center gap-2"
>
<img
src={'https://api.dicebear.com/7.x/pixel-art/svg?seed=' + server.name}
alt={server.name}
class="size-6 rounded-full"
/>
{server.name}
</a>
<Sidebar.MenuSubButton
onclick={(e) => {
e.preventDefault();
currentPage = server.id;
subPage = null;
}}
>
<img
src={'https://api.dicebear.com/7.x/pixel-art/svg?seed=' + server.name}
alt={server.name}
class="size-6 rounded-full"
/>
{server.name}
</Sidebar.MenuSubButton>
</Sidebar.MenuSubItem>
{#each server.channels as channel (channel.id)}
<a
onclick={(e) => {
e.preventDefault();
currentPage = server.id;
subPage = channel.id;
}}
href="##"
class="flex items-center gap-2"
>
{channel.name}
</a>
{/each}
{/each}
</Sidebar.MenuSub>
</Collapsible.Content>

View file

@ -3,6 +3,8 @@ import { definePrefix, type Puuid } from './puuid';
export const UserID = definePrefix('user');
export const GroupID = definePrefix('group');
export const ServerID = definePrefix('srv');
export const ChannelID = definePrefix('ch');
export const FriendRequestID = definePrefix('frq');
export const DirectMessageID = definePrefix('dmid');
@ -10,6 +12,7 @@ export type UserId = Puuid<'user'>;
export type GroupId = Puuid<'group'>;
export type ServerId = Puuid<'srv'>;
export type DirectMessageId = Puuid<'dmid'>;
export type ChannelId = Puuid<'ch'>;
export const Status: Record<string, 1 | 2 | 3> = {
OFFLINE: 1,
@ -23,6 +26,11 @@ export type OverviewUser = {
image: string;
dmId?: string;
};
export interface Channel {
id: string;
name: string;
}
export interface Message {
id: string;
authorId: string;
@ -42,6 +50,7 @@ export type OverviewServer = {
name: string;
ownerId: string;
image: string;
channels: Channel[];
};
export type OverviewGroup = {
id: string;

View file

@ -10,7 +10,8 @@ export function definePrefix<const P extends string>(prefix: P) {
return {
prefix,
is(value: string): value is Puuid<P> {
is(value: string | undefined | null): value is Puuid<P> {
if (!value) return false;
return value.startsWith(prefix + '_');
},

View file

@ -84,16 +84,38 @@ export async function validateSessionToken(token: string) {
})
);
const servers = (user.servers as string[]).length
let servers = (user.servers as string[]).length
? await db
.select({
id: table.server.id,
name: table.server.name,
ownerId: table.server.owner
ownerId: table.server.owner,
channels: table.server.channels
})
.from(table.server)
.where(inArray(table.server.id, user.servers as string[]))
: [];
servers = await Promise.all(
servers.map(async (z) => {
return {
...z,
channels: (
await Promise.all(
(z.channels as string[]).map(async (m) => {
const channel = await db.select().from(table.channel).where(eq(table.channel.id, m));
if (!channel || channel.length == 0) return;
return {
name: channel[0].name,
id: channel[0].id
};
})
)
).filter(Boolean)
};
})
);
const groups = (user.groups as string[]).length
? await db
.select({