feat: function delete chat dev done

This commit is contained in:
butterfly 2024-04-26 19:33:22 +08:00
parent 48e8c0a194
commit 1a636b0f50
36 changed files with 598 additions and 187 deletions

View File

@ -0,0 +1,136 @@
import React, { useState } from "react";
import { createRoot } from "react-dom/client";
import * as AlertDialog from "@radix-ui/react-alert-dialog";
import Warning from "@/app/icons/warning.svg";
import Btn from "@/app/components/Btn";
interface ConfirmProps {
onOk?: () => Promise<void> | void;
onCancel?: () => void;
okText: string;
cancelText: string;
content: React.ReactNode;
title: React.ReactNode;
visible?: boolean;
}
const baseZIndex = 150;
const Confirm = (props: ConfirmProps) => {
const { visible, onOk, onCancel, okText, cancelText, content, title } = props;
const [open, setOpen] = useState(false);
const mergeOpen = visible ?? open;
return (
<AlertDialog.Root open={mergeOpen} onOpenChange={setOpen}>
<AlertDialog.Portal>
<AlertDialog.Overlay
className="bg-confirm-mask fixed inset-0 animate-mask "
style={{ zIndex: baseZIndex - 1 }}
/>
<AlertDialog.Content
className={`
fixed inset-0 flex flex-col item-start top-0 left-[50vw] translate-x-[-50%]
`}
style={{ zIndex: baseZIndex - 1 }}
>
<div className="flex-1">&nbsp;</div>
<div
className={`flex flex-col
bg-confirm-panel text-confirm-mask
md:p-6 md:w-confirm md:gap-6 md:rounded-lg
`}
>
<AlertDialog.Title
className={`
flex items-center justify-start gap-3 font-common
md:text-chat-header-title md:font-bold md:leading-5
`}
>
<Warning />
{title}
</AlertDialog.Title>
<AlertDialog.Description
className={`
font-common font-normal
md:text-sm-title md:leading-[158%]
`}
>
{content}
</AlertDialog.Description>
<div
style={{ display: "flex", gap: 10, justifyContent: "flex-end" }}
>
<AlertDialog.Cancel asChild>
<Btn
className={`
md:px-4 md:py-2.5 bg-delete-chat-cancel-btn border border-delete-chat-cancel-btn text-text-delete-chat-cancel-btn rounded-md
`}
onClick={() => {
setOpen(false);
onCancel?.();
}}
text={cancelText}
/>
</AlertDialog.Cancel>
<AlertDialog.Action asChild>
<Btn
className={`
md:px-4 md:py-2.5 bg-delete-chat-ok-btn text-text-delete-chat-ok-btn rounded-md
`}
onClick={() => {
const toDo = onOk?.();
if (toDo instanceof Promise) {
toDo.then(() => {
setOpen(false);
});
} else {
setOpen(false);
}
}}
text={okText}
/>
</AlertDialog.Action>
</div>
</div>
<div className="flex-1">&nbsp;</div>
</AlertDialog.Content>
</AlertDialog.Portal>
</AlertDialog.Root>
);
};
const div = document.createElement("div");
div.id = "confirm-root";
div.style.height = "0px";
document.body.appendChild(div);
const show = (props: Omit<ConfirmProps, "visible" | "onCancel" | "onOk">) => {
const root = createRoot(div);
const closeModal = () => {
root.unmount();
};
return new Promise<boolean>((resolve) => {
root.render(
<Confirm
{...props}
visible={true}
onCancel={() => {
closeModal();
resolve(false);
}}
onOk={() => {
closeModal();
resolve(true);
}}
/>,
);
});
};
Confirm.show = show;
export default Confirm;

View File

