From 742180989793563aa53e4d023fd75d142818f087 Mon Sep 17 00:00:00 2001 From: deepinsect Date: Tue, 25 Feb 2025 13:45:34 +0800 Subject: [PATCH] compelete --- package.json | 1 + src/main/presenter/threadPresenter/index.ts | 6 ++ src/renderer/index.html | 2 +- .../src/components/SearchResultsDrawer.vue | 71 +++++++++++++++++ .../message/MessageBlockContent.vue | 53 ++++++++++++- .../components/message/MessageBlockSearch.vue | 18 ++++- .../message/MessageItemAssistant.vue | 19 ++++- .../components/message/ReferencePreview.vue | 79 +++++++++++++++++++ src/renderer/src/i18n/en-US.json | 4 +- src/renderer/src/i18n/ja-JP.json | 4 +- src/renderer/src/i18n/ko-KR.json | 4 +- src/renderer/src/i18n/ru-RU.json | 4 +- src/renderer/src/i18n/zh-CN.json | 4 +- src/renderer/src/i18n/zh-HK.json | 4 +- src/renderer/src/lib/markdown.helper.ts | 56 ++++++++++++- src/shared/presenter.d.ts | 2 + 16 files changed, 319 insertions(+), 12 deletions(-) create mode 100644 src/renderer/src/components/SearchResultsDrawer.vue create mode 100644 src/renderer/src/components/message/ReferencePreview.vue diff --git a/package.json b/package.json index a431669..76fab6a 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ "katex": "^0.16.21", "lucide-vue-next": "^0.474.0", "markdown-it": "^14.1.0", + "markdown-it-footnote": "^4.0.0", "markdown-it-mathjax3": "^4.3.2", "markdown-it-texmath": "^1.0.0", "marked": "^15.0.7", diff --git a/src/main/presenter/threadPresenter/index.ts b/src/main/presenter/threadPresenter/index.ts index 47f622c..b74dd34 100644 --- a/src/main/presenter/threadPresenter/index.ts +++ b/src/main/presenter/threadPresenter/index.ts @@ -677,6 +677,12 @@ export class ThreadPresenter implements IThreadPresenter { return await this.messageManager.getLastUserMessage(conversationId) } + // 从数据库获取搜索结果 + async getSearchResults(messageId: string): Promise { + const results = await this.sqlitePresenter.getMessageAttachments(messageId, 'search_result') + return results.map((result) => JSON.parse(result.content) as SearchResult) ?? [] + } + async startStreamCompletion(conversationId: string, queryMsgId?: string) { const state = Array.from(this.generatingMessages.values()).find( (state) => state.conversationId === conversationId diff --git a/src/renderer/index.html b/src/renderer/index.html index 3e4ebf2..1ea446f 100644 --- a/src/renderer/index.html +++ b/src/renderer/index.html @@ -6,7 +6,7 @@ diff --git a/src/renderer/src/components/SearchResultsDrawer.vue b/src/renderer/src/components/SearchResultsDrawer.vue new file mode 100644 index 0000000..8047718 --- /dev/null +++ b/src/renderer/src/components/SearchResultsDrawer.vue @@ -0,0 +1,71 @@ + + + diff --git a/src/renderer/src/components/message/MessageBlockContent.vue b/src/renderer/src/components/message/MessageBlockContent.vue index 91e1896..93f1a21 100644 --- a/src/renderer/src/components/message/MessageBlockContent.vue +++ b/src/renderer/src/components/message/MessageBlockContent.vue @@ -8,14 +8,16 @@ v-html="renderedContent" > + diff --git a/src/renderer/src/components/message/MessageBlockSearch.vue b/src/renderer/src/components/message/MessageBlockSearch.vue index 6173f97..a2e40d8 100644 --- a/src/renderer/src/components/message/MessageBlockSearch.vue +++ b/src/renderer/src/components/message/MessageBlockSearch.vue @@ -1,6 +1,7 @@ diff --git a/src/renderer/src/components/message/MessageItemAssistant.vue b/src/renderer/src/components/message/MessageItemAssistant.vue index 469de32..5fa97e1 100644 --- a/src/renderer/src/components/message/MessageItemAssistant.vue +++ b/src/renderer/src/components/message/MessageItemAssistant.vue @@ -17,13 +17,22 @@
- + - +
@@ -105,6 +114,12 @@ watch( } ) +const isSearchResult = computed(() => { + return Boolean( + currentContent.value?.some((block) => block.type === 'search' && block.status === 'success') + ) +}) + onMounted(() => { // 默认显示最后一个变体 currentVariantIndex.value = allVariants.value.length diff --git a/src/renderer/src/components/message/ReferencePreview.vue b/src/renderer/src/components/message/ReferencePreview.vue new file mode 100644 index 0000000..cb48908 --- /dev/null +++ b/src/renderer/src/components/message/ReferencePreview.vue @@ -0,0 +1,79 @@ + + + diff --git a/src/renderer/src/i18n/en-US.json b/src/renderer/src/i18n/en-US.json index 9a85dec..127262b 100644 --- a/src/renderer/src/i18n/en-US.json +++ b/src/renderer/src/i18n/en-US.json @@ -42,7 +42,9 @@ }, "search": { "results": "Found {0} web pages", - "searching": "Searching..." + "searching": "Searching...", + "title": "Search Results", + "description": "Found {0} related results" } }, "model": { diff --git a/src/renderer/src/i18n/ja-JP.json b/src/renderer/src/i18n/ja-JP.json index f2c756b..d17720b 100644 --- a/src/renderer/src/i18n/ja-JP.json +++ b/src/renderer/src/i18n/ja-JP.json @@ -42,7 +42,9 @@ }, "search": { "results": "{0}件のウェブページが見つかりました", - "searching": "検索中..." + "searching": "検索中...", + "title": "検索結果", + "description": "{0}件の関連結果が見つかりました" } }, "model": { diff --git a/src/renderer/src/i18n/ko-KR.json b/src/renderer/src/i18n/ko-KR.json index e68c4e4..fd5022f 100644 --- a/src/renderer/src/i18n/ko-KR.json +++ b/src/renderer/src/i18n/ko-KR.json @@ -42,7 +42,9 @@ }, "search": { "results": "{0}개의 웹페이지가 검색되었습니다", - "searching": "검색 중..." + "searching": "검색 중...", + "title": "검색 결과", + "description": "{0}개의 관련 결과를 찾았습니다" } }, "model": { diff --git a/src/renderer/src/i18n/ru-RU.json b/src/renderer/src/i18n/ru-RU.json index 88b93fb..710106c 100644 --- a/src/renderer/src/i18n/ru-RU.json +++ b/src/renderer/src/i18n/ru-RU.json @@ -42,7 +42,9 @@ }, "search": { "results": "Найдено {0} веб-страниц", - "searching": "Поиск..." + "searching": "Поиск...", + "title": "Результаты поиска", + "description": "Найдено {0} связанных результатов" } }, "model": { diff --git a/src/renderer/src/i18n/zh-CN.json b/src/renderer/src/i18n/zh-CN.json index 20c0d0b..0ae5d90 100644 --- a/src/renderer/src/i18n/zh-CN.json +++ b/src/renderer/src/i18n/zh-CN.json @@ -42,7 +42,9 @@ }, "search": { "results": "已搜索到{0}个网页", - "searching": "搜索中..." + "searching": "搜索中...", + "title": "搜索结果", + "description": "共找到 {0} 条相关结果" } }, "model": { diff --git a/src/renderer/src/i18n/zh-HK.json b/src/renderer/src/i18n/zh-HK.json index f3f609c..62a59d7 100644 --- a/src/renderer/src/i18n/zh-HK.json +++ b/src/renderer/src/i18n/zh-HK.json @@ -42,7 +42,9 @@ }, "search": { "results": "已搜索到{0}個網頁", - "searching": "搜索中..." + "searching": "搜索中...", + "title": "搜索結果", + "description": "共找到 {0} 條相關結果" } }, "model": { diff --git a/src/renderer/src/lib/markdown.helper.ts b/src/renderer/src/lib/markdown.helper.ts index 53865eb..0f6b15d 100644 --- a/src/renderer/src/lib/markdown.helper.ts +++ b/src/renderer/src/lib/markdown.helper.ts @@ -1,6 +1,6 @@ import MarkdownIt from 'markdown-it' import mathjax3 from 'markdown-it-mathjax3' - +// import footnote from 'markdown-it-footnote' // Create markdown-it instance with configuration const md = new MarkdownIt({ html: true, @@ -103,4 +103,58 @@ export const enableDebugRendering = () => { } } +// Custom reference inline rule +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const referenceInline = (state: any, silent: boolean) => { + if (state.src[state.pos] !== '[') return false + + const match = /^\[(\d+)\]/.exec(state.src.slice(state.pos)) + if (!match) return false + + if (!silent) { + const id = match[1] + const token = state.push('reference', 'span', 0) + token.content = id + token.markup = match[0] + } + + state.pos += match[0].length + return true +} + +// Add rendering rule for references +md.renderer.rules.reference = (tokens, idx) => { + const id = tokens[idx].content + return `${id}` +} + +// Register custom rule +md.inline.ruler.before('escape', 'reference', referenceInline) + +export const initReference = ({ + onClick, + onHover +}: { + onClick: (id: string, rect: DOMRect) => void + onHover: (id: string, isHover: boolean, rect: DOMRect) => void +}) => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ;(window as any).handleReferenceClick = (id: string, event: MouseEvent) => { + const rect = (event.target as HTMLElement).getBoundingClientRect() + onClick(id, rect) + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ;(window as any).handleReferenceHover = (id: string, isHover: boolean, event: MouseEvent) => { + const rect = (event.target as HTMLElement).getBoundingClientRect() + onHover(id, isHover, rect) + } +} + export const renderMarkdown = (content: string) => md.render(content) diff --git a/src/shared/presenter.d.ts b/src/shared/presenter.d.ts index 1fea6f0..2828964 100644 --- a/src/shared/presenter.d.ts +++ b/src/shared/presenter.d.ts @@ -245,6 +245,8 @@ export interface IThreadPresenter { setActiveConversation(conversationId: string): Promise getActiveConversation(): Promise + getSearchResults(messageId: string): Promise + // 消息操作 getMessages( conversationId: string,