feat: query for autocompletion using local db

This commit is contained in:
Alejandro Gomez
2023-01-17 00:19:50 +01:00
parent e304d4cbac
commit 432165d7af
2 changed files with 26 additions and 15 deletions

View File

@ -24,6 +24,12 @@
margin-right: 8px; margin-right: 8px;
} }
.user-picture .avatar {
border-width: 1px;
width: 40px;
height: 40px;
}
.user-details { .user-details {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@ -1,31 +1,23 @@
import "@webscopeio/react-textarea-autocomplete/style.css"; import "@webscopeio/react-textarea-autocomplete/style.css";
import "./Textarea.css"; import "./Textarea.css";
import Nostrich from "../nostrich.jpg";
import { useState } from "react";
import { useLiveQuery } from "dexie-react-hooks"; import { useLiveQuery } from "dexie-react-hooks";
import ReactTextareaAutocomplete from "@webscopeio/react-textarea-autocomplete"; import ReactTextareaAutocomplete from "@webscopeio/react-textarea-autocomplete";
import TextareaAutosize from "react-textarea-autosize"; import TextareaAutosize from "react-textarea-autosize";
import Avatar from "./Avatar";
import Nip05 from "./Nip05"; import Nip05 from "./Nip05";
import { hexToBech32 } from "../Util"; import { hexToBech32 } from "../Util";
import { db } from "../db"; import { db } from "../db";
import { MetadataCache } from "../db/User"; import { MetadataCache } from "../db/User";
function searchUsers(query: string, users: MetadataCache[]) { const UserItem = (metadata: MetadataCache) => {
const q = query.toLowerCase() const { pubkey, display_name, picture, nip05, ...rest } = metadata
return users.filter(({ name, display_name, about, nip05 }: MetadataCache) => {
return name?.toLowerCase().includes(q)
|| display_name?.toLowerCase().includes(q)
|| about?.toLowerCase().includes(q)
|| nip05?.toLowerCase().includes(q)
}).slice(0, 3)
}
const UserItem = ({ pubkey, display_name, picture, nip05, ...rest }: MetadataCache) => {
return ( return (
<div key={pubkey} className="user-item"> <div key={pubkey} className="user-item">
<div className="user-picture"> <div className="user-picture">
{picture && <img src={picture ? picture : Nostrich} className="picture" />} <Avatar user={metadata} />
</div> </div>
<div className="user-details"> <div className="user-details">
<strong>{display_name || rest.name}</strong> <strong>{display_name || rest.name}</strong>
@ -36,10 +28,23 @@ const UserItem = ({ pubkey, display_name, picture, nip05, ...rest }: MetadataCac
} }
const Textarea = ({ users, onChange, ...rest }: any) => { const Textarea = ({ users, onChange, ...rest }: any) => {
const [query, setQuery] = useState('')
const allUsers = useLiveQuery( const allUsers = useLiveQuery(
() => db.users.toArray() () => db.users
.where("name").startsWithIgnoreCase(query)
.or("display_name").startsWithIgnoreCase(query)
.or("nip05").startsWithIgnoreCase(query)
.limit(5)
.toArray(),
[query],
); );
const userDataProvider = (token: string) => {
setQuery(token)
return allUsers
}
return ( return (
<ReactTextareaAutocomplete <ReactTextareaAutocomplete
{...rest} {...rest}
@ -50,7 +55,7 @@ const Textarea = ({ users, onChange, ...rest }: any) => {
trigger={{ trigger={{
"@": { "@": {
afterWhitespace: true, afterWhitespace: true,
dataProvider: token => allUsers ? searchUsers(token, allUsers) : [], dataProvider: userDataProvider,
component: (props: any) => <UserItem {...props.entity} />, component: (props: any) => <UserItem {...props.entity} />,
output: (item: any) => `@${hexToBech32("npub", item.pubkey)}` output: (item: any) => `@${hexToBech32("npub", item.pubkey)}`
} }