From 675ef123036d069c9b75fc620c7027f2a7e87b91 Mon Sep 17 00:00:00 2001 From: NSUWAL123 Date: Thu, 21 Mar 2024 09:41:29 +0545 Subject: [PATCH 1/7] fix projectListMap: remove geolocation from homePage map --- .../src/components/home/ProjectListMap.tsx | 170 ------------------ 1 file changed, 170 deletions(-) diff --git a/src/frontend/src/components/home/ProjectListMap.tsx b/src/frontend/src/components/home/ProjectListMap.tsx index 8471f0812e..9964ab4c77 100644 --- a/src/frontend/src/components/home/ProjectListMap.tsx +++ b/src/frontend/src/components/home/ProjectListMap.tsx @@ -2,7 +2,6 @@ import React, { useState, useEffect } from 'react'; import { useOLMap } from '@/components/MapComponent/OpenLayersComponent'; import { MapContainer as MapComponent } from '@/components/MapComponent/OpenLayersComponent'; import LayerSwitcherControl from '@/components/MapComponent/OpenLayersComponent/LayerSwitcher/index.js'; -import OLVectorLayer from 'ol/layer/Vector'; import { ClusterLayer } from '@/components/MapComponent/OpenLayersComponent/Layers'; import CoreModules from '@/shared/CoreModules'; import { geojsonObjectModel } from '@/constants/geojsonObjectModal'; @@ -12,16 +11,6 @@ import { useNavigate } from 'react-router-dom'; import environment from '@/environment'; import { Style, Text, Icon, Fill } from 'ol/style'; import { projectType } from '@/models/home/homeModel'; -import Control from 'ol/control/Control'; -import { Feature } from 'ol'; -import { circular } from 'ol/geom/Polygon'; -import { Point } from 'ol/geom'; -import { fromLonLat } from 'ol/proj'; -import VectorSource from 'ol/source/Vector'; -import logo from '@/assets/images/navigation.svg'; -import RedNavigationMarker from '@/assets/images/rednavigationmarker.svg'; -import navigationMarker from '@/assets/images/navigation.png'; -import pngbluedot from '@/assets/images/png bluedot.png'; type HomeProjectSummaryType = { features: { geometry: any; properties: any; type: any }[]; @@ -34,21 +23,6 @@ type HomeProjectSummaryType = { }; }; -// const projectGeojsonLayerStyle = { -// ...defaultStyles, -// fillOpacity: 0, -// lineColor: '#ffffff', -// labelFontSize: 20, -// lineThickness: 7, -// lineOpacity: 40, -// showLabel: true, -// labelField: 'project_id', -// labelOffsetY: 35, -// labelFontWeight: 'bold', -// labelMaxResolution: 10000, -// icon: { scale: [0.09, 0.09], url: MarkerIcon }, -// }; - const getIndividualStyle = (featureProperty) => { const style = new Style({ image: new Icon({ @@ -77,151 +51,7 @@ const ProjectListMap = () => { zoom: 4, maxZoom: 20, }); - useEffect(() => { - if (!map) return; - const source = new VectorSource(); - const layer = new OLVectorLayer({ - source: source, - }); - map?.addLayer(layer); - - navigator.geolocation.watchPosition( - function (pos) { - const coords = [pos.coords.longitude, pos.coords.latitude]; - source.clear(true); - source.addFeatures([ - new Feature(circular(coords, pos.coords.accuracy).transform('EPSG:4326', map.getView().getProjection())), - new Feature(new Point(fromLonLat(coords))), - ]); - }, - function (error) { - alert(`ERROR: ${error.message}`); - }, - { - enableHighAccuracy: true, - }, - ); - const locate = document.createElement('div'); - locate.className = 'ol-control ol-unselectable locate'; - locate.innerHTML = ''; - locate.addEventListener('click', function () { - if (!source.isEmpty()) { - map.getView().fit(source.getExtent(), { - maxZoom: 18, - duration: 500, - }); - } - }); - map.addControl( - new Control({ - element: locate, - }), - ); - //! [style] - const style = new Style({ - fill: new Fill({ - color: 'rgba(0, 0, 255, 0.2)', - }), - image: new Icon({ - src: pngbluedot, - scale: 0.09, - imgSize: [27, 55], - rotateWithView: true, - }), - }); - layer.setStyle(style); - - function handleReading(quaternion) { - // https://w3c.github.io/orientation-sensor/#model explains the order of - // the 4 elements in the sensor.quaternion array. - let [qx, qy, qz, qw] = quaternion; - - // When the phone is lying flat, we want to treat the direction toward the - // top of the phone as the "forward" direction; when the phone is held - // upright, we want to treat the direction out the back of the phone as the - // "forward" direction. So, let's determine the compass heading of the - // phone based on the vector between these directions, i.e. at a 45-degree - // angle between the positive Y-axis and the negative Z-axis in this figure: - // https://w3c.github.io/orientation-sensor/#absoluteorientationsensor-model - - // To find the current "forward" direction of the phone, we want to take this - // vector, (0, 1, -1), and apply the same rotation as the phone's rotation. - const y = 1; - const z = -1; - - // From experimentation, it looks like the quaternion from the sensor is - // the inverse rotation, so we need to flip the fourth component. - qw = -qw; - - // This section explains how to convert the quaternion to a rotation matrix: - // https://w3c.github.io/orientation-sensor/#convert-quaternion-to-rotation-matrix - // Now let's multiply the forward vector by the rotation matrix. - const rx = y * (2 * qx * qy + 2 * qw * qz) + z * (2 * qx * qz - 2 * qw * qy); - const ry = y * (1 - 2 * qx * qx - 2 * qz * qz) + z * (2 * qy * qz + 2 * qw * qx); - const rz = y * (2 * qy * qz + 2 * qw * qx) + z * (1 - 2 * qx * qx - 2 * qy * qy); - - // This gives us a rotated vector indicating the "forward" direction of the - // phone with respect to the earth. We only care about the orientation of - // this vector in the XY plane (the plane tangential to the ground), i.e. - // the heading of the (rx, ry) vector, where (0, 1) is north. - - const radians = Math.atan2(ry, rx); - const degrees = (radians * 180) / Math.PI; // counterclockwise from +X axis - let heading = 90 - degrees; - if (heading < 0) heading += 360; - heading = Math.round(heading); - - // info.value = - // qx.toFixed(3) + - // "\n" + - // qy.toFixed(3) + - // "\n" + - // qz.toFixed(3) + - // "\n" + - // qw.toFixed(3) + - // "\n\n" + - // rx.toFixed(3) + - // "\n" + - // ry.toFixed(3) + - // "\n" + - // rz.toFixed(3) + - // "\n\nHeading: " + - // heading; - console.log(heading, 'heading'); - console.log((Math.PI / 180) * heading, '(Math.PI / 180) * heading'); - // To make the arrow point north, rotate it opposite to the phone rotation. - style.getImage().setRotation((Math.PI / 180) * heading); - } - - // See the API specification at: https://w3c.github.io/orientation-sensor - // We use referenceFrame: 'screen' because the web page will rotate when - // the phone switches from portrait to landscape. - const sensor = new AbsoluteOrientationSensor({ - frequency: 60, - referenceFrame: 'screen', - }); - sensor.addEventListener('reading', (event) => { - console.log(event, 'event'); - layer.on('postrender', handleReading(sensor.quaternion)); - }); - // handleReading([0.509, -0.071, -0.19, 0.836]); - - Promise.all([ - navigator.permissions.query({ name: 'accelerometer' }), - navigator.permissions.query({ name: 'magnetometer' }), - navigator.permissions.query({ name: 'gyroscope' }), - ]).then((results) => { - if (results.every((result) => result.state === 'granted')) { - sensor.start(); - console.log('Sensor started!'); - // stat.value = "Sensor started!"; - } else { - console.log('No permissions to use AbsoluteOrientationSensor.'); - // stat.value = "No permissions to use AbsoluteOrientationSensor."; - } - }); - }, [map]); const homeProjectSummary: projectType[] = CoreModules.useAppSelector((state) => state.home.homeProjectSummary); useEffect(() => { if (homeProjectSummary?.length === 0) return; From 24941f8dec986e2f84cca8946659934308a3c788 Mon Sep 17 00:00:00 2001 From: NSUWAL123 Date: Thu, 21 Mar 2024 09:42:12 +0545 Subject: [PATCH 2/7] refactor projectListMap: remove old vectorLayer code --- .../src/components/home/ProjectListMap.tsx | 39 ------------------- 1 file changed, 39 deletions(-) diff --git a/src/frontend/src/components/home/ProjectListMap.tsx b/src/frontend/src/components/home/ProjectListMap.tsx index 9964ab4c77..81703e08e9 100644 --- a/src/frontend/src/components/home/ProjectListMap.tsx +++ b/src/frontend/src/components/home/ProjectListMap.tsx @@ -91,45 +91,6 @@ const ProjectListMap = () => { }} > - {/* {projectGeojson && projectGeojson?.features?.length > 0 && ( - { - // if (!selectedFeature) - // return layer.setStyle((feature, resolution) => - // getStyles({ - // style: { ...projectGeojsonLayerStyle }, - // feature, - // resolution, - // }), - // ); - // else { - // selectedFeature.setStyle((feature, resolution) => - // getStyles({ - // style: { ...projectGeojsonLayerStyle, icon: { scale: [0.15, 0.15], url: MarkerIcon } }, - // feature, - // resolution, - // }), - // ); - // } - // // selectedFeature.setStyle({ - // // ...projectGeojsonLayerStyle, - // // icon: { scale: [0.15, 0.15], url: MarkerIcon }, - // // }); - // // selectedFeature.setStyle(); - // }} - /> - )} */} {projectGeojson && projectGeojson?.features?.length > 0 && ( Date: Thu, 21 Mar 2024 11:49:58 +0545 Subject: [PATCH 3/7] feat projectDetails: geolocationStatus add --- .../ProjectDetailsV2/MapControlComponent.tsx | 22 ++++++++----------- src/frontend/src/store/slices/ProjectSlice.ts | 4 ++++ src/frontend/src/store/types/IProject.ts | 1 + src/frontend/src/views/ProjectDetailsV2.tsx | 5 +++-- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/frontend/src/components/ProjectDetailsV2/MapControlComponent.tsx b/src/frontend/src/components/ProjectDetailsV2/MapControlComponent.tsx index d90c248a61..6432ee634a 100644 --- a/src/frontend/src/components/ProjectDetailsV2/MapControlComponent.tsx +++ b/src/frontend/src/components/ProjectDetailsV2/MapControlComponent.tsx @@ -1,6 +1,9 @@ import React, { useState } from 'react'; import AssetModules from '@/shared/AssetModules'; import VectorLayer from 'ol/layer/Vector'; +import CoreModules from '@/shared/CoreModules.js'; +import { ProjectActions } from '@/store/slices/ProjectSlice'; +import { useAppSelector } from '@/types/reduxTypes'; const MapControlComponent = ({ map }) => { const btnList = [ @@ -26,6 +29,10 @@ const MapControlComponent = ({ map }) => { }, ]; + const dispatch = CoreModules.useAppDispatch(); + const [toggleCurrentLoc, setToggleCurrentLoc] = useState(false); + const geolocationStatus = useAppSelector((state) => state.project.geolocationStatus); + const handleOnClick = (btnId) => { if (btnId === 'add') { const actualZoom = map.getView().getZoom(); @@ -34,19 +41,8 @@ const MapControlComponent = ({ map }) => { const actualZoom = map.getView().getZoom(); map.getView().setZoom(actualZoom - 1); } else if (btnId === 'currentLocation') { - const layers = map.getAllLayers(); - let extent; - layers.map((layer) => { - if (layer instanceof VectorLayer) { - const layerName = layer.getProperties().name; - if (layerName === 'geolocation') { - extent = layer.getSource().getExtent(); - } - } - }); - map.getView().fit(extent, { - padding: [10, 10, 10, 10], - }); + setToggleCurrentLoc(!toggleCurrentLoc); + dispatch(ProjectActions.ToggleGeolocationStatus(!geolocationStatus)); } else if (btnId === 'taskBoundries') { const layers = map.getAllLayers(); let extent; diff --git a/src/frontend/src/store/slices/ProjectSlice.ts b/src/frontend/src/store/slices/ProjectSlice.ts index 94002ba403..eebbac3c47 100755 --- a/src/frontend/src/store/slices/ProjectSlice.ts +++ b/src/frontend/src/store/slices/ProjectSlice.ts @@ -31,6 +31,7 @@ const initialState: ProjectStateTypes = { last_active: '', }, projectDashboardLoading: false, + geolocationStatus: false, }; const ProjectSlice = createSlice({ @@ -95,6 +96,9 @@ const ProjectSlice = createSlice({ SetProjectDashboardLoading(state, action) { state.projectDashboardLoading = action.payload; }, + ToggleGeolocationStatus(state, action) { + state.geolocationStatus = action.payload; + }, }, }); diff --git a/src/frontend/src/store/types/IProject.ts b/src/frontend/src/store/types/IProject.ts index 12eba2d6f5..9fa9e88069 100644 --- a/src/frontend/src/store/types/IProject.ts +++ b/src/frontend/src/store/types/IProject.ts @@ -25,6 +25,7 @@ export type ProjectStateTypes = { projectDetailsLoading: boolean; projectDashboardDetail: projectDashboardDetailTypes; projectDashboardLoading: boolean; + geolocationStatus: boolean; }; type tilesListTypes = { diff --git a/src/frontend/src/views/ProjectDetailsV2.tsx b/src/frontend/src/views/ProjectDetailsV2.tsx index fb58acf51e..987d8d8e00 100644 --- a/src/frontend/src/views/ProjectDetailsV2.tsx +++ b/src/frontend/src/views/ProjectDetailsV2.tsx @@ -63,6 +63,7 @@ const Home = () => { const mobileFooterSelection = useAppSelector((state) => state.project.mobileFooterSelection); const mapTheme = useAppSelector((state) => state.theme.hotTheme); const projectDetailsLoading = useAppSelector((state) => state?.project?.projectDetailsLoading); + const geolocationStatus = useAppSelector((state) => state.project.geolocationStatus); //snackbar handle close funtion const handleClose = (event, reason) => { @@ -106,8 +107,8 @@ const Home = () => { useEffect(() => { if (!map) return; - Geolocation(map); - }, [map]); + Geolocation(map, geolocationStatus); + }, [geolocationStatus]); const { y } = OnScroll(map, windowSize.width); From f8cdd2657eba890899d851feafebe210c03463cd Mon Sep 17 00:00:00 2001 From: NSUWAL123 Date: Thu, 21 Mar 2024 11:51:24 +0545 Subject: [PATCH 4/7] fix geoLocation: add & remove geoLocation layer conditionally --- src/frontend/src/utilfunctions/Geolocation.ts | 208 ++++++++++-------- 1 file changed, 121 insertions(+), 87 deletions(-) diff --git a/src/frontend/src/utilfunctions/Geolocation.ts b/src/frontend/src/utilfunctions/Geolocation.ts index f15bcb9c66..050b37fb11 100644 --- a/src/frontend/src/utilfunctions/Geolocation.ts +++ b/src/frontend/src/utilfunctions/Geolocation.ts @@ -8,6 +8,7 @@ import { fromLonLat } from 'ol/proj'; import { circular } from 'ol/geom/Polygon'; import { Style } from 'ol/style'; import { Icon } from 'ol/style'; +import VectorLayer from 'ol/layer/Vector'; const locationIconStyle = new Style({ fill: new Fill({ @@ -21,7 +22,7 @@ const locationIconStyle = new Style({ }), }); -export const Geolocation = (map) => { +export const Geolocation = (map, geolocationStatus) => { if (!map) return; const source = new VectorSource(); const layer = new OLVectorLayer({ @@ -30,93 +31,126 @@ export const Geolocation = (map) => { name: 'geolocation', }, }); - map?.addLayer(layer); - - navigator.geolocation.watchPosition( - function (pos) { - const coords = [pos.coords.longitude, pos.coords.latitude]; - source.clear(true); - source.addFeatures([ - new Feature(circular(coords, pos.coords.accuracy).transform('EPSG:4326', map.getView().getProjection())), - new Feature(new Point(fromLonLat(coords))), - ]); - }, - function (error) { - alert(`ERROR: ${error.message}`); - }, - { - enableHighAccuracy: true, - }, - ); - - layer.setStyle(locationIconStyle); - - function handleReading(quaternion) { - // https://w3c.github.io/orientation-sensor/#model explains the order of - // the 4 elements in the sensor.quaternion array. - let [qx, qy, qz, qw] = quaternion; - - // When the phone is lying flat, we want to treat the direction toward the - // top of the phone as the "forward" direction; when the phone is held - // upright, we want to treat the direction out the back of the phone as the - // "forward" direction. So, let's determine the compass heading of the - // phone based on the vector between these directions, i.e. at a 45-degree - // angle between the positive Y-axis and the negative Z-axis in this figure: - // https://w3c.github.io/orientation-sensor/#absoluteorientationsensor-model - - // To find the current "forward" direction of the phone, we want to take this - // vector, (0, 1, -1), and apply the same rotation as the phone's rotation. - const y = 1; - const z = -1; - - // From experimentation, it looks like the quaternion from the sensor is - // the inverse rotation, so we need to flip the fourth component. - qw = -qw; - - // This section explains how to convert the quaternion to a rotation matrix: - // https://w3c.github.io/orientation-sensor/#convert-quaternion-to-rotation-matrix - // Now let's multiply the forward vector by the rotation matrix. - const rx = y * (2 * qx * qy + 2 * qw * qz) + z * (2 * qx * qz - 2 * qw * qy); - const ry = y * (1 - 2 * qx * qx - 2 * qz * qz) + z * (2 * qy * qz + 2 * qw * qx); - const rz = y * (2 * qy * qz + 2 * qw * qx) + z * (1 - 2 * qx * qx - 2 * qy * qy); - - // This gives us a rotated vector indicating the "forward" direction of the - // phone with respect to the earth. We only care about the orientation of - // this vector in the XY plane (the plane tangential to the ground), i.e. - // the heading of the (rx, ry) vector, where (0, 1) is north. - - const radians = Math.atan2(ry, rx); - const degrees = (radians * 180) / Math.PI; // counterclockwise from +X axis - let heading = 90 - degrees; - if (heading < 0) heading += 360; - heading = Math.round(heading); - - // To make the arrow point north, rotate it opposite to the phone rotation. - locationIconStyle.getImage().setRotation((Math.PI / 180) * heading); - } - // See the API specification at: https://w3c.github.io/orientation-sensor - // We use referenceFrame: 'screen' because the web page will rotate when - // the phone switches from portrait to landscape. - const sensor = new AbsoluteOrientationSensor({ - frequency: 60, - referenceFrame: 'screen', - }); - sensor.addEventListener('reading', (event) => { - layer.on('postrender', handleReading(sensor.quaternion)); - }); - // handleReading([0.509, -0.071, -0.19, 0.836]); - - Promise.all([ - navigator.permissions.query({ name: 'accelerometer' }), - navigator.permissions.query({ name: 'magnetometer' }), - navigator.permissions.query({ name: 'gyroscope' }), - ]).then((results) => { - if (results.every((result) => result.state === 'granted')) { - sensor.start(); - // stat.value = "Sensor started!"; - } else { - // stat.value = "No permissions to use AbsoluteOrientationSensor."; + let hasGeolocationLayer = false; + const layers = map.getAllLayers(); + layers.map((layerx) => { + if (layerx instanceof VectorLayer) { + const layerName = layerx.getProperties().name; + if (layerName === 'geolocation') { + hasGeolocationLayer = true; + } } }); + + // only add layer if geolocationStatus is on & has no prior layer with name geolocation + if (geolocationStatus && !hasGeolocationLayer) { + map?.addLayer(layer); + } + + if (geolocationStatus) { + navigator.geolocation.watchPosition( + function (pos) { + const coords = [pos.coords.longitude, pos.coords.latitude]; + source.clear(true); + source.addFeatures([ + new Feature(circular(coords, pos.coords.accuracy).transform('EPSG:4326', map.getView().getProjection())), + new Feature(new Point(fromLonLat(coords))), + ]); + }, + function (error) { + alert(`ERROR: ${error.message}`); + }, + { + enableHighAccuracy: true, + }, + ); + + layer.setStyle(locationIconStyle); + + function handleReading(quaternion) { + // https://w3c.github.io/orientation-sensor/#model explains the order of + // the 4 elements in the sensor.quaternion array. + let [qx, qy, qz, qw] = quaternion; + + // When the phone is lying flat, we want to treat the direction toward the + // top of the phone as the "forward" direction; when the phone is held + // upright, we want to treat the direction out the back of the phone as the + // "forward" direction. So, let's determine the compass heading of the + // phone based on the vector between these directions, i.e. at a 45-degree + // angle between the positive Y-axis and the negative Z-axis in this figure: + // https://w3c.github.io/orientation-sensor/#absoluteorientationsensor-model + + // To find the current "forward" direction of the phone, we want to take this + // vector, (0, 1, -1), and apply the same rotation as the phone's rotation. + const y = 1; + const z = -1; + + // From experimentation, it looks like the quaternion from the sensor is + // the inverse rotation, so we need to flip the fourth component. + qw = -qw; + + // This section explains how to convert the quaternion to a rotation matrix: + // https://w3c.github.io/orientation-sensor/#convert-quaternion-to-rotation-matrix + // Now let's multiply the forward vector by the rotation matrix. + const rx = y * (2 * qx * qy + 2 * qw * qz) + z * (2 * qx * qz - 2 * qw * qy); + const ry = y * (1 - 2 * qx * qx - 2 * qz * qz) + z * (2 * qy * qz + 2 * qw * qx); + const rz = y * (2 * qy * qz + 2 * qw * qx) + z * (1 - 2 * qx * qx - 2 * qy * qy); + + // This gives us a rotated vector indicating the "forward" direction of the + // phone with respect to the earth. We only care about the orientation of + // this vector in the XY plane (the plane tangential to the ground), i.e. + // the heading of the (rx, ry) vector, where (0, 1) is north. + + const radians = Math.atan2(ry, rx); + const degrees = (radians * 180) / Math.PI; // counterclockwise from +X axis + let heading = 90 - degrees; + if (heading < 0) heading += 360; + heading = Math.round(heading); + + // To make the arrow point north, rotate it opposite to the phone rotation. + locationIconStyle.getImage().setRotation((Math.PI / 180) * heading); + } + + // See the API specification at: https://w3c.github.io/orientation-sensor + // We use referenceFrame: 'screen' because the web page will rotate when + // the phone switches from portrait to landscape. + const sensor = new AbsoluteOrientationSensor({ + frequency: 60, + referenceFrame: 'screen', + }); + sensor.addEventListener('reading', (event) => { + layer.on('postrender', handleReading(sensor.quaternion)); + }); + // handleReading([0.509, -0.071, -0.19, 0.836]); + + Promise.all([ + navigator.permissions.query({ name: 'accelerometer' }), + navigator.permissions.query({ name: 'magnetometer' }), + navigator.permissions.query({ name: 'gyroscope' }), + ]).then((results) => { + if (results.every((result) => result.state === 'granted')) { + sensor.start(); + // stat.value = "Sensor started!"; + } else { + // stat.value = "No permissions to use AbsoluteOrientationSensor."; + } + }); + } + + // remove the geolocation layer if geolocationStatus turned off + if (!geolocationStatus) { + let layerToBeRemoved; + layers.map((layerx) => { + if (layerx instanceof VectorLayer) { + const layerName = layerx.getProperties().name; + if (layerName === 'geolocation') { + layerToBeRemoved = layerx; + } + } + }); + if (layerToBeRemoved) { + map?.removeLayer(layerToBeRemoved); + } + } }; From 5065673bbd8c97fdddb1091a71b7290dc224a224 Mon Sep 17 00:00:00 2001 From: NSUWAL123 Date: Thu, 21 Mar 2024 12:49:29 +0545 Subject: [PATCH 5/7] fix mapControlComponent: change geolocation point to red if status on --- .../src/components/ProjectDetailsV2/MapControlComponent.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/components/ProjectDetailsV2/MapControlComponent.tsx b/src/frontend/src/components/ProjectDetailsV2/MapControlComponent.tsx index 6432ee634a..41882956f7 100644 --- a/src/frontend/src/components/ProjectDetailsV2/MapControlComponent.tsx +++ b/src/frontend/src/components/ProjectDetailsV2/MapControlComponent.tsx @@ -65,7 +65,9 @@ const MapControlComponent = ({ map }) => { {btnList.map((btn) => (
handleOnClick(btn.id)} title={btn.title} > From ed36198162db610af17f60418d33036ea04522cf Mon Sep 17 00:00:00 2001 From: NSUWAL123 Date: Thu, 21 Mar 2024 12:50:19 +0545 Subject: [PATCH 6/7] fix projectDetails: set generateMbtiles btn to bottom for mobile screen --- src/frontend/src/views/ProjectDetailsV2.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/views/ProjectDetailsV2.tsx b/src/frontend/src/views/ProjectDetailsV2.tsx index 987d8d8e00..d71ba9bda1 100644 --- a/src/frontend/src/views/ProjectDetailsV2.tsx +++ b/src/frontend/src/views/ProjectDetailsV2.tsx @@ -361,7 +361,7 @@ const Home = () => { collapsed={true} />
-
+