old-twitter-image-search/src/GrapeSearch.tsx

135 lines
4.0 KiB
TypeScript

import { Component, createSignal, For, Show } from "solid-js";
import { DANBOORU_API, booru_post, iqdb_search, saucenao_search, tweet_search } from "./api";
import { DanboIcon, IqdbIcon, SauceIcon, GrapeCatIcon } from './Icons';
import { click_out_directive } from "./helper";
type GrapeSearchParams = {
media_url:string[],
id:string,
username: string
}
// Typescript strips this directive if we don't
// force call it in this module
const clickOutside = click_out_directive
export function GrapeSearch({media_url,id, username}:GrapeSearchParams) {
const [showTooltip, setShowTooltip] = createSignal(false);
const [ShowDanboResult, setShowDanboResult] = createSignal(false);
const [danboPostID, setPostID ] = createSignal(0);
const [posts, setPosts] = createSignal<Array<booru_post>>([])
const booru_check = async (e:MouseEvent) => {
//console.debug({id,username})
//console.debug({event:e});
const ico = e.target as HTMLImageElement;
ico.classList.add('otis-icon-loading');
ico.classList.remove('otis-icon-noresult');
const res = await tweet_search(id,username)
ico.classList.remove('otis-icon-loading');
if ( res.length == 0 ) {
ico.classList.add('otis-icon-noresult');
ico.title = "Can't find any post based on Tweet ID."
return console.debug("grape: none")
}
setPosts(res)
if ( res.length === 1 ) setShowDanboResult(true)
else setShowTooltip(true)
}
const iqdb_check = async (e:MouseEvent) => {
const ico = e.target as HTMLImageElement;
ico.classList.add('otis-icon-loading');
ico.classList.remove('otis-icon-noresult');
// TODO: handle which image to check
const res = await iqdb_search(media_url[0])
ico.classList.remove('otis-icon-loading');
if ( res.length == 0 ) {
ico.classList.add('otis-icon-noresult');
ico.title = "No relevant image search results from IQDB"
return console.debug("iqdb: none");
}
setPosts(res)
if ( res.length === 1 ) setShowDanboResult(true)
else setShowTooltip(true)
}
const sauce_check = async (e:MouseEvent) => {
const ico = e.target as HTMLImageElement;
ico.classList.add('otis-icon-loading');
ico.classList.remove('otis-icon-noresult');
// TODO: handle which image to check
const res = await saucenao_search(media_url[0]);
ico.classList.remove('otis-icon-loading');
if ( res.length == 0 ) {
ico.classList.add('otis-icon-noresult');
ico.title = "No relevant image search results from IQDB"
return console.debug("sauce: none");
}
setPosts(res)
if ( res.length === 1 ) setShowDanboResult(true)
else setShowTooltip(true)
}
const DanboPostsResult = () => (
<>
<DanboIcon />
<a
rel="noopener"
target="_blank"
class={"danbo-text-link"}
href={`${DANBOORU_API}/posts/${posts()[0]?.id}`}
onmouseover={() => setShowTooltip(true)}>
{`#${posts()[0]?.id}`}
</a>
</>
)
return ( <>
<span>
<Show
when={!ShowDanboResult()}
fallback={<DanboPostsResult /> }>
<GrapeCatIcon onClick={booru_check} />
<IqdbIcon onClick={iqdb_check} />
<SauceIcon onClick={sauce_check} />
</Show>
</span>
<div class={"dropdown-menu danbo-more-results"} use:clickOutside={() => setShowTooltip(false)} hidden={!showTooltip()}>
<For each={posts()}>
{ (post) =>
<span
class={"danbo-item"}
onClick={() => window.open(`${DANBOORU_API}/posts/${post.id}`,'_blank')}>
<img src={post.thumbnail} width="80px"/>
<div>
<div> #{post.id} </div>
<div> {post.source_domain} </div>
<div> { post.img_width >= 0 ? `${post.img_width} x ${post.img_height}` : ""} </div>
</div>
</span>
}
</For>
</div>
</>
)
}