mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-01-02 18:39:05 +01:00
Download File Option (#80)
This adds to the context menu to give the ability to download a file. It also fixes a couple bugs and improves some formatting of the directory view.
This commit is contained in:
parent
566f6764c2
commit
0a8c97858c
@ -1,6 +1,7 @@
|
|||||||
// Copyright 2024, Command Line Inc.
|
// Copyright 2024, Command Line Inc.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import { getBackendHostPort } from "@/app/store/global";
|
||||||
import * as keyutil from "@/util/keyutil";
|
import * as keyutil from "@/util/keyutil";
|
||||||
import * as electron from "electron";
|
import * as electron from "electron";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
@ -421,6 +422,13 @@ electron.ipcMain.on("getPlatform", (event) => {
|
|||||||
event.returnValue = unamePlatform;
|
event.returnValue = unamePlatform;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
electron.ipcMain.on("download", (event, payload) => {
|
||||||
|
const window = electron.BrowserWindow.fromWebContents(event.sender);
|
||||||
|
const baseName = payload.filePath.split(/[\\/]/).pop();
|
||||||
|
const streamingUrl = getBackendHostPort() + "/wave/stream-file?path=" + encodeURIComponent(payload.filePath);
|
||||||
|
window.webContents.downloadURL(streamingUrl);
|
||||||
|
});
|
||||||
|
|
||||||
electron.ipcMain.on("getCursorPoint", (event) => {
|
electron.ipcMain.on("getCursorPoint", (event) => {
|
||||||
const window = electron.BrowserWindow.fromWebContents(event.sender);
|
const window = electron.BrowserWindow.fromWebContents(event.sender);
|
||||||
const screenPoint = electron.screen.getCursorScreenPoint();
|
const screenPoint = electron.screen.getCursorScreenPoint();
|
||||||
|
@ -11,4 +11,5 @@ contextBridge.exposeInMainWorld("api", {
|
|||||||
openNewWindow: () => ipcRenderer.send("openNewWindow"),
|
openNewWindow: () => ipcRenderer.send("openNewWindow"),
|
||||||
showContextMenu: (menu, position) => ipcRenderer.send("contextmenu-show", menu, position),
|
showContextMenu: (menu, position) => ipcRenderer.send("contextmenu-show", menu, position),
|
||||||
onContextMenuClick: (callback) => ipcRenderer.on("contextmenu-click", callback),
|
onContextMenuClick: (callback) => ipcRenderer.on("contextmenu-click", callback),
|
||||||
|
downloadFile: (filePath) => ipcRenderer.send("download", { filePath }),
|
||||||
});
|
});
|
||||||
|
@ -15,7 +15,7 @@ import clsx from "clsx";
|
|||||||
import * as jotai from "jotai";
|
import * as jotai from "jotai";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { ContextMenuModel } from "../store/contextmenu";
|
import { ContextMenuModel } from "../store/contextmenu";
|
||||||
import { atoms, createBlock } from "../store/global";
|
import { atoms, createBlock, getApi } from "../store/global";
|
||||||
|
|
||||||
import "./directorypreview.less";
|
import "./directorypreview.less";
|
||||||
|
|
||||||
@ -52,6 +52,7 @@ function getBestUnit(bytes: number, si: boolean = false, sigfig: number = 3): st
|
|||||||
while (currentValue > divisor && idx < units.length - 1) {
|
while (currentValue > divisor && idx < units.length - 1) {
|
||||||
currentUnit = units[idx];
|
currentUnit = units[idx];
|
||||||
currentValue /= divisor;
|
currentValue /= divisor;
|
||||||
|
idx += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return `${parseFloat(currentValue.toPrecision(sigfig))}${displaySuffixes[currentUnit]}`;
|
return `${parseFloat(currentValue.toPrecision(sigfig))}${displaySuffixes[currentUnit]}`;
|
||||||
@ -136,9 +137,20 @@ function handleFileContextMenu(e: React.MouseEvent<HTMLDivElement>, path: string
|
|||||||
await services.FileService.DeleteFile(path).catch((e) => console.log(e)); //todo these errors need a popup
|
await services.FileService.DeleteFile(path).catch((e) => console.log(e)); //todo these errors need a popup
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
menu.push({
|
||||||
|
label: "Download File",
|
||||||
|
click: async () => {
|
||||||
|
getApi().downloadFile(path);
|
||||||
|
},
|
||||||
|
});
|
||||||
ContextMenuModel.showContextMenu(menu, e);
|
ContextMenuModel.showContextMenu(menu, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cleanMimetype(input: string): string {
|
||||||
|
const truncated = input.split(";")[0];
|
||||||
|
return truncated.trim();
|
||||||
|
}
|
||||||
|
|
||||||
function DirectoryTable({ data, cwd, setFileName }: DirectoryTableProps) {
|
function DirectoryTable({ data, cwd, setFileName }: DirectoryTableProps) {
|
||||||
let settings = jotai.useAtomValue(atoms.settingsConfigAtom);
|
let settings = jotai.useAtomValue(atoms.settingsConfigAtom);
|
||||||
const getIconFromMimeType = React.useCallback(
|
const getIconFromMimeType = React.useCallback(
|
||||||
@ -154,11 +166,23 @@ function DirectoryTable({ data, cwd, setFileName }: DirectoryTableProps) {
|
|||||||
},
|
},
|
||||||
[settings.mimetypes]
|
[settings.mimetypes]
|
||||||
);
|
);
|
||||||
|
const getIconColor = React.useCallback(
|
||||||
|
(mimeType: string): string => {
|
||||||
|
let iconColor = settings.mimetypes[mimeType]?.color ?? "inherit";
|
||||||
|
return iconColor;
|
||||||
|
},
|
||||||
|
[settings.mimetypes]
|
||||||
|
);
|
||||||
const columns = React.useMemo(
|
const columns = React.useMemo(
|
||||||
() => [
|
() => [
|
||||||
columnHelper.accessor("mimetype", {
|
columnHelper.accessor("mimetype", {
|
||||||
cell: (info) => <i className={getIconFromMimeType(info.getValue() ?? "")}></i>,
|
cell: (info) => (
|
||||||
header: () => <span>Type</span>,
|
<i
|
||||||
|
className={getIconFromMimeType(info.getValue() ?? "")}
|
||||||
|
style={{ color: getIconColor(info.getValue() ?? "") }}
|
||||||
|
></i>
|
||||||
|
),
|
||||||
|
header: () => <span></span>,
|
||||||
id: "logo",
|
id: "logo",
|
||||||
size: 25,
|
size: 25,
|
||||||
enableSorting: false,
|
enableSorting: false,
|
||||||
@ -191,7 +215,7 @@ function DirectoryTable({ data, cwd, setFileName }: DirectoryTableProps) {
|
|||||||
sortingFn: "auto",
|
sortingFn: "auto",
|
||||||
}),
|
}),
|
||||||
columnHelper.accessor("mimetype", {
|
columnHelper.accessor("mimetype", {
|
||||||
cell: (info) => <span className="dir-table-type">{info.getValue()}</span>,
|
cell: (info) => <span className="dir-table-type">{cleanMimetype(info.getValue() ?? "")}</span>,
|
||||||
header: () => <span>Type</span>,
|
header: () => <span>Type</span>,
|
||||||
sortingFn: "alphanumeric",
|
sortingFn: "alphanumeric",
|
||||||
}),
|
}),
|
||||||
|
1
frontend/types/custom.d.ts
vendored
1
frontend/types/custom.d.ts
vendored
@ -36,6 +36,7 @@ declare global {
|
|||||||
onContextMenuClick: (callback: (id: string) => void) => void;
|
onContextMenuClick: (callback: (id: string) => void) => void;
|
||||||
onNavigate: (callback: (url: string) => void) => void;
|
onNavigate: (callback: (url: string) => void) => void;
|
||||||
onIframeNavigate: (callback: (url: string) => void) => void;
|
onIframeNavigate: (callback: (url: string) => void) => void;
|
||||||
|
downloadFile: (path: string) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ElectronContextMenuItem = {
|
type ElectronContextMenuItem = {
|
||||||
|
1
frontend/types/gotypes.d.ts
vendored
1
frontend/types/gotypes.d.ts
vendored
@ -180,6 +180,7 @@ declare global {
|
|||||||
// wconfig.MimeTypeConfigType
|
// wconfig.MimeTypeConfigType
|
||||||
type MimeTypeConfigType = {
|
type MimeTypeConfigType = {
|
||||||
icon: string;
|
icon: string;
|
||||||
|
color: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
// waveobj.ORef
|
// waveobj.ORef
|
||||||
|
@ -39,7 +39,8 @@ type DateTimeFormatConfigType struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type MimeTypeConfigType struct {
|
type MimeTypeConfigType struct {
|
||||||
Icon string `json:"icon"`
|
Icon string `json:"icon"`
|
||||||
|
Color string `json:"color"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type BlockHeaderOpts struct {
|
type BlockHeaderOpts struct {
|
||||||
@ -67,7 +68,7 @@ func getSettingsConfigDefaults() SettingsConfigType {
|
|||||||
"audio": {Icon: "file-audio"},
|
"audio": {Icon: "file-audio"},
|
||||||
"application/pdf": {Icon: "file-pdf"},
|
"application/pdf": {Icon: "file-pdf"},
|
||||||
"application/json": {Icon: "file-lines"},
|
"application/json": {Icon: "file-lines"},
|
||||||
"directory": {Icon: "folder"},
|
"directory": {Icon: "folder", Color: "#2e62d2"},
|
||||||
"font": {Icon: "book-font"},
|
"font": {Icon: "book-font"},
|
||||||
"image": {Icon: "file-image"},
|
"image": {Icon: "file-image"},
|
||||||
"text": {Icon: "file-lines"},
|
"text": {Icon: "file-lines"},
|
||||||
|
Loading…
Reference in New Issue
Block a user