@panoramax/web-viewer 5.0.0-develop-d26305dd → 5.0.0-develop-be5ba1a7

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.
Files changed (153) hide show
  1. package/build/cjs/index.js +1 -1
  2. package/build/cjs/index_photoviewer.js +1 -1
  3. package/build/esm/components/core/Basic.js +1 -1
  4. package/build/esm/translations/el.json +92 -1
  5. package/package.json +1 -1
  6. package/build/bundle.cjs +0 -3399
  7. package/build/bundle.cjs.map +0 -1
  8. package/build/bundle_photoviewer.cjs +0 -2510
  9. package/build/bundle_photoviewer.cjs.map +0 -1
  10. package/build/components/core/Basic.css +0 -56
  11. package/build/components/core/Basic.js +0 -378
  12. package/build/components/core/CoverageMap.css +0 -10
  13. package/build/components/core/CoverageMap.js +0 -169
  14. package/build/components/core/Editor.css +0 -33
  15. package/build/components/core/Editor.js +0 -398
  16. package/build/components/core/PhotoViewer.css +0 -70
  17. package/build/components/core/PhotoViewer.js +0 -650
  18. package/build/components/core/Viewer.css +0 -130
  19. package/build/components/core/Viewer.js +0 -711
  20. package/build/components/core/index.js +0 -10
  21. package/build/components/index.js +0 -11
  22. package/build/components/index_photoviewer.js +0 -6
  23. package/build/components/layout/BottomDrawer.js +0 -258
  24. package/build/components/layout/CorneredGrid.js +0 -143
  25. package/build/components/layout/Mini.js +0 -121
  26. package/build/components/layout/Tabs.js +0 -140
  27. package/build/components/layout/index.js +0 -9
  28. package/build/components/menus/LocationPrecisionDoc.js +0 -42
  29. package/build/components/menus/MapBackground.js +0 -110
  30. package/build/components/menus/MapFilters.js +0 -567
  31. package/build/components/menus/MapLayers.js +0 -238
  32. package/build/components/menus/MapLegend.js +0 -68
  33. package/build/components/menus/MiniPictureLegend.js +0 -73
  34. package/build/components/menus/PictureLegend.js +0 -379
  35. package/build/components/menus/PictureMetadata.js +0 -380
  36. package/build/components/menus/PlayerOptions.js +0 -93
  37. package/build/components/menus/QualityScoreDoc.js +0 -42
  38. package/build/components/menus/ReportForm.js +0 -132
  39. package/build/components/menus/SemanticsDoc.js +0 -38
  40. package/build/components/menus/SemanticsDownload.js +0 -33
  41. package/build/components/menus/SemanticsFilters.js +0 -153
  42. package/build/components/menus/SemanticsList.js +0 -413
  43. package/build/components/menus/SemanticsMetadata.js +0 -368
  44. package/build/components/menus/Share.js +0 -105
  45. package/build/components/menus/index.js +0 -22
  46. package/build/components/menus/index_photoviewer.js +0 -11
  47. package/build/components/styles.js +0 -557
  48. package/build/components/ui/AnnotationsSwitch.js +0 -159
  49. package/build/components/ui/Button.js +0 -77
  50. package/build/components/ui/ButtonGroup.css +0 -59
  51. package/build/components/ui/ButtonGroup.js +0 -69
  52. package/build/components/ui/CopyButton.js +0 -110
  53. package/build/components/ui/Grade.js +0 -54
  54. package/build/components/ui/GradeFilter.js +0 -122
  55. package/build/components/ui/IconSwitch.js +0 -193
  56. package/build/components/ui/LinkButton.js +0 -67
  57. package/build/components/ui/ListGroup.js +0 -66
  58. package/build/components/ui/ListItem.js +0 -90
  59. package/build/components/ui/Loader.js +0 -203
  60. package/build/components/ui/Map.css +0 -63
  61. package/build/components/ui/Map.js +0 -853
  62. package/build/components/ui/MapMore.js +0 -175
  63. package/build/components/ui/Photo.css +0 -50
  64. package/build/components/ui/Photo.js +0 -1502
  65. package/build/components/ui/Popup.js +0 -145
  66. package/build/components/ui/ProgressBar.js +0 -104
  67. package/build/components/ui/QualityScore.js +0 -147
  68. package/build/components/ui/SearchBar.js +0 -374
  69. package/build/components/ui/SemanticsEditor.js +0 -191
  70. package/build/components/ui/SemanticsTable.js +0 -88
  71. package/build/components/ui/Switch.js +0 -139
  72. package/build/components/ui/TogglableGroup.js +0 -157
  73. package/build/components/ui/index.js +0 -29
  74. package/build/components/ui/index_photoviewer.js +0 -21
  75. package/build/components/ui/widgets/CopyCoordinates.js +0 -75
  76. package/build/components/ui/widgets/GeoSearch.css +0 -21
  77. package/build/components/ui/widgets/GeoSearch.js +0 -150
  78. package/build/components/ui/widgets/Legend.js +0 -190
  79. package/build/components/ui/widgets/LevelSelect.css +0 -51
  80. package/build/components/ui/widgets/LevelSelect.js +0 -143
  81. package/build/components/ui/widgets/MapFiltersButton.js +0 -114
  82. package/build/components/ui/widgets/MapLayersButton.js +0 -79
  83. package/build/components/ui/widgets/OSMEditors.js +0 -155
  84. package/build/components/ui/widgets/PictureLegendActions.js +0 -99
  85. package/build/components/ui/widgets/Player.css +0 -7
  86. package/build/components/ui/widgets/Player.js +0 -154
  87. package/build/components/ui/widgets/SemanticsFiltersButton.js +0 -65
  88. package/build/components/ui/widgets/Zoom.js +0 -84
  89. package/build/components/ui/widgets/index.js +0 -16
  90. package/build/components/ui/widgets/index_photoviewer.js +0 -7
  91. package/build/img/arrow_360.svg +0 -14
  92. package/build/img/arrow_flat.svg +0 -11
  93. package/build/img/arrow_triangle.svg +0 -9
  94. package/build/img/arrow_turn.svg +0 -8
  95. package/build/img/bg_aerial.jpg +0 -0
  96. package/build/img/bg_streets.jpg +0 -0
  97. package/build/img/loader_base.jpg +0 -0
  98. package/build/img/logo_dead.svg +0 -91
  99. package/build/img/marker.svg +0 -17
  100. package/build/img/marker_blue.svg +0 -20
  101. package/build/img/osm.svg +0 -49
  102. package/build/img/panoramax.svg +0 -13
  103. package/build/img/switch_big.svg +0 -54
  104. package/build/img/switch_mini.svg +0 -48
  105. package/build/img/wd.svg +0 -1
  106. package/build/index_photoviewer.js +0 -4
  107. package/build/package.json +0 -148
  108. package/build/servers.js +0 -14
  109. package/build/translations/ar.json +0 -1
  110. package/build/translations/be.json +0 -257
  111. package/build/translations/br.json +0 -81
  112. package/build/translations/cy.json +0 -117
  113. package/build/translations/da.json +0 -300
  114. package/build/translations/de.json +0 -309
  115. package/build/translations/en.json +0 -294
  116. package/build/translations/eo.json +0 -235
  117. package/build/translations/es.json +0 -292
  118. package/build/translations/fi.json +0 -1
  119. package/build/translations/fr.json +0 -294
  120. package/build/translations/hr.json +0 -294
  121. package/build/translations/hu.json +0 -294
  122. package/build/translations/it.json +0 -306
  123. package/build/translations/ja.json +0 -182
  124. package/build/translations/ko.json +0 -1
  125. package/build/translations/nl.json +0 -305
  126. package/build/translations/nn.json +0 -1
  127. package/build/translations/pl.json +0 -169
  128. package/build/translations/pt.json +0 -296
  129. package/build/translations/pt_BR.json +0 -304
  130. package/build/translations/sv.json +0 -182
  131. package/build/translations/ti.json +0 -9
  132. package/build/translations/tr.json +0 -297
  133. package/build/translations/uk.json +0 -268
  134. package/build/translations/zh_Hant.json +0 -309
  135. package/build/utils/API.js +0 -928
  136. package/build/utils/InitParameters.js +0 -521
  137. package/build/utils/MapStyleComposer.js +0 -889
  138. package/build/utils/PanoraMapProtocol.js +0 -49
  139. package/build/utils/PhotoAdapter.js +0 -49
  140. package/build/utils/PresetsManager.js +0 -148
  141. package/build/utils/SemanticsMapProtocol.js +0 -144
  142. package/build/utils/URLHandler.js +0 -426
  143. package/build/utils/geocoder.js +0 -203
  144. package/build/utils/i18n.js +0 -128
  145. package/build/utils/index.js +0 -17
  146. package/build/utils/index_photoviewer.js +0 -14
  147. package/build/utils/indoor.js +0 -200
  148. package/build/utils/map.js +0 -788
  149. package/build/utils/picture.js +0 -507
  150. package/build/utils/semantics.js +0 -321
  151. package/build/utils/services.js +0 -148
  152. package/build/utils/utils.js +0 -433
  153. package/build/utils/widgets.js +0 -110
