소스 검색

Merge commit '1be5bd26b834eb42d3732ce410772270bcfa8a45' into app-permission

* commit '1be5bd26b834eb42d3732ce410772270bcfa8a45':
  永久移除了网页在加载时候的预设prompt.json功能
  🚫 已移除的emoji功能: emoji-picker-react包 - 移除了复杂的emoji选择器组件 emoji.tsx文件 - 移除了自定义的emoji选择和显示组件 AvatarPicker功能 - 替换为简化版本,不再依赖外部emoji库 EmojiAvatar组件 - 替换为简单的文本显示或SVG图标 ✅ 保留的emoji功能: markdown中的emoji显示 - 完整保留了所有相关样式: .markdown-body .emoji - 基础emoji样式 .markdown-body g-emoji - GitHub风格emoji显示 .markdown-body g-emoji img - emoji图片样式 .markdown-body .footnotes .data-footnote-backref g-emoji - 脚注中的emoji
Ryuiso 6 달 전
부모
커밋
840498bb07

+ 2 - 0
.gitignore

@@ -47,5 +47,7 @@ dev
 *.key.pub
 
 masks.json
+
+# .cursor
 .cursor
 .history

+ 24 - 1
app/components/DeepSeekChat.tsx

@@ -23,7 +23,30 @@ import sdsk from "../icons/sdsk.png";
 import sdsk_selected from "../icons/sdsk_selected.png";
 import hlw from "../icons/hlw.png";
 import hlw_selected from "../icons/hlw_selected.png";
