feat: load session and display start button if not exists

This commit is contained in:
wancat committed 2024-06-27 11:55:34 +08:00
1 parent c64043316e
commit 3398d18055
7 files changed
+51 -56

No files matched your search

+16 -8
View File
@@ -1,14 +1,14 @@
<script setup lang="ts">
import { ref, watch } from 'vue'
import { computed, ref, watch } from 'vue'
import useSession from '../../store/session'
import MarkdownText from '../MarkdownText.vue'
const sessionStore = useSession()
const current = ref(-1)
watch(
() => sessionStore.session.hints,
() => sessionStore.session?.hints,
(hints) => {
current.value = hints.length - 1
current.value = hints ? hints.length - 1 : -1
},
{ deep: true }
)
@@ -20,10 +20,18 @@ const left = () => {
}
const right = () => {
if (current.value < sessionStore.session.hints.length - 1) {
if (current.value < (sessionStore.session?.hints.length ?? 0) - 1) {
current.value += 1
}
}
const length = computed(() => {
return sessionStore.session?.hints.length ?? 0
})
const disabled = computed(() => {
return current.value === length.value - 1
})
</script>
<template>
@@ -50,13 +58,13 @@ const right = () => {
<p class="inline text-text font-xl w-1/14 p-2 m-1">{{ current + 1 }}</p>
<p class="inline text-text font-xl w-1/14 p-2 m-1">/</p>
<p class="inline text-text font-xl w-1/14 p-2 m-1">
{{ sessionStore.session.hints.length }}
{{ length }}
</p>
<button
class="p-2 m-1 w-1/8"
id="Rbutton"
@click="right"
:disabled="current === sessionStore.session.hints.length - 1"
:disabled="disabled"
>
<font-awesome-icon :icon="['fas', 'arrow-right']" class="text-text" />
</button>
@@ -65,7 +73,7 @@ const right = () => {
<div id="hint" class="bg-bg p-8 overflow-y-auto">
<ul>
<li
v-for="response in sessionStore.session.responses[current]"
v-for="response in sessionStore.session?.responses[current]"
:key="response.type"
class="text-text font-xl whitespace-pre-wrap"
>
@@ -74,7 +82,7 @@ const right = () => {
</div>
</li>
<li
v-for="hint in sessionStore.session.hints[current]"
v-for="hint in sessionStore.session?.hints[current]"
:key="hint"
class="text-text-primary font-xl whitespace-pre-wrap"
>
+1 -1
View File
@@ -6,7 +6,7 @@ import { Task } from '../../types'
const sessionStore = useSession()
const tasks = computed(() => {
return sessionStore.session.tasks.map((task: Task) => {
return sessionStore.session?.tasks.map((task: Task) => {
const prefix = task.completed ? '✓' : '➤'
const color = task.completed ? 'text-text-primary' : 'text-text'
return {
+2 -17
View File
@@ -1,31 +1,16 @@
<script setup lang="ts">
import { useToast } from 'vue-toastification'
import { onMounted, ref } from 'vue'
import { computed } from 'vue'
import useSession from '../../store/session'
const props = defineProps({
questId: {
type: String,
required: true,
},
})
const toast = useToast()
const showCover = ref(true)
const sessionStore = useSession()
onMounted(async () => {
sessionStore.setQuest(props.questId)
if (await sessionStore.getActiveSession()) {
showCover.value = false
}
sessionStore.setup()
})
const showCover = computed(() => sessionStore.session === null)
const startSession = async () => {
try {
await sessionStore.createSession()
showCover.value = false
} catch (err: any) {
console.error(err)
toast.error(err.message)
+1
View File
@@ -10,6 +10,7 @@ const sessionStore = useSession()
<ul>
<li>
<FileNode
v-if="sessionStore.session"
:node="sessionStore.session.graph"
:pwd="sessionStore.session.pwd"
/>
+12 -25
View File
@@ -1,7 +1,7 @@
import { defineStore } from 'pinia'
import { FileGraph, FileObject } from '@linux-odyssey/file-graph'
import { IQuest } from '@linux-odyssey/models'
import { createSession, getQuest, getSessions } from '../utils/api'
import { createSession, getActiveSession, getQuest } from '../utils/api'
import Socket from '../utils/socket'
import SocketTerminal from '../utils/terminal'
import { Session, StageResponse } from '../types'
@@ -10,26 +10,14 @@ const socket = new Socket()
const term = new SocketTerminal(40, 80)
interface Store {
session: Session
session: Session | null
questId: string
quest: IQuest | null
}
const useSession = defineStore('session', {
state: (): Store => ({
session: {
_id: '',
status: 'inactive',
graph: new FileGraph({
path: '/',
type: 'folder',
discovered: false,
}),
pwd: '',
hints: [],
tasks: [],
responses: [],
},
session: null,
questId: '',
quest: null,
}),
@@ -50,19 +38,13 @@ const useSession = defineStore('session', {
this.setSession(session)
},
async getActiveSession() {
const sessions = await getSessions({
questId: this.questId,
limit: 1,
order: 'desc',
status: 'active',
})
if (sessions.length > 0) {
this.setSession(sessions[0])
return true
const session = await getActiveSession(this.questId)
if (session) {
this.setSession(session)
}
return false
},
updateGraph(event: { discover?: FileObject[]; pwd?: string }) {
if (!this.session) return
if (event.discover) {
this.session.graph.discover(event.discover)
}
@@ -71,6 +53,7 @@ const useSession = defineStore('session', {
}
},
newResponse(response: StageResponse) {
if (!this.session) return
this.session.responses.push(response.responses)
this.session.hints.push(response.hints)
this.session.tasks = response.tasks
@@ -95,6 +78,10 @@ const useSession = defineStore('session', {
this.newResponse(response)
})
},
setStatus(status: string) {
if (!this.session) return
this.session.status = status
},
},
})
+9
View File
@@ -34,3 +34,12 @@ export async function getSessions(
const res = await api.get<Session[]>('/sessions', { params: request })
return res.data
}
export async function getActiveSession(
questId: string
): Promise<Session | null> {
const res = await api.get<Session | null>('/sessions/active', {
params: { questId },
})
return res.data
}
+10 -5
View File
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { computed } from 'vue'
import { computed, onMounted } from 'vue'
// import { onMounted } from 'vue'
// import { useToast } from 'vue-toastification'
import useSession from '../store/session'
@@ -18,16 +18,21 @@ import StartButton from '../components/game/StartButton.vue'
const sessionStore = useSession()
const completed = computed(() => {
return sessionStore.session.status === 'finished'
return sessionStore.session?.status === 'finished'
})
defineProps({
const props = defineProps({
questId: {
type: String,
required: true,
},
})
// const toast = useToast()
onMounted(async () => {
sessionStore.setup()
await sessionStore.setQuest(props.questId)
await sessionStore.getActiveSession()
})
</script>
<template>
@@ -42,7 +47,7 @@ defineProps({
<input
type="hidden"
id="currentStatus"
:value="sessionStore.session.status"
:value="sessionStore.session?.status"
/>
<!-- main -->
<div id="main" class="h-full pt-10 w-full flex p-3 space-x-3">