diff options
Diffstat (limited to '')
-rw-r--r-- | g4f/gui/client/js/chat.v1.js | 47 | ||||
-rw-r--r-- | g4f/gui/webview.py | 24 |
2 files changed, 55 insertions, 16 deletions
diff --git a/g4f/gui/client/js/chat.v1.js b/g4f/gui/client/js/chat.v1.js index 16b4acb9..d07597ea 100644 --- a/g4f/gui/client/js/chat.v1.js +++ b/g4f/gui/client/js/chat.v1.js @@ -27,6 +27,13 @@ messageInput.addEventListener("focus", () => { document.documentElement.scrollTop = document.documentElement.scrollHeight; }); +appStorage = window.localStorage || { + setItem: (key, value) => self[key] = value, + getItem: (key) => self[key], + removeItem: (key) => delete self[key], + length: 0 +} + const markdown_render = (content) => { return markdown.render(content .replaceAll(/<!--.+-->/gm, "") @@ -67,10 +74,10 @@ const register_remove_message = async () => { } const delete_conversations = async () => { - for (let i = 0; i < localStorage.length; i++){ - let key = localStorage.key(i); + for (let i = 0; i < appStorage.length; i++){ + let key = appStorage.key(i); if (key.startsWith("conversation:")) { - localStorage.removeItem(key); + appStorage.removeItem(key); } } hide_sidebar(); @@ -261,6 +268,7 @@ const ask_gpt = async () => { body: body }); const reader = response.body.pipeThrough(new TextDecoderStream()).getReader(); + let buffer = "" while (true) { const { value, done } = await reader.read(); if (done) break; @@ -268,7 +276,14 @@ const ask_gpt = async () => { if (!line) { continue; } - const message = JSON.parse(line); + let message; + try { + message = JSON.parse(buffer + line); + buffer = ""; + } catch { + buffer += line + continue; + } if (message.type == "content") { text += message.content; } else if (message.type == "provider") { @@ -389,7 +404,7 @@ const hide_option = async (conversation_id) => { }; const delete_conversation = async (conversation_id) => { - localStorage.removeItem(`conversation:${conversation_id}`); + appStorage.removeItem(`conversation:${conversation_id}`); const conversation = document.getElementById(`convo-${conversation_id}`); conversation.remove(); @@ -491,13 +506,13 @@ const load_conversation = async (conversation_id, scroll = true) => { async function get_conversation(conversation_id) { let conversation = await JSON.parse( - localStorage.getItem(`conversation:${conversation_id}`) + appStorage.getItem(`conversation:${conversation_id}`) ); return conversation; } async function save_conversation(conversation_id, conversation) { - localStorage.setItem( + appStorage.setItem( `conversation:${conversation_id}`, JSON.stringify(conversation) ); @@ -515,7 +530,7 @@ async function add_conversation(conversation_id, content) { title = content + ' '.repeat(19 - content.length) } - if (localStorage.getItem(`conversation:${conversation_id}`) == null) { + if (appStorage.getItem(`conversation:${conversation_id}`) == null) { await save_conversation(conversation_id, { id: conversation_id, title: title, @@ -577,9 +592,9 @@ const add_message = async (conversation_id, role, content, provider) => { const load_conversations = async () => { let conversations = []; - for (let i = 0; i < localStorage.length; i++) { - if (localStorage.key(i).startsWith("conversation:")) { - let conversation = localStorage.getItem(localStorage.key(i)); + for (let i = 0; i < appStorage.length; i++) { + if (appStorage.key(i).startsWith("conversation:")) { + let conversation = appStorage.getItem(appStorage.key(i)); conversations.push(JSON.parse(conversation)); } } @@ -657,10 +672,10 @@ const register_settings_localstorage = async () => { element.addEventListener('change', async (event) => { switch (event.target.type) { case "checkbox": - localStorage.setItem(id, event.target.checked); + appStorage.setItem(id, event.target.checked); break; case "select-one": - localStorage.setItem(id, event.target.selectedIndex); + appStorage.setItem(id, event.target.selectedIndex); break; default: console.warn("Unresolved element type"); @@ -672,7 +687,7 @@ const register_settings_localstorage = async () => { const load_settings_localstorage = async () => { for (id of ["switch", "model", "jailbreak", "patch", "provider", "history"]) { element = document.getElementById(id); - value = localStorage.getItem(element.id); + value = appStorage.getItem(element.id); if (value) { switch (element.type) { case "checkbox": @@ -712,12 +727,12 @@ const say_hello = async () => { // Theme storage for recurring viewers const storeTheme = function (theme) { - localStorage.setItem("theme", theme); + appStorage.setItem("theme", theme); }; // set theme when visitor returns const setTheme = function () { - const activeTheme = localStorage.getItem("theme"); + const activeTheme = appStorage.getItem("theme"); colorThemes.forEach((themeOption) => { if (themeOption.id === activeTheme) { themeOption.checked = true; diff --git a/g4f/gui/webview.py b/g4f/gui/webview.py new file mode 100644 index 00000000..5a4263dc --- /dev/null +++ b/g4f/gui/webview.py @@ -0,0 +1,24 @@ +import webview +from functools import partial +from platformdirs import user_config_dir + +from g4f.gui import run_gui +from g4f.gui.run import gui_parser +import g4f.version +import g4f.debug + +def run_webview(host: str = "0.0.0.0", port: int = 8080, debug: bool = True): + webview.create_window(f"g4f - {g4f.version.utils.current_version}", f"http://{host}:{port}/") + if debug: + g4f.debug.logging = True + webview.start( + partial(run_gui, host, port), + private_mode=False, + storage_path=user_config_dir("g4f-webview"), + debug=debug + ) + +if __name__ == "__main__": + parser = gui_parser() + args = parser.parse_args() + run_webview(args.host, args.port, args.debug)
\ No newline at end of file |