add follow distance indicator to profile pages
Some checks failed
continuous-integration/drone/pr Build is failing

This commit is contained in:
Martti Malmi 2023-11-26 12:07:41 +02:00
parent a592974b93
commit a612db65c7
3 changed files with 59 additions and 37 deletions

View 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>
);
}

View File

@ -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
} }

View File

@ -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()}</>}