@panoramax/web-viewer 3.2.3-develop-a4cbf815 → 3.2.3-develop-cb38d751

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.
@@ -18,14 +18,17 @@ https://api.panoramax.xyz/?map=19.51/48.1204522/-1.7199004&pic=890b6268-7716-4e3
18
18
 
19
19
  ### :material-target: `focus`: main shown element
20
20
 
21
- Switch to choose which element between map, picture or metadata should be shown wide at start. Examples:
21
+ Switch to choose which element between map or picture should be shown wide at start. Examples:
22
22
 
23
23
  - `focus=map`
24
24
  - `focus=pic`
25
- - `focus=meta`
26
25
 
27
26
  By default, picture is shown wide.
28
27
 
28
+ !!! note
29
+
30
+ In versions prior to 4.0.0, another `meta` value was also available to display picture metadata popup. As this part of interface is shown directly on picture side since 4.0.0, this parameter was removed. If present, picture is shown focused.
31
+
29
32
  ### :simple-speedtest: `speed`: sequence play speed
30
33
 
31
34
  The duration of stay on a picture during sequence play (excluding image dowloading time), in milliseconds. Authorized values are between 0 and 3000. Example:
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@panoramax/web-viewer",
3
- "version": "3.2.3-develop-a4cbf815",
3
+ "version": "3.2.3-develop-cb38d751",
4
4
  "description": "Panoramax web viewer for geolocated pictures",
5
5
  "main": "build/index.js",
6
6
  "author": "Panoramax team",
@@ -262,18 +262,17 @@ export default class MapFilters extends LitElement {
262
262
  this._onFormChange();
263
263
  }
264
264
 
