2021-05-10 15:47:35 +00:00
|
|
|
<script>
|
2021-05-09 15:07:23 +00:00
|
|
|
import { onMount } from "svelte";
|
2021-09-10 19:05:45 +00:00
|
|
|
import { getPostSearchTag, getTagAutocomplete } 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 = [];
|
2021-05-11 10:50:34 +00:00
|
|
|
for (let i = 0; i < parts; i++) {
|
|
|
|
let currentColumn = [];
|
|
|
|
for (let j = i; j < array.length; j += parts) {
|
|
|
|
currentColumn.push(array[j]);
|
|
|
|
}
|
|
|
|
result.push(currentColumn);
|
2021-05-11 10:06:25 +00:00
|
|
|
}
|
|
|
|
return result;
|
|
|
|
};
|
|
|
|
|
|
|
|
let postChunks = [];
|
|
|
|
// split posts into 4 columns
|
|
|
|
$: {
|
2021-05-11 10:50:34 +00:00
|
|
|
postChunks = splitToChunks(posts, 5);
|
2021-05-11 10:06:25 +00:00
|
|
|
}
|
|
|
|
|
2021-05-09 15:07:23 +00:00
|
|
|
const getData = async () => {
|
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-09-10 18:56:42 +00:00
|
|
|
const onAutocomplete = async () => {
|
|
|
|
const list = await getTagAutocomplete();
|
|
|
|
return list;
|
|
|
|
};
|
|
|
|
|
2021-05-11 11:06:48 +00:00
|
|
|
$: {
|
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-11 11:06:48 +00:00
|
|
|
posts = [];
|
2021-05-10 02:45:40 +00:00
|
|
|
getData();
|
2021-05-11 11:06:48 +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}
|
2021-09-10 18:56:42 +00:00
|
|
|
autoComplete={onAutocomplete}
|
|
|
|
autoCompleteKey={"name"}
|
2021-05-10 20:25:33 +00:00
|
|
|
/>
|
|
|
|
</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}
|
2021-05-11 10:50:34 +00:00
|
|
|
<div class="column is-one-fifth">
|
2021-05-11 10:06:25 +00:00
|
|
|
{#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}
|
2021-05-11 12:21:11 +00:00
|
|
|
src={post.thumbnail_path}
|
2021-05-11 10:06:25 +00:00
|
|
|
/>
|
|
|
|
</Link>
|
|
|
|
</figure>
|
|
|
|
</div>
|
2021-05-11 11:06:48 +00:00
|
|
|
<div class="card-content">
|
|
|
|
{#if post.tags}
|
2021-05-11 10:06:25 +00:00
|
|
|
{#each post.tags as tag (tag)}
|
|
|
|
<TagLink {tag} />
|
|
|
|
{/each}
|
2021-05-11 11:06:48 +00:00
|
|
|
{:else}
|
|
|
|
<TagLink tag="tagme" />
|
|
|
|
{/if}
|
|
|
|
</div>
|
2021-05-11 10:06:25 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{/each}
|
|
|
|
</div>
|
|
|
|
{/each}
|
|
|
|
</div>
|
|
|
|
<InfiniteScroll
|
|
|
|
hasMore={newBatch.length}
|
|
|
|
elementScroll={document}
|
|
|
|
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}
|
2021-05-11 10:50:34 +00:00
|
|
|
<div class="notification is-primary">
|
|
|
|
<p class="has-text-centered">End of posts</p>
|
|
|
|
</div>
|
2021-05-11 10:06:25 +00:00
|
|
|
{/if}
|
2021-05-10 20:25:33 +00:00
|
|
|
</div>
|
|
|
|
</section>
|