Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add author, image, and read time estimate to blog #481

Merged
merged 20 commits into from
Jun 4, 2022
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/lib/blog/util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* Takes a string (either html or plaintext) and calculates the time
* (in minutes) to read a blog post, By default it uses 225 the default adult
* average reading time based on a quick google search, but may be overrided
* with the wpm parameter
jaasonw marked this conversation as resolved.
Show resolved Hide resolved
* @param string The string containing the blog text
* @param wpm (Optional) defines words per minute to assume the reader reads at
* @returns The estimated read time of an article in minutes
*/
jaasonw marked this conversation as resolved.
Show resolved Hide resolved
export function readingTime(string: string, wpm = 225) {
jaasonw marked this conversation as resolved.
Show resolved Hide resolved
const text = string.replace(/<\/?[^>]+(>|$)/, '').trim();
return Math.ceil(text.split(/\s+/).length / wpm);
}
19 changes: 18 additions & 1 deletion src/routes/blog/[id].svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
<script lang="ts">
import type { Newsletter } from './_query';
import Spacing from '$lib/components/sections/spacing.svelte';
import { readingTime } from '$lib/blog/util';
import { Temporal } from '@js-temporal/polyfill';

export let post: Newsletter;
</script>
Expand All @@ -30,7 +32,8 @@
<h1 class="headers size-lg">{post.title}</h1>

<Spacing --min="16px" --med="16px" --max="16px" />

<img src={post.author.picture} alt="" />
<Spacing --min="16px" --med="16px" --max="16px" />
<p>
by
<a
Expand All @@ -41,6 +44,15 @@
@{post.author.displayname}
</a>
</p>
<p>
{Temporal.Instant.from(post.createdAt).toLocaleString('en-US', {
calendar: 'gregory',
year: 'numeric',
month: 'long',
day: 'numeric',
})} •
{readingTime(post.html)} min read
</p>

<Spacing --min="75px" --med="100px" --max="150px" />

Expand Down Expand Up @@ -98,4 +110,9 @@
}
}
}
img {
height: 100%;
width: 5em;
border-radius: 50%;
}
</style>
2 changes: 1 addition & 1 deletion src/routes/blog/_index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ test('can render', () => {

test('can find the correct page title', () => {
const { getByText } = render(Blog);
expect(getByText('The official acmCSUF blog.')).toBeDefined();
expect(getByText('The official ACM at CSUF blog.')).toBeDefined();
});

test('can render 3 blog posts', () => {
Expand Down
4 changes: 2 additions & 2 deletions src/routes/blog/_query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ export interface Newsletter {
discussionUrl: string;
title: string;
html: string;
createdAt: number | null;
lastEdited: number | null;
createdAt: string | null;
lastEdited: string | null;
labels: string[];
author: {
displayname: string;
Expand Down
107 changes: 96 additions & 11 deletions src/routes/blog/index.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,38 @@
<script lang="ts">
import type { Newsletter } from './_query';
import Spacing from '$lib/components/sections/spacing.svelte';
import { Temporal } from '@js-temporal/polyfill';
import { readingTime } from '$lib/blog/util';
jaasonw marked this conversation as resolved.
Show resolved Hide resolved

export let posts: Newsletter[] = [];
</script>

<svelte:head>
<title>acmCSUF / README</title>
<title>README / ACM at CSUF</title>
</svelte:head>

<Spacing --min="175px" --med="200px" --max="200px" />

<section>
<img src="assets/readme-logomark.svg" alt="README by acmCSUF" />
<section class="main-header">
<img src="/assets/readme-logomark.svg" alt="README by acmCSUF" />

<div>
<h1 class="size-xxl">README</h1>
<h2 class="size-md">by ACM at <b class="acm-blue">CSUF</b></h2>
</div>
</section>

<h2 class="subtitle headers">
The official acmCSUF blog.<a href="/blog.xml"
<section>
<h2 class="subtitle headers size-md">
The official ACM at CSUF blog.<a href="/blog.xml"
><img src="assets/badges/feed-icon.svg" alt="RSS feed logo" /></a
>
</h2>
</section>

<Spacing --min="100px" --med="175px" --max="200px" />
<Spacing --min="175px" --med="200px" --max="200px" />

<section>
<ul>
{#each posts as post (post.id)}
<li class="blog-post">
Expand All @@ -39,6 +50,23 @@
<div class="markdown-body">
{@html post.html}
</div>
<div id="author">
<a href={post.author.url}>
<img src={post.author.picture} alt="" />
</a>
<div id="author-info">
<a href={post.author.url}>{post.author.displayname}</a>
<p>
{Temporal.Instant.from(post.createdAt).toLocaleString('en-US', {
calendar: 'gregory',
year: 'numeric',
month: 'long',
day: 'numeric',
})} •
{readingTime(post.html)} min read
</p>
</div>
</div>
<small class="ita">{post.labels.join(', ')}</small>
</a>
</li>
Expand All @@ -52,7 +80,8 @@
.subtitle {
a {
display: inline-block;
padding-left: 2.5vw;
padding-left: 0em;
margin-top: 3vw;
vertical-align: baseline;

img {
Expand All @@ -64,7 +93,7 @@

section {
display: flex;
flex-direction: column;
flex-direction: row;
align-items: center;
justify-content: center;
margin: 0 24px;
Expand All @@ -73,12 +102,26 @@
transition: 0.25s ease-in-out;
}

div {
h1 {
font-weight: 550;
height: 95px;
line-height: 100px;
}

h2 {
font-weight: 600;
margin-left: 5px;
}
}

img {
max-width: 600px;
max-width: 200px;
width: 100%;
height: auto;
margin-left: -2.2vw;

margin-bottom: 8px;
margin-right: 2vw;
}

ul {
Expand All @@ -100,7 +143,8 @@
a {
text-decoration: none;
padding: 2em;
display: block;
display: flex;
flex-direction: column;

.markdown-body {
max-height: 100px;
Expand All @@ -114,6 +158,47 @@
}
}
}
#author {
display: flex;
gap: 1em;
margin-bottom: 1em;
align-items: center;
img {
border-radius: 50%;
width: 2.5em;
height: 100%;
margin: 0;
}
div {
display: flex;
flex-direction: column;
}
p {
font-size: 0.8em;
}
a {
padding: 0;
font-weight: 600;
}
a:hover {
text-decoration: underline;
}
}
}

@media (max-width: 600px) {
.main-header {
flex-direction: column;

div h2 {
text-align: center;
}
}

.subtitle {
text-align: center;
padding-top: 1em;
}
}

@media (max-width: 900px) {
Expand Down
29 changes: 6 additions & 23 deletions static/assets/readme-logomark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions static/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

--perma-light: #f8f8f8;

/* Generator: https://xgkft.csb.app/ (280px-1000px viewport-width, 1rem=16px) */
jaasonw marked this conversation as resolved.
Show resolved Hide resolved
--size-xxl: clamp(2.8125rem, 1.8403rem + 5.5556vw, 5.3125rem);
--size-xl: clamp(2rem, 1.7545rem + 1.0909vw, 3.5rem);
--size-lg: clamp(1.5rem, 1.3773rem + 0.5455vw, 2.25rem);
--size-md: clamp(1.125rem, 1.0636rem + 0.2727vw, 1.5rem);
Expand Down Expand Up @@ -98,6 +100,10 @@ body {
color: var(--acm-sky);
}

.size-xxl {
font-size: var(--size-xxl);
}

.size-xl {
font-size: var(--size-xl);
}
Expand Down