diff --git a/src/components/notice.tsx b/src/components/notice.tsx
new file mode 100644
index 0000000..eedc7a5
--- /dev/null
+++ b/src/components/notice.tsx
@@ -0,0 +1,88 @@
+import ReactDOM from "react-dom";
+import { ReactNode, useState } from "react";
+import { Box, IconButton, Slide, Snackbar, Typography } from "@mui/material";
+import { Close, CheckCircleRounded, ErrorRounded } from "@mui/icons-material";
+
+interface InnerProps {
+ type: string;
+ duration?: number;
+ message: ReactNode;
+ onClose: () => void;
+}
+
+const NoticeInner = (props: InnerProps) => {
+ const { type, message, duration = 2000, onClose } = props;
+ const [visible, setVisible] = useState(true);
+
+ const onBtnClose = () => {
+ setVisible(false);
+ onClose();
+ };
+ const onAutoClose = (_e: any, reason: string) => {
+ if (reason !== "clickaway") onBtnClose();
+ };
+
+ const msgElement =
+ type === "info" ? (
+ message
+ ) : (
+
+ {type === "error" && }
+ {type === "success" && }
+
+ {message}
+
+ );
+
+ return (
+ }
+ transitionDuration={200}
+ action={
+
+
+
+ }
+ />
+ );
+};
+
+interface NoticeInstance {
+ (props: Omit): void;
+
+ info(message: ReactNode, duration?: number): void;
+ error(message: ReactNode, duration?: number): void;
+ success(message: ReactNode, duration?: number): void;
+}
+
+let parent: HTMLDivElement = null!;
+
+// @ts-ignore
+const Notice: NoticeInstance = (props) => {
+ if (!parent) {
+ parent = document.createElement("div");
+ document.body.appendChild(parent);
+ }
+
+ const container = document.createElement("div");
+ parent.appendChild(container);
+
+ const onUnmount = () => {
+ const result = ReactDOM.unmountComponentAtNode(container);
+ if (result && parent) parent.removeChild(container);
+ };
+
+ ReactDOM.render(, container);
+};
+
+(["info", "error", "success"] as const).forEach((type) => {
+ Notice[type] = (message, duration) => Notice({ type, message, duration });
+});
+
+export default Notice;
diff --git a/src/pages/profiles.tsx b/src/pages/profiles.tsx
index 57ef2d4..cbf8a3f 100644
--- a/src/pages/profiles.tsx
+++ b/src/pages/profiles.tsx
@@ -9,14 +9,13 @@ import {
} from "../services/cmds";
import { getProxies, updateProxy } from "../services/api";
import noop from "../utils/noop";
-import useNotice from "../utils/use-notice";
+import Notice from "../components/notice";
import BasePage from "../components/base-page";
import ProfileItemComp from "../components/profile-item";
const ProfilePage = () => {
const [url, setUrl] = useState("");
const [disabled, setDisabled] = useState(false);
- const [notice, noticeElement] = useNotice();
const { mutate } = useSWRConfig();
const { data: profiles = {} } = useSWR("getProfiles", getProfiles);
@@ -72,9 +71,9 @@ const ProfilePage = () => {
await importProfile(url);
mutate("getProfiles", getProfiles());
if (!profiles.items?.length) selectProfile(0).catch(noop);
- notice.success("Successfully import profile.");
+ Notice.success("Successfully import profile.");
} catch {
- notice.error("Failed to import profile.");
+ Notice.error("Failed to import profile.");
} finally {
setDisabled(false);
}
@@ -108,7 +107,7 @@ const ProfilePage = () => {
fullWidth
value={url}
onChange={(e) => setUrl(e.target.value)}
- sx={{ mr: 4 }}
+ sx={{ mr: 2 }}
/>