blowater/UI/search.tsx
2023-06-30 14:05:57 +00:00

86 lines
3.6 KiB
TypeScript

/** @jsx h */
import { h } from "https://esm.sh/preact@10.11.3";
import { tw } from "https://esm.sh/twind@0.16.16";
import { EventEmitter } from "../event-bus.ts";
import { sleep } from "https://raw.githubusercontent.com/BlowaterNostr/csp/master/csp.ts";
import { SearchModel, SearchUpdate } from "./search_model.ts";
import { PublicKey } from "https://raw.githubusercontent.com/BlowaterNostr/nostr.ts/main/key.ts";
import { Avatar } from "./components/avatar.tsx";
export function Search(props: {
deps: {
eventEmitter: EventEmitter<SearchUpdate>;
};
model: SearchModel;
}) {
return (
<div
onKeyDown={(e) => {
if (e.code === "Escape") {
props.deps.eventEmitter.emit({ type: "CancelSearch" });
}
}}
class={tw`fixed inset-0 bg-[#000000C0] items-center justify-center flex z-20`}
>
<div
class={tw`fixed inset-0 z-[-1]`}
onClick={() => {
props.deps.eventEmitter.emit({ type: "CancelSearch" });
}}
>
</div>
<div
class={tw`absolute max-w-[40rem] w-3/5 max-h-[24.72rem] bg-[#2B2D31] rounded-2xl px-4 py-3 flex flex-col z-10`}
>
<input
ref={async (e) => {
await sleep(0); // wait util element mounted
e?.focus();
}}
onInput={(e) => {
props.deps.eventEmitter.emit({
type: "Search",
text: e.currentTarget.value,
});
}}
type="text"
class={tw`p-2 rounded focus-visible:outline-none bg-[#1E1F22] text-[#DADBDF] placeholder-[#86888B]`}
placeholder="Search a user's public key"
/>
{props.model.searchResults.length > 0
? (
<ul
class={tw`flex-1 list-none mt-4 p-1 overflow-y-auto`}
>
{props.model.searchResults.map((result) => {
return (
<li
onClick={() => {
props.deps.eventEmitter.emit({
type: "SelectProfile",
pubkey: result.pubkey,
});
}}
class={tw`w-full flex items-center px-4 py-2 text-[#B8B9BF] hover:bg-[#404249] rounded cursor-pointer`}
>
<Avatar
class={tw`w-8 h-8 mr-2`}
picture={result.profile?.picture}
/>
<p class={tw`truncate`}>
{result.profile?.name
? result.profile.name
: result.pubkey.bech32()}
</p>
</li>
);
})}
</ul>
)
: undefined}
</div>
</div>
);
}