Spaces:
Sleeping
Sleeping
feat: 通过上下方向键在对话框中自动填入用户历史发送信息 (#509)
Browse files* 加入了方向键的支持,可以通过上下方向键自动填入历史信息
* 更新默认的最大历史长度为常量32
* 修改了阻止默认行为的逻辑,只对于对于需要响应的时候,才阻止上下键的默认行为。
- ChuanhuChatbot.py +1 -0
- assets/custom.js +70 -1
ChuanhuChatbot.py
CHANGED
@@ -51,6 +51,7 @@ with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
|
|
51 |
with gr.Row():
|
52 |
with gr.Column(scale=12):
|
53 |
user_input = gr.Textbox(
|
|
|
54 |
show_label=False, placeholder="在这里输入"
|
55 |
).style(container=False)
|
56 |
with gr.Column(min_width=70, scale=1):
|
|
|
51 |
with gr.Row():
|
52 |
with gr.Column(scale=12):
|
53 |
user_input = gr.Textbox(
|
54 |
+
elem_id="user_input_tb",
|
55 |
show_label=False, placeholder="在这里输入"
|
56 |
).style(container=False)
|
57 |
with gr.Column(min_width=70, scale=1):
|
assets/custom.js
CHANGED
@@ -1 +1,70 @@
|
|
1 |
-
// custom javascript here
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// custom javascript here
|
2 |
+
const MAX_HISTORY_LENGTH = 32;
|
3 |
+
|
4 |
+
var key_down_history = [];
|
5 |
+
var currentIndex = -1;
|
6 |
+
var user_input_ta;
|
7 |
+
|
8 |
+
var ga = document.getElementsByTagName("gradio-app");
|
9 |
+
var targetNode = ga[0];
|
10 |
+
var observer = new MutationObserver(function(mutations) {
|
11 |
+
for (var i = 0; i < mutations.length; i++) {
|
12 |
+
if (mutations[i].addedNodes.length) {
|
13 |
+
var user_input_tb = document.getElementById('user_input_tb');
|
14 |
+
if (user_input_tb) {
|
15 |
+
// 监听到user_input_tb被添加到DOM树中
|
16 |
+
// 这里可以编写元素加载完成后需要执行的代码
|
17 |
+
user_input_ta = user_input_tb.querySelector("textarea");
|
18 |
+
if (user_input_ta){
|
19 |
+
observer.disconnect(); // 停止监听
|
20 |
+
// 在 textarea 上监听 keydown 事件
|
21 |
+
user_input_ta.addEventListener("keydown", function (event) {
|
22 |
+
var value = user_input_ta.value.trim();
|
23 |
+
// 判断按下的是否为方向键
|
24 |
+
if (event.code === 'ArrowUp' || event.code === 'ArrowDown') {
|
25 |
+
// 如果按下的是方向键,且输入框中有内容,且历史记录中没有该内容,则不执行操作
|
26 |
+
if(value && key_down_history.indexOf(value) === -1)
|
27 |
+
return;
|
28 |
+
// 对于需要响应的动作,阻止默认行为。
|
29 |
+
event.preventDefault();
|
30 |
+
var length = key_down_history.length;
|
31 |
+
if(length === 0) {
|
32 |
+
currentIndex = -1; // 如果历史记录为空,直接将当前选中的记录重置
|
33 |
+
return;
|
34 |
+
}
|
35 |
+
if (currentIndex === -1) {
|
36 |
+
currentIndex = length;
|
37 |
+
}
|
38 |
+
if (event.code === 'ArrowUp' && currentIndex > 0) {
|
39 |
+
currentIndex--;
|
40 |
+
user_input_ta.value = key_down_history[currentIndex];
|
41 |
+
} else if (event.code === 'ArrowDown' && currentIndex < length - 1) {
|
42 |
+
currentIndex++;
|
43 |
+
user_input_ta.value = key_down_history[currentIndex];
|
44 |
+
}
|
45 |
+
user_input_ta.selectionStart = user_input_ta.value.length;
|
46 |
+
user_input_ta.selectionEnd = user_input_ta.value.length;
|
47 |
+
const input_event = new InputEvent("input", {bubbles: true, cancelable: true});
|
48 |
+
user_input_ta.dispatchEvent(input_event);
|
49 |
+
}else if(event.code === "Enter") {
|
50 |
+
if (value) {
|
51 |
+
currentIndex = -1;
|
52 |
+
if(key_down_history.indexOf(value) === -1){
|
53 |
+
key_down_history.push(value);
|
54 |
+
if (key_down_history.length > MAX_HISTORY_LENGTH) {
|
55 |
+
key_down_history.shift();
|
56 |
+
}
|
57 |
+
}
|
58 |
+
}
|
59 |
+
}
|
60 |
+
});
|
61 |
+
break;
|
62 |
+
}
|
63 |
+
}
|
64 |
+
}
|
65 |
+
}
|
66 |
+
});
|
67 |
+
|
68 |
+
// 监听目标节点的子节点列表是否发生变化
|
69 |
+
observer.observe(targetNode, { childList: true , subtree: true });
|
70 |
+
|