mirror of
https://github.com/sigcn/pg.git
synced 2025-09-27 01:05:51 +08:00
peermap/ui: supports i18n
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.23-alpine AS builder
|
||||
FROM golang:1.24-alpine AS builder
|
||||
ADD . /pg
|
||||
WORKDIR /pg
|
||||
ARG version=unknown
|
||||
|
65
peermap/ui/package-lock.json
generated
65
peermap/ui/package-lock.json
generated
@@ -9,6 +9,7 @@
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"vue": "^3.5.13",
|
||||
"vue-i18n": "^11.1.2",
|
||||
"vue-router": "^4.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -912,6 +913,50 @@
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@intlify/core-base": {
|
||||
"version": "11.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/@intlify/core-base/-/core-base-11.1.2.tgz",
|
||||
"integrity": "sha512-nmG512G8QOABsserleechwHGZxzKSAlggGf9hQX0nltvSwyKNVuB/4o6iFeG2OnjXK253r8p8eSDOZf8PgFdWw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@intlify/message-compiler": "11.1.2",
|
||||
"@intlify/shared": "11.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/kazupon"
|
||||
}
|
||||
},
|
||||
"node_modules/@intlify/message-compiler": {
|
||||
"version": "11.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/@intlify/message-compiler/-/message-compiler-11.1.2.tgz",
|
||||
"integrity": "sha512-T/xbNDzi+Yv0Qn2Dfz2CWCAJiwNgU5d95EhhAEf4YmOgjCKktpfpiUSmLcBvK1CtLpPQ85AMMQk/2NCcXnNj1g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@intlify/shared": "11.1.2",
|
||||
"source-map-js": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/kazupon"
|
||||
}
|
||||
},
|
||||
"node_modules/@intlify/shared": {
|
||||
"version": "11.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/@intlify/shared/-/shared-11.1.2.tgz",
|
||||
"integrity": "sha512-dF2iMMy8P9uKVHV/20LA1ulFLL+MKSbfMiixSmn6fpwqzvix38OIc7ebgnFbBqElvghZCW9ACtzKTGKsTGTWGA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/kazupon"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/gen-mapping": {
|
||||
"version": "0.3.8",
|
||||
"resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
|
||||
@@ -2734,6 +2779,26 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/vue-i18n": {
|
||||
"version": "11.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/vue-i18n/-/vue-i18n-11.1.2.tgz",
|
||||
"integrity": "sha512-MfdkdKGUHN+jkkaMT5Zbl4FpRmN7kfelJIwKoUpJ32ONIxdFhzxZiLTVaAXkAwvH3y9GmWpoiwjDqbPIkPIMFA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@intlify/core-base": "11.1.2",
|
||||
"@intlify/shared": "11.1.2",
|
||||
"@vue/devtools-api": "^6.5.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/kazupon"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-router": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.5.0.tgz",
|
||||
|
@@ -11,6 +11,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"vue": "^3.5.13",
|
||||
"vue-i18n": "^11.1.2",
|
||||
"vue-router": "^4.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
41
peermap/ui/src/i18n.js
Normal file
41
peermap/ui/src/i18n.js
Normal file
@@ -0,0 +1,41 @@
|
||||
export default {
|
||||
en: {
|
||||
enter_secret: 'Enter your json secret',
|
||||
sign_in: 'Sign in',
|
||||
sign_in_with: 'Sign in with {provider}',
|
||||
first_time: 'First time?',
|
||||
read_docs: 'Learn more at',
|
||||
sign_out: 'Sign out',
|
||||
generate_secret: 'Generate a secret',
|
||||
or: 'OR',
|
||||
help: {
|
||||
no_any_node: 'No any node was found, follow these steps to run your node.',
|
||||
step1: '1. Download the binary pgcli',
|
||||
step1c: 'Go to github {link} page, download for your os and arch.',
|
||||
step2: '2. Download secret json file',
|
||||
step2c:
|
||||
'Click {btn} at the top right of the current page to download a pre-shared network secret file.',
|
||||
step3: '3. Run in the terminal(with root privileges)',
|
||||
read_docs: 'For more details, please read the {link}.',
|
||||
},
|
||||
},
|
||||
zh: {
|
||||
enter_secret: '请输入 JSON 格式的密钥',
|
||||
sign_in: '登录',
|
||||
sign_in_with: '使用 {provider} 登录',
|
||||
first_time: '第一次使用?',
|
||||
read_docs: '欲了解更多,请访问',
|
||||
sign_out: '登出',
|
||||
generate_secret: '下载密钥',
|
||||
or: '或者',
|
||||
help: {
|
||||
no_any_node: '还没有节点,按下面的步骤运行第一个节点。',
|
||||
step1: '1. 下载可执行程序 pgcli',
|
||||
step1c: '访问 Github {link} 页面, 下载适合你操作系统和架构的程序包。',
|
||||
step2: '2. 下载密钥文件',
|
||||
step2c: '点击本页右上角的 {btn} 按钮,下载一个预共享网络密钥文件。',
|
||||
step3: '3. 在终端运行(需要管理员权限)',
|
||||
read_docs: '请访问 {link} 了解更多姿势。',
|
||||
},
|
||||
},
|
||||
}
|
@@ -1,11 +1,21 @@
|
||||
import './assets/main.css'
|
||||
|
||||
import { createApp } from 'vue'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import lang from '@/i18n'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
fallbackLocale: 'en',
|
||||
locale: navigator.language == 'zh-CN' ? 'zh' : 'en',
|
||||
messages: lang,
|
||||
})
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(router)
|
||||
app.use(i18n)
|
||||
|
||||
app.mount('#app')
|
||||
|
@@ -52,9 +52,12 @@ onMounted(async () => {
|
||||
<template>
|
||||
<header v-if="session">
|
||||
<div class="network">
|
||||
<span>{{ session.network }}</span> <a href="javascript:;" @click="signout">Sign out</a>
|
||||
<span>{{ session.network }}</span>
|
||||
<a href="javascript:;" @click="signout">{{ $t('sign_out') }}</a>
|
||||
</div>
|
||||
<a class="generateSecret" href="javascript:;" @click="downloadSecret">Generate a secret</a>
|
||||
<a class="generateSecret" href="javascript:;" @click="downloadSecret">
|
||||
{{ $t('generate_secret') }}
|
||||
</a>
|
||||
</header>
|
||||
<main v-if="session">
|
||||
<ul v-if="peers.length > 0">
|
||||
@@ -69,25 +72,33 @@ onMounted(async () => {
|
||||
</li>
|
||||
</ul>
|
||||
<div v-else class="usage">
|
||||
<div class="title">No any node was found, follow these steps to run your node.</div>
|
||||
<div class="title">{{ $t('help.no_any_node') }}</div>
|
||||
<div class="code">
|
||||
<div class="step">1. Download the binary pgcli</div>
|
||||
<div class="step">{{ $t('help.step1') }}</div>
|
||||
<div class="stepc">
|
||||
Go to github <a href="https://github.com/sigcn/pg/releases">releases</a> page, download
|
||||
for your os and arch.
|
||||
<i18n-t keypath="help.step1c">
|
||||
<template #link>
|
||||
<a href="https://github.com/sigcn/pg/releases">releases</a>
|
||||
</template>
|
||||
</i18n-t>
|
||||
</div>
|
||||
<div class="step">2. Download secret json file</div>
|
||||
<div class="step">{{ $t('help.step2') }}</div>
|
||||
<div class="stepc">
|
||||
Click <strong>Generate a secret</strong> at the top right of the current page to download
|
||||
a pre-shared network secret file.
|
||||
<i18n-t keypath="help.step2c">
|
||||
<template #btn>
|
||||
<strong>{{ $t('generate_secret') }}</strong>
|
||||
</template>
|
||||
</i18n-t>
|
||||
</div>
|
||||
<div class="step">3. Run in the terminal(with root privileges)</div>
|
||||
<div class="step">{{ $t('help.step3') }}</div>
|
||||
<code
|
||||
>pgcli vpn -s {{ (serverInfo || { url: '' }).url }} -4 100.99.0.1/24 -f
|
||||
{{ session.network }}_psns.json</code
|
||||
>
|
||||
<div class="title">
|
||||
For more details, please read the <a href="https://docs.openpg.in">docs</a>.
|
||||
<i18n-t keypath="help.read_docs">
|
||||
<template #link> <a href="https://docs.openpg.in">docs</a></template>
|
||||
</i18n-t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -58,18 +58,20 @@ onMounted(loadProviders)
|
||||
</div>
|
||||
</div>
|
||||
<div class="secret">
|
||||
<input ref="secretInput" v-model="secret" placeholder="Enter your json secret" />
|
||||
<button @click="signinBtn">Sign in</button>
|
||||
<input ref="secretInput" v-model="secret" :placeholder="$t('enter_secret')" />
|
||||
<button @click="signinBtn">{{ $t('sign_in') }}</button>
|
||||
</div>
|
||||
<div v-if="providers" class="or">OR</div>
|
||||
<div v-if="providers" class="or">{{ $t('or') }}</div>
|
||||
<ul v-if="providers" class="login">
|
||||
<li v-for="(provider, index) in providers" :key="index" @click="signin(provider)">
|
||||
Sign in with {{ provider }}
|
||||
{{
|
||||
$t('sign_in_with', { provider: provider.replace(/^./, (match) => match.toUpperCase()) })
|
||||
}}
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tips">
|
||||
<span style="color: #000">First time?</span> Learn more at
|
||||
<a href="https://docs.openpg.in">docs.openpg.in</a>
|
||||
<span style="color: #000">{{ $t('first_time') }}</span>
|
||||
{{ $t('read_docs') }} <a href="https://docs.openpg.in">docs.openpg.in</a>
|
||||
</div>
|
||||
</main>
|
||||
</template>
|
||||
|
Reference in New Issue
Block a user