🚧 Add HTML output to game state
[rhynodge.git] / src / main / kotlin / net / pterodactylus / rhynodge / filters / webpages / epicgames / FreeGamesState.kt
1 package net.pterodactylus.rhynodge.filters.webpages.epicgames
2
3 import kotlinx.html.body
4 import kotlinx.html.div
5 import kotlinx.html.dom.createHTMLDocument
6 import kotlinx.html.dom.serialize
7 import kotlinx.html.head
8 import kotlinx.html.html
9 import kotlinx.html.img
10 import kotlinx.html.style
11 import kotlinx.html.unsafe
12 import net.pterodactylus.rhynodge.states.AbstractState
13 import java.time.ZoneId
14 import java.util.Comparator.comparing
15
16 class FreeGamesState(val games: Set<FreeGame>, private val triggered: Boolean = false, private val timezone: ZoneId = ZoneId.systemDefault()) : AbstractState(true) {
17
18         override fun plainText() = games
19                 .sortedWith(comparing(FreeGame::startDate).thenBy(FreeGame::title))
20                 .joinToString("\n") { game ->
21                         "${game.title}: ${"%tF %<tT".format(game.startDate.atZone(timezone))} - ${"%tF %<tT".format(game.endDate.atZone(timezone))} (${game.imageUrl})"
22                 }
23
24         override fun htmlText() = createHTMLDocument().html {
25                 head {
26                         style("text/css") {
27                                 unsafe {
28                                         raw(
29                                                 """
30                                                 .game { display: inline-grid; width: 200px; height: 350px; grid-template-rows: 0fr 1fr 0fr 0fr; font-family: 'Recursive Sans Linear Static', Roboto, serif; color: white; text-shadow: 2px 2px black; margin: 0 1ex 1ex 0; }
31                                                 .game .game-image { grid-area: 1/1/5/2; }
32                                                 .game .game-image img { object-fit: cover; width: 100%; height: 100%; }
33                                                 .game .game-title { grid-area: 1/1/2/2; padding: 1ex; font-size: 150%; font-weight: bold; }
34                                                 .game .game-start { grid-area: 3/1/4/2; padding: 1ex 1ex 0ex 1ex; }
35                                                 .game .game-end { grid-area: 4/1/5/2; padding: 0ex 1ex 1ex 1ex; }
36                                         """
37                                         )
38                                 }
39                         }
40                 }
41                 body {
42                         div("games") {
43                                 games
44                                         .sortedWith(comparing(FreeGame::startDate).thenBy(FreeGame::title))
45                                         .forEach { game ->
46                                                 div("game") {
47                                                         div("game-image") {
48                                                                 img(src = game.imageUrl)
49                                                         }
50                                                         div("game-title") {
51                                                                 +game.title
52                                                         }
53                                                         div("game-start") {
54                                                                 +"%tF %<tT".format(game.startDate.atZone(timezone))
55                                                         }
56                                                         div("game-end") {
57                                                                 +"%tF %<tT".format(game.endDate.atZone(timezone))
58                                                         }
59                                                 }
60                                         }
61                         }
62                 }
63         }.serialize(prettyPrint = true)
64
65         override fun triggered() = triggered
66
67 }