add follow distance indicator to profile pages
Some checks failed
continuous-integration/drone/pr Build is failing
Some checks failed
continuous-integration/drone/pr Build is failing
This commit is contained in:
parent
a592974b93
commit
a612db65c7
28
packages/app/src/Element/User/FollowDistanceIndicator.tsx
Normal file
28
packages/app/src/Element/User/FollowDistanceIndicator.tsx
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { HexKey, socialGraphInstance } from "@snort/system";
|
||||||
|
import Icon from "@/Icons/Icon";
|
||||||
|
import classNames from "classnames";
|
||||||
|
|
||||||
|
interface FollowDistanceIndicatorProps {
|
||||||
|
pubkey: HexKey;
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function FollowDistanceIndicator({ pubkey, className }: FollowDistanceIndicatorProps) {
|
||||||
|
const followDistance = socialGraphInstance.getFollowDistance(pubkey);
|
||||||
|
let followDistanceColor = "";
|
||||||
|
|
||||||
|
if (followDistance <= 1) {
|
||||||
|
followDistanceColor = "success";
|
||||||
|
} else if (followDistance === 2 && socialGraphInstance.followedByFriendsCount(pubkey) >= 10) {
|
||||||
|
followDistanceColor = "text-nostr-orange";
|
||||||
|
} else if (followDistance > 2) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span className={classNames("icon-circle", className)}>
|
||||||
|
<Icon name="check" className={followDistanceColor} size={10} />
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
@ -11,6 +11,7 @@ import Icon from "@/Icons/Icon";
|
|||||||
import DisplayName from "./DisplayName";
|
import DisplayName from "./DisplayName";
|
||||||
import { ProfileLink } from "./ProfileLink";
|
import { ProfileLink } from "./ProfileLink";
|
||||||
import { ProfileCard } from "./ProfileCard";
|
import { ProfileCard } from "./ProfileCard";
|
||||||
|
import FollowDistanceIndicator from "@/Element/User/FollowDistanceIndicator";
|
||||||
|
|
||||||
export interface ProfileImageProps {
|
export interface ProfileImageProps {
|
||||||
pubkey: HexKey;
|
pubkey: HexKey;
|
||||||
@ -49,7 +50,6 @@ export default function ProfileImage({
|
|||||||
}: ProfileImageProps) {
|
}: ProfileImageProps) {
|
||||||
const user = useUserProfile(profile ? "" : pubkey) ?? profile;
|
const user = useUserProfile(profile ? "" : pubkey) ?? profile;
|
||||||
const nip05 = defaultNip ? defaultNip : user?.nip05;
|
const nip05 = defaultNip ? defaultNip : user?.nip05;
|
||||||
const followDistance = socialGraphInstance.getFollowDistance(pubkey);
|
|
||||||
const [isHovering, setIsHovering] = useState(false);
|
const [isHovering, setIsHovering] = useState(false);
|
||||||
|
|
||||||
const hoverTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
const hoverTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
||||||
@ -72,12 +72,6 @@ export default function ProfileImage({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function inner() {
|
function inner() {
|
||||||
let followDistanceColor = "";
|
|
||||||
if (followDistance <= 1) {
|
|
||||||
followDistanceColor = "success";
|
|
||||||
} else if (followDistance === 2 && socialGraphInstance.followedByFriendsCount(pubkey) >= 10) {
|
|
||||||
followDistanceColor = "text-nostr-orange";
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="avatar-wrapper" onMouseEnter={handleMouseEnter}>
|
<div className="avatar-wrapper" onMouseEnter={handleMouseEnter}>
|
||||||
@ -87,14 +81,10 @@ export default function ProfileImage({
|
|||||||
size={size}
|
size={size}
|
||||||
imageOverlay={imageOverlay}
|
imageOverlay={imageOverlay}
|
||||||
icons={
|
icons={
|
||||||
(followDistance <= 2 && showFollowDistance) || icons ? (
|
showFollowDistance || icons ? (
|
||||||
<>
|
<>
|
||||||
{icons}
|
{icons}
|
||||||
{showFollowDistance && (
|
{showFollowDistance && <FollowDistanceIndicator pubkey={pubkey} />}
|
||||||
<div className="icon-circle">
|
|
||||||
<Icon name="check" className={followDistanceColor} size={10} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
) : undefined
|
) : undefined
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,7 @@ import { UserWebsiteLink } from "@/Element/User/UserWebsiteLink";
|
|||||||
import { useMuteList, usePinList } from "@/Hooks/useLists";
|
import { useMuteList, usePinList } from "@/Hooks/useLists";
|
||||||
|
|
||||||
import messages from "../messages";
|
import messages from "../messages";
|
||||||
|
import FollowDistanceIndicator from "@/Element/User/FollowDistanceIndicator";
|
||||||
|
|
||||||
interface ProfilePageProps {
|
interface ProfilePageProps {
|
||||||
id?: string;
|
id?: string;
|
||||||
@ -163,31 +164,34 @@ export default function ProfilePage({ id: propId, state }: ProfilePageProps) {
|
|||||||
<FollowsYou followsMe={follows.includes(loginPubKey ?? "")} />
|
<FollowsYou followsMe={follows.includes(loginPubKey ?? "")} />
|
||||||
</h2>
|
</h2>
|
||||||
{user?.nip05 && <Nip05 nip05={user.nip05} pubkey={user.pubkey} />}
|
{user?.nip05 && <Nip05 nip05={user.nip05} pubkey={user.pubkey} />}
|
||||||
{followedByFriends.size > 0 && (
|
<div className="flex flex-row items-center">
|
||||||
<div className="text-gray-light">
|
{user?.pubkey && <FollowDistanceIndicator className="p-2" pubkey={user.pubkey} />}
|
||||||
<span className="mr-1">
|
{followedByFriends.size > 0 && (
|
||||||
<FormattedMessage defaultMessage="Followed by" id="6mr8WU" />
|
<div className="text-gray-light">
|
||||||
</span>
|
<span className="mr-1">
|
||||||
{Array.from(followedByFriends)
|
<FormattedMessage defaultMessage="Followed by" id="6mr8WU" />
|
||||||
.slice(0, MAX_FOLLOWED_BY_FRIENDS)
|
|
||||||
.map(a => {
|
|
||||||
return (
|
|
||||||
<span className="inline-block" key={a}>
|
|
||||||
<ProfileImage showFollowDistance={false} pubkey={a} size={24} showUsername={false} />
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
{followedByFriends.size > MAX_FOLLOWED_BY_FRIENDS && (
|
|
||||||
<span>
|
|
||||||
<FormattedMessage
|
|
||||||
defaultMessage="and {count} others you follow"
|
|
||||||
id="CYkOCI"
|
|
||||||
values={{ count: followedByFriends.size - MAX_FOLLOWED_BY_FRIENDS }}
|
|
||||||
/>
|
|
||||||
</span>
|
</span>
|
||||||
)}
|
{Array.from(followedByFriends)
|
||||||
</div>
|
.slice(0, MAX_FOLLOWED_BY_FRIENDS)
|
||||||
)}
|
.map(a => {
|
||||||
|
return (
|
||||||
|
<span className="inline-block" key={a}>
|
||||||
|
<ProfileImage showFollowDistance={false} pubkey={a} size={24} showUsername={false} />
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
{followedByFriends.size > MAX_FOLLOWED_BY_FRIENDS && (
|
||||||
|
<span>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="and {count} others you follow"
|
||||||
|
id="CYkOCI"
|
||||||
|
values={{ count: followedByFriends.size - MAX_FOLLOWED_BY_FRIENDS }}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{showBadges && <BadgeList badges={badges} />}
|
{showBadges && <BadgeList badges={badges} />}
|
||||||
{showStatus && <>{musicStatus()}</>}
|
{showStatus && <>{musicStatus()}</>}
|
||||||
|
Loading…
Reference in New Issue
Block a user