ajout images, requetes et proprietes d'affichage
davvalent

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