From bc6d02d9747b5a5c8d720fcb6884ae48b946f69b Mon Sep 17 00:00:00 2001 From: ari melody Date: Tue, 2 Jul 2024 12:55:51 +0100 Subject: [PATCH 1/3] add getNotifications() api method --- src/lib/client/api.js | 21 ++++++++++++++++++++- src/lib/client/client.js | 4 ++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/lib/client/api.js b/src/lib/client/api.js index 11d3238..46f4c89 100644 --- a/src/lib/client/api.js +++ b/src/lib/client/api.js @@ -91,8 +91,27 @@ export async function verifyCredentials() { return data; } +export async function getNotifications(since_id, limit, types) { + if (!get(client).user) return false; + + let url = `https://${get(client).instance.host}/api/v1/notifications`; + + let params = new URLSearchParams(); + if (since_id) params.append("max_id", last_post_id); + if (limit) params.append("limit", limit); + if (types) params.append("types", types.join(',')); + const params_string = params.toString(); + if (params_string) url += '?' + params_string; + + const data = await fetch(url, { + method: 'GET', + headers: { "Authorization": "Bearer " + get(client).app.token } + }).then(res => res.json()); + + return data; +} + export async function getTimeline(last_post_id) { - if (!get(client).instance || !get(client).app) return false; let url = `https://${get(client).instance.host}/api/v1/timelines/home`; if (last_post_id) url += "?max_id=" + last_post_id; const data = await fetch(url, { diff --git a/src/lib/client/client.js b/src/lib/client/client.js index 44e7b53..c83d383 100644 --- a/src/lib/client/client.js +++ b/src/lib/client/client.js @@ -93,6 +93,10 @@ export class Client { return user; } + async getNotifications(since_id, limit, types) { + return await api.getNotifications(since_id, limit, types); + } + async getTimeline(last_post_id) { return await api.getTimeline(last_post_id); } From 015a3e65e169762313802ab9661e1bb355efc571 Mon Sep 17 00:00:00 2001 From: ari melody Date: Tue, 2 Jul 2024 13:50:53 +0100 Subject: [PATCH 2/3] fixed getNotifications() --- src/lib/client/api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/client/api.js b/src/lib/client/api.js index 46f4c89..14c4965 100644 --- a/src/lib/client/api.js +++ b/src/lib/client/api.js @@ -97,7 +97,7 @@ export async function getNotifications(since_id, limit, types) { let url = `https://${get(client).instance.host}/api/v1/notifications`; let params = new URLSearchParams(); - if (since_id) params.append("max_id", last_post_id); + if (since_id) params.append("since_id", since_id); if (limit) params.append("limit", limit); if (types) params.append("types", types.join(',')); const params_string = params.toString(); From 998e8f2517bee19b54539e54de0a9b130ee1f272 Mon Sep 17 00:00:00 2001 From: ari melody Date: Tue, 2 Jul 2024 19:38:20 +0100 Subject: [PATCH 3/3] another huge commit but we have notifs now yay --- src/lib/client/api.js | 3 +- src/lib/client/client.js | 4 + src/lib/notifications.js | 40 +++++ src/lib/stores/user.js | 4 + src/lib/timeline.js | 10 +- src/lib/ui/Button.svelte | 14 +- src/lib/ui/Feed.svelte | 12 +- src/lib/ui/Navigation.svelte | 33 ++-- src/lib/ui/Notification.svelte | 227 ++++++++++++++++++++++++++ src/lib/ui/post/Body.svelte | 3 +- src/lib/ui/post/ReactionBar.svelte | 3 +- src/routes/+layout.svelte | 18 +- src/routes/+page.js | 4 - src/routes/+page.svelte | 13 +- src/routes/callback/+page.svelte | 16 +- src/routes/notifications/+page.svelte | 57 +++++++ src/routes/post/[id]/+page.svelte | 33 +++- 17 files changed, 442 insertions(+), 52 deletions(-) create mode 100644 src/lib/notifications.js create mode 100644 src/lib/stores/user.js create mode 100644 src/lib/ui/Notification.svelte create mode 100644 src/routes/notifications/+page.svelte diff --git a/src/lib/client/api.js b/src/lib/client/api.js index 14c4965..c3accbb 100644 --- a/src/lib/client/api.js +++ b/src/lib/client/api.js @@ -219,6 +219,7 @@ export async function parsePost(data, ancestor_count) { let post = new Post(); post.text = data.content; + post.html = data.content; post.reply = null; if ((data.in_reply_to_id || data.reply) && @@ -278,7 +279,7 @@ export async function parseUser(data) { user = new User(); user.id = data.id; - user.nickname = data.display_name; + user.nickname = data.display_name.trim(); user.username = data.username; user.avatar_url = data.avatar; user.url = data.url; diff --git a/src/lib/client/client.js b/src/lib/client/client.js index c83d383..3ac4269 100644 --- a/src/lib/client/client.js +++ b/src/lib/client/client.js @@ -1,6 +1,8 @@ import { Instance, server_types } from './instance.js'; import * as api from './api.js'; import { get, writable } from 'svelte/store'; +import { last_read_notif_id } from '$lib/notifications.js'; +import { user } from '$lib/stores/user.js'; export const client = writable(false); @@ -177,6 +179,7 @@ export class Client { host: this.instance.host, version: this.instance.version, }, + last_read_notif_id: get(last_read_notif_id), app: this.app, })); } @@ -191,6 +194,7 @@ export class Client { return false; } this.instance = new Instance(saved.instance.host, saved.instance.version); + last_read_notif_id.set(saved.last_read_notif_id || 0); this.app = saved.app; client.set(this); return true; diff --git a/src/lib/notifications.js b/src/lib/notifications.js new file mode 100644 index 0000000..5d16795 --- /dev/null +++ b/src/lib/notifications.js @@ -0,0 +1,40 @@ +import { client } from '$lib/client/client.js'; +import * as api from '$lib/client/api.js'; +import { get, writable } from 'svelte/store'; + +export let notifications = writable([]); +export let unread_notif_count = writable(0); +export let last_read_notif_id = writable(0); + +let loading; +export async function getNotifications() { + if (loading) return; // no spamming!! + loading = true; + + api.getNotifications().then(async data => { + if (!data || data.length <= 0) return; + notifications.set([]); + for (let i in data) { + let notif = data[i]; + notif.accounts = [ await api.parseUser(notif.account) ]; + if (get(notifications).length > 0) { + let prev = get(notifications)[get(notifications).length - 1]; + if (notif.type === prev.type) { + if (prev.status && notif.status && prev.status.id === notif.status.id) { + notifications.update(notifications => { + notifications[notifications.length - 1].accounts.push(notif.accounts[0]); + return notifications; + }); + continue; + } + } + } + notif.status = await api.parsePost(notif.status, 0, false); + notifications.update(notifications => [...notifications, notif]); + } + last_read_notif_id.set(data[0].id); + unread_notif_count.set(0); + get(client).save(); + loading = false; + }); +} diff --git a/src/lib/stores/user.js b/src/lib/stores/user.js new file mode 100644 index 0000000..6648031 --- /dev/null +++ b/src/lib/stores/user.js @@ -0,0 +1,4 @@ +import { writable } from 'svelte/store'; + +export let user = writable(0); +export let logged_in = writable(false); diff --git a/src/lib/timeline.js b/src/lib/timeline.js index a9fcdbf..0ef7b8f 100644 --- a/src/lib/timeline.js +++ b/src/lib/timeline.js @@ -2,7 +2,7 @@ import { client } from '$lib/client/client.js'; import { get, writable } from 'svelte/store'; import { parsePost } from '$lib/client/api.js'; -export let posts = writable([]); +export let timeline = writable([]); let loading = false; @@ -11,8 +11,8 @@ export async function getTimeline(clean) { loading = true; let timeline_data; - if (clean || get(posts).length === 0) timeline_data = await get(client).getTimeline() - else timeline_data = await get(client).getTimeline(get(posts)[get(posts).length - 1].id); + if (clean || get(timeline).length === 0) timeline_data = await get(client).getTimeline() + else timeline_data = await get(client).getTimeline(get(timeline)[get(timeline).length - 1].id); if (!timeline_data) { console.error(`Failed to retrieve timeline.`); @@ -20,7 +20,7 @@ export async function getTimeline(clean) { return; } - if (clean) posts.set([]); + if (clean) timeline.set([]); for (let i in timeline_data) { const post_data = timeline_data[i]; @@ -36,7 +36,7 @@ export async function getTimeline(clean) { } continue; } - posts.update(current => [...current, post]); + timeline.update(current => [...current, post]); } loading = false; } diff --git a/src/lib/ui/Button.svelte b/src/lib/ui/Button.svelte index 4a7d95e..ea68fc4 100644 --- a/src/lib/ui/Button.svelte +++ b/src/lib/ui/Button.svelte @@ -1,6 +1,8 @@ + + +

+ Post by {@html post.user.rich_name} +

{/await} -
{#await post} -
+
loading post...
{:then post} @@ -78,11 +89,19 @@