implement posts

This commit is contained in:
Daniel Bulant 2022-03-05 11:33:46 +01:00
parent 6a413fec6e
commit 52ac06a796
25 changed files with 325 additions and 96 deletions

View file

@ -15,6 +15,7 @@
},
"type": "module",
"dependencies": {
"@sveltejs/adapter-static": "^1.0.0-next.26"
"@sveltejs/adapter-static": "^1.0.0-next.26",
"luxon": "^2.3.1"
}
}

View file

@ -4,11 +4,13 @@ specifiers:
'@sveltejs/adapter-auto': next
'@sveltejs/adapter-static': ^1.0.0-next.26
'@sveltejs/kit': next
luxon: ^2.3.1
mdsvex: ^0.10.5
svelte: ^3.44.0
dependencies:
'@sveltejs/adapter-static': 1.0.0-next.26
luxon: 2.3.1
devDependencies:
'@sveltejs/adapter-auto': 1.0.0-next.30
@ -369,6 +371,11 @@ packages:
engines: {node: '>=6'}
dev: true
/luxon/2.3.1:
resolution: {integrity: sha512-I8vnjOmhXsMSlNMZlMkSOvgrxKJl0uOsEzdGgGNZuZPaS9KlefpE9KV95QFftlJSC+1UyCC9/I69R02cz/zcCA==}
engines: {node: '>=12'}
dev: false
/magic-string/0.25.7:
resolution: {integrity: sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==}
dependencies:

View file

@ -4,6 +4,7 @@
<meta charset="utf-8" />
<link rel="icon" href="%svelte.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="%svelte.assets%/prism/dark.css" />
<link rel="stylesheet" href="%svelte.assets%/global.css" />
%svelte.head%
</head>

View file

@ -7,13 +7,13 @@
<div class="profiles">
<a href="https://github.com/danbulant" rel="noreferrer noopener" target="_blank">
<div class="github" title="GitHub">
<img src="/github.png" alt="Github Icon" draggable={false}>
<img src="/tech/github.png" alt="Github Icon" draggable={false}>
<span>danbulant</span>
</div>
</a>
<a href="https://discord.gg/XKPbz5xRuK" rel="noreferrer noopener" target="_blank">
<div class="discord" title="Discord">
<img src="/discord.png" alt="Discord Icon" draggable={false}>
<img src="/tech/discord.png" alt="Discord Icon" draggable={false}>
<span>TechmandanCZ#3372</span>
</div>
</a>

View file

