mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
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:
@@ -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 };
|
||||
@@ -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">
|
||||
|
||||
Reference in New Issue
Block a user