80 lines
2.0 KiB
Svelte
80 lines
2.0 KiB
Svelte
<script lang="ts" context="module">
|
|
export const load: Load = async ({ url, fetch }) => {
|
|
const yurikoEndpoint = 'https://search.blog.nanao.moe';
|
|
const apiEndpoint = '/api/article/search?';
|
|
const queryString = 'q=';
|
|
const pageString = '&page=';
|
|
|
|
const q = url.searchParams.get('q') ?? '';
|
|
const page = url.searchParams.get('page') ?? 1;
|
|
|
|
const search = await fetch(
|
|
`${yurikoEndpoint}${apiEndpoint}${queryString}${q}${pageString}${page}`
|
|
);
|
|
const result = await search.json();
|
|
|
|
return {
|
|
props: {
|
|
query: q,
|
|
posts: result.result
|
|
}
|
|
};
|
|
};
|
|
</script>
|
|
|
|
<script lang="ts">
|
|
import { browser } from '$app/env';
|
|
import dayjs from 'dayjs';
|
|
|
|
import Container from '@damillora/plachta/components/Container/Container.svelte';
|
|
import Hero from '@damillora/plachta/components/Hero/Hero.svelte';
|
|
import Index from '@damillora/plachta/components/PageTypes/Index.svelte';
|
|
import SearchCard from '@damillora/plachta/components/PostCard/SearchCard.svelte';
|
|
import { onMount } from 'svelte';
|
|
import { search } from '$lib/content/searchApi';
|
|
import type { Load } from '@sveltejs/kit';
|
|
export let query = '';
|
|
export let posts: any[] = [];
|
|
let newPosts: any[] = [];
|
|
let page = 1;
|
|
$: posts = [...posts, ...newPosts];
|
|
|
|
async function loadPage() {
|
|
const posts = await search(query, page);
|
|
|
|
newPosts = posts.result;
|
|
}
|
|
|
|
let footer: HTMLElement;
|
|
|
|
onMount(() => {
|
|
if (browser) {
|
|
const handleIntersect: IntersectionObserverCallback = (entries, observer) => {
|
|
const first = entries[0];
|
|
if (first.isIntersecting) {
|
|
page++;
|
|
loadPage();
|
|
}
|
|
};
|
|
const options = { threshold: 0.125, rootMargin: '-100% 0% 100%' };
|
|
const observer = new IntersectionObserver(handleIntersect, options);
|
|
observer.observe(footer);
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<svelte:head>
|
|
<title>Damillora's Virtual Memoir</title>
|
|
</svelte:head>
|
|
|
|
<Hero background="/images/default-feature.jpg" />
|
|
|
|
<Container>
|
|
<Index>
|
|
{#each posts as post}
|
|
<SearchCard title={post.title} url={post.url} excerpt={post.excerpt} />
|
|
{/each}
|
|
</Index>
|
|
<div bind:this={footer} />
|
|
</Container>
|