109 lines
3.3 KiB
TypeScript
109 lines
3.3 KiB
TypeScript
import { FolderPicker } from "./components/FolderPicker";
|
|
import { listen } from "@tauri-apps/api/event";
|
|
import { createEffect, createSignal } from "solid-js";
|
|
import { Search } from "@kobalte/core/search";
|
|
import { IconSearch, IconRefresh } from "@tabler/icons-solidjs";
|
|
|
|
type Emoji = {
|
|
emoji: string;
|
|
name: string;
|
|
};
|
|
|
|
function App() {
|
|
const [latestImage, setLatestImage] = createSignal<string | null>(null);
|
|
const [options, setOptions] = createSignal<Emoji[]>([]);
|
|
const [emoji, setEmoji] = createSignal<Emoji | null>(null);
|
|
|
|
const emojiData: Emoji[] = [
|
|
{ emoji: "😀", name: "Grinning Face" },
|
|
{ emoji: "😃", name: "Grinning Face with Big Eyes" },
|
|
{ emoji: "😄", name: "Grinning Face with Smiling Eyes" },
|
|
{ emoji: "😁", name: "Beaming Face with Smiling Eyes" },
|
|
{ emoji: "😆", name: "Grinning Squinting Face" },
|
|
];
|
|
|
|
const queryEmojiData = (query: string) => {
|
|
return emojiData.filter((emoji) =>
|
|
emoji.name.toLowerCase().includes(query.toLowerCase())
|
|
);
|
|
};
|
|
|
|
createEffect(() => {
|
|
// Listen for PNG processing events
|
|
const unlisten = listen("png-processed", (event) => {
|
|
console.log("Received processed PNG");
|
|
const base64Data = event.payload as string;
|
|
setLatestImage(`data:image/png;base64,${base64Data}`);
|
|
});
|
|
|
|
return () => {
|
|
unlisten.then((fn) => fn()); // Cleanup listener
|
|
};
|
|
});
|
|
|
|
return (
|
|
<main class="container pt-8">
|
|
<h1>hello???</h1>
|
|
<FolderPicker />
|
|
|
|
{latestImage() && (
|
|
<div class="mt-4">
|
|
<h3>Latest Processed Image:</h3>
|
|
<img
|
|
src={latestImage() || undefined}
|
|
alt="Latest processed"
|
|
class="max-w-md"
|
|
/>
|
|
</div>
|
|
)}
|
|
|
|
<Search
|
|
triggerMode="focus"
|
|
options={options()}
|
|
onInputChange={(query) => setOptions(queryEmojiData(query))}
|
|
onChange={(result) => setEmoji(result)}
|
|
optionValue="name"
|
|
optionLabel="name"
|
|
placeholder="Search an emoji…"
|
|
itemComponent={(props) => (
|
|
<Search.Item item={props.item} class="search__item">
|
|
<Search.ItemLabel>{props.item.rawValue.emoji}</Search.ItemLabel>
|
|
</Search.Item>
|
|
)}
|
|
>
|
|
<Search.Control class="search__control" aria-label="Emoji">
|
|
<Search.Indicator
|
|
class="search__indicator"
|
|
loadingComponent={
|
|
<Search.Icon class="load__icon">
|
|
<IconRefresh class="spin__icon" />
|
|
</Search.Icon>
|
|
}
|
|
>
|
|
<Search.Icon class="search__icon">
|
|
<IconSearch class="center__icon" />
|
|
</Search.Icon>
|
|
</Search.Indicator>
|
|
<Search.Input class="search__input" />
|
|
</Search.Control>
|
|
<Search.Portal>
|
|
<Search.Content
|
|
class="search__content"
|
|
onCloseAutoFocus={(e) => e.preventDefault()}
|
|
>
|
|
<Search.Listbox class="search__listbox" />
|
|
<Search.NoResult class="search__no_result">
|
|
😬 No emoji found
|
|
</Search.NoResult>
|
|
</Search.Content>
|
|
</Search.Portal>
|
|
</Search>
|
|
<div class="result__content">
|
|
Emoji selected: {emoji()?.emoji} {emoji()?.name}
|
|
</div>
|
|
</main>
|
|
);
|
|
}
|
|
|
|
export default App;
|