This commit is contained in:
parent
981ab5790a
commit
5a63a21fec
@ -572,7 +572,8 @@ export function NoteCreator() {
|
||||
</>
|
||||
)}
|
||||
{note.preview && getPreviewNote()}
|
||||
{!note.preview && (<>
|
||||
{!note.preview && (
|
||||
<>
|
||||
<div onPaste={handlePaste} className={classNames("note-creator", { poll: Boolean(note.pollOptions) })}>
|
||||
<Textarea
|
||||
onDragOver={handleDragOver}
|
||||
@ -592,13 +593,20 @@ export function NoteCreator() {
|
||||
{renderPollOptions()}
|
||||
</div>
|
||||
<div className="flex flex-col g4">
|
||||
<TagsInput value={note.hashTags} onChange={e => note.update(s => s.hashTags = e)} placeHolder={formatMessage({
|
||||
defaultMessage: "Add up to 4 hashtags"
|
||||
})} separators={["Enter", ","]} />
|
||||
{note.hashTags.length > 4 && <small className="warning">
|
||||
<FormattedMessage defaultMessage="Try to use less than 4 hashtags to stay on topic 🙏" />
|
||||
</small>}
|
||||
<TrendingHashTagsLine onClick={t => note.update(s => s.hashTags = appendDedupe(s.hashTags, [t]))} />
|
||||
<TagsInput
|
||||
value={note.hashTags}
|
||||
onChange={e => note.update(s => (s.hashTags = e))}
|
||||
placeHolder={formatMessage({
|
||||
defaultMessage: "Add up to 4 hashtags",
|
||||
})}
|
||||
separators={["Enter", ","]}
|
||||
/>
|
||||
{note.hashTags.length > 4 && (
|
||||
<small className="warning">
|
||||
<FormattedMessage defaultMessage="Try to use less than 5 hashtags to stay on topic 🙏" />
|
||||
</small>
|
||||
)}
|
||||
<TrendingHashTagsLine onClick={t => note.update(s => (s.hashTags = appendDedupe(s.hashTags, [t])))} />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
@ -627,7 +635,7 @@ export function NoteCreator() {
|
||||
}
|
||||
|
||||
function TrendingHashTagsLine(props: { onClick: (tag: string) => void }) {
|
||||
const [hashtags, setHashtags] = useState<Array<{ hashtag: string, posts: number }>>();
|
||||
const [hashtags, setHashtags] = useState<Array<{ hashtag: string; posts: number }>>();
|
||||
const { lang } = useLocale();
|
||||
|
||||
async function loadTrendingHashtags() {
|
||||
@ -641,14 +649,18 @@ function TrendingHashTagsLine(props: { onClick: (tag: string) => void }) {
|
||||
}, []);
|
||||
|
||||
if (!hashtags || hashtags.length === 0) return;
|
||||
return <div className="flex flex-col g4">
|
||||
return (
|
||||
<div className="flex flex-col g4">
|
||||
<small>
|
||||
<FormattedMessage defaultMessage="Popular Hashtags" />
|
||||
</small>
|
||||
<div className="flex g4 flex-wrap">
|
||||
{hashtags.slice(0, 5).map(a => <span className="px-2 py-1 bg-dark rounded-full pointer nowrap" onClick={() => props.onClick(a.hashtag)}>
|
||||
{hashtags.slice(0, 5).map(a => (
|
||||
<span className="px-2 py-1 bg-dark rounded-full pointer nowrap" onClick={() => props.onClick(a.hashtag)}>
|
||||
#{a.hashtag}
|
||||
</span>)}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -7,7 +7,7 @@ import { HashTagHeader } from "Pages/HashTagsPage";
|
||||
import { useLocale } from "IntlProvider";
|
||||
|
||||
export default function TrendingHashtags({ title }: { title?: ReactNode }) {
|
||||
const [hashtags, setHashtags] = useState<Array<{ hashtag: string, posts: number }>>();
|
||||
const [hashtags, setHashtags] = useState<Array<{ hashtag: string; posts: number }>>();
|
||||
const [error, setError] = useState<Error>();
|
||||
const { lang } = useLocale();
|
||||
|
||||
@ -28,8 +28,12 @@ export default function TrendingHashtags({ title }: { title?: ReactNode }) {
|
||||
if (error) return <ErrorOrOffline error={error} onRetry={loadTrendingHashtags} className="p" />;
|
||||
if (!hashtags) return <PageSpinner />;
|
||||
|
||||
return <>
|
||||
return (
|
||||
<>
|
||||
{title}
|
||||
{hashtags.map(a => <HashTagHeader tag={a.hashtag} className="bb p" />)}
|
||||
{hashtags.map(a => (
|
||||
<HashTagHeader tag={a.hashtag} events={a.posts} className="bb p" />
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
6
packages/app/src/External/NostrBand.ts
vendored
6
packages/app/src/External/NostrBand.ts
vendored
@ -20,9 +20,9 @@ export interface TrendingNoteResponse {
|
||||
|
||||
export interface TrendingHashtagsResponse {
|
||||
hashtags: Array<{
|
||||
hashtag: string,
|
||||
posts: number
|
||||
}>
|
||||
hashtag: string;
|
||||
posts: number;
|
||||
}>;
|
||||
}
|
||||
|
||||
export interface SuggestedFollow {
|
||||
|
@ -12,6 +12,7 @@ import { setTags } from "Login";
|
||||
import AsyncButton from "Element/AsyncButton";
|
||||
import ProfileImage from "Element/User/ProfileImage";
|
||||
import classNames from "classnames";
|
||||
import { formatShort } from "Number";
|
||||
|
||||
const HashTagsPage = () => {
|
||||
const params = useParams();
|
||||
@ -34,7 +35,7 @@ const HashTagsPage = () => {
|
||||
|
||||
export default HashTagsPage;
|
||||
|
||||
export function HashTagHeader({ tag, className }: { tag: string, className?: string }) {
|
||||
export function HashTagHeader({ tag, events, className }: { tag: string; events?: number; className?: string }) {
|
||||
const login = useLogin();
|
||||
const isFollowing = useMemo(() => {
|
||||
return login.tags.item.includes(tag);
|
||||
@ -63,7 +64,19 @@ export function HashTagHeader({ tag, className }: { tag: string, className?: str
|
||||
return (
|
||||
<div className={classNames("flex flex-col", className)}>
|
||||
<div className="flex items-center justify-between">
|
||||
<b className="text-lg">#{tag}</b>
|
||||
<div className="flex g8 items-center">
|
||||
<b className="text-xl">#{tag}</b>
|
||||
{events && (
|
||||
<small>
|
||||
<FormattedMessage
|
||||
defaultMessage="{n} notes"
|
||||
values={{
|
||||
n: formatShort(events),
|
||||
}}
|
||||
/>
|
||||
</small>
|
||||
)}
|
||||
</div>
|
||||
{isFollowing ? (
|
||||
<AsyncButton className="secondary" onClick={() => followTags(login.tags.item.filter(t => t !== tag))}>
|
||||
<FormattedMessage defaultMessage="Unfollow" />
|
||||
|
@ -298,6 +298,9 @@
|
||||
"defaultMessage": "Parent",
|
||||
"description": "Link to parent note in thread"
|
||||
},
|
||||
"AIgmDy": {
|
||||
"defaultMessage": "Add up to 4 hashtags"
|
||||
},
|
||||
"AN0Z7Q": {
|
||||
"defaultMessage": "Muted Words"
|
||||
},
|
||||
@ -879,6 +882,9 @@
|
||||
"XICsE8": {
|
||||
"defaultMessage": "File hosts"
|
||||
},
|
||||
"XXm7jJ": {
|
||||
"defaultMessage": "Trending Hashtags"
|
||||
},
|
||||
"XgWvGA": {
|
||||
"defaultMessage": "Reactions"
|
||||
},
|
||||
@ -993,9 +999,15 @@
|
||||
"d7d0/x": {
|
||||
"defaultMessage": "LN Address"
|
||||
},
|
||||
"d8gpCh": {
|
||||
"defaultMessage": "Try to use less than 5 hashtags to stay on topic 🙏"
|
||||
},
|
||||
"dOQCL8": {
|
||||
"defaultMessage": "Display name"
|
||||
},
|
||||
"ddd3JX": {
|
||||
"defaultMessage": "Popular Hashtags"
|
||||
},
|
||||
"deEeEI": {
|
||||
"defaultMessage": "Register"
|
||||
},
|
||||
@ -1382,6 +1394,9 @@
|
||||
"ugyJnE": {
|
||||
"defaultMessage": "Sending notes and other stuff"
|
||||
},
|
||||
"un1nGw": {
|
||||
"defaultMessage": "{n} notes"
|
||||
},
|
||||
"usAvMr": {
|
||||
"defaultMessage": "Edit Profile"
|
||||
},
|
||||
|
@ -98,6 +98,7 @@
|
||||
"9wO4wJ": "Lightning Invoice",
|
||||
"ABAQyo": "Chats",
|
||||
"ADmfQT": "Parent",
|
||||
"AIgmDy": "Add up to 4 hashtags",
|
||||
"AN0Z7Q": "Muted Words",
|
||||
"ASRK0S": "This author has been muted",
|
||||
"Ai8VHU": "Unlimited note retention on Snort relay",
|
||||
@ -289,6 +290,7 @@
|
||||
"X7xU8J": "nsec, npub, nip-05, hex, mnemonic",
|
||||
"XECMfW": "Send usage metrics",
|
||||
"XICsE8": "File hosts",
|
||||
"XXm7jJ": "Trending Hashtags",
|
||||
"XgWvGA": "Reactions",
|
||||
"Xopqkl": "Your default zap amount is {number} sats, example values are calculated from this.",
|
||||
"XrSk2j": "Redeem",
|
||||
@ -326,7 +328,9 @@
|
||||
"d+6YsV": "Lists to mute:",
|
||||
"d6CyG5": "History",
|
||||
"d7d0/x": "LN Address",
|
||||
"d8gpCh": "Try to use less than 5 hashtags to stay on topic 🙏",
|
||||
"dOQCL8": "Display name",
|
||||
"ddd3JX": "Popular Hashtags",
|
||||
"deEeEI": "Register",
|
||||
"dmsiLv": "A default Zap Pool split of {n} has been configured for {site} developers, you can disable it at any time in {link}",
|
||||
"e61Jf3": "Coming soon",
|
||||
@ -455,6 +459,7 @@
|
||||
"uSV4Ti": "Reposts need to be manually confirmed",
|
||||
"uc0din": "Send sats splits to",
|
||||
"ugyJnE": "Sending notes and other stuff",
|
||||
"un1nGw": "{n} notes",
|
||||
"usAvMr": "Edit Profile",
|
||||
"v8lolG": "Start chat",
|
||||
"vB3oQ/": "Must be a contact list or pubkey list",
|
||||
|
Loading…
Reference in New Issue
Block a user