mirror of
https://github.com/snachodog/tok-to-insta-follower-bridge.git
synced 2025-04-23 20:12:22 -06:00
🎨 add match type label
This commit is contained in:
parent
3bec59a08e
commit
160575e016
@ -1,19 +1,40 @@
|
|||||||
import type { ProfileView } from "@atproto/api/dist/client/types/app/bsky/actor/defs"
|
import type { ProfileView } from "@atproto/api/dist/client/types/app/bsky/actor/defs"
|
||||||
|
import { BSKY_USER_MATCH_TYPE } from "./constants"
|
||||||
|
|
||||||
export const isSimilarUser = (terms: string[], bskyProfile: ProfileView | undefined) => {
|
export const isSimilarUser = (terms: string[], bskyProfile: ProfileView | undefined): {
|
||||||
if(!bskyProfile) { return false }
|
isSimilar: boolean,
|
||||||
|
type: typeof BSKY_USER_MATCH_TYPE[keyof typeof BSKY_USER_MATCH_TYPE],
|
||||||
|
} => {
|
||||||
|
if (!bskyProfile) {
|
||||||
|
return {
|
||||||
|
isSimilar: false,
|
||||||
|
type: BSKY_USER_MATCH_TYPE.NONE,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return terms.some(term => {
|
for (const term of terms) {
|
||||||
const lowerCaseName = term.toLocaleLowerCase()
|
const lowerCaseName = term.toLocaleLowerCase()
|
||||||
if(lowerCaseName === bskyProfile?.handle.toLocaleLowerCase().replace("@", "").split('.')[0]) {
|
if (lowerCaseName === bskyProfile?.handle.toLocaleLowerCase().replace("@", "").split('.')[0]) {
|
||||||
return true
|
return {
|
||||||
|
isSimilar: true,
|
||||||
|
type: BSKY_USER_MATCH_TYPE.HANDLE,
|
||||||
}
|
}
|
||||||
if(lowerCaseName === bskyProfile.displayName?.toLocaleLowerCase()) {
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
if(bskyProfile.description?.toLocaleLowerCase().includes(lowerCaseName)) {
|
if (lowerCaseName === bskyProfile.displayName?.toLocaleLowerCase()) {
|
||||||
return true
|
return {
|
||||||
|
isSimilar: true,
|
||||||
|
type: BSKY_USER_MATCH_TYPE.DISPLAY_NAME,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bskyProfile.description?.toLocaleLowerCase().includes(lowerCaseName)) {
|
||||||
|
return {
|
||||||
|
isSimilar: true,
|
||||||
|
type: BSKY_USER_MATCH_TYPE.DESCRIPTION,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
isSimilar: false,
|
||||||
|
type: BSKY_USER_MATCH_TYPE.NONE,
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
import type { ProfileView, ViewerState } from "@atproto/api/dist/client/types/app/bsky/actor/defs"
|
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 van from 'vanjs-core'
|
||||||
|
import { BSKY_USER_MATCH_TYPE } from "~lib/constants"
|
||||||
|
|
||||||
|
|
||||||
const { a, div, p, img, button, span } = van.tags
|
const { a, div, p, img, button, span } = van.tags
|
||||||
|
const { svg, path } = van.tagsNS("http://www.w3.org/2000/svg")
|
||||||
|
|
||||||
export type UserCellBtnLabel = {
|
export type UserCellBtnLabel = {
|
||||||
add: string,
|
add: string,
|
||||||
@ -79,20 +82,48 @@ const Avatar = ({ avatar }: { avatar?: string }) => {
|
|||||||
return avatar ? img({ src: avatar, width: "40" }) : div({ class: "no-avatar" })
|
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", "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 or display 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 = ({
|
export const BskyUserCell = ({
|
||||||
profile,
|
profile,
|
||||||
statusKey,
|
statusKey,
|
||||||
btnLabel,
|
btnLabel,
|
||||||
|
matchType,
|
||||||
addAction,
|
addAction,
|
||||||
removeAction,
|
removeAction,
|
||||||
}: {
|
}: {
|
||||||
profile: ProfileView,
|
profile: ProfileView,
|
||||||
statusKey: keyof ViewerState,
|
statusKey: keyof ViewerState,
|
||||||
btnLabel: UserCellBtnLabel,
|
btnLabel: UserCellBtnLabel,
|
||||||
|
matchType: typeof BSKY_USER_MATCH_TYPE[keyof typeof BSKY_USER_MATCH_TYPE],
|
||||||
addAction: () => Promise<void>,
|
addAction: () => Promise<void>,
|
||||||
removeAction: () => Promise<void>
|
removeAction: () => Promise<void>
|
||||||
}) => {
|
}) => {
|
||||||
return div({ class: "bsky-user-content" },
|
return div({ class: "bsky-user-content-wrapper" },
|
||||||
|
MatchTypeLabel({ matchType }),
|
||||||
|
div({ class: "bsky-user-content" },
|
||||||
div({ class: "icon-section" },
|
div({ class: "icon-section" },
|
||||||
a({ href: `https://bsky.app/profile/${profile.handle}`, target: "_blank", rel: "noopener" },
|
a({ href: `https://bsky.app/profile/${profile.handle}`, target: "_blank", rel: "noopener" },
|
||||||
Avatar({ avatar: profile.avatar }),
|
Avatar({ avatar: profile.avatar }),
|
||||||
@ -122,5 +153,5 @@ export const BskyUserCell = ({
|
|||||||
),
|
),
|
||||||
profile.description ? p({ class: "description" }, profile.description) : "",
|
profile.description ? p({ class: "description" }, profile.description) : "",
|
||||||
),
|
),
|
||||||
)
|
))
|
||||||
}
|
}
|
||||||
|
@ -19,11 +19,12 @@ const WarningIcon = () => svg(
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
export const NotFoundCell = () => div({ class: "bsky-user-content bsky-user-content__not-found" },
|
export const NotFoundCell = () => div({ class: "bsky-user-content-wrapper" },
|
||||||
|
div({ class: "bsky-user-content bsky-user-content__not-found" },
|
||||||
WarningIcon(),
|
WarningIcon(),
|
||||||
p({
|
p({
|
||||||
class: "not-found"
|
class: "not-found"
|
||||||
},
|
},
|
||||||
"No similar users found."
|
"No similar users found."
|
||||||
)
|
)
|
||||||
)
|
))
|
||||||
|
@ -23,3 +23,11 @@ export const VIEWER_STATE = {
|
|||||||
BLOCKING: "blocking",
|
BLOCKING: "blocking",
|
||||||
FOLLOWING: "following",
|
FOLLOWING: "following",
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
|
|
||||||
|
export const BSKY_USER_MATCH_TYPE = {
|
||||||
|
HANDLE: "handle",
|
||||||
|
DISPLAY_NAME: "display_name",
|
||||||
|
DESCRIPTION: "description",
|
||||||
|
NONE: "none",
|
||||||
|
} as const
|
||||||
|
@ -3,6 +3,7 @@ import van from "vanjs-core"
|
|||||||
import { ReloadButton } from "./components/ReloadBtn"
|
import { ReloadButton } from "./components/ReloadBtn"
|
||||||
import { NotFoundCell } from "./components/NotFoundCell"
|
import { NotFoundCell } from "./components/NotFoundCell"
|
||||||
import { BskyUserCell, type UserCellBtnLabel } from "./components/BskyUserCell"
|
import { BskyUserCell, type UserCellBtnLabel } from "./components/BskyUserCell"
|
||||||
|
import type { BSKY_USER_MATCH_TYPE } from "./constants"
|
||||||
|
|
||||||
export const getUserCells = ({ queryParam, filterInsertedElement }: { queryParam: string, filterInsertedElement: boolean }) => {
|
export const getUserCells = ({ queryParam, filterInsertedElement }: { queryParam: string, filterInsertedElement: boolean }) => {
|
||||||
const userCells = document.querySelectorAll(queryParam);
|
const userCells = document.querySelectorAll(queryParam);
|
||||||
@ -12,7 +13,7 @@ export const getUserCells = ({ queryParam, filterInsertedElement }: { queryParam
|
|||||||
return Array.from(userCells).filter((userCell) => {
|
return Array.from(userCells).filter((userCell) => {
|
||||||
const nextElement = userCell.nextElementSibling
|
const nextElement = userCell.nextElementSibling
|
||||||
if (!nextElement) { return true }
|
if (!nextElement) { return true }
|
||||||
return nextElement.classList.contains("bsky-user-content") === false
|
return nextElement.classList.contains("bsky-user-content-wrapper") === false
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
return Array.from(userCells)
|
return Array.from(userCells)
|
||||||
@ -32,11 +33,12 @@ export const getAccountNameAndDisplayName = (userCell: Element) => {
|
|||||||
return { twAccountName, twDisplayName, twAccountNameRemoveUnderscore }
|
return { twAccountName, twDisplayName, twAccountNameRemoveUnderscore }
|
||||||
}
|
}
|
||||||
|
|
||||||
export const insertBskyProfileEl = ({ dom, profile, statusKey, btnLabel, addAction, removeAction }: {
|
export const insertBskyProfileEl = ({ dom, profile, statusKey, btnLabel, matchType, addAction, removeAction }: {
|
||||||
dom: Element,
|
dom: Element,
|
||||||
profile: ProfileView,
|
profile: ProfileView,
|
||||||
statusKey: keyof ViewerState,
|
statusKey: keyof ViewerState,
|
||||||
btnLabel: UserCellBtnLabel,
|
btnLabel: UserCellBtnLabel,
|
||||||
|
matchType: typeof BSKY_USER_MATCH_TYPE[keyof typeof BSKY_USER_MATCH_TYPE],
|
||||||
addAction: () => Promise<void>,
|
addAction: () => Promise<void>,
|
||||||
removeAction: () => Promise<void>
|
removeAction: () => Promise<void>
|
||||||
}) => {
|
}) => {
|
||||||
@ -44,6 +46,7 @@ export const insertBskyProfileEl = ({ dom, profile, statusKey, btnLabel, addActi
|
|||||||
profile,
|
profile,
|
||||||
statusKey,
|
statusKey,
|
||||||
btnLabel,
|
btnLabel,
|
||||||
|
matchType,
|
||||||
addAction,
|
addAction,
|
||||||
removeAction,
|
removeAction,
|
||||||
}))
|
}))
|
||||||
|
@ -55,6 +55,7 @@ export const searchAndInsertBskyUsers = async (
|
|||||||
]
|
]
|
||||||
|
|
||||||
let targetAccount = null
|
let targetAccount = null
|
||||||
|
let matchType = null
|
||||||
|
|
||||||
// Loop over search parameters and break if a user is found
|
// Loop over search parameters and break if a user is found
|
||||||
for (const term of searchTerms) {
|
for (const term of searchTerms) {
|
||||||
@ -63,7 +64,7 @@ export const searchAndInsertBskyUsers = async (
|
|||||||
limit: 1,
|
limit: 1,
|
||||||
})
|
})
|
||||||
|
|
||||||
const isUserFound = isSimilarUser([
|
const { isSimilar: isUserFound, type } = isSimilarUser([
|
||||||
twAccountName,
|
twAccountName,
|
||||||
twAccountNameRemoveUnderscore,
|
twAccountNameRemoveUnderscore,
|
||||||
twDisplayName,
|
twDisplayName,
|
||||||
@ -71,6 +72,7 @@ export const searchAndInsertBskyUsers = async (
|
|||||||
|
|
||||||
if (isUserFound) {
|
if (isUserFound) {
|
||||||
targetAccount = searchResult
|
targetAccount = searchResult
|
||||||
|
matchType = type
|
||||||
break; // Stop searching when a user is found
|
break; // Stop searching when a user is found
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,6 +84,7 @@ export const searchAndInsertBskyUsers = async (
|
|||||||
profile: targetAccount,
|
profile: targetAccount,
|
||||||
statusKey,
|
statusKey,
|
||||||
btnLabel,
|
btnLabel,
|
||||||
|
matchType,
|
||||||
addAction: async () => {
|
addAction: async () => {
|
||||||
const result = await addQuery(targetAccount.did);
|
const result = await addQuery(targetAccount.did);
|
||||||
bskyUserUrlMap.set(targetAccount.did, result.uri)
|
bskyUserUrlMap.set(targetAccount.did, result.uri)
|
||||||
|
@ -6,6 +6,29 @@
|
|||||||
--bsky-primary-hover-color: #2563eb;
|
--bsky-primary-hover-color: #2563eb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bsky-user-content-wrapper .match-type {
|
||||||
|
color: var(--bsky-primary-color);
|
||||||
|
padding: 2px 14px 2px 14px;
|
||||||
|
font-size: 10px;
|
||||||
|
font-weight: bold;
|
||||||
|
width: fit-content;
|
||||||
|
display: flex;
|
||||||
|
gap: 4px;
|
||||||
|
border-radius: 10px 10px 0px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bsky-user-content-wrapper .match-type.match-type__handle {
|
||||||
|
background-color: #ffd700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bsky-user-content-wrapper .match-type.match-type__display-name {
|
||||||
|
background-color: #FFA07A;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bsky-user-content-wrapper .match-type.match-type__description {
|
||||||
|
background-color: #D3D3D3;
|
||||||
|
}
|
||||||
|
|
||||||
.bsky-user-content {
|
.bsky-user-content {
|
||||||
background: rgb(2,0,36);
|
background: rgb(2,0,36);
|
||||||
background: var(--bsky-primary-color);
|
background: var(--bsky-primary-color);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user