The code and data behind xeiaso.net
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add page that explains the characters in the blog

Signed-off-by: Xe <me@christine.website>

Xe Iaso 295a2f99 36e51652

+179 -8
+77
dhall/characters.dhall
··· 1 + let xesite = ./types/package.dhall 2 + 3 + let Prelude = ./Prelude.dhall 4 + 5 + let C = xesite.Character 6 + 7 + let they = ./pronouns/they.dhall 8 + 9 + let characters = 10 + [ C::{ 11 + , name = "Mara" 12 + , stickerName = "mara" 13 + , defaultPose = "hacker" 14 + , description = 15 + "Mara was the first character added to this blog. She is written to be the student in the Socratic dialogues. She has a fair amount of knowledge about technology, just enough to not be afraid to ask for clarification on how things fit into the larger picture or to call the teacher out for being vague or misleading. Mara helps Aoi get up to speed with some topics. Mara is a shark with brown hair that has a red streak." 16 + , stickers = [ "aha", "hacker", "happy", "hmm", "sh0rck", "wat" ] 17 + } 18 + , C::{ 19 + , name = "Cadey" 20 + , stickerName = "cadey" 21 + , defaultPose = "enby" 22 + , description = 23 + "Cadey is written as the teacher in the Socratic dialogues. They started out as a self-insert for the author of this blog to de-emphasize certain points, but then evolved into a way to have interplay between themselves and Mara. They are written as someone who has expertise in the topics being discussed, but doesn't have perfect expertise. They help Mara with answers to questions about details to the topics being discussed and work well with Numa due to being friends for a very long time. Cadey is an orcadragon with pink hair." 24 + , pronouns = they 25 + , stickers = 26 + [ "aha" 27 + , "angy" 28 + , "coffee" 29 + , "enby" 30 + , "facepalm" 31 + , "hug" 32 + , "percussive-maintenance" 33 + , "wat" 34 + ] 35 + } 36 + , C::{ 37 + , name = "Numa" 38 + , stickerName = "numa" 39 + , defaultPose = "delet" 40 + , description = 41 + "Numa is the keeper of firey hot takes. Born in the fires of shitposting and satire, Numa genuinely does care about the topics being discussed, but has a bad habit of communicating in shitposts, memes, and hot takes intentionally designed to make you reconsider how serious she is being about any given topic. She could definitely be a wonderful teacher if she could lessen up a bit on the satire. The stickers for Numa are 3d renders of the author's v-tubing avatar, but Numa is written differently than the characterization of the author when streaming. Numa is a fairly tall (6') human with neon green hair that usually wears it in a high ponytail." 42 + , stickers = 43 + [ "delet" 44 + , "delet2" 45 + , "dismay" 46 + , "happy" 47 + , "neutral" 48 + , "stare" 49 + , "thinking" 50 + , "vibe" 51 + ] 52 + } 53 + , C::{ 54 + , name = "Aoi" 55 + , stickerName = "aoi" 56 + , defaultPose = "cheer" 57 + , description = 58 + "Aoi is the idealist. She is another student type like Mara, but hasn't been marred by the cynicism that can come with experience in this industry. If Mara is a junior in a university going for a programming degree, Aoi would be a freshman. Aoi can feel bullied by misunderstanding Numa's satire as rudeness, but looks up to Mara and Cadey as ideals for where she wants to go in the industry. Aoi is a blue-haired foxgirl." 59 + , stickers = 60 + [ "angy" 61 + , "cheer" 62 + , "coffee" 63 + , "concern" 64 + , "facepalm" 65 + , "grin" 66 + , "happy" 67 + , "rage" 68 + , "sleepy" 69 + , "smug" 70 + , "sus" 71 + , "wut" 72 + , "yawn" 73 + ] 74 + } 75 + ] 76 + 77 + in characters
+1
dhall/package.dhall
··· 82 82 , Link::{ url = "irc://irc.libera.chat/#xeserv", title = "IRC" } 83 83 ] 84 84 , pronouns = ./pronouns.dhall 85 + , characters = ./characters.dhall 85 86 }
+19
dhall/types/Character.dhall
··· 1 + let PronounSet = ./PronounSet.dhall 2 + 3 + in { Type = 4 + { name : Text 5 + , stickerName : Text 6 + , defaultPose : Text 7 + , description : Text 8 + , pronouns : PronounSet.Type 9 + , stickers : List Text 10 + } 11 + , default = 12 + { name = "" 13 + , stickerName = "" 14 + , defaultPose = "" 15 + , description = "" 16 + , pronouns = ../pronouns/she.dhall 17 + , stickers = [] : List Text 18 + } 19 + }
+4
dhall/types/Config.dhall
··· 2 2 3 3 let Author = ./Author.dhall 4 4 5 + let Character = ./Character.dhall 6 + 5 7 let Job = ./Job.dhall 6 8 7 9 let Link = ./Link.dhall ··· 34 36 , notableProjects : List Link.Type 35 37 , contactLinks : List Link.Type 36 38 , pronouns : List PronounSet.Type 39 + , characters : List Character.Type 37 40 } 38 41 , default = 39 42 { signalboost = [] : List Person.Type ··· 49 52 , notableProjects = [] : List Link.Type 50 53 , contactLinks = [] : List Link.Type 51 54 , pronouns = [] : List PronounSet.Type 55 + , characters = [] : List Character.Type 52 56 } 53 57 }
+1
dhall/types/package.dhall
··· 1 1 { Author = ./Author.dhall 2 + , Character = ./Character.dhall 2 3 , Company = ./Company.dhall 3 4 , Config = ./Config.dhall 4 5 , Job = ./Job.dhall
+1 -1
lib/xesite_markdown/src/lib.rs
··· 124 124 <div class="{class}"> 125 125 <img src="https://cdn.xeiaso.net/sticker/{name_lower}/{mood}/{size}" alt="{name} is {mood}"> 126 126 </div> 127 - <div class="conversation-chat">&lt;<b>{name}</b>&gt; "# 127 + <div class="conversation-chat">&lt;<a href="/characters#{name_lower}"><b>{name}</b></a>&gt; "# 128 128 ), 129 129 ContentType::Html, 130 130 );
+1 -1
lib/xesite_templates/src/lib.rs
··· 75 75 } 76 76 ."conversation-chat" { 77 77 "<" 78 - b { (name) } 78 + a href={"/characters#" (name_lower)} { b { (name) } } 79 79 "> " 80 80 (body) 81 81 }
+46 -6
src/app/config.rs
··· 28 28 #[serde(rename = "contactLinks")] 29 29 pub contact_links: Vec<Link>, 30 30 pub pronouns: Vec<PronounSet>, 31 + pub characters: Vec<Character>, 31 32 } 32 33 33 34 #[derive(Clone, Deserialize, Serialize, Default)] 34 35 pub struct PronounSet { 35 - nominative: String, 36 - accusative: String, 36 + pub nominative: String, 37 + pub accusative: String, 37 38 #[serde(rename = "possessiveDeterminer")] 38 - possessive_determiner: String, 39 - possessive: String, 40 - reflexive: String, 41 - singular: bool, 39 + pub possessive_determiner: String, 40 + pub possessive: String, 41 + pub reflexive: String, 42 + pub singular: bool, 42 43 } 43 44 44 45 impl Render for PronounSet { ··· 80 81 "Please note that this pronoun is normally a plural pronoun. It is used here to refer to a single person. For more information on this, see " 81 82 a href="https://www.merriam-webster.com/words-at-play/singular-nonbinary-they" {"this page from Merriam-Webster"} 82 83 " that will explain in more detail." 84 + } 85 + } 86 + } 87 + } 88 + } 89 + 90 + #[derive(Clone, Deserialize, Serialize, Default)] 91 + pub struct Character { 92 + pub name: String, 93 + #[serde(rename = "stickerName")] 94 + pub sticker_name: String, 95 + #[serde(rename = "defaultPose")] 96 + pub default_pose: String, 97 + pub description: String, 98 + pub pronouns: PronounSet, 99 + pub stickers: Vec<String>, 100 + } 101 + 102 + impl Render for Character { 103 + fn render(&self) -> Markup { 104 + html! { 105 + h2 #(self.sticker_name) {(self.name)} 106 + (xesite_templates::sticker(self.sticker_name.clone(), self.default_pose.clone())) 107 + p {(self.description)} 108 + details { 109 + summary { "Pronouns (" (self.pronouns.nominative) "/" (self.pronouns.accusative) ")" } 110 + (self.pronouns) 111 + } 112 + 113 + details { 114 + summary { "All stickers" } 115 + .grid { 116 + @for sticker in &self.stickers { 117 + .cell."-3of12" { 118 + (xesite_templates::sticker(self.sticker_name.clone(), sticker.clone())) 119 + br; 120 + (sticker) 121 + } 122 + } 83 123 } 84 124 } 85 125 }
+9
src/handlers/mod.rs
··· 69 69 } 70 70 71 71 #[instrument(skip(state))] 72 + pub async fn characters(Extension(state): Extension<Arc<State>>) -> Markup { 73 + HIT_COUNTER.with_label_values(&["characters"]).inc(); 74 + let state = state.clone(); 75 + let cfg = state.cfg.clone(); 76 + 77 + tmpl::characters(&cfg.characters) 78 + } 79 + 80 + #[instrument(skip(state))] 72 81 pub async fn index(Extension(state): Extension<Arc<State>>) -> Result<Markup> { 73 82 HIT_COUNTER.with_label_values(&["index"]).inc(); 74 83 let state = state.clone();
+1
src/main.rs
··· 167 167 .route("/api/talks/:name", get(handlers::api::talk)) 168 168 // static pages 169 169 .route("/", get(handlers::index)) 170 + .route("/characters", get(handlers::characters)) 170 171 .route("/contact", get(handlers::contact)) 171 172 .route("/feeds", get(handlers::feeds)) 172 173 .route("/resume", get(handlers::resume))
+19
src/tmpl/mod.rs
··· 233 233 ) 234 234 } 235 235 236 + pub fn characters(characters: &Vec<Character>) -> Markup { 237 + base( 238 + Some("Characters"), 239 + None, 240 + html! { 241 + h1 {"Characters"} 242 + p{ 243 + "When I am writing articles on this blog, sometimes I will use " 244 + a href="https://en.wikipedia.org/wiki/Socratic_method" {"the Socratic method"} 245 + " to help illustrate my point. These characters are written off of a set of tropes to help give them a place in the discussions. The characters are just that, characters. Their dialogues are fiction, unless otherwise indicated everything that happens in those dialogues are products of the author's imagination or are used in a fictitious manner. Any resemblance to actual persons (living or dead) is purely coincidental." 246 + } 247 + 248 + @for character in characters { 249 + (character) 250 + } 251 + }, 252 + ) 253 + } 254 + 236 255 pub fn patrons(patrons: &Users) -> Markup { 237 256 base( 238 257 Some("Patrons"),