From fa98592205f188e7e5747b153cab337c79439dbb Mon Sep 17 00:00:00 2001 From: kawamataryo Date: Wed, 24 Jan 2024 19:59:09 +0900 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fixed=20unnecessary=20permission?= =?UTF-8?q?=20requests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/contents/content.ts | 90 ------------ src/lib/components/BskyUserCell.ts | 209 ---------------------------- src/lib/components/NotFoundCell.ts | 35 ----- src/lib/components/ReloadBtn.ts | 24 ---- src/lib/domHelpers.ts | 63 --------- src/lib/searchAndInsertBskyUsers.ts | 142 ------------------- src/lib/searchBskyUsers.ts | 85 ----------- 7 files changed, 648 deletions(-) delete mode 100644 src/contents/content.ts delete mode 100644 src/lib/components/BskyUserCell.ts delete mode 100644 src/lib/components/NotFoundCell.ts delete mode 100644 src/lib/components/ReloadBtn.ts delete mode 100644 src/lib/searchAndInsertBskyUsers.ts diff --git a/src/contents/content.ts b/src/contents/content.ts deleted file mode 100644 index 1099edc..0000000 --- a/src/contents/content.ts +++ /dev/null @@ -1,90 +0,0 @@ -// TODO: Remove this file. This is for legacy code. -// import type { PlasmoCSConfig } from "plasmo"; -// import { BskyServiceWorkerClient } from "~lib/bskyServiceWorkerClient"; -// import { MESSAGE_NAMES, VIEWER_STATE } from "~lib/constants"; -// import { searchAndInsertBskyUsers } from "~lib/searchAndInsertBskyUsers"; -// import { type BskyLoginParams } from "../lib/bskyClient"; -// import "../style.content.legacy.css"; - -// export const config: PlasmoCSConfig = { -// matches: ["https://twitter.com/*", "https://x.com/*"], -// all_frames: true, -// }; - -// const searchAndShowBskyUsers = async ({ -// identifier, -// password, -// messageName, -// }: BskyLoginParams & { messageName: string }) => { -// const agent = await BskyServiceWorkerClient.createAgent({ -// identifier, -// password, -// }); - -// switch (messageName) { -// case MESSAGE_NAMES.SEARCH_BSKY_USER_ON_FOLLOW_PAGE: -// await searchAndInsertBskyUsers({ -// agent, -// btnLabel: { -// add: "Follow", -// remove: "Unfollow", -// progressive: "Following", -// }, -// statusKey: VIEWER_STATE.FOLLOWING, -// userCellQueryParam: -// '[data-testid="primaryColumn"] [data-testid="UserCell"]', -// addQuery: async (arg: string) => await agent.follow(arg), -// removeQuery: async (arg: string) => await agent.unfollow(arg), -// }); -// break; -// case MESSAGE_NAMES.SEARCH_BSKY_USER_ON_LIST_MEMBERS_PAGE: -// await searchAndInsertBskyUsers({ -// agent, -// btnLabel: { -// add: "Follow", -// remove: "Unfollow", -// progressive: "Following", -// }, -// statusKey: VIEWER_STATE.FOLLOWING, -// userCellQueryParam: -// '[data-testid="cellInnerDiv"] [data-testid="UserCell"]', -// addQuery: async (arg: string) => await agent.follow(arg), -// removeQuery: async (arg: string) => await agent.unfollow(arg), -// }); -// 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 searchAndInsertBskyUsers({ -// agent, -// btnLabel: { -// add: "Block", -// remove: "Unblock", -// progressive: "Blocking", -// }, -// statusKey: VIEWER_STATE.BLOCKING, -// userCellQueryParam: '[data-testid="UserCell"]', -// addQuery: async (arg: string) => await agent.block(arg), -// removeQuery: async (arg: string) => await agent.unblock(arg), -// }); -// break; -// } -// }; - -// chrome.runtime.onMessage.addListener((message, _, sendResponse) => { -// if (Object.values(MESSAGE_NAMES).includes(message.name)) { -// searchAndShowBskyUsers({ -// identifier: message.body.userId, -// password: message.body.password, -// messageName: message.name, -// }) -// .then(() => { -// sendResponse({ hasError: false }); -// }) -// .catch((e) => { -// console.error(e); -// sendResponse({ hasError: true, message: e.toString() }); -// }); -// return true; -// } -// return false; -// }); diff --git a/src/lib/components/BskyUserCell.ts b/src/lib/components/BskyUserCell.ts deleted file mode 100644 index b434777..0000000 --- a/src/lib/components/BskyUserCell.ts +++ /dev/null @@ -1,209 +0,0 @@ -import type { - ProfileView, - ViewerState, -} from "@atproto/api/dist/client/types/app/bsky/actor/defs"; -import { P, match } from "ts-pattern"; -import van from "vanjs-core"; -import { BSKY_USER_MATCH_TYPE } from "~lib/constants"; - -const { a, div, p, img, button, span } = van.tags; -const { svg, path } = van.tagsNS("http://www.w3.org/2000/svg"); - -export type UserCellBtnLabel = { - add: string; - remove: string; - progressive: string; -}; - -const ActionButton = ({ - statusKey, - profile, - btnLabel, - addAction, - removeAction, -}: { - profile: ProfileView; - statusKey: keyof ViewerState; - btnLabel: UserCellBtnLabel; - addAction: () => Promise; - removeAction: () => Promise; -}) => { - const label = van.state( - `${ - profile.viewer[statusKey] ? btnLabel.progressive : btnLabel.add - } on Bluesky`, - ); - - const isStateOfBeing = van.state(profile.viewer[statusKey]); - const isProcessing = van.state(false); - const isJustApplied = van.state(false); - - const beingClass = van.derive(() => - isStateOfBeing.val ? "action-button__being" : "", - ); - const processingClass = van.derive(() => - isProcessing.val ? "action-button__processing" : "", - ); - const justAppliedClass = van.derive(() => - isJustApplied.val ? "action-button__just-applied" : "", - ); - - const onClick = async () => { - if (isProcessing.val) return; - isProcessing.val = true; - label.val = "Processing..."; - - if (isStateOfBeing.val) { - await removeAction(); - label.val = `${btnLabel.add} on Bluesky`; - isStateOfBeing.val = false; - } else { - await addAction(); - label.val = `${btnLabel.progressive} on Bluesky`; - isStateOfBeing.val = true; - isJustApplied.val = true; - } - - isProcessing.val = false; - }; - - const onMouseover = () => { - if (isProcessing.val || isJustApplied.val || !isStateOfBeing.val) return; - - label.val = `${btnLabel.remove} on Bluesky`; - }; - - const onMouseout = () => { - if (isJustApplied.val) { - isJustApplied.val = false; - } - if (!isStateOfBeing.val) return; - - label.val = `${btnLabel.progressive} on Bluesky`; - }; - - return button( - { - class: () => - `action-button ${beingClass.val} ${processingClass.val} ${justAppliedClass.val}`, - onclick: onClick, - onmouseover: onMouseover, - onmouseout: onMouseout, - }, - () => label.val, - ); -}; - -const Avatar = ({ avatar }: { avatar?: string }) => { - return avatar - ? img({ src: avatar, width: "40" }) - : div({ class: "no-avatar" }); -}; - -const MatchTypeLabel = ({ - matchType, -}: { - matchType: (typeof BSKY_USER_MATCH_TYPE)[keyof typeof BSKY_USER_MATCH_TYPE]; -}) => { - const [text, labelClass] = match(matchType) - .with(BSKY_USER_MATCH_TYPE.HANDLE, () => [ - "Same handle name", - "match-type__handle", - ]) - .with(BSKY_USER_MATCH_TYPE.DISPLAY_NAME, () => [ - "Same display name", - "match-type__display-name", - ]) - .with(BSKY_USER_MATCH_TYPE.DESCRIPTION, () => [ - "Included handle name in description", - "match-type__description", - ]) - .run(); - - return div( - { class: `match-type ${labelClass}` }, - svg( - { - fill: "none", - width: "12", - viewBox: "0 0 24 24", - "stroke-width": "3", - stroke: "currentColor", - class: "w-6 h-6", - }, - path({ - "stroke-linecap": "round", - "stroke-linejoin": "round", - d: "M4.5 12.75l6 6 9-13.5", - }), - ), - text, - ); -}; - -export const BskyUserCell = ({ - profile, - statusKey, - btnLabel, - matchType, - addAction, - removeAction, -}: { - profile: ProfileView; - statusKey: keyof ViewerState; - btnLabel: UserCellBtnLabel; - matchType: (typeof BSKY_USER_MATCH_TYPE)[keyof typeof BSKY_USER_MATCH_TYPE]; - addAction: () => Promise; - removeAction: () => Promise; -}) => { - return div( - { class: "bsky-user-content-wrapper" }, - MatchTypeLabel({ matchType }), - div( - { class: "bsky-user-content bsky-fade-in" }, - div( - { class: "icon-section" }, - a( - { - href: `https://bsky.app/profile/${profile.handle}`, - target: "_blank", - rel: "noopener", - }, - Avatar({ avatar: profile.avatar }), - ), - ), - div( - { class: "content" }, - div( - { class: "name-and-controller" }, - div( - p( - { class: "display-name" }, - a( - { - href: `https://bsky.app/profile/${profile.handle}`, - target: "_blank", - rel: "noopener", - }, - profile.displayName ?? profile.handle, - ), - ), - p({ class: "handle" }, `@${profile.handle}`), - ), - div( - ActionButton({ - profile, - statusKey, - btnLabel, - addAction, - removeAction, - }), - ), - ), - profile.description - ? p({ class: "description" }, profile.description) - : "", - ), - ), - ); -}; diff --git a/src/lib/components/NotFoundCell.ts b/src/lib/components/NotFoundCell.ts deleted file mode 100644 index 1607d00..0000000 --- a/src/lib/components/NotFoundCell.ts +++ /dev/null @@ -1,35 +0,0 @@ -import van from "vanjs-core"; - -const { div, p } = van.tags; -const { svg, path } = van.tagsNS("http://www.w3.org/2000/svg"); - -const WarningIcon = () => - svg( - { - fill: "none", - "stroke-width": "1.5", - stroke: "currentColor", - class: "w-6 h-6", - viewBox: "0 0 24 24", - }, - path({ - "stroke-linecap": "round", - "stroke-linejoin": "round", - d: "M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z", - }), - ); - -export const NotFoundCell = () => - div( - { class: "bsky-user-content-wrapper" }, - div( - { class: "bsky-user-content bsky-user-content__not-found bsky-fade-in" }, - WarningIcon(), - p( - { - class: "not-found", - }, - "No similar users found.", - ), - ), - ); diff --git a/src/lib/components/ReloadBtn.ts b/src/lib/components/ReloadBtn.ts deleted file mode 100644 index 3b248bf..0000000 --- a/src/lib/components/ReloadBtn.ts +++ /dev/null @@ -1,24 +0,0 @@ -import van from "vanjs-core"; - -const { button, div } = van.tags; - -export const ReloadButton = ({ clickAction }: { clickAction: () => void }) => { - const deleted = van.state(false); - - return () => - deleted.val - ? null - : div( - { class: "bsky-reload-btn-wrapper" }, - button( - { - class: "bsky-reload-btn bsky-fade-in", - onclick: () => { - clickAction(); - deleted.val = true; - }, - }, - "Find More", - ), - ); -}; diff --git a/src/lib/domHelpers.ts b/src/lib/domHelpers.ts index aafc12a..f39fbc9 100644 --- a/src/lib/domHelpers.ts +++ b/src/lib/domHelpers.ts @@ -1,13 +1,3 @@ -import type { - ProfileView, - ViewerState, -} from "@atproto/api/dist/client/types/app/bsky/actor/defs"; -import van from "vanjs-core"; -import { BskyUserCell, type UserCellBtnLabel } from "./components/BskyUserCell"; -import { NotFoundCell } from "./components/NotFoundCell"; -import { ReloadButton } from "./components/ReloadBtn"; -import type { BSKY_USER_MATCH_TYPE } from "./constants"; - export const getUserCells = ({ queryParam, filterInsertedElement, @@ -29,20 +19,6 @@ export const getUserCells = ({ return Array.from(userCells); }; -export const insertReloadEl = (clickAction: () => void) => { - const lastInsertedEl = Array.from( - document.querySelectorAll(".bsky-user-content"), - ).at(-1); - van.add(lastInsertedEl.parentElement, ReloadButton({ clickAction })); -}; - -export const removeReloadEl = () => { - const reloadEl = document.querySelectorAll(".bsky-reload-btn-wrapper"); - for (const el of reloadEl) { - el.remove(); - } -}; - export const getAccountNameAndDisplayName = (userCell: Element) => { const [avatarEl, displayNameEl] = userCell.querySelectorAll("a"); const twAccountName = avatarEl?.getAttribute("href")?.replace("/", ""); @@ -50,42 +26,3 @@ export const getAccountNameAndDisplayName = (userCell: Element) => { const twDisplayName = displayNameEl?.textContent; return { twAccountName, twDisplayName, twAccountNameRemoveUnderscore }; }; - -export const insertBskyProfileEl = ({ - dom, - profile, - statusKey, - btnLabel, - matchType, - addAction, - removeAction, -}: { - dom: Element; - profile: ProfileView; - statusKey: keyof ViewerState; - btnLabel: UserCellBtnLabel; - matchType: (typeof BSKY_USER_MATCH_TYPE)[keyof typeof BSKY_USER_MATCH_TYPE]; - addAction: () => Promise; - removeAction: () => Promise; -}) => { - van.add( - dom.parentElement, - BskyUserCell({ - profile, - statusKey, - btnLabel, - matchType, - addAction, - removeAction, - }), - ); -}; - -export const insertNotFoundEl = (dom: Element) => { - van.add(dom.parentElement, NotFoundCell()); -}; - -export const isOutOfTopViewport = (el: Element) => { - const rect = el.getBoundingClientRect(); - return rect.top < 0; -}; diff --git a/src/lib/searchAndInsertBskyUsers.ts b/src/lib/searchAndInsertBskyUsers.ts deleted file mode 100644 index d9aac66..0000000 --- a/src/lib/searchAndInsertBskyUsers.ts +++ /dev/null @@ -1,142 +0,0 @@ -import type { ViewerState } from "@atproto/api/dist/client/types/app/bsky/actor/defs"; -import { isSimilarUser } from "~lib/bskyHelpers"; -import { - getAccountNameAndDisplayName, - getUserCells, - insertBskyProfileEl, - insertNotFoundEl, - insertReloadEl, -} from "~lib/domHelpers"; -import { debugLog, isOneSymbol } from "~lib/utils"; -import type { BskyClient } from "./bskyClient"; -import type { BskyServiceWorkerClient } from "./bskyServiceWorkerClient"; -import type { UserCellBtnLabel } from "./components/BskyUserCell"; -import { isOutOfTopViewport, removeReloadEl } from "./domHelpers"; - -const notFoundUserCache = new Set(); - -const bskyUserUrlMap = new Map(); - -export const searchAndInsertBskyUsers = async ({ - agent, - btnLabel, - userCellQueryParam, - statusKey, - addQuery, - removeQuery, -}: { - agent: BskyServiceWorkerClient | BskyClient; - userCellQueryParam: string; - btnLabel: UserCellBtnLabel; - statusKey: keyof ViewerState; - // biome-ignore lint: - addQuery: (arg: string) => Promise; - // biome-ignore lint: - removeQuery: (arg: string) => Promise; -}) => { - removeReloadEl(); - - const userCells = getUserCells({ - queryParam: userCellQueryParam, - filterInsertedElement: true, - }); - 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, twAccountNameRemoveUnderscore } = - getAccountNameAndDisplayName(userCell); - - if (notFoundUserCache.has(twAccountName)) { - insertNotFoundEl(userCell); - continue; - } - - const searchTerms = [twAccountNameRemoveUnderscore, twDisplayName]; - - let targetAccount = null; - let matchType = null; - - // Loop over search parameters and break if a user is found - searchLoop: for (const term of searchTerms) { - // one symbol is not a valid search term for bsky - if (!term || isOneSymbol(term)) { - continue; - } - try { - const searchResults = await agent.searchUser({ - term: term, - limit: 3, - }); - - for (const searchResult of searchResults) { - const { isSimilar: isUserFound, type } = isSimilarUser( - { - accountName: twAccountName, - accountNameRemoveUnderscore: twAccountNameRemoveUnderscore, - displayName: twDisplayName, - }, - searchResult, - ); - - if (isUserFound) { - targetAccount = searchResult; - matchType = type; - break searchLoop; // Stop searching when a user is found - } - } - } catch (e) { - console.error(e); - } - } - - // insert bsky profile or not found element - if (targetAccount) { - insertBskyProfileEl({ - dom: userCell, - profile: targetAccount, - statusKey, - btnLabel, - matchType, - addAction: async () => { - const result = await addQuery(targetAccount.did); - bskyUserUrlMap.set(targetAccount.did, result.uri); - }, - removeAction: async () => { - if (targetAccount?.viewer?.following) { - await removeQuery(targetAccount?.viewer?.following); - } else { - await removeQuery(bskyUserUrlMap.get(targetAccount.did)); - } - }, - }); - } else { - insertNotFoundEl(userCell); - notFoundUserCache.add(twAccountName); - } - - index++; - - if (process.env.NODE_ENV === "development" && index > 5) { - break; - } - } - - // TODO: if there are more users, insert reload button - insertReloadEl(async () => { - await searchAndInsertBskyUsers({ - agent, - btnLabel, - userCellQueryParam, - statusKey, - addQuery, - removeQuery, - }); - }); -}; diff --git a/src/lib/searchBskyUsers.ts b/src/lib/searchBskyUsers.ts index a45deef..20d1e9f 100644 --- a/src/lib/searchBskyUsers.ts +++ b/src/lib/searchBskyUsers.ts @@ -3,9 +3,6 @@ import { isSimilarUser } from "~lib/bskyHelpers"; import { getAccountNameAndDisplayName, getUserCells, - insertBskyProfileEl, - insertNotFoundEl, - insertReloadEl, } from "~lib/domHelpers"; import { debugLog, isOneSymbol } from "~lib/utils"; import type { BskyClient } from "./bskyClient"; @@ -63,85 +60,3 @@ export const searchBskyUser = async ({ return null; }; - -export const searchBskyUsers = async ({ - agent, - userCellQueryParam, -}: { - agent: BskyServiceWorkerClient | BskyClient; - userCellQueryParam: string; -}) => { - const userCells = getUserCells({ - queryParam: userCellQueryParam, - filterInsertedElement: true, - }); - debugLog(`userCells length: ${userCells.length}`); - - let index = 0; - - const targetAccounts = [] as ProfileView[]; - - // loop over twitter user profile cells and search and insert bsky user - for (const userCell of userCells) { - const { twAccountName, twDisplayName, twAccountNameRemoveUnderscore } = - getAccountNameAndDisplayName(userCell); - - if (notFoundUserCache.has(twAccountName)) { - insertNotFoundEl(userCell); - continue; - } - - const searchTerms = [twAccountNameRemoveUnderscore, twDisplayName]; - - let targetAccount = null; - let matchType = null; - - // Loop over search parameters and break if a user is found - searchLoop: for (const term of searchTerms) { - // one symbol is not a valid search term for bsky - if (!term || isOneSymbol(term)) { - continue; - } - try { - const searchResults = await agent.searchUser({ - term: term, - limit: 3, - }); - - for (const searchResult of searchResults) { - const { isSimilar: isUserFound, type } = isSimilarUser( - { - accountName: twAccountName, - accountNameRemoveUnderscore: twAccountNameRemoveUnderscore, - displayName: twDisplayName, - }, - searchResult, - ); - - if (isUserFound) { - targetAccount = searchResult; - matchType = type; - break searchLoop; // Stop searching when a user is found - } - } - } catch (e) { - console.error(e); - } - } - - // insert bsky profile or not found element - if (targetAccount) { - targetAccounts.push(targetAccount); - } else { - notFoundUserCache.add(twAccountName); - } - - index++; - - // if (process.env.NODE_ENV === "development" && index > 5) { - // break - // } - } - - return targetAccounts; -};