@panoramax/web-viewer 3.1.1-develop-2701b828 → 3.1.1-develop-7b28b173

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.1-develop-2701b828",
3
+ "version": "3.1.1-develop-7b28b173",
4
4
  "description": "Panoramax web viewer for geolocated pictures",
5
5
  "main": "build/index.js",
6
6
  "author": "Panoramax team",
package/src/Viewer.js CHANGED
@@ -235,6 +235,7 @@ class Viewer extends CoreView {
235
235
  const userSearchField = document.getElementById("gvs-filter-search-user").querySelector("input");
236
236
  if(userSearchField) {
237
237
  userSearchField.setItem(userNames);
238
+ userSearchField.parentNode.classList.add("gvs-filter-active");
238
239
  }
239
240
  }).catch(e => console.warn("Error when looking up for user names", e));
240
241
  }
@@ -16,10 +16,10 @@
16
16
  "expand": "展開",
17
17
  "expand_info": "在整個畫面顯示此小工具",
18
18
  "filter_camera_model": "按相機型號",
19
- "filter_date": "按日期",
20
- "filter_picture": "按相片類型",
19
+ "filter_date": "日期",
20
+ "filter_picture": "相片類型",
21
21
  "filter_reset": "重設",
22
- "filter_user": "按使用者",
22
+ "filter_user": "使用者",
23
23
  "filter_zoom_in": "拉近地圖以顯示篩選結果",
24
24
  "filters": "篩選器",
25
25
  "id": "iD",
@@ -54,7 +54,8 @@
54
54
  "🔍 正在分析 EXIF 詮釋資料",
55
55
  "🏘️ 正在算繪 3D",
56
56
  "📷 正在初始化 360° 相片",
57
- "🟠 正在平衡色彩"
57
+ "🟠 正在平衡色彩",
58
+ "💯 正在計算品質分數 ©"
58
59
  ],
59
60
  "map_background": "地圖背景",
60
61
  "map_background_aerial": "衛星",
@@ -65,7 +66,7 @@
65
66
  "map_theme_age_2": "< 2 年",
66
67
  "map_theme_age_3": "< 1 年",
67
68
  "map_theme_age_4": "< 1 個月",
68
- "map_theme_default": "預設",
69
+ "map_theme_default": "經典",
69
70
  "map_theme_type": "相機類型",
70
71
  "metadata": "相片詮釋資料",
71
72
  "metadata_camera": "相機",
@@ -125,7 +126,15 @@
125
126
  "report_email": "您的 email",
126
127
  "report_nature_label": "問題的類型",
127
128
  "report_nature": {
128
- "": "選擇問題的類型…"
129
+ "": "選擇問題的類型…",
130
+ "blur_missing": "可以看見人臉或車牌",
131
+ "blur_excess": "不需要模糊的物件被模糊處理了",
132
+ "inappropriate": "不當的相片 (不相關、裸體…)",
133
+ "privacy": "可以看見私人的道路或資產",
134
+ "picture_low_quality": "相片的品質很差",
135
+ "mislocated": "相片在地圖上的位置不正確",
136
+ "copyright": "相片侵犯了版權",
137
+ "other": "任何其他類型的問題"
129
138
  },
130
139
  "share_embed_docs": "深入了解嵌入設定值",
131
140
  "error_retry": "請稍後再試",
@@ -135,13 +144,27 @@
135
144
  "report_whole_sequence": "這個問題影響整個序列",
136
145
  "report_details": "更多資訊",
137
146
  "report_details_placeholder": "選填,您可以詳述此問題和它造成的影響",
138
- "report_wait": "正在傳送報告..."
147
+ "report_wait": "正在傳送報告...",
148
+ "report_success": "已成功發送報告,我們將儘快對它進行審核。",
149
+ "report_failure": "建立報告時發送錯誤: {e},請稍後再試。",
150
+ "report_auth": "此報告將使用您的帳戶「{a}」發送",
151
+ "filter_qualityscore": "品質分數",
152
+ "filter_qualityscore_help": "點擊以啟用或停用",
153
+ "map_theme_score": "品質分數",
154
+ "metadata_camera_resolution": "解析度",
155
+ "metadata_quality": "品質分數",
156
+ "metadata_quality_help": "了解有關品質分數的更多資訊",
157
+ "metadata_quality_gps_score": "定位分數",
158
+ "metadata_quality_resolution_score": "解析度分數",
159
+ "metadata_quality_missing": "相片未包含資訊",
160
+ "report": "檢舉相片"
139
161
  },
