89 lines
2.5 KiB
Plaintext
89 lines
2.5 KiB
Plaintext
import Component from '@glimmer/component';
|
|
import PlacesSidebar from '#components/places-sidebar';
|
|
import { service } from '@ember/service';
|
|
import { action } from '@ember/object';
|
|
import { tracked } from '@glimmer/tracking';
|
|
|
|
export default class PlaceTemplate extends Component {
|
|
@service router;
|
|
@service storage;
|
|
|
|
@tracked localPlace = null;
|
|
|
|
constructor() {
|
|
super(...arguments);
|
|
this.localPlace = this.args.model;
|
|
}
|
|
|
|
// Update local place if model changes (e.g. navigation)
|
|
// We can use a getter or an effect, but in GJS a getter is easiest if we don't need manual overrides often.
|
|
// But we DO need to override it when saving.
|
|
|
|
// Actually, we can just use a derived state that prefers the local override?
|
|
// Let's use a modifier or just sync it.
|
|
|
|
get place() {
|
|
// 1. Resolve the ID from the model (OSM ID or internal ID)
|
|
const model = this.args.model;
|
|
const id = model.osmId || model.id;
|
|
|
|
// 2. Check the storage service for a LIVE version of this bookmark
|
|
// This is the most critical fix: Storage is the source of truth.
|
|
// Since `this.storage.savedPlaces` is @tracked, this getter will re-compute
|
|
// whenever a bookmark is added or removed.
|
|
const saved = this.storage.findPlaceById(id);
|
|
if (saved) {
|
|
return saved;
|
|
}
|
|
|
|
// 3. If not saved, check our local "optimistic" state (from handleUpdate)
|
|
// This handles the "unsaved" state immediately after deletion before any other sync
|
|
if (
|
|
this.localPlace &&
|
|
(this.localPlace.osmId === id || this.localPlace.id === id)
|
|
) {
|
|
return this.localPlace;
|
|
}
|
|
|
|
// 4. Fallback to the route model (which might be the stale "saved" object from when the route loaded)
|
|
// If the model *has* a createdAt but we didn't find it in step 2 (storage),
|
|
// it means it was deleted. We must return a sanitized version.
|
|
if (model.createdAt) {
|
|
return {
|
|
...model,
|
|
id: undefined,
|
|
createdAt: undefined,
|
|
geohash: undefined,
|
|
};
|
|
}
|
|
|
|
return model;
|
|
}
|
|
|
|
@action
|
|
handleUpdate(newPlace) {
|
|
console.log('Updating local place state:', newPlace);
|
|
this.localPlace = newPlace;
|
|
this.storage.notifyChange();
|
|
}
|
|
|
|
@action
|
|
refreshMap() {
|
|
this.storage.notifyChange();
|
|
}
|
|
|
|
@action
|
|
close() {
|
|
this.router.transitionTo('index');
|
|
}
|
|
|
|
<template>
|
|
<PlacesSidebar
|
|
@selectedPlace={{this.place}}
|
|
@onClose={{this.close}}
|
|
@onBookmarkChange={{this.refreshMap}}
|
|
@onUpdate={{this.handleUpdate}}
|
|
/>
|
|
</template>
|
|
}
|