109 lines
2.7 KiB
JavaScript
109 lines
2.7 KiB
JavaScript
import Controller from '@ember/controller';
|
|
import { service } from '@ember/service';
|
|
import { action } from '@ember/object';
|
|
import { tracked } from '@glimmer/tracking';
|
|
import { task } from 'ember-concurrency';
|
|
|
|
export default class ListsListController extends Controller {
|
|
@service router;
|
|
@service mapUi;
|
|
@service storage;
|
|
|
|
@tracked model;
|
|
@tracked loadedPlaces = [];
|
|
|
|
get listId() {
|
|
return this.model?.list_id;
|
|
}
|
|
|
|
loadPlacesTask = task({ restartable: true }, async (listId) => {
|
|
this.loadedPlaces = []; // Clear previous elements immediately to show fresh loader
|
|
try {
|
|
this.loadedPlaces = await this.storage.getPlacesInList(listId);
|
|
} catch (e) {
|
|
console.error('Failed to load places in list', listId, e);
|
|
this.loadedPlaces = [];
|
|
}
|
|
});
|
|
|
|
get scrollTop() {
|
|
return this.mapUi.getScrollPosition(`list-${this.listId}`);
|
|
}
|
|
|
|
get listColor() {
|
|
const list = this.storage.lists.find((l) => l.id === this.listId);
|
|
if (list && list.color) {
|
|
return list.color;
|
|
}
|
|
return getComputedStyle(document.documentElement)
|
|
.getPropertyValue('--default-list-color')
|
|
.trim();
|
|
}
|
|
|
|
get listTitle() {
|
|
const list = this.storage.lists.find((l) => l.id === this.listId);
|
|
return list ? list.title : 'Collections';
|
|
}
|
|
|
|
get places() {
|
|
const currentList = this.storage.lists.find((l) => l.id === this.listId);
|
|
const placeRefsIds = new Set(
|
|
currentList?.placeRefs?.map((ref) => ref.id) || []
|
|
);
|
|
|
|
// Filter live tracked savedPlaces that are in this list
|
|
const livePlaces = this.storage.savedPlaces.filter((p) =>
|
|
placeRefsIds.has(p.id)
|
|
);
|
|
|
|
const merged = [];
|
|
const seen = new Set();
|
|
|
|
// Process live state first to reflect deletions/edits immediately
|
|
livePlaces.forEach((p) => {
|
|
merged.push(p);
|
|
seen.add(p.id);
|
|
});
|
|
|
|
// Supplement with any background-fetched places that are still valid but not in live state yet
|
|
this.loadedPlaces.forEach((p) => {
|
|
if (placeRefsIds.has(p.id) && !seen.has(p.id)) {
|
|
merged.push(p);
|
|
seen.add(p.id);
|
|
}
|
|
});
|
|
|
|
return merged;
|
|
}
|
|
|
|
@action
|
|
selectPlace(place) {
|
|
if (place) {
|
|
const sidebarContent = document.querySelector('.sidebar-content');
|
|
if (sidebarContent) {
|
|
this.mapUi.saveScrollPosition(
|
|
`list-${this.listId}`,
|
|
sidebarContent.scrollTop
|
|
);
|
|
}
|
|
this.mapUi.returnToRoute = {
|
|
name: 'lists.list',
|
|
model: this.listId,
|
|
};
|
|
this.mapUi.showSidebar();
|
|
this.mapUi.preventNextZoom = true;
|
|
this.router.transitionTo('place', place);
|
|
}
|
|
}
|
|
|
|
@action
|
|
close() {
|
|
this.router.transitionTo('index');
|
|
}
|
|
|
|
@action
|
|
backToLists() {
|
|
this.router.transitionTo('lists.index');
|
|
}
|
|
}
|