Hansimov commited on
Commit
7dd081a
1 Parent(s): bdfe063

:gem: [Feature] Auto scroll when content updated; disable scroll if user wheel or touch move; restore scroll if user click scroll-to-bottom button

Browse files
apps/llm_mixer/index.html CHANGED
@@ -78,6 +78,12 @@
78
  title="Temperature"
79
  ></select>
80
  </div>
 
 
 
 
 
 
81
  </div>
82
  <div class="mt-2 row no-gutters">
83
  <div class="col-auto pl-3 pr-0">
 
78
  title="Temperature"
79
  ></select>
80
  </div>
81
+ <div class="col"></div>
82
+ <div class="col-auto pr-0">
83
+ <button id="scroll-to-bottom-button" class="btn px-0">
84
+ <i class="fa fa-angles-down"></i>
85
+ </button>
86
+ </div>
87
  </div>
88
  <div class="mt-2 row no-gutters">
89
  <div class="col-auto pl-3 pr-0">
apps/llm_mixer/js/buttons_binder.js CHANGED
@@ -1,10 +1,11 @@
1
  import { ChatCompletionsRequester } from "./llm_requester.js";
2
  import {
3
- pop_messager,
4
  stop_latest_message_animation,
5
  start_latest_message_animation,
6
  create_new_chat_session,
7
  get_latest_message_content_displayer,
 
 
8
  } from "./chat_operator.js";
9
 
10
  export function bind_chat_buttons() {
@@ -18,6 +19,11 @@ export function bind_chat_buttons() {
18
  openai_api_key_binder.bind();
19
  let show_endpoint_and_key_binder = new ShowEndpointAndKeyButtonBinder();
20
  show_endpoint_and_key_binder.bind();
 
 
 
 
 
21
  }
22
 
23
  class SendUserInputButtonBinder {
@@ -87,6 +93,7 @@ class SendUserInputButtonBinder {
87
  .addClass("icon-success");
88
  hljs.highlightAll();
89
  console.log(get_latest_message_content_displayer().data("raw_content"));
 
90
  }
91
  }
92
 
@@ -162,3 +169,26 @@ class ShowEndpointAndKeyButtonBinder {
162
  });
163
  }
164
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import { ChatCompletionsRequester } from "./llm_requester.js";
2
  import {
 
3
  stop_latest_message_animation,
4
  start_latest_message_animation,
5
  create_new_chat_session,
6
  get_latest_message_content_displayer,
7
+ scroll_to_bottom,
8
+ set_user_scroll_status,
9
  } from "./chat_operator.js";
10
 
11
  export function bind_chat_buttons() {
 
19
  openai_api_key_binder.bind();
20
  let show_endpoint_and_key_binder = new ShowEndpointAndKeyButtonBinder();
21
  show_endpoint_and_key_binder.bind();
22
+ let scroll_to_bottom_binder = new ScrollToBottomButtonBinder();
23
+ scroll_to_bottom_binder.bind();
24
+ let chat_session_container_scroll_binder =
25
+ new ChatSessionContainerScrollBinder();
26
+ chat_session_container_scroll_binder.bind();
27
  }
28
 
29
  class SendUserInputButtonBinder {
 
93
  .addClass("icon-success");
94
  hljs.highlightAll();
95
  console.log(get_latest_message_content_displayer().data("raw_content"));
96
+ set_user_scroll_status(false);
97
  }
98
  }
99
 
 
169
  });
170
  }
171
  }
172
+
173
+ class ScrollToBottomButtonBinder {
174
+ constructor() {}
175
+ bind() {
176
+ const button = $("#scroll-to-bottom-button");
177
+ button.attr("title", "Scroll to bottom");
178
+ button.click(() => {
179
+ set_user_scroll_status(false);
180
+ scroll_to_bottom(true);
181
+ });
182
+ }
183
+ }
184
+
185
+ class ChatSessionContainerScrollBinder {
186
+ constructor() {}
187
+ bind() {
188
+ $("#chat-session-container").on("wheel touchmove", function () {
189
+ if ($("#send-user-input").attr("status") === "stop") {
190
+ set_user_scroll_status(true);
191
+ }
192
+ });
193
+ }
194
+ }
apps/llm_mixer/js/chat_operator.js CHANGED
@@ -10,6 +10,32 @@ let chat_history = [messager_list];
10
  let md_to_html_converter = new showdown.Converter();
11
  md_to_html_converter.setFlavor("github");
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  export function get_active_messager_list() {
14
  return chat_history[chat_history.length - 1];
15
  }
@@ -32,6 +58,7 @@ export function create_messager(
32
  };
33
  let messager = new Messager(message);
34
  get_active_messager_list().push(messager);
 
35
  }
36
 
37
  export function get_selected_llm_model() {
@@ -111,6 +138,7 @@ export function update_message(json_chunks, content_displayer = null) {
111
  content_displayer
112
  .find("table")
113
  .addClass("table table-bordered table-hover");
 
114
  }
115
  if (finish_reason === "stop") {
116
  console.log("[STOP]");
 
10
  let md_to_html_converter = new showdown.Converter();
11
  md_to_html_converter.setFlavor("github");
12
 
13
+ let is_user_scrolling = false;
14
+
15
+ export function set_user_scroll_status(val = true) {
16
+ is_user_scrolling = val;
17
+ }
18
+
19
+ export function scroll_to_bottom(animate = false) {
20
+ if (is_user_scrolling) {
21
+ return;
22
+ }
23
+ console.log("scroll_to_bottom");
24
+ if (animate) {
25
+ $("#chat-session-container").animate(
26
+ {
27
+ scrollTop: $("#chat-session-container").prop("scrollHeight"),
28
+ },
29
+ 500
30
+ );
31
+ } else {
32
+ $("#chat-session-container").prop(
33
+ "scrollTop",
34
+ $("#chat-session-container").prop("scrollHeight")
35
+ );
36
+ }
37
+ }
38
+
39
  export function get_active_messager_list() {
40
  return chat_history[chat_history.length - 1];
41
  }
 
58
  };
59
  let messager = new Messager(message);
60
  get_active_messager_list().push(messager);
61
+ scroll_to_bottom();
62
  }
63
 
64
  export function get_selected_llm_model() {
 
138
  content_displayer
139
  .find("table")
140
  .addClass("table table-bordered table-hover");
141
+ scroll_to_bottom();
142
  }
143
  if (finish_reason === "stop") {
144
  console.log("[STOP]");
apps/llm_mixer/js/default.css CHANGED
@@ -35,7 +35,7 @@
35
  }
36
 
37
  #available-models-select {
38
- max-width: calc(100vw - 150px);
39
  }
40
 
41
  #temperature-select {
 
35
  }
36
 
37
  #available-models-select {
38
+ max-width: calc(100vw - 200px);
39
  }
40
 
41
  #temperature-select {
apps/llm_mixer/js/main.js CHANGED
@@ -1,7 +1,6 @@
1
  import {
2
  setup_available_models_on_select,
3
  setup_temperature_on_select,
4
- setup_endpoint_and_key,
5
  } from "./llm_models_loader.js";
6
  import { bind_chat_buttons } from "./buttons_binder.js";
7
  var user_input_history = [];
 
1
  import {
2
  setup_available_models_on_select,
3
  setup_temperature_on_select,
 
4
  } from "./llm_models_loader.js";
5
  import { bind_chat_buttons } from "./buttons_binder.js";
6
  var user_input_history = [];