Moar UI fixes #73
4
d.ts
Normal file
4
d.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
declare module "*.jpg" {
|
||||||
|
const value: any
|
||||||
|
export default value
|
||||||
|
}
|
35
src/element/Avatar.css
Normal file
35
src/element/Avatar.css
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
.avatar {
|
||||||
|
border-radius: 50%;
|
||||||
|
height: 210px;
|
||||||
|
width: 210px;
|
||||||
|
background-image: var(--img-url), var(--gray-gradient);
|
||||||
|
border: 2px solid transparent;
|
||||||
|
background-origin: border-box;
|
||||||
|
background-clip: content-box, border-box;
|
||||||
|
background-size: cover;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar[data-domain="snort.social"] {
|
||||||
|
background-image: var(--img-url), var(--snort-gradient);
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar[data-domain="nostrplebs.com"] {
|
||||||
|
background-image: var(--img-url), var(--nostrplebs-gradient);
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar[data-domain="nostrpurple.com"] {
|
||||||
|
background-image: var(--img-url), var(--nostrplebs-gradient);
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar[data-domain="nostr.fan"] {
|
||||||
|
background-image: var(--img-url), var(--nostrplebs-gradient);
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar[data-domain="nostrich.zone"] {
|
||||||
|
background-image: var(--img-url), var(--nostrplebs-gradient);
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar[data-domain="nostriches.net"] {
|
||||||
|
background-image: var(--img-url), var(--nostrplebs-gradient);
|
||||||
|
}
|
25
src/element/Avatar.tsx
Normal file
25
src/element/Avatar.tsx
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import "./Avatar.css";
|
||||||
|
import Nostrich from "../nostrich.jpg";
|
||||||
|
|
||||||
|
import { CSSProperties } from "react";
|
||||||
|
|
||||||
|
import type { UserMetadata } from "../nostr";
|
||||||
|
|
||||||
|
|
||||||
|
const Avatar = ({ user, ...rest }: { user?: UserMetadata, onClick?: () => void}) => {
|
||||||
|
const avatarUrl = (user?.picture?.length ?? 0) === 0 ? Nostrich : user?.picture
|
||||||
|
const backgroundImage = `url(${avatarUrl})`
|
||||||
|
const domain = user?.nip05 && user.nip05.split('@')[1]
|
||||||
|
const style = { '--img-url': backgroundImage } as CSSProperties
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
{...rest}
|
||||||
|
style={style}
|
||||||
|
className="avatar"
|
||||||
|
data-domain={domain?.toLowerCase()}
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Avatar
|
@ -2,7 +2,8 @@
|
|||||||
background: var(--bg-color);
|
background: var(--bg-color);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
border: 1px solid var(--gray-tertiary);
|
border: 1px solid var(--gray-tertiary);
|
||||||
padding: 10px;
|
padding: 12px;
|
||||||
|
margin: 10px auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.note-invoice h2, .note-invoice h4, .note-invoice p {
|
.note-invoice h2, .note-invoice h4, .note-invoice p {
|
||||||
|
@ -12,12 +12,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.note > .header .reply {
|
.note > .header .reply {
|
||||||
font-size: small;
|
font-size: 12px;
|
||||||
color: var(--gray-light);
|
color: var(--gray-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
.note > .header > .info {
|
.note > .header > .info {
|
||||||
font-size: small;
|
font-size: 10px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
color: var(--gray-light);
|
color: var(--gray-light);
|
||||||
align-self: flex-start;
|
align-self: flex-start;
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
.reaction > .header > .info {
|
.reaction > .header > .info {
|
||||||
color: var(--gray-light);
|
color: var(--gray-light);
|
||||||
font-size: small;
|
font-size: 10px;
|
||||||
align-self: flex-start;
|
align-self: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,11 +3,14 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pfp img {
|
.pfp .avatar-wrapper {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pfp .avatar {
|
||||||
|
border-width: 1px;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
margin-right: 10px;
|
|
||||||
border-radius: 100%;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
import "./ProfileImage.css";
|
import "./ProfileImage.css";
|
||||||
// @ts-ignore
|
|
||||||
import Nostrich from "../nostrich.jpg";
|
|
||||||
|
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
import useProfile from "../feed/ProfileFeed";
|
import useProfile from "../feed/ProfileFeed";
|
||||||
import { hexToBech32, profileLink } from "../Util";
|
import { hexToBech32, profileLink } from "../Util";
|
||||||
import LazyImage from "./LazyImage";
|
import Avatar from "./Avatar"
|
||||||
import Nip05 from "./Nip05";
|
import Nip05 from "./Nip05";
|
||||||
import { HexKey } from "../nostr";
|
import { HexKey } from "../nostr";
|
||||||
|
|
||||||
@ -35,7 +33,9 @@ export default function ProfileImage({ pubkey, subHeader, showUsername = true, c
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`pfp${className ? ` ${className}` : ""}`}>
|
<div className={`pfp${className ? ` ${className}` : ""}`}>
|
||||||
<LazyImage src={hasImage ? user!.picture : Nostrich} onClick={() => navigate(link ?? profileLink(pubkey))} />
|
<div className="avatar-wrapper">
|
||||||
|
<Avatar user={user} onClick={() => navigate(link ?? profileLink(pubkey))} />
|
||||||
|
</div>
|
||||||
{showUsername && (<div className="f-grow">
|
{showUsername && (<div className="f-grow">
|
||||||
<Link key={pubkey} to={link ?? profileLink(pubkey)}>
|
<Link key={pubkey} to={link ?? profileLink(pubkey)}>
|
||||||
<div className="profile-name">
|
<div className="profile-name">
|
||||||
|
@ -33,6 +33,13 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text li {
|
||||||
|
margin-top: -1em;
|
||||||
|
}
|
||||||
|
.text li:last-child {
|
||||||
|
margin-bottom: -2em;
|
||||||
|
}
|
||||||
|
|
||||||
.text hr {
|
.text hr {
|
||||||
border: 0;
|
border: 0;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import "./Textarea.css";
|
import "./Textarea.css";
|
||||||
// @ts-expect-error
|
|
||||||
import Nostrich from "../nostrich.jpg";
|
import Nostrich from "../nostrich.jpg";
|
||||||
|
|
||||||
import { useLiveQuery } from "dexie-react-hooks";
|
import { useLiveQuery } from "dexie-react-hooks";
|
||||||
|
@ -44,42 +44,6 @@
|
|||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile .avatar {
|
|
||||||
border-radius: 50%;
|
|
||||||
height: 210px;
|
|
||||||
width: 210px;
|
|
||||||
background-image: var(--img-url), var(--gray-gradient);
|
|
||||||
border: 4px solid transparent;
|
|
||||||
background-origin: border-box;
|
|
||||||
background-clip: content-box, border-box;
|
|
||||||
background-size: cover;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.profile .avatar[data-domain="snort.social"] {
|
|
||||||
background-image: var(--img-url), var(--snort-gradient);
|
|
||||||
}
|
|
||||||
|
|
||||||
.profile .avatar[data-domain="nostrplebs.com"] {
|
|
||||||
background-image: var(--img-url), var(--nostrplebs-gradient);
|
|
||||||
}
|
|
||||||
|
|
||||||
.profile .avatar[data-domain="nostrpurple.com"] {
|
|
||||||
background-image: var(--img-url), var(--nostrplebs-gradient);
|
|
||||||
}
|
|
||||||
|
|
||||||
.profile .avatar[data-domain="nostr.fan"] {
|
|
||||||
background-image: var(--img-url), var(--nostrplebs-gradient);
|
|
||||||
}
|
|
||||||
|
|
||||||
.profile .avatar[data-domain="nostrich.zone"] {
|
|
||||||
background-image: var(--img-url), var(--nostrplebs-gradient);
|
|
||||||
}
|
|
||||||
|
|
||||||
.profile .avatar[data-domain="nostriches.net"] {
|
|
||||||
background-image: var(--img-url), var(--nostrplebs-gradient);
|
|
||||||
}
|
|
||||||
|
|
||||||
.profile .name {
|
.profile .name {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import "./ProfilePage.css";
|
import "./ProfilePage.css";
|
||||||
// @ts-ignore
|
|
||||||
import Nostrich from "../nostrich.jpg";
|
|
||||||
|
|
||||||
import { useEffect, useMemo, useState } from "react";
|
import { useEffect, useMemo, useState } from "react";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
@ -11,6 +9,7 @@ import { useNavigate, useParams } from "react-router-dom";
|
|||||||
import useProfile from "../feed/ProfileFeed";
|
import useProfile from "../feed/ProfileFeed";
|
||||||
import FollowButton from "../element/FollowButton";
|
import FollowButton from "../element/FollowButton";
|
||||||
import { extractLnAddress, parseId, hexToBech32 } from "../Util";
|
import { extractLnAddress, parseId, hexToBech32 } from "../Util";
|
||||||
|
import Avatar from "../element/Avatar";
|
||||||
import Timeline from "../element/Timeline";
|
import Timeline from "../element/Timeline";
|
||||||
import Text from '../element/Text'
|
import Text from '../element/Text'
|
||||||
import LNURLTip from "../element/LNURLTip";
|
import LNURLTip from "../element/LNURLTip";
|
||||||
@ -39,10 +38,7 @@ export default function ProfilePage() {
|
|||||||
const isMe = loginPubKey === id;
|
const isMe = loginPubKey === id;
|
||||||
const [showLnQr, setShowLnQr] = useState<boolean>(false);
|
const [showLnQr, setShowLnQr] = useState<boolean>(false);
|
||||||
const [tab, setTab] = useState(ProfileTab.Notes);
|
const [tab, setTab] = useState(ProfileTab.Notes);
|
||||||
const about = Text({ content: user?.about ?? "", users: new Map(), tags: [] })
|
const about = Text({ content: user?.about || '', tags: [], users: new Map() })
|
||||||
const avatarUrl = (user?.picture?.length ?? 0) === 0 ? Nostrich : user?.picture
|
|
||||||
const backgroundImage = `url(${avatarUrl})`
|
|
||||||
const domain = user?.nip05 && user.nip05.split('@')[1]
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setTab(ProfileTab.Notes);
|
setTab(ProfileTab.Notes);
|
||||||
@ -109,8 +105,7 @@ export default function ProfilePage() {
|
|||||||
function avatar() {
|
function avatar() {
|
||||||
return (
|
return (
|
||||||
<div className="avatar-wrapper">
|
<div className="avatar-wrapper">
|
||||||
<div style={{ ['--img-url' as any]: backgroundImage }} className="avatar" data-domain={domain?.toLowerCase()}>
|
<Avatar user={user} />
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import "./SettingsPage.css";
|
import "./SettingsPage.css";
|
||||||
// @ts-ignore
|
|
||||||
import Nostrich from "../nostrich.jpg";
|
import Nostrich from "../nostrich.jpg";
|
||||||
|
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
@ -196,7 +195,7 @@ export default function SettingsPage() {
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h2>Header</h2>
|
<h2>Header</h2>
|
||||||
<div style={{ backgroundImage: `url(${(banner?.length ?? 0) === 0 ? avatarPicture : banner})` }} className="banner">
|
<div style={{ backgroundImage: `url(${(banner?.length ?? 0) === 0 ? Nostrich : banner})` }} className="banner">
|
||||||
<div className="edit" onClick={() => setNewBanner()}>Edit</div>
|
<div className="edit" onClick={() => setNewBanner()}>Edit</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user