From 5e025bf048b720652ef96321c18ba67085ce1683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?sunsonliu=28=E5=88=98=E9=98=B3=29?= Date: Sun, 22 Dec 2024 22:27:56 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20#1006=20=E6=B5=81=E5=BC=8F=E4=BC=9A?= =?UTF-8?q?=E8=AF=9D=E5=9C=BA=E6=99=AF=E4=B8=AD=EF=BC=8C=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?`flowSessionCursor`=E9=85=8D=E7=BD=AE=E9=A1=B9=EF=BC=8C?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E8=99=9A=E6=8B=9F=E5=85=89=E6=A0=87=E7=9A=84?= =?UTF-8?q?=E6=95=88=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/api.html | 10 ++++++++++ examples/scripts/ai-chat-demo.js | 1 + src/Cherry.config.js | 7 +++++++ src/Cherry.js | 15 ++++++++++++++ src/Engine.js | 34 +++++++++++++++++++++++++++++++- src/sass/cherry.scss | 18 +++++++++++++++++ types/cherry.d.ts | 7 +++++++ 7 files changed, 91 insertions(+), 1 deletion(-) diff --git a/examples/api.html b/examples/api.html index 1316cec2b..8f6e023f3 100644 --- a/examples/api.html +++ b/examples/api.html @@ -281,6 +281,16 @@

refreshPreviewer()

+
+

clearFlowSessionCursor()

+

清空流程会话中添加的虚拟光标

+
+ + 试一试 +
+
+

diff --git a/examples/scripts/ai-chat-demo.js b/examples/scripts/ai-chat-demo.js index 0ec578b0b..736552a91 100644 --- a/examples/scripts/ai-chat-demo.js +++ b/examples/scripts/ai-chat-demo.js @@ -7,6 +7,7 @@ var cherryConfig = { global: { // 开启流式模式 (默认 true) flowSessionContext: true, + flowSessionCursor: 'default', }, syntax: { codeBlock: { diff --git a/src/Cherry.config.js b/src/Cherry.config.js index 10d2b52c0..043c1f464 100644 --- a/src/Cherry.config.js +++ b/src/Cherry.config.js @@ -197,6 +197,13 @@ const defaultConfig = { * 后续如果有新的需求,可提issue反馈 */ flowSessionContext: true, + /** + * 流式会话时,在最后位置增加一个类似光标的dom + * - 'default':用cherry提供的默认样式 + * - '':不增加任何dom + * - '': 自定义的dom + */ + flowSessionCursor: '', }, // 内置语法配置 syntax: { diff --git a/src/Cherry.js b/src/Cherry.js index c114bcca0..2fdb39eb4 100644 --- a/src/Cherry.js +++ b/src/Cherry.js @@ -122,6 +122,9 @@ export default class Cherry extends CherryStatic { this.lastMarkdownText = ''; this.$event = new Event(this.instanceId); + if (this.options.engine.global.flowSessionCursor === 'default') { + this.options.engine.global.flowSessionCursor = ''; + } /** * @type {import('./Engine').default} */ @@ -1086,4 +1089,16 @@ export default class Cherry extends CherryStatic { // @ts-ignore this.toc.setModelToLocalStorage(targetModel); } + + /** + * 清空流程会话中添加的虚拟光标 + */ + clearFlowSessionCursor() { + if (this.options.engine.global.flowSessionCursor) { + this.previewer.getDom().innerHTML = this.previewer + .getDom() + // @ts-ignore + .innerHTML.replaceAll(this.options.engine.global.flowSessionCursor, ''); + } + } } diff --git a/src/Engine.js b/src/Engine.js index d66eb466e..9969de26b 100644 --- a/src/Engine.js +++ b/src/Engine.js @@ -266,17 +266,49 @@ export default class Engine { }); } + /** + * 流式输出场景时,在最后增加一个光标占位 + * @param {string} md 内容 + * @returns {string} + */ + $setFlowSessionCursorCache(md) { + if (this.$cherry.options.engine.global.flowSessionContext && this.$cherry.options.engine.global.flowSessionCursor) { + return `${md}CHERRY_FLOW_SESSION_CURSOR`; + } + return md; + } + + /** + * 流式输出场景时,把最后的光标占位替换为配置的dom元素,并在一段时间后删除该元素 + * @param {string} md 内容 + * @returns {string} + */ + $clearFlowSessionCursorCache(md) { + if (this.$cherry.options.engine.global.flowSessionCursor) { + if (this.clearCursorTimer) { + clearTimeout(this.clearCursorTimer); + } + this.clearCursorTimer = setTimeout(() => { + this.$cherry.clearFlowSessionCursor(); + }, 2560); + return md.replace(/CHERRY_FLOW_SESSION_CURSOR/g, this.$cherry.options.engine.global.flowSessionCursor); + } + return md; + } + /** * @param {string} md md字符串 * @returns {string} 获取html */ makeHtml(md) { - let $md = this.$cacheBigData(md); + let $md = this.$setFlowSessionCursorCache(md); + $md = this.$cacheBigData($md); $md = this.$beforeMakeHtml($md); $md = this.$dealParagraph($md); $md = this.$afterMakeHtml($md); this.$fireHookAction($md, 'paragraph', '$cleanCache'); $md = this.$deCacheBigData($md); + $md = this.$clearFlowSessionCursorCache($md); return $md; } diff --git a/src/sass/cherry.scss b/src/sass/cherry.scss index 7b8c3916d..5b5b5e677 100644 --- a/src/sass/cherry.scss +++ b/src/sass/cherry.scss @@ -813,6 +813,24 @@ background-color: #3582fb; } } + + @keyframes blink { + 0% { + opacity: 1; + } + 50% { + opacity: 0; + } + 100% { + opacity: 1; + } + } + + .cherry-flow-session-cursor { + background-color: #3582fb88; + padding: 0 2.5px; + animation: blink 1s infinite; + } } .cherry-color-wrap { diff --git a/types/cherry.d.ts b/types/cherry.d.ts index 1d94c81b3..09400b24c 100644 --- a/types/cherry.d.ts +++ b/types/cherry.d.ts @@ -237,6 +237,13 @@ export interface CherryEngineOptions { * 后续如果有新的需求,可提issue反馈 */ flowSessionContext?: boolean; + /** + * 流式会话时,在最后位置增加一个类似光标的dom + * - 'default':用cherry提供的默认样式 + * - '':不增加任何dom + * - '': 自定义的dom + */ + flowSessionCursor?: string; }; /** 内置语法配置 */ syntax?: {