allow ?fullscreen=true for embedded map support

This commit is contained in:
Will Freeman
2025-03-28 13:41:21 -06:00
parent d748908cfd
commit dafd8bb325
3 changed files with 59 additions and 47 deletions
+44 -41
View File
@@ -6,6 +6,7 @@ import { useTheme } from 'vuetify';
const theme = useTheme(); const theme = useTheme();
const router = useRouter(); const router = useRouter();
const isDark = computed(() => theme.name.value === 'dark'); const isDark = computed(() => theme.name.value === 'dark');
const isFullscreen = computed(() => router.currentRoute.value?.query.fullscreen === 'true');
function toggleTheme() { function toggleTheme() {
const newTheme = theme.global.name.value === 'dark' ? 'light' : 'dark'; const newTheme = theme.global.name.value === 'dark' ? 'light' : 'dark';
@@ -46,53 +47,55 @@ watch(() => theme.global.name.value, (newTheme) => {
<template> <template>
<v-app> <v-app>
<v-app-bar <template v-if="!isFullscreen">
flat <v-app-bar
prominent flat
> prominent
<v-app-bar-nav-icon variant="text" @click.stop="drawer = !drawer"></v-app-bar-nav-icon> >
<v-app-bar-nav-icon variant="text" @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
<v-toolbar-title> <v-toolbar-title>
<v-img style="cursor: pointer" height="36" width="130" src="/deflock-logo.svg" @click="router.push('/')" /> <v-img style="cursor: pointer" height="36" width="130" src="/deflock-logo.svg" @click="router.push('/')" />
</v-toolbar-title> </v-toolbar-title>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<!-- <v-btn icon> <!-- <v-btn icon>
<v-icon @click="toggleTheme">mdi-theme-light-dark</v-icon> <v-icon @click="toggleTheme">mdi-theme-light-dark</v-icon>
</v-btn> --> </v-btn> -->
</v-app-bar> </v-app-bar>
<v-navigation-drawer <v-navigation-drawer
v-model="drawer" v-model="drawer"
temporary temporary
> >
<v-list nav> <v-list nav>
<v-list-subheader>DeFlock</v-list-subheader> <v-list-subheader>DeFlock</v-list-subheader>
<v-list-item <v-list-item
v-for="item in items" v-for="item in items"
:key="item.title" :key="item.title"
link link
:to="item.to" :to="item.to"
><v-icon start>{{ item.icon }}</v-icon>{{ item.title }}</v-list-item> ><v-icon start>{{ item.icon }}</v-icon>{{ item.title }}</v-list-item>
<v-divider /> <v-divider />
<v-list-subheader>Get Involved</v-list-subheader> <v-list-subheader>Get Involved</v-list-subheader>
<v-list-item <v-list-item
v-for="item in metaItems" v-for="item in metaItems"
:key="item.title" :key="item.title"
link link
:to="item.to" :to="item.to"
:href="item.href" :href="item.href"
:target="{ '_blank': item.href }" :target="{ '_blank': item.href }"
> >
<v-icon v-if="item.icon" start>{{ item.icon }}</v-icon> <v-icon v-if="item.icon" start>{{ item.icon }}</v-icon>
<v-img v-else-if="item.customIcon" class="mr-2 custom-icon" contain width="24" height="24" :src="isDark ? item.customIconDark : item.customIcon" style="vertical-align: middle;" /> <v-img v-else-if="item.customIcon" class="mr-2 custom-icon" contain width="24" height="24" :src="isDark ? item.customIconDark : item.customIcon" style="vertical-align: middle;" />
<span style="vertical-align: middle;">{{ item.title }}</span> <span style="vertical-align: middle;">{{ item.title }}</span>
</v-list-item> </v-list-item>
</v-list> </v-list>
</v-navigation-drawer> </v-navigation-drawer>
</template>
<v-main> <v-main>
<RouterView /> <RouterView />
+7 -3
View File
@@ -1,5 +1,8 @@
<template> <template>
<div id="map"> <div id="map" :style="{
height: isFullScreen ? '100dvh' : 'calc(100dvh - 64px)',
marginTop: isFullScreen ? '0' : '64px',
}">
<div class="topleft"> <div class="topleft">
<slot name="topleft"></slot> <slot name="topleft"></slot>
</div> </div>
@@ -16,6 +19,8 @@ import L, { type LatLngTuple, type FeatureGroup, type MarkerClusterGroup, type M
import type { ALPR } from '@/types'; import type { ALPR } from '@/types';
import DFMapPopup from './DFMapPopup.vue'; import DFMapPopup from './DFMapPopup.vue';
import { createVuetify } from 'vuetify' import { createVuetify } from 'vuetify'
import { useRoute } from 'vue-router';
import { computed } from 'vue';
import 'leaflet/dist/leaflet.css'; import 'leaflet/dist/leaflet.css';
import 'leaflet.markercluster'; import 'leaflet.markercluster';
import 'leaflet.markercluster/dist/MarkerCluster.Default.css'; import 'leaflet.markercluster/dist/MarkerCluster.Default.css';
@@ -26,6 +31,7 @@ const MARKER_COLOR = 'rgb(63,84,243)';
// Internal State Management // Internal State Management
const markerMap = new Map<string, Marker | CircleMarker>(); const markerMap = new Map<string, Marker | CircleMarker>();
const isInternalUpdate = ref(false); const isInternalUpdate = ref(false);
const isFullScreen = computed(() => useRoute().query.fullscreen === 'true');
const props = defineProps({ const props = defineProps({
center: { center: {
@@ -278,8 +284,6 @@ function registerMapEvents() {
@import 'leaflet.markercluster/dist/MarkerCluster.css'; @import 'leaflet.markercluster/dist/MarkerCluster.css';
#map { #map {
height: calc(100dvh - 64px);
margin-top: 64px;
width: 100%; width: 100%;
position: absolute; position: absolute;
top: 0; top: 0;
+6 -1
View File
@@ -140,8 +140,13 @@ function updateURL() {
return; return;
} }
const currentRoute = router.currentRoute.value;
const newHash = `#map=${zoom.value}/${center.value.lat.toFixed(6)}/${center.value.lng.toFixed(6)}`;
router.replace({ router.replace({
hash: `#map=${zoom.value}/${center.value.lat.toFixed(6)}/${center.value.lng.toFixed(6)}` path: currentRoute.path,
query: currentRoute.query,
hash: newHash,
}); });
} }