Enhance map functionality and API documentation
- Updated API documentation for the `rebuildZooms` endpoint to clarify its long execution time and response behavior. - Modified MapView component to manage tile cache invalidation after rebuilding zoom levels, ensuring fresh tile display. - Introduced a new composable for handling tile cache invalidation state after admin actions. - Enhanced character icon creation to reflect ownership status with distinct colors. - Improved loading state handling in various components for better user experience during data fetching.
This commit is contained in:
@@ -195,6 +195,8 @@ let intervalId: ReturnType<typeof setInterval> | null = null
|
||||
let autoMode = false
|
||||
let mapContainer: HTMLElement | null = null
|
||||
let contextMenuHandler: ((ev: MouseEvent) => void) | null = null
|
||||
let mounted = false
|
||||
let visibilityChangeHandler: (() => void) | null = null
|
||||
|
||||
function toLatLng(x: number, y: number) {
|
||||
return leafletMap!.unproject([x, y], HnHMaxZoom)
|
||||
@@ -264,6 +266,7 @@ function onKeydown(e: KeyboardEvent) {
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
mounted = true
|
||||
if (import.meta.client) {
|
||||
window.addEventListener('keydown', onKeydown)
|
||||
}
|
||||
@@ -353,9 +356,11 @@ onMounted(async () => {
|
||||
getCurrentMapId: () => mapLogic.state.mapid.value,
|
||||
connectionStateRef: sseConnectionState,
|
||||
onMerge: (mapTo: number, shift: { x: number; y: number }) => {
|
||||
if (!mounted) return
|
||||
const latLng = toLatLng(shift.x * 100, shift.y * 100)
|
||||
layersManager!.changeMap(mapTo)
|
||||
api.getMarkers().then((body) => {
|
||||
if (!mounted) return
|
||||
layersManager!.updateMarkers(Array.isArray(body) ? body : [])
|
||||
questGivers.value = layersManager!.getQuestGivers()
|
||||
})
|
||||
@@ -363,6 +368,17 @@ onMounted(async () => {
|
||||
},
|
||||
})
|
||||
|
||||
const { shouldInvalidateTileCache, clearRebuildDoneFlag } = useRebuildZoomsInvalidation()
|
||||
if (shouldInvalidateTileCache()) {
|
||||
mapInit.layer.cache = {}
|
||||
mapInit.overlayLayer.cache = {}
|
||||
clearRebuildDoneFlag()
|
||||
nextTick(() => {
|
||||
mapInit.layer.redraw()
|
||||
mapInit.overlayLayer.redraw()
|
||||
})
|
||||
}
|
||||
|
||||
const charsList = Array.isArray(charactersData) ? charactersData : []
|
||||
layersManager.updateCharacters(charsList)
|
||||
players.value = layersManager.getPlayers()
|
||||
@@ -395,6 +411,7 @@ onMounted(async () => {
|
||||
|
||||
// Markers load asynchronously after map is visible.
|
||||
api.getMarkers().then((body) => {
|
||||
if (!mounted) return
|
||||
layersManager!.updateMarkers(Array.isArray(body) ? body : [])
|
||||
questGivers.value = layersManager!.getQuestGivers()
|
||||
})
|
||||
@@ -406,6 +423,7 @@ onMounted(async () => {
|
||||
api
|
||||
.getCharacters()
|
||||
.then((body) => {
|
||||
if (!mounted) return
|
||||
const list = Array.isArray(body) ? body : []
|
||||
layersManager!.updateCharacters(list)
|
||||
players.value = layersManager!.getPlayers()
|
||||
@@ -429,17 +447,31 @@ onMounted(async () => {
|
||||
|
||||
startCharacterPoll()
|
||||
if (import.meta.client) {
|
||||
document.addEventListener('visibilitychange', () => {
|
||||
visibilityChangeHandler = () => {
|
||||
startCharacterPoll()
|
||||
})
|
||||
}
|
||||
document.addEventListener('visibilitychange', visibilityChangeHandler)
|
||||
}
|
||||
|
||||
watch(mapLogic.state.showGridCoordinates, (v) => {
|
||||
if (mapInit?.coordLayer) {
|
||||
;(mapInit.coordLayer.options as { visible?: boolean }).visible = v
|
||||
mapInit.coordLayer.setOpacity(v ? 1 : 0)
|
||||
mapInit.coordLayer.redraw?.()
|
||||
if (v) mapInit.coordLayer.bringToFront?.()
|
||||
if (!mapInit?.coordLayer || !leafletMap) return
|
||||
const coordLayer = mapInit.coordLayer
|
||||
const layerWithMap = coordLayer as L.GridLayer & { _map?: L.Map }
|
||||
if (v) {
|
||||
;(coordLayer.options as { visible?: boolean }).visible = true
|
||||
if (!layerWithMap._map) {
|
||||
coordLayer.addTo(leafletMap)
|
||||
coordLayer.setZIndex(500)
|
||||
coordLayer.setOpacity(1)
|
||||
coordLayer.bringToFront?.()
|
||||
}
|
||||
leafletMap.invalidateSize()
|
||||
nextTick(() => {
|
||||
coordLayer.redraw?.()
|
||||
})
|
||||
} else {
|
||||
coordLayer.setOpacity(0)
|
||||
coordLayer.remove()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -553,8 +585,12 @@ onMounted(async () => {
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
mounted = false
|
||||
if (import.meta.client) {
|
||||
window.removeEventListener('keydown', onKeydown)
|
||||
if (visibilityChangeHandler) {
|
||||
document.removeEventListener('visibilitychange', visibilityChangeHandler)
|
||||
}
|
||||
}
|
||||
mapNavigate.setGoTo(null)
|
||||
if (contextMenuHandler) {
|
||||
|
||||
@@ -56,7 +56,12 @@
|
||||
Display
|
||||
</h3>
|
||||
<label class="label cursor-pointer justify-start gap-2 py-0 hover:bg-base-200/50 rounded-lg px-2 -mx-2 touch-manipulation" :class="touchFriendly ? 'min-h-11' : ''">
|
||||
<input v-model="showGridCoordinates" type="checkbox" class="checkbox checkbox-sm" />
|
||||
<input
|
||||
v-model="showGridCoordinates"
|
||||
type="checkbox"
|
||||
class="checkbox checkbox-sm"
|
||||
data-testid="show-grid-coordinates"
|
||||
/>
|
||||
<span>Show grid coordinates</span>
|
||||
</label>
|
||||
<label class="label cursor-pointer justify-start gap-2 py-0 hover:bg-base-200/50 rounded-lg px-2 -mx-2 touch-manipulation" :class="touchFriendly ? 'min-h-11' : ''">
|
||||
|
||||
Reference in New Issue
Block a user