135 lines
4.0 KiB
TypeScript
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>
|
|
</>
|
|
)
|
|
}
|