diff --git a/puppet/src/contentscript.js b/puppet/src/contentscript.js index 3a69cd4..34fd2af 100644 --- a/puppet/src/contentscript.js +++ b/puppet/src/contentscript.js @@ -274,7 +274,7 @@ class MautrixController { * @return {ChatListInfo} - The info in the element. */ parseChatListItem(element, knownId) { - return { + return !element.classList.contains("chatList") ? null : { id: knownId || this.getChatListItemId(element), name: this.getChatListItemName(element), // TODO icon, but only for groups @@ -294,6 +294,7 @@ class MautrixController { } /** + * TODO * Check if an image has been downloaded. * * @param {number} id - The ID of the message whose image to check. @@ -307,6 +308,7 @@ class MautrixController { } /** + * TODO * Download an image and return it as a data URL. * Used for downloading the blob: URLs in image messages. * @@ -331,18 +333,32 @@ class MautrixController { * @private */ _observeChatListMutations(mutations) { - /* TODO + // TODO Observe *added/removed* chats, not just new messages const changedChatIDs = new Set() for (const change of mutations) { console.debug("Chat list mutation:", change) - if (!(change.target instanceof Element) - || change.target.tagName.toLowerCase() === "mws-conversation-list-item-menu") { - console.debug("Ignoring chat list mutation:", change.target instanceof Element) - continue + if (change.target.id == "_chat_list_body") { + // TODO + // These could be new chats, or they're + // existing ones that just moved around. + /* + for (const node of change.addedNodes) { + } + */ } - const chat = this.parseChatListItem(change.target.closest("mws-conversation-list-item")) - console.debug("Changed chat list item:", chat) - changedChatIDs.add(chat.id) + else if (change.target.tagName == "LI") + { + for (const node of change.addedNodes) { + const chat = this.parseChatListItem(node) + if (chat) { + console.debug("Changed chat list item:", chat) + changedChatIDs.add(chat.id) + } else { + console.debug("Could not parse node as a chat list item:", node) + } + } + } + // change.removedNodes tells you which chats that had notifications are now read. } if (changedChatIDs.size > 0) { console.debug("Dispatching chat list mutations:", changedChatIDs) @@ -350,28 +366,25 @@ class MautrixController { () => console.debug("Chat list mutations dispatched"), err => console.error("Error dispatching chat list mutations:", err)) } - */ } /** - * Add a mutation observer to the given element. - * - * @param {Element} element - The DOM element to add the mutation observer to. + * Add a mutation observer to the chat list. */ - addChatListObserver(element) { + addChatListObserver() { if (this.chatListObserver !== null) { this.removeChatListObserver() } this.chatListObserver = new MutationObserver(mutations => { - /* TODO try { this._observeChatListMutations(mutations) } catch (err) { console.error("Error observing chat list mutations:", err) } - */ }) - this.chatListObserver.observe(element, { childList: true, subtree: true }) + this.chatListObserver.observe( + document.querySelector("#_chat_list_body"), + { childList: true, subtree: true }) console.debug("Started chat list observer") } diff --git a/puppet/src/puppet.js b/puppet/src/puppet.js index f3e07ea..b7c87a1 100644 --- a/puppet/src/puppet.js +++ b/puppet/src/puppet.js @@ -95,10 +95,8 @@ export default class MessagesPuppeteer { await this.page.exposeFunction("__mautrixExpiry", this._receiveExpiry.bind(this)) await this.page.exposeFunction("__mautrixReceiveMessageID", id => this.sentMessageIDs.add(id)) - /* TODO await this.page.exposeFunction("__mautrixReceiveChanges", this._receiveChatListChanges.bind(this)) - */ await this.page.exposeFunction("__chronoParseDate", chrono.parseDate) // NOTE Must *always* re-login on a browser session, so no need to check if already logged in @@ -390,8 +388,8 @@ export default class MessagesPuppeteer { async startObserving() { this.log("Adding chat list observer") - await this.page.$eval("#_chat_list_body", - element => window.__mautrixController.addChatListObserver(element)) + await this.page.evaluate( + () => window.__mautrixController.addChatListObserver()) } async stopObserving() { @@ -502,6 +500,7 @@ export default class MessagesPuppeteer { async _getMessagesUnsafe(id, minID = 0) { // TODO Also handle "decrypting" state // TODO Handle unloaded messages. Maybe scroll up + // TODO This will mark the chat as "read"! await this._switchChat(id) this.log("Waiting for messages to load") const messages = await this.page.evaluate(