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;
- }
-
-
Add Place Photo
+
Add Photo for {{this.title}}
{{#if this.error}}
@@ -127,30 +140,6 @@ export default class PlacePhotoUpload extends Component {