Some fixes for nosleep and moving the map around

This commit is contained in:
Lucas Verney 2018-07-03 18:09:56 +02:00
parent 857e95845c
commit 37413a7e21
6 changed files with 89 additions and 64 deletions

View File

@ -23,7 +23,7 @@
"vue-router": "^3.0.1", "vue-router": "^3.0.1",
"vue2-leaflet": "^1.0.2", "vue2-leaflet": "^1.0.2",
"vue2-leaflet-tracksymbol": "^1.0.10", "vue2-leaflet-tracksymbol": "^1.0.10",
"vuetify": "^1.0.0", "vuetify": "^1.1.0",
"vuex": "^3.0.1" "vuex": "^3.0.1"
}, },
"devDependencies": { "devDependencies": {

7
src/components/Intro.vue Normal file
View File

@ -0,0 +1,7 @@
<template>
</template>
<script>
export default {
};
</script>

View File

@ -10,6 +10,20 @@
<ReportMarker v-for="marker in markers" :key="marker.id" :marker="marker"></ReportMarker> <ReportMarker v-for="marker in markers" :key="marker.id" :marker="marker"></ReportMarker>
</v-lmap> </v-lmap>
<v-btn
absolute
dark
fab
large
bottom
left
color="blue"
class="overlayButton"
v-if="recenterButton"
@click.native.stop="recenterMap"
>
<v-icon>my_location</v-icon>
</v-btn>
</div> </div>
</template> </template>
@ -79,26 +93,39 @@ export default {
this.isProgrammaticZoom = true; this.isProgrammaticZoom = true;
this.map.once('zoomend', () => { this.isProgrammaticZoom = false; }); this.map.once('zoomend', () => { this.isProgrammaticZoom = false; });
} }
if (this.map.getCenter() !== this.positionLatLng) { if (
this.map.getCenter().lat !== this.positionLatLng[0] &&
this.map.getCenter().lng !== this.positionLatLng[1]
) {
this.isProgrammaticMove = true; this.isProgrammaticMove = true;
this.map.once('moveend', () => { this.isProgrammaticMove = false; }); this.map.once('moveend', () => { this.isProgrammaticMove = false; });
} }
this.map.setView(this.positionLatLng, this.zoom); this.map.setView(this.positionLatLng, this.zoom);
this.showCompass(); this.showCompass();
}, },
updated() { watch: {
positionLatLng: (newPositionLatLng) => {
if (!this.map) {
// Map should have been created
return;
}
if (!this.recenterButton) { if (!this.recenterButton) {
// Handle programmatic navigation
if (this.map.getZoom() !== this.zoom) { if (this.map.getZoom() !== this.zoom) {
this.isProgrammaticZoom = true; this.isProgrammaticZoom = true;
this.map.once('zoomend', () => { this.isProgrammaticZoom = false; }); this.map.once('zoomend', () => { this.isProgrammaticZoom = false; });
} }
if (this.map.getCenter() !== this.positionLatLng) { if (
this.map.getCenter().lat !== newPositionLatLng[0] &&
this.map.getCenter().lng !== newPositionLatLng[1]
) {
this.isProgrammaticMove = true; this.isProgrammaticMove = true;
this.map.once('moveend', () => { this.isProgrammaticMove = false; }); this.map.once('moveend', () => { this.isProgrammaticMove = false; });
} }
this.map.setView(this.positionLatLng, this.zoom); this.map.setView(this.positionLatLng, this.zoom);
} }
}, },
},
data() { data() {
return { return {
attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors', attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors',
@ -110,7 +137,7 @@ export default {
isMouseDown: false, isMouseDown: false,
isProgrammaticZoom: false, isProgrammaticZoom: false,
isProgrammaticMove: false, isProgrammaticMove: false,
recenterButton: null, recenterButton: false,
map: null, map: null,
}; };
}, },
@ -120,7 +147,8 @@ export default {
this.onPress(event.latlng); this.onPress(event.latlng);
} }
}, },
onMoveStart() { onMoveStart(ev) {
console.log(ev, this.isProgrammaticMove);
if (!this.isProgrammaticMove) { if (!this.isProgrammaticMove) {
this.showRecenterButton(); this.showRecenterButton();
} }
@ -142,22 +170,12 @@ export default {
}, },
showRecenterButton() { showRecenterButton() {
if (!this.recenterButton) { if (!this.recenterButton) {
this.recenterButton = L.control({ position: 'bottomleft' }); this.recenterButton = true;
this.recenterButton.onAdd = () => {
const btn = L.DomUtil.create('button', 'overlayButton btn btn--floating btn--large theme--dark blue legend');
btn.type = 'button';
btn.addEventListener('click', this.recenterMap);
btn.innerHTML = '<div class="btn__content"><i aria-hidden="true" class="icon material-icons">my_location</i></div>';
L.DomEvent.disableClickPropagation(btn);
return btn;
};
this.map.addControl(this.recenterButton);
} }
}, },
hideRecenterButton() { hideRecenterButton() {
if (this.recenterButton) { if (this.recenterButton) {
this.map.removeControl(this.recenterButton); this.recenterButton = false;
this.recenterButton = null;
} }
}, },
recenterMap() { recenterMap() {
@ -166,7 +184,10 @@ export default {
this.isProgrammaticZoom = true; this.isProgrammaticZoom = true;
this.map.once('zoomend', () => { this.isProgrammaticZoom = false; }); this.map.once('zoomend', () => { this.isProgrammaticZoom = false; });
} }
if (this.map.getCenter() !== this.positionLatLng) { if (
this.map.getCenter().lat !== this.positionLatLng[0] &&
this.map.getCenter().lng !== this.positionLatLng[1]
) {
this.isProgrammaticMove = true; this.isProgrammaticMove = true;
this.map.once('moveend', () => { this.isProgrammaticMove = false; }); this.map.once('moveend', () => { this.isProgrammaticMove = false; });
} }

View File

@ -12,6 +12,9 @@ export default {
fetching: 'Fetching current position…', fetching: 'Fetching current position…',
unavailable: 'Sorry, geolocation is not available in your browser.', unavailable: 'Sorry, geolocation is not available in your browser.',
}, },
intro: {
start: "Let's go!",
},
menu: { menu: {
About: 'Help', About: 'Help',
Map: 'Map', Map: 'Map',

View File

@ -1,10 +1,17 @@
<template> <template>
<v-container fluid fill-height class="no-padding"> <v-container fluid fill-height class="no-padding">
<v-layout row wrap fill-height> <v-layout v-if="isIntro" row wrap class="text-xs-center blue lighten-2">
<v-flex xs8 offset-xs2>
<p><img src="static/icon.svg" alt="Logo"/></p></p>
<p>{{ $t('about.summary') }}</p>
<v-btn round color="green" dark @click="introButtonClick">{{ $t('intro.start') }}</v-btn>
</v-flex>
</v-layout>
<v-layout v-else row wrap fill-height>
<v-flex xs12 fill-height v-if="latLng"> <v-flex xs12 fill-height v-if="latLng">
<Map :positionLatLng="latLng" :heading="heading" :accuracy="accuracy" :markers="reportsMarkers" :onPress="showReportDialog"></Map> <Map :positionLatLng="latLng" :heading="heading" :accuracy="accuracy" :markers="reportsMarkers" :onPress="showReportDialog"></Map>
<v-btn <v-btn
fixed absolute
dark dark
fab fab
large large
@ -46,16 +53,12 @@ export default {
Map, Map,
ReportDialog, ReportDialog,
}, },
created() {
this.initializePositionWatching();
this.listenForFirstInteraction();
this.$store.dispatch('fetchReports');
window.addEventListener('keydown', this.hideReportDialogOnEsc);
},
beforeDestroy() { beforeDestroy() {
if (!this.isIntro) {
this.disableNoSleep(); this.disableNoSleep();
this.disablePositionWatching(); this.disablePositionWatching();
window.removeEventListener('keydown', this.hideReportDialogOnEsc); window.removeEventListener('keydown', this.hideReportDialogOnEsc);
}
}, },
computed: { computed: {
reportsMarkers() { reportsMarkers() {
@ -73,6 +76,7 @@ export default {
dialog: false, dialog: false,
error: null, error: null,
heading: null, heading: null,
isIntro: true,
latLng: null, latLng: null,
noSleep: null, noSleep: null,
reportLat: null, reportLat: null,
@ -163,25 +167,12 @@ export default {
this.dialog = false; this.dialog = false;
} }
}, },
handleFirstUserInteraction() { introButtonClick() {
this.setNoSleep(); this.setNoSleep();
this.isIntro = false;
window.removeEventListener('mousemove', this.handleFirstUserInteraction, false); this.initializePositionWatching();
window.removeEventListener('mousedown', this.handleFirstUserInteraction, false); this.$store.dispatch('fetchReports');
window.removeEventListener('keypress', this.handleFirstUserInteraction, false); window.addEventListener('keydown', this.hideReportDialogOnEsc);
window.removeEventListener('DOMMouseScroll', this.handleFirstUserInteraction, false);
window.removeEventListener('mousewheel', this.handleFirstUserInteraction, false);
window.removeEventListener('touchmove', this.handleFirstUserInteraction, false);
window.removeEventListener('MSPointerMove', this.handleFirstUserInteraction, false);
},
listenForFirstInteraction() {
window.addEventListener('mousemove', this.handleFirstUserInteraction, false);
window.addEventListener('mousedown', this.handleFirstUserInteraction, false);
window.addEventListener('keypress', this.handleFirstUserInteraction, false);
window.addEventListener('DOMMouseScroll', this.handleFirstUserInteraction, false);
window.addEventListener('mousewheel', this.handleFirstUserInteraction, false);
window.addEventListener('touchmove', this.handleFirstUserInteraction, false);
window.addEventListener('MSPointerMove', this.handleFirstUserInteraction, false);
}, },
}, },
}; };
@ -191,14 +182,17 @@ export default {
.no-padding { .no-padding {
padding: 0; padding: 0;
} }
.overlayButton {
z-index: 1000 !important;
}
</style> </style>
<style> <style>
.overlay { .v-overlay, .v-dialog__content {
z-index: 1002 !important; z-index: 1002 !important;
} }
.overlayButton {
z-index: 1000 !important;
position: absolute !important;
bottom: 24px !important;
border-radius: 50% !important;
}
</style> </style>

View File

@ -5992,9 +5992,9 @@ vue@^2.5.2:
version "2.5.16" version "2.5.16"
resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.16.tgz#07edb75e8412aaeed871ebafa99f4672584a0085" resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.16.tgz#07edb75e8412aaeed871ebafa99f4672584a0085"
vuetify@^1.0.0: vuetify@^1.1.0:
version "1.0.19" version "1.1.1"
resolved "https://registry.yarnpkg.com/vuetify/-/vuetify-1.0.19.tgz#fb6d123dd1c217795fc2333e912c0ecbed2ed69e" resolved "https://registry.yarnpkg.com/vuetify/-/vuetify-1.1.1.tgz#8d8f64306a45aaf862487addae8decf082dac0a3"
vuex@^3.0.1: vuex@^3.0.1:
version "3.0.1" version "3.0.1"