feat: remove typesense
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
import { Signal, useSignal } from "@preact/signals";
|
||||
import { useEffect, useRef } from "preact/hooks";
|
||||
import { useRef } from "preact/hooks";
|
||||
import { useEventListener } from "@lib/hooks/useEventListener.ts";
|
||||
import { menus } from "@islands/KMenu/commands.ts";
|
||||
import { MenuEntry } from "@islands/KMenu/types.ts";
|
||||
|
@ -31,13 +31,13 @@ export const menus: Record<string, Menu> = {
|
||||
title: "Login",
|
||||
icon: "IconLogin",
|
||||
cb: () => {
|
||||
const url = new URL(window.location.href);
|
||||
const url = new URL(globalThis.location.href);
|
||||
url.pathname = "/api/auth/login";
|
||||
url.searchParams.set(
|
||||
"redirect",
|
||||
encodeURIComponent(window.location.pathname),
|
||||
encodeURIComponent(globalThis.location.pathname),
|
||||
);
|
||||
window.location.href = url.href;
|
||||
globalThis.location.href = url.href;
|
||||
},
|
||||
visible: () => {
|
||||
return !getCookie("session_cookie");
|
||||
@ -47,35 +47,24 @@ export const menus: Record<string, Menu> = {
|
||||
title: "Search",
|
||||
icon: "IconSearch",
|
||||
cb: () => {
|
||||
window.location.href += "?q=";
|
||||
globalThis.location.href += "?q=";
|
||||
},
|
||||
visible: () => {
|
||||
return !!getCookie("session_cookie") && window.location.search === "";
|
||||
return !!getCookie("session_cookie") &&
|
||||
globalThis.location.search === "";
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Logout",
|
||||
icon: "IconLogout",
|
||||
cb: () => {
|
||||
const url = new URL(window.location.href);
|
||||
const url = new URL(globalThis.location.href);
|
||||
url.pathname = "/api/auth/logout";
|
||||
url.searchParams.set(
|
||||
"redirect",
|
||||
encodeURIComponent(window.location.pathname),
|
||||
encodeURIComponent(globalThis.location.pathname),
|
||||
);
|
||||
window.location.href = url.href;
|
||||
},
|
||||
visible: () => {
|
||||
return !!getCookie("session_cookie");
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Sync Typesense",
|
||||
icon: "IconStarFilled",
|
||||
cb: () => {
|
||||
fetch("/api/query/sync", {
|
||||
method: "POST",
|
||||
});
|
||||
globalThis.location.href = url.href;
|
||||
},
|
||||
visible: () => {
|
||||
return !!getCookie("session_cookie");
|
||||
|
@ -2,7 +2,7 @@ import { useEffect, useRef } from "preact/hooks";
|
||||
import useDebouncedCallback from "@lib/hooks/useDebouncedCallback.ts";
|
||||
import { IconLoader2, IconSearch } from "@components/icons.tsx";
|
||||
import { useEventListener } from "@lib/hooks/useEventListener.ts";
|
||||
import { SearchResult } from "@lib/types.ts";
|
||||
import { GenericResource } from "@lib/types.ts";
|
||||
import { resources } from "@lib/resources.ts";
|
||||
import { getCookie } from "@lib/string.ts";
|
||||
import { IS_BROWSER } from "$fresh/runtime.ts";
|
||||
@ -17,13 +17,13 @@ export async function fetchQueryResource(url: URL, type = "") {
|
||||
const status = url.searchParams.get("status");
|
||||
|
||||
try {
|
||||
url.pathname = "/api/resources";
|
||||
url.searchParams.set("q", encodeURIComponent(query || "*"));
|
||||
url.pathname = "/api/query";
|
||||
url.searchParams.set("q", encodeURIComponent(query || ""));
|
||||
if (status) {
|
||||
url.searchParams.set("status", "not-seen");
|
||||
}
|
||||
if (type) {
|
||||
url.searchParams.set("type", type);
|
||||
url.searchParams.set("types", type);
|
||||
}
|
||||
const response = await fetch(url);
|
||||
const jsonData = await response.json();
|
||||
@ -39,9 +39,9 @@ export const RedirectSearchHandler = () => {
|
||||
if (e?.target?.nodeName == "INPUT") return;
|
||||
if (
|
||||
e.key === "?" &&
|
||||
window.location.search === ""
|
||||
globalThis.location.search === ""
|
||||
) {
|
||||
window.location.href += "?q=*";
|
||||
globalThis.location.href += "?q=";
|
||||
}
|
||||
}, IS_BROWSER ? document?.body : undefined);
|
||||
}
|
||||
@ -50,12 +50,12 @@ export const RedirectSearchHandler = () => {
|
||||
};
|
||||
|
||||
const SearchResultImage = ({ src }: { src: string }) => {
|
||||
const imageSrc = `/api/images?image=${src}&width=50&height=50`;
|
||||
|
||||
return (
|
||||
<Image
|
||||
class="object-cover w-12 h-12 rounded-full"
|
||||
src={imageSrc}
|
||||
width="50"
|
||||
height="50"
|
||||
src={src}
|
||||
alt="preview image"
|
||||
/>
|
||||
);
|
||||
@ -63,13 +63,12 @@ const SearchResultImage = ({ src }: { src: string }) => {
|
||||
|
||||
export const SearchResultItem = (
|
||||
{ item, showEmoji = false }: {
|
||||
item: NonNullable<SearchResult["hits"]>[number];
|
||||
item: GenericResource;
|
||||
showEmoji?: boolean;
|
||||
},
|
||||
) => {
|
||||
const doc = item.document;
|
||||
const resourceType = resources[doc.type];
|
||||
const href = resourceType ? `${resourceType.link}/${doc.id}` : "";
|
||||
const resourceType = resources[item.type];
|
||||
const href = resourceType ? `${resourceType.link}/${item.id}` : "";
|
||||
return (
|
||||
<a
|
||||
href={href}
|
||||
@ -78,21 +77,21 @@ export const SearchResultItem = (
|
||||
{showEmoji && resourceType
|
||||
? <Emoji class="w-7 h-7" name={resourceType.emoji} />
|
||||
: ""}
|
||||
{doc?.image && <SearchResultImage src={doc.image} />}
|
||||
{doc?.name}
|
||||
{item.meta?.image && <SearchResultImage src={item.meta?.image} />}
|
||||
{item?.name}
|
||||
</a>
|
||||
);
|
||||
};
|
||||
|
||||
export const SearchResultList = (
|
||||
{ result, showEmoji }: { result: SearchResult; showEmoji?: boolean },
|
||||
{ result, showEmoji }: { result: GenericResource[]; showEmoji?: boolean },
|
||||
) => {
|
||||
return (
|
||||
<div class="mt-4">
|
||||
{result?.hits
|
||||
{result?.length
|
||||
? (
|
||||
<div class="flex flex-col gap-4">
|
||||
{result.hits.map((hit) => (
|
||||
{result.map((hit) => (
|
||||
<SearchResultItem item={hit} showEmoji={showEmoji} />
|
||||
))}
|
||||
</div>
|
||||
@ -106,17 +105,17 @@ const Search = (
|
||||
{ q = "*", type, results }: {
|
||||
q: string;
|
||||
type?: string;
|
||||
results?: SearchResult;
|
||||
results?: GenericResource[];
|
||||
},
|
||||
) => {
|
||||
const searchQuery = useSignal(q);
|
||||
const data = useSignal<SearchResult | undefined>(results);
|
||||
const data = useSignal<GenericResource[] | undefined>(results);
|
||||
const isLoading = useSignal(false);
|
||||
const showSeenStatus = useSignal(false);
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
if ("history" in globalThis) {
|
||||
const u = new URL(window.location.href);
|
||||
const u = new URL(globalThis.location.href);
|
||||
if (u.searchParams.get("q") !== searchQuery.value) {
|
||||
u.searchParams.set("q", searchQuery.value);
|
||||
}
|
||||
@ -126,14 +125,14 @@ const Search = (
|
||||
u.searchParams.delete("rating");
|
||||
}
|
||||
|
||||
window.history.replaceState({}, "", u);
|
||||
globalThis.history.replaceState({}, "", u);
|
||||
}
|
||||
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
isLoading.value = true;
|
||||
const jsonData = await fetchQueryResource(
|
||||
new URL(window?.location.href),
|
||||
new URL(globalThis?.location.href),
|
||||
type,
|
||||
);
|
||||
data.value = jsonData;
|
||||
@ -188,7 +187,7 @@ const Search = (
|
||||
<Checkbox label="seen" checked={showSeenStatus} />
|
||||
<Rating rating={4} />
|
||||
</header>
|
||||
{data?.value?.hits?.length && !isLoading.value
|
||||
{data.value?.length && !isLoading.value
|
||||
? <SearchResultList showEmoji={!type} result={data.value} />
|
||||
: isLoading.value
|
||||
? <div />
|
||||
|
Reference in New Issue
Block a user