140
162
  "map": {
141
163
  "loading": "正在載入…",
142
164
  "no_thumbnail": "沒有縮圖",
143
165
  "not_public": "未公開顯示",
144
- "thumbnail": "遊標懸停相片的縮圖"
166
+ "thumbnail": "遊標懸停相片的縮圖",
167
+ "slow_loading": "地圖載入速度緩慢而且可能出現損壞"
145
168
  },
146
169
  "psv": {
147
170
  "ctrlZoom": "使用 CTRL + 滑鼠滾輪縮放圖片",
@@ -62,6 +62,19 @@ export function createExpandableButton(id, icon, label, container, classes = [])
62
62
  btn.title = label;
63
63
  }
64
64
  btn.classList.add("gvs-btn", "gvs-widget-bg", "gvs-btn-expandable", ...classes);
65
+ btn.setActive = val => {
66
+ let span = btn.querySelector(".gvs-filters-active");
67
+ if(val && !span) {
68
+ span = document.createElement("span");
69
+ span.classList.add("gvs-filters-active");
70
+ const svg = btn.querySelector("svg");
71
+ if(svg.nextSibling) { btn.insertBefore(span, svg.nextSibling); }
72
+ else { btn.appendChild(span); }
73
+ }
74
+ else if(!val && span) {
75
+ span.remove();
76
+ }
77
+ };
65
78
  return btn;
66
79
  }
67
80
 
@@ -207,6 +207,63 @@ span.gvs-input-btn {
207
207
  width: 100%;
208
208
  }
209
209
 
210
+ /* Checkbox looking like buttons */
211
+ .gvs-input-group.gvs-checkbox-btns {
212
+ gap: 0;
213
+ }
214
+ .gvs-checkbox-btns label {
215
+ display: inline-block;
216
+ padding: 2px 7px;
217
+ background: none;
218
+ border: 1px solid var(--widget-border-btn);
219
+ color: var(--widget-font-btn-direct);
220
+ cursor: pointer;
221
+ font-size: 16px;
222
+ text-decoration: none;
223
+ border-left-width: 0px;
224
+ }
225
+ .gvs-checkbox-btns label:hover {
226
+ background-color: var(--widget-bg-hover);
227
+ }
228
+ .gvs-checkbox-btns label:first-of-type {
229
+ border-top-left-radius: 8px;
230
+ border-bottom-left-radius: 8px;
231
+ border-left-width: 1px;
232
+ }
233
+ .gvs-checkbox-btns label:last-of-type {
234
+ border-top-right-radius: 8px;
235
+ border-bottom-right-radius: 8px;
236
+ }
237
+ .gvs-checkbox-btns input[type="checkbox"] { display: none; }
238
+ .gvs-checkbox-btns input[type="checkbox"]:checked + label {
239
+ background-color: var(--widget-bg-active);
240
+ color: var(--widget-font-active);
241
+ }
242
+ .gvs-checkbox-btns input[type="checkbox"]:checked + label:first-of-type {
243
+ border-right-color: white;
244
+ }
245
+
246
+ /* Input shortcuts */
247
+ .gvs-input-shortcuts {
248
+ margin-top: -10px;
249
+ margin-bottom: 5px;
250
+ }
251
+ .gvs-input-shortcuts button {
252
+ border: none;
253
+ height: 20px;
254
+ line-height: 20px;
255
+ font-size: 11px;
256
+ padding: 0 8px;
257
+ vertical-align: middle;
258
+ background-color: var(--grey-pale);
259
+ color: var(--black);
260
+ border-radius: 10px;
261
+ cursor: pointer;
262
+ }
263
+ .gvs-input-shortcuts button:hover {
264
+ background-color: #d9dcd9;
265
+ }
266
+
210
267
 
211
268
  /* Group */
