refine i18n, fill in miss parts

fix resetTrust cant recover send button in UI
This commit is contained in:
2026-02-07 14:11:57 +08:00
parent 4b5d2b656b
commit 20a25e8c49
12 changed files with 140 additions and 38 deletions

2
.vscode/launch.json vendored
View File

@@ -9,7 +9,7 @@
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/main.go",
"program": "${workspaceFolder}",
"preLaunchTask": "build frontend"
}
]

View File

@@ -9,8 +9,8 @@ import { Call as $Call, CancellablePromise as $CancellablePromise, Create as $Cr
// @ts-ignore: Unused imports
import * as $models from "./models.js";
export function AddTrustedPeer(peerID: string, publicKey: string): $CancellablePromise<void> {
return $Call.ByID(2866399505, peerID, publicKey);
export function AddTrust(peerID: string, publicKey: string): $CancellablePromise<void> {
return $Call.ByID(2986105628, peerID, publicKey);
}
export function GetAutoAccept(): $CancellablePromise<boolean> {
@@ -41,8 +41,8 @@ export function GetSavePath(): $CancellablePromise<string> {
return $Call.ByID(4081533263);
}
export function GetTrustedPeer(): $CancellablePromise<{ [_: string]: string }> {
return $Call.ByID(1253442080).then(($result: any) => {
export function GetTrusted(): $CancellablePromise<{ [_: string]: string }> {
return $Call.ByID(800326956).then(($result: any) => {
return $$createType0($result);
});
}
@@ -57,12 +57,12 @@ export function GetWindowState(): $CancellablePromise<$models.WindowState> {
});
}
export function IsTrustedPeer(peerID: string): $CancellablePromise<boolean> {
return $Call.ByID(3452062706, peerID);
export function IsTrusted(peerID: string): $CancellablePromise<boolean> {
return $Call.ByID(1255607538, peerID);
}
export function RemoveTrustedPeer(peerID: string): $CancellablePromise<void> {
return $Call.ByID(909233322, peerID);
export function RemoveTrust(peerID: string): $CancellablePromise<void> {
return $Call.ByID(732981195, peerID);
}
/**

View File

@@ -15,15 +15,15 @@ import {
} from "../../bindings/mesh-drop/internal/transfer/service";
import { Peer } from "../../bindings/mesh-drop/internal/discovery/models";
import {
IsTrustedPeer,
AddTrustedPeer,
RemoveTrustedPeer,
IsTrusted,
AddTrust,
RemoveTrust,
} from "../../bindings/mesh-drop/internal/config/config";
// --- 生命周期 ---
onMounted(async () => {
try {
isTrusted.value = await IsTrustedPeer(props.peer.id);
isTrusted.value = await IsTrusted(props.peer.id);
} catch (err) {
console.error("Failed to check trusted peer status:", err);
}
@@ -136,7 +136,7 @@ const handleSendFolder = async () => {
SendFolder(props.peer, selectedIp.value, folderPath as string).catch((e) => {
console.error(e);
alert("Failed to send folder: " + e);
alert(t("discover.sendFolderFailed", { error: e }));
});
emit("transferStarted");
};
@@ -150,19 +150,21 @@ const handleSendClipboard = async () => {
}
SendText(props.peer, selectedIp.value, text).catch((e) => {
console.error(e);
alert("Failed to send clipboard: " + e);
alert(t("discover.sendClipboardFailed", { error: e }));
});
emit("transferStarted");
};
const handleTrust = () => {
AddTrustedPeer(props.peer.id, props.peer.pk);
AddTrust(props.peer.id, props.peer.pk);
isTrusted.value = true;
};
const handleUntrust = () => {
RemoveTrustedPeer(props.peer.id);
RemoveTrust(props.peer.id);
isTrusted.value = false;
props.peer.trust_mismatch = false;
};
</script>
@@ -226,9 +228,9 @@ const handleUntrust = () => {
variant="tonal"
prepend-icon="mdi-alert"
:ripple="false"
style="pointer-events: none"
style="pointer-events: none; min-width: 0"
>
{{ t("discover.mismatch") }}
<span class="text-truncate">{{ t("discover.mismatch") }}</span>
</v-btn>
<v-menu v-else>

View File

@@ -51,7 +51,7 @@ onMounted(async () => {
// --- 方法 ---
const changeSavePath = async () => {
const opts: Dialogs.OpenFileDialogOptions = {
Title: "Select Save Path",
Title: t("settings.selectSavePath"),
CanChooseDirectories: true,
CanChooseFiles: false,
AllowsMultipleSelection: false,

View File

@@ -7,7 +7,10 @@
"edit": "Edit",
"loading": "Loading...",
"success": "Success",
"error": "Error"
"error": "Error",
"accept": "Accept",
"reject": "Reject",
"copy": "Copy"
},
"menu": {
"discover": "Discover",
@@ -17,7 +20,20 @@
"discover": {
"scanning": "Scanning for peers...",
"noPeers": "No peers found",
"send": "Send"
"send": "Send",
"sendFiles": "Send Files",
"sendFolder": "Send Folder",
"sendText": "Send Text",
"sendClipboard": "Send Clipboard",
"selectFolder": "Select Folder",
"clipboardEmpty": "Clipboard is empty",
"noRoute": "No Route",
"mismatch": "Trust Mismatch",
"resetTrust": "Reset Trust",
"trustPeer": "Trust Peer",
"untrustPeer": "Untrust Peer",
"sendFolderFailed": "Failed to send folder: {error}",
"sendClipboardFailed": "Failed to send clipboard: {error}"
},
"transfers": {
"noTransfers": "No transfers yet",
@@ -26,7 +42,16 @@
"transferring": "Transferring",
"completed": "Completed",
"failed": "Failed",
"cancelled": "Cancelled"
"cancelled": "Cancelled",
"selectSavePath": "Select Save Path",
"text": "Text",
"folder": "Folder",
"securityAlert": "Security Alert",
"rejected": "Rejected",
"waitingForAccept": "Waiting for accept",
"saveToFolder": "Save to Folder",
"viewContent": "View Content",
"textContent": "Text Content"
},
"settings": {
"savePath": "Save Path",
@@ -35,6 +60,7 @@
"saveHistory": "Save History",
"autoAccept": "Auto Accept",
"version": "Version",
"language": "Language"
"language": "Language",
"selectSavePath": "Select Save Path"
}
}

View File

@@ -7,7 +7,10 @@
"edit": "编辑",
"loading": "加载中...",
"success": "成功",
"error": "错误"
"error": "错误",
"accept": "接收",
"reject": "拒绝",
"copy": "复制"
},
"menu": {
"discover": "发现",
@@ -17,7 +20,20 @@
"discover": {
"scanning": "正在扫描设备...",
"noPeers": "未发现设备",
"send": "发送"
"send": "发送",
"sendFiles": "发送文件",
"sendFolder": "发送文件夹",
"sendText": "发送文本",
"sendClipboard": "发送剪贴板",
"selectFolder": "选择文件夹",
"clipboardEmpty": "剪贴板为空",
"noRoute": "不可达",
"mismatch": "信任不匹配",
"resetTrust": "重置信任",
"trustPeer": "信任设备",
"untrustPeer": "取消信任",
"sendFolderFailed": "发送文件夹失败: {error}",
"sendClipboardFailed": "发送剪贴板失败: {error}"
},
"transfers": {
"noTransfers": "暂无传输记录",
@@ -26,7 +42,16 @@
"transferring": "传输中",
"completed": "已完成",
"failed": "失败",
"cancelled": "已取消"
"cancelled": "已取消",
"selectSavePath": "选择保存路径",
"text": "文本",
"folder": "文件夹",
"securityAlert": "安全警告",
"rejected": "已拒绝",
"waitingForAccept": "等待接收",
"saveToFolder": "保存到文件夹",
"viewContent": "查看内容",
"textContent": "文本内容"
},
"settings": {
"savePath": "保存路径",
@@ -35,6 +60,7 @@
"saveHistory": "保存历史记录",
"autoAccept": "自动接收",
"version": "版本",
"language": "语言"
"language": "语言",
"selectSavePath": "选择保存路径"
}
}

View File

@@ -254,7 +254,7 @@ func (c *Config) GetWindowState() WindowState {
return c.WindowState
}
func (c *Config) AddTrustedPeer(peerID string, publicKey string) {
func (c *Config) AddTrust(peerID string, publicKey string) {
c.mu.Lock()
defer c.mu.Unlock()
if c.TrustedPeer == nil {
@@ -265,13 +265,13 @@ func (c *Config) AddTrustedPeer(peerID string, publicKey string) {
_ = c.save()
}
func (c *Config) GetTrustedPeer() map[string]string {
func (c *Config) GetTrusted() map[string]string {
c.mu.RLock()
defer c.mu.RUnlock()
return c.TrustedPeer
}
func (c *Config) RemoveTrustedPeer(peerID string) {
func (c *Config) RemoveTrust(peerID string) {
c.mu.Lock()
defer c.mu.Unlock()
delete(c.TrustedPeer, peerID)
@@ -279,7 +279,7 @@ func (c *Config) RemoveTrustedPeer(peerID string) {
_ = c.save()
}
func (c *Config) IsTrustedPeer(peerID string) bool {
func (c *Config) IsTrusted(peerID string) bool {
c.mu.RLock()
defer c.mu.RUnlock()
_, exists := c.TrustedPeer[peerID]

View File

@@ -228,7 +228,7 @@ func (s *Service) startListening() {
// 验证身份一致性 (防止 ID 欺骗)
trustMismatch := false
trustedKeys := s.config.GetTrustedPeer()
trustedKeys := s.config.GetTrusted()
if knownKey, ok := trustedKeys[packet.ID]; ok {
if knownKey != packet.PublicKey {
slog.Warn("SECURITY ALERT: Peer ID mismatch with known public key (Spoofing attempt?)", "id", packet.ID, "known_key", knownKey, "received_key", packet.PublicKey)
@@ -236,6 +236,13 @@ func (s *Service) startListening() {
// 当发现 ID 欺骗时,不更新 peer而是标记为 trustMismatch
// 用户可以手动重新添加信任
}
} else {
// 不存在于信任列表
// 存在之前在信任列表,但是不匹配被用户手动重置了,此时需要将 peer.TrustMismatch 标记为 false
// 否则在 handleHeartbeat 里会一直标记为不匹配
if peer, ok := s.peers[packet.ID]; ok {
peer.TrustMismatch = false
}
}
s.handleHeartbeat(packet, remoteAddr.IP.String(), trustMismatch)

View File

@@ -49,7 +49,7 @@ func (s *Service) handleAsk(c *gin.Context) {
task.Sender.TrustMismatch = peer.TrustMismatch
}
if s.config.GetAutoAccept() || (s.config.IsTrustedPeer(task.Sender.ID) && !task.Sender.TrustMismatch) {
if s.config.GetAutoAccept() || (s.config.IsTrusted(task.Sender.ID) && !task.Sender.TrustMismatch) {
task.DecisionChan <- Decision{
ID: task.ID,
Accepted: true,

View File

@@ -81,6 +81,9 @@ func main() {
},
})
// 设置系统托盘
setupSystray(app, window)
// 窗口文件拖拽事件
window.OnWindowEvent(events.Common.WindowFilesDropped, func(event *application.WindowEvent) {
files := event.Context().DroppedFiles()
@@ -91,10 +94,6 @@ func main() {
})
})
// 窗口关闭事件
// window.OnWindowEvent(events.Common.WindowClosing, func(event *application.WindowEvent) {
// })
// 应用关闭事件
app.OnShutdown(func() {
x, y := window.Position()

7
systray.go Normal file
View File

@@ -0,0 +1,7 @@
//go:build !windows
package main
import "github.com/wailsapp/wails/v3/pkg/application"
func setupSystray(app *application.App, window *application.WebviewWindow) {}

35
systray_windows.go Normal file
View File

@@ -0,0 +1,35 @@
//go:build windows
package main
import (
"github.com/wailsapp/wails/v3/pkg/application"
"github.com/wailsapp/wails/v3/pkg/events"
)
func setupSystray(app *application.App, window *application.WebviewWindow) {
systray := app.SystemTray.New()
systray.SetIcon(icon)
systray.SetLabel("Mesh Drop")
menu := app.NewMenu()
menu.Add("Quit").OnClick(func(ctx *application.Context) {
app.Quit()
})
systray.OnClick(func() {
if window.IsVisible() {
window.Hide()
} else {
window.Show()
window.Focus()
}
})
systray.SetMenu(menu)
window.OnWindowEvent(events.Common.WindowClosing, func(event *application.WindowEvent) {
event.Cancel()
window.Hide()
})
}