From 9807a2b822bbfd875ed96752b463ce900edf72a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Fri, 7 Aug 2026 07:03:31 -0600 Subject: [PATCH] Add alt text to photo uploads - Form field for optionally adding a description - Publish as `imeta` `alt` - Render as `` alt when set Fixes a placeholder being published instead. Also strips the current placeholder if set as alt text (for existing uploads). --- app/components/photo-carousel.gjs | 8 +-- app/components/place-photo-upload.gjs | 38 +++++++++--- app/styles/app.css | 14 ++--- app/utils/nostr.js | 6 ++ pnpm-lock.yaml | 17 ++--- .../components/place-photo-upload-test.gjs | 23 +++++++ tests/unit/utils/nostr-test.js | 62 +++++++++++++++++++ 7 files changed, 140 insertions(+), 28 deletions(-) diff --git a/app/components/photo-carousel.gjs b/app/components/photo-carousel.gjs index d901dfb..1d9ea96 100644 --- a/app/components/photo-carousel.gjs +++ b/app/components/photo-carousel.gjs @@ -237,7 +237,7 @@ export default class PhotoCarousel extends Component { data-src={{photo.url}} class="place-header-photo {{if photo.isLandscape 'landscape' 'portrait'}}" - alt={{@name}} + alt={{photo.alt}} {{fadeInImage photo.url}} /> {{else if this.isGalleryThumbnails}} @@ -245,7 +245,7 @@ export default class PhotoCarousel extends Component { data-src={{if photo.thumbUrl photo.thumbUrl photo.url}} class="place-header-photo {{if photo.isLandscape 'landscape' 'portrait'}}" - alt={{@name}} + alt={{photo.alt}} {{fadeInImage (if photo.thumbUrl photo.thumbUrl photo.url)}} /> {{else}} @@ -260,7 +260,7 @@ export default class PhotoCarousel extends Component { {{@name}} @@ -269,7 +269,7 @@ export default class PhotoCarousel extends Component { {{@name}} {{/if}} diff --git a/app/components/place-photo-upload.gjs b/app/components/place-photo-upload.gjs index e0434aa..e204479 100644 --- a/app/components/place-photo-upload.gjs +++ b/app/components/place-photo-upload.gjs @@ -27,6 +27,7 @@ export default class PlacePhotoUpload extends Component { @tracked isPublishing = false; @tracked isDragging = false; @tracked selectedTags = []; + @tracked altText = ''; get place() { return this.args.place || {}; @@ -103,6 +104,7 @@ export default class PlacePhotoUpload extends Component { this.file = null; this.uploadedPhoto = null; this.selectedTags = []; + this.altText = ''; if (this.args.onUploadStateChange) { this.args.onUploadStateChange(false); } @@ -118,6 +120,11 @@ export default class PlacePhotoUpload extends Component { this.selectedTags = [tag]; } + @action + updateAltText(event) { + this.altText = event.target.value; + } + deletePhotoTask = task(async (photoData) => { try { if (photoData.hash) { @@ -177,7 +184,10 @@ export default class PlacePhotoUpload extends Component { imeta.push(`dim ${photo.dim}`); } - imeta.push('alt A photo of a place'); + const alt = this.altText.trim(); + if (alt) { + imeta.push(`alt ${alt}`); + } if (photo.fallbackUrls && photo.fallbackUrls.length > 0) { for (const fallbackUrl of photo.fallbackUrls) { @@ -209,6 +219,7 @@ export default class PlacePhotoUpload extends Component { // Clear out the file so user can upload more or be done this.file = null; this.uploadedPhoto = null; + this.altText = ''; if (this.args.onUploadStateChange) { this.args.onUploadStateChange(false); @@ -235,13 +246,11 @@ export default class PlacePhotoUpload extends Component { {{/if}} {{#if this.file}} -
- -
+ {{#if this.suggestedTags.length}}
@@ -263,6 +272,19 @@ export default class PlacePhotoUpload extends Component {
{{/if}} +
+ + +
+