+
{children}
);
@@ -158,17 +164,27 @@ function MarkdownContent({ children, className, acceptHtml }: MarkdownProps) {
);
}
-function Markdown(props: MarkdownProps) {
+function Markdown({ children, ...props }: MarkdownProps) {
// memoize the component
- const { children, className, acceptHtml } = props;
return useMemo(
- () => (
-
- {children}
-
- ),
- [props.children, props.className, props.acceptHtml],
+ () => {children} ,
+ [props, children],
);
}
+type CodeMarkdownProps = MarkdownProps & {
+ filename: string;
+};
+
+export function CodeMarkdown({ filename, ...props }: CodeMarkdownProps) {
+ const suffix = filename.includes(".") ? filename.split(".").pop() : "";
+ const children = useMemo(() => {
+ const content = props.children.toString();
+
+ return `\`\`\`${suffix}\n${content}\n\`\`\``;
+ }, [props.children]);
+
+ return {children} ;
+}
+
export default Markdown;
diff --git a/app/src/components/plugins/file.tsx b/app/src/components/plugins/file.tsx
index ce11d7a..721f271 100644
--- a/app/src/components/plugins/file.tsx
+++ b/app/src/components/plugins/file.tsx
@@ -1,7 +1,8 @@
-import { Download, File } from "lucide-react";
+import { Download, Eye, File } from "lucide-react";
import { saveAsFile, saveBlobAsFile } from "@/utils/dom.ts";
import { useMemo } from "react";
import { Button } from "@/components/ui/button.tsx";
+import FileViewer from "@/components/FileViewer.tsx";
/**
* file format:
@@ -37,7 +38,7 @@ export function parseFile(data: string, acceptDownload?: boolean) {
{filename}
- {image && (
+ {image ? (
+ ) : (
+
+
+
)}
{image &&
}
diff --git a/app/src/resources/i18n/cn.json b/app/src/resources/i18n/cn.json
index c036a08..84ef26b 100644
--- a/app/src/resources/i18n/cn.json
+++ b/app/src/resources/i18n/cn.json
@@ -241,6 +241,7 @@
"confirm": "确认",
"percent": "{{cent}}折",
"file": {
+ "file": "文件",
"upload": "上传文件",
"type": "支持 pdf, docx, pptx, xlsx, 图像, 文本等格式",
"drop": "拖拽文件到此处或点击上传",
diff --git a/app/src/resources/i18n/en.json b/app/src/resources/i18n/en.json
index e808696..8f822a1 100644
--- a/app/src/resources/i18n/en.json
+++ b/app/src/resources/i18n/en.json
@@ -207,7 +207,8 @@
"empty-file": "Empty File",
"empty-file-prompt": "File content is empty, has been automatically ignored",
"large-file-success": "Parsing Successful",
- "large-file-success-prompt": "Large file parsed successfully in {{time}} seconds"
+ "large-file-success-prompt": "Large file parsed successfully in {{time}} seconds",
+ "file": "Files"
},
"generate": {
"title": "AI Project Generator",
diff --git a/app/src/resources/i18n/ja.json b/app/src/resources/i18n/ja.json
index 9b3674d..da8cadc 100644
--- a/app/src/resources/i18n/ja.json
+++ b/app/src/resources/i18n/ja.json
@@ -207,7 +207,8 @@
"empty-file": "コンテンツファイルがありません",
"empty-file-prompt": "ファイルの内容が空で、自動的に無視されます",
"large-file-success": "解析に成功しました",
- "large-file-success-prompt": "{{time}}秒で大きなファイルが正常に解析されました"
+ "large-file-success-prompt": "{{time}}秒で大きなファイルが正常に解析されました",
+ "file": "ファイル"
},
"generate": {
"title": "AIプロジェクトビルダー",
diff --git a/app/src/resources/i18n/ru.json b/app/src/resources/i18n/ru.json
index 025452c..77e2c70 100644
--- a/app/src/resources/i18n/ru.json
+++ b/app/src/resources/i18n/ru.json
@@ -207,7 +207,8 @@
"empty-file": "Пустой файл",
"empty-file-prompt": "Содержимое файла пустое, автоматически проигнорировано",
"large-file-success": "Синтаксический анализ успешно завершен",
- "large-file-success-prompt": "Большой файл успешно проанализирован за {{time}} секунды"
+ "large-file-success-prompt": "Большой файл успешно проанализирован за {{time}} секунды",
+ "file": "Документ"
},
"generate": {
"title": "Генератор AI проектов",
diff --git a/docker-compose.yaml b/docker-compose.yaml
index d873685..d83a484 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -39,6 +39,10 @@ services:
links:
- mysql
- redis
+ ulimits:
+ nofile:
+ soft: 65535
+ hard: 65535
environment:
MYSQL_HOST: mysql
MYSQL_USER: chatnio
diff --git a/manager/connection.go b/manager/connection.go
index c8630ee..94821b4 100644
--- a/manager/connection.go
+++ b/manager/connection.go
@@ -147,8 +147,6 @@ func (c *Connection) Process(handler func(*conversation.FormMessage) error) {
}
func (c *Connection) Handle(handler func(*conversation.FormMessage) error) {
- defer c.conn.DeferClose()
-
go c.Process(handler)
c.ReadWorker()
}
diff --git a/manager/manager.go b/manager/manager.go
index b67c44e..7d9b9af 100644
--- a/manager/manager.go
+++ b/manager/manager.go
@@ -58,6 +58,7 @@ func ChatAPI(c *gin.Context) {
if conn = utils.NewWebsocket(c, false); conn == nil {
return
}
+ defer conn.DeferClose()
db := utils.GetDBFromContext(c)