summaryrefslogtreecommitdiffstats
path: root/g4f/gui/client
diff options
context:
space:
mode:
Diffstat (limited to 'g4f/gui/client')
-rw-r--r--g4f/gui/client/css/style.css13
-rw-r--r--g4f/gui/client/html/index.html24
-rw-r--r--g4f/gui/client/js/chat.v1.js74
3 files changed, 86 insertions, 25 deletions
diff --git a/g4f/gui/client/css/style.css b/g4f/gui/client/css/style.css
index 2d4c9857..e77410ab 100644
--- a/g4f/gui/client/css/style.css
+++ b/g4f/gui/client/css/style.css
@@ -404,7 +404,7 @@ body {
display: none;
}
-#image {
+#image, #file {
display: none;
}
@@ -412,13 +412,22 @@ label[for="image"]:has(> input:valid){
color: var(--accent);
}
-label[for="image"] {
+label[for="file"]:has(> input:valid){
+ color: var(--accent);
+}
+
+label[for="image"], label[for="file"] {
cursor: pointer;
position: absolute;
top: 10px;
left: 10px;
}
+label[for="file"] {
+ top: 32px;
+ left: 10px;
+}
+
.buttons input[type="checkbox"] {
height: 0;
width: 0;
diff --git a/g4f/gui/client/html/index.html b/g4f/gui/client/html/index.html
index 3f2bb0c0..95489ba4 100644
--- a/g4f/gui/client/html/index.html
+++ b/g4f/gui/client/html/index.html
@@ -118,6 +118,10 @@
<input type="file" id="image" name="image" accept="image/png, image/gif, image/jpeg" required/>
<i class="fa-regular fa-image"></i>
</label>
+ <label for="file">
+ <input type="file" id="file" name="file" accept="text/plain, text/html, text/xml, application/json, text/javascript, .sh, .py, .php, .css, .yaml, .sql, .svg, .log, .csv, .twig, .md" required/>
+ <i class="fa-solid fa-paperclip"></i>
+ </label>
<div id="send-button">
<i class="fa-solid fa-paper-plane-top"></i>
</div>
@@ -125,7 +129,14 @@
</div>
<div class="buttons">
<div class="field">
- <select name="model" id="model"></select>
+ <select name="model" id="model">
+ <option value="">Model: Default</option>
+ <option value="gpt-4">gpt-4</option>
+ <option value="gpt-3.5-turbo">gpt-3.5-turbo</option>
+ <option value="llama2-70b">llama2-70b</option>
+ <option value="gemini-pro">gemini-pro</option>
+ <option value="">----</option>
+ </select>
</div>
<div class="field">
<select name="jailbreak" id="jailbreak" style="display: none;">
@@ -138,7 +149,16 @@
<option value="gpt-evil-1.0">evil 1.0</option>
</select>
<div class="field">
- <select name="provider" id="provider"></select>
+ <select name="provider" id="provider">
+ <option value="">Provider: Auto</option>
+ <option value="Bing">Bing</option>
+ <option value="OpenaiChat">OpenaiChat</option>
+ <option value="HuggingChat">HuggingChat</option>
+ <option value="Bard">Bard</option>
+ <option value="Liaobots">Liaobots</option>
+ <option value="Phind">Phind</option>
+ <option value="">----</option>
+ </select>
</div>
</div>
<div class="field">
diff --git a/g4f/gui/client/js/chat.v1.js b/g4f/gui/client/js/chat.v1.js
index ccc9461b..7ed9f183 100644
--- a/g4f/gui/client/js/chat.v1.js
+++ b/g4f/gui/client/js/chat.v1.js
@@ -7,7 +7,9 @@ const spinner = box_conversations.querySelector(".spinner");
const stop_generating = document.querySelector(`.stop_generating`);
const regenerate = document.querySelector(`.regenerate`);
const send_button = document.querySelector(`#send-button`);
-const imageInput = document.querySelector('#image') ;
+const imageInput = document.querySelector('#image');
+const fileInput = document.querySelector('#file');
+
let prompt_lock = false;
hljs.addPlugin(new CopyButtonPlugin());
@@ -42,6 +44,11 @@ const handle_ask = async () => {
if (message.length > 0) {
message_input.value = '';
await add_conversation(window.conversation_id, message);
+ if ("text" in fileInput.dataset) {
+ message += '\n```' + fileInput.dataset.type + '\n';
+ message += fileInput.dataset.text;
+ message += '\n```'
+ }
await add_message(window.conversation_id, "user", message);
window.token = message_id();
message_box.innerHTML += `
@@ -55,6 +62,9 @@ const handle_ask = async () => {
</div>
</div>
`;
+ document.querySelectorAll('code:not(.hljs').forEach((el) => {
+ hljs.highlightElement(el);
+ });
await ask_gpt();
}
};
@@ -171,17 +181,30 @@ const ask_gpt = async () => {
content_inner.innerHTML += "<p>An error occured, please try again, if the problem persists, please use a other model or provider.</p>";
} else {
html = markdown_render(text);
- html = html.substring(0, html.lastIndexOf('</p>')) + '<span id="cursor"></span></p>';
+ let lastElement, lastIndex = null;
+ for (element of ['</p>', '</code></pre>', '</li>\n</ol>']) {
+ const index = html.lastIndexOf(element)
+ if (index > lastIndex) {
+ lastElement = element;
+ lastIndex = index;
+ }
+ }
+ if (lastIndex) {
+ html = html.substring(0, lastIndex) + '<span id="cursor"></span>' + lastElement;
+ }
content_inner.innerHTML = html;
- document.querySelectorAll('code').forEach((el) => {
+ document.querySelectorAll('code:not(.hljs').forEach((el) => {
hljs.highlightElement(el);
});
}
window.scrollTo(0, 0);
- message_box.scrollTo({ top: message_box.scrollHeight, behavior: "auto" });
+ if (message_box.scrollTop >= message_box.scrollHeight - message_box.clientHeight - 100) {
+ message_box.scrollTo({ top: message_box.scrollHeight, behavior: "auto" });
+ }
}
if (!error && imageInput) imageInput.value = "";
+ if (!error && fileInput) fileInput.value = "";
} catch (e) {
console.error(e);
@@ -305,7 +328,7 @@ const load_conversation = async (conversation_id) => {
`;
}
- document.querySelectorAll(`code`).forEach((el) => {
+ document.querySelectorAll('code:not(.hljs').forEach((el) => {
hljs.highlightElement(el);
});
@@ -400,7 +423,7 @@ const load_conversations = async (limit, offset, loader) => {
`;
}
- document.querySelectorAll(`code`).forEach((el) => {
+ document.querySelectorAll('code:not(.hljs').forEach((el) => {
hljs.highlightElement(el);
});
};
@@ -602,14 +625,7 @@ observer.observe(message_input, { attributes: true });
(async () => {
response = await fetch('/backend-api/v2/models')
models = await response.json()
-
let select = document.getElementById('model');
- select.textContent = '';
-
- let auto = document.createElement('option');
- auto.value = '';
- auto.text = 'Model: Default';
- select.appendChild(auto);
for (model of models) {
let option = document.createElement('option');
@@ -619,14 +635,7 @@ observer.observe(message_input, { attributes: true });
response = await fetch('/backend-api/v2/providers')
providers = await response.json()
-
select = document.getElementById('provider');
- select.textContent = '';
-
- auto = document.createElement('option');
- auto.value = '';
- auto.text = 'Provider: Auto';
- select.appendChild(auto);
for (provider of providers) {
let option = document.createElement('option');
@@ -650,4 +659,27 @@ observer.observe(message_input, { attributes: true });
text += versions["version"];
}
document.getElementById("version_text").innerHTML = text
-})() \ No newline at end of file
+})()
+
+fileInput.addEventListener('change', async (event) => {
+ if (fileInput.files.length) {
+ type = fileInput.files[0].type;
+ if (type && type.indexOf('/')) {
+ type = type.split('/').pop().replace('x-', '')
+ type = type.replace('plain', 'plaintext')
+ .replace('shellscript', 'sh')
+ .replace('svg+xml', 'svg')
+ .replace('vnd.trolltech.linguist', 'ts')
+ } else {
+ type = fileInput.files[0].name.split('.').pop()
+ }
+ fileInput.dataset.type = type
+ const reader = new FileReader();
+ reader.addEventListener('load', (event) => {
+ fileInput.dataset.text = event.target.result;
+ });
+ reader.readAsText(fileInput.files[0]);
+ } else {
+ delete fileInput.dataset.text;
+ }
+}); \ No newline at end of file