130 lines
3.8 KiB
JavaScript
130 lines
3.8 KiB
JavaScript
import * as MAP from "./map.js"
|
|
import { PlaceDatabase } from "./places.js";
|
|
import {FeatureElement} from "./components/feature.js"
|
|
import "./components/feature-short-header.js"
|
|
|
|
/** La carte */
|
|
|
|
/** La base de données de lieux @type {PlaceDatabase|null} */
|
|
let places = null
|
|
|
|
// CHARGEMENT
|
|
await Promise.all([
|
|
// Base de données des zones
|
|
PlaceDatabase.createDefault().then(db => places = db),
|
|
MAP.init()
|
|
]);
|
|
|
|
// Un petit point de debug
|
|
window.interhackPlaces = places;
|
|
|
|
await MAP.init_places(places)
|
|
|
|
// GESTION de la recherche
|
|
const search_form = document.getElementById("search-area")
|
|
search_form.elements["query"].addEventListener("change", () => search_form.requestSubmit())
|
|
search_form.elements["query"].addEventListener("input", () => search_form.requestSubmit())
|
|
|
|
window.addEventListener("hashchange", () => {
|
|
let place_id = decodeURIComponent(location.hash.substring(1))
|
|
if(place_id){
|
|
MAP.highlight(place_id)
|
|
} else {
|
|
MAP.unhighlight_all()
|
|
}
|
|
})
|
|
|
|
search_form.addEventListener("submit", e => {
|
|
e.preventDefault()
|
|
if(places){
|
|
let data = new FormData(search_form)
|
|
|
|
if(data.get("query")){
|
|
let resultElements = []
|
|
|
|
let search_results = places.search(data.get("query"))
|
|
|
|
for(let result_item of search_results){
|
|
let el = document.createElement("li")
|
|
let a = document.createElement("a")
|
|
el.append(a)
|
|
a.href = "#"+encodeURIComponent(result_item.ref)
|
|
a.addEventListener("click", e => {
|
|
e.preventDefault()
|
|
openSearchResultItem(result_item.feature)
|
|
})
|
|
let header = document.createElement("camp-feature-short-header")
|
|
header.feature = result_item.feature
|
|
a.append(header)
|
|
resultElements.push(el)
|
|
}
|
|
|
|
if(!document.getElementById("search-result")){
|
|
let el = document.createElement("ol")
|
|
el.id = "search-result"
|
|
document.getElementById("result-panel").replaceChildren(el)
|
|
}
|
|
|
|
if(resultElements.length > 0){
|
|
document.getElementById("search-result").replaceChildren(...resultElements)
|
|
} else {
|
|
document.getElementById("search-result").replaceChildren(document.createTextNode("Pas de resultat"))
|
|
}
|
|
|
|
document.getElementById("search-result").children[0]?.scrollIntoView()
|
|
} else {
|
|
document.getElementById("search-result")?.remove()
|
|
}
|
|
|
|
}
|
|
})
|
|
|
|
function openSearchResultItem(feature){
|
|
let searchResultContainer = document.getElementById("search-result")
|
|
if(searchResultContainer){
|
|
let featureIndex = -1
|
|
let featureFound = false
|
|
let newChildren = []
|
|
for(let el of searchResultContainer.children){
|
|
let featureHeader = el.querySelector("camp-feature-short-header")
|
|
if(!featureHeader)
|
|
continue
|
|
let root = document.createElement("camp-feature")
|
|
root.feature = featureHeader.feature
|
|
newChildren.push(root)
|
|
if(!featureFound){
|
|
featureIndex += 1
|
|
if(feature == root.feature){
|
|
featureFound = true
|
|
}
|
|
}
|
|
}
|
|
let panel = document.getElementById("result-panel")
|
|
panel.replaceChildren(...newChildren)
|
|
requestAnimationFrame(() => {
|
|
if(featureFound){
|
|
panel.setActiveChildrenIndex(featureIndex, {behavior: "instant"})
|
|
} else {
|
|
panel.activeChildrenIndex = 0
|
|
}
|
|
})
|
|
let newUrl = new URL(window.location)
|
|
newUrl.hash = feature.id
|
|
window.history.replaceState(newUrl.toString(), "")
|
|
}
|
|
}
|
|
|
|
document.getElementById("result-panel").addEventListener("activePanelChange", e => {
|
|
let activeElement = e.target.children[e.activePanelIndex]
|
|
if(activeElement instanceof FeatureElement){
|
|
let feature = activeElement.feature
|
|
if(feature){
|
|
MAP.highlight(feature.id)
|
|
} else {
|
|
MAP.unhighlight_all()
|
|
}
|
|
console.log("active panel changed: "+e.activePanelIndex, feature)
|
|
} else {
|
|
MAP.unhighlight_all()
|
|
}
|
|
})
|