@@ -1,380 +0,0 @@
1
- import { LitElement, css, nothing } from "lit";
2
- import { html, unsafeStatic } from "lit/static-html.js";
3
- import { fa, onceParentAvailable, createWebComp } from "../../utils/widgets.js";
4
- import {
5
- faCamera, faImage, faImages, faInfoCircle, faLocationDot,
6
- faMedal, faQuestion, faScroll, faTags,
7
- } from "@fortawesome/free-solid-svg-icons";
8
- import { dataBlocks, faSvg, hidden, textarea, titles } from "../styles.js";
9
- import { getGPSPrecision } from "../../utils/picture.js";
10
- import { PanoramaxMetaCatalogURL } from "../../utils/services.js";
11
- import {
12
- QUALITYSCORE_GPS_VALUES, QUALITYSCORE_POND_GPS, QUALITYSCORE_POND_RES,
13
- QUALITYSCORE_RES_360_VALUES, QUALITYSCORE_RES_FLAT_VALUES, getGrade
14
- } from "../../utils/utils.js";
15
-
16
- const missing = () => fa(faQuestion, {styles: {height: "16px"}});
17
-
18
- /**
19
- * Picture metadata displays detailed info about a single picture (ID, capture context, EXIF attributes...).
20
- * @class Panoramax.components.menus.PictureMetadata
21
- * @element pnx-picture-metadata
22
- * @extends [lit.LitElement](https://lit.dev/docs/api/LitElement/)
23
- * @example
24
- * ```html
25
- * <pnx-picture-metadata ._parent=${viewer} />
26
- * ```
27
- */
28
- export default class PictureMetadata extends LitElement {
29
- /** @private */
30
- static styles = [ faSvg, titles, textarea, hidden, dataBlocks, css`
31
- div[slot="content"] {
32
- padding: 5px 10px;
33
- background-color: #ededed;
34
- }
35
-
36
- .data-block {
37
- min-width: 50%;
38
- }
39
-
40
- pnx-semantics-table {
41
- overflow-x: auto;
42
- display: block;
43
- }
44
- ` ];
45
-
46
- /**
47
- * Component properties.
48
- * @memberof Panoramax.components.menus.PictureMetadata#
49
- * @type {Object}
50
- * @property {boolean} [block-editor=false] Set to true to avoid going beyond semantics editor
51
- */
52
- static properties = {
53
- _meta: {state: true},
54
- "block-editor": { type: Boolean },
55
- };
56
-
57
- /** @private */
58
- connectedCallback() {
59
- super.connectedCallback();
60
-
61
- const gototags = () => {
62
- const tabs = this.shadowRoot.querySelector("pnx-tabs");
63
- if(tabs) { tabs.setAttribute("activeTabIndex", 4); }
64
- };
65
-
66
- window.navigation?.addEventListener("navigate", () => {
67
- this.requestUpdate();
68
- });
69
-
70
- onceParentAvailable(this).then(() => {
71
- this._meta = this._parent?.psv?.getPictureMetadata();
72
- this._parent?.oncePSVReady?.().then(() => {
73
- this._parent.psv.addEventListener("picture-loaded", () => {
74
- this._meta = this._parent.psv.getPictureMetadata();
75
- });
76
- if(!this._parent._initParams.getParentPostInit().skipTagsMenuOpening) {
77
- this._parent.psv.addEventListener("annotation-focused", gototags);
78
- this._parent.psv.addEventListener("annotations-toggled", e => {
79
- if(e.detail.visible) {
80
- gototags();
81
- }
82
- });
83
- if(this._parent.psv.getSelectedAnnotations().length > 0) {
84
- gototags();
85
- }
86
- }
87
- });
88
- });
89
- }
90
-
91
- /** @private */
92
- _onQualityScoreClick() {
93
- const qsTab = this.shadowRoot.querySelector("pnx-tabs");
94
- if(qsTab) {
95
- qsTab.setAttribute("activeTabIndex", 3);
96
- }
97
- }
98
-
99
- /** @private */
100
- _onCaptureDateClick() {
101
- const qsTab = this.shadowRoot.querySelector("pnx-tabs");
102
- if(qsTab) {
103
- qsTab.setAttribute("activeTabIndex", 1);
104
- }
105
- }
106
-
107
- /** @private */
108
- _toTab(title, data) {
109
- return html`
110
- <h4 slot="title">${title}</h4>
111
- <div slot="content" class="data-blocks">
112
- ${data.filter(b => b).map(b => html`<div class="data-block" style=${b.style}>
113
- <h5>${b.title}</h5>
114
- <div style=${b.content_style} @click=${b.click}>${b.content}</div>
115
- </div>`)}
116
- </div>
117
- `;
118
- }
119
-
120
- /** @private */
121
- render() {
122
- if(!this._meta) { return nothing; }
123
-
124
- const lang = this._parent?.lang || window.navigator.language;
125
-
126
- // Generic information
127
- const persOrient = this._meta?.properties?.["pers:interior_orientation"];
128
- const makeModel = [persOrient.camera_manufacturer, persOrient.camera_model].filter(v => v).join(" ");
129
- const focal = persOrient?.focal_length ? `${persOrient?.focal_length} mm` : missing();
130
- let resmp = persOrient?.["sensor_array_dimensions"];
131
- if(resmp) { resmp = `${resmp[0]} x ${resmp[1]} px (${Math.floor(resmp[0] * resmp[1] / 1000000)} Mpx)`;}
132
- let pictype = this._parent?._t.pnx.picture_flat;
133
- let pictypelong = this._parent?._t.pnx.picture_flat_long;
134
- let picFov = persOrient?.["field_of_view"]; // Use raw value instead of horizontalFov to avoid default showing up
135
- if(picFov !== null && picFov !== undefined) {
136
- if(picFov === 360) {
137
- pictype = this._parent?._t.pnx.picture_360;
138
- pictypelong = this._parent?._t.pnx.picture_360_long;
139
- }
140
- else { pictype += ` (${picFov}°)`; }
141
- }
142
-
143
- // Camera tab
144
- const cameraData = [
145
- { title: this._parent?._t.pnx.metadata_camera_make, content: persOrient?.camera_manufacturer || missing() },
146
- { title: this._parent?._t.pnx.metadata_camera_model, content: persOrient?.camera_model || missing() },
147
- { title: this._parent?._t.pnx.metadata_camera_type, content: pictype },
148
- { title: this._parent?._t.pnx.metadata_camera_resolution, content: resmp || missing() },
149
- { title: this._parent?._t.pnx.metadata_camera_focal_length, content: focal },
150
- // Capture date
151
- this._meta?.caption?.date && {
152
- title: this._parent?._t.pnx.metadata_general_date,
153
- content: html`
154
- <strong>${new Intl.DateTimeFormat(lang, {
155
- timeZone: this._meta.caption.tz,
156
- dateStyle: "short"
157
- }).format(this._meta.caption.date)}</strong>
158
- <br />${new Intl.DateTimeFormat(lang, {
159
- timeZone: this._meta.caption.tz,
160
- hour: "numeric",
161
- minute: "numeric",
162
- second: "numeric",
163
- fractionalSecondDigits: 3,
164
- timeZoneName: "longOffset"
165
- }).format(this._meta.caption.date)}
166
- `
167
- }
168
- ];
169
-
170
- // Location tab
171
- const orientation = this._meta?.properties?.["view:azimuth"] !== undefined && `${this._meta.properties["view:azimuth"]}°`;
172
- const locationData = [
173
- {
174
- title: this._parent?._t.pnx.metadata_location_coordinates,
175
- content: html`
176
- ${this._meta.gps[0].toFixed(5)}, ${this._meta.gps[1].toFixed(5)}
177
- <pnx-copy-coordinates
178
- ._parent=${this._parent}
179
- .gps=${this._meta.gps}
180
- style="margin-left: 10px"
181
- ></pnx-copy-coordinates>
182
- `,
183
- style: "width: 100%"
184
- },
185
- { title: this._parent?._t.pnx.metadata_location_orientation, content: orientation || missing() },
186
- { title: this._parent?._t.pnx.metadata_location_precision, content: getGPSPrecision(this._meta) || missing() },
187
- ];
188
-
189
- // Quality tab
190
- const hasQualityScore = (
191
- this._parent?.map?._hasQualityScore?.()
192
- || this._meta?.properties?.["quality:horizontal_accuracy"]
193
- || this._meta?.properties?.["panoramax:horizontal_pixel_density"]
194
- );
195
- let qualityData, generalGrade;
196
- if(hasQualityScore) {
197
- const gpsGrade = getGrade(QUALITYSCORE_GPS_VALUES, this._meta?.properties?.["quality:horizontal_accuracy"]);
198
- const resGrade = getGrade(
199
- this._meta?.horizontalFov === 360 ? QUALITYSCORE_RES_360_VALUES : QUALITYSCORE_RES_FLAT_VALUES,
200
- this._meta?.properties?.["panoramax:horizontal_pixel_density"]
201
- );
202
-
203
- // Note: score is also calculated in utils/map code
204
- generalGrade = Math.round((resGrade || 1) * QUALITYSCORE_POND_RES + (gpsGrade || 1) * QUALITYSCORE_POND_GPS);
205
-
206
- qualityData = [
207
- {
208
- title: html`
209
- ${this._parent?._t.pnx.metadata_quality_score}
210
- <pnx-button
211
- title="${this._parent?._t.pnx.metadata_quality_help}"
212
- kind="superinline"
213
- @click=${() => this._parent?._showQualityScoreDoc()}
214
- >
215
- ${fa(faInfoCircle)}
216
- </pnx-button>
217
- `,
218
- content: html`<pnx-quality-score grade=${generalGrade} style="font-size: 16px"></pnx-quality-score>`,
219
- style: "width: 100%"
220
- },
221
- {
222
- title: this._parent?._t.pnx.metadata_quality_gps_score,
223
- content: createWebComp("pnx-grade", { stars: gpsGrade, _t: this._parent?._t })
224
- },
225
- {
226
- title: this._parent?._t.pnx.metadata_quality_resolution_score,
227
- content: createWebComp("pnx-grade", { stars: resGrade, _t: this._parent?._t })
228
- },
229
- ];
230
- }
231
-
232
- // EXIF data
233
- const exifData = Object.entries(this._meta.properties.exif)
234
- .sort()
235
- .filter(([, value]) => value)
236
- .map(([key, value]) => {
237
- if(JSON.stringify(value).includes("\\u")) {
238
- value = JSON.stringify(value).replace(/\\u[0-9A-Fa-f]{4}/g, unicode => (
239
- " 0x" + parseInt(unicode.slice(2), 16).toString(16).toUpperCase().padStart(4, "0")
240
- )).slice(1, -1).trim();
241
- }
242
- return {
243
- title: key,
244
- content: value.length > 30 ? html`<textarea readonly .value=${value}></textarea>`: value,
245
- style: value.length > 30 ? "width: 100%" : undefined
246
- };
247
- });
248
- exifData.unshift({
249
- content: html`
250
- <pnx-link-button
251
- size="sm"
252
- target="_blank"
253
- href="https://exiv2.org/metadata.html"
254
- title=${this._parent?._t.pnx.metadata_exif_doc_title}
255
- >${fa(faInfoCircle)} ${this._parent?._t.pnx.metadata_exif_doc}</pnx-link-button>
256
- `,
257
- style: "width: 100%"
258
- });
259
-
260
- // General metadata
261
- const overview = [
262
- // Producer
263
- this._meta?.caption?.producer?.length > 0 && {
264
- title: this._parent?._t.pnx.metadata_general_author,
265
- content: html`
266
- <strong>${this._meta.caption.producer[this._meta.caption.producer.length - 1]}</strong>
267
- ${this._meta.caption.producer.length > 1 ? html`<br />${this._meta.caption.producer.slice(0, -1).join(", ")}` : nothing}
268
- `
269
- },
270
- // Capture date
271
- this._meta?.caption?.date && {
272
- title: this._parent?._t.pnx.metadata_general_date,
273
- click: this._onCaptureDateClick,
274
- content_style: "cursor: pointer",
275
- content: html`
276
- <strong>${new Intl.DateTimeFormat(lang, {timeZone: this._meta.caption.tz, dateStyle: "long"}).format(this._meta.caption.date)}</strong>
277
- <br />${new Intl.DateTimeFormat(lang, {timeZone: this._meta.caption.tz, hour: "numeric",minute:"numeric", second: "numeric"}).format(this._meta.caption.date)}
278
- `
279
- },
280
- // Camera
281
- persOrient && {
282
- title: this._parent?._t.pnx.metadata_camera,
283
- content: html`
284
- <strong>${makeModel.length > 0 ? makeModel : missing()}</strong>
285
- <br />${pictypelong}
286
- `
287
- },
288
- // License
289
- this._meta?.caption?.license && {
290
- title: this._parent?._t.pnx.metadata_general_license,
291
- content: html`${unsafeStatic(this._meta.caption.license)}`
292
- },
293
- // Quality score
294
- hasQualityScore && {
295
- title: this._parent?._t.pnx.metadata_quality,
296
- click: this._onQualityScoreClick,
297
- content: html`<pnx-quality-score
298
- grade=${generalGrade}
299
- style="font-size: 14px; cursor: pointer"
300
- />`
301
- },
302
- // Copy ID
303
- {
304
- title: this._parent?._t.pnx.metadata_general_copy_id,
305
- content_style: "display: flex; gap: 5px;",
306
- content: html`
307
- <pnx-copy-button
308
- kind="outline"
309
- size="sm"
310
- ._t=${this._parent?._t}
311
- text=${this._meta.id}
312
- title=${this._meta.id}
313
- style="flex: 1"
314
- >
315
- ${fa(faImage)} ${this._parent?._t.pnx.metadata_general_picid}
316
- </pnx-copy-button>
317
- <pnx-copy-button
318
- kind="outline"
319
- size="sm"
320
- ._t=${this._parent?._t}
321
- text=${this._meta.sequence.id}
322
- title=${this._meta.sequence.id}
323
- style="flex: 1"
324
- >
325
- ${fa(faImages)} ${this._parent?._t.pnx.metadata_general_seqid}
326
- </pnx-copy-button>
327
- `
328
- },
329
- this._meta?.origInstance && {
330
- title: this._parent?._t.pnx.metadata_general_instance,
331
- content: html`<strong>
332
- <a href=${this._meta.origInstance.href+window.location.search} target="_blank" style="text-decoration: none">
333
- <img
334
- src=${PanoramaxMetaCatalogURL()+"/api/instances/"+this._meta.origInstance.instance_name+"/logo"}
335
- style="height: 30px; max-width: 150px; vertical-align: middle"
336
- alt=""
337
- />
338
- <span style="text-decoration: underline">
339
- ${this._meta.origInstance.instance_name || this._meta.origInstance.href.replace(/^http.?:\/\//, "")}
340
- </span>
341
- </a>
342
- </strong>`
343
- }
344
- ];
345
-
346
- return html`<pnx-tabs .hideNav=${this["block-editor"]}>
347
- ${this._toTab( // General
348
- html`${fa(faImage)} ${this._parent?._t.pnx.metadata_summary}`,
349
- overview
350
- )}
351
-
352
- ${this._toTab( // Camera
353
- html`${fa(faCamera)} ${this._parent?._t.pnx.metadata_camera}`,
354
- cameraData
355
- )}
356
-
357
- ${this._toTab( // Position
358
- html`${fa(faLocationDot)} ${this._parent?._t.pnx.metadata_location}`,
359
- locationData
360
- )}
361
-
362
- ${hasQualityScore ? this._toTab( // Quality
363
- html`${fa(faMedal)} ${this._parent?._t.pnx.metadata_quality}`,
364
- qualityData
365
- ) : nothing}
366
-
367
- <h4 slot="title">${fa(faTags)} ${this._parent?._t.pnx.semantics_title}</h4>
368
- <div slot="content" class="data-blocks">
369
- <pnx-semantics-metadata ._parent=${this._parent}></pnx-semantics-metadata>
370
- </div>
371
-
372
- ${this._meta.properties?.exif ? this._toTab( // EXIF
373
- html`${fa(faScroll)} ${this._parent?._t.pnx.metadata_exif}`,
374
- exifData
375
- ) : nothing}
376
- </pnx-tabs>`;
377
- }
378
- }
379
-
380
- customElements.define("pnx-picture-metadata", PictureMetadata);
@@ -1,93 +0,0 @@
1
- import { LitElement, css, html } from "lit";
2
- import { faSvg } from "../styles.js";
3
- import { faLightbulb, faPersonBiking, faRocket } from "@fortawesome/free-solid-svg-icons";
4
- import { PIC_MAX_STAY_DURATION } from "../ui/Photo.js";
5
- import { fa, onceParentAvailable } from "../../utils/widgets.js";
6
-
7
- /**
8
- * Player Options menu displays player speed and contrast settings.
9
- * @class Panoramax.components.menus.PlayerOptions
10
- * @element pnx-player-options
11
- * @extends [lit.LitElement](https://lit.dev/docs/api/LitElement/)
12
- * @example
13
- * ```html
14
- * <pnx-player-options ._parent=${viewer} />
15
- * ```
16
- */
17
- export default class PlayerOptions extends LitElement {
18
- /** @private */
19
- static styles = [ faSvg, css`
20
- :host {
21
- display: flex;
22
- flex-direction: row;
23
- align-items: center;
24
- justify-content: center;
25
- gap: 15px;
26
- padding: 5px 15px;
27
- }
28
-
29
- .pnx-input-range {
30
- display: flex;
31
- justify-content: space-between;
32
- gap: 10px;
33
- align-items: center;
34
- width: 100%;
35
- }
36
- ` ];
37
-
38
- /** @private */
39
- connectedCallback() {
40
- super.connectedCallback();
41
- onceParentAvailable(this).then(() => this._parent?.psv?.addEventListener("transition-duration-changed", e => {
42
- this.renderRoot.querySelector("#pnx-player-speed").value = PIC_MAX_STAY_DURATION - e.detail.value;
43
- }));
44
- }
45
-
46
- /** @private */
47
- _onSpeedChange(e) {
48
- const newSpeed = PIC_MAX_STAY_DURATION - e.target.value;
49
- this._parent?.psv?.setTransitionDuration(newSpeed);
50
- }
51
-
52
- /** @private */
53
- _onContrastClick() {
54
- const btn = this.renderRoot.querySelector("#pnx-player-contrast");
55
- if(btn.getAttribute("active") == "true") {
56
- btn.removeAttribute("active");
57
- this._parent?.psv?.setHigherContrast(false);
58
- }
59
- else {
60
- btn.setAttribute("active", "true");
61
- this._parent?.psv?.setHigherContrast(true);
62
- }
63
- }
64
-
65
- /** @private */
66
- render() {
67
- return html`
68
- <div class="pnx-input-range" title="${this._parent?._t.pnx.sequence_speed}">
69
- ${fa(faPersonBiking)}
70
- <input
71
- id="pnx-player-speed"
72
- type="range" name="speed"
73
- min="0" max="${PIC_MAX_STAY_DURATION - 100}"
74
- value="${PIC_MAX_STAY_DURATION - this._parent?.psv.getTransitionDuration()}"
75
- title="${this._parent?._t.pnx.sequence_speed}"
76
- style="width: 100%;"
77
- @change=${this._onSpeedChange}
78
- />
79
- ${fa(faRocket)}
80
- </div>
81
- <pnx-button
82
- id="pnx-player-contrast"
83
- title="${this._parent?._t.pnx.contrast}"
84
- kind="outline"
85
- @click=${this._onContrastClick}
86
- >
87
- ${fa(faLightbulb)}
88
- </pnx-button>
89
- `;
90
- }
91
- }
92
-
93
- customElements.define("pnx-player-options", PlayerOptions);
@@ -1,42 +0,0 @@
1
- import { LitElement, html } from "lit";
2
- import { docPopup, faSvg, titles } from "../styles.js";
3
- import { fa } from "../../utils/widgets.js";
4
- import { faExternalLinkAlt, faMedal } from "@fortawesome/free-solid-svg-icons";
5
-
6
- /**
7
- * Quality Score Doc displays a synthetic summary of how Quality Score is computed.
8
- * @class Panoramax.components.menus.QualityScoreDoc
9
- * @element pnx-quality-score-doc
10
- * @extends [lit.LitElement](https://lit.dev/docs/api/LitElement/)
11
- * @example
12
- * ```html
13
- * <pnx-quality-score-doc ._t=${viewer._t} />
14
- * ```
15
- */
16
- export default class QualityScoreDoc extends LitElement {
17
- static styles = [ titles, faSvg, docPopup ];
18
-
19
- render() {
20
- return html`
21
- <h4>${fa(faMedal)} ${this._t?.pnx.filter_qualityscore}</h4>
22
- <p>${this._t?.pnx.qualityscore_doc_1}</p>
23
- <p>${this._t?.pnx.qualityscore_doc_2}</p>
24
- <pnx-quality-score grade=""></pnx-quality-score>
25
- <p>${this._t?.pnx.qualityscore_doc_3}</p>
26
- <p>${this._t?.pnx.qualityscore_doc_4}</p>
27
- <ul>
28
- <li>${this._t?.pnx.qualityscore_doc_41}</li>
29
- <li>${this._t?.pnx.qualityscore_doc_42}</li>
30
- </ul>
31
- <p>${this._t?.pnx.qualityscore_doc_5}</p>
32
- <pnx-link-button
33
- href="https://docs.panoramax.fr/pictures-metadata/quality_score/"
34
- target="_blank"
35
- kind="outline"
36
- style="width: 100%"
37
- >${fa(faExternalLinkAlt)} ${this._t?.pnx.popup_details_link}</pnx-link-button>
38
- `;
39
- }
40
- }
41
-
42
- customElements.define("pnx-quality-score-doc", QualityScoreDoc);
@@ -1,132 +0,0 @@
1
- import { LitElement, css, html, nothing } from "lit";
2
- import { faSvg, input, select, textarea, titles } from "../styles.js";
3
- import { fa } from "../../utils/widgets.js";
4
- import {
5
- faAt, faCircleInfo, faCommentDots,
6
- faPaperPlane, faTriangleExclamation,
7
- } from "@fortawesome/free-solid-svg-icons";
8
- import { getUserAccount } from "../../utils/utils.js";
9
-
10
- const REPORT_NATURE = [
11
- "", "blur_missing", "blur_excess", "inappropriate", "privacy",
12
- "picture_low_quality", "mislocated", "copyright", "other"
13
- ];
14
-
15
- /**
16
- * Report Form displays a form to send issues about pictures.
17
- * @class Panoramax.components.menus.ReportForm
18
- * @element pnx-report-form
19
- * @extends [lit.LitElement](https://lit.dev/docs/api/LitElement/)
20
- * @example
21
- * ```html
22
- * <pnx-report-form ._parent=${viewer} />
23
- * ```
24
- */
25
- export default class ReportForm extends LitElement {
26
- /** @private */
27
- static styles = [ titles, faSvg, select, textarea, input, css`
28
- .group {
29
- margin-bottom: 10px;
30
- }
31
-
32
- .group:not(.group-inline) label {
33
- margin-bottom: 5px;
34
- display: inline-block;
35
- }
36
- ` ];
37
-
38
- /** @private */
39
- static properties = {
40
- mode: {state: true},
41
- failure: {state: true},
42
- };
43
-
44
- /** @private */
45
- _onSubmit(e) {
46
- e.preventDefault();
47
-
48
- const picMeta = this._parent?.psv?.getPictureMetadata();
49
- const data = Object.fromEntries(new FormData(e.target));
50
- const params = {
51
- issue: data.issue,
52
- picture_id: data["whole-sequence"] ? null : picMeta?.id,
53
- reporter_comments: data.comments,
54
- reporter_email: data.email,
55
- sequence_id: picMeta?.sequence?.id
56
- };
57
-
58
- this.mode = "wait";
59
-
60
- // Call API
61
- this._parent?.getAPI().sendReport(params).then(() => {
62
- this.mode = "success";
63
- }).catch(e => {
64
- console.error(e);
65
- this.mode = "failure";
66
- this.failure = e;
67
- });
68
- }
69
-
70
- /** @private */
71
- render() {
72
- const userAccount = getUserAccount();
73
-
74
- if(this.mode) {
75
- return html`
76
- <h4>${fa(faTriangleExclamation)} ${this._parent?._t.pnx.report}</h4>
77
- <p>
78
- ${this.mode === "wait" ? this._parent?._t.pnx.report_wait : nothing}
79
- ${this.mode === "success" ? this._parent?._t.pnx.report_success : nothing}
80
- ${this.mode === "failure" ? this._parent?._t.pnx.report_failure.replace("{e}", this.failure) : nothing}
81
- </p>
82
- `;
83
- }
84
-
85
- return html`
86
- <h4>${fa(faTriangleExclamation)} ${this._parent?._t.pnx.report}</h4>
87
-
88
- ${userAccount && this._parent?._t ? html`
89
- <p>${this._parent?._t.pnx.report_auth.replace("{a}", userAccount.name)}</p>
90
- ` : nothing}
91
-
92
- <form @submit=${this._onSubmit.bind(this)}>
93
- <div class="group">
94
- <label for="issue">${fa(faCircleInfo)} ${this._parent?._t.pnx.report_nature_label}</label>
95
- <select name="issue" id="issue" required class="pnx-100w">
96
- ${REPORT_NATURE.map(nature => html`
97
- <option
98
- value=${nature}
99
- ${nature === "" ? html`disabled selected hidden` : nothing}
100
- >
101
- ${this._parent?._t.pnx.report_nature[nature]}
102
- </option>
103
- `)}
104
- </select>
105
- </div>
106
-
107
- <div class="group group-inline">
108
- <input name="whole-sequence" id="whole-sequence" type="checkbox" />
109
- <label for="whole-sequence">${this._parent?._t.pnx.report_whole_sequence}</label>
110
- </div>
111
-
112
- <div class="group">
113
- <label for="comments">${fa(faCommentDots)} ${this._parent?._t.pnx.report_details}</label>
114
- <textarea name="comments" id="comments" placeholder=${this._parent?._t.pnx.report_details_placeholder}></textarea>
115
- </div>
116
-
117
- ${!userAccount ? html`
118
- <div class="group">
119
- <label for="email">${fa(faAt)} ${this._parent?._t.pnx.report_email}</label>
120
- <input type="email" name="email" id="email" placeholder=${this._parent?._t.pnx.report_email_placeholder} class="pnx-100w" />
121
- </div>
122
- `: nothing}
123
-
124
- <pnx-button type="submit" style="width: 100%">
125
- ${fa(faPaperPlane)} ${this._parent?._t.pnx.report_submit}
126
- </pnx-button>
127
- </form>
128
- `;
129
- }
130
- }
131
-
132
- customElements.define("pnx-report-form", ReportForm);
@@ -1,38 +0,0 @@
1
- import { LitElement, html } from "lit";
2
- import { docPopup, faSvg, titles } from "../styles.js";
3
- import { fa } from "../../utils/widgets.js";
4
- import { faExternalLinkAlt, faTags } from "@fortawesome/free-solid-svg-icons";
5
-
6
- /**
7
- * Semantics Doc displays a synthetic summary of what are semantics and how to use it.
8
- * @class Panoramax.components.menus.SemanticsDoc
9
- * @element pnx-semantics-doc
10
- * @extends [lit.LitElement](https://lit.dev/docs/api/LitElement/)
11
- * @example
12
- * ```html
13
- * <pnx-semantics-doc ._t=${viewer._t} />
14
- * ```
15
- */
16
- export default class SemanticsDoc extends LitElement {
17
- static styles = [ titles, faSvg, docPopup ];
18
-
19
- render() {
20
- return html`
21
- <h4>${fa(faTags)} ${this._t?.pnx.semantics_title}</h4>
22
- <p>${this._t?.pnx.semantics_doc_info1}</p>
23
- <ul style="padding-left: 1.5em;">
24
- <li>${this._t?.pnx.semantics_doc_info1u1}</li>
25
- <li>${this._t?.pnx.semantics_doc_info2}</li>
26
- </ul>
27
- <p>${this._t?.pnx.semantics_doc_info3}</p>
28
- <pnx-link-button
29
- href="https://docs.panoramax.fr/tags/"
30
- target="_blank"
31
- kind="outline"
32
- style="width: 100%"
33
- >${fa(faExternalLinkAlt)} ${this._t?.pnx.popup_details_link}</pnx-link-button>
34
- `;
35
- }
36
- }
37
-
38
- customElements.define("pnx-semantics-doc", SemanticsDoc);