homeflowjs 0.11.8 → 0.11.10

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": "homeflowjs",
3
- "version": "0.11.8",
3
+ "version": "0.11.10",
4
4
  "description": "JavaScript toolkit for Homeflow themes",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -7,6 +7,7 @@ import { buildQueryString } from '../../search/property-search/property-search';
7
7
  import { setPlace, setSearchField } from '../../actions/search.actions';
8
8
  import { setProperties, setSelectedMarker, setPagination } from '../../actions/properties.actions';
9
9
  import { setLoading } from '../../actions/app.actions';
10
+ import { currentGeonameId } from '../../utils/index';
10
11
 
11
12
  const element = function (X, Y) {
12
13
  this.X = X;
@@ -56,8 +57,8 @@ export default class DraggableMap {
56
57
  this.mapLoadedTimes = 1;
57
58
  this.render();
58
59
  this.buildPolygon();
59
- this.setMarkersFor(this.propertiesOrBreadcrumbs());
60
- if (this.noLocationfound) { this.setToMarkeredBounds(); }
60
+ this.setMarkers();
61
+ if (this.noLocationfound || Homeflow.get('breadcrumbs_map')) { this.setToMarkeredBounds(); }
61
62
  if (Homeflow.get('custom_map_zoom') !== null) {
62
63
  this.map.setZoom(Homeflow.get('custom_map_zoom'));
63
64
  }
@@ -122,7 +123,10 @@ export default class DraggableMap {
122
123
  }
123
124
 
124
125
  generateMarker(property) {
125
- const marker = L.marker([property.lat, property.lng], { icon: Homeflow.get('custom_property_pin')(property) });
126
+ const marker = L.marker(
127
+ [property.lat, property.lng],
128
+ { title: property.name, icon: Homeflow.get('custom_property_pin')(property) }
129
+ );
126
130
 
127
131
  // add the property to marker attributes so they can be accessed on click
128
132
  marker.property = property;
@@ -138,7 +142,6 @@ export default class DraggableMap {
138
142
 
139
143
  if (Homeflow.get('pop_up_on_mouseover')) {
140
144
  marker.on("mouseover", e => marker.openPopup());
141
-
142
145
  marker.on("mouseout", e => setTimeout((() => marker.closePopup()), 4000));
143
146
  }
144
147
  }
@@ -244,47 +247,105 @@ export default class DraggableMap {
244
247
  }
245
248
  }
246
249
 
247
- setMarkersFor(propertiesOrBreadcrumbs) {
248
- let bounds;
249
- if (this.marker_layer != null) { this.map.removeLayer(this.marker_layer); }
250
- if (!propertiesOrBreadcrumbs) { return null }
250
+ initLayers() {
251
+ if (this.clusteringMarkerLayer) this.map.removeLayer(this.clusteringMarkerLayer);
252
+ if (this.nonClusteringMarkerLayer) this.map.removeLayer(this.nonClusteringMarkerLayer);
251
253
 
252
- if (Homeflow.get('pin_clustering') && !this.breadcrumbs?.length) {
253
- let radius = Homeflow.get('custom_clustering_radius');
254
- if (!radius) {
255
- radius = 10;
256
- }
257
- this.marker_layer = new L.MarkerClusterGroup({ maxClusterRadius: radius, showCoverageOnHover: false });
254
+ const radius = Homeflow.get('custom_clustering_radius') || 10;
255
+
256
+ this.clusteringMarkerLayer = new L.MarkerClusterGroup({ maxClusterRadius: radius, showCoverageOnHover: false });
257
+ this.nonClusteringMarkerLayer = L.featureGroup();
258
+ }
259
+
260
+ setMarkers() {
261
+ this.initLayers();
262
+
263
+ if (!this.properties && !this.breadcrumbs) { return null }
264
+
265
+
266
+ if (this.isDisplayProperties()) {
267
+ this.properties?.map(property => this.setPropertyMarker(property));
258
268
  } else {
259
- this.marker_layer = L.featureGroup();
260
- }
261
- const markers = propertiesOrBreadcrumbs.map((propertyOrBreadcrumb) => {
262
- if (propertyOrBreadcrumb.property_id != null || Homeflow.get('breadcrumbs_map')) {
263
- if (propertyOrBreadcrumb.lat !== 0 && propertyOrBreadcrumb.lng !== 0) {
264
- const m = this.generateMarker(propertyOrBreadcrumb);
265
- this.marker_layer.addLayer(m);
266
- return m;
267
- }
268
- }
269
- });
270
- this.marker_layer.addTo(this.map);
271
- this.bounds = this.marker_layer.getBounds();
272
- return bounds = [this.marker_layer.getBounds()];
269
+ this.breadcrumbs?.map(breadcrumb => this.setBreadcrumbMarker(breadcrumb));
270
+ }
271
+
272
+ this.clusteringMarkerLayer.addTo(this.map);
273
+ this.nonClusteringMarkerLayer.addTo(this.map);
274
+
275
+ return this.bounds;
276
+ }
277
+
278
+ setPropertyMarker(property) {
279
+ const geonameId = property.geoname_ids?.slice(-1)[0];
280
+ const layer = Homeflow.get('pin_clustering') ? this.clusteringMarkerLayer : this.nonClusteringMarkerLayer;
281
+
282
+ if (property.property_id === null || property.lat === 0 || property.lng === 0) return;
283
+ if (geonameId && Homeflow.get('breadcrumbs_map') && geonameId !== currentGeonameId()) return;
284
+
285
+ layer.addLayer(this.generateMarker(property));
286
+ }
287
+
288
+ setBreadcrumbMarker(breadcrumb) {
289
+ if (!breadcrumb.lat || !breadcrumb.lng) return;
290
+
291
+ this.nonClusteringMarkerLayer.addLayer(this.generateMarker(breadcrumb));
273
292
  }
274
293
 
275
294
  setToMarkeredBounds() {
276
- if (this.bounds != null) {
277
- if (Homeflow.get('custom_map_bounds_padding')) {
278
- this.map.fitBounds(this.bounds, Homeflow.get('custom_map_bounds_padding'));
279
- } else {
280
- this.map.fitBounds(this.bounds);
281
- }
295
+ const options = Homeflow.get('custom_map_bounds_padding');
296
+ const bounds = this.getMarkerBounds();
282
297
 
283
- if (Homeflow.get('custom_map_centre_lat') && Homeflow.get('custom_map_centre_lng')) {
284
- this.map.setView([Homeflow.get('custom_map_centre_lat'), Homeflow.get('custom_map_centre_lng')], 7);
285
- }
298
+ if (!bounds || !bounds.isValid()) return;
299
+
300
+ this.map.fitBounds(bounds, options);
301
+
302
+ if (Homeflow.get('custom_map_centre_lat') && Homeflow.get('custom_map_centre_lng')) {
303
+ this.map.setView([Homeflow.get('custom_map_centre_lat'), Homeflow.get('custom_map_centre_lng')], 7);
304
+ }
286
305
 
287
- return Homeflow.kickEvent('non_standard_zoom', this.map, 4);
306
+ Homeflow.kickEvent('non_standard_zoom', this.map, 4);
307
+ }
308
+
309
+ getMarkerBounds() {
310
+ if (this.bounds && this.bounds.isValid()) {
311
+ return this.bounds;
312
+ } else {
313
+ const bounds = [this.getTopLeftMarkerCoordinates(), this.getBottomRightMarkerCoordinates()];
314
+ if (bounds.flat().find(coordinate => coordinate === Infinity)) return null;
315
+
316
+ return L.latLngBounds(...bounds.map(bound => L.latLng(...bound)));
317
+ }
318
+ }
319
+
320
+ getTopLeftMarkerCoordinates() {
321
+ return [
322
+ Math.min(...this.parseCoordinateArray([this.properties, this.breadcrumbs].flat(), 'lat')),
323
+ Math.min(...this.parseCoordinateArray([this.properties, this.breadcrumbs].flat(), 'lng'))
324
+ ];
325
+ }
326
+
327
+ getBottomRightMarkerCoordinates() {
328
+ return [
329
+ Math.max(...this.parseCoordinateArray([this.properties, this.breadcrumbs].flat(), 'lat')),
330
+ Math.max(...this.parseCoordinateArray([this.properties, this.breadcrumbs].flat(), 'lng'))
331
+ ];
332
+ }
333
+
334
+ parseCoordinateArray(items, coordinateType) {
335
+ if (!items) return [];
336
+
337
+ return items.filter(item => item).map(item => parseFloat(item[coordinateType])).filter(Number);
338
+ }
339
+
340
+ isDisplayProperties() {
341
+ const { properties: { pagination: { total_count: totalCount } } } = store.getState();
342
+
343
+ if (!this.breadcrumbs || !Homeflow.get('breadcrumbs_map')) {
344
+ return true;
345
+ } else if (this.properties && totalCount <= this.properties.length) {
346
+ return true;
347
+ } else {
348
+ return false;
288
349
  }
289
350
  }
290
351
 
@@ -411,7 +472,7 @@ export default class DraggableMap {
411
472
  // if (this.tile_view != null) {
412
473
  // this.tile_view = new Ctesius.Views.Tiles({ collection: this.collection });
413
474
  // }
414
- return this.setMarkersFor(this.propertiesOrBreadcrumbs());
475
+ return this.setMarkers();
415
476
  });
416
477
  }
417
478
  }
@@ -575,7 +636,7 @@ export default class DraggableMap {
575
636
  // this.tile_view = new Ctesius.Views.Tiles({ collection: this.collection });
576
637
  // }
577
638
 
578
- return this.setMarkersFor(this.propertiesOrBreadcrumbs());
639
+ return this.setMarkers();
579
640
  })
