This commit is contained in:
2024-02-25 08:27:01 +08:00
commit 20c1fa08dc
279 changed files with 78489 additions and 0 deletions

30
src/hooks/fileSubtitle.js Normal file
View File

@@ -0,0 +1,30 @@
import { useDispatch } from "react-redux";
import { useCallback, useEffect, useState } from "react";
import { changeSubTitle } from "../redux/viewUpdate/action";
import pathHelper from "../utils/page";
export default function UseFileSubTitle(query, math, location) {
const dispatch = useDispatch();
const [title, setTitle] = useState("");
const [path, setPath] = useState("");
const SetSubTitle = useCallback(
(title) => dispatch(changeSubTitle(title)),
[dispatch]
);
useEffect(() => {
if (!pathHelper.isSharePage(location.pathname)) {
const path = query.get("p").split("/");
setPath(query.get("p"));
SetSubTitle(path[path.length - 1]);
setTitle(path[path.length - 1]);
} else {
SetSubTitle(query.get("name"));
setTitle(query.get("name"));
setPath(query.get("share_path"));
}
// eslint-disable-next-line
}, [math.params[0], location]);
return { title, path };
}

132
src/hooks/normal.js Normal file
View File

@@ -0,0 +1,132 @@
import React, {
forwardRef,
useCallback,
useEffect,
useRef,
useState,
} from "react";
import { useDispatch } from "react-redux";
import API from "../middleware/Api";
import {
FormControl,
Input,
InputAdornment,
InputLabel,
makeStyles,
TextField,
} from "@material-ui/core";
import Placeholder from "../component/Placeholder/Captcha";
import { defaultValidate, useStyle } from "./useCaptcha";
import { toggleSnackbar } from "../redux/explorer";
import { useTranslation } from "react-i18next";
const NormalCaptcha = forwardRef(function NormalCaptcha(
{ captchaRef, setLoading },
ref
) {
const { t } = useTranslation();
const classes = useStyle();
const [captcha, setCaptcha] = useState("");
const [captchaData, setCaptchaData] = useState(null);
const dispatch = useDispatch();
const ToggleSnackbar = useCallback(
(vertical, horizontal, msg, color) =>
dispatch(toggleSnackbar(vertical, horizontal, msg, color)),
[dispatch]
);
const refreshCaptcha = () => {
API.get("/site/captcha")
.then((response) => {
setCaptchaData(response.data);
setLoading(false);
})
.catch((error) => {
ToggleSnackbar(
"top",
"right",
t("login.captchaError", { message: error.message }),
"error"
);
});
};
useEffect(() => {
ref.current = refreshCaptcha;
refreshCaptcha();
}, []);
useEffect(() => {
captchaRef.current.captchaCode = captcha;
}, [captcha]);
return (
<div className={classes.captchaInputContainer}>
<FormControl margin="normal" required fullWidth>
<TextField
variant={"outlined"}
label={t("login.captcha")}
inputProps={{
name: "captcha",
id: "captcha",
}}
onChange={(e) => setCaptcha(e.target.value)}
value={captcha}
autoComplete
InputProps={{
endAdornment: (
<InputAdornment position={"end"}>
<div
className={classes.captchaImageContainer}
title={t("login.clickToRefresh")}
>
{captchaData === null && <Placeholder />}
{captchaData !== null && (
<img
className={classes.captchaImage}
src={captchaData}
alt="captcha"
onClick={refreshCaptcha}
/>
)}
</div>
</InputAdornment>
),
}}
/>
</FormControl>{" "}
</div>
);
});
export default function useNormalCaptcha(captchaRefreshRef, setLoading) {
const isValidate = useRef({
isValidate: true,
});
const captchaParamsRef = useRef({
captchaCode: "",
});
const CaptchaRender = useCallback(
function Normal() {
return (
<NormalCaptcha
captchaRef={captchaParamsRef}
ref={captchaRefreshRef}
setLoading={setLoading}
/>
);
},
[captchaParamsRef, captchaRefreshRef, setLoading]
);
return {
isValidate,
validate: defaultValidate,
captchaParamsRef,
CaptchaRender,
};
}

29
src/hooks/pagination.js Normal file
View File

@@ -0,0 +1,29 @@
import React, { useMemo } from "react";
import { useSelector } from "react-redux";
const paginate = (array, page_size, page_number) =>
page_size === -1
? array
: array.slice((page_number - 1) * page_size, page_number * page_size);
export function usePagination() {
const files = useSelector((state) => state.explorer.fileList);
const folders = useSelector((state) => state.explorer.dirList);
const pagination = useSelector((state) => state.viewUpdate.pagination);
const { dirList, fileList, startIndex } = useMemo(() => {
const all = paginate(
[...folders, ...files],
pagination.size,
pagination.page
);
const dirList = [];
const fileList = [];
all.forEach((v) =>
v.type === "dir" ? dirList.push(v) : fileList.push(v)
);
const startIndex = pagination.size * (pagination.page - 1);
return { dirList, fileList, startIndex };
}, [folders, files, pagination]);
return { dirList, fileList, startIndex };
}

68
src/hooks/recaptcha.js Normal file
View File

