feat(desktop): native download and working context menu actions
This commit is contained in:
@@ -270,6 +270,17 @@ function showToast(message: string, type = "info") {
|
||||
}, 2500);
|
||||
}
|
||||
|
||||
function prependTransferTask(task: { id: string; name: string; speed: string; progress: number; status: string }) {
|
||||
transferTasks.value = [task, ...transferTasks.value.slice(0, 49)];
|
||||
}
|
||||
|
||||
function updateTransferTask(
|
||||
id: string,
|
||||
patch: Partial<{ name: string; speed: string; progress: number; status: string }>,
|
||||
) {
|
||||
transferTasks.value = transferTasks.value.map((task) => (task.id === id ? { ...task, ...patch } : task));
|
||||
}
|
||||
|
||||
async function invokeBridge(command: string, payload: Record<string, any>) {
|
||||
try {
|
||||
return await invoke<BridgeResponse>(command, payload);
|
||||
@@ -328,6 +339,20 @@ async function loadShares(silent = false) {
|
||||
if (!silent) sharesLoading.value = false;
|
||||
}
|
||||
|
||||
async function getSignedUrlForItem(item: FileItem, mode: "download" | "preview") {
|
||||
const targetPath = buildItemPath(item);
|
||||
const response = await invokeBridge("api_get_download_url", {
|
||||
baseUrl: appConfig.baseUrl,
|
||||
path: targetPath,
|
||||
mode,
|
||||
});
|
||||
if (response.ok && response.data?.success && response.data?.downloadUrl) {
|
||||
return String(response.data.downloadUrl);
|
||||
}
|
||||
showToast(response.data?.message || "获取链接失败", "error");
|
||||
return "";
|
||||
}
|
||||
|
||||
async function createShareForItem(current: FileItem) {
|
||||
const response = await invokeBridge("api_create_share", {
|
||||
baseUrl: appConfig.baseUrl,
|
||||
@@ -571,28 +596,32 @@ async function downloadSelected(target?: FileItem | null) {
|
||||
showToast("当前仅支持下载文件", "info");
|
||||
return;
|
||||
}
|
||||
const targetPath = buildItemPath(current);
|
||||
const response = await invokeBridge("api_get_download_url", {
|
||||
baseUrl: appConfig.baseUrl,
|
||||
path: targetPath,
|
||||
mode: "download",
|
||||
const signedUrl = await getSignedUrlForItem(current, "download");
|
||||
if (!signedUrl) return;
|
||||
|
||||
const taskId = `D-${Date.now()}`;
|
||||
prependTransferTask({
|
||||
id: taskId,
|
||||
name: current.displayName || current.name,
|
||||
speed: "原生下载",
|
||||
progress: 1,
|
||||
status: "downloading",
|
||||
});
|
||||
if (response.ok && response.data?.success && response.data?.downloadUrl) {
|
||||
await openUrl(response.data.downloadUrl);
|
||||
showToast("已调用系统浏览器开始下载", "success");
|
||||
transferTasks.value = [
|
||||
{
|
||||
id: `D-${Date.now()}`,
|
||||
name: current.displayName || current.name,
|
||||
speed: "直连",
|
||||
progress: 100,
|
||||
status: "dispatched",
|
||||
},
|
||||
...transferTasks.value.slice(0, 29),
|
||||
];
|
||||
|
||||
const nativeResponse = await invokeBridge("api_native_download", {
|
||||
url: signedUrl,
|
||||
fileName: current.displayName || current.name,
|
||||
});
|
||||
|
||||
if (nativeResponse.ok && nativeResponse.data?.success) {
|
||||
updateTransferTask(taskId, { speed: "-", progress: 100, status: "done" });
|
||||
const savedPath = nativeResponse.data?.savePath ? `\n${nativeResponse.data.savePath}` : "";
|
||||
showToast(`下载完成${savedPath}`, "success");
|
||||
return;
|
||||
}
|
||||
showToast(response.data?.message || "获取下载链接失败", "error");
|
||||
|
||||
updateTransferTask(taskId, { speed: "-", progress: 0, status: "failed" });
|
||||
showToast(nativeResponse.data?.message || "原生下载失败", "error");
|
||||
}
|
||||
|
||||
function selectFile(item: FileItem) {
|
||||
@@ -604,6 +633,11 @@ async function openItem(item: FileItem) {
|
||||
if (item.isDirectory || item.type === "directory") {
|
||||
const nextPath = buildItemPath(item);
|
||||
await loadFiles(nextPath);
|
||||
return;
|
||||
}
|
||||
const previewUrl = await getSignedUrlForItem(item, "preview");
|
||||
if (previewUrl) {
|
||||
await openUrl(previewUrl);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -921,7 +955,7 @@ onBeforeUnmount(() => {
|
||||
@click.stop
|
||||
>
|
||||
<button class="context-item" @click="executeContextAction('open')">
|
||||
{{ contextMenu.item.isDirectory ? "打开文件夹" : "打开/下载" }}
|
||||
{{ contextMenu.item.isDirectory ? "打开文件夹" : "打开预览" }}
|
||||
</button>
|
||||
<button v-if="!contextMenu.item.isDirectory" class="context-item" @click="executeContextAction('download')">下载文件</button>
|
||||
<button class="context-item" @click="executeContextAction('rename')">重命名</button>
|
||||
|
||||
Reference in New Issue
Block a user