File size: 10,083 Bytes
f5223c1
ac03bb3
 
 
af38c19
d1f0f2d
2ced09a
 
3a17e83
120437c
6e6dab9
4e6658c
b30bb95
541cc7d
897b3f0
e950717
897b3f0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e950717
 
 
22b469d
 
 
897b3f0
 
 
af38c19
 
 
6e6dab9
 
 
af38c19
6e6dab9
ac03bb3
6e6dab9
6ed2c8f
 
 
 
4a1d039
 
 
 
 
6ed2c8f
077080c
6e6dab9
 
 
6ed2c8f
077080c
 
 
 
4a1d039
 
077080c
4a1d039
077080c
6ed2c8f
 
 
 
 
077080c
011422d
 
 
 
 
 
 
 
 
6e6dab9
451c088
 
2ced09a
 
 
 
 
 
 
 
 
6e6dab9
077080c
 
011422d
4a1d039
ac03bb3
 
4a1d039
 
 
c5c7ecf
1be3dd1
d1f0f2d
541cc7d
077080c
af38c19
 
 
e950717
6e6dab9
af38c19
 
 
b30bb95
af38c19
 
6e6dab9
 
bc9cd50
 
e950717
bc9cd50
 
9136fd8
bc9cd50
 
 
120437c
76d4a74
bc9cd50
 
 
 
 
 
 
120437c
bc9cd50
 
 
 
 
e950717
bc9cd50
 
9136fd8
bc9cd50
 
 
76d4a74
bc9cd50
 
 
 
 
 
 
9136fd8
 
e950717
9136fd8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7dd081a
 
e950717
7dd081a
 
 
 
541cc7d
 
7dd081a
 
 
 
f12b690
e950717
f12b690
 
 
 
f8ad7ae
1f718de
 
f8ad7ae
10e33e0
ebbfc38
f8ad7ae
ebbfc38
f8ad7ae
 
10e33e0
 
ebbfc38
f12b690
 
 
 
 
 
 
 
 
 
 
 
 
 
 
af8a4b7
e950717
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22b469d
 
 
 
 
 
 
 
 
 
 
af8a4b7
e950717
af8a4b7
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
import { ChatCompletionsRequester } from "../networks/llm_requester.js";
import {
    stop_latest_message_animation,
    start_latest_message_animation,
    create_new_chat_session,
    get_latest_message_content_displayer,
    get_selected_llm_model,
    create_messager,
} from "./chat_operator.js";
import { setup_available_models_on_select } from "./llm_models_loader.js";

import { screen_scroller } from "./screen_scroller.js";
import { chat_history_storer } from "../networks/chat_history_storer.js";

export class ButtonsBinder {
    constructor() { }
    bind() {
        let send_user_input_binder = new SendUserInputButtonBinder();
        send_user_input_binder.bind();
        let new_chat_binder = new NewChatButtonBinder();
        new_chat_binder.bind();
        let openai_endpoint_binder = new OpenaiEndpointButtonBinder();
        openai_endpoint_binder.bind();
        let openai_api_key_binder = new OpenaiAPIKeyButtonBinder();
        openai_api_key_binder.bind();
        let show_endpoint_and_key_binder = new ShowEndpointAndKeyButtonBinder();
        show_endpoint_and_key_binder.bind();
        let scroll_to_bottom_binder = new ScrollToBottomButtonBinder();
        scroll_to_bottom_binder.bind();
        let screenshot_button_binder = new ScreenshotButtonBinder();
        screenshot_button_binder.bind();
        let chat_history_sidebar_toggle_button_binder =
            new ChatHistorySidebarToggleButtonBinder();
        chat_history_sidebar_toggle_button_binder.bind();
        let clear_chat_history_button_binder =
            new ClearChatHistoryButtonBinder();
        clear_chat_history_button_binder.bind();
        let available_models_select_binder = new AvailableModelsSelectBinder();
        available_models_select_binder.bind();
    }
}

class SendUserInputButtonBinder {
    constructor() {
        this.requester = null;
    }
    bind() {
        const button = $("#send-user-input");
        button.attr("status", "send").attr("title", "Send");
        button.click(async () => {
            await this.handle_user_input(button);
        });

        $("#user-input").keypress(async (event) => {
            if (
                event.key === "Enter" &&
                !event.shiftKey &&
                button.attr("status") === "send"
            ) {
                event.preventDefault();
                await this.send(button);
            }
        });
    }
    async handle_user_input(button) {
        let user_input_content = $("#user-input").val();
        if (user_input_content === "") {
            return;
        }
        let status = button.attr("status");
        if (status === "send") {
            this.send(button);
        } else if (status === "stop") {
            this.stop(button);
            return;
        } else {
            console.log("No action");
        }
    }

    async send(button) {
        // console.log("Send");
        let button_icon = button.find("i");
        button.attr("status", "stop").attr("title", "Stop");
        button_icon.removeClass().addClass("fa fa-circle-pause fa-fade-fast");
        await this.post_user_input();
        await this.stop(button);
    }

    async post_user_input() {
        let user_input_content = $("#user-input").val();
        console.log(user_input_content);
        if (get_selected_llm_model() == "notes") {
            create_messager("user", user_input_content);
        } else {
            this.requester = new ChatCompletionsRequester(user_input_content);
            this.requester.create_messager_components();
            start_latest_message_animation();
            await this.requester.post();
            this.requester.stop();
        }
    }

