CoolFace
Apppublic

sleepdeep/llm-deploy

sourceHugging Faceupdated 3y agoView on Hugging Face
0likes
main.js451 linesDownload Raw Back to js
1let main_parent = document.getElementById("chat-tab").parentNode;2let extensions = document.getElementById("extensions");3 4main_parent.childNodes[0].classList.add("header_bar");5main_parent.style = "padding: 0; margin: 0";6main_parent.parentNode.style = "gap: 0";7main_parent.parentNode.parentNode.style = "padding: 0";8 9document.querySelector(".header_bar").addEventListener("click", function(event) {10  if (event.target.tagName === "BUTTON") {11    const buttonText = event.target.textContent.trim();12 13    let chat_visible = (buttonText == "Chat");14    let default_visible = (buttonText == "Default");15    let notebook_visible = (buttonText == "Notebook");16 17    // Check if one of the generation tabs is visible18    if (chat_visible || notebook_visible || default_visible) {19      extensions && (extensions.style.display = "flex");20 21      if (chat_visible) {22        this.style.marginBottom = "0px";23        extensions && (extensions.style.maxWidth = "880px");24        extensions && (extensions.style.padding = "0px");25      } else {26        this.style.marginBottom = "19px";27        extensions && (extensions.style.maxWidth = "none");28        extensions && (extensions.style.padding = "15px");29      }30    } else {31      this.style.marginBottom = "19px";32      extensions && (extensions.style.display = "none");33    }34  }35});36 37//------------------------------------------------38// Keyboard shortcuts39//------------------------------------------------40let previousTabId = "chat-tab-button";41document.addEventListener("keydown", function(event) {42 43  // Stop generation on Esc pressed44  if (event.key === "Escape") {45    // Find the element with id 'stop' and click it46    var stopButton = document.getElementById("stop");47    if (stopButton) {48      stopButton.click();49    }50  }51 52  // Show chat controls on Ctrl + S53  else if (event.ctrlKey && event.key == "s") {54    event.preventDefault();55 56    var showControlsElement = document.getElementById("show-controls");57    if (showControlsElement && showControlsElement.childNodes.length >= 4) {58      showControlsElement.childNodes[3].click();59 60      var arr = document.getElementById("chat-input").childNodes[2].childNodes;61      arr[arr.length - 1].focus();62    }63  }64 65  // Regenerate on Ctrl + Enter66  else if (event.ctrlKey && event.key === "Enter") {67    event.preventDefault();68    document.getElementById("Regenerate").click();69  }70 71  // Continue on Alt + Enter72  else if (event.altKey && event.key === "Enter") {73    event.preventDefault();74    document.getElementById("Continue").click();75  }76 77  // Remove last on Ctrl + Shift + Backspace78  else if (event.ctrlKey && event.shiftKey && event.key === "Backspace") {79    event.preventDefault();80    document.getElementById("Remove-last").click();81  }82 83  // Copy last on Ctrl + Shift + K84  else if (event.ctrlKey && event.shiftKey && event.key === "K") {85    event.preventDefault();86    document.getElementById("Copy-last").click();87  }88 89  // Replace last on Ctrl + Shift + L90  else if (event.ctrlKey && event.shiftKey && event.key === "L") {91    event.preventDefault();92    document.getElementById("Replace-last").click();93  }94 95  // Impersonate on Ctrl + Shift + M96  else if (event.ctrlKey && event.shiftKey && event.key === "M") {97    event.preventDefault();98    document.getElementById("Impersonate").click();99  }100 101  // Switch between tabs on Tab102  else if (!event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey && event.key === "Tab") {103    event.preventDefault();104    var parametersButton = document.getElementById("parameters-button");105    var parentContainer = parametersButton.parentNode;106    var selectedChild = parentContainer.querySelector(".selected");107 108    if (selectedChild.id == "parameters-button") {109      document.getElementById(previousTabId).click();110    } else {111      previousTabId = selectedChild.id;112      parametersButton.click();113    }114  }115});116 117//------------------------------------------------118// Position the chat typing dots119//------------------------------------------------120typing = document.getElementById("typing-container");121typingParent = typing.parentNode;122typingSibling = typing.previousElementSibling;123typingSibling.insertBefore(typing, typingSibling.childNodes[2]);124 125//------------------------------------------------126// Chat scrolling127//------------------------------------------------128const targetElement = document.getElementById("chat").parentNode.parentNode.parentNode;129targetElement.classList.add("pretty_scrollbar");130targetElement.classList.add("chat-parent");131let isScrolled = false;132 133targetElement.addEventListener("scroll", function() {134  let diff = targetElement.scrollHeight - targetElement.clientHeight;135  if(Math.abs(targetElement.scrollTop - diff) <= 10 || diff == 0) {136    isScrolled = false;137  } else {138    isScrolled = true;139  }140});141 142// Create a MutationObserver instance143const observer = new MutationObserver(function(mutations) {144  mutations.forEach(function(mutation) {145    updateCssProperties();146 147    if(!isScrolled) {148      targetElement.scrollTop = targetElement.scrollHeight;149    }150 151    const firstChild = targetElement.children[0];152    if (firstChild.classList.contains("generating")) {153      typing.parentNode.classList.add("visible-dots");154      document.getElementById("stop").style.display = "flex";155      document.getElementById("Generate").style.display = "none";156    } else {157      typing.parentNode.classList.remove("visible-dots");158      document.getElementById("stop").style.display = "none";159      document.getElementById("Generate").style.display = "flex";160    }161 162  });163});164 165// Configure the observer to watch for changes in the subtree and attributes166const config = {167  childList: true,168  subtree: true,169  characterData: true,170  attributeOldValue: true,171  characterDataOldValue: true172};173 174// Start observing the target element175observer.observe(targetElement, config);176 177//------------------------------------------------178// Add some scrollbars179//------------------------------------------------180const textareaElements = document.querySelectorAll(".add_scrollbar textarea");181for(i = 0; i < textareaElements.length; i++) {182  textareaElements[i].classList.remove("scroll-hide");183  textareaElements[i].classList.add("pretty_scrollbar");184  textareaElements[i].style.resize = "none";185}186 187//------------------------------------------------188// Remove some backgrounds189//------------------------------------------------190const noBackgroundelements = document.querySelectorAll(".no-background");191for(i = 0; i < noBackgroundelements.length; i++) {192  noBackgroundelements[i].parentNode.style.border = "none";193  noBackgroundelements[i].parentNode.parentNode.parentNode.style.alignItems = "center";194}195 196const slimDropdownElements = document.querySelectorAll(".slim-dropdown");197for (i = 0; i < slimDropdownElements.length; i++) {198  const parentNode = slimDropdownElements[i].parentNode;199  parentNode.style.background = "transparent";200  parentNode.style.border = "0";201}202 203//------------------------------------------------204// Create the hover menu in the chat tab205// The show/hide events were adapted from:206// https://github.com/SillyTavern/SillyTavern/blob/6c8bd06308c69d51e2eb174541792a870a83d2d6/public/script.js207//------------------------------------------------208var buttonsInChat = document.querySelectorAll("#chat-tab:not(.old-ui) #chat-buttons button");209var button = document.getElementById("hover-element-button");210var menu = document.getElementById("hover-menu");211var istouchscreen = (navigator.maxTouchPoints > 0) || "ontouchstart" in document.documentElement;212 213function showMenu() {214  menu.style.display = "flex"; // Show the menu215}216 217function hideMenu() {218  menu.style.display = "none"; // Hide the menu219  if (!istouchscreen) {220    document.querySelector("#chat-input textarea").focus(); // Focus on the chat input221  }222}223 224if (buttonsInChat.length > 0) {225  for (let i = buttonsInChat.length - 1; i >= 0; i--) {226    const thisButton = buttonsInChat[i];227    menu.appendChild(thisButton);228 229    thisButton.addEventListener("click", () => {230      hideMenu();231    });232 233    const buttonText = thisButton.textContent;234    const matches = buttonText.match(/(\(.*?\))/);235 236    if (matches && matches.length > 1) {237      // Apply the transparent-substring class to the matched substring238      const substring = matches[1];239      const newText = buttonText.replace(substring, `&nbsp;<span class="transparent-substring">${substring.slice(1, -1)}</span>`);240      thisButton.innerHTML = newText;241    }242  }243} else {244  buttonsInChat = document.querySelectorAll("#chat-tab.old-ui #chat-buttons button");245  for (let i = 0; i < buttonsInChat.length; i++) {246    buttonsInChat[i].textContent = buttonsInChat[i].textContent.replace(/ \(.*?\)/, "");247  }248  document.getElementById("gr-hover-container").style.display = "none";249}250 251function isMouseOverButtonOrMenu() {252  return menu.matches(":hover") || button.matches(":hover");253}254 255button.addEventListener("mouseenter", function () {256  if (!istouchscreen) {257    showMenu();258  }259});260 261button.addEventListener("click", function () {262  if (menu.style.display === "flex") {263    hideMenu();264  }265  else {266    showMenu();267  }268});269 270// Add event listener for mouseleave on the button271button.addEventListener("mouseleave", function () {272  // Delay to prevent menu hiding when the mouse leaves the button into the menu273  setTimeout(function () {274    if (!isMouseOverButtonOrMenu()) {275      hideMenu();276    }277  }, 100);278});279 280// Add event listener for mouseleave on the menu281menu.addEventListener("mouseleave", function () {282  // Delay to prevent menu hide when the mouse leaves the menu into the button283  setTimeout(function () {284    if (!isMouseOverButtonOrMenu()) {285      hideMenu();286    }287  }, 100);288});289 290// Add event listener for click anywhere in the document291document.addEventListener("click", function (event) {292  // Check if the click is outside the button/menu and the menu is visible293  if (!isMouseOverButtonOrMenu() && menu.style.display === "flex") {294    hideMenu();295  }296 297  if (event.target.classList.contains("pfp_character")) {298    toggleBigPicture();299  }300});301 302//------------------------------------------------303// Relocate the "Show controls" checkbox304//------------------------------------------------305var elementToMove = document.getElementById("show-controls");306var parent = elementToMove.parentNode;307for (var i = 0; i < 2; i++) {308  parent = parent.parentNode;309}310 311parent.insertBefore(elementToMove, parent.firstChild);312 313//------------------------------------------------314// Make the chat input grow upwards instead of downwards315//------------------------------------------------316document.getElementById("show-controls").parentNode.style.position = "absolute";317document.getElementById("show-controls").parentNode.style.bottom = "0px";318 319//------------------------------------------------320// Focus on the chat input321//------------------------------------------------322const chatTextArea = document.getElementById("chat-input").querySelector("textarea");323 324function respondToChatInputVisibility(element, callback) {325  var options = {326    root: document.documentElement,327  };328 329  var observer = new IntersectionObserver((entries, observer) => {330    entries.forEach(entry => {331      callback(entry.intersectionRatio > 0);332    });333  }, options);334 335  observer.observe(element);336}337 338function handleChatInputVisibilityChange(isVisible) {339  if (isVisible) {340    chatTextArea.focus();341  }342}343 344respondToChatInputVisibility(chatTextArea, handleChatInputVisibilityChange);345 346//------------------------------------------------347// Show enlarged character picture when the profile348// picture is clicked on349//------------------------------------------------350let bigPictureVisible = false;351 352function addBigPicture() {353  var imgElement = document.createElement("img");354  var timestamp = new Date().getTime();355  imgElement.src = "/file/cache/pfp_character.png?time=" + timestamp;356  imgElement.classList.add("bigProfilePicture");357 358  var imgElementParent = document.getElementById("chat").parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode;359  imgElementParent.appendChild(imgElement);360}361 362function deleteBigPicture() {363  var bigProfilePictures = document.querySelectorAll(".bigProfilePicture");364  bigProfilePictures.forEach(function (element) {365    element.parentNode.removeChild(element);366  });367}368 369function toggleBigPicture() {370  if(bigPictureVisible) {371    deleteBigPicture();372    bigPictureVisible = false;373  } else {374    addBigPicture();375    bigPictureVisible = true;376  }377}378 379//------------------------------------------------380// Define global CSS properties for resizing and381// positioning certain elements382//------------------------------------------------383let currentChatInputHeight = 0;384 385function updateCssProperties() {386  // Set the height of the chat area387  const chatContainer = document.getElementById("chat").parentNode.parentNode.parentNode;388  const chatInputHeight = document.querySelector("#chat-input textarea").clientHeight;389  if (chatContainer.clientHeight > 0) {390    const newChatHeight = `${chatContainer.clientHeight - chatInputHeight + 40}px`;391    document.documentElement.style.setProperty("--chat-height", newChatHeight);392    document.documentElement.style.setProperty("--input-delta", `${chatInputHeight - 40}px`);393 394    // Set the position offset of the chat input box395    const header = document.querySelector(".header_bar");396    const headerHeight = `${header.clientHeight}px`;397    document.documentElement.style.setProperty("--header-height", headerHeight);398 399    // Offset the scroll position of the chat area400    if (chatInputHeight !== currentChatInputHeight) {401      chatContainer.scrollTop += chatInputHeight > currentChatInputHeight ? chatInputHeight : -chatInputHeight;402      currentChatInputHeight = chatInputHeight;403    }404  }405}406 407new ResizeObserver(updateCssProperties)408  .observe(document.querySelector("#chat-input textarea"));409 410window.addEventListener("resize", updateCssProperties);411 412//------------------------------------------------413// Keep track of the display width to position the past414// chats dropdown on desktop415//------------------------------------------------416function updateDocumentWidth() {417  var updatedWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;418  document.documentElement.style.setProperty("--document-width", updatedWidth + "px");419}420 421updateDocumentWidth();422window.addEventListener("resize", updateDocumentWidth);423 424//------------------------------------------------425// Focus on the rename text area when it becomes visible426//------------------------------------------------427const renameTextArea = document.getElementById("rename-row").querySelector("textarea");428 429function respondToRenameVisibility(element, callback) {430  var options = {431    root: document.documentElement,432  };433 434  var observer = new IntersectionObserver((entries, observer) => {435    entries.forEach(entry => {436      callback(entry.intersectionRatio > 0);437    });438  }, options);439 440  observer.observe(element);441}442 443 444function handleVisibilityChange(isVisible) {445  if (isVisible) {446    renameTextArea.focus();447  }448}449 450respondToRenameVisibility(renameTextArea, handleVisibilityChange);451