@@ -0,0 +1,68 @@
import React, { useCallback, useEffect, useRef, useState } from "react";
import { useSelector } from "react-redux";
import { FormControl } from "@material-ui/core";
import ReCaptcha from "../component/Login/ReCaptcha";
import { defaultValidate, useStyle } from "./useCaptcha";
const Recaptcha = ({ captchaRef, setLoading }) => {
const classes = useStyle();
const [captcha, setCaptcha] = useState("");
const reCaptchaKey = useSelector(
(state) => state.siteConfig.captcha_ReCaptchaKey
);
useEffect(() => {
captchaRef.current.captchaCode = captcha;
}, [captcha]);
useEffect(() => setLoading(false), []);
return (
<div className={classes.captchaContainer}>
<FormControl margin="normal" required fullWidth>
<div>
<ReCaptcha
style={{
display: "inline-block",
}}
sitekey={reCaptchaKey}
onChange={(value) => setCaptcha(value)}
id="captcha"
name="captcha"
/>
</div>
</FormControl>{" "}
</div>
);
};
export default function useRecaptcha(setLoading) {
const isValidate = useRef({
isValidate: true,
});
const captchaParamsRef = useRef({
captchaCode: "",
});
const CaptchaRender = useCallback(
function RecaptchaRender() {
return (
<Recaptcha
captchaRef={captchaParamsRef}
setLoading={setLoading}
/>
);
},
[captchaParamsRef, setLoading]
);
return {
isValidate,
validate: defaultValidate,
captchaParamsRef,
CaptchaRender,
};
}

81
src/hooks/tcaptcha.js Normal file
View File

@@ -0,0 +1,81 @@
import React, { forwardRef, useCallback, useRef } from "react";
import Script from "react-load-script";
import { useSelector } from "react-redux";
const TCaptcha = forwardRef(function TCaptcha(
{ captchaRef, setLoading, isValidateRef, submitRef },
ref
) {
const appid = useSelector(
(state) => state.siteConfig.tcaptcha_captcha_app_id
);
const onLoad = () => {
try {
ref.current = new window.TencentCaptcha(appid, function (res) {
if (res.ret === 0) {
captchaRef.current.ticket = res.ticket;
captchaRef.current.randstr = res.randstr;
isValidateRef.current.isValidate = true;
submitRef.current.submit();
console.log(submitRef);
} else {
submitRef.current.setLoading(false);
}
});
} catch (e) {
console.error(e);
}
setLoading(false);
};
return (
<Script
url={"https://ssl.captcha.qq.com/TCaptcha.js"}
onLoad={onLoad}
/>
);
});
export default function useTCaptcha(setLoading) {
const isValidate = useRef({
isValidate: false,
});
const captchaParamsRef = useRef({
ticket: "",
randstr: "",
});
const submitRef = useRef({
// eslint-disable-next-line @typescript-eslint/no-empty-function
submit: () => {},
// eslint-disable-next-line @typescript-eslint/no-empty-function
setLoading: () => {},
});
const captchaRef = useRef();
const CaptchaRender = useCallback(
function TCaptchaRender() {
return (
<TCaptcha
captchaRef={captchaParamsRef}
setLoading={setLoading}
isValidateRef={isValidate}
submitRef={submitRef}
ref={captchaRef}
/>
);
},
[captchaParamsRef, setLoading, isValidate, submitRef, captchaRef]
);
return {
isValidate: isValidate,
validate: (submit, setLoading) => {
submitRef.current.submit = submit;
submitRef.current.setLoading = setLoading;
captchaRef.current.show();
},
captchaParamsRef,
CaptchaRender,
};
}

59
src/hooks/useCaptcha.js Normal file
View File

@@ -0,0 +1,59 @@
import { useSelector } from "react-redux";
import { useRef, useState } from "react";
import { makeStyles } from "@material-ui/core";
import useNormalCaptcha from "./normal";
import useRecaptcha from "./recaptcha";
import useTCaptcha from "./tcaptcha";
export const useStyle = makeStyles((theme) => ({
captchaContainer: {
display: "flex",
marginTop: "10px",
alignItems: "center",
[theme.breakpoints.down("sm")]: {
marginTop: 0,
display: "block",
},
},
captchaInputContainer: {
marginTop: 0,
},
captchaImageContainer: {
cursor: "pointer",
marginLeft: "1rem",
[theme.breakpoints.down("sm")]: {
marginLeft: 0,
},
},
captchaImage: {
borderRadius: theme.shape.borderRadius,
height: 48,
marginTop: 4,
},
}));
// eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/no-empty-function
export const defaultValidate = (submit, setLoading) => {};
export const useCaptcha = () => {
const captchaType = useSelector((state) => state.siteConfig.captcha_type);
const [captchaLoading, setCaptchaLoading] = useState(true);
// eslint-disable-next-line @typescript-eslint/no-empty-function
const captchaRefreshRef = useRef(() => {});
const normal = useNormalCaptcha(captchaRefreshRef, setCaptchaLoading);
const recaptcha = useRecaptcha(setCaptchaLoading);
const tcaptcha = useTCaptcha(setCaptchaLoading);
switch (captchaType) {
case "normal":
return { ...normal, captchaRefreshRef, captchaLoading };
case "recaptcha":
return { ...recaptcha, captchaRefreshRef, captchaLoading };
case "tcaptcha":
return { ...tcaptcha, captchaRefreshRef, captchaLoading };
default:
return { ...normal, captchaRefreshRef, captchaLoading };
}
};