More Directory Formatting (#108)

This makes the following changes
- allow directory rows to overflow their container on resize (allowing
scroll as a temporary test)
- fix directory width to account for resizer width
- add ellipsis to name column on table resize
- add the rightmost resizer back (more as a temporary test)
- do not search when the filtered contents are empty
- cap the index to the end of the list of the number of entries becomes
less than the current index
- do not redo backend call on filter or search of directory results
- add letter spacing on header row
This commit is contained in:
Sylvie Crowe 2024-07-10 02:21:29 -07:00 committed by GitHub
parent ff8fe94b1c
commit cb77c2047e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 57 additions and 22 deletions

View File

@ -4,7 +4,9 @@
height: 100%;
overflow-x: hidden;
.dir-table {
overflow-x: hidden;
height: 100%;
min-width: 600px;
--col-size-size: 0.2rem;
border-radius: 3px;
display: flex;
@ -16,9 +18,11 @@
border-bottom: 1px solid var(--border-color);
padding: 4px 6px;
background-color: var(--panel-bg-color);
align-items: center;
font-size: 0.75rem;
.dir-table-head-cell {
flex: 0 0 auto;
}
.dir-table-head-cell:not(:first-child) {
position: relative;
display: flex;
@ -31,13 +35,15 @@
gap: 0.3rem;
flex: 1 1 auto;
overflow-x: hidden;
letter-spacing: -0.12px;
.dir-table-head-direction {
margin-right: 0.2rem;
margin-top: 0.2rem;
}
.dir-table-head-size {
.dir-table-head-size,
.dir-table-head-type {
width: 100%;
text-align: right;
}
@ -59,10 +65,12 @@
&:last-child {
.dir-table-head-resize-box {
width: 0;
}
}
}
.dir-table-head-cell:has(.dir-table-head-cell-content .dir-table-head-name) {
}
}
}
@ -91,9 +99,8 @@
.dir-table-body-row {
display: flex;
align-items: center;
align-self: stretch;
border-radius: 6px;
gap: 12px;
padding: 0 6px;
&.focused {
background-color: rgb(from var(--accent-color) r g b / 0.5);
@ -133,6 +140,10 @@
padding: 0.25rem;
cursor: default;
font-size: 0.8125rem;
flex: 0 0 auto;
&:has(.dir-table-name) {
}
&.col-size {
text-align: right;
@ -143,12 +154,20 @@
.dir-table-size,
.dir-table-type {
color: var(--secondary-text-color);
margin-right: 12px;
}
.dir-table-type {
float: right;
}
.dir-table-modestr {
font-family: Hack;
}
&:has(.dir-table-name) {
text-overflow: ellipsis;
}
.dir-table-name {
font-weight: 500;
}

View File

@ -183,7 +183,7 @@ function DirectoryTable({
}),
columnHelper.accessor("name", {
cell: (info) => <span className="dir-table-name">{info.getValue()}</span>,
header: () => <span>Name</span>,
header: () => <span className="dir-table-head-name">Name</span>,
sortingFn: "alphanumeric",
}),
columnHelper.accessor("modestr", {
@ -206,7 +206,7 @@ function DirectoryTable({
}),
columnHelper.accessor("mimetype", {
cell: (info) => <span className="dir-table-type">{cleanMimetype(info.getValue() ?? "")}</span>,
header: () => <span>Type</span>,
header: () => <span className="dir-table-head-type">Type</span>,
sortingFn: "alphanumeric",
}),
columnHelper.accessor("path", {}),
@ -270,11 +270,13 @@ function DirectoryTable({
{table.getHeaderGroups().map((headerGroup) => (
<div className="dir-table-head-row" key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<div className="dir-table-head-cell">
<div
className="dir-table-head-cell"
key={header.id}
style={{ width: `calc(var(--header-${header.id}-size) * 1px)` }}
>
<div
className="dir-table-head-cell-content"
key={header.id}
style={{ width: `calc(var(--header-${header.id}-size) * 1px)` }}
onClick={() => header.column.toggleSorting()}
>
{header.isPlaceholder
@ -474,7 +476,8 @@ interface DirectoryPreviewProps {
function DirectoryPreview({ fileNameAtom, model }: DirectoryPreviewProps) {
const [searchText, setSearchText] = React.useState("");
const [focusIndex, setFocusIndex] = React.useState(0);
const [content, setContent] = React.useState<FileInfo[]>([]);
const [unfilteredData, setUnfilteredData] = React.useState<FileInfo[]>([]);
const [filteredData, setFilteredData] = React.useState<FileInfo[]>([]);
const [fileName, setFileName] = jotai.useAtom(fileNameAtom);
const hideHiddenFiles = jotai.useAtomValue(model.showHiddenFiles);
const [selectedPath, setSelectedPath] = React.useState("");
@ -494,16 +497,20 @@ function DirectoryPreview({ fileNameAtom, model }: DirectoryPreviewProps) {
const file = await services.FileService.ReadFile(fileName);
const serializedContent = util.base64ToString(file?.data64);
let content: FileInfo[] = JSON.parse(serializedContent);
let filtered = content.filter((fileInfo) => {
if (hideHiddenFiles && fileInfo.name.startsWith(".") && fileInfo.name != "..") {
return false;
}
return fileInfo.name.toLowerCase().includes(searchText);
});
setContent(filtered);
setUnfilteredData(content);
};
getContent();
}, [fileName, searchText, hideHiddenFiles, refreshVersion]);
}, [fileName, refreshVersion]);
React.useEffect(() => {
let filtered = unfilteredData.filter((fileInfo) => {
if (hideHiddenFiles && fileInfo.name.startsWith(".") && fileInfo.name != "..") {
return false;
}
return fileInfo.name.toLowerCase().includes(searchText);
});
setFilteredData(filtered);
}, [unfilteredData, hideHiddenFiles, searchText]);
const handleKeyDown = React.useCallback(
(waveEvent: WaveKeyboardEvent): boolean => {
@ -516,18 +523,27 @@ function DirectoryPreview({ fileNameAtom, model }: DirectoryPreviewProps) {
return true;
}
if (keyutil.checkKeyPressed(waveEvent, "ArrowDown")) {
setFocusIndex((idx) => Math.min(idx + 1, content.length - 1));
setFocusIndex((idx) => Math.min(idx + 1, filteredData.length - 1));
return true;
}
if (keyutil.checkKeyPressed(waveEvent, "Enter")) {
if (filteredData.length == 0) {
return;
}
setFileName(selectedPath);
setSearchText("");
return true;
}
},
[content, focusIndex, selectedPath]
[filteredData, setFocusIndex, selectedPath]
);
React.useEffect(() => {
if (filteredData.length != 0 && focusIndex > filteredData.length - 1) {
setFocusIndex(filteredData.length - 1);
}
}, [filteredData]);
return (
<div
className="dir-table-container"
@ -549,7 +565,7 @@ function DirectoryPreview({ fileNameAtom, model }: DirectoryPreviewProps) {
/>
</div>
<DirectoryTable
data={content}
data={filteredData}
search={searchText}
focusIndex={focusIndex}
setFileName={setFileName}