qr on profile

This commit is contained in:
Alejandro Gomez 2023-01-29 23:11:04 +01:00
parent 1d29d53c7b
commit 5def7c8b9a
No known key found for this signature in database
GPG Key ID: 4DF39E566658C817
7 changed files with 114 additions and 48 deletions

View File

@ -0,0 +1,22 @@
import type { ReactNode } from "react";
interface IconButtonProps {
onClick(): void
children: ReactNode
}
const IconButton = ({ onClick, children }: IconButtonProps) => {
return (
<button
className="icon"
type="button"
onClick={onClick}
>
<div className="icon-wrapper">
{children}
</div>
</button>
)
}
export default IconButton

View File

@ -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) {
@ -46,6 +47,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>
);
}

11
src/Icons/Qr.tsx Normal file
View File

@ -0,0 +1,11 @@
import IconProps from './IconProps';
const Qr = (props: IconProps) => {
return (
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
<path d="M4.5 4.5H4.51M15.5 4.5H15.51M4.5 15.5H4.51M11 11H11.01M15.5 15.5H15.51M15 19H19V15M12 14.5V19M19 12H14.5M13.6 8H17.4C17.9601 8 18.2401 8 18.454 7.89101C18.6422 7.79513 18.7951 7.64215 18.891 7.45399C19 7.24008 19 6.96005 19 6.4V2.6C19 2.03995 19 1.75992 18.891 1.54601C18.7951 1.35785 18.6422 1.20487 18.454 1.10899C18.2401 1 17.9601 1 17.4 1H13.6C13.0399 1 12.7599 1 12.546 1.10899C12.3578 1.20487 12.2049 1.35785 12.109 1.54601C12 1.75992 12 2.03995 12 2.6V6.4C12 6.96005 12 7.24008 12.109 7.45399C12.2049 7.64215 12.3578 7.79513 12.546 7.89101C12.7599 8 13.0399 8 13.6 8ZM2.6 8H6.4C6.96005 8 7.24008 8 7.45399 7.89101C7.64215 7.79513 7.79513 7.64215 7.89101 7.45399C8 7.24008 8 6.96005 8 6.4V2.6C8 2.03995 8 1.75992 7.89101 1.54601C7.79513 1.35785 7.64215 1.20487 7.45399 1.10899C7.24008 1 6.96005 1 6.4 1H2.6C2.03995 1 1.75992 1 1.54601 1.10899C1.35785 1.20487 1.20487 1.35785 1.10899 1.54601C1 1.75992 1 2.03995 1 2.6V6.4C1 6.96005 1 7.24008 1.10899 7.45399C1.20487 7.64215 1.35785 7.79513 1.54601 7.89101C1.75992 8 2.03995 8 2.6 8ZM2.6 19H6.4C6.96005 19 7.24008 19 7.45399 18.891C7.64215 18.7951 7.79513 18.6422 7.89101 18.454C8 18.2401 8 17.9601 8 17.4V13.6C8 13.0399 8 12.7599 7.89101 12.546C7.79513 12.3578 7.64215 12.2049 7.45399 12.109C7.24008 12 6.96005 12 6.4 12H2.6C2.03995 12 1.75992 12 1.54601 12.109C1.35785 12.2049 1.20487 12.3578 1.10899 12.546C1 12.7599 1 13.0399 1 13.6V17.4C1 17.9601 1 18.2401 1.10899 18.454C1.20487 18.6422 1.35785 18.7951 1.54601 18.891C1.75992 19 2.03995 19 2.6 19Z" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
)
}
export default Qr

View File

@ -1,7 +1,7 @@
const Search = () => {
return (
<svg width="20" height="21" viewBox="0 0 20 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19 19.5L14.65 15.15M17 9.5C17 13.9183 13.4183 17.5 9 17.5C4.58172 17.5 1 13.9183 1 9.5C1 5.08172 4.58172 1.5 9 1.5C13.4183 1.5 17 5.08172 17 9.5Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M19 19.5L14.65 15.15M17 9.5C17 13.9183 13.4183 17.5 9 17.5C4.58172 17.5 1 13.9183 1 9.5C1 5.08172 4.58172 1.5 9 1.5C13.4183 1.5 17 5.08172 17 9.5Z" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
)
}

View File

