Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,12 @@ windows-sys = { version = "0.61", features = [
"Win32_System_Environment",
# explorer.exe 按 Windows 目录拼全路径,不按 PATH 找(`clients::explorer`)
"Win32_System_SystemInformation",
# 启动时看 Alt 键有没有按着:按着就先显示连接选择(`connection::launch`)
"Win32_UI_Input_KeyboardAndMouse",
# 数据目录建成只有自己能读(受保护的 DACL),见 `private_dir`
"Win32_Security",
"Win32_Security_Authorization",
"Win32_Storage_FileSystem",
] }
# 系统通知走 WinRT 的 toast:能原地更新、撤回、点开落到对应页面(见
# `notices/windows/`)。版本跟着 Tauri 在 Windows 上已经拉进来的那一份,不多编一套
Expand Down
29 changes: 29 additions & 0 deletions src-tauri/build.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,32 @@
fn main() {
core_tag();
tauri_build::build()
}

/// 这一版应用配的是哪一版 core:`Cargo.lock` 里 tw-api 锁到的 tag,去掉开头的 `v`。
///
/// 连远程 core 时版本对不上,界面要说出「本应用需要 core X」。**从锁文件读,不另写
/// 一份**:打包脚本取 twcore 看的也是这一行(`scripts/fetch-core.sh`),两处说的
/// 必然是同一版。读不到(临时用 `[patch]` 指向本地 core 时就是这样)记成 `dev`
fn core_tag() {
println!("cargo:rerun-if-changed=Cargo.lock");
let lock = std::fs::read_to_string("Cargo.lock").unwrap_or_default();
let mut in_api = false;
let mut tag = None;
for line in lock.lines() {
if line.starts_with("name = ") {
in_api = line == "name = \"tw-api\"";
} else if in_api
&& line.starts_with("source = ")
&& let Some(i) = line.find("tag=v")
{
let rest = &line[i + "tag=v".len()..];
let end = rest.find(['#', '&', '"']).unwrap_or(rest.len());
tag = Some(rest[..end].to_string());
}
}
println!(
"cargo:rustc-env=TW_CORE_TAG={}",
tag.unwrap_or_else(|| "dev".into())
);
}
13 changes: 13 additions & 0 deletions src-tauri/capabilities/picker.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "picker",
"description": "启动时的连接选择。按内容定好高度(picker_fit,走 Rust)之后自己亮出来、拿焦点;选好之后由 Rust 关掉它(pick_connection)。别的都不需要。",
"windows": [
"picker"
],
"permissions": [
"core:default",
"core:window:allow-show",
"core:window:allow-set-focus"
]
}
47 changes: 47 additions & 0 deletions src-tauri/src/clients.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,50 @@ fn reveal(path: &str) -> Result<(), String> {
)
.to_string())
}

/// 这台机器上已接管、还指着本机网关的客户端。切到远程之前的确认里说(「已接管的 3 个
/// 客户端仍指向本机网关 127.0.0.1:8788」)
#[derive(Debug, Clone, Default, serde::Serialize)]
pub struct Adopted {
pub count: usize,
/// 本机网关此刻的地址
pub local_addr: Option<String>,
}

/// 数一数这台机器上已接管、还指着本机网关的客户端。**数不出来就当没有**:确认框里
/// 少说一条提醒,不该挡住切换。
///
/// TODO(P3):客户端接管整块搬进 lite 之后,改成问 lite 自己的扫描;现在还是问本机
/// core 的 `/clients`(`control` 必须是本机那一个,见 `Supervisor::control`)。
pub async fn adopted_pointing_at_local(control: &crate::control::ControlClient) -> Adopted {
let (clients, status) = tokio::join!(control.call::<ep::Clients>(&[], &()), control.status());
let local_addr = status.ok().and_then(|s| s.gateway_addr);
let count = match (&clients, &local_addr) {
(Ok(list), Some(addr)) => list
.clients
.iter()
.filter(|c| c.adopted_at_ms.is_some())
.filter(|c| {
c.endpoint
.as_deref()
.is_none_or(|e| e.contains(addr.as_str()))
})
.count(),
_ => 0,
};
Adopted { count, local_addr }
}

/// 把这台机器上已接管的客户端改为指向 `gateway_addr`(远程服务器的网关)。返回改了
/// 几个。切换确认里勾了「同时将这些客户端改为指向…」时调。
///
/// TODO(P3):接管搬进 lite 之后在这里接上 —— 对每个已接管、指着本机网关的客户端,
/// 用 lite 侧的接管代码把端点换成 `http://{gateway_addr}`,密钥换成服务器上为它发放的
/// 专用密钥。在那之前如实说做不到,不假装改过了。
pub async fn retarget_adopted_clients(
app: &tauri::AppHandle,
gateway_addr: &str,
) -> anyhow::Result<usize> {
let _ = app;
anyhow::bail!("retargeting adopted clients to {gateway_addr} is not implemented yet (P3)")
}
Loading
Loading