@ -1,15 +1,16 @@
<script>
export var thumbnail;
export var bigThumbnail;
export var categories = [];
export var author;
export var date;
export var relDate;
export var title;
export var authorIcon;
export var description;
export var path;
</script>
<div class="post">
<img src={thumbnail} alt="Thumbnail" class="thumbnail" draggable={false}>
<a href={path} class="post">
<img src={bigThumbnail} width="800" height="400" alt="Thumbnail" class="thumbnail" draggable={false}>
<div class="data">
<div class="categories">
{#each categories as category}
@ -20,19 +21,22 @@
<p>{description}</p>
<div class="author">
<img src={authorIcon} alt="Avatar of author" draggable={false}>
<span class="spacer"></span>
<span class="author">{author}</span>
<span class="date">{date}</span>
<span class="spacer"></span>
<span class="date">{relDate}</span>
</div>
</div>
</div>
</a>
<style>
.post {
cursor: pointer;
user-select: none;
}
a.post:hover {
text-decoration: none;
}
.thumbnail {
border-radius: 5px;
width: 100%;
@ -59,5 +63,6 @@
.author img {
height: 100%;
border-radius: 50%;
padding-right: 5px;
}
</style>

View file

@ -0,0 +1,20 @@
<script>
import darkmode from "$lib/stores/darkmode";
import Bar from "./bar.svelte";
import Button from "./button.svelte";
import Split from "./split.svelte";
function toggle() {
$darkmode = !$darkmode;
}
</script>
<div class="bar" class:dark={$darkmode}>
<Bar>
<a href="/"><h3>Daniel Bulant</h3></a>
<Split />
<Button text on:click={toggle}>{$darkmode ? "Light" : "Dark"} mode</Button>
<a href="/#contact" class="big">Contact</a>
<a href="/posts" class="big">Blog</a>
</Bar>
</div>

View file

@ -6,6 +6,7 @@
export var title;
export var authorIcon;
export var currentHover;
export var path;
var grayscale = false;
$: grayscale = currentHover && currentHover !== title;
@ -18,8 +19,8 @@
}
</script>
<div class="post" class:grayscale on:mouseenter={mouseenter} on:mouseleave={mouseleave}>
<img src={thumbnail} alt="Thumbnail" class="thumbnail" draggable={false}>
<a href={path} class="post" class:grayscale on:mouseenter={mouseenter} on:mouseleave={mouseleave}>
<img src={thumbnail} height="256" width="256" alt="Thumbnail" class="thumbnail" draggable={false}>
<div class="data">
<div class="categories">
{#each categories as category}
@ -35,12 +36,15 @@
<span class="date">{date}</span>
</div>
</div>
</div>
</a>
<style>
.grayscale {
filter: grayscale(100%) blur(2px);
}
a.post:hover {
text-decoration: none;
}
.post {
transition: filter .3s;
cursor: pointer;

View file

@ -2,45 +2,9 @@
import HeroPost from "./heroPost.svelte";
import Post from "./post.svelte";
var heroPost = {
title: "Test hero post",
author: "Daniel Bulant",
authorIcon: "/logo.png",
thumbnail: "https://picsum.photos/800/400?random=1",
categories: ["test"],
description: "Test description",
date: "16-01-2021"
};
export var posts;
var posts = [{
title: "Test post 1",
author: "Daniel Bulant",
authorIcon: "/logo.png",
thumbnail: "https://picsum.photos/150?random=1",
categories: ["test"],
date: "16-01-2021"
}, {
title: "Test post 2",
author: "Daniel Bulant",
authorIcon: "/logo.png",
thumbnail: "https://picsum.photos/150?random=2",
categories: ["test"],
date: "16-01-2021"
}, {
title: "Test post 3",
author: "Daniel Bulant",
authorIcon: "/logo.png",
thumbnail: "https://picsum.photos/150?random=3",
categories: ["test"],
date: "16-01-2021"
}, {
title: "Test post 4",
author: "Daniel Bulant",
authorIcon: "/logo.png",
thumbnail: "https://picsum.photos/150?random=4",
categories: ["test"],
date: "16-01-2021"
}];
var heroPost = posts[0];
var currentHover = null;
</script>
@ -50,11 +14,13 @@
<div class="hero">
<HeroPost {...heroPost} />
</div>
<div class="posts">
{#each posts as post (post.title)}
<Post {...post} bind:currentHover />
{/each}
</div>
{#if posts.length > 1}
<div class="posts">
{#each posts.slice(1) as post (post.title)}
<Post {...post} bind:currentHover />
{/each}
</div>
{/if}
</div>
<style>

View file

@ -0,0 +1,28 @@
<script>
import Navbar from "$lib/components/navbar.svelte";
import darkmode from "$lib/stores/darkmode";
export let title;
export let date;
</script>
<svelte:head>
<title>Daniel Bulant - Homepage</title>
<meta name="description" content="Homepage of danbulant.eu - List of my projects, contact info.">
</svelte:head>
<Navbar />
<main class:dark={$darkmode}>
<h1>{title}</h1>
<span>{date}</span>
<slot />
</main>
<style>
main {
margin: 0 auto;
max-width: 700px;
padding: 0 20px;
}
</style>

View file

@ -8,6 +8,15 @@ const darkmode = writable(
darkmode.subscribe(v => {
if(typeof window !== "undefined")
localStorage.setItem("darkmode", JSON.stringify(v));
if(typeof document !== "undefined") {
if(v) {
document.body.classList.add("dark");
} else {
document.body.classList.remove("dark");
}
}
});
export default darkmode;

View file

@ -0,0 +1,27 @@
import { DateTime } from "luxon";
export async function get() {
const allPostFiles = import.meta.glob('../posts/*.md')
const iterablePostFiles = Object.entries(allPostFiles)
const allPosts = await Promise.all(
iterablePostFiles.map(async ([path, resolver]) => {
const { metadata } = await resolver()
const postPath = path.slice(2, -3)
return {
...metadata,
relDate: DateTime.fromISO(metadata.date).toRelativeCalendar(),
path: postPath,
}
})
)
const sortedPosts = allPosts.sort((a, b) => {
return new Date(b.date) - new Date(a.date)
})
return {
body: sortedPosts
}
}

View file

@ -1,32 +1,35 @@
<script context="module">
/** @type {import('./[slug]').Load} */
export async function load({ params, fetch, session, stuff }) {
const response = await fetch("/api/posts.json");
return {
props: {
posts: response.ok && (await response.json())
}
};
}
</script>
<script>
import Bar from "$lib/components/bar.svelte";
import Button from "$lib/components/button.svelte";
import Contact from "$lib/components/contact.svelte";
import Hero from "$lib/components/hero.svelte";
// import Posts from "$lib/components/posts.svelte";
import Navbar from "$lib/components/navbar.svelte";
import Posts from "$lib/components/posts.svelte";
import Project from "$lib/components/project.svelte";
import Split from "$lib/components/split.svelte";
import TechnologyDetails from "$lib/components/technologyDetails.svelte";
import darkmode from "$lib/stores/darkmode";
function toggle() {
$darkmode = !$darkmode;
}
$: {
if(typeof document !== "undefined") {
if($darkmode) {
document.body.classList.add("dark");
} else {
document.body.classList.remove("dark");
}
}
}
var technologySelected = null;
var technologyHover = false;
/** @type {null | "websites" | "applications" | "bots"} */
var appTypeHover = null;
export var posts;
$: console.log(posts);
</script>
<svelte:head>
@ -34,14 +37,7 @@
<meta name="description" content="Homepage of danbulant.eu - List of my projects, contact info.">
</svelte:head>
<div class="bar" class:dark={$darkmode}>
<Bar>
<h3>Daniel Bulant</h3>
<Split />
<Button text on:click={toggle}>{$darkmode ? "Light" : "Dark"} mode</Button>
<a href="#contact" class="big">Contact</a>
</Bar>
</div>
<Navbar />
<main class:dark={$darkmode}>
<Hero>
<h1>I'm a young developer making <u on:mouseenter={() => appTypeHover = "websites"} on:mouseleave={() => appTypeHover == "websites" && (appTypeHover = null)}>websites</u>,
@ -120,7 +116,7 @@
Rust
</li>
<li on:click={() => technologySelected = "x11"}>
<img src="/x11.png" alt="" draggable={false} />
<img src="/tech/x11.png" alt="" draggable={false} />
X11
</li>
<li on:click={() => technologySelected = "cs"}>
@ -140,15 +136,15 @@
React
</li>
<li on:click={() => technologySelected = "nomad"}>
<img src="/nomad.svg" alt="" draggable={false} />
<img src="/tech/nomad.svg" alt="" draggable={false} />
Nomad
</li>
<li on:click={() => technologySelected = "consul"}>
<img src="/consul.svg" alt="" draggable={false} />
<img src="/tech/consul.svg" alt="" draggable={false} />
Consul
</li>
<li on:click={() => technologySelected = "discord"}>
<img src="/discord.png" alt="" draggable={false}>
<img src="/tech/discord.png" alt="" draggable={false}>
Discord
</li>
</ul>
@ -186,17 +182,19 @@
Linux
</li>
<li on:click={() => technologySelected = "nginx"}>
<img src="/nginx.svg" alt="" draggable={false} />
<img src="/tech/nginx.svg" alt="" draggable={false} />
Nginx
</li>
<li on:click={() => technologySelected = "cloudflare"}>
<img src="/cloudflare.png" alt="" draggable={false} />
<img src="/tech/cloudflare.png" alt="" draggable={false} />
Cloudflare
</li>
</ul>
</div>
</div>
<!-- <Posts /> -->
{#if posts}
<Posts {posts} />
{/if}
<div id="contact">
<Contact />
</div>
@ -205,15 +203,19 @@
<Bar>
<h3>Daniel Bulant</h3>
<Split />
<a href="https://github.com/shinoa-hiragi" rel="noreferrer noopener" target="_blank" class="text-right">
<h3>
Design by Carl Hansen
</h3>
</a>
<h3>
Design by Carl Hansen
</h3>
</Bar>
</div>
<style>
/* :global(body) {
background-image: linear-gradient(to top, rgb(242,210,223), transparent min(180vh, 1080px));
}
:global(body.dark) {
background-image: linear-gradient(to top, rgba(94, 61, 74, 0.685), transparent min(180vh, 1080px));
} */
.relative {
position: relative;
}

16
src/routes/posts/test.md Normal file
View file

@ -0,0 +1,16 @@
---
title: Test post
date: 2022-03-05T10:16
author: Daniel Bulant
authorIcon: /logo.png
thumbnail: https://picsum.photos/256?random=1
bigThumbnail: https://picsum.photos/800/400?random=1
categories: [test]
description: Test description
---
Yeah so this is a post
```js
console.log("Code block");
```

View file

@ -9,14 +9,11 @@ body {
margin: 0;
box-sizing: border-box;
font-family: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
margin-top: 30px;
transition: color .3s, background-color .3s;
background-image: linear-gradient(to top, rgb(242,210,223), transparent min(180vh, 1080px));
}
body.dark {
background-color: #1f1f1f;
background-image: linear-gradient(to top, rgba(94, 61, 74, 0.685), transparent min(180vh, 1080px));
color: rgb(191, 191, 191);
}

143
static/prism/dark.css Normal file
View file

@ -0,0 +1,143 @@
/**
* atom-dark theme for `prism.js`
* Based on Atom's `atom-dark` theme: https://github.com/atom/atom-dark-syntax
* @author Joe Gibson (@gibsjose)
*/
code[class*="language-"],
pre[class*="language-"] {
color: #c5c8c6;
text-shadow: 0 1px rgba(0, 0, 0, 0.3);
font-family: Inconsolata, Monaco, Consolas, 'Courier New', Courier, monospace;
direction: ltr;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
border-radius: 0.3em;
}
:not(pre) > code[class*="language-"],
pre[class*="language-"] {
background: #1d1f21;
}
/* Inline code */
:not(pre) > code[class*="language-"] {
padding: .1em;
border-radius: .3em;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: #7C7C7C;
}
.token.punctuation {
color: #c5c8c6;
}
.namespace {
opacity: .7;
}
.token.property,
.token.keyword,
.token.tag {
color: #96CBFE;
}
.token.class-name {
color: #FFFFB6;
text-decoration: underline;
}
.token.boolean,
.token.constant {
color: #99CC99;
}
.token.symbol,
.token.deleted {
color: #f92672;
}
.token.number {
color: #FF73FD;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #A8FF60;
}
.token.variable {
color: #C6C5FE;
}
.token.operator {
color: #EDEDED;
}
.token.entity {
color: #FFFFB6;
cursor: help;
}
.token.url {
color: #96CBFE;
}
.language-css .token.string,
.style .token.string {
color: #87C38A;
}
.token.atrule,
.token.attr-value {
color: #F9EE98;
}
.token.function {
color: #DAD085;
}
.token.regex {
color: #E9C062;
}
.token.important {
color: #fd971f;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}

View file

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View file

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 2 KiB

View file

Before

Width:  |  Height:  |  Size: 559 B

After

Width:  |  Height:  |  Size: 559 B

View file

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View file

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View file

Before

Width:  |  Height:  |  Size: 105 KiB

After

Width:  |  Height:  |  Size: 105 KiB

View file

@ -13,7 +13,10 @@ const config = {
preprocess: [
mdsvex({
extensions: ['.md']
extensions: ['.md'],
layout: {
_: "./src/lib/layouts/post.svelte"
}
})
]
};