Client - add a fullscreen control to workout map - fix #140

This commit is contained in:
Sam
2022-01-15 20:13:25 +01:00
parent 2242525b39
commit 8897659c62
18 changed files with 125 additions and 66 deletions

View File

@ -23,6 +23,7 @@
"register-service-worker": "^1.7.1",
"vue": "^3.0.0",
"vue-chart-3": "^3.0.7",
"vue-fullscreen": "^3.1.1",
"vue-i18n": "^9.1.9",
"vue-router": "^4.0.0-0",
"vuex": "^4.0.0-0"

View File

@ -2,47 +2,65 @@
<div id="workout-map">
<div v-if="workoutData.loading" class="leaflet-container" />
<div v-else>
<div class="leaflet-container" v-if="workoutData.workout.with_gpx">
<LMap
v-if="geoJson.jsonData && center && bounds.length === 2"
:zoom="13"
:maxZoom="19"
:center="center"
:bounds="bounds"
ref="workoutMap"
@ready="fitBounds(bounds)"
<VFullscreen v-if="workoutData.workout.with_gpx" v-model="isFullscreen">
<div
class="leaflet-container"
:class="{ 'fullscreen-map': isFullscreen }"
>
<LControlLayers />
<LControl position="topleft" class="reset-button" @click="resetZoom">
<i class="fa fa-refresh" aria-hidden="true"></i>
</LControl>
<LTileLayer
:url="`${getApiUrl()}workouts/map_tile/{s}/{z}/{x}/{y}.png`"
:attribution="appConfig.map_attribution"
<LMap
v-if="geoJson.jsonData && center && bounds.length === 2"
:zoom="13"
:maxZoom="19"
:center="center"
:bounds="bounds"
/>
<LGeoJson :geojson="geoJson.jsonData" />
<LMarker
v-if="markerCoordinates.latitude"
:lat-lng="[markerCoordinates.latitude, markerCoordinates.longitude]"
/>
<LLayerGroup
:name="$t('workouts.START_AND_FINISH')"
layer-type="overlay"
ref="workoutMap"
@ready="fitBounds(bounds)"
>
<CustomMarker
v-if="startMarkerCoordinates.latitude"
:markerCoordinates="startMarkerCoordinates"
:isStart="true"
<LControlLayers />
<LControl position="topleft" class="map-control" @click="resetZoom">
<i class="fa fa-refresh" aria-hidden="true" />
</LControl>
<LControl
position="topleft"
class="map-control"
@click="toggleFullscreen"
>
<i
:class="`fa fa-${isFullscreen ? 'compress' : 'arrows-alt'}`"
aria-hidden="true"
/>
</LControl>
<LTileLayer
:url="`${getApiUrl()}workouts/map_tile/{s}/{z}/{x}/{y}.png`"
:attribution="appConfig.map_attribution"
:bounds="bounds"
/>
<CustomMarker
v-if="endMarkerCoordinates.latitude"
:markerCoordinates="endMarkerCoordinates"
:isStart="false"
<LGeoJson :geojson="geoJson.jsonData" />
<LMarker
v-if="markerCoordinates.latitude"
:lat-lng="[
markerCoordinates.latitude,
markerCoordinates.longitude,
]"
/>
</LLayerGroup>
</LMap>
</div>
<LLayerGroup
:name="$t('workouts.START_AND_FINISH')"
layer-type="overlay"
>
<CustomMarker
v-if="startMarkerCoordinates.latitude"
:markerCoordinates="startMarkerCoordinates"
:isStart="true"
/>
<CustomMarker
v-if="endMarkerCoordinates.latitude"
:markerCoordinates="endMarkerCoordinates"
:isStart="false"
/>
</LLayerGroup>
</LMap>
</div>
</VFullscreen>
<div v-else class="no-map">{{ $t('workouts.NO_MAP') }}</div>
</div>
</div>
@ -114,6 +132,7 @@
}
: {}
)
const isFullscreen = ref(false)
function getGeoJson(gpxContent: string): GeoJSONData {
if (!gpxContent || gpxContent !== '') {
@ -157,6 +176,14 @@
function resetZoom() {
workoutMap.value?.leafletObject.fitBounds(getBounds())
}
function toggleFullscreen() {
isFullscreen.value = !isFullscreen.value
if (!isFullscreen.value) {
setTimeout(() => {
resetZoom()
}, 100)
}
}
</script>
<style lang="scss" scoped>
@ -171,13 +198,21 @@
.no-map {
line-height: 400px;
}
.reset-button {
.map-control {
background: #ffffff;
padding: 5px 10px;
border: 2px solid #bfc0ab;
border-radius: 3px;
color: #000000;
}
::v-deep(.fullscreen) {
display: flex;
align-items: center;
.fullscreen-map {
height: 100%;
width: 100%;
}
}
@media screen and (max-width: $small-limit) {
padding: 0;

View File

@ -14,6 +14,7 @@ import {
} from 'chart.js'
import ChartDataLabels from 'chartjs-plugin-datalabels'
import { createApp } from 'vue'
import VueFullscreen from 'vue-fullscreen'
import './registerServiceWorker'
import App from './App.vue'
@ -45,6 +46,7 @@ const app = createApp(App)
.use(i18n)
.use(store)
.use(router)
.use(VueFullscreen, { name: 'VFullscreen' })
.directive('click-outside', clickOutsideDirective)
customComponents.forEach((component) => {

View File

@ -8501,6 +8501,11 @@ schema-utils@^3.0.0:
ajv "^6.12.5"
ajv-keywords "^3.5.2"
screenfull@^5.1.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/screenfull/-/screenfull-5.2.0.tgz#6533d524d30621fc1283b9692146f3f13a93d1ba"
integrity sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==
select-hose@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
@ -9773,6 +9778,13 @@ vue-eslint-parser@^7.0.0, vue-eslint-parser@^7.10.0:
lodash "^4.17.21"
semver "^6.3.0"
vue-fullscreen@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/vue-fullscreen/-/vue-fullscreen-3.1.1.tgz#385097e0b43f4604ded99adb0ceb225dea3e0326"
integrity sha512-I59sIO0O22116gwVPo1qM2cNf5binEC5vTswIm8qJsqgatGfFquIJANpoVggSUS2EgUF0Xg4tHliT1ITcwQw8Q==
dependencies:
screenfull "^5.1.0"
vue-hot-reload-api@^2.3.0:
version "2.3.4"
resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz#532955cc1eb208a3d990b3a9f9a70574657e08f2"