1212import zone .nox .data .Post ;
1313
1414import java .util .List ;
15+ import java .util .Map .Entry ;
16+ import java .util .stream .Collectors ;
17+ import java .util .stream .Stream ;
1518
1619import static dev .nipafx .ginevra .html .HtmlElement .div ;
20+ import static dev .nipafx .ginevra .html .HtmlElement .span ;
1721import static java .util .Comparator .comparing ;
1822import static zone .nox .components .Components .layout ;
1923import static zone .nox .components .Components .postBlock ;
2024
2125public class LandingPage implements Template {
2226
23- public record Style (Classes posts , Classes post , Css css ) implements CssStyle { }
27+ public record Style (Classes posts , Classes year , Classes post , Css css ) implements CssStyle { }
2428
2529 @ StyledWith
2630 public static final Style STYLE = Css .parse (Style .class , """
@@ -32,6 +36,13 @@ public record Style(Classes posts, Classes post, Css css) implements CssStyle {
3236 gap: var(--gap);
3337 }
3438
39+ .year {
40+ font-family: var(--alt-font), "sans-serif";
41+ font-size: var(--font-size-small);
42+ color: var(--yellow);
43+ text-align: center;
44+ }
45+
3546 .post {
3647 width: 100%
3748 }
@@ -43,18 +54,29 @@ public HtmlPage compose(@ForAllIn("posts") List<Post> posts) {
4354 }
4455
4556 private Element composePage (List <Post > posts ) {
57+ var postsByYear = posts .stream ().collect (Collectors .groupingBy (post -> post .date ().getYear ()));
4658 return layout
4759 .title ("Radio Nox" )
4860 .description ("News from the Shadows of Neotropolis." )
4961 .content (div
5062 .classes (STYLE .posts )
51- .children (posts .stream ()
52- .sorted (comparing (Post ::index ).reversed ())
53- .map (post -> div
54- .classes (STYLE .post )
55- .children (postBlock (post )))
63+ .children (postsByYear
64+ .entrySet ().stream ()
65+ .sorted (Entry .<Integer , List <Post >> comparingByKey ().reversed ())
66+ .flatMap (entry -> composeYearWithPosts (entry .getKey (), entry .getValue ()))
5667 .toList ())
5768 );
5869 }
5970
71+ private Stream <Element > composeYearWithPosts (int year , List <Post > posts ) {
72+ return Stream .concat (
73+ Stream .of (span .classes (STYLE .year ).text ("Y" + year )),
74+ posts .stream ()
75+ .sorted (comparing (Post ::index ).reversed ())
76+ .map (post -> div
77+ .classes (STYLE .post )
78+ .children (postBlock (post )))
79+ );
80+ }
81+
6082}
0 commit comments