File size: 7,832 Bytes
6e6dab9
ac03bb3
 
 
af38c19
d1f0f2d
7dd081a
 
ac03bb3
6e6dab9
af38c19
bc9cd50
 
 
 
 
 
 
 
9136fd8
 
7dd081a
 
 
 
 
f12b690
 
af8a4b7
 
af38c19
 
 
6e6dab9
 
 
af38c19
6e6dab9
ac03bb3
6e6dab9
6ed2c8f
 
 
 
4a1d039
 
 
 
 
6ed2c8f
077080c
6e6dab9
 
 
6ed2c8f
077080c
 
 
 
4a1d039
 
077080c
4a1d039
077080c
6ed2c8f
 
 
 
 
077080c
6e6dab9
451c088
 
 
ed18d7d
 
6e6dab9
 
077080c
 
 
4a1d039
ac03bb3
c98264e
077080c
ac03bb3
077080c
 
 
4a1d039
077080c
ac03bb3
 
4a1d039
 
 
c5c7ecf
1be3dd1
d1f0f2d
7dd081a
077080c
af38c19
 
 
 
6e6dab9
af38c19
 
 
 
 
6e6dab9
 
bc9cd50
 
 
 
 
9136fd8
bc9cd50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9136fd8
bc9cd50
 
 
 
 
 
 
 
 
 
 
9136fd8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7dd081a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f12b690
 
 
 
 
 
 
ebbfc38
 
 
 
 
 
f12b690
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import { ChatCompletionsRequester } from "./llm_requester.js";
import {
    stop_latest_message_animation,
    start_latest_message_animation,
    create_new_chat_session,
    get_latest_message_content_displayer,
    scroll_to_bottom,
    set_user_scroll_status,
} from "./chat_operator.js";

export function bind_chat_buttons() {
    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 chat_session_container_scroll_binder =
        new ChatSessionContainerScrollBinder();
    chat_session_container_scroll_binder.bind();
    let screenshot_button_binder = new ScreenshotButtonBinder();
    screenshot_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 post_user_input() {
        let user_input_content = $("#user-input").val();
        console.log(user_input_content);
        this.requester = new ChatCompletionsRequester(user_input_content);
        this.requester.create_messager_components();
        start_latest_message_animation();
        await this.requester.post();
    }

    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 stop(button) {
        console.log("Stop");
        let button_icon = button.find("i");
        this.requester.stop();
        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"));
        set_user_scroll_status(false);
    }
}

class NewChatButtonBinder {
    constructor() {}
    bind() {
        const button = $("#new-chat-session");
        button.attr("status", "new").attr("title", "New Chat");
        button.click(() => {
            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);
            console.log(`GET OpenAI Endpoint: ${stored_openai_endpoint}`);
        }
        button.click(() => {
            console.log($("#openai-endpoint").val());
            localStorage.setItem(
                "openai_endpoint",
                $("#openai-endpoint").val()
            );
        });
    }
}

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(`GET 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(() => {
            set_user_scroll_status(false);
            scroll_to_bottom(true);
        });
    }
}

class ChatSessionContainerScrollBinder {
    constructor() {}
    bind() {
        $("#chat-session-container").on("wheel touchmove", function () {
            if ($("#send-user-input").attr("status") === "stop") {
                set_user_scroll_status(true);
            }
        });
    }
}

class ScreenshotButtonBinder {
    constructor() {}
    bind() {
        const button = $("#screenshot-button");
        button.attr("title", "Take screenshot for whole chat");
        button.click(() => {
            let screenshot_padding = 10;
            html2canvas($("#messagers-container")[0], {
                x: -screenshot_padding,
                width:
                    $("#messagers-container").width() + 2 * screenshot_padding,
            }).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 AvailableModelsSelectBinder {
    constructor() {}
    bind() {
        const select = $("#available-models-select");
        select.change(() => {
            console.log(select.val());
            localStorage.setItem("default_model", select.val());
        });
    }
}