Skip to content

Commit fcd7f33

Browse files
authored
Merge pull request #45 from BuildFire/add-camera-control
feat(camera-control):add camera control
2 parents 29a427a + 2fec309 commit fcd7f33

7 files changed

Lines changed: 94 additions & 16 deletions

File tree

src/control/content/js/listView/introMap.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/* eslint-disable max-len */
22
import state from "../../state";
3+
import { isCameraControlVersion } from "../../../../shared/utils/mapUtils";
34

45
const convertMileToMeter = (distanceInMiles) => {
56
if (typeof distanceInMiles === "number") {
@@ -16,16 +17,21 @@ window.initAreaRadiusMap = () => {
1617

1718
const areaAddressInput = document.getElementById("area-radius-address-input");
1819
const areaRadiusInput = document.getElementById("location-area-radius-input");
19-
20-
const map = new google.maps.Map(document.getElementById("local-area-map"), {
20+
const options = {
2121
center: { lat: 32.7182625, lng: -117.1601157 },
2222
zoom: 1,
23-
zoomControl: true,
2423
mapTypeControl: false,
2524
streetViewControl: false,
2625
fullscreenControl: false,
2726
gestureHandling: "greedy",
28-
});
27+
};
28+
if (isCameraControlVersion()) {
29+
options.cameraControl = true;
30+
} else {
31+
options.zoomControl = true;
32+
}
33+
34+
const map = new google.maps.Map(document.getElementById("local-area-map"), options);
2935
state.map = map;
3036

3137
const autocomplete = new google.maps.places.SearchBox(

src/control/content/js/locations/index.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import Locations from "../../../../repository/Locations";
2020
import Category from "../../../../entities/Category";
2121
import { validateOpeningHoursDuplication } from '../../../../shared/utils';
2222
import constants from '../../../../widget/js/constants';
23+
import { isCameraControlVersion } from "../../../../shared/utils/mapUtils";
24+
2325
const breadcrumbsSelector = document.querySelector("#breadcrumbs");
2426
const sidenavContainer = document.querySelector("#sidenav-container");
2527
const locationsSection = document.querySelector("#main");
@@ -1118,15 +1120,20 @@ const createEmptyHolder = (message) => {
11181120

11191121
window.intiMap = () => {
11201122
console.log("Map Ready");
1121-
const map = new google.maps.Map(document.getElementById("location-map"), {
1123+
const options = {
11221124
center: { lat: 32.7182625, lng: -117.1601157 },
11231125
zoom: 1,
1124-
zoomControl: true,
11251126
mapTypeControl: false,
11261127
streetViewControl: false,
11271128
fullscreenControl: false,
11281129
gestureHandling: "greedy",
1129-
});
1130+
};
1131+
if (isCameraControlVersion()) {
1132+
options.cameraControl = true;
1133+
} else {
1134+
options.zoomControl = true;
1135+
}
1136+
const map = new google.maps.Map(document.getElementById("location-map"), options);
11301137
state.map = map;
11311138

11321139
const autocomplete = new google.maps.places.SearchBox(

src/control/settings/settings.js

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import LocationEditingListUI from './js/ui/locationEditingListUI';
1212
import DialogComponent from './js/ui/dialog/dialog';
1313
import Locations from '../../repository/Locations';
1414
import { getDisplayName } from './js/util/helpers';
15+
import { isCameraControlVersion } from '../../shared/utils/mapUtils';
1516

1617
const sidenavContainer = document.getElementById('sidenav-container');
1718
const emptyState = document.getElementById('empty-state');
@@ -377,7 +378,6 @@ const removeAsEditingLocations = (location, index, callback) => {
377378
}, (e, data) => {
378379
if (e) console.error(e);
379380
if (data && data.selectedButton.key === "y") {
380-
381381
const payload = {
382382
$set: {
383383
lastUpdatedOn: new Date(),
@@ -651,7 +651,6 @@ const openLocationPermsDialog = (location) => {
651651
callback(item);
652652
};
653653

654-
655654
const locationTagsListContainer = document.createElement('div');
656655
const tagsContainerTitle = document.createElement('h5');
657656

@@ -740,7 +739,6 @@ const initLocationEditing = () => {
740739
const defaultLocationsTimeRadios = document.querySelectorAll('input[name="defaultLocationTime"]');
741740
let timeoutId;
742741

743-
744742
for (const radio of defaultLocationsTimeRadios) {
745743
if (radio.value === state.settings.locationEditors.time) {
746744
radio.checked = true;
@@ -1015,15 +1013,20 @@ const initMap = () => {
10151013

10161014
window.intiGoogleMap = () => {
10171015
const searchBoxElem = document.querySelector('#initial-area-location-input');
1018-
const map = new google.maps.Map(document.getElementById("location-map"), {
1016+
const options = {
10191017
center: { lat: -34.397, lng: 150.644 },
10201018
zoom: 10,
1021-
zoomControl: true,
10221019
mapTypeControl: false,
10231020
streetViewControl: false,
10241021
fullscreenControl: false,
10251022
gestureHandling: "greedy",
1026-
});
1023+
};
1024+
if (isCameraControlVersion()) {
1025+
options.cameraControl = true;
1026+
} else {
1027+
options.zoomControl = true;
1028+
}
1029+
const map = new google.maps.Map(document.getElementById("location-map"), options);
10271030
state.map = map;
10281031

10291032
const autocomplete = new google.maps.places.SearchBox(
@@ -1102,7 +1105,7 @@ window.intiGoogleMap = () => {
11021105
console.log("No results found");
11031106
}
11041107
} else {
1105-
console.log("Geocoder failed due to: " + status);
1108+
console.log(`Geocoder failed due to: ${status}`);
11061109
}
11071110
}
11081111
);
@@ -1185,7 +1188,7 @@ const setActiveSidenavTab = (section) => {
11851188
const sidenav = document.querySelector('#sidenav');
11861189
for (const tab of sidenav.childNodes) {
11871190
tab.querySelector('a').classList.remove('active');
1188-
};
1191+
}
11891192

11901193
sidenav.querySelector(`#${section}-tab`).firstChild.classList.add('active');
11911194
};

src/shared/utils/mapUtils.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// eslint-disable-next-line max-len
2+
/**
3+
* Starting from version 3.60 (released in February 2025), Google Maps introduces a new Camera control
4+
* which replaces the traditional Zoom control as part of the default UI.
5+
* This version check function is necessary because the behavior of the controls changes:
6+
* If the version is 3.60 or higher, the new Camera control will be the default
7+
* If the version is below 3.60, the legacy Zoom control will still be applicable.
8+
* By determining the version, this function allows the code to handle the transition smoothly, ensuring compatibility with both
9+
* the old and new controls.
10+
*/
11+
12+
// eslint-disable-next-line import/prefer-default-export
13+
export const isCameraControlVersion = function () {
14+
const parseVersion = function (versionString) {
15+
const parts = versionString.split('.');
16+
return parts.map((part) => {
17+
const numericPart = part.replace(/\D/g, ''); // Extract the number
18+
const suffix = part.replace(/\d/g, ''); // Extract non-numeric suffix (e.g., 'beta')
19+
20+
return {
21+
number: parseInt(numericPart, 10) || 0,
22+
suffix: suffix || null
23+
};
24+
});
25+
};
26+
27+
const compareVersions = function (currentVersion, requiredVersion) {
28+
const length = Math.max(currentVersion.length, requiredVersion.length);
29+
30+
for (let i = 0; i < length; i++) {
31+
const curr = currentVersion[i] || { number: 0, suffix: null };
32+
const req = requiredVersion[i] || { number: 0, suffix: null };
33+
34+
if (curr.number > req.number) return 1;
35+
if (curr.number < req.number) return -1;
36+
37+
if (curr.suffix && !req.suffix) return -1; // beta is considered lower than stable
38+
if (!curr.suffix && req.suffix) return 1;
39+
if (curr.suffix && req.suffix && curr.suffix > req.suffix) return 1;
40+
if (curr.suffix && req.suffix && curr.suffix < req.suffix) return -1;
41+
}
42+
43+
return 0;
44+
};
45+
const VersionCheckService = function () {
46+
const currentVersionString = google.maps.version;
47+
const currentVersion = parseVersion(currentVersionString);
48+
const requiredVersion = parseVersion('3.60');
49+
return compareVersions(currentVersion, requiredVersion) >= 0;
50+
};
51+
return VersionCheckService();
52+
};

src/widget/css/main.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,11 @@ body section#home {
886886
z-index: 1;
887887
cursor: pointer;
888888
}
889+
.map-center-btn.left {
890+
right: initial;
891+
left: 10px;
892+
bottom: 115px;
893+
}
889894

890895
.map-center-btn * {
891896
pointer-events: none;

src/widget/js/map/Map.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import MarkerClusterer from './markercluster';
22
import CustomMarker from './CustomMarker';
33
import { cdnImage } from '../util/helpers';
4+
import { isCameraControlVersion } from "../../../shared/utils/mapUtils";
5+
46

57
export default class Map {
68
constructor(selector, options) {
@@ -26,6 +28,9 @@ export default class Map {
2628
},
2729
...userOptions,
2830
};
31+
if (isCameraControlVersion()) {
32+
document.querySelector('.map-center-btn').classList.add('left');
33+
}
2934
this.map = new google.maps.Map(selector, options);
3035
google.maps.event.addListenerOnce(this.map, 'idle', this.attachMapListeners.bind(this));
3136
}

src/widget/widget.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,7 @@ const initEventListeners = () => {
807807
const chipSets = {};
808808
const initFilterOverlay = () => {
809809
let categories = state.categories
810-
810+
811811
let html = '';
812812
const container = document.querySelector('#filter .expansion-panel__container .accordion');
813813
categories.forEach((category) => {

0 commit comments

Comments
 (0)