@use templates::{base, partials::comment}; @use template_utils::*; @use plume_models::blogs::Blog; @use plume_models::comments::{Comment, CommentTree}; @use plume_models::posts::Post; @use plume_models::tags::Tag; @use plume_models::users::User; @use validator::ValidationErrors; @use routes::comments::NewCommentForm; @use routes::*; @(ctx: BaseContext, article: Post, blog: Blog, comment_form: &NewCommentForm, comment_errors: ValidationErrors, tags: Vec<Tag>, comments: Vec<CommentTree>, previous_comment: Option<Comment>, n_likes: i64, n_reshares: i64, has_liked: bool, has_reshared: bool, is_following: bool, author: User) @:base(ctx, article.title.clone(), { <meta property="og:title" content="@article.title"/> <meta property="og:type" content="article"/> @if article.cover_id.is_some() { <meta property="og:image" content="@Html(article.cover_url(ctx.0).unwrap_or_default())"/> } <meta property="og:url" content="@uri!(posts::details: blog = blog.get_fqn(ctx.0), slug = &article.slug, responding_to = _)"/> <meta property="og:description" content="@article.subtitle"/> }, { <a href="@uri!(blogs::details: name = blog.get_fqn(ctx.0), page = _)">@blog.title</a> }, { <div class="h-entry"> <h1 class="article p-name">@&article.title</h1> <h2 class="article p-summary">@&article.subtitle</h2> <div class="article-info"> <span class="author"> @Html(i18n!(ctx.1, "Written by {0}"; format!("<a href=\"{}\">{}</a>", uri!(user::details: name = &author.get_fqn(ctx.0)), escape(&author.name(ctx.0))))) </span> — <span class="date dt-published" datetime="@article.creation_date.format("%F %T")">@article.creation_date.format("%B %e, %Y")</span><a class="u-url" href="@article.ap_url"></a> @if ctx.2.clone().map(|u| u.id == author.id).unwrap_or(false) { — <a href="@uri!(posts::edit: blog = blog.get_fqn(ctx.0), slug = &article.slug)">@i18n!(ctx.1, "Edit")</a> — <form class="inline" method="post" action="@uri!(posts::delete: blog_name = blog.get_fqn(ctx.0), slug = &article.slug)"> <input onclick="return confirm('Are you sure you?')" type="submit" value="@i18n!(ctx.1, "Delete this article")"> </form> } @if !article.published { <span class="badge">@i18n!(ctx.1, "Draft")</span> } </div> @if article.cover_id.is_some() { <div class="cover" style="background-image: url('@Html(article.cover_url(ctx.0).unwrap_or_default())')"></div> <img class="hidden u-photo" src="@article.cover_url(ctx.0).unwrap_or_default()" /> } <article class="e-content"> @Html(&article.content) </article> <div class="article-meta"> <p> @if article.license.is_empty() { @i18n!(ctx.1, "All rights reserved."; &article.license) } else { @i18n!(ctx.1, "This article is under the {0} license."; &article.license) } </p> <ul class="tags"> @for tag in tags { @if !tag.is_hashtag { <li><a class="p-category" href="@uri!(tags::tag: name = &tag.tag, page = _)">@tag.tag</a></li> } else { <span class="hidden p-category">@tag.tag</span> } } </ul> <div class="flex p-author h-card"> @avatar(ctx.0, &author, Size::Medium, true, ctx.1) <div class="grow"> <h2 class="p-name"> <a href="@uri!(user::details: name = author.get_fqn(ctx.0))">@author.name(ctx.0)</a> <a rel="author" class="u-url" href="@author.ap_url"></a> </h2> <p>@Html(&author.summary)</h2> </div> @if !ctx.2.as_ref().map(|u| u.id == author.id).unwrap_or(false) { <form action="@uri!(user::follow: name = author.get_fqn(ctx.0))" method="POST"> <input type="submit" class="button" value="@if is_following {@i18n!(ctx.1, "Unsubscribe")} else {@i18n!(ctx.1, "Subscribe")}"> </form> } </div> @if ctx.2.is_some() { <div class="actions"> <form class="likes" action="@uri!(likes::create: blog = blog.get_fqn(ctx.0), slug = &article.slug)" method="POST"> <p aria-label="@i18n!(ctx.1, "One like", "{0} likes"; n_likes)" title="@i18n!(ctx.1, "One like", "{0} likes"; n_likes)"> @n_likes </p> @if has_liked { <button type="submit" class="action liked">@icon!("heart") @i18n!(ctx.1, "I don't like this anymore")</button> } else { <button type="submit" class="action">@icon!("heart") @i18n!(ctx.1, "Add yours")</button> } </form> <form class="reshares" action="@uri!(reshares::create: blog = blog.get_fqn(ctx.0), slug = &article.slug)" method="POST"> <p aria-label="@i18n!(ctx.1, "One boost", "{0} boost"; n_reshares)" title="@i18n!(ctx.1, "One boost", "{0} boosts"; n_reshares)"> @n_reshares </p> @if has_reshared { <button type="submit" class="action reshared">@icon!("repeat") @i18n!(ctx.1, "I don't want to boost this anymore")</button> } else { <button type="submit" class="action">@icon!("repeat") @i18n!(ctx.1, "Boost")</button> } </form> </div> } else { <p class="center">@i18n!(ctx.1, "Login or use your Fediverse account to interact with this article")</p> <div class="actions"> <div class="likes"> <p aria-label="@i18n!(ctx.1, "One like", "{0} likes"; n_likes)" title="@i18n!(ctx.1, "One like", "{0} likes"; n_likes)"> @n_likes </p> <a href="@uri!(session::new: m = i18n!(ctx.1, "Login to like"))" class="action">@icon!("heart") @i18n!(ctx.1, "Add yours")</a> </div> <div class="reshares"> <p aria-label="@i18n!(ctx.1, "One boost", "{0} boost"; n_reshares)" title="@i18n!(ctx.1, "One boost", "{0} boosts"; n_reshares)"> @n_reshares </p> <a href="@uri!(session::new: m = i18n!(ctx.1, "Login to boost"))" class="action">@icon!("repeat") @i18n!(ctx.1, "Boost")</a> </div> </div> } <div class="comments"> <h2>@i18n!(ctx.1, "Comments")</h2> @if ctx.2.is_some() { <form method="post" action="@uri!(comments::create: blog_name = blog.get_fqn(ctx.0), slug = &article.slug)"> @input!(ctx.1, warning (optional text), "Content warning", comment_form, comment_errors, "") <label for="plume-editor">@i18n!(ctx.1, "Your comment")</label> @if let Some(ref prev) = previous_comment { <input type="hidden" name="responding_to" value="@prev.id"/> } <textarea id="plume-editor" name="content">@comment_form.content</textarea> <input type="submit" value="@i18n!(ctx.1, "Submit comment")" /> </form> } @if !comments.is_empty() { <div class="list"> @for comm in comments { @:comment(ctx, &comm, Some(&article.ap_url), &blog.get_fqn(ctx.0), &article.slug) } </div> } else { <p class="center">@i18n!(ctx.1, "No comments yet. Be the first to react!")</p> } </div> </div> </div> })