Start moving leaflet controls to vue

This commit is contained in:
James Lyne 2022-06-23 20:46:00 +01:00
parent 9938f30c84
commit 26d5d59b1b
6 changed files with 225 additions and 47 deletions

View File

@ -15,7 +15,9 @@
--> -->
<template> <template>
<Map></Map> <Map v-slot="slotProps">
<MapUI v-if="slotProps.leaflet" :leaflet="slotProps.leaflet"></MapUI>
</Map>
<ChatBox v-if="chatBoxEnabled" v-show="chatBoxEnabled && chatVisible"></ChatBox> <ChatBox v-if="chatBoxEnabled" v-show="chatBoxEnabled && chatVisible"></ChatBox>
<LoginModal v-if="loginEnabled" v-show="loginModalVisible" :required="loginRequired"></LoginModal> <LoginModal v-if="loginEnabled" v-show="loginModalVisible" :required="loginRequired"></LoginModal>
<Sidebar></Sidebar> <Sidebar></Sidebar>
@ -36,10 +38,12 @@ import {LiveAtlasServerDefinition, LiveAtlasUIElement} from "@/index";
import LoginModal from "@/components/login/LoginModal.vue"; import LoginModal from "@/components/login/LoginModal.vue";
import {notify} from "@kyvg/vue3-notification"; import {notify} from "@kyvg/vue3-notification";
import {clearPlayerImageCache} from "@/util/images"; import {clearPlayerImageCache} from "@/util/images";
import MapUI from "@/components/MapUI.vue";
export default defineComponent({ export default defineComponent({
name: 'App', name: 'App',
components: { components: {
MapUI,
Map, Map,
Sidebar, Sidebar,
ChatBox, ChatBox,

View File

@ -22,18 +22,10 @@
<TileLayerOverlay v-for="[name, overlay] in overlays" :key="name" :options="overlay" :leaflet="leaflet"></TileLayerOverlay> <TileLayerOverlay v-for="[name, overlay] in overlays" :key="name" :options="overlay" :leaflet="leaflet"></TileLayerOverlay>
<PlayersLayer v-if="playerMarkersEnabled" :leaflet="leaflet"></PlayersLayer> <PlayersLayer v-if="playerMarkersEnabled" :leaflet="leaflet"></PlayersLayer>
<MarkerSetLayer v-for="[name, markerSet] in markerSets" :key="name" :markerSet="markerSet" :leaflet="leaflet"></MarkerSetLayer> <MarkerSetLayer v-for="[name, markerSet] in markerSets" :key="name" :markerSet="markerSet" :leaflet="leaflet"></MarkerSetLayer>
<LogoControl v-for="logo in logoControls" :key="JSON.stringify(logo)" :options="logo" :leaflet="leaflet"></LogoControl>
<CoordinatesControl v-if="coordinatesControlEnabled" :leaflet="leaflet"></CoordinatesControl>
<LinkControl v-if="linkControlEnabled" :leaflet="leaflet"></LinkControl>
<ClockControl v-if="clockControlEnabled" :leaflet="leaflet"></ClockControl>
<LoginControl v-if="loginEnabled" :leaflet="leaflet"></LoginControl>
<ChatControl v-if="chatBoxEnabled" :leaflet="leaflet"></ChatControl>
</template> </template>
</div> </div>
<MapContextMenu v-if="contextMenuEnabled && leaflet" :leaflet="leaflet"></MapContextMenu> <slot :leaflet="leaflet"></slot>
</template> </template>
<script lang="ts"> <script lang="ts">
@ -43,32 +35,17 @@ import {useStore} from '@/store';
import TileLayer from "@/components/map/layer/TileLayer.vue"; import TileLayer from "@/components/map/layer/TileLayer.vue";
import PlayersLayer from "@/components/map/layer/PlayersLayer.vue"; import PlayersLayer from "@/components/map/layer/PlayersLayer.vue";
import MarkerSetLayer from "@/components/map/layer/MarkerSetLayer.vue"; import MarkerSetLayer from "@/components/map/layer/MarkerSetLayer.vue";
import CoordinatesControl from "@/components/map/control/CoordinatesControl.vue";
import ClockControl from "@/components/map/control/ClockControl.vue";
import LinkControl from "@/components/map/control/LinkControl.vue";
import ChatControl from "@/components/map/control/ChatControl.vue";
import LogoControl from "@/components/map/control/LogoControl.vue";
import {MutationTypes} from "@/store/mutation-types"; import {MutationTypes} from "@/store/mutation-types";
import LiveAtlasLeafletMap from "@/leaflet/LiveAtlasLeafletMap"; import LiveAtlasLeafletMap from "@/leaflet/LiveAtlasLeafletMap";
import {LoadingControl} from "@/leaflet/control/LoadingControl";
import MapContextMenu from "@/components/map/MapContextMenu.vue";
import {LiveAtlasLocation, LiveAtlasPlayer, LiveAtlasMapViewTarget} from "@/index"; import {LiveAtlasLocation, LiveAtlasPlayer, LiveAtlasMapViewTarget} from "@/index";
import LoginControl from "@/components/map/control/LoginControl.vue";
import TileLayerOverlay from "@/components/map/layer/TileLayerOverlay.vue"; import TileLayerOverlay from "@/components/map/layer/TileLayerOverlay.vue";
export default defineComponent({ export default defineComponent({
components: { components: {
TileLayerOverlay, TileLayerOverlay,
MapContextMenu,
TileLayer, TileLayer,
PlayersLayer, PlayersLayer,
MarkerSetLayer, MarkerSetLayer
CoordinatesControl,
ClockControl,
LinkControl,
ChatControl,
LogoControl,
LoginControl
}, },
setup() { setup() {
@ -81,13 +58,6 @@ export default defineComponent({
configuration = computed(() => store.state.configuration), configuration = computed(() => store.state.configuration),
playerMarkersEnabled = computed(() => store.getters.playerMarkersEnabled), playerMarkersEnabled = computed(() => store.getters.playerMarkersEnabled),
coordinatesControlEnabled = computed(() => store.getters.coordinatesControlEnabled),
clockControlEnabled = computed(() => store.getters.clockControlEnabled),
linkControlEnabled = computed(() => store.state.components.linkControl),
chatBoxEnabled = computed(() => store.state.components.chatBox),
loginEnabled = computed(() => store.state.components.login),
contextMenuEnabled = computed(() => !store.state.ui.disableContextMenu),
logoControls = computed(() => store.state.components.logoControls),
currentWorld = computed(() => store.state.currentWorld), currentWorld = computed(() => store.state.currentWorld),
currentMap = computed(() => store.state.currentMap), currentMap = computed(() => store.state.currentMap),
@ -110,14 +80,7 @@ export default defineComponent({
configuration, configuration,
playerMarkersEnabled, playerMarkersEnabled,
coordinatesControlEnabled,
clockControlEnabled,
linkControlEnabled,
chatBoxEnabled,
loginEnabled,
contextMenuEnabled,
logoControls,
followTarget, followTarget,
viewTarget, viewTarget,
parsedUrl, parsedUrl,
@ -265,11 +228,6 @@ export default defineComponent({
this.leaflet.createPane('vectors'); this.leaflet.createPane('vectors');
this.leaflet.addControl(new LoadingControl({
position: 'topleft',
delayIndicator: 500,
}));
this.leaflet.on('moveend', () => { this.leaflet.on('moveend', () => {
if(this.currentMap) { if(this.currentMap) {
useStore().commit(MutationTypes.SET_CURRENT_LOCATION, this.currentMap useStore().commit(MutationTypes.SET_CURRENT_LOCATION, this.currentMap

216
src/components/MapUI.vue Normal file
View File

@ -0,0 +1,216 @@
<!--
- Copyright 2022 James Lyne
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-->
<template>
<div id="ui">
<div id="ui__top-center" class="ui__section">
<ClockControl v-if="clockControlEnabled" :leaflet="leaflet"></ClockControl>
</div>
<div id="ui__top-left" class="ui__section section--vertical">
<div class="ui__toolbar toolbar--vertical"></div>
</div>
<div id="ui__bottom-left" class="ui__section">
<div class="ui__toolbar toolbar--vertical">
<LoginControl v-if="loginEnabled" :leaflet="leaflet"></LoginControl>
<ChatControl v-if="chatBoxEnabled" :leaflet="leaflet"></ChatControl>
</div>
<div class="ui__toolbar">
<LinkControl v-if="linkControlEnabled" :leaflet="leaflet"></LinkControl>
<CoordinatesControl v-if="coordinatesControlEnabled" :leaflet="leaflet"></CoordinatesControl>
</div>
</div>
<div id="ui__top-right" class="ui__section">
</div>
<div id="ui__bottom-right" class="ui__section"></div>
</div>
<!-- <LogoControl v-for="logo in logoControls" :key="JSON.stringify(logo)" :options="logo" :leaflet="leaflet"></LogoControl>-->
<MapContextMenu v-if="contextMenuEnabled && leaflet" :leaflet="leaflet"></MapContextMenu>
</template>
<script lang="ts">
import {computed, defineComponent} from "@vue/runtime-core";
import {useStore} from '@/store';
import CoordinatesControl from "@/components/map/control/CoordinatesControl.vue";
import ClockControl from "@/components/map/control/ClockControl.vue";
import LinkControl from "@/components/map/control/LinkControl.vue";
import ChatControl from "@/components/map/control/ChatControl.vue";
import LogoControl from "@/components/map/control/LogoControl.vue";
import {LoadingControl} from "@/leaflet/control/LoadingControl";
import MapContextMenu from "@/components/map/MapContextMenu.vue";
import LoginControl from "@/components/map/control/LoginControl.vue";
import {onMounted} from "vue";
import LiveAtlasLeafletMap from "@/leaflet/LiveAtlasLeafletMap";
export default defineComponent({
props: {
leaflet: {
type: Object as () => LiveAtlasLeafletMap,
required: true,
}
},
components: {
LogoControl,
CoordinatesControl,
LinkControl,
ClockControl,
LoginControl,
ChatControl,
MapContextMenu
},
setup(props) {
const store = useStore(),
contextMenuEnabled = computed(() => !store.state.ui.disableContextMenu),
coordinatesControlEnabled = computed(() => store.getters.coordinatesControlEnabled),
clockControlEnabled = computed(() => store.getters.clockControlEnabled),
linkControlEnabled = computed(() => store.state.components.linkControl),
chatBoxEnabled = computed(() => store.state.components.chatBox),
loginEnabled = computed(() => store.state.components.login),
logoControls = computed(() => store.state.components.logoControls);
onMounted(() => {
props.leaflet.addControl(new LoadingControl({
position: 'topleft',
delayIndicator: 500,
}))
});
return {
contextMenuEnabled,
coordinatesControlEnabled,
clockControlEnabled,
linkControlEnabled,
chatBoxEnabled,
loginEnabled,
logoControls,
}
}
});
</script>
<style lang="scss">
@import '../scss/placeholders';
#ui {
position: fixed;
top: 0;
left: 0;
box-sizing: border-box;
height: 100vh; /* Use explicit height to make safari happy */
width: 100vw;
pointer-events: none;
display: grid;
grid-template-columns: 1fr min-content 1fr;
grid-template-rows: 1fr 1fr;
z-index: 1003;
padding: var(--ui-element-spacing);
}
.ui__section {
display: grid;
grid-gap: var(--ui-element-spacing);
align-items: start;
justify-items: start;
}
.ui__toolbar {
display: grid;
grid-gap: var(--ui-element-spacing);
grid-auto-flow: column;
align-items: start;
justify-items: start;
&.toolbar--vertical {
flex-direction: column;
grid-auto-flow: row;
}
}
.ui__element {
box-sizing: border-box;
@media print {
display: none !important;
}
}
.ui__button,
.ui__panel {
box-shadow: var(--box-shadow);
}
.ui__button {
@extend %button;
pointer-events: auto;
width: var(--ui-button-size);
height: var(--ui-button-size);
line-height: 3.5rem;
}
.ui__panel {
@extend %panel;
}
.ui__group {
display: flex;
flex-direction: inherit;
box-shadow: var(--box-shadow);
border-radius: var(--border-radius);
.ui__button {
box-shadow: none;
border-radius: calc(var(--border-radius) - 0.2rem);
&:not(:first-child) {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
&:not(:last-child) {
border-bottom: 0.1rem solid var(--border-color);
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
}
}
#ui__top-center {
grid-row: 1;
grid-column: 2;
}
#ui__top-left {
grid-row: 1;
grid-column: 1;
}
#ui__bottom-left {
grid-row: -1;
grid-column: 1;
}
#ui__bottom-right {
grid-row: -1;
grid-column: -1;
}
</style>

View File

@ -40,6 +40,7 @@
user-select: none; user-select: none;
padding: 0.8rem 0.8rem 0.7rem; padding: 0.8rem 0.8rem 0.7rem;
line-height: 2rem; line-height: 2rem;
letter-spacing: 0.02rem;
-webkit-tap-highlight-color: transparent; -webkit-tap-highlight-color: transparent;
.svg-icon { .svg-icon {

View File

@ -53,5 +53,4 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 1.5rem; padding: 1.5rem;
position: relative;
} }

View File

@ -79,7 +79,7 @@ a {
color: var(--text-base); color: var(--text-base);
} }
button, [type=button] { button, input[type=button], input[type=reset], input[type=submit] {
@extend %button; @extend %button;
} }