Browse Source

feat: close #2267 display a modal to export image

Yidadaa 1 year ago
parent
commit
6c6a2d08db
4 changed files with 35 additions and 7 deletions
  1. 25 6
      app/components/exporter.tsx
  2. 2 1
      app/components/ui-lib.tsx
  3. 4 0
      app/locales/cn.ts
  4. 4 0
      app/locales/en.ts

+ 25 - 6
app/components/exporter.tsx

@@ -1,7 +1,8 @@
+/* eslint-disable @next/next/no-img-element */
 import { ChatMessage, useAppConfig, useChatStore } from "../store";
 import Locale from "../locales";
 import styles from "./exporter.module.scss";
-import { List, ListItem, Modal, Select, showToast } from "./ui-lib";
+import { List, ListItem, Modal, Select, showModal, showToast } from "./ui-lib";
 import { IconButton } from "./button";
 import { copyToClipboard, downloadAs, useMobileScreen } from "../utils";
 
@@ -23,6 +24,7 @@ import { DEFAULT_MASK_AVATAR } from "../store/mask";
 import { api } from "../client/api";
 import { prettyObject } from "../utils/format";
 import { EXPORT_MESSAGE_CLASS_NAME } from "../constant";
+import { getClientConfig } from "../config/client";
 
 const Markdown = dynamic(async () => (await import("./markdown")).Markdown, {
   loading: () => <LoadingIcon />,
@@ -357,6 +359,24 @@ function ExportAvatar(props: { avatar: string }) {
   return <Avatar avatar={props.avatar}></Avatar>;
 }
 
+export function showImageModal(img: string) {
+  showModal({
+    title: Locale.Export.Image.Modal,
+    children: (
+      <div>
+        <img
+          src={img}
+          alt="preview"
+          style={{
+            maxWidth: "100%",
+          }}
+        ></img>
+      </div>
+    ),
+    defaultMax: true,
+  });
+}
+
 export function ImagePreviewer(props: {
   messages: ChatMessage[];
   topic: string;
@@ -369,6 +389,7 @@ export function ImagePreviewer(props: {
   const previewRef = useRef<HTMLDivElement>(null);
 
   const copy = () => {
+    showToast(Locale.Export.Image.Toast);
     const dom = previewRef.current;
     if (!dom) return;
     toBlob(dom).then((blob) => {
@@ -393,17 +414,15 @@ export function ImagePreviewer(props: {
   const isMobile = useMobileScreen();
 
   const download = () => {
+    showToast(Locale.Export.Image.Toast);
     const dom = previewRef.current;
     if (!dom) return;
     toPng(dom)
       .then((blob) => {
         if (!blob) return;
 
-        if (isMobile) {
-          const image = new Image();
-          image.src = blob;
-          const win = window.open("");
-          win?.document.write(image.outerHTML);
+        if (isMobile || getClientConfig()?.isApp) {
+          showImageModal(blob);
         } else {
           const link = document.createElement("a");
           link.download = `${props.topic}.png`;

+ 2 - 1
app/components/ui-lib.tsx

@@ -95,6 +95,7 @@ interface ModalProps {
   title: string;
   children?: any;
   actions?: JSX.Element[];
+  defaultMax?: boolean;
   onClose?: () => void;
 }
 export function Modal(props: ModalProps) {
@@ -113,7 +114,7 @@ export function Modal(props: ModalProps) {
     // eslint-disable-next-line react-hooks/exhaustive-deps
   }, []);
 
-  const [isMax, setMax] = useState(false);
+  const [isMax, setMax] = useState(!!props.defaultMax);
 
   return (
     <div

+ 4 - 0
app/locales/cn.ts

@@ -86,6 +86,10 @@ const cn = {
       Select: "选取",
       Preview: "预览",
     },
+    Image: {
+      Toast: "正在生成截图",
+      Modal: "长按或右键保存图片",
+    },
   },
   Select: {
     Search: "搜索消息",

+ 4 - 0
app/locales/en.ts

@@ -87,6 +87,10 @@ const en: LocaleType = {
       Select: "Select",
       Preview: "Preview",
     },
+    Image: {
+      Toast: "Capturing Image...",
+      Modal: "Long press or right click to save image",
+    },
   },
   Select: {
     Search: "Search",