better "followed by" layout

This commit is contained in:
Martti Malmi 2023-11-29 13:20:43 +02:00
parent 5be04c86b3
commit c3a6304573
4 changed files with 27 additions and 25 deletions

View File

@ -1,21 +1,20 @@
import "./DisplayName.css"; import "./DisplayName.css";
import { useMemo } from "react"; import { useMemo } from "react";
import { HexKey, UserMetadata } from "@snort/system"; import { HexKey, UserMetadata } from "@snort/system";
import { getDisplayNameOrPlaceHolder } from "@/SnortUtils"; import { getDisplayNameOrPlaceHolder } from "@/SnortUtils";
import { useUserProfile } from "@snort/system-react";
import classNames from "classnames";
interface DisplayNameProps { interface DisplayNameProps {
pubkey: HexKey; pubkey: HexKey;
user: UserMetadata | undefined; user: UserMetadata | undefined;
} }
const DisplayName = ({ pubkey, user }: DisplayNameProps) => { const DisplayName = ({ pubkey }: DisplayNameProps) => {
const [name, isPlaceHolder] = useMemo(() => getDisplayNameOrPlaceHolder(user, pubkey), [user, pubkey]); const profile = useUserProfile(pubkey);
const [name, isPlaceHolder] = useMemo(() => getDisplayNameOrPlaceHolder(profile, pubkey), [profile, pubkey]);
if (isPlaceHolder) { return <span className={classNames({ placeholder: isPlaceHolder })}>{name}</span>;
return <span className="placeholder">{name}</span>;
}
return name;
}; };
export default DisplayName; export default DisplayName;

View File

@ -18,7 +18,7 @@ export function UserWebsiteLink({ user }: { user?: MetadataCache | UserMetadata
if (user?.website) { if (user?.website) {
return ( return (
<div className="user-profile-link f-ellipsis"> <div className="user-profile-link f-ellipsis flex gap-2 items-center">
<Icon name="link-02" size={16} /> <Icon name="link-02" size={16} />
<a href={website_url} target="_blank" rel="noreferrer"> <a href={website_url} target="_blank" rel="noreferrer">
{tryFormatWebsite(user.website)} {tryFormatWebsite(user.website)}

View File

@ -130,12 +130,6 @@
line-height: 24px; line-height: 24px;
} }
.profile .link {
display: flex;
align-items: center;
gap: 8px;
}
.profile .link svg { .profile .link svg {
color: var(--highlight); color: var(--highlight);
} }

View File

@ -1,5 +1,5 @@
import "./ProfilePage.css"; import "./ProfilePage.css";
import { useEffect, useState } from "react"; import { Fragment, useEffect, useState } from "react";
import { FormattedMessage } from "react-intl"; import { FormattedMessage } from "react-intl";
import { useLocation, useNavigate, useParams } from "react-router-dom"; import { useLocation, useNavigate, useParams } from "react-router-dom";
import { import {
@ -61,6 +61,8 @@ import { useMuteList, usePinList } from "@/Hooks/useLists";
import messages from "../messages"; import messages from "../messages";
import FollowDistanceIndicator from "@/Element/User/FollowDistanceIndicator"; import FollowDistanceIndicator from "@/Element/User/FollowDistanceIndicator";
import classNames from "classnames";
import { ProfileLink } from "@/Element/User/ProfileLink";
interface ProfilePageProps { interface ProfilePageProps {
id?: string; id?: string;
@ -156,6 +158,7 @@ export default function ProfilePage({ id: propId, state }: ProfilePageProps) {
function username() { function username() {
const followedByFriends = user?.pubkey ? socialGraphInstance.followedByFriends(user.pubkey) : new Set<string>(); const followedByFriends = user?.pubkey ? socialGraphInstance.followedByFriends(user.pubkey) : new Set<string>();
const MAX_FOLLOWED_BY_FRIENDS = 3; const MAX_FOLLOWED_BY_FRIENDS = 3;
const followedByFriendsArray = Array.from(followedByFriends).slice(0, MAX_FOLLOWED_BY_FRIENDS);
return ( return (
<> <>
<div className="flex flex-col g4"> <div className="flex flex-col g4">
@ -168,18 +171,24 @@ export default function ProfilePage({ id: propId, state }: ProfilePageProps) {
{user?.pubkey && <FollowDistanceIndicator className="p-2" pubkey={user.pubkey} />} {user?.pubkey && <FollowDistanceIndicator className="p-2" pubkey={user.pubkey} />}
{followedByFriends.size > 0 && ( {followedByFriends.size > 0 && (
<div className="text-gray-light"> <div className="text-gray-light">
{followedByFriendsArray.map((a, index) => {
return (
<span className={classNames({ "-ml-4": index > 0 }, "inline-block")} key={a}>
<ProfileImage showFollowDistance={false} pubkey={a} size={24} showUsername={false} />
</span>
);
})}
<span className="mr-1"> <span className="mr-1">
<FormattedMessage defaultMessage="Followed by" id="6mr8WU" /> <FormattedMessage defaultMessage="Followed by" id="6mr8WU" />
</span> </span>
{Array.from(followedByFriends) {followedByFriendsArray.map((a, index) => (
.slice(0, MAX_FOLLOWED_BY_FRIENDS) <Fragment key={a}>
.map(a => { <ProfileLink pubkey={a} user={undefined} className="link inline">
return ( <DisplayName user={undefined} pubkey={a} />
<span className="inline-block" key={a}> </ProfileLink>
<ProfileImage showFollowDistance={false} pubkey={a} size={24} showUsername={false} /> {index < followedByFriendsArray.length - 1 && ","}{" "}
</span> </Fragment>
); ))}
})}
{followedByFriends.size > MAX_FOLLOWED_BY_FRIENDS && ( {followedByFriends.size > MAX_FOLLOWED_BY_FRIENDS && (
<span> <span>
<FormattedMessage <FormattedMessage
@ -208,7 +217,7 @@ export default function ProfilePage({ id: propId, state }: ProfilePageProps) {
<> <>
<UserWebsiteLink user={user} /> <UserWebsiteLink user={user} />
{lnurl && ( {lnurl && (
<div className="link lnurl f-ellipsis" onClick={() => setShowLnQr(true)}> <div className="link lnurl f-ellipsis flex gap-2 items-center" onClick={() => setShowLnQr(true)}>
<Icon name="zapCircle" size={16} /> <Icon name="zapCircle" size={16} />
{lnurl.name} {lnurl.name}
</div> </div>