feat: profile qr
This commit is contained in:
parent
d2ac231f89
commit
ab120e114f
@ -6,7 +6,8 @@ export interface QrCodeProps {
|
||||
link?: string,
|
||||
avatar?: string,
|
||||
height?: number,
|
||||
width?: number
|
||||
width?: number,
|
||||
className?: string
|
||||
}
|
||||
|
||||
export default function QrCode(props: QrCodeProps) {
|
||||
@ -26,9 +27,6 @@ export default function QrCode(props: QrCodeProps) {
|
||||
},
|
||||
cornersSquareOptions: {
|
||||
type: 'extra-rounded'
|
||||
},
|
||||
imageOptions: {
|
||||
crossOrigin: "anonymous"
|
||||
}
|
||||
});
|
||||
qrRef.current.innerHTML = "";
|
||||
@ -46,6 +44,6 @@ export default function QrCode(props: QrCodeProps) {
|
||||
}, [props.data, props.link]);
|
||||
|
||||
return (
|
||||
<div className="qr" ref={qrRef}></div>
|
||||
<div className={`qr${props.className ? ` ${props.className}` : ""}`} ref={qrRef}></div>
|
||||
);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
.profile {
|
||||
flex-direction: column;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.profile .banner {
|
||||
@ -7,18 +7,18 @@
|
||||
height: 210px;
|
||||
margin-bottom: -80px;
|
||||
object-fit: cover;
|
||||
mask-image: linear-gradient(to bottom, var(--bg-color) 60%, rgba(0,0,0,0));
|
||||
-webkit-mask-image: linear-gradient(to bottom, var(--bg-color) 60%, rgba(0,0,0,0));
|
||||
mask-image: linear-gradient(to bottom, var(--bg-color) 60%, rgba(0, 0, 0, 0));
|
||||
-webkit-mask-image: linear-gradient(to bottom, var(--bg-color) 60%, rgba(0, 0, 0, 0));
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
@media (min-width: 720px) {
|
||||
.profile .banner {
|
||||
width: 100%;
|
||||
max-width: 720px;
|
||||
height: 300px;
|
||||
margin-bottom: -120px;
|
||||
}
|
||||
.profile .banner {
|
||||
width: 100%;
|
||||
max-width: 720px;
|
||||
height: 300px;
|
||||
margin-bottom: -120px;
|
||||
}
|
||||
}
|
||||
|
||||
.profile p {
|
||||
@ -30,12 +30,12 @@
|
||||
}
|
||||
|
||||
@media (min-width: 720px) {
|
||||
.profile .banner {
|
||||
width: 100%;
|
||||
max-width: 720px;
|
||||
height: 300px;
|
||||
margin-bottom: -120px;
|
||||
}
|
||||
.profile .banner {
|
||||
width: 100%;
|
||||
max-width: 720px;
|
||||
height: 300px;
|
||||
margin-bottom: -120px;
|
||||
}
|
||||
}
|
||||
|
||||
.profile .avatar-wrapper {
|
||||
@ -89,36 +89,50 @@
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.profile .copy .body { font-size: 12px }
|
||||
.profile .copy .body {
|
||||
font-size: 12px
|
||||
}
|
||||
|
||||
@media (min-width: 360px) {
|
||||
.profile .copy .body { font-size: 14px }
|
||||
.profile .details-wrapper, .profile .avatar-wrapper { margin-left: 21px; }
|
||||
.profile .details { width: calc(100% - 21px); }
|
||||
.profile .copy .body {
|
||||
font-size: 14px
|
||||
}
|
||||
|
||||
.profile .details-wrapper, .profile .avatar-wrapper {
|
||||
margin-left: 21px;
|
||||
}
|
||||
|
||||
.profile .details {
|
||||
width: calc(100% - 21px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 720px) {
|
||||
.profile .details-wrapper, .profile .avatar-wrapper { margin-left: 30px; }
|
||||
.profile .details { width: calc(100% - 30px); }
|
||||
.profile .details-wrapper, .profile .avatar-wrapper {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
.profile .details {
|
||||
width: calc(100% - 30px);
|
||||
}
|
||||
}
|
||||
|
||||
.profile .follow-button {
|
||||
.profile .p-buttons {
|
||||
position: absolute;
|
||||
top: -30px;
|
||||
right: 20px;
|
||||
}
|
||||
|
||||
.profile .message-button {
|
||||
position: absolute;
|
||||
top: -30px;
|
||||
right: 74px;
|
||||
.profile .p-buttons>div {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.profile .no-banner .follow-button {
|
||||
right: 0px;
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
.profile .no-banner .message-button {
|
||||
right: 54px;
|
||||
right: 54px;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
@ -128,8 +142,8 @@
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.tabs > div {
|
||||
margin-right: 0;
|
||||
.tabs>div {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.tab {
|
||||
@ -137,6 +151,7 @@
|
||||
padding: 8px 0;
|
||||
border-bottom: 3px solid var(--gray-secondary);
|
||||
}
|
||||
|
||||
.tab.active {
|
||||
border-bottom: 3px solid var(--highlight);
|
||||
}
|
||||
@ -156,24 +171,26 @@
|
||||
}
|
||||
|
||||
.profile .no-banner .avatar-wrapper, .profile .no-banner .details-wrapper {
|
||||
margin: 0 auto;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
@media (min-width: 720px) {
|
||||
.profile .no-banner {
|
||||
width: 100%;
|
||||
flex-direction: row;
|
||||
justify-content: space-around;
|
||||
margin-top: 21px;
|
||||
}
|
||||
.profile .no-banner .avatar-wrapper {
|
||||
margin: auto 10px;
|
||||
}
|
||||
.profile .no-banner .details-wrapper {
|
||||
margin-left: 10px;
|
||||
margin-top: 21px;
|
||||
max-width: 420px;
|
||||
}
|
||||
.profile .no-banner {
|
||||
width: 100%;
|
||||
flex-direction: row;
|
||||
justify-content: space-around;
|
||||
margin-top: 21px;
|
||||
}
|
||||
|
||||
.profile .no-banner .avatar-wrapper {
|
||||
margin: auto 10px;
|
||||
}
|
||||
|
||||
.profile .no-banner .details-wrapper {
|
||||
margin-left: 10px;
|
||||
margin-top: 21px;
|
||||
max-width: 420px;
|
||||
}
|
||||
}
|
||||
|
||||
.profile .links {
|
||||
@ -210,4 +227,4 @@
|
||||
|
||||
.profile .zap {
|
||||
margin-right: .3em;
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ import "./ProfilePage.css";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faGear, faEnvelope } from "@fortawesome/free-solid-svg-icons";
|
||||
import { faGear, faEnvelope, faQrcode } from "@fortawesome/free-solid-svg-icons";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
|
||||
import { useUserProfile } from "Feed/ProfileFeed";
|
||||
@ -21,6 +21,8 @@ import FollowsList from "Element/FollowsList";
|
||||
import { RootState } from "State/Store";
|
||||
import { HexKey } from "Nostr";
|
||||
import FollowsYou from "Element/FollowsYou"
|
||||
import QrCode from "Element/QrCode";
|
||||
import Modal from "Element/Modal";
|
||||
|
||||
enum ProfileTab {
|
||||
Notes = "Notes",
|
||||
@ -39,6 +41,7 @@ export default function ProfilePage() {
|
||||
const isMe = loginPubKey === id;
|
||||
const [showLnQr, setShowLnQr] = useState<boolean>(false);
|
||||
const [tab, setTab] = useState(ProfileTab.Notes);
|
||||
const [showProfileQr, setShowProfileQr] = useState<boolean>(false);
|
||||
const about = Text({ content: user?.about || '', tags: [], users: new Map() })
|
||||
|
||||
useEffect(() => {
|
||||
@ -119,17 +122,30 @@ export default function ProfilePage() {
|
||||
return (
|
||||
<div className="details-wrapper">
|
||||
{username()}
|
||||
{isMe ? (
|
||||
<div className="btn btn-icon follow-button" onClick={() => navigate("/settings")}>
|
||||
<FontAwesomeIcon icon={faGear} size="lg" />
|
||||
|
||||
<div className="p-buttons">
|
||||
<div className="btn" onClick={() => setShowProfileQr(true)}>
|
||||
<FontAwesomeIcon icon={faQrcode} size="lg" />
|
||||
</div>
|
||||
) : <>
|
||||
<div className="btn message-button" onClick={() => navigate(`/messages/${hexToBech32("npub", id)}`)}>
|
||||
<FontAwesomeIcon icon={faEnvelope} size="lg" />
|
||||
</div>
|
||||
<FollowButton pubkey={id} />
|
||||
</>
|
||||
}
|
||||
{showProfileQr && (<Modal onClose={() => setShowProfileQr(false)}>
|
||||
<div className="card">
|
||||
<QrCode data={`nostr:${hexToBech32("npub", id)}`} link={undefined} className="m10"
|
||||
avatar={user?.picture}/>
|
||||
</div>
|
||||
</Modal>)}
|
||||
{isMe ? (
|
||||
<div className="btn" onClick={() => navigate("/settings")}>
|
||||
<FontAwesomeIcon icon={faGear} size="lg" />
|
||||
</div>
|
||||
) : <>
|
||||
<div className="btn" onClick={() => navigate(`/messages/${hexToBech32("npub", id)}`)}>
|
||||
<FontAwesomeIcon icon={faEnvelope} size="lg" />
|
||||
</div>
|
||||
<FollowButton pubkey={id} />
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
|
||||
{bio()}
|
||||
</div>
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user