Fix/UI detail (#414)
Some checks are pending
EasyTier Core / pre_job (push) Waiting to run
EasyTier Core / build (freebsd-13.2-x86_64, 13.2, ubuntu-latest, x86_64-unknown-freebsd) (push) Blocked by required conditions
EasyTier Core / build (linux-aarch64, ubuntu-latest, aarch64-unknown-linux-musl) (push) Blocked by required conditions
EasyTier Core / build (linux-arm, ubuntu-latest, arm-unknown-linux-musleabi) (push) Blocked by required conditions
EasyTier Core / build (linux-armhf, ubuntu-latest, arm-unknown-linux-musleabihf) (push) Blocked by required conditions
EasyTier Core / build (linux-armv7, ubuntu-latest, armv7-unknown-linux-musleabi) (push) Blocked by required conditions
EasyTier Core / build (linux-armv7hf, ubuntu-latest, armv7-unknown-linux-musleabihf) (push) Blocked by required conditions
EasyTier Core / build (linux-mips, ubuntu-latest, mips-unknown-linux-musl) (push) Blocked by required conditions
EasyTier Core / build (linux-mipsel, ubuntu-latest, mipsel-unknown-linux-musl) (push) Blocked by required conditions
EasyTier Core / build (linux-x86_64, ubuntu-latest, x86_64-unknown-linux-musl) (push) Blocked by required conditions
EasyTier Core / build (macos-aarch64, macos-latest, aarch64-apple-darwin) (push) Blocked by required conditions
EasyTier Core / build (macos-x86_64, macos-latest, x86_64-apple-darwin) (push) Blocked by required conditions
EasyTier Core / build (windows-x86_64, windows-latest, x86_64-pc-windows-msvc) (push) Blocked by required conditions
EasyTier Core / core-result (push) Blocked by required conditions
EasyTier GUI / pre_job (push) Waiting to run
EasyTier GUI / build-gui (linux-aarch64, aarch64-unknown-linux-gnu, ubuntu-latest, aarch64-unknown-linux-musl) (push) Blocked by required conditions
EasyTier GUI / build-gui (linux-x86_64, x86_64-unknown-linux-gnu, ubuntu-latest, x86_64-unknown-linux-musl) (push) Blocked by required conditions
EasyTier GUI / build-gui (macos-aarch64, aarch64-apple-darwin, macos-latest, aarch64-apple-darwin) (push) Blocked by required conditions
EasyTier GUI / build-gui (macos-x86_64, x86_64-apple-darwin, macos-latest, x86_64-apple-darwin) (push) Blocked by required conditions
EasyTier GUI / build-gui (windows-x86_64, x86_64-pc-windows-msvc, windows-latest, x86_64-pc-windows-msvc) (push) Blocked by required conditions
EasyTier GUI / gui-result (push) Blocked by required conditions
EasyTier Mobile / pre_job (push) Waiting to run
EasyTier Mobile / build-mobile (android, ubuntu-latest, android) (push) Blocked by required conditions
EasyTier Mobile / mobile-result (push) Blocked by required conditions
EasyTier Test / pre_job (push) Waiting to run
EasyTier Test / test (push) Blocked by required conditions

This commit is contained in:
m1m1sha 2024-10-12 00:36:57 +08:00 committed by GitHub
parent d2291628e0
commit 9824d0adaa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 664 additions and 685 deletions

View File

@ -1,5 +1,86 @@
{ {
"i18n-ally.localesPaths": [ "cSpell.words": [
"locales" "easytier",
"Vite",
"vueuse",
"pinia",
"demi",
"antfu",
"iconify",
"intlify",
"vitejs",
"unplugin",
"pnpm"
],
"i18n-ally.sourceLanguage": "en",
"i18n-ally.keystyle": "nested",
"i18n-ally.localesPaths": "locales",
"i18n-ally.sortKeys": true,
// Disable the default formatter
"prettier.enable": false,
"editor.formatOnSave": false,
// Auto fix
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.organizeImports": "never"
},
// Silent the stylistic rules in you IDE, but still auto fix them
"eslint.rules.customizations": [
{
"rule": "style/*",
"severity": "off"
},
{
"rule": "format/*",
"severity": "off"
},
{
"rule": "*-indent",
"severity": "off"
},
{
"rule": "*-spacing",
"severity": "off"
},
{
"rule": "*-spaces",
"severity": "off"
},
{
"rule": "*-order",
"severity": "off"
},
{
"rule": "*-dangle",
"severity": "off"
},
{
"rule": "*-newline",
"severity": "off"
},
{
"rule": "*quotes",
"severity": "off"
},
{
"rule": "*semi",
"severity": "off"
}
],
// The following is optional.
// It's better to put under project setting `.vscode/settings.json`
// to avoid conflicts with working with different eslint configs
// that does not support all formats.
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"vue",
"html",
"markdown",
"json",
"jsonc",
"yaml"
] ]
} }

