mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-11-08 19:22:44 +08:00
feat(notice): persist toast position preference (#5621)
* feat(notice): persist toast position preference * docs: Changelog.md
This commit is contained in:
@@ -1,6 +1,12 @@
|
||||
import { CloseRounded } from "@mui/icons-material";
|
||||
import { Snackbar, Alert, IconButton, Box } from "@mui/material";
|
||||
import React, { useSyncExternalStore } from "react";
|
||||
import {
|
||||
Snackbar,
|
||||
Alert,
|
||||
IconButton,
|
||||
Box,
|
||||
type SnackbarOrigin,
|
||||
} from "@mui/material";
|
||||
import React, { useMemo, useSyncExternalStore } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import {
|
||||
@@ -10,8 +16,41 @@ import {
|
||||
} from "@/services/notice-service";
|
||||
import type { TranslationKey } from "@/types/generated/i18n-keys";
|
||||
|
||||
export const NoticeManager: React.FC = () => {
|
||||
type NoticePosition = NonNullable<IVergeConfig["notice_position"]>;
|
||||
|
||||
const VALID_POSITIONS: NoticePosition[] = [
|
||||
"top-left",
|
||||
"top-right",
|
||||
"bottom-left",
|
||||
"bottom-right",
|
||||
];
|
||||
|
||||
const resolvePosition = (position?: NoticePosition | null): NoticePosition => {
|
||||
if (position && VALID_POSITIONS.includes(position)) {
|
||||
return position;
|
||||
}
|
||||
return "top-right";
|
||||
};
|
||||
|
||||
const getAnchorOrigin = (position: NoticePosition): SnackbarOrigin => {
|
||||
const [vertical, horizontal] = position.split("-") as [
|
||||
SnackbarOrigin["vertical"],
|
||||
SnackbarOrigin["horizontal"],
|
||||
];
|
||||
return { vertical, horizontal };
|
||||
};
|
||||
|
||||
interface NoticeManagerProps {
|
||||
position?: NoticePosition | null;
|
||||
}
|
||||
|
||||
export const NoticeManager: React.FC<NoticeManagerProps> = ({ position }) => {
|
||||
const { t } = useTranslation();
|
||||
const resolvedPosition = useMemo(() => resolvePosition(position), [position]);
|
||||
const anchorOrigin = useMemo(
|
||||
() => getAnchorOrigin(resolvedPosition),
|
||||
[resolvedPosition],
|
||||
);
|
||||
const currentNotices = useSyncExternalStore(
|
||||
subscribeNotices,
|
||||
getSnapshotNotices,
|
||||
@@ -25,8 +64,10 @@ export const NoticeManager: React.FC = () => {
|
||||
<Box
|
||||
sx={{
|
||||
position: "fixed",
|
||||
top: "20px",
|
||||
right: "20px",
|
||||
top: anchorOrigin.vertical === "top" ? "20px" : "auto",
|
||||
bottom: anchorOrigin.vertical === "bottom" ? "20px" : "auto",
|
||||
left: anchorOrigin.horizontal === "left" ? "20px" : "auto",
|
||||
right: anchorOrigin.horizontal === "right" ? "20px" : "auto",
|
||||
zIndex: 1500,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
@@ -38,7 +79,7 @@ export const NoticeManager: React.FC = () => {
|
||||
<Snackbar
|
||||
key={notice.id}
|
||||
open={true}
|
||||
anchorOrigin={{ vertical: "top", horizontal: "right" }}
|
||||
anchorOrigin={anchorOrigin}
|
||||
sx={{
|
||||
position: "relative",
|
||||
transform: "none",
|
||||
|
||||
Reference in New Issue
Block a user