@ -1,4 +1,5 @@
|
||||
import { HexKey, TaggedRawEvent, UserMetadata } from "../nostr";
|
||||
import { hexToBech32 } from "../Util";
|
||||
|
||||
export interface MetadataCache extends UserMetadata {
|
||||
/**
|
||||
@ -22,6 +23,7 @@ export function mapEventToProfile(ev: TaggedRawEvent) {
|
||||
let data: UserMetadata = JSON.parse(ev.content);
|
||||
return {
|
||||
pubkey: ev.pubkey,
|
||||
npub: hexToBech32("npub", ev.pubkey),
|
||||
created: ev.created_at,
|
||||
loaded: new Date().getTime(),
|
||||
...data
|
||||
|
@ -1,5 +1,6 @@
|
||||
import Dexie, { Table } from 'dexie';
|
||||
import { MetadataCache } from './User';
|
||||
import Dexie, { Table } from "dexie";
|
||||
import { MetadataCache } from "./User";
|
||||
import { hexToBech32 } from "../Util";
|
||||
|
||||
|
||||
export class SnortDB extends Dexie {
|
||||
@ -7,8 +8,12 @@ export class SnortDB extends Dexie {
|
||||
|
||||
constructor() {
|
||||
super('snortDB');
|
||||
this.version(1).stores({
|
||||
users: '++pubkey, name, display_name, picture, nip05' // Primary key and indexed props
|
||||
this.version(2).stores({
|
||||
users: '++pubkey, name, display_name, picture, nip05, npub'
|
||||
}).upgrade(tx => {
|
||||
return tx.table("users").toCollection().modify(user => {
|
||||
user.npub = hexToBech32("npub", user.pubkey)
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
.user-item {
|
||||
.user-item, .emoji-item {
|
||||
background: var(--gray);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@ -7,7 +7,7 @@
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.user-item:hover {
|
||||
.user-item:hover, .emoji-item:hover {
|
||||
background: var(--gray-tertiary);
|
||||
}
|
||||
|
||||
@ -39,3 +39,16 @@
|
||||
.nip05 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.emoji-item {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.emoji-item .emoji {
|
||||
margin-right: .2em;
|
||||
min-width: 20px;
|
||||
}
|
||||
|
||||
.emoji-item .emoji-name {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import "./Textarea.css";
|
||||
import { useState } from "react";
|
||||
import { useLiveQuery } from "dexie-react-hooks";
|
||||
import ReactTextareaAutocomplete from "@webscopeio/react-textarea-autocomplete";
|
||||
import emoji from "@jukben/emoji-search";
|
||||
import TextareaAutosize from "react-textarea-autosize";
|
||||
|
||||
import Avatar from "./Avatar";
|
||||
@ -12,6 +13,20 @@ import { hexToBech32 } from "../Util";
|
||||
import { db } from "../db";
|
||||
import { MetadataCache } from "../db/User";
|
||||
|
||||
interface EmojiItemProps {
|
||||
name: string
|
||||
char: string
|
||||
}
|
||||
|
||||
const EmojiItem = ({ entity: { name, char } }: { entity: EmojiItemProps }) => {
|
||||
return (
|
||||
<div className="emoji-item">
|
||||
<div className="emoji">{char}</div>
|
||||
<div className="emoji-name">{name}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const UserItem = (metadata: MetadataCache) => {
|
||||
const { pubkey, display_name, picture, nip05, ...rest } = metadata
|
||||
return (
|
||||
@ -32,7 +47,8 @@ const Textarea = ({ users, onChange, ...rest }: any) => {
|
||||
|
||||
const allUsers = useLiveQuery(
|
||||
() => db.users
|
||||
.where("name").startsWithIgnoreCase(query)
|
||||
.where("npub").startsWithIgnoreCase(query)
|
||||
.or("name").startsWithIgnoreCase(query)
|
||||
.or("display_name").startsWithIgnoreCase(query)
|
||||
.or("nip05").startsWithIgnoreCase(query)
|
||||
.limit(5)
|
||||
@ -45,6 +61,12 @@ const Textarea = ({ users, onChange, ...rest }: any) => {
|
||||
return allUsers
|
||||
}
|
||||
|
||||
const emojiDataProvider = (token: string) => {
|
||||
return emoji(token)
|
||||
.slice(0, 10)
|
||||
.map(({ name, char }) => ({ name, char }));
|
||||
}
|
||||
|
||||
return (
|
||||
<ReactTextareaAutocomplete
|
||||
{...rest}
|
||||
@ -53,6 +75,11 @@ const Textarea = ({ users, onChange, ...rest }: any) => {
|
||||
onChange={onChange}
|
||||
textAreaComponent={TextareaAutosize}
|
||||
trigger={{
|
||||
":": {
|
||||
dataProvider: emojiDataProvider,
|
||||
component: EmojiItem,
|
||||
output: (item: EmojiItemProps, trigger) => item.char
|
||||
},
|
||||
"@": {
|
||||
afterWhitespace: true,
|
||||
dataProvider: userDataProvider,
|
||||
|
Reference in New Issue
Block a user