mirror of
https://github.com/HugoAura/Seewo-HugoAura.git
synced 2026-06-22 08:05:55 +08:00
[🚧 Fix] <PLS & FS> Improve PLS download logic & UX
1. [+] 增加了 PLS 下载操作的取消功能 2. [/] 修复了 FS IPC 中 `downloadFile` 时, 过早地从 downloadTasks 中删除任务的逻辑错误。 3. [↑] 改进了 PLS IPC 中 `handlePLSDownload` 获取版本信息时的逻辑, 现在该函数会从全局 API 信息中逐个尝试 API 域名。减少了极端网络环境下, 版本信息获取失败的可能性。 4. [/] 修复了下载失败后, 下载按钮依然保持灰显的问题。 5. [+] 为 PLS 下载增加了进度条显示。 6. [/] 优化了 `plsConnectionManager` 中一些不必要的 IPC 状态同步 (有些时候还会导致逻辑错误)。
This commit is contained in:
@@ -38,10 +38,13 @@ const composableFunctions = {
|
||||
progressCallback(failedTemplate);
|
||||
return false;
|
||||
}
|
||||
if (!fs.existsSync(path.dirname(targetPath))) {
|
||||
failedTemplate.message = "Path not exists";
|
||||
progressCallback(failedTemplate);
|
||||
|
||||
const dirName = path.dirname(targetPath);
|
||||
|
||||
if (!fs.existsSync(dirName)) {
|
||||
fs.mkdirSync(dirName);
|
||||
}
|
||||
|
||||
const httpModuleIns = url.startsWith("https") ? nodeHttps : nodeHttp;
|
||||
|
||||
global.__HUGO_AURA__.fsTasks?.downloadTasks.set(taskId, {
|
||||
@@ -49,6 +52,14 @@ const composableFunctions = {
|
||||
cancelReq: null,
|
||||
});
|
||||
|
||||
progressCallback({
|
||||
id: taskId,
|
||||
progress: 0,
|
||||
status: "waiting",
|
||||
dlUrl: url,
|
||||
savePath: targetPath,
|
||||
});
|
||||
|
||||
const fsStream = fs.createWriteStream(targetPath);
|
||||
|
||||
const dlReq = httpModuleIns.get(url, (response) => {
|
||||
@@ -64,9 +75,12 @@ const composableFunctions = {
|
||||
const totalBytes = parseInt(contentLength, 10) || 0; // No error handling 😆
|
||||
let curRecvBytes = 0;
|
||||
|
||||
let hasCancelled = false;
|
||||
|
||||
global.__HUGO_AURA__.fsTasks?.downloadTasks.set(taskId, {
|
||||
status: "progressing",
|
||||
cancelReq: () => {
|
||||
hasCancelled = true;
|
||||
dlReq.destroy();
|
||||
fsStream.close();
|
||||
fs.unlink(targetPath, () => {});
|
||||
@@ -102,6 +116,9 @@ const composableFunctions = {
|
||||
|
||||
fsStream.on("finish", () => {
|
||||
fsStream.close();
|
||||
if (hasCancelled) {
|
||||
return;
|
||||
}
|
||||
progressCallback({
|
||||
id: taskId,
|
||||
progress: (100).toFixed(2),
|
||||
@@ -111,9 +128,9 @@ const composableFunctions = {
|
||||
dlUrl: url,
|
||||
savePath: targetPath,
|
||||
});
|
||||
global.__HUGO_AURA__.fsTasks?.downloadTasks.delete(taskId);
|
||||
});
|
||||
|
||||
global.__HUGO_AURA__.fsTasks?.downloadTasks.delete(taskId);
|
||||
return true;
|
||||
});
|
||||
|
||||
@@ -123,7 +140,10 @@ const composableFunctions = {
|
||||
failedTemplate.message =
|
||||
"Request error: Unexpected error while downloading file";
|
||||
failedTemplate.errorObj = e;
|
||||
console.error(`[HugoAura / IPC / FS / ERROR] Error downloading file from ${url}, errorObj:`, e);
|
||||
console.error(
|
||||
`[HugoAura / IPC / FS / ERROR] Error downloading file from ${url}, errorObj:`,
|
||||
e
|
||||
);
|
||||
progressCallback(failedTemplate);
|
||||
global.__HUGO_AURA__.fsTasks?.downloadTasks.delete(taskId);
|
||||
return false;
|
||||
|
||||
@@ -71,34 +71,92 @@ const functions = {
|
||||
handlePLSDownload: async (channel, callbackFn, binPath) => {
|
||||
// TODO: Channel selection
|
||||
const apiInfo = global.__HUGO_AURA_API__;
|
||||
let plsVersionInfo = {};
|
||||
|
||||
const getVerPromise = new Promise((resolve) => {
|
||||
const getVerPromise = new Promise(async (resolveGetVerReq) => {
|
||||
// ↓ 目前 channel param 没有什么用处
|
||||
nodeHttps
|
||||
.get(
|
||||
`${apiInfo.baseUrl}${apiInfo.plsUpdate}?channel=${channel}`,
|
||||
(rep) => {
|
||||
let dataChunk = "";
|
||||
rep.on("data", (chunk) => {
|
||||
dataChunk += chunk;
|
||||
});
|
||||
for (const apiDomain of apiInfo.domains) {
|
||||
const reqPromise = new Promise((resolveHttpRequest) => {
|
||||
nodeHttps
|
||||
.get(
|
||||
`${apiDomain}${apiInfo.plsUpdate}?channel=${channel}`,
|
||||
(rep) => {
|
||||
let dataChunk = "";
|
||||
rep.on("data", (chunk) => {
|
||||
dataChunk += chunk;
|
||||
});
|
||||
|
||||
rep.on("end", () => {
|
||||
resolve({
|
||||
success: true,
|
||||
data: dataChunk,
|
||||
rep.on("end", () => {
|
||||
let parsedData = {};
|
||||
try {
|
||||
parsedData = JSON.parse(dataChunk);
|
||||
} catch (e) {
|
||||
callbackFn({
|
||||
id: "",
|
||||
progress: 0,
|
||||
status: "struggling",
|
||||
dlUrl: null,
|
||||
savePath: null,
|
||||
message: `数据解析失败, 正在尝试 API 域名 ${
|
||||
apiInfo.domains[apiInfo.domains.indexOf(apiDomain) + 1]
|
||||
} ...`,
|
||||
errorObj: e,
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
resolveHttpRequest({
|
||||
success: false,
|
||||
errorObj: e,
|
||||
});
|
||||
}, 1000);
|
||||
return;
|
||||
}
|
||||
|
||||
resolveHttpRequest({
|
||||
success: true,
|
||||
data: parsedData,
|
||||
});
|
||||
return;
|
||||
});
|
||||
}
|
||||
)
|
||||
.on("error", (e) => {
|
||||
callbackFn({
|
||||
id: "",
|
||||
progress: 0,
|
||||
status: "struggling",
|
||||
dlUrl: null,
|
||||
savePath: null,
|
||||
message: `连接失败, 正在尝试 API 域名 ${
|
||||
apiInfo.domains[apiInfo.domains.indexOf(apiDomain) + 1]
|
||||
} ...`,
|
||||
errorObj: e,
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
resolveHttpRequest({
|
||||
success: false,
|
||||
errorObj: e,
|
||||
});
|
||||
}, 1000);
|
||||
});
|
||||
}
|
||||
)
|
||||
.on("error", (e) => {
|
||||
resolve({
|
||||
success: false,
|
||||
data: null,
|
||||
errorObj: e,
|
||||
});
|
||||
});
|
||||
|
||||
const requestResult = await reqPromise;
|
||||
if (requestResult.success) {
|
||||
resolveGetVerReq({
|
||||
success: true,
|
||||
data: requestResult.data,
|
||||
});
|
||||
break;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
resolveGetVerReq({
|
||||
success: false,
|
||||
data: null,
|
||||
});
|
||||
});
|
||||
|
||||
const rawResInfo = await getVerPromise;
|
||||
@@ -109,30 +167,12 @@ const functions = {
|
||||
status: "failed",
|
||||
dlUrl: null,
|
||||
savePath: null,
|
||||
message: "未能获取 PLS 版本信息",
|
||||
errorObj: rawResInfo.errorObj ? rawResInfo.errorObj : null,
|
||||
message: "未能获取 PLS 版本信息, 所有 API 域名均无法连接",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
plsVersionInfo = JSON.parse(rawResInfo.data);
|
||||
} catch (e) {
|
||||
callbackFn({
|
||||
id: "",
|
||||
progress: 0,
|
||||
status: "failed",
|
||||
dlUrl: null,
|
||||
savePath: null,
|
||||
message: "PLS 版本信息解析失败",
|
||||
errorObj: e,
|
||||
});
|
||||
console.error(
|
||||
"[HugoAura / IPC / PLS] Error querying PLS version info:",
|
||||
e
|
||||
);
|
||||
return false;
|
||||
}
|
||||
const plsVersionInfo = rawResInfo.data;
|
||||
|
||||
let deviceArch = process.env.PROCESSOR_ARCHITEW6432
|
||||
? process.env.PROCESSOR_ARCHITEW6432
|
||||
@@ -155,7 +195,16 @@ const functions = {
|
||||
fsComposables.downloadFile(
|
||||
plsVersionInfo.data.downloadUrl[deviceArch],
|
||||
binPath,
|
||||
callbackFn
|
||||
(...args) => {
|
||||
if (args[0].status === "done") {
|
||||
if (global.__HUGO_AURA__.plsStats) {
|
||||
global.__HUGO_AURA__.plsStats.installed = true;
|
||||
global.__HUGO_AURA__.plsStats.status = "dead";
|
||||
}
|
||||
}
|
||||
|
||||
callbackFn(...args);
|
||||
}
|
||||
);
|
||||
},
|
||||
};
|
||||
@@ -192,11 +241,18 @@ const applyPlsIpcHandler = (ipcMain) => {
|
||||
(_event, _arg) => {
|
||||
try {
|
||||
const result = fs.existsSync(PLS_BIN_PATH);
|
||||
|
||||
if (global.__HUGO_AURA__.plsStats?.status === "notInstalled") {
|
||||
global.__HUGO_AURA__.plsStats.status = "dead";
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: { isExists: result },
|
||||
};
|
||||
} catch (e) {
|
||||
// @ts-expect-error
|
||||
global.__HUGO_AURA__.plsStats.status = "notInstalled";
|
||||
return {
|
||||
success: false,
|
||||
data: { isExists: false },
|
||||
|
||||
Reference in New Issue
Block a user