From 861c03b85160972431ca9b262345d15edecf9acb Mon Sep 17 00:00:00 2001
From: Fuwn
Date: Tue, 24 Oct 2023 17:12:54 -0700
Subject: feat: badge wall
---
src/lib/userBadgesDatabase.ts | 57 +++++
src/routes/api/badges/add/+server.ts | 23 ++
src/routes/api/badges/remove/+server.ts | 22 ++
src/routes/user/[user]/+page.server.ts | 5 +
src/routes/user/[user]/+page.svelte | 40 ++++
src/routes/user/[user]/badges/+page.server.ts | 11 +
src/routes/user/[user]/badges/+page.svelte | 301 ++++++++++++++++++++++++++
7 files changed, 459 insertions(+)
create mode 100644 src/lib/userBadgesDatabase.ts
create mode 100644 src/routes/api/badges/add/+server.ts
create mode 100644 src/routes/api/badges/remove/+server.ts
create mode 100644 src/routes/user/[user]/+page.server.ts
create mode 100644 src/routes/user/[user]/+page.svelte
create mode 100644 src/routes/user/[user]/badges/+page.server.ts
create mode 100644 src/routes/user/[user]/badges/+page.svelte
(limited to 'src')
diff --git a/src/lib/userBadgesDatabase.ts b/src/lib/userBadgesDatabase.ts
new file mode 100644
index 00000000..c129770e
--- /dev/null
+++ b/src/lib/userBadgesDatabase.ts
@@ -0,0 +1,57 @@
+import { dev } from '$app/environment';
+import Database from 'better-sqlite3';
+
+export interface Badge {
+ post: string;
+ image: string;
+ description?: string;
+ id?: number;
+}
+
+const database = new Database('./due_moe.sqlite3', {
+ verbose: dev ? console.log : undefined
+});
+
+database.exec(`create table if not exists user_badges (
+ id integer primary key,
+ user_id integer not null,
+ post text not null,
+ image text not null,
+ description text default null,
+ time timestamp default current_timestamp
+)`);
+
+export const getUserBadges = (userId: number): Badge[] => {
+ return database
+ .prepare('select * from user_badges where user_id = ?')
+ .all(String(userId)) as Badge[];
+};
+
+export const addUserBadge = (userId: number, badge: Badge) => {
+ const { post, image, description } = badge;
+ const statement = database.prepare(`
+ insert into user_badges (user_id, post, image, description) values (?, ?, ?, ?)
+ `);
+
+ statement.run(userId, post, image, description);
+};
+
+export const addUserBadges = (userId: number, badges: Badge[]) => {
+ const statement = database.prepare(`
+ insert into user_badges (user_id, post, image, description) values (?, ?, ?, ?)
+ `);
+
+ for (const badge of badges) {
+ const { post, image, description } = badge;
+
+ statement.run(userId, post, image, description);
+ }
+};
+
+export const removeUserBadge = (userId: number, id: number) => {
+ if (!isNaN(id)) {
+ const statement = database.prepare('delete from user_badges where user_id = ? and id = ?');
+
+ statement.run(userId, id);
+ }
+};
diff --git a/src/routes/api/badges/add/+server.ts b/src/routes/api/badges/add/+server.ts
new file mode 100644
index 00000000..6ce9421e
--- /dev/null
+++ b/src/routes/api/badges/add/+server.ts
@@ -0,0 +1,23 @@
+import { userIdentity } from '$lib/AniList/identity.js';
+import { addUserBadges } from '$lib/userBadgesDatabase.js';
+
+export const POST = async ({ cookies, request }) => {
+ const userCookie = cookies.get('user');
+
+ if (!userCookie) {
+ return new Response('Unauthenticated', { status: 401 });
+ }
+
+ const user = JSON.parse(userCookie);
+ const identity = await userIdentity({
+ tokenType: user['token_type'],
+ expiresIn: user['expires_in'],
+ accessToken: user['access_token'],
+ refreshToken: user['refresh_token']
+ });
+ const formData = await request.json();
+
+ addUserBadges(identity.id, formData);
+
+ return Response.json({});
+};
diff --git a/src/routes/api/badges/remove/+server.ts b/src/routes/api/badges/remove/+server.ts
new file mode 100644
index 00000000..8b05369a
--- /dev/null
+++ b/src/routes/api/badges/remove/+server.ts
@@ -0,0 +1,22 @@
+import { userIdentity } from '$lib/AniList/identity.js';
+import { removeUserBadge } from '$lib/userBadgesDatabase.js';
+
+export const POST = async ({ url, cookies }) => {
+ const userCookie = cookies.get('user');
+
+ if (!userCookie) {
+ return new Response('Unauthenticated', { status: 401 });
+ }
+
+ const user = JSON.parse(userCookie);
+ const identity = await userIdentity({
+ tokenType: user['token_type'],
+ expiresIn: user['expires_in'],
+ accessToken: user['access_token'],
+ refreshToken: user['refresh_token']
+ });
+
+ removeUserBadge(identity.id, Number(url.searchParams.get('id')));
+
+ return Response.json({});
+};
diff --git a/src/routes/user/[user]/+page.server.ts b/src/routes/user/[user]/+page.server.ts
new file mode 100644
index 00000000..76d2d889
--- /dev/null
+++ b/src/routes/user/[user]/+page.server.ts
@@ -0,0 +1,5 @@
+export const load = ({ params }) => {
+ return {
+ username: params.user
+ };
+};
diff --git a/src/routes/user/[user]/+page.svelte b/src/routes/user/[user]/+page.svelte
new file mode 100644
index 00000000..227ba252
--- /dev/null
+++ b/src/routes/user/[user]/+page.svelte
@@ -0,0 +1,40 @@
+
+
+{#if userData === null}
+ Could not load user profile for @{data.username} .
+
+
+
+ Does this user exist?
+{:else if userData === undefined}
+ Loading ...
+{:else}
+
+ @{userData.name}
+ • Badge Wall
+
+
+ This user has watched {(userData.statistics.anime.minutesWatched / 60 / 24).toFixed(1)} days of anime
+ and read
+ {((userData.statistics.manga.chaptersRead * 8.58) / 60 / 24).toFixed(1)} days of manga.
+{/if}
diff --git a/src/routes/user/[user]/badges/+page.server.ts b/src/routes/user/[user]/badges/+page.server.ts
new file mode 100644
index 00000000..4be5bcd2
--- /dev/null
+++ b/src/routes/user/[user]/badges/+page.server.ts
@@ -0,0 +1,11 @@
+import { user } from '$lib/AniList/user.js';
+import { getUserBadges } from '$lib/userBadgesDatabase.js';
+
+export const load = async ({ params }) => {
+ const badges = getUserBadges((await user(params.user)).id);
+
+ return {
+ username: params.user,
+ badges
+ };
+};
diff --git a/src/routes/user/[user]/badges/+page.svelte b/src/routes/user/[user]/badges/+page.svelte
new file mode 100644
index 00000000..276bf1ca
--- /dev/null
+++ b/src/routes/user/[user]/badges/+page.svelte
@@ -0,0 +1,301 @@
+
+
+{#await currentUserIdentity}
+ Loading ...
+{:then identity}
+ {@const isOwner = identity && identity.name === data.username}
+
+ Back to Profile
+ {#if isOwner}
+ •
+ (editMode = !editMode)}
+ >{editMode ? 'Disable' : 'Enable'} Edit Mode
+ {/if}
+
+
+ {#if editMode && isOwner}
+
+ Delete mode is enabled. Click on an image to delete it. There is no confirmation, so be
+ careful!
+
+
+
+
+
+
+ Add Badge
+
+ {/if}
+
+
+{/await}
+
+
--
cgit v1.2.3
From ab00423409358eace0aa66017bfb252cdf680fd5 Mon Sep 17 00:00:00 2001
From: Fuwn
Date: Tue, 24 Oct 2023 17:23:09 -0700
Subject: feat(badges): add safe limits
---
src/lib/userBadgesDatabase.ts | 6 +++---
src/routes/user/[user]/badges/+page.svelte | 34 ++++++++++++++++++------------
2 files changed, 23 insertions(+), 17 deletions(-)
(limited to 'src')
diff --git a/src/lib/userBadgesDatabase.ts b/src/lib/userBadgesDatabase.ts
index c129770e..ae1b1176 100644
--- a/src/lib/userBadgesDatabase.ts
+++ b/src/lib/userBadgesDatabase.ts
@@ -15,9 +15,9 @@ const database = new Database('./due_moe.sqlite3', {
database.exec(`create table if not exists user_badges (
id integer primary key,
user_id integer not null,
- post text not null,
- image text not null,
- description text default null,
+ post text(1000) not null,
+ image text(1000) not null,
+ description text(1000) default null,
time timestamp default current_timestamp
)`);
diff --git a/src/routes/user/[user]/badges/+page.svelte b/src/routes/user/[user]/badges/+page.svelte
index 276bf1ca..8ed7b878 100644
--- a/src/routes/user/[user]/badges/+page.svelte
+++ b/src/routes/user/[user]/badges/+page.svelte
@@ -186,18 +186,12 @@
// }
// ];
- // onMount(async () => {
- // const id = (await user(data.username)).id;
-
- // for (const badge of badges) {
- // await fetch(`/api/badges-add?id=${id}`, {
- // method: 'POST',
- // body: JSON.stringify(badge)
- // });
- // }
- // });
-
onMount(async () => {
+ // await fetch(`/api/badges/add`, {
+ // method: 'POST',
+ // body: JSON.stringify(badges)
+ // });
+
if (data.user) {
currentUserIdentity = userIdentity(data.user);
} else {
@@ -258,9 +252,21 @@
-
-
-
+
+
+
Add Badge
{/if}
--
cgit v1.2.3
From f7ac01d320e825e0ee7962149923614fb37af843 Mon Sep 17 00:00:00 2001
From: Fuwn
Date: Tue, 24 Oct 2023 17:24:48 -0700
Subject: feat(badges): remove test values
---
src/routes/user/[user]/badges/+page.svelte | 183 -----------------------------
1 file changed, 183 deletions(-)
(limited to 'src')
diff --git a/src/routes/user/[user]/badges/+page.svelte b/src/routes/user/[user]/badges/+page.svelte
index 8ed7b878..293a7ba5 100644
--- a/src/routes/user/[user]/badges/+page.svelte
+++ b/src/routes/user/[user]/badges/+page.svelte
@@ -8,190 +8,7 @@
let editMode = false;
let currentUserIdentity: ReturnType;
- // const badges: Badge[] = [
- // {
- // post: 'https://anilist.co/activity/611973592',
- // image: 'https://files.catbox.moe/6tvw17.png'
- // },
- // { post: 'https://anilist.co/activity/611972285', image: 'https://files.catbox.moe/rn5qr5.png' },
- // { post: 'https://anilist.co/activity/611977824', image: 'https://i.imgur.com/DFkT4zB.png' },
- // {
- // post: 'https://anilist.co/activity/612036793',
- // image:
- // 'https://cdn.discordapp.com/attachments/1136989514653519924/1144851101414326333/Badge2_26-08-23.png'
- // },
- // {
- // post: 'https://anilist.co/activity/612273794',
- // image:
- // 'https://cdn.discordapp.com/attachments/1118627570074800264/1144773312468234351/DOGDAY_5_v2.png'
- // },
- // { post: 'https://anilist.co/activity/613961295', image: 'https://files.catbox.moe/6rebg8.png' },
- // { post: 'https://anilist.co/activity/614793182', image: 'https://imgur.com/QhJbw4l.png' },
- // { post: 'https://anilist.co/activity/615002857', image: 'https://files.catbox.moe/oc8g02.png' },
- // { post: 'https://anilist.co/activity/615426233', image: 'https://files.catbox.moe/4z226e.png' },
- // { post: 'https://anilist.co/activity/615427328', image: 'https://files.catbox.moe/tqcltp.png' },
- // { post: 'https://anilist.co/activity/615920191', image: 'https://files.catbox.moe/frw5p5.png' },
- // { post: 'https://anilist.co/activity/616629257', image: 'https://files.catbox.moe/15st7d.png' },
- // { post: 'https://anilist.co/activity/617442391', image: 'https://i.imgur.com/aHkSRCz.gif' },
- // {
- // post: 'https://anilist.co/activity/617445099',
- // image:
- // 'https://cdn.discordapp.com/attachments/1118627570074800264/1148663790452346961/chondyunbday.gif'
- // },
- // {
- // post: 'https://anilist.co/activity/617616590',
- // image:
- // 'https://cdn.discordapp.com/attachments/1136989514653519924/1148678438551568444/Badge_3.png'
- // },
- // { post: 'https://anilist.co/activity/617842237', image: 'https://i.imgur.com/Zx4uiAz.gif' },
- // { post: 'https://anilist.co/activity/618296369', image: 'https://i.imgur.com/V6UsqYI.gif' },
- // { post: 'https://anilist.co/activity/618664650', image: 'https://imgur.com/x98vT7p.png' },
- // { post: 'https://anilist.co/activity/619306471', image: 'https://i.imgur.com/GppbpqE.png' },
- // { post: 'https://anilist.co/activity/619657632', image: 'https://files.catbox.moe/barla6.png' },
- // { post: 'https://anilist.co/activity/619659847', image: 'https://i.imgur.com/e81dgSB.gif' },
- // { post: 'https://anilist.co/activity/619661657', image: 'https://i.imgur.com/S0fSeD4.gif' },
- // { post: 'https://anilist.co/activity/619664832', image: 'https://i.imgur.com/EXNQE3n.gif' },
- // {
- // post: 'https://anilist.co/activity/619764622',
- // image:
- // 'https://cdn.discordapp.com/attachments/1118627570074800264/1151314632942817290/persona_5_3.png'
- // },
- // { post: 'https://anilist.co/activity/620025361', image: 'https://i.imgur.com/DmEl13g.gif' },
- // { post: 'https://anilist.co/activity/620125206', image: 'https://i.imgur.com/SmzhGyu.gif' },
- // { post: 'https://anilist.co/activity/620125762', image: 'https://i.imgur.com/38I5gUM.gif' },
- // { post: 'https://anilist.co/activity/620126356', image: 'https://i.imgur.com/9I7Xggm.gif' },
- // { post: 'https://anilist.co/activity/620600819', image: 'https://i.imgur.com/nHREaUc.png' },
- // { post: 'https://anilist.co/activity/620989269', image: 'https://imgur.com/XjhyOHU.png' },
- // {
- // post: 'https://anilist.co/activity/621253410',
- // image:
- // 'https://cdn.discordapp.com/attachments/1139717993845239849/1147701375707381760/0028HLA.png'
- // },
- // { post: 'https://anilist.co/activity/621787546', image: 'https://i.imgur.com/tn5yVsk.gif' },
- // {
- // post: 'https://anilist.co/activity/621789551',
- // image: 'https://i.postimg.cc/Z5325GDx/ota-day-otaku-academia-ittle-witch-academia.png'
- // },
- // { post: 'https://anilist.co/activity/622236894', image: 'https://i.imgur.com/vicrIfS.png' },
- // { post: 'https://anilist.co/activity/622237728', image: 'https://i.imgur.com/TLSC65A.jpg' },
- // { post: 'https://anilist.co/activity/623156563', image: 'https://files.catbox.moe/ujf0ym.png' },
- // { post: 'https://anilist.co/activity/623990926', image: 'https://files.catbox.moe/gkalwm.png' },
- // {
- // post: 'https://anilist.co/activity/623995806',
- // image:
- // 'https://cdn.discordapp.com/attachments/1118627570074800264/1154888665638649916/monikabday.png'
- // },
- // { post: 'https://anilist.co/activity/624542383', image: 'https://files.catbox.moe/9tzs66.png' },
- // {
- // post: 'https://anilist.co/activity/624542383',
- // image:
- // 'https://cdn.discordapp.com/attachments/1136989514653519924/1154540564671377459/EMILIA_BADGE_2.png'
- // },
- // { post: 'https://anilist.co/activity/624543474', image: 'https://imgur.com/WQuXh6g.png' },
- // {
- // post: 'https://anilist.co/activity/624544489',
- // image:
- // 'https://cdn.discordapp.com/attachments/1136989514653519924/1154736156093726870/fsdfwefewfwf.png'
- // },
- // {
- // post: 'https://anilist.co/activity/624545233',
- // image:
- // 'https://cdn.discordapp.com/attachments/1136989514653519924/1153606849464111134/katoubadge1.png'
- // },
- // { post: 'https://anilist.co/activity/624548754', image: 'https://imgur.com/j5aqX5w.png' },
- // {
- // post: 'https://anilist.co/activity/624549956',
- // image:
- // 'https://cdn.discordapp.com/attachments/1152962059126972417/1154745849465811015/Day_of_Mid_2.png'
- // },
- // { post: 'https://anilist.co/activity/626483669', image: 'https://files.catbox.moe/lz0r48.png' },
- // {
- // post: 'https://anilist.co/activity/626483669',
- // image:
- // 'https://cdn.discordapp.com/attachments/1118627570074800264/1156396779332456538/jojobdayb.png'
- // },
- // {
- // post: 'https://anilist.co/activity/626770819',
- // image:
- // 'https://cdn.discordapp.com/attachments/1136989514653519924/1156582649779994664/kikurihiroi.png'
- // },
- // { post: 'https://anilist.co/activity/626772329', image: 'https://i.imgur.com/P09v438.gif' },
- // {
- // post: 'https://anilist.co/activity/627283326',
- // image:
- // 'https://cdn.discordapp.com/attachments/1118627570074800264/1157124224197083226/coffeeday2.png'
- // },
- // {
- // post: 'https://anilist.co/activity/628202238',
- // image:
- // 'https://cdn.discordapp.com/attachments/1136989514653519924/1156472801457340506/rinshima1.png'
- // },
- // {
- // post: 'https://anilist.co/activity/628202913',
- // image:
- // 'https://cdn.discordapp.com/attachments/1136989514653519924/1157574135069806592/Badge-1_-_01_10_23.png'
- // },
- // {
- // post: 'https://anilist.co/activity/628305048',
- // image:
- // 'https://cdn.discordapp.com/attachments/1118627570074800264/1157650582094479370/SakeDay2.png'
- // },
- // { post: 'https://anilist.co/activity/629168789', image: 'https://files.catbox.moe/0mwudd.png' },
- // { post: 'https://anilist.co/activity/629592629', image: 'https://files.catbox.moe/pyjy0z.png' },
- // { post: 'https://anilist.co/activity/629593251', image: 'https://files.catbox.moe/e9xx50.png' },
- // { post: 'https://anilist.co/activity/630084060', image: 'https://i.imgur.com/zVU0gie.gif' },
- // { post: 'https://anilist.co/activity/630462423', image: 'https://files.catbox.moe/b63wxi.png' },
- // {
- // post: 'https://anilist.co/activity/630464366',
- // image:
- // 'https://cdn.discordapp.com/attachments/1118627570074800264/1158527481486266490/codegeass1.png'
- // },
- // { post: 'https://anilist.co/activity/630996180', image: 'https://files.catbox.moe/ap15dx.png' },
- // { post: 'https://anilist.co/activity/631494022', image: 'https://files.catbox.moe/fw4rqx.png' },
- // {
- // post: 'https://anilist.co/activity/631503062',
- // image:
- // 'https://cdn.discordapp.com/attachments/1118627570074800264/1158787682231660684/rize1.png'
- // },
- // {
- // post: 'https://anilist.co/activity/632259051',
- // image:
- // 'https://cdn.discordapp.com/attachments/1154438205731524638/1158943217459412992/Luna_Bday2023_Axel5.png'
- // },
- // { post: 'https://anilist.co/activity/632260829', image: 'https://files.catbox.moe/ighico.png' },
- // { post: 'https://anilist.co/activity/632311940', image: 'https://files.catbox.moe/ukv6tv.png' },
- // {
- // post: 'https://anilist.co/activity/632311940',
- // image:
- // 'https://cdn.discordapp.com/attachments/1136989514653519924/1160915207711895593/Gintoki_2.png'
- // },
- // {
- // post: 'https://anilist.co/activity/632407688',
- // image:
- // 'https://cdn.discordapp.com/attachments/1136989514653519924/1159856849735127110/Nishinoya_1.png'
- // },
- // { post: 'https://anilist.co/activity/632832412', image: 'https://files.catbox.moe/9lk6s1.png' },
- // { post: 'https://anilist.co/activity/633710355', image: 'https://i.imgur.com/JmpriDr.gif' },
- // { post: 'https://anilist.co/activity/633710743', image: 'https://files.catbox.moe/it9d7q.png' },
- // {
- // post: 'https://anilist.co/activity/633711260',
- // image:
- // 'https://cdn.discordapp.com/attachments/1118627570074800264/1160674827670134804/Sonia1.png'
- // },
- // { post: 'https://anilist.co/activity/634118108', image: 'https://files.catbox.moe/tzudpj.png' },
- // {
- // post: 'https://anilist.co/activity/634119722',
- // image:
- // 'https://cdn.discordapp.com/attachments/1085425937933418578/1162583650840354846/Mystery_Day_badge_4.png'
- // }
- // ];
-
onMount(async () => {
- // await fetch(`/api/badges/add`, {
- // method: 'POST',
- // body: JSON.stringify(badges)
- // });
-
if (data.user) {
currentUserIdentity = userIdentity(data.user);
} else {
--
cgit v1.2.3
From dc9755d709b5bc88fd81f6e11641c1e78659283d Mon Sep 17 00:00:00 2001
From: Fuwn
Date: Tue, 24 Oct 2023 17:28:39 -0700
Subject: fix(database): change path for docker
---
src/lib/userBadgesDatabase.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'src')
diff --git a/src/lib/userBadgesDatabase.ts b/src/lib/userBadgesDatabase.ts
index ae1b1176..78655cd3 100644
--- a/src/lib/userBadgesDatabase.ts
+++ b/src/lib/userBadgesDatabase.ts
@@ -8,7 +8,7 @@ export interface Badge {
id?: number;
}
-const database = new Database('./due_moe.sqlite3', {
+const database = new Database('./data/due_moe.sqlite3', {
verbose: dev ? console.log : undefined
});
--
cgit v1.2.3
From 36d2b84670a096550b03ceb276184ab309b5364a Mon Sep 17 00:00:00 2001
From: Fuwn
Date: Tue, 24 Oct 2023 18:09:27 -0700
Subject: feat(layout): profile item navigation
---
src/routes/+layout.svelte | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
(limited to 'src')
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index 19df3f1c..20ae9ef4 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -52,11 +52,17 @@
「 Home • Completed •
Manga & LN Updates •
- Tools • Settings 」
+ Tools • {#if data.user}
+ Profile •
+ {/if} Settings 」
-
Home •
Completed •
Tools
+
Home •
Completed •
Tools
+ {#if data.user}
+ •
Profile
+ {/if}
+
Settings
Manga & LN Updates
--
cgit v1.2.3
From 4a97d2608aaae9ff7711acf8f37ef45cdb349293 Mon Sep 17 00:00:00 2001
From: Fuwn
Date: Tue, 24 Oct 2023 18:13:12 -0700
Subject: fix(routes): remove old user route
---
src/routes/@[user]/+page.server.ts | 5 -----
src/routes/@[user]/+page.svelte | 45 --------------------------------------
2 files changed, 50 deletions(-)
delete mode 100644 src/routes/@[user]/+page.server.ts
delete mode 100644 src/routes/@[user]/+page.svelte
(limited to 'src')
diff --git a/src/routes/@[user]/+page.server.ts b/src/routes/@[user]/+page.server.ts
deleted file mode 100644
index 76d2d889..00000000
--- a/src/routes/@[user]/+page.server.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export const load = ({ params }) => {
- return {
- username: params.user
- };
-};
diff --git a/src/routes/@[user]/+page.svelte b/src/routes/@[user]/+page.svelte
deleted file mode 100644
index 1763193a..00000000
--- a/src/routes/@[user]/+page.svelte
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-{#if userData === null}
- Could not load user profile for @{data.username} .
-
-
-
- Does this user exist?
-{:else if userData === undefined}
- Loading ...
-{:else}
- @{userData.name}
-
-
-
- This user has watched {(userData.statistics.anime.minutesWatched / 60 / 24).toFixed(1)} days of anime
- and read
- {((userData.statistics.manga.chaptersRead * 8.58) / 60 / 24).toFixed(1)} days of manga.
-{/if}
-
-
-
-
-
-This page is under construction!
--
cgit v1.2.3
From f99fd41ee23d7669812ff1d88d23a9b7f22db901 Mon Sep 17 00:00:00 2001
From: Fuwn
Date: Tue, 24 Oct 2023 18:18:37 -0700
Subject: feat(user): prettier user route
---
src/lib/AniList/user.ts | 5 ++++-
src/routes/user/[user]/+page.svelte | 44 ++++++++++++++++++++++++++++---------
2 files changed, 38 insertions(+), 11 deletions(-)
(limited to 'src')
diff --git a/src/lib/AniList/user.ts b/src/lib/AniList/user.ts
index dd9995fd..fdc98a58 100644
--- a/src/lib/AniList/user.ts
+++ b/src/lib/AniList/user.ts
@@ -15,6 +15,9 @@ export interface User {
volumesRead: number;
};
};
+ avatar: {
+ large: string;
+ };
}
export const user = async (username: string): Promise => {
@@ -28,7 +31,7 @@ export const user = async (username: string): Promise => {
},
body: JSON.stringify({
query: `{ User(name: "${username}") {
- name id statistics {
+ name id avatar { large } statistics {
anime {
count meanScore minutesWatched episodesWatched
}
diff --git a/src/routes/user/[user]/+page.svelte b/src/routes/user/[user]/+page.svelte
index 227ba252..858e6aec 100644
--- a/src/routes/user/[user]/+page.svelte
+++ b/src/routes/user/[user]/+page.svelte
@@ -27,14 +27,38 @@
{:else if userData === undefined}
Loading ...
{:else}
-
- @{userData.name}
- • Badge Wall
-
-
- This user has watched {(userData.statistics.anime.minutesWatched / 60 / 24).toFixed(1)} days of anime
- and read
- {((userData.statistics.manga.chaptersRead * 8.58) / 60 / 24).toFixed(1)} days of manga.
+
+
+
+
+
+
+
+
+
+ @{userData.name}
+ • Badge Wall
+
+
+ This user has watched {(userData.statistics.anime.minutesWatched / 60 / 24).toFixed(1)} days of
+ anime and read
+ {((userData.statistics.manga.chaptersRead * 8.58) / 60 / 24).toFixed(1)} days of manga.
+
+
{/if}
+
+
--
cgit v1.2.3
From e61da1367da23c309bd006416d598d861dfcfb2c Mon Sep 17 00:00:00 2001
From: Fuwn
Date: Thu, 26 Oct 2023 14:48:00 -0700
Subject: refactor(badges): move to bun:sqlite
---
src/lib/userBadgesDatabase.ts | 61 ++++++++++++++----------------
src/routes/api/badges/add/+server.ts | 11 ++++--
src/routes/user/[user]/badges/+page.svelte | 31 +++++++--------
3 files changed, 52 insertions(+), 51 deletions(-)
(limited to 'src')
diff --git a/src/lib/userBadgesDatabase.ts b/src/lib/userBadgesDatabase.ts
index 78655cd3..8cf40d5b 100644
--- a/src/lib/userBadgesDatabase.ts
+++ b/src/lib/userBadgesDatabase.ts
@@ -1,57 +1,54 @@
-import { dev } from '$app/environment';
-import Database from 'better-sqlite3';
+import { Database } from 'bun:sqlite';
export interface Badge {
- post: string;
- image: string;
+ post?: string;
+ image?: string;
description?: string;
id?: number;
}
const database = new Database('./data/due_moe.sqlite3', {
- verbose: dev ? console.log : undefined
+ create: true
});
-database.exec(`create table if not exists user_badges (
- id integer primary key,
- user_id integer not null,
- post text(1000) not null,
- image text(1000) not null,
- description text(1000) default null,
- time timestamp default current_timestamp
-)`);
+database
+ .query(
+ `CREATE TABLE IF NOT EXISTS user_badges (
+ id INTEGER PRIMARY KEY,
+ user_id INTEGER NOT NULL,
+ post TEXT(1000) NOT NULL,
+ image TEXT(1000) NOT NULL,
+ description TEXT(1000) DEFAULT NULL,
+ time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+)`
+ )
+ .run();
export const getUserBadges = (userId: number): Badge[] => {
return database
- .prepare('select * from user_badges where user_id = ?')
- .all(String(userId)) as Badge[];
+ .query('SELECT * FROM user_badges WHERE user_id = $userId')
+ .all({ $userId: String(userId) }) as Badge[];
};
export const addUserBadge = (userId: number, badge: Badge) => {
const { post, image, description } = badge;
- const statement = database.prepare(`
- insert into user_badges (user_id, post, image, description) values (?, ?, ?, ?)
- `);
- statement.run(userId, post, image, description);
-};
-
-export const addUserBadges = (userId: number, badges: Badge[]) => {
- const statement = database.prepare(`
- insert into user_badges (user_id, post, image, description) values (?, ?, ?, ?)
- `);
+ if (post === undefined || image === undefined) {
+ return;
+ }
- for (const badge of badges) {
- const { post, image, description } = badge;
+ const statement = database.query(
+ `INSERT INTO user_badges (user_id, post, image, description) VALUES (?1, ?2, ?3, ?4);`
+ );
- statement.run(userId, post, image, description);
- }
+ statement.run([userId, post, image, description]);
};
export const removeUserBadge = (userId: number, id: number) => {
if (!isNaN(id)) {
- const statement = database.prepare('delete from user_badges where user_id = ? and id = ?');
-
- statement.run(userId, id);
+ database.query('DELETE FROM user_badges WHERE user_id = $userId AND id = $id').run({
+ $userId: userId,
+ $id: id
+ });
}
};
diff --git a/src/routes/api/badges/add/+server.ts b/src/routes/api/badges/add/+server.ts
index 6ce9421e..627176a7 100644
--- a/src/routes/api/badges/add/+server.ts
+++ b/src/routes/api/badges/add/+server.ts
@@ -1,7 +1,7 @@
import { userIdentity } from '$lib/AniList/identity.js';
-import { addUserBadges } from '$lib/userBadgesDatabase.js';
+import { addUserBadge } from '$lib/userBadgesDatabase.js';
-export const POST = async ({ cookies, request }) => {
+export const POST = async ({ cookies, url }) => {
const userCookie = cookies.get('user');
if (!userCookie) {
@@ -15,9 +15,12 @@ export const POST = async ({ cookies, request }) => {
accessToken: user['access_token'],
refreshToken: user['refresh_token']
});
- const formData = await request.json();
- addUserBadges(identity.id, formData);
+ addUserBadge(identity.id, {
+ post: url.searchParams.get('post') || undefined,
+ image: url.searchParams.get('image') || undefined,
+ description: url.searchParams.get('description') || undefined
+ });
return Response.json({});
};
diff --git a/src/routes/user/[user]/badges/+page.svelte b/src/routes/user/[user]/badges/+page.svelte
index 293a7ba5..324d568e 100644
--- a/src/routes/user/[user]/badges/+page.svelte
+++ b/src/routes/user/[user]/badges/+page.svelte
@@ -26,25 +26,26 @@
const activityURL = document.querySelector('input[name="activity_url"]') as HTMLInputElement;
const description = document.querySelector('input[name="description"]') as HTMLInputElement;
- fetch(`/api/badges/add`, {
- method: 'POST',
- body: JSON.stringify([
- { image: imageURL.value, post: activityURL.value, description: description.value }
- ])
+ fetch(
+ `/api/badges/add?image=${encodeURIComponent(imageURL.value)}&post=${encodeURIComponent(
+ activityURL.value
+ )}&description=${encodeURIComponent(description.value)}`,
+ {
+ method: 'POST'
+ }
+ ).then(() => {
+ imageURL.value = '';
+ activityURL.value = '';
+ description.value = '';
});
-
- console.log(imageURL.value, activityURL.value, description.value);
-
- imageURL.value = '';
- activityURL.value = '';
- description.value = '';
};
const removeBadge = (badge: Badge) => {
fetch(`/api/badges/remove?id=${badge.id}`, {
method: 'POST'
+ }).then(() => {
+ (document.querySelector(`#badge-${badge.id}`) as HTMLAnchorElement).style.display = 'none';
});
- (document.querySelector(`#badge-${badge.id}`) as HTMLAnchorElement).style.display = 'none';
};
@@ -56,9 +57,9 @@
Back to Profile
{#if isOwner}
•
- (editMode = !editMode)}
- >{editMode ? 'Disable' : 'Enable'} Edit Mode
+ (editMode = !editMode)}>
+ {editMode ? 'Disable' : 'Enable'} Edit Mode
+
{/if}
--
cgit v1.2.3