This commit is contained in:
cupcakearmy 2021-12-25 12:40:35 +01:00
parent d8fe85c4ca
commit 31fc15118b
No known key found for this signature in database
GPG Key ID: 3235314B4D31232F
10 changed files with 219 additions and 36 deletions

View File

@ -13,35 +13,11 @@
<body> <body>
<div id="svelte">%svelte.body%</div> <div id="svelte">%svelte.body%</div>
<script type="text/javascript">
var _paq = (window._paq = window._paq || [])
_paq.push(['setDocumentTitle', document.domain + '/' + document.title])
_paq.push(['setCookieDomain', '*.nicco.io'])
_paq.push(['disableCookies'])
_paq.push(['trackPageView'])
_paq.push(['enableLinkTracking'])
;(function () {
var u = '//stats.nicco.io/'
_paq.push(['setTrackerUrl', u + 'rainbow'])
_paq.push(['setSiteId', '1'])
var d = document,
g = d.createElement('script'),
s = d.getElementsByTagName('script')[0]
g.type = 'text/javascript'
g.async = true
g.src = u + 'unicorn'
s.parentNode.insertBefore(g, s)
})()
</script>
<noscript
><p>
<img src="//stats.nicco.io/rainbow?idsite=1&amp;rec=1" style="border: 0" alt="" /></p
></noscript>
<script <script
async async
defer defer
data-website-id="3808ed9b-9fc6-481b-bf6c-45e07f7aedf9" data-website-id="3808ed9b-9fc6-481b-bf6c-45e07f7aedf9"
data-domains="nicco.io"
src="https://spectare.nicco.io/unicorn.js" src="https://spectare.nicco.io/unicorn.js"
></script> ></script>
</body> </body>

View File