265
- /**
266
- * Shortcut button click: change associated input value
267
- * @private
268
- */
269
- _onShortcutClick(field, value) {
270
- return () => {
271
- const elem = this.shadowRoot.getElementById(field);
272
- if(elem) {
273
- if(elem.value !== value) { elem.value = value; }
274
- else { elem.value = ""; }
275
- }
276
- };
265
+ /** @private */
266
+ _onDateShortcut(date) {
267
+ const dateFromField = this.shadowRoot.getElementById("pnx-filter-date-from");
268
+ const dateToField = this.shadowRoot.getElementById("pnx-filter-date-end");
269
+
270
+ if(dateFromField) {
271
+ if(dateFromField.value !== date) { dateFromField.value = date; }
272
+ else { dateFromField.value = ""; }
273
+ }
274
+
275
+ if(dateToField) { dateToField.value = ""; }
277
276
  }
278
277
 
279
278
  /** @private */
@@ -290,13 +289,13 @@ export default class MapFilters extends LitElement {
290
289
  <h4>${fa(faCalendar)} ${this._parent?._t.pnx.filter_date}</h4>
291
290
  <div class="pnx-input-shortcuts">
292
291
  <button
293
- @click=${this._onShortcutClick("pnx-filter-date-from", new Date(new Date().setMonth(new Date().getMonth() - 1)).toISOString().split("T")[0])}
292
+ @click=${() => this._onDateShortcut(new Date(new Date().setMonth(new Date().getMonth() - 1)).toISOString().split("T")[0])}
294
293
  >${this._parent?._t.pnx.filter_date_1month}</button>
295
294
  <button
296
- @click=${this._onShortcutClick("pnx-filter-date-from", new Date(new Date().setMonth(new Date().getMonth() - 6)).toISOString().split("T")[0])}
295
+ @click=${() => this._onDateShortcut(new Date(new Date().setMonth(new Date().getMonth() - 6)).toISOString().split("T")[0])}
297
296
  >${this._parent?._t.pnx.filter_date_6months}</button>
298
297
  <button
299
- @click=${this._onShortcutClick("pnx-filter-date-from", new Date(new Date().setFullYear(new Date().getFullYear() - 1)).toISOString().split("T")[0])}
298
+ @click=${() => this._onDateShortcut(new Date(new Date().setFullYear(new Date().getFullYear() - 1)).toISOString().split("T")[0])}
300
299
  >${this._parent?._t.pnx.filter_date_1year}</button>
301
300
  </div>
302
301
  <div class="pnx-input-group">
@@ -32,16 +32,6 @@ const missing = () => fa(faQuestion, {styles: {height: "16px"}});
32
32
  export default class PictureMetadata extends LitElement {
33
33
  /** @private */
34
34
  static styles = [ titles, textarea, css`
35
- h4[slot="title"] {
36
- margin: 0;
37
- justify-content: center;
38
- font-size: 0.8em;
39
- line-height: 2em;
40
- padding: 0.5em 0;
41
- }
42
- h4[slot="title"] svg.svg-inline--fa {
43
- height: 14px;
44
- }
45
35
  div[slot="content"] {
46
36
  padding: 5px 10px;
47
37
  background-color: #ededed;
@@ -1,8 +1,10 @@
1
1
  import { LitElement, css, html } from "lit";
2
2
  import { fa } from "../../utils/widgets";
3
- import { faSvg, textarea, titles } from "../styles";
3
+ import { faSvg, textarea, titles, input } from "../styles";
4
4
  import { faMap } from "@fortawesome/free-solid-svg-icons/faMap";
5
5
  import { faCircleInfo } from "@fortawesome/free-solid-svg-icons/faCircleInfo";
6
+ import { faShareAlt } from "@fortawesome/free-solid-svg-icons/faShareAlt";
7
+ import { faLink } from "@fortawesome/free-solid-svg-icons/faLink";
6
8
 
7
9
  /**
8
10
  * Share Menu displays links for quick picture sharing.
@@ -16,35 +18,25 @@ import { faCircleInfo } from "@fortawesome/free-solid-svg-icons/faCircleInfo";
16
18
  */
17
19
  export default class ShareMenu extends LitElement {
18
20
  /** @private */
19
- static styles = [ faSvg, textarea, titles, css`
20
- .pnx-many-buttons {
21
+ static styles = [ faSvg, input, textarea, titles, css`
22
+ div[slot="content"] {
23
+ margin-top: 10px;
24
+ }
25
+ .links {
21
26
  display: flex;
22
- flex-direction: row;
23
- width: 100%;
24
27
  gap: 5px;
25
- justify-content: space-between;
26
- align-items: center;
27
- flex-wrap: wrap;
28
- white-space: nowrap;
29
- }
30
-
31
- .pnx-many-buttons textarea {
32
- font-size: 0.8em;
33
- height: 50px;
34
28
  }
35
-
36
- .pnx-many-buttons pnx-button,
37
- .pnx-many-buttons pnx-copy-button,
38
- .pnx-many-buttons pnx-link-button {
39
- flex-basis: 100%;
40
- flex-grow: 2;
41
- flex-shrink: 2;
29
+ .embed {
30
+ display: flex;
31
+ gap: 5px;
32
+ align-items: center;
33
+ flex-direction: column;
42
34
  }
43
35
  ` ];
44
36
 
45
37
  /** @private */
46
38
  static properties = {
47
- _baseUrl: {state: true},
39
+ _url: {state: true},
48
40
  };
49
41
 
50
42
  constructor() {
@@ -63,29 +55,45 @@ export default class ShareMenu extends LitElement {
63
55
 
64
56
  /** @private */
65
57
  _onUrlChange() {
66
- this._baseUrl = window.location.href.replace(/\/$/, "");
58
+ const baseUrl = window.location.href.replace(/\/$/, "");
59
+ this._url = this._parent?.urlHandler?.nextShortLink(baseUrl) || baseUrl;
67
60
  }
68
61
 
69
62
  /** @private */
70
63
  render() {
71
- const shareUrl = this._parent?.urlHandler?.nextShortLink(this._baseUrl) || this._baseUrl;
72
- const iframe = `<iframe src="${shareUrl}" style="border: none; width: 500px; height: 300px"></iframe>`;
64
+ const iframe = `<iframe src="${this._url}" style="border: none; width: 500px; height: 300px"></iframe>`;
73
65
 
74
66
  return html`
75
- <h4>
76
- ${fa(faMap)} ${this._parent?._t.pnx.share_embed}
77
- <pnx-link-button
78
- href="https://docs.panoramax.fr/web-viewer/03_URL_settings/"
79
- title="${this._parent?._t.pnx.share_embed_docs}"
80
- target="_blank"
81
- kind="outline">
82
- ${fa(faCircleInfo, {styles: {padding: "0 3px"}})}
83
- </pnx-link-button>
84
- </h4>
85
- <div class="pnx-many-buttons">
86
- <textarea readonly>${iframe}</textarea>
87
- <pnx-copy-button ._t=${this._parent?._t} text=${iframe}></pnx-copy-button>
88
- </div>`;
67
+ <h4>${fa(faShareAlt)} ${this._parent?._t.pnx.share}</h4>
68
+ <pnx-tabs>
69
+ <h4 slot="title">${fa(faLink)} ${this._parent?._t.pnx.share_page}</h4>
70
+ <div slot="content">
71
+ <div class="links">
72
+ <input type="text" readonly value=${this._url} style="flex: 2" />
73
+ <pnx-copy-button ._t=${this._parent?._t} text=${this._url}></pnx-copy-button>
74
+ </div>
75
+ </div>
76
+
77
+ <h4 slot="title">${fa(faMap)} ${this._parent?._t.pnx.share_embed}</h4>
78
+ <div slot="content">
79
+ <div class="embed">
80
+ <pnx-link-button
81
+ href="https://docs.panoramax.fr/web-viewer/03_URL_settings/"
82
+ target="_blank"
83
+ kind="superinline"
84
+ size="sm"
85
+ >
86
+ ${fa(faCircleInfo)} ${this._parent?._t.pnx.share_embed_docs}
87
+ </pnx-link-button>
88
+ <textarea readonly>${iframe}</textarea>
89
+ <pnx-copy-button
90
+ ._t=${this._parent?._t}
91
+ text=${iframe}
92
+ style="width: 100%"
93
+ ></pnx-copy-button>
94
+ </div>
95
+ </div>
96
+ </pnx-tabs>`;
89
97
  }
90
98
  }
91
99
 
@@ -303,6 +303,17 @@ export const titles = css`
303
303
  h4 > svg.svg-inline--fa {
304
304
  height: 18px;
305
305
  }
306
+
307
+ h4[slot="title"] {
308
+ margin: 0;
309
+ justify-content: center;
310
+ font-size: 0.8em;
311
+ line-height: 2em;
312
+ padding: 0.5em 0;
313
+ }
314
+ h4[slot="title"] svg.svg-inline--fa {
315
+ height: 14px;
316
+ }
306
317
  `;
307
318
 
308
319
  // Active icon badge
@@ -30,14 +30,12 @@ export default class PictureLegendActions extends LitElement {
30
30
  */
31
31
  static properties = {
32
32
  full: { type: Boolean },
33
- _baseUrl: {state: true},
34
33
  _meta: { state: true },
35
34
  };
36
35
 
37
36
  constructor() {
38
37
  super();
39
38
  this.full = false;
40
- this._onUrlChange();
41
39
  }
42
40
 
43
41
  /** @private */
@@ -45,20 +43,13 @@ export default class PictureLegendActions extends LitElement {
45
43
  super.connectedCallback();
46
44
 
47
45
  this._parent?.onceReady().then(() => {
48
- this._onUrlChange();
49
46
  this._meta = this._parent.psv.getPictureMetadata();
50
- this._parent.urlHandler.addEventListener("url-changed", this._onUrlChange.bind(this));
51
47
  this._parent.psv.addEventListener("picture-loaded", () => {
52
48
  this._meta = this._parent.psv.getPictureMetadata();
53
49
  });
54
50
  });
55
51
  }
56
52
 
57
- /** @private */
58
- _onUrlChange() {
59
- this._baseUrl = window.location.href.replace(/\/$/, "");
60
- }
61
-
62
53
  /** @private */
63
54
  _onPrint() {
64
55
  this._closeGroup();
@@ -84,8 +75,6 @@ export default class PictureLegendActions extends LitElement {
84
75
 
85
76
  /** @private */
86
77
  render() {
87
- const shareUrl = this._parent?.urlHandler?.nextShortLink(this._baseUrl) || this._baseUrl;
88
-
89
78
  return html`<pnx-togglable-group padded="false" id="pic-legend-headline-menu" ._parent=${this._parent}>
90
79
  <pnx-button slot="button" kind="inline">${fa(faEllipsisV)}</pnx-button>
91
80
  <pnx-list-group class="pnx-print-hidden" @click=${this._closeMenu}>
@@ -96,9 +85,6 @@ export default class PictureLegendActions extends LitElement {
96
85
  href=${this._meta?.panorama?.hdUrl}
97
86
  @click=${this._closeGroup}
98
87
  >${this._parent?._t.pnx.share_image}</a>
99
- <pnx-copy-button ._t=${this._parent?._t} text=${shareUrl} unstyled>
100
- ${this._parent?._t.pnx.share_page}
101
- </pnx-copy-button>
102
88
  ${this._parent.isWidthSmall() ? nothing : html`<button @click=${this._onPrint}>
103
89
  ${this._parent?._t.pnx.share_print}
104
90
  </button>`}
@@ -90,7 +90,7 @@ export default class InitParameters { // eslint-disable-line import/no-unused-mo
90
90
  let map_pic_score = urlParams.pic_score;
91
91
 
92
92
  // Check coherence
93
- if(!["map", "meta", "pic"].includes(focus)) {
93
+ if(!["map", "pic"].includes(focus)) {
94
94
  console.warn("Invalid value for parameter focus:", focus);
95
95
  focus = map && !picture ? "map" : "pic";
96
96
  }
@@ -373,13 +373,6 @@ export function alterPhotoViewerState(viewer, params) {
373
373
  export function alterViewerState(viewer, params) {
374
374
  alterPhotoViewerState(viewer, params);
375
375
 
376
- // Restore selected picture
377
- let pic = params.picture || params.pic;
378
- if(pic && params.focus && params.focus == "meta") {
379
- // TODO open expanded legend
380
- //viewer.psv.addEventListener("picture-loaded", () => viewer._showPictureMetadata(), { once: true });
381
- }
382
-
383
376
  // Change focus
384
377
  if(params.focus === "map" && viewer?.map) {
385
378
  viewer.setPopup(false);
@@ -73,7 +73,6 @@ export default class URLHandler extends EventTarget {
73
73
  hashParts.map = this.currentMapString();
74
74
  hashParts.focus = "pic";
75
75
  if(this._parent.isMapWide()) { hashParts.focus = "map"; }
76
- if(this._parent.popup.hasAttribute("visible")) { hashParts.focus = "meta"; }
77
76
  if(this._parent.map.hasTwoBackgrounds() && this._parent.map.getBackground()) {
78
77
  hashParts.background = this._parent.map.getBackground();
79
78
  }
@@ -333,18 +332,11 @@ export default class URLHandler extends EventTarget {
333
332
  const prevPic = this.currentURLParams().pic || "";
334
333
  const nextPic = this._parent?.psv?.getPictureId?.() || "";
335
334
 
336
- const prevFocus = this.currentURLParams().focus || "";
337
- const nextFocus = nextUrl.search.includes("focus=meta") ? "meta" : (nextUrl.search.includes("focus=map") ? "map" : "pic");
338
-
339
335
  try {
340
336
  // If different pic, add entry in browser history
341
337
  if(prevPic != nextPic) {
342
338
  window.history.pushState(window.history.state, null, nextUrl.href);
343
339
  }
344
- // If metadata popup is open, come back to pic/map
345
- else if(prevFocus != nextFocus && nextFocus == "meta") {
346
- window.history.pushState(window.history.state, null, nextUrl.href);
347
- }
348
340
  // If same pic, just update viewer params
349
341
  else {
350
342
  window.history.replaceState(window.history.state, null, nextUrl.href);
@@ -461,14 +461,6 @@ describe("alterViewerState", () => {
461
461
  expect(viewer.select).toHaveBeenCalledWith();
462
462
  });
463
463
 
464
- // it("should show picture metadata when focus is meta and picture is loaded", () => {
465
- // const params = { picture: "pic1", focus: "meta" };
466
- // alterViewerState(viewer, params);
467
- // expect(viewer.psv.addEventListener).toHaveBeenCalledWith("picture-loaded", expect.any(Function), { once: true });
468
- // const listener = viewer.psv.addEventListener.mock.calls[0][1];
469
- // listener();
470
- // });
471
-
472
464
  it("should set focus to map when focus param is map and map exists", () => {
473
465
  const params = { focus: "map", forceFocus: true };
474
466
  viewer.map = {};
@@ -160,7 +160,7 @@ describe("nextURLString", () => {
160
160
  };
161
161
  const uh = new URLHandler(v);
162
162
  uh.currentMapString = () => "18/0.5/-12";
163
- expect(uh.nextURLString()).toBe("?focus=meta&map=18/0.5/-12");
163
+ expect(uh.nextURLString()).toBe("?focus=pic&map=18/0.5/-12");
164
164
  });
165
165
 
166
166
  it("works with nav", () => {