diff --git a/aiserver.py b/aiserver.py index 6880ebfa..42eea963 100644 --- a/aiserver.py +++ b/aiserver.py @@ -257,13 +257,15 @@ def sendModelSelection(menu="mainmenu", folder="./models"): if koboldai_vars.host: breadcrumbs = [] menu_list = [[folder, menu, "", False] for folder in paths] + menu_list_ui_2 = [[folder[0], folder[1], "", False] for folder in paths] menu_list.append(["Return to Main Menu", "mainmenu", "", True]) + menu_list_ui_2.append(["Return to Main Menu", "mainmenu", "", True]) if os.path.abspath("{}/models".format(os.getcwd())) == os.path.abspath(folder): showdelete=True else: showdelete=False emit('from_server', {'cmd': 'show_model_menu', 'data': menu_list, 'menu': menu, 'breadcrumbs': breadcrumbs, "showdelete": showdelete}, broadcast=True, room="UI_1") - emit('show_model_menu', {'data': menu_list, 'menu': menu, 'breadcrumbs': breadcrumbs, "showdelete": showdelete}, broadcast=False, room="UI_2") + emit('show_model_menu', {'data': menu_list_ui_2, 'menu': menu, 'breadcrumbs': breadcrumbs, "showdelete": showdelete}, broadcast=False, room="UI_2") else: emit('from_server', {'cmd': 'show_model_menu', 'data': model_menu[menu], 'menu': menu, 'breadcrumbs': [], "showdelete": False}, broadcast=True, room="UI_1") emit('show_model_menu', {'data': model_menu[menu], 'menu': menu, 'breadcrumbs': [], "showdelete": False}, broadcast=False, room="UI_2") @@ -1010,6 +1012,8 @@ def get_model_info(model, directory=""): key_value = js["apikey"] elif 'oaiapikey' in js and js['oaiapikey'] != "": key_value = js["oaiapikey"] + if model in ('GooseAI', 'OAI'): + get_oai_models({'model': model, 'key': key_value}) key = True elif model == 'ReadOnly': pass @@ -1045,11 +1049,10 @@ def get_model_info(model, directory=""): 'url': url, 'gpu_names': gpu_names}, broadcast=True, room="UI_1") emit('selected_model_info', {'key_value': key_value, 'key':key, 'gpu':gpu, 'layer_count':layer_count, 'breakmodel':breakmodel, - 'disk_break_value': disk_blocks, 'disk_break': not utils.HAS_ACCELERATE, + 'disk_break_value': disk_blocks, 'disk_break': utils.HAS_ACCELERATE, 'break_values': break_values, 'gpu_count': gpu_count, 'url': url, 'gpu_names': gpu_names}, broadcast=False, room="UI_2") - if key_value != "": - get_oai_models(key_value) + def get_layer_count(model, directory=""): @@ -1072,12 +1075,14 @@ def get_layer_count(model, directory=""): else: return None - -def get_oai_models(key): +@socketio.on('OAI_Key_Update') +def get_oai_models(data): + key = data['key'] + model = data['model'] koboldai_vars.oaiapikey = key - if koboldai_vars.model == 'OAI': + if model == 'OAI': url = "https://api.openai.com/v1/engines" - elif koboldai_vars.model == 'GooseAI': + elif model == 'GooseAI': url = "https://api.goose.ai/v1/engines" else: return @@ -1106,8 +1111,8 @@ def get_oai_models(key): # If the client settings file doesn't exist, create it # Write API key to file os.makedirs('settings', exist_ok=True) - if path.exists("settings/{}.settings".format(koboldai_vars.model)): - with open("settings/{}.settings".format(koboldai_vars.model), "r") as file: + if path.exists("settings/{}.settings".format(model)): + with open("settings/{}.settings".format(model), "r") as file: js = json.load(file) if 'online_model' in js: online_model = js['online_model'] @@ -1115,11 +1120,12 @@ def get_oai_models(key): if js['apikey'] != key: changed=True if changed: - with open("settings/{}.settings".format(koboldai_vars.model), "w") as file: + with open("settings/{}.settings".format(model), "w") as file: js["apikey"] = key file.write(json.dumps(js, indent=3), room="UI_1") - emit('from_server', {'cmd': 'oai_engines', 'data': engines, 'online_model': online_model}, broadcast=True) + emit('from_server', {'cmd': 'oai_engines', 'data': engines, 'online_model': online_model}, broadcast=True, room="UI_1") + emit('oai_engines', {'data': engines, 'online_model': online_model}, room="UI_2") else: # Something went wrong, print the message and quit since we can't initialize an engine print("{0}ERROR!{1}".format(colors.RED, colors.END), room="UI_1") @@ -3205,7 +3211,7 @@ def get_message(msg): else: print(colors.RED + "WARNING!!: Someone maliciously attempted to delete " + msg['data'] + " the attempt has been blocked.") elif(msg['cmd'] == 'OAI_Key_Update'): - get_oai_models(msg['key']) + get_oai_models({'model': koboldai_vars.model, 'key': msg['key']}) elif(msg['cmd'] == 'loadselect'): koboldai_vars.loadselect = msg["data"] elif(msg['cmd'] == 'spselect'): @@ -5835,9 +5841,32 @@ def ui2_connect(): #==================================================================# @app.route("/popup_test") def popup_test(): - file_popup("Test Popup", "./", "return_event_name", folder_only=False, editable=True, deleteable=True, jailed=False, item_check=check_if_dir_is_model) + file_popup("Test Popup", "./", "return_event_name", renameable=True, folder_only=False, editable=True, deleteable=True, jailed=False, item_check=check_if_dir_is_model) return "ok" +@socketio.on('upload_file') +def upload_file(data): + print("upload_file {}".format(data['filename'])) + if 'current_folder' in session: + path = os.path.abspath(os.path.join(session['current_folder'], data['filename']).replace("\\", "/")).replace("\\", "/") + print("Want to save to {}".format(path)) + if 'popup_jailed_dir' not in session: + print("Someone is trying to upload a file to your server. Blocked.") + elif session['popup_jailed_dir'] is None: + if os.path.exists(path): + emit("error_popup", "The file already exists. Please delete it or rename the file before uploading", room="UI_2"); + else: + with open(path, "wb") as f: + f.write(data['data']) + get_files_folders(session['current_folder']) + elif session['popup_jailed_dir'] in session['current_folder']: + if os.path.exists(path): + emit("error_popup", "The file already exists. Please delete it or rename the file before uploading", room="UI_2"); + else: + with open(path, "wb") as f: + f.write(data['data']) + get_files_folders(session['current_folder']) + @socketio.on('popup_change_folder') def popup_change_folder(data): print("Doing popup change folder: {}".format(data)) @@ -5851,6 +5880,24 @@ def popup_change_folder(data): else: print("User is trying to get at files in your server outside the jail. Blocked. Jailed Dir: {} Requested Dir: {}".format(session['popup_jailed_dir'], data)) +@socketio.on('popup_rename') +def popup_rename(data): + if 'popup_renameable' not in session: + print("Someone is trying to rename a file in your server. Blocked.") + return + if not session['popup_renameable']: + print("Someone is trying to rename a file in your server. Blocked.") + return + + if session['popup_jailed_dir'] is None: + os.rename(data['file'], data['new_name']) + get_files_folders(os.path.dirname(data['file'])) + elif session['popup_jailed_dir'] in data: + os.rename(data['file'], data['new_name']) + get_files_folders(os.path.dirname(data['file'])) + else: + print("User is trying to rename files in your server outside the jail. Blocked. Jailed Dir: {} Requested Dir: {}".format(session['popup_jailed_dir'], data['file'])) + @socketio.on('popup_delete') def popup_delete(data): if 'popup_deletable' not in session: @@ -5919,7 +5966,7 @@ def popup_change_file(data): else: print("User is trying to delete files in your server outside the jail. Blocked. Jailed Dir: {} Requested Dir: {}".format(session['popup_jailed_dir'], data)) -def file_popup(popup_title, starting_folder, return_event, jailed=True, folder_only=True, deleteable=False, editable=False, show_breadcrumbs=True, item_check=None, show_hidden=False): +def file_popup(popup_title, starting_folder, return_event, upload=True, jailed=True, folder_only=True, renameable=False, deleteable=False, editable=False, show_breadcrumbs=True, item_check=None, show_hidden=False): #starting_folder = The folder we're going to get folders and/or items from #return_event = the socketio event that will be emitted when the load button is clicked #jailed = if set to true will look for the session variable jailed_folder and prevent navigation outside of that folder @@ -5934,20 +5981,23 @@ def file_popup(popup_title, starting_folder, return_event, jailed=True, folder_o else: session['popup_jailed_dir'] = None session['popup_deletable'] = deleteable + session['popup_renameable'] = renameable session['popup_editable'] = editable session['popup_show_hidden'] = show_hidden session['popup_item_check'] = item_check session['popup_folder_only'] = folder_only session['popup_show_breadcrumbs'] = show_breadcrumbs + session['upload'] = upload - socketio.emit("load_popup", {"popup_title": popup_title, "call_back": return_event, "deleteable": deleteable, "editable": editable}, broadcast=True, room="UI_2") - socketio.emit("load_popup", {"popup_title": popup_title, "call_back": return_event, "deleteable": deleteable, "editable": editable}, broadcast=True, room="UI_1") + socketio.emit("load_popup", {"popup_title": popup_title, "call_back": return_event, "renameable": renameable, "deleteable": deleteable, "editable": editable, 'upload': upload}, broadcast=True, room="UI_2") + socketio.emit("load_popup", {"popup_title": popup_title, "call_back": return_event, "renameable": renameable, "deleteable": deleteable, "editable": editable, 'upload': upload}, broadcast=True, room="UI_1") get_files_folders(starting_folder) def get_files_folders(starting_folder): import stat + session['current_folder'] = starting_folder item_check = session['popup_item_check'] show_breadcrumbs = session['popup_show_breadcrumbs'] show_hidden = session['popup_show_hidden'] @@ -6101,14 +6151,51 @@ def UI_2_load_model_button(data): #==================================================================# @socketio.on('select_model') def UI_2_load_model_button(data): + print(data) + + #We've selected a menu if data['model'] in model_menu: sendModelSelection(menu=data['model']) + #We've selected a custom line + elif data['menu'] in ("NeoCustom", "GPT2Custom"): + get_model_info(data['menu'], directory=data['display_name']) + #We've selected a custom menu + elif data['model'] in ("NeoCustom", "GPT2Custom"): + sendModelSelection(menu=data['model'], folder="./models") else: #We now have some model we want to potentially load. #First we need to send the client the model parameters (layers, etc) - print("getting model info for {}".format(data['model'])) get_model_info(data['model']) +#==================================================================# +# Event triggered when user loads a model +#==================================================================# +@socketio.on('load_model') +def UI_2_load_model(data): + print(data) + if not os.path.exists("settings/"): + os.mkdir("settings") + changed = True + if not utils.HAS_ACCELERATE: + data['disk_layers'] = "0" + if os.path.exists("settings/" + data['model'].replace('/', '_') + ".breakmodel"): + with open("settings/" + data['model'].replace('/', '_') + ".breakmodel", "r") as file: + file_data = file.read().split('\n')[:2] + if len(file_data) < 2: + file_data.append("0") + gpu_layers, disk_layers = file_data + if gpu_layers == data['gpu_layers'] and disk_layers == data['disk_layers']: + changed = False + if changed: + f = open("settings/" + data['model'].replace('/', '_') + ".breakmodel", "w") + f.write(data['gpu_layers'] + '\n' + data['disk_layers']) + f.close() + koboldai_vars.colaburl = data['url'] + "/request" + koboldai_vars.model = data['model'] + koboldai_vars.custmodpth = data['path'] + print("loading Model") + load_model(use_gpu=data['use_gpu'], gpu_layers=data['gpu_layers'], disk_layers=data['disk_layers'], online_model=data['online_model']) + #==================================================================# # Event triggered to rely a message #==================================================================# diff --git a/static/koboldai.css b/static/koboldai.css index c8fcac85..c888c35b 100644 --- a/static/koboldai.css +++ b/static/koboldai.css @@ -203,6 +203,12 @@ cursor: pointer; } +@media only screen and (max-width: 768px) { +.menu_pin { + display: hidden; +} +} +@media only screen and not (max-width: 768px) { .menu_pin { position: fixed; top:10px; @@ -215,6 +221,7 @@ transition: left 0.5s; cursor: pointer; } +} .menu_pin.hidden { left: 0px; @@ -236,6 +243,7 @@ transition: 0.5s; } +@media only screen and not (max-width: 768px) { .SideMenu.pinned { height: 100%; width: var(--flyout_menu_width); @@ -247,6 +255,7 @@ overflow-x: hidden; transition: 0.5s; } +} .SideMenu.open { width: var(--flyout_menu_width); @@ -366,9 +375,11 @@ body { grid-template-rows: auto 100px; } +@media only screen and not (max-width: 768px) { .main-grid.pinned { margin-left: var(--flyout_menu_width); } +} /* ---------------------------------- GAME SCREEN ----------------------------------*/ .gamescreen { @@ -577,8 +588,8 @@ td.sequence:hover { background-color: var(--popup_item_color); padding: 2px; display: grid; - grid-template-areas: "folder_icon delete_icon edit_icon file"; - grid-template-columns: 20px 20px 20px auto; + grid-template-areas: "folder_icon delete_icon edit_icon rename_icon file"; + grid-template-columns: 20px 20px 20px 20px auto; } @@ -590,6 +601,10 @@ td.sequence:hover { grid-area: edit_icon; } +.popup .item .rename_icon { + grid-area: rename_icon; +} + .popup .item .delete_icon { grid-area: delete_icon; } diff --git a/static/koboldai.js b/static/koboldai.js index 391964f0..4a7f724f 100644 --- a/static/koboldai.js +++ b/static/koboldai.js @@ -14,6 +14,8 @@ socket.on('popup_breadcrumbs', function(data){popup_breadcrumbs(data);}); socket.on('popup_edit_file', function(data){popup_edit_file(data);}); socket.on('show_model_menu', function(data){show_model_menu(data);}); socket.on('selected_model_info', function(data){selected_model_info(data);}); +socket.on('oai_engines', function(data){oai_engines(data);}); +socket.on('error_popup', function(data){error_popup(data);}); //socket.onAny(function(event_name, data) {console.log({"event": event_name, "class": data.classname, "data": data});}); var backend_vars = {}; @@ -21,6 +23,7 @@ var presets = {} var ai_busy_start = Date.now(); var popup_deleteable = false; var popup_editable = false; +var popup_renameable = false; //-----------------------------------Server to UI Functions----------------------------------------------- function connect() { console.log("connected"); @@ -287,6 +290,7 @@ function var_changed(data) { function load_popup(data) { popup_deleteable = data.deleteable; popup_editable = data.editable; + popup_renameable = data.renameable; var popup = document.getElementById("popup"); var popup_title = document.getElementById("popup_title"); popup_title.textContent = data.popup_title; @@ -300,17 +304,47 @@ function load_popup(data) { breadcrumbs.removeChild(breadcrumbs.firstChild); } + if (data.upload) { + const dropArea = document.getElementById('popup_list'); + dropArea.addEventListener('dragover', (event) => { + event.stopPropagation(); + event.preventDefault(); + // Style the drag-and-drop as a "copy file" operation. + event.dataTransfer.dropEffect = 'copy'; + }); + + dropArea.addEventListener('drop', (event) => { + event.stopPropagation(); + event.preventDefault(); + const fileList = event.dataTransfer.files; + for (file of fileList) { + reader = new FileReader(); + reader.onload = function (event) { + socket.emit("upload_file", {'filename': file.name, "data": event.target.result}); + }; + reader.readAsArrayBuffer(file); + } + }); + } else { + + } + popup.classList.remove("hidden"); //adjust accept button - var accept = document.getElementById("popup_accept"); - accept.classList.add("disabled"); - accept.setAttribute("emit", data.call_back); - accept.setAttribute("selected_value", ""); - accept.onclick = function () { - socket.emit(this.emit, this.getAttribute("selected_value")); - document.getElementById("popup").classList.add("hidden"); - }; + if (data.call_back == "") { + document.getElementById("popup_load_cancel").classList.add("hidden"); + } else { + document.getElementById("popup_load_cancel").classList.remove("hidden"); + var accept = document.getElementById("popup_accept"); + accept.classList.add("disabled"); + accept.setAttribute("emit", data.call_back); + accept.setAttribute("selected_value", ""); + accept.onclick = function () { + socket.emit(this.emit, this.getAttribute("selected_value")); + document.getElementById("popup").classList.add("hidden"); + }; + } } @@ -320,6 +354,7 @@ function popup_items(data) { while (popup_list.firstChild) { popup_list.removeChild(popup_list.firstChild); } + document.getElementById('popup_upload_input').value = ""; for (item of data) { var list_item = document.createElement("span"); @@ -339,7 +374,8 @@ function popup_items(data) { edit_icon.classList.add("edit_icon"); if ((popup_editable) && !(item[0])) { edit_icon.classList.add("oi"); - edit_icon.setAttribute('data-glyph', "pencil"); + edit_icon.setAttribute('data-glyph', "spreadsheet"); + edit_icon.title = "Edit" edit_icon.id = item[1]; edit_icon.onclick = function () { socket.emit("popup_edit", this.id); @@ -347,12 +383,31 @@ function popup_items(data) { } list_item.append(edit_icon); + //create the rename icon + var rename_icon = document.createElement("span"); + rename_icon.classList.add("rename_icon"); + if ((popup_renameable) && !(item[0])) { + rename_icon.classList.add("oi"); + rename_icon.setAttribute('data-glyph', "pencil"); + rename_icon.title = "Rename" + rename_icon.id = item[1]; + rename_icon.setAttribute("filename", item[2]); + rename_icon.onclick = function () { + var new_name = prompt("Please enter new filename for \n"+ this.getAttribute("filename")); + if (new_name != null) { + socket.emit("popup_rename", {"file": this.id, "new_name": new_name}); + } + }; + } + list_item.append(rename_icon); + //create the delete icon var delete_icon = document.createElement("span"); delete_icon.classList.add("delete_icon"); if (popup_deleteable) { delete_icon.classList.add("oi"); delete_icon.setAttribute('data-glyph', "x"); + delete_icon.title = "Delete" delete_icon.id = item[1]; delete_icon.setAttribute("folder", item[0]); delete_icon.onclick = function () { @@ -448,7 +503,30 @@ function popup_edit_file(data) { popup_list.append(textarea); } -//--------------------------------------------UI to Server Functions---------------------------------- + +function error_popup(data) { + alert(data); +} + +function oai_engines(data) { + console.log(data); + var oaimodel = document.getElementById("oaimodel") + oaimodel.classList.remove("hidden") + selected_item = 0; + length = oaimodel.options.length; + for (let i = 0; i < length; i++) { + oaimodel.options.remove(1); + } + for (item of data.data) { + var option = document.createElement("option"); + option.value = item[0]; + option.text = item[1]; + if(data.online_model == item[0]) { + option.selected = true; + } + oaimodel.appendChild(option); + } +} function show_model_menu(data) { document.getElementById("loadmodelcontainer").classList.remove("hidden"); @@ -528,7 +606,9 @@ function show_model_menu(data) { //create the actual item var popup_item = document.createElement("span"); popup_item.classList.add("model"); + popup_item.setAttribute("display_name", item[0]); popup_item.id = item[1]; + popup_item.setAttribute("Menu", data.menu) //name text var text = document.createElement("span"); @@ -542,14 +622,17 @@ function show_model_menu(data) { popup_item.append(text); popup_item.onclick = function () { - var accept = document.getElementById("popup_accept"); + var accept = document.getElementById("btn_loadmodelaccept"); accept.classList.add("disabled"); - socket.emit("select_model", {"model": this.id, "menu": this.getAttribute("Menu")}); + socket.emit("select_model", {"model": this.id, "menu": this.getAttribute("Menu"), "display_name": this.getAttribute("display_name")}); var model_list = document.getElementById('loadmodellistcontent').getElementsByClassName("selected"); for (model of model_list) { model.classList.remove("selected"); } this.classList.add("selected"); + accept.setAttribute("selected_model", this.id); + accept.setAttribute("menu", this.getAttribute("Menu")); + accept.setAttribute("display_name", this.getAttribute("display_name")); }; list_item.append(popup_item); @@ -560,6 +643,7 @@ function show_model_menu(data) { } function selected_model_info(data) { + console.log(data); var accept = document.getElementById("btn_loadmodelaccept"); //hide or unhide key if (data.key) { @@ -653,56 +737,58 @@ function selected_model_info(data) { } //add the disk layers - var div = document.createElement("div"); - div.classList.add("model_setting_container"); - //build GPU text - var span = document.createElement("span"); - span.classList.add("model_setting_label"); - span.textContent = "Disk cache: " - //build layer count box - var input = document.createElement("input"); - input.classList.add("model_setting_value"); - input.classList.add("setting_value"); - input.inputmode = "numeric"; - input.id = "disk_layers_box"; - input.value = data.disk_break_value; - input.onblur = function () { - document.getElementById(this.id.replace("_box", "")).value = this.value; - update_gpu_layers(); - } - span.append(input); - div.append(span); - //build layer count slider - var input = document.createElement("input"); - input.classList.add("model_setting_item"); - input.type = "range"; - input.min = 0; - input.max = data.layer_count; - input.step = 1; - input.value = data.disk_break_value; - input.id = "disk_layers"; - input.onchange = function () { - document.getElementById(this.id+"_box").value = this.value; - update_gpu_layers(); - } - div.append(input); - //build slider bar #s - //min - var span = document.createElement("span"); - span.classList.add("model_setting_minlabel"); - var span2 = document.createElement("span"); - span2.style="top: -4px; position: relative;"; - span2.textContent = 0; - span.append(span2); - div.append(span); - //max - var span = document.createElement("span"); - span.classList.add("model_setting_maxlabel"); - var span2 = document.createElement("span"); - span2.style="top: -4px; position: relative;"; - span2.textContent = data.layer_count; - span.append(span2); - div.append(span); + if (data.disk_break) { + var div = document.createElement("div"); + div.classList.add("model_setting_container"); + //build GPU text + var span = document.createElement("span"); + span.classList.add("model_setting_label"); + span.textContent = "Disk cache: " + //build layer count box + var input = document.createElement("input"); + input.classList.add("model_setting_value"); + input.classList.add("setting_value"); + input.inputmode = "numeric"; + input.id = "disk_layers_box"; + input.value = data.disk_break_value; + input.onblur = function () { + document.getElementById(this.id.replace("_box", "")).value = this.value; + update_gpu_layers(); + } + span.append(input); + div.append(span); + //build layer count slider + var input = document.createElement("input"); + input.classList.add("model_setting_item"); + input.type = "range"; + input.min = 0; + input.max = data.layer_count; + input.step = 1; + input.value = data.disk_break_value; + input.id = "disk_layers"; + input.onchange = function () { + document.getElementById(this.id+"_box").value = this.value; + update_gpu_layers(); + } + div.append(input); + //build slider bar #s + //min + var span = document.createElement("span"); + span.classList.add("model_setting_minlabel"); + var span2 = document.createElement("span"); + span2.style="top: -4px; position: relative;"; + span2.textContent = 0; + span.append(span2); + div.append(span); + //max + var span = document.createElement("span"); + span.classList.add("model_setting_maxlabel"); + var span2 = document.createElement("span"); + span2.style="top: -4px; position: relative;"; + span2.textContent = data.layer_count; + span.append(span2); + div.append(span); + } model_layer_bars.append(div); @@ -738,11 +824,49 @@ function update_gpu_layers() { } function load_model() { - message = {'cmd': 'load_model', 'use_gpu': $('#use_gpu')[0].checked, - 'key': $('#modelkey')[0].value, 'gpu_layers': gpu_layers.slice(0, -1), - 'disk_layers': disk_layers, 'url': $('#modelurl')[0].value, - 'online_model': $('#oaimodel')[0].value}; + var accept = document.getElementById('btn_loadmodelaccept'); + gpu_layers = [] + for (let i=0; i < document.getElementById("gpu_count").value; i++) { + gpu_layers.push(document.getElementById("gpu_layers_"+i).value); + } + if (document.getElementById("disk_layers")) { + disk_layers = document.getElementById("disk_layers").value; + } else { + disk_layers = "0"; + } + //Need to do different stuff with custom models + if ((accept.getAttribute('menu') == 'GPT2Custom') || (accept.getAttribute('menu') == 'NeoCustom')) { + var model = document.getElementById("btn_loadmodelaccept").getAttribute("menu"); + var path = document.getElementById("btn_loadmodelaccept").getAttribute("display_name"); + } else { + var model = document.getElementById("btn_loadmodelaccept").getAttribute("selected_model"); + var path = ""; + } + + message = {'model': model, 'path': path, 'use_gpu': document.getElementById("use_gpu").checked, + 'key': document.getElementById('modelkey').value, 'gpu_layers': gpu_layers.join(), + 'disk_layers': disk_layers, 'url': document.getElementById("modelurl").value, + 'online_model': document.getElementById("oaimodel").value}; + console.log(message); + socket.emit("load_model", message); + document.getElementById("loadmodelcontainer").classList.add("hidden"); } + + +//--------------------------------------------UI to Server Functions---------------------------------- + + +function upload_file(file_box) { + var fileList = file_box.files; + for (file of fileList) { + reader = new FileReader(); + reader.onload = function (event) { + socket.emit("upload_file", {'filename': file.name, "data": event.target.result}); + }; + reader.readAsArrayBuffer(file); + } +} + //--------------------------------------------General UI Functions------------------------------------ String.prototype.toHHMMSS = function () { var sec_num = parseInt(this, 10); // don't forget the second param diff --git a/templates/index_new.html b/templates/index_new.html index 44e36106..03e3148b 100644 --- a/templates/index_new.html +++ b/templates/index_new.html @@ -69,7 +69,11 @@ -