View File

@ -18,6 +18,7 @@
"@tauri-apps/plugin-os": "2.0.0-rc.1", "@tauri-apps/plugin-os": "2.0.0-rc.1",
"@tauri-apps/plugin-process": "2.0.0-rc.1", "@tauri-apps/plugin-process": "2.0.0-rc.1",
"@tauri-apps/plugin-shell": "2.0.0-rc.1", "@tauri-apps/plugin-shell": "2.0.0-rc.1",
"@vueuse/core": "^11.1.0",
"aura": "link:@primevue\\themes\\aura", "aura": "link:@primevue\\themes\\aura",
"ip-num": "1.5.1", "ip-num": "1.5.1",
"pinia": "^2.2.4", "pinia": "^2.2.4",
@ -38,7 +39,7 @@
"@types/node": "^22.7.4", "@types/node": "^22.7.4",
"@types/uuid": "^10.0.0", "@types/uuid": "^10.0.0",
"@vitejs/plugin-vue": "^5.1.4", "@vitejs/plugin-vue": "^5.1.4",
"@vue-macros/volar": "^0.29.1", "@vue-macros/volar": "0.30.3",
"autoprefixer": "^10.4.20", "autoprefixer": "^10.4.20",
"eslint": "^9.12.0", "eslint": "^9.12.0",
"eslint-plugin-format": "^0.1.2", "eslint-plugin-format": "^0.1.2",
@ -57,5 +58,6 @@
"vite-plugin-vue-layouts": "^0.11.0", "vite-plugin-vue-layouts": "^0.11.0",
"vue-i18n": "^10.0.0", "vue-i18n": "^10.0.0",
"vue-tsc": "^2.1.6" "vue-tsc": "^2.1.6"
} },
"packageManager": "pnpm@9.12.1+sha512.e5a7e52a4183a02d5931057f7a0dbff9d5e9ce3161e33fa68ae392125b79282a8a8a470a51dfc8a0ed86221442eb2fb57019b0990ed24fab519bf0e1bc5ccfc4"
} }

File diff suppressed because it is too large Load Diff

View File

@ -44,6 +44,8 @@ declare global {
const mapWritableState: typeof import('pinia')['mapWritableState'] const mapWritableState: typeof import('pinia')['mapWritableState']
const markRaw: typeof import('vue')['markRaw'] const markRaw: typeof import('vue')['markRaw']
const nextTick: typeof import('vue')['nextTick'] const nextTick: typeof import('vue')['nextTick']
const num2ipv4: typeof import('./composables/utils')['num2ipv4']
const num2ipv6: typeof import('./composables/utils')['num2ipv6']
const onActivated: typeof import('vue')['onActivated'] const onActivated: typeof import('vue')['onActivated']
const onBeforeMount: typeof import('vue')['onBeforeMount'] const onBeforeMount: typeof import('vue')['onBeforeMount']
const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave'] const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave']
@ -150,6 +152,8 @@ declare module 'vue' {
readonly mapWritableState: UnwrapRef<typeof import('pinia')['mapWritableState']> readonly mapWritableState: UnwrapRef<typeof import('pinia')['mapWritableState']>
readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']> readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']>
readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']> readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']>
readonly num2ipv4: UnwrapRef<typeof import('./composables/utils')['num2ipv4']>
readonly num2ipv6: UnwrapRef<typeof import('./composables/utils')['num2ipv6']>
readonly onActivated: UnwrapRef<typeof import('vue')['onActivated']> readonly onActivated: UnwrapRef<typeof import('vue')['onActivated']>
readonly onBeforeMount: UnwrapRef<typeof import('vue')['onBeforeMount']> readonly onBeforeMount: UnwrapRef<typeof import('vue')['onBeforeMount']>
readonly onBeforeRouteLeave: UnwrapRef<typeof import('vue-router')['onBeforeRouteLeave']> readonly onBeforeRouteLeave: UnwrapRef<typeof import('vue-router')['onBeforeRouteLeave']>

View File

