From 77a9a6842be5e32d119f2cf43a9f9124adf1306e Mon Sep 17 00:00:00 2001 From: Danny Morabito Date: Sat, 21 Dec 2024 21:27:38 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Improve=20home=20page=20and=20lette?= =?UTF-8?q?rs=20functionality?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 📝 Add better product descriptions on the home page - 🎨 Improve styles: fix title that looked "like a button" (reference #7) - 🛠️ Render markdown for letters (fix #8) - ⬆️ Update dependencies --- package.json | 4 +- src/components/LoginWithNostr.svelte | 37 +++++++++++++++++- src/components/RecipientChip.svelte | 32 ++++++++-------- src/lib/style/layout.css | 27 ++++++------- src/lib/style/typography.css | 57 +++++++++++++++++++++++----- src/routes/letters/[id]/+page.svelte | 13 +++++-- 6 files changed, 127 insertions(+), 43 deletions(-) diff --git a/package.json b/package.json index c0cc5de..200d5e8 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,8 @@ }, "devDependencies": { "@iconify/svelte": "^4.0.2", - "@sveltejs/adapter-node": "^5.2.9", "@sveltejs/adapter-auto": "^3.3.1", + "@sveltejs/adapter-node": "^5.2.9", "@sveltejs/kit": "^2.9.0", "@sveltejs/vite-plugin-svelte": "^4.0.2", "prettier": "^3.4.1", @@ -30,6 +30,8 @@ "@nostr-dev-kit/ndk": "^2.10.7", "@nostr-dev-kit/ndk-cache-dexie": "^2.5.8", "@nostr-dev-kit/ndk-svelte": "^2.3.2", + "dompurify": "^3.2.3", + "marked": "^15.0.4", "qrcode": "^1.5.4" } } diff --git a/src/components/LoginWithNostr.svelte b/src/components/LoginWithNostr.svelte index 4fa02b0..f237ff9 100644 --- a/src/components/LoginWithNostr.svelte +++ b/src/components/LoginWithNostr.svelte @@ -169,8 +169,43 @@ {/if} {:else} +
+

+ + A Better Way to Email +

+ +

+ Welcome to npub.email! We've created a new kind of email service that puts your privacy first. + Think of it like regular email, but with extra security and cool features built in. +

+
+ + +
+

Ready to try a better kind of email? Join us and take control of your communications!

+
+
- + +
+
+ +
+

+ 👀 What's Next? Even Better Privacy +

+

+ Want to see something really cool? Check out Eve - our upcoming Closed Community Networks project.
+ We can't say much yet, but if you're into maximum privacy and love having community, you'll want to watch this + space.
+ Take a peek at arx-ccn.com if you're curious. +

+
+ +
+ Made by Arx - Making Privacy Simple
+
{/if} diff --git a/src/lib/style/layout.css b/src/lib/style/layout.css index 5353156..efe6aa9 100644 --- a/src/lib/style/layout.css +++ b/src/lib/style/layout.css @@ -138,30 +138,31 @@ h3 { .section-title { position: fixed; display: flex; - width: calc(100%); + width: 100%; margin: calc(var(--spacing-md) * -1); padding: var(--spacing-md); - background: var(--ternary); - border: 1px solid var(--accent); z-index: 99999; - border-top-left-radius: 16px; - border-top-right-radius: 16px; - place-content: center; + place-content: center; align-items: center; gap: var(--spacing-xs); + font-size: 1.25rem; + font-weight: bold; + + &:is(.dialog-content .section-title) { + background: var(--ternary); + border: 1px solid var(--accent); + border-top-left-radius: 16px; + border-bottom-left-radius: 16px; + } + > .close-button { position: absolute; top: var(--spacing-md); - right: calc( - var(--spacing-md) * 2 + 1.5rem - ); + right: calc(var(--spacing-md) * 2 + 1.5rem); } & + * { - margin-top: calc( - 1.5rem + - var(--spacing-md) * 3 - ); + margin-top: calc(1.5rem + var(--spacing-md) * 3); } } diff --git a/src/lib/style/typography.css b/src/lib/style/typography.css index ec6b470..b2a55b9 100644 --- a/src/lib/style/typography.css +++ b/src/lib/style/typography.css @@ -1,11 +1,50 @@ p.error { - color: oklch(60% 50% 35); - font-weight: 700; - font-size: 0.9rem; - text-align: center; - text-shadow: -1.5px -1.5px 0 oklch(15% 10% 35), - 1.5px -1.5px 0 oklch(15% 10% 35), - -1.5px 1.5px 0 oklch(15% 10% 35), - 1.5px 1.5px 0 oklch(15% 10% 35); - letter-spacing: 1px; + color: oklch(60% 50% 35); + font-weight: 700; + font-size: 0.9rem; + text-align: center; + text-shadow: -1.5px -1.5px 0 oklch(15% 10% 35), 1.5px -1.5px 0 + oklch(15% 10% 35), -1.5px 1.5px 0 oklch(15% 10% 35), 1.5px 1.5px 0 + oklch(15% 10% 35); + letter-spacing: 1px; } + +blockquote { + --hue: calc(var(--base-hue)); + border-left: 2px solid oklch(50% 0.2 var(--hue)); + margin: 0; + padding: 0; + padding-left: 1em; +} + +:is(blockquote blockquote) { + --hue: calc(var(--base-hue) + 45); +} + +:is(blockquote blockquote blockquote) { + --hue: calc(var(--base-hue) + 90); +} + +:is(blockquote blockquote blockquote blockquote) { + --hue: calc(var(--base-hue) + 135); +} + +:is(blockquote blockquote blockquote blockquote blockquote) { + --hue: calc(var(--base-hue) + 180); +} + +:is(blockquote blockquote blockquote blockquote blockquote blockquote) { + --hue: calc(var(--base-hue) + 225); +} + +:is(blockquote blockquote blockquote blockquote blockquote blockquote blockquote) { + --hue: calc(var(--base-hue) + 270); +} + +:is(blockquote blockquote blockquote blockquote blockquote blockquote blockquote blockquote) { + --hue: calc(var(--base-hue) + 315); +} + +:is(blockquote blockquote blockquote blockquote blockquote blockquote blockquote blockquote blockquote) { + --hue: var(--base-hue); +} \ No newline at end of file diff --git a/src/routes/letters/[id]/+page.svelte b/src/routes/letters/[id]/+page.svelte index 482a5a4..f15add4 100644 --- a/src/routes/letters/[id]/+page.svelte +++ b/src/routes/letters/[id]/+page.svelte @@ -8,6 +8,8 @@ import { Letter } from '$lib/letter'; import Dialog from '../../../components/Dialog.svelte'; import AnimatedQRCode from '../../../components/AnimatedQRCode.svelte'; + import DOMPurify from 'dompurify'; + import * as marked from 'marked'; const { data } = $props(); const { id } = data; @@ -18,7 +20,7 @@ let stampDialogOpen = $state(false); onMount(async () => { - let letterEvent = await $ndk.fetchEvent(id); + const letterEvent = await $ndk.fetchEvent(id); if (!letterEvent) { loading = false; error = 'Error fetching letter'; @@ -28,12 +30,15 @@ if (!(letter instanceof Letter)) { error = 'Message is not a letter'; loading = false; + return; } + renderedContent = DOMPurify.sanitize(await marked.parse(letter.content, { + async: true + })); loading = false; }); $inspect(letter); - function handleReply() { if (!letter) return; const params = { @@ -49,6 +54,8 @@ const url = `/compose?${queryString}`; goto(url); } + + let renderedContent = $state('loading...'); {#if loading} @@ -117,7 +124,7 @@ -
{letter.content}
+
{@html renderedContent}
{/if}