parent
959578cfe9
commit
e9b4f41b1e
@ -3,7 +3,7 @@
|
|||||||
<v-toolbar
|
<v-toolbar
|
||||||
app
|
app
|
||||||
>
|
>
|
||||||
<router-link :to="{ name: 'Map' }" class="noLinkDecoration">
|
<router-link :to="{ name: 'Onboarding' }" class="noLinkDecoration">
|
||||||
<v-toolbar-title v-text="title" class="ma-0"></v-toolbar-title>
|
<v-toolbar-title v-text="title" class="ma-0"></v-toolbar-title>
|
||||||
</router-link>
|
</router-link>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
|
@ -8,17 +8,20 @@
|
|||||||
<p>{{ $t('about.usageDescription') }}</p>
|
<p>{{ $t('about.usageDescription') }}</p>
|
||||||
|
|
||||||
<h2 class="body-2">{{ $t('about.availableReportsTitle') }}</h2>
|
<h2 class="body-2">{{ $t('about.availableReportsTitle') }}</h2>
|
||||||
<ul class="ml-3">
|
<ReportsDescription></ReportsDescription>
|
||||||
<li><strong>{{ $t('reportLabels.accident') }}</strong>{{ $t('misc.spaceBeforeDoublePunctuations') }}: {{ $t('reportLabels.accidentDescription') }}</li>
|
|
||||||
<li><strong>{{ $t('reportLabels.gcum') }}</strong>{{ $t('misc.spaceBeforeDoublePunctuations') }}: {{ $t('reportLabels.gcumDescription') }}</li>
|
|
||||||
<li><strong>{{ $t('reportLabels.interrupt') }}</strong>{{ $t('misc.spaceBeforeDoublePunctuations') }}: {{ $t('reportLabels.interruptDescription') }}</li>
|
|
||||||
<li><strong>{{ $t('reportLabels.obstacle') }}</strong>{{ $t('misc.spaceBeforeDoublePunctuations') }}: {{ $t('reportLabels.obstacleDescription') }}</li>
|
|
||||||
<li><strong>{{ $t('reportLabels.pothole') }}</strong>{{ $t('misc.spaceBeforeDoublePunctuations') }}: {{ $t('reportLabels.potholeDescription') }}</li>
|
|
||||||
<li><strong>{{ $t('reportLabels.misc') }}</strong>{{ $t('misc.spaceBeforeDoublePunctuations') }}: {{ $t('reportLabels.miscDescription') }}</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<p class="mt-3" v-html="$t('about.license')"></p>
|
<p class="mt-3" v-html="$t('about.license')"></p>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
</v-layout>
|
</v-layout>
|
||||||
</v-container>
|
</v-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ReportsDescription from '@/components/ReportsDescription.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
ReportsDescription,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
34
src/components/ReportsDescription.vue
Normal file
34
src/components/ReportsDescription.vue
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<template>
|
||||||
|
<table class="margin-auto">
|
||||||
|
<tr v-for="type in REPORT_TYPES_ORDER">
|
||||||
|
<td class="pa-2"><img class="reportIcon" :src="REPORT_TYPES[type].image"/></td>
|
||||||
|
<td class="pa-2 text-xs-left"><strong>{{ $t(REPORT_TYPES[type].label) }}</strong>{{ $t('misc.spaceBeforeDoublePunctuations') }}: {{ $t(REPORT_TYPES[type].description) }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { REPORT_TYPES, REPORT_TYPES_ORDER } from '@/constants';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
REPORT_TYPES,
|
||||||
|
REPORT_TYPES_ORDER,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.margin-auto {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reportIcon {
|
||||||
|
background: white;
|
||||||
|
width: 100px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
</style>
|
@ -15,6 +15,7 @@ import potholeIcon from '@/assets/pothole.svg';
|
|||||||
|
|
||||||
export const REPORT_TYPES = {
|
export const REPORT_TYPES = {
|
||||||
accident: {
|
accident: {
|
||||||
|
description: 'reportLabels.accidentDescription',
|
||||||
label: 'reportLabels.accident',
|
label: 'reportLabels.accident',
|
||||||
image: accidentIcon,
|
image: accidentIcon,
|
||||||
marker: L.icon({
|
marker: L.icon({
|
||||||
@ -30,6 +31,7 @@ export const REPORT_TYPES = {
|
|||||||
|
|
||||||
},
|
},
|
||||||
gcum: {
|
gcum: {
|
||||||
|
description: 'reportLabels.gcumDescription',
|
||||||
label: 'reportLabels.gcum',
|
label: 'reportLabels.gcum',
|
||||||
image: gcumIcon,
|
image: gcumIcon,
|
||||||
marker: L.icon({
|
marker: L.icon({
|
||||||
@ -45,6 +47,7 @@ export const REPORT_TYPES = {
|
|||||||
|
|
||||||
},
|
},
|
||||||
interrupt: {
|
interrupt: {
|
||||||
|
description: 'reportLabels.interruptDescription',
|
||||||
label: 'reportLabels.interrupt',
|
label: 'reportLabels.interrupt',
|
||||||
image: interruptIcon,
|
image: interruptIcon,
|
||||||
marker: L.icon({
|
marker: L.icon({
|
||||||
@ -59,6 +62,7 @@ export const REPORT_TYPES = {
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
misc: {
|
misc: {
|
||||||
|
description: 'reportLabels.miscDescription',
|
||||||
label: 'reportLabels.misc',
|
label: 'reportLabels.misc',
|
||||||
image: miscIcon,
|
image: miscIcon,
|
||||||
marker: L.icon({
|
marker: L.icon({
|
||||||
@ -73,6 +77,7 @@ export const REPORT_TYPES = {
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
obstacle: {
|
obstacle: {
|
||||||
|
description: 'reportLabels.obstacleDescription',
|
||||||
label: 'reportLabels.obstacle',
|
label: 'reportLabels.obstacle',
|
||||||
image: obstacleIcon,
|
image: obstacleIcon,
|
||||||
marker: L.icon({
|
marker: L.icon({
|
||||||
@ -87,6 +92,7 @@ export const REPORT_TYPES = {
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
pothole: {
|
pothole: {
|
||||||
|
description: 'reportLabels.potholeDescription',
|
||||||
label: 'reportLabels.pothole',
|
label: 'reportLabels.pothole',
|
||||||
image: potholeIcon,
|
image: potholeIcon,
|
||||||
marker: L.icon({
|
marker: L.icon({
|
||||||
@ -119,4 +125,4 @@ export const EARTH_RADIUS = 6378137;
|
|||||||
export const DEFAULT_ZOOM = 17;
|
export const DEFAULT_ZOOM = 17;
|
||||||
export const MIN_ZOOM = 10;
|
export const MIN_ZOOM = 10;
|
||||||
export const MAX_ZOOM = 18;
|
export const MAX_ZOOM = 18;
|
||||||
export const TILE_SERVER = process.env.TILE_SERVER || 'https://a.tile.thunderforest.com/cycle/{z}/{x}/{y}.png';
|
export const TILE_SERVER = process.env.TILE_SERVER || 'https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png';
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
export default {
|
export default {
|
||||||
about: {
|
about: {
|
||||||
availableReportsTitle: 'The available reports so far are:',
|
availableReportsTitle: 'The available reports so far are:',
|
||||||
geolocationDescription: 'As of current version, your precise geolocation is handled within your device and never sent from it to any external service. The map background is downloaded on demand from <a href="http://thunderforest.com/">Thunderforest</a> and they have then access to an estimate of the displayed position.',
|
geolocationDescription: 'As of current version, your precise geolocation is handled within your device and never sent from it to any external service. The map background is downloaded on demand from <a href="https://carto.com/location-data-services/basemaps/">Carto.com</a> and they have then access to an estimate of the displayed position.',
|
||||||
license: 'It is released under an <a href="https://opensource.org/licenses/MIT">MIT license</a> (<a href="https://framagit.org/phyks/cyclassist">source code</a>). Icons are based on creations from Wikimedia and Vecteezy. The map background is using tiles from <a href="https://www.opencyclemap.org/docs/">OpenCycleMap</a>, thanks to <a href="https://www.openstreetmap.org/copyright">OpenStreetMap contributors</a> and <a href="http://leafletjs.com/">Leaflet</a>. Collected reports are available under <a href="https://opendatacommons.org/licenses/odbl/">ODbL license</a>.',
|
license: 'It is released under an <a href="https://opensource.org/licenses/MIT">MIT license</a> (<a href="https://framagit.org/phyks/cyclassist">source code</a>). Icons are based on creations from Wikimedia and Vecteezy. The map background is using tiles from <a href="https://carto.com/location-data-services/basemaps/">Carto.com</a>, thanks to <a href="https://www.openstreetmap.org/copyright">OpenStreetMap contributors</a> and <a href="http://leafletjs.com/">Leaflet</a>. Collected reports are available under <a href="https://opendatacommons.org/licenses/odbl/">ODbL license</a>.',
|
||||||
summary: 'This app lets you track and share issues with bike lanes.',
|
summary: 'This app lets you track and share issues with bike lanes.',
|
||||||
usage: 'How to use',
|
usage: 'How to use',
|
||||||
usageDescription: 'Use the button in the lower right corner to add a new report at your current location. To add a report elsewhere, do a click where you want the report to be shown. Press on a marker on the map to display more informations and report the problem as being still there or solved.',
|
usageDescription: 'Use the button in the lower right corner to add a new report at your current location. To add a report elsewhere, do a click where you want the report to be shown. Press on a marker on the map to display more informations and report the problem as being still there or solved.',
|
||||||
@ -18,10 +18,16 @@ export default {
|
|||||||
},
|
},
|
||||||
geolocation: {
|
geolocation: {
|
||||||
fetching: 'Fetching current position…',
|
fetching: 'Fetching current position…',
|
||||||
|
geolocation: 'Geolocation',
|
||||||
unavailable: 'Sorry, geolocation is not available in your browser.',
|
unavailable: 'Sorry, geolocation is not available in your browser.',
|
||||||
},
|
},
|
||||||
intro: {
|
intro: {
|
||||||
start: "Let's go!",
|
checkingPermissions: 'Checking permissions',
|
||||||
|
next: 'Next',
|
||||||
|
ready: 'Ready to start',
|
||||||
|
reportTypes: 'Report types',
|
||||||
|
startReporting: 'Start reporting!',
|
||||||
|
welcome: 'Welcome',
|
||||||
},
|
},
|
||||||
menu: {
|
menu: {
|
||||||
About: 'Help',
|
About: 'Help',
|
||||||
@ -42,9 +48,9 @@ export default {
|
|||||||
},
|
},
|
||||||
reportLabels: {
|
reportLabels: {
|
||||||
accident: 'Accident',
|
accident: 'Accident',
|
||||||
accidentDescription: 'Any accident on the road (active for one hour).',
|
accidentDescription: 'Any accident on the road (automatically removed after one hour).',
|
||||||
gcum: 'GCUM',
|
gcum: 'GCUM',
|
||||||
gcumDescription: 'A car poorly parked on a bike lane. Such reports are automatically deleted after one hour, as they are by nature temporary (active for one hour).',
|
gcumDescription: 'A car poorly parked on a bike lane. Such reports are automatically deleted after one hour, as they are by nature temporary (automatically removed after one hour).',
|
||||||
interrupt: 'Interruption',
|
interrupt: 'Interruption',
|
||||||
interruptDescription: 'An interruption of the bike lane (works, unexpected end of the bike lane, etc.).',
|
interruptDescription: 'An interruption of the bike lane (works, unexpected end of the bike lane, etc.).',
|
||||||
misc: 'Other',
|
misc: 'Other',
|
||||||
@ -58,5 +64,6 @@ export default {
|
|||||||
locale: 'Language',
|
locale: 'Language',
|
||||||
preventSuspend: 'Prevent device from going to sleep',
|
preventSuspend: 'Prevent device from going to sleep',
|
||||||
save: 'Save',
|
save: 'Save',
|
||||||
|
skipOnboarding: 'Skip onboarding',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
export default {
|
export default {
|
||||||
about: {
|
about: {
|
||||||
availableReportsTitle: "Les signalements disponibles pour l'instant sont :",
|
availableReportsTitle: "Les signalements disponibles pour l'instant sont :",
|
||||||
geolocationDescription: "Dans la version actuelle, votre position est traitée directement par votre appareil et n'est jamais envoyée à un service externe. Le fond de carte est téléchargé à la demande depuis <a href='http://thunderforest.com/'>Thunderforest</a> et ils ont donc accès à une estimation de la position affichée.",
|
geolocationDescription: "Dans la version actuelle, votre position est traitée directement par votre appareil et n'est jamais envoyée à un service externe. Le fond de carte est téléchargé à la demande depuis <a href='https://carto.com/location-data-services/basemaps/'>Carto.com</a> et ils ont donc accès à une estimation de la position affichée.",
|
||||||
license: "Le code source est sous <a href='https://opensource.org/licenses/MIT'>licence MIT license</a> (<a href='https://framagit.org/phyks/cyclassist'>code source</a>). Les icones sont basées sur des travaux de Wikimedia et Vecteezy. Les tuiles de fond de carte proviennent de chez <a href='https://www.opencyclemap.org/docs/'>OpenCycleMap</a>, grace aux <a href='https://www.openstreetmap.org/copyright'>contributeurs OpenStreetMap</a> et à <a href='http://leafletjs.com/'>Leaflet</a>. Les signalements sont disponibles sous <a href='https://opendatacommons.org/licenses/odbl/'>licence ODbL</a>.",
|
license: "Le code source est sous <a href='https://opensource.org/licenses/MIT'>licence MIT license</a> (<a href='https://framagit.org/phyks/cyclassist'>code source</a>). Les icones sont basées sur des travaux de Wikimedia et Vecteezy. Les tuiles de fond de carte proviennent de chez <a href='https://carto.com/location-data-services/basemaps/'>Carto.com</a>, grace aux <a href='https://www.openstreetmap.org/copyright'>contributeurs OpenStreetMap</a> et à <a href='http://leafletjs.com/'>Leaflet</a>. Les signalements sont disponibles sous <a href='https://opendatacommons.org/licenses/odbl/'>licence ODbL</a>.",
|
||||||
summary: 'Cette application vous permet de signaler et de partager des problèmes avec les itinéraires cyclables.',
|
summary: 'Cette application vous permet de signaler et de partager des problèmes avec les itinéraires cyclables.',
|
||||||
usage: 'Utilisation',
|
usage: 'Utilisation',
|
||||||
usageDescription: "Utilisez le bouton en bas à droite pour ajouter un signalement à votre emplacement actuel. Pour ajouter un signalement ailleurs, faites un appui à l'emplacement souhaité sur la carte. Appuyer sur un marqueur sur la carte pour afficher plus d'informations et signaler que le problème est toujours présent ou non.",
|
usageDescription: "Utilisez le bouton en bas à droite pour ajouter un signalement à votre emplacement actuel. Pour ajouter un signalement ailleurs, faites un appui à l'emplacement souhaité sur la carte. Appuyer sur un marqueur sur la carte pour afficher plus d'informations et signaler que le problème est toujours présent ou non.",
|
||||||
@ -18,10 +18,16 @@ export default {
|
|||||||
},
|
},
|
||||||
geolocation: {
|
geolocation: {
|
||||||
fetching: 'En attente de votre position…',
|
fetching: 'En attente de votre position…',
|
||||||
|
geolocation: 'Géolocalisation',
|
||||||
unavailable: "Désolé, la géolocalisation n'est pas disponible dans votre navigateur.",
|
unavailable: "Désolé, la géolocalisation n'est pas disponible dans votre navigateur.",
|
||||||
},
|
},
|
||||||
intro: {
|
intro: {
|
||||||
start: "C'est parti !",
|
checkingPermissions: 'Vérification des permissions',
|
||||||
|
next: 'Suivant',
|
||||||
|
ready: 'Tout est prêt !',
|
||||||
|
reportTypes: 'Types de signalements',
|
||||||
|
startReporting: 'Commencer à signaler !',
|
||||||
|
welcome: 'Bienvenue !',
|
||||||
},
|
},
|
||||||
menu: {
|
menu: {
|
||||||
About: 'Aide',
|
About: 'Aide',
|
||||||
@ -42,9 +48,9 @@ export default {
|
|||||||
},
|
},
|
||||||
reportLabels: {
|
reportLabels: {
|
||||||
accident: 'Accident',
|
accident: 'Accident',
|
||||||
accidentDescription: 'Un accident sur la route (actif pour une heure).',
|
accidentDescription: 'Un accident sur la route (automatiquement supprimé après une heure).',
|
||||||
gcum: 'GCUM',
|
gcum: 'GCUM',
|
||||||
gcumDescription: "Une voiture (mal) garée sur la piste cyclable. Ces signalements sont automatiquement supprimés au bout d'une heure car ils sont par essence temporaires (actif pour une heure).",
|
gcumDescription: 'Une voiture (mal) garée sur la piste cyclable (automatiquement supprimé après une heure).',
|
||||||
interrupt: 'Interruption',
|
interrupt: 'Interruption',
|
||||||
interruptDescription: "Une interruption d'itinéraire cyclable (travaux, arrêt inattendu d'une piste cyclable, etc)",
|
interruptDescription: "Une interruption d'itinéraire cyclable (travaux, arrêt inattendu d'une piste cyclable, etc)",
|
||||||
misc: 'Autre',
|
misc: 'Autre',
|
||||||
@ -58,5 +64,6 @@ export default {
|
|||||||
locale: 'Langue',
|
locale: 'Langue',
|
||||||
preventSuspend: "Empêcher l'appareil de passer en veille",
|
preventSuspend: "Empêcher l'appareil de passer en veille",
|
||||||
save: 'Sauver',
|
save: 'Sauver',
|
||||||
|
skipOnboarding: "Sauter l'introduction",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -2,6 +2,7 @@ import Vue from 'vue';
|
|||||||
import Router from 'vue-router';
|
import Router from 'vue-router';
|
||||||
import About from '@/components/About.vue';
|
import About from '@/components/About.vue';
|
||||||
import Map from '@/views/Map.vue';
|
import Map from '@/views/Map.vue';
|
||||||
|
import Onboarding from '@/views/Onboarding.vue';
|
||||||
import Settings from '@/views/Settings.vue';
|
import Settings from '@/views/Settings.vue';
|
||||||
|
|
||||||
Vue.use(Router);
|
Vue.use(Router);
|
||||||
@ -14,10 +15,15 @@ export default new Router({
|
|||||||
component: About,
|
component: About,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/map',
|
||||||
name: 'Map',
|
name: 'Map',
|
||||||
component: Map,
|
component: Map,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
name: 'Onboarding',
|
||||||
|
component: Onboarding,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/settings',
|
path: '/settings',
|
||||||
name: 'Settings',
|
name: 'Settings',
|
||||||
|
@ -8,11 +8,16 @@ import * as types from './mutations-types';
|
|||||||
// Load settings from storage
|
// Load settings from storage
|
||||||
let locale = null;
|
let locale = null;
|
||||||
let preventSuspend = null;
|
let preventSuspend = null;
|
||||||
|
let skipOnboarding = null;
|
||||||
if (storageAvailable('localStorage')) {
|
if (storageAvailable('localStorage')) {
|
||||||
preventSuspend = localStorage.getItem('preventSuspend');
|
preventSuspend = localStorage.getItem('preventSuspend');
|
||||||
if (preventSuspend) {
|
if (preventSuspend) {
|
||||||
preventSuspend = JSON.parse(preventSuspend);
|
preventSuspend = JSON.parse(preventSuspend);
|
||||||
}
|
}
|
||||||
|
skipOnboarding = localStorage.getItem('skipOnboarding');
|
||||||
|
if (skipOnboarding) {
|
||||||
|
skipOnboarding = JSON.parse(skipOnboarding);
|
||||||
|
}
|
||||||
|
|
||||||
locale = localStorage.getItem('locale');
|
locale = localStorage.getItem('locale');
|
||||||
if (!messages[locale]) {
|
if (!messages[locale]) {
|
||||||
@ -42,6 +47,7 @@ export const initialState = {
|
|||||||
settings: {
|
settings: {
|
||||||
locale: locale || 'en',
|
locale: locale || 'en',
|
||||||
preventSuspend: preventSuspend || true,
|
preventSuspend: preventSuspend || true,
|
||||||
|
skipOnboarding: skipOnboarding || false,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,13 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-container fluid fill-height class="no-padding">
|
<v-container fluid fill-height class="no-padding">
|
||||||
<v-layout v-if="isIntro" row wrap class="text-xs-center blue lighten-2">
|
<v-layout row wrap fill-height>
|
||||||
<v-flex xs8 offset-xs2>
|
|
||||||
<p><img src="@/assets/logo.svg" alt="Logo"/></p></p>
|
|
||||||
<p>{{ $t('about.summary') }}</p>
|
|
||||||
<v-btn role="button" round color="green" dark @click="introButtonClick">{{ $t('intro.start') }}</v-btn>
|
|
||||||
</v-flex>
|
|
||||||
</v-layout>
|
|
||||||
<v-layout v-else row wrap fill-height>
|
|
||||||
<ReportCard></ReportCard>
|
<ReportCard></ReportCard>
|
||||||
<v-flex xs12 fill-height v-if="latLng">
|
<v-flex xs12 fill-height v-if="latLng">
|
||||||
<Map :positionLatLng="latLng" :reportLatLng="reportLatLng" :polyline="positionHistory" :heading="heading" :accuracy="accuracy" :markers="reportsMarkers" :onPress="showReportDialog"></Map>
|
<Map :positionLatLng="latLng" :reportLatLng="reportLatLng" :polyline="positionHistory" :heading="heading" :accuracy="accuracy" :markers="reportsMarkers" :onPress="showReportDialog"></Map>
|
||||||
@ -58,12 +51,15 @@ export default {
|
|||||||
ReportCard,
|
ReportCard,
|
||||||
ReportDialog,
|
ReportDialog,
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
created() {
|
||||||
if (!this.isIntro) {
|
if (!this.$store.state.settings.skipOnboarding) {
|
||||||
this.disableNoSleep();
|
this.$router.replace({ name: 'Onboarding' });
|
||||||
this.disablePositionWatching();
|
|
||||||
window.removeEventListener('keydown', this.hideReportDialogOnEsc);
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
this.disableNoSleep();
|
||||||
|
this.disablePositionWatching();
|
||||||
|
window.removeEventListener('keydown', this.hideReportDialogOnEsc);
|
||||||
this.$store.dispatch('hideReportDetails');
|
this.$store.dispatch('hideReportDetails');
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -88,7 +84,6 @@ export default {
|
|||||||
dialog: false,
|
dialog: false,
|
||||||
error: null,
|
error: null,
|
||||||
heading: null,
|
heading: null,
|
||||||
isIntro: true,
|
|
||||||
latLng: null,
|
latLng: null,
|
||||||
noSleep: null,
|
noSleep: null,
|
||||||
positionHistory: [],
|
positionHistory: [],
|
||||||
@ -154,6 +149,11 @@ export default {
|
|||||||
}
|
}
|
||||||
this.accuracy = position.coords.accuracy ? position.coords.accuracy : null;
|
this.accuracy = position.coords.accuracy ? position.coords.accuracy : null;
|
||||||
},
|
},
|
||||||
|
disableNoSleep() {
|
||||||
|
if (this.noSleep) {
|
||||||
|
this.noSleep.disable();
|
||||||
|
}
|
||||||
|
},
|
||||||
setNoSleep() {
|
setNoSleep() {
|
||||||
let preventSuspend = localStorage.getItem('preventSuspend');
|
let preventSuspend = localStorage.getItem('preventSuspend');
|
||||||
if (preventSuspend) {
|
if (preventSuspend) {
|
||||||
@ -167,11 +167,6 @@ export default {
|
|||||||
this.noSleep.enable();
|
this.noSleep.enable();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
disableNoSleep() {
|
|
||||||
if (this.noSleep) {
|
|
||||||
this.noSleep.disable();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
showReportDialog(latlng) {
|
showReportDialog(latlng) {
|
||||||
if (latlng) {
|
if (latlng) {
|
||||||
this.reportLat = latlng.lat;
|
this.reportLat = latlng.lat;
|
||||||
@ -193,13 +188,12 @@ export default {
|
|||||||
this.dialog = false;
|
this.dialog = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
introButtonClick() {
|
},
|
||||||
this.setNoSleep();
|
mounted() {
|
||||||
this.isIntro = false;
|
this.setNoSleep();
|
||||||
this.initializePositionWatching();
|
this.initializePositionWatching();
|
||||||
this.$store.dispatch('fetchReports');
|
this.$store.dispatch('fetchReports');
|
||||||
window.addEventListener('keydown', this.hideReportDialogOnEsc);
|
window.addEventListener('keydown', this.hideReportDialogOnEsc);
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
113
src/views/Onboarding.vue
Normal file
113
src/views/Onboarding.vue
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
<template>
|
||||||
|
<v-container fluid fill-height class="no-padding">
|
||||||
|
<v-layout row wrap class="text-xs-center blue lighten-2 px-2" v-if="step == 0">
|
||||||
|
<v-flex xs12>
|
||||||
|
<h2 class="display-1 pa-3">{{ $t('intro.welcome') }}</h2>
|
||||||
|
<p>{{ $t('about.summary') }}</p>
|
||||||
|
<p><img src="@/assets/logo.svg" alt="Logo"/></p>
|
||||||
|
<v-btn role="button" round color="green" dark @click="step += 1">{{ $t('intro.next') }}</v-btn>
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
<v-layout row wrap class="text-xs-center blue lighten-2 px-2" v-if="step == 1">
|
||||||
|
<v-flex xs12>
|
||||||
|
<h2 class="headline pa-3">{{ $t('intro.reportTypes') }}</h2>
|
||||||
|
|
||||||
|
<p class="text-xs-center">En cliquant sur l'icône <v-icon>report_problem</v-icon>, la boîte de signalement s'ouvre. Vous pouvez signaler :</p>
|
||||||
|
|
||||||
|
<ReportsDescription></ReportsDescription>
|
||||||
|
|
||||||
|
<v-btn role="button" round color="green" dark @click="step += 1">{{ $t('intro.next') }}</v-btn>
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
<v-layout row wrap class="text-xs-center blue lighten-2" v-if="step == 2">
|
||||||
|
<v-flex xs8 offset-xs2>
|
||||||
|
<h2 class="headline pa-3">{{ $t('intro.checkingPermissions') }}</h2>
|
||||||
|
|
||||||
|
<v-layout row class="white mb-3">
|
||||||
|
<v-flex xs6 offset-xs3>
|
||||||
|
<v-switch class="switch" color="success" :label="$t('geolocation.geolocation')" v-model="hasGeolocationPermission" readonly @click="handleGeolocationPermission"></v-switch>
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
|
||||||
|
<v-btn :disabled="!hasGeolocationPermission" role="button" round color="green" dark @click="step += 1">{{ $t('intro.next') }}</v-btn>
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
<v-layout row wrap class="text-xs-center blue lighten-2" v-if="step == 3">
|
||||||
|
<v-flex xs8 offset-xs2>
|
||||||
|
<h2 class="headline pa-3">{{ $t('intro.ready') }}</h2>
|
||||||
|
<p><img src="@/assets/logo.svg" alt="Logo"/></p>
|
||||||
|
<v-btn role="button" round color="green" dark @click="goToMap">{{ $t('intro.startReporting') }}</v-btn>
|
||||||
|
</v-flex>
|
||||||
|
</v-layout>
|
||||||
|
</v-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ReportsDescription from '@/components/ReportsDescription.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
ReportsDescription,
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
if (navigator.permissions) {
|
||||||
|
navigator.permissions.query({ name: 'geolocation' }).then((result) => {
|
||||||
|
this.hasGeolocationPermission = (result.state === 'granted');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
let step = 0;
|
||||||
|
if (this.$store.state.settings.skipOnboarding) {
|
||||||
|
step = 3;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
hasGeolocationPermission: false,
|
||||||
|
step,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleGeolocationPermission() {
|
||||||
|
if (this.hasGeolocationPermission) {
|
||||||
|
// Permission already granted
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Explicitly request the permission to the user
|
||||||
|
navigator.geolocation.getCurrentPosition(
|
||||||
|
() => {
|
||||||
|
this.hasGeolocationPermission = true;
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
if (error.code === 1) { // Permission denied
|
||||||
|
this.hasGeolocationPermission = false;
|
||||||
|
} else {
|
||||||
|
this.hasGeolocationPermission = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timeout: 0,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
goToMap() {
|
||||||
|
if (!this.$store.state.settings.skipOnboarding) {
|
||||||
|
this.$store.dispatch('setSetting', { setting: 'skipOnboarding', value: true });
|
||||||
|
}
|
||||||
|
this.$router.push({ name: 'Map' });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.no-padding {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.switch .v-label {
|
||||||
|
color: rgba(0,0,0,.87);
|
||||||
|
}
|
||||||
|
</style>
|
@ -16,6 +16,11 @@
|
|||||||
v-model="preventSuspend"
|
v-model="preventSuspend"
|
||||||
></v-checkbox>
|
></v-checkbox>
|
||||||
|
|
||||||
|
<v-checkbox
|
||||||
|
:label="$t('settings.skipOnboarding')"
|
||||||
|
v-model="skipOnboarding"
|
||||||
|
></v-checkbox>
|
||||||
|
|
||||||
<v-btn role="button" @click="submit">{{ $t('settings.save') }}</v-btn>
|
<v-btn role="button" @click="submit">{{ $t('settings.save') }}</v-btn>
|
||||||
</form>
|
</form>
|
||||||
</v-flex>
|
</v-flex>
|
||||||
@ -32,12 +37,14 @@ export default {
|
|||||||
i18nItems: Object.keys(messages),
|
i18nItems: Object.keys(messages),
|
||||||
locale: this.$store.state.settings.locale,
|
locale: this.$store.state.settings.locale,
|
||||||
preventSuspend: this.$store.state.settings.preventSuspend,
|
preventSuspend: this.$store.state.settings.preventSuspend,
|
||||||
|
skipOnboarding: this.$store.state.settings.skipOnboarding,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
submit() {
|
submit() {
|
||||||
this.$store.dispatch('setLocale', { locale: this.locale });
|
this.$store.dispatch('setLocale', { locale: this.locale });
|
||||||
this.$store.dispatch('setSetting', { setting: 'preventSuspend', value: this.preventSuspend });
|
this.$store.dispatch('setSetting', { setting: 'preventSuspend', value: this.preventSuspend });
|
||||||
|
this.$store.dispatch('setSetting', { setting: 'skipOnboarding', value: this.skipOnboarding });
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user