Shioriko/web/app/src/routes/Posts.svelte

147 lines
4.7 KiB
Svelte
Raw Normal View History

2021-05-10 15:47:35 +00:00
<script>
2021-05-09 15:07:23 +00:00
import { onMount } from "svelte";
2021-05-10 20:25:33 +00:00
import { getPostSearchTag } from "../api.js";
2021-05-11 10:06:25 +00:00
import { Link, navigate } from "svelte-routing";
import InfiniteScroll from "svelte-infinite-scroll";
import TagLink from "../TagLink.svelte";
2021-05-10 20:25:33 +00:00
import queryString from "query-string";
import Tags from "svelte-tags-input";
2021-05-11 10:06:25 +00:00
import { add_attribute } from "svelte/internal";
2021-05-10 02:45:40 +00:00
export let location;
2021-05-09 15:07:23 +00:00
2021-05-10 20:25:33 +00:00
let searchTerms = [];
2021-05-09 15:07:23 +00:00
let page = 1;
let posts = [];
2021-05-11 10:06:25 +00:00
let newBatch = [];
const splitToChunks = (array, parts) => {
let result = [];
for (let i = parts; i > 0; i--) {
result.push(array.slice(i * parts, i * parts + parts + 1));
}
return result;
};
let postChunks = [];
// split posts into 4 columns
$: {
postChunks = splitToChunks(posts, 4);
}
2021-05-09 15:07:23 +00:00
const getData = async () => {
2021-05-11 10:06:25 +00:00
console.log("page " + page);
2021-05-10 20:25:33 +00:00
const data = await getPostSearchTag({ page, q: searchTerms.join("+") });
2021-05-11 10:06:25 +00:00
if (data.posts) {
newBatch = data.posts;
} else {
newBatch = [];
2021-05-10 02:45:40 +00:00
}
2021-05-10 15:47:35 +00:00
};
2021-05-11 10:06:25 +00:00
$: {
posts = [...posts, ...newBatch];
}
2021-05-10 20:25:33 +00:00
let queryParams;
const onTagChange = (value) => {
searchTerms = value.detail.tags;
};
2021-05-11 10:06:25 +00:00
onMount(() => {
2021-05-10 15:47:35 +00:00
queryParams = queryString.parse(location.search);
2021-05-10 20:25:33 +00:00
if (queryParams.tags) {
searchTerms = queryParams.tags.split(" ");
} else {
searchTerms = [];
}
2021-05-10 02:45:40 +00:00
getData();
2021-05-11 10:06:25 +00:00
});
2021-05-10 20:25:33 +00:00
const onSearch = (i) => {
if (searchTerms.length > 0) {
navigate(`/posts?tags=${searchTerms.join("+")}`);
} else {
navigate(`/posts`);
}
};
2021-05-09 15:07:23 +00:00
</script>
<section class="hero is-primary">
<div class="hero-body">
2021-05-10 15:47:35 +00:00
<p class="title">Posts</p>
2021-05-09 15:07:23 +00:00
</div>
</section>
2021-05-10 20:25:33 +00:00
<section class="section">
<div class="container">
<div class="block">
<form on:submit|preventDefault={onSearch}>
<div class="field has-addons">
<div class="control is-expanded">
<div class="control" id="tags">
<Tags
tags={searchTerms}
2021-05-11 10:06:25 +00:00
addKeys={[9, 32]}
2021-05-10 20:25:33 +00:00
on:tags={onTagChange}
/>
</div>
</div>
<div class="control">
<button type="submit" class="button is-primary">
Search
</button>
</div>
</div>
</form>
</div>
<div class="block">
2021-05-11 10:06:25 +00:00
<div class="columns">
{#each postChunks as postChunk}
<div class="column is-3">
{#each postChunk as post, i (post.id)}
<div class="block">
<div class="card">
<div class="card-image">
<figure class="image">
<Link to="/post/{post.id}">
<img
alt={post.id}
src={post.image_path}
/>
</Link>
</figure>
</div>
<div class="card-content">
{#if post.tags}
{#each post.tags as tag (tag)}
<TagLink {tag} />
{/each}
{:else}
None
{/if}
</div>
</div>
</div>
{/each}
</div>
{/each}
</div>
<InfiniteScroll
hasMore={newBatch.length}
elementScroll={document}
threshold={0}
on:loadMore={() => {
page++;
getData();
}}
2021-05-10 20:25:33 +00:00
/>
</div>
2021-05-11 10:06:25 +00:00
{#if newBatch.length == 0}
<div class="notification is-primary">
<p class="has-text-centered">End of posts</p>
</div>
{/if}
2021-05-10 20:25:33 +00:00
</div>
</section>