Skip to content

Commit c0292ac

Browse files
committed
add subpages
1 parent b5ea650 commit c0292ac

File tree

7 files changed

+169
-45
lines changed

7 files changed

+169
-45
lines changed

.github/workflows/main.yml

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,10 @@ jobs:
6060
if: steps.changes.outputs.cppcon23 == 'true'
6161
- name: Prepare final artifact
6262
run: |
63-
mkdir -p ./dist
64-
mv ./slides/cppcon23/dist ./dist/cppcon23
65-
mkdir -p ./dist/cppcon23/images
66-
mv ./slides/cppcon23/images/cppcon-title-page.png ./dist/cppcon23/images
63+
mkdir -p ./dist/slides
64+
mv ./slides/cppcon23/dist ./dist/slides/cppcon23
65+
mkdir -p ./dist/slides/cppcon23/images
66+
mv ./slides/cppcon23/images/cppcon-title-page.png ./dist/slides/cppcon23/images
6767
tar -zcf cppcon23.tar.gz ./dist
6868
if: steps.changes.outputs.cppcon23 == 'true'
6969
- name: push api to aws
@@ -116,10 +116,10 @@ jobs:
116116
if: steps.changes.outputs.cppcon21 == 'true'
117117
- name: Prepare final artifact
118118
run: |
119-
mkdir -p ./dist
120-
mv ./slides/cppcon21/dist ./dist/cppcon21
121-
mkdir -p ./dist/cppcon21/images
122-
mv ./slides/cppcon21/images/cppcon-title-page.png ./dist/cppcon21/images
119+
mkdir -p ./dist/slides
120+
mv ./slides/cppcon21/dist ./dist/slides/cppcon21
121+
mkdir -p ./dist/slides/cppcon21/images
122+
mv ./slides/cppcon21/images/cppcon-title-page.png ./dist/slides/cppcon21/images
123123
tar -zcf cppcon21.tar.gz ./dist
124124
if: steps.changes.outputs.cppcon21 == 'true'
125125
- name: push api to aws
@@ -153,10 +153,10 @@ jobs:
153153
role-to-assume: ${{ secrets.AWS_ROLE }}
154154
- name: Prepare final artifact
155155
run: |
156-
mkdir -p ./dist/bazelcon23/images
157-
mv ./slides/bazelcon23/redirect.html ./dist/bazelcon23/index.html
158-
mv ./slides/bazelcon23/slides-bazelcon23-pejman.pdf ./dist/bazelcon23/
159-
mv ./slides/bazelcon23/images/bazelcon-cover.png ./dist/bazelcon23/images/
156+
mkdir -p ./dist/slides/bazelcon23/images
157+
mv ./slides/bazelcon23/redirect.html ./dist/slides/bazelcon23/index.html
158+
mv ./slides/bazelcon23/slides-bazelcon23-pejman.pdf ./dist/slides/bazelcon23/
159+
mv ./slides/bazelcon23/images/bazelcon-cover.png ./dist/slides/bazelcon23/images/
160160
tar -zcf bazelcon23.tar.gz ./dist
161161
if: steps.changes.outputs.bazelcon23 == 'true'
162162
- name: push api to aws

web/app/[slug]/page.tsx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2024 Pejman Ghorbanzade
2+
3+
import DarkModeButton from '@/components/DarkModeButton';
4+
import NavBar from '@/components/NavBar';
5+
import TalkEntry from '@/components/TalkEntry';
6+
import { getTalks } from '@/components/utils';
7+
8+
export async function generateStaticParams() {
9+
return (await getTalks()).map((talk) => ({ slug: talk.slug }));
10+
}
11+
12+
export default async function Home({ params }: { params: { slug: string } }) {
13+
const talk = (await getTalks()).filter((v) => v.slug === params.slug)[0];
14+
return (
15+
<main>
16+
<div className="mx-auto max-w-screen-lg space-y-4 py-4">
17+
<NavBar />
18+
<div className="relative min-h-24 rounded-lg border-slate-300 bg-white p-6 dark:border-slate-700 dark:bg-gradient-to-br dark:from-black dark:to-slate-900 border">
19+
<div className="prose dark:prose-invert">
20+
<div className="text-2xl">Public Talks</div>
21+
<div>Pejman Ghorbanzade</div>
22+
</div>
23+
<div className="absolute right-6 top-10">
24+
<DarkModeButton />
25+
</div>
26+
</div>
27+
<TalkEntry talk={talk} />
28+
</div>
29+
</main>
30+
);
31+
}

