[feat] Anime review page

Changed files
+202 -31
src
+5 -4
gleam.toml
··· 2 version = "1.0.0" 3 4 [dependencies] 5 - gleam_stdlib = ">= 0.34.0 and < 2.0.0" 6 lustre = ">= 4.2.0 and < 5.0.0" 7 - tom = ">= 0.3.0 and < 1.0.0" 8 - simplifile = ">= 1.7.0 and < 2.0.0" 9 commonmark = ">= 0.1.8 and < 1.0.0" 10 glailglind = ">= 1.1.2 and < 2.0.0" 11 - lustre_ssg = ">= 0.8.0 and < 1.0.0" 12 13 [dev-dependencies] 14 gleeunit = ">= 1.0.0 and < 2.0.0"
··· 2 version = "1.0.0" 3 4 [dependencies] 5 + gleam_stdlib = ">= 0.34.0 and < 0.50.0" 6 lustre = ">= 4.2.0 and < 5.0.0" 7 + tom = ">= 1.0.0 and < 2.0.0" 8 + simplifile = ">= 2.0.0 and < 3.0.0" 9 commonmark = ">= 0.1.8 and < 1.0.0" 10 glailglind = ">= 1.1.2 and < 2.0.0" 11 + lustre_ssg = ">= 0.8.3 and < 1.0.0" 12 + gsv = ">= 3.0.1 and < 4.0.0" 13 14 [dev-dependencies] 15 gleeunit = ">= 1.0.0 and < 2.0.0"
+25 -19
manifest.toml
··· 3 4 packages = [ 5 { name = "commonmark", version = "0.1.8", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "commonmark", source = "hex", outer_checksum = "D20FD8F1B147C3F9288FDB84CC790B5136FFD9D4BD04E121BE851B7EB02A6566" }, 6 - { name = "filepath", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "EFB6FF65C98B2A16378ABC3EE2B14124168C0CE5201553DE652E2644DCFDB594" }, 7 - { name = "glailglind", version = "1.1.2", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_http", "gleam_httpc", "gleam_stdlib", "shellout", "simplifile", "tom"], otp_app = "glailglind", source = "hex", outer_checksum = "DD037D129592B871E943EAB9C137CE3B017C784D3DEB8180A2954D113D4EE479" }, 8 - { name = "gleam_erlang", version = "0.25.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "054D571A7092D2A9727B3E5D183B7507DAB0DA41556EC9133606F09C15497373" }, 9 - { name = "gleam_http", version = "3.6.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_http", source = "hex", outer_checksum = "8C07DF9DF8CC7F054C650839A51C30A7D3C26482AC241C899C1CEA86B22DBE51" }, 10 - { name = "gleam_httpc", version = "2.2.0", build_tools = ["gleam"], requirements = ["gleam_http", "gleam_stdlib"], otp_app = "gleam_httpc", source = "hex", outer_checksum = "CF76C71002DEECF6DC5D9CA83D962728FAE166B57926BE442D827004D3C7DF1B" }, 11 - { name = "gleam_json", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib", "thoas"], otp_app = "gleam_json", source = "hex", outer_checksum = "9063D14D25406326C0255BDA0021541E797D8A7A12573D849462CAFED459F6EB" }, 12 - { name = "gleam_otp", version = "0.10.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "0B04FE915ACECE539B317F9652CAADBBC0F000184D586AAAF2D94C100945D72B" }, 13 - { name = "gleam_stdlib", version = "0.37.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "5398BD6C2ABA17338F676F42F404B9B7BABE1C8DC7380031ACB05BBE1BCF3742" }, 14 - { name = "gleeunit", version = "1.1.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "72CDC3D3F719478F26C4E2C5FED3E657AC81EC14A47D2D2DEBB8693CA3220C3B" }, 15 - { name = "jot", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "jot", source = "hex", outer_checksum = "A929403A34DC43422BA50D9BE0B61447DE4F0AD62215BB8C640445370C02EC8B" }, 16 - { name = "lustre", version = "4.2.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_json", "gleam_otp", "gleam_stdlib"], otp_app = "lustre", source = "hex", outer_checksum = "258F876CD7AB12C2C773F1A30F76DFC0A0ED989B720070DF32FC0717A6A0E60C" }, 17 - { name = "lustre_ssg", version = "0.8.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "jot", "lustre", "simplifile", "tom"], otp_app = "lustre_ssg", source = "hex", outer_checksum = "46BC70203D7730314E2CB78A3F7237F1753D86B05F4B7B26722F7FAB7345047C" }, 18 { name = "shellout", version = "1.6.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "shellout", source = "hex", outer_checksum = "E2FCD18957F0E9F67E1F497FC9FF57393392F8A9BAEAEA4779541DE7A68DD7E0" }, 19 - { name = "simplifile", version = "1.7.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "1D5DFA3A2F9319EC85825F6ED88B8E449F381B0D55A62F5E61424E748E7DDEB0" }, 20 - { name = "thoas", version = "1.2.0", build_tools = ["rebar3"], requirements = [], otp_app = "thoas", source = "hex", outer_checksum = "540C8CB7D9257F2AD0A14145DC23560F91ACDCA995F0CCBA779EB33AF5D859D1" }, 21 - { name = "tom", version = "0.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "tom", source = "hex", outer_checksum = "0831C73E45405A2153091226BF98FB485ED16376988602CC01A5FD086B82D577" }, 22 ] 23 24 [requirements] 25 commonmark = { version = ">= 0.1.8 and < 1.0.0" } 26 glailglind = { version = ">= 1.1.2 and < 2.0.0" } 27 - gleam_stdlib = { version = ">= 0.34.0 and < 2.0.0" } 28 gleeunit = { version = ">= 1.0.0 and < 2.0.0" } 29 lustre = { version = ">= 4.2.0 and < 5.0.0" } 30 - lustre_ssg = { version = ">= 0.8.0 and < 1.0.0" } 31 - simplifile = { version = ">= 1.7.0 and < 2.0.0" } 32 - tom = { version = ">= 0.3.0 and < 1.0.0" }
··· 3 4 packages = [ 5 { name = "commonmark", version = "0.1.8", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "commonmark", source = "hex", outer_checksum = "D20FD8F1B147C3F9288FDB84CC790B5136FFD9D4BD04E121BE851B7EB02A6566" }, 6 + { name = "envoy", version = "1.0.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "envoy", source = "hex", outer_checksum = "95FD059345AA982E89A0B6E2A3BF1CF43E17A7048DCD85B5B65D3B9E4E39D359" }, 7 + { name = "exception", version = "2.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "exception", source = "hex", outer_checksum = "F5580D584F16A20B7FCDCABF9E9BE9A2C1F6AC4F9176FA6DD0B63E3B20D450AA" }, 8 + { name = "filepath", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "67A6D15FB39EEB69DD31F8C145BB5A421790581BD6AA14B33D64D5A55DBD6587" }, 9 + { name = "glailglind", version = "1.1.3", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_http", "gleam_httpc", "gleam_stdlib", "shellout", "simplifile", "tom"], otp_app = "glailglind", source = "hex", outer_checksum = "4617C93C84172CF99EC05B4706720098A0BF299539DD58DD3D90DB2BF2B472F8" }, 10 + { name = "gleam_crypto", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_crypto", source = "hex", outer_checksum = "8AE56026B3E05EBB1F076778478A762E9EB62B31AEEB4285755452F397029D22" }, 11 + { name = "gleam_erlang", version = "0.33.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "A1D26B80F01901B59AABEE3475DD4C18D27D58FA5C897D922FCB9B099749C064" }, 12 + { name = "gleam_http", version = "3.7.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_http", source = "hex", outer_checksum = "8A70D2F70BB7CFEB5DF048A2183FFBA91AF6D4CF5798504841744A16999E33D2" }, 13 + { name = "gleam_httpc", version = "2.3.0", build_tools = ["gleam"], requirements = ["gleam_http", "gleam_stdlib"], otp_app = "gleam_httpc", source = "hex", outer_checksum = "CF6CDD88830CC9853F7638ECC0BE7D7CD9522640DA5FAB4C08CFAC8DEBD08028" }, 14 + { name = "gleam_json", version = "2.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_json", source = "hex", outer_checksum = "0A57FB5666E695FD2BEE74C0428A98B0FC11A395D2C7B4CDF5E22C5DD32C74C6" }, 15 + { name = "gleam_otp", version = "0.16.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "FA0EB761339749B4E82D63016C6A18C4E6662DA05BAB6F1346F9AF2E679E301A" }, 16 + { name = "gleam_stdlib", version = "0.49.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "A7DB09F15738198A87255425FBCE049B4B84C77CC522786DC923DABA73911F13" }, 17 + { name = "glearray", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "glearray", source = "hex", outer_checksum = "B99767A9BC63EF9CC8809F66C7276042E5EFEACAA5B25188B552D3691B91AC6D" }, 18 + { name = "gleeunit", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "F7A7228925D3EE7D0813C922E062BFD6D7E9310F0BEE585D3A42F3307E3CFD13" }, 19 + { name = "gsv", version = "3.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib", "glearray"], otp_app = "gsv", source = "hex", outer_checksum = "31D3C88CECA73DE800FCE66A8F77354FDDA8EB627E2040AA4A27577AD43A68D4" }, 20 + { name = "jot", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "jot", source = "hex", outer_checksum = "A0A52BD8D079AB0ABF80BE11DC63B85CF5791125991A029FAD7D17820D9419D8" }, 21 + { name = "lustre", version = "4.6.3", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_json", "gleam_otp", "gleam_stdlib"], otp_app = "lustre", source = "hex", outer_checksum = "BDF833368F6C8F152F948D5B6A79866E9881CB80CB66C0685B3327E7DCBFB12F" }, 22 + { name = "lustre_ssg", version = "0.8.3", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib", "jot", "lustre", "simplifile", "temporary", "tom"], otp_app = "lustre_ssg", source = "hex", outer_checksum = "5F1DF752AE6AAD0BD332CCB52E1CF2086997CF55EB59894080F4E3ADF691B95C" }, 23 { name = "shellout", version = "1.6.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "shellout", source = "hex", outer_checksum = "E2FCD18957F0E9F67E1F497FC9FF57393392F8A9BAEAEA4779541DE7A68DD7E0" }, 24 + { name = "simplifile", version = "2.2.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "0DFABEF7DC7A9E2FF4BB27B108034E60C81BEBFCB7AB816B9E7E18ED4503ACD8" }, 25 + { name = "temporary", version = "1.0.0", build_tools = ["gleam"], requirements = ["envoy", "exception", "filepath", "gleam_crypto", "gleam_stdlib", "simplifile"], otp_app = "temporary", source = "hex", outer_checksum = "51C0FEF4D72CE7CA507BD188B21C1F00695B3D5B09D7DFE38240BFD3A8E1E9B3" }, 26 + { name = "tom", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "tom", source = "hex", outer_checksum = "228E667239504B57AD05EC3C332C930391592F6C974D0EFECF32FFD0F3629A27" }, 27 ] 28 29 [requirements] 30 commonmark = { version = ">= 0.1.8 and < 1.0.0" } 31 glailglind = { version = ">= 1.1.2 and < 2.0.0" } 32 + gleam_stdlib = { version = ">= 0.34.0 and < 0.50.0" } 33 gleeunit = { version = ">= 1.0.0 and < 2.0.0" } 34 + gsv = { version = ">= 3.0.1 and < 4.0.0" } 35 lustre = { version = ">= 4.2.0 and < 5.0.0" } 36 + lustre_ssg = { version = ">= 0.8.3 and < 1.0.0" } 37 + simplifile = { version = ">= 2.0.0 and < 3.0.0" } 38 + tom = { version = ">= 1.0.0 and < 2.0.0" }
+26 -6
src/build.gleam
··· 1 import gleam/dict 2 import gleam/io 3 import gleam/list 4 import gleam/result 5 import gleam/string 6 import lustre/ssg 7 import tailwind 8 import website/common 9 - 10 import website/page/index 11 import website/page/post 12 import website/page/project 13 14 - import website/data/posts 15 - import website/data/projects 16 - 17 pub fn main() { 18 let projects = 19 dict.from_list( ··· 25 posts.all() 26 |> list.map(fn(post) { #(post.id, post) }), 27 ) 28 29 let build = 30 ssg.new("./priv") ··· 43 |> ssg.add_dynamic_route("/posts", posts, fn(p) { 44 post.view(p) |> common.wrapper(p.title, _) 45 }) 46 - |> ssg.use_index_routes 47 |> ssg.add_static_dir("./src/static/") 48 - |> ssg.build 49 |> result.map_error(string.inspect) 50 |> result.try(fn(_) { 51 [
··· 1 import gleam/dict 2 import gleam/io 3 import gleam/list 4 + import gleam/option 5 import gleam/result 6 import gleam/string 7 + import gsv 8 import lustre/ssg 9 + import simplifile 10 import tailwind 11 import website/common 12 + import website/data/posts 13 + import website/data/projects 14 + import website/page/anime 15 import website/page/index 16 import website/page/post 17 import website/page/project 18 19 pub fn main() { 20 let projects = 21 dict.from_list( ··· 27 posts.all() 28 |> list.map(fn(post) { #(post.id, post) }), 29 ) 30 + let assert Ok(anime_csv) = simplifile.read("./src/website/data/anime.csv") 31 + let assert Ok(anime_rows) = gsv.to_lists(anime_csv) 32 + let anime = 33 + anime_rows 34 + |> list.map(fn(row) { 35 + case row { 36 + [title] -> Ok(common.Anime(title, option.None, option.None)) 37 + [title, link] -> Ok(common.Anime(title, option.Some(link), option.None)) 38 + [title, link, thoughts] -> 39 + Ok(common.Anime(title, option.Some(link), option.Some(thoughts))) 40 + _ -> Error(Nil) 41 + } 42 + }) 43 + |> result.values() 44 45 let build = 46 ssg.new("./priv") ··· 59 |> ssg.add_dynamic_route("/posts", posts, fn(p) { 60 post.view(p) |> common.wrapper(p.title, _) 61 }) 62 + |> ssg.add_static_route( 63 + "/anime", 64 + anime.view(anime) |> common.wrapper("Anime", _), 65 + ) 66 + |> ssg.use_index_routes() 67 |> ssg.add_static_dir("./src/static/") 68 + |> ssg.build() 69 |> result.map_error(string.inspect) 70 |> result.try(fn(_) { 71 [
+8 -2
src/website/common.gleam
··· 1 import gleam/int 2 import lustre/attribute as attr 3 import lustre/element 4 import lustre/element/html ··· 31 summary: element.Element(a), 32 content: element.Element(a), 33 ) 34 } 35 36 pub fn wrapper( ··· 79 80 If you wish to get in contact, please send an email to [mia@naomieow.xyz](mailto:mia@naomieow.xyz), or contact me on [Discord](https://chat.lesbian.skin). 81 " 82 - |> md.render, 83 ), 84 ]) 85 } ··· 98 navitem(name: "Home", href: ""), 99 navitem(name: "Projects", href: "projects"), 100 navitem(name: "Posts", href: "posts"), 101 darkmode(), 102 ], 103 ) ··· 128 ) 129 } 130 131 - pub fn link(text: String, link: String) -> element.Element(a) { 132 html.a([attr.href(link), attr.class("text-pink-400 underline")], [ 133 element.text(text), 134 ])
··· 1 import gleam/int 2 + import gleam/option.{type Option} 3 import lustre/attribute as attr 4 import lustre/element 5 import lustre/element/html ··· 32 summary: element.Element(a), 33 content: element.Element(a), 34 ) 35 + } 36 + 37 + pub type Anime { 38 + Anime(title: String, link: Option(String), thoughts: Option(String)) 39 } 40 41 pub fn wrapper( ··· 84 85 If you wish to get in contact, please send an email to [mia@naomieow.xyz](mailto:mia@naomieow.xyz), or contact me on [Discord](https://chat.lesbian.skin). 86 " 87 + |> md.render(), 88 ), 89 ]) 90 } ··· 103 navitem(name: "Home", href: ""), 104 navitem(name: "Projects", href: "projects"), 105 navitem(name: "Posts", href: "posts"), 106 + navitem(name: "Anime", href: "anime"), 107 darkmode(), 108 ], 109 ) ··· 134 ) 135 } 136 137 + pub fn link(text text: String, link link: String) -> element.Element(a) { 138 html.a([attr.href(link), attr.class("text-pink-400 underline")], [ 139 element.text(text), 140 ])
+52
src/website/data/anime.csv
···
··· 1 + Frieren: Beyond Journey’s End,https://anilist.co/anime/154587/Frieren-Beyond-Journeys-End/ 2 + DAN DA DAN,https://anilist.co/anime/171018/DAN-DA-DAN/ 3 + Kaiju No.8,https://anilist.co/anime/153288/Kaiju-No8/,"I'm a huge kaiju fan, so this one is quite biased!" 4 + Fullmetal Alchemist: Brotherhood,https://anilist.co/anime/5114/Fullmetal-Alchemist-Brotherhood/ 5 + Gundam: TWFM,https://anilist.co/anime/139274/Mobile-Suit-Gundam-The-Witch-from-Mercury/ 6 + Jujutsu Kaisen S2,https://anilist.co/anime/145064/JUJUTSU-KAISEN-Season-2/ 7 + Chainsaw Man,https://anilist.co/anime/127230/Chainsaw-Man/ 8 + Love is War S3,https://anilist.co/anime/125367/Kaguyasama-Love-is-War-Ultra-Romantic/ 9 + Love is War,https://anilist.co/anime/101921/Kaguyasama-Love-is-War/ 10 + Love is War S4,https://anilist.co/anime/151384/Kaguyasama-Love-is-War-The-First-Kiss-That-Never-Ends/ 11 + Love is War S2,https://anilist.co/anime/112641/Kaguyasama-Love-is-War/ 12 + Evangelion 1.0,https://anilist.co/anime/2759/Evangelion-10-You-Are-Not-Alone/,All the Eva movies are basically the same tier 13 + Evangelion 2.0,https://anilist.co/anime/3784/Evangelion-20-You-Can-Not-Advance/ 14 + Evangelion 3.0,https://anilist.co/anime/3785/Evangelion-30-You-Can-Not-Redo/ 15 + Evangelion 3.0+1.0,https://anilist.co/anime/3786/Evangelion-3010-Thrice-Upon-a-Time/ 16 + JoJo's P3,https://anilist.co/anime/20474/JoJos-Bizarre-Adventure-Stardust-Crusaders/ 17 + JoJo's P3P2,https://anilist.co/anime/20799/JoJos-Bizarre-Adventure-Stardust-Crusaders--Battle-in-Egypt/ 18 + JoJo's P4,https://anilist.co/anime/21450/JoJos-Bizarre-Adventure-Diamond-is-Unbreakable/ 19 + Attack on Titan,https://anilist.co/anime/16498/Attack-on-Titan/ 20 + Attack on Titan S4,https://anilist.co/anime/110277/Attack-on-Titan-Final-Season/ 21 + Attack on Titan S4P2,https://anilist.co/anime/131681/Attack-on-Titan-Final-Season-Part-2/ 22 + Attack on Titan S3,https://anilist.co/anime/99147/Attack-on-Titan-Season-3/ 23 + Attack on Titan S2,https://anilist.co/anime/20958/Attack-on-Titan-Season-2/ 24 + Attack on Titan S3P2,https://anilist.co/anime/104578/Attack-on-Titan-Season-3-Part-2/ 25 + Hell's Paradise,https://anilist.co/anime/128893/Hells-Paradise/ 26 + Death Note,https://anilist.co/anime/1535/Death-Note/ 27 + Attack on Titan S4P3S1,https://anilist.co/anime/146984/Attack-on-Titan-Final-Season-THE-FINAL-CHAPTERS-Special-1/ 28 + Attack on Titan S4P3S2,https://anilist.co/anime/162314/Attack-on-Titan-Final-Season-THE-FINAL-CHAPTERS-Special-2/ 29 + Cyberpunk: Edgerunners,https://anilist.co/anime/120377/Cyberpunk-Edgerunners/ 30 + My Hero Academia S7,https://anilist.co/anime/163139/My-Hero-Academia-Season-7/ 31 + Mushoku Tensei S2P2,https://anilist.co/anime/166873/Mushoku-Tensei-Jobless-Reincarnation-Season-2-Part-2/ 32 + Demon Slayer S4,https://anilist.co/anime/166240/Demon-Slayer-Kimetsu-no-Yaiba-Hashira-Training-Arc/ 33 + Demon Slayer S2,https://anilist.co/anime/142329/Demon-Slayer-Kimetsu-no-Yaiba-Entertainment-District-Arc/ 34 + Fate/Zero,https://anilist.co/anime/10087/FateZero/ 35 + Bocchi the Rock,https://anilist.co/anime/130003/BOCCHI-THE-ROCK/ 36 + Demon Slayer S3,https://anilist.co/anime/145139/Demon-Slayer-Kimetsu-no-Yaiba-Swordsmith-Village-Arc/ 37 + Demon Slayer: Mugen Train,https://anilist.co/anime/112151/Demon-Slayer-Kimetsu-no-Yaiba-The-Movie-Mugen-Train/ 38 + Demon Slayer,https://anilist.co/anime/101922/Demon-Slayer-Kimetsu-no-Yaiba/ 39 + Blue Exorcist S3,https://anilist.co/anime/158931/Blue-Exorcist-Shimane-Illuminati-Saga/ 40 + Blue Exorcist S4,https://anilist.co/anime/176311/Blue-Exorcist-Beyond-the-Snow-Saga/ 41 + Jujutsu Kaisen 0,https://anilist.co/anime/131573/JUJUTSU-KAISEN-0/ 42 + Attack on Titan: No Regrets,https://anilist.co/anime/20811/Attack-on-Titan-No-Regrets/ 43 + Blue Exorcist S2,https://anilist.co/anime/21861/Blue-Exorcist-Kyoto-Saga/ 44 + Blue Exorcist,https://anilist.co/anime/9919/Blue-Exorcist/,If episodes 17-25 didn't exist this would be higher than Season 2 45 + 7th Time Loop,https://anilist.co/anime/168374/7th-Time-Loop-The-Villainess-Enjoys-a-Carefree-Life-Married-to-Her-Worst-Enemy/ 46 + Campfire Cooking,https://anilist.co/anime/156067/Campfire-Cooking-in-Another-World-with-my-Absurd-Skill/ 47 + Mashle,https://anilist.co/anime/151801/MASHLE-MAGIC-AND-MUSCLES/ 48 + Mashle S2,https://anilist.co/anime/166610/MASHLE-MAGIC-AND-MUSCLES-Season-2/ 49 + 86,https://anilist.co/anime/116589/86-EIGHTYSIX/ 50 + 86 S2,https://anilist.co/anime/131586/86-EIGHTYSIX-Part-2/ 51 + AMAIM,https://anilist.co/anime/143203/AMAIM-Warrior-at-the-Borderline-Part-2/ 52 + Aldnoah.Zero,https://anilist.co/anime/20632/ALDNOAHZERO/
+86
src/website/page/anime.gleam
···
··· 1 + import gleam/float 2 + import gleam/int 3 + import gleam/list 4 + import gleam/option.{None, Some} 5 + import lustre/attribute as attr 6 + import lustre/element.{type Element} 7 + import lustre/element/html 8 + import lustre/ssg/djot 9 + import website/common.{type Anime} 10 + import website/md 11 + 12 + fn score(index: Int, length: Int) -> Int { 13 + float.truncate(int.to_float(length - index) /. int.to_float(length) *. 100.0) 14 + } 15 + 16 + pub fn view(anime: List(Anime)) -> List(Element(a)) { 17 + let length = list.length(anime) 18 + [ 19 + html.div( 20 + [ 21 + attr.class( 22 + "drop-shadow-md text-xl p-4 mb-4 rounded-xl bg-gray-200 dark:bg-neutral-800 dark:text-neutral-200", 23 + ), 24 + ], 25 + { 26 + "This is a non-comprehensive list of anime I have watched, sorted by whether or not I liked an anime more than the one below it. The \"score\" displayed on the left of each anime isn't technically decided by me and is actually dynamically created using the very basic formula: 27 + `(list_length - anime_index) / list_length * 100` 28 + where `anime_index` starts at `0` for the top-most anime. The (scoreless) list is [stored as a CSV](https://codeberg.org/naomi/website/src/branch/main/src/website/data/anime.csv) in the source code for the website, and is updated whenever I feel like it. 29 + I've also included some notes on some of the animes where I feel that I have something to comment on. 30 + Currently `" 31 + <> int.to_string(length) 32 + <> "` out of my (educated guess) `300+` watched anime are listed." 33 + } 34 + |> djot.content() 35 + |> md.render(), 36 + ), 37 + html.div( 38 + [attr.class("grid grid-cols-[min-content_33%_auto] gap-x-4")], 39 + list.index_map(anime, fn(a, i) { anime_entry(a, i, length) }) 40 + |> list.flatten(), 41 + ), 42 + ] 43 + } 44 + 45 + fn anime_entry( 46 + anime a: common.Anime, 47 + index i: Int, 48 + length length: Int, 49 + ) -> List(Element(a)) { 50 + [ 51 + html.p( 52 + [ 53 + attr.class( 54 + "drop-shadow-md text-xl p-4 mb-4 rounded-xl bg-gray-200 dark:bg-neutral-800 dark:text-neutral-200", 55 + ), 56 + ], 57 + [element.text(int.to_string(score(i, length)) <> "/100")], 58 + ), 59 + html.p( 60 + [ 61 + attr.class( 62 + "drop-shadow-md text-xl p-4 mb-4 rounded-xl bg-gray-200 dark:bg-neutral-800 dark:text-neutral-200", 63 + ), 64 + ], 65 + [ 66 + case a.link { 67 + None -> element.text(a.title) 68 + Some(link) -> common.link(a.title, link) 69 + }, 70 + ], 71 + ), 72 + html.p( 73 + [ 74 + attr.class( 75 + "drop-shadow-md text-xl p-4 mb-4 rounded-xl bg-gray-200 dark:bg-neutral-800 dark:text-neutral-200", 76 + ), 77 + ], 78 + [ 79 + case a.thoughts { 80 + None -> element.text("Nothing to add") 81 + Some(thoughts) -> element.text(thoughts) 82 + }, 83 + ], 84 + ), 85 + ] 86 + }