2025-02-07 02:54:20 -05:00
|
|
|
use v6.e.PREVIEW;
|
|
|
|
unit module Render::Post;
|
|
|
|
|
|
|
|
use Render::Util;
|
|
|
|
use DB::Post;
|
2025-02-09 02:43:22 -05:00
|
|
|
use DB::Series;
|
2025-02-07 02:54:20 -05:00
|
|
|
|
|
|
|
use HTML::Functional;
|
|
|
|
|
|
|
|
sub post-date(Post:D $post) is export {
|
|
|
|
my $datetime = $post.posted-at;
|
|
|
|
my $timestamp = sprintf(
|
|
|
|
"%s %02d:%02d%s",
|
|
|
|
$datetime.yyyy-mm-dd,
|
|
|
|
($datetime.hour % 12) || 12,
|
|
|
|
$datetime.minute,
|
|
|
|
$datetime.hour < 12 ?? 'am' !! 'pm'
|
|
|
|
);
|
|
|
|
|
|
|
|
div :class<post-time>, :title("Posted At $timestamp"), [
|
|
|
|
icon 'time';
|
|
|
|
' ';
|
|
|
|
$timestamp
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
|
|
|
sub post-edit(Post:D $post) is export {
|
|
|
|
return [] unless $post.edited-at.elems;
|
|
|
|
my $datetime = $post.edited-at.max;
|
|
|
|
my $timestamp = sprintf(
|
|
|
|
"%s %02d:%02d%s",
|
|
|
|
$datetime.yyyy-mm-dd,
|
|
|
|
($datetime.hour % 12) || 12,
|
|
|
|
$datetime.minute,
|
|
|
|
$datetime.hour < 12 ?? 'am' !! 'pm'
|
|
|
|
);
|
|
|
|
|
|
|
|
div :class<post-edit>, :title("Last Edited At $timestamp"), [
|
|
|
|
icon 'edit';
|
|
|
|
' ';
|
|
|
|
$timestamp
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
|
|
|
sub post-read-time(Post:D $post) is export {
|
|
|
|
my ($slow, $average, $fast) = $post.readtimes;
|
|
|
|
div :class<post-read-time>, :title<Estimated read time at 140/180/220 WPM>, [
|
|
|
|
icon 'timer';
|
|
|
|
' ';
|
|
|
|
mins-to-string $slow;
|
|
|
|
' ';
|
|
|
|
'/';
|
|
|
|
' ';
|
|
|
|
mins-to-string $average;
|
|
|
|
' ';
|
|
|
|
'/';
|
|
|
|
' ';
|
|
|
|
mins-to-string $fast;
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
|
|
|
sub post-tag(Str:D $tag) is export {
|
|
|
|
span :class<post-tag>, [
|
|
|
|
a :href("/tags/$tag.html"), [
|
|
|
|
icon 'hash';
|
2025-02-09 03:10:21 -05:00
|
|
|
span $tag;
|
2025-02-07 02:54:20 -05:00
|
|
|
]
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
|
|
|
sub post-tags(Post:D $post) is export {
|
2025-02-07 06:02:53 -05:00
|
|
|
my @tags = $post.tags.sort;
|
2025-02-07 02:54:20 -05:00
|
|
|
if @tags {
|
|
|
|
@tags.=map(*.&post-tag);
|
|
|
|
div :class<post-tags>, [
|
|
|
|
icon 'purchase-tag-alt';
|
|
|
|
' ';
|
|
|
|
intersperse(', ', @tags);
|
|
|
|
]
|
|
|
|
} else {
|
|
|
|
[]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-02-09 02:43:22 -05:00
|
|
|
sub series-tag(Int:D $post-id, Int:D $series-id, Series:D $series) is export {
|
|
|
|
span :class<post-series-tag>, [
|
|
|
|
a :href("/series/$series-id.html"), [
|
|
|
|
icon 'book';
|
|
|
|
' ';
|
|
|
|
span :class<post-series-tag-inner>, [
|
|
|
|
$series.title;
|
|
|
|
' ';
|
|
|
|
'(';
|
|
|
|
($series.post-ids.first($post-id, :k) + 1).Str;
|
|
|
|
'/';
|
|
|
|
$series.post-ids.elems.Str;
|
|
|
|
')';
|
|
|
|
]
|
|
|
|
]
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
|
|
|
sub post-series-tags(Int:D $post-id, Post:D $post, $db) is export {
|
|
|
|
# Find all the series this post is in
|
|
|
|
my @series = $db.series.grep(*.value.contains-post: $post-id);
|
|
|
|
if @series {
|
|
|
|
div :class<post-series-tags>,
|
|
|
|
@series.map(-> $pair {
|
|
|
|
series-tag $post-id, $pair.key, $pair.value
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
[]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sub post-info(Int:D $id, Post:D $post, $db) is export {
|
2025-02-07 02:54:20 -05:00
|
|
|
div :class<post-info>, [
|
|
|
|
post-date $post;
|
|
|
|
post-edit $post;
|
|
|
|
post-read-time $post;
|
|
|
|
post-tags $post;
|
2025-02-09 02:43:22 -05:00
|
|
|
post-series-tags $id, $post, $db;
|
2025-02-07 02:54:20 -05:00
|
|
|
];
|
|
|
|
}
|
|
|
|
|
2025-02-09 02:43:22 -05:00
|
|
|
sub post-header(Int:D $id, Post:D $post, $db) is export {
|
2025-02-07 02:54:20 -05:00
|
|
|
header :class<post-header>, [
|
|
|
|
div :class<post-title>, [
|
|
|
|
h1 $post.title;
|
|
|
|
];
|
2025-02-09 02:43:22 -05:00
|
|
|
post-info $id, $post, $db;
|
2025-02-07 02:54:20 -05:00
|
|
|
]
|
|
|
|
}
|