Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- [#123] Dark mode
- [#117] Users can see their location on the post map
- [#131] A message displays when an anonymous user clicks a heart

### Changed

- Map marker icon inherits the style of the Habitat logo

### Fixed

- Do not expect only database ID to be 1 for any entity
Expand Down
6 changes: 3 additions & 3 deletions assets/create_post.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ map.setMaxBounds(perimeter.getBounds().pad(0.3));
map.setMinZoom(map.getBoundsZoom(map.options.maxBounds));

var markerIcon = L.icon({
iconUrl: '/build/images/marker-icon.2b3e1faf.png',
iconSize: [25, 41],
iconAnchor: [13, 41],
iconUrl: '/build/images/marker_icon.png',
iconSize: [30, 41],
iconAnchor: [15, 41],
})

L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
Expand Down
Binary file added assets/img/location_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/img/marker_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 42 additions & 0 deletions assets/styles/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,48 @@ body {
}

#map { height: 100%; }

#map .leaflet-btn {
background-color: #fff;
border: 2px solid rgba(0,0,0,0.2);
border-radius: 4px;
background-clip: padding-box;
font-size: 15px;
height: 33px;
width: 33px;
}

#map .leaflet-btn-active {
background-color: #fffacd;
}

#map .leaflet-btn:hover {
background: rgb(244, 244, 244);
border: 2px solid rgba(0,0,0,0.33);
}

#map .leaflet-btn-active:hover {
background-color: #ffffe0;
}

@keyframes pulse {
0% { filter: brightness(1); }
50% { filter: brightness(1.3); }
100% { filter: brightness(1); }
}
#map .my-location-icon {
animation: pulse 2s infinite;
}

@keyframes walk {
to {
stroke-dashoffset: 24;
}
}
#map .location-path {
animation: walk 1s infinite;
}

.post-card a {
text-decoration: none !important;
}
Expand Down
159 changes: 156 additions & 3 deletions assets/view_map.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ require('leaflet');

if (document.getElementById('map') !== null) {
var location;
var watchPosition;
var myLocationEnabled = false;
var myLocationRefresh = false;
var relativeDistanceControl;
var centerLatLng = document.getElementById('map').dataset.center;
var centerLatLngArr = [
centerLatLng.substring(0, centerLatLng.indexOf(',')),
Expand All @@ -13,16 +17,39 @@ if (document.getElementById('map') !== null) {
});

var markerIcon = L.icon({
iconUrl: '/build/images/marker-icon.2b3e1faf.png',
iconSize: [25, 41],
iconAnchor: [13, 41],
iconUrl: '/build/images/marker_icon.png',
iconSize: [30, 41],
iconAnchor: [15, 41],
})

L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);

L.Control.MyLocation = L.Control.extend({
onAdd: function(map) {
viewLocationButton = L.DomUtil.create('button', 'leaflet-btn');

viewLocationButton.id = 'view-location-btn';
viewLocationButton.innerHTML = '<i class="bi bi-compass"></i>';
viewLocationButton.title = document.getElementById('map').dataset.showcurrentlocation;
viewLocationButton.setAttribute('data-test', 'current-location-btn')

return viewLocationButton;
},

onRemove: function(map) {
}
})
L.control.MyLocation = function(opts) {
return new L.Control.MyLocation(opts);
}

L.control.MyLocation({
position: 'bottomleft'
}).addTo(map);

