adds notifications

This commit is contained in:
Christian Beutel
2024-12-21 03:24:36 +01:00
parent 034f6873c1
commit 9140b523da
39 changed files with 1613 additions and 142 deletions

View File

@@ -3,7 +3,13 @@ import '$lib/i18n';
import type { LayoutServerLoad } from './$types';
import { env } from "$env/dynamic/private";
import type { Settings } from '$lib/models/settings';
import { notifications_index } from '$lib/stores/notification_store';
export const load: LayoutServerLoad = async ({ locals, url }) => {
return { settings: locals.settings as Settings, origin: env.ORIGIN }
export const load: LayoutServerLoad = async ({ locals, url, fetch }) => {
let notifications
if (locals.user) {
notifications = await notifications_index({ recipient: locals.user.id }, 1, 10, fetch);
}
return { settings: locals.settings as Settings, notifications, origin: env.ORIGIN }
}

View File

@@ -1,5 +1,5 @@
import type { Follow } from '$lib/models/follow';
import type { User } from '$lib/models/user';
import type { UserAnonymous } from '$lib/models/user';
import { pb } from '$lib/pocketbase';
import { error, json, type RequestEvent } from '@sveltejs/kit';
@@ -21,8 +21,8 @@ export async function GET(event: RequestEvent) {
.getList<Follow>(parseInt(page), parseInt(perPage), { sort: sort ?? "", filter: filter ?? "", requestKey: filter })
}
for (const follow of r.items) {
const follower = await pb.collection('users_anonymous').getOne<User>(follow.follower, {requestKey: filter})
const followee = await pb.collection('users_anonymous').getOne<User>(follow.followee, {requestKey: filter})
const follower = await pb.collection('users_anonymous').getOne<UserAnonymous>(follow.follower, { requestKey: filter })
const followee = await pb.collection('users_anonymous').getOne<UserAnonymous>(follow.followee, { requestKey: filter })
follow.expand = {
follower, followee
}

View File

@@ -0,0 +1,34 @@
import type { Notification } from '$lib/models/notification';
import type { UserAnonymous } from '$lib/models/user';
import { pb } from '$lib/pocketbase';
import { error, json, type RequestEvent } from '@sveltejs/kit';
export async function GET(event: RequestEvent) {
const page = event.url.searchParams.get("page") ?? "0";
const perPage = event.url.searchParams.get("per-page") ?? "10";
const sort = event.url.searchParams.get('sort') ?? ""
const filter = event.url.searchParams.get("filter") ?? "";
try {
let r;
if (parseInt(perPage) < 0) {
r = {
items: await pb.collection('notifications')
.getFullList<Notification>({ sort: sort, filter: filter, requestKey: filter })
}
} else {
r = await pb.collection('notifications')
.getList<Notification>(parseInt(page), parseInt(perPage), { sort: sort ?? "", filter: filter ?? "", requestKey: filter })
}
for (const notification of r.items) {
const recipient = await pb.collection('users_anonymous').getOne<UserAnonymous>(notification.recipient, { requestKey: filter })
const author = await pb.collection('users_anonymous').getOne<UserAnonymous>(notification.author, { requestKey: filter })
notification.expand = {
recipient, author
}
}
return json(r)
} catch (e: any) {
throw error(e.status, e);
}
}

View File

@@ -0,0 +1,15 @@
import type { Follow } from "$lib/models/follow";
import { pb } from "$lib/pocketbase";
import { error, json, type RequestEvent } from "@sveltejs/kit";
export async function POST(event: RequestEvent) {
const data = await event.request.json()
try {
const r = await pb.collection('notifications').update<Notification>(event.params.id as string, { ...data, seen: true })
return json(r);
} catch (e: any) {
throw error(e.status, e)
}
}

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { goto } from "$app/navigation";
import { goto, invalidate, invalidateAll } from "$app/navigation";
import { page } from "$app/stores";
import { env } from "$env/dynamic/public";
import Button from "$lib/components/base/button.svelte";
@@ -45,7 +45,7 @@
loading = true;
try {
await login(newUser);
goto($page.url.searchParams.get("r") ?? "/");
window.location.href = $page.url.searchParams.get("r") ?? "/";
} catch (e) {
if (
e instanceof ClientResponseError &&

View File

@@ -13,6 +13,7 @@
text: $_("language") + " & " + $_("units"),
value: "/settings/language",
},
{ text: $_("notifications"), value: "/settings/notifications" },
{ text: $_("map"), value: "/settings/map" },
{ text: `${$_("import")}/${$_("export")}`, value: "/settings/export" },
{

View File

@@ -0,0 +1,99 @@
<script lang="ts">
import { page } from "$app/stores";
import Toggle from "$lib/components/base/toggle.svelte";
import { NotificationType } from "$lib/models/notification";
import type { Settings } from "$lib/models/settings";
import { settings_update } from "$lib/stores/settings_store";
import { _ } from "svelte-i18n";
const notifications = ($page.data.settings as Settings)?.notifications ?? {
list_create: {
web: true,
email: true,
},
list_share: {
web: true,
email: true,
},
trail_create: {
web: true,
email: true,
},
trail_share: {
web: true,
email: true,
},
new_follower: {
web: true,
email: true,
},
trail_comment: {
web: true,
email: true,
},
};
const notificationItems: { text: string; key: NotificationType }[] = [
{
text: $_("notification-trail-comment"),
key: NotificationType.trailComment,
},
{
text: $_("notification-new-follower"),
key: NotificationType.newFollower,
},
{
text: $_("notification-trail-create"),
key: NotificationType.trailCreate,
},
{
text: $_("notification-trail-share"),
key: NotificationType.trailShare,
},
{
text: $_("notification-list-create"),
key: NotificationType.listCreate,
},
{
text: $_("notification-list-share"),
key: NotificationType.listShare,
},
];
async function updateNotificationSettings() {
await settings_update({
id: $page.data.settings!.id,
notifications,
});
}
</script>
<svelte:head>
<title>{$_("settings")} | wanderer</title>
</svelte:head>
<h2 class="text-2xl font-semibold">{$_("notifications")}</h2>
<hr class="mt-4 mb-6 border-input-border" />
<div
class="grid gap-4"
style="grid-template-columns: 1fr min-content min-content;"
>
<div></div>
<span class="text-sm font-medium">Web</span>
<span class="text-sm font-medium">Email</span>
{#each notificationItems as item}
<p>{item.text}</p>
<div>
<Toggle
on:change={updateNotificationSettings}
bind:value={notifications[item.key].web}
></Toggle>
</div>
<div>
<Toggle
on:change={updateNotificationSettings}
bind:value={notifications[item.key].email}
></Toggle>
</div>
{/each}
</div>

View File

@@ -257,6 +257,7 @@
$form.id = prevId;
$form.expand.gpx_data = gpxData;
$form.category = $page.data.settings.category || $categories[0].id;
$form.public = $page.data.settings?.privacy.trails === "public";
const log = new SummitLog(parseResult.trail.date as string, {
distance: $form.distance,