🚀 support for firefox

This commit is contained in:
kawamataryo 2023-08-25 23:26:36 +09:00
parent 0e4c201394
commit 36f590f1a6
12 changed files with 206 additions and 10 deletions

View File

@ -1,4 +1,4 @@
name: "Publish to Chrome Web Store" name: "Publish to Extension Store"
on: on:
push: push:
branches: branches:
@ -64,12 +64,12 @@ jobs:
run: npx changeset tag run: npx changeset tag
- name: Build the extension - name: Build the extension
run: npm run build run: npm run build && npm run build:firefox
- name: Package the extension into a zip artifact - name: Package the extension into a zip artifact
run: npm run package run: npm run package && npm run package:firefox
- name: Publish to Chrome Web Store - name: Publish to Extension Store
uses: PlasmoHQ/bpp@v3 uses: PlasmoHQ/bpp@v3
with: with:
keys: ${{ secrets.PUBLISH_KEYS }} keys: ${{ secrets.PUBLISH_KEYS }}

View File

@ -11,6 +11,7 @@ https://github.com/kawamataryo/sky-follower-bridge/assets/11070996/0c87f9b9-573f
## 📦 Installation ## 📦 Installation
- [Chrome Web Store](https://chrome.google.com/webstore/detail/sky-follower-bridge/behhbpbpmailcnfbjagknjngnfdojpko) - [Chrome Web Store](https://chrome.google.com/webstore/detail/sky-follower-bridge/behhbpbpmailcnfbjagknjngnfdojpko)
- [Firefox Add-ons](https://addons.mozilla.org/ja/firefox/addon/sky-follower-bridge/)
## 🚀 How to use ## 🚀 How to use
1. Open your Twitter [Follower](https://twitter.com/following) or [Follow](https://twitter.com/followers) or [list members](), [blocking](https://twitter.com/settings/blocked/all) page. 1. Open your Twitter [Follower](https://twitter.com/following) or [Follow](https://twitter.com/followers) or [list members](), [blocking](https://twitter.com/settings/blocked/all) page.

View File

@ -0,0 +1,13 @@
import type { PlasmoMessaging } from "@plasmohq/messaging"
import { BskyClient } from "~lib/bskyClient";
const handler: PlasmoMessaging.MessageHandler = async (req, res) => {
const { session, subjectDid } = req.body
const client = BskyClient.createAgentFromSession(session)
res.send({
result: await client.block(subjectDid)
})
}
export default handler

View File

@ -0,0 +1,13 @@
import type { PlasmoMessaging } from "@plasmohq/messaging"
import { BskyClient } from "~lib/bskyClient";
const handler: PlasmoMessaging.MessageHandler = async (req, res) => {
const { session, subjectDid } = req.body
const client = BskyClient.createAgentFromSession(session)
res.send({
result: await client.follow(subjectDid)
})
}
export default handler

View File

@ -0,0 +1,17 @@
import type { PlasmoMessaging } from "@plasmohq/messaging"
import { BskyClient } from "../../lib/bskyClient";
const handler: PlasmoMessaging.MessageHandler = async (req, res) => {
const { identifier, password } = req.body
const agent = await BskyClient.createAgent({
identifier,
password,
})
res.send({
session: agent.session,
})
}
export default handler

View File

@ -0,0 +1,16 @@
import type { PlasmoMessaging } from "@plasmohq/messaging"
import { BskyClient } from "~lib/bskyClient";
const handler: PlasmoMessaging.MessageHandler = async (req, res) => {
const { session, term, limit } = req.body
const client = BskyClient.createAgentFromSession(session)
res.send({
actors: await client.searchUser({
term,
limit,
})
})
}
export default handler

View File

@ -0,0 +1,13 @@
import type { PlasmoMessaging } from "@plasmohq/messaging"
import { BskyClient } from "~lib/bskyClient";
const handler: PlasmoMessaging.MessageHandler = async (req, res) => {
const { session, blockUri } = req.body
const client = BskyClient.createAgentFromSession(session)
res.send({
result: await client.unblock(blockUri)
})
}
export default handler

View File

@ -0,0 +1,13 @@
import type { PlasmoMessaging } from "@plasmohq/messaging"
import { BskyClient } from "~lib/bskyClient";
const handler: PlasmoMessaging.MessageHandler = async (req, res) => {
const { session, followUri } = req.body
const client = BskyClient.createAgentFromSession(session)
res.send({
result: await client.unfollow(followUri)
})
}
export default handler

View File

@ -1,8 +1,9 @@
import { BskyClient, type BskyLoginParams } from "./lib/bskyClient"; import { 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 { searchAndInsertBskyUsers } from '~lib/searchAndInsertBskyUsers'; import { searchAndInsertBskyUsers } from '~lib/searchAndInsertBskyUsers';
import { BskyServiceWorkerClient } from "~lib/bskyServiceWorkerClient";
export const config: PlasmoCSConfig = { export const config: PlasmoCSConfig = {
matches: ["https://twitter.com/*", "https://x.com/*"], matches: ["https://twitter.com/*", "https://x.com/*"],
@ -15,10 +16,11 @@ const searchAndShowBskyUsers = async ({
messageName, messageName,
}: BskyLoginParams & { messageName: string }) => { }: BskyLoginParams & { messageName: string }) => {
const agent = await BskyClient.createAgent({ const agent = await BskyServiceWorkerClient.createAgent({
identifier, identifier,
password, password,
}) });
switch (messageName) { switch (messageName) {
case MESSAGE_NAMES.SEARCH_BSKY_USER_ON_FOLLOW_PAGE: case MESSAGE_NAMES.SEARCH_BSKY_USER_ON_FOLLOW_PAGE:
await searchAndInsertBskyUsers({ await searchAndInsertBskyUsers({

View File

@ -1,4 +1,4 @@
import { AtUri, BskyAgent } from "@atproto/api"; import { AtUri, BskyAgent, type AtpSessionData } from "@atproto/api";
export type BskyLoginParams = { export type BskyLoginParams = {
identifier: string; identifier: string;
@ -13,9 +13,24 @@ export class BskyClient {
email: string; email: string;
}; };
agent: BskyAgent; agent: BskyAgent;
session = {}
private constructor() { private constructor() {
this.agent = new BskyAgent({ service: this.service }); this.agent = new BskyAgent({ service: this.service, persistSession: (evt, session) => {
this.session = session
} });
}
public static createAgentFromSession(session: AtpSessionData): BskyClient {
const client = new BskyClient();
client.agent.resumeSession(session);
client.me = {
did: session.did,
handle: session.handle,
email: session.email,
}
return client;
} }
public static async createAgent({ public static async createAgent({

View File

@ -0,0 +1,92 @@
import { sendToBackground } from "@plasmohq/messaging";
export type BskyLoginParams = {
identifier: string;
password: string;
}
export class BskyServiceWorkerClient {
private session = {}
private constructor() {
}
public static async createAgent({
identifier,
password,
}: BskyLoginParams): Promise<BskyServiceWorkerClient> {
const client = new BskyServiceWorkerClient();
const { session } = await sendToBackground({
name: "login",
body: {
identifier,
password,
}
})
client.session = session
return client;
}
public searchUser = async ({
term,
limit,
}: {
term: string;
limit: number;
}) => {
const { actors } = await sendToBackground({
name: "searchUser",
body: {
session: this.session,
term,
limit,
}
})
return actors;
};
public follow = async (subjectDid: string) => {
const { result } = await sendToBackground({
name: "follow",
body: {
session: this.session,
subjectDid
}
})
return result;
}
public unfollow = async (followUri: string) => {
const { result } = await sendToBackground({
name: "unfollow",
body: {
session: this.session,
followUri
}
})
return result;
}
public block = async (subjectDid: string) => {
const { result } = await sendToBackground({
name: "block",
body: {
session: this.session,
subjectDid
}
})
return result;
}
public unblock = async (blockUri: string) => {
// TODO: unblock is not working. Need to fix it.
const { result } = await sendToBackground({
name: "unblock",
body: {
session: this.session,
blockUri
}
})
return result;
}
}

View File

@ -5,6 +5,7 @@ import { debugLog } from "~lib/utils";
import type { BskyClient } from './bskyClient'; import type { BskyClient } from './bskyClient';
import type { ViewerState } from '@atproto/api/dist/client/types/app/bsky/actor/defs'; import type { ViewerState } from '@atproto/api/dist/client/types/app/bsky/actor/defs';
import type { UserCellBtnLabel } from './components/BskyUserCell'; import type { UserCellBtnLabel } from './components/BskyUserCell';
import type { BskyServiceWorkerClient } from './bskyServiceWorkerClient';
const notFoundUserCache = new Set<string>() const notFoundUserCache = new Set<string>()
@ -20,7 +21,7 @@ export const searchAndInsertBskyUsers = async (
addQuery, addQuery,
removeQuery, removeQuery,
}: { }: {
agent: BskyClient, agent: BskyServiceWorkerClient | BskyClient,
userCellQueryParam: string, userCellQueryParam: string,
btnLabel: UserCellBtnLabel, btnLabel: UserCellBtnLabel,
statusKey: keyof ViewerState, statusKey: keyof ViewerState,