mirror of
https://github.com/linux-odyssey/linux-odyssey.git
synced 2026-11-05 19:20:12 +08:00
translation and little format fixture
This commit is contained in:
1 parent
f6c3b33da9
commit
9da23b5dc1
14 files changed
+155
-54
No files matched your search
@@ -108,7 +108,10 @@ const handleChange = () => {
|
|||||||
:icon="['fab', 'google']"
|
:icon="['fab', 'google']"
|
||||||
class="text-text-secondary px-3 text-lg"
|
class="text-text-secondary px-3 text-lg"
|
||||||
/>
|
/>
|
||||||
<span class="font-medium">Continue with Google</span>
|
<span class="font-medium">
|
||||||
|
<!-- Continue with Google -->
|
||||||
|
以Google繼續
|
||||||
|
</span>
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
v-if="availableMethods.github"
|
v-if="availableMethods.github"
|
||||||
@@ -119,17 +122,21 @@ const handleChange = () => {
|
|||||||
:icon="['fab', 'github']"
|
:icon="['fab', 'github']"
|
||||||
class="text-text-secondary px-3 text-lg"
|
class="text-text-secondary px-3 text-lg"
|
||||||
/>
|
/>
|
||||||
<span class="font-medium">Continue with GitHub</span>
|
<span class="font-medium">
|
||||||
|
<!-- Continue with GitHub -->
|
||||||
|
以Github繼續
|
||||||
|
</span>
|
||||||
</a>
|
</a>
|
||||||
<p
|
<p
|
||||||
class="text-text-secondary flex justify-center mt-3"
|
class="text-text-secondary flex justify-center mt-3"
|
||||||
v-if="type === 'login' || type === 'register'"
|
v-if="type === 'login' || type === 'register'"
|
||||||
>
|
>
|
||||||
or
|
<!-- or -->
|
||||||
|
或
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-6">
|
<div class="mb-6">
|
||||||
<input
|
<!-- <input
|
||||||
type="text"
|
type="text"
|
||||||
id="username"
|
id="username"
|
||||||
ref="usernameInput"
|
ref="usernameInput"
|
||||||
@@ -139,6 +146,17 @@ const handleChange = () => {
|
|||||||
required
|
required
|
||||||
@input="handleChange()"
|
@input="handleChange()"
|
||||||
autocomplete="username"
|
autocomplete="username"
|
||||||
|
/> -->
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="username"
|
||||||
|
ref="usernameInput"
|
||||||
|
class="my-4 bg-bg-primary text-text-primary bg- rounded-md block w-full px-3 h-10 shadow-sm focus:outline-none placeholder:text-text-line focus:ring-2 focus:ring-text-primary ring-1 ring-bg-secondary"
|
||||||
|
:placeholder="type === 'login' ? '電子郵件 / 帳號名稱' : '帳號名稱'"
|
||||||
|
v-model="username"
|
||||||
|
required
|
||||||
|
@input="handleChange()"
|
||||||
|
autocomplete="username"
|
||||||
/>
|
/>
|
||||||
<label
|
<label
|
||||||
class="text-sm font-normal text-text-secondary"
|
class="text-sm font-normal text-text-secondary"
|
||||||
@@ -149,7 +167,7 @@ const handleChange = () => {
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-6" v-if="type === 'register'">
|
<div class="mb-6" v-if="type === 'register'">
|
||||||
<input
|
<!-- <input
|
||||||
type="email"
|
type="email"
|
||||||
id="email"
|
id="email"
|
||||||
ref="emailInput"
|
ref="emailInput"
|
||||||
@@ -159,10 +177,21 @@ const handleChange = () => {
|
|||||||
required
|
required
|
||||||
@input="handleChange()"
|
@input="handleChange()"
|
||||||
autocomplete="email"
|
autocomplete="email"
|
||||||
|
/> -->
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
id="email"
|
||||||
|
ref="emailInput"
|
||||||
|
class="my-4 bg-bg-primary text-text-primary bg- rounded-md block w-full px-3 h-10 shadow-sm focus:outline-none placeholder:text-text-line focus:ring-2 focus:ring-text-primary ring-1 ring-bg-secondary"
|
||||||
|
placeholder="電子郵件"
|
||||||
|
v-model="email"
|
||||||
|
required
|
||||||
|
@input="handleChange()"
|
||||||
|
autocomplete="email"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-6" v-if="type === 'login' || type === 'register'">
|
<div class="mb-6" v-if="type === 'login' || type === 'register'">
|
||||||
<input
|
<!-- <input
|
||||||
type="password"
|
type="password"
|
||||||
id="password"
|
id="password"
|
||||||
class="my-4 bg-bg-primary text-text-primary bg- rounded-md block w-full px-3 h-10 shadow-sm focus:outline-none placeholder:text-text-line focus:ring-2 focus:ring-text-primary ring-1 ring-bg-secondary"
|
class="my-4 bg-bg-primary text-text-primary bg- rounded-md block w-full px-3 h-10 shadow-sm focus:outline-none placeholder:text-text-line focus:ring-2 focus:ring-text-primary ring-1 ring-bg-secondary"
|
||||||
@@ -170,6 +199,15 @@ const handleChange = () => {
|
|||||||
v-model="password"
|
v-model="password"
|
||||||
required
|
required
|
||||||
@input="handleChange()"
|
@input="handleChange()"
|
||||||
|
/> -->
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
id="password"
|
||||||
|
class="my-4 bg-bg-primary text-text-primary bg- rounded-md block w-full px-3 h-10 shadow-sm focus:outline-none placeholder:text-text-line focus:ring-2 focus:ring-text-primary ring-1 ring-bg-secondary"
|
||||||
|
placeholder="密碼"
|
||||||
|
v-model="password"
|
||||||
|
required
|
||||||
|
@input="handleChange()"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-error flex justify-center" v-if="errorMessage">
|
<p class="text-error flex justify-center" v-if="errorMessage">
|
||||||
@@ -179,21 +217,35 @@ const handleChange = () => {
|
|||||||
class="inline-flex justify-center rounded-lg font-black py-2 bg-text-primary text-bg w-full"
|
class="inline-flex justify-center rounded-lg font-black py-2 bg-text-primary text-bg w-full"
|
||||||
type="submit"
|
type="submit"
|
||||||
>
|
>
|
||||||
<span v-if="type === 'login'">Log In</span>
|
<span v-if="type === 'login'">
|
||||||
<span v-else>Sign Up</span>
|
<!-- Log In -->
|
||||||
|
登入
|
||||||
|
</span>
|
||||||
|
<span v-else>
|
||||||
|
<!-- Sign Up -->
|
||||||
|
註冊
|
||||||
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<p class="text-text flex justify-center mt-3">
|
<p class="text-text flex justify-center mt-3">
|
||||||
<span v-if="type === 'register'"
|
<span v-if="type === 'register'">
|
||||||
>Already have an account?
|
<!-- Already have an account? -->
|
||||||
|
已經有帳號了嗎?
|
||||||
<RouterLink class="text-text-primary font-bold" to="/login">
|
<RouterLink class="text-text-primary font-bold" to="/login">
|
||||||
<u>Log in</u>
|
<u>
|
||||||
|
<!-- Log in -->
|
||||||
|
登入
|
||||||
|
</u>
|
||||||
</RouterLink></span
|
</RouterLink></span
|
||||||
>
|
>
|
||||||
<span v-else-if="type === 'login'"
|
<span v-else-if="type === 'login'">
|
||||||
>Don't have an account?
|
<!-- Don't have an account? -->
|
||||||
|
還沒有帳號嗎?
|
||||||
<RouterLink class="text-text-primary font-bold" to="/register">
|
<RouterLink class="text-text-primary font-bold" to="/register">
|
||||||
<u>Sign up</u>
|
<u>
|
||||||
|
<!-- Sign up -->
|
||||||
|
註冊
|
||||||
|
</u>
|
||||||
</RouterLink></span
|
</RouterLink></span
|
||||||
>
|
>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -2,8 +2,14 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<font-awesome-icon :icon="['fas', 'list']" class="text-text-primary p-1" />
|
<font-awesome-icon :icon="['fas', 'list']" class="text-text-primary p-1" />
|
||||||
<h1 class="inline text-text-primary font-xl">Command Cheatsheets</h1>
|
<h1 class="inline text-text-primary font-xl">
|
||||||
|
<!-- Command Cheatsheets -->
|
||||||
|
指令之書
|
||||||
|
</h1>
|
||||||
<div id="cheatsheets">
|
<div id="cheatsheets">
|
||||||
<p class="text-text-secondary">--Command List--</p>
|
<p class="text-text-secondary">
|
||||||
|
<!-- --Command List-- -->
|
||||||
|
-- --指令列表-- --
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -19,7 +19,8 @@ setTimeout(() => {
|
|||||||
<div class="modal-content bg-bg-secondary rounded-lg">
|
<div class="modal-content bg-bg-secondary rounded-lg">
|
||||||
<span class="close text-text" @click="closeModal">×</span>
|
<span class="close text-text" @click="closeModal">×</span>
|
||||||
<h2 class="text-2xl text-text mb-5 w-full inline-flex justify-center">
|
<h2 class="text-2xl text-text mb-5 w-full inline-flex justify-center">
|
||||||
Quest Completed!
|
<!-- Quest Completed! -->
|
||||||
|
關卡完成!
|
||||||
</h2>
|
</h2>
|
||||||
<p class="text-base text-text">
|
<p class="text-base text-text">
|
||||||
您已成功完成挑戰,真的非常感謝您的參與!<br />
|
您已成功完成挑戰,真的非常感謝您的參與!<br />
|
||||||
|
|||||||
@@ -5,21 +5,30 @@
|
|||||||
:icon="['far', 'circle-question']"
|
:icon="['far', 'circle-question']"
|
||||||
class="text-text-disabled"
|
class="text-text-disabled"
|
||||||
/>
|
/>
|
||||||
<p class="text-text-disabled inline ml-1">Solution</p>
|
<p class="text-text-disabled inline ml-1">
|
||||||
|
<!-- Solution -->
|
||||||
|
解答
|
||||||
|
</p>
|
||||||
</button>
|
</button>
|
||||||
<button id="reset" class="bg-bg-secondary rounded-lg p-2" @click="reset">
|
<button id="reset" class="bg-bg-secondary rounded-lg p-2" @click="reset">
|
||||||
<font-awesome-icon
|
<font-awesome-icon
|
||||||
:icon="['fas', 'arrow-rotate-left']"
|
:icon="['fas', 'arrow-rotate-left']"
|
||||||
class="text-text-primary"
|
class="text-text-primary"
|
||||||
/>
|
/>
|
||||||
<p class="text-text-primary inline ml-1">Reset</p>
|
<p class="text-text-primary inline ml-1">
|
||||||
|
<!-- Reset -->
|
||||||
|
重來
|
||||||
|
</p>
|
||||||
</button>
|
</button>
|
||||||
<button id="continue" class="bg-bg-disabled rounded-lg p-2">
|
<button id="continue" class="bg-bg-disabled rounded-lg p-2">
|
||||||
<font-awesome-icon
|
<font-awesome-icon
|
||||||
:icon="['far', 'circle-right']"
|
:icon="['far', 'circle-right']"
|
||||||
class="text-text-disabled"
|
class="text-text-disabled"
|
||||||
/>
|
/>
|
||||||
<p class="text-text-disabled inline ml-1">Continue</p>
|
<p class="text-text-disabled inline ml-1">
|
||||||
|
<!-- Continue -->
|
||||||
|
繼續
|
||||||
|
</p>
|
||||||
</button>
|
</button>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ const handleLogout = async () => {
|
|||||||
</button> -->
|
</button> -->
|
||||||
<p
|
<p
|
||||||
class="text-text-primary inline-block font-bold whitespace-nowrap"
|
class="text-text-primary inline-block font-bold whitespace-nowrap"
|
||||||
|
style="font-size: 2vh"
|
||||||
v-if="sessionStore.quest"
|
v-if="sessionStore.quest"
|
||||||
>
|
>
|
||||||
{{ sessionStore.quest.title }}
|
{{ sessionStore.quest.title }}
|
||||||
|
|||||||
@@ -30,7 +30,10 @@ const right = () => {
|
|||||||
:icon="['far', 'lightbulb']"
|
:icon="['far', 'lightbulb']"
|
||||||
class="text-yellow-200 p-2 content-center"
|
class="text-yellow-200 p-2 content-center"
|
||||||
/>
|
/>
|
||||||
<h1 class="inline text-text font-xl p-2 m-1">Hint</h1>
|
<h1 class="inline text-text font-xl p-2 m-1">
|
||||||
|
<!-- Hint -->
|
||||||
|
提示
|
||||||
|
</h1>
|
||||||
<div v-if="current !== -1" class="w-full flex justify-end">
|
<div v-if="current !== -1" class="w-full flex justify-end">
|
||||||
<button
|
<button
|
||||||
class="p-2 m-1 w-1/8"
|
class="p-2 m-1 w-1/8"
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ const marginX = 100
|
|||||||
const marginY = 65
|
const marginY = 65
|
||||||
const chartContainer = ref(null)
|
const chartContainer = ref(null)
|
||||||
let chartInstance = null
|
let chartInstance = null
|
||||||
|
const fullwidth = window.screen.width
|
||||||
|
|
||||||
use([GraphChart, SVGRenderer, TitleComponent, TooltipComponent])
|
use([GraphChart, SVGRenderer, TitleComponent, TooltipComponent])
|
||||||
|
|
||||||
@@ -49,11 +50,11 @@ const genOption = (nodes, edges) => ({
|
|||||||
symbol: () => {
|
symbol: () => {
|
||||||
return NodeImage
|
return NodeImage
|
||||||
},
|
},
|
||||||
symbolSize: [200, 100],
|
symbolSize: [fullwidth / 10, fullwidth / 20],
|
||||||
roam: true,
|
roam: false,
|
||||||
label: {
|
label: {
|
||||||
show: true,
|
show: true,
|
||||||
fontSize: 22,
|
fontSize: fullwidth / 90,
|
||||||
},
|
},
|
||||||
edgeSymbol: ['pin', 'arrow'],
|
edgeSymbol: ['pin', 'arrow'],
|
||||||
edgeSymbolSize: [2, 15],
|
edgeSymbolSize: [2, 15],
|
||||||
@@ -126,7 +127,8 @@ function initChart(option) {
|
|||||||
if (unlocked) {
|
if (unlocked) {
|
||||||
router.push({ name: 'game', params: { questId: id } })
|
router.push({ name: 'game', params: { questId: id } })
|
||||||
} else {
|
} else {
|
||||||
toast.warning('You have not completed the previous quest yet!')
|
// toast.warning('You have not completed the previous quest yet!')
|
||||||
|
toast.warning('你還沒完成前一個關卡!')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -147,9 +149,11 @@ onMounted(async () => {
|
|||||||
class="p-2 stroke-2 scale-y-120 justify-center items-center"
|
class="p-2 stroke-2 scale-y-120 justify-center items-center"
|
||||||
/>
|
/>
|
||||||
<h1
|
<h1
|
||||||
class="text-text-primary text-xl p-2.5 absolute w-fit z-2 font-mono font-bold flex flax-wrap"
|
class="p-4 absolute w-fit z-2 font-mono flex flax-wrap text-xl"
|
||||||
|
style="width: 30%; height: 6%; font-size: 3vh; color: #00ff00"
|
||||||
>
|
>
|
||||||
Get through your linux journey!
|
<!-- Get through your linux journey! -->
|
||||||
|
踏上你的Linux冒險之旅吧!
|
||||||
</h1>
|
</h1>
|
||||||
<div class="flex flex-wrap absolute w-full h-full z-1">
|
<div class="flex flex-wrap absolute w-full h-full z-1">
|
||||||
<div ref="chartContainer" class="w-full h-full flex flex-wrap"></div>
|
<div ref="chartContainer" class="w-full h-full flex flex-wrap"></div>
|
||||||
|
|||||||
@@ -12,7 +12,10 @@ import sessionStore from '../store/session'
|
|||||||
<div v-if="sessionStore.quest" class="whitespace-pre-wrap">
|
<div v-if="sessionStore.quest" class="whitespace-pre-wrap">
|
||||||
<p class="text-text">{{ sessionStore.quest.instruction }}</p>
|
<p class="text-text">{{ sessionStore.quest.instruction }}</p>
|
||||||
<br />
|
<br />
|
||||||
<p class="text-text">Tasks:</p>
|
<p class="text-text">
|
||||||
|
<!-- Tasks: -->
|
||||||
|
任務:
|
||||||
|
</p>
|
||||||
<ul v-if="sessionStore.session">
|
<ul v-if="sessionStore.session">
|
||||||
<li v-for="task in sessionStore.session.tasks" :key="task.id">
|
<li v-for="task in sessionStore.session.tasks" :key="task.id">
|
||||||
<p v-if="task.completed" class="text-text-primary">
|
<p v-if="task.completed" class="text-text-primary">
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<font-awesome-icon :icon="['fas', 'terminal']" class="text-text p-1" />
|
<font-awesome-icon :icon="['fas', 'terminal']" class="text-text p-1" />
|
||||||
<button class="text-text h-[5%]">Terminal</button>
|
<button class="text-text h-[5%]">
|
||||||
|
<!-- Terminal -->
|
||||||
|
終端機
|
||||||
|
</button>
|
||||||
<div
|
<div
|
||||||
id="terminal"
|
id="terminal"
|
||||||
ref="terminal"
|
ref="terminal"
|
||||||
|
|||||||
@@ -8,21 +8,24 @@ import { checkUsername, chooseUsername } from '../utils/auth'
|
|||||||
async function check({ username, error }) {
|
async function check({ username, error }) {
|
||||||
if (username) {
|
if (username) {
|
||||||
if (!isValidUsername(username)) {
|
if (!isValidUsername(username)) {
|
||||||
error('Invalid username.')
|
// error('Invalid username.')
|
||||||
|
error('無效的帳號名稱')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await checkUsername(username)
|
await checkUsername(username)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err instanceof TooManyRequestsError) {
|
if (err instanceof TooManyRequestsError) {
|
||||||
error('Too many requests. Try again in 2 minutes.')
|
// error('Too many requests. Try again in 2 minutes.')
|
||||||
|
error('太多請求,兩分鐘後再試一次。')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (err instanceof ValidationError) {
|
if (err instanceof ValidationError) {
|
||||||
error(err.message)
|
error(err.message)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
error('Something went wrong. Please try again later.')
|
// error('Something went wrong. Please try again later.')
|
||||||
|
error('出了點問題,請再試一次。')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -33,7 +36,8 @@ async function handleSubmit({ username, success, error }) {
|
|||||||
success()
|
success()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err instanceof TooManyRequestsError) {
|
if (err instanceof TooManyRequestsError) {
|
||||||
error('Too many requests. Try again in 2 minutes.')
|
// error('Too many requests. Try again in 2 minutes.')
|
||||||
|
error('太多請求,兩分鐘後再試一次。')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (err instanceof ValidationError) {
|
if (err instanceof ValidationError) {
|
||||||
|
|||||||
@@ -30,13 +30,15 @@ onMounted(async () => {
|
|||||||
await init(props.questId)
|
await init(props.questId)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err instanceof LoadQuestError) {
|
if (err instanceof LoadQuestError) {
|
||||||
toast.error(`Failed to load quest: ${err.questId}. Please check the URL.`)
|
// toast.error(`Failed to load quest: ${err.questId}. Please check the URL.`)
|
||||||
|
toast.error(`無法讀取關卡: ${err.questId},請確認網頁連結。`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (err instanceof LoadSessionError) {
|
if (err instanceof LoadSessionError) {
|
||||||
toast.error(
|
// toast.error(
|
||||||
`Failed to create session for quest: ${err.questId}. Please re-login and try again.`
|
// `Failed to create session for quest: ${err.questId}. Please re-login and try again.`
|
||||||
)
|
// )
|
||||||
|
toast.error(`無法建立工作階段: ${err.questId},請重新登入再試一次。`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
console.error(err)
|
console.error(err)
|
||||||
|
|||||||
@@ -15,19 +15,23 @@ const handleLogin = async ({ username, password, success, error }) => {
|
|||||||
if (isSuccess) success()
|
if (isSuccess) success()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err instanceof TooManyRequestsError) {
|
if (err instanceof TooManyRequestsError) {
|
||||||
error('Too many requests. Try again in 2 minutes.')
|
// error('Too many requests. Try again in 2 minutes.')
|
||||||
|
error('太多請求,兩分鐘後再試一次。')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (err instanceof UnauthorizedError) {
|
if (err instanceof UnauthorizedError) {
|
||||||
error('Wrong username or password.')
|
// error('Wrong username or password.')
|
||||||
|
error('錯誤的帳號名稱或密碼。')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (err instanceof ValidationError) {
|
if (err instanceof ValidationError) {
|
||||||
error('Invalid username or password.')
|
// error('Invalid username or password.')
|
||||||
|
error('無效的帳號名稱或密碼。')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
console.error(err)
|
console.error(err)
|
||||||
error('Something went wrong.')
|
// error('Something went wrong.')
|
||||||
|
error('出了點問題。')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -7,10 +7,11 @@ import GameHeaderPart from '../components/GameHeaderPart.vue'
|
|||||||
<div class="h-[6vh] w-full">
|
<div class="h-[6vh] w-full">
|
||||||
<GameHeaderPart />
|
<GameHeaderPart />
|
||||||
<p
|
<p
|
||||||
class="text-text-primary absolute z-1 font-bold inline-block"
|
class="text-text-primary absolute z-1 font-bold inline-block tracking-widest"
|
||||||
style="left: 1.2%; top: 1.5%; height: 100%"
|
style="left: 1.2%; top: 1.5%; height: 100%; font-size: 2vh"
|
||||||
>
|
>
|
||||||
Quest Map
|
<!-- Quest Map -->
|
||||||
|
Unix編年史
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col justify-center items-center w-full h-[94vh]">
|
<div class="flex flex-col justify-center items-center w-full h-[94vh]">
|
||||||
|
|||||||
@@ -17,11 +17,13 @@ function handleRegister({ username, email, password, success, error }) {
|
|||||||
.then(success)
|
.then(success)
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
if (err instanceof TooManyRequestsError) {
|
if (err instanceof TooManyRequestsError) {
|
||||||
error('Too many requests. Try again in 2 minutes.')
|
// error('Too many requests. Try again in 2 minutes.')
|
||||||
|
error('太多請求,兩分鐘後再試一次。')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (err instanceof UnauthorizedError) {
|
if (err instanceof UnauthorizedError) {
|
||||||
error('Invalid username or password.')
|
// error('Invalid username or password.')
|
||||||
|
error('無效的帳號名稱或密碼。')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (err instanceof ValidationError) {
|
if (err instanceof ValidationError) {
|
||||||
@@ -29,23 +31,27 @@ function handleRegister({ username, email, password, success, error }) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
console.error(err)
|
console.error(err)
|
||||||
error('Something went wrong.')
|
// error('Something went wrong.')
|
||||||
|
error('出了點問題。')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function check({ username, email, password, error }) {
|
async function check({ username, email, password, error }) {
|
||||||
if (username && !isValidUsername(username)) {
|
if (username && !isValidUsername(username)) {
|
||||||
error('Invalid username.')
|
// error('Invalid username.')
|
||||||
|
error('無效的帳號名稱')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (email && !validator.isEmail(email)) {
|
if (email && !validator.isEmail(email)) {
|
||||||
error('Invalid email.')
|
// error('Invalid email.')
|
||||||
|
error('無效的電子郵件')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (password && !validator.isStrongPassword(password, passwordPolicy)) {
|
if (password && !validator.isStrongPassword(password, passwordPolicy)) {
|
||||||
error(
|
// error(
|
||||||
'Your password must be 8+ characters with at least one number, one upper and one lower case letter.'
|
// 'Your password must be 8+ characters with at least one number, one upper and one lower case letter.'
|
||||||
)
|
// )
|
||||||
|
error('密碼必須超過8個字元,至少包含一個數字、一個大寫及一個小寫。')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -56,11 +62,13 @@ async function check({ username, email, password, error }) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (err instanceof TooManyRequestsError) {
|
if (err instanceof TooManyRequestsError) {
|
||||||
error('Too many requests. Try again in 2 minutes.')
|
// error('Too many requests. Try again in 2 minutes.')
|
||||||
|
error('太多請求,兩分鐘後再試一次。')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
console.error(err)
|
console.error(err)
|
||||||
error('Something went wrong.')
|
// error('Something went wrong.')
|
||||||
|
error('出了點問題。')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in new issue
Block a user