feat: drag file to chatbot to upload 拖动以上传文件 (#1396)

* feat: 拖动以上传文件

* 上传文件过程中转圈圈

* fix: 解决仅在第一次上传时才有上传动画的问题

---------

Co-authored-by: 505030475 <qingxu.fu@outlook.com>
This commit is contained in:
Keldos 2023-12-21 10:24:11 +08:00 committed by GitHub
parent f7588d4776
commit 2b90302851
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 145 additions and 48 deletions

View File

@ -292,7 +292,9 @@ def main():
cancel_handles.append(click_handle)
# 文件上传区接收文件后与chatbot的互动
file_upload.upload(on_file_uploaded, [file_upload, chatbot, txt, txt2, checkboxes, cookies], [chatbot, txt, txt2, cookies])
file_upload.upload(None, None, None, _js=r"()=>{toast_push('上传完毕, 请等待文件清单展现后继续操作 ...'); cancel_loading_status();}")
file_upload_2.upload(on_file_uploaded, [file_upload_2, chatbot, txt, txt2, checkboxes, cookies], [chatbot, txt, txt2, cookies])
file_upload_2.upload(None, None, None, _js=r"()=>{toast_push('上传完毕, 请等待文件清单展现后继续操作 ...'); cancel_loading_status();}")
# 函数插件-固定按钮区
for k in plugins:
if not plugins[k].get("AsButton", True): continue

View File

@ -102,8 +102,7 @@ function chatbotAutoHeight(){
// 自动调整高度
function update_height() {
var { panel_height_target, chatbot_height, chatbot } = get_elements(true);
if (panel_height_target!=chatbot_height)
{
if (panel_height_target != chatbot_height) {
var pixelString = panel_height_target.toString() + 'px';
chatbot.style.maxHeight = pixelString; chatbot.style.height = pixelString;
}
@ -111,8 +110,7 @@ function chatbotAutoHeight(){
function update_height_slow() {
var { panel_height_target, chatbot_height, chatbot } = get_elements();
if (panel_height_target!=chatbot_height)
{
if (panel_height_target != chatbot_height) {
new_panel_height = (panel_height_target - chatbot_height) * 0.5 + chatbot_height;
if (Math.abs(new_panel_height - panel_height_target) < 10) {
new_panel_height = panel_height_target;
@ -173,7 +171,7 @@ function add_func_paste(input) {
}
if (paste_files.length > 0) {
// 按照文件列表执行批量上传逻辑
await paste_upload_files(paste_files);
await upload_files(paste_files);
paste_files = []
}
@ -182,8 +180,42 @@ function add_func_paste(input) {
}
}
function add_func_drag(elem) {
if (elem) {
const dragEvents = ["dragover", "dragenter"];
const leaveEvents = ["dragleave", "dragend", "drop"];
async function paste_upload_files(files) {
const onDrag = function (e) {
e.preventDefault();
e.stopPropagation();
if (elem_upload_float.querySelector("input[type=file]")) {
toast_push('释放以上传文件', 50)
} else {
toast_push('⚠️请先删除上传区中的历史文件,再尝试上传。', 50)
}
};
const onLeave = function (e) {
e.preventDefault();
e.stopPropagation();
};
dragEvents.forEach(event => {
elem.addEventListener(event, onDrag);
});
leaveEvents.forEach(event => {
elem.addEventListener(event, onLeave);
});
elem.addEventListener("drop", async function (e) {
const files = e.dataTransfer.files;
await upload_files(files);
});
}
}
async function upload_files(files) {
const uploadInputElement = elem_upload_float.querySelector("input[type=file]");
let totalSizeMb = 0
if (files && files.length > 0) {
@ -195,7 +227,7 @@ async function paste_upload_files(files) {
}
// 检查文件总大小是否超过20MB
if (totalSizeMb > 20) {
toast_push('⚠️文件夹大于20MB 🚀上传文件中', 2000)
toast_push('⚠️文件夹大于 20MB 🚀上传文件中', 3000)
// return; // 如果超过了指定大小, 可以不进行后续上传操作
}
// 监听change事件 原生Gradio可以实现
@ -205,9 +237,10 @@ async function paste_upload_files(files) {
Object.defineProperty(event, "currentTarget", { value: uploadInputElement, enumerable: true });
Object.defineProperty(uploadInputElement, "files", { value: files, enumerable: true });
uploadInputElement.dispatchEvent(event);
// toast_push('🎉上传文件成功', 2000)
} else {
toast_push('⚠️请先删除上传区中的历史文件,再尝试粘贴。', 2000)
toast_push('⚠️请先删除上传区中的历史文件,再尝试上传。', 3000)
}
}
}
@ -231,13 +264,71 @@ var elem_upload = null;
var elem_upload_float = null;
var elem_input_main = null;
var elem_input_float = null;
var gptChatbot = null;
function begin_loading_status() {
// Create the loader div and add styling
var loader = document.createElement('div');
loader.id = 'Js_File_Loading';
loader.style.position = "absolute";
loader.style.top = "50%";
loader.style.left = "50%";
loader.style.width = "60px";
loader.style.height = "60px";
loader.style.border = "16px solid #f3f3f3";
loader.style.borderTop = "16px solid #3498db";
loader.style.borderRadius = "50%";
loader.style.animation = "spin 2s linear infinite";
loader.style.transform = "translate(-50%, -50%)";
document.body.appendChild(loader); // Add the loader to the body
// Set the CSS animation keyframes
var styleSheet = document.createElement('style');
// styleSheet.type = 'text/css';
styleSheet.id = 'Js_File_Loading_Style'
styleSheet.innerText = `
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}`;
document.head.appendChild(styleSheet);
}
function cancel_loading_status() {
var loadingElement = document.getElementById('Js_File_Loading');
if (loadingElement) {
document.body.removeChild(loadingElement); // remove the loader from the body
}
var loadingStyle = document.getElementById('Js_File_Loading_Style');
if (loadingStyle) {
document.head.removeChild(loadingStyle);
}
let clearButton = document.querySelectorAll('div[id*="elem_upload"] button[aria-label="Clear"]');
for (let button of clearButton) {
button.addEventListener('click', function () {
setTimeout(function () {
register_upload_event();
}, 50);
});
}
}
function register_upload_event() {
elem_upload_float = document.getElementById('elem_upload_float')
const upload_component = elem_upload_float.querySelector("input[type=file]");
if (upload_component) {
upload_component.addEventListener('change', function (event) {
toast_push('正在上传中,请稍等。', 2000);
begin_loading_status();
});
}
}
function monitoring_input_box() {
register_upload_event();
elem_upload = document.getElementById('elem_upload')
elem_upload_float = document.getElementById('elem_upload_float')
elem_input_main = document.getElementById('user_input_main')
elem_input_float = document.getElementById('user_input_float')
if (elem_input_main) {
if (elem_input_main.querySelector("textarea")) {
add_func_paste(elem_input_main.querySelector("textarea"))
@ -248,6 +339,10 @@ function monitoring_input_box() {
add_func_paste(elem_input_float.querySelector("textarea"))
}
}
gptChatbot = document.getElementById('gpt-chatbot')
if (gptChatbot) {
add_func_drag(gptChatbot)
}
}