diff --git a/app/src/components/ControlPalette.vue b/app/src/components/ControlPalette.vue index 470a29a..6d80f56 100644 --- a/app/src/components/ControlPalette.vue +++ b/app/src/components/ControlPalette.vue @@ -25,10 +25,10 @@ diff --git a/app/src/components/GameHeaderPart.vue b/app/src/components/GameHeaderPart.vue index 093047f..7fb256b 100644 --- a/app/src/components/GameHeaderPart.vue +++ b/app/src/components/GameHeaderPart.vue @@ -4,12 +4,18 @@ import { useRouter } from 'vue-router' import { logout } from '../utils/auth' import { bugReportUrl } from '../config' import api from '../utils/api' +import { reset } from '../store/session' const router = useRouter() const handleLogout = async () => { - await logout() - router.push({ name: 'login' }) + try { + await logout() + reset() + router.push({ name: 'login' }) + } catch (err) { + console.error(err) + } } const questData = ref(null) diff --git a/app/src/components/HintPart.vue b/app/src/components/HintPart.vue index 3656d00..dad0189 100644 --- a/app/src/components/HintPart.vue +++ b/app/src/components/HintPart.vue @@ -1,11 +1,15 @@ - - Failed to get quest infomation - - - {{ questData.title }} + + {{ sessionStore.quest.title }} - - {{ questData.instruction }} + + {{ sessionStore.quest.instruction }} Tasks: - - + + ✓ {{ task.name }} @@ -43,7 +26,6 @@ onMounted(async () => { - {{ questErr.message }} Loading... diff --git a/app/src/components/TerminalPart.vue b/app/src/components/TerminalPart.vue index d77b891..dadedc6 100644 --- a/app/src/components/TerminalPart.vue +++ b/app/src/components/TerminalPart.vue @@ -10,12 +10,13 @@ diff --git a/app/src/components/TreeChart.vue b/app/src/components/TreeChart.vue index dad6ac6..d71134e 100644 --- a/app/src/components/TreeChart.vue +++ b/app/src/components/TreeChart.vue @@ -1,6 +1,6 @@ @@ -8,8 +8,8 @@ import sessionManager from '../utils/session.js' diff --git a/app/src/store/session.js b/app/src/store/session.js new file mode 100644 index 0000000..eae3b08 --- /dev/null +++ b/app/src/store/session.js @@ -0,0 +1,127 @@ +import { reactive } from 'vue' +import { FileGraph } from '@linux-odyssey/file-graph' +import api from '../utils/api' +import Socket from '../utils/socket' +import SocketTerminal from '../utils/terminal' + +function newSession() { + const graph = new FileGraph({ + path: '/', + type: 'folder', + discovered: false, + }) + return { + status: 'inactive', + graph, + pwd: '', + hints: [], + tasks: [], + } +} + +const store = reactive({ + session: newSession(), + questId: '', + quest: null, +}) + +const socket = new Socket() +const term = new SocketTerminal(40, 80) + +function setQuest(questId) { + api.get(`/quests/${questId}`).then((res) => { + store.questId = res.data._id + store.quest = res.data + }) +} + +async function setSession(session) { + store.session = session + store.session.graph = new FileGraph(session.graph) + term.reset() + await socket.connect(session) + term.focus() +} + +export async function createSession() { + console.log('Creating a new session...') + const res = await api.post('/sessions', { quest_id: store.questId }) + const { data } = res + await setSession(data) +} + +async function getActiveSession(questId) { + const res = await api.post('/sessions/active', { + quest_id: questId, + }) + const session = res.data + try { + await setSession(session) + } catch (err) { + console.log(err) + await createSession().catch(console.error) + } +} + +function updateGraph(event) { + if (event.discover) { + store.session.graph.discover(event.discover) + } + if (event.pwd) { + store.session.pwd = event.pwd + } +} + +function updateHints(hints) { + store.session.hints.push(...hints) +} + +function updateStatus(status) { + store.session.status = status +} + +function setTasks(tasks) { + store.session.tasks = tasks +} + +export function useTerminal() { + return term +} + +export function reset() { + socket.reset() + term.reset() + store.session = newSession() + store.quest = null +} + +export async function init(questId) { + reset() + await setQuest(questId) + await getActiveSession(questId) +} + +function setup() { + socket.on('terminal', (data) => { + term.write(data) + }) + term.onData((data) => { + socket.emit('terminal', data) + }) + socket.on('graph', (event) => { + updateGraph(event) + }) + socket.on('hints', (event) => { + updateHints(event) + }) + socket.on('tasks', (tasks) => { + setTasks(tasks) + }) + socket.on('status', (event) => { + updateStatus(event) + }) +} + +setup() + +export default store diff --git a/app/src/utils/session.js b/app/src/utils/session.js deleted file mode 100644 index bbf0f3b..0000000 --- a/app/src/utils/session.js +++ /dev/null @@ -1,107 +0,0 @@ -import { ref } from 'vue' -import { FileGraph } from '@linux-odyssey/file-graph' -import api from './api' -import Socket from './socket' -import SocketTerminal from './terminal' - -class SessionManager { - constructor(questId) { - this.questId = questId - this.session = ref(null) - this.hints = ref([]) - this.graph = ref( - new FileGraph({ - path: '/', - type: 'folder', - discovered: false, - }) - ) - this.pwd = ref('') - this.status = ref('inactive') - this.socket = new Socket() - this.term = new SocketTerminal(40, 80) - } - - init() { - this.socket.on('terminal', (data) => { - this.term.write(data) - }) - this.term.onData((data) => { - this.socket.emit('terminal', data) - }) - this.socket.on('graph', (event) => { - this.handleGraphUpdate(event) - }) - this.socket.on('hints', (event) => { - this.handleHintUpdate(event) - }) - this.socket.on('tasks', (tasks) => { - this.setTasks(tasks) - }) - this.socket.on('status', (event) => { - this.handleStatusUpdate(event) - }) - return this.getActiveSession() - } - - getSession() { - return this.session.value - } - - async setSession(session) { - this.session.value = session - this.graph.value = new FileGraph(session.graph) - this.hints.value = session.hints - this.status.value = session.status - this.term.reset() - await this.socket.connect(session) - this.term.focus() - } - - handleGraphUpdate(event) { - if (event.discover) { - this.graph.value.discover(event.discover) - } - if (event.pwd) { - this.pwd.value = event.pwd - } - } - - handleHintUpdate(hints) { - this.hints.value = [...this.hints.value, ...hints] - } - - handleStatusUpdate(status) { - this.status.value = status - } - - setTasks(tasks) { - this.session.value.tasks = tasks - } - - async createSession() { - console.log('Creating a new session...') - const res = await api.post('/sessions', { quest_id: this.questId }) - const { data } = res - console.log('Created Session ID:', data._id) - this.setSession(data) - } - - async getActiveSession() { - const res = await api.post('/sessions/active', { - quest_id: this.questId, - }) - const session = res.data - console.log(session) - try { - await this.setSession(session) - } catch (err) { - console.log(err) - this.createSession().catch(console.error) - } - } -} - -const sessionManager = new SessionManager('helloworld') - -export default sessionManager diff --git a/app/src/utils/socket.js b/app/src/utils/socket.js index 54fbb49..f242485 100644 --- a/app/src/utils/socket.js +++ b/app/src/utils/socket.js @@ -8,10 +8,7 @@ class SocketWrapper { connect(session) { return new Promise((resolve, reject) => { - if (this.socket) { - this.socket.off() - this.socket.disconnect() - } + this.disconnect() this.socket = io('', { query: { @@ -38,25 +35,26 @@ class SocketWrapper { } } - once(event, callback) { - if (this.socket) { - this.socket.once(event, callback) - } - } - bindListeners() { this.listeners.forEach(({ event, callback }) => { this.socket.on(event, callback) }) } - send(data) { - this.socket.send(data) - } - emit(event, data) { this.socket.emit(event, data) } + + disconnect() { + if (this.socket) { + this.socket.off() + this.socket.disconnect() + } + } + + reset() { + this.disconnect() + } } export default SocketWrapper diff --git a/app/src/views/GamePage.vue b/app/src/views/GamePage.vue index 9ffbee7..082d692 100644 --- a/app/src/views/GamePage.vue +++ b/app/src/views/GamePage.vue @@ -1,6 +1,6 @@ @@ -28,7 +28,7 @@ onMounted(async () => {
{{ questData.instruction }}
{{ sessionStore.quest.instruction }}
Tasks:
✓ {{ task.name }} @@ -43,7 +26,6 @@ onMounted(async () => {
{{ questErr.message }}
Loading...