580
641
  // return $.get(url, (res, status, xhr) => {
581
642
  // s.set('performed_data', res);
@@ -591,7 +652,7 @@ export default class DraggableMap {
591
652
  // }
592
653
  // else { }
593
654
  // //@tile_view.collection(@collection)
594
- // return this.setMarkersFor(this.collection.models);
655
+ // return this.setMarkers();
595
656
  // });
596
657
  }
597
658
 
@@ -645,7 +706,7 @@ export default class DraggableMap {
645
706
 
646
707
  if (breadcrumbs && this.breadcrumbs !== breadcrumbs) {
647
708
  this.breadcrumbs = breadcrumbs;
648
- this.setMarkersFor(breadcrumbs);
709
+ this.setMarkers();
649
710
  }
650
711
  }
651
712
  }
package/utils/index.js CHANGED
@@ -80,4 +80,10 @@ export const compact = (array) => array.filter((item) => typeof item !== 'undefi
80
80
 
81
81
  export const sanitizeText = (string) => new Option(string).innerHTML;
82
82
 
83
+ export const currentGeonameId = (path) => {
84
+ const pathname = path || window.location.pathname;
85
+ const segment = pathname.split('/').reverse().find(item => item.startsWith('gid-'))?.replace(/^gid-/, '')
86
+ return parseInt(segment, 10) || null;
87
+ };
88
+
83
89
  export const DEBOUNCE_DELAY = 200;
@@ -19,3 +19,13 @@ describe('sanitizeText', () => {
19
19
  expect(utils.sanitizeText('<hello>')).toEqual('&lt;hello&gt;');
20
20
  });
21
21
  });
22
+
23
+ describe('currentGeonameId', () => {
24
+ it('returns Geoname ID from path', () => {
25
+ expect(utils.currentGeonameId('/foo/bar/baz/gid-12345/qux')).toEqual(12345);
26
+ });
27
+
28
+ it('returns `null` when no Geoname ID detected', () => {
29
+ expect(utils.currentGeonameId('/foo/bar/baz/qux')).toEqual(null);
30
+ });
31
+ });