new post hashtags

This commit is contained in:
hzrd149 2023-07-11 07:56:51 -05:00
parent f16955f3dc
commit d46327ec29
6 changed files with 44 additions and 7 deletions

View File

@ -0,0 +1,5 @@
---
"nostrudel": minor
---
Support hashtags in new post modal

View File

@ -0,0 +1,5 @@
---
"nostrudel": patch
---
Fix bug with non-english hashtags not showing

View File

@ -6,7 +6,7 @@ import { UserLink } from "../user-link";
import { EventPointer, ProfilePointer } from "nostr-tools/lib/nip19";
import { Link } from "@chakra-ui/react";
import { Link as RouterLink } from "react-router-dom";
import { matchNostrLink } from "../../helpers/regexp";
import { matchHashtag, matchNostrLink } from "../../helpers/regexp";
// nostr:nevent1qqsthg2qlxp9l7egtwa92t8lusm7pjknmjwa75ctrrpcjyulr9754fqpz3mhxue69uhhyetvv9ujuerpd46hxtnfduq36amnwvaz7tmwdaehgu3dwp6kytnhv4kxcmmjv3jhytnwv46q2qg5q9
// nostr:nevent1qqsq3wc73lqxd70lg43m5rul57d4mhcanttjat56e30yx5zla48qzlspz9mhxue69uhkummnw3e82efwvdhk6qgdwaehxw309ahx7uewd3hkcq5hsum
@ -68,14 +68,21 @@ export function embedNostrHashtags(content: EmbedableContent, event: NostrEvent
return embedJSX(content, {
name: "nostr-hashtag",
regexp: /#(\w+)/i,
regexp: matchHashtag,
getLocation: (match) => {
if (match.index === undefined) throw new Error("match dose not have index");
const start = match.index + match[1].length;
const end = start + 1 + match[2].length;
return { start, end };
},
render: (match) => {
const hashtag = match[1].toLowerCase();
const hashtag = match[2].toLowerCase();
if (hashtags.includes(hashtag)) {
return (
<Link as={RouterLink} to={`/t/${hashtag}`} color="blue.500">
#{match[1]}
#{match[2]}
</Link>
);
}

View File

@ -18,7 +18,7 @@ import { useList } from "react-use";
import { nostrPostAction, PostResult } from "../../classes/nostr-post-action";
import { normalizeToHex } from "../../helpers/nip19";
import { getReferences } from "../../helpers/nostr-event";
import { mentionNpubOrNote } from "../../helpers/regexp";
import { matchHashtag, mentionNpubOrNote } from "../../helpers/regexp";
import { useWriteRelayUrls } from "../../hooks/use-client-relays";
import { useIsMobile } from "../../hooks/use-is-mobile";
import { useSigningContext } from "../../providers/signing-provider";
@ -60,6 +60,15 @@ function finalizeNote(draft: DraftNostrEvent) {
updatedDraft.content = c.slice(0, match.index) + `#[${index}]` + c.slice(match.index + match[0].length);
}
// replace all uses of #hashtag
const matches = updatedDraft.content.matchAll(new RegExp(matchHashtag, "gi"));
for (const [_, space, hashtag] of matches) {
const lower = hashtag.toLocaleLowerCase();
if (!updatedDraft.tags.find((t) => t[0] === "t" && t[1] === lower)) {
updatedDraft.tags.push(["t", lower]);
}
}
return updatedDraft;
}

View File

@ -5,8 +5,17 @@ export type EmbedType = {
regexp: RegExp;
render: (match: RegExpMatchArray) => JSX.Element | string | null;
name: string;
getLocation?: (match: RegExpMatchArray) => { start: number; end: number };
};
function defaultGetLocation(match: RegExpMatchArray) {
if (match.index === undefined) throw new Error("match dose not have index");
return {
start: match.index,
end: match.index + match[0].length,
};
}
export function embedJSX(content: EmbedableContent, embed: EmbedType): EmbedableContent {
return content
.map((subContent, i) => {
@ -14,8 +23,9 @@ export function embedJSX(content: EmbedableContent, embed: EmbedType): Embedable
const match = subContent.match(embed.regexp);
if (match && match.index !== undefined) {
const before = subContent.slice(0, match.index);
const after = subContent.slice(match.index + match[0].length, subContent.length);
const { start, end } = (embed.getLocation || defaultGetLocation)(match);
const before = subContent.slice(0, start);
const after = subContent.slice(end, subContent.length);
let embedRender = embed.render(match);
if (embedRender === null) return subContent;

View File

@ -3,3 +3,4 @@ export const matchImageUrls =
/https?:\/\/([\dA-z\.-]+\.[A-z\.]{2,12})((?:\/[\+~%\/\.\w\-_]*)?\.(?:svg|gif|png|jpg|jpeg|webp|avif))(\??(?:[\?#\-\+=&;%@\.\w_]*)#?(?:[\-\.\!\/\\\w]*))?/i;
export const matchNostrLink = /(nostr:|@)?((npub|note|nprofile|nevent)1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]{58,})/i;
export const matchHashtag = /(^|\s)#([^\s#]+)/i;