Add a way to report a bug, close #34
This commit is contained in:
parent
6f8b3ada2c
commit
b8ae8e9fa3
@ -6,6 +6,8 @@ locale = json.loads(sys.stdin.read())
|
|||||||
|
|
||||||
nested_json = {}
|
nested_json = {}
|
||||||
for key, value in locale.items():
|
for key, value in locale.items():
|
||||||
|
if not value:
|
||||||
|
continue
|
||||||
split_key = key.split('.')
|
split_key = key.split('.')
|
||||||
d = nested_json
|
d = nested_json
|
||||||
for key2 in split_key[:-1]:
|
for key2 in split_key[:-1]:
|
||||||
|
@ -41,6 +41,9 @@
|
|||||||
<v-list-tile @click="goToSettings">
|
<v-list-tile @click="goToSettings">
|
||||||
<v-list-tile-title>{{ $t("menu.Settings") }}</v-list-tile-title>
|
<v-list-tile-title>{{ $t("menu.Settings") }}</v-list-tile-title>
|
||||||
</v-list-tile>
|
</v-list-tile>
|
||||||
|
<v-list-tile @click="isReportIssueModalShown = true">
|
||||||
|
<v-list-tile-title>{{ $t("menu.reportIssue") }}</v-list-tile-title>
|
||||||
|
</v-list-tile>
|
||||||
</v-list>
|
</v-list>
|
||||||
</v-menu>
|
</v-menu>
|
||||||
<v-btn icon role="button" :aria-label="$t('buttons.back')" v-else @click="goBack">
|
<v-btn icon role="button" :aria-label="$t('buttons.back')" v-else @click="goBack">
|
||||||
@ -53,6 +56,7 @@
|
|||||||
<v-content>
|
<v-content>
|
||||||
<ReportErrorModal v-model="hasReportError"></ReportErrorModal>
|
<ReportErrorModal v-model="hasReportError"></ReportErrorModal>
|
||||||
<ShareMapViewModal v-model="isShareMapViewModalShown"></ShareMapViewModal>
|
<ShareMapViewModal v-model="isShareMapViewModalShown"></ShareMapViewModal>
|
||||||
|
<ReportIssueModal v-model="isReportIssueModalShown"></ReportIssueModal>
|
||||||
<router-view></router-view>
|
<router-view></router-view>
|
||||||
</v-content>
|
</v-content>
|
||||||
</v-app>
|
</v-app>
|
||||||
@ -66,11 +70,13 @@ import moment from 'moment';
|
|||||||
import { DELAY_BETWEEN_API_BATCH_REQUESTS, VERSION } from '@/constants';
|
import { DELAY_BETWEEN_API_BATCH_REQUESTS, VERSION } from '@/constants';
|
||||||
|
|
||||||
import ReportErrorModal from '@/components/ReportErrorModal.vue';
|
import ReportErrorModal from '@/components/ReportErrorModal.vue';
|
||||||
|
import ReportIssueModal from '@/components/ReportIssueModal.vue';
|
||||||
import ShareMapViewModal from '@/components/ShareMapViewModal.vue';
|
import ShareMapViewModal from '@/components/ShareMapViewModal.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
ReportErrorModal,
|
ReportErrorModal,
|
||||||
|
ReportIssueModal,
|
||||||
ShareMapViewModal,
|
ShareMapViewModal,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -90,6 +96,7 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
hasReportError: false,
|
hasReportError: false,
|
||||||
|
isReportIssueModalShown: false,
|
||||||
isSendingReports: false,
|
isSendingReports: false,
|
||||||
isShareMapViewModalShown: false,
|
isShareMapViewModalShown: false,
|
||||||
title: "Cycl'Assist",
|
title: "Cycl'Assist",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-dialog v-model="isModalShown" max-width="290">
|
<v-dialog v-model="isModalShown" :max-width="maxWidth">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</v-dialog>
|
</v-dialog>
|
||||||
</template>
|
</template>
|
||||||
@ -36,6 +36,10 @@ export default {
|
|||||||
window.addEventListener('keydown', this.hideModalOnEsc);
|
window.addEventListener('keydown', this.hideModalOnEsc);
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
maxWidth: {
|
||||||
|
type: Number,
|
||||||
|
default: 290,
|
||||||
|
},
|
||||||
value: Boolean,
|
value: Boolean,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
96
src/components/ReportIssueModal.vue
Normal file
96
src/components/ReportIssueModal.vue
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<template>
|
||||||
|
<Modal v-model="isActive" :maxWidth="400">
|
||||||
|
<v-card>
|
||||||
|
<v-card-title class="headline">{{ $t('reportIssueModal.reportIssue') }}</v-card-title>
|
||||||
|
|
||||||
|
<v-card-text>
|
||||||
|
<v-textarea :label="$t('reportIssueModal.description')" v-model="description"></v-textarea>
|
||||||
|
<v-checkbox v-if="isIncludeGPXVisible" :label="$t('reportIssueModal.includeGPX')" v-model="shouldIncludeGPX"></v-checkbox>
|
||||||
|
</v-card-text>
|
||||||
|
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
|
||||||
|
<v-btn
|
||||||
|
@click="sendEmail"
|
||||||
|
color="green darken-1"
|
||||||
|
:dark="!!description"
|
||||||
|
:disabled="!description"
|
||||||
|
:href="mailtoLink"
|
||||||
|
large
|
||||||
|
role="button"
|
||||||
|
>
|
||||||
|
{{ $t('reportIssueModal.send') }} <v-icon class="ml-1">email</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
|
||||||
|
{{ $t('misc.or') }}
|
||||||
|
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
|
||||||
|
<v-btn
|
||||||
|
color="grey"
|
||||||
|
@click="isActive = false"
|
||||||
|
dark
|
||||||
|
large
|
||||||
|
role="button"
|
||||||
|
>
|
||||||
|
{{ $t('buttons.close') }}
|
||||||
|
</v-btn>
|
||||||
|
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { CONTACT_EMAIL_ADDRESS } from '@/constants';
|
||||||
|
|
||||||
|
import Modal from '@/components/Modal.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Modal,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isActive: {
|
||||||
|
get() {
|
||||||
|
return this.value;
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.$emit('input', val);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
isIncludeGPXVisible() {
|
||||||
|
return this.$store.state.location.gpx.length > 0;
|
||||||
|
},
|
||||||
|
mailtoLink() {
|
||||||
|
let mailText = this.description;
|
||||||
|
if (this.shouldIncludeGPX) {
|
||||||
|
mailText += `\n\nGPX trace: ${JSON.stringify(this.$store.state.location.gpx)}.`;
|
||||||
|
}
|
||||||
|
return `mailto:${CONTACT_EMAIL_ADDRESS}?subject=Issue%20with%20Cyclassist&body=${encodeURIComponent(mailText)}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
description: null,
|
||||||
|
shouldIncludeGPX: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
sendEmail() {
|
||||||
|
// Close modal
|
||||||
|
this.isActive = false;
|
||||||
|
// Reset description and checkbox
|
||||||
|
this.description = null;
|
||||||
|
this.shouldIncludeGPX = false;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
value: Boolean,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
@ -115,3 +115,6 @@ export const DELAY_BETWEEN_API_BATCH_REQUESTS = 1000;
|
|||||||
|
|
||||||
// A vibration sequence for report alarms
|
// A vibration sequence for report alarms
|
||||||
export const REPORT_ALARM_VIBRATION_SEQUENCE = [500];
|
export const REPORT_ALARM_VIBRATION_SEQUENCE = [500];
|
||||||
|
|
||||||
|
// Email address to send issues to
|
||||||
|
export const CONTACT_EMAIL_ADDRESS = 'phyks+cyclassist@phyks.me';
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
"About": "Help",
|
"About": "Help",
|
||||||
"Settings": "Settings",
|
"Settings": "Settings",
|
||||||
"exportGPX": "Export GPX",
|
"exportGPX": "Export GPX",
|
||||||
|
"reportIssue": "Report an issue",
|
||||||
"shareMapView": "Share map view"
|
"shareMapView": "Share map view"
|
||||||
},
|
},
|
||||||
"misc": {
|
"misc": {
|
||||||
@ -57,8 +58,7 @@
|
|||||||
"discard": "Discard",
|
"discard": "Discard",
|
||||||
"ok": "OK",
|
"ok": "OK",
|
||||||
"or": "or",
|
"or": "or",
|
||||||
"retry": "Retry",
|
"retry": "Retry"
|
||||||
"spaceBeforeDoublePunctuations": ""
|
|
||||||
},
|
},
|
||||||
"permissions": {
|
"permissions": {
|
||||||
"geolocation": "Geolocation",
|
"geolocation": "Geolocation",
|
||||||
@ -75,6 +75,12 @@
|
|||||||
"unableToSendDescription": "There was a network issue preventing from sending the latest report.",
|
"unableToSendDescription": "There was a network issue preventing from sending the latest report.",
|
||||||
"unableToSendTitle": "Unable to send latest report"
|
"unableToSendTitle": "Unable to send latest report"
|
||||||
},
|
},
|
||||||
|
"reportIssueModal": {
|
||||||
|
"description": "Description",
|
||||||
|
"includeGPX": "Include the current GPS trace?",
|
||||||
|
"reportIssue": "Report an issue",
|
||||||
|
"send": "Send"
|
||||||
|
},
|
||||||
"reportLabels": {
|
"reportLabels": {
|
||||||
"accident": "Accident",
|
"accident": "Accident",
|
||||||
"accidentDescription": "Any accident on the road (automatically removed after one hour).",
|
"accidentDescription": "Any accident on the road (automatically removed after one hour).",
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"availableReportsTitle": "Les signalements disponibles pour l'instant sont :",
|
"availableReportsTitle": "Les signalements disponibles pour l'instant sont :",
|
||||||
"lastReportAdded": "Dernier signalement ajout\u00e9 {fromNow}.",
|
"lastReportAdded": "Dernier signalement ajout\u00e9 {fromNow}.",
|
||||||
"license": "Licence",
|
"license": "Licence",
|
||||||
"licenseDescription": "Le code source est sous <a href=\"https://opensource.org/licenses/MIT\">licence MIT</a> (<a href=\"https://framagit.org/phyks/cyclassist\">code source</a>). Les ic\u00f4nes sont bas\u00e9es sur des travaux de Wikimedia, Vecteezy, Pixabay ou Flaticon. Les sons sont bas\u00e9s sur des \u0153uvres sous CC0 de <a href=\"https://freesound.org/\">freesound.org</a>. Les tuiles de fond de carte proviennent de chez <a href=\"https://carto.com/location-data-services/basemaps/\">Carto.com</a> ou <a href=\"http://thunderforest.com/\">Thunderforest</a>, gr\u00e2ce aux <a href=\"https://www.openstreetmap.org/copyright\">contributeurs OpenStreetMap</a> et \u00e0 <a href=\"http://openlayers.org/\">OpenLayers</a>. Les signalements sont disponibles sous <a href=\"https://opendatacommons.org/licenses/odbl/\">licence ODbL</a>. La saisie manuelle de la position utilise l'excellente API de <a href=\"https://adresse.data.gouv.fr\">adresse.data.gouv.fr</a>.",
|
"licenseDescription": "Le code source est sous <a href=\"https://opensource.org/licenses/MIT\">licence MIT</a> (<a href=\"https://framagit.org/phyks/cyclassist\">code source</a>). Les ic\u00f4nes sont bas\u00e9es sur des travaux de Wikimedia, Vecteezy, Pixabay ou Flaticon. Les sons sont bas\u00e9s sur des \u0153uvres sous CC0 de <a href=\"https://freesound.org/\">freesound.org</a>. Les tuiles de fond de carte proviennent de chez <a href=\"https://carto.com/location-data-services/basemaps/\">Carto.com</a> ou <a href=\"http://thunderforest.com/\">Thunderforest</a>, gr\u00e2ce aux <a href=\"https://www.openstreetmap.org/copyright\">contributeurs OpenStreetMap</a> et \u00e0 <a href=\"http://leafletjs.com/\">Leaflet</a>. Les signalements sont disponibles sous <a href=\"https://opendatacommons.org/licenses/odbl/\">licence ODbL</a>. La saisie manuelle de la position utilise l'excellente API de <a href=\"https://adresse.data.gouv.fr\">adresse.data.gouv.fr</a>.",
|
||||||
"nbActiveReports": "Aucun signalement actif. | Un signalement actif. | {nbActiveReports} signalements actifs.",
|
"nbActiveReports": "Aucun signalement actif. | Un signalement actif. | {nbActiveReports} signalements actifs.",
|
||||||
"nbReports": "Aucun signalement. | Un signalement. | {nbReports} signalements.",
|
"nbReports": "Aucun signalement. | Un signalement. | {nbReports} signalements.",
|
||||||
"stats": "Statistiques",
|
"stats": "Statistiques",
|
||||||
@ -50,6 +50,7 @@
|
|||||||
"About": "Aide",
|
"About": "Aide",
|
||||||
"Settings": "Pr\u00e9f\u00e9rences",
|
"Settings": "Pr\u00e9f\u00e9rences",
|
||||||
"exportGPX": "Exporter en GPX",
|
"exportGPX": "Exporter en GPX",
|
||||||
|
"reportIssue": "Signaler un bug",
|
||||||
"shareMapView": "Partager"
|
"shareMapView": "Partager"
|
||||||
},
|
},
|
||||||
"misc": {
|
"misc": {
|
||||||
@ -57,8 +58,7 @@
|
|||||||
"discard": "Annuler",
|
"discard": "Annuler",
|
||||||
"ok": "OK",
|
"ok": "OK",
|
||||||
"or": "ou",
|
"or": "ou",
|
||||||
"retry": "R\u00e9essayer",
|
"retry": "R\u00e9essayer"
|
||||||
"spaceBeforeDoublePunctuations": " "
|
|
||||||
},
|
},
|
||||||
"permissions": {
|
"permissions": {
|
||||||
"geolocation": "G\u00e9olocalisation",
|
"geolocation": "G\u00e9olocalisation",
|
||||||
@ -75,6 +75,12 @@
|
|||||||
"unableToSendDescription": "Une erreur de r\u00e9seau emp\u00eache l'envoi du dernier signalement.",
|
"unableToSendDescription": "Une erreur de r\u00e9seau emp\u00eache l'envoi du dernier signalement.",
|
||||||
"unableToSendTitle": "Impossible d'envoyer le dernier signalement"
|
"unableToSendTitle": "Impossible d'envoyer le dernier signalement"
|
||||||
},
|
},
|
||||||
|
"reportIssueModal": {
|
||||||
|
"description": "Description",
|
||||||
|
"includeGPX": "Inclure la trace GPS courante",
|
||||||
|
"reportIssue": "Signaler un bug",
|
||||||
|
"send": "Envoyer"
|
||||||
|
},
|
||||||
"reportLabels": {
|
"reportLabels": {
|
||||||
"accident": "Accident",
|
"accident": "Accident",
|
||||||
"accidentDescription": "Un accident sur la route (automatiquement supprim\u00e9 apr\u00e8s une heure).",
|
"accidentDescription": "Un accident sur la route (automatiquement supprim\u00e9 apr\u00e8s une heure).",
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"availableReportsTitle": "Los senhalaments disponibles pel moment son :",
|
"availableReportsTitle": "Los senhalaments disponibles pel moment son :",
|
||||||
"lastReportAdded": "Darri\u00e8ra senhalament ajustat {fromNow}.",
|
"lastReportAdded": "Darri\u00e8ra senhalament ajustat {fromNow}.",
|
||||||
"license": "Lic\u00e9ncia",
|
"license": "Lic\u00e9ncia",
|
||||||
"licenseDescription": "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, Vecteezy, Pixabay or Flaticon. Sounds are based on CC0 works from <a href=\"https://freesound.org/\">freesound.org</a>. The map background is using tiles from <a href=\"https://carto.com/location-data-services/basemaps/\">Carto.com</a> or <a href=\"http://thunderforest.com/\">Thunderforest</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>. Manual location picking uses the awesome API from <a href=\"https://adresse.data.gouv.fr\">adresse.data.gouv.fr</a>.",
|
"licenseDescription": "Lo c\u00f2di font es jos <a href=\"https://opensource.org/licenses/MIT\">lic\u00e9ncia MIT</a> (<a href=\"https://framagit.org/phyks/cyclassist\">c\u00f2di font</a>). Las ic\u00f2nas son basadas sus d'\u00f2bras de Wikimedia, Vecteezy, Pixabay o Flaticon. Las teulas de fons venon <a href=\"https://carto.com/location-data-services/basemaps/\">Carto.com</a> o <a href=\"http://thunderforest.com/\">Thunderforest</a>, gr\u00e0cia als <a href=\"https://www.openstreetmap.org/copyright\">contributors OpenStreetMap</a> e a <a href=\"http://leafletjs.com/\">Leaflet</a>. Los senhalaments son disponibles jos <a href=\"https://opendatacommons.org/licenses/odbl/\">lic\u00e9ncia ODbL</a>. La sasida manuala de la posicion utiliza l'excellenta API de <a href=\"https://adresse.data.gouv.fr\">adresse.data.gouv.fr</a>.",
|
||||||
"nbActiveReports": "Cap de senhalament actiu. |\u00a0Un senhalament actiu. | {nbActiveReports} senhalaments actius.",
|
"nbActiveReports": "Cap de senhalament actiu. |\u00a0Un senhalament actiu. | {nbActiveReports} senhalaments actius.",
|
||||||
"nbReports": "Cap de senhalament. | Un senhalament. | {nbReports} senhalaments.",
|
"nbReports": "Cap de senhalament. | Un senhalament. | {nbReports} senhalaments.",
|
||||||
"stats": "Estatisticas",
|
"stats": "Estatisticas",
|
||||||
@ -57,8 +57,7 @@
|
|||||||
"discard": "Anullar",
|
"discard": "Anullar",
|
||||||
"ok": "D\u2019acc\u00f2rdi",
|
"ok": "D\u2019acc\u00f2rdi",
|
||||||
"or": "o",
|
"or": "o",
|
||||||
"retry": "Ensajar tornamai",
|
"retry": "Ensajar tornamai"
|
||||||
"spaceBeforeDoublePunctuations": " "
|
|
||||||
},
|
},
|
||||||
"permissions": {
|
"permissions": {
|
||||||
"geolocation": "Geolocalizacion",
|
"geolocation": "Geolocalizacion",
|
||||||
@ -90,12 +89,9 @@
|
|||||||
"potholeDescription": "Un trauc per la rota."
|
"potholeDescription": "Un trauc per la rota."
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"autorotate": "",
|
|
||||||
"customTileServer": "Servidor de teulas personalizat",
|
"customTileServer": "Servidor de teulas personalizat",
|
||||||
"customTileServerURL": "URL del servidor de teulas personalizat",
|
"customTileServerURL": "URL del servidor de teulas personalizat",
|
||||||
"customTileServerURLHint": "Per exemple\u00a0: http://tile.thunderforest.com/cycle/{z}/{x}/{y}.png",
|
"customTileServerURLHint": "Per exemple\u00a0: http://tile.thunderforest.com/cycle/{z}/{x}/{y}.png",
|
||||||
"defaultOrientationMode": "",
|
|
||||||
"fixedNorth": "",
|
|
||||||
"locale": "Lenga",
|
"locale": "Lenga",
|
||||||
"skipOnboarding": "Passar l'introduccion",
|
"skipOnboarding": "Passar l'introduccion",
|
||||||
"tileServer": "Servidor de teulas per la mapa"
|
"tileServer": "Servidor de teulas per la mapa"
|
||||||
|
@ -16,6 +16,7 @@ import VProgressCircular from 'vuetify/es5/components/VProgressCircular';
|
|||||||
import VProgressLinear from 'vuetify/es5/components/VProgressLinear';
|
import VProgressLinear from 'vuetify/es5/components/VProgressLinear';
|
||||||
import VSelect from 'vuetify/es5/components/VSelect';
|
import VSelect from 'vuetify/es5/components/VSelect';
|
||||||
import VSwitch from 'vuetify/es5/components/VSwitch';
|
import VSwitch from 'vuetify/es5/components/VSwitch';
|
||||||
|
import VTextarea from 'vuetify/es5/components/VTextarea';
|
||||||
import VTextField from 'vuetify/es5/components/VTextField';
|
import VTextField from 'vuetify/es5/components/VTextField';
|
||||||
import VToolbar from 'vuetify/es5/components/VToolbar';
|
import VToolbar from 'vuetify/es5/components/VToolbar';
|
||||||
|
|
||||||
@ -37,6 +38,7 @@ Vue.use(Vuetify, {
|
|||||||
VProgressLinear,
|
VProgressLinear,
|
||||||
VSelect,
|
VSelect,
|
||||||
VSwitch,
|
VSwitch,
|
||||||
|
VTextarea,
|
||||||
VTextField,
|
VTextField,
|
||||||
VToolbar,
|
VToolbar,
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user