-import { Avatar } from "./emoji";
+// Avatar组件替代实现
+import BotIcon from "../icons/bot.svg";
+import BlackBotIcon from "../icons/black-bot.svg";
+
+function Avatar(props: { model?: string; avatar?: string }) {
+  if (props.model) {
+    return (
+      <div className="no-dark">
+        {props.model?.startsWith("gpt-4") ? (
+          <BlackBotIcon className="user-avatar" />
+        ) : (
+          <BotIcon className="user-avatar" />
+        )}
+      </div>
+    );
+  }
+
+  return (
+    <div className="user-avatar">
+      {/* 移除emoji头像,使用默认bot图标 */}
+      <BotIcon className="user-avatar" />
+    </div>
+  );
+}
 import { MaskAvatar } from "./mask";
 
 import {

+ 24 - 1
app/components/chat.tsx

@@ -101,7 +101,30 @@ import {
   ServiceProvider,
   Plugin,
 } from "../constant";
-import { Avatar } from "./emoji";
+// Avatar组件替代实现
+import BotIcon from "../icons/bot.svg";
+import BlackBotIcon from "../icons/black-bot.svg";
+
+function Avatar(props: { model?: string; avatar?: string }) {
+  if (props.model) {
+    return (
+      <div className="no-dark">
+        {props.model?.startsWith("gpt-4") ? (
+          <BlackBotIcon className="user-avatar" />
+        ) : (
+          <BotIcon className="user-avatar" />
+        )}
+      </div>
+    );
+  }
+
+  return (
+    <div className="user-avatar">
+      {/* 移除emoji头像,使用默认bot图标 */}
+      <BotIcon className="user-avatar" />
+    </div>
+  );
+}
 import { ContextPrompts, MaskAvatar, MaskConfig } from "./mask";
 import { useMaskStore } from "../store/mask";
 import { ChatCommandPrefix, useChatCommand, useCommand } from "../command";

+ 0 - 63
app/components/emoji.tsx

@@ -1,63 +0,0 @@
-import EmojiPicker, {
-  Emoji,
-  EmojiStyle,
-  Theme as EmojiTheme,
-} from "emoji-picker-react";
-
-import { ModelType } from "../store";
-
-import BotIcon from "../icons/bot.svg";
-import BlackBotIcon from "../icons/black-bot.svg";
-
-export function getEmojiUrl(unified: string, style: EmojiStyle) {
-  // Whoever owns this Content Delivery Network (CDN), I am using your CDN to serve emojis
-  // Old CDN broken, so I had to switch to this one
-  // Author: https://github.com/H0llyW00dzZ
-  return `https://fastly.jsdelivr.net/npm/emoji-datasource-apple/img/${style}/64/${unified}.png`;
-}
-
-export function AvatarPicker(props: {
-  onEmojiClick: (emojiId: string) => void;
-}) {
-  return (
-    <EmojiPicker
-      width={"100%"}
-      lazyLoadEmojis
-      theme={EmojiTheme.AUTO}
-      getEmojiUrl={getEmojiUrl}
-      onEmojiClick={(e) => {
-        props.onEmojiClick(e.unified);
-      }}
-    />
-  );
-}
-
-export function Avatar(props: { model?: ModelType; avatar?: string }) {
-  if (props.model) {
-    return (
-      <div className="no-dark">
-        {props.model?.startsWith("gpt-4") ? (
-          <BlackBotIcon className="user-avatar" />
-        ) : (
-          <BotIcon className="user-avatar" />
-        )}
-      </div>
-    );
-  }
-
-  return (
-    <div className="user-avatar">
-      {props.avatar && <EmojiAvatar avatar={props.avatar} />}
-    </div>
-  );
-}
-
-export function EmojiAvatar(props: { avatar: string; size?: number }) {
-  return (
-    <Emoji
-      unified={props.avatar}
-      size={props.size ?? 18}
-      getEmojiUrl={getEmojiUrl}
-    />
-  );
-}

+ 24 - 3
app/components/exporter.tsx

@@ -23,12 +23,33 @@ import CopyIcon from "../icons/copy.svg";
 import LoadingIcon from "../icons/three-dots.svg";
 import ChatGptIcon from "../icons/chatgpt.png";
 import ShareIcon from "../icons/share.svg";
-import BotIcon from "../icons/bot.png";
-
 import DownloadIcon from "../icons/download.svg";
 import { useEffect, useMemo, useRef, useState } from "react";
 import { MessageSelector, useMessageSelector } from "./message-selector";
-import { Avatar } from "./emoji";
+// Avatar组件替代实现
+import BotIcon from "../icons/bot.svg";
+import BlackBotIcon from "../icons/black-bot.svg";
+
+function Avatar(props: { model?: string; avatar?: string }) {
+  if (props.model) {
+    return (
+      <div className="no-dark">
+        {props.model?.startsWith("gpt-4") ? (
+          <BlackBotIcon className="user-avatar" />
+        ) : (
+          <BotIcon className="user-avatar" />
+        )}
+      </div>
+    );
+  }
+
+  return (
+    <div className="user-avatar">
+      {/* 移除emoji头像,使用默认bot图标 */}
+      <BotIcon className="user-avatar" />
+    </div>
+  );
+}
 import dynamic from "next/dynamic";
 import NextImage from "next/image";
 

+ 50 - 1
app/components/mask.tsx

@@ -32,7 +32,56 @@ import {
   Select,
   showConfirm,
 } from "./ui-lib";
-import { Avatar, AvatarPicker } from "./emoji";
+// Avatar组件替代实现
+import BotIcon from "../icons/bot.svg";
+import BlackBotIcon from "../icons/black-bot.svg";
+
+function Avatar(props: { model?: string; avatar?: string }) {
+  if (props.model) {
+    return (
+      <div className="no-dark">
+        {props.model?.startsWith("gpt-4") ? (
+          <BlackBotIcon className="user-avatar" />
+        ) : (
+          <BotIcon className="user-avatar" />
+        )}
+      </div>
+    );
+  }
+
+  return (
+    <div className="user-avatar">
+      {/* 移除emoji头像,使用默认bot图标 */}
+      <BotIcon className="user-avatar" />
+    </div>
+  );
+}
+
+// 简化的AvatarPicker替代实现
+function AvatarPicker(props: { onEmojiClick: (emoji: string) => void }) {
+  const defaultAvatars = ["🤖", "👤", "💬", "🎯", "⭐", "🔥"];
+  
+  return (
+    <div style={{ padding: "10px", display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: "10px" }}>
+      {defaultAvatars.map((emoji, index) => (
+        <div
+          key={index}
+          style={{
+            padding: "8px",
+            borderRadius: "4px",
+            border: "1px solid #ccc",
+            textAlign: "center",
+            cursor: "pointer",
+            fontSize: "20px"
+          }}
+          onClick={() => props.onEmojiClick(emoji)}
+        >
+          {emoji}
+        </div>
+      ))}
+    </div>
+  );
+}
 import Locale, { AllLangs, ALL_LANG_OPTIONS, Lang } from "../locales";
 import { useNavigate } from "react-router-dom";
 

+ 24 - 1
app/components/message-selector.tsx

@@ -2,7 +2,30 @@ import { useEffect, useMemo, useState } from "react";
 import { ChatMessage, useAppConfig, useChatStore } from "../store";
 import { Updater } from "../typing";
 import { IconButton } from "./button";
-import { Avatar } from "./emoji";
+// Avatar组件替代实现
+import BotIcon from "../icons/bot.svg";
+import BlackBotIcon from "../icons/black-bot.svg";
+
+function Avatar(props: { model?: string; avatar?: string }) {
+  if (props.model) {
+    return (
+      <div className="no-dark">
+        {props.model?.startsWith("gpt-4") ? (
+          <BlackBotIcon className="user-avatar" />
+        ) : (
+          <BotIcon className="user-avatar" />
+        )}
+      </div>
+    );
+  }
+
+  return (
+    <div className="user-avatar">
+      {/* 移除emoji头像,使用默认bot图标 */}
+      <BotIcon className="user-avatar" />
+    </div>
+  );
+}
 import { MaskAvatar } from "./mask";
 import Locale from "../locales";
 

+ 14 - 1
app/components/new-chat.tsx

@@ -1,7 +1,20 @@
 import { useEffect, useRef, useState } from "react";
 import { Path, SlotID } from "../constant";
 import { IconButton } from "./button";
-import { EmojiAvatar } from "./emoji";
+// EmojiAvatar组件替代实现
+import BotIcon from "../icons/bot.svg";
+
+function EmojiAvatar(props: { avatar: string; size?: number }) {
+  // 简单显示emoji文本,或者使用默认图标
+  if (props.avatar && props.avatar.length > 0) {
+    return (
+      <span style={{ fontSize: props.size || 18 }}>
+        {props.avatar}
+      </span>
+    );
+  }
+  return <BotIcon className="user-avatar" />;
+}
 import styles from "./new-chat.module.scss";
 
 import LeftIcon from "../icons/left.svg";

+ 54 - 4
app/components/settings.tsx

@@ -74,7 +74,56 @@ import { Prompt, SearchService, usePromptStore } from "../store/prompt";
 import { ErrorBoundary } from "./error";
 import { InputRange } from "./input-range";
 import { useNavigate } from "react-router-dom";
-import { Avatar, AvatarPicker } from "./emoji";
+// Avatar组件替代实现
+import BotIcon from "../icons/bot.svg";
+import BlackBotIcon from "../icons/black-bot.svg";
+
+function Avatar(props: { model?: string; avatar?: string }) {
+  if (props.model) {
+    return (
+      <div className="no-dark">
+        {props.model?.startsWith("gpt-4") ? (
+          <BlackBotIcon className="user-avatar" />
+        ) : (
+          <BotIcon className="user-avatar" />
+        )}
+      </div>
+    );
+  }
+
+  return (
+    <div className="user-avatar">
+      {/* 移除emoji头像,使用默认bot图标 */}
+      <BotIcon className="user-avatar" />
+    </div>
+  );
+}
+
+// 简化的AvatarPicker替代实现
+function AvatarPicker(props: { onEmojiClick: (emoji: string) => void }) {
+  const defaultAvatars = ["🤖", "👤", "💬", "🎯", "⭐", "🔥"];
+  
+  return (
+    <div style={{ padding: "10px", display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: "10px" }}>
+      {defaultAvatars.map((emoji, index) => (
+        <div
+          key={index}
+          style={{
+            padding: "8px",
+            borderRadius: "4px",
+            border: "1px solid #ccc",
+            textAlign: "center",
+            cursor: "pointer",
+            fontSize: "20px"
+          }}
+          onClick={() => props.onEmojiClick(emoji)}
+        >
+          {emoji}
+        </div>
+      ))}
+    </div>
+  );
+}
 import { getClientConfig } from "../config/client";
 import { useSyncStore } from "../store/sync";
 import { nanoid } from "nanoid";
@@ -133,8 +182,8 @@ function EditPromptModal(props: { id: string; onClose: () => void }) {
 function UserPromptModal(props: { onClose?: () => void }) {
   const promptStore = usePromptStore();
   const userPrompts = promptStore.getUserPrompts();
-  const builtinPrompts = SearchService.builtinPrompts;
-  const allPrompts = userPrompts.concat(builtinPrompts);
+  // 移除内置提示词,仅使用用户提示词
+  const allPrompts = userPrompts;
   const [searchInput, setSearchInput] = useState("");
   const [searchPrompts, setSearchPrompts] = useState<Prompt[]>([]);
   const prompts = searchInput.length > 0 ? searchPrompts : allPrompts;
@@ -633,7 +682,8 @@ export function Settings() {
   );
 
   const promptStore = usePromptStore();
-  const builtinCount = SearchService.count.builtin;
+  // 移除内置提示词,设置count为0
+  const builtinCount = 0;
   const customCount = promptStore.getUserPrompts().length ?? 0;
   const [shouldShowPromptModal, setShowPromptModal] = useState(false);
 

+ 19 - 53
app/store/prompt.ts

@@ -14,21 +14,15 @@ export interface Prompt {
 
 export const SearchService = {
   ready: false,
-  builtinEngine: new Fuse<Prompt>([], {keys: [ "title" ]}),
   userEngine: new Fuse<Prompt>([], {keys: [ "title" ]}),
-  count: {
-    builtin: 0,
-  },
   allPrompts: [] as Prompt[],
-  builtinPrompts: [] as Prompt[],
 
   init(builtinPrompts: Prompt[], userPrompts: Prompt[]) {
     if ( this.ready ) {
       return;
     }
-    this.allPrompts = userPrompts.concat(builtinPrompts);
-    this.builtinPrompts = builtinPrompts.slice();
-    this.builtinEngine.setCollection(builtinPrompts);
+    // 移除内置提示词支持,仅使用用户提示词
+    this.allPrompts = userPrompts;
     this.userEngine.setCollection(userPrompts);
     this.ready = true;
   },
@@ -43,8 +37,7 @@ export const SearchService = {
 
   search(text: string) {
     const userResults = this.userEngine.search(text);
-    const builtinResults = this.builtinEngine.search(text);
-    return userResults.concat(builtinResults).map((v) => v.item);
+    return userResults.map((v) => v.item);
   },
 };
 
@@ -71,11 +64,6 @@ export const usePromptStore = createPersistStore(
 
       get(id: string) {
         const targetPrompt = get().prompts[id];
-
-        if ( !targetPrompt ) {
-          return SearchService.builtinPrompts.find((v) => v.id === id);
-        }
-
         return targetPrompt;
       },
 
@@ -124,8 +112,8 @@ export const usePromptStore = createPersistStore(
 
       search(text: string) {
         if ( text.length === 0 ) {
-          // return all rompts
-          return this.getUserPrompts().concat(SearchService.builtinPrompts);
+          // 仅返回用户提示词
+          return this.getUserPrompts();
         }
         return SearchService.search(text) as Prompt[];
       },
@@ -147,42 +135,20 @@ export const usePromptStore = createPersistStore(
       },
 
       onRehydrateStorage(state) {
-        const PROMPT_URL = "./prompts.json";
-
-        type PromptList = Array<[ string, string ]>; // [标题, 内容]的元组数组
-        // tw: Array<[string, string]>; // 已停用繁体中文提示词
-        // en: Array<[string, string]>; // 已停用英文提示词
-
-        fetch(PROMPT_URL)
-            .then((res) => res.json())
-            .then((res) => {
-              let fetchPrompts = [
-                // res.en, res.tw,  // 注释掉英文和繁体中文提示词
-                res.cn ];
-          // if ( getLang() === "cn" ) {
-          //   fetchPrompts = fetchPrompts.reverse();
-          // }
-              const builtinPrompts = fetchPrompts.filter(item => item).map((promptList: PromptList) => {
-                return promptList.map(
-                    ([ title, content ]) =>
-                        ({
-                          id: nanoid(),
-                          title,
-                          content,
-                          createdAt: Date.now(),
-                        }) as Prompt,
-                );
-              });
-
-              const userPrompts = usePromptStore.getState().getUserPrompts() ?? [];
-
-              const allPromptsForSearch = builtinPrompts
-                  .reduce((pre, cur) => pre.concat(cur), [])
-                  .filter((v) => !!v.title && !!v.content);
-              SearchService.count.builtin =
-                  res.cn.length; // 仅计算中文提示词数量
-              SearchService.init(allPromptsForSearch, userPrompts);
-            });
+        // ==============
+        // 移除 prompts.json 自动加载
+        // 说明:不再从前端控制提示词配置,移除内置提示词系统
+        // ==============
+        
+        return (state) => {
+          // 使用回调中的 state 参数获取用户提示词
+          const userPrompts = state ? Object.values(state.prompts ?? {}).sort((a, b) => 
+            b.id && a.id ? b.createdAt - a.createdAt : 0
+          ) : [];
+          
+          // 仅使用用户自定义提示词,不加载内置提示词
+          SearchService.init([], userPrompts);
+        };
       },
     },
 );

+ 1 - 1
next.config.mjs

@@ -92,7 +92,7 @@ if (mode !== "export") {
       },
       {
         source: "/bigmodel-api/:path*",
-        destination: "http://192.168.3.27:8091/:path*",
+        destination: "http://192.168.3.3:8091/:path*",
         // destination: "http://192.168.3.123:8091/:path*",
       },
       {

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 245 - 141
package-lock.json


+ 1 - 1
package.json

@@ -30,7 +30,7 @@
     "antd": "^5.25.0",
     "axios": "^1.7.7",
     "dayjs": "^1.11.12",
-    "emoji-picker-react": "^4.9.2",
+
     "fuse.js": "^7.0.0",
     "heic2any": "^0.0.4",
     "html-to-image": "^1.11.11",

+ 0 - 10
public/prompts.json

@@ -1,10 +0,0 @@
-{
-  "cn": [
-    [
-      "文档",
-      "背景资料:\n\n\"\"\n{{ knowledge}}\n\"\"\n\n你是建科工程咨询有限公司的校园招聘小助手“建科小K”,请根据背景资料回答同学们提出的校园招聘问题,要求如下:\n1.从背景资料中,寻找问题对应的答案;\n2.时刻牢记,如果无法从背景资料中找到问题的答案原文,请输出“亲爱的同学,针对这个问题,我的知识库里没有相关的信息。其他相关资讯,可前往企业校招子站、空中宣讲会页面,或关注我司微信公众号,并感谢大家对我们的关注和支持!”;\n3.如果你的回答与背景资料的原文不一致请重新输出,以确保你的答案与背景资料原文一致;\n4.不允许在答案中添加编造成分;\n5.使用“友好、礼貌、条理清晰”的风格;\n6.严格按照格式输出,仅输出问题的答案,不要输出额外内容,同学如果问了多个问题,请清晰地组织你的回答;\n7.不要回答有损本公司,即建科工程咨询有限公司,的问题;\n8.你只能回答与招聘有关联的问题,与招聘完全无关的问题直接回答“亲爱的同学,针对这个问题,我的知识库里没有相关的信息。其他相关资讯,可前往企业校招子站、空中宣讲会页面,或关注我司微信公众号,并感谢大家对我们的关注和支持!”;\n9.如果同学跟你打招呼(例如说你好、hi、hello、你好呀),请你有礼貌地同样打招呼,并且邀请同学继续提问;\n10.直接回答同学即可,无需说出你的思考过程,或者你参考了什么资料;\n11.务必使用分点来让思路更加清晰,例如可以使用“*”“-”或数字符号来进行分点回答;\n12. 你的从资料中总结的回答必须完整,不需要精简、不能遗漏;\n\n内容问题:{{question}}\n答案:"
-    ]
-  ],
-  "tw": [],
-  "en": []
-}

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.