forked from Kieran/snort
profile panel
This commit is contained in:
parent
663c2ea433
commit
d5d299a5cf
@ -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;
|
||||||
|
@ -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={{
|
||||||
":": {
|
":": {
|
||||||
|
@ -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)}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user