huge refactor. addresses #21 w/ inifinite scrolling notifications

This commit is contained in:
ari melody 2024-07-03 22:00:32 +01:00
parent f883b61659
commit 2e64f63caa
Signed by: ari
GPG key ID: CF99829C92678188
29 changed files with 887 additions and 1030 deletions

View file

@ -1,39 +1,42 @@
<script>
import '$lib/app.css';
import * as api from '$lib/api.js';
import { server } from '$lib/client/server.js';
import { app } from '$lib/client/app.js';
import { account, logged_in } from '$lib/stores/account.js';
import { parseAccount } from '$lib/account.js';
import { unread_notif_count, last_read_notif_id } from '$lib/notifications.js';
import { get } from 'svelte/store';
import Navigation from '$lib/ui/Navigation.svelte';
import Widgets from '$lib/ui/Widgets.svelte';
import { client, Client } from '$lib/client/client.js';
import { user, getUser } from '$lib/stores/user.js';
import { get } from 'svelte/store';
import { logged_in } from '$lib/stores/user.js';
import { unread_notif_count, last_read_notif_id } from '$lib/notifications.js';
let ready = new Promise(resolve => {
if (get(client)) {
if (get(user)) logged_in.set(true);
return resolve();
async function init() {
if (!get(app) || !get(app).token) {
account.set(false);
logged_in.set(false);
return;
}
let new_client = new Client();
new_client.load();
client.set(new_client);
return getUser().then(new_user => {
if (!new_user) return resolve();
// logged in- attempt to retrieve using token
const data = await api.verifyCredentials(get(server).host, get(app).token);
if (!data) return;
logged_in.set(true);
user.set(new_user);
account.set(parseAccount(data));
logged_in.set(true);
console.log(`Logged in as @${get(account).username}@${get(account).host}`);
// spin up async task to fetch notifications
get(client).getNotifications(
get(last_read_notif_id)
).then(notif_data => {
if (!notif_data) return;
unread_notif_count.set(notif_data.length);
});
// spin up async task to fetch notifications
const notif_data = await api.getNotifications(
get(server).host,
get(app).token,
get(last_read_notif_id)
);
return resolve();
});
});
if (!notif_data) return;
unread_notif_count.set(notif_data.length);
};
</script>
<div id="app">
@ -43,7 +46,7 @@
</header>
<main>
{#await ready}
{#await init()}
<div class="loading throb">
<span>just a moment...</span>
</div>

View file

@ -1,13 +1,11 @@
<script>
import { page } from '$app/stores';
import { get } from 'svelte/store';
import { logged_in } from '$lib/stores/user.js';
import { logged_in } from '$lib/stores/account.js';
import { timeline, getTimeline } from '$lib/timeline.js';
import LoginForm from '$lib/ui/LoginForm.svelte';
import Feed from '$lib/ui/Feed.svelte';
import User from '$lib/user/user.js';
import Button from '$lib/ui/Button.svelte';
logged_in.subscribe(logged_in => {
if (logged_in) getTimeline();

View file

@ -1,42 +1,48 @@
<script>
import { client } from '$lib/client/client.js';
import * as api from '$lib/api.js';
import { server } from '$lib/client/server.js';
import { app } from '$lib/client/app.js';
import { parseAccount } from '$lib/account.js';
import { get } from 'svelte/store';
import { goto } from '$app/navigation';
import { error } from '@sveltejs/kit';
import { get } from 'svelte/store';
import { last_read_notif_id } from '$lib/notifications.js';
import { logged_in, user, getUser } from '$lib/stores/user.js';
import { unread_notif_count, last_read_notif_id } from '$lib/notifications.js';
import { logged_in, account } from '$lib/stores/account.js';
export let data;
let auth_code = data.code;
if (!auth_code) {
if (!auth_code || !get(server) || !get(app)) {
error(400, { message: "Bad request" });
} else {
get(client).getToken(auth_code).then(token => {
api.getToken(get(server).host, get(app).id, get(app).secret, auth_code).then(token => {
if (!token) {
error(400, { message: "Invalid auth code provided" });
return;
}
client.update(c => {
c.app.token = token;
c.save();
return c;
app.update(app => {
app.token = token;
return app;
});
getUser().then(new_user => {
if (!new_user) return;
api.verifyCredentials(get(server).host, get(app).token).then(data => {
if (!data) return goto("/");
account.set(parseAccount(data));
logged_in.set(true);
user.set(new_user);
console.log(`Logged in as @${get(account).username}@${get(account).host}`);
return get(client).getNotifications(
// spin up async task to fetch notifications
return api.getNotifications(
get(server).host,
get(app).token,
get(last_read_notif_id)
).then(notif_data => {
unread_notif_count.set(0);
if (notif_data.constructor === Array && notif_data.length > 0)
last_read_notif_id.set(notif_data[0].id);
get(client).save();
goto("/");
});
});

View file

@ -1,21 +1,20 @@
<script>
import { notifications, getNotifications } from '$lib/notifications.js';
import { logged_in } from '$lib/stores/user.js';
import { logged_in } from '$lib/stores/account.js';
import { goto } from '$app/navigation';
import { page } from '$app/stores';
import { get } from 'svelte/store';
import Notification from '$lib/ui/Notification.svelte';
if (!get(logged_in)) goto("/");
getNotifications();
/*
document.addEventListener("scroll", event => {
if (get(logged_in) && get(page).url.pathname !== "/") return;
if (get(logged_in) && get(page).url.pathname !== "/notifications") return;
if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 2048) {
getNotifications();
}
});
*/
</script>
<header>

View file

@ -1,7 +1,9 @@
<script>
import { client } from '$lib/client/client.js';
import * as api from '$lib/client/api.js';
import { logged_in } from '$lib/stores/user.js';
import * as api from '$lib/api.js';
import { logged_in } from '$lib/stores/account.js';
import { server } from '$lib/client/server.js';
import { app } from '$lib/client/app.js';
import { parsePost } from '$lib/post.js';
import { get } from 'svelte/store';
import { goto, afterNavigate } from '$app/navigation';
import { base } from '$app/paths'
@ -21,15 +23,15 @@
})
$: post = (async resolve => {
const post_data = await get(client).getPost(data.post_id, 0, false);
const post_data = await api.getPost(get(server).host, get(app).token, data.post_id);
if (!post_data) {
error = `Failed to retrieve post <code>${data.post_id}</code>.`;
console.error(`Failed to retrieve post ${data.post_id}.`);
return;
}
let post = await api.parsePost(post_data, 0, false);
let post = await parsePost(post_data, 0);
const post_context = await get(client).getPostContext(data.post_id);
const post_context = await api.getPostContext(get(server).host, get(app).token, data.post_id);
if (!post_context || !post_context.ancestors || !post_context.descendants)
return post;
@ -37,16 +39,14 @@
// handle ancestors (above post)
let thread_top = post;
while (post_context.ancestors.length > 0) {
thread_top.reply = await api.parsePost(post_context.ancestors.pop(), 0, false);
thread_top.reply = await parsePost(post_context.ancestors.pop(), 0);
thread_top = thread_top.reply;
}
// handle descendants (below post)
post.replies = [];
for (let i in post_context.descendants) {
post.replies.push(
api.parsePost(post_context.descendants[i], 0, false)
);
post.replies.push(parsePost(post_context.descendants[i], 0));
}
return post;
@ -59,9 +59,9 @@
<nav>
<Button centered on:click={() => {goto(previous_page)}}>Back</Button>
</nav>
<img src={post.user.avatar_url} type={post.user.avatar_type} alt="" width="40" height="40" class="header-avatar" loading="lazy" decoding="async">
<img src={post.account.avatar_url} type={post.account.avatar_type} alt="" width="40" height="40" class="header-avatar" loading="lazy" decoding="async">
<h1>
Post by {@html post.user.rich_name}
Post by {@html post.account.rich_name}
</h1>
{/await}
</header>