+
+

- {#if user.status === Status.OFFLINE}
-
- {:else if user.status === Status.DND}
-
- {:else if user.status === Status.ONLINE}
-
- {/if}
+
+ {#if user.status === Status.OFFLINE}
+
+ {:else if user.status === Status.DND}
+
+ {:else if user.status === Status.ONLINE}
+
+ {/if}
+
- {user.username}
-
+
+
diff --git a/src/lib/components/member-sidebar.svelte b/src/lib/components/member-sidebar.svelte
index 0a0a15a..f7d28e9 100644
--- a/src/lib/components/member-sidebar.svelte
+++ b/src/lib/components/member-sidebar.svelte
@@ -1,36 +1,128 @@
+
+
+ {#if user && currentEntityId}
+
+
+
+
+ Group Settings
+ Configure your group settings here.
+
+
+
+
+ User Permissions
+ {#if user.id == currentEntity.ownerId}
+ Admin Settings
+ {/if}
+
+ {#if ServerID.is(currentEntityId)}
+ not done yet for later
+ {:else if GroupID.is(currentEntityId)}
+ {#if user.id == currentEntity.ownerId}
+
+
+
+ {/if}
+
+
+ {#if (currentEntity as OverviewGroup).permissions.addMembers || user.id == currentEntity.ownerId}
+
you have permission to add members
+ {/if}
+ {#if (currentEntity as OverviewGroup).permissions.changeTitle || user.id == currentEntity.ownerId}
+ you have permission to change title
+ {/if}
+ {#if (currentEntity as OverviewGroup).permissions.removeMembers || user.id == currentEntity.ownerId}
+ you have permission to remove members
+ {/if}
+
+
+ {/if}
+
+
+
+ {/if}
+
+
Members
@@ -41,7 +133,7 @@
{#snippet child({ props })}
-
+
{/snippet}
@@ -49,45 +141,5 @@
-
- {#if currentEntityId && ServerID.is(currentEntityId) && user}
-
- Server Actions
-
-
-
-
-
- {#snippet child({ props })}
-
- {/snippet}
-
-
-
- {#if user.id === members.find((m) => m.id === currentEntityId)?.ownerId}
-
-
- {#snippet child({ props })}
-
- {/snippet}
-
-
- {/if}
-
-
-
- {/if}
diff --git a/src/lib/index.ts b/src/lib/index.ts
index dc54252..7a96895 100644
--- a/src/lib/index.ts
+++ b/src/lib/index.ts
@@ -49,6 +49,11 @@ export type OverviewGroup = {
ownerId: string;
members: number;
image: string;
+ permissions: {
+ changeTitle: boolean;
+ addMembers: boolean;
+ removeMembers: boolean;
+ };
};
export interface UserWithStatus extends OverviewUser {
diff --git a/src/lib/server/auth.ts b/src/lib/server/auth.ts
index 0ef8352..b25e23d 100644
--- a/src/lib/server/auth.ts
+++ b/src/lib/server/auth.ts
@@ -100,7 +100,10 @@ export async function validateSessionToken(token: string) {
id: table.group.id,
name: table.group.name,
ownerId: table.group.owner,
- members: table.group.members
+ members: table.group.members,
+ changeTitle: table.group.changeTitle,
+ addMembers: table.group.addMembers,
+ removeMembers: table.group.removeMembers
})
.from(table.group)
.where(inArray(table.group.id, user.groups as string[]))
@@ -124,7 +127,15 @@ export async function validateSessionToken(token: string) {
servers,
friends,
groups: groups.map((z) => {
- return { ...z, members: (z.members as string[]).length };
+ return {
+ ...z,
+ members: (z.members as string[]).length,
+ permissions: {
+ changeTitle: !!z.changeTitle,
+ addMembers: !!z.addMembers,
+ removeMembers: !!z.removeMembers
+ }
+ };
}),
friendRequests
}
diff --git a/src/lib/server/db/schema.ts b/src/lib/server/db/schema.ts
index ec3b684..4d5a8cd 100644
--- a/src/lib/server/db/schema.ts
+++ b/src/lib/server/db/schema.ts
@@ -1,3 +1,4 @@
+import { boolean } from 'drizzle-orm/singlestore-core';
import { Status } from '../../index.ts';
import { sqliteTable, integer, text } from 'drizzle-orm/sqlite-core';
@@ -37,6 +38,9 @@ export const group = sqliteTable('group', {
owner: text('owner')
.notNull()
.references(() => user.id),
+ changeTitle: integer('change_title').default(1).notNull(),
+ addMembers: integer('add_members').default(1).notNull(),
+ removeMembers: integer('remove_members').default(0).notNull(),
members: text('members', { mode: 'json' }).default([]).notNull(),
messages: text('messages', { mode: 'json' }).default([]).notNull()
});
diff --git a/src/routes/api/members/[entityId]/+server.ts b/src/routes/api/members/[entityId]/+server.ts
index 640364c..37c7565 100644
--- a/src/routes/api/members/[entityId]/+server.ts
+++ b/src/routes/api/members/[entityId]/+server.ts
@@ -1,4 +1,4 @@
-import { db } from '$lib/server/db';
+import { db, kvStore } from '$lib/server/db';
import * as table from '$lib/server/db/schema';
import { eq, inArray } from 'drizzle-orm';
import { GroupID, ServerID } from '$lib';
@@ -27,6 +27,9 @@ export const GET: RequestHandler = async ({ params }) => {
return json({
members: members.map((member) => ({
id: member.id,
+ status: kvStore.get('user-' + member.id + '-state'),
+ //@TODO Implement statusmessage
+ statusMessage: Math.random() > 0.5 ? 'vibing 🟢' : 'not vibing',
username: member.username,
image: `https://api.dicebear.com/7.x/pixel-art/svg?seed=${member.username}`
}))
@@ -48,6 +51,9 @@ export const GET: RequestHandler = async ({ params }) => {
return json({
members: members.map((member) => ({
id: member.id,
+ status: kvStore.get('user-' + member.id + '-state'),
+ //@TODO Implement statusmessage
+ statusMessage: Math.random() > 0.5 ? 'vibing 🟢' : 'not vibing',
username: member.username,
image: `https://api.dicebear.com/7.x/pixel-art/svg?seed=${member.username}`
}))
diff --git a/src/routes/api/status/[userId]/+server.ts b/src/routes/api/status/[userId]/+server.ts
index e04baf1..b82b69f 100644
--- a/src/routes/api/status/[userId]/+server.ts
+++ b/src/routes/api/status/[userId]/+server.ts
@@ -1,6 +1,7 @@
import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import { kvStore } from '$lib/server/db';
+import { Status } from '$lib';
export const GET: RequestHandler = async ({ params }) => {
const { userId } = params;
@@ -9,6 +10,11 @@ export const GET: RequestHandler = async ({ params }) => {
userId,
status: kvStore.get('user-' + userId + '-state'),
//@TODO Implement statusmessage
- statusMessage: Math.random() > 0.5 ? 'vibing 🟢' : null
+ statusMessage:
+ kvStore.get('user-' + userId + '-state') != Status.OFFLINE
+ ? Math.random() > 0.5
+ ? 'vibing 🟢'
+ : 'not vibing'
+ : ''
});
};
diff --git a/src/routes/api/updates/+server.ts b/src/routes/api/updates/+server.ts
index c3608e7..fc608e1 100644
--- a/src/routes/api/updates/+server.ts
+++ b/src/routes/api/updates/+server.ts
@@ -37,6 +37,8 @@ export async function GET({ locals, request }) {
const userId = locals.user.id;
//@TODO add more to subscribed eventually, server members, et cetera
const subscribed = locals.user.friends.map((f) => f.id);
+ subscribed.push(userId); // shit such as friend requests
+
const overwrite = locals.user.statusOverwrite;
const sessionId = crypto.randomUUID();
diff --git a/src/routes/app/+page.server.ts b/src/routes/app/+page.server.ts
index 2d70873..068cceb 100644
--- a/src/routes/app/+page.server.ts
+++ b/src/routes/app/+page.server.ts
@@ -7,6 +7,7 @@ import { DirectMessageID, FriendRequestID, GroupID, ServerID } from '$lib';
import { eq } from 'drizzle-orm';
import { and } from 'drizzle-orm';
import { type User } from '$lib/server/db/schema';
+import { _sendToSubscribers } from '../api/updates/+server';
export const load: PageServerLoad = async () => {
const user = requireLogin();
return { user };
@@ -92,6 +93,8 @@ export const actions = {
.where(eq(table.user.id, user[0].id));
});
+ _sendToSubscribers(locals.user!.id, { type: 'friends', status: 'accepted' });
+ _sendToSubscribers(user[0].id, { type: 'friends', status: 'accepted' });
return { success: true };
}
@@ -111,6 +114,8 @@ export const actions = {
fromUsername: locals.user!.username
});
+ _sendToSubscribers(locals.user!.id, { type: 'friends', status: 'sent-request' });
+ _sendToSubscribers(user[0].id, { type: 'friends', status: 'new-request' });
return { success: true };
},
removeFriend: async ({ request, locals }) => {
@@ -185,6 +190,9 @@ export const actions = {
// delete the request
await db.delete(table.friendRequest).where(eq(table.friendRequest.id, requestId)).limit(1);
+ _sendToSubscribers(fr.fromUser, { type: 'friends', status: 'request-cancelled' });
+ _sendToSubscribers(fr.toUser, { type: 'friends', status: 'request-cancelled' });
+
return { success: true };
},
createGroup: async ({ request, locals }) => {
diff --git a/src/routes/app/+page.svelte b/src/routes/app/+page.svelte
index 85a8392..64824a2 100644
--- a/src/routes/app/+page.svelte
+++ b/src/routes/app/+page.svelte
@@ -33,7 +33,7 @@
let { form, data }: { form: ActionData; data: PageServerData } = $props();
let currentPageID: (UserId | GroupId | ServerId) | null = $state(null);
let currentPage: OverviewUser | OverviewGroup | OverviewServer | undefined = $state();
-
+ let ownerId: string | null = $state(null);
let isMembersTabOpen = $state(true);
let members: UserWithStatus[] = $state([]);
@@ -72,6 +72,7 @@
members = data.members;
}
fetchMembers();
+ ownerId = (currentPage as OverviewGroup | OverviewServer).ownerId;
} else {
isMembersTabOpen = false;
}
@@ -125,6 +126,7 @@
name: z.name,
ownerId: z.ownerId,
members: z.members,
+ permissions: z.permissions,
image: 'https://api.dicebear.com/7.x/pixel-art/svg?seed=' + z.name
};
});
@@ -160,15 +162,22 @@
const json = JSON.parse(e.data) as
| { type: 'connected'; sessionId: string }
| { type: 'message'; message: ReturnMessage }
- | { type: 'status'; id: string; status: 1 | 2 | 3 };
+ | { type: 'status'; id: string; status: 1 | 2 | 3 }
+ | { type: 'friends'; status: string };
+ if (json.type == 'friends') {
+ alert(json.status);
+ location.reload();
+ }
if (json.type == 'connected') {
console.log('SSE connected. We are sessionID ' + json.sessionId);
sessionId = json.sessionId;
}
if (json.type == 'status') {
+ //@TODO update everywhere where user is used
const friend = overview_data.friends.find((z) => z.id == json.id);
+
if (friend) {
friend.status = json.status;
}
@@ -325,6 +334,7 @@
bind:open={isMembersTabOpen}
user={data.user}
{members}
+ currentEntity={currentPage}
currentEntityId={currentPageID}
/>