Note creator V2 styles
This commit is contained in:
37
packages/app/src/Element/AsyncIcon.tsx
Normal file
37
packages/app/src/Element/AsyncIcon.tsx
Normal file
@ -0,0 +1,37 @@
|
||||
import Icon from "Icons/Icon";
|
||||
import Spinner from "Icons/Spinner";
|
||||
import { HTMLProps, useState } from "react";
|
||||
|
||||
export interface AsyncIconProps extends HTMLProps<HTMLDivElement> {
|
||||
iconName: string;
|
||||
iconSize?: number;
|
||||
loading?: boolean;
|
||||
onClick?: (e: React.MouseEvent<HTMLDivElement>) => Promise<void>;
|
||||
}
|
||||
|
||||
export function AsyncIcon(props: AsyncIconProps) {
|
||||
const [loading, setLoading] = useState(props.loading ?? false);
|
||||
|
||||
async function handleClick(e: React.MouseEvent<HTMLDivElement>) {
|
||||
setLoading(true);
|
||||
try {
|
||||
if (props.onClick) {
|
||||
await props.onClick(e);
|
||||
}
|
||||
} catch (ex) {
|
||||
console.error(ex);
|
||||
}
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
const mergedProps = { ...props } as Record<string, unknown>;
|
||||
delete mergedProps["iconName"];
|
||||
delete mergedProps["iconSize"];
|
||||
delete mergedProps["loading"];
|
||||
return (
|
||||
<div {...mergedProps} onClick={e => handleClick(e)}>
|
||||
{loading ? <Spinner /> : <Icon name={props.iconName} size={props.iconSize} />}
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
}
|
@ -12,11 +12,16 @@
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
background-color: var(--note-bg);
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
background-color: var(--gray-superdark);
|
||||
padding: 16px 24px;
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 500px;
|
||||
border: 1px solid var(--font-tertiary-color);
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
}
|
||||
|
||||
.modal-body button:hover {
|
||||
background-color: var(--gray);
|
||||
}
|
||||
|
@ -48,11 +48,13 @@ export interface NoteProps {
|
||||
depth?: number;
|
||||
options?: {
|
||||
showHeader?: boolean;
|
||||
showContextMenu?: boolean;
|
||||
showTime?: boolean;
|
||||
showPinned?: boolean;
|
||||
showBookmarked?: boolean;
|
||||
showFooter?: boolean;
|
||||
showReactionsLink?: boolean;
|
||||
showMedia?: boolean;
|
||||
canUnpin?: boolean;
|
||||
canUnbookmark?: boolean;
|
||||
canClick?: boolean;
|
||||
@ -151,6 +153,7 @@ export default function Note(props: NoteProps) {
|
||||
showFooter: true,
|
||||
canUnpin: false,
|
||||
canUnbookmark: false,
|
||||
showContextMenu: true,
|
||||
...opt,
|
||||
};
|
||||
|
||||
@ -209,7 +212,15 @@ export default function Note(props: NoteProps) {
|
||||
</Reveal>
|
||||
);
|
||||
}
|
||||
return <Text content={body} tags={ev.tags} creator={ev.pubkey} depth={props.depth} />;
|
||||
return (
|
||||
<Text
|
||||
content={body}
|
||||
tags={ev.tags}
|
||||
creator={ev.pubkey}
|
||||
depth={props.depth}
|
||||
disableMedia={!(options.showMedia ?? true)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
function goToEvent(
|
||||
@ -355,12 +366,14 @@ export default function Note(props: NoteProps) {
|
||||
<Icon name="pin" /> <FormattedMessage {...messages.Pinned} />
|
||||
</div>
|
||||
)}
|
||||
<NoteContextMenu
|
||||
ev={ev}
|
||||
react={async () => {}}
|
||||
onTranslated={t => setTranslated(t)}
|
||||
setShowReactions={setShowReactions}
|
||||
/>
|
||||
{options.showContextMenu && (
|
||||
<NoteContextMenu
|
||||
ev={ev}
|
||||
react={async () => {}}
|
||||
onTranslated={t => setTranslated(t)}
|
||||
setShowReactions={setShowReactions}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
@ -1,22 +1,43 @@
|
||||
.note-creator {
|
||||
margin-bottom: 10px;
|
||||
background-color: var(--note-bg);
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
padding: 6px;
|
||||
position: relative;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0px 0px 6px 1px rgba(182, 108, 156, 0.3);
|
||||
background: linear-gradient(var(--gray-superdark), var(--gray-superdark)) padding-box,
|
||||
linear-gradient(90deg, #ef9644, #fd7c49, #ff5e58, #ff3b70, #ff088e, #eb00b1, #c31ed5, #7b41f6) border-box;
|
||||
}
|
||||
|
||||
.note-reply {
|
||||
margin: 10px;
|
||||
.note-creator-modal .modal-body {
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.note-creator-modal .note.card {
|
||||
padding: 8px 12px;
|
||||
border-radius: 12px;
|
||||
background-color: var(--gray-dark);
|
||||
}
|
||||
|
||||
.note-creator-modal h4 {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 1.21px;
|
||||
text-transform: uppercase;
|
||||
color: var(--gray-light);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.note-creator-relay {
|
||||
background-color: var(--gray-dark);
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.note-creator textarea {
|
||||
border: none;
|
||||
outline: none;
|
||||
resize: none;
|
||||
background-color: var(--note-bg);
|
||||
border-radius: 10px 10px 0 0;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
margin: 8px 12px;
|
||||
background-color: var(--gray-superdark);
|
||||
min-height: 100px;
|
||||
width: stretch;
|
||||
width: -webkit-fill-available;
|
||||
@ -30,67 +51,9 @@
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
@media (min-width: 520px) {
|
||||
.note-creator textarea {
|
||||
min-height: 210px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 720px) {
|
||||
.note-creator textarea {
|
||||
min-height: 321px;
|
||||
}
|
||||
}
|
||||
|
||||
.note-creator.poll textarea {
|
||||
min-height: 120px;
|
||||
}
|
||||
.note-creator-actions {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.note-creator .insert {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
width: stretch;
|
||||
width: -webkit-fill-available;
|
||||
width: -moz-available;
|
||||
}
|
||||
|
||||
.note-creator .insert > button {
|
||||
width: 48px;
|
||||
height: 36px;
|
||||
background: var(--gray-dark);
|
||||
color: white;
|
||||
border-radius: 17px;
|
||||
margin-right: 5px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.note-creator .attachment:hover {
|
||||
background: var(--font-color);
|
||||
color: var(--gray-dark);
|
||||
}
|
||||
|
||||
.light .note-creator .attachment {
|
||||
background: var(--gray-light);
|
||||
}
|
||||
|
||||
.light .note-creator .attachment:hover {
|
||||
background: var(--gray-dark);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.note-creator-actions button:not(:last-child) {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.note-creator .error {
|
||||
position: absolute;
|
||||
@ -101,6 +64,19 @@
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.note-creator-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.note-creator-icon.pfp .avatar {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.note-create-button {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
@ -120,17 +96,3 @@
|
||||
right: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.note-creator-modal .modal-body {
|
||||
background: var(--modal-bg-color);
|
||||
}
|
||||
|
||||
.note-preview {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.note-preview-body {
|
||||
text-overflow: ellipsis;
|
||||
padding: 4px 4px 0 56px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
import "./NoteCreator.css";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
@ -37,22 +38,7 @@ import { getCurrentSubscription } from "Subscription";
|
||||
import useLogin from "Hooks/useLogin";
|
||||
import { System } from "index";
|
||||
import AsyncButton from "Element/AsyncButton";
|
||||
|
||||
interface NotePreviewProps {
|
||||
note: TaggedNostrEvent;
|
||||
}
|
||||
|
||||
function NotePreview({ note }: NotePreviewProps) {
|
||||
return (
|
||||
<div className="note-preview">
|
||||
<ProfileImage pubkey={note.pubkey} />
|
||||
<div className="note-preview-body">
|
||||
{note.content.slice(0, 136)}
|
||||
{note.content.length > 140 && "..."}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
import { AsyncIcon } from "Element/AsyncIcon";
|
||||
|
||||
export function NoteCreator() {
|
||||
const { formatMessage } = useIntl();
|
||||
@ -72,7 +58,6 @@ export function NoteCreator() {
|
||||
selectedCustomRelays,
|
||||
error,
|
||||
} = useSelector((s: RootState) => s.noteCreator);
|
||||
const [uploadInProgress, setUploadInProgress] = useState(false);
|
||||
const dispatch = useDispatch();
|
||||
const sub = getCurrentSubscription(LoginStore.allSubscriptions());
|
||||
const login = useLogin();
|
||||
@ -138,7 +123,6 @@ export function NoteCreator() {
|
||||
}
|
||||
|
||||
async function uploadFile(file: File | Blob) {
|
||||
setUploadInProgress(true);
|
||||
try {
|
||||
if (file) {
|
||||
const rx = await uploader.upload(file, file.name);
|
||||
@ -156,8 +140,6 @@ export function NoteCreator() {
|
||||
if (error instanceof Error) {
|
||||
dispatch(setError(error?.message));
|
||||
}
|
||||
} finally {
|
||||
setUploadInProgress(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,8 +180,10 @@ export function NoteCreator() {
|
||||
data={preview as TaggedNostrEvent}
|
||||
related={[]}
|
||||
options={{
|
||||
showContextMenu: false,
|
||||
showFooter: false,
|
||||
canClick: false,
|
||||
showTime: false,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
@ -254,14 +238,12 @@ export function NoteCreator() {
|
||||
|
||||
function renderRelayCustomisation() {
|
||||
return (
|
||||
<div>
|
||||
<div className="flex-column g8">
|
||||
{Object.keys(relays.item || {})
|
||||
.filter(el => relays.item[el].write)
|
||||
.map((r, i, a) => (
|
||||
<div className="card flex">
|
||||
<div className="flex f-col f-grow">
|
||||
<div>{r}</div>
|
||||
</div>
|
||||
<div className="p flex f-space note-creator-relay">
|
||||
<div>{r}</div>
|
||||
<div>
|
||||
<input
|
||||
type="checkbox"
|
||||
@ -322,103 +304,97 @@ export function NoteCreator() {
|
||||
<>
|
||||
{show && (
|
||||
<Modal className="note-creator-modal" onClose={() => dispatch(setShow(false))}>
|
||||
{replyTo && <NotePreview note={replyTo} />}
|
||||
{replyTo && (
|
||||
<Note
|
||||
data={replyTo}
|
||||
related={[]}
|
||||
options={{
|
||||
showFooter: false,
|
||||
showContextMenu: false,
|
||||
showTime: false,
|
||||
canClick: false,
|
||||
showMedia: false,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{preview && getPreviewNote()}
|
||||
{!preview && (
|
||||
<div
|
||||
onPaste={handlePaste}
|
||||
className={`flex note-creator${replyTo ? " note-reply" : ""}${pollOptions ? " poll" : ""}`}>
|
||||
<div className="flex f-col f-grow">
|
||||
<Textarea
|
||||
autoFocus
|
||||
className={`textarea ${active ? "textarea--focused" : ""}`}
|
||||
onChange={onChange}
|
||||
value={note}
|
||||
onFocus={() => dispatch(setActive(true))}
|
||||
onKeyDown={e => {
|
||||
if (e.key === "Enter" && e.metaKey) {
|
||||
sendNote().catch(console.warn);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
{renderPollOptions()}
|
||||
<div className="insert">
|
||||
{sub && (
|
||||
<Menu
|
||||
menuButton={
|
||||
<button>
|
||||
<Icon name="code-circle" />
|
||||
</button>
|
||||
}
|
||||
menuClassName="ctx-menu">
|
||||
{listAccounts()}
|
||||
</Menu>
|
||||
)}
|
||||
{pollOptions === undefined && !replyTo && (
|
||||
<button onClick={() => dispatch(setPollOptions(["A", "B"]))}>
|
||||
<Icon name="pie-chart" />
|
||||
</button>
|
||||
)}
|
||||
<button onClick={attachFile}>
|
||||
<Icon name="attachment" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{error && <span className="error">{error}</span>}
|
||||
<div onPaste={handlePaste} className={`note-creator${pollOptions ? " poll" : ""}`}>
|
||||
<Textarea
|
||||
autoFocus
|
||||
className={`textarea ${active ? "textarea--focused" : ""}`}
|
||||
onChange={onChange}
|
||||
value={note}
|
||||
onFocus={() => dispatch(setActive(true))}
|
||||
onKeyDown={e => {
|
||||
if (e.key === "Enter" && e.metaKey) {
|
||||
sendNote().catch(console.warn);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
{renderPollOptions()}
|
||||
</div>
|
||||
)}
|
||||
<div className="note-creator-actions">
|
||||
{uploadInProgress && <Spinner />}
|
||||
<button className="secondary" onClick={() => dispatch(setShowAdvanced(!showAdvanced))}>
|
||||
<FormattedMessage defaultMessage="Advanced" />
|
||||
</button>
|
||||
<button className="secondary" onClick={cancel}>
|
||||
<FormattedMessage {...messages.Cancel} />
|
||||
</button>
|
||||
<AsyncButton onClick={onSubmit}>
|
||||
{replyTo ? <FormattedMessage {...messages.Reply} /> : <FormattedMessage {...messages.Send} />}
|
||||
</AsyncButton>
|
||||
<div className="flex f-space">
|
||||
<div className="flex g8">
|
||||
<ProfileImage pubkey={login.publicKey ?? ""} className="note-creator-icon" link="" showUsername={false} />
|
||||
{pollOptions === undefined && !replyTo && (
|
||||
<div className="note-creator-icon">
|
||||
<Icon name="pie-chart" onClick={() => dispatch(setPollOptions(["A", "B"]))} size={24} />
|
||||
</div>
|
||||
)}
|
||||
<AsyncIcon iconName="image-plus" iconSize={24} onClick={attachFile} className="note-creator-icon" />
|
||||
<button className="secondary" onClick={() => dispatch(setShowAdvanced(!showAdvanced))}>
|
||||
<FormattedMessage defaultMessage="Advanced" />
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex g8">
|
||||
<button className="secondary" onClick={cancel}>
|
||||
<FormattedMessage defaultMessage="Cancel" />
|
||||
</button>
|
||||
<AsyncButton onClick={onSubmit}>
|
||||
{replyTo ? <FormattedMessage defaultMessage="Reply" /> : <FormattedMessage defaultMessage="Send" />}
|
||||
</AsyncButton>
|
||||
</div>
|
||||
</div>
|
||||
{error && <span className="error">{error}</span>}
|
||||
{showAdvanced && (
|
||||
<div>
|
||||
<>
|
||||
<button className="secondary" onClick={loadPreview}>
|
||||
<FormattedMessage defaultMessage="Toggle Preview" />
|
||||
</button>
|
||||
<h4>
|
||||
<FormattedMessage defaultMessage="Custom Relays" />
|
||||
</h4>
|
||||
<p>
|
||||
<FormattedMessage defaultMessage="Send note to a subset of your write relays" />
|
||||
</p>
|
||||
{renderRelayCustomisation()}
|
||||
<h4>
|
||||
<FormattedMessage defaultMessage="Forward Zaps" />
|
||||
</h4>
|
||||
<p>
|
||||
<div>
|
||||
<h4>
|
||||
<FormattedMessage defaultMessage="Custom Relays" />
|
||||
</h4>
|
||||
<p>
|
||||
<FormattedMessage defaultMessage="Send note to a subset of your write relays" />
|
||||
</p>
|
||||
{renderRelayCustomisation()}
|
||||
</div>
|
||||
<div className="flex-column g8">
|
||||
<h4>
|
||||
<FormattedMessage defaultMessage="Forward Zaps" />
|
||||
</h4>
|
||||
<FormattedMessage defaultMessage="All zaps sent to this note will be received by the following LNURL" />
|
||||
</p>
|
||||
<b className="warning">
|
||||
<FormattedMessage defaultMessage="Not all clients support this yet" />
|
||||
</b>
|
||||
<input
|
||||
type="text"
|
||||
className="w-max"
|
||||
placeholder={formatMessage({
|
||||
defaultMessage: "LNURL to forward zaps to",
|
||||
})}
|
||||
value={zapForward}
|
||||
onChange={e => dispatch(setZapForward(e.target.value))}
|
||||
/>
|
||||
<h4>
|
||||
<FormattedMessage defaultMessage="Sensitive Content" />
|
||||
</h4>
|
||||
<p>
|
||||
<input
|
||||
type="text"
|
||||
className="w-max"
|
||||
placeholder={formatMessage({
|
||||
defaultMessage: "LNURL to forward zaps to",
|
||||
})}
|
||||
value={zapForward}
|
||||
onChange={e => dispatch(setZapForward(e.target.value))}
|
||||
/>
|
||||
<span className="warning">
|
||||
<FormattedMessage defaultMessage="Not all clients support this yet" />
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex-column g8">
|
||||
<h4>
|
||||
<FormattedMessage defaultMessage="Sensitive Content" />
|
||||
</h4>
|
||||
<FormattedMessage defaultMessage="Users must accept the content warning to show the content of your note." />
|
||||
</p>
|
||||
<b className="warning">
|
||||
<FormattedMessage defaultMessage="Not all clients support this yet" />
|
||||
</b>
|
||||
<div className="flex">
|
||||
<input
|
||||
className="w-max"
|
||||
type="text"
|
||||
@ -430,8 +406,11 @@ export function NoteCreator() {
|
||||
defaultMessage: "Reason",
|
||||
})}
|
||||
/>
|
||||
<span className="warning">
|
||||
<FormattedMessage defaultMessage="Not all clients support this yet" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</Modal>
|
||||
)}
|
||||
|
@ -6,9 +6,6 @@ import { TaggedNostrEvent, HexKey, u256, ParsedZap, countLeadingZeros } from "@s
|
||||
import { LNURL } from "@snort/shared";
|
||||
import { useUserProfile } from "@snort/system-react";
|
||||
|
||||
import Icon from "Icons/Icon";
|
||||
import Spinner from "Icons/Spinner";
|
||||
|
||||
import { formatShort } from "Number";
|
||||
import useEventPublisher from "Feed/EventPublisher";
|
||||
import { delay, findTag, normalizeReaction, unwrap } from "SnortUtils";
|
||||
@ -17,6 +14,7 @@ import SendSats from "Element/SendSats";
|
||||
import { ZapsSummary } from "Element/Zap";
|
||||
import { RootState } from "State/Store";
|
||||
import { setReplyTo, setShow, reset } from "State/NoteCreator";
|
||||
import { AsyncIcon } from "Element/AsyncIcon";
|
||||
|
||||
import { useWallet } from "Wallet";
|
||||
import useLogin from "Hooks/useLogin";
|
||||
@ -282,27 +280,14 @@ interface AsyncFooterIconProps extends HTMLProps<HTMLDivElement> {
|
||||
}
|
||||
|
||||
function AsyncFooterIcon(props: AsyncFooterIconProps) {
|
||||
const [loading, setLoading] = useState(props.loading ?? false);
|
||||
|
||||
async function handleClick(e: React.MouseEvent<HTMLDivElement>) {
|
||||
setLoading(true);
|
||||
try {
|
||||
if (props.onClick) {
|
||||
await props.onClick(e);
|
||||
}
|
||||
} catch (ex) {
|
||||
console.error(ex);
|
||||
}
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
const mergedProps = {
|
||||
...props,
|
||||
iconSize: 18,
|
||||
className: `reaction-pill${props.className ? ` ${props.className}` : ""}`,
|
||||
};
|
||||
return (
|
||||
<div
|
||||
{...props}
|
||||
className={`reaction-pill${props.className ? ` ${props.className}` : ""}`}
|
||||
onClick={e => handleClick(e)}>
|
||||
{loading ? <Spinner /> : <Icon name={props.iconName} size={18} />}
|
||||
<AsyncIcon {...mergedProps}>
|
||||
{props.value > 0 && <div className="reaction-pill-number">{formatShort(props.value)}</div>}
|
||||
</div>
|
||||
</AsyncIcon>
|
||||
);
|
||||
}
|
||||
|
@ -48,25 +48,37 @@ export default function ProfileImage({
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Link
|
||||
className={`pfp${className ? ` ${className}` : ""}`}
|
||||
to={link === undefined ? profileLink(pubkey) : link}
|
||||
onClick={handleClick}>
|
||||
<div className="avatar-wrapper">
|
||||
<Avatar user={user} size={size} />
|
||||
</div>
|
||||
{showUsername && (
|
||||
<div className="f-ellipsis">
|
||||
<div className="username">
|
||||
<div>{name.trim()}</div>
|
||||
{nip05 && <Nip05 nip05={nip05} pubkey={pubkey} verifyNip={verifyNip} />}
|
||||
</div>
|
||||
<div className="subheader">{subHeader}</div>
|
||||
function inner() {
|
||||
return (
|
||||
<>
|
||||
<div className="avatar-wrapper">
|
||||
<Avatar user={user} size={size} />
|
||||
</div>
|
||||
)}
|
||||
</Link>
|
||||
);
|
||||
{showUsername && (
|
||||
<div className="f-ellipsis">
|
||||
<div className="username">
|
||||
<div>{name.trim()}</div>
|
||||
{nip05 && <Nip05 nip05={nip05} pubkey={pubkey} verifyNip={verifyNip} />}
|
||||
</div>
|
||||
<div className="subheader">{subHeader}</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
if (link === "") {
|
||||
return <div className={`pfp${className ? ` ${className}` : ""}`}>{inner()}</div>;
|
||||
} else {
|
||||
return (
|
||||
<Link
|
||||
className={`pfp${className ? ` ${className}` : ""}`}
|
||||
to={link === undefined ? profileLink(pubkey) : link}
|
||||
onClick={handleClick}>
|
||||
{inner()}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function getDisplayName(user: UserMetadata | undefined, pubkey: HexKey) {
|
||||
|
@ -7,7 +7,7 @@
|
||||
}
|
||||
|
||||
.light .reactions-modal .modal-body {
|
||||
background-color: var(--note-bg);
|
||||
background-color: var(--gray-superdark);
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
|
@ -22,7 +22,7 @@
|
||||
}
|
||||
|
||||
.light .lnurl-tip {
|
||||
background-color: var(--note-bg);
|
||||
background-color: var(--gray-superdark);
|
||||
}
|
||||
|
||||
.lnurl-tip h3 {
|
||||
@ -95,7 +95,7 @@
|
||||
|
||||
.sat-amount.active {
|
||||
font-weight: bold;
|
||||
color: var(--note-bg);
|
||||
color: var(--gray-superdark);
|
||||
background-color: var(--font-color);
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
.user-item,
|
||||
.emoji-item {
|
||||
color: var(--font-color);
|
||||
background: var(--note-bg);
|
||||
background: var(--gray-superdark);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
@ -37,7 +37,7 @@
|
||||
}
|
||||
|
||||
.thread-container .show-more {
|
||||
background: var(--note-bg);
|
||||
background: var(--gray-superdark);
|
||||
padding-left: 76px;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
@ -95,12 +95,12 @@
|
||||
|
||||
.thread-container .collapsed,
|
||||
.thread-container .show-more-container {
|
||||
background: var(--note-bg);
|
||||
background: var(--gray-superdark);
|
||||
min-height: 48px;
|
||||
}
|
||||
|
||||
.thread-container .collapsed {
|
||||
background-color: var(--note-bg);
|
||||
background-color: var(--gray-superdark);
|
||||
}
|
||||
|
||||
.thread-container .hidden-note {
|
||||
|
Reference in New Issue
Block a user