Spaces:
Running
Running
Update application/static/js/components/uiManager.js
Browse files
application/static/js/components/uiManager.js
CHANGED
@@ -1,109 +1,202 @@
|
|
1 |
-
import Initialize from "./initialize.js";
|
2 |
-
import Chat from "./chat.js";
|
3 |
-
import RenderSymbols from "./renderSymbols.js";
|
4 |
-
class UIManager{
|
5 |
-
constructor(){
|
6 |
-
this.initializer = new Initialize(this);
|
7 |
-
this.chat = new Chat(this);
|
8 |
-
this.renderSymbols = new RenderSymbols();
|
9 |
-
this.menu = document.getElementById('menu');
|
10 |
-
this.hamburger = document.getElementById('hamburger');
|
11 |
-
this.messagesDiv = document.getElementById('messages');
|
12 |
-
this.container = document.getElementById('container')
|
13 |
-
this.prevChatsCont = document.getElementById('prevChatsCont');
|
14 |
-
this.textBox = document.getElementById('textBox');
|
15 |
-
this.sendBtn = document.getElementById('sendBtn');
|
16 |
-
this.newChat = document.getElementById('newChat');
|
17 |
-
this.models = document.getElementById('models');
|
18 |
-
this.initialized = false;
|
19 |
-
this.webSearchBtn = document.getElementById('webSearch');
|
20 |
-
this.webSearch = false;
|
21 |
-
this.aiDiv;
|
22 |
-
this.userDiv;
|
23 |
-
this.aiP;
|
24 |
-
this.userP;
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
this.
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
this.
|
66 |
-
|
67 |
-
this.
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
this.
|
72 |
-
this.
|
73 |
-
|
74 |
-
|
75 |
-
this.
|
76 |
-
this.
|
77 |
-
this.
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
this.
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
109 |
export default UIManager
|
|
|
1 |
+
import Initialize from "./initialize.js";
|
2 |
+
import Chat from "./chat.js";
|
3 |
+
import RenderSymbols from "./renderSymbols.js";
|
4 |
+
class UIManager{
|
5 |
+
constructor(){
|
6 |
+
this.initializer = new Initialize(this);
|
7 |
+
this.chat = new Chat(this);
|
8 |
+
this.renderSymbols = new RenderSymbols();
|
9 |
+
this.menu = document.getElementById('menu');
|
10 |
+
this.hamburger = document.getElementById('hamburger');
|
11 |
+
this.messagesDiv = document.getElementById('messages');
|
12 |
+
this.container = document.getElementById('container')
|
13 |
+
this.prevChatsCont = document.getElementById('prevChatsCont');
|
14 |
+
this.textBox = document.getElementById('textBox');
|
15 |
+
this.sendBtn = document.getElementById('sendBtn');
|
16 |
+
this.newChat = document.getElementById('newChat');
|
17 |
+
this.models = document.getElementById('models');
|
18 |
+
this.initialized = false;
|
19 |
+
this.webSearchBtn = document.getElementById('webSearch');
|
20 |
+
this.webSearch = false;
|
21 |
+
this.aiDiv;
|
22 |
+
this.userDiv;
|
23 |
+
this.aiP;
|
24 |
+
this.userP;
|
25 |
+
this.imageMode = false;
|
26 |
+
this.dialog = null;
|
27 |
+
}
|
28 |
+
async run(){
|
29 |
+
await this.initializer.initialize();
|
30 |
+
this.handleTextBoxHeight();
|
31 |
+
this.events();
|
32 |
+
}
|
33 |
+
events(){
|
34 |
+
this.sendBtn.addEventListener('click',()=>{
|
35 |
+
this.send();
|
36 |
+
})
|
37 |
+
window.addEventListener('keydown',(e)=>{
|
38 |
+
if (e.key === '/' && document.activeElement === this.textBox) {
|
39 |
+
e.preventDefault();
|
40 |
+
this.showDialog();
|
41 |
+
}
|
42 |
+
|
43 |
+
if(e.key=='Enter' && !this.sendBtn.disabled){
|
44 |
+
this.send();
|
45 |
+
}
|
46 |
+
})
|
47 |
+
this.newChat.addEventListener('click', async ()=>{
|
48 |
+
await this.initializer.initialize();
|
49 |
+
})
|
50 |
+
this.webSearchBtn.addEventListener('click', ()=>{
|
51 |
+
if(this.webSearch){
|
52 |
+
this.webSearchBtn.style.color = 'white';
|
53 |
+
} else{
|
54 |
+
this.webSearchBtn.style.color = 'rgba(30,30,250,0.8)';
|
55 |
+
}
|
56 |
+
this.webSearch = !this.webSearch;
|
57 |
+
|
58 |
+
})
|
59 |
+
document.getElementById('closeAlert').onclick = ()=>{
|
60 |
+
document.getElementById('alert').style.display = 'none'
|
61 |
+
}
|
62 |
+
}
|
63 |
+
|
64 |
+
showDialog() {
|
65 |
+
if (this.dialog) {
|
66 |
+
this.dialog.remove();
|
67 |
+
this.dialog = null;
|
68 |
+
return;
|
69 |
+
}
|
70 |
+
this.dialog = document.createElement('div');
|
71 |
+
this.dialog.style.position = 'absolute';
|
72 |
+
this.dialog.style.top = `${this.textBox.offsetTop - 100}px`;
|
73 |
+
this.dialog.style.left = `${this.textBox.offsetLeft}px`;
|
74 |
+
this.dialog.style.backgroundColor = 'white';
|
75 |
+
this.dialog.style.border = '1px solid black';
|
76 |
+
this.dialog.style.padding = '10px';
|
77 |
+
this.dialog.style.zIndex = '1000';
|
78 |
+
this.dialog.innerHTML = `
|
79 |
+
<button id="dialogImage">Image</button>
|
80 |
+
<button id="dialogSearch">Search</button>
|
81 |
+
`;
|
82 |
+
document.body.appendChild(this.dialog);
|
83 |
+
|
84 |
+
document.getElementById('dialogImage').addEventListener('click', () => {
|
85 |
+
this.imageMode = true;
|
86 |
+
this.textBox.value = "/image ";
|
87 |
+
this.dialog.remove();
|
88 |
+
this.dialog = null;
|
89 |
+
|
90 |
+
});
|
91 |
+
|
92 |
+
document.getElementById('dialogSearch').addEventListener('click', () => {
|
93 |
+
this.webSearch = true;
|
94 |
+
this.webSearchBtn.style.color = 'rgba(30,30,250,0.8)';
|
95 |
+
this.textBox.value = "/search ";
|
96 |
+
this.dialog.remove();
|
97 |
+
this.dialog = null;
|
98 |
+
});
|
99 |
+
}
|
100 |
+
|
101 |
+
|
102 |
+
|
103 |
+
async send(){
|
104 |
+
let promptText = this.textBox.value;
|
105 |
+
let imageBase64 = null;
|
106 |
+
|
107 |
+
if (this.imageMode) {
|
108 |
+
const file = await this.getImageFile();
|
109 |
+
if (file) {
|
110 |
+
imageBase64 = await this.getBase64(file);
|
111 |
+
}
|
112 |
+
promptText = promptText.replace(/^\/image\s*/, '');
|
113 |
+
this.imageMode = false;
|
114 |
+
}
|
115 |
+
|
116 |
+
this.appendUserMsg(promptText, imageBase64);
|
117 |
+
this.appendAiMsg();
|
118 |
+
|
119 |
+
|
120 |
+
await this.chat.chat();
|
121 |
+
}
|
122 |
+
|
123 |
+
|
124 |
+
async getImageFile() {
|
125 |
+
return new Promise(resolve => {
|
126 |
+
const input = document.createElement('input');
|
127 |
+
input.type = 'file';
|
128 |
+
input.accept = 'image/*';
|
129 |
+
input.onchange = e => {
|
130 |
+
const file = e.target.files[0];
|
131 |
+
resolve(file);
|
132 |
+
};
|
133 |
+
input.click();
|
134 |
+
});
|
135 |
+
}
|
136 |
+
|
137 |
+
async getBase64(file) {
|
138 |
+
return new Promise((resolve, reject) => {
|
139 |
+
const reader = new FileReader();
|
140 |
+
reader.readAsDataURL(file);
|
141 |
+
reader.onload = () => resolve(reader.result);
|
142 |
+
reader.onerror = error => reject(error);
|
143 |
+
});
|
144 |
+
}
|
145 |
+
|
146 |
+
|
147 |
+
appendUserMsg(msg=false, imageBase64 = null){
|
148 |
+
this.userDiv = document.createElement('div');
|
149 |
+
this.userDiv.className = 'user';
|
150 |
+
this.userP = document.createElement('p');
|
151 |
+
if(msg){
|
152 |
+
this.userP.innerText = msg;
|
153 |
+
} else{
|
154 |
+
this.userP.innerText = this.textBox.value;
|
155 |
+
}
|
156 |
+
|
157 |
+
if (imageBase64) {
|
158 |
+
const img = document.createElement('img');
|
159 |
+
img.src = imageBase64;
|
160 |
+
img.style.maxWidth = '100%';
|
161 |
+
img.style.height = 'auto';
|
162 |
+
this.userDiv.appendChild(img);
|
163 |
+
}
|
164 |
+
|
165 |
+
this.userDiv.appendChild(this.userP);
|
166 |
+
this.messagesDiv.appendChild(this.userDiv);
|
167 |
+
}
|
168 |
+
appendAiMsg(msg=false){
|
169 |
+
this.aiDiv = document.createElement('div');
|
170 |
+
this.aiDiv.className = 'ai';
|
171 |
+
this.aiP = document.createElement('p');
|
172 |
+
if(msg){
|
173 |
+
this.aiP.innerText=msg;
|
174 |
+
}
|
175 |
+
this.aiDiv.appendChild(this.aiP);
|
176 |
+
this.messagesDiv.appendChild(this.aiDiv);
|
177 |
+
}
|
178 |
+
handleTextBoxHeight() {
|
179 |
+
this.textBox.oninput = () => {
|
180 |
+
this.textBox.style.height = 'auto';
|
181 |
+
if (this.textBox.scrollHeight <= 150) {
|
182 |
+
if(this.textBox.scrollHeight>60){
|
183 |
+
this.textBox.style.height = `${this.textBox.scrollHeight}px`;
|
184 |
+
}
|
185 |
+
} else {
|
186 |
+
this.textBox.style.height = '150px';
|
187 |
+
}
|
188 |
+
};
|
189 |
+
}
|
190 |
+
addChat(){
|
191 |
+
const prevChat = document.createElement('div');
|
192 |
+
prevChat.innerText = this.initializer.convTitle;
|
193 |
+
prevChat.className = 'prevChat';
|
194 |
+
prevChat.id = this.initializer.convId;
|
195 |
+
this.prevChatsCont.prepend(prevChat);
|
196 |
+
prevChat.style.backgroundColor = 'rgb(53, 53, 53)';
|
197 |
+
prevChat.addEventListener('click', ()=>{
|
198 |
+
this.initializer.reInitialize(prevChat.id);
|
199 |
+
})
|
200 |
+
}
|
201 |
+
}
|
202 |
export default UIManager
|