You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

132 lines
6.7 KiB

use std::sync::Arc;
use crate::cached_wattpad::*;
use crate::components::header::{Header, HeaderLink};
use crate::WATTPAD;
use axum::extract::{Extension, Query, State as AxumState};
use maud::{html, Markup, PreEscaped, DOCTYPE};
use regex::Regex;
use serde::Deserialize;
#[derive(Deserialize)]
pub struct StoryParams {
id: Option<String>,
chapter: Option<usize>,
}
pub async fn render(Query(params): Query<StoryParams>) -> Markup {
if let Some(id) = params.id {
//let story = state.wattpad.get_story(id.as_str()).await;
let story = get_story(id.as_str()).await;
if let Ok(story) = story {
if let Some(part_idx) = params.chapter {
let part = story.get_part(part_idx).await;
if let Ok(part) = part {
let style_matching_regex = Regex::new("style=\"(.+?)\"").unwrap();
html! {
(DOCTYPE)
html {
head {
meta name="viewport" content="width=device-width, initial-scale=1.0";
style {(PreEscaped(
grass::include!("./css/index.scss")
))}
script {(PreEscaped(
include_str!("../../scripts/StoryContent.js")
))}
}
body {
(Header({
let mut story_parts: Vec<HeaderLink> = story._parts.iter().enumerate().map(|(idx, part)| HeaderLink { path: format!("/story?id={}&chapter={}", story.id, idx), name: part.title.clone(), prefix: None, postfix: None }).collect();
story_parts.insert(0, HeaderLink { path: format!("/story?id={}", story.id), name: "Details".to_string(), prefix: None, postfix: Some("|".to_string()) });
story_parts.insert(0, HeaderLink { path: "/".to_string(), name: "Homepage".to_string(), prefix: None, postfix: None });
story_parts
}, format!("/story?id={}&chapter={}", story.id, part_idx)))
div .story-content {
@for paragraph in part.get_paragraphs().expect("Failed to get paragraphs of part") {
p style=({
let attributes = paragraph.attributes.unwrap_or_default();
let captures = style_matching_regex.captures(attributes.as_str());
match captures {
Some(e) => e.get(1).unwrap().as_str().to_string(),
None => String::default()
}
}) { (PreEscaped(paragraph.html)) }
}
}
}
}
}
} else {
html! {
h1 { "Err: Chapter not found" }
}
}
} else {
html! {
(DOCTYPE)
html {
head {
meta name="viewport" content="width=device-width, initial-scale=1.0";
style {(PreEscaped(
grass::include!("./css/index.scss")
))}
script {(PreEscaped(
include_str!("../../scripts/StoryDetails.js")
))}
}
body {
(Header({
let mut story_parts: Vec<HeaderLink> = story._parts.iter().enumerate().map(|(idx, part)| HeaderLink { path: format!("/story?id={}&chapter={}", story.id, idx), name: part.title.clone(), prefix: None, postfix: None }).collect();
story_parts.insert(0, HeaderLink { path: format!("/story?id={}", story.id), name: "Details".to_string(), prefix: None, postfix: Some("|".to_string()) });
story_parts.insert(0, HeaderLink { path: "/".to_string(), name: "Homepage".to_string(), prefix: None, postfix: None });
story_parts
}, format!("/story?id={}", story.id)))
div .story-page-container {
div .story-page {
img .story-cover #storycover src=(story.cover);
div .story-details {
h3 #storyname {
(story.title)
}
p {
(PreEscaped(story.description.replace("\n", "<br/>")))
}
p {
"Original URL: "
a href=(story.url) { (story.url) }
br;
"Author: "
a href=(format!("/user?name={}", story._user.fullname)) {(story._user.name)}
br;
"© " (story.copyright)
}
div .tag-container {
@for tag in story.tags {
div .tag {
a href=(format!("/search?query={}&type=tag", tag)) { "#"(tag) }
}
}
}
}
}
div .story-buttons #detail-buttons {
button #favorite { "Save Story" }
}
}
}
}
}
}
} else {
html! {
h1 { "Err: Story not found" }
}
}
} else {
html! {
h1 { "Err: Story not specified" }
}
}
}