From 3298961748ec331669e8e34d8e33b585d439c032 Mon Sep 17 00:00:00 2001 From: Yidadaa Date: Wed, 28 Jun 2023 23:40:39 +0800 Subject: [PATCH] feat: replace window.confirm with showConfirm --- app/components/chat-list.tsx | 8 +++++-- app/components/chat.tsx | 6 ++--- app/components/error.tsx | 12 ++++++---- app/components/mask.tsx | 18 +++++++++++---- app/components/new-chat.tsx | 5 ++-- app/components/settings.tsx | 13 +++++++---- app/components/sidebar.tsx | 6 ++--- app/components/ui-lib.tsx | 45 +++++++++++++++++++++++++++++++++++- 8 files changed, 89 insertions(+), 24 deletions(-) diff --git a/app/components/chat-list.tsx b/app/components/chat-list.tsx index fc4e5378..a6143f32 100644 --- a/app/components/chat-list.tsx +++ b/app/components/chat-list.tsx @@ -17,6 +17,7 @@ import { Path } from "../constant"; import { MaskAvatar } from "./mask"; import { Mask } from "../store/mask"; import { useRef, useEffect } from "react"; +import { showConfirm } from "./ui-lib"; export function ChatItem(props: { onClick?: () => void; @@ -139,8 +140,11 @@ export function ChatList(props: { narrow?: boolean }) { navigate(Path.Chat); selectSession(i); }} - onDelete={() => { - if (!props.narrow || confirm(Locale.Home.DeleteChat)) { + onDelete={async () => { + if ( + !props.narrow || + (await showConfirm(Locale.Home.DeleteChat)) + ) { chatStore.deleteSession(i); } }} diff --git a/app/components/chat.tsx b/app/components/chat.tsx index 6db5eb2b..fd732b9d 100644 --- a/app/components/chat.tsx +++ b/app/components/chat.tsx @@ -61,7 +61,7 @@ import Locale from "../locales"; import { IconButton } from "./button"; import styles from "./chat.module.scss"; -import { ListItem, Modal, showToast } from "./ui-lib"; +import { ListItem, Modal, showConfirm, showToast } from "./ui-lib"; import { useLocation, useNavigate } from "react-router-dom"; import { LAST_INPUT_KEY, Path, REQUEST_TIMEOUT_MS } from "../constant"; import { Avatar } from "./emoji"; @@ -93,8 +93,8 @@ export function SessionConfigModel(props: { onClose: () => void }) { icon={} bordered text={Locale.Chat.Config.Reset} - onClick={() => { - if (confirm(Locale.Memory.ResetConfirm)) { + onClick={async () => { + if (await showConfirm(Locale.Memory.ResetConfirm)) { chatStore.updateCurrentSession( (session) => (session.memoryPrompt = ""), ); diff --git a/app/components/error.tsx b/app/components/error.tsx index 0e01c417..33abe931 100644 --- a/app/components/error.tsx +++ b/app/components/error.tsx @@ -5,6 +5,7 @@ import ResetIcon from "../icons/reload.svg"; import { ISSUE_URL } from "../constant"; import Locale from "../locales"; import { downloadAs } from "../utils"; +import { showConfirm } from "./ui-lib"; interface IErrorBoundaryState { hasError: boolean; @@ -57,10 +58,13 @@ export class ErrorBoundary extends React.Component { } text="Clear All Data" - onClick={() => - confirm(Locale.Settings.Actions.ConfirmClearAll) && - this.clearAndSaveData() - } + onClick={async () => { + if ( + await showConfirm(Locale.Settings.Actions.ConfirmClearAll) + ) { + this.clearAndSaveData(); + } + }} bordered /> diff --git a/app/components/mask.tsx b/app/components/mask.tsx index d48ed7c2..c10ba476 100644 --- a/app/components/mask.tsx +++ b/app/components/mask.tsx @@ -15,7 +15,15 @@ import CopyIcon from "../icons/copy.svg"; import { DEFAULT_MASK_AVATAR, Mask, useMaskStore } from "../store/mask"; import { ChatMessage, ModelConfig, useAppConfig, useChatStore } from "../store"; import { ROLES } from "../client/api"; -import { Input, List, ListItem, Modal, Popover, Select } from "./ui-lib"; +import { + Input, + List, + ListItem, + Modal, + Popover, + Select, + showConfirm, +} from "./ui-lib"; import { Avatar, AvatarPicker } from "./emoji"; import Locale, { AllLangs, ALL_LANG_OPTIONS, Lang } from "../locales"; import { useNavigate } from "react-router-dom"; @@ -125,10 +133,10 @@ export function MaskConfig(props: { { + onChange={async (e) => { if ( e.currentTarget.checked && - confirm(Locale.Mask.Config.Sync.Confirm) + (await showConfirm(Locale.Mask.Config.Sync.Confirm)) ) { props.updateMask((mask) => { mask.syncGlobalConfig = e.currentTarget.checked; @@ -439,8 +447,8 @@ export function MaskPage() { } text={Locale.Mask.Item.Delete} - onClick={() => { - if (confirm(Locale.Mask.Item.DeleteConfirm)) { + onClick={async () => { + if (await showConfirm(Locale.Mask.Item.DeleteConfirm)) { maskStore.delete(m.id); } }} diff --git a/app/components/new-chat.tsx b/app/components/new-chat.tsx index 30041c5c..64c4703a 100644 --- a/app/components/new-chat.tsx +++ b/app/components/new-chat.tsx @@ -14,6 +14,7 @@ import Locale from "../locales"; import { useAppConfig, useChatStore } from "../store"; import { MaskAvatar } from "./mask"; import { useCommand } from "../command"; +import { showConfirm } from "./ui-lib"; function getIntersectionArea(aRect: DOMRect, bRect: DOMRect) { const xmin = Math.max(aRect.x, bRect.x); @@ -125,8 +126,8 @@ export function NewChat() { {!state?.fromHome && ( { - if (confirm(Locale.NewChat.ConfirmNoShow)) { + onClick={async () => { + if (await showConfirm(Locale.NewChat.ConfirmNoShow)) { startChat(); config.update( (config) => (config.dontShowMaskSplashScreen = true), diff --git a/app/components/settings.tsx b/app/components/settings.tsx index 1d45a0c6..54389c9b 100644 --- a/app/components/settings.tsx +++ b/app/components/settings.tsx @@ -18,6 +18,7 @@ import { PasswordInput, Popover, Select, + showConfirm, } from "./ui-lib"; import { ModelConfigList } from "./model-config"; @@ -377,8 +378,10 @@ export function Settings() {
} - onClick={() => { - if (confirm(Locale.Settings.Actions.ConfirmClearAll)) { + onClick={async () => { + if ( + await showConfirm(Locale.Settings.Actions.ConfirmClearAll) + ) { chatStore.clearAllData(); } }} @@ -389,8 +392,10 @@ export function Settings() {
} - onClick={() => { - if (confirm(Locale.Settings.Actions.ConfirmResetAll)) { + onClick={async () => { + if ( + await showConfirm(Locale.Settings.Actions.ConfirmResetAll) + ) { resetConfig(); } }} diff --git a/app/components/sidebar.tsx b/app/components/sidebar.tsx index 038ca86f..d9d861d5 100644 --- a/app/components/sidebar.tsx +++ b/app/components/sidebar.tsx @@ -26,7 +26,7 @@ import { import { Link, useNavigate } from "react-router-dom"; import { useMobileScreen } from "../utils"; import dynamic from "next/dynamic"; -import { showToast } from "./ui-lib"; +import { showConfirm, showToast } from "./ui-lib"; const ChatList = dynamic(async () => (await import("./chat-list")).ChatList, { loading: () => null, @@ -160,8 +160,8 @@ export function SideBar(props: { className?: string }) {
} - onClick={() => { - if (confirm(Locale.Home.DeleteChat)) { + onClick={async () => { + if (await showConfirm(Locale.Home.DeleteChat)) { chatStore.deleteSession(chatStore.currentSessionIndex); } }} diff --git a/app/components/ui-lib.tsx b/app/components/ui-lib.tsx index be9b30a6..156eecfa 100644 --- a/app/components/ui-lib.tsx +++ b/app/components/ui-lib.tsx @@ -4,6 +4,7 @@ import CloseIcon from "../icons/close.svg"; import EyeIcon from "../icons/eye.svg"; import EyeOffIcon from "../icons/eye-off.svg"; import DownIcon from "../icons/down.svg"; +import Locale from "../locales"; import { createRoot } from "react-dom/client"; import React, { HTMLProps, useEffect, useState } from "react"; @@ -87,7 +88,7 @@ export function Loading() { interface ModalProps { title: string; - children?: JSX.Element | JSX.Element[]; + children?: any; actions?: JSX.Element[]; onClose?: () => void; } @@ -262,3 +263,45 @@ export function Select(
); } + +export function showConfirm(content: any) { + const div = document.createElement("div"); + div.className = "modal-mask"; + document.body.appendChild(div); + + const root = createRoot(div); + const closeModal = () => { + root.unmount(); + div.remove(); + }; + + return new Promise((resolve) => { + root.render( + { + resolve(false); + closeModal(); + }} + >
, + { + resolve(true); + closeModal(); + }} + >, + ]} + onClose={closeModal} + > + {content} + , + ); + }); +}