add unfollow action

This commit is contained in:
kawamataryo 2023-05-21 22:02:59 +09:00
parent 4d46a620e4
commit c08c857e36
4 changed files with 87 additions and 22 deletions

View File

@ -15,6 +15,8 @@ let abortController = new AbortController();
const notFoundUserCache = new Set<string>()
const followerUrlMap = new Map<string, string>()
const initialize = async () => {
abortController.abort()
abortController = new AbortController()
@ -47,13 +49,24 @@ const searchBskyUsers = async ({
limit: 1,
})
// TODO: Refactor, this is duplicated
// first, search by account name
if (isSimilarUser(twDisplayName, searchResultByAccountName) || isSimilarUser(twAccountName, searchResultByAccountName)) {
insertBskyProfileEl({
dom: userCell,
profile: searchResultByAccountName,
abortController,
clickAction: async () => { await agent.follow(searchResultByAccountName.did) }
followAction: async () => {
const result = await agent.follow(searchResultByAccountName.did);
followerUrlMap.set(searchResultByAccountName.did, result.uri)
},
unfollowAction: async () => {
if(searchResultByAccountName?.viewer?.following) {
await agent.unfollow(searchResultByAccountName?.viewer?.following);
} else {
await agent.unfollow(followerUrlMap.get(searchResultByAccountName.did));
}
},
})
} else {
// if not found, search by display name
@ -66,30 +79,35 @@ const searchBskyUsers = async ({
dom: userCell,
profile: searchResultByDisplayName,
abortController,
clickAction: async () => { await agent.follow(searchResultByAccountName.did) }
followAction: async () => {
const result = await agent.follow(searchResultByDisplayName.did);
followerUrlMap.set(searchResultByDisplayName.did, result.uri)
},
unfollowAction: async () => {
if(searchResultByDisplayName?.viewer?.following) {
await agent.unfollow(searchResultByDisplayName?.viewer?.following);
} else {
await agent.unfollow(followerUrlMap.get(searchResultByDisplayName.did));
}
},
})
} else {
insertNotFoundEl(userCell)
notFoundUserCache.add(twAccountName)
}
}
if (process.env.NODE_ENV === "development" && index > 100) {
if (process.env.NODE_ENV === "development" && index > 5) {
break
}
}
// if there are more users, insert reload button
const finishedUserCells = getUserCells({
filterInsertedElement: false
})
if (finishedUserCells.at(-1) !== userCells.at(-1)) {
insertReloadEl(async () => {
await searchBskyUsers({
userId,
password,
})
// TODO: if there are more users, insert reload button
insertReloadEl(async () => {
await searchBskyUsers({
userId,
password,
})
}
})
}

View File

@ -1,4 +1,4 @@
import { AppBskyFeedPost, AppBskyRichtextFacet, BskyAgent } from "@atproto/api";
import { BskyAgent } from "@atproto/api";
export class BskyClient {
private service = "https://bsky.social";
@ -34,6 +34,10 @@ export class BskyClient {
};
public follow = async (subjectDid: string) => {
await this.agent.follow(subjectDid);
return await this.agent.follow(subjectDid);
}
public unfollow = async (followUri: string) => {
return await this.agent.deleteFollow(followUri);
}
}

View File

@ -46,7 +46,7 @@ export const getAccountNameAndDisplayName = (userCell: Element) => {
const twDisplayName = displayNameEl?.textContent
return { twAccountName, twDisplayName }
}
export const insertBskyProfileEl = ({ dom, profile, abortController, clickAction }: { dom: Element, profile: ProfileView, abortController: AbortController, clickAction: () => void }) => {
export const insertBskyProfileEl = ({ dom, profile, abortController, followAction, unfollowAction }: { dom: Element, profile: ProfileView, abortController: AbortController, followAction: () => void, unfollowAction: () => void }) => {
const avatarEl = profile.avatar ? `<img src="${profile.avatar}" width="48" />` : "<div class='no-avatar'></div>"
const followButtonEl = profile.viewer?.following ? "<button class='follow-button follow-button__following'>Following on Bluesky</button>" : "<button class='follow-button'>Follow on Bluesky</button>"
dom.insertAdjacentHTML('afterend', `
@ -68,20 +68,55 @@ export const insertBskyProfileEl = ({ dom, profile, abortController, clickAction
</div>
${profile.description ? `<p class="description">${profile.description}</p>` : ""}
</div>
<simple-greeting></simple-greeting>
</div>
`)
dom.nextElementSibling?.addEventListener('click', async (e) => {
// TODO: Add unfollow action
const bskyUserContentDom = dom.nextElementSibling as Element
// register a click action
bskyUserContentDom?.addEventListener('click', async (e) => {
const target = e.target as Element
const classList = target.classList
// follow action
if (classList.contains('follow-button') && !classList.contains('follow-button__following')) {
target.textContent = "processing..."
target.classList.add('follow-button__processing')
await clickAction()
await followAction()
target.textContent = "Following on Bluesky"
target.classList.remove('follow-button__processing')
target.classList.add('follow-button__following')
return
}
// unfollow action
if (classList.contains('follow-button') && classList.contains('follow-button__following')) {
target.textContent = "processing..."
target.classList.add('follow-button__processing')
await unfollowAction()
target.textContent = "Follow on Bluesky"
target.classList.remove('follow-button__processing')
target.classList.remove('follow-button__following')
return
}
}, {
signal: abortController.signal
})
// register a hover action
bskyUserContentDom?.addEventListener('mouseover', async (e) => {
const target = e.target as Element
const classList = target.classList
if (classList.contains('follow-button') && classList.contains('follow-button__following')) {
target.textContent = "Unfollow on Bluesky"
}
}, {
signal: abortController.signal
})
bskyUserContentDom?.addEventListener('mouseout', async (e) => {
const target = e.target as Element
const classList = target.classList
if (classList.contains('follow-button') && classList.contains('follow-button__following')) {
target.textContent = "Following on Bluesky"
}
}, {
signal: abortController.signal

View File

@ -78,12 +78,20 @@
.name-and-controller .follow-button__following {
background: transparent;
color: #fff;
cursor: auto;
cursor: pointer;
}
.name-and-controller .follow-button__following:hover {
background: rgba(255, 0, 0, 0.1);
color: red;
border: 1px solid red;
cursor: pointer;
}
.name-and-controller .follow-button__processing {
background: rgb(255,255,255, 0.3);;
color: #fff;
border: 1px solid #fff;
cursor: auto;
}