1
0
forked from noxious/client

#321 - Made mapObjectList & tileList side panels

This commit is contained in:
Colin Kallemein 2025-01-31 22:35:13 +01:00
parent 7d3946e274
commit d665ac989c
4 changed files with 131 additions and 125 deletions

View File

@ -1,9 +1,11 @@
<template> <template>
<Modal ref="modalRef" :modal-width="645" :modal-height="260" :bg-style="'none'"> <div class="absolute border-0 border-l-2 border-solid border-gray-500 w-1/4 min-w-80 flex flex-col top-0 right-0 z-10 h-dvh bg-gray-800" v-if="isOpen">
<template #modalHeader> <div class="relative z-10 p-2.5 border-solid border-0 border-b border-gray-500 text-right">
<h3 class="text-lg text-white">Map objects</h3> <h3 class="text-lg text-white">Map objects</h3>
</template> </div>
<template #modalBody> <div class="overflow-hidden grow relative">
<div class="absolute w-full h-full top-0 left-0">
<div class="relative z-10 h-full">
<div class="flex pt-4 pl-4"> <div class="flex pt-4 pl-4">
<div class="w-full flex gap-1.5 flex-row"> <div class="w-full flex gap-1.5 flex-row">
<div> <div>
@ -12,7 +14,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="flex flex-col h-full p-4"> <div class="flex flex-col h-[calc(100%_-_170px)] p-4 pb-24">
<div class="mb-4 flex flex-wrap gap-2"> <div class="mb-4 flex flex-wrap gap-2">
<button v-for="tag in uniqueTags" :key="tag" @click="toggleTag(tag)" class="btn-cyan" :class="{ 'opacity-50': !selectedTags.includes(tag) }"> <button v-for="tag in uniqueTags" :key="tag" @click="toggleTag(tag)" class="btn-cyan" :class="{ 'opacity-50': !selectedTags.includes(tag) }">
{{ tag }} {{ tag }}
@ -22,13 +24,13 @@
<div class="flex justify-between flex-wrap gap-2.5 items-center"> <div class="flex justify-between flex-wrap gap-2.5 items-center">
<div v-for="(mapObject, index) in filteredMapObjects" :key="index" class="max-w-1/4 inline-block"> <div v-for="(mapObject, index) in filteredMapObjects" :key="index" class="max-w-1/4 inline-block">
<img <img
class="border-2 border-solid max-w-full" class="border-2 border-solid rounded max-w-full"
:src="`${config.server_endpoint}/textures/map_objects/${mapObject.id}.png`" :src="`${config.server_endpoint}/textures/map_objects/${mapObject.id}.png`"
alt="Object" alt="Object"
@click="mapEditor.setSelectedMapObject(mapObject)" @click="mapEditor.setSelectedMapObject(mapObject)"
:class="{ :class="{
'cursor-pointer transition-all duration-300': true, 'cursor-pointer transition-all duration-300': true,
'border-cyan shadow-lg scale-105': mapEditor.selectedMapObject.value?.id === mapObject.id, 'border-cyan shadow-lg': mapEditor.selectedMapObject.value?.id === mapObject.id,
'border-transparent hover:border-gray-300': mapEditor.selectedMapObject.value?.id !== mapObject.id 'border-transparent hover:border-gray-300': mapEditor.selectedMapObject.value?.id !== mapObject.id
}" }"
/> />
@ -36,31 +38,32 @@
</div> </div>
</div> </div>
</div> </div>
</template> </div>
</Modal> </div>
</div>
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import config from '@/application/config' import config from '@/application/config'
import type { MapObject } from '@/application/types' import type { MapObject } from '@/application/types'
import Modal from '@/components/utilities/Modal.vue'
import { useMapEditorComposable } from '@/composables/useMapEditorComposable' import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
import { MapObjectStorage } from '@/storage/storages' import { MapObjectStorage } from '@/storage/storages'
import { liveQuery } from 'dexie' import { liveQuery } from 'dexie'
import { computed, onMounted, onUnmounted, ref, useTemplateRef } from 'vue' import { computed, onMounted, onUnmounted, ref } from 'vue'
defineExpose({
open: () => (isOpen.value = true),
close: () => (isOpen.value = false),
toggle: () => (isOpen.value = !isOpen.value)
})
const isOpen = ref(false)
const mapObjectStorage = new MapObjectStorage() const mapObjectStorage = new MapObjectStorage()
const isModalOpen = ref(false)
const mapEditor = useMapEditorComposable() const mapEditor = useMapEditorComposable()
const searchQuery = ref('') const searchQuery = ref('')
const selectedTags = ref<string[]>([]) const selectedTags = ref<string[]>([])
const mapObjectList = ref<MapObject[]>([]) const mapObjectList = ref<MapObject[]>([])
const modalRef = useTemplateRef('modalRef')
defineExpose({
open: () => modalRef.value?.open(),
close: () => modalRef.value?.close()
})
const uniqueTags = computed(() => { const uniqueTags = computed(() => {
const allTags = mapObjectList.value.flatMap((obj) => obj.tags || []) const allTags = mapObjectList.value.flatMap((obj) => obj.tags || [])
@ -86,13 +89,12 @@ const toggleTag = (tag: string) => {
let subscription: any = null let subscription: any = null
onMounted(() => { onMounted(() => {
isModalOpen.value = true
subscription = liveQuery(() => mapObjectStorage.liveQuery()).subscribe({ subscription = liveQuery(() => mapObjectStorage.liveQuery()).subscribe({
next: (result) => { next: (result) => {
mapObjectList.value = result mapObjectList.value = result
}, },
error: (error) => { error: (error) => {
console.error('Failed to fetch tiles:', error) console.error('Failed to fetch objects:', error)
} }
}) })
}) })

View File

@ -1,10 +1,12 @@
<template> <template>
<Modal ref="modalRef" :modal-width="645" :modal-height="600" :bg-style="'none'"> <div class="absolute border-0 border-l-2 border-solid border-gray-500 w-1/4 min-w-80 flex flex-col top-0 right-0 z-10 h-dvh bg-gray-800" v-if="isOpen">
<template #modalHeader> <div class="relative z-10 p-2.5 border-solid border-0 border-b border-gray-500 text-right">
<h3 class="text-lg text-white">Tiles</h3> <h3 class="text-lg text-white">Tiles</h3>
</template> </div>
<template #modalBody> <div class="overflow-hidden grow relative">
<div class="h-full overflow-auto" v-if="!selectedGroup"> <div class="absolute top-0 left-0 h-full w-full">
<div class="relative z-10 h-full">
<div class="h-full" v-if="!selectedGroup">
<div class="flex pt-4 pl-4"> <div class="flex pt-4 pl-4">
<div class="w-full flex gap-1.5 flex-row"> <div class="w-full flex gap-1.5 flex-row">
<div> <div>
@ -13,14 +15,14 @@
</div> </div>
</div> </div>
</div> </div>
<div class="flex flex-col h-full p-4"> <div class="flex flex-col h-[calc(100%_-_170px)] p-4 pb-24">
<div class="mb-4 flex flex-wrap gap-2"> <div class="mb-4 flex flex-wrap gap-2">
<button v-for="tag in uniqueTags" :key="tag" @click="toggleTag(tag)" class="btn-cyan" :class="{ 'opacity-50': !selectedTags.includes(tag) }"> <button v-for="tag in uniqueTags" :key="tag" @click="toggleTag(tag)" class="btn-cyan" :class="{ 'opacity-50': !selectedTags.includes(tag) }">
{{ tag }} {{ tag }}
</button> </button>
</div> </div>
<div class="h-[calc(100%_-_60px)] flex-grow overflow-y-auto"> <div class="h-full flex-grow overflow-y-auto">
<div class="grid grid-cols-8 gap-2 justify-items-center"> <div class="grid grid-cols-4 gap-2 justify-items-center">
<div v-for="group in groupedTiles" :key="group.parent.id" class="flex flex-col items-center justify-center relative"> <div v-for="group in groupedTiles" :key="group.parent.id" class="flex flex-col items-center justify-center relative">
<img <img
class="max-w-full max-h-full border-2 border-solid cursor-pointer transition-all duration-300" class="max-w-full max-h-full border-2 border-solid cursor-pointer transition-all duration-300"
@ -76,19 +78,21 @@
</div> </div>
</div> </div>
</div> </div>
</template> </div>
</Modal> </div>
</div>
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import config from '@/application/config' import config from '@/application/config'
import type { Tile } from '@/application/types' import type { Tile } from '@/application/types'
import Modal from '@/components/utilities/Modal.vue'
import { useMapEditorComposable } from '@/composables/useMapEditorComposable' import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
import { TileStorage } from '@/storage/storages' import { TileStorage } from '@/storage/storages'
import { liveQuery } from 'dexie' import { liveQuery } from 'dexie'
import { computed, onMounted, onUnmounted, ref, useTemplateRef } from 'vue' import { computed, onMounted, onUnmounted, ref } from 'vue'
const isOpen = ref(false)
const tileStorage = new TileStorage() const tileStorage = new TileStorage()
const mapEditor = useMapEditorComposable() const mapEditor = useMapEditorComposable()
const searchQuery = ref('') const searchQuery = ref('')
@ -96,11 +100,11 @@ const selectedTags = ref<string[]>([])
const tileCategories = ref<Map<string, string>>(new Map()) const tileCategories = ref<Map<string, string>>(new Map())
const selectedGroup = ref<{ parent: Tile; children: Tile[] } | null>(null) const selectedGroup = ref<{ parent: Tile; children: Tile[] } | null>(null)
const tiles = ref<Tile[]>([]) const tiles = ref<Tile[]>([])
const modalRef = useTemplateRef('modalRef')
defineExpose({ defineExpose({
open: () => modalRef.value?.open(), open: () => (isOpen.value = true),
close: () => modalRef.value?.close() close: () => (isOpen.value = false),
toggle: () => (isOpen.value = !isOpen.value)
}) })
const uniqueTags = computed(() => { const uniqueTags = computed(() => {

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="flex justify-center p-5"> <div class="flex justify-center p-5">
<div class="toolbar fixed bottom-0 left-0 m-3 rounded flex bg-gray solid border-solid border-2 border-gray-500 text-gray-300 p-1.5 px-3 h-10"> <div class="toolbar fixed bottom-0 left-0 m-3 rounded flex bg-gray solid border-solid border-2 border-gray-500 text-gray-300 p-1.5 px-3 h-10 z-20">
<div ref="toolbar" class="tools flex gap-2.5" v-if="mapEditor.currentMap.value"> <div ref="toolbar" class="tools flex gap-2.5" v-if="mapEditor.currentMap.value">
<button class="flex justify-center items-center min-w-10 p-0 relative" :class="{ 'border-0 border-b-[3px] border-solid border-cyan gap-2.5': mapEditor.tool.value === 'move' }" @click="handleClick('move')"> <button class="flex justify-center items-center min-w-10 p-0 relative" :class="{ 'border-0 border-b-[3px] border-solid border-cyan gap-2.5': mapEditor.tool.value === 'move' }" @click="handleClick('move')">
<img class="invert w-5 h-5" src="/assets/icons/mapEditor/move.svg" alt="Move camera" /> <span class="h-5" :class="{ 'ml-2.5': mapEditor.tool.value !== 'move' }">(M)</span> <img class="invert w-5 h-5" src="/assets/icons/mapEditor/move.svg" alt="Move camera" /> <span class="h-5" :class="{ 'ml-2.5': mapEditor.tool.value !== 'move' }">(M)</span>

View File

@ -12,14 +12,14 @@
@open-maps="mapModal?.open" @open-maps="mapModal?.open"
@open-settings="mapSettingsModal?.open" @open-settings="mapSettingsModal?.open"
@close-editor="mapEditor.toggleActive" @close-editor="mapEditor.toggleActive"
@close-lists="tileModal?.close" @close-lists="tileList?.close"
@closeLists="objectModal?.close" @closeLists="objectList?.close"
@open-tile-list="tileModal?.open" @open-tile-list="tileList?.open"
@open-map-object-list="objectModal?.open" @open-map-object-list="objectList?.open"
/> />
<MapList ref="mapModal" @open-create-map="mapSettingsModal?.open" /> <MapList ref="mapModal" @open-create-map="mapSettingsModal?.open" />
<TileList ref="tileModal" /> <TileList ref="tileList" />
<ObjectList ref="objectModal" /> <ObjectList ref="objectList"/>
<MapSettings ref="mapSettingsModal" /> <MapSettings ref="mapSettingsModal" />
<TeleportModal ref="teleportModal" /> <TeleportModal ref="teleportModal" />
</div> </div>
@ -52,8 +52,8 @@ const gameStore = useGameStore()
const toolbar = useTemplateRef('toolbar') const toolbar = useTemplateRef('toolbar')
const mapModal = useTemplateRef('mapModal') const mapModal = useTemplateRef('mapModal')
const tileModal = useTemplateRef('tileModal') const tileList = useTemplateRef('tileList')
const objectModal = useTemplateRef('objectModal') const objectList = useTemplateRef('objectList')
const mapSettingsModal = useTemplateRef('mapSettingsModal') const mapSettingsModal = useTemplateRef('mapSettingsModal')
const teleportModal = useTemplateRef('teleportModal') const teleportModal = useTemplateRef('teleportModal')