Cleanups and speedups

This commit is contained in:
Andrew Ferrazzutti 2021-02-21 02:07:48 -05:00
parent 4cda93dd9b
commit a43502b45e
2 changed files with 54 additions and 57 deletions

View File

@ -270,11 +270,12 @@ class MautrixController {
* Parse a conversation list item element. * Parse a conversation list item element.
* *
* @param {Element} element - The element to parse. * @param {Element} element - The element to parse.
* @param {null|string} knownId - The ID of this element, if it is known.
* @return {ChatListInfo} - The info in the element. * @return {ChatListInfo} - The info in the element.
*/ */
parseChatListItem(element) { parseChatListItem(element, knownId) {
return { return {
id: this.getChatListItemId(element), id: knownId || this.getChatListItemId(element),
name: this.getChatListItemName(element), name: this.getChatListItemName(element),
// TODO icon, but only for groups // TODO icon, but only for groups
lastMsg: this.getChatListItemLastMsg(element), lastMsg: this.getChatListItemLastMsg(element),
@ -283,12 +284,12 @@ class MautrixController {
} }
/** /**
* Parse a mws-conversations-list .conv-container list. * Parse the list of recent/saved chats.
* @param {Element} element - The chat list element.
* @return {[ChatListInfo]} - The list of chats. * @return {[ChatListInfo]} - The list of chats.
*/ */
parseChatList(element) { parseChatList() {
return Array.from(element.children).map( const chatList = document.querySelector("#_chat_list_body")
return Array.from(chatList.children).map(
child => this.parseChatListItem(child.firstElementChild)) child => this.parseChatListItem(child.firstElementChild))
} }

View File

@ -331,8 +331,8 @@ export default class MessagesPuppeteer {
* @return {Promise<[ChatListInfo]>} - List of chat IDs in order of most recent message. * @return {Promise<[ChatListInfo]>} - List of chat IDs in order of most recent message.
*/ */
async getRecentChats() { async getRecentChats() {
return await this.page.$eval("#_chat_list_body", return await this.page.evaluate(
elem => window.__mautrixController.parseChatList(elem)) () => window.__mautrixController.parseChatList())
} }
/** /**
@ -403,74 +403,70 @@ export default class MessagesPuppeteer {
return `#_chat_list_body div[data-chatid="${id}"]` return `#_chat_list_body div[data-chatid="${id}"]`
} }
async _switchChatUnsafe(id) { async _switchChat(id) {
this.log("Switching to chat", id) this.log(`Switching to chat ${id}`)
const chatListItem = await this.page.$(this._listItemSelector(id)) const chatListItem = await this.page.$(this._listItemSelector(id))
await chatListItem.click() await chatListItem.click()
return chatListItem
const chatHeader = await this.page.waitForSelector("#_chat_header_area > .mdRGT04Link")
const chatListInfo = await chatListItem.evaluate(
(e, id) => window.__mautrixController.parseChatListItem(e, id),
id)
this.log(`Waiting for chat header title to be "${chatListInfo.name}"`)
const chatHeaderTitleElement = await chatHeader.$(".mdRGT04Ttl")
await this.page.waitForFunction(
(element, targetText) => element.innerText == targetText,
{},
chatHeaderTitleElement, chatListInfo.name)
return [chatListItem, chatListInfo, chatHeader]
} }
async _getChatInfoUnsafe(id) { async _getChatInfoUnsafe(id) {
let [isDirect, isGroup, isRoom] = [false,false,false]
switch (id.charAt(0)) {
case 'u':
isDirect = true
break
case 'c':
isGroup = true
break
case 'r':
isRoom = true
break
}
// TODO This will mark the chat as "read"! // TODO This will mark the chat as "read"!
const chatListItem = await this._switchChatUnsafe(id) const [chatListItem, chatListInfo, chatHeader] = await this._switchChat(id)
const chatHeader = await this.page.waitForSelector("#_chat_header_area > .mdRGT04Link")
/* TODO Make this work
const chatListName = await chatListItem.evaluate(e => window.__mautrixController.getChatListItemName(e))
this.log(`Waiting for chat header title to be "${chatListName}"`)
const chatHeaderTitleElement = await chatHeader.$(".mdRGT04Ttl")
await this.page.waitForFunction((element, targetText) => {
element.innerText == targetText
},
{},
chatHeaderTitleElement, chatListName)
*/await this.page.waitForTimeout(3000)
this.log("Clicking chat header")
await chatHeader.click()
const chatDetailArea = await this.page.waitForSelector("#_chat_detail_area > .mdRGT02Info")
this.log("Gathering participants")
let participants let participants
const participantList = await chatDetailArea.$("ul.mdRGT13Ul") if (isGroup || isRoom) {
if (participantList) { this.log("Found multi-user chat, so clicking chat header to get participants")
// TODO Use "id" syntax to tell if this is a chat/room/group, not selectors: await chatHeader.click()
// c: group const participantList = await this.page.waitForSelector("#_chat_detail_area > .mdRGT02Info ul.mdRGT13Ul")
// r: room if (isGroup) {
// u: chat
// It's defined by the LINE API!
if (await chatDetailArea.$("#leaveGroup")) {
this.log("Found group")
// This is a *group* (like a Matrix room)
// TODO Is a group not actually created until a message is sent(?) // TODO Is a group not actually created until a message is sent(?)
// If so, maybe don't create a portal until there is a message. // If so, maybe don't create a portal until there is a message.
participants = await participantList.evaluate( participants = await participantList.evaluate(
elem => window.__mautrixController.parseParticipantList(elem)) elem => window.__mautrixController.parseParticipantList(elem))
} else if (await chatDetailArea.$("ul [data-click-name='leave_room'")) { } else if (isRoom) {
this.log("Found room") this.log("TODO: Room participant lists don't have user IDs...")
// This is a *room* (canonical multi-user DM)
// TODO Find a way to get participant IDs from a room member list!!
participants = [] participants = []
} }
} }
else else
{ {
this.log("Found chat") this.log(`Found direct chat with ${id}`)
//const chatDetailArea = await this.page.waitForSelector("#_chat_detail_area > .mdRGT02Info")
//await chatDetailArea.$(".MdTxtDesc02") || // 1:1 chat with custom title - get participant's real name //await chatDetailArea.$(".MdTxtDesc02") || // 1:1 chat with custom title - get participant's real name
participants = [{ participants = [{
id: id, // the ID of a 1:1 chat is the other user's member ID id: id,
name: await chatDetailArea.$eval( name: chatListInfo.name,
"#_chat_contact_detail_view > a",
element => element.innerText),
}] }]
// TODO Or just look up the member ID in the contact list?
} }
return { return {participants, ...chatListInfo}
participants,
...await this.page.$eval(this._listItemSelector(id),
elem => window.__mautrixController.parseChatListItem(elem)),
}
} }
// TODO Catch "An error has occurred" dialog // TODO Catch "An error has occurred" dialog
@ -479,7 +475,7 @@ export default class MessagesPuppeteer {
// Always present, just made visible via classes // Always present, just made visible via classes
async _sendMessageUnsafe(chatID, text) { async _sendMessageUnsafe(chatID, text) {
await this._switchChatUnsafe(chatID) await this._switchChat(chatID)
const promise = this.page.evaluate( const promise = this.page.evaluate(
() => window.__mautrixController.promiseOwnMessage()) () => window.__mautrixController.promiseOwnMessage())
@ -506,7 +502,7 @@ export default class MessagesPuppeteer {
async _getMessagesUnsafe(id, minID = 0) { async _getMessagesUnsafe(id, minID = 0) {
// TODO Also handle "decrypting" state // TODO Also handle "decrypting" state
// TODO Handle unloaded messages. Maybe scroll up // TODO Handle unloaded messages. Maybe scroll up
await this._switchChatUnsafe(id) await this._switchChat(id)
this.log("Waiting for messages to load") this.log("Waiting for messages to load")
const messages = await this.page.evaluate( const messages = await this.page.evaluate(
() => window.__mautrixController.parseMessageList()) () => window.__mautrixController.parseMessageList())