address review comments
This commit is contained in:
parent
666ab8ebdb
commit
c1877b35ad
@ -13,6 +13,7 @@
|
|||||||
"@types/node": "^18.11.18",
|
"@types/node": "^18.11.18",
|
||||||
"@types/react": "^18.0.26",
|
"@types/react": "^18.0.26",
|
||||||
"@types/react-dom": "^18.0.10",
|
"@types/react-dom": "^18.0.10",
|
||||||
|
"@types/webscopeio__react-textarea-autocomplete": "^4.7.2",
|
||||||
"@webscopeio/react-textarea-autocomplete": "^4.9.2",
|
"@webscopeio/react-textarea-autocomplete": "^4.9.2",
|
||||||
"bech32": "^2.0.0",
|
"bech32": "^2.0.0",
|
||||||
"light-bolt11-decoder": "^2.1.0",
|
"light-bolt11-decoder": "^2.1.0",
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
background-color: var(--gray);
|
background-color: var(--gray);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
overflow: hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.note-creator textarea {
|
.note-creator textarea {
|
||||||
@ -20,7 +19,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.note-creator .textarea--focused {
|
.note-creator .textarea--focused {
|
||||||
min-height: 150px;
|
min-height: 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.note-creator .actions {
|
.note-creator .actions {
|
||||||
|
@ -2,19 +2,27 @@ import { Component } from "react";
|
|||||||
|
|
||||||
import ReactTextareaAutocomplete from "@webscopeio/react-textarea-autocomplete";
|
import ReactTextareaAutocomplete from "@webscopeio/react-textarea-autocomplete";
|
||||||
|
|
||||||
|
// @ts-expect-error
|
||||||
import Nip05, { useIsVerified } from "./Nip05";
|
import Nip05, { useIsVerified } from "./Nip05";
|
||||||
import "@webscopeio/react-textarea-autocomplete/style.css";
|
import "@webscopeio/react-textarea-autocomplete/style.css";
|
||||||
import "./Textarea.css";
|
import "./Textarea.css";
|
||||||
|
// @ts-expect-error
|
||||||
import Nostrich from "../nostrich.jpg";
|
import Nostrich from "../nostrich.jpg";
|
||||||
|
// @ts-expect-error
|
||||||
|
import { hexToBech32 } from "../Util";
|
||||||
|
import type { User } from "../nostr/types";
|
||||||
|
|
||||||
function searchUsers(query, users) {
|
function searchUsers(query: string, users: Record<string, User>) {
|
||||||
const q = query.toLowerCase()
|
const q = query.toLowerCase()
|
||||||
return Object.values(users).filter(({ name, display_name, about }) => {
|
return Object.values(users).filter(({ name, display_name, about, nip05 }) => {
|
||||||
return name.toLowerCase().includes(q) || display_name?.includes(q) || about?.includes(q)
|
return name?.toLowerCase().includes(q)
|
||||||
|
|| display_name?.toLowerCase().includes(q)
|
||||||
|
|| about?.toLowerCase().includes(q)
|
||||||
|
|| nip05?.toLowerCase().includes(q)
|
||||||
}).slice(0, 3)
|
}).slice(0, 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
const UserItem = ({ pubkey, display_name, picture, nip05, ...rest }) => {
|
const UserItem = ({ pubkey, display_name, picture, nip05, ...rest }: User) => {
|
||||||
const { isVerified, couldNotVerify, name, domain } = useIsVerified(nip05, pubkey)
|
const { isVerified, couldNotVerify, name, domain } = useIsVerified(nip05, pubkey)
|
||||||
return (
|
return (
|
||||||
<div key={pubkey} className="user-item">
|
<div key={pubkey} className="user-item">
|
||||||
@ -31,6 +39,7 @@ const UserItem = ({ pubkey, display_name, picture, nip05, ...rest }) => {
|
|||||||
|
|
||||||
export default class Textarea extends Component {
|
export default class Textarea extends Component {
|
||||||
render() {
|
render() {
|
||||||
|
// @ts-expect-error
|
||||||
const { users, onChange, ...rest } = this.props
|
const { users, onChange, ...rest } = this.props
|
||||||
return (
|
return (
|
||||||
<ReactTextareaAutocomplete
|
<ReactTextareaAutocomplete
|
||||||
@ -38,6 +47,7 @@ export default class Textarea extends Component {
|
|||||||
loadingComponent={() => <span>Loading....</span>}
|
loadingComponent={() => <span>Loading....</span>}
|
||||||
placeholder="Say something!"
|
placeholder="Say something!"
|
||||||
ref={rta => {
|
ref={rta => {
|
||||||
|
// @ts-expect-error
|
||||||
this.rta = rta;
|
this.rta = rta;
|
||||||
}}
|
}}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
@ -45,8 +55,8 @@ export default class Textarea extends Component {
|
|||||||
"@": {
|
"@": {
|
||||||
afterWhitespace: true,
|
afterWhitespace: true,
|
||||||
dataProvider: token => searchUsers(token, users),
|
dataProvider: token => searchUsers(token, users),
|
||||||
component: ({ entity }) => <UserItem {...entity} />,
|
component: (props: any) => <UserItem {...props.entity} />,
|
||||||
output: (item, trigger) => `@${item.pubkey}`
|
output: (item: any) => `@${hexToBech32("npub", item.pubkey)}`
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
@ -32,20 +32,18 @@ export default function useEventPublisher() {
|
|||||||
|
|
||||||
|
|
||||||
function processMentions(ev, msg) {
|
function processMentions(ev, msg) {
|
||||||
const replaceHexKey = (match) => {
|
|
||||||
const idx = ev.Tags.length;
|
|
||||||
ev.Tags.push(new Tag(["p", match.slice(1)], idx));
|
|
||||||
return `#[${idx}]`
|
|
||||||
}
|
|
||||||
const replaceNpub = (match) => {
|
const replaceNpub = (match) => {
|
||||||
const npub = match.slice(1);
|
const npub = match.slice(1);
|
||||||
const hex = bech32ToHex(npub);
|
try {
|
||||||
const idx = ev.Tags.length;
|
const hex = bech32ToHex(npub);
|
||||||
ev.Tags.push(new Tag(["p", hex], idx));
|
const idx = ev.Tags.length;
|
||||||
return `#[${idx}]`
|
ev.Tags.push(new Tag(["p", hex], idx));
|
||||||
|
return `#[${idx}]`
|
||||||
|
} catch (error) {
|
||||||
|
return match
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let content = msg.replace(/@[0-9A-Fa-f]{64}/g, replaceHexKey)
|
let content = msg.replace(/@npub[a-z0-9]+/g, replaceNpub)
|
||||||
.replace(/@npub[a-z0-9]+/g, replaceNpub)
|
|
||||||
ev.Content = content;
|
ev.Content = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
9
src/nostr/types.tsx
Normal file
9
src/nostr/types.tsx
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
export type User = {
|
||||||
|
name?: string
|
||||||
|
about?: string
|
||||||
|
display_name?: string
|
||||||
|
nip05?: string
|
||||||
|
pubkey: string
|
||||||
|
picture?: string
|
||||||
|
}
|
||||||
|
|
@ -2121,6 +2121,13 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz#b6725d5f4af24ace33b36fafd295136e75509f43"
|
resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz#b6725d5f4af24ace33b36fafd295136e75509f43"
|
||||||
integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==
|
integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==
|
||||||
|
|
||||||
|
"@types/webscopeio__react-textarea-autocomplete@^4.7.2":
|
||||||
|
version "4.7.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/webscopeio__react-textarea-autocomplete/-/webscopeio__react-textarea-autocomplete-4.7.2.tgz#605e8a6b4194fb4b6e55df8a19bc8fcd56319cfa"
|
||||||
|
integrity sha512-e1DZGD+eH19BnllTWCGXAdrMa2kI53wEMuhn/d+wUmnu8//ZI6BiuK/EPdw07fI4+tlyo5qdPZdXdpkoXHJVOw==
|
||||||
|
dependencies:
|
||||||
|
"@types/react" "*"
|
||||||
|
|
||||||
"@types/ws@^8.5.1":
|
"@types/ws@^8.5.1":
|
||||||
version "8.5.4"
|
version "8.5.4"
|
||||||
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.4.tgz#bb10e36116d6e570dd943735f86c933c1587b8a5"
|
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.4.tgz#bb10e36116d6e570dd943735f86c933c1587b8a5"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user