first commit

This commit is contained in:
2025-10-19 13:31:11 +00:00
commit 8bfc183b66
1248 changed files with 195992 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
import { useMediaQuery, useTheme } from "@mui/material";
import { useContext, useEffect } from "react";
import { closeShareReadme } from "../../../redux/globalStateSlice.ts";
import { useAppDispatch, useAppSelector } from "../../../redux/hooks.ts";
import { detectReadMe } from "../../../redux/thunks/share.ts";
import { FmIndexContext } from "../FmIndexContext.tsx";
import ReadMeDialog from "./ReadMeDialog.tsx";
import ReadMeSideBar from "./ReadMeSideBar.tsx";
export const ReadMe = () => {
const fmIndex = useContext(FmIndexContext);
const dispatch = useAppDispatch();
const detect = useAppSelector((state) => state.globalState.shareReadmeDetect);
const theme = useTheme();
const isTablet = useMediaQuery(theme.breakpoints.down("md"));
useEffect(() => {
if (detect) {
dispatch(detectReadMe(fmIndex, isTablet));
}
}, [detect, dispatch]);
useEffect(() => {
if (detect === 0) {
setTimeout(() => {
dispatch(closeShareReadme());
}, 500);
}
}, [detect]);
if (isTablet) {
return <ReadMeDialog />;
}
return <ReadMeSideBar />;
};

View File

@@ -0,0 +1,82 @@
import { Box, Skeleton, useTheme } from "@mui/material";
import { lazy, Suspense, useCallback, useEffect, useState } from "react";
import { useAppDispatch, useAppSelector } from "../../../redux/hooks.ts";
import { getEntityContent } from "../../../redux/thunks/file.ts";
import { markdownImagePreviewHandler } from "../../../redux/thunks/viewer.ts";
import Header from "../Sidebar/Header.tsx";
const MarkdownEditor = lazy(() => import("../../Viewers/MarkdownEditor/Editor.tsx"));
const Loading = () => {
return (
<Box sx={{ p: 2 }}>
<Skeleton variant="text" width="100%" height={24} />
<Skeleton variant="text" width="40%" height={24} />
<Skeleton variant="text" width="75%" height={24} />
<Skeleton variant="text" width="85%" height={24} />
<Skeleton variant="text" width="20%" height={24} />
</Box>
);
};
const ReadMeContent = () => {
const theme = useTheme();
const dispatch = useAppDispatch();
const readMeTarget = useAppSelector((state) => state.globalState.shareReadmeTarget);
const [loading, setLoading] = useState(true);
const [value, setValue] = useState("");
useEffect(() => {
if (readMeTarget) {
setLoading(true);
dispatch(getEntityContent(readMeTarget))
.then((res) => {
const content = new TextDecoder().decode(res);
setValue(content);
setLoading(false);
})
.catch(() => {
setLoading(false);
});
}
}, [readMeTarget]);
const imagePreviewHandler = useCallback(
async (imageSource: string) => {
return dispatch(markdownImagePreviewHandler(imageSource, readMeTarget?.path ?? ""));
},
[dispatch, readMeTarget],
);
return (
<Box sx={{ display: "flex", flexDirection: "column", height: "100%" }}>
<Header target={readMeTarget} variant={"readme"} />
<Box
sx={{
width: "100%",
bgcolor: "background.paper",
borderTop: 1,
borderColor: "divider",
overflow: "auto",
}}
>
{loading && <Loading />}
{!loading && (
<Suspense fallback={<Loading />}>
<MarkdownEditor
displayOnly
value={value}
darkMode={theme.palette.mode === "dark"}
readOnly={true}
onChange={() => {}}
initialValue={value}
imagePreviewHandler={imagePreviewHandler}
/>
</Suspense>
)}
</Box>
</Box>
);
};
export default ReadMeContent;

View File

@@ -0,0 +1,35 @@
import { Dialog, Slide } from "@mui/material";
import { TransitionProps } from "@mui/material/transitions";
import { forwardRef } from "react";
import { closeShareReadme } from "../../../redux/globalStateSlice.ts";
import { useAppDispatch, useAppSelector } from "../../../redux/hooks.ts";
import ReadMeContent from "./ReadMeContent.tsx";
const Transition = forwardRef(function Transition(
props: TransitionProps & {
children: React.ReactElement<unknown>;
},
ref: React.Ref<unknown>,
) {
return <Slide direction="up" ref={ref} {...props} />;
});
const ReadMeDialog = () => {
const dispatch = useAppDispatch();
const readMeOpen = useAppSelector((state) => state.globalState.shareReadmeOpen);
return (
<Dialog
fullScreen
TransitionComponent={Transition}
open={!!readMeOpen}
onClose={() => {
dispatch(closeShareReadme());
}}
>
<ReadMeContent />
</Dialog>
);
};
export default ReadMeDialog;

View File

@@ -0,0 +1,28 @@
import { Box, Collapse } from "@mui/material";
import { useAppSelector } from "../../../redux/hooks.ts";
import { RadiusFrame } from "../../Frame/RadiusFrame.tsx";
import ReadMeContent from "./ReadMeContent.tsx";
const ReadMeSideBar = () => {
const readMeOpen = useAppSelector((state) => state.globalState.shareReadmeOpen);
return (
<Box>
<Collapse in={readMeOpen} sx={{ height: "100%" }} orientation={"horizontal"} unmountOnExit timeout={"auto"}>
<RadiusFrame
sx={{
width: "400px",
height: "100%",
ml: 1,
overflow: "hidden",
borderRadius: (theme) => theme.shape.borderRadius / 8,
}}
withBorder={true}
>
<ReadMeContent />
</RadiusFrame>
</Collapse>
</Box>
);
};
export default ReadMeSideBar;