feat: rewrite map state handling

This commit is contained in:
wancat committed 2024-07-31 17:54:59 +08:00
1 parent 8f6914d46c
commit 1572b2ea06
2 files changed
+69 -37

No files matched your search

+68 -36
View File
@@ -1,5 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, computed } from 'vue' import { ref, onMounted, watch } from 'vue'
import { IQuest } from '@linux-odyssey/models'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { useToast } from 'vue-toastification' import { useToast } from 'vue-toastification'
import { DAG } from '@linux-odyssey/utils' import { DAG } from '@linux-odyssey/utils'
@@ -10,50 +11,79 @@ const store = useUserProfile()
const router = useRouter() const router = useRouter()
const toast = useToast() const toast = useToast()
const quests = ref([])
const svgWidth = ref(window.innerWidth) const svgWidth = ref(window.innerWidth)
const svgHeight = ref(window.innerHeight) const svgHeight = ref(window.innerHeight)
const marginX = 60 const marginX = 80
const marginY = 50 const marginY = 80
const nodeWidth = 150
const nodeHeight = 50
async function getQuests() { async function getQuests() {
try { try {
const res = await api.get('/quests') const res = await api.get<IQuest[]>('/quests')
quests.value = res.data return res.data
} catch (err) { } catch (err) {
console.error(err) console.error(err)
throw err throw err
} }
} }
const graphData = computed(() => { type Node = {
const dag = new DAG(quests.value) id: string
title: string
x: number
y: number
completed: boolean
unlocked: boolean
}
console.log(store.progress) type Edge = {
const nodes = dag.getNodes().map((node) => ({ source: Node
id: node._id, target: Node
title: node.title, }
x: marginX * node.layer * 2,
// y: marginX * node.index - (marginX * dag.getLayer(node._id)) / 2,
y: marginY * node.index + svgHeight.value / 2,
completed: store.progress[node._id]?.completed || false,
unlocked: node.requirements.every(
(req: string) => store.progress[req]?.completed
),
}))
console.log(nodes) const graphData = ref<{ nodes: Node[]; edges: Edge[] }>({
nodes: [],
const edges = dag.getEdgesArray().map((edge: any) => ({ edges: [],
source: nodes.find((n) => n.id === edge[0]),
target: nodes.find((n) => n.id === edge[1]),
}))
return { nodes, edges }
}) })
function handleNodeClick(node: any) { async function computeGraphData() {
if (!store.progress) return
try {
const quests = await getQuests()
const dag = new DAG(quests)
const nodesValues = dag.getNodes()
const nodes = nodesValues.map((node) => ({
id: node._id,
title: node.title,
x: marginX * node.layer * 2,
y:
marginY * node.index -
(marginX * dag.getLayer(node._id)) / 2 +
svgHeight.value / 2,
completed: store.progress[node._id]?.completed || false,
unlocked: node.requirements.every(
(req: string) => store.progress[req]?.completed
),
}))
// const edges = dag.getEdgesArray().map((edge) => ({
// source: nodes.find((n) => n.id === edge[0]),
// target: nodes.find((n) => n.id === edge[1]),
// }))
graphData.value = { nodes, edges: [] }
} catch (error) {
console.error('Error computing graph data:', error)
toast.error('Failed to load quest data')
}
}
function handleNodeClick(node: { id: string; unlocked: boolean }) {
if (node.unlocked) { if (node.unlocked) {
router.push({ name: 'game', params: { questId: node.id } }) router.push({ name: 'game', params: { questId: node.id } })
} else { } else {
@@ -63,8 +93,10 @@ function handleNodeClick(node: any) {
onMounted(async () => { onMounted(async () => {
await store.loadUserProfile() await store.loadUserProfile()
await getQuests() await computeGraphData()
}) })
watch(() => store.progress, computeGraphData, { deep: true })
</script> </script>
<template> <template>
@@ -101,14 +133,14 @@ onMounted(async () => {
@click="handleNodeClick(node)" @click="handleNodeClick(node)"
> >
<rect <rect
:x="node.x - 50" :x="node.x - nodeWidth / 2"
:y="node.y - 25" :y="node.y - nodeHeight / 2"
width="100" :width="nodeWidth"
height="50" :height="nodeHeight"
rx="10" rx="10"
ry="10" ry="10"
:fill=" :fill="
node.completed ? '#00ff00' : node.unlocked ? '#ADADB5' : '#505050' node.completed ? '#00bb00' : node.unlocked ? '#ADADB5' : '#505050'
" "
/> />
<text <text
@@ -117,7 +149,7 @@ onMounted(async () => {
text-anchor="middle" text-anchor="middle"
alignment-baseline="middle" alignment-baseline="middle"
fill="white" fill="white"
font-size="12" font-size="16"
> >
{{ node.title }} {{ node.title }}
</text> </text>
+1 -1
View File
@@ -42,7 +42,7 @@ export default class DAG {
if (!node) { if (!node) {
throw new Error(`Node ${id} not found`) throw new Error(`Node ${id} not found`)
} }
return this.layers[node.layer - 1] return this.layers[node.layer - 1] || 0
} }
private setLayer(id: string) { private setLayer(id: string) {