>(null);
-
- const setType = useCallback(
- (newValue: string) => {
- (async () => {
- setTabValue(newValue);
- setInner(null);
- await sleep(0);
- setInner(typeToElement(newValue));
- })();
- },
- [setTabValue, setInner]
- );
-
+ const location = useLocation();
+ const navigate = useNavigate();
const handleTabChange = useCallback(
(_: ChangeEvent<{}>, newValue: string) => {
- setType(newValue);
+ navigate("/" + newValue);
},
- [setTabValue]
+ [navigate]
);
- useEffect(() => {
- setType(FileBrowserType);
- }, []);
-
return (
-
+
+
+
+ } />} />
+ } />} />
+ } />} />
+ } />
+
+
- {inner}
);
};
diff --git a/frontend/src/file.tsx b/frontend/src/file.tsx
index fb7b20f..6f243d3 100644
--- a/frontend/src/file.tsx
+++ b/frontend/src/file.tsx
@@ -2,7 +2,7 @@ import { useState, useRef, useEffect, useMemo, useCallback } from "react";
import Grid from "@mui/material/Grid";
import Box from "@mui/material/Box";
-import { FullFileBrowser, FileBrowserHandle, FileArray } from "chonky";
+import { FullFileBrowser, FileBrowserProps, FileBrowserHandle, FileArray } from "chonky";
import { ChonkyActions, ChonkyFileActionData } from "chonky";
import "./app.less";
@@ -32,7 +32,7 @@ const useDualSide = () => {
return { instances, refreshAll };
};
-const useFileBrowser = (refreshAll: () => Promise, openDetailModel: (detail: FileGetReply) => void) => {
+const useFileBrowser = (storageKey: string, refreshAll: () => Promise, openDetailModel: (detail: FileGetReply) => void) => {
const [files, setFiles] = useState(Array(1).fill(null));
const [folderChain, setFolderChan] = useState([Root]);
const currentID = useMemo(() => {
@@ -48,15 +48,28 @@ const useFileBrowser = (refreshAll: () => Promise, openDetailModel: (detai
return last.id;
}, [folderChain]);
- const openFolder = useCallback((id: string) => {
- (async () => {
- const [file, folderChain] = await Promise.all([cli.fileGet({ id: BigInt(id) }).response, cli.fileListParents({ id: BigInt(id) }).response]);
+ const openFolder = useCallback(async (id: string) => {
+ const [file, folderChain] = await Promise.all([cli.fileGet({ id: BigInt(id) }).response, cli.fileListParents({ id: BigInt(id) }).response]);
- setFiles(convertFiles(file.children));
- setFolderChan([Root, ...convertFiles(folderChain.parents)]);
+ setFiles(convertFiles(file.children));
+ setFolderChan([Root, ...convertFiles(folderChain.parents)]);
+ localStorage.setItem(storageKey, id);
+ }, []);
+ useEffect(() => {
+ (async () => {
+ const storagedID = localStorage.getItem(storageKey);
+ if (storagedID) {
+ try {
+ await openFolder(storagedID);
+ return;
+ } catch (e) {
+ console.log("open storaged id fail, err= ", e);
+ }
+ }
+
+ openFolder(Root.id);
})();
}, []);
- useEffect(() => openFolder(Root.id), []);
const onFileAction = useCallback(
(data: ChonkyFileActionData) => {
@@ -157,8 +170,8 @@ export const FileBrowser = () => {
const { instances, refreshAll } = useDualSide();
const { detail, openDetailModel, closeDetailModel } = useDetailModal();
- const leftProps = useFileBrowser(refreshAll, openDetailModel);
- const rightProps = useFileBrowser(refreshAll, openDetailModel);
+ const leftProps = useFileBrowser("file_browser:left:current_id", refreshAll, openDetailModel);
+ const rightProps = useFileBrowser("file_browser:right:current_id", refreshAll, openDetailModel);
useEffect(() => {
Object.values(instances).map((inst) => inst.current?.requestFileAction(ChonkyActions.ToggleHiddenFiles, {}));
@@ -167,6 +180,7 @@ export const FileBrowser = () => {
}, 10000);
return () => clearInterval(interval);
}, []);
+ useEffect(() => {});
return (
diff --git a/frontend/src/jobs.tsx b/frontend/src/jobs.tsx
index 37b12fe..e4d3e65 100644
--- a/frontend/src/jobs.tsx
+++ b/frontend/src/jobs.tsx
@@ -348,10 +348,18 @@ const ViewLogDialog = ({ jobID }: { jobID: bigint }) => {
const LogConsole = ({ jobId }: { jobId: bigint }) => {
const [log, setLog] = useState("");
+ const bottom = useRef(null);
const refreshLog = useCallback(async () => {
const reply = await cli.jobGetLog({ jobId, offset: BigInt(log.length) }).response;
setLog(log + new TextDecoder().decode(reply.logs));
- }, [log, setLog]);
+
+ if (log.length === 0 && reply.logs.length > 0 && bottom && bottom.current) {
+ await sleep(10);
+ (bottom.current as HTMLElement).scrollIntoView(true);
+ await sleep(10);
+ (bottom.current as HTMLElement).parentElement?.scrollBy(0, 100);
+ }
+ }, [log, setLog, bottom]);
useEffect(() => {
let closed = false;
(async () => {
@@ -366,7 +374,12 @@ const LogConsole = ({ jobId }: { jobId: bigint }) => {
};
}, [refreshLog]);
- return {log || "loading..."};
+ return (
+
+ {log || "loading..."}
+
+
+ );
};
const ArchiveViewFilesDialog = ({ sources }: { sources: SourceState[] }) => {
diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx
index f7a9b63..f57e866 100644
--- a/frontend/src/main.tsx
+++ b/frontend/src/main.tsx
@@ -1,10 +1,13 @@
import React from "react";
import ReactDOM from "react-dom/client";
+import { BrowserRouter } from "react-router-dom";
import App from "./app";
import "./index.css";
import "./init";
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
-
+
+
+
);
diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts
index b53ad6d..7222466 100644
--- a/frontend/vite.config.ts
+++ b/frontend/vite.config.ts
@@ -4,7 +4,6 @@ import react from "@vitejs/plugin-react";
// https://vitejs.dev/config/
export default defineConfig(({ command, mode }) => {
const env = loadEnv(mode, process.cwd(), "");
- console.log(env);
return {
plugins: [react()],
diff --git a/tools/recover.go b/tools/recover.go
index dbc82e8..93c4a41 100644
--- a/tools/recover.go
+++ b/tools/recover.go
@@ -9,6 +9,10 @@ import (
)
func Wrap(ctx context.Context, f func()) {
+ WrapWithLogger(ctx, logrus.StandardLogger(), f)
+}
+
+func WrapWithLogger(ctx context.Context, logger *logrus.Logger, f func()) {
defer func() {
e := recover()
if e == nil {
@@ -23,7 +27,7 @@ func Wrap(ctx context.Context, f func()) {
err = fmt.Errorf("%v", err)
}
- logrus.WithContext(ctx).WithError(err).Errorf("panic: %s", debug.Stack())
+ logger.WithContext(ctx).WithError(err).Errorf("panic: %s", debug.Stack())
}()
f()