web/app/page.tsx

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,9 @@
11
// Copyright 2024 Pejman Ghorbanzade
22

33
import DarkModeButton from '@/components/DarkModeButton';
4-
import Talks from '@/components/Talks';
5-
import type { Talk } from '@/components/types';
64
import NavBar from '@/components/NavBar';
7-
8-
async function getTalks(): Promise<Talk[]> {
9-
const content = await fetch(
10-
'https://raw.githubusercontent.com/ghorbanzade/talks/main/web/talks.json'
11-
);
12-
const raw = JSON.parse(await content.text()) as Talk[];
13-
return raw
14-
.filter((v) => !v.tags.includes('hide'))
15-
.sort((a, b) => {
16-
const aScore = a.tags.includes('highlight');
17-
const bScore = b.tags.includes('highlight');
18-
return aScore !== bScore
19-
? Number(bScore) - Number(aScore)
20-
: +new Date(b.date!) - +new Date(a.date!);
21-
});
22-
}
5+
import Talks from '@/components/Talks';
6+
import { getTalks } from '@/components/utils';
237

248
export default async function Home() {
259
const talks = await getTalks();

web/components/TalkEntry.tsx

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright 2024 Pejman Ghorbanzade
2+
3+
import { Talk } from '@/components/types';
4+
import { format } from 'date-fns';
5+
import Markdown from 'markdown-to-jsx';
6+
7+
export default function TalkEntry({ talk }: { talk: Talk }) {
8+
return (
9+
<div className="min-h-24 prose prose-base prose-slate min-w-full dark:prose-invert py-6 space-y-4">
10+
<div className="flex justify-between rounded-lg border-slate-300 bg-white p-6 dark:border-slate-700 dark:bg-gradient-to-br dark:from-black dark:to-slate-900 border">
11+
<div>
12+
<div>
13+
<span className="font-semibold">{talk.conference}</span>
14+
{talk.location && (
15+
<span className="font-light">, {talk.location}</span>
16+
)}
17+
</div>
18+
<div className="text-xl">{talk.title}</div>
19+
</div>
20+
<div className="flex items-center">
21+
<time dateTime={talk.date}>
22+
{format(new Date(talk.date!), 'LLL yyyy')}
23+
</time>
24+
</div>
25+
</div>
26+
<div className="rounded-lg border-slate-300 bg-white p-6 dark:border-slate-700 dark:bg-gradient-to-br dark:from-black dark:to-slate-900 border">
27+
<Links links={talk.links} />
28+
</div>
29+
{talk.links.youtube && (
30+
<div className="rounded-lg border-slate-300 bg-white p-6 dark:border-slate-700 dark:bg-gradient-to-br dark:from-black dark:to-slate-900 border">
31+
<YouTube link={talk.links.youtube} />
32+
</div>
33+
)}
34+
{talk.abstract && !talk.tags.includes('hide-abstract') && (
35+
<div className="rounded-lg border-slate-300 bg-white p-6 dark:border-slate-700 dark:bg-gradient-to-br dark:from-black dark:to-slate-900 border">
36+
<div className="text-xl">Abstract</div>
37+
<Markdown className="wsl-mark prose prose-base prose-slate min-w-full dark:prose-invert">
38+
{talk.abstract}
39+
</Markdown>
40+
</div>
41+
)}
42+
</div>
43+
);
44+
}
45+
46+
function YouTube({ link }: { link: string }) {
47+
return (
48+
<iframe
49+
width="100%"
50+
height="auto"
51+
style={{ aspectRatio: 16 / 9 }}
52+
src={`https://youtube.com/embed/${link.slice('https://youtu.be/'.length)}`}
53+
title="YouTube video player"
54+
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
55+
allowFullScreen
56+
/>
57+
);
58+
}
59+
60+
function Links({ links }: { links: Talk['links'] }) {
61+
return (
62+
<div className="flex space-x-6">
63+
{links.registration && (
64+
<a href={links.registration} target="_blank">
65+
Registration
66+
</a>
67+
)}
68+
{(links.pdf || links.html) && (
69+
<div>
70+
<span>Slides (</span>
71+
{links.html && (
72+
<a href={links.html} target="_blank">
73+
HTML
74+
</a>
75+
)}
76+
{links.html && links.pdf && <span>, </span>}
77+
{links.pdf && (
78+
<a href={links.pdf} target="_blank">
79+
PDF
80+
</a>
81+
)}
82+
<span>)</span>
83+
</div>
84+
)}
85+
{links.repository && (
86+
<a href={links.repository} target="_blank">
87+
Repository
88+
</a>
89+
)}
90+
</div>
91+
);
92+
}

web/components/Talks.tsx

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
// Copyright 2024 Pejman Ghorbanzade
22
'use client';
33

4+
import Link from 'next/link';
45
import { useState } from 'react';
56
import { format } from 'date-fns';
67
import Markdown from 'markdown-to-jsx';
7-
import type { Talk, View } from '@/components/types';
88
import ViewToggleButton from '@/components/ViewToggleButton';
9+
import type { Talk, View } from '@/components/types';
910

1011
export default function Talks({ talks }: { talks: Talk[] }) {
1112
const [view, setView] = useState<View>('list');
@@ -42,14 +43,12 @@ function ListEntry({ talk }: { talk: Talk }) {
4243
<div className="min-h-24 prose prose-base prose-slate min-w-full dark:prose-invert py-6">
4344
<div className="flex justify-between">
4445
<div>
45-
<div className="flex items-center space-x-2">
46-
<div>
47-
<span className="font-semibold">{talk.conference}</span>
48-
{talk.location && (
49-
<span className="font-light">, {talk.location}</span>
50-
)}
51-
</div>
52-
</div>
46+
<Link className="cursor-pointer" href={`/${talk.slug}`}>
47+
<span className="font-semibold">{talk.conference}</span>
48+
{talk.location && (
49+
<span className="font-light">, {talk.location}</span>
50+
)}
51+
</Link>
5352
<div className="text-xl">{talk.title}</div>
5453
<div className="flex space-x-6">
5554
{talk.abstract && !talk.tags.includes('hide-abstract') && (

web/components/utils.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2024 Pejman Ghorbanzade
2+
3+
import { Talk } from '@/components/types';
4+
5+
export async function getTalks(): Promise<Talk[]> {
6+
const content: Talk[] = await fetch(
7+
'https://raw.githubusercontent.com/ghorbanzade/talks/main/web/talks.json'
8+
).then((res) => res.json());
9+
return content
10+
.filter((v) => !v.tags.includes('hide'))
11+
.sort((a, b) => {
12+
const sa = a.tags.includes('highlight');
13+
const sb = b.tags.includes('highlight');
14+
return sa !== sb
15+
? Number(sb) - Number(sa)
16+
: +new Date(b.date!) - +new Date(a.date!);
17+
});
18+
}

web/talks.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"abstract": "Web application developers have high standards in developer experience including fast build and test times, short feedback cycles, and easy dependency management. Using Bazel to deliver an intuitive web development workflow that meets these expectations involves solving numerous challenges.\n\nThis talk shares our experience using Bazel’s NodeJS toolchain and the various Aspect.build’s rules repositories to accelerate the development and maintenance of our 40+ web applications across Aurora. We will show how we used Bazel's JSON Trace Profiling to find performance improvement opportunities that helped us reduce our application build times by 50% and test execution times by 70%. We will share how we combined Vite and iBazel to enable hot module replacement and achieve fast iteration loops, and used Gazelle and PNPM to simplify the management of NPM dependencies across our Bazel monorepo.",
1111
"links": {
1212
"registration": "https://rsvp.withgoogle.com/events/bazelcon2023",
13-
"pdf": "https://pejman.dev/talks/bazelcon23/slides-bazelcon23-pejman.pdf",
13+
"pdf": "https://pejman.dev/talks/slides/bazelcon23/slides-bazelcon23-pejman.pdf",
1414
"youtube": "https://youtu.be/Xs3E5SvSYg4",
1515
"cover": "https://raw.githubusercontent.com/ghorbanzade/talks/main/slides/bazelcon23/images/bazelcon-cover.png",
1616
"repository": "https://github.com/ghorbanzade/talks/tree/main/slides/bazelcon23"
@@ -27,8 +27,8 @@
2727
"abstract": "Making code changes to real-world software systems runs the risk of introducing unintended side-effects that are costly to find and fix. To mitigate this risk, engineering teams significantly invest in adopting various software testing practices. Despite best efforts, effectively and reliably identifying software regressions remains a challenge and results in long feedback cycles that hurt developer productivity. This problem is more pronounced in C++ software systems, given that their application domains often impose tight requirements on system safety and performance.\n\nThis talk shows you how continuous regression testing can help you find regressions in behavior or performance of your software during the development stage. It is a practical walk-through of how to build a regression testing framework in C++, how to use it to write effective regression tests, and how to integrate it with your CI pipeline to automate the execution of your tests as part of the CI or on a dedicated test server. It also includes recommendations on how to avoid common design pitfalls that lead to tests that are either flaky or untrustworthy or difficult to run at scale.\n\nThis talk also introduces a free and open-source software for continuous regression testing C++ applications. We will use a series of hands-on demos to showcase the end-to-end workflow of finding regressions in common C++ development scenarios including refactoring functions, upgrading dependencies, and updating the build toolchain. We also show a few less common use-cases such as profiling the size of binaries and tracking the exported symbols of a shared library, to inspire you to think how regression testing could unlock faster and safer refactoring for you and your team.",
2828
"links": {
2929
"registration": "https://cppcon2023.sched.com/event/1Qtgx/continuous-regression-testing-for-safer-and-faster-refactoring",
30-
"html": "https://pejman.dev/talks/cppcon23/",
31-
"pdf": "https://pejman.dev/talks/cppcon23/slides-cppcon23-pejman.pdf",
30+
"html": "https://pejman.dev/talks/slides/cppcon23/",
31+
"pdf": "https://pejman.dev/talks/slides/cppcon23/slides-cppcon23-pejman.pdf",
3232
"youtube": "https://youtu.be/c8Z3iSL9vYs",
3333
"cover": "https://raw.githubusercontent.com/ghorbanzade/talks/main/slides/cppcon23/images/cppcon-cover.png",
3434
"repository": "https://github.com/ghorbanzade/talks/tree/main/slides/cppcon23"
@@ -89,7 +89,7 @@
8989
"abstract": "Making code changes to real-world software systems runs the risk of introducing unintended side-effects that are costly to find and fix. There are methods and tools to help us mitigate the inherent risks. One of these methods is regression testing which helps us compare the behavior of a given version of our software against a previous version, using a large number of test cases. This talk outlines the benefits and challenges of continuous regression testing in the development of real-world software, reviews some of the well-known regression testing tools available in the Java ecosystem, and introduces a new tool with a novel approach to regression testing, to show the impact of continuous software testing on improving developer productivity and software development efficiency.",
9090
"links": {
9191
"registration": "https://www.meetup.com/DenverJavaUsersGroup/events/cpmtcqydcgbrb/",
92-
"youtube": "https://www.youtube.com/watch?v=6LtgbTdUJEQ",
92+
"youtube": "https://youtu.be/6LtgbTdUJEQ",
9393
"html": "https://touca.io/talks/djug22",
9494
"pdf": "https://touca.io/talks/djug22/slides-djug22-pejman.pdf"
9595
}
@@ -152,8 +152,8 @@
152152
"abstract": "As software engineers, we all prefer using performant libraries with user-friendly interfaces. But designing a template-free interface can be challenging for some C++ libraries, like serialization libraries, that need to support generic values but handle them differently based on their type.\n\nThis talk shows how we can leverage partial template specialization to implement a generic user-friendly API that can be extended to support custom user-defined types. As a proof of concept, I will showcase an extensible type serialization system, that is built on top of the FlatBuffers serialization library, and enables users to register custom serializers for their user-defined types to support their automatic serialization at runtime.\n\nTemplate programming is generally known to be associated with long type names and indecipherable compile-time errors. This presentation includes examples and recommendations that help C++ engineers to create more expressive and easy-to-understand implementations. Finally, the talk describes how C++20 features like Concepts can further simplify those implementations and facilitate designing elegant user-friendly programming interfaces.",
153153
"links": {
154154
"registration": "https://cppcon2021.sched.com/event/nvDM/building-an-extensible-type-serialization-system-using-partial-template-specialization",
155-
"html": "https://pejman.dev/talks/cppcon21/",
156-
"pdf": "https://pejman.dev/talks/cppcon21/slides-cppcon23-pejman.pdf",
155+
"html": "https://pejman.dev/talks/slides/cppcon21/",
156+
"pdf": "https://pejman.dev/talks/slides/cppcon21/slides-cppcon23-pejman.pdf",
157157
"youtube": "https://youtu.be/2dvZR2zemrM",
158158
"repository": "https://github.com/ghorbanzade/cppcon21"
159159
}

0 commit comments

Comments
 (0)