@ -1,7 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import InputGroup from 'primevue/inputgroup' import InputGroup from 'primevue/inputgroup'
import InputGroupAddon from 'primevue/inputgroupaddon' import InputGroupAddon from 'primevue/inputgroupaddon'
import { ping } from 'tauri-plugin-vpnservice-api'
import { getOsHostname } from '~/composables/network' import { getOsHostname } from '~/composables/network'
import { NetworkingMethod } from '~/types/network' import { NetworkingMethod } from '~/types/network'
@ -42,10 +41,11 @@ function searchUrlSuggestions(e: { query: string }): string[] {
if (query.match(/^\w+:.*/)) { if (query.match(/^\w+:.*/)) {
// if query is a valid url, then add to suggestions // if query is a valid url, then add to suggestions
try { try {
// eslint-disable-next-line no-new
new URL(query) new URL(query)
ret.push(query) ret.push(query)
} }
catch (e) {} catch {}
} }
else { else {
for (const proto in protos) { for (const proto in protos) {
@ -128,18 +128,12 @@ const osHostname = ref<string>('')
onMounted(async () => { onMounted(async () => {
osHostname.value = await getOsHostname() osHostname.value = await getOsHostname()
osHostname.value = await ping('ffdklsajflkdsjl') || ''
}) })
</script> </script>
<template> <template>
<div class="flex flex-column h-full"> <div class="flex flex-column h-full">
<div class="flex flex-column"> <div class="flex flex-column">
<div class="w-10/12 self-center mb-3">
<Message severity="warn">
{{ t('dhcp_experimental_warning') }}
</Message>
</div>
<div class="w-10/12 self-center "> <div class="w-10/12 self-center ">
<Panel :header="t('basic_settings')"> <Panel :header="t('basic_settings')">
<div class="flex flex-column gap-y-2"> <div class="flex flex-column gap-y-2">

View File

@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { useTimeAgo } from '@vueuse/core'
import { IPv4, IPv6 } from 'ip-num/IPNumber' import { IPv4, IPv6 } from 'ip-num/IPNumber'
import type { NodeInfo, PeerRoutePair } from '~/types/network' import type { NodeInfo, PeerRoutePair } from '~/types/network'
@ -111,6 +112,13 @@ function version(info: PeerRoutePair) {
return info.route.version === '' ? 'unknown' : info.route.version return info.route.version === '' ? 'unknown' : info.route.version
} }
function ipFormat(info: PeerRoutePair) {
const ip = info.route.ipv4_addr
if (typeof ip === 'string')
return ip
return ip ? `${num2ipv4(ip.address)}/${ip.network_length}` : ''
}
const myNodeInfo = computed(() => { const myNodeInfo = computed(() => {
if (!curNetworkInst.value) if (!curNetworkInst.value)
return {} as NodeInfo return {} as NodeInfo
@ -151,7 +159,7 @@ const myNodeInfoChips = computed(() => {
const local_ipv4s = my_node_info.ips?.interface_ipv4s const local_ipv4s = my_node_info.ips?.interface_ipv4s
for (const [idx, ip] of local_ipv4s?.entries()) { for (const [idx, ip] of local_ipv4s?.entries()) {
chips.push({ chips.push({
label: `Local IPv4 ${idx}: ${IPv4.fromNumber(ip.addr)}`, label: `Local IPv4 ${idx}: ${num2ipv4(ip)}`,
icon: '', icon: '',
} as Chip) } as Chip)
} }
@ -160,11 +168,7 @@ const myNodeInfoChips = computed(() => {
const local_ipv6s = my_node_info.ips?.interface_ipv6s const local_ipv6s = my_node_info.ips?.interface_ipv6s
for (const [idx, ip] of local_ipv6s?.entries()) { for (const [idx, ip] of local_ipv6s?.entries()) {
chips.push({ chips.push({
label: `Local IPv6 ${idx}: ${IPv6.fromBigInt((BigInt(ip.part1) << BigInt(96)) label: `Local IPv6 ${idx}: ${num2ipv6(ip)}`,
+ (BigInt(ip.part2) << BigInt(64))
+ (BigInt(ip.part3) << BigInt(32))
+ BigInt(ip.part4),
)}`,
icon: '', icon: '',
} as Chip) } as Chip)
} }
@ -312,16 +316,18 @@ function showEventLogs() {
<template> <template>
<div> <div>
<Dialog v-model:visible="dialogVisible" modal :header="t(dialogHeader)" :style="{ width: '70%' }"> <Dialog v-model:visible="dialogVisible" modal :header="t(dialogHeader)" class="w-2/3 h-auto">
<Panel> <ScrollPanel v-if="dialogHeader === 'vpn_portal_config'">
<ScrollPanel style="width: 100%; height: 400px">
<pre>{{ dialogContent }}</pre> <pre>{{ dialogContent }}</pre>
</ScrollPanel> </ScrollPanel>
</Panel> <Timeline v-else :value="dialogContent">
<Divider /> <template #opposite="slotProps">
<div class="flex justify-content-end gap-2"> <small class="text-surface-500 dark:text-surface-400">{{ useTimeAgo(Date.parse(slotProps.item[0])) }}</small>
<Button type="button" :label="t('close')" @click="dialogVisible = false" /> </template>
</div> <template #content="slotProps">
{{ slotProps.item[1] }}
</template>
</Timeline>
</Dialog> </Dialog>
<Card v-if="curNetworkInst?.error_msg"> <Card v-if="curNetworkInst?.error_msg">
@ -405,14 +411,22 @@ function showEventLogs() {
</template> </template>
<template #content> <template #content>
<DataTable :value="peerRouteInfos" column-resize-mode="fit" table-style="width: 100%"> <DataTable :value="peerRouteInfos" column-resize-mode="fit" table-style="width: 100%">
<Column field="route.ipv4_addr" style="width: 100px;" :header="t('virtual_ipv4')" /> <Column :field="ipFormat" style="width: 100px;" :header="t('virtual_ipv4')" />
<Column field="route.hostname" style="max-width: 250px;" :header="t('hostname')" /> <Column style="max-width: 250px;" :header="t('hostname')">
<template #body="slotProps">
<span v-tooltip="slotProps.data.route.hostname">{{ slotProps.data.route.hostname }}</span>
</template>
</Column>
<Column :field="routeCost" style="width: 100px;" :header="t('route_cost')" /> <Column :field="routeCost" style="width: 100px;" :header="t('route_cost')" />
<Column :field="latencyMs" style="width: 80px;" :header="t('latency')" /> <Column :field="latencyMs" style="width: 80px;" :header="t('latency')" />
<Column :field="txBytes" style="width: 80px;" :header="t('upload_bytes')" /> <Column :field="txBytes" style="width: 80px;" :header="t('upload_bytes')" />
<Column :field="rxBytes" style="width: 80px;" :header="t('download_bytes')" /> <Column :field="rxBytes" style="width: 80px;" :header="t('download_bytes')" />
<Column :field="lossRate" style="width: 100px;" :header="t('loss_rate')" /> <Column :field="lossRate" style="width: 100px;" :header="t('loss_rate')" />
<Column :field="version" style="width: 100px;" :header="t('status.version')" /> <Column style="width: 100px;" :header="t('status.version')">
<template #body="slotProps">
<span>{{ version(slotProps.data) }}</span>
</template>
</Column>
</DataTable> </DataTable>
</template> </template>
</Card> </Card>

View File

@ -0,0 +1,15 @@
import { IPv4, IPv6 } from 'ip-num/IPNumber'
import type { Ipv4Addr, Ipv6Addr } from '~/types/network'
export function num2ipv4(ip: Ipv4Addr) {
return IPv4.fromNumber(ip.addr)
}
export function num2ipv6(ip: Ipv6Addr) {
return IPv6.fromBigInt(
(BigInt(ip.part1) << BigInt(96))
+ (BigInt(ip.part2) << BigInt(64))
+ (BigInt(ip.part3) << BigInt(32))
+ BigInt(ip.part4),
)
}

View File

@ -2,7 +2,16 @@ import { disable, enable, isEnabled } from '@tauri-apps/plugin-autostart'
export async function loadAutoLaunchStatusAsync(target_enable: boolean): Promise<boolean> { export async function loadAutoLaunchStatusAsync(target_enable: boolean): Promise<boolean> {
try { try {
target_enable ? await enable() : await disable() if (target_enable) {
await enable()
}
else {
// 消除没有配置自启动时进行关闭操作报错
try {
await disable()
}
catch { }
}
localStorage.setItem('auto_launch', JSON.stringify(await isEnabled())) localStorage.setItem('auto_launch', JSON.stringify(await isEnabled()))
return isEnabled() return isEnabled()
} }

View File

@ -181,7 +181,7 @@ const setting_menu_items = ref([
label: () => t('logging_open_dir'), label: () => t('logging_open_dir'),
icon: 'pi pi-folder-open', icon: 'pi pi-folder-open',
command: async () => { command: async () => {
console.log('open log dir', await appLogDir()) // console.log('open log dir', await appLogDir())
await open(await appLogDir()) await open(await appLogDir())
}, },
}) })

View File

@ -137,7 +137,10 @@ export interface StunInfo {
export interface Route { export interface Route {
peer_id: number peer_id: number
ipv4_addr: string ipv4_addr: {
address: Ipv4Addr
network_length: number
} | string | null
next_hop_peer_id: number next_hop_peer_id: number
cost: number cost: number
proxy_cidrs: string[] proxy_cidrs: string[]