Skip to content

Commit

Permalink
feat: inject conversationManage.js instead of executing it every time
Browse files Browse the repository at this point in the history
  • Loading branch information
F33RNI committed Apr 1, 2024
1 parent 5d5ad78 commit 0fd00eb
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 56 deletions.
112 changes: 61 additions & 51 deletions src/lmao/ms_copilot/conversationManage.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,13 @@
* SOFTWARE.
*/

// driver.execute_async_script() callback
const callback = arguments[arguments.length - 1];
/**
* Call this from python script to check if this file is injected
* @returns true
*/
function isManageInjected() {
return true;
}

/**
* Tries to click on "See all recent chats" button without raising any error
Expand Down Expand Up @@ -88,60 +93,65 @@ function renameChatAndConfirm(conversationID) {
confirmBtn.click();
}

// Extract arguments (action, conversation ID)
// Action can be "load", "delete" or "rename"
const action = arguments[0];
const conversationID = arguments[1];
/**
* Loads or deletes specific conversation or renames the last one into conversationID
* @param {string} action "load", "delete" or "rename"
* @param {string} conversationID ID of conversation to load, delete or rename last into
*/
function conversationManage(action, conversationID) {
// driver.execute_async_script() callback
const callback = arguments[arguments.length - 1];

try {
// Open conversation (load it)
if (action === "load") {
// Expand all chats -> wait 500ms -> find conversation -> open it -> return the same conversation ID or "null"
expandChats();
setTimeout(function () {
const cibThreadContainer = searchCibThreadContainer(conversationID, true);
if (cibThreadContainer === null) {
callback("" + null);
}
try {
// Open conversation (load it)
if (action === "load") {
// Expand all chats -> wait 500ms -> find conversation -> open it -> return the same conversation ID or "null"
expandChats();
setTimeout(function () {
const cibThreadContainer = searchCibThreadContainer(conversationID, true);
if (cibThreadContainer === null) {
callback("" + null);
}

const loadChatBtn = cibThreadContainer.querySelector("div > div > button");
loadChatBtn.focus();
loadChatBtn.click();
callback("" + conversationID);
}, 500);
}
const loadChatBtn = cibThreadContainer.querySelector("div > div > button");
loadChatBtn.focus();
loadChatBtn.click();
callback("" + conversationID);
}, 500);
}

// Delete conversation
else if (action === "delete") {
// Expand all chats -> wait 500ms -> find conversation -> delete it -> return the same conversation ID or "null"
expandChats();
setTimeout(function () {
const cibThreadContainer = searchCibThreadContainer(conversationID, false);
if (cibThreadContainer === null) {
callback("" + null);
}
// Delete conversation
else if (action === "delete") {
// Expand all chats -> wait 500ms -> find conversation -> delete it -> return the same conversation ID or "null"
expandChats();
setTimeout(function () {
const cibThreadContainer = searchCibThreadContainer(conversationID, false);
if (cibThreadContainer === null) {
callback("" + null);
}

const loadChatBtn = cibThreadContainer.querySelector("div > div > button");
loadChatBtn.focus();
const deleteChatBtn = cibThreadContainer.querySelector("div > div > div.controls > button.delete.icon-button");
deleteChatBtn.click();
callback("" + conversationID);
}, 500);
}
const loadChatBtn = cibThreadContainer.querySelector("div > div > button");
loadChatBtn.focus();
const deleteChatBtn = cibThreadContainer.querySelector("div > div > div.controls > button.delete.icon-button");
deleteChatBtn.click();
callback("" + conversationID);
}, 500);
}

// Rename conversation
else if (action === "rename") {
// Enter edit mode -> wait 500ms -> rename and confirm -> return the same conversation ID
startRenameMode();
setTimeout(function () {
renameChatAndConfirm(conversationID);
callback("" + conversationID);
}, 500);
// Rename conversation
else if (action === "rename") {
// Enter edit mode -> wait 500ms -> rename and confirm -> return the same conversation ID
startRenameMode();
setTimeout(function () {
renameChatAndConfirm(conversationID);
callback("" + conversationID);
}, 500);
}
}
}

// Log and return error
catch (error) {
console.error(error);
callback("" + error);
// Log and return error as string
catch (error) {
console.error(error);
callback("" + error);
}
}
24 changes: 19 additions & 5 deletions src/lmao/ms_copilot/ms_copilot_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
from lmao.ms_copilot.proxy_extension import ProxyExtension


# JS script that injects pretty "large" JS file into <head></head>. Pass script's content as first argument
# JS script that injects "large" JS file into <head></head>. Pass script's content as first argument
_INJECT_JS = """
const injectedScript = document.createElement("script");
injectedScript.type = "text/javascript";
Expand Down Expand Up @@ -118,7 +118,7 @@
_IMAGE_PASTE_DELAY = 3

# How long to wait after receiving message finish to make sure it's really finish (due to image generations)
_WAIT_AFTER_FINISH = 3
_WAIT_AFTER_FINISH = 2.5


# Class to keep placeholder https://stackoverflow.com/a/21754294
Expand Down Expand Up @@ -812,16 +812,30 @@ def _conversation_manage(self, action: str, conversation_id: str, raise_on_error
Returns:
bool: True if successful, False if not
"""
logging.info(f"Trying to {action} conversation")
# Check if conversationManage.js is injected
is_injected = False
try:
is_injected = self.driver.execute_script("return isManageInjected();")
except:
pass

# Inject JS
if not is_injected:
logging.warning("conversationManage is not injected. Injecting it")
self.driver.execute_script(_INJECT_JS, self._conversation_manage_js)
logging.info(f"Injected? {self.driver.execute_script('return isManageInjected();')}")

# Execute script and wait for callback or timeout
try:
logging.info(f"Trying to asynchronously {action} conversation")
self.driver.set_script_timeout(_WAIT_TIMEOUT)
conversation_id_ = self.driver.execute_async_script(self._conversation_manage_js, action, conversation_id)
conversation_id_ = self.driver.execute_async_script(f"conversationManage({action}, {conversation_id});")
if conversation_id_ is None:
raise Exception(f"Unable to {action} conversation to {conversation_id}")
elif conversation_id_ != conversation_id:
raise Exception(str(conversation_id_))
else:
logging.info(f'"Conversation {action}" finished successfully')
logging.info(f'Operation "conversation {action}" finished successfully')
time.sleep(1)
return True
except Exception as e:
Expand Down

0 comments on commit 0fd00eb

Please sign in to comment.