@panoramax/web-viewer 3.2.3-develop-97f87faf → 3.2.3-develop-f4edbdd3
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/CHANGELOG.md +1 -0
- package/build/index.js +46 -36
- package/build/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/core/Viewer.js +14 -5
- package/src/components/layout/BottomDrawer.js +58 -24
- package/src/components/menus/MapFilters.js +30 -27
- package/src/components/ui/CopyButton.js +9 -3
- package/src/components/ui/MapMore.js +3 -3
- package/src/components/ui/TogglableGroup.js +2 -1
- package/src/translations/en.json +3 -1
- package/src/translations/fr.json +3 -1
package/package.json
CHANGED
|
@@ -266,7 +266,12 @@ export default class Viewer extends PhotoViewer {
|
|
|
266
266
|
// Select after none selected -> show pic wide
|
|
267
267
|
else {
|
|
268
268
|
this.mini.classList.remove("pnx-hidden");
|
|
269
|
-
if(isNullId(old)) {
|
|
269
|
+
if(isNullId(old)) {
|
|
270
|
+
this._setFocus("pic");
|
|
271
|
+
if(this.bottomDrawer?.getAttribute?.("openness") === "closed") {
|
|
272
|
+
this.bottomDrawer.setAttribute("openness", "half-opened");
|
|
273
|
+
}
|
|
274
|
+
}
|
|
270
275
|
}
|
|
271
276
|
}
|
|
272
277
|
|
|
@@ -526,13 +531,17 @@ export default class Viewer extends PhotoViewer {
|
|
|
526
531
|
const mapFiltersMenu = querySelectorDeep("#pnx-map-filters-menu");
|
|
527
532
|
const fMinDate = mapFiltersMenu?.shadowRoot.getElementById("pnx-filter-date-from");
|
|
528
533
|
const fMaxDate = mapFiltersMenu?.shadowRoot.getElementById("pnx-filter-date-end");
|
|
529
|
-
const
|
|
530
|
-
const fType360 = mapFiltersMenu?.shadowRoot.getElementById("pnx-filter-type-360");
|
|
534
|
+
const fTypes = mapFiltersMenu?.shadowRoot.querySelectorAll("input[name='pnx-filter-type']");
|
|
531
535
|
const fMapTheme = querySelectorDeep("#pnx-map-theme");
|
|
532
536
|
|
|
533
537
|
let type = "";
|
|
534
|
-
|
|
535
|
-
|
|
538
|
+
for(let fTypeId = 0 ; fTypeId < fTypes.length; fTypeId++) {
|
|
539
|
+
const fType = fTypes[fTypeId];
|
|
540
|
+
if(fType.checked) {
|
|
541
|
+
type = fType.value;
|
|
542
|
+
break;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
536
545
|
|
|
537
546
|
let qualityscore = [];
|
|
538
547
|
if(this.map?._hasQualityScore()) {
|
|
@@ -2,7 +2,6 @@ import { LitElement, html, css } from "lit";
|
|
|
2
2
|
import { classMap } from "lit/directives/class-map.js";
|
|
3
3
|
|
|
4
4
|
const OPENNESS_Y_PCT = { "opened": 0, "half-opened": 0.7, "closed": 1 };
|
|
5
|
-
const OPENNESS_Y_PCT_RANGE = { "opened": [0, 0.4], "half-opened": [0.4, 0.8], "closed": [0.8, 1] };
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* BottomDrawer layout offers a mobile-like drawer menu, coming from bottom of the screen.
|
|
@@ -27,6 +26,7 @@ export default class BottomDrawer extends LitElement {
|
|
|
27
26
|
width: 100%;
|
|
28
27
|
z-index: 130;
|
|
29
28
|
pointer-events: none;
|
|
29
|
+
touch-action: none;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
.drawer {
|
|
@@ -38,7 +38,7 @@ export default class BottomDrawer extends LitElement {
|
|
|
38
38
|
flex-direction: column;
|
|
39
39
|
transition: transform 0.3s ease;
|
|
40
40
|
will-change: transform;
|
|
41
|
-
touch-action:
|
|
41
|
+
touch-action: auto;
|
|
42
42
|
pointer-events: auto;
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -53,9 +53,7 @@ export default class BottomDrawer extends LitElement {
|
|
|
53
53
|
display: flex;
|
|
54
54
|
align-items: center;
|
|
55
55
|
justify-content: center;
|
|
56
|
-
cursor:
|
|
57
|
-
touch-action: none;
|
|
58
|
-
pointer-events: auto;
|
|
56
|
+
cursor: pointer;
|
|
59
57
|
}
|
|
60
58
|
|
|
61
59
|
.handle-bar {
|
|
@@ -95,23 +93,37 @@ export default class BottomDrawer extends LitElement {
|
|
|
95
93
|
/** @private */
|
|
96
94
|
firstUpdated() {
|
|
97
95
|
super.firstUpdated();
|
|
96
|
+
|
|
98
97
|
this._boundTouchMove = this._onTouchMove.bind(this);
|
|
99
98
|
this._boundTouchEnd = this._onTouchEnd.bind(this);
|
|
100
99
|
|
|
101
100
|
this._drawerHeight = window.innerHeight - 30;
|
|
102
|
-
|
|
101
|
+
|
|
102
|
+
const drawer = this._getDrawer();
|
|
103
103
|
if (!drawer) { return; }
|
|
104
104
|
drawer.style.height = `${this._drawerHeight}px`;
|
|
105
105
|
drawer.style.maxHeight = `${this._drawerHeight}px`;
|
|
106
|
+
|
|
107
|
+
this._parent?.onceReady().then(() => {
|
|
108
|
+
this._parent.map?.addEventListener("click", () => this.openness = "closed");
|
|
109
|
+
this._parent.psv?.addEventListener("click", () => this.openness = "closed");
|
|
110
|
+
});
|
|
106
111
|
}
|
|
107
112
|
|
|
108
113
|
/** @private */
|
|
109
114
|
attributeChangedCallback(name, old, value) {
|
|
110
115
|
super.attributeChangedCallback(name, old, value);
|
|
111
116
|
|
|
112
|
-
if(name === "openness"
|
|
113
|
-
|
|
114
|
-
if(
|
|
117
|
+
if(name === "openness") {
|
|
118
|
+
// If not fully opened, force content scroll back to top
|
|
119
|
+
if(value !== "opened") {
|
|
120
|
+
const content = this.shadowRoot.querySelector(".content");
|
|
121
|
+
if(content) { content.scrollTop = 0; }
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Remove hand-defined transform
|
|
125
|
+
const drawer = this._getDrawer();
|
|
126
|
+
if (drawer) { drawer.style.transform = null; }
|
|
115
127
|
}
|
|
116
128
|
}
|
|
117
129
|
|
|
@@ -121,10 +133,16 @@ export default class BottomDrawer extends LitElement {
|
|
|
121
133
|
this._cleanupTouchListeners();
|
|
122
134
|
}
|
|
123
135
|
|
|
136
|
+
/** @private */
|
|
137
|
+
_getDrawer() {
|
|
138
|
+
return this.shadowRoot?.querySelector(".drawer");
|
|
139
|
+
}
|
|
140
|
+
|
|
124
141
|
/** @private */
|
|
125
142
|
_onHandleClick() {
|
|
126
|
-
if(this.openness === "opened"
|
|
143
|
+
if(this.openness === "opened") { this.openness = "closed"; }
|
|
127
144
|
else if(this.openness === "half-opened") { this.openness = "opened"; }
|
|
145
|
+
else if(this.openness === "closed") { this.openness = "half-opened"; }
|
|
128
146
|
}
|
|
129
147
|
|
|
130
148
|
/** @private */
|
|
@@ -154,10 +172,19 @@ export default class BottomDrawer extends LitElement {
|
|
|
154
172
|
}
|
|
155
173
|
|
|
156
174
|
/** @private */
|
|
157
|
-
_onTouchEnd() {
|
|
158
|
-
|
|
175
|
+
_onTouchEnd(e) {
|
|
176
|
+
// Touchend is also called when "clicking" on mobile
|
|
177
|
+
if ((!this._isDragging || Math.abs(this._deltaFingerY) < 30) && !e.target.closest(".handle")) { return; }
|
|
178
|
+
e.preventDefault();
|
|
179
|
+
|
|
159
180
|
this._isDragging = false;
|
|
160
|
-
|
|
181
|
+
|
|
182
|
+
if(this._deltaFingerY === 0 && this.openness === "closed") {
|
|
183
|
+
this.openness = "half-opened";
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
this._updateDrawerTransform(this._drawerY + this._deltaFingerY, true);
|
|
187
|
+
}
|
|
161
188
|
|
|
162
189
|
this._cleanupTouchListeners();
|
|
163
190
|
this._startFingerY = null;
|
|
@@ -173,25 +200,32 @@ export default class BottomDrawer extends LitElement {
|
|
|
173
200
|
|
|
174
201
|
/** @private */
|
|
175
202
|
_updateDrawerTransform(y, snap = false) {
|
|
176
|
-
const drawer = this.
|
|
203
|
+
const drawer = this._getDrawer();
|
|
177
204
|
if (!drawer) { return; }
|
|
178
205
|
|
|
179
206
|
y = Math.max(0, Math.min(y, this._drawerHeight - 30));
|
|
180
207
|
|
|
181
208
|
// Snap to nearest static position
|
|
182
209
|
if(snap) {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
210
|
+
// Gesture goes up
|
|
211
|
+
if(this._deltaFingerY < 0) {
|
|
212
|
+
if(this.openness === "closed") {
|
|
213
|
+
// How much it goes up ?
|
|
214
|
+
if(Math.abs(this._deltaFingerY) > this._drawerHeight * (1-OPENNESS_Y_PCT["half-opened"])) {
|
|
215
|
+
this.openness = "opened";
|
|
216
|
+
}
|
|
217
|
+
else { this.openness = "half-opened"; }
|
|
218
|
+
}
|
|
219
|
+
else { this.openness = "opened"; }
|
|
220
|
+
}
|
|
221
|
+
// Gesture goes down
|
|
222
|
+
else { this.openness = "closed"; }
|
|
223
|
+
|
|
188
224
|
this._drawerY = null;
|
|
189
|
-
|
|
190
|
-
}
|
|
191
|
-
// Live drag
|
|
192
|
-
else {
|
|
193
|
-
drawer.style.transform = `translateY(${y}px)`;
|
|
225
|
+
y = Math.max(0, Math.min(OPENNESS_Y_PCT[this.openness] * this._drawerHeight, this._drawerHeight - 30));
|
|
194
226
|
}
|
|
227
|
+
|
|
228
|
+
drawer.style.transform = `translateY(${y}px)`;
|
|
195
229
|
}
|
|
196
230
|
|
|
197
231
|
/** @private */
|
|
@@ -5,7 +5,6 @@ import { faSvg, titles } from "../styles";
|
|
|
5
5
|
import { faImage } from "@fortawesome/free-solid-svg-icons/faImage";
|
|
6
6
|
import { faCalendar } from "@fortawesome/free-solid-svg-icons/faCalendar";
|
|
7
7
|
import { faArrowRight } from "@fortawesome/free-solid-svg-icons/faArrowRight";
|
|
8
|
-
import { faPanorama } from "@fortawesome/free-solid-svg-icons/faPanorama";
|
|
9
8
|
import { faMedal } from "@fortawesome/free-solid-svg-icons/faMedal";
|
|
10
9
|
import { faInfoCircle } from "@fortawesome/free-solid-svg-icons/faInfoCircle";
|
|
11
10
|
import { faUser } from "@fortawesome/free-solid-svg-icons/faUser";
|
|
@@ -90,10 +89,8 @@ export default class MapFilters extends LitElement {
|
|
|
90
89
|
}
|
|
91
90
|
.pnx-input-shortcuts button {
|
|
92
91
|
border: none;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
font-size: 0.8em;
|
|
96
|
-
padding: 0 8px;
|
|
92
|
+
font-size: 0.75em;
|
|
93
|
+
padding: 2px 6px;
|
|
97
94
|
vertical-align: middle;
|
|
98
95
|
background-color: var(--grey-pale);
|
|
99
96
|
color: var(--black);
|
|
@@ -132,12 +129,12 @@ export default class MapFilters extends LitElement {
|
|
|
132
129
|
border-top-right-radius: 8px;
|
|
133
130
|
border-bottom-right-radius: 8px;
|
|
134
131
|
}
|
|
135
|
-
.pnx-checkbox-btns input[type="
|
|
136
|
-
.pnx-checkbox-btns input[type="
|
|
132
|
+
.pnx-checkbox-btns input[type="radio"] { display: none; }
|
|
133
|
+
.pnx-checkbox-btns input[type="radio"]:checked + label {
|
|
137
134
|
background-color: var(--widget-bg-active);
|
|
138
135
|
color: var(--widget-font-active);
|
|
139
136
|
}
|
|
140
|
-
.pnx-checkbox-btns input[type="
|
|
137
|
+
.pnx-checkbox-btns input[type="radio"]:checked + label:first-of-type {
|
|
141
138
|
border-right-color: white;
|
|
142
139
|
}
|
|
143
140
|
|
|
@@ -158,8 +155,7 @@ export default class MapFilters extends LitElement {
|
|
|
158
155
|
showZoomIn: {state: true},
|
|
159
156
|
minDate: {state: true},
|
|
160
157
|
maxDate: {state: true},
|
|
161
|
-
|
|
162
|
-
type360: {state: true},
|
|
158
|
+
type: {state: true},
|
|
163
159
|
score: {state: true},
|
|
164
160
|
user: {state: true},
|
|
165
161
|
};
|
|
@@ -217,14 +213,9 @@ export default class MapFilters extends LitElement {
|
|
|
217
213
|
|
|
218
214
|
this.score = e?.qualityscore?.length < 5 ? e.qualityscore.join(",") : "";
|
|
219
215
|
|
|
216
|
+
this.type = "";
|
|
220
217
|
if(e?.pic_type && e.pic_type != "") {
|
|
221
|
-
this.
|
|
222
|
-
this.typeFlat = e.pic_type == "flat";
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
if(this.type360 === this.typeFlat) {
|
|
226
|
-
this.type360 = false;
|
|
227
|
-
this.typeFlat = false;
|
|
218
|
+
this.type = e.pic_type == "flat" ? "flat" : "equirectangular";
|
|
228
219
|
}
|
|
229
220
|
}
|
|
230
221
|
|
|
@@ -265,8 +256,7 @@ export default class MapFilters extends LitElement {
|
|
|
265
256
|
this.shadowRoot.querySelector("#pnx-filter-search-user")?.reset();
|
|
266
257
|
this.minDate = null;
|
|
267
258
|
this.maxDate = null;
|
|
268
|
-
this.
|
|
269
|
-
this.type360 = null;
|
|
259
|
+
this.type = "";
|
|
270
260
|
this.score = null;
|
|
271
261
|
this.user = null;
|
|
272
262
|
this._onFormChange();
|
|
@@ -302,6 +292,9 @@ export default class MapFilters extends LitElement {
|
|
|
302
292
|
<button
|
|
303
293
|
@click=${this._onShortcutClick("pnx-filter-date-from", new Date(new Date().setMonth(new Date().getMonth() - 1)).toISOString().split("T")[0])}
|
|
304
294
|
>${this._parent?._t.pnx.filter_date_1month}</button>
|
|
295
|
+
<button
|
|
296
|
+
@click=${this._onShortcutClick("pnx-filter-date-from", new Date(new Date().setMonth(new Date().getMonth() - 6)).toISOString().split("T")[0])}
|
|
297
|
+
>${this._parent?._t.pnx.filter_date_6months}</button>
|
|
305
298
|
<button
|
|
306
299
|
@click=${this._onShortcutClick("pnx-filter-date-from", new Date(new Date().setFullYear(new Date().getFullYear() - 1)).toISOString().split("T")[0])}
|
|
307
300
|
>${this._parent?._t.pnx.filter_date_1year}</button>
|
|
@@ -327,19 +320,29 @@ export default class MapFilters extends LitElement {
|
|
|
327
320
|
<h4>${fa(faImage)} ${this._parent?._t.pnx.filter_picture}</h4>
|
|
328
321
|
<div class="pnx-input-group pnx-checkbox-btns" style="justify-content: center;">
|
|
329
322
|
<input
|
|
330
|
-
type="
|
|
323
|
+
type="radio"
|
|
324
|
+
id="pnx-filter-type-all"
|
|
325
|
+
name="pnx-filter-type"
|
|
326
|
+
value=""
|
|
327
|
+
.checked=${!this.type || this.type === ""}
|
|
328
|
+
/>
|
|
329
|
+
<label for="pnx-filter-type-all">${this._parent?._t.pnx.picture_all}</label>
|
|
330
|
+
<input
|
|
331
|
+
type="radio"
|
|
331
332
|
id="pnx-filter-type-flat"
|
|
332
|
-
name="
|
|
333
|
-
|
|
333
|
+
name="pnx-filter-type"
|
|
334
|
+
value="flat"
|
|
335
|
+
.checked=${this.type === "flat"}
|
|
334
336
|
/>
|
|
335
|
-
<label for="pnx-filter-type-flat">${
|
|
337
|
+
<label for="pnx-filter-type-flat">${this._parent?._t.pnx.picture_flat}</label>
|
|
336
338
|
<input
|
|
337
|
-
type="
|
|
339
|
+
type="radio"
|
|
338
340
|
id="pnx-filter-type-360"
|
|
339
|
-
name="
|
|
340
|
-
|
|
341
|
+
name="pnx-filter-type"
|
|
342
|
+
value="equirectangular"
|
|
343
|
+
.checked=${this.type === "equirectangular"}
|
|
341
344
|
/>
|
|
342
|
-
<label for="pnx-filter-type-360">${
|
|
345
|
+
<label for="pnx-filter-type-360">${this._parent?._t.pnx.picture_360}</label>
|
|
343
346
|
</div>
|
|
344
347
|
</div>
|
|
345
348
|
|
|
@@ -72,9 +72,15 @@ export default class CopyButton extends LitElement {
|
|
|
72
72
|
else if(this.text !== "") {
|
|
73
73
|
textToCopy = this.text;
|
|
74
74
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
|
|
76
|
+
if(!navigator?.clipboard) {
|
|
77
|
+
alert("Clipboard is not available");
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
navigator.clipboard.writeText(textToCopy);
|
|
81
|
+
this._active = true;
|
|
82
|
+
setTimeout(() => this._active = false, 2000);
|
|
83
|
+
}
|
|
78
84
|
}
|
|
79
85
|
|
|
80
86
|
/** @private */
|
|
@@ -235,9 +235,9 @@ export default class MapMore extends Map {
|
|
|
235
235
|
}
|
|
236
236
|
|
|
237
237
|
if(filters.pic_type && filters.pic_type !== "") {
|
|
238
|
-
this._mapFilters.pic_type = filters.pic_type;
|
|
239
|
-
mapSeqFilters.push(["==", ["get", "type"],
|
|
240
|
-
mapPicFilters.push(["==", ["get", "type"],
|
|
238
|
+
this._mapFilters.pic_type = filters.pic_type === "flat" ? "flat" : "equirectangular";
|
|
239
|
+
mapSeqFilters.push(["==", ["get", "type"], this._mapFilters.pic_type]);
|
|
240
|
+
mapPicFilters.push(["==", ["get", "type"], this._mapFilters.pic_type]);
|
|
241
241
|
}
|
|
242
242
|
if(this._hasGridStats()) {
|
|
243
243
|
reloadMapStyle = true;
|
|
@@ -98,6 +98,7 @@ export default class TogglableGroup extends LitElement {
|
|
|
98
98
|
menu.style.right = null;
|
|
99
99
|
menu.style.left = null;
|
|
100
100
|
menu.style.overflowY = null;
|
|
101
|
+
menu.style.marginTop = null;
|
|
101
102
|
|
|
102
103
|
// Get positions on screen
|
|
103
104
|
const btnRect = btn.getBoundingClientRect();
|
|
@@ -130,7 +131,7 @@ export default class TogglableGroup extends LitElement {
|
|
|
130
131
|
}
|
|
131
132
|
// Overflows width = move to left
|
|
132
133
|
else if(!fitsWidth) {
|
|
133
|
-
menu.style.
|
|
134
|
+
menu.style.marginTop = `${btnMenuMargin}px`;
|
|
134
135
|
menu.style.right = `${window.innerWidth - btnRect.right}px`;
|
|
135
136
|
}
|
|
136
137
|
}
|
package/src/translations/en.json
CHANGED
|
@@ -105,11 +105,13 @@
|
|
|
105
105
|
"error_api_compatibility": "The pictures server is not compatible with this viewer version",
|
|
106
106
|
"filter_date": "Date",
|
|
107
107
|
"filter_date_1month": "1 month",
|
|
108
|
+
"filter_date_6months": "6 months",
|
|
108
109
|
"filter_date_1year": "1 year",
|
|
109
110
|
"filter_user": "User",
|
|
110
111
|
"filter_user_mypics": "My pictures",
|
|
111
112
|
"filter_picture": "Picture type",
|
|
112
|
-
"filter_zoom_in": "Zoom-in to see this filter",
|
|
113
|
+
"filter_zoom_in": "Zoom-in the map to see this filter",
|
|
114
|
+
"picture_all": "All",
|
|
113
115
|
"picture_flat": "Classic",
|
|
114
116
|
"picture_360": "360°",
|
|
115
117
|
"picture_flat_long": "Classic picture",
|
package/src/translations/fr.json
CHANGED
|
@@ -105,10 +105,12 @@
|
|
|
105
105
|
"error_api_compatibility": "Le serveur de photos n'est pas compatible avec cette visionneuse",
|
|
106
106
|
"filter_date": "Date",
|
|
107
107
|
"filter_date_1month": "1 mois",
|
|
108
|
+
"filter_date_6months": "6 mois",
|
|
108
109
|
"filter_date_1year": "1 an",
|
|
109
110
|
"filter_user": "Utilisateur",
|
|
110
111
|
"filter_user_mypics": "Mes photos",
|
|
111
112
|
"filter_picture": "Type d'image",
|
|
113
|
+
"picture_all": "Tout",
|
|
112
114
|
"picture_flat": "Classique",
|
|
113
115
|
"picture_360": "360°",
|
|
114
116
|
"picture_flat_long": "Photo classique",
|
|
@@ -120,7 +122,7 @@
|
|
|
120
122
|
"qualityscore_doc_2": "Le score est affiché sous la forme d'une lettre A/B/C/D/E (A étant le meilleur, E le moins bon), et visualisable grâce à cette échelle :",
|
|
121
123
|
"qualityscore_doc_3": "Il est calculé en fonction de la précision du GPS ainsi que la résolution de la photo. Un matériel professionnel aura une note de A, une caméra sportive 360° une note de B, et un smartphone une note de C à E.",
|
|
122
124
|
"qualityscore_doc_link": "En savoir plus sur le Score de Qualité",
|
|
123
|
-
"filter_zoom_in": "Zoomez
|
|
125
|
+
"filter_zoom_in": "Zoomez la carte pour voir ce filtre",
|
|
124
126
|
"map_background": "Fond de carte",
|
|
125
127
|
"map_background_aerial": "Satellite",
|
|
126
128
|
"map_background_streets": "Plan",
|