Browse Source

Merge pull request #2264 from Yidadaa/bugfix-0705

feat: close #1072 share mask as link
Yifei Zhang 1 year ago
parent
commit
94a50f92e1
5 changed files with 52 additions and 17 deletions
  1. 15 13
      app/command.ts
  2. 20 1
      app/components/mask.tsx
  3. 7 3
      app/components/new-chat.tsx
  4. 5 0
      app/locales/cn.ts
  5. 5 0
      app/locales/en.ts

+ 15 - 13
app/command.ts

@@ -1,3 +1,4 @@
+import { useEffect } from "react";
 import { useSearchParams } from "react-router-dom";
 import Locale from "./locales";
 
@@ -11,21 +12,22 @@ interface Commands {
 export function useCommand(commands: Commands = {}) {
   const [searchParams, setSearchParams] = useSearchParams();
 
-  if (commands === undefined) return;
+  useEffect(() => {
+    let shouldUpdate = false;
+    searchParams.forEach((param, name) => {
+      const commandName = name as keyof Commands;
+      if (typeof commands[commandName] === "function") {
+        commands[commandName]!(param);
+        searchParams.delete(name);
+        shouldUpdate = true;
+      }
+    });
 
-  let shouldUpdate = false;
-  searchParams.forEach((param, name) => {
-    const commandName = name as keyof Commands;
-    if (typeof commands[commandName] === "function") {
-      commands[commandName]!(param);
-      searchParams.delete(name);
-      shouldUpdate = true;
+    if (shouldUpdate) {
+      setSearchParams(searchParams);
     }
-  });
-
-  if (shouldUpdate) {
-    setSearchParams(searchParams);
-  }
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+  }, [searchParams, commands]);
 }
 
 interface ChatCommands {

+ 20 - 1
app/components/mask.tsx

@@ -30,7 +30,7 @@ import { useNavigate } from "react-router-dom";
 
 import chatStyle from "./chat.module.scss";
 import { useEffect, useState } from "react";
-import { downloadAs, readFromFile } from "../utils";
+import { copyToClipboard, downloadAs, readFromFile } from "../utils";
 import { Updater } from "../typing";
 import { ModelConfigList } from "./model-config";
 import { FileName, Path } from "../constant";
@@ -65,6 +65,11 @@ export function MaskConfig(props: {
     });
   };
 
+  const copyMaskLink = () => {
+    const maskLink = `${location.protocol}//${location.host}/#${Path.NewChat}?mask=${props.mask.id}`;
+    copyToClipboard(maskLink);
+  };
+
   const globalConfig = useAppConfig();
 
   return (
@@ -125,6 +130,20 @@ export function MaskConfig(props: {
             }}
           ></input>
         </ListItem>
+
+        {!props.shouldSyncFromGlobal ? (
+          <ListItem
+            title={Locale.Mask.Config.Share.Title}
+            subTitle={Locale.Mask.Config.Share.SubTitle}
+          >
+            <IconButton
+              icon={<CopyIcon />}
+              text={Locale.Mask.Config.Share.Action}
+              onClick={copyMaskLink}
+            />
+          </ListItem>
+        ) : null}
+
         {props.shouldSyncFromGlobal ? (
           <ListItem
             title={Locale.Mask.Config.Sync.Title}

+ 7 - 3
app/components/new-chat.tsx

@@ -15,6 +15,7 @@ import { useAppConfig, useChatStore } from "../store";
 import { MaskAvatar } from "./mask";
 import { useCommand } from "../command";
 import { showConfirm } from "./ui-lib";
+import { BUILTIN_MASK_STORE } from "../masks";
 
 function getIntersectionArea(aRect: DOMRect, bRect: DOMRect) {
   const xmin = Math.max(aRect.x, bRect.x);
@@ -93,14 +94,17 @@ export function NewChat() {
   const { state } = useLocation();
 
   const startChat = (mask?: Mask) => {
-    chatStore.newSession(mask);
-    setTimeout(() => navigate(Path.Chat), 1);
+    setTimeout(() => {
+      chatStore.newSession(mask);
+      navigate(Path.Chat);
+    }, 10);
   };
 
   useCommand({
     mask: (id) => {
       try {
-        const mask = maskStore.get(parseInt(id));
+        const intId = parseInt(id);
+        const mask = maskStore.get(intId) ?? BUILTIN_MASK_STORE.get(intId);
         startChat(mask ?? undefined);
       } catch {
         console.error("[New Chat] failed to create chat from mask id=", id);

+ 5 - 0
app/locales/cn.ts

@@ -297,6 +297,11 @@ const cn = {
         Title: "隐藏预设对话",
         SubTitle: "隐藏后预设对话不会出现在聊天界面",
       },
+      Share: {
+        Title: "分享此面具",
+        SubTitle: "生成此面具的直达链接",
+        Action: "复制链接",
+      },
     },
   },
   NewChat: {

+ 5 - 0
app/locales/en.ts

@@ -301,6 +301,11 @@ const en: LocaleType = {
         Title: "Hide Context Prompts",
         SubTitle: "Do not show in-context prompts in chat",
       },
+      Share: {
+        Title: "Share This Mask",
+        SubTitle: "Generate a link to this mask",
+        Action: "Copy Link",
+      },
     },
   },
   NewChat: {