davvalent commited on 2023-03-27 13:16:05
Showing 2 changed files, with 99 additions and 44 deletions.
| ... | ... |
@@ -112,7 +112,7 @@ header div#application-header h1 {
|
| 112 | 112 |
transition: none; |
| 113 | 113 |
} |
| 114 | 114 |
|
| 115 |
-#loader {
|
|
| 115 |
+.loader {
|
|
| 116 | 116 |
position: absolute; |
| 117 | 117 |
inset: 0; |
| 118 | 118 |
background: rgba(255, 255, 255); |
| ... | ... |
@@ -121,7 +121,7 @@ header div#application-header h1 {
|
| 121 | 121 |
z-index: 500; |
| 122 | 122 |
text-align: center; |
| 123 | 123 |
} |
| 124 |
-#loader p {
|
|
| 124 |
+.loader p {
|
|
| 125 | 125 |
position: relative; |
| 126 | 126 |
top: 40%; |
| 127 | 127 |
font-size: x-large; |
| ... | ... |
@@ -155,6 +155,7 @@ header div#application-header h1 {
|
| 155 | 155 |
height: 50vh; |
| 156 | 156 |
} |
| 157 | 157 |
*/ |
| 158 |
+ |
|
| 158 | 159 |
.rdf-data {
|
| 159 | 160 |
height: calc(50% - 40px); |
| 160 | 161 |
} |
| ... | ... |
@@ -166,7 +167,7 @@ header div#application-header h1 {
|
| 166 | 167 |
* top: 10px permet de les aligner en bas |
| 167 | 168 |
* top: -10px permet de combler l'espace créé en haut |
| 168 | 169 |
* +/- 2 px de jeu |
| 169 |
- * à surveiller |
|
| 170 |
+ * certains écarts sont trop grands pour être pris en charge par cette solution |
|
| 170 | 171 |
*/ |
| 171 | 172 |
.glide__track {
|
| 172 | 173 |
position: relative; |
| ... | ... |
@@ -175,7 +176,9 @@ header div#application-header h1 {
|
| 175 | 176 |
.glide__slides {
|
| 176 | 177 |
top: 10px; |
| 177 | 178 |
} |
| 178 |
- |
|
| 179 |
+.custom-glide {
|
|
| 180 |
+ position: relative; |
|
| 181 |
+} |
|
| 179 | 182 |
.glide__slide {
|
| 180 | 183 |
max-width: 100%; |
| 181 | 184 |
position: relative; |
| ... | ... |
@@ -117,28 +117,31 @@ |
| 117 | 117 |
layer.bindPopup(popup); |
| 118 | 118 |
|
| 119 | 119 |
/** Event passé automatiquement au callback */ |
| 120 |
- layer.on("click", (e) => {
|
|
| 120 |
+ layer.on("popupopen", async (e) => {
|
|
| 121 | 121 |
|
| 122 |
+ const popupId = `id-${e.popup._leaflet_id}-`;
|
|
| 123 |
+ |
|
| 124 |
+ let response; |
|
| 122 | 125 |
let URI = feature.properties.URI; |
| 123 | 126 |
|
| 124 | 127 |
if (dev()) {
|
| 125 | 128 |
if (sessionStorage.getItem("onLineTripleStore") !== "true") {
|
| 126 | 129 |
URI = feature.properties.URI.replace("http://data.qdmtl.ca", sessionStorage.getItem("devTripleStoreUrl"));
|
| 130 |
+ devConsole("Dev triple store");
|
|
| 127 | 131 |
} |
| 128 | 132 |
} |
| 129 | 133 |
|
| 130 | 134 |
/** |
| 131 | 135 |
* Fetching the ressource |
| 132 |
- * Thenable since await is not allowed if not at top level |
|
| 133 | 136 |
*/ |
| 134 |
- fetch(URI, {
|
|
| 137 |
+ response = await fetch(URI, {
|
|
| 135 | 138 |
method: "GET", |
| 136 | 139 |
headers: {
|
| 137 | 140 |
"Accept": "application/ld+json", |
| 138 | 141 |
} |
| 139 |
- }) |
|
| 140 |
- .then((response) => response.json()) |
|
| 141 |
- .then((jsonLD) => {
|
|
| 142 |
+ }); |
|
| 143 |
+ |
|
| 144 |
+ const jsonLD = await response.json(); |
|
| 142 | 145 |
|
| 143 | 146 |
if (dev) {
|
| 144 | 147 |
console.log("Dev: Response from RDF store: ", jsonLD);
|
| ... | ... |
@@ -146,30 +149,16 @@ |
| 146 | 149 |
|
| 147 | 150 |
const popUpInformation = ` |
| 148 | 151 |
|
| 149 |
- <div id="loader"> |
|
| 152 |
+ <div id="${popupId}loader" class="loader">
|
|
| 150 | 153 |
<div class="spinner"></div> |
| 151 | 154 |
<p>Chargement</p> |
| 155 |
+ <p id="${popupId}counter"></p>
|
|
| 152 | 156 |
</div> |
| 153 | 157 |
|
| 154 |
- <div class="glide"> |
|
| 158 |
+ <div id="${popupId}glide" class="custom-glide">
|
|
| 155 | 159 |
|
| 156 | 160 |
<div class="glide__track" data-glide-el="track"> |
| 157 |
- <ul class="glide__slides"> |
|
| 158 |
- <li class="glide__slide"> |
|
| 159 |
- <img |
|
| 160 |
- src="https://archivesdemontreal.ica-atom.org/uploads/r/ville-de-montreal-section-des-archives/1/7/178126/VM94C196-0132.jpg" |
|
| 161 |
- alt="foo" |
|
| 162 |
- title="bar"> |
|
| 163 |
- <div class="overlay"></div> |
|
| 164 |
- </li> |
|
| 165 |
- <li class="glide__slide"> |
|
| 166 |
- <img src="https://archivesdemontreal.ica-atom.org/uploads/r/ville-de-montreal-section-des-archives/1/8/184246/VM94C196-0839.jpg"> |
|
| 167 |
- <div class="overlay"></div> |
|
| 168 |
- </li> |
|
| 169 |
- <li class="glide__slide"> |
|
| 170 |
- <img src="https://archivesdemontreal.ica-atom.org/uploads/r/ville-de-montreal-section-des-archives/1/7/177798/VM94C196-0038.jpg"> |
|
| 171 |
- <div class="overlay"></div> |
|
| 172 |
- </li> |
|
| 161 |
+ <ul class="glide__slides" id="${popupId}slides">
|
|
| 173 | 162 |
</ul> |
| 174 | 163 |
</div> |
| 175 | 164 |
|
| ... | ... |
@@ -197,15 +186,10 @@ |
| 197 | 186 |
|
| 198 | 187 |
popup.setContent(popUpInformation); |
| 199 | 188 |
|
| 200 |
- if (dev()) {
|
|
| 201 |
- console.log("Dev popup:", popup);
|
|
| 202 |
- } |
|
| 203 |
- |
|
| 204 | 189 |
/** |
| 205 | 190 |
* Déplacement et centrage de la punaise |
| 206 | 191 |
*/ |
| 207 |
- let targetLatLng = L.latLng( |
|
| 208 |
- /** Coordonnées sont inversées avec GeoJSON */ |
|
| 192 |
+ let targetLatLng = L.latLng(// coordonnées sont inversées avec GeoJSON */ |
|
| 209 | 193 |
feature.geometry.coordinates[1], |
| 210 | 194 |
feature.geometry.coordinates[0], |
| 211 | 195 |
); |
| ... | ... |
@@ -215,9 +199,81 @@ |
| 215 | 199 |
targetLatLng = pifm.unproject(targetPoint, targetZoom); |
| 216 | 200 |
pifm.setView(targetLatLng, targetZoom); |
| 217 | 201 |
|
| 218 |
- setTimeout(() => {
|
|
| 202 |
+ /** Récupérer l'URI de la ressource */ |
|
| 203 |
+ let ressourceUri; |
|
| 204 |
+ jsonLD["@graph"].forEach((ressource)=> {
|
|
| 205 |
+ |
|
| 206 |
+ if (ressource["@id"].search("http://data.qdmtl.ca/Building/") > -1) {
|
|
| 207 |
+ ressourceUri = ressource["@id"]; |
|
| 208 |
+ } |
|
| 209 |
+ }) |
|
| 219 | 210 |
|
| 220 |
- const glide = new Glide(".glide", {
|
|
| 211 |
+ /** SPARQL query for images */ |
|
| 212 |
+ let imagesQuery = "PREFIX rico:<https://www.ica.org/standards/RiC/ontology#>PREFIX schema:<https://schema.org/>SELECT ?f WHERE{[]a rico:Record;rico:hasInstantiation ?i;rico:hasOrHadMainSubject<";
|
|
| 213 |
+ imagesQuery += ressourceUri; |
|
| 214 |
+ imagesQuery += ">.?i schema:image ?f.}"; |
|
| 215 |
+ imagesQuery = "query=" + encodeURIComponent(imagesQuery); |
|
| 216 |
+ |
|
| 217 |
+ /** fetch images URL */ |
|
| 218 |
+ response = await fetch(tripleStoreEndpointUrl, {
|
|
| 219 |
+ method: "POST", |
|
| 220 |
+ headers: {
|
|
| 221 |
+ "Accept": "application/sparql-results+json", |
|
| 222 |
+ "Content-Type": "application/x-www-form-urlencoded" |
|
| 223 |
+ }, |
|
| 224 |
+ body: imagesQuery |
|
| 225 |
+ }); |
|
| 226 |
+ |
|
| 227 |
+ const sparqlResponse = await response.json(); |
|
| 228 |
+ |
|
| 229 |
+ /** URLs list */ |
|
| 230 |
+ let imageUrls = sparqlResponse.results.bindings.map(url => {
|
|
| 231 |
+ return url.f.value; |
|
| 232 |
+ }); |
|
| 233 |
+ |
|
| 234 |
+ /** loads an image, returns a promise */ |
|
| 235 |
+ const loadImage = src => {
|
|
| 236 |
+ |
|
| 237 |
+ return new Promise((resolve, reject) => {
|
|
| 238 |
+ |
|
| 239 |
+ const img = new Image(); |
|
| 240 |
+ img.onload = () => resolve(img); |
|
| 241 |
+ img.onerror = reject; |
|
| 242 |
+ img.src = src; |
|
| 243 |
+ }); |
|
| 244 |
+ } |
|
| 245 |
+ |
|
| 246 |
+ /** loading all ressource images, async */ |
|
| 247 |
+ const imagesElements = await Promise.all(imageUrls.map(loadImage)); |
|
| 248 |
+ |
|
| 249 |
+ /** printing information */ |
|
| 250 |
+ console.log("Nombre d'images téléchargées : ", imagesElements.length);
|
|
| 251 |
+ const imagesList = imagesElements.map((element) => {
|
|
| 252 |
+ return element.currentSrc; |
|
| 253 |
+ }) |
|
| 254 |
+ console.log("URLs of images", imagesList);
|
|
| 255 |
+ |
|
| 256 |
+ /** update the DOM with images for the Leaflet popup */ |
|
| 257 |
+ imagesElements.forEach((image, index) => {
|
|
| 258 |
+ |
|
| 259 |
+ let overlay = document.createElement("div");
|
|
| 260 |
+ overlay.className = "overlay"; |
|
| 261 |
+ |
|
| 262 |
+ let slide = document.createElement("li");
|
|
| 263 |
+ slide.className = "glide__slide"; |
|
| 264 |
+ slide.appendChild(image); |
|
| 265 |
+ slide.append(overlay); |
|
| 266 |
+ |
|
| 267 |
+ let slides = document.querySelector(`#${popupId}slides`);
|
|
| 268 |
+ slides.appendChild(slide); |
|
| 269 |
+ |
|
| 270 |
+ /** the loop blocks the main thread so this does nothing */ |
|
| 271 |
+ let counter = document.querySelector(`p#${popupId}counter`);
|
|
| 272 |
+ counter.innerText = `${++index}/${imagesElements.length}`;
|
|
| 273 |
+ }); |
|
| 274 |
+ |
|
| 275 |
+ /** caroussel */ |
|
| 276 |
+ const glide = new Glide(`#${popupId}glide`, {
|
|
| 221 | 277 |
type: 'carousel', |
| 222 | 278 |
perView: 2, |
| 223 | 279 |
focusAt: "center", |
| ... | ... |
@@ -228,15 +284,11 @@ |
| 228 | 284 |
|
| 229 | 285 |
glide.mount(); |
| 230 | 286 |
|
| 231 |
- let loader = document.querySelector("#loader");
|
|
| 232 |
- |
|
| 287 |
+ /** hide the spinner */ |
|
| 288 |
+ let loader = document.querySelector(`#${popupId}loader`);
|
|
| 289 |
+ setTimeout(() => { // wait to make sure it's clean
|
|
| 233 | 290 |
loader.style.display = "none"; |
| 234 |
- |
|
| 235 |
- }, 1000); |
|
| 236 |
- }, |
|
| 237 |
- (reason) => {
|
|
| 238 |
- /* rejection handler */ |
|
| 239 |
- }).catch(err => console.log(err)); |
|
| 291 |
+ }, 300); |
|
| 240 | 292 |
}); |
| 241 | 293 |
} |
| 242 | 294 |
}), |
| 243 | 295 |