212
269
  .gvs-group {
@@ -591,10 +648,25 @@ a.gvs-btn { text-decoration: none; }
591
648
 
592
649
  /* Filters */
593
650
  #gvs-filter { margin-bottom: 5px; }
651
+ .gvs-filters-active {
652
+ width: 15px;
653
+ height: 15px;
654
+ border-radius: 8px;
655
+ border: 3px solid white;
656
+ position: absolute;
657
+ left: 20px;
658
+ top: 5px;
659
+ background-color: var(--orange);
660
+ }
594
661
  #gvs-filter-panel {
595
662
  width: 350px;
596
663
  max-width: 350px;
597
664
  }
665
+ #gvs-filter-panel .gvs-filter-active {
666
+ background-color: var(--widget-bg-active);
667
+ border-color: var(--widget-bg-active);
668
+ color: var(--widget-font-active);
669
+ }
598
670
  #gvs-filter-panel input[type=date] {
599
671
  min-width: 0;
600
672
  flex-grow: 2;
@@ -602,6 +674,10 @@ a.gvs-btn { text-decoration: none; }
602
674
  text-align: center;
603
675
  }
604
676
  #gvs-filter-camera-model, #gvs-filter-search-user { width: 100%; }
677
+ #gvs-filter-search-user.gvs-filter-active input {
678
+ color: var(--widget-font-active);
679
+ background: none;
680
+ }
605
681
  #gvs-filter-zoomin {
606
682
  text-align: center;
607
683
  font-weight: bold;
