<template> <div class="h-full overflow-auto"> <div class="relative p-2.5 flex flex-col items-center justify-between h-[300px]"> <div class="filler"></div> <img class="max-h-[280px]" :src="`${config.server_endpoint}/assets/tiles/${selectedTile?.id}.png`" :alt="'Tile ' + selectedTile?.id" /> <button class="btn-bordeaux px-[15px] py-1.5 min-w-[100px]" type="button" @click.prevent="removeTile">Remove</button> <div class="absolute left-0 bottom-0 w-full h-[1px] bg-cyan-200"></div> </div> <div class="m-2.5 p-2.5 block"> <form class="flex gap-2.5 flex-wrap" @submit.prevent="saveTile"> <div class="w-full flex flex-col mb-5"> <label class="mb-1.5 font-titles" for="name">Name</label> <input v-model="tileName" class="input-cyan" type="text" name="name" placeholder="Tile #1" /> </div> <div class="w-full flex flex-col mb-5"> <label class="mb-1.5 font-titles" for="origin-x">Tags</label> <ChipsInput v-model="tileTags" @update:modelValue="tileTags = $event" /> </div> <button class="btn-cyan px-[15px] py-1.5 min-w-[100px]" type="submit">Save</button> </form> </div> </div> </template> <script setup lang="ts"> import type { Tile } from '@/types' import { computed, onBeforeUnmount, onMounted, ref, toRaw, watch } from 'vue' import { useAssetManagerStore } from '@/stores/assetManager' import { useZoneEditorStore } from '@/stores/zoneEditor' import { useGameStore } from '@/stores/game' import config from '@/config' import ChipsInput from '@/components/forms/ChipsInput.vue' const gameStore = useGameStore() const assetManagerStore = useAssetManagerStore() const zoneEditorStore = useZoneEditorStore() const selectedTile = computed(() => assetManagerStore.selectedTile) const tileName = ref('') const tileTags = ref() if (!selectedTile.value) { console.error('No tile selected') } if (selectedTile.value) { tileName.value = selectedTile.value.name tileTags.value = selectedTile.value.tags } watch(selectedTile, (tile: Tile | null) => { if (!tile) return tileName.value = tile.name tileTags.value = tile.tags }) function removeTile() { gameStore.connection?.emit('gm:tile:remove', { tile: selectedTile.value?.id }, (response: boolean) => { if (!response) { console.error('Failed to remove tile') return } refreshTileList() }) } function refreshTileList(unsetSelectedTile = true) { gameStore.connection?.emit('gm:tile:list', {}, (response: Tile[]) => { assetManagerStore.setTileList(response) if (unsetSelectedTile) { assetManagerStore.setSelectedTile(null) } if (zoneEditorStore.active) { console.log('Refreshing tile list for zone store') zoneEditorStore.setTileList(response) } }) } function saveTile() { if (!selectedTile.value) { console.error('No tile selected') return } gameStore.connection?.emit( 'gm:tile:update', { id: selectedTile.value.id, name: tileName.value, tags: tileTags.value }, (response: boolean) => { if (!response) { console.error('Failed to save tile') return } refreshTileList(false) } ) } onMounted(() => { if (!selectedTile.value) return }) onBeforeUnmount(() => { assetManagerStore.setSelectedTile(null) }) </script>