mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-21 16:38:23 +01:00
Search Fixes (#84)
This change: - now clears the search box when entering a new directory - fixes some styling issues - adds a .. to the path - uses the correct path (except on the initial start of the directory widget)
This commit is contained in:
parent
76c909114e
commit
23e1c8797d
@ -1,8 +1,6 @@
|
||||
// Copyright 2024, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { getBackendHostPort } from "@/app/store/global";
|
||||
import * as keyutil from "@/util/keyutil";
|
||||
import * as electron from "electron";
|
||||
import fs from "fs";
|
||||
import * as child_process from "node:child_process";
|
||||
@ -10,7 +8,9 @@ import os from "os";
|
||||
import * as path from "path";
|
||||
import * as readline from "readline";
|
||||
import { debounce } from "throttle-debounce";
|
||||
import { getBackendHostPort } from "../frontend/app/store/global";
|
||||
import * as services from "../frontend/app/store/services";
|
||||
import * as keyutil from "../frontend/util/keyutil";
|
||||
|
||||
const electronApp = electron.app;
|
||||
const isDev = process.env.WAVETERM_DEV;
|
||||
|
@ -51,11 +51,31 @@
|
||||
border-radius: 3px;
|
||||
|
||||
&.focused {
|
||||
background-color: var(--accent-color);
|
||||
background-color: rgb(from var(--accent-color) r g b / 0.7);
|
||||
color: var(--main-text-color);
|
||||
|
||||
.dir-table-body-cell {
|
||||
.dir-table-lastmod,
|
||||
.dir-table-modestr,
|
||||
.dir-table-size,
|
||||
.dir-table-type {
|
||||
color: var(--main-text-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background-color: var(--accent-color);
|
||||
background-color: rgb(from var(--accent-color) r g b / 0.7);
|
||||
color: var(--main-text-color);
|
||||
|
||||
.dir-table-body-cell {
|
||||
.dir-table-lastmod,
|
||||
.dir-table-modestr,
|
||||
.dir-table-size,
|
||||
.dir-table-type {
|
||||
color: var(--main-text-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:hover:not(:focus):not(.focused) {
|
||||
|
@ -26,6 +26,7 @@ interface DirectoryTableProps {
|
||||
enter: boolean;
|
||||
setFocusIndex: (_: number) => void;
|
||||
setFileName: (_: string) => void;
|
||||
setSearch: (_: string) => void;
|
||||
}
|
||||
|
||||
const columnHelper = createColumnHelper<FileInfo>();
|
||||
@ -154,7 +155,7 @@ function cleanMimetype(input: string): string {
|
||||
return truncated.trim();
|
||||
}
|
||||
|
||||
function DirectoryTable({ data, cwd, focusIndex, enter, setFocusIndex, setFileName }: DirectoryTableProps) {
|
||||
function DirectoryTable({ data, cwd, focusIndex, enter, setFocusIndex, setFileName, setSearch }: DirectoryTableProps) {
|
||||
let settings = jotai.useAtomValue(atoms.settingsConfigAtom);
|
||||
const getIconFromMimeType = React.useCallback(
|
||||
(mimeType: string): string => {
|
||||
@ -190,8 +191,8 @@ function DirectoryTable({ data, cwd, focusIndex, enter, setFocusIndex, setFileNa
|
||||
size: 25,
|
||||
enableSorting: false,
|
||||
}),
|
||||
columnHelper.accessor("path", {
|
||||
cell: (info) => <span className="dir-table-path">{info.getValue()}</span>,
|
||||
columnHelper.accessor("name", {
|
||||
cell: (info) => <span className="dir-table-name">{info.getValue()}</span>,
|
||||
header: () => <span>Name</span>,
|
||||
sortingFn: "alphanumeric",
|
||||
}),
|
||||
@ -222,6 +223,7 @@ function DirectoryTable({ data, cwd, focusIndex, enter, setFocusIndex, setFileNa
|
||||
header: () => <span>Type</span>,
|
||||
sortingFn: "alphanumeric",
|
||||
}),
|
||||
columnHelper.accessor("path", {}),
|
||||
],
|
||||
[settings]
|
||||
);
|
||||
@ -232,13 +234,17 @@ function DirectoryTable({ data, cwd, focusIndex, enter, setFocusIndex, setFileNa
|
||||
columnResizeMode: "onChange",
|
||||
getSortedRowModel: getSortedRowModel(),
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
|
||||
initialState: {
|
||||
sorting: [
|
||||
{
|
||||
id: "path",
|
||||
id: "name",
|
||||
desc: false,
|
||||
},
|
||||
],
|
||||
columnVisibility: {
|
||||
path: false,
|
||||
},
|
||||
},
|
||||
enableMultiSort: false,
|
||||
enableSortingRemoval: false,
|
||||
@ -289,6 +295,7 @@ function DirectoryTable({ data, cwd, focusIndex, enter, setFocusIndex, setFileNa
|
||||
enter={enter}
|
||||
setFileName={setFileName}
|
||||
setFocusIndex={setFocusIndex}
|
||||
setSearch={setSearch}
|
||||
/>
|
||||
) : (
|
||||
<TableBody
|
||||
@ -298,6 +305,7 @@ function DirectoryTable({ data, cwd, focusIndex, enter, setFocusIndex, setFileNa
|
||||
enter={enter}
|
||||
setFileName={setFileName}
|
||||
setFocusIndex={setFocusIndex}
|
||||
setSearch={setSearch}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@ -311,16 +319,17 @@ interface TableBodyProps {
|
||||
enter: boolean;
|
||||
setFocusIndex: (_: number) => void;
|
||||
setFileName: (_: string) => void;
|
||||
setSearch: (_: string) => void;
|
||||
}
|
||||
|
||||
function TableBody({ table, cwd, focusIndex, enter, setFocusIndex, setFileName }: TableBodyProps) {
|
||||
function TableBody({ table, cwd, focusIndex, enter, setFocusIndex, setFileName, setSearch }: TableBodyProps) {
|
||||
let [refresh, setRefresh] = React.useState(false);
|
||||
|
||||
React.useEffect(() => {
|
||||
const selected = (table.getSortedRowModel()?.flatRows[focusIndex]?.getValue("path") as string) ?? null;
|
||||
if (selected != null) {
|
||||
const fullPath = cwd.concat("/", selected);
|
||||
setFileName(fullPath);
|
||||
setFileName(selected);
|
||||
setSearch("");
|
||||
}
|
||||
}, [enter]);
|
||||
|
||||
@ -333,11 +342,11 @@ function TableBody({ table, cwd, focusIndex, enter, setFocusIndex, setFileName }
|
||||
key={row.id}
|
||||
onDoubleClick={() => {
|
||||
const newFileName = row.getValue("path") as string;
|
||||
const fullPath = cwd.concat("/", newFileName);
|
||||
setFileName(fullPath);
|
||||
setFileName(newFileName);
|
||||
setSearch("");
|
||||
}}
|
||||
onClick={() => setFocusIndex(idx)}
|
||||
onContextMenu={(e) => handleFileContextMenu(e, cwd.concat("/", row.getValue("path") as string))}
|
||||
onContextMenu={(e) => handleFileContextMenu(e, row.getValue("path") as string)}
|
||||
>
|
||||
{row.getVisibleCells().map((cell) => {
|
||||
return (
|
||||
@ -378,7 +387,7 @@ function DirectoryPreview({ fileNameAtom }: DirectoryPreviewProps) {
|
||||
const serializedContent = util.base64ToString(file?.data64);
|
||||
let content: FileInfo[] = JSON.parse(serializedContent);
|
||||
let filtered = content.filter((fileInfo) => {
|
||||
return fileInfo.path.toLowerCase().includes(searchText);
|
||||
return fileInfo.name.toLowerCase().includes(searchText);
|
||||
});
|
||||
setContent(filtered);
|
||||
};
|
||||
@ -432,6 +441,7 @@ function DirectoryPreview({ fileNameAtom }: DirectoryPreviewProps) {
|
||||
onChange={(e) => setSearchText(e.target.value.toLowerCase())}
|
||||
maxLength={400}
|
||||
autoFocus={true}
|
||||
value={searchText}
|
||||
/>
|
||||
</div>
|
||||
<DirectoryTable
|
||||
@ -441,6 +451,7 @@ function DirectoryPreview({ fileNameAtom }: DirectoryPreviewProps) {
|
||||
enter={enter}
|
||||
setFileName={setFileName}
|
||||
setFocusIndex={setFocusIndex}
|
||||
setSearch={setSearchText}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
5
frontend/types/gotypes.d.ts
vendored
5
frontend/types/gotypes.d.ts
vendored
@ -61,7 +61,7 @@ declare global {
|
||||
|
||||
// wshutil.BlockInputCommand
|
||||
type BlockInputCommand = {
|
||||
blockid?: string;
|
||||
blockid: string;
|
||||
command: "controller:input";
|
||||
inputdata64?: string;
|
||||
signame?: string;
|
||||
@ -139,6 +139,7 @@ declare global {
|
||||
// fileservice.FileInfo
|
||||
type FileInfo = {
|
||||
path: string;
|
||||
name: string;
|
||||
notfound?: boolean;
|
||||
size: number;
|
||||
mode: number;
|
||||
@ -381,4 +382,4 @@ declare global {
|
||||
|
||||
}
|
||||
|
||||
export {}
|
||||
export {}
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
@ -25,6 +26,7 @@ type FileService struct{}
|
||||
|
||||
type FileInfo struct {
|
||||
Path string `json:"path"` // cleaned path
|
||||
Name string `json:"name"`
|
||||
NotFound bool `json:"notfound,omitempty"`
|
||||
Size int64 `json:"size"`
|
||||
Mode os.FileMode `json:"mode"`
|
||||
@ -51,6 +53,7 @@ func (fs *FileService) StatFile(path string) (*FileInfo, error) {
|
||||
mimeType := utilfn.DetectMimeType(cleanedPath)
|
||||
return &FileInfo{
|
||||
Path: cleanedPath,
|
||||
Name: finfo.Name(),
|
||||
Size: finfo.Size(),
|
||||
Mode: finfo.Mode(),
|
||||
ModeStr: finfo.Mode().String(),
|
||||
@ -80,6 +83,13 @@ func (fs *FileService) ReadFile(path string) (*FullFile, error) {
|
||||
innerFilesEntries = innerFilesEntries[:1000]
|
||||
}
|
||||
var innerFilesInfo []FileInfo
|
||||
parent := filepath.Dir(finfo.Path)
|
||||
parentFileInfo, err := fs.StatFile(parent)
|
||||
if err == nil && parent != finfo.Path {
|
||||
log.Printf("adding parent")
|
||||
parentFileInfo.Name = ".."
|
||||
innerFilesInfo = append(innerFilesInfo, *parentFileInfo)
|
||||
}
|
||||
for _, innerFileEntry := range innerFilesEntries {
|
||||
innerFileInfoInt, _ := innerFileEntry.Info()
|
||||
mimeType := utilfn.DetectMimeType(filepath.Join(finfo.Path, innerFileInfoInt.Name()))
|
||||
@ -90,7 +100,8 @@ func (fs *FileService) ReadFile(path string) (*FullFile, error) {
|
||||
fileSize = innerFileInfoInt.Size()
|
||||
}
|
||||
innerFileInfo := FileInfo{
|
||||
Path: innerFileInfoInt.Name(),
|
||||
Path: filepath.Join(finfo.Path, innerFileInfoInt.Name()),
|
||||
Name: innerFileInfoInt.Name(),
|
||||
Size: fileSize,
|
||||
Mode: innerFileInfoInt.Mode(),
|
||||
ModeStr: innerFileInfoInt.Mode().String(),
|
||||
|
@ -68,7 +68,7 @@ func getSettingsConfigDefaults() SettingsConfigType {
|
||||
"audio": {Icon: "file-audio"},
|
||||
"application/pdf": {Icon: "file-pdf"},
|
||||
"application/json": {Icon: "file-lines"},
|
||||
"directory": {Icon: "folder", Color: "#2e62d2"},
|
||||
"directory": {Icon: "folder", Color: "var(--term-bright-blue)"},
|
||||
"font": {Icon: "book-font"},
|
||||
"image": {Icon: "file-image"},
|
||||
"text": {Icon: "file-lines"},
|
||||
|
Loading…
Reference in New Issue
Block a user