@ -3,11 +3,12 @@
import ImageFrame from '../components/ImageFrame.svelte' import ImageFrame from '../components/ImageFrame.svelte'
import PostAttributes from '../components/PostAttributes.svelte' import PostAttributes from '../components/PostAttributes.svelte'
import Tags from './Tags.svelte'
export let post: GQLBasePostFragment export let post: GQLBasePostFragment
</script> </script>
<a href={`blog/${post.slug}`} class:without={!post.post.featured}> <a href={`/blog/${post.slug}`} class:without={!post.post.featured}>
{#if post.post.featured} {#if post.post.featured}
<ImageFrame src={post.post.featured.sourceUrl} alt={post.post.featured.altText} /> <ImageFrame src={post.post.featured.sourceUrl} alt={post.post.featured.altText} />
{/if} {/if}
@ -15,6 +16,7 @@
<h2> <h2>
{@html post.title} {@html post.title}
</h2> </h2>
<Tags tags={post.tags.nodes} />
</a> </a>
<style> <style>
@ -33,9 +35,13 @@
transition: var(--animation); transition: var(--animation);
background-color: var(--clr-light); background-color: var(--clr-light);
} }
a:hover h2 { a :global(img) {
top: -1em; transition: var(--animation);
transform: scale(0.95); position: relative;
top: 0;
}
a:hover :global(img) {
top: 2.5rem;
} }
a > :global(div) { a > :global(div) {

View File

@ -0,0 +1,28 @@
<script lang="ts">
export let name: string = ''
export let href: string = ''
export let count: number = 0
</script>
<a {href}>
<div>
{name} <i>{count}</i>
</div>
</a>
<style>
div {
display: inline-block;
margin: 0.25rem;
padding: 0 0.5rem;
background-color: var(--clr-primary);
width: max-content;
}
i {
font-family: 'Courier New', Courier, monospace;
font-size: 0.85em;
font-weight: bold;
color: var(--clr-secondary);
}
</style>

View File

@ -0,0 +1,34 @@
<script lang="ts">
import type { GQLBaseTagFragment } from '$lib/gql/gen'
import Tag from './Tag.svelte'
export let tags: readonly GQLBaseTagFragment[]
export let rows: number = 1
$: height = rows * 2
</script>
<div style="height: {height}em;">
{#each tags as { slug, name, count }}
<Tag {name} {count} href="/blog/tags/{slug}" />
{/each}
</div>
<style>
div {
display: flex;
flex-direction: row;
overflow: auto;
align-items: center;
justify-content: flex-start;
margin: 0 -0.25rem;
}
div::-webkit-scrollbar {
display: none;
}
div {
-ms-overflow-style: none;
scrollbar-width: none;
}
</style>

View File

@ -9205,24 +9205,38 @@ export type GQLProjectsOneQueryVariables = Exact<{
export type GQLProjectsOneQuery = { readonly __typename?: 'RootQuery', readonly project: { readonly __typename?: 'Project', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly project: { readonly __typename?: 'Project_Project', readonly date: string, readonly link: string, readonly description: string } } }; export type GQLProjectsOneQuery = { readonly __typename?: 'RootQuery', readonly project: { readonly __typename?: 'Project', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly project: { readonly __typename?: 'Project_Project', readonly date: string, readonly link: string, readonly description: string } } };
export type GQLBasePostFragment = { readonly __typename?: 'Post', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly date: string, readonly modified: string, readonly post: { readonly __typename?: 'Post_Post', readonly featured: { readonly __typename?: 'MediaItem', readonly srcSet: string, readonly altText: string, readonly sourceUrl: string } } }; export type GQLBasePostFragment = { readonly __typename?: 'Post', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly date: string, readonly modified: string, readonly tags: { readonly __typename?: 'PostToTagConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Tag', readonly id: string, readonly slug: string, readonly name: string, readonly count: number }> }, readonly post: { readonly __typename?: 'Post_Post', readonly featured: { readonly __typename?: 'MediaItem', readonly srcSet: string, readonly altText: string, readonly sourceUrl: string } } };
export type GQLPostsManyQueryVariables = Exact<{ [key: string]: never; }>; export type GQLPostsManyQueryVariables = Exact<{ [key: string]: never; }>;
export type GQLPostsManyQuery = { readonly __typename?: 'RootQuery', readonly posts: { readonly __typename?: 'RootQueryToPostConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Post', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly date: string, readonly modified: string, readonly post: { readonly __typename?: 'Post_Post', readonly featured: { readonly __typename?: 'MediaItem', readonly srcSet: string, readonly altText: string, readonly sourceUrl: string } } }> } }; export type GQLPostsManyQuery = { readonly __typename?: 'RootQuery', readonly posts: { readonly __typename?: 'RootQueryToPostConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Post', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly date: string, readonly modified: string, readonly tags: { readonly __typename?: 'PostToTagConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Tag', readonly id: string, readonly slug: string, readonly name: string, readonly count: number }> }, readonly post: { readonly __typename?: 'Post_Post', readonly featured: { readonly __typename?: 'MediaItem', readonly srcSet: string, readonly altText: string, readonly sourceUrl: string } } }> } };
export type GQLPostsOneQueryVariables = Exact<{ export type GQLPostsOneQueryVariables = Exact<{
slug: Scalars['ID']; slug: Scalars['ID'];
}>; }>;
export type GQLPostsOneQuery = { readonly __typename?: 'RootQuery', readonly post: { readonly __typename?: 'Post', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly date: string, readonly modified: string, readonly post: { readonly __typename?: 'Post_Post', readonly featured: { readonly __typename?: 'MediaItem', readonly srcSet: string, readonly altText: string, readonly sourceUrl: string } } } }; export type GQLPostsOneQuery = { readonly __typename?: 'RootQuery', readonly post: { readonly __typename?: 'Post', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly date: string, readonly modified: string, readonly tags: { readonly __typename?: 'PostToTagConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Tag', readonly id: string, readonly slug: string, readonly name: string, readonly count: number }> }, readonly post: { readonly __typename?: 'Post_Post', readonly featured: { readonly __typename?: 'MediaItem', readonly srcSet: string, readonly altText: string, readonly sourceUrl: string } } } };
export type GQLPostsManyByTagQueryVariables = Exact<{
tag: Scalars['String'];
}>;
export type GQLPostsManyByTagQuery = { readonly __typename?: 'RootQuery', readonly posts: { readonly __typename?: 'RootQueryToPostConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Post', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly date: string, readonly modified: string, readonly tags: { readonly __typename?: 'PostToTagConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Tag', readonly id: string, readonly slug: string, readonly name: string, readonly count: number }> }, readonly post: { readonly __typename?: 'Post_Post', readonly featured: { readonly __typename?: 'MediaItem', readonly srcSet: string, readonly altText: string, readonly sourceUrl: string } } }> } };
export type GQLSearchQueryVariables = Exact<{ [key: string]: never; }>; export type GQLSearchQueryVariables = Exact<{ [key: string]: never; }>;
export type GQLSearchQuery = { readonly __typename?: 'RootQuery', readonly posts: { readonly __typename?: 'RootQueryToPostConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Post', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly date: string, readonly modified: string, readonly post: { readonly __typename?: 'Post_Post', readonly featured: { readonly __typename?: 'MediaItem', readonly srcSet: string, readonly altText: string, readonly sourceUrl: string } } }> }, readonly projects: { readonly __typename?: 'RootQueryToProjectConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Project', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly project: { readonly __typename?: 'Project_Project', readonly date: string, readonly link: string, readonly description: string } }> }, readonly works: { readonly __typename?: 'RootQueryToWorkConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Work', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly work: { readonly __typename?: 'Work_Work', readonly date: string, readonly link: string, readonly role: string, readonly image: { readonly __typename?: 'MediaItem', readonly srcSet: string, readonly altText: string, readonly sourceUrl: string } } }> } }; export type GQLSearchQuery = { readonly __typename?: 'RootQuery', readonly posts: { readonly __typename?: 'RootQueryToPostConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Post', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly date: string, readonly modified: string, readonly tags: { readonly __typename?: 'PostToTagConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Tag', readonly id: string, readonly slug: string, readonly name: string, readonly count: number }> }, readonly post: { readonly __typename?: 'Post_Post', readonly featured: { readonly __typename?: 'MediaItem', readonly srcSet: string, readonly altText: string, readonly sourceUrl: string } } }> }, readonly projects: { readonly __typename?: 'RootQueryToProjectConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Project', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly project: { readonly __typename?: 'Project_Project', readonly date: string, readonly link: string, readonly description: string } }> }, readonly works: { readonly __typename?: 'RootQueryToWorkConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Work', readonly id: string, readonly slug: string, readonly title: string, readonly content: string, readonly status: string, readonly work: { readonly __typename?: 'Work_Work', readonly date: string, readonly link: string, readonly role: string, readonly image: { readonly __typename?: 'MediaItem', readonly srcSet: string, readonly altText: string, readonly sourceUrl: string } } }> } };
export type GQLBaseTagFragment = { readonly __typename?: 'Tag', readonly id: string, readonly slug: string, readonly name: string, readonly count: number };
export type GQLTagsManyQueryVariables = Exact<{ [key: string]: never; }>;
export type GQLTagsManyQuery = { readonly __typename?: 'RootQuery', readonly tags: { readonly __typename?: 'RootQueryToTagConnection', readonly nodes: ReadonlyArray<{ readonly __typename?: 'Tag', readonly id: string, readonly slug: string, readonly name: string, readonly count: number }> } };
export const BasePageFragmentDoc = gql` export const BasePageFragmentDoc = gql`
fragment BasePage on Page { fragment BasePage on Page {
@ -9271,6 +9285,14 @@ export const BaseProjectFragmentDoc = gql`
} }
} }
`; `;
export const BaseTagFragmentDoc = gql`
fragment BaseTag on Tag {
id
slug
name
count
}
`;
export const BasePostFragmentDoc = gql` export const BasePostFragmentDoc = gql`
fragment BasePost on Post { fragment BasePost on Post {
id id
@ -9280,13 +9302,19 @@ export const BasePostFragmentDoc = gql`
status status
date date
modified modified
tags {
nodes {
...BaseTag
}
}
post { post {
featured { featured {
...BaseMediaItem ...BaseMediaItem
} }
} }
} }
${BaseMediaItemFragmentDoc}`; ${BaseTagFragmentDoc}
${BaseMediaItemFragmentDoc}`;
export const MediaItemsManyDocument = gql` export const MediaItemsManyDocument = gql`
query MediaItemsMany { query MediaItemsMany {
mediaItems(first: 100, where: {status: PUBLISH}) { mediaItems(first: 100, where: {status: PUBLISH}) {
@ -9367,6 +9395,15 @@ export const PostsOneDocument = gql`
} }
} }
${BasePostFragmentDoc}`; ${BasePostFragmentDoc}`;
export const PostsManyByTagDocument = gql`
query PostsManyByTag($tag: String!) {
posts(first: 100, where: {status: PUBLISH, tag: $tag}) {
nodes {
...BasePost
}
}
}
${BasePostFragmentDoc}`;
export const SearchDocument = gql` export const SearchDocument = gql`
query Search { query Search {
posts(first: 100) { posts(first: 100) {
@ -9388,6 +9425,15 @@ export const SearchDocument = gql`
${BasePostFragmentDoc} ${BasePostFragmentDoc}
${BaseProjectFragmentDoc} ${BaseProjectFragmentDoc}
${BaseWorkFragmentDoc}`; ${BaseWorkFragmentDoc}`;
export const TagsManyDocument = gql`
query TagsMany {
tags(first: 100) {
nodes {
...BaseTag
}
}
}
${BaseTagFragmentDoc}`;
export type SdkFunctionWrapper = <T>(action: (requestHeaders?:Record<string, string>) => Promise<T>, operationName: string) => Promise<T>; export type SdkFunctionWrapper = <T>(action: (requestHeaders?:Record<string, string>) => Promise<T>, operationName: string) => Promise<T>;
@ -9426,8 +9472,14 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper =
PostsOne(variables: GQLPostsOneQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<GQLPostsOneQuery> { PostsOne(variables: GQLPostsOneQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<GQLPostsOneQuery> {
return withWrapper((wrappedRequestHeaders) => client.request<GQLPostsOneQuery>(PostsOneDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'PostsOne'); return withWrapper((wrappedRequestHeaders) => client.request<GQLPostsOneQuery>(PostsOneDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'PostsOne');
}, },
PostsManyByTag(variables: GQLPostsManyByTagQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<GQLPostsManyByTagQuery> {
return withWrapper((wrappedRequestHeaders) => client.request<GQLPostsManyByTagQuery>(PostsManyByTagDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'PostsManyByTag');
},
Search(variables?: GQLSearchQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<GQLSearchQuery> { Search(variables?: GQLSearchQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<GQLSearchQuery> {
return withWrapper((wrappedRequestHeaders) => client.request<GQLSearchQuery>(SearchDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'Search'); return withWrapper((wrappedRequestHeaders) => client.request<GQLSearchQuery>(SearchDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'Search');
},
TagsMany(variables?: GQLTagsManyQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<GQLTagsManyQuery> {
return withWrapper((wrappedRequestHeaders) => client.request<GQLTagsManyQuery>(TagsManyDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'TagsMany');
} }
}; };
} }

View File

@ -105,6 +105,11 @@ fragment BasePost on Post {
status status
date date
modified modified
tags {
nodes {
...BaseTag
}
}
post { post {
featured { featured {
...BaseMediaItem ...BaseMediaItem
@ -126,6 +131,14 @@ query PostsOne($slug: ID!) {
} }
} }
query PostsManyByTag($tag: String!) {
posts(first: 100, where: { status: PUBLISH, tag: $tag }) {
nodes {
...BasePost
}
}
}
query Search { query Search {
posts(first: 100) { posts(first: 100) {
nodes { nodes {
@ -143,3 +156,18 @@ query Search {
} }
} }
} }
fragment BaseTag on Tag {
id
slug
name
count
}
query TagsMany {
tags(first: 100) {
nodes {
...BaseTag
}
}
}

View File

@ -54,6 +54,19 @@ export async function get(args: ServerRequest) {
} }
} }
case 'tags': {
if (all) {
const data = await SDK.TagsMany()
const sorted = [...data.tags.nodes].filter((t) => t.count).sort((a, b) => b.count - a.count)
return { body: sorted }
}
}
case 'postsByTags': {
const data = await SDK.PostsManyByTag({ tag: slug })
return { body: data.posts.nodes }
}
default: default:
return { status: 404 } return { status: 404 }
} }

View File

@ -15,6 +15,7 @@
import PostAttributes from '$lib/components/PostAttributes.svelte' import PostAttributes from '$lib/components/PostAttributes.svelte'
import WpAdapter from '$lib/components/WPAdapter.svelte' import WpAdapter from '$lib/components/WPAdapter.svelte'
import type { GQLBasePostFragment } from '$lib/gql/gen' import type { GQLBasePostFragment } from '$lib/gql/gen'
import Tags from '$lib/components/Tags.svelte'
export let data: GQLBasePostFragment export let data: GQLBasePostFragment
</script> </script>
@ -28,4 +29,5 @@
{#if data.content} {#if data.content}
<WpAdapter content={data.content} /> <WpAdapter content={data.content} />
{/if} {/if}
<Tags tags={data.tags.nodes} />
</SimplePage> </SimplePage>

View File

@ -6,6 +6,7 @@
return { return {
props: { props: {
data: await fetch('/api/posts/*.json').then((r) => r.json()), data: await fetch('/api/posts/*.json').then((r) => r.json()),
tags: await fetch('/api/tags/*.json').then((r) => r.json()),
}, },
} }
} }
@ -14,17 +15,29 @@
<script lang="ts"> <script lang="ts">
import SimplePage from '$lib/components/SimplePage.svelte' import SimplePage from '$lib/components/SimplePage.svelte'
import PostPreview from '$lib/components/PostPreview.svelte' import PostPreview from '$lib/components/PostPreview.svelte'
import type { GQLBasePostFragment } from '$lib/gql/gen' import type { GQLBasePostFragment, GQLBaseTagFragment } from '$lib/gql/gen'
import Tags from '$lib/components/Tags.svelte'
export let data: GQLBasePostFragment[] export let data: GQLBasePostFragment[]
export let tags: GQLBaseTagFragment[]
</script> </script>
<svelte:head> <svelte:head>
<title>Blog</title> <title>Blog</title>
</svelte:head> </svelte:head>
<SimplePage title="Works"> <SimplePage title="Blog">
<b>Explore Tags</b>
<Tags {tags} />
<div />
{#each data as post} {#each data as post}
<PostPreview {post} /> <PostPreview {post} />
{/each} {/each}
</SimplePage> </SimplePage>
<style>
div {
margin-bottom: 3em;
}
</style>

View File

@ -0,0 +1,31 @@
<script lang="ts" context="module">
import type { Load } from '@sveltejs/kit'
export const load: Load = async ({ fetch, page }) => {
return {
props: {
slug: page.params.slug,
data: await fetch(`/api/postsByTags/${page.params.slug}.json`).then((r) => r.json()),
},
}
}
</script>
<script lang="ts">
import SimplePage from '$lib/components/SimplePage.svelte'
import type { GQLPostsManyByTagQuery } from '$lib/gql/gen'
import PostPreview from '$lib/components/PostPreview.svelte'
export let slug: string
export let data: GQLPostsManyByTagQuery['posts']['nodes']
</script>
<svelte:head>
<title>Blog - {slug}</title>
</svelte:head>
<SimplePage title={slug}>
{#each data as post}
<PostPreview {post} />
{/each}
</SimplePage>