Characters always try to display charas

This commit is contained in:
p11 2025-05-30 01:56:52 +02:00
parent 0eaddcbdac
commit 76bf715e55
2 changed files with 54 additions and 27 deletions

View File

@ -1,10 +1,7 @@
use chara::CharacterDefinition; use chara::CharacterDefinition;
use maud::{Markup, html}; use maud::{Markup, html};
pub fn render_character(def: &CharacterDefinition, relative_path: &str) -> Markup { pub fn render_character(name: &str, def: &CharacterDefinition, relative_path: &str) -> Markup {
let relative_path = relative_path.rsplit_once('/');
let relative_path = relative_path.map_or("", |(l, _r)| l);
html! { html! {
style { (CHARACTER_CSS) } style { (CHARACTER_CSS) }
@ -12,7 +9,7 @@ pub fn render_character(def: &CharacterDefinition, relative_path: &str) -> Marku
div.character-container { div.character-container {
@for layer in &def.layers { @for layer in &def.layers {
img.character-layer img.character-layer
id=(format!("{}-layer", layer.internal_name)) id=(format!("{name}-{}-layer", layer.internal_name))
src=(layer.entries.first().map(|e| format!("/{relative_path}/{}", e.path)).unwrap_or_default()) src=(layer.entries.first().map(|e| format!("/{relative_path}/{}", e.path)).unwrap_or_default())
style=(format!("display: {};", style=(format!("display: {};",
if !layer.entries.is_empty() && !layer.entries[0].path.is_empty() { if !layer.entries.is_empty() && !layer.entries[0].path.is_empty() {
@ -33,11 +30,11 @@ pub fn render_character(def: &CharacterDefinition, relative_path: &str) -> Marku
@for (i, entry) in layer.entries.iter().enumerate() { @for (i, entry) in layer.entries.iter().enumerate() {
label.option { label.option {
input type="radio" input type="radio"
name=(layer.internal_name) name=(format!("{name}-{}", layer.internal_name))
value=(entry.path) value=(format!("/{relative_path}/{}", entry.path))
checked[i==0] checked[i==0]
onchange=(format!( onchange=(format!(
"var img=document.getElementById('{}-layer');img.src=this.value;img.style.display=this.value==''?'none':'block';", "var img=document.getElementById('{name}-{}-layer');img.src=this.value;img.style.display=this.value==''?'none':'block';",
layer.internal_name layer.internal_name
)); ));
(entry.name) (entry.name)

View File

@ -378,7 +378,6 @@ fn handle_connection(
reply_binary(stream, &relative_path, "image", &ending, path) reply_binary(stream, &relative_path, "image", &ending, path)
} }
"mp3" | "wav" => reply_binary(stream, &relative_path, "audio", &ending, path), "mp3" | "wav" => reply_binary(stream, &relative_path, "audio", &ending, path),
"chara" => reply_chara(stream, &relative_path, path),
_ => fail(stream), _ => fail(stream),
} }
return; return;
@ -459,22 +458,6 @@ fn load_character_file(path: &Path) -> Option<CharacterDefinition> {
.map(|content| CharacterDefinition::parse(&content)) .map(|content| CharacterDefinition::parse(&content))
} }
fn reply_chara(mut stream: TcpStream, relative_path: &str, mut path: PathBuf) {
path.push(relative_path);
let Some(def) = load_character_file(&path) else {
fail(stream);
return;
};
let _ = write!(stream, "HTTP/1.1 200 OK\r\n");
let _ = write!(stream, "Content-Type: text/html\r\n");
let _ = write!(stream, "\r\n");
let html = render_character(&def, relative_path);
let _ = stream.write_all(html.into_string().as_bytes());
}
fn handle_relative_connection( fn handle_relative_connection(
info: Arc<SiteInfo>, info: Arc<SiteInfo>,
mut stream: TcpStream, mut stream: TcpStream,
@ -638,12 +621,28 @@ fn handle_relative_connection(
} }
} }
fn chara_handler<W: Write>(path: &Path, relative_path: &str) -> impl Fn(&str, &mut W, usize) {
move |entry, output, _level| {
let mut chara_path = path.to_path_buf();
chara_path.push(relative_path);
chara_path.push(format!("{entry}.chara"));
let Some(def) = load_character_file(&chara_path) else {
return;
};
let html = render_character(entry, &def, relative_path);
let _ = output.write_all(html.into_string().as_bytes());
}
}
if back { if back {
let _ = writeln!(stream, "<h1>{title}</h1>"); let _ = writeln!(stream, "<h1>{title}</h1>");
} }
enum TabInfo { enum TabInfo {
Lines(Vec<String>), Lines(Vec<String>),
Chara(Vec<String>),
Game(IndexMap<Box<str>, Box<str>>), Game(IndexMap<Box<str>, Box<str>>),
Description, Description,
Comment(Vec<Comment>), Comment(Vec<Comment>),
@ -677,6 +676,7 @@ fn handle_relative_connection(
let mut current_title: Box<str> = "".into(); let mut current_title: Box<str> = "".into();
let mut current_lines = Vec::new(); let mut current_lines = Vec::new();
let mut chara = false;
for line in BufReader::new(pk_file).lines() { for line in BufReader::new(pk_file).lines() {
let Ok(line) = line else { let Ok(line) = line else {
@ -686,16 +686,36 @@ fn handle_relative_connection(
if !current_title.is_empty() { if !current_title.is_empty() {
sections.push(Tab { sections.push(Tab {
title: current_title, title: current_title,
info: TabInfo::Lines(current_lines), info: if chara {
TabInfo::Chara(current_lines)
} else {
TabInfo::Lines(current_lines)
},
}) })
} }
chara = title == "Characters";
current_title = title.into(); current_title = title.into();
current_lines = vec![line]; current_lines = vec![line];
continue; continue;
} }
current_lines.push(line); if chara && line.starts_with('#') {
let mut count = 0;
for c in line.chars() {
if c == '#' {
count += 1;
continue;
}
break;
}
current_lines.push(line.clone());
current_lines.push(format!("+ {}", line[count..].trim()));
} else {
current_lines.push(line);
}
} }
sections.push(Tab { sections.push(Tab {
@ -810,6 +830,16 @@ fn handle_relative_connection(
.with_use_textboxes(true), .with_use_textboxes(true),
); );
} }
TabInfo::Chara(lines) => {
convert_extended(
lines,
&mut stream,
Settings::default()
.with_handler(chara_handler(path, relative_path))
.with_start_level(1)
.with_use_textboxes(true),
);
}
TabInfo::Game(config_map) => { TabInfo::Game(config_map) => {
if render_novel( if render_novel(
config_map, config_map,