Skip to content

Commit 1a3c9e1

Browse files
committed
Add fancy decks listing
1 parent b4ab6ae commit 1a3c9e1

File tree

9 files changed

+422
-15
lines changed

9 files changed

+422
-15
lines changed

Diff for: .github/workflows/build-and-deploy.yml

+11-15
Original file line numberDiff line numberDiff line change
@@ -34,22 +34,18 @@ jobs:
3434
fi
3535
done
3636
37-
- name: Generate Index File
37+
- uses: actions/setup-python@v5
38+
with:
39+
python-version: "3.13"
40+
cache: "pip"
41+
- run: pip install -r scripts/requirements.txt
42+
43+
44+
- name: Generate listing
3845
run: |
39-
echo '<!DOCTYPE html>' > build/index.html
40-
echo '<html lang="en">' >> build/index.html
41-
echo '<head><meta charset="UTF-8"><title>Codestar Slide Decks</title></head>' >> build/index.html
42-
echo '<body>' >> build/index.html
43-
echo '<h1>Codestar Slide Decks</h1>' >> build/index.html
44-
echo '<ul>' >> build/index.html
45-
for dir in $(ls build); do
46-
if [ -d "build/$dir" -a -f "build/$dir/index.html" ]; then
47-
echo "<li><a href='./$dir/'>$dir</a></li>" >> build/index.html
48-
fi
49-
done
50-
echo '</ul>' >> build/index.html
51-
echo '</body>' >> build/index.html
52-
echo '</html>' >> build/index.html
46+
python scripts/decks_list.py
47+
cp listing/* build/
48+
mv decks.json build/
5349
5450
- name: Upload artifacts
5551
id: deployment

Diff for: example.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---
22
marp: true
33
title: New Codestar Marp theme
4+
author: Hamza Haiken
45
theme: codestar
56
# class: invert
67
paginate: true

Diff for: listing/bg.jpg

496 KB
Loading

Diff for: listing/decks.json

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
[
2+
{
3+
"title": "Embracing Functional Paradigms Wow This Title Is Very Long I Wonder What Happens Now",
4+
"author": "Alice Anna McLongname",
5+
"date": "2024-08-15",
6+
"path": "example",
7+
"total_slides": 25
8+
},
9+
{
10+
"title": "From Zero to Svelte: Building Interactive Web Apps the Modern Way",
11+
"author": "Bob Carter",
12+
"date": "2024-03-08",
13+
"path": "example",
14+
"total_slides": 20
15+
},
16+
{
17+
"title": "Kotlin's Sweet Spot: A Practical Guide to Multi-Platform Development",
18+
"author": "Chris Taylor",
19+
"date": "2024-02-12",
20+
"path": "example",
21+
"total_slides": 30
22+
},
23+
{
24+
"title": "Functional Programming in the Frontend: Lessons from Svelte and Beyond",
25+
"author": "Dana Lee",
26+
"date": "2024-05-10",
27+
"path": "example",
28+
"total_slides": 22
29+
},
30+
{
31+
"title": "Scala’s Cats Library: Mastering Monads, Functors, and More",
32+
"author": "Eve Johnson",
33+
"date": "2024-06-07",
34+
"path": "example",
35+
"total_slides": 35
36+
},
37+
{
38+
"title": "Reactive Web UIs with Svelte: A Deep Dive",
39+
"author": "Frank Moore",
40+
"date": "2024-01-15",
41+
"path": "example",
42+
"total_slides": 18
43+
},
44+
{
45+
"title": "Functional Design Patterns in Scala and Kotlin",
46+
"author": "Grace Kim",
47+
"date": "2024-08-19",
48+
"path": "example",
49+
"total_slides": 28
50+
},
51+
{
52+
"title": "Scalable State Management in Svelte Applications",
53+
"author": "Harry White",
54+
"date": "2024-10-23",
55+
"path": "example",
56+
"total_slides": 26
57+
},
58+
{
59+
"title": "Concurrency Simplified: Functional Techniques in Scala",
60+
"author": "Ivy Martinez",
61+
"date": "2024-10-20",
62+
"path": "example",
63+
"total_slides": 32
64+
},
65+
{
66+
"title": "Crafting Maintainable Codebases with Kotlin and Scala",
67+
"author": "Jack Miller",
68+
"date": "2024-03-15",
69+
"path": "example",
70+
"total_slides": 29
71+
}
72+
]

Diff for: listing/index.html

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<link rel="preconnect" href="https://fonts.googleapis.com">
6+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
7+
<link rel="stylesheet" href="listing.css">
8+
9+
<script src="//cdnjs.cloudflare.com/ajax/libs/list.js/2.3.1/list.min.js"></script>
10+
<script src="listing.js"></script>
11+
</head>
12+
<body>
13+
<div class="container">
14+
<h1><span>C</span><span class="star">*</span><span>destar Slide Decks</span></h1>
15+
<div class="decks" id="decks">
16+
<div class="inputs">
17+
<input class="search" placeholder="Search..." />
18+
<button class="sort" title="Sort by title" data-sort="title"></button>
19+
<button class="sort" title="Sort by author" data-sort="author"></button>
20+
<button class="sort" title="Sort by date" data-sort="date"></button>
21+
<button class="sort" title="Sort by number of slides" data-sort="total_slides"></button>
22+
</div>
23+
<ul class="list"></ul>
24+
</div>
25+
<div class="attribution">Background by <a href="www.freepik.com">Freepik</a></div>
26+
</div>
27+
</body>
28+
</html>

Diff for: listing/listing.css

+206
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
@import url("https://fonts.googleapis.com/css2?family=Righteous&display=swap");
2+
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@800&display=swap');
3+
4+
@font-face {
5+
font-family: "Conduit";
6+
src: url("https://raw.githubusercontent.com/code-star/codestar-marp/master/theme/fonts/ConduitITCStd.woff") format("woff");
7+
}
8+
9+
@font-face {
10+
font-family: "Conduit";
11+
font-weight: bold;
12+
src: url("https://raw.githubusercontent.com/code-star/codestar-marp/master/theme/fonts/ConduitITCStd-Bold.woff") format("woff");
13+
}
14+
15+
:root {
16+
font-family: "Conduit";
17+
--bg: rgba(0, 0, 0, 0.25);
18+
color: white;
19+
}
20+
21+
html, body {
22+
margin: 0;
23+
padding: 0;
24+
}
25+
26+
h1 {
27+
color: white;
28+
font-family: Righteous;
29+
text-transform: lowercase;
30+
font-size: 5em;
31+
display: flex;
32+
margin-top: 0.3em;
33+
margin-bottom: 0.3em;
34+
}
35+
36+
.star {
37+
color: #ddd;
38+
margin-top: 0.06em;
39+
font-size: 1.45em;
40+
font-family: Montserrat;
41+
margin-bottom: -0.5em;
42+
}
43+
44+
button, input, ul, li {
45+
all: unset;
46+
}
47+
48+
.container {
49+
position: relative;
50+
display: flex;
51+
flex-direction: column;
52+
width: 100%;
53+
height: 100vh;
54+
max-height: 100vh;
55+
align-items: center;
56+
background-image: url("bg.jpg");
57+
background-size: cover;
58+
background-position: center;
59+
filter: sepia(0.4) hue-rotate(-6deg) saturate(0.94);
60+
}
61+
62+
.attribution {
63+
color: #444;
64+
position: absolute;
65+
bottom: 0.7em;
66+
right: 1.6em;
67+
transform: rotate(90deg);
68+
transform-origin: bottom right;
69+
}
70+
71+
.attribution a {
72+
text-decoration: none;
73+
color: #777;
74+
}
75+
76+
.decks {
77+
display: flex;
78+
flex-direction: column;
79+
width: 100%;
80+
align-items: center;
81+
flex-grow: 1;
82+
overflow: hidden;
83+
gap: 0.5em;
84+
85+
font-size: 2em;
86+
max-height: 100%;
87+
z-index: 1;
88+
}
89+
90+
.list {
91+
flex-grow: 1;
92+
overflow-y: auto;
93+
width: 100%;
94+
display: flex;
95+
flex-direction: column;
96+
align-items: center;
97+
}
98+
99+
.link {
100+
text-decoration: none;
101+
color: unset;
102+
}
103+
104+
105+
.deck, .inputs {
106+
background: var(--bg);
107+
backdrop-filter: blur(13px);
108+
}
109+
110+
.deck {
111+
margin-bottom: 0.5em;
112+
display: grid;
113+
width: 750px;
114+
grid-template-columns: .5fr .4fr .1fr;
115+
grid-template-rows: .5fr .5fr;
116+
height: 3em;
117+
padding: 0.5em;
118+
border-radius: 0.5em;
119+
transition: transform 0.05s ease-out;
120+
}
121+
122+
.deck:hover {
123+
transform: scale(1.05);
124+
}
125+
126+
.title, .author, .date, .total_slides {
127+
display: flex;
128+
justify-content: center;
129+
align-items: center;
130+
}
131+
132+
133+
.title {
134+
grid-area: 1 / 1 / 3 / 2;
135+
margin-bottom: -0.15em;
136+
overflow: hidden;
137+
text-overflow: ellipsis;
138+
}
139+
140+
.author {
141+
grid-area: 1 / 2 / 2 / 3;
142+
font-size: 0.8em;
143+
font-style: italic;
144+
margin-bottom: -0.15em;
145+
}
146+
147+
.date {
148+
grid-area: 2 / 2 / 3 / 3;
149+
align-items: center;
150+
font-size: 0.6em;
151+
margin-bottom: -0.15em;
152+
font-weight: bold;
153+
}
154+
155+
.total_slides {
156+
grid-area: 1 / 3 / 3 / 4;
157+
font-family: Righteous;
158+
flex-direction: column;
159+
}
160+
161+
.total_slides::after {
162+
content: "slides";
163+
font-size: 50%;
164+
}
165+
166+
.inputs {
167+
display: flex;
168+
width: calc(750px + 0.5em);
169+
align-items: center;
170+
gap: 0.5em;
171+
border-radius: 0.5em;
172+
padding-right: 0.5em;
173+
}
174+
175+
.search {
176+
flex-grow: 1;
177+
padding: 0.6em 0.5em 0.4em 0.5em;
178+
}
179+
180+
.search::placeholder {
181+
color: #bbb;
182+
font-style: italic;
183+
}
184+
185+
button[data-sort="title"] {
186+
background: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJmZWF0aGVyIGZlYXRoZXItYm9va21hcmsiPjxwYXRoIGQ9Ik0xOSAyMWwtNy01LTcgNVY1YTIgMiAwIDAgMSAyLTJoMTBhMiAyIDAgMCAxIDIgMnoiPjwvcGF0aD48L3N2Zz4=");
187+
}
188+
189+
button[data-sort="author"] {
190+
background: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJmZWF0aGVyIGZlYXRoZXItdXNlciI+PHBhdGggZD0iTTIwIDIxdi0yYTQgNCAwIDAgMC00LTRIOGE0IDQgMCAwIDAtNCA0djIiPjwvcGF0aD48Y2lyY2xlIGN4PSIxMiIgY3k9IjciIHI9IjQiPjwvY2lyY2xlPjwvc3ZnPg==");
191+
}
192+
193+
button[data-sort="date"] {
194+
background: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJmZWF0aGVyIGZlYXRoZXItY2FsZW5kYXIiPjxyZWN0IHg9IjMiIHk9IjQiIHdpZHRoPSIxOCIgaGVpZ2h0PSIxOCIgcng9IjIiIHJ5PSIyIj48L3JlY3Q+PGxpbmUgeDE9IjE2IiB5MT0iMiIgeDI9IjE2IiB5Mj0iNiI+PC9saW5lPjxsaW5lIHgxPSI4IiB5MT0iMiIgeDI9IjgiIHkyPSI2Ij48L2xpbmU+PGxpbmUgeDE9IjMiIHkxPSIxMCIgeDI9IjIxIiB5Mj0iMTAiPjwvbGluZT48L3N2Zz4=");
195+
}
196+
197+
button[data-sort="total_slides"] {
198+
background: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJmZWF0aGVyIGZlYXRoZXItbGF5ZXJzIj48cG9seWdvbiBwb2ludHM9IjEyIDIgMiA3IDEyIDEyIDIyIDcgMTIgMiI+PC9wb2x5Z29uPjxwb2x5bGluZSBwb2ludHM9IjIgMTcgMTIgMjIgMjIgMTciPjwvcG9seWxpbmU+PHBvbHlsaW5lIHBvaW50cz0iMiAxMiAxMiAxNyAyMiAxMiI+PC9wb2x5bGluZT48L3N2Zz4=");
199+
}
200+
201+
button[data-sort] {
202+
width: 24px;
203+
height: 24px;
204+
cursor: pointer;
205+
filter: invert(1);
206+
}

Diff for: listing/listing.js

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
function truncate(s, n) {
2+
if (s.length <= n) return s
3+
4+
const truncated = s.slice(0, n - 3);
5+
const lastSpace = truncated.lastIndexOf(" ");
6+
7+
return (lastSpace > -1 ? truncated.slice(0, lastSpace) : truncated) + "...";
8+
}
9+
10+
fetch("decks.json")
11+
.then(response => {
12+
return response.json();
13+
})
14+
.then(data => {
15+
const items = data.map(i => ({
16+
...i,
17+
title: truncate(i.title, 75),
18+
date: i.date.replaceAll("-", "&ndash;"),
19+
link: window.location.href + i.path
20+
}))
21+
22+
const options = {
23+
valueNames: [
24+
"title", "author", "date", "total_slides",
25+
{ name: "link", attr: "href" }
26+
],
27+
item: `
28+
<li>
29+
<a class="link deck">
30+
<div class="title"></div>
31+
<div class="author"></div>
32+
<div class="date"></div>
33+
<div class="total_slides"></div>
34+
</a>
35+
</li>
36+
`
37+
};
38+
39+
const deckList = new List("decks", options, items);
40+
})
41+
.catch(error => {
42+
console.error("Error fetching or processing the decks list:", error);
43+
});

0 commit comments

Comments
 (0)