diff --git a/src/background/messages/addUserToList.ts b/src/background/messages/addUserToList.ts new file mode 100644 index 0000000..ba0f053 --- /dev/null +++ b/src/background/messages/addUserToList.ts @@ -0,0 +1,21 @@ +import type { PlasmoMessaging } from "@plasmohq/messaging"; +import { BskyClient } from "~lib/bskyClient"; + +const handler: PlasmoMessaging.MessageHandler = async (req, res) => { + const { session, userDid, listUri } = req.body; + const client = await BskyClient.createAgentFromSession(session); + + try { + res.send({ + result: await client.addUserToList({ userDid, listUri }), + }); + } catch (e) { + res.send({ + error: { + message: e.message, + }, + }); + } +}; + +export default handler; diff --git a/src/background/messages/createList.ts b/src/background/messages/createList.ts new file mode 100644 index 0000000..9bf7e03 --- /dev/null +++ b/src/background/messages/createList.ts @@ -0,0 +1,21 @@ +import type { PlasmoMessaging } from "@plasmohq/messaging"; +import { BskyClient } from "~lib/bskyClient"; + +const handler: PlasmoMessaging.MessageHandler = async (req, res) => { + const { session, name, description } = req.body; + const client = await BskyClient.createAgentFromSession(session); + + try { + res.send({ + uri: await client.createList({ name, description }), + }); + } catch (e) { + res.send({ + error: { + message: e.message, + }, + }); + } +}; + +export default handler; diff --git a/src/background/messages/createListAndAddUsers.ts b/src/background/messages/createListAndAddUsers.ts new file mode 100644 index 0000000..da1f917 --- /dev/null +++ b/src/background/messages/createListAndAddUsers.ts @@ -0,0 +1,35 @@ +import type { PlasmoMessaging } from "@plasmohq/messaging"; +import { BskyClient } from "~lib/bskyClient"; +import { STORAGE_KEYS } from "~lib/constants"; + +const handler: PlasmoMessaging.MessageHandler = async (req, res) => { + const { name, description, userDids } = req.body; + + const storage = await chrome.storage.local.get( + STORAGE_KEYS.BSKY_CLIENT_SESSION, + ); + const session = storage[STORAGE_KEYS.BSKY_CLIENT_SESSION]; + + if (!session || !session.did) { + res.send({ + error: { + message: "Invalid session data", + }, + }); + return; + } + + try { + const client = await BskyClient.createAgentFromSession(session); + await client.createListAndAddUsers({ name, description, userDids }); + res.send({ success: true }); + } catch (e) { + res.send({ + error: { + message: e.message, + }, + }); + } +}; + +export default handler; diff --git a/src/contents/App.tsx b/src/contents/App.tsx index 1aa71b7..ae7a62b 100644 --- a/src/contents/App.tsx +++ b/src/contents/App.tsx @@ -29,6 +29,7 @@ const App = () => { restart, isBottomReached, errorMessage, + listName, } = useRetrieveBskyUsers(); const [isModalOpen, setIsModalOpen] = React.useState(false); @@ -72,7 +73,10 @@ const App = () => { const stopAndShowDetectedUsers = async () => { stopRetrieveLoop(); - await chrome.storage.local.set({ users: JSON.stringify(users) }); + await chrome.storage.local.set({ + users: JSON.stringify(users), + listName: listName, + }); openOptionPage(); }; diff --git a/src/lib/bskyClient.ts b/src/lib/bskyClient.ts index e3a9195..daa1a77 100644 --- a/src/lib/bskyClient.ts +++ b/src/lib/bskyClient.ts @@ -114,4 +114,59 @@ export class BskyClient { rkey, }); }; + + public createList = async ({ + name, + description, + }: { + name: string; + description: string; + }) => { + const result = await this.agent.com.atproto.repo.createRecord({ + repo: this.me.did, + collection: "app.bsky.graph.list", + record: { + $type: "app.bsky.graph.list", + purpose: "app.bsky.graph.defs#curatelist", + name, + description, + createdAt: new Date().toISOString(), + }, + }); + return result.data.uri; + }; + + public addUserToList = async ({ + userDid, + listUri, + }: { + userDid: string; + listUri: string; + }) => { + return await this.agent.com.atproto.repo.createRecord({ + repo: this.me.did, + collection: "app.bsky.graph.listitem", + record: { + $type: "app.bsky.graph.listitem", + subject: userDid, + list: listUri, + createdAt: new Date().toISOString(), + }, + }); + }; + + public createListAndAddUsers = async ({ + name, + description, + userDids, + }: { + name: string; + description: string; + userDids: string[]; + }) => { + const listUri = await this.createList({ name, description }); + for (const userDid of userDids) { + await this.addUserToList({ userDid, listUri }); + } + }; } diff --git a/src/lib/bskyServiceWorkerClient.ts b/src/lib/bskyServiceWorkerClient.ts index 6a72c15..1cb7ede 100644 --- a/src/lib/bskyServiceWorkerClient.ts +++ b/src/lib/bskyServiceWorkerClient.ts @@ -110,4 +110,59 @@ export class BskyServiceWorkerClient { return result; }; + + public createList = async ({ + name, + description, + }: { + name: string; + description: string; + }) => { + const { uri, error } = await sendToBackground({ + name: "createList", + body: { + session: this.session, + name, + description, + }, + }); + if (error) throw new Error(error.message); + + return uri; + }; + + public addUserToList = async ({ + userDid, + listUri, + }: { + userDid: string; + listUri: string; + }) => { + const { result, error } = await sendToBackground({ + name: "addUserToList", + body: { + session: this.session, + userDid, + listUri, + }, + }); + if (error) throw new Error(error.message); + + return result; + }; + + public createListAndAddUsers = async ({ + name, + description, + userDids, + }: { + name: string; + description: string; + userDids: string[]; + }) => { + const listUri = await this.createList({ name, description }); + for (const userDid of userDids) { + await this.addUserToList({ userDid, listUri }); + } + }; } diff --git a/src/lib/components/Sidebar.tsx b/src/lib/components/Sidebar.tsx index db6589b..24aad8e 100644 --- a/src/lib/components/Sidebar.tsx +++ b/src/lib/components/Sidebar.tsx @@ -25,6 +25,19 @@ const Sidebar = ({ actionMode, matchTypeStats, }: Props) => { + const getActionLabel = () => { + switch (actionMode) { + case ACTION_MODE.FOLLOW: + return "Follow All"; + case ACTION_MODE.BLOCK: + return "Block All"; + case ACTION_MODE.IMPORT_LIST: + return "Import List"; + default: + return ""; + } + }; + return (