feat: add basic directory navigation in preview

Note: this does not add backwards navigation and will break if
attempting to open certain types of files.
This commit is contained in:
Sylvia Crowe
2024-05-29 00:00:36 -07:00
parent 7a54b79bda
commit b9f6da57f9
7 changed files with 85 additions and 23 deletions
@@ -42,6 +42,7 @@
.dir-table-body-cell {
overflow: hidden;
white-space: nowrap;
padding: 0.25rem;
}
}
@@ -3,12 +3,15 @@
import { FileInfo } from "@/bindings/fileservice";
import { Table, createColumnHelper, flexRender, getCoreRowModel, useReactTable } from "@tanstack/react-table";
import * as jotai from "jotai";
import path from "path";
import React from "react";
import "./directorytable.less";
import "./directorypreview.less";
interface DirectoryTableProps {
data: FileInfo[];
setFileName: (_: string) => void;
}
const columnHelper = createColumnHelper<FileInfo>();
@@ -28,7 +31,7 @@ const defaultColumns = [
}),
];
function DirectoryTable<T, U>({ data }: DirectoryTableProps) {
function DirectoryTable<T, U>({ data, setFileName }: DirectoryTableProps) {
const [columns] = React.useState<typeof defaultColumns>(() => [...defaultColumns]);
const table = useReactTable({
data,
@@ -73,26 +76,39 @@ function DirectoryTable<T, U>({ data }: DirectoryTableProps) {
))}
</div>
{table.getState().columnSizingInfo.isResizingColumn ? (
<MemoizedTableBody table={table} />
<MemoizedTableBody table={table} setFileName={setFileName} />
) : (
<TableBody table={table} />
<TableBody table={table} setFileName={setFileName} />
)}
</div>
);
}
function TableBody({ table }: { table: Table<FileInfo> }) {
interface TableBodyProps {
table: Table<FileInfo>;
setFileName: (_: string) => void;
}
function TableBody({ table, setFileName }: TableBodyProps) {
return (
<div className="dir-table-body">
{table.getRowModel().rows.map((row) => (
<div className="dir-table-body-row" key={row.id} tabIndex={0}>
<div
className="dir-table-body-row"
key={row.id}
tabIndex={0}
onDoubleClick={() => {
const newFileName = row.getValue("path") as string;
setFileName(newFileName);
}}
>
{row.getVisibleCells().map((cell) => (
<div
className="dir-table-body-cell"
key={cell.id}
style={{ width: `calc(var(--col-${cell.column.id}-size) * 1px)` }}
>
{cell.renderValue<any>()}
{path.basename(cell.renderValue<any>())}
</div>
))}
</div>
@@ -106,4 +122,16 @@ const MemoizedTableBody = React.memo(
(prev, next) => prev.table.options.data == next.table.options.data
) as typeof TableBody;
export { DirectoryTable };
interface DirectoryPreviewProps {
contentAtom: jotai.Atom<Promise<string>>;
fileNameAtom: jotai.WritableAtom<string, [string], void>;
}
function DirectoryPreview({ contentAtom, fileNameAtom }: DirectoryPreviewProps) {
const contentText = jotai.useAtomValue(contentAtom);
let content: FileInfo[] = JSON.parse(contentText);
let [fileName, setFileName] = jotai.useAtom(fileNameAtom);
return <DirectoryTable data={content} setFileName={setFileName} />;
}
export { DirectoryPreview };
+16 -13
View File
@@ -2,13 +2,13 @@
// SPDX-License-Identifier: Apache-2.0
import { FileInfo, FileService, FullFile } from "@/bindings/fileservice";
import { DirectoryTable } from "@/element/directorytable";
import { Markdown } from "@/element/markdown";
import { useBlockAtom } from "@/store/global";
import { useBlockAtom, useBlockCache } from "@/store/global";
import * as WOS from "@/store/wos";
import * as util from "@/util/util";
import * as jotai from "jotai";
import { CenteredDiv } from "../element/quickelems";
import { DirectoryPreview } from "./directorypreview";
import "./view.less";
@@ -54,12 +54,6 @@ function StreamingPreview({ fileInfo }: { fileInfo: FileInfo }) {
return <CenteredDiv>Preview Not Supported</CenteredDiv>;
}
function DirectoryPreview({ contentAtom }: { contentAtom: jotai.Atom<Promise<string>> }) {
const contentText = jotai.useAtomValue(contentAtom);
let content: FileInfo[] = JSON.parse(contentText);
return <DirectoryTable data={content} />;
}
function PreviewView({ blockId }: { blockId: string }) {
const blockData = WOS.useWaveObjectValueWithSuspense<Block>(WOS.makeORef("block", blockId));
if (blockData == null) {
@@ -69,11 +63,20 @@ function PreviewView({ blockId }: { blockId: string }) {
</div>
);
}
const fileNameAtom = useBlockAtom(blockId, "preview:filename", () =>
jotai.atom<string>((get) => {
return blockData?.meta?.file;
})
const blockAtom = WOS.getWaveObjectAtom<Block>(`block:${blockId}`);
const fileNameAtom: jotai.WritableAtom<string, [string], void> = useBlockCache(blockId, "preview:filename", () =>
jotai.atom<string, [string], void>(
(get) => {
return get(blockAtom)?.meta?.file;
},
(get, set, update) => {
const blockId = get(blockAtom)?.oid;
WOS.UpdateObjectMeta(`block:${blockId}`, { file: update });
}
)
);
let name = jotai.useAtomValue(fileNameAtom);
console.log("file: ", name);
const statFileAtom = useBlockAtom(blockId, "preview:statfile", () =>
jotai.atom<Promise<FileInfo>>(async (get) => {
const fileName = get(fileNameAtom);
@@ -133,7 +136,7 @@ function PreviewView({ blockId }: { blockId: string }) {
);
}
if (mimeType === "directory") {
return <DirectoryPreview contentAtom={fileContentAtom} />;
return <DirectoryPreview contentAtom={fileContentAtom} fileNameAtom={fileNameAtom} />;
}
return (
<div className="view-preview">