mirror of
https://github.com/snachodog/tok-to-insta-follower-bridge.git
synced 2025-09-13 23:43:31 -06:00
✨ use vanjs
This commit is contained in:
125
src/lib/components/BskyUserCell.ts
Normal file
125
src/lib/components/BskyUserCell.ts
Normal file
@@ -0,0 +1,125 @@
|
||||
import type { ProfileView, ViewerState } from "@atproto/api/dist/client/types/app/bsky/actor/defs"
|
||||
import van from 'vanjs-core'
|
||||
|
||||
const { a, div, p, img, button } = van.tags
|
||||
|
||||
export type UserCellBtnLabel = {
|
||||
add: string,
|
||||
remove: string,
|
||||
progressive: string,
|
||||
}
|
||||
|
||||
const ActionButton = ({ statusKey, profile, btnLabel, addAction, removeAction }: {
|
||||
profile: ProfileView,
|
||||
statusKey: keyof ViewerState,
|
||||
btnLabel: UserCellBtnLabel,
|
||||
addAction: () => Promise<void>,
|
||||
removeAction: () => Promise<void>
|
||||
}) => {
|
||||
const label = van.state(`${profile.viewer[statusKey] ? btnLabel.progressive : btnLabel.add} on Bluesky`)
|
||||
|
||||
const isStateOfBeing = van.state(profile.viewer[statusKey])
|
||||
const isProcessing = van.state(false)
|
||||
const isJustApplied = van.state(false)
|
||||
|
||||
const beingClass = van.derive(() => isStateOfBeing.val ? "action-button__being" : "")
|
||||
const processingClass = van.derive(() => isProcessing.val ? "action-button__processing" : "")
|
||||
const justAppliedClass = van.derive(() => isJustApplied.val ? "action-button__just-applied" : "")
|
||||
|
||||
const onClick = async () => {
|
||||
if (isProcessing.val) return
|
||||
isProcessing.val = true
|
||||
label.val = "Processing..."
|
||||
|
||||
if (isStateOfBeing.val) {
|
||||
await removeAction()
|
||||
label.val = `${btnLabel.add} on Bluesky`
|
||||
isStateOfBeing.val = false
|
||||
} else {
|
||||
await addAction()
|
||||
label.val = `${btnLabel.progressive} on Bluesky`
|
||||
isStateOfBeing.val = true
|
||||
isJustApplied.val = true
|
||||
}
|
||||
|
||||
isProcessing.val = false
|
||||
}
|
||||
|
||||
const onMouseover = () => {
|
||||
if(
|
||||
isProcessing.val ||
|
||||
isJustApplied.val ||
|
||||
!isStateOfBeing.val
|
||||
) return
|
||||
|
||||
label.val = `${btnLabel.remove} on Bluesky`
|
||||
}
|
||||
|
||||
const onMouseout = () => {
|
||||
if (isJustApplied.val) {
|
||||
isJustApplied.val = false
|
||||
}
|
||||
if(!isStateOfBeing.val) return
|
||||
|
||||
label.val = `${btnLabel.progressive} on Bluesky`
|
||||
}
|
||||
|
||||
return () => button({
|
||||
class: `action-button ${beingClass.val} ${processingClass.val} ${justAppliedClass.val}`,
|
||||
onclick: onClick,
|
||||
onmouseover: onMouseover,
|
||||
onmouseout: onMouseout,
|
||||
},
|
||||
label.val,
|
||||
)
|
||||
}
|
||||
|
||||
const Avatar = ({ avatar }: { avatar?: string }) => {
|
||||
return avatar ? img({ src: avatar, width: "40" }) : div({ class: "no-avatar" })
|
||||
}
|
||||
|
||||
export const BskyUserCell = ({
|
||||
profile,
|
||||
statusKey,
|
||||
btnLabel,
|
||||
addAction,
|
||||
removeAction,
|
||||
}: {
|
||||
profile: ProfileView,
|
||||
statusKey: keyof ViewerState,
|
||||
btnLabel: UserCellBtnLabel,
|
||||
addAction: () => Promise<void>,
|
||||
removeAction: () => Promise<void>
|
||||
}) => {
|
||||
return div({ class: "bsky-user-content" },
|
||||
div({ class: "icon-section"},
|
||||
a({ href: `https://bsky.app/profile/${profile.handle}`, target: "_blank", rel: "noopener" },
|
||||
Avatar({ avatar: profile.avatar }),
|
||||
),
|
||||
),
|
||||
div({ class: "content" },
|
||||
div({ class: "name-and-controller" },
|
||||
div(
|
||||
p({ class: "display-name" },
|
||||
a({ href: `https://bsky.app/profile/${profile.handle}`, target: "_blank", rel: "noopener" },
|
||||
profile.displayName ?? profile.handle,
|
||||
),
|
||||
),
|
||||
p({ class: "handle" },
|
||||
`@${profile.handle}`,
|
||||
),
|
||||
),
|
||||
div(
|
||||
ActionButton({
|
||||
profile,
|
||||
statusKey,
|
||||
btnLabel,
|
||||
addAction,
|
||||
removeAction,
|
||||
})
|
||||
),
|
||||
),
|
||||
profile.description ? p({ class: "description" }, profile.description) : "",
|
||||
),
|
||||
)
|
||||
}
|
29
src/lib/components/NotFoundCell.ts
Normal file
29
src/lib/components/NotFoundCell.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
|
||||
import van from "vanjs-core"
|
||||
|
||||
const { div, p } = van.tags
|
||||
const { svg, path } = van.tagsNS("http://www.w3.org/2000/svg")
|
||||
|
||||
const WarningIcon = () => svg(
|
||||
{
|
||||
fill: "none",
|
||||
"stroke-width": "1.5",
|
||||
stroke: "currentColor",
|
||||
class: "w-6 h-6",
|
||||
viewBox: "0 0 24 24"
|
||||
},
|
||||
path({
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
d: "M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z"
|
||||
}),
|
||||
)
|
||||
|
||||
export const NotFoundCell = () => div({ class: "bsky-user-content bsky-user-content__not-found" },
|
||||
WarningIcon(),
|
||||
p({
|
||||
class: "not-found"
|
||||
},
|
||||
"No similar users found."
|
||||
)
|
||||
)
|
19
src/lib/components/ReloadBtn.ts
Normal file
19
src/lib/components/ReloadBtn.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import van from "vanjs-core"
|
||||
|
||||
const { button, div } = van.tags
|
||||
|
||||
export const ReloadButton = ({clickAction}: {clickAction: () => void}) => {
|
||||
const deleted = van.state(false)
|
||||
|
||||
return () => deleted.val ? null : div({ class: "bsky-reload-btn-wrapper" },
|
||||
button(
|
||||
{
|
||||
class: "bsky-reload-btn",
|
||||
onclick: () => {
|
||||
clickAction()
|
||||
deleted.val = true
|
||||
}
|
||||
},
|
||||
"Find More"
|
||||
))
|
||||
}
|
Reference in New Issue
Block a user