From 74222ead4561bed30527571f8161b926a42a4393 Mon Sep 17 00:00:00 2001 From: sam Date: Tue, 3 Dec 2024 15:19:52 +0100 Subject: [PATCH 1/5] feat(frontend): replace placeholder avatar with identicons i don't actually know what the license on the kitten image is, and while it's very unlikely, i don't want to get into legal trouble. it was only ever supposed to be a temporary image, too. identicons aren't the prettiest but at least they have a clear license :3 --- Foxnouns.Frontend/package.json | 1 + Foxnouns.Frontend/pnpm-lock.yaml | 9 ++++++++ .../src/lib/components/Avatar.svelte | 22 +++++++++++++++---- .../lib/components/editor/AvatarEditor.svelte | 5 +++-- .../components/profile/ProfileHeader.svelte | 1 + .../components/profile/user/MemberCard.svelte | 1 + .../src/routes/settings/+page.svelte | 1 + .../src/routes/settings/members/+page.svelte | 1 + .../routes/settings/members/[id]/+page.svelte | 1 + .../src/routes/settings/profile/+page.svelte | 1 + 10 files changed, 37 insertions(+), 6 deletions(-) diff --git a/Foxnouns.Frontend/package.json b/Foxnouns.Frontend/package.json index 3fc70d1..0e74736 100644 --- a/Foxnouns.Frontend/package.json +++ b/Foxnouns.Frontend/package.json @@ -42,6 +42,7 @@ "bootstrap-icons": "^1.11.3", "luxon": "^3.5.0", "markdown-it": "^14.1.0", + "minidenticons": "^4.2.1", "pretty-bytes": "^6.1.1", "sanitize-html": "^2.13.1", "svelte-tippy": "^1.3.2", diff --git a/Foxnouns.Frontend/pnpm-lock.yaml b/Foxnouns.Frontend/pnpm-lock.yaml index 9b78513..bb1a839 100644 --- a/Foxnouns.Frontend/pnpm-lock.yaml +++ b/Foxnouns.Frontend/pnpm-lock.yaml @@ -23,6 +23,9 @@ importers: markdown-it: specifier: ^14.1.0 version: 14.1.0 + minidenticons: + specifier: ^4.2.1 + version: 4.2.1 pretty-bytes: specifier: ^6.1.1 version: 6.1.1 @@ -1110,6 +1113,10 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + minidenticons@4.2.1: + resolution: {integrity: sha512-oWfFivA0lOx/V/bO/YIJbthB26lV8JXYvhnv9zM2hNd3fzsHTXQ6c6bWZPcvhD3nnOB+lQk/D9lF43BXixrN8g==} + engines: {node: '>=15.14.0'} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -2369,6 +2376,8 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 + minidenticons@4.2.1: {} + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 diff --git a/Foxnouns.Frontend/src/lib/components/Avatar.svelte b/Foxnouns.Frontend/src/lib/components/Avatar.svelte index 99dd8f3..d9f4eec 100644 --- a/Foxnouns.Frontend/src/lib/components/Avatar.svelte +++ b/Foxnouns.Frontend/src/lib/components/Avatar.svelte @@ -1,16 +1,22 @@ diff --git a/Foxnouns.Frontend/src/lib/components/editor/AvatarEditor.svelte b/Foxnouns.Frontend/src/lib/components/editor/AvatarEditor.svelte index 05a9a62..e18c6b6 100644 --- a/Foxnouns.Frontend/src/lib/components/editor/AvatarEditor.svelte +++ b/Foxnouns.Frontend/src/lib/components/editor/AvatarEditor.svelte @@ -7,12 +7,13 @@ import ShortNoscriptWarning from "./ShortNoscriptWarning.svelte"; type Props = { + name: string; current: string | null; alt: string; update: (avatar: string) => Promise; updated: boolean; }; - let { current, alt, update: onclick, updated }: Props = $props(); + let { name, current, alt, update: onclick, updated }: Props = $props(); const MAX_AVATAR_BYTES = 1_000_000; @@ -40,7 +41,7 @@

- +

