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:
Sylvie Crowe 2024-06-27 12:30:08 -07:00 committed by GitHub
parent 76c909114e
commit 23e1c8797d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 62 additions and 19 deletions

View File

@ -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;

View File

@ -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) {

View File

@ -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}
/>
</>
);

View File

@ -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 {}

View File

@ -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(),

View File

@ -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"},