mirror of
https://github.com/snachodog/tok-to-insta-follower-bridge.git
synced 2025-09-13 07:23:32 -06:00
🚀 implement batch search feature
This commit is contained in:
129
src/contents/App.tsx
Normal file
129
src/contents/App.tsx
Normal file
@@ -0,0 +1,129 @@
|
||||
import type { PlasmoCSConfig } from "plasmo";
|
||||
import React from "react";
|
||||
import AlertError from "~lib/components/AlertError";
|
||||
import AlertSuccess from "~lib/components/AlertSuccess";
|
||||
import MatchTypeFilter from "~lib/components/MatchTypeFilter";
|
||||
import Modal from "~lib/components/Modal";
|
||||
import UserCard from "~lib/components/UserCard";
|
||||
import UserCardSkeleton from "~lib/components/UserCardSkeleton";
|
||||
import { MESSAGE_NAMES } from "~lib/constants";
|
||||
import { useRetrieveBskyUsers } from "~lib/hooks/useRetrieveBskyUsers";
|
||||
import cssText from "data-text:~style.content.css";
|
||||
|
||||
export const config: PlasmoCSConfig = {
|
||||
matches: ["https://twitter.com/*", "https://x.com/*"],
|
||||
all_frames: true,
|
||||
};
|
||||
|
||||
export const getStyle = () => {
|
||||
const style = document.createElement("style");
|
||||
// patch for shadow dom
|
||||
style.textContent = cssText.replaceAll(":root", ":host");
|
||||
return style;
|
||||
};
|
||||
|
||||
const App = () => {
|
||||
const {
|
||||
initialize,
|
||||
modalRef,
|
||||
users,
|
||||
loading,
|
||||
handleClickAction,
|
||||
actionMode,
|
||||
errorMessage,
|
||||
restart,
|
||||
isRateLimitError,
|
||||
isSucceeded,
|
||||
matchTypeFilter,
|
||||
changeMatchTypeFilter,
|
||||
filteredUsers,
|
||||
} = useRetrieveBskyUsers();
|
||||
|
||||
React.useEffect(() => {
|
||||
const messageHandler = (
|
||||
message: {
|
||||
name: (typeof MESSAGE_NAMES)[keyof typeof MESSAGE_NAMES];
|
||||
body: {
|
||||
userId: string;
|
||||
password: string;
|
||||
};
|
||||
},
|
||||
_sender: chrome.runtime.MessageSender,
|
||||
sendResponse: (response?: Record<string, unknown>) => void,
|
||||
) => {
|
||||
if (Object.values(MESSAGE_NAMES).includes(message.name)) {
|
||||
initialize({
|
||||
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;
|
||||
};
|
||||
|
||||
chrome.runtime.onMessage.addListener(messageHandler);
|
||||
return () => {
|
||||
chrome.runtime.onMessage.removeListener(messageHandler);
|
||||
};
|
||||
}, [initialize]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal anchorRef={modalRef}>
|
||||
<div className="flex flex-col gap-6">
|
||||
<div className="flex justify-between">
|
||||
<h1 className="text-2xl font-bold">Find Bluesky Users</h1>
|
||||
<div className="flex gap-3 items-center">
|
||||
{loading && (
|
||||
<p className="loading loading-spinner loading-md text-primary" />
|
||||
)}
|
||||
<p className="text-sm">Detected:</p>
|
||||
<p className="font-bold text-xl">{users.length}</p>
|
||||
</div>
|
||||
</div>
|
||||
<MatchTypeFilter
|
||||
value={matchTypeFilter}
|
||||
onChange={changeMatchTypeFilter}
|
||||
/>
|
||||
{isSucceeded && (
|
||||
<AlertSuccess>
|
||||
<span className="font-bold">{users.length}</span> Bluesky accounts
|
||||
detected.
|
||||
</AlertSuccess>
|
||||
)}
|
||||
{errorMessage && (
|
||||
<AlertError retryAction={isRateLimitError ? restart : undefined}>
|
||||
{errorMessage}
|
||||
</AlertError>
|
||||
)}
|
||||
<div className="flex flex-col gap-4 overflow-scroll max-h-[60vh]">
|
||||
{filteredUsers.length > 0 ? (
|
||||
<div className="">
|
||||
{filteredUsers.map((user) => (
|
||||
<UserCard
|
||||
key={user.handle}
|
||||
user={user}
|
||||
clickAction={handleClickAction}
|
||||
actionMode={actionMode}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
loading && <UserCardSkeleton />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
90
src/contents/content.ts
Normal file
90
src/contents/content.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
// 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;
|
||||
// });
|
Reference in New Issue
Block a user