2018-06-25 18:29:57 +02:00
|
|
|
<template>
|
|
|
|
<v-app>
|
|
|
|
<v-toolbar
|
|
|
|
app
|
|
|
|
>
|
2018-07-17 16:37:46 +02:00
|
|
|
<router-link :to="{ name: 'Map' }" class="noLinkDecoration">
|
2018-06-25 18:29:57 +02:00
|
|
|
<v-toolbar-title v-text="title" class="ma-0"></v-toolbar-title>
|
|
|
|
</router-link>
|
|
|
|
<v-spacer></v-spacer>
|
2018-07-26 13:55:08 +02:00
|
|
|
<v-btn
|
|
|
|
v-if="unsentReportsLength > 0"
|
|
|
|
icon
|
|
|
|
role="button"
|
|
|
|
:aria-label="$t('buttons.uploadUnsents')"
|
|
|
|
:loading="isSendingReports"
|
|
|
|
:disabled="isSendingReports"
|
|
|
|
class="mr-3"
|
|
|
|
color="orange"
|
|
|
|
dark
|
|
|
|
@click="sendUnsentReports"
|
|
|
|
>
|
|
|
|
<v-badge color="orange" left>
|
|
|
|
<span slot="badge">{{ unsentReportsLength }}</span>
|
|
|
|
<v-icon>cloud_upload</v-icon>
|
|
|
|
</v-badge>
|
|
|
|
</v-btn>
|
2018-11-25 17:43:54 +01:00
|
|
|
<v-menu
|
|
|
|
offset-y
|
|
|
|
class="menu"
|
|
|
|
v-if="showMenu"
|
|
|
|
>
|
2018-07-11 01:14:54 +02:00
|
|
|
<v-btn slot="activator" icon role="button" :aria-label="$t('buttons.menu')">
|
2018-06-25 18:29:57 +02:00
|
|
|
<v-icon>more_vert</v-icon>
|
|
|
|
</v-btn>
|
|
|
|
<v-list>
|
2018-11-07 20:04:00 +01:00
|
|
|
<v-list-tile @click="isSearchModalShown = true" v-if="isMapLoaded">
|
|
|
|
<v-list-tile-title>{{ $t("menu.search") }}</v-list-tile-title>
|
|
|
|
</v-list-tile>
|
2018-08-03 16:53:15 +02:00
|
|
|
<v-list-tile @click="exportGPX" v-if="isExportGPXMenuEntryVisible">
|
|
|
|
<v-list-tile-title>{{ $t("menu.exportGPX") }}</v-list-tile-title>
|
|
|
|
</v-list-tile>
|
2018-11-07 20:04:00 +01:00
|
|
|
<v-list-tile @click="isShareMapViewModalShown = true" v-if="isMapLoaded">
|
2018-07-21 20:00:37 +02:00
|
|
|
<v-list-tile-title>{{ $t("menu.shareMapView") }}</v-list-tile-title>
|
2018-06-28 14:40:56 +02:00
|
|
|
</v-list-tile>
|
|
|
|
<v-list-tile @click="goToAbout">
|
|
|
|
<v-list-tile-title>{{ $t("menu.About") }}</v-list-tile-title>
|
|
|
|
</v-list-tile>
|
|
|
|
<v-list-tile @click="goToSettings">
|
|
|
|
<v-list-tile-title>{{ $t("menu.Settings") }}</v-list-tile-title>
|
2018-06-25 18:29:57 +02:00
|
|
|
</v-list-tile>
|
2018-08-25 18:15:19 +02:00
|
|
|
<v-list-tile @click="isReportIssueModalShown = true">
|
|
|
|
<v-list-tile-title>{{ $t("menu.reportIssue") }}</v-list-tile-title>
|
|
|
|
</v-list-tile>
|
2018-06-25 18:29:57 +02:00
|
|
|
</v-list>
|
|
|
|
</v-menu>
|
2018-07-21 20:00:37 +02:00
|
|
|
<v-btn icon role="button" :aria-label="$t('buttons.back')" v-else @click="goBack">
|
|
|
|
<v-icon>arrow_back</v-icon>
|
|
|
|
</v-btn>
|
2018-07-04 18:20:28 +02:00
|
|
|
<div>
|
2018-11-25 17:43:54 +01:00
|
|
|
<v-progress-linear
|
|
|
|
v-if="isLoading"
|
|
|
|
:indeterminate="true"
|
|
|
|
class="progressBar"
|
|
|
|
></v-progress-linear>
|
2018-07-04 18:20:28 +02:00
|
|
|
</div>
|
2018-06-25 18:29:57 +02:00
|
|
|
</v-toolbar>
|
|
|
|
<v-content>
|
2018-11-25 17:43:54 +01:00
|
|
|
<Alert
|
|
|
|
type="error"
|
|
|
|
:text="$t('reportDialog.unableToSend')"
|
|
|
|
:onDismiss="dismissError"
|
|
|
|
v-if="hasReportError"
|
|
|
|
></Alert>
|
2018-07-21 20:00:37 +02:00
|
|
|
<ShareMapViewModal v-model="isShareMapViewModalShown"></ShareMapViewModal>
|
2018-08-25 18:15:19 +02:00
|
|
|
<ReportIssueModal v-model="isReportIssueModalShown"></ReportIssueModal>
|
2018-11-07 20:04:00 +01:00
|
|
|
<SearchModal v-model="isSearchModalShown"></SearchModal>
|
2018-07-21 20:00:37 +02:00
|
|
|
<router-view></router-view>
|
2018-06-25 18:29:57 +02:00
|
|
|
</v-content>
|
|
|
|
</v-app>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
2018-10-25 16:50:38 +02:00
|
|
|
import runtime from 'serviceworker-webpack-plugin/lib/runtime';
|
|
|
|
|
2018-08-28 16:50:57 +02:00
|
|
|
import { DELAY_BETWEEN_API_BATCH_REQUESTS } from '@/constants';
|
2018-07-26 13:55:08 +02:00
|
|
|
|
2018-11-07 23:18:45 +01:00
|
|
|
import Alert from '@/components/Alert.vue';
|
2018-08-25 18:15:19 +02:00
|
|
|
import ReportIssueModal from '@/components/ReportIssueModal.vue';
|
2018-11-07 20:04:00 +01:00
|
|
|
import SearchModal from '@/components/SearchModal.vue';
|
2018-07-21 20:00:37 +02:00
|
|
|
import ShareMapViewModal from '@/components/ShareMapViewModal.vue';
|
|
|
|
|
2018-06-25 18:29:57 +02:00
|
|
|
export default {
|
2018-07-21 20:00:37 +02:00
|
|
|
components: {
|
2018-11-07 23:18:45 +01:00
|
|
|
Alert,
|
2018-08-25 18:15:19 +02:00
|
|
|
ReportIssueModal,
|
2018-11-07 20:04:00 +01:00
|
|
|
SearchModal,
|
2018-07-21 20:00:37 +02:00
|
|
|
ShareMapViewModal,
|
|
|
|
},
|
2018-07-04 18:20:28 +02:00
|
|
|
computed: {
|
|
|
|
isLoading() {
|
|
|
|
return this.$store.state.isLoading;
|
|
|
|
},
|
2018-08-03 16:53:15 +02:00
|
|
|
isExportGPXMenuEntryVisible() {
|
|
|
|
return this.$store.state.location.gpx.length > 0;
|
|
|
|
},
|
2018-11-07 20:04:00 +01:00
|
|
|
isMapLoaded() {
|
2018-11-07 22:25:31 +01:00
|
|
|
return (
|
|
|
|
this.$store.state.map.center.every(item => item !== null)
|
|
|
|
|| this.$store.getters.getLastLocation
|
|
|
|
);
|
2018-07-21 20:00:37 +02:00
|
|
|
},
|
2018-11-25 17:43:54 +01:00
|
|
|
showMenu() {
|
|
|
|
return (
|
|
|
|
this.$route.name === 'Onboarding'
|
|
|
|
|| this.$route.name === 'Map'
|
|
|
|
|| this.$route.name === 'SharedMap'
|
|
|
|
);
|
|
|
|
},
|
2018-07-26 13:55:08 +02:00
|
|
|
unsentReportsLength() {
|
|
|
|
return this.$store.state.unsentReports.length;
|
|
|
|
},
|
2018-07-04 18:20:28 +02:00
|
|
|
},
|
2018-06-25 18:29:57 +02:00
|
|
|
data() {
|
|
|
|
return {
|
2018-07-26 13:55:08 +02:00
|
|
|
hasReportError: false,
|
2018-08-25 18:15:19 +02:00
|
|
|
isReportIssueModalShown: false,
|
2018-11-07 20:04:00 +01:00
|
|
|
isSearchModalShown: false,
|
2018-07-26 13:55:08 +02:00
|
|
|
isSendingReports: false,
|
2018-07-21 20:00:37 +02:00
|
|
|
isShareMapViewModalShown: false,
|
|
|
|
title: "Cycl'Assist",
|
2018-06-25 18:29:57 +02:00
|
|
|
};
|
|
|
|
},
|
|
|
|
methods: {
|
2018-11-07 23:18:45 +01:00
|
|
|
dismissError() {
|
|
|
|
this.hasReportError = false;
|
|
|
|
},
|
2018-08-03 16:53:15 +02:00
|
|
|
exportGPX() {
|
2018-08-28 16:50:57 +02:00
|
|
|
import('@/tools/exportGPX' /* webpackChunkName: "MapView" */).then((module) => {
|
|
|
|
const activityName = this.$t('misc.activityName');
|
|
|
|
module.default(activityName, this.$store.state.location.gpx);
|
2018-08-03 16:53:15 +02:00
|
|
|
});
|
|
|
|
},
|
2018-06-25 18:29:57 +02:00
|
|
|
goToAbout() {
|
|
|
|
this.$router.push({ name: 'About' });
|
|
|
|
},
|
2018-07-21 20:00:37 +02:00
|
|
|
goBack() {
|
|
|
|
this.$router.go(-1);
|
2018-06-28 14:40:56 +02:00
|
|
|
},
|
|
|
|
goToSettings() {
|
|
|
|
this.$router.push({ name: 'Settings' });
|
|
|
|
},
|
2018-07-26 13:55:08 +02:00
|
|
|
sendUnsentReports() {
|
|
|
|
if (!this.unsentReportsLength) {
|
|
|
|
this.isSendingReports = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.isSendingReports = true;
|
|
|
|
|
|
|
|
const index = this.unsentReportsLength - 1;
|
|
|
|
const report = this.$store.state.unsentReports[index];
|
|
|
|
this.$store.dispatch('saveReport', report)
|
|
|
|
.then(() => {
|
|
|
|
this.$store.dispatch('removeUnsentReport', { index });
|
|
|
|
this.hasReportError = false;
|
|
|
|
setTimeout(this.sendUnsentReports, DELAY_BETWEEN_API_BATCH_REQUESTS);
|
|
|
|
})
|
|
|
|
.catch((exc) => {
|
|
|
|
console.error(exc);
|
|
|
|
this.hasReportError = true;
|
|
|
|
this.isSendingReports = false;
|
|
|
|
});
|
|
|
|
},
|
2018-06-25 18:29:57 +02:00
|
|
|
},
|
2018-10-25 16:50:38 +02:00
|
|
|
mounted() {
|
|
|
|
if ('serviceWorker' in navigator) {
|
|
|
|
runtime.register().catch((error) => {
|
|
|
|
console.log(`Registration failed with ${error}.`);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
2018-06-25 18:29:57 +02:00
|
|
|
};
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
.menu {
|
|
|
|
z-index: 2000 !important;
|
|
|
|
}
|
|
|
|
|
|
|
|
.noLinkDecoration {
|
|
|
|
color: rgba(0, 0, 0, .87);
|
|
|
|
text-decoration: none;
|
|
|
|
}
|
2018-07-04 18:20:28 +02:00
|
|
|
|
|
|
|
.progressBar {
|
|
|
|
margin: 0;
|
|
|
|
position: absolute;
|
|
|
|
bottom: 0;
|
|
|
|
left: 0;
|
|
|
|
}
|
2018-06-25 18:29:57 +02:00
|
|
|
</style>
|
2018-06-27 11:21:29 +02:00
|
|
|
|
|
|
|
<style>
|
2018-07-03 19:54:32 +02:00
|
|
|
body, html, .application {
|
|
|
|
height: 100%;
|
|
|
|
}
|
|
|
|
|
|
|
|
.application--wrap {
|
|
|
|
min-height: 100% !important;
|
2018-08-24 23:34:37 +02:00
|
|
|
overflow: auto;
|
2018-07-03 19:54:32 +02:00
|
|
|
}
|
|
|
|
|
2018-06-27 11:21:29 +02:00
|
|
|
.bottom-sheet.dialog {
|
|
|
|
webkit-transition: .1s cubic-bezier(.25, .8, .5, 1);
|
|
|
|
transition: .1s cubic-bezier(.25, .8, .5, 1);
|
|
|
|
}
|
|
|
|
</style>
|