Compare commits

..
2 Commits
12 changed files with 99 additions and 53 deletions
+5 -13
View File
@@ -4,17 +4,9 @@
</NuxtLayout> </NuxtLayout>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { useDark, useToggle, usePreferredDark } from "@vueuse/core"; import useMainStore from "@/stores/index";
import { isFunction } from "lodash-es"; import { initTheme } from "@/composables/theme";
const isDark = usePreferredDark(); const mainStore = useMainStore();
const darkConfig = useDark({ // console.log(mainStore.theme)
selector: "html", initTheme(mainStore.theme);
attribute: "class",
valueDark: "dark",
valueLight: "",
});
const toggleDark = useToggle(darkConfig);
if (isDark && isFunction(toggleDark)) {
toggleDark(isDark);
}
</script> </script>
+21
View File
@@ -0,0 +1,21 @@
import { useDark, useToggle, usePreferredDark } from "@vueuse/core";
import { isFunction } from "lodash-es";
// const isDark = usePreferredDark();
const darkConfig = useDark({
selector: "html",
attribute: "class",
valueDark: "dark",
valueLight: "",
});
const toggleDark = useToggle(darkConfig);
export const initTheme = (isDark: boolean) => {
if (isDark && isFunction(toggleDark)) {
toggleDark(isDark);
}
};
export const setTheme = (dark: boolean) => {
if (isFunction(toggleDark)) {
toggleDark(dark);
}
}
+27 -6
View File
@@ -2,6 +2,8 @@ import { Menu, MenuItem, PredefinedMenuItem } from "@tauri-apps/api/menu";
import { TrayIcon } from "@tauri-apps/api/tray"; import { TrayIcon } from "@tauri-apps/api/tray";
import { getCurrentWindow } from "@tauri-apps/api/window"; import { getCurrentWindow } from "@tauri-apps/api/window";
import pkg from "@/package.json"; import pkg from "@/package.json";
import { setTheme } from "~/composables/theme";
import useMainStore from "@/stores/index";
const DEFAULT_TRAY_NAME = "main"; const DEFAULT_TRAY_NAME = "main";
@@ -20,8 +22,8 @@ export async function useTray(init: boolean = false, beforExit: Function) {
tray = await TrayIcon.getById(DEFAULT_TRAY_NAME); tray = await TrayIcon.getById(DEFAULT_TRAY_NAME);
if (!tray) { if (!tray) {
tray = await TrayIcon.new({ tray = await TrayIcon.new({
tooltip: `EasyTier\n${pkg.version}`, tooltip: `EasyTierGame\n${pkg.version}`,
title: `EasyTier\n${pkg.version}`, title: `EasyTierGame\n${pkg.version}`,
id: DEFAULT_TRAY_NAME, id: DEFAULT_TRAY_NAME,
menu: await Menu.new({ menu: await Menu.new({
id: "main", id: "main",
@@ -38,7 +40,7 @@ export async function useTray(init: boolean = false, beforExit: Function) {
} }
if (init) { if (init) {
tray.setTooltip(`EasyTier\n${pkg.version}`); tray.setTooltip(`EasyTierGame\n${pkg.version}`);
tray.setMenuOnLeftClick(false); tray.setMenuOnLeftClick(false);
tray.setMenu( tray.setMenu(
await Menu.new({ await Menu.new({
@@ -52,7 +54,12 @@ export async function useTray(init: boolean = false, beforExit: Function) {
} }
export async function generateMenuItem(beforExit: Function) { export async function generateMenuItem(beforExit: Function) {
return [await MenuItemShow("显示 / 隐藏"), await PredefinedMenuItem.new({ item: "Separator" }), await MenuItemExit("退出", beforExit)]; return [
await MenuItemShow("显示 / 隐藏"),
await MenuItemTheme(),
await PredefinedMenuItem.new({ item: "Separator" }),
await MenuItemExit("退出", beforExit),
];
} }
export async function MenuItemExit(text: string, beforExit: Function) { export async function MenuItemExit(text: string, beforExit: Function) {
@@ -78,6 +85,20 @@ export async function MenuItemShow(text: string) {
}); });
} }
export async function MenuItemTheme() {
return await MenuItem.new({
id: "theme",
text: "主题切换",
action: async () => {
const mainStore = useMainStore();
mainStore.theme = !mainStore.theme;
// const appWindow = getCurrentWindow();
// appWindow.emitTo("main", "config", { theme: mainStore.theme });
await setTheme(mainStore.theme);
},
});
}
// export async function setTrayMenu(items: (MenuItem | PredefinedMenuItem)[] | undefined = undefined) { // export async function setTrayMenu(items: (MenuItem | PredefinedMenuItem)[] | undefined = undefined) {
// // const tray = await useTray() // // const tray = await useTray()
// const tray = await TrayIcon.getById(DEFAULT_TRAY_NAME) // const tray = await TrayIcon.getById(DEFAULT_TRAY_NAME)
@@ -98,8 +119,8 @@ export async function setTrayRunState(tray: TrayIcon | null, isRunning: boolean
export async function setTrayTooltip(tray: TrayIcon | null, tooltip?: string | null) { export async function setTrayTooltip(tray: TrayIcon | null, tooltip?: string | null) {
if (!tray) return; if (!tray) return;
if (tooltip) { if (tooltip) {
await tray.setTooltip(`EasyTier\n${pkg.version}\n${tooltip}`); await tray.setTooltip(`EasyTierGame\n${pkg.version}\n${tooltip}`);
} else { } else {
await tray.setTooltip(`EasyTier\n${pkg.version}`); await tray.setTooltip(`EasyTierGame\n${pkg.version}`);
} }
} }
+1 -1
View File
@@ -3,7 +3,7 @@
"private": true, "private": true,
"author": "leizi97", "author": "leizi97",
"description": "A simple network initiator based on Easytier", "description": "A simple network initiator based on Easytier",
"version": "1.1.1", "version": "1.1.3",
"scripts": { "scripts": {
"dev": "nuxt dev --dotenv env/.env.dev --host 0.0.0.0", "dev": "nuxt dev --dotenv env/.env.dev --host 0.0.0.0",
"build": "nuxt generate --dotenv env/.env.prod" "build": "nuxt generate --dotenv env/.env.prod"
+20 -17
View File
@@ -1,41 +1,44 @@
<template> <template>
<div class="h-full overflow-auto flex flex-col items-start px-[25px]"> <div class="h-full overflow-auto flex flex-col items-start px-[25px]">
<div><ElCheckbox v-model="mainStore.config.coonectAfterStart">软件启动后自动"启动联机"(搭配开机自启无感联机)</ElCheckbox></div>
<div><ElCheckbox v-model="mainStore.config.disableIpv6">不使用IPv6</ElCheckbox></div> <div><ElCheckbox v-model="mainStore.config.disableIpv6">不使用IPv6</ElCheckbox></div>
<div><ElCheckbox v-model="mainStore.config.disbleListenner">不监听任何端口只连接到对等节点</ElCheckbox></div> <div class="flex items-center gap-[10px]">
<div><ElCheckbox v-model="mainStore.config.enablExitNode">允许此节点成为出口节点</ElCheckbox></div> <ElCheckbox v-model="mainStore.config.devName">自定义网卡名</ElCheckbox>
<div><ElCheckbox v-model="mainStore.config.disableEncryption">禁用对等节点通信的加密默认为false必须与对等节点相同</ElCheckbox></div> <ElInput maxlength="10" v-model="mainStore.config.devNameValue" placeholder="请输入网卡名"/>
<div><ElCheckbox v-model="mainStore.config.multiThread">使用多线程运行时默认为单线程</ElCheckbox></div>
<div><ElCheckbox v-model="mainStore.config.noTun">不创建TUN设备可以使用子网代理访问节点</ElCheckbox></div>
<div><ElCheckbox v-model="mainStore.config.useSmoltcp">为子网代理启用smoltcp堆栈</ElCheckbox></div>
<div><ElCheckbox v-model="mainStore.config.latencyfirst">延迟优先模式将尝试使用最低延迟路径转发流量默认使用最短路径</ElCheckbox></div>
<div><ElCheckbox v-model="mainStore.config.disableUdpHolePunching">禁用UDP打洞功能</ElCheckbox></div>
<div>
<ElCheckbox v-model="mainStore.config.relayAllPeerrpc">转发所有对等节点的RPC数据包即使对等节点不在转发网络白名单内</ElCheckbox>
</div> </div>
<div><ElCheckbox v-model="mainStore.config.disbleListenner">不监听任何端口只连接到对等节点</ElCheckbox></div>
<div><ElCheckbox v-model="mainStore.config.coonectAfterStart">软件启动后自动"启动联机"(搭配开机自启无感联机)</ElCheckbox></div>
<div class="flex items-center gap-[15px] flex-nowrap"> <div class="flex items-center gap-[15px] flex-nowrap">
<ElCheckbox v-model="mainStore.config.saveErrorLog">输出日志到本地</ElCheckbox> <ElCheckbox v-model="mainStore.config.saveErrorLog">输出日志到本地</ElCheckbox>
<div class="w-[140px]"> <div class="w-[140px]">
<ElSelect <ElSelect
v-model="mainStore.config.logLevel" v-model="mainStore.config.logLevel"
placeholder="请选择日志等级" placeholder="请选择日志等级"
class="ml-[5px]" class="ml-[5px]">
>
<ElOption <ElOption
v-for="item in data" v-for="item in data"
:key="item" :key="item"
:label="`level - ${item}`" :label="`level - ${item}`"
:value="item" :value="item"></ElOption>
></ElOption>
</ElSelect> </ElSelect>
</div> </div>
<ElButton <ElButton
@click="openLogDir" @click="openLogDir"
size="small" size="small">
>
打开日志目录 打开日志目录
</ElButton> </ElButton>
</div> </div>
<ElDivider />
<div><ElCheckbox v-model="mainStore.config.enablExitNode">允许此节点成为出口节点</ElCheckbox></div>
<div><ElCheckbox v-model="mainStore.config.disableEncryption">禁用对等节点通信的加密默认为false必须与对等节点相同</ElCheckbox></div>
<div><ElCheckbox v-model="mainStore.config.multiThread">使用多线程运行时默认为单线程</ElCheckbox></div>
<ElDivider />
<div><ElCheckbox v-model="mainStore.config.noTun">不创建TUN设备可以使用子网代理访问节点</ElCheckbox></div>
<div><ElCheckbox v-model="mainStore.config.useSmoltcp">为子网代理启用smoltcp堆栈</ElCheckbox></div>
<div><ElCheckbox v-model="mainStore.config.latencyfirst">延迟优先模式将尝试使用最低延迟路径转发流量默认使用最短路径</ElCheckbox></div>
<div><ElCheckbox v-model="mainStore.config.disableUdpHolePunching">禁用UDP打洞功能</ElCheckbox></div>
<div>
<ElCheckbox v-model="mainStore.config.relayAllPeerrpc">转发所有对等节点的RPC数据包即使对等节点不在转发网络白名单内</ElCheckbox>
</div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
+3
View File
@@ -714,6 +714,9 @@
if (config.saveErrorLog) { if (config.saveErrorLog) {
args.push("--file-log-level", config.logLevel, "--file-log-dir", import.meta.env.VITE_LOG_PATH); args.push("--file-log-level", config.logLevel, "--file-log-dir", import.meta.env.VITE_LOG_PATH);
} }
if(config.devName && config.devNameValue) {
args.push("--dev-name", config.devNameValue);
}
return args; return args;
}; };
+10 -11
View File
@@ -5,13 +5,11 @@
<ElTable <ElTable
stripe stripe
:data="data.member" :data="data.member"
v-else v-else>
>
<ElTableColumn <ElTableColumn
v-for="prop in showTableHeader" v-for="prop in showTableHeader"
:label="prop[1]" :label="prop[1]"
:key="prop[0]" :key="prop[0]">
>
<template #default="{ row }"> <template #default="{ row }">
<span v-if="prop[0] == 'loss_rate'"> <span v-if="prop[0] == 'loss_rate'">
{{ row[prop[0]] && row[prop[0]] != "-" ? Number(row[prop[0]] * 100).toFixed(2) + "%" : row[prop[0]] }} {{ row[prop[0]] && row[prop[0]] != "-" ? Number(row[prop[0]] * 100).toFixed(2) + "%" : row[prop[0]] }}
@@ -20,8 +18,7 @@
<ElTag <ElTag
v-else v-else
effect="dark" effect="dark"
:type="row[prop[0]] == 'p2p' ? 'success' : 'info'" :type="row[prop[0]] == 'p2p' ? 'success' : 'info'">
>
{{ row[prop[0]] }} {{ row[prop[0]] }}
</ElTag> </ElTag>
</template> </template>
@@ -35,22 +32,23 @@
import { reactive, onMounted, onBeforeUnmount } from "vue"; import { reactive, onMounted, onBeforeUnmount } from "vue";
import { parsePeerInfo } from "@/utils"; import { parsePeerInfo } from "@/utils";
const data = reactive<{ member: any[] }>({ const data = reactive<{ member: any[] }>({
member: [] member: [],
}); });
const showTableHeader = [ const showTableHeader = [
["ipv4", "虚拟网IP"],
["hostname", "主机名"], ["hostname", "主机名"],
["cost", "路由"],
["lat_ms", "延迟/ms"], ["lat_ms", "延迟/ms"],
["ipv4", "虚拟网IP"],
["cost", "路由"],
["loss_rate", "丢包率"], ["loss_rate", "丢包率"],
["version", "版本"] ["nat_type", "NAT类型"],
["version", "版本"],
]; ];
const listenOutput = async () => { const listenOutput = async () => {
const member = await invoke("get_members_by_cli"); const member = await invoke("get_members_by_cli");
const peerInfo = parsePeerInfo(member as string); const peerInfo = parsePeerInfo(member as string);
peerInfo.forEach(value => { peerInfo.forEach((value) => {
if (value.cost === "Local") { if (value.cost === "Local") {
value.cost = "本机"; value.cost = "本机";
} }
@@ -58,6 +56,7 @@
value.ipv4 = value.ipv4.split("/")[0]; value.ipv4 = value.ipv4.split("/")[0];
} }
}); });
console.log(peerInfo);
data.member = peerInfo; data.member = peerInfo;
}; };
+1 -1
View File
@@ -1109,7 +1109,7 @@ checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125"
[[package]] [[package]]
name = "easytier-game" name = "easytier-game"
version = "1.1.1" version = "1.1.3"
dependencies = [ dependencies = [
"log", "log",
"planif", "planif",
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "easytier-game" name = "easytier-game"
version = "1.1.1" version = "1.1.3"
homepage = "https://github.com/EasyTier/EasyTier" homepage = "https://github.com/EasyTier/EasyTier"
repository = "https://github.com/EasyTier/EasytierGame" repository = "https://github.com/EasyTier/EasytierGame"
description = "A simple network initiator based on Easytier" description = "A simple network initiator based on Easytier"
+2 -2
View File
@@ -1,7 +1,7 @@
{ {
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json", "$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"productName": "easytier-game", "productName": "easytier-game",
"version": "1.1.0", "version": "1.1.3",
"identifier": "com.tauri.easytier-game", "identifier": "com.tauri.easytier-game",
"build": { "build": {
@@ -13,7 +13,7 @@
"app": { "app": {
"windows": [ "windows": [
{ {
"title": "easytier-game 1.1.1", "title": "easytier-game 1.1.3",
"width": 335, "width": 335,
"height": 305, "height": 305,
"resizable": false, "resizable": false,
+7 -1
View File
@@ -26,7 +26,10 @@ export default defineStore("main", {
dhcp: true, // 是否使用DHCP dhcp: true, // 是否使用DHCP
saveErrorLog: true, // 是否保存错误日志 saveErrorLog: true, // 是否保存错误日志
logLevel: "error", //日志等级 logLevel: "error", //日志等级
devName: false, //自定义网卡名
devNameValue: "", //自定义网卡名
}, },
theme: false, //主题 false light true dark
configStartEnable: false, //使用配置文件启动 configStartEnable: false, //使用配置文件启动
configPath: "", //配置文件路径 configPath: "", //配置文件路径
cidrEnable: false, cidrEnable: false,
@@ -37,6 +40,7 @@ export default defineStore("main", {
paths: [ paths: [
"basePeers", "basePeers",
"cidrEnable", "cidrEnable",
"theme",
"config.proxyNetworks", "config.proxyNetworks",
"config.serverUrl", "config.serverUrl",
"config.networkName", "config.networkName",
@@ -58,7 +62,9 @@ export default defineStore("main", {
"config.hostname", "config.hostname",
"config.dhcp", "config.dhcp",
"config.saveErrorLog", "config.saveErrorLog",
"config.logLevel" "config.logLevel",
"config.devName",
"config.devNameValue",
], ],
}, },
}); });
+1
View File
@@ -6,6 +6,7 @@
"components/**/*.ts", "components/**/*.ts",
"components/**/*.js", "components/**/*.js",
"components/**/*.vue", "components/**/*.vue",
"app.vue",
"pages/**/*.ts", "pages/**/*.ts",
"pages/**/*.js", "pages/**/*.js",
"pages/**/*.vue", "pages/**/*.vue",