diff --git a/Foxnouns.Frontend/src/lib/components/profile/ProfileHeader.svelte b/Foxnouns.Frontend/src/lib/components/profile/ProfileHeader.svelte index d28a001..0fd1960 100644 --- a/Foxnouns.Frontend/src/lib/components/profile/ProfileHeader.svelte +++ b/Foxnouns.Frontend/src/lib/components/profile/ProfileHeader.svelte @@ -22,6 +22,7 @@
{$t("settings.avatar")}
diff --git a/Foxnouns.Frontend/src/routes/settings/members/+page.svelte b/Foxnouns.Frontend/src/routes/settings/members/+page.svelte index 563cf90..6963c0c 100644 --- a/Foxnouns.Frontend/src/routes/settings/members/+page.svelte +++ b/Foxnouns.Frontend/src/routes/settings/members/+page.svelte @@ -30,6 +30,7 @@ {#each data.members as member (member.id)}

{$t("settings.avatar")}

{$t("settings.avatar")}

Date: Tue, 3 Dec 2024 20:02:09 +0100 Subject: [PATCH 2/5] feat(frontend): export ui --- .../src/lib/i18n/locales/en.json | 8 ++- .../src/routes/settings/+page.svelte | 3 +- .../routes/settings/export/+page.server.ts | 35 +++++++++++++ .../src/routes/settings/export/+page.svelte | 49 +++++++++++++++++++ .../routes/settings/members/[id]/+page.svelte | 9 ++-- .../routes/settings/members/new/+page.svelte | 3 +- .../src/routes/settings/profile/+page.svelte | 3 +- .../routes/settings/profile/bio/+page.svelte | 3 +- 8 files changed, 104 insertions(+), 9 deletions(-) create mode 100644 Foxnouns.Frontend/src/routes/settings/export/+page.server.ts create mode 100644 Foxnouns.Frontend/src/routes/settings/export/+page.svelte diff --git a/Foxnouns.Frontend/src/lib/i18n/locales/en.json b/Foxnouns.Frontend/src/lib/i18n/locales/en.json index 73063c5..6a9f9f6 100644 --- a/Foxnouns.Frontend/src/lib/i18n/locales/en.json +++ b/Foxnouns.Frontend/src/lib/i18n/locales/en.json @@ -112,7 +112,13 @@ "create-member-name-label": "Member name", "auth-remove-method": "Remove", "force-log-out-warning": "Make sure you're still able to log in before using this!", - "force-log-out-confirmation": "Are you sure you want to log out from all devices? If you just want to log out from this device, click the \"Log out\" button on your settings page." + "force-log-out-confirmation": "Are you sure you want to log out from all devices? If you just want to log out from this device, click the \"Log out\" button on your settings page.", + "export-request-success": "Successfully requested a new export! Please note that it may take a few minutes to complete, especially if you have a lot of members.", + "export-title": "Request a copy of your data", + "export-info": "You can request a copy of your data once every 24 hours. Exports are stored for 15 days (a little over two weeks) and then deleted.", + "export-expires-at": "(expires {{expiresAt}})", + "export-download": "Download export", + "export-request-button": "Request a new export" }, "yes": "Yes", "no": "No", diff --git a/Foxnouns.Frontend/src/routes/settings/+page.svelte b/Foxnouns.Frontend/src/routes/settings/+page.svelte index 79f7d64..f43c8a5 100644 --- a/Foxnouns.Frontend/src/routes/settings/+page.svelte +++ b/Foxnouns.Frontend/src/routes/settings/+page.svelte @@ -7,6 +7,7 @@ import Error from "$components/Error.svelte"; import { idTimestamp } from "$lib"; import { DateTime } from "luxon"; + import { enhance } from "$app/forms"; type Props = { data: PageData; form: ActionData }; let { data, form }: Props = $props(); @@ -20,7 +21,7 @@
Change your username
-
+ { + const resp = await apiRequest("GET", "/data-exports", { + fetch, + cookies, + isInternal: true, + }); + + let canExport = true; + if (resp.expires_at) { + const created = DateTime.fromISO(resp.expires_at).minus(Duration.fromObject({ days: 15 })); + canExport = DateTime.now().diff(created, "seconds").seconds >= 86400; + } + + return { url: resp.url, expiresAt: resp.expires_at, canExport }; +}; + +export const actions = { + default: async ({ fetch, cookies }) => { + try { + fastRequest("POST", "/data-exports", { fetch, cookies, isInternal: true }); + return { ok: true, error: null }; + } catch (e) { + if (e instanceof ApiError) return { ok: false, error: e.obj }; + log.error("Error requesting data export:", e); + throw e; + } + }, +}; diff --git a/Foxnouns.Frontend/src/routes/settings/export/+page.svelte b/Foxnouns.Frontend/src/routes/settings/export/+page.svelte new file mode 100644 index 0000000..874f8e8 --- /dev/null +++ b/Foxnouns.Frontend/src/routes/settings/export/+page.svelte @@ -0,0 +1,49 @@ + + +
diff --git a/Foxnouns.Frontend/src/routes/settings/members/[id]/+page.svelte b/Foxnouns.Frontend/src/routes/settings/members/[id]/+page.svelte index 22fd219..b4b38e2 100644 --- a/Foxnouns.Frontend/src/routes/settings/members/[id]/+page.svelte +++ b/Foxnouns.Frontend/src/routes/settings/members/[id]/+page.svelte @@ -14,6 +14,7 @@ import SidEditor from "$components/editor/SidEditor.svelte"; import BioEditor from "$components/editor/BioEditor.svelte"; import { PUBLIC_BASE_URL } from "$env/static/public"; + import { enhance } from "$app/forms"; type Props = { data: PageData; form: ActionData }; let { data, form }: Props = $props(); @@ -83,7 +84,7 @@

{$t("edit-profile.member-name")}

-
+

{$t("edit-profile.display-name")}

- +

{$t("edit-profile.profile-options-header")}

- +

{$t("edit-profile.bio-tab")}

- +
diff --git a/Foxnouns.Frontend/src/routes/settings/members/new/+page.svelte b/Foxnouns.Frontend/src/routes/settings/members/new/+page.svelte index 7999be2..2c1fc0b 100644 --- a/Foxnouns.Frontend/src/routes/settings/members/new/+page.svelte +++ b/Foxnouns.Frontend/src/routes/settings/members/new/+page.svelte @@ -1,4 +1,5 @@ + +

Link a new Fediverse account

+ +
+ + + + +

+ {$t("auth.log-in-with-fediverse-error-blurb")} + +

+
diff --git a/migrators/NetImporter/NetImporter.csproj b/migrators/NetImporter/NetImporter.csproj index e62f921..08a1aa3 100644 --- a/migrators/NetImporter/NetImporter.csproj +++ b/migrators/NetImporter/NetImporter.csproj @@ -1,25 +1,26 @@  - - Exe - net8.0 - enable - enable - + + Exe + net8.0 + enable + enable + - - - + + + - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + +