diff --git a/app/components/modal.gjs b/app/components/modal.gjs new file mode 100644 index 0000000..e9751e3 --- /dev/null +++ b/app/components/modal.gjs @@ -0,0 +1,43 @@ +import Component from '@glimmer/component'; +import { action } from '@ember/object'; +import { on } from '@ember/modifier'; +import Icon from './icon'; + +export default class Modal extends Component { + @action + stopProp(e) { + e.stopPropagation(); + } + + @action + close() { + if (this.args.onClose) { + this.args.onClose(); + } + } + + +} diff --git a/app/components/place-details.gjs b/app/components/place-details.gjs index 0377e2c..a665da0 100644 --- a/app/components/place-details.gjs +++ b/app/components/place-details.gjs @@ -9,6 +9,8 @@ import { getSocialInfo } from '../utils/social-links'; import Icon from '../components/icon'; import PlaceEditForm from './place-edit-form'; import PlaceListsManager from './place-lists-manager'; +import PlacePhotoUpload from './place-photo-upload'; +import Modal from './modal'; import { tracked } from '@glimmer/tracking'; import { action } from '@ember/object'; @@ -17,6 +19,20 @@ export default class PlaceDetails extends Component { @service storage; @tracked isEditing = false; @tracked showLists = false; + @tracked isPhotoUploadModalOpen = false; + + @action + openPhotoUploadModal(e) { + if (e) { + e.preventDefault(); + } + this.isPhotoUploadModalOpen = true; + } + + @action + closePhotoUploadModal() { + this.isPhotoUploadModalOpen = false; + } get isSaved() { return this.storage.isPlaceSaved(this.place.id || this.place.osmId); @@ -499,7 +515,24 @@ export default class PlaceDetails extends Component {

{{/if}} + {{#if this.osmUrl}} +

+ + + + Add a photo + + +

+ {{/if}} + + + {{#if this.isPhotoUploadModalOpen}} + + + + {{/if}} } diff --git a/app/components/place-photo-upload.gjs b/app/components/place-photo-upload.gjs index 86d0343..d65337a 100644 --- a/app/components/place-photo-upload.gjs +++ b/app/components/place-photo-upload.gjs @@ -4,17 +4,24 @@ import { action } from '@ember/object'; import { inject as service } from '@ember/service'; import { on } from '@ember/modifier'; import { EventFactory } from 'applesauce-core'; +import Geohash from 'latlon-geohash'; export default class PlacePhotoUpload extends Component { @service nostrAuth; @service nostrRelay; @tracked photoUrl = ''; - @tracked osmId = ''; - @tracked geohash = ''; @tracked status = ''; @tracked error = ''; + get place() { + return this.args.place || {}; + } + + get title() { + return this.place.title || 'this place'; + } + @action async login() { try { @@ -50,8 +57,16 @@ export default class PlacePhotoUpload extends Component { return; } - if (!this.photoUrl || !this.osmId || !this.geohash) { - this.error = 'Please provide an OSM ID, Geohash, and upload a photo.'; + if (!this.photoUrl) { + this.error = 'Please upload a photo.'; + return; + } + + const { osmId, lat, lon } = this.place; + const osmType = this.place.osmType || 'node'; + + if (!osmId) { + this.error = 'This place does not have a valid OSM ID.'; return; } @@ -61,21 +76,28 @@ export default class PlacePhotoUpload extends Component { try { const factory = new EventFactory({ signer: this.nostrAuth.signer }); + const tags = [['i', `osm:${osmType}:${osmId}`]]; + + if (lat && lon) { + tags.push(['g', Geohash.encode(lat, lon, 4)]); + tags.push(['g', Geohash.encode(lat, lon, 6)]); + tags.push(['g', Geohash.encode(lat, lon, 7)]); + tags.push(['g', Geohash.encode(lat, lon, 9)]); + } + + tags.push([ + 'imeta', + `url ${this.photoUrl}`, + 'm image/jpeg', + 'dim 600x400', + 'alt A photo of a place', + ]); + // NIP-XX draft Place Photo event const template = { kind: 360, content: '', - tags: [ - ['i', `osm:node:${this.osmId}`], - ['g', this.geohash], - [ - 'imeta', - `url ${this.photoUrl}`, - 'm image/jpeg', - 'dim 600x400', - 'alt A photo of a place', - ], - ], + tags, }; // Ensure created_at is present before signing @@ -89,24 +111,15 @@ export default class PlacePhotoUpload extends Component { this.status = 'Published successfully!'; // Reset form this.photoUrl = ''; - this.osmId = ''; - this.geohash = ''; } catch (e) { this.error = 'Failed to publish: ' + e.message; this.status = ''; } } - @action updateOsmId(e) { - this.osmId = e.target.value; - } - @action updateGeohash(e) { - this.geohash = e.target.value; - } -