@panoramax/web-viewer 3.1.0-develop-428bc81e → 3.1.0-develop-088b8c49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@panoramax/web-viewer",
3
- "version": "3.1.0-develop-428bc81e",
3
+ "version": "3.1.0-develop-088b8c49",
4
4
  "description": "Panoramax web viewer for geolocated pictures",
5
5
  "main": "build/index.js",
6
6
  "author": "Panoramax team",
@@ -96,8 +96,8 @@
96
96
  "@photo-sphere-viewer/markers-plugin": "5.10.1",
97
97
  "@photo-sphere-viewer/virtual-tour-plugin": "5.10.1",
98
98
  "documentation": "^14.0.1",
99
- "maplibre-gl": "^3.6.2",
100
- "pmtiles": "^2.11.0"
99
+ "maplibre-gl": "^4.7.1",
100
+ "pmtiles": "^3.2.0"
101
101
  },
102
102
  "eslintConfig": {
103
103
  "env": {
@@ -96,6 +96,13 @@ export default class Map extends maplibregl.Map {
96
96
  // Parent selection
97
97
  this._parent.addEventListener("select", this.reloadLayersStyles.bind(this));
98
98
 
99
+ // Timeout for initial loading
100
+ setTimeout(() => {
101
+ if(!this.loaded() && this._parent._loader.isVisible()) {
102
+ this._parent._loader.dismiss({}, this._parent._t.map.slow_loading, () => {});
103
+ }
104
+ }, 15000);
105
+
99
106
  this.on("load", async () => {
100
107
  await this.setVisibleUsers(this._parent._options.users);
101
108
  this.reloadLayersStyles();
@@ -291,10 +298,10 @@ export default class Map extends maplibregl.Map {
291
298
  filterUserLayersContent(dataType, filter) {
292
299
  [...this._userLayers].forEach(l => {
293
300
  this.setFilter(getUserLayerId(l, dataType), filter);
294
- if(dataType === "sequences") {
301
+ if(dataType === "sequences" && this.getLayer(getUserLayerId(l, "sequences_plus"))) {
295
302
  this.setFilter(getUserLayerId(l, "sequences_plus"), filter);
296
303
  }
297
- if(dataType === "pictures") {
304
+ if(dataType === "pictures" && this.getLayer(getUserLayerId(l, "pictures_symbols"))) {
298
305
  this.setFilter(getUserLayerId(l, "pictures_symbols"), filter);
299
306
  }
300
307
  });
@@ -362,7 +369,7 @@ export default class Map extends maplibregl.Map {
362
369
  Object.entries(style.sources).forEach(([sId, s]) => this.addSource(sId, s));
363
370
  style.layers = style.layers || [];
364
371
  const layers = style.layers.concat(getMissingLayerStyles(style.sources, style.layers));
365
- layers.forEach(l => this.addLayer(l, firstLabelLayerId?.id));
372
+ layers.filter(l => Object.keys(l).length > 0).forEach(l => this.addLayer(l, firstLabelLayerId?.id));
366
373
  }
367
374
 
368
375
  // Map interaction events
@@ -609,7 +616,7 @@ export default class Map extends maplibregl.Map {
609
616
  if(thumbUrl) {
610
617
  let content = document.createElement("img");
611
618
  content.classList.add("gvs-map-thumb");
612
- content.alt = this._parent._t.thumbnail;
619
+ content.alt = this._parent._t.map.thumbnail;
613
620
  let img = new Image();
614
621
  img.src = thumbUrl;
615
622
 
@@ -634,7 +641,7 @@ export default class Map extends maplibregl.Map {
634
641
  }
635
642
  }
636
643
  else {
637
- this._picPopup.setHTML(`<i>${this._parent._t.no_thumbnail}</i>`);
644
+ this._picPopup.setHTML(`<i>${this._parent._t.map.no_thumbnail}</i>`);
638
645
  }
639
646
  }
640
647
  };
@@ -161,6 +161,7 @@
161
161
  "loading": "Loading…",
162
162
  "thumbnail": "Thumbnail of hovered picture",
163
163
  "no_thumbnail": "No thumbnail",
164
- "not_public": "Not publicly visible"
164
+ "not_public": "Not publicly visible",
165
+ "slow_loading": "Map is slow to load and could appear broken"
165
166
  }
166
167
  }
@@ -161,6 +161,7 @@
161
161
  "loading": "Chargement…",
162
162
  "thumbnail": "Miniature de la photo survolée",
163
163
  "no_thumbnail": "Pas de miniature",
164
- "not_public": "Masqué au public"
164
+ "not_public": "Masqué au public",
165
+ "slow_loading": "La carte est longue à charger et pourrait apparaître cassée"
165
166
  }
166
167
  }
package/src/utils/API.js CHANGED
@@ -285,7 +285,9 @@ export default class API {
285
285
  * @returns {object} The fetch options
286
286
  */
287
287
  _getFetchOptions() {
288
- return Object.assign({}, this._fetchOpts);
288
+ return Object.assign({
289
+ signal: AbortSignal.timeout(15000)
290
+ }, this._fetchOpts);
289
291
  }
290
292
 
291
293
  /**
@@ -295,8 +297,10 @@ export default class API {
295
297
  * @returns {function} The RequestTransformFunction
296
298
  */
297
299
  _getMapRequestTransform() {
300
+ const fetchOpts = this._getFetchOptions();
301
+ delete fetchOpts.signal;
298
302
  // Only if tiles endpoint is enabled and fetch options set
299
- if(Object.keys(this._getFetchOptions()).length > 0) {
303
+ if(Object.keys(fetchOpts).length > 0) {
300
304
  return (url) => {
301
305
  // As MapLibre will use this function for all its calls
302
306
  // We must make sure fetch options are sent only for
@@ -304,7 +308,7 @@ export default class API {
304
308
  if(url.startsWith(this._endpoint)) {
305
309
  return {
306
310
  url,
307
- ...this._getFetchOptions()
311
+ ...fetchOpts
308
312
  };
309
313
  }
310
314
  };
@@ -338,7 +338,7 @@ export function apiFeatureToPSVNode(f, t, fastInternet=false, customLinkFilter=n
338
338
  let panorama;
339
339
 
340
340
  // Cropped panorama
341
- if(Object.keys(croppedPanoData).length > 0) {
341
+ if(!tileUrl && Object.keys(croppedPanoData).length > 0) {
342
342
  panorama = {
343
343
  baseUrl: fastInternet ? hdUrl : baseUrl,
344
344
  origBaseUrl: fastInternet ? hdUrl : baseUrl,
@@ -723,6 +723,8 @@ export default class Widgets {
723
723
  const overridenGeocoder = query => {
724
724
  const rgxCoords = /([-+]?\d{1,2}\.\d+),\s*([-+]?\d{1,3}\.\d+)/;
725
725
  const coordsMatch = query.match(rgxCoords);
726
+ const rgxUuid = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/;
727
+ const uuidMatch = query.match(rgxUuid);
726
728
 
727
729
  if(coordsMatch) {
728
730
  const lat = parseFloat(coordsMatch[1]);
@@ -732,7 +734,12 @@ export default class Widgets {
732
734
  zoom: 16,
733
735
  });
734
736
  return Promise.resolve(true);
735
- } else {
737
+ }
738
+ else if(uuidMatch) {
739
+ this._viewer.select(null, query);
740
+ return Promise.resolve(true);
741
+ }
742
+ else {
736
743
  return this._viewer.map.geocoder({
737
744
  query,
738
745
  limit: 3,
@@ -18,6 +18,7 @@ jest.mock("../src/components/Photo", () => class {
18
18
  });
19
19
 
20
20
  jest.mock("../src/components/Map", () => class {});
21
+ global.AbortSignal = { timeout: jest.fn() };
21
22
 
22
23
  const API_URL = "http://localhost:5000/api/search";
23
24
 
@@ -5,6 +5,7 @@ jest.mock("maplibre-gl", () => ({
5
5
  }));
6
6
 
7
7
  jest.mock("../src/components/Map", () => class {});
8
+ global.AbortSignal = { timeout: jest.fn() };
8
9
 
9
10
  const API_URL = "http://localhost:5000/api/search";
10
11
 
@@ -19,6 +19,8 @@ jest.mock("maplibre-gl", () => ({
19
19
  Map: class {},
20
20
  }));
21
21
 
22
+ global.AbortSignal = { timeout: jest.fn() };
23
+
22
24
  const API_URL = "http://localhost:5000/api/search";
23
25
 
24
26
 
@@ -7,6 +7,7 @@ jest.mock("maplibre-gl", () => ({
7
7
  }));
8
8
 
9
9
  global.console = { info: jest.fn() };
10
+ global.AbortSignal = { timeout: jest.fn() };
10
11
 
11
12
  describe("constructor", () => {
12
13
  it("works with JS element", () => {
@@ -206,6 +206,7 @@ describe("filterUserLayersContent", () => {
206
206
  const m = new Map(p, c);
207
207
  m.getSource = () => true;
208
208
  m.setPaintProperty = jest.fn();
209
+ m.getLayer = () => true;
209
210
  m._fire("load");
210
211
  m.setFilter = jest.fn();
211
212
  m.filterUserLayersContent("pictures", [["test", "true"]]);
@@ -3,6 +3,7 @@ import API from "../../src/utils/API";
3
3
  jest.mock("maplibre-gl", () => ({
4
4
  addProtocol: jest.fn(),
5
5
  }));
6
+ global.AbortSignal = { timeout: jest.fn() };
6
7
 
7
8
  const ENDPOINT = "https://panoramax.ign.fr/api";
8
9
  const VALID_LANDING = {