    async stop(button) {
        // console.log("Stop");
        let button_icon = button.find("i");
        stop_latest_message_animation();
        button.attr("status", "send").attr("title", "Send");
        button_icon
            .removeClass()
            .addClass("fa fa-paper-plane")
            .addClass("icon-success");
        hljs.highlightAll();
        console.log(get_latest_message_content_displayer().data("raw_content"));
        screen_scroller.set_user_scrolling(false);
    }
}

class NewChatButtonBinder {
    constructor() { }
    bind() {
        const button = $("#new-chat-session");
        button.attr("status", "new").attr("title", "New Chat");
        button.click(() => {
            chat_history_storer.save_current_chat_session();
            create_new_chat_session();
        });
    }
}

class OpenaiEndpointButtonBinder {
    constructor() { }
    bind() {
        const button = $("#openai-endpoint-button");
        button.attr("title", "Submit Endpoint");
        const stored_openai_endpoint = localStorage.getItem("openai_endpoint");
        if (stored_openai_endpoint) {
            $("#openai-endpoint").val(stored_openai_endpoint);
            setup_available_models_on_select();
            console.log(`openai_endpoint: ${stored_openai_endpoint}`);
        }
        button.click(() => {
            console.log($("#openai-endpoint").val());
            localStorage.setItem(
                "openai_endpoint",
                $("#openai-endpoint").val()
            );
            setup_available_models_on_select();
        });
    }
}

class OpenaiAPIKeyButtonBinder {
    constructor() { }
    bind() {
        const button = $("#openai-api-key-button");
        button.attr("title", "Submit API Key");
        const stored_openai_api_key = localStorage.getItem("openai_api_key");
        if (stored_openai_api_key) {
            $("#openai-api-key").val(stored_openai_api_key);
            console.log(`openai_api_key: ${stored_openai_api_key}`);
        }
        button.click(() => {
            console.log($("#openai-api-key").val());
            localStorage.setItem("openai_api_key", $("#openai-api-key").val());
        });
    }
}

class ShowEndpointAndKeyButtonBinder {
    constructor() { }
    bind() {
        const button = $("#show-endpoint-and-key-button");
        button.attr("title", "Show endpoint and api key");

        if (localStorage.getItem("openai_endpoint")) {
            $("#openai-endpoint").parent().hide();
            $("#openai-endpoint-button").parent().hide();
        }

        if (localStorage.getItem("openai_api_key")) {
            $("#openai-api-key").parent().hide();
            $("#openai-api-key-button").parent().hide();
        }

        button.click(() => {
            $("#openai-endpoint").parent().toggle();
            $("#openai-endpoint-button").parent().toggle();
            $("#openai-api-key").parent().toggle();
            $("#openai-api-key-button").parent().toggle();
        });
    }
}

class ScrollToBottomButtonBinder {
    constructor() { }
    bind() {
        const button = $("#scroll-to-bottom-button");
        button.attr("title", "Scroll to bottom");
        button.click(() => {
            screen_scroller.set_user_scrolling(false);
            screen_scroller.scroll_to_bottom(true);
        });
    }
}

class ScreenshotButtonBinder {
    constructor() { }
    bind() {
        const button = $("#screenshot-button");
        button.attr("title", "Take screenshot for whole chat");
        button.click(() => {
            let screenshot_padding = 20;
            // default padding is 0.75em (12px)
            // p-1 (4px)(0.25em); p-2 (8px)(0.5em); p-3 (16px)(1em);
            let container_padding = 12;
            let right_offset = 20;
            html2canvas($("#messagers-container")[0], {
                x: -(container_padding + screenshot_padding),
                width:
                    $("#messagers-container").width() +
                    container_padding * 2 +
                    screenshot_padding * 2 +
                    right_offset,
            }).then((canvas) => {
                var link = document.createElement("a");
                let date = new Date();
                let date_string = date.toISOString().split("T")[0];
                let time_string = date
                    .toTimeString()
                    .split(" ")[0]
                    .replace(/:/g, "-");
                let datetime_string = `${date_string}_${time_string}`;
                link.download = `chat_${datetime_string}.png`;
                link.href = canvas.toDataURL("image/png");
                link.click();
            });
        });
    }
}

class ChatHistorySidebarToggleButtonBinder {
    constructor() { }
    get_show_sidebar_storage() {
        return localStorage.getItem("show_chat_history_sidebar");
    }
    bind() {
        const sidebar = $("#chat-history-sidebar");

        // this line is not to check value as false,
        // but to check item not existed in localStorage
        if (!this.get_show_sidebar_storage()) {
            localStorage.setItem("show_chat_history_sidebar", "true");
        }
        if (this.get_show_sidebar_storage() === "true") {
            sidebar.addClass("show");
        }

        const toggle_button = $("#chat-history-sidebar-toggle-button");
        toggle_button.click(() => {
            sidebar.toggleClass("show");
            localStorage.setItem(
                "show_chat_history_sidebar", sidebar.hasClass("show").toString()
            );
        });

        const close_button = $("#chat-history-sidebar-close-button");
        close_button.click(() => {
            sidebar.removeClass("show");
            localStorage.setItem("show_chat_history_sidebar", "false");
        });
    }
}

class ClearChatHistoryButtonBinder {
    constructor() { }
    bind() {
        const button = $("#clear-chat-history-button");
        button.attr("title", "Clear chat history");
        button.click(() => {
            chat_history_storer.clear_database();
        });
    }
}

class AvailableModelsSelectBinder {
    constructor() { }
    bind() {
        const select = $("#available-models-select");
        select.change(() => {
            console.log(select.val());
            localStorage.setItem("default_model", select.val());
        });
    }
}