diff --git a/src/lib/components/app-sidebar.svelte b/src/lib/components/app-sidebar.svelte index d8ad9be..88b444f 100644 --- a/src/lib/components/app-sidebar.svelte +++ b/src/lib/components/app-sidebar.svelte @@ -24,6 +24,8 @@ import { overview_data } from '$lib/state.svelte'; + let dialogType: 'create_channel' | 'leave_server' | '' = $state(''); + let { currentPage = $bindable(), subPage = $bindable(), @@ -505,59 +507,115 @@ - Create channel + { + dialogType = 'create_channel'; + }}>Create channel + + + { + dialogType = 'leave_server'; + }}>Leave server - -
{ - return async ({ result }) => { - if (result.type == 'success') { - toast.success('Created channel successfully'); - } + {#if dialogType == 'create_channel'} + + { + return async ({ result }) => { + if (result.type == 'success') { + toast.success('Created channel successfully'); + } - if (result.type == 'error' || result.type == 'failure') { - toast.error( - 'Could not create channel: ' + - (result.type === 'error' ? result.error : result.data?.error) - ); - } + if (result.type == 'error' || result.type == 'failure') { + toast.error( + 'Could not create channel: ' + + (result.type === 'error' ? result.error : result.data?.error) + ); + } - await invalidateAll(); - await fill_overview_data(psd); - }; - }} - > - - Create a channel - Add a new channel to this server. - + await invalidateAll(); + await fill_overview_data(psd); + }; + }} + > + + Create a channel + Add a new channel to this server. + -
- - +
+ + + +
+ + + Cancel + + + + + {:else if dialogType == 'leave_server'} + +
{ + return async ({ result }) => { + if (result.type == 'success') { + toast.success('Left server successfully'); + } + + if (result.type == 'error' || result.type == 'failure') { + toast.error( + 'Could not leave server: ' + + (result.type === 'error' ? result.error : result.data?.error) + ); + } + + await invalidateAll(); + await fill_overview_data(psd); + }; + }} + > -
- - Cancel - - - -
+ + Leave this server + Would you like to leave this server? + + + + No + + + +
+ {/if} {#each server.channels as channel (channel.id)} diff --git a/src/routes/api/updates/+server.ts b/src/routes/api/updates/+server.ts index 26d80cf..54f2e0d 100644 --- a/src/routes/api/updates/+server.ts +++ b/src/routes/api/updates/+server.ts @@ -43,7 +43,9 @@ 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); + const subscribed = locals.user.friends + .map((f) => f.id) // friends + .concat(locals.user.servers.map((z) => z.id)); // server changes like nameschanges and etc subscribed.push(userId); // shit such as friend requests const overwrite = locals.user.statusOverwrite; diff --git a/src/routes/app/+page.svelte b/src/routes/app/+page.svelte index 53f7300..ba301f1 100644 --- a/src/routes/app/+page.svelte +++ b/src/routes/app/+page.svelte @@ -122,7 +122,7 @@ }); } - previousSubscription = currentPageID; + previousSubscription = subscribe; } getMessages(); diff --git a/src/routes/app/ServerDashboard.svelte b/src/routes/app/ServerDashboard.svelte index 189a376..feda057 100644 --- a/src/routes/app/ServerDashboard.svelte +++ b/src/routes/app/ServerDashboard.svelte @@ -241,23 +241,26 @@

Server Settings

-
- { - server.name = e.currentTarget.value; - }} - /> - -
-

Changes are local only (no backend yet)

+
{ + return async ({ result }) => { + if (result.type === 'success') { + toast.success('Server name updated successfully'); + await invalidateAll(); + await fill_overview_data(psd); + } else if (result.type === 'failure') { + toast.error('Failed to update server name: ' + result.data?.error); + } + }; + }} + class="flex items-center gap-4" + > + + + +
diff --git a/src/routes/app/actions/server.ts b/src/routes/app/actions/server.ts index 9be372c..df800cb 100644 --- a/src/routes/app/actions/server.ts +++ b/src/routes/app/actions/server.ts @@ -3,7 +3,7 @@ import { db } from '$lib/server/db'; import * as table from '$lib/server/db/schema'; import { ChannelID, InviteID, ServerID } from '$lib'; import { eq } from 'drizzle-orm'; -import { _sendToUser } from '../../api/updates/+server'; +import { _sendToSubscribers } from '../../api/updates/+server'; import type { Actions } from '../$types'; export default { @@ -83,6 +83,7 @@ export default { .where(eq(table.server.id, server[0].id)); }); } + _sendToSubscribers(server[0].id, { type: 'server', status: 'new-member' }); return { success: true }; }, @@ -189,7 +190,31 @@ export default { .set({ servers: locals.user!.servers.map((z) => z.id).concat([serverId]) }) .where(eq(table.user.id, locals.user!.id)); - _sendToUser(locals.user!.id, { type: 'server', status: 'server-created' }); + return { success: true }; + }, + changeServerName: async ({ request, locals }) => { + const data = await request.formData(); + const name = data.get('name'); + const serverId = data.get('serverId'); + + if (typeof name !== 'string' || name.length < 3) { + return fail(400, { error: 'Server name too short' }); + } + + if (typeof serverId !== 'string') { + return fail(400, { error: 'Server ID incorrect' }); + } + + const server = await db.select().from(table.server).where(eq(table.server.id, serverId)); + if (!server || server.length == 0) { + return fail(400, { error: 'Server ID invalid' }); + } + + // @TODO check permissions here (only owner or users with manageServer permission should be able to change server name) + + await db.update(table.server).set({ name }).where(eq(table.server.id, serverId)); + + _sendToSubscribers(serverId, { type: 'server', status: 'server-updated' }); return { success: true }; }, createChannel: async ({ request, locals }) => { @@ -228,6 +253,7 @@ export default { }) .where(eq(table.server.id, serverId)); }); + _sendToSubscribers(serverId, { type: 'server', status: 'channel-created' }); return { success: true }; }, @@ -263,6 +289,7 @@ export default { .where(eq(table.server.id, serverId)); }); + _sendToSubscribers(serverId, { type: 'server', status: 'channel-deleted' }); return { success: true }; }, deleteServer: async ({ request, locals }) => { @@ -304,7 +331,49 @@ export default { await tx.delete(table.server).where(eq(table.server.id, serverId)); }); - _sendToUser(locals.user!.id, { type: 'server', status: 'server-deleted' }); + _sendToSubscribers(serverId, { type: 'server', status: 'server-deleted' }); + return { success: true }; + }, + leaveServer: async ({ request, locals }) => { + const data = await request.formData(); + const serverId = data.get('serverId'); + + if (typeof serverId !== 'string') { + return fail(400, { error: 'Server ID incorrect' }); + } + + const server = await db.select().from(table.server).where(eq(table.server.id, serverId)); + if (!server || server.length == 0) { + return fail(400, { error: 'Server ID invalid' }); + } + + if (server[0].owner === locals.user!.id) { + return fail(400, { error: 'Owners cannot leave their own server' }); + } + + if (!locals.user!.servers.some((z) => z.id == serverId)) { + return fail(400, { error: 'Not in this server' }); + } + + await db.transaction(async (tx) => { + // Remove server from user's server list + await tx + .update(table.user) + .set({ + servers: locals.user!.servers.map((z) => z.id).filter((id) => id !== serverId) + }) + .where(eq(table.user.id, locals.user!.id)); + + // Remove user from server's member list + await tx + .update(table.server) + .set({ + members: (server[0].members as string[]).filter((id) => id !== locals.user!.id) + }) + .where(eq(table.server.id, serverId)); + }); + + _sendToSubscribers(serverId, { type: 'server', status: 'server-left' }); return { success: true }; } } satisfies Actions;