Refactor to use routes, make POIs linkable
This commit is contained in:
@@ -5,14 +5,19 @@ import PlacesSidebar from '#components/places-sidebar';
|
||||
import { service } from '@ember/service';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import { action } from '@ember/object';
|
||||
import { eq } from 'ember-truth-helpers';
|
||||
import { and } from 'ember-truth-helpers';
|
||||
|
||||
export default class ApplicationComponent extends Component {
|
||||
@service storage;
|
||||
@service router;
|
||||
|
||||
@tracked nearbyPlaces = null;
|
||||
@tracked selectedPlace = null;
|
||||
@tracked isSidebarOpen = false;
|
||||
@tracked bookmarksVersion = 0;
|
||||
// @tracked bookmarksVersion = 0; // Moved to storage service
|
||||
|
||||
get isSidebarOpen() {
|
||||
return !!this.nearbyPlaces || this.router.currentRouteName === 'place';
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
@@ -23,45 +28,56 @@ export default class ApplicationComponent extends Component {
|
||||
|
||||
@action
|
||||
showPlaces(places, selectedPlace = null) {
|
||||
this.nearbyPlaces = places;
|
||||
this.selectedPlace = selectedPlace;
|
||||
this.isSidebarOpen = true;
|
||||
// If we have a specific place, transition to the route
|
||||
if (selectedPlace) {
|
||||
// Use ID if available, or osmId
|
||||
const id = selectedPlace.id || selectedPlace.osmId;
|
||||
if (id) {
|
||||
this.router.transitionTo('place', id);
|
||||
}
|
||||
this.nearbyPlaces = null; // Clear list when selecting specific
|
||||
} else if (places && places.length > 0) {
|
||||
// Show list case
|
||||
this.nearbyPlaces = places;
|
||||
this.router.transitionTo('index');
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
selectPlace(place) {
|
||||
this.selectedPlace = place;
|
||||
selectFromList(place) {
|
||||
if (place) {
|
||||
const id = place.id || place.osmId;
|
||||
if (id) {
|
||||
this.router.transitionTo('place', id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
closeSidebar() {
|
||||
this.isSidebarOpen = false;
|
||||
this.nearbyPlaces = null;
|
||||
this.selectedPlace = null;
|
||||
this.router.transitionTo('index');
|
||||
}
|
||||
|
||||
@action
|
||||
refreshBookmarks() {
|
||||
this.bookmarksVersion++;
|
||||
this.storage.notifyChange();
|
||||
}
|
||||
|
||||
<template>
|
||||
{{pageTitle "M/\RCO"}}
|
||||
|
||||
<Map
|
||||
@onPlacesFound={{this.showPlaces}}
|
||||
<Map
|
||||
@onPlacesFound={{this.showPlaces}}
|
||||
@isSidebarOpen={{this.isSidebarOpen}}
|
||||
@onOutsideClick={{this.closeSidebar}}
|
||||
@bookmarksVersion={{this.bookmarksVersion}}
|
||||
/>
|
||||
|
||||
{{#if this.isSidebarOpen}}
|
||||
<PlacesSidebar
|
||||
@places={{this.nearbyPlaces}}
|
||||
@selectedPlace={{this.selectedPlace}}
|
||||
@onSelect={{this.selectPlace}}
|
||||
@onClose={{this.closeSidebar}}
|
||||
@onBookmarkChange={{this.refreshBookmarks}}
|
||||
{{#if (and (eq this.router.currentRouteName "index") this.nearbyPlaces)}}
|
||||
<PlacesSidebar
|
||||
@places={{this.nearbyPlaces}}
|
||||
@onSelect={{this.selectFromList}}
|
||||
@onClose={{this.closeSidebar}}
|
||||
/>
|
||||
{{/if}}
|
||||
|
||||
|
||||
68
app/templates/place.gjs
Normal file
68
app/templates/place.gjs
Normal file
@@ -0,0 +1,68 @@
|
||||
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() {
|
||||
// If we have a manually updated place (from save), use it.
|
||||
// Otherwise use the route model.
|
||||
// We need to ensure we reset `localPlace` when navigating to a NEW place.
|
||||
// Comparing IDs is a safe bet.
|
||||
|
||||
const model = this.args.model;
|
||||
if (
|
||||
this.localPlace &&
|
||||
(this.localPlace.id === model.id || this.localPlace.osmId === model.osmId)
|
||||
) {
|
||||
// If the local place is "richer" (has createdAt), prefer it.
|
||||
if (this.localPlace.createdAt && !model.createdAt) return this.localPlace;
|
||||
// If we deleted it (local has no createdAt, model might?) - wait, if we delete, we close sidebar.
|
||||
}
|
||||
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>
|
||||
}
|
||||
Reference in New Issue
Block a user