let latLng = L.latLng(
centerLatLngArr
);
Expand All @@ -31,4 +58,130 @@ if (document.getElementById('map') !== null) {

map.addLayer(location);
map.setMaxBounds(latLng.toBounds(500));

document.getElementById('view-location-btn').onclick = function() {
myLocationEnabled = !myLocationEnabled;
if (myLocationEnabled) {
viewLocationButton.title = document.getElementById('map').dataset.hidecurrentlocation;
document.getElementById('view-location-btn').classList.add('leaflet-btn-active');
watchPosition = navigator.geolocation.watchPosition(setCurrentPosition, failCurrentPosition);
} else {
navigator.geolocation.clearWatch(watchPosition);
disableCurrentLocation();
}
}

function centerOnBounds(bounds) {
map.panTo(bounds.getCenter());
map.setMaxBounds(bounds.pad(0.5));
map.fitBounds(bounds);
}

function centerOnMarker() {
map.removeLayer(myLocation);
map.removeLayer(line);
map.setMaxBounds(latLng.toBounds(500));
map.panTo(latLng);
}

function failCurrentPosition(err) {
switch (err.code) {
case 1:
alert(document.getElementById('map').dataset.error);
break;
default:
alert(err.message);
}

disableCurrentLocation();
}

function disableCurrentLocation() {
viewLocationButton.title = document.getElementById('map').dataset.showcurrentlocation;
document.getElementById('view-location-btn').classList.remove('leaflet-btn-active');

if (relativeDistanceControl !== undefined) {
relativeDistanceControl.remove();
relativeDistanceControl = undefined;
}
myLocationRefresh = false;
centerOnMarker();
}

function setCurrentPosition(position) {
if (!myLocationEnabled) {
return;
}

var currentLatLng = L.latLng(parseFloat(position.coords.latitude).toPrecision(6), parseFloat(position.coords.longitude).toPrecision(6));

var locationIcon = L.icon({
iconUrl: '/build/images/location_icon.png',
iconSize: [30, 30],
iconAnchor: [15, 15],
className: 'my-location-icon',
})


let bounds = L.latLngBounds(latLng, currentLatLng);
if (myLocationRefresh) {
myLocation.setLatLng(currentLatLng);
map.removeLayer(line);
line = undefined;
distanceIndicator.innerHTML = printDistance(map.distance(currentLatLng, latLng));
// TODO:
// When the user is moving, it would be nice to center on the bounds of the target and their location
// but only if they haven't panned or zoomed - because otherwise that would be a frustrating experience.
// This is difficult because leaflet cannot currently discern between automated and manual pan/zoom events.
// Once this is available, we can implement it: https://github.com/Leaflet/Leaflet/pull/6929
// centerOnBounds(bounds);
} else {
myLocation = L.marker(currentLatLng, { icon: locationIcon, zIndexOffset: -1000 });
map.addLayer(myLocation);
myLocationRefresh = true;
centerOnBounds(bounds);

L.Control.RelativeDistance = L.Control.extend({
onAdd: function(map) {
distanceIndicator = L.DomUtil.create('div', 'bg-light rounded shadow-sm opacity-75 p-1 fs-6');

distanceIndicator.id = 'distanceIndicator';
distanceIndicator.title = document.getElementById('map').dataset.showcurrentlocation;
distanceIndicator.innerHTML = printDistance(map.distance(currentLatLng, latLng));
distanceIndicator.setAttribute('data-test', 'distance-indicator')

return distanceIndicator;
},

onRemove: function(map) {
}
})
L.control.RelativeDistance = function(opts) {
return new L.Control.RelativeDistance(opts);
}

relativeDistanceControl = L.control.RelativeDistance({
position: 'topright'
}).addTo(map);
}

line = L.polyline([latLng, currentLatLng], { color: 'white', weight: 6, dashArray: '10,14', className: 'location-path' });
line.addTo(map);
}

function printDistance(meters) {
let distance;
if (document.getElementById('map').dataset.measurementtype === 'km') {
distance = parseFloat(meters / 1000).toFixed(1);
} else {
distance = parseFloat(meters * 0.000621371192).toFixed(1);
}

if (distance % 1 === 0) {
distance = Math.round(distance);
}

return distance + ' ' + document.getElementById('map').dataset.measurement + ' ' + document.getElementById('map').dataset.away;
}
}

12 changes: 6 additions & 6 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
"php": ">=8.4.17",
"ext-ctype": "*",
"ext-iconv": "*",
"aws/aws-sdk-php": "^3.380.3",
"aws/aws-sdk-php": "^3.383.1",
"doctrine/doctrine-bundle": "^3.2.2",
"doctrine/doctrine-migrations-bundle": "^4.0",
"doctrine/orm": "^3.6.4",
"doctrine/orm": "^3.6.7",
"dragonmantank/cron-expression": ">=3.6",
"knplabs/knp-time-bundle": "^2.5",
"symfony/console": "8.0.*",
"symfony/dotenv": "8.0.*",
"symfony/expression-language": "8.0.*",
"symfony/flex": "^2.10",
"symfony/flex": "^2.11",
"symfony/framework-bundle": "8.0.*",
"symfony/html-sanitizer": "8.0.*",
"symfony/mailer": "8.0.*",
Expand All @@ -29,7 +29,7 @@
"symfony/security-csrf": "8.0.*",
"symfony/translation": "8.0.*",
"symfony/twig-bundle": "8.0.*",
"symfony/ux-twig-component": "^2.35",
"symfony/ux-twig-component": "^2.36",
"symfony/validator": "8.0.*",
"symfony/webpack-encore-bundle": "^2.4",
"symfony/yaml": "8.0.*"
Expand Down Expand Up @@ -89,8 +89,8 @@
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^4.3.1",
"friendsofphp/php-cs-fixer": "^3.95.1",
"phpunit/phpunit": "^13.1.8",
"friendsofphp/php-cs-fixer": "^3.95.3",
"phpunit/phpunit": "^13.1.13",
"symfony/browser-kit": "8.0.*",
"symfony/css-selector": "8.0.*",
"symfony/maker-bundle": "^1.67.0"
Expand Down
Loading
Loading