mirror of
https://github.com/linux-odyssey/linux-odyssey.git
synced 2026-11-06 03:20:13 +08:00
feat(i18n): add localized content for game page
This commit is contained in:
1 parent
87df12ac85
commit
03fbae616d
9 files changed
+90
-20
No files matched your search
@@ -1,7 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<font-awesome-icon :icon="['fas', 'list']" class="text-text-primary p-1" />
|
||||
<h1 id="CommandBook" class="inline text-text-primary font-xl">指令之書</h1>
|
||||
<h1 id="CommandBook" class="inline text-text-primary font-xl">
|
||||
{{ t('game.command_book') }}
|
||||
</h1>
|
||||
<div id="cheatsheets">
|
||||
<p class="text-text-secondary">-- --指令列表-- --</p>
|
||||
<p class="text-text-secondary">-- --{{ t('game.cheatsheets') }}-- --</p>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,4 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useToast } from 'vue-toastification'
|
||||
import { ref } from 'vue'
|
||||
@@ -6,6 +7,8 @@ import { Vue3Lottie } from 'vue3-lottie'
|
||||
// import { surveyUrl } from '../config'
|
||||
import CompleteAnimation from '../../img/complete-animation.json'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const showModal = ref(true) // Controls whether the modal is visible or not
|
||||
const router = useRouter()
|
||||
const toast = useToast()
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useToast } from 'vue-toastification'
|
||||
import { useSession } from '../../store/session'
|
||||
import { openBugReport, openQuestSurvey } from '../../utils/formbricks'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const router = useRouter()
|
||||
const sessionStore = useSession()
|
||||
const reset = async () => {
|
||||
@@ -14,16 +17,17 @@ const continuePlay = async () => {
|
||||
try {
|
||||
router.push({ name: 'map' })
|
||||
} catch (err) {
|
||||
useToast().error('無法讀取地圖')
|
||||
useToast().error(t('quest_map.load_quest_map_failed'))
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="mt-2 flex flex-row gap-3 justify-center">
|
||||
<section class="mt-2 flex flex-row gap-2 justify-center">
|
||||
<button
|
||||
id="survey"
|
||||
:title="t('game_nav.survey')"
|
||||
class="bg-bg-secondary rounded-lg p-2"
|
||||
@click="openQuestSurvey"
|
||||
>
|
||||
@@ -31,15 +35,18 @@ const continuePlay = async () => {
|
||||
:icon="['fas', 'file-invoice']"
|
||||
class="text-text-primary px-1"
|
||||
/>
|
||||
<p class="text-text-primary inline md:flex">問卷</p>
|
||||
<p class="text-text-primary text-xs">{{ t('game_nav.survey') }}</p>
|
||||
</button>
|
||||
<button
|
||||
title="Bug Report"
|
||||
id="bug-report"
|
||||
:title="t('game_nav.bug_report')"
|
||||
@click="openBugReport"
|
||||
class="bg-bg-secondary rounded-lg p-2"
|
||||
>
|
||||
<font-awesome-icon :icon="['fas', 'bug']" class="text-text-primary" />
|
||||
<p class="text-text-primary inline ml-1 md:flex">回報</p>
|
||||
<p class="text-text-primary text-xs">
|
||||
{{ t('game_nav.bug_report') }}
|
||||
</p>
|
||||
</button>
|
||||
<!-- <button disabled id="solution" class="bg-bg-disabled rounded-lg p-2">
|
||||
<font-awesome-icon
|
||||
@@ -48,15 +55,23 @@ const continuePlay = async () => {
|
||||
/>
|
||||
<p class="text-text-disabled inline ml-1 md:flex">解答</p>
|
||||
</button> -->
|
||||
<button id="reset" class="bg-bg-secondary rounded-lg p-2" @click="reset">
|
||||
<button
|
||||
id="reset"
|
||||
:title="t('game.reset')"
|
||||
class="bg-bg-secondary rounded-lg p-2"
|
||||
@click="reset"
|
||||
>
|
||||
<font-awesome-icon
|
||||
:icon="['fas', 'arrow-rotate-left']"
|
||||
class="text-text-primary px-1"
|
||||
/>
|
||||
<p class="text-text-primary inline ml-1 md:flex">重來</p>
|
||||
<p class="text-text-primary text-xs">
|
||||
{{ t('game.reset') }}
|
||||
</p>
|
||||
</button>
|
||||
<button
|
||||
id="continue"
|
||||
:title="t('game.continue')"
|
||||
class="bg-bg-secondary rounded-lg p-2"
|
||||
@click="continuePlay"
|
||||
>
|
||||
@@ -64,7 +79,9 @@ const continuePlay = async () => {
|
||||
:icon="['far', 'circle-right']"
|
||||
class="text-text-primary px-1"
|
||||
/>
|
||||
<p class="text-text-primary inline ml-1 md:flex">繼續</p>
|
||||
<p class="text-text-primary text-xs">
|
||||
{{ t('game.continue') }}
|
||||
</p>
|
||||
</button>
|
||||
</section>
|
||||
</template>
|
||||
@@ -1,8 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { useSession } from '../../store/session'
|
||||
import MarkdownText from '../MarkdownText.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const sessionStore = useSession()
|
||||
const current = ref(-1)
|
||||
const hintDetails = ref<HTMLDetailsElement | null>(null)
|
||||
@@ -52,7 +55,9 @@ watch(response, () => {
|
||||
:icon="['far', 'lightbulb']"
|
||||
class="text-yellow-200 p-2 content-center"
|
||||
/>
|
||||
<h1 class="inline text-text w-1/2 font-xl p-2 m-1">說明</h1>
|
||||
<h1 class="inline text-text w-1/2 font-xl p-2 m-1">
|
||||
{{ t('game.description') }}
|
||||
</h1>
|
||||
<div v-if="current !== -1" class="flex w-full justify-end items-end">
|
||||
<button
|
||||
class="p-2 m-1 w-1/8"
|
||||
@@ -98,7 +103,7 @@ watch(response, () => {
|
||||
class="text-text-primary font-xl whitespace-pre-wrap"
|
||||
>
|
||||
<details ref="hintDetails">
|
||||
<summary class="cursor-pointer">提示</summary>
|
||||
<summary class="cursor-pointer">{{ t('game.hint') }}</summary>
|
||||
<MarkdownText :content="response.hint" />
|
||||
</details>
|
||||
</li>
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { computed } from 'vue'
|
||||
import MarkdownText from '../MarkdownText.vue'
|
||||
import { useSession } from '../../store/session'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const sessionStore = useSession()
|
||||
const tasks = computed(() => {
|
||||
console.log('session', sessionStore.session)
|
||||
@@ -31,14 +34,14 @@ const tasks = computed(() => {
|
||||
:content="sessionStore.quest.instruction"
|
||||
/>
|
||||
<br />
|
||||
<p id="tasks" class="text-text">任務:</p>
|
||||
<p id="tasks" class="text-text font-bold">{{ t('game.task') }}</p>
|
||||
<ul v-if="sessionStore.session">
|
||||
<li v-for="task in tasks" :key="task.id">
|
||||
<MarkdownText :class="task.class" :content="task.content" />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<p class="text-text" v-else>Loading...</p>
|
||||
<p class="text-text" v-else>{{ t('game.loading') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,8 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useToast } from 'vue-toastification'
|
||||
import { computed } from 'vue'
|
||||
import { useSession } from '../../store/session'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const toast = useToast()
|
||||
const sessionStore = useSession()
|
||||
|
||||
@@ -31,7 +34,7 @@ const startSession = async () => {
|
||||
:icon="['fas', 'play']"
|
||||
class="text-text-primary h-full px-3"
|
||||
/>
|
||||
<p class="text-text-primary inline ml-1 md:flex">開始</p>
|
||||
<p class="text-text-primary inline ml-1 md:flex">{{ t('game.start') }}</p>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,7 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { onMounted, onUnmounted, ref } from 'vue'
|
||||
import { useSession, useTerminal } from '../../store/session'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const sessionStore = useSession()
|
||||
|
||||
const terminal = ref<HTMLElement | null>(null)
|
||||
@@ -24,14 +27,14 @@ onMounted(() => {
|
||||
<div class="flex flex-col h-full">
|
||||
<div class="flex items-center gap-2 p-1">
|
||||
<font-awesome-icon :icon="['fas', 'terminal']" class="text-text" />
|
||||
<button id="Terminal" class="text-text">終端機</button>
|
||||
<p id="Terminal" class="text-text">{{ t('game.terminal') }}</p>
|
||||
|
||||
<a
|
||||
class="text-sm font-normal text-gray-200 ml-10"
|
||||
class="text-xs font-normal text-gray-200 ml-10 bg-bg-primary rounded-lg px-2 py-1 hover:bg-bg-primary-hover transition-colors duration-300"
|
||||
:href="`/terminal/${sessionStore.session?.containerName}?token=${sessionStore.session?.token}`"
|
||||
target="_blank"
|
||||
>
|
||||
Open Terminal in New Tab
|
||||
{{ t('game.open_terminal_in_new_tab') }}
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
|
||||
@@ -77,7 +77,8 @@
|
||||
},
|
||||
"quest_map": {
|
||||
"title": "Quest Map",
|
||||
"intro": "Embark on your Linux adventure!"
|
||||
"intro": "Embark on your Linux adventure!",
|
||||
"load_quest_map_failed": "Failed to Load Quest Map"
|
||||
},
|
||||
"quest": {
|
||||
"start": "Start Adventure",
|
||||
@@ -89,5 +90,18 @@
|
||||
"score": "Score",
|
||||
"completed_quests": "Completed Quests",
|
||||
"load_leaderboard_failed": "Failed to Load Leaderboard"
|
||||
},
|
||||
"game": {
|
||||
"start": "Start",
|
||||
"task": "Task:",
|
||||
"loading": "Loading...",
|
||||
"description": "Description",
|
||||
"hint": "Hint",
|
||||
"terminal": "Terminal",
|
||||
"open_terminal_in_new_tab": "Open Terminal in New Tab",
|
||||
"reset": "Reset",
|
||||
"continue": "Continue",
|
||||
"command_book": "Command Book",
|
||||
"cheatsheets": "Cheat Sheets"
|
||||
}
|
||||
}
|
||||
@@ -77,7 +77,8 @@
|
||||
},
|
||||
"quest_map": {
|
||||
"title": "關卡地圖",
|
||||
"intro": "踏上你的Linux冒險之旅吧!"
|
||||
"intro": "踏上你的Linux冒險之旅吧!",
|
||||
"load_quest_map_failed": "無法讀取關卡地圖"
|
||||
},
|
||||
"quest": {
|
||||
"start": "開始冒險",
|
||||
@@ -89,5 +90,18 @@
|
||||
"score": "分數",
|
||||
"completed_quests": "完成關卡",
|
||||
"load_leaderboard_failed": "無法讀取排行榜"
|
||||
},
|
||||
"game": {
|
||||
"start": "開始",
|
||||
"task": "任務:",
|
||||
"loading": "載入中...",
|
||||
"description": "說明",
|
||||
"hint": "提示",
|
||||
"terminal": "終端機",
|
||||
"open_terminal_in_new_tab": "在新分頁開啟終端機",
|
||||
"reset": "重置",
|
||||
"continue": "繼續",
|
||||
"command_book": "指令之書",
|
||||
"cheatsheets": "指令列表"
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user