aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFuwn <[email protected]>2023-12-29 22:17:10 -0800
committerFuwn <[email protected]>2023-12-29 22:17:10 -0800
commitd5b6445d6587473f9bb669fa7117c2621408b8ca (patch)
treee9b73327d507aed83c2a01624f99907601366db7 /src
parentfeat(badges): double click to delete badge (diff)
downloaddue.moe-d5b6445d6587473f9bb669fa7117c2621408b8ca.tar.xz
due.moe-d5b6445d6587473f9bb669fa7117c2621408b8ca.zip
feat(badges): live update on delete and add
Diffstat (limited to 'src')
-rw-r--r--src/routes/user/[user]/badges/+page.svelte180
1 files changed, 105 insertions, 75 deletions
diff --git a/src/routes/user/[user]/badges/+page.svelte b/src/routes/user/[user]/badges/+page.svelte
index febf5bdf..8a15425c 100644
--- a/src/routes/user/[user]/badges/+page.svelte
+++ b/src/routes/user/[user]/badges/+page.svelte
@@ -14,7 +14,7 @@
let currentUserIdentity: ReturnType<typeof userIdentity>;
let error: null | string;
// const socket = io();
- let badges: Badge[] | null = null;
+ let badgesPromise: Promise<Response>;
let dark = true;
let transparent = false;
let confirmDelete = 0;
@@ -22,7 +22,7 @@
onMount(async () => {
// socket.on('badges', (message) => (badges = message));
- badges = await (await fetch(`/api/badges?id=${(await user(data.username)).id}`)).json();
+ badgesPromise = fetch(`/api/badges?id=${(await user(data.username)).id}`);
if (data.user) {
currentUserIdentity = userIdentity(data.user);
@@ -62,12 +62,16 @@
{
method: 'PUT'
}
- ).then(() => {
- error = null;
- imageURL.value = '';
- activityURL.value = '';
- description.value = '';
- });
+ )
+ .then(() => {
+ error = null;
+ imageURL.value = '';
+ activityURL.value = '';
+ description.value = '';
+ })
+ .then(async () => {
+ badgesPromise = fetch(`/api/badges?id=${(await user(data.username)).id}`);
+ });
};
const removeBadge = (badge: Badge) => {
@@ -87,9 +91,13 @@
fetch(`/api/badges?id=${badge.id}`, {
method: 'DELETE'
- }).then(() => {
- (document.querySelector(`#badge-${badge.id}`) as HTMLAnchorElement).style.display = 'none';
- });
+ })
+ .then(() => {
+ (document.querySelector(`#badge-${badge.id}`) as HTMLAnchorElement).style.display = 'none';
+ })
+ .then(async () => {
+ badgesPromise = fetch(`/api/badges?id=${(await user(data.username)).id}`);
+ });
};
const screenshot = async () => {
@@ -148,74 +156,96 @@
<HeadTitle route={`${data.username}'s Badge Wall`} path={`/user/${data.username}`} />
{#await currentUserIdentity}
- Loading user identity ... 50%
+ Loading user identity ... 60%
{:then identity}
- {@const isOwner = identity && identity.name === data.username}
-
- {#if isOwner}
- <p>
- <a href={`/user/${data.username}`}>Back to Profile</a>
- •
- <a href={`#`} on:click={() => (editMode = !editMode)}>
- {editMode ? 'Disable' : 'Enable'} Edit Mode
- </a>
- •
- <a href={`#`} on:click={() => screenshot()}>Download</a>
- •
- <input type="checkbox" bind:checked={dark} /> Dark Mode
- <input type="checkbox" bind:checked={transparent} /> Transparent Background
- </p>
- {/if}
-
- {#if editMode && isOwner}
- <p>
- Edit mode is enabled. Click on an image <b>twice</b> to delete it. There is no confirmation, so
- be careful!
- </p>
-
- {#if error}
- <p style="color: red;">{error}</p>
- {/if}
+ {#await badgesPromise}
+ Loading badges ... 40%
+ {:then badgesResponse}
+ {#if badgesResponse}
+ {#await badgesResponse.json()}
+ Loading badges ... 80%
+ {:then badges}
+ {@const isOwner = identity && identity.name === data.username}
+
+ {#if isOwner}
+ <p>
+ <a href={`/user/${data.username}`}>Back to Profile</a>
+ •
+ <a href={`#`} on:click={() => (editMode = !editMode)}>
+ {editMode ? 'Disable' : 'Enable'} Edit Mode
+ </a>
+ •
+ <a href={`#`} on:click={() => screenshot()}>Download</a>
+ •
+ <input type="checkbox" bind:checked={dark} /> Dark Mode
+ <input type="checkbox" bind:checked={transparent} /> Transparent Background
+ </p>
+ {/if}
- <p>
- <input type="text" placeholder="Image URL" name="image_url" minlength="1" maxlength="1000" />
- <input
- type="text"
- placeholder="Activity URL"
- name="activity_url"
- minlength="1"
- maxlength="1000"
- />
- <input
- type="text"
- placeholder="Description (Optional)"
- name="description"
- minlength="1"
- maxlength="1000"
- />
- <a href={`#`} on:click={submitBadge}>Add Badge</a>
- </p>
- {/if}
-
- <div id="badges">
- {#if badges === null}
- {@html nbsp('Loading badges ... 50%')}
- {:else if badges.length === 0}
- {@html nbsp('No badges found for this user.')}
- {:else}
- {#each badges as badge}
- {#if editMode}
- <a href={`#`} on:click={() => removeBadge(badge)} id={`badge-${badge.id}`}>
- <img src={badge.image} alt={badge.description} title={badge.description} />
- </a>
- {:else}
- <a href={badge.post} target="_blank" id={`badge-${badge.id}`}>
- <img src={badge.image} alt={badge.description} title={badge.description} />
- </a>
+ {#if editMode && isOwner}
+ <p>
+ Edit mode is enabled. Click on an image <b>twice</b> to delete it. There is no confirmation,
+ so be careful!
+ </p>
+
+ {#if error}
+ <p style="color: red;">{error}</p>
+ {/if}
+
+ <p>
+ <input
+ type="text"
+ placeholder="Image URL"
+ name="image_url"
+ minlength="1"
+ maxlength="1000"
+ />
+ <input
+ type="text"
+ placeholder="Activity URL"
+ name="activity_url"
+ minlength="1"
+ maxlength="1000"
+ />
+ <input
+ type="text"
+ placeholder="Description (Optional)"
+ name="description"
+ minlength="1"
+ maxlength="1000"
+ />
+ <a href={`#`} on:click={submitBadge}>Add Badge</a>
+ </p>
{/if}
- {/each}
+
+ <div id="badges">
+ {#if badges === null}
+ {@html nbsp('Loading badges ... 50%')}
+ {:else if badges.length === 0}
+ {@html nbsp('No badges found for this user.')}
+ {:else}
+ {#each badges as badge}
+ {#if editMode}
+ <a href={`#`} on:click={() => removeBadge(badge)} id={`badge-${badge.id}`}>
+ <img src={badge.image} alt={badge.description} title={badge.description} />
+ </a>
+ {:else}
+ <a href={badge.post} target="_blank" id={`badge-${badge.id}`}>
+ <img src={badge.image} alt={badge.description} title={badge.description} />
+ </a>
+ {/if}
+ {/each}
+ {/if}
+ </div>
+ {:catch}
+ <p>Could not parse badges</p>
+ {/await}
+ {:else}
+ Loading badges ... 20%
{/if}
- </div>
+ {:catch}
+ <p>Could not fetch badges</p>
+ {/await}
{/await}
<style>