From 3064ffea2d34c6300565daaa7aaee7178d87d9cc Mon Sep 17 00:00:00 2001 From: kawamataryo Date: Fri, 18 Aug 2023 21:44:04 +0900 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor=20search=20logic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/content.ts | 6 +- src/lib/bskyHelpers.ts | 26 +++++---- src/lib/domHelpers.ts | 3 +- src/lib/searchAndInsertBskyUsers.ts | 90 ++++++++++++++--------------- 4 files changed, 64 insertions(+), 61 deletions(-) diff --git a/src/content.ts b/src/content.ts index 7141561..85f1c20 100644 --- a/src/content.ts +++ b/src/content.ts @@ -2,7 +2,7 @@ import { BskyClient, type BskyLoginParams } from "./lib/bskyClient"; import type { PlasmoCSConfig } from "plasmo" import { MESSAGE_NAMES, VIEWER_STATE } from "~lib/constants"; import "./style.content.css" -import { searchBskyUsers } from '~lib/searchAndInsertBskyUsers'; +import { searchAndInsertBskyUsers } from '~lib/searchAndInsertBskyUsers'; export const config: PlasmoCSConfig = { matches: ["https://twitter.com/*", "https://x.com/*"], @@ -21,7 +21,7 @@ const searchAndShowBskyUsers = async ({ }) switch (messageName) { case MESSAGE_NAMES.SEARCH_BSKY_USER_ON_FOLLOW_PAGE: - await searchBskyUsers({ + await searchAndInsertBskyUsers({ agent, btnLabel: { add: "Follow", @@ -36,7 +36,7 @@ const searchAndShowBskyUsers = async ({ break case MESSAGE_NAMES.SEARCH_BSKY_USER_ON_BLOCK_PAGE: // TODO: If already blocked, don't show blocking state. because blocking user can't find. - await searchBskyUsers({ + await searchAndInsertBskyUsers({ agent, btnLabel: { add: "Block", diff --git a/src/lib/bskyHelpers.ts b/src/lib/bskyHelpers.ts index 45d3d53..7cd14a3 100644 --- a/src/lib/bskyHelpers.ts +++ b/src/lib/bskyHelpers.ts @@ -1,17 +1,19 @@ import type { ProfileView } from "@atproto/api/dist/client/types/app/bsky/actor/defs" -export const isSimilarUser = (name: string, bskyProfile: ProfileView | undefined) => { +export const isSimilarUser = (terms: string[], bskyProfile: ProfileView | undefined) => { if(!bskyProfile) { return false } - const lowerCaseName = name.toLocaleLowerCase() - if(lowerCaseName === bskyProfile?.handle.toLocaleLowerCase().replace("@", "").split('.')[0]) { - return true - } - if(lowerCaseName === bskyProfile.displayName?.toLocaleLowerCase()) { - return true - } - if(bskyProfile.description?.toLocaleLowerCase().includes(lowerCaseName)) { - return true - } - return false + return terms.some(term => { + const lowerCaseName = term.toLocaleLowerCase() + if(lowerCaseName === bskyProfile?.handle.toLocaleLowerCase().replace("@", "").split('.')[0]) { + return true + } + if(lowerCaseName === bskyProfile.displayName?.toLocaleLowerCase()) { + return true + } + if(bskyProfile.description?.toLocaleLowerCase().includes(lowerCaseName)) { + return true + } + return false + }) } diff --git a/src/lib/domHelpers.ts b/src/lib/domHelpers.ts index 07494ce..b1b1b2e 100644 --- a/src/lib/domHelpers.ts +++ b/src/lib/domHelpers.ts @@ -27,8 +27,9 @@ export const insertReloadEl = (clickAction: () => void) => { export const getAccountNameAndDisplayName = (userCell: Element) => { const [avatarEl, displayNameEl] = userCell?.querySelectorAll("a") const twAccountName = avatarEl?.getAttribute("href")?.replace("/", "") + const twAccountNameRemoveUnderscore = twAccountName.replace("_", "") // bsky does not allow underscore in handle. so remove it. const twDisplayName = displayNameEl?.textContent - return { twAccountName, twDisplayName } + return { twAccountName, twDisplayName, twAccountNameRemoveUnderscore } } export const insertBskyProfileEl = ({ dom, profile, statusKey, btnLabel, addAction, removeAction }: { diff --git a/src/lib/searchAndInsertBskyUsers.ts b/src/lib/searchAndInsertBskyUsers.ts index 475220c..4e08288 100644 --- a/src/lib/searchAndInsertBskyUsers.ts +++ b/src/lib/searchAndInsertBskyUsers.ts @@ -9,9 +9,9 @@ import type { UserCellBtnLabel } from './components/BskyUserCell'; const notFoundUserCache = new Set() -const followerUrlMap = new Map() +const bskyUserUrlMap = new Map() -export const searchBskyUsers = async ( +export const searchAndInsertBskyUsers = async ( { agent, btnLabel, @@ -35,80 +35,80 @@ export const searchBskyUsers = async ( debugLog(`userCells length: ${userCells.length}`) let index = 0 + + // loop over twitter user profile cells and search and insert bsky user for (const userCell of userCells) { if (isOutOfTopViewport(userCell)) { continue } - const { twAccountName, twDisplayName } = getAccountNameAndDisplayName(userCell) + + const { twAccountName, twDisplayName, twAccountNameRemoveUnderscore } = getAccountNameAndDisplayName(userCell) + if (notFoundUserCache.has(twAccountName)) { insertNotFoundEl(userCell) continue } - const [searchResultByAccountName] = await agent.searchUser({ - term: twAccountName, - limit: 1, - }) + const searchTerms = [ + twAccountNameRemoveUnderscore, + twDisplayName, + ] - // TODO: Refactor, this is duplicated - // first, search by account name - if (isSimilarUser(twDisplayName, searchResultByAccountName) || isSimilarUser(twAccountName, searchResultByAccountName)) { + let targetAccount = null + + // Loop over search parameters and break if a user is found + for (const term of searchTerms) { + const [searchResult] = await agent.searchUser({ + term: term, + limit: 1, + }) + + const isUserFound = isSimilarUser([ + twAccountName, + twAccountNameRemoveUnderscore, + twDisplayName, + ], searchResult) + + if (isUserFound) { + targetAccount = searchResult + break; // Stop searching when a user is found + } + } + + // insert bsky profile or not found element + if (targetAccount) { insertBskyProfileEl({ dom: userCell, - profile: searchResultByAccountName, + profile: targetAccount, statusKey, btnLabel, addAction: async () => { - const result = await addQuery(searchResultByAccountName.did); - followerUrlMap.set(searchResultByAccountName.did, result.uri) + const result = await addQuery(targetAccount.did); + bskyUserUrlMap.set(targetAccount.did, result.uri) }, removeAction: async () => { - if (searchResultByAccountName?.viewer?.following) { - await removeQuery(searchResultByAccountName?.viewer?.following); + if (targetAccount?.viewer?.following) { + await removeQuery(targetAccount?.viewer?.following); } else { - await removeQuery(followerUrlMap.get(searchResultByAccountName.did)); + await removeQuery(bskyUserUrlMap.get(targetAccount.did)); } }, }) } else { - // if not found, search by display name - const [searchResultByDisplayName] = await agent.searchUser({ - term: twDisplayName, - limit: 1, - }) - if (isSimilarUser(twDisplayName, searchResultByDisplayName) || isSimilarUser(twAccountName, searchResultByDisplayName)) { - insertBskyProfileEl({ - dom: userCell, - profile: searchResultByDisplayName, - statusKey, - btnLabel, - addAction: async () => { - const result = await addQuery(searchResultByDisplayName.did); - followerUrlMap.set(searchResultByDisplayName.did, result.uri) - }, - removeAction: async () => { - if (searchResultByDisplayName?.viewer?.following) { - await removeQuery(searchResultByDisplayName?.viewer?.following); - } else { - await removeQuery(followerUrlMap.get(searchResultByDisplayName.did)); - } - }, - }) - } else { - insertNotFoundEl(userCell) - notFoundUserCache.add(twAccountName) - } + insertNotFoundEl(userCell) + notFoundUserCache.add(twAccountName) } index++ - if (process.env.NODE_ENV === "development" && index > 5) { + + if (process.env.NODE_ENV === "development" && index > 20) { break } } // TODO: if there are more users, insert reload button insertReloadEl(async () => { - await searchBskyUsers({ + await searchAndInsertBskyUsers({ agent, btnLabel, userCellQueryParam,