+1
-1
@@ -3,7 +3,7 @@
|
|||||||
"trailingComma": "es5",
|
"trailingComma": "es5",
|
||||||
"tabWidth": 2,
|
"tabWidth": 2,
|
||||||
"useTabs": true,
|
"useTabs": true,
|
||||||
"semi": false,
|
"semi": true,
|
||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
"bracketSpacing": true
|
"bracketSpacing": true
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -1,12 +1,12 @@
|
|||||||
import { defineConfig } from 'astro/config'
|
import { defineConfig } from 'astro/config';
|
||||||
import netlify from '@astrojs/netlify/functions'
|
import netlify from '@astrojs/netlify/functions';
|
||||||
|
|
||||||
// https://astro.build/config
|
// https://astro.build/config
|
||||||
import mdx from '@astrojs/mdx'
|
import mdx from '@astrojs/mdx';
|
||||||
|
|
||||||
// https://astro.build/config
|
// https://astro.build/config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
output: 'server',
|
output: 'server',
|
||||||
adapter: netlify(),
|
adapter: netlify(),
|
||||||
integrations: [mdx()],
|
integrations: [mdx()],
|
||||||
})
|
});
|
||||||
|
|||||||
Generated
-11786
File diff suppressed because it is too large
Load Diff
@@ -15,6 +15,7 @@
|
|||||||
"@astrojs/netlify": "^3.0.4",
|
"@astrojs/netlify": "^3.0.4",
|
||||||
"@astrojs/rss": "^3.0.0",
|
"@astrojs/rss": "^3.0.0",
|
||||||
"astro": "^3.5.4",
|
"astro": "^3.5.4",
|
||||||
|
"date-fns": "^3.3.1",
|
||||||
"date-fns-tz": "^1.3.7",
|
"date-fns-tz": "^1.3.7",
|
||||||
"markdown-it": "^13.0.1",
|
"markdown-it": "^13.0.1",
|
||||||
"sanitize-html": "^2.9.0"
|
"sanitize-html": "^2.9.0"
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
---
|
---
|
||||||
import FormattedDate from '@components/FormattedDate.astro'
|
import FormattedDate from '@components/FormattedDate.astro';
|
||||||
import Calendar from './icons/Calendar.astro'
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
title: String
|
title: String;
|
||||||
date: String
|
date: Date;
|
||||||
slug: String
|
slug?: String;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { title, date, slug } = Astro.props
|
const { title, date, slug } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="blog-header">
|
<div class="blog-header">
|
||||||
@@ -17,8 +16,8 @@ const { title, date, slug } = Astro.props
|
|||||||
</h2>
|
</h2>
|
||||||
<h3>
|
<h3>
|
||||||
<!-- <img class="svg-icon" src={calendarIcon} alt="" /> -->
|
<!-- <img class="svg-icon" src={calendarIcon} alt="" /> -->
|
||||||
<Calendar />
|
|
||||||
<FormattedDate date={date} />
|
🗓️ <FormattedDate date={date} />
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -30,10 +29,15 @@ const { title, date, slug } = Astro.props
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h2,
|
||||||
|
h2 a {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
font-size: 1.1rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
---
|
---
|
||||||
import RSSIcon from './icons/RSS.astro'
|
const year = new Date().getFullYear();
|
||||||
const year = new Date().getFullYear()
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
---
|
---
|
||||||
import { format, add } from 'date-fns'
|
import { format, add } from 'date-fns';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
date: Date
|
date: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { date } = Astro.props
|
const { date } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<span>{format(add(new Date(date), { hours: 6 }), 'MMM do, y')}</span>
|
<span>{format(add(new Date(date), { hours: 6 }), 'MMM do, y')}</span>
|
||||||
|
|||||||
+16
-24
@@ -1,17 +1,14 @@
|
|||||||
---
|
---
|
||||||
import UserIcon from './icons/UserIcon.astro'
|
const { pathname } = Astro.url;
|
||||||
import WebsiteIcon from './icons/Website.astro'
|
|
||||||
|
|
||||||
const { pathname } = Astro.url
|
|
||||||
|
|
||||||
const navLinks = [
|
const navLinks = [
|
||||||
{ label: 'Blog', path: '/' },
|
{ label: '📝 Blog', path: '/' },
|
||||||
{ label: 'About', path: '/about/' },
|
{ label: '👤 About', path: '/about/' },
|
||||||
]
|
];
|
||||||
---
|
---
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
<h1>Graham's Blog</h1>
|
<h1>ghall.blog</h1>
|
||||||
<nav>
|
<nav>
|
||||||
<ul>
|
<ul>
|
||||||
{
|
{
|
||||||
@@ -21,14 +18,6 @@ const navLinks = [
|
|||||||
class={pathname === link.path ? 'active-nav' : null}
|
class={pathname === link.path ? 'active-nav' : null}
|
||||||
href={link.path}
|
href={link.path}
|
||||||
>
|
>
|
||||||
{() => {
|
|
||||||
switch (link.label) {
|
|
||||||
case 'Blog':
|
|
||||||
return <WebsiteIcon class="icon" />
|
|
||||||
case 'About':
|
|
||||||
return <UserIcon class="icon" />
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
<span>{link.label}</span>
|
<span>{link.label}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@@ -41,7 +30,7 @@ const navLinks = [
|
|||||||
<style>
|
<style>
|
||||||
header {
|
header {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0.5rem 1rem;
|
padding: 1.5rem 1rem;
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -50,8 +39,13 @@ const navLinks = [
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
header h1 {
|
h1 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
font-size: 1.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav ul {
|
nav ul {
|
||||||
@@ -66,6 +60,7 @@ const navLinks = [
|
|||||||
nav ul li {
|
nav ul li {
|
||||||
height: 40px;
|
height: 40px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav ul li a {
|
nav ul li a {
|
||||||
@@ -78,13 +73,10 @@ const navLinks = [
|
|||||||
}
|
}
|
||||||
|
|
||||||
nav ul li a::before {
|
nav ul li a::before {
|
||||||
content: '';
|
content: '❯';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -10px;
|
left: -12px;
|
||||||
width: 6px;
|
color: var(--blue);
|
||||||
height: 6px;
|
|
||||||
border-radius: 10px;
|
|
||||||
background-color: var(--blue);
|
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
---
|
---
|
||||||
import BlogHeader from '@components/BlogHeader.astro'
|
import BlogHeader from '@components/BlogHeader.astro';
|
||||||
import Tags from '@components/Tags.astro'
|
import Tags from '@components/Tags.astro';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
post: Object
|
post: Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { post } = Astro.props
|
const { post } = Astro.props;
|
||||||
const { data, slug } = post
|
const { data, slug } = post;
|
||||||
---
|
---
|
||||||
|
|
||||||
<article class="post-preview">
|
<article class="post-preview">
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
---
|
---
|
||||||
const { tags } = Astro.props
|
const { tags } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="tag-container">
|
<div class="tag-container">
|
||||||
{
|
{
|
||||||
tags.sort().map((tag: string) => (
|
tags.sort().map((tag: string) => (
|
||||||
<a class="tag" href={`/archive/${tag}?page=1`}>
|
<a class="tag" href={`/archive/${tag}?page=1`}>
|
||||||
{tag}
|
#{tag}
|
||||||
</a>
|
</a>
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -18,19 +18,8 @@ const { tags } = Astro.props
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tag {
|
.tag {
|
||||||
font-size: 0.8rem;
|
font-size: 1rem;
|
||||||
color: white;
|
|
||||||
padding: 4px 8px;
|
|
||||||
border-radius: 25px;
|
|
||||||
background: var(--blue);
|
|
||||||
line-height: 2rem;
|
line-height: 2rem;
|
||||||
transition: filter 0.15s;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag:hover {
|
|
||||||
text-decoration: none;
|
|
||||||
filter: saturate(120%);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tag:not(:last-child) {
|
.tag:not(:last-child) {
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0_287_24406)" fill="currentColor"><path d="M18.4 3a1 1 0 1 0-2 0h2zm-2 3.6a1 1 0 1 0 2 0h-2zM7.6 3a1 1 0 0 0-2 0h2zm-2 3.6a1 1 0 0 0 2 0h-2zM3.586 20.414l-.707.707.707-.707zm16.828 0l-.707-.707.707.707zm0-15.028l.707-.707-.707.707zm-16.828 0l-.707-.707.707.707zM20 8.8V17h2V8.8h-2zM17 20H7v2h10v-2zM4 17V8.8H2V17h2zM7.001 5.8H16.998v-2H7.003v2zM21 9H3v2h18V9zm-4.6-6v3.6h2V3h-2zM5.6 3v3.6h2V3h-2zM7 20c-.971 0-1.599-.002-2.061-.064-.434-.059-.57-.153-.646-.229l-1.414 1.414c.51.51 1.138.709 1.793.797C5.3 22.002 6.085 22 7 22v-2zm-5-3c0 .915-.002 1.701.082 2.328.088.655.287 1.284.797 1.793l1.414-1.414c-.076-.076-.17-.212-.229-.646C4.002 18.6 4 17.971 4 17H2zm18 0c0 .971-.002 1.599-.064 2.061-.059.434-.153.57-.229.646l1.414 1.414c.51-.51.709-1.138.797-1.793C22.002 18.7 22 17.915 22 17h-2zm-3 5c.915 0 1.701.002 2.328-.082.655-.088 1.284-.287 1.793-.797l-1.414-1.414c-.076.076-.212.17-.646.229-.462.062-1.09.064-2.061.064v2zm5-13.2c0-.915.002-1.701-.082-2.328-.088-.655-.287-1.284-.797-1.793l-1.414 1.414c.076.076.17.212.229.646.062.462.064 1.09.064 2.061h2zm-5.001-3c.971 0 1.6.002 2.062.064.434.059.57.153.646.229l1.414-1.414c-.51-.51-1.138-.709-1.794-.797C18.7 3.798 17.914 3.8 17 3.8v2zM4 8.8c0-.971.002-1.599.064-2.061.059-.434.153-.57.229-.646L2.879 4.679c-.51.51-.709 1.138-.797 1.793C1.998 7.1 2 7.885 2 8.8h2zm3.001-5c-.915 0-1.701-.002-2.328.082-.656.088-1.285.287-1.794.797l1.414 1.414c.076-.076.212-.17.646-.229.463-.062 1.09-.064 2.062-.064v-2zM8.5 17.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm4.5 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm4.5 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/><path d="M17.5 17.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm-9-4a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm4.5 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm4.5 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/><path d="M17.5 13.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/></g><defs><clipPath id="clip0_287_24406"><path fill="currentColor" d="M0 0H24V24H0z"/></clipPath></defs></svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.9 KiB |
@@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 -960 960 960" width="48"><path d="M218-120q-41 0-69.5-28.5T120-218q0-41 28.5-69.5T218-316q41 0 69.5 28.5T316-218q0 41-28.5 69.5T218-120Zm492 0q0-122-46.5-229.5T537-537q-80-80-187.5-126.5T120-710v-90q141 0 264.5 53.5t216 146q92.5 92.5 146 216T800-120h-90Zm-238 0q0-158-97-259T120-480v-90q97 0 178 34t139.5 94Q496-382 529-299.5T562-120h-90Z"/></svg>
|
|
||||||
|
Before Width: | Height: | Size: 422 B |
@@ -1 +0,0 @@
|
|||||||
<svg fill="none" height="24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M19 21v-1.45c0-.977 0-1.465-.113-1.864a3 3 0 0 0-2.073-2.073c-.399-.113-.887-.113-1.864-.113h-6.9c-.977 0-1.465 0-1.864.113a3 3 0 0 0-2.073 2.073C4 18.085 4 18.573 4 19.55V21M16.2 7.06c0 2.245-1.88 4.065-4.2 4.065S7.8 9.305 7.8 7.06 9.68 2.996 12 2.996s4.2 1.82 4.2 4.064z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/></svg>
|
|
||||||
|
Before Width: | Height: | Size: 452 B |
@@ -1 +0,0 @@
|
|||||||
<svg fill="none" height="24" width="24" xmlns="http://www.w3.org/2000/svg"><g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><rect height="18" rx="2" width="18" x="3" y="3"/><path d="M3 7h18M7 11.5h10M7 16h6"/></g></svg>
|
|
||||||
|
Before Width: | Height: | Size: 260 B |
@@ -66,4 +66,4 @@ I changed up some of the categories to avoid any entries with "none" or "N/A".
|
|||||||
|
|
||||||
- [Collections](https://collectionsdb.com/) - Personal Database
|
- [Collections](https://collectionsdb.com/) - Personal Database
|
||||||
- [Vinegar](https://andadinosaur.com/launch-vinegar) - Replaces YouTube player with standard HTML `<video>` tag
|
- [Vinegar](https://andadinosaur.com/launch-vinegar) - Replaces YouTube player with standard HTML `<video>` tag
|
||||||
- [Contexts](https://contexts.co/) - `CMD + tab` replacement
|
- [Contexts](https://contexts.co/) - <kbd>⌘</kbd> + <kbd>tab</kbd> replacement
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ tags: ['Tech', 'Apps', 'Mental Health']
|
|||||||
|
|
||||||
With the upcoming iOS 17.2 update, we’ll finally get our hands on the new Journal app Apple announced at WWDC earlier this year. I decided to be brave and install the public beta so I could take a look and get some first impressions. As someone with mental health struggles, I appreciate the recent efforts Apple has put into making these kinds of features available, so I was really excited to take a look at this latest addition.
|
With the upcoming iOS 17.2 update, we’ll finally get our hands on the new Journal app Apple announced at WWDC earlier this year. I decided to be brave and install the public beta so I could take a look and get some first impressions. As someone with mental health struggles, I appreciate the recent efforts Apple has put into making these kinds of features available, so I was really excited to take a look at this latest addition.
|
||||||
|
|
||||||
First off, I like the simplicity of the interface. It doesn’t have much going on, and I think that’s a point in its favor. You can open the app and get journalling right away. It even offers you journalling prompt which is excellent for those like me who are not always sure what to write about. [^1]
|
First off, I like the simplicity of the interface. It doesn’t have much going on, and I think that’s a point in its favor. You can open the app and get journaling right away. It even offers you journaling prompt which is excellent for those like me who are not always sure what to write about. [^1]
|
||||||
|
|
||||||
It doesn’t have the bells and whistles an app like Day One has, but when it comes to writing a journal entry you’re given the option to add photos, location, and even an audio recording. It’s pretty barebones, but I think that’s ok. The one thing I would like is the ability to tie into the mood tracking on Apple Watch and either be able to set your current mood from the app, or tie mood tracking into the Journaling Suggestions feature.
|
It doesn’t have the bells and whistles an app like Day One has, but when it comes to writing a journal entry you’re given the option to add photos, location, and even an audio recording. It’s pretty barebones, but I think that’s ok. The one thing I would like is the ability to tie into the mood tracking on Apple Watch and either be able to set your current mood from the app, or tie mood tracking into the Journaling Suggestions feature.
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { z, defineCollection } from 'astro:content'
|
import { z, defineCollection } from 'astro:content';
|
||||||
|
|
||||||
const blogCollection = defineCollection({
|
const blogCollection = defineCollection({
|
||||||
schema: z.object({
|
schema: z.object({
|
||||||
@@ -22,8 +22,8 @@ const blogCollection = defineCollection({
|
|||||||
])
|
])
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
})
|
});
|
||||||
|
|
||||||
export const collections = {
|
export const collections = {
|
||||||
blog: blogCollection,
|
blog: blogCollection,
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
export const prerender = true
|
export const prerender = true;
|
||||||
import Layout from '@layouts/Layout.astro'
|
import Layout from '@layouts/Layout.astro';
|
||||||
|
|
||||||
const styles = {
|
const styles = {
|
||||||
img: {
|
img: {
|
||||||
@@ -10,7 +10,7 @@ const styles = {
|
|||||||
marginBottom: '26px',
|
marginBottom: '26px',
|
||||||
borderRadius: '200px',
|
borderRadius: '200px',
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="About">
|
<Layout title="About">
|
||||||
|
|||||||
@@ -1,16 +1,14 @@
|
|||||||
---
|
---
|
||||||
import '@styles/global.css'
|
import '@styles/global.css';
|
||||||
|
|
||||||
import Header from '@components/Header.astro'
|
import Header from '@components/Header.astro';
|
||||||
import Footer from '@components/Footer.astro'
|
import Footer from '@components/Footer.astro';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
title: string
|
title: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const title = Astro.props.frontmatter
|
const title = Astro.props.title;
|
||||||
? Astro.props.frontmatter.title
|
|
||||||
: Astro.props.title
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
|
|||||||
+1
-1
@@ -11,6 +11,6 @@ I also like writing about stuff, so I put together this site to share whatever's
|
|||||||
|
|
||||||
If your interested in checking out my web dev projects, check out [my portfolio](https://ghall.dev/).
|
If your interested in checking out my web dev projects, check out [my portfolio](https://ghall.dev/).
|
||||||
|
|
||||||
If you want to get in touch, I'm on <a rel="me" href="https://home.social/@ghalldev">Mastodon</a>.
|
If you want to get in touch, I'm on <a rel="me" href="https://mastodon.social/@ghalldev">Mastodon</a>.
|
||||||
|
|
||||||
My portrait was drawn by [Natalia Vazquez](https://www.nataliavazquezgarcia.com).
|
My portrait was drawn by [Natalia Vazquez](https://www.nataliavazquezgarcia.com).
|
||||||
|
|||||||
@@ -1,33 +1,37 @@
|
|||||||
---
|
---
|
||||||
import { getCollection } from 'astro:content'
|
import { getCollection } from 'astro:content';
|
||||||
|
|
||||||
import Layout from '@layouts/Layout.astro'
|
import Layout from '@layouts/Layout.astro';
|
||||||
import FormattedDate from '@components/FormattedDate.astro'
|
import FormattedDate from '@components/FormattedDate.astro';
|
||||||
|
|
||||||
const { tag } = Astro.params
|
const { tag } = Astro.params;
|
||||||
|
|
||||||
const page = Number.parseInt(Astro.url.searchParams.get('page'))
|
const page = Number.parseInt(Astro.url.searchParams.get('page'));
|
||||||
const prevPage = page - 1
|
const prevPage = page - 1;
|
||||||
const nextPage = page + 1
|
const nextPage = page + 1;
|
||||||
|
|
||||||
const posts = await getCollection('blog', ({ data }) => {
|
const posts = await getCollection('blog', ({ data }) => {
|
||||||
if (tag === 'all') {
|
if (tag === 'all') {
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
return data.tags.includes(tag)
|
return data.tags.includes(tag);
|
||||||
})
|
});
|
||||||
|
|
||||||
if (posts.length === 0) {
|
if (posts.length === 0) {
|
||||||
return Astro.redirect('/404')
|
return Astro.redirect('/404');
|
||||||
}
|
}
|
||||||
|
|
||||||
posts.sort((a, b) => Date.parse(b.data.pubDate) - Date.parse(a.data.pubDate))
|
posts.sort(
|
||||||
const totalPosts = posts.length
|
(a, b) =>
|
||||||
|
Date.parse(String(b.data.pubDate)) - Date.parse(String(a.data.pubDate))
|
||||||
|
);
|
||||||
|
|
||||||
const start = (page - 1) * 10
|
const totalPosts = posts.length;
|
||||||
const end = page * 10
|
|
||||||
|
|
||||||
const displayPosts = posts.slice(start, end)
|
const start = (page - 1) * 10;
|
||||||
|
const end = page * 10;
|
||||||
|
|
||||||
|
const displayPosts = posts.slice(start, end);
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Blog Archive">
|
<Layout title="Blog Archive">
|
||||||
@@ -41,22 +45,10 @@ const displayPosts = posts.slice(start, end)
|
|||||||
}
|
}
|
||||||
<div class="navigation">
|
<div class="navigation">
|
||||||
<div>
|
<div>
|
||||||
{
|
{page === 1 ? null : <a href={`?page=${prevPage}`}>← Previous</a>}
|
||||||
page === 1 ? null : (
|
|
||||||
<a class="link-button blue-btn" href={`?page=${prevPage}`}>
|
|
||||||
← Previous
|
|
||||||
</a>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{
|
{end >= totalPosts ? null : <a href={`?page=${nextPage}`}>Next →</a>}
|
||||||
end >= totalPosts ? null : (
|
|
||||||
<a class="link-button blue-btn" href={`?page=${nextPage}`}>
|
|
||||||
Next →
|
|
||||||
</a>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|||||||
+11
-9
@@ -1,26 +1,28 @@
|
|||||||
---
|
---
|
||||||
export const prerender = true
|
export const prerender = true;
|
||||||
import { getCollection } from 'astro:content'
|
import { getCollection } from 'astro:content';
|
||||||
|
|
||||||
import Layout from '@layouts/Layout.astro'
|
import Layout from '@layouts/Layout.astro';
|
||||||
import PostPreview from '@components/PostPreview.astro'
|
import PostPreview from '@components/PostPreview.astro';
|
||||||
|
|
||||||
const posts = await getCollection('blog')
|
const posts = await getCollection('blog');
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Home">
|
<Layout title="Home">
|
||||||
{
|
{
|
||||||
posts
|
posts
|
||||||
.sort((a, b) => Date.parse(b.data.pubDate) - Date.parse(a.data.pubDate))
|
.sort(
|
||||||
|
(a, b) =>
|
||||||
|
new Date(b.data.pubDate).valueOf() -
|
||||||
|
new Date(a.data.pubDate).valueOf()
|
||||||
|
)
|
||||||
.slice(0, 5)
|
.slice(0, 5)
|
||||||
.map((post) => <PostPreview post={post} />)
|
.map((post) => <PostPreview post={post} />)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
posts.length < 5 ? null : (
|
posts.length < 5 ? null : (
|
||||||
<div class="more-posts">
|
<div class="more-posts">
|
||||||
<a class="link-button blue-btn" href="/archive/all?page=1">
|
<a href="/archive/all?page=1">All Posts</a>
|
||||||
All Posts
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
---
|
---
|
||||||
export const prerender = true
|
export const prerender = true;
|
||||||
import { getCollection } from 'astro:content'
|
import { getCollection } from 'astro:content';
|
||||||
|
|
||||||
import Layout from '@layouts/Layout.astro'
|
import Layout from '@layouts/Layout.astro';
|
||||||
import BlogHeader from '@components/BlogHeader.astro'
|
import BlogHeader from '@components/BlogHeader.astro';
|
||||||
import Tags from '@components/Tags.astro'
|
import Tags from '@components/Tags.astro';
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
const posts = await getCollection('blog')
|
const posts = await getCollection('blog');
|
||||||
return posts.map((post) => ({
|
return posts.map((post) => ({
|
||||||
params: { slug: post.slug },
|
params: { slug: post.slug },
|
||||||
props: { post },
|
props: { post },
|
||||||
}))
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
const { post } = Astro.props
|
const { post } = Astro.props;
|
||||||
|
|
||||||
const { data } = post
|
const { data } = post;
|
||||||
|
|
||||||
const { Content } = await post.render()
|
const { Content } = await post.render();
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title={data.title}>
|
<Layout title={data.title}>
|
||||||
@@ -39,11 +39,10 @@ const { Content } = await post.render()
|
|||||||
.no-shadow {
|
.no-shadow {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
.footnotes li {
|
.footnotes {
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
}
|
}
|
||||||
.footnotes p {
|
.footnotes p {
|
||||||
font-size: 0.8rem;
|
|
||||||
display: inline;
|
display: inline;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import rss from '@astrojs/rss'
|
import rss from '@astrojs/rss';
|
||||||
import { getCollection } from 'astro:content'
|
import { getCollection } from 'astro:content';
|
||||||
import sanitizeHtml from 'sanitize-html'
|
import sanitizeHtml from 'sanitize-html';
|
||||||
import MarkdownIt from 'markdown-it'
|
import MarkdownIt from 'markdown-it';
|
||||||
const parser = new MarkdownIt({ html: true })
|
const parser = new MarkdownIt({ html: true });
|
||||||
|
|
||||||
export async function get(context) {
|
export async function get(context) {
|
||||||
const blog = await getCollection('blog')
|
const blog = await getCollection('blog');
|
||||||
return rss({
|
return rss({
|
||||||
title: 'ghall.blog',
|
title: 'ghall.blog',
|
||||||
description:
|
description:
|
||||||
@@ -19,5 +19,5 @@ export async function get(context) {
|
|||||||
link: `/posts/${post.slug}/`,
|
link: `/posts/${post.slug}/`,
|
||||||
content: sanitizeHtml(parser.render(post.body)),
|
content: sanitizeHtml(parser.render(post.body)),
|
||||||
})),
|
})),
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+27
-11
@@ -1,15 +1,13 @@
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: Manrope;
|
font-family: CrimsonText;
|
||||||
src: url(./fonts/Manrope-Regular.ttf) format('truetype');
|
src: url(./fonts/CrimsonText-Regular.ttf) format('truetype');
|
||||||
font-weight: normal;
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-display: block;
|
font-display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: Manrope;
|
font-family: JetBrainsMono;
|
||||||
src: url(./fonts/Manrope-Bold.ttf) format('truetype');
|
src: url(./fonts/JetBrainsMono-VariableFont_wght.ttf) format('truetype');
|
||||||
font-weight: bold;
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-display: block;
|
font-display: block;
|
||||||
}
|
}
|
||||||
@@ -22,7 +20,7 @@
|
|||||||
--background: white;
|
--background: white;
|
||||||
--radius: 5px;
|
--radius: 5px;
|
||||||
--shadow: rgba(149, 157, 165, 0.2) 0px 8px 24px;
|
--shadow: rgba(149, 157, 165, 0.2) 0px 8px 24px;
|
||||||
--border: 1px solid rgb(239, 239, 239);
|
--border: 1px solid #7f7f7f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
@@ -37,7 +35,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
font-family: 'Manrope', sans-serif;
|
/* font-family: 'CrimsonText', serif; */
|
||||||
|
font-family: 'CrimsonText', serif;
|
||||||
|
font-size: 1.2rem;
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
letter-spacing: 0.03rem;
|
letter-spacing: 0.03rem;
|
||||||
}
|
}
|
||||||
@@ -68,7 +68,7 @@ h4 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
font-size: 1.05rem;
|
line-height: 1.8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
blockquote {
|
blockquote {
|
||||||
@@ -83,6 +83,21 @@ hr {
|
|||||||
margin: 2rem 0;
|
margin: 2rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kbd {
|
||||||
|
padding: 2px 8px;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
font-family: sans-serif;
|
||||||
|
border: var(--border);
|
||||||
|
border-radius: var(--radius);
|
||||||
|
background: var(--flat-bg);
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.02) 0px 1px 3px 0px,
|
||||||
|
rgba(27, 31, 35, 0.15) 0px 0px 0px 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
sup > a {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
/* Links */
|
/* Links */
|
||||||
|
|
||||||
a {
|
a {
|
||||||
@@ -99,7 +114,8 @@ a:hover {
|
|||||||
pre code,
|
pre code,
|
||||||
code {
|
code {
|
||||||
color: var(--orange);
|
color: var(--orange);
|
||||||
font-family: monospace;
|
font-family: 'JetBrainsMono', monospace;
|
||||||
|
font-size: 1rem;
|
||||||
padding: 2px 4px;
|
padding: 2px 4px;
|
||||||
border-radius: var(--radius);
|
border-radius: var(--radius);
|
||||||
background: rgba(155, 155, 155, 0.2);
|
background: rgba(155, 155, 155, 0.2);
|
||||||
@@ -243,7 +259,7 @@ dialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.post-preview {
|
.post-preview {
|
||||||
padding: 0.1rem 1rem 2rem;
|
padding: 0.1rem 0rem 2rem;
|
||||||
margin: 0 0 1.5rem 0;
|
margin: 0 0 1.5rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user