profile panel

This commit is contained in:
Kieran 2023-05-15 11:53:03 +01:00
parent 663c2ea433
commit d5d299a5cf
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
5 changed files with 55 additions and 8 deletions

View File

@ -6,13 +6,18 @@ import type { UserMetadata } from "@snort/nostr";
import useImgProxy from "Hooks/useImgProxy"; import useImgProxy from "Hooks/useImgProxy";
const Avatar = ({ user, ...rest }: { user?: UserMetadata; onClick?: () => void }) => { interface AvatarProps {
user?: UserMetadata;
onClick?: () => void;
size?: number;
}
const Avatar = ({ user, size, onClick }: AvatarProps) => {
const [url, setUrl] = useState<string>(Nostrich); const [url, setUrl] = useState<string>(Nostrich);
const { proxy } = useImgProxy(); const { proxy } = useImgProxy();
useEffect(() => { useEffect(() => {
if (user?.picture) { if (user?.picture) {
const url = proxy(user.picture, 120); const url = proxy(user.picture, size ?? 120);
setUrl(url); setUrl(url);
} }
}, [user]); }, [user]);
@ -20,7 +25,7 @@ const Avatar = ({ user, ...rest }: { user?: UserMetadata; onClick?: () => void }
const backgroundImage = `url(${url})`; const backgroundImage = `url(${url})`;
const style = { "--img-url": backgroundImage } as CSSProperties; const style = { "--img-url": backgroundImage } as CSSProperties;
const domain = user?.nip05 && user.nip05.split("@")[1]; const domain = user?.nip05 && user.nip05.split("@")[1];
return <div {...rest} style={style} className="avatar" data-domain={domain?.toLowerCase()}></div>; return <div onClick={onClick} style={style} className="avatar" data-domain={domain?.toLowerCase()}></div>;
}; };
export default Avatar; export default Avatar;

View File

@ -47,6 +47,7 @@ const UserItem = (metadata: MetadataCache) => {
interface TextareaProps { interface TextareaProps {
autoFocus: boolean; autoFocus: boolean;
className: string; className: string;
placeholder?: string;
onChange(ev: React.ChangeEvent<HTMLTextAreaElement>): void; onChange(ev: React.ChangeEvent<HTMLTextAreaElement>): void;
value: string; value: string;
onFocus(): void; onFocus(): void;
@ -72,7 +73,7 @@ const Textarea = (props: TextareaProps) => {
dir="auto" dir="auto"
{...props} {...props}
loadingComponent={() => <span>Loading...</span>} loadingComponent={() => <span>Loading...</span>}
placeholder={formatMessage(messages.NotePlaceholder)} placeholder={props.placeholder ?? formatMessage(messages.NotePlaceholder)}
textAreaComponent={TextareaAutosize} textAreaComponent={TextareaAutosize}
trigger={{ trigger={{
":": { ":": {

View File

@ -84,6 +84,7 @@ export default function WriteDm({ chatPubKey }: { chatPubKey: string }) {
<div className="w-max"> <div className="w-max">
<Textarea <Textarea
autoFocus={true} autoFocus={true}
placeholder=""
className="" className=""
value={msg} value={msg}
onChange={e => onChange(e)} onChange={e => onChange(e)}

View File

@ -11,13 +11,15 @@
.dm-page { .dm-page {
grid-template-columns: 100vw; grid-template-columns: 100vw;
} }
.dm-page > div:nth-child(1) { .dm-page > div:nth-child(1) {
margin: 0 !important; margin: 0 !important;
} }
} }
@media (min-width: 1500px) { @media (min-width: 1500px) {
.dm-page { .dm-page {
grid-template-columns: 350px auto 350px; grid-template-columns: 400px auto 400px;
} }
} }
@ -37,3 +39,12 @@
.dm-page > div:nth-child(3) { .dm-page > div:nth-child(3) {
margin: 0 10px; margin: 0 10px;
} }
.dm-page > div:nth-child(3) .avatar {
margin-left: auto;
margin-right: auto;
}
.dm-page > div:nth-child(3) .card {
cursor: pointer;
}

View File

@ -4,7 +4,7 @@ import { useNavigate } from "react-router-dom";
import { HexKey, RawEvent, NostrPrefix } from "@snort/nostr"; import { HexKey, RawEvent, NostrPrefix } from "@snort/nostr";
import UnreadCount from "Element/UnreadCount"; import UnreadCount from "Element/UnreadCount";
import ProfileImage from "Element/ProfileImage"; import ProfileImage, { getDisplayName } from "Element/ProfileImage";
import { dedupe, hexToBech32, unwrap } from "Util"; import { dedupe, hexToBech32, unwrap } from "Util";
import NoteToSelf from "Element/NoteToSelf"; import NoteToSelf from "Element/NoteToSelf";
import useModeration from "Hooks/useModeration"; import useModeration from "Hooks/useModeration";
@ -13,6 +13,10 @@ import useLogin from "Hooks/useLogin";
import usePageWidth from "Hooks/usePageWidth"; import usePageWidth from "Hooks/usePageWidth";
import NoteTime from "Element/NoteTime"; import NoteTime from "Element/NoteTime";
import DmWindow from "Element/DmWindow"; import DmWindow from "Element/DmWindow";
import Avatar from "Element/Avatar";
import { useUserProfile } from "Hooks/useUserProfile";
import Icon from "Icons/Icon";
import Text from "Element/Text";
import "./MessagesPage.css"; import "./MessagesPage.css";
import messages from "./messages"; import messages from "./messages";
@ -43,7 +47,7 @@ export default function MessagesPage() {
); );
} }
return []; return [];
}, [dms, login.publicKey]); }, [dms, login.publicKey, isMuted]);
const unreadCount = useMemo(() => chats.reduce((p, c) => p + c.unreadMessages, 0), [chats]); const unreadCount = useMemo(() => chats.reduce((p, c) => p + c.unreadMessages, 0), [chats]);
@ -112,8 +116,33 @@ export default function MessagesPage() {
.map(person)} .map(person)}
</div> </div>
{pageWidth >= TwoCol && chat && <DmWindow id={chat} />} {pageWidth >= TwoCol && chat && <DmWindow id={chat} />}
{pageWidth >= ThreeCol && <div></div>} {pageWidth >= ThreeCol && chat && (
<div>
<ProfileDmActions pubkey={chat} />
</div> </div>
)}
</div>
);
}
function ProfileDmActions({ pubkey }: { pubkey: string }) {
const profile = useUserProfile(pubkey);
const { block, unblock, isBlocked } = useModeration();
const blocked = isBlocked(pubkey);
return (
<>
<Avatar user={profile} size={210} />
<h2>{getDisplayName(profile, pubkey)}</h2>
<p>
<Text content={profile?.about ?? ""} tags={[]} creator={pubkey} disableMedia={true} depth={0} />
</p>
<div className="settings-row" onClick={() => (blocked ? unblock(pubkey) : block(pubkey))}>
<Icon name="block" />
{blocked ? <FormattedMessage defaultMessage="Unblock" /> : <FormattedMessage defaultMessage="Block" />}
</div>
</>
); );
} }