@ -46,10 +46,6 @@
color: var(--gray-light);
}
.profile .name .copy {
margin-bottom: 8px;
}
.profile .avatar-wrapper {
z-index: 1;
}
@ -103,10 +99,6 @@
font-size: 14px;
}
.tabs > div {
margin-right: 0;
}
.profile .links {
margin-top: 4px;
margin-left: 2px;
@ -175,6 +167,15 @@
position: absolute;
top: 80px;
right: 0;
display: flex;
flex-direction: row;
align-items: center;
}
.profile .icon-actions {
display: flex;
flex-direction: row;
align-items: center;
}
@media (min-width: 520px) {
@ -187,6 +188,10 @@
margin-right: 8px;
}
.profile .profile-actions button.icon:not(:last-child) {
margin-right: 0;
}
@media (min-width: 520px) {
.profile .banner {
width: 100%;
@ -194,5 +199,17 @@
height: 300px;
margin-bottom: -100px;
}
.profile .profile-actions button.icon:not(:last-child) {
margin-right: 2px;
}
}
.profile .npub {
display: flex;
flex-direction: row;
align-items: center;
}
.qr-modal .modal-body {
width: unset;
}

View File

@ -5,6 +5,7 @@ import { useSelector } from "react-redux";
import { useNavigate, useParams } from "react-router-dom";
import Link from "Icons/Link";
import Qr from "Icons/Qr";
import Zap from "Icons/Zap";
import Envelope from "Icons/Envelope";
import { useUserProfile } from "Feed/ProfileFeed";
@ -22,9 +23,12 @@ import FollowersList from "Element/FollowersList";
import BlockList from "Element/BlockList";
import MutedList from "Element/MutedList";
import FollowsList from "Element/FollowsList";
import IconButton from "Element/IconButton";
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",
@ -46,8 +50,9 @@ 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 aboutText = user?.about || ''
const about = Text({ content: user?.about || '', tags: [], users: new Map() })
const about = Text({ content: aboutText, tags: [], users: new Map() })
const lnurl = extractLnAddress(user?.lud16 || user?.lud06 || "");
useEffect(() => {
@ -132,41 +137,49 @@ export default function ProfilePage() {
)
}
function renderIcons() {
return (
<div className="icon-actions">
<IconButton onClick={() => setShowProfileQr(true)}>
<Qr width={14} height={16} />
</IconButton>
{showProfileQr && (
<Modal className="qr-modal" onClose={() => setShowProfileQr(false)}>
<QrCode data={`nostr:${hexToBech32("npub", id)}`} link={undefined} className="m10"/>
</Modal>
)}
{isMe ? (
<>
<LogoutButton />
<button type="button" onClick={() => navigate("/settings")}>
Settings
</button>
</>
) : (
<>
<IconButton onClick={() => setShowLnQr(true)}>
<Zap width={14} height={16} />
</IconButton>
{!loggedOut && (
<>
<IconButton onClick={() => navigate(`/messages/${hexToBech32("npub", id)}`)}>
<Envelope width={16} height={13} />
</IconButton>
</>
)}
</>
)}
</div>
)
}
function userDetails() {
return (
<div className="details-wrapper">
{username()}
<div className="profile-actions">
{isMe ? (
<>
<LogoutButton />
<button type="button" onClick={() => navigate("/settings")}>
Settings
</button>
</>
) : (
<>
<button
className="icon"
type="button"
onClick={() => setShowLnQr(true)}
>
<Zap width={14} height={16} />
</button>
{!loggedOut && (
<>
<button
className="icon"
type="button"
onClick={() => navigate(`/messages/${hexToBech32("npub", id)}`)}
>
<Envelope width={16} height={13} />
</button>
<FollowButton pubkey={id} />
</>
)}
</>
)}
{renderIcons()}
{!isMe && <FollowButton pubkey={id} />}
</div>
{bio()}
</div>

View File

@ -171,11 +171,17 @@ button.icon {
border: none;
background: none;
color: var(--font-color);
min-height: 28px;
}
button.icon .icon-wrapper {
display: flex;
align-items: center;
justify-content: center;
}
button.icon:hover {
color: white;
background: var(--highlight);
color: var(--highlight);
}
.btn {
@ -420,11 +426,7 @@ body.scroll-lock {
}
.tabs>div {
margin-right: 10px;
cursor: pointer;
}
.tabs>div:last-child {
margin: 0;
}