- Updated Makefile to include `--build` flag for `docker-compose.dev.yml` and `--no-cache` for `docker-compose.prod.yml` to ensure fresh builds. - Added new CSS styles for Leaflet tooltips and popups to utilize theme colors, enhancing visual consistency. - Enhanced MapView component with new props for markers and current zoom level, improving marker management and zoom functionality. - Introduced new icons for copy and info actions to improve user interface clarity. - Updated MapBookmarks and MapControls components to support new features and improve user experience with bookmarks and zoom controls. - Refactored MapSearch to display coordinates and improve marker search functionality.
132 lines
4.6 KiB
Vue
132 lines
4.6 KiB
Vue
<template>
|
||
<section class="flex flex-col gap-2">
|
||
<h3 class="text-xs font-semibold uppercase tracking-wider text-base-content/70 flex items-center gap-1.5">
|
||
<icons-icon-bookmark class="size-3.5 opacity-80" aria-hidden="true" />
|
||
Saved locations
|
||
</h3>
|
||
<div class="flex flex-col gap-1 max-h-40 overflow-y-auto">
|
||
<template v-if="bookmarks.length === 0">
|
||
<p class="text-xs text-base-content/60 py-1">No saved locations.</p>
|
||
<p class="text-xs text-base-content/50 py-0">Add your first location below.</p>
|
||
</template>
|
||
<template v-else>
|
||
<div
|
||
v-for="b in bookmarks"
|
||
:key="b.id"
|
||
class="flex items-center gap-2 group rounded-lg hover:bg-base-200/50 px-2 py-1.5 -mx-2"
|
||
>
|
||
<button
|
||
type="button"
|
||
class="btn btn-ghost btn-xs flex-1 min-w-0 justify-start text-left truncate font-normal"
|
||
:title="`Go to ${b.name}`"
|
||
@click="onGoTo(b)"
|
||
>
|
||
<span class="truncate">{{ b.name }}</span>
|
||
</button>
|
||
<button
|
||
v-if="openBookmarkModal"
|
||
type="button"
|
||
class="btn btn-ghost btn-xs btn-square shrink-0 opacity-70 hover:opacity-100"
|
||
aria-label="Edit bookmark name"
|
||
@click="openBookmarkModal(b.name, 'Edit bookmark name', { kind: 'edit', editId: b.id })"
|
||
>
|
||
<icons-icon-pencil class="size-3.5" />
|
||
</button>
|
||
<button
|
||
type="button"
|
||
class="btn btn-ghost btn-xs btn-square shrink-0 opacity-70 hover:opacity-100 hover:text-error"
|
||
aria-label="Remove bookmark"
|
||
@click="onRemove(b.id)"
|
||
>
|
||
×
|
||
</button>
|
||
</div>
|
||
</template>
|
||
</div>
|
||
<div v-if="openBookmarkModal" class="flex flex-col gap-1">
|
||
<button
|
||
type="button"
|
||
class="btn btn-primary btn-sm w-full"
|
||
:class="touchFriendly ? 'min-h-11' : ''"
|
||
:disabled="!selectedMarkerForBookmark"
|
||
:title="selectedMarkerForBookmark ? 'Add selected quest giver as bookmark' : 'Select a quest giver from the list above to add it as a bookmark.'"
|
||
@click="onAddSelectedMarker"
|
||
>
|
||
<icons-icon-plus class="size-4" />
|
||
Add selected marker
|
||
</button>
|
||
<button
|
||
type="button"
|
||
class="btn btn-outline btn-sm w-full"
|
||
:class="touchFriendly ? 'min-h-11' : ''"
|
||
:disabled="!canAddCurrent"
|
||
title="Save current map position"
|
||
@click="onAddCurrent"
|
||
>
|
||
<icons-icon-plus class="size-4" />
|
||
Add current location
|
||
</button>
|
||
</div>
|
||
</section>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import type { MapInfo } from '~/types/api'
|
||
import { useMapBookmarks } from '~/composables/useMapBookmarks'
|
||
import { useMapNavigate } from '~/composables/useMapNavigate'
|
||
|
||
export type SelectedMarkerForBookmark = { mapId: number; x: number; y: number; name: string } | null
|
||
|
||
type BookmarkModalPayload =
|
||
| { kind: 'add'; mapId: number; x: number; y: number; zoom?: number }
|
||
| { kind: 'edit'; editId: string }
|
||
type OpenBookmarkModalFn = (defaultName: string, title: string, data: BookmarkModalPayload) => void
|
||
|
||
const props = withDefaults(
|
||
defineProps<{
|
||
maps: MapInfo[]
|
||
currentMapId: number | null
|
||
currentCoords: { x: number; y: number; z: number } | null
|
||
selectedMarkerForBookmark?: SelectedMarkerForBookmark
|
||
touchFriendly?: boolean
|
||
}>(),
|
||
{ selectedMarkerForBookmark: null, touchFriendly: false }
|
||
)
|
||
|
||
const { bookmarks, remove } = useMapBookmarks()
|
||
const { goToCoords } = useMapNavigate()
|
||
const openBookmarkModal = inject<OpenBookmarkModalFn>('openBookmarkModal')
|
||
|
||
const canAddCurrent = computed(
|
||
() =>
|
||
props.currentMapId != null &&
|
||
props.currentCoords != null &&
|
||
props.currentMapId >= 0
|
||
)
|
||
|
||
function onGoTo(b: { mapId: number; x: number; y: number; zoom?: number }) {
|
||
goToCoords(b.mapId, b.x, b.y, b.zoom)
|
||
}
|
||
|
||
function onRemove(id: string) {
|
||
remove(id)
|
||
}
|
||
|
||
function onAddSelectedMarker() {
|
||
const m = props.selectedMarkerForBookmark
|
||
if (!m || !openBookmarkModal) return
|
||
openBookmarkModal(m.name, 'Add bookmark', { kind: 'add', mapId: m.mapId, x: m.x, y: m.y })
|
||
}
|
||
|
||
function onAddCurrent() {
|
||
if (!canAddCurrent.value || !openBookmarkModal) return
|
||
const mapId = props.currentMapId!
|
||
const { x, y, z } = props.currentCoords!
|
||
openBookmarkModal(
|
||
`${props.maps.find((map) => map.ID === mapId)?.Name ?? `Map ${mapId}`} ${x}, ${y}`,
|
||
'Add bookmark',
|
||
{ kind: 'add', mapId, x, y, zoom: z }
|
||
)
|
||
}
|
||
</script>
|