diff --git a/README.md b/README.md index 27138922..e24bd361 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ Snort supports the following NIP's: - [x] NIP-26: Delegated Event Signing (Display delegated signings only) - [x] NIP-27: Text note references (Parsing only) - [ ] NIP-28: Public Chat +- [x] NIP-30: Custom Emoji - [x] NIP-36: Sensitive Content - [ ] NIP-40: Expiration Timestamp - [x] NIP-42: Authentication of clients to relays diff --git a/packages/app/src/Element/Text.css b/packages/app/src/Element/Text.css index 46c37e7f..3ede68b3 100644 --- a/packages/app/src/Element/Text.css +++ b/packages/app/src/Element/Text.css @@ -61,7 +61,7 @@ margin: 20px; } -.text img, +.text img:not(.custom-emoji), .text video, .text iframe, .text audio { diff --git a/packages/app/src/Element/Text.tsx b/packages/app/src/Element/Text.tsx index 36c57b61..68017aad 100644 --- a/packages/app/src/Element/Text.tsx +++ b/packages/app/src/Element/Text.tsx @@ -10,6 +10,7 @@ import Hashtag from "Element/Hashtag"; import Mention from "Element/Mention"; import HyperText from "Element/HyperText"; import CashuNuts from "Element/CashuNuts"; +import { ProxyImg } from "Element/ProxyImg"; export type Fragment = string | React.ReactNode; @@ -156,12 +157,31 @@ export default function Text({ content, tags, creator, disableMedia, depth }: Te .flat(); } + function extractCustomEmoji(fragments: Fragment[]) { + return fragments + .map(f => { + if (typeof f === "string") { + return f.split(/:(\w+):/g).map(i => { + const t = tags.find(a => a[0] === "emoji" && a[1] === i); + if (t) { + return ; + } else { + return i; + } + }); + } + return f; + }) + .flat(); + } + function transformText(frag: TextFragment) { let fragments = extractMentions(frag); fragments = extractLinks(fragments); fragments = extractInvoices(fragments); fragments = extractHashtags(fragments); fragments = extractCashuTokens(fragments); + fragments = extractCustomEmoji(fragments); return fragments; }