mirror of
https://github.com/snachodog/tok-to-insta-follower-bridge.git
synced 2025-04-23 20:12:22 -06:00
♻️ refactor search logic
This commit is contained in:
parent
294be1b03b
commit
3064ffea2d
@ -2,7 +2,7 @@ import { BskyClient, type BskyLoginParams } from "./lib/bskyClient";
|
|||||||
import type { PlasmoCSConfig } from "plasmo"
|
import type { PlasmoCSConfig } from "plasmo"
|
||||||
import { MESSAGE_NAMES, VIEWER_STATE } from "~lib/constants";
|
import { MESSAGE_NAMES, VIEWER_STATE } from "~lib/constants";
|
||||||
import "./style.content.css"
|
import "./style.content.css"
|
||||||
import { searchBskyUsers } from '~lib/searchAndInsertBskyUsers';
|
import { searchAndInsertBskyUsers } from '~lib/searchAndInsertBskyUsers';
|
||||||
|
|
||||||
export const config: PlasmoCSConfig = {
|
export const config: PlasmoCSConfig = {
|
||||||
matches: ["https://twitter.com/*", "https://x.com/*"],
|
matches: ["https://twitter.com/*", "https://x.com/*"],
|
||||||
@ -21,7 +21,7 @@ const searchAndShowBskyUsers = async ({
|
|||||||
})
|
})
|
||||||
switch (messageName) {
|
switch (messageName) {
|
||||||
case MESSAGE_NAMES.SEARCH_BSKY_USER_ON_FOLLOW_PAGE:
|
case MESSAGE_NAMES.SEARCH_BSKY_USER_ON_FOLLOW_PAGE:
|
||||||
await searchBskyUsers({
|
await searchAndInsertBskyUsers({
|
||||||
agent,
|
agent,
|
||||||
btnLabel: {
|
btnLabel: {
|
||||||
add: "Follow",
|
add: "Follow",
|
||||||
@ -36,7 +36,7 @@ const searchAndShowBskyUsers = async ({
|
|||||||
break
|
break
|
||||||
case MESSAGE_NAMES.SEARCH_BSKY_USER_ON_BLOCK_PAGE:
|
case MESSAGE_NAMES.SEARCH_BSKY_USER_ON_BLOCK_PAGE:
|
||||||
// TODO: If already blocked, don't show blocking state. because blocking user can't find.
|
// TODO: If already blocked, don't show blocking state. because blocking user can't find.
|
||||||
await searchBskyUsers({
|
await searchAndInsertBskyUsers({
|
||||||
agent,
|
agent,
|
||||||
btnLabel: {
|
btnLabel: {
|
||||||
add: "Block",
|
add: "Block",
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import type { ProfileView } from "@atproto/api/dist/client/types/app/bsky/actor/defs"
|
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 }
|
if(!bskyProfile) { return false }
|
||||||
|
|
||||||
const lowerCaseName = name.toLocaleLowerCase()
|
return terms.some(term => {
|
||||||
|
const lowerCaseName = term.toLocaleLowerCase()
|
||||||
if(lowerCaseName === bskyProfile?.handle.toLocaleLowerCase().replace("@", "").split('.')[0]) {
|
if(lowerCaseName === bskyProfile?.handle.toLocaleLowerCase().replace("@", "").split('.')[0]) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -14,4 +15,5 @@ export const isSimilarUser = (name: string, bskyProfile: ProfileView | undefined
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,9 @@ export const insertReloadEl = (clickAction: () => void) => {
|
|||||||
export const getAccountNameAndDisplayName = (userCell: Element) => {
|
export const getAccountNameAndDisplayName = (userCell: Element) => {
|
||||||
const [avatarEl, displayNameEl] = userCell?.querySelectorAll("a")
|
const [avatarEl, displayNameEl] = userCell?.querySelectorAll("a")
|
||||||
const twAccountName = avatarEl?.getAttribute("href")?.replace("/", "")
|
const twAccountName = avatarEl?.getAttribute("href")?.replace("/", "")
|
||||||
|
const twAccountNameRemoveUnderscore = twAccountName.replace("_", "") // bsky does not allow underscore in handle. so remove it.
|
||||||
const twDisplayName = displayNameEl?.textContent
|
const twDisplayName = displayNameEl?.textContent
|
||||||
return { twAccountName, twDisplayName }
|
return { twAccountName, twDisplayName, twAccountNameRemoveUnderscore }
|
||||||
}
|
}
|
||||||
|
|
||||||
export const insertBskyProfileEl = ({ dom, profile, statusKey, btnLabel, addAction, removeAction }: {
|
export const insertBskyProfileEl = ({ dom, profile, statusKey, btnLabel, addAction, removeAction }: {
|
||||||
|
@ -9,9 +9,9 @@ import type { UserCellBtnLabel } from './components/BskyUserCell';
|
|||||||
|
|
||||||
const notFoundUserCache = new Set<string>()
|
const notFoundUserCache = new Set<string>()
|
||||||
|
|
||||||
const followerUrlMap = new Map<string, string>()
|
const bskyUserUrlMap = new Map<string, string>()
|
||||||
|
|
||||||
export const searchBskyUsers = async (
|
export const searchAndInsertBskyUsers = async (
|
||||||
{
|
{
|
||||||
agent,
|
agent,
|
||||||
btnLabel,
|
btnLabel,
|
||||||
@ -35,62 +35,62 @@ export const searchBskyUsers = async (
|
|||||||
debugLog(`userCells length: ${userCells.length}`)
|
debugLog(`userCells length: ${userCells.length}`)
|
||||||
|
|
||||||
let index = 0
|
let index = 0
|
||||||
|
|
||||||
|
// loop over twitter user profile cells and search and insert bsky user
|
||||||
for (const userCell of userCells) {
|
for (const userCell of userCells) {
|
||||||
if (isOutOfTopViewport(userCell)) {
|
if (isOutOfTopViewport(userCell)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
const { twAccountName, twDisplayName } = getAccountNameAndDisplayName(userCell)
|
|
||||||
|
const { twAccountName, twDisplayName, twAccountNameRemoveUnderscore } = getAccountNameAndDisplayName(userCell)
|
||||||
|
|
||||||
if (notFoundUserCache.has(twAccountName)) {
|
if (notFoundUserCache.has(twAccountName)) {
|
||||||
insertNotFoundEl(userCell)
|
insertNotFoundEl(userCell)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
const [searchResultByAccountName] = await agent.searchUser({
|
const searchTerms = [
|
||||||
term: twAccountName,
|
twAccountNameRemoveUnderscore,
|
||||||
|
twDisplayName,
|
||||||
|
]
|
||||||
|
|
||||||
|
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,
|
limit: 1,
|
||||||
})
|
})
|
||||||
|
|
||||||
// TODO: Refactor, this is duplicated
|
const isUserFound = isSimilarUser([
|
||||||
// first, search by account name
|
twAccountName,
|
||||||
if (isSimilarUser(twDisplayName, searchResultByAccountName) || isSimilarUser(twAccountName, searchResultByAccountName)) {
|
twAccountNameRemoveUnderscore,
|
||||||
insertBskyProfileEl({
|
twDisplayName,
|
||||||
dom: userCell,
|
], searchResult)
|
||||||
profile: searchResultByAccountName,
|
|
||||||
statusKey,
|
if (isUserFound) {
|
||||||
btnLabel,
|
targetAccount = searchResult
|
||||||
addAction: async () => {
|
break; // Stop searching when a user is found
|
||||||
const result = await addQuery(searchResultByAccountName.did);
|
|
||||||
followerUrlMap.set(searchResultByAccountName.did, result.uri)
|
|
||||||
},
|
|
||||||
removeAction: async () => {
|
|
||||||
if (searchResultByAccountName?.viewer?.following) {
|
|
||||||
await removeQuery(searchResultByAccountName?.viewer?.following);
|
|
||||||
} else {
|
|
||||||
await removeQuery(followerUrlMap.get(searchResultByAccountName.did));
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
})
|
|
||||||
} else {
|
// insert bsky profile or not found element
|
||||||
// if not found, search by display name
|
if (targetAccount) {
|
||||||
const [searchResultByDisplayName] = await agent.searchUser({
|
|
||||||
term: twDisplayName,
|
|
||||||
limit: 1,
|
|
||||||
})
|
|
||||||
if (isSimilarUser(twDisplayName, searchResultByDisplayName) || isSimilarUser(twAccountName, searchResultByDisplayName)) {
|
|
||||||
insertBskyProfileEl({
|
insertBskyProfileEl({
|
||||||
dom: userCell,
|
dom: userCell,
|
||||||
profile: searchResultByDisplayName,
|
profile: targetAccount,
|
||||||
statusKey,
|
statusKey,
|
||||||
btnLabel,
|
btnLabel,
|
||||||
addAction: async () => {
|
addAction: async () => {
|
||||||
const result = await addQuery(searchResultByDisplayName.did);
|
const result = await addQuery(targetAccount.did);
|
||||||
followerUrlMap.set(searchResultByDisplayName.did, result.uri)
|
bskyUserUrlMap.set(targetAccount.did, result.uri)
|
||||||
},
|
},
|
||||||
removeAction: async () => {
|
removeAction: async () => {
|
||||||
if (searchResultByDisplayName?.viewer?.following) {
|
if (targetAccount?.viewer?.following) {
|
||||||
await removeQuery(searchResultByDisplayName?.viewer?.following);
|
await removeQuery(targetAccount?.viewer?.following);
|
||||||
} else {
|
} else {
|
||||||
await removeQuery(followerUrlMap.get(searchResultByDisplayName.did));
|
await removeQuery(bskyUserUrlMap.get(targetAccount.did));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -98,17 +98,17 @@ export const searchBskyUsers = async (
|
|||||||
insertNotFoundEl(userCell)
|
insertNotFoundEl(userCell)
|
||||||
notFoundUserCache.add(twAccountName)
|
notFoundUserCache.add(twAccountName)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
index++
|
index++
|
||||||
if (process.env.NODE_ENV === "development" && index > 5) {
|
|
||||||
|
if (process.env.NODE_ENV === "development" && index > 20) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: if there are more users, insert reload button
|
// TODO: if there are more users, insert reload button
|
||||||
insertReloadEl(async () => {
|
insertReloadEl(async () => {
|
||||||
await searchBskyUsers({
|
await searchAndInsertBskyUsers({
|
||||||
agent,
|
agent,
|
||||||
btnLabel,
|
btnLabel,
|
||||||
userCellQueryParam,
|
userCellQueryParam,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user