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 |
+
|