@@ -978,17 +978,21 @@ export default class Widgets {
978
978
  <form id="gvs-filter-form">
979
979
  <div id="gvs-filter-zoomin">${fat(faTriangleExclamation)} ${this._t.gvs.filter_zoom_in}</div>
980
980
  <h4>${fat(faCalendar)} ${this._t.gvs.filter_date}</h4>
981
+ <div class="gvs-input-shortcuts">
982
+ <button data-for="gvs-filter-date-from" data-value="${new Date(new Date().setMonth(new Date().getMonth() - 1)).toISOString().split("T")[0]}">1 mois</button>
983
+ <button data-for="gvs-filter-date-from" data-value="${new Date(new Date().setFullYear(new Date().getFullYear() - 1)).toISOString().split("T")[0]}">1 an</button>
984
+ </div>
981
985
  <div class="gvs-input-group">
982
986
  <input type="date" id="gvs-filter-date-from" />
983
987
  ${fat(faArrowRight)}
984
988
  <input type="date" id="gvs-filter-date-end" />
985
989
  </div>
986
990
  <h4>${fat(faImage)} ${this._t.gvs.filter_picture}</h4>
987
- <div class="gvs-input-group" style="justify-content: center;">
991
+ <div class="gvs-input-group gvs-checkbox-btns" style="justify-content: center;">
988
992
  <input type="checkbox" id="gvs-filter-type-flat" name="flat" checked />
989
- <label for="gvs-filter-type-flat" style="margin-right: 20px">${this._t.gvs.picture_flat}</label>
993
+ <label for="gvs-filter-type-flat">${fat(faImage)} ${this._t.gvs.picture_flat}</label>
990
994
  <input type="checkbox" id="gvs-filter-type-360" name="360" checked />
991
- <label for="gvs-filter-type-360">${this._t.gvs.picture_360}</label>
995
+ <label for="gvs-filter-type-360">${fat(faPanorama)} ${this._t.gvs.picture_360}</label>
992
996
  </div>
993
997
  </form>
994
998
  `;
@@ -1046,17 +1050,25 @@ export default class Widgets {
1046
1050
  input.id = "gvs-filter-user";
1047
1051
  input.classList.add("gvs-input-group");
1048
1052
 
1049
- const userSearch = createSearchBar(
1053
+ let userSearch;
1054
+ userSearch = createSearchBar(
1050
1055
  "gvs-filter-search-user",
1051
1056
  this._t.gvs.search_user,
1052
- q => this._viewer._api.searchUsers(q)
1053
- .then(data => ((data || [])
1054
- .map(f => ({
1055
- title: f.label,
1056
- data: f
1057
- }))
1058
- )),
1059
- d => this._viewer.map.setVisibleUsers(d ? [d.data.id] : ["geovisio"]),
1057
+ q => {
1058
+ userSearch.classList.remove("gvs-filter-active");
1059
+ return this._viewer._api.searchUsers(q)
1060
+ .then(data => ((data || [])
1061
+ .map(f => ({
1062
+ title: f.label,
1063
+ data: f
1064
+ }))
1065
+ ));
1066
+ },
1067
+ d => {
1068
+ if(d) { userSearch.classList.add("gvs-filter-active"); }
1069
+ else { userSearch.classList.remove("gvs-filter-active"); }
1070
+ return this._viewer.map.setVisibleUsers(d ? [d.data.id] : ["geovisio"]);
1071
+ },
1060
1072
  this,
1061
1073
  true
1062
1074
  );
@@ -1064,6 +1076,27 @@ export default class Widgets {
1064
1076
  form.appendChild(input);
1065
1077
  }
1066
1078
 
1079
+ // Shortcuts
1080
+ pnlFilter.querySelectorAll(".gvs-input-shortcuts button").forEach(btn => {
1081
+ btn.addEventListener("click", () => {
1082
+ const elem = document.getElementById(btn.getAttribute("data-for"));
1083
+ const val = btn.getAttribute("data-value");
1084
+ if(elem && elem.value !== val) { elem.value = val; }
1085
+ else { elem.value = ""; }
1086
+ });
1087
+ });
1088
+
1089
+ // Fields change events (for active highlighting)
1090
+ const fMinDate = document.getElementById("gvs-filter-date-from");
1091
+ const fMaxDate = document.getElementById("gvs-filter-date-end");
1092
+ [fMinDate, fMaxDate].forEach(f => {
1093
+ f.addEventListener("change", () => {
1094
+ if(f.value) { f.classList.add("gvs-filter-active"); }
1095
+ else { f.classList.remove("gvs-filter-active"); }
1096
+ });
1097
+ });
1098
+
1099
+ // Form update events
1067
1100
  this._formDelay = null;
1068
1101
 
1069
1102
  const onFormChange = () => {
@@ -1136,6 +1169,7 @@ export default class Widgets {
1136
1169
  * @private
1137
1170
  */
1138
1171
  _listenMapFiltersChanges() {
1172
+ const btnFilter = document.getElementById("gvs-filter");
1139
1173
  const fMinDate = document.getElementById("gvs-filter-date-from");
1140
1174
  const fMaxDate = document.getElementById("gvs-filter-date-end");
1141
1175
  const fTypeFlat = document.getElementById("gvs-filter-type-flat");
@@ -1149,8 +1183,16 @@ export default class Widgets {
1149
1183
 
1150
1184
  // Update widget based on programmatic filter changes
1151
1185
  this._viewer.addEventListener("filters-changed", e => {
1152
- if(e.detail.minDate) { fMinDate.value = e.detail.minDate; }
1153
- if(e.detail.maxDate) { fMaxDate.value = e.detail.maxDate; }
1186
+ if(e.detail.minDate) {
1187
+ fMinDate.value = e.detail.minDate;
1188
+ fMinDate.classList.add("gvs-filter-active");
1189
+ }
1190
+ else { fMinDate.classList.remove("gvs-filter-active"); }
1191
+ if(e.detail.maxDate) {
1192
+ fMaxDate.value = e.detail.maxDate;
1193
+ fMaxDate.classList.add("gvs-filter-active");
1194
+ }
1195
+ else { fMaxDate.classList.remove("gvs-filter-active"); }
1154
1196
  if(e.detail.theme) { fMapTheme.value = e.detail.theme; }
1155
1197
  if(e.detail.type) {
1156
1198
  fType360.checked = ["", "equirectangular"].includes(e.detail.type);
@@ -1163,6 +1205,7 @@ export default class Widgets {
1163
1205
  fScoreD.checked = e.detail.qualityscore.includes(2) && e.detail.qualityscore.length < 5;
1164
1206
  fScoreE.checked = e.detail.qualityscore.includes(1) && e.detail.qualityscore.length < 5;
1165
1207
  }
1208
+ btnFilter.setActive(Object.keys(e.detail).filter(d => d && d !== "theme").length > 0);
1166
1209
  this._onMapThemeChange();
1167
1210
  });
1168
1211