@ -52,13 +52,13 @@ export function ListItem(props: ListItemProps) {
const context = useContext(ListContext);
const [childrenType, setMeta] = useState<ChildrenMeta["type"]>("unknown");
const [childrenMeta, setMeta] = useState<ChildrenMeta>({});
const { inputNextLine, rangeNextLine } = context;
let internalNextLine;
switch (childrenType) {
switch (childrenMeta.type) {
case "input":
internalNextLine = !!(nextline || inputNextLine);
break;
@ -69,8 +69,8 @@ export function ListItem(props: ListItemProps) {
internalNextLine = false;
}
const updateType = useCallback((m: ChildrenMeta) => {
setMeta(m.type);
const update = useCallback((m: ChildrenMeta) => {
setMeta(m);
}, []);
return (
@ -88,7 +88,7 @@ export function ListItem(props: ListItemProps) {
<div className={` text-sm text-text-list-subtitle`}>{subTitle}</div>
)}
</div>
<ListContext.Provider value={{ ...context, update: updateType }}>
<ListContext.Provider value={{ ...context, update }}>
<div
className={`${
internalNextLine ? "mt-[0.625rem]" : "max-w-[70%]"

View File

@ -86,13 +86,13 @@ export default function MenuLayout<
/>
{!isMobileScreen && (
<div
className={`group absolute right-0 h-[100%] flex items-center`}
className={`group/menu-dragger absolute right-0 h-[100%] flex items-center`}
onPointerDown={(e) => {
startDragWidth.current = config.sidebarWidth;
onDragStart(e as any);
}}
>
<div className="opacity-0 group-hover:bg-[rgba($color: #000000, $alpha: 0.01)] group-hover:opacity-20">
<div className="opacity-0 group-hover/menu-dragger:bg-[rgba($color: #000000, $alpha: 0.01)] group-hover/menu-dragger:opacity-20">
<DragIcon />
</div>
</div>

View File

@ -1,9 +1,16 @@
import useRelativePosition from "@/app/hooks/useRelativePosition";
import { getCSSVar } from "@/app/utils";
import { useMemo, useState } from "react";
import { RefObject, useEffect, useMemo, useRef, useState } from "react";
import { createPortal } from "react-dom";
const ArrowIcon = ({ color }: { color: string }) => {
const ArrowIcon = ({ sibling }: { sibling: RefObject<HTMLDivElement> }) => {
const [color, setColor] = useState<string>("");
useEffect(() => {
if (sibling.current) {
const { backgroundColor } = window.getComputedStyle(sibling.current);
setColor(backgroundColor);
}
}, []);
return (
<svg
xmlns="http://www.w3.org/2000/svg"
@ -33,10 +40,10 @@ if (!popoverRoot) {
popoverRoot.style.position = "fixed";
popoverRoot.style.bottom = "0";
popoverRoot.style.zIndex = "100";
popoverRoot.id = "popoverRootName";
popoverRoot.id = "popover-root";
}
export default function Popover(props: {
export interface PopoverProps {
content?: JSX.Element | string;
children?: JSX.Element;
show?: boolean;
@ -44,10 +51,12 @@ export default function Popover(props: {
className?: string;
popoverClassName?: string;
trigger?: "hover" | "click";
placement?: "t" | "lt" | "rt" | "lb" | "rb" | "b";
placement?: "t" | "lt" | "rt" | "lb" | "rb" | "b" | "l" | "r";
noArrow?: boolean;
bgcolor?: string;
}) {
delayClose?: number;
}
export default function Popover(props: PopoverProps) {
const {
content,
children,
@ -58,7 +67,7 @@ export default function Popover(props: {
trigger = "hover",
placement = "t",
noArrow = false,
bgcolor,
delayClose = 0,
} = props;
const [internalShow, setShow] = useState(false);
@ -66,6 +75,17 @@ export default function Popover(props: {
delay: 0,
});
const popoverCommonClass = `absolute p-2 box-border`;
const mergedShow = show ?? internalShow;
const { arrowClassName, placementStyle } = useMemo(() => {
const arrowCommonClassName = `${
noArrow ? "hidden" : ""
} absolute z-10 left-[50%] translate-x-[calc(-50%)]`;
let defaultTopPlacement = true; // when users dont config 't' or 'b'
const {
distanceToBottomBoundary = 0,
distanceToLeftBoundary = 0,
@ -75,102 +95,107 @@ export default function Popover(props: {
targetW = 0,
} = position?.poi || {};
let placementStyle: React.CSSProperties = {};
const popoverCommonClass = `absolute p-2 box-border`;
const mergedShow = show ?? internalShow;
let placementClassName;
let arrowClassName = "absolute left-[50%] translate-x-[calc(-50%)]";
arrowClassName += " ";
switch (placement) {
case "b":
placementStyle = {
top: `calc(-${distanceToBottomBoundary}px + 0.5rem)`,
left: `calc(${distanceToLeftBoundary + targetW}px - ${
targetW * 0.02
}px)`,
transform: "translateX(-50%)",
};
placementClassName =
"top-[calc(100%+0.5rem)] left-[50%] translate-x-[calc(-50%)]";
arrowClassName += "top-[calc(100%+0.5rem)] translate-y-[calc(-100%)]";
break;
// case 'l':
// placementClassName = '';
// break;
// case 'r':
// placementClassName = '';
// break;
case "rb":
placementStyle = {
top: `calc(-${distanceToBottomBoundary}px + 0.5rem)`,
right: `calc(${distanceToRightBoundary}px - ${targetW * 0.02}px)`,
};
placementClassName = "top-[calc(100%+0.5rem)] right-[calc(-2%)]";
arrowClassName += "top-[calc(100%+0.5rem)] translate-y-[calc(-100%)]";
break;
case "rt":
placementStyle = {
bottom: `calc(${distanceToBottomBoundary + targetH}px + 0.5rem)`,
right: `calc(${distanceToRightBoundary}px - ${targetW * 0.02}px)`,
};
placementClassName = "bottom-[calc(100%+0.5rem)] right-[calc(-2%)]";
arrowClassName += "bottom-[calc(100%+0.5rem)] translate-y-[calc(100%)]";
break;
case "lt":
placementStyle = {
bottom: `calc(${distanceToBottomBoundary + targetH}px + 0.5rem)`,
left: `calc(${distanceToLeftBoundary}px - ${targetW * 0.02}px)`,
};
placementClassName = "bottom-[calc(100%+0.5rem)] left-[calc(-2%)]";
arrowClassName += "bottom-[calc(100%+0.5rem)] translate-y-[calc(100%)]";
break;
case "lb":
placementStyle = {
top: `calc(-${distanceToBottomBoundary}px + 0.5rem)`,
left: `calc(${distanceToLeftBoundary}px - ${targetW * 0.02}px)`,
};
placementClassName = "top-[calc(100%+0.5rem)] left-[calc(-2%)]";
arrowClassName += "top-[calc(100%+0.5rem)] translate-y-[calc(-100%)]";
break;
case "t":
default:
placementStyle = {
bottom: `calc(${distanceToBottomBoundary + targetH}px + 0.5rem)`,
left: `calc(${distanceToLeftBoundary + targetW}px - ${
targetW * 0.02
}px)`,
transform: "translateX(-50%)",
};
placementClassName =
"bottom-[calc(100%+0.5rem)] left-[50%] translate-x-[calc(-50%)]";
arrowClassName += "bottom-[calc(100%+0.5rem)] translate-y-[calc(100%)]";
if (distanceToBottomBoundary > distanceToTopBoundary) {
defaultTopPlacement = false;
}
if (noArrow) {
arrowClassName = "hidden";
}
const placements = {
lt: {
placementStyle: {
bottom: `calc(${distanceToBottomBoundary + targetH}px + 0.5rem)`,
left: `calc(${distanceToLeftBoundary}px - ${targetW * 0.02}px)`,
},
arrowClassName: `${arrowCommonClassName} bottom-[calc(100%+0.5rem)] translate-y-[calc(100%)]`,
},
lb: {
placementStyle: {
top: `calc(-${distanceToBottomBoundary}px + 0.5rem)`,
left: `calc(${distanceToLeftBoundary}px - ${targetW * 0.02}px)`,
},
arrowClassName: `${arrowCommonClassName} top-[calc(100%+0.5rem)] translate-y-[calc(-100%)]`,
},
rt: {
placementStyle: {
bottom: `calc(${distanceToBottomBoundary + targetH}px + 0.5rem)`,
right: `calc(${distanceToRightBoundary}px - ${targetW * 0.02}px)`,
},
arrowClassName: `${arrowCommonClassName} bottom-[calc(100%+0.5rem)] translate-y-[calc(100%)]`,
},
rb: {
placementStyle: {
top: `calc(-${distanceToBottomBoundary}px + 0.5rem)`,
right: `calc(${distanceToRightBoundary}px - ${targetW * 0.02}px)`,
},
arrowClassName: `${arrowCommonClassName} top-[calc(100%+0.5rem)] translate-y-[calc(-100%)]`,
},
t: {
placementStyle: {
bottom: `calc(${distanceToBottomBoundary + targetH}px + 0.5rem)`,
left: `calc(${distanceToLeftBoundary + targetW / 2}px`,
transform: "translateX(-50%)",
},
arrowClassName: `${arrowCommonClassName} bottom-[calc(100%+0.5rem)] translate-y-[calc(100%)]`,
},
b: {
placementStyle: {
top: `calc(-${distanceToBottomBoundary}px + 0.5rem)`,
left: `calc(${distanceToLeftBoundary + targetW / 2}px`,
transform: "translateX(-50%)",
},
arrowClassName: `${arrowCommonClassName} top-[calc(100%+0.5rem)] translate-y-[calc(-100%)]`,
},
};
const internalBgColor = useMemo(() => {
return bgcolor ?? getCSSVar("--tip-popover-color");
}, [bgcolor]);
const getStyle = () => {
if (["l", "r"].includes(placement)) {
return placements[
`${placement}${defaultTopPlacement ? "t" : "b"}` as
| "lt"
| "lb"
| "rb"
| "rt"
];
}
return placements[placement as Exclude<typeof placement, "l" | "r">];
};
return getStyle();
}, [Object.values(position?.poi || {})]);
const popoverRef = useRef<HTMLDivElement>(null);
const closeTimer = useRef<number>(0);
if (trigger === "click") {
const handleOpen = (e: { currentTarget: any }) => {
clearTimeout(closeTimer.current);
onShow?.(true);
setShow(true);
getRelativePosition(e.currentTarget, "");
window.document.documentElement.style.overflow = "hidden";
};
const handleClose = () => {
if (delayClose) {
closeTimer.current = window.setTimeout(() => {
onShow?.(false);
setShow(false);
}, delayClose);
} else {
onShow?.(false);
setShow(false);
}
window.document.documentElement.style.overflow = "auto";
};
return (
<div
className={`relative ${className}`}
onClick={(e) => {
e.preventDefault();
onShow?.(!mergedShow);
setShow(!mergedShow);
e.stopPropagation();
if (!mergedShow) {
getRelativePosition(e.currentTarget, "");
window.document.documentElement.style.overflow = "hidden";
handleOpen(e);
} else {
window.document.documentElement.style.overflow = "auto";
handleClose();
}
}}
>
@ -179,29 +204,32 @@ export default function Popover(props: {
<>
{!noArrow && (
<div className={`${arrowClassName}`}>
<ArrowIcon color={internalBgColor} />
<ArrowIcon sibling={popoverRef} />
</div>
)}
{createPortal(
<div
className={`${popoverCommonClass} ${popoverClassName} cursor-pointer`}
style={{ zIndex: baseZIndex + 1, ...placementStyle }}
ref={popoverRef}
>
{content}
</div>,
popoverRoot,
)}
{createPortal(
<div
className=" fixed w-[100%] h-[100%] top-0 left-0 right-0 bottom-0"
className=" fixed w-[100vw] h-[100vh] right-0 bottom-0"
style={{ zIndex: baseZIndex }}
onClick={(e) => {
e.preventDefault();
onShow?.(!mergedShow);
setShow(!mergedShow);
handleClose();
}}
>
&nbsp;
</div>
</div>,
popoverRoot,
)}
</>
)}
</div>
@ -209,18 +237,53 @@ export default function Popover(props: {
}
return (
<div className={`group relative ${className}`}>
{children}
{!noArrow && (
<div className={`hidden group-hover:block ${arrowClassName}`}>
<ArrowIcon color={internalBgColor} />
</div>
)}
<div
className={`hidden group-hover:block ${popoverCommonClass} ${placementClassName} ${popoverClassName}`}
className={`relative ${className}`}
onPointerEnter={(e) => {
e.preventDefault();
clearTimeout(closeTimer.current);
onShow?.(true);
setShow(true);
getRelativePosition(e.currentTarget, "");
window.document.documentElement.style.overflow = "hidden";
}}
onPointerLeave={(e) => {
e.preventDefault();
if (delayClose) {
closeTimer.current = window.setTimeout(() => {
onShow?.(false);
setShow(false);
}, delayClose);
} else {
onShow?.(false);
setShow(false);
}
window.document.documentElement.style.overflow = "auto";
}}
>
{children}
{mergedShow && (
<>
<div
className={`${
noArrow ? "opacity-0" : ""
} bg-inherit ${arrowClassName}`}
style={{ zIndex: baseZIndex + 1 }}
>
<ArrowIcon sibling={popoverRef} />
</div>
{createPortal(
<div
className={` whitespace-nowrap ${popoverCommonClass} ${popoverClassName} cursor-pointer`}
style={{ zIndex: baseZIndex + 1, ...placementStyle }}
ref={popoverRef}
>
{content}
</div>
</div>,
popoverRoot,
)}
</>
)}
</div>
);
}

View File

@ -1,6 +1,6 @@
import { useContext, useEffect, useRef } from "react";
import { ListContext } from "@/app/components/List";
import useResizeObserver from "use-resize-observer";
import { useResizeObserver } from "usehooks-ts";
interface SlideRangeProps {
className?: string;
@ -31,13 +31,16 @@ export default function SlideRange(props: SlideRangeProps) {
const slideRef = useRef<HTMLDivElement>(null);
const { ref, width = 1 } = useResizeObserver<HTMLDivElement>();
ref(slideRef.current);
useResizeObserver({
ref: slideRef,
onResize: () => {
setProperty(value);
},
});
const transformToWidth = (x: number = start) => {
const abs = x - start;
const maxWidth = width - margin * 2;
const maxWidth = (slideRef.current?.clientWidth || 1) - margin * 2;
const result = (abs / stroke) * maxWidth;
return result;
};
@ -49,10 +52,10 @@ export default function SlideRange(props: SlideRangeProps) {
`${initWidth + margin}px`,
);
};
useEffect(() => {
setProperty(value);
update?.({ type: "range" });
}, [width]);
}, []);
return (
<div

View File

@ -18,14 +18,16 @@ import { useCommand } from "@/app/command";
import { prettyObject } from "@/app/utils/format";
import { ExportMessageModal } from "@/app/components/exporter";
import PromptToast from "./PromptToast";
import { EditMessageModal } from "./EditMessageModal";
import ChatHeader from "./ChatHeader";
import ChatInputPanel, { ChatInputPanelInstance } from "./ChatInputPanel";
import ChatMessagePanel, { RenderMessage } from "./ChatMessagePanel";
import PromptToast from "./components/PromptToast";
import { EditMessageModal } from "./components/EditMessageModal";
import ChatHeader from "./components/ChatHeader";
import ChatInputPanel, {
ChatInputPanelInstance,
} from "./components/ChatInputPanel";
import ChatMessagePanel, { RenderMessage } from "./components/ChatMessagePanel";
import { useAllModels } from "@/app/utils/hooks";
import useRows from "@/app/hooks/useRows";
import SessionConfigModel from "./SessionConfigModal";
import SessionConfigModel from "./components/SessionConfigModal";
import useScrollToBottom from "@/app/hooks/useScrollToBottom";
function _Chat() {

View File

@ -208,7 +208,7 @@ export function ChatActions(props: {
);
}
const popoverClassName = `bg-chat-actions-btn-popover whitespace-nowrap px-3 py-2.5 text-text-chat-actions-btn-popover text-sm-title rounded-md`;
const popoverClassName = `bg-chat-actions-btn-popover px-3 py-2.5 text-text-chat-actions-btn-popover text-sm-title rounded-md`;
return (
<div className={`flex gap-2 item-center ${props.className}`}>

View File

@ -1,13 +1,9 @@
import { Fragment, useEffect, useMemo } from "react";
import { Fragment, useMemo } from "react";
import { ChatMessage, useChatStore } from "@/app/store/chat";
import { CHAT_PAGE_SIZE } from "@/app/constant";
import Locale from "@/app/locales";
import {
getMessageImages,
getMessageTextContent,
selectOrCopy,
} from "@/app/utils";
import { getMessageTextContent, selectOrCopy } from "@/app/utils";
import LoadingIcon from "@/app/icons/three-dots.svg";

View File

@ -1,7 +1,7 @@
import { useEffect, useRef, useState } from "react";
import { Prompt } from "@/app/store/prompt";
import styles from "./index.module.scss";
import styles from "../index.module.scss";
import useShowPromptHint from "@/app/hooks/useShowPromptHint";
export type RenderPompt = Pick<Prompt, "title" | "content">;

View File

@ -3,7 +3,7 @@ import Locale from "@/app/locales";
import BrainIcon from "@/app/icons/brain.svg";
import styles from "./index.module.scss";
import styles from "../index.module.scss";
export default function PromptToast(props: {
showToast?: boolean;

View File

@ -8,7 +8,7 @@ import { Path } from "@/app/constant";
import ResetIcon from "@/app/icons/reload.svg";
import CopyIcon from "@/app/icons/copy.svg";
import MaskConfig from "@/app/containers/Settings/MaskConfig";
import MaskConfig from "@/app/containers/Settings/components/MaskConfig";
import { ListItem } from "@/app/components/List";
export default function SessionConfigModel(props: { onClose: () => void }) {

View File

@ -12,7 +12,6 @@ import { useLocation, useNavigate } from "react-router-dom";
import { Path } from "@/app/constant";
import { Mask } from "@/app/store/mask";
import { useRef, useEffect } from "react";
import { showConfirm } from "@/app/components/ui-lib";
import AddIcon from "@/app/icons/addIcon.svg";
import NextChatTitle from "@/app/icons/nextchatTitle.svg";
@ -24,7 +23,8 @@ import LogIcon from "@/app/icons/logIcon.svg";
import MenuLayout from "@/app/components/MenuLayout";
import Panel from "./ChatPanel";
import Popover from "@/app/components/Popover";
import Popover, { PopoverProps } from "@/app/components/Popover";
import Confirm from "@/app/components/Confirm";
export function SessionItem(props: {
onClick?: () => void;
@ -37,6 +37,7 @@ export function SessionItem(props: {
index: number;
narrow?: boolean;
mask: Mask;
isMobileScreen: boolean;
}) {
const draggableRef = useRef<HTMLDivElement | null>(null);
useEffect(() => {
@ -53,7 +54,7 @@ export function SessionItem(props: {
<Draggable draggableId={`${props.id}`} index={props.index}>
{(provided) => (
<div
className={`group relative flex p-3 items-center gap-2 self-stretch rounded-md mb-2 ${
className={`group/chat-menu-list relative flex p-3 items-center gap-2 self-stretch rounded-md mb-2 ${
props.selected &&
(currentPath === Path.Chat || currentPath === Path.Home)
? `bg-chat-menu-session-selected border-chat-menu-session-selected border `
@ -81,7 +82,7 @@ export function SessionItem(props: {
{props.title}
</div>
<div
className={`text-text-chat-menu-item-time text-sm group-hover:opacity-0 pl-3`}
className={`text-text-chat-menu-item-time text-sm group-hover/chat-menu-list:opacity-0 pl-3`}
>
{getTime(props.time)}
</div>
@ -106,10 +107,17 @@ export function SessionItem(props: {
</div>
</div>
}
className=""
popoverClassName={`
px-2 py-1 border-delete-chat-popover bg-delete-chat-popover-panel rounded-md shadow-delete-chat-popover-shadow
`}
noArrow
placement={props.isMobileScreen ? "r" : "l"}
className="!absolute top-[50%] translate-y-[-50%] right-3"
trigger={props.isMobileScreen ? "click" : "hover"}
delayClose={100}
>
<div
className={`absolute top-[50%] translate-y-[-50%] right-3 pointer-events-none opacity-0 group-hover:pointer-events-auto group-hover:opacity-100`}
className={` pointer-events-none opacity-0 group-hover/chat-menu-list:pointer-events-auto group-hover/chat-menu-list:opacity-100`}
>
<DeleteIcon />
</div>
@ -230,13 +238,18 @@ export default MenuLayout(function SessionList(props) {
}}
onDelete={async () => {
if (
!isMobileScreen ||
(await showConfirm(Locale.Home.DeleteChat))
await Confirm.show({
okText: Locale.ChatItem.DeleteOkBtn,
cancelText: Locale.ChatItem.DeleteCancelBtn,
title: Locale.ChatItem.DeleteTitle,
content: Locale.ChatItem.DeleteContent,
})
) {
chatStore.deleteSession(i);
}
}}
mask={item.mask}
isMobileScreen={isMobileScreen}
/>
))}
{provided.placeholder}

View File

@ -7,15 +7,15 @@ import List from "@/app/components/List";
import { useNavigate } from "react-router-dom";
import { getClientConfig } from "@/app/config/client";
import Card from "@/app/components/Card";
import SettingHeader from "./SettingHeader";
import SettingHeader from "./components/SettingHeader";
import { MenuWrapperInspectProps } from "@/app/components/MenuLayout";
import SyncItems from "./SyncItems";
import DangerItems from "./DangerItems";
import AppSetting from "./AppSetting";
import MaskSetting from "./MaskSetting";
import PromptSetting from "./PromptSetting";
import ProviderSetting from "./ProviderSetting";
import ModelConfigList from "./ModelSetting";
import SyncItems from "./components/SyncItems";
import DangerItems from "./components/DangerItems";
import AppSetting from "./components/AppSetting";
import MaskSetting from "./components/MaskSetting";
import PromptSetting from "./components/PromptSetting";
import ProviderSetting from "./components/ProviderSetting";
import ModelConfigList from "./components/ModelSetting";
export default function Settings(props: MenuWrapperInspectProps) {
const { setShowPanel } = props;

View File

@ -1,7 +1,7 @@
import LoadingIcon from "@/app/icons/three-dots.svg";
import ResetIcon from "@/app/icons/reload.svg";
import styles from "./index.module.scss";
import styles from "../index.module.scss";
import { useEffect, useState } from "react";
import { Avatar, AvatarPicker } from "@/app/components/emoji";

View File

@ -9,7 +9,7 @@ import { copyToClipboard } from "@/app/utils";
import Locale from "@/app/locales";
import { Popover, showConfirm } from "@/app/components/ui-lib";
import { AvatarPicker } from "@/app/components/emoji";
import ModelSetting from "@/app/containers/Settings/ModelSetting";
import ModelSetting from "@/app/containers/Settings/components/ModelSetting";
import { IconButton } from "@/app/components/button";
import CopyIcon from "@/app/icons/copy.svg";

View File

@ -1,4 +1,3 @@
import { useNavigate } from "react-router-dom";
import Locale from "@/app/locales";
import GobackIcon from "@/app/icons/goback.svg";

View File

@ -11,7 +11,7 @@ import ClearIcon from "@/app/icons/clear.svg";
import EditIcon from "@/app/icons/edit.svg";
import EyeIcon from "@/app/icons/eye.svg";
import styles from "./index.module.scss";
import styles from "../index.module.scss";
import { copyToClipboard } from "@/app/utils";
import Input from "@/app/components/Input";

3
app/icons/warning.svg Normal file
View File

@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.99984 1.6665C5.40817 1.6665 1.6665 5.40817 1.6665 9.99984C1.6665 14.5915 5.40817 18.3332 9.99984 18.3332C14.5915 18.3332 18.3332 14.5915 18.3332 9.99984C18.3332 5.40817 14.5915 1.6665 9.99984 1.6665ZM9.37484 6.6665C9.37484 6.32484 9.65817 6.0415 9.99984 6.0415C10.3415 6.0415 10.6248 6.32484 10.6248 6.6665V10.8332C10.6248 11.1748 10.3415 11.4582 9.99984 11.4582C9.65817 11.4582 9.37484 11.1748 9.37484 10.8332V6.6665ZM10.7665 13.6498C10.7248 13.7582 10.6665 13.8415 10.5915 13.9248C10.5082 13.9998 10.4165 14.0582 10.3165 14.0998C10.2165 14.1415 10.1082 14.1665 9.99984 14.1665C9.8915 14.1665 9.78317 14.1415 9.68317 14.0998C9.58317 14.0582 9.4915 13.9998 9.40817 13.9248C9.33317 13.8415 9.27484 13.7582 9.23317 13.6498C9.1915 13.5498 9.1665 13.4415 9.1665 13.3332C9.1665 13.2248 9.1915 13.1165 9.23317 13.0165C9.27484 12.9165 9.33317 12.8248 9.40817 12.7415C9.4915 12.6665 9.58317 12.6082 9.68317 12.5665C9.88317 12.4832 10.1165 12.4832 10.3165 12.5665C10.4165 12.6082 10.5082 12.6665 10.5915 12.7415C10.6665 12.8248 10.7248 12.9165 10.7665 13.0165C10.8082 13.1165 10.8332 13.2248 10.8332 13.3332C10.8332 13.4415 10.8082 13.5498 10.7665 13.6498Z" fill="#FF5454"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -20,6 +20,10 @@ const cn = {
},
ChatItem: {
ChatItemCount: (count: number) => `${count} 条对话`,
DeleteContent: "删除助手后,无法检索聊天内容。你确定要删除它吗?",
DeleteTitle: "删除助手",
DeleteCancelBtn: "取消",
DeleteOkBtn: "删除",
},
Chat: {
SubTitle: (count: number) => `${count} 条对话`,

View File

@ -22,6 +22,11 @@ const en: LocaleType = {
},
ChatItem: {
ChatItemCount: (count: number) => `${count} messages`,
DeleteContent:
"After deleting the assistant, the chat content cannot be retrieved. Are you sure to delete it?",
DeleteTitle: "Delete assistant",
DeleteCancelBtn: "Cancel",
DeleteOkBtn: "Delete",
},
Chat: {
SubTitle: (count: number) => `${count} messages`,

View File

@ -70,6 +70,13 @@ body {
--menu-item-time: rgba(0, 0, 0, 0.3);
--siderbar-mobile-height: 3.125rem;
--max-message-width: calc(var(--chat-panel-max-width) * 0.6);
--confirm-mask-bg: rgba(0, 0, 0, 0.7);
--confirm-mask-text: #18182a;
--delete-chat-ok-btn-bg: #ff5454;
--delete-chat-ok-btn-text: #fff;
--delete-chat-cancel-btn-bg: #fff;
--delete-chat-cancel-btn-text: #18182a;
--delete-chat-cancel-btn-border: #e2e2e6;
}
.dark {

View File

@ -19,6 +19,7 @@
"@fortaine/fetch-event-source": "^3.0.6",
"@hello-pangea/dnd": "^16.5.0",
"@next/third-parties": "^14.1.0",
"@radix-ui/react-alert-dialog": "^1.0.5",
"@radix-ui/react-switch": "^1.0.3",
"@svgr/webpack": "^6.5.1",
"@vercel/analytics": "^0.1.11",
@ -43,7 +44,7 @@
"sass": "^1.59.2",
"spark-md5": "^3.0.2",
"use-debounce": "^9.0.4",
"use-resize-observer": "^9.1.0",
"usehooks-ts": "^3.1.0",
"zustand": "^4.3.8"
},
"devDependencies": {

View File

@ -71,6 +71,7 @@ module.exports = {
'thumbnail': '5rem',
'actions-popover': '203px',
'switch': '2.25rem',
'confirm': '26.25rem',
},
flexBasis: {
'sidebar': 'var(--menu-width)',
@ -126,6 +127,11 @@ module.exports = {
'settings-header-mobile': 'var(--similar-highlight-hood-bg)',
'settings-panel': 'var(--default-container-bg)',
'sidebar-mobile': 'var(--similar-highlight-hood-bg)',
'delete-chat-popover-panel': 'var(--similar-panel-bg)',
'confirm-mask': 'var(--confirm-mask-bg)',
'confirm-panel': 'var(--similar-panel-bg)',
'delete-chat-ok-btn': 'var(--delete-chat-ok-btn-bg)',
'delete-chat-cancel-btn': 'var(--delete-chat-cancel-btn-bg)',
},
backgroundImage: {
// 'chat-panel-message-user': 'linear-gradient(259deg, #9786FF 8.42%, #4A5CFF 90.13%)',
@ -146,7 +152,8 @@ module.exports = {
'chat-input-hood-focus-shadow': '0px 4px 20px 0px rgba(60, 68, 255, 0.13)',
'select-popover-shadow': '0px 14px 40px 0px rgba(0, 0, 0, 0.12)',
'message-actions-bar': '0px 4px 30px 0px var(--small-widget-border)',
'prompt-hint-container': 'inset 0 4px 8px 0 rgba(0, 0, 0, 0.1)'
'prompt-hint-container': 'inset 0 4px 8px 0 rgba(0, 0, 0, 0.1)',
'delete-chat-popover-shadow': '0px 0px 1px 0px rgba(0, 0, 0, 0.08), 0px 8px 20px 0px rgba(0, 0, 0, 0.08)',
},
colors: {
'select-popover': 'var(--small-widget-border)',
@ -160,6 +167,8 @@ module.exports = {
'chat-menu-session-selected': 'var(--menu-item-selected-border)',
'settings-menu-item-selected': 'var(--menu-item-selected-border)',
'settings-header': 'var(--panel-header-border)',
'delete-chat-popover': 'var(--small-widget-border)',
'delete-chat-cancel-btn': 'var(--delete-chat-cancel-btn-border)',
'text-sidebar-tab-mobile-active': 'var(--sidebar-tab-mobile-active-text)',
'text-sidebar-tab-mobile-inactive': 'var(--weakness-text)',
'text-btn-primary': 'var(--bg-contract-text)',
@ -183,7 +192,19 @@ module.exports = {
'text-settings-menu-title': 'var(--key-text)',
'text-settings-menu-item-title': 'var(--key-text)',
'text-settings-panel-header-title': 'var(--key-text)',
'text-confirm-mask': 'var(--confirm-mask-text)',
'text-delete-chat-ok-btn': 'var(--delete-chat-ok-btn-text)',
'text-delete-chat-cancel-btn': 'var(--delete-chat-cancel-btn-text)',
},
keyframes: {
mask: {
'0%': { opacity: 0 },
'100%': { opacity: 1 },
}
},
animation: {
mask: 'mask 150ms cubic-bezier(0.16, 1, 0.3, 1)'
}
},
borderRadius: {
'none': '0',

190
yarn.lock
View File

@ -1242,11 +1242,6 @@
"@jridgewell/resolve-uri" "3.1.0"
"@jridgewell/sourcemap-codec" "1.4.14"
"@juggle/resize-observer@^3.3.1":
version "3.4.0"
resolved "https://registry.npmmirror.com/@juggle/resize-observer/-/resize-observer-3.4.0.tgz#08d6c5e20cf7e4cc02fd181c4b0c225cd31dbb60"
integrity sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==
"@next/env@13.4.9":
version "13.4.9"
resolved "https://registry.yarnpkg.com/@next/env/-/env-13.4.9.tgz#b77759514dd56bfa9791770755a2482f4d6ca93e"
@ -1349,6 +1344,19 @@
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-alert-dialog@^1.0.5":
version "1.0.5"
resolved "https://registry.npmmirror.com/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.0.5.tgz#70dd529cbf1e4bff386814d3776901fcaa131b8c"
integrity sha512-OrVIOcZL0tl6xibeuGt5/+UxoT2N27KCFOPjFyfXMnchxSHZ/OW7cCX2nGlIYJrbHK/fczPcFzAwvNBB6XBNMA==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/primitive" "1.0.1"
"@radix-ui/react-compose-refs" "1.0.1"
"@radix-ui/react-context" "1.0.1"
"@radix-ui/react-dialog" "1.0.5"
"@radix-ui/react-primitive" "1.0.3"
"@radix-ui/react-slot" "1.0.2"
"@radix-ui/react-compose-refs@1.0.1":
version "1.0.1"
resolved "https://registry.npmmirror.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz#7ed868b66946aa6030e580b1ffca386dd4d21989"
@ -1363,6 +1371,81 @@
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-dialog@1.0.5":
version "1.0.5"
resolved "https://registry.npmmirror.com/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz#71657b1b116de6c7a0b03242d7d43e01062c7300"
integrity sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/primitive" "1.0.1"
"@radix-ui/react-compose-refs" "1.0.1"
"@radix-ui/react-context" "1.0.1"
"@radix-ui/react-dismissable-layer" "1.0.5"
"@radix-ui/react-focus-guards" "1.0.1"
"@radix-ui/react-focus-scope" "1.0.4"
"@radix-ui/react-id" "1.0.1"
"@radix-ui/react-portal" "1.0.4"
"@radix-ui/react-presence" "1.0.1"
"@radix-ui/react-primitive" "1.0.3"
"@radix-ui/react-slot" "1.0.2"
"@radix-ui/react-use-controllable-state" "1.0.1"
aria-hidden "^1.1.1"
react-remove-scroll "2.5.5"
"@radix-ui/react-dismissable-layer@1.0.5":
version "1.0.5"
resolved "https://registry.npmmirror.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz#3f98425b82b9068dfbab5db5fff3df6ebf48b9d4"
integrity sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/primitive" "1.0.1"
"@radix-ui/react-compose-refs" "1.0.1"
"@radix-ui/react-primitive" "1.0.3"
"@radix-ui/react-use-callback-ref" "1.0.1"
"@radix-ui/react-use-escape-keydown" "1.0.3"
"@radix-ui/react-focus-guards@1.0.1":
version "1.0.1"
resolved "https://registry.npmmirror.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz#1ea7e32092216b946397866199d892f71f7f98ad"
integrity sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-focus-scope@1.0.4":
version "1.0.4"
resolved "https://registry.npmmirror.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz#2ac45fce8c5bb33eb18419cdc1905ef4f1906525"
integrity sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-compose-refs" "1.0.1"
"@radix-ui/react-primitive" "1.0.3"
"@radix-ui/react-use-callback-ref" "1.0.1"
"@radix-ui/react-id@1.0.1":
version "1.0.1"
resolved "https://registry.npmmirror.com/@radix-ui/react-id/-/react-id-1.0.1.tgz#73cdc181f650e4df24f0b6a5b7aa426b912c88c0"
integrity sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-use-layout-effect" "1.0.1"
"@radix-ui/react-portal@1.0.4":
version "1.0.4"
resolved "https://registry.npmmirror.com/@radix-ui/react-portal/-/react-portal-1.0.4.tgz#df4bfd353db3b1e84e639e9c63a5f2565fb00e15"
integrity sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-primitive" "1.0.3"
"@radix-ui/react-presence@1.0.1":
version "1.0.1"
resolved "https://registry.npmmirror.com/@radix-ui/react-presence/-/react-presence-1.0.1.tgz#491990ba913b8e2a5db1b06b203cb24b5cdef9ba"
integrity sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-compose-refs" "1.0.1"
"@radix-ui/react-use-layout-effect" "1.0.1"
"@radix-ui/react-primitive@1.0.3":
version "1.0.3"
resolved "https://registry.npmmirror.com/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz#d49ea0f3f0b2fe3ab1cb5667eb03e8b843b914d0"
@ -1408,6 +1491,14 @@
"@babel/runtime" "^7.13.10"
"@radix-ui/react-use-callback-ref" "1.0.1"
"@radix-ui/react-use-escape-keydown@1.0.3":
version "1.0.3"
resolved "https://registry.npmmirror.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz#217b840c250541609c66f67ed7bab2b733620755"
integrity sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-use-callback-ref" "1.0.1"
"@radix-ui/react-use-layout-effect@1.0.1":
version "1.0.1"
resolved "https://registry.npmmirror.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz#be8c7bc809b0c8934acf6657b577daf948a75399"
@ -2064,6 +2155,13 @@ argparse@^2.0.1:
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
aria-hidden@^1.1.1:
version "1.2.4"
resolved "https://registry.npmmirror.com/aria-hidden/-/aria-hidden-1.2.4.tgz#b78e383fdbc04d05762c78b4a25a501e736c4522"
integrity sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==
dependencies:
tslib "^2.0.0"
aria-query@^5.1.3:
version "5.1.3"
resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.1.3.tgz#19db27cd101152773631396f7a95a3b58c22c35e"
@ -2971,6 +3069,11 @@ dequal@^2.0.0:
resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be"
integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==
detect-node-es@^1.1.0:
version "1.1.0"
resolved "https://registry.npmmirror.com/detect-node-es/-/detect-node-es-1.1.0.tgz#163acdf643330caa0b4cd7c21e7ee7755d6fa493"
integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==
didyoumean@^1.2.2:
version "1.2.2"
resolved "https://registry.npmmirror.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037"
@ -3670,6 +3773,11 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@
has "^1.0.3"
has-symbols "^1.0.3"
get-nonce@^1.0.0:
version "1.0.1"
resolved "https://registry.npmmirror.com/get-nonce/-/get-nonce-1.0.1.tgz#fdf3f0278073820d2ce9426c18f07481b1e0cdf3"
integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==
get-stream@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
@ -4041,6 +4149,13 @@ internmap@^1.0.0:
resolved "https://registry.yarnpkg.com/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95"
integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==
invariant@^2.2.4:
version "2.2.4"
resolved "https://registry.npmmirror.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==
dependencies:
loose-envify "^1.0.0"
is-arguments@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b"
@ -4488,7 +4603,7 @@ longest-streak@^3.0.0:
resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-3.1.0.tgz#62fa67cd958742a1574af9f39866364102d90cd4"
integrity sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==
loose-envify@^1.1.0, loose-envify@^1.4.0:
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
@ -5574,6 +5689,25 @@ react-redux@^8.1.3:
react-is "^18.0.0"
use-sync-external-store "^1.0.0"
react-remove-scroll-bar@^2.3.3:
version "2.3.6"
resolved "https://registry.npmmirror.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz#3e585e9d163be84a010180b18721e851ac81a29c"
integrity sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==
dependencies:
react-style-singleton "^2.2.1"
tslib "^2.0.0"
react-remove-scroll@2.5.5:
version "2.5.5"
resolved "https://registry.npmmirror.com/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz#1e31a1260df08887a8a0e46d09271b52b3a37e77"
integrity sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==
dependencies:
react-remove-scroll-bar "^2.3.3"
react-style-singleton "^2.2.1"
tslib "^2.1.0"
use-callback-ref "^1.3.0"
use-sidecar "^1.1.2"
react-router-dom@^6.15.0:
version "6.15.0"
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.15.0.tgz#6da7db61e56797266fbbef0d5e324d6ac443ee40"
@ -5589,6 +5723,15 @@ react-router@6.15.0:
dependencies:
"@remix-run/router" "1.8.0"
react-style-singleton@^2.2.1:
version "2.2.1"
resolved "https://registry.npmmirror.com/react-style-singleton/-/react-style-singleton-2.2.1.tgz#f99e420492b2d8f34d38308ff660b60d0b1205b4"
integrity sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==
dependencies:
get-nonce "^1.0.0"
invariant "^2.2.4"
tslib "^2.0.0"
react@^18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
@ -6336,16 +6479,16 @@ tsconfig-paths@^3.14.1:
minimist "^1.2.6"
strip-bom "^3.0.0"
tslib@^2.0.0, tslib@^2.6.2:
version "2.6.2"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
tslib@^2.1.0, tslib@^2.4.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf"
integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==
tslib@^2.6.2:
version "2.6.2"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
type-check@^0.4.0, type-check@~0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
@ -6527,6 +6670,13 @@ url-loader@^4.1.1:
mime-types "^2.1.27"
schema-utils "^3.0.0"
use-callback-ref@^1.3.0:
version "1.3.2"
resolved "https://registry.npmmirror.com/use-callback-ref/-/use-callback-ref-1.3.2.tgz#6134c7f6ff76e2be0b56c809b17a650c942b1693"
integrity sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==
dependencies:
tslib "^2.0.0"
use-debounce@^9.0.4:
version "9.0.4"
resolved "https://registry.yarnpkg.com/use-debounce/-/use-debounce-9.0.4.tgz#51d25d856fbdfeb537553972ce3943b897f1ac85"
@ -6537,18 +6687,26 @@ use-memo-one@^1.1.3:
resolved "https://registry.npmmirror.com/use-memo-one/-/use-memo-one-1.1.3.tgz#2fd2e43a2169eabc7496960ace8c79efef975e99"
integrity sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==
use-resize-observer@^9.1.0:
version "9.1.0"
resolved "https://registry.npmmirror.com/use-resize-observer/-/use-resize-observer-9.1.0.tgz#14735235cf3268569c1ea468f8a90c5789fc5c6c"
integrity sha512-R25VqO9Wb3asSD4eqtcxk8sJalvIOYBqS8MNZlpDSQ4l4xMQxC/J7Id9HoTqPq8FwULIn0PVW+OAqF2dyYbjow==
use-sidecar@^1.1.2:
version "1.1.2"
resolved "https://registry.npmmirror.com/use-sidecar/-/use-sidecar-1.1.2.tgz#2f43126ba2d7d7e117aa5855e5d8f0276dfe73c2"
integrity sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==
dependencies:
"@juggle/resize-observer" "^3.3.1"
detect-node-es "^1.1.0"
tslib "^2.0.0"
use-sync-external-store@1.2.0, use-sync-external-store@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
usehooks-ts@^3.1.0:
version "3.1.0"
resolved "https://registry.npmmirror.com/usehooks-ts/-/usehooks-ts-3.1.0.tgz#156119f36efc85f1b1952616c02580f140950eca"
integrity sha512-bBIa7yUyPhE1BCc0GmR96VU/15l/9gP1Ch5mYdLcFBaFGQsdmXkvjV0TtOqW1yUd6VjIwDunm+flSciCQXujiw==
dependencies:
lodash.debounce "^4.0.8"
util-deprecate@^1.0.2:
version "1.0.2"
resolved "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"