From dc5bac67aacabbfa7a72bf6c303446c78c037ae5 Mon Sep 17 00:00:00 2001 From: Jon Staab Date: Tue, 3 Feb 2026 14:18:58 -0800 Subject: [PATCH] Add image uploads to classifieds --- src/app/components/ClassifiedCreate.svelte | 93 +++++---- src/app/components/ClassifiedItem.svelte | 9 +- src/app/components/Content.svelte | 7 +- src/app/components/CurrencyInput.svelte | 2 +- src/app/components/EventReply.svelte | 13 +- src/app/components/MenuSettings.svelte | 196 +++++++++--------- .../components/NoteContentClassified.svelte | 9 +- src/app/core/commands.ts | 20 +- src/lib/components/ImagesInput.svelte | 125 +++++++++++ src/lib/components/Modal.svelte | 2 +- src/lib/components/ModalBody.svelte | 3 +- .../spaces/[relay]/calendar/[id]/+page.svelte | 6 +- .../[relay]/classifieds/[id]/+page.svelte | 6 +- .../spaces/[relay]/goals/[id]/+page.svelte | 6 +- .../spaces/[relay]/threads/[id]/+page.svelte | 6 +- 15 files changed, 324 insertions(+), 179 deletions(-) create mode 100644 src/lib/components/ImagesInput.svelte diff --git a/src/app/components/ClassifiedCreate.svelte b/src/app/components/ClassifiedCreate.svelte index bf31c316..ee5d91b2 100644 --- a/src/app/components/ClassifiedCreate.svelte +++ b/src/app/components/ClassifiedCreate.svelte @@ -1,25 +1,25 @@ @@ -129,29 +154,21 @@ {#snippet label()} -

Images

+

Images (optional)

{/snippet} {#snippet input()} - todo: attach multiple images + {/snippet}
- - - +
diff --git a/src/app/components/ClassifiedItem.svelte b/src/app/components/ClassifiedItem.svelte index 60ddddbb..75f9afcb 100644 --- a/src/app/components/ClassifiedItem.svelte +++ b/src/app/components/ClassifiedItem.svelte @@ -1,8 +1,9 @@ {/if} +
+ {#each images as image (image)} + + {/each} +
Posted by diff --git a/src/app/components/Content.svelte b/src/app/components/Content.svelte index 31ff39f9..963177a6 100644 --- a/src/app/components/Content.svelte +++ b/src/app/components/Content.svelte @@ -186,7 +186,12 @@ {/if} {:else if isEllipsis(parsed) && expandInline} {@html renderAsHtml(parsed)} - + {:else} {@html renderAsHtml(parsed)} {/if} diff --git a/src/app/components/CurrencyInput.svelte b/src/app/components/CurrencyInput.svelte index 1f2c0949..455d0695 100644 --- a/src/app/components/CurrencyInput.svelte +++ b/src/app/components/CurrencyInput.svelte @@ -3,7 +3,7 @@ import {writable} from "svelte/store" import type {Writable} from "svelte/store" import type {Instance} from "tippy.js" - import {preventDefault} from '@lib/html' + import {preventDefault} from "@lib/html" import {createSearch} from "@welshman/app" import {currencyOptions, displayCurrency} from "@lib/currency" import Suggestions from "@lib/components/Suggestions.svelte" diff --git a/src/app/components/EventReply.svelte b/src/app/components/EventReply.svelte index 7b74b2d0..20a9826a 100644 --- a/src/app/components/EventReply.svelte +++ b/src/app/components/EventReply.svelte @@ -6,7 +6,6 @@ import Paperclip from "@assets/icons/paperclip-2.svg?dataurl" import Icon from "@lib/components/Icon.svelte" import Button from "@lib/components/Button.svelte" - import ModalFooter from "@lib/components/ModalFooter.svelte" import EditorContent from "@app/editor/EditorContent.svelte" import {publishComment, canEnforceNip70} from "@app/core/commands" import {PROTECTED} from "@app/core/state" @@ -65,12 +64,8 @@
-
-
+ +
@@ -86,9 +81,9 @@ {/if}
- +
- +
diff --git a/src/app/components/MenuSettings.svelte b/src/app/components/MenuSettings.svelte index e0518953..a9d48102 100644 --- a/src/app/components/MenuSettings.svelte +++ b/src/app/components/MenuSettings.svelte @@ -10,6 +10,8 @@ import Icon from "@lib/components/Icon.svelte" import Link from "@lib/components/Link.svelte" import Button from "@lib/components/Button.svelte" + import Modal from "@lib/components/Modal.svelte" + import ModalBody from "@lib/components/ModalBody.svelte" import CardButton from "@lib/components/CardButton.svelte" import LogOut from "@app/components/LogOut.svelte" import {PLATFORM_NAME} from "@app/core/state" @@ -21,99 +23,101 @@ const toggleTheme = () => theme.set($theme === "dark" ? "light" : "dark") - + + + + + {#snippet icon()} +
+ {/snippet} + {#snippet title()} +
Profile
+ {/snippet} + {#snippet info()} +
Customize your user profile
+ {/snippet} +
+ + + + {#snippet icon()} +
+ {/snippet} + {#snippet title()} +
Alerts
+ {/snippet} + {#snippet info()} +
Set up email digests and push notifications
+ {/snippet} +
+ + + + {#snippet icon()} +
+ {/snippet} + {#snippet title()} +
Wallet
+ {/snippet} + {#snippet info()} +
Connect a bitcoin wallet for sending social tips
+ {/snippet} +
+ + + + {#snippet icon()} +
+ {/snippet} + {#snippet title()} +
Relays
+ {/snippet} + {#snippet info()} +
Control how {PLATFORM_NAME} talks to the network
+ {/snippet} +
+ + + + {#snippet icon()} +
+ {/snippet} + {#snippet title()} +
Settings
+ {/snippet} + {#snippet info()} +
Get into the details about how {PLATFORM_NAME} works
+ {/snippet} +
+ + + + + {#snippet icon()} +
+ {/snippet} + {#snippet title()} +
About
+ {/snippet} + {#snippet info()} +
Learn about {PLATFORM_NAME} and support the developer
+ {/snippet} +
+ + +
+
diff --git a/src/app/components/NoteContentClassified.svelte b/src/app/components/NoteContentClassified.svelte index ca6ec43b..051d856d 100644 --- a/src/app/components/NoteContentClassified.svelte +++ b/src/app/components/NoteContentClassified.svelte @@ -1,11 +1,13 @@
@@ -15,4 +17,9 @@ {#if props.event.content} {/if} +
+ {#each images as image (image)} + + {/each} +
diff --git a/src/app/core/commands.ts b/src/app/core/commands.ts index 1abc77e8..cf6e9249 100644 --- a/src/app/core/commands.ts +++ b/src/app/core/commands.ts @@ -43,6 +43,7 @@ import { toNostrURI, RelayMode, getTagValues, + uploadBlob, canUploadBlob, encryptFile, makeBlossomAuthEvent, @@ -50,7 +51,6 @@ import { editProfile, createProfile, uniqTags, - makeHttpAuthHeader, } from "@welshman/util" import {Pool, AuthStatus, SocketStatus} from "@welshman/net" import {Router} from "@welshman/router" @@ -509,8 +509,6 @@ export const uploadFile = async (file: File, options: UploadFileOptions = {}) => try { const {name, type} = file - console.log("======== 1", name, type, options.encrypt) - if (!type.match("image/(webp|gif|svg)")) { file = await compressFile(file, options) } @@ -532,25 +530,14 @@ export const uploadFile = async (file: File, options: UploadFileOptions = {}) => } const ext = "." + type.split("/")[1] - console.log("======== 2", ext) const server = await getBlossomServer(options) - console.log("======== 3", server) + console.log("====", server) const hashes = [await sha256(await file.arrayBuffer())] const $signer = signer.get() || Nip01Signer.ephemeral() const authTemplate = makeBlossomAuthEvent({action: "upload", server, hashes}) const authEvent = await $signer.sign(authTemplate) - console.log("======== 4", authEvent.id) - // const res = await uploadBlob(server, file, {authEvent}) - - const res = await fetch(`${new URL(server).origin}/upload`, { - method: "PUT", - headers: {Authorization: makeHttpAuthHeader(authEvent)}, - body: file instanceof Blob ? file : new Blob([file]), - }) - - console.log("======== 5", res.status) + const res = await uploadBlob(server, file, {authEvent}) const text = await res.text() - console.log("======== 6", text) let {uploaded, url, ...task} = parseJson(text) || {} @@ -569,7 +556,6 @@ export const uploadFile = async (file: File, options: UploadFileOptions = {}) => return {result} } catch (e: any) { - console.log("========= error", String(e)) console.error("Error caught when uploading file:", e) return {error: e.toString()} diff --git a/src/lib/components/ImagesInput.svelte b/src/lib/components/ImagesInput.svelte new file mode 100644 index 00000000..aaa0184d --- /dev/null +++ b/src/lib/components/ImagesInput.svelte @@ -0,0 +1,125 @@ + + +
+
+ {#each value as item, index (index)} +
handleDragStart(e, index)} + ondragover={e => handleDragOver(e, index)} + ondragend={handleDragEnd}> + Upload preview + +
+ {/each} + +
+ +
diff --git a/src/lib/components/Modal.svelte b/src/lib/components/Modal.svelte index 9721a05f..e755aea1 100644 --- a/src/lib/components/Modal.svelte +++ b/src/lib/components/Modal.svelte @@ -12,6 +12,6 @@ const {children, tag = "div", ...props}: Props = $props() - + {@render children?.()} diff --git a/src/lib/components/ModalBody.svelte b/src/lib/components/ModalBody.svelte index b66af5d1..85c67ea8 100644 --- a/src/lib/components/ModalBody.svelte +++ b/src/lib/components/ModalBody.svelte @@ -10,7 +10,6 @@ const {children, ...props}: Props = $props() -
+
{@render children?.()}
diff --git a/src/routes/spaces/[relay]/calendar/[id]/+page.svelte b/src/routes/spaces/[relay]/calendar/[id]/+page.svelte index 151c0905..7151a23b 100644 --- a/src/routes/spaces/[relay]/calendar/[id]/+page.svelte +++ b/src/routes/spaces/[relay]/calendar/[id]/+page.svelte @@ -15,7 +15,7 @@ import PageContent from "@lib/components/PageContent.svelte" import Spinner from "@lib/components/Spinner.svelte" import Button from "@lib/components/Button.svelte" - import Content from "@app/components/Content.svelte" + import NoteContent from "@app/components/NoteContent.svelte" import NoteCard from "@app/components/NoteCard.svelte" import SpaceMenuButton from "@app/components/SpaceMenuButton.svelte" import CalendarEventActions from "@app/components/CalendarEventActions.svelte" @@ -89,7 +89,7 @@
- +
@@ -107,7 +107,7 @@ {#each sortBy(e => e.created_at, $replies).slice(0, showAll ? undefined : 4) as reply (reply.id)}
- +
diff --git a/src/routes/spaces/[relay]/classifieds/[id]/+page.svelte b/src/routes/spaces/[relay]/classifieds/[id]/+page.svelte index 97caa088..99c4a13c 100644 --- a/src/routes/spaces/[relay]/classifieds/[id]/+page.svelte +++ b/src/routes/spaces/[relay]/classifieds/[id]/+page.svelte @@ -15,7 +15,7 @@ import PageContent from "@lib/components/PageContent.svelte" import Spinner from "@lib/components/Spinner.svelte" import Button from "@lib/components/Button.svelte" - import Content from "@app/components/Content.svelte" + import NoteContent from "@app/components/NoteContent.svelte" import NoteCard from "@app/components/NoteCard.svelte" import SpaceMenuButton from "@app/components/SpaceMenuButton.svelte" import ClassifiedActions from "@app/components/ClassifiedActions.svelte" @@ -83,7 +83,7 @@
- +
@@ -98,7 +98,7 @@ {#each $replies.slice(0, showAll ? undefined : 4) as reply (reply.id)}
- +
diff --git a/src/routes/spaces/[relay]/goals/[id]/+page.svelte b/src/routes/spaces/[relay]/goals/[id]/+page.svelte index 12167d2b..bf2a7f9c 100644 --- a/src/routes/spaces/[relay]/goals/[id]/+page.svelte +++ b/src/routes/spaces/[relay]/goals/[id]/+page.svelte @@ -15,7 +15,7 @@ import PageContent from "@lib/components/PageContent.svelte" import Spinner from "@lib/components/Spinner.svelte" import Button from "@lib/components/Button.svelte" - import Content from "@app/components/Content.svelte" + import NoteContent from "@app/components/NoteContent.svelte" import NoteCard from "@app/components/NoteCard.svelte" import SpaceMenuButton from "@app/components/SpaceMenuButton.svelte" import GoalSummary from "@app/components/GoalSummary.svelte" @@ -85,7 +85,7 @@
- +
@@ -101,7 +101,7 @@ {#each $replies.slice(0, showAll ? undefined : 4) as reply (reply.id)}
- +
diff --git a/src/routes/spaces/[relay]/threads/[id]/+page.svelte b/src/routes/spaces/[relay]/threads/[id]/+page.svelte index b6ba0d24..350651d8 100644 --- a/src/routes/spaces/[relay]/threads/[id]/+page.svelte +++ b/src/routes/spaces/[relay]/threads/[id]/+page.svelte @@ -15,7 +15,7 @@ import PageContent from "@lib/components/PageContent.svelte" import Spinner from "@lib/components/Spinner.svelte" import Button from "@lib/components/Button.svelte" - import Content from "@app/components/Content.svelte" + import NoteContent from "@app/components/NoteContent.svelte" import NoteCard from "@app/components/NoteCard.svelte" import SpaceMenuButton from "@app/components/SpaceMenuButton.svelte" import ThreadActions from "@app/components/ThreadActions.svelte" @@ -83,7 +83,7 @@
- +
@@ -98,7 +98,7 @@ {#each $replies.slice(0, showAll ? undefined : 4) as reply (reply.id)}
- +