diff --git a/app/components/map.gjs b/app/components/map.gjs index 1079d6d..2b743dd 100644 --- a/app/components/map.gjs +++ b/app/components/map.gjs @@ -82,8 +82,6 @@ export default class MapComponent extends Component { async loadBookmarks() { try { - // Wait a moment for RemoteStorage to be ready (if needed), - // or just try fetching. The 'connected' event is better but for now: const places = await this.storage.places.listAll(); this.bookmarkSource.clear(); @@ -108,6 +106,18 @@ export default class MapComponent extends Component { } handleMapClick = async (event) => { + // 0. Handle closing sidebar if open and clicked on empty map area + if (this.args.isSidebarOpen) { + // We can just trigger the outside click and return. + // However, if the user clicked on a feature, maybe they want to switch selection? + // The requirement says "when clicking on the map while the sidebar is open, it should close the sidebar instead of executing the normal map click logic" + // This implies strict closing behavior. + if (this.args.onOutsideClick) { + this.args.onOutsideClick(); + } + return; + } + const coords = toLonLat(event.coordinate); const [lon, lat] = coords; diff --git a/app/components/places-sidebar.gjs b/app/components/places-sidebar.gjs index 1cda858..f25ff1a 100644 --- a/app/components/places-sidebar.gjs +++ b/app/components/places-sidebar.gjs @@ -37,38 +37,67 @@ export default class PlacesSidebar extends Component { } @action - async savePlace(poi) { - if (!poi) return; + async toggleSave(place) { + if (!place) return; - // Map Overpass POI to our Place schema - const placeData = { - title: poi.tags.name || poi.tags['name:en'] || 'Untitled Place', - lat: poi.lat, - lon: poi.lon, - tags: [], - url: poi.tags.website, - osmId: String(poi.id), - // We rely on the module to generate ID and Geohash - }; + if (place.createdAt) { + // It's a saved bookmark -> Delete it + if (confirm(`Delete "${place.title}"?`)) { + try { + // We need geohash to delete. + // Existing bookmarks have it. + // If for some reason it's missing (shouldn't happen for saved items), we can't delete easily. + if (place.id && place.geohash) { + await this.storage.places.remove(place.id, place.geohash); + console.log('Place deleted:', place.title); + + // Close sidebar after delete since the item is gone from "Saved" context + // Or we could revert to "Save" state if we had the original POI data, + // but usually we just close or show "Nearby". + if (this.args.onClose) { + this.args.onClose(); + } + } else { + alert('Cannot delete: Missing ID or Geohash'); + } + } catch (e) { + console.error('Failed to delete:', e); + alert('Failed to delete: ' + e.message); + } + } + } else { + // It's a fresh POI -> Save it + + // Map Overpass POI to our Place schema + const placeData = { + title: place.tags.name || place.tags['name:en'] || 'Untitled Place', + lat: place.lat, + lon: place.lon, + tags: [], + url: place.tags.website, + osmId: String(place.id), + // We rely on the module to generate ID and Geohash + }; - try { - await this.storage.places.store(placeData); - console.log('Place saved:', placeData.title); - alert('Place saved!'); // Quick feedback for now - - // Notify the map component to refresh bookmarks if possible. - // Since we don't have a direct callback here yet, we might rely on - // RemoteStorage events or just simple refresh if the map listens. - if (this.args.onBookmarkSaved) { - this.args.onBookmarkSaved(); + try { + const savedPlace = await this.storage.places.store(placeData); + console.log('Place saved:', placeData.title); + + // Update the selected place in the UI to be the saved bookmark + // (so the button turns to "Saved") + // We can update the local tracked property if we are viewing a single item + // or let the parent update. + // Ideally, we switch `this.selectedPlace` to the `savedPlace` returned by the store. + this.selectedPlace = savedPlace; + + // Notify parent if needed (map will auto-update via events) + if (this.args.onBookmarkSaved) { + this.args.onBookmarkSaved(); + } + } catch (error) { + console.error('Failed to save place:', error); + alert('Failed to save place: ' + error.message); } - - if (this.args.onClose) { - this.args.onClose(); - } - } catch (error) { - console.error('Failed to save place:', error); - alert('Failed to save place: ' + error.message); } } @@ -106,16 +135,9 @@ export default class PlacesSidebar extends Component { {{/if}}
- {{!-- Only show save button if it doesn't look like a saved bookmark (bookmarks have 'createdAt') --}} - {{#unless this.selectedPlace.createdAt}} - - {{else}} - - {{/unless}} +
diff --git a/app/templates/application.gjs b/app/templates/application.gjs index 9251c4b..1e05af7 100644 --- a/app/templates/application.gjs +++ b/app/templates/application.gjs @@ -39,6 +39,8 @@ export default class ApplicationComponent extends Component { {{#if this.isSidebarOpen}}