Remove bookmarks

This commit is contained in:
2026-01-16 11:50:49 +07:00
parent 5f6a13386b
commit 12253a41b9
3 changed files with 75 additions and 41 deletions

View File

@@ -82,8 +82,6 @@ export default class MapComponent extends Component {
async loadBookmarks() { async loadBookmarks() {
try { 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(); const places = await this.storage.places.listAll();
this.bookmarkSource.clear(); this.bookmarkSource.clear();
@@ -108,6 +106,18 @@ export default class MapComponent extends Component {
} }
handleMapClick = async (event) => { 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 coords = toLonLat(event.coordinate);
const [lon, lat] = coords; const [lon, lat] = coords;

View File

@@ -37,38 +37,67 @@ export default class PlacesSidebar extends Component {
} }
@action @action
async savePlace(poi) { async toggleSave(place) {
if (!poi) return; if (!place) return;
// Map Overpass POI to our Place schema if (place.createdAt) {
const placeData = { // It's a saved bookmark -> Delete it
title: poi.tags.name || poi.tags['name:en'] || 'Untitled Place', if (confirm(`Delete "${place.title}"?`)) {
lat: poi.lat, try {
lon: poi.lon, // We need geohash to delete.
tags: [], // Existing bookmarks have it.
url: poi.tags.website, // If for some reason it's missing (shouldn't happen for saved items), we can't delete easily.
osmId: String(poi.id), if (place.id && place.geohash) {
// We rely on the module to generate ID and 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 { try {
await this.storage.places.store(placeData); const savedPlace = await this.storage.places.store(placeData);
console.log('Place saved:', placeData.title); console.log('Place saved:', placeData.title);
alert('Place saved!'); // Quick feedback for now
// Update the selected place in the UI to be the saved bookmark
// Notify the map component to refresh bookmarks if possible. // (so the button turns to "Saved")
// Since we don't have a direct callback here yet, we might rely on // We can update the local tracked property if we are viewing a single item
// RemoteStorage events or just simple refresh if the map listens. // or let the parent update.
if (this.args.onBookmarkSaved) { // Ideally, we switch `this.selectedPlace` to the `savedPlace` returned by the store.
this.args.onBookmarkSaved(); 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}} {{/if}}
<div class="actions"> <div class="actions">
{{!-- Only show save button if it doesn't look like a saved bookmark (bookmarks have 'createdAt') --}} <button type="button" class={{if this.selectedPlace.createdAt "btn-secondary" "btn-primary"}} {{on "click" (fn this.toggleSave this.selectedPlace)}}>
{{#unless this.selectedPlace.createdAt}} {{if this.selectedPlace.createdAt "Saved ✓" "Save"}}
<button type="button" class="btn-primary" {{on "click" (fn this.savePlace this.selectedPlace)}}> </button>
Save Bookmark
</button>
{{else}}
<button type="button" class="btn-secondary" disabled>
Saved ✓
</button>
{{/unless}}
</div> </div>
<div class="meta-info"> <div class="meta-info">

View File

@@ -39,6 +39,8 @@ export default class ApplicationComponent extends Component {
<Map <Map
@onPlacesFound={{this.showPlaces}} @onPlacesFound={{this.showPlaces}}
@isSidebarOpen={{this.isSidebarOpen}}
@onOutsideClick={{this.closeSidebar}}
/> />
{{#if this.isSidebarOpen}} {{#if this.isSidebarOpen}}