@@ 1,4 1,3 @@
-a_comment = a comment
about = About
about_title = About this instance
about_what_is = What is lotide?
@@ 15,14 14,13 @@ administration_edit = Edit Instance Details
administration_edit_invitations_enabled = Invitations:
administration_edit_signup_allowed = Public Signups:
administration_invitation_creation_requirement = Invitations can be created by
-administration_invitations_enabled = Invitations are currently
-administration_signup_allowed = Signups are currently
+administration_invitations_enabled = Invitations are currently { $part_enabled }
+administration_signup_allowed = Signups are currently { $part_allowed }
all = All
all_title = The Whole Known Network
allowed_false = not allowed
allowed_true = allowed
and_more = …and more
-by = by
comment = Comment
comments = Comments
comment_attachment_prefix = Attachment:
@@ 61,7 59,7 @@ enabled_false = disabled
fetch = Fetch
flag_comment_prompt = Add a comment:
flag_dismiss = Dismiss
-flagged_by = Flagged by
+flagged_by = Flagged by { $part_user }
flags = Flags
flags_title_community = Flags for this Community
flags_title_other = Flags
@@ 98,10 96,8 @@ moderation_dashboard_some = Moderation Dashboard (Pending Actions)
moderators = Moderators
modlog = Modlog
modlog_event_approve_post = Post Approved:
-modlog_event_delete_post_1 = Deleted a post by
-modlog_event_delete_post_2 = in
-modlog_event_delete_comment_1 = Deleted a comment by
-modlog_event_delete_comment_2 = on
+modlog_event_delete_post = Deleted a post by { $part_user } in { $part_community }
+modlog_event_delete_comment = Deleted a comment by { $part_user } in { $part_community }
modlog_event_reject_post = Post Rejected:
modlog_event_suspend_user = User Suspended:
modlog_event_unsuspend_user = User Unsuspended:
@@ 118,9 114,11 @@ not_site_admin = You are not an instance admin
nothing = Looks like there's nothing here.
nothing_yet = Looks like there's nothing here (yet!).
notifications = Notifications
-notification_comment_mention_1 = You were mentioned in
+notification_comment_mention = You were mentioned in { $part_comment } on { $part_post }:
+notification_comment_mention_part_comment = a comment
+notification_comment_reply = Reply to { $part_your_comment } on { $part_post }:
+notification_comment_reply_part_your_comment = your comment
notification_post_mention = You were mentioned in a post:
-on = on
on_your_post = on your post
open_menu = Open Menu
poll_new_closes_prompt = Closes in:
@@ 153,6 151,10 @@ post_new_missing_content_type = Missing Content-Type for image upload
post_new_image_prompt = Image:
post_not_approved = This post has not been approved by the community.
post_rejected = This post has been rejected by the community.
+post_submitted = Submitted { $part_time }
+post_submitted_by = Submitted { $part_time } by { $part_user }
+post_submitted_by_to = Submitted { $part_time } by { $part_user } to { $part_community }
+post_submitted_to = Submitted { $part_time } to { $part_community }
post_timeframe = Posts from:
preview = Preview
profile = Profile
@@ 163,7 165,6 @@ remove = remove
remove_upvote = Remove upvote
reply = reply
reply_submit = Reply
-reply_to = Reply to
requirement_none = all users
requirement_site_admin = site admins
save = Save
@@ 179,8 180,9 @@ sort_hot = hot
sort_new = new
sort_top = top
submit = Submit
-submitted = Submitted
text_with_markdown = Text (markdown supported)
+thing_comment = { $part_comment } on { $part_post }:
+thing_comment_part_comment = Comment
time_input_minutes = minutes
time_input_hours = hours
time_input_days = days
@@ 228,7 230,6 @@ timeframe_month = past month
timeframe_week = past week
timeframe_year = past year
title = Title
-to = to
to_parent = View Parent
to_post = Comment on
unknown = [unknown]
@@ 252,7 253,6 @@ user_suspended_note = This user has been suspended.
username_prompt = Username:
view_at_source = View at Source
view_more_comments = View More Comments
-your_comment = your comment
your_note = Personal Note
your_note_add = Add Personal Note
your_note_edit = Edit Personal Note
@@ 302,26 302,52 @@ impl<'a, T: HavingContent + 'a> render::Render for ContentView<'a, T> {
}
}
-#[render::component]
-pub fn FlagItem<'a>(flag: &'a RespFlagInfo<'a>, in_community: bool, lang: &'a crate::Translator) {
- let RespFlagDetails::Post { post } = &flag.details;
+pub struct FlagItem<'a> {
+ pub flag: &'a RespFlagInfo<'a>,
+ pub in_community: bool,
+ pub lang: &'a crate::Translator,
+}
- render::rsx! {
- <li class={"flagItem"}>
- <div class={"flaggedContent"}>
- <PostItemContent post={post} in_community no_user={false} lang />
- </div>
- {lang.tr(&lang::FLAGGED_BY)}{" "}<UserLink user={Some(&flag.flagger)} lang />
- {
- flag.content.as_ref().map(|content| {
- render::rsx! {
- <blockquote>
- {content.content_text.as_ref()}
- </blockquote>
- }
- })
- }
- </li>
+impl<'a> render::Render for FlagItem<'a> {
+ fn render_into<W: std::fmt::Write + ?Sized>(self, w: &mut W) -> std::fmt::Result {
+ let Self {
+ flag,
+ in_community,
+ lang,
+ } = self;
+
+ let RespFlagDetails::Post { post } = &flag.details;
+
+ render::rsx! {
+ <li class={"flagItem"}>
+ <div class={"flaggedContent"}>
+ <PostItemContent post={post} in_community no_user={false} lang />
+ </div>
+ {
+ lang::TrElements::new(
+ lang.tr(&lang::flagged_by(lang::LangPlaceholder(0))),
+ |id, w| {
+ match id {
+ 0 => render::rsx! {
+ <UserLink user={Some(&flag.flagger)} lang />
+ }.render_into(w),
+ _ => unreachable!(),
+ }
+ },
+ )
+ }
+ {
+ flag.content.as_ref().map(|content| {
+ render::rsx! {
+ <blockquote>
+ {content.content_text.as_ref()}
+ </blockquote>
+ }
+ })
+ }
+ </li>
+ }
+ .render_into(w)
}
}
@@ 464,58 490,69 @@ pub fn PostItem<'a>(
}
}
-#[render::component]
-pub fn PostItemContent<'a>(
+pub struct PostItemContent<'a> {
post: &'a RespPostListPost<'a>,
in_community: bool,
no_user: bool,
lang: &'a crate::Translator,
-) {
- let post_href = format!("/posts/{}", post.as_ref().as_ref().id);
+}
- render::rsx! {
- <>
- <div class={"titleLine"}>
- <a href={post_href.clone()}>
- {post.as_ref().as_ref().sensitive.then(|| hitide_icons::SENSITIVE.img(lang.tr(&lang::SENSITIVE)))}
- {post.as_ref().as_ref().title.as_ref()}
- </a>
- {
- post.as_ref().href.as_ref().map(|href| {
- render::rsx! {
- <em><a href={href.as_ref()}>{abbreviate_link(href)}{" ↗"}</a></em>
- }
- })
- }
- </div>
- <small>
- {lang.tr(&lang::SUBMITTED)}
- {" "}
- <TimeAgo since={chrono::DateTime::parse_from_rfc3339(&post.as_ref().created).unwrap()} lang />
- {
- if no_user {
- None
- } else {
- Some(render::rsx! {
- <>
- {" "}{lang.tr(&lang::BY)}{" "}<UserLink lang user={post.as_ref().author.as_ref()} />
- </>
+impl<'a> render::Render for PostItemContent<'a> {
+ fn render_into<W: std::fmt::Write + ?Sized>(self, w: &mut W) -> std::fmt::Result {
+ let Self {
+ post,
+ in_community,
+ no_user,
+ lang,
+ } = self;
+
+ let post_href = format!("/posts/{}", post.as_ref().as_ref().id);
+
+ render::rsx! {
+ <>
+ <div class={"titleLine"}>
+ <a href={post_href.clone()}>
+ {post.as_ref().as_ref().sensitive.then(|| hitide_icons::SENSITIVE.img(lang.tr(&lang::SENSITIVE)))}
+ {post.as_ref().as_ref().title.as_ref()}
+ </a>
+ {
+ post.as_ref().href.as_ref().map(|href| {
+ render::rsx! {
+ <em><a href={href.as_ref()}>{abbreviate_link(href)}{" ↗"}</a></em>
+ }
})
}
- }
- {
- if !in_community {
- Some(render::rsx! {
- <>{" "}{lang.tr(&lang::TO)}{" "}<CommunityLink community={&post.as_ref().community} /></>
- })
- } else {
- None
+ </div>
+ <small>
+ {
+ lang::TrElements::new(
+ lang.tr(&match (no_user, in_community) {
+ (false, false) => lang::post_submitted_by_to(lang::LangPlaceholder(0), lang::LangPlaceholder(1), lang::LangPlaceholder(2)),
+ (false, true) => lang::post_submitted_by(lang::LangPlaceholder(0), lang::LangPlaceholder(1)),
+ (true, false) => lang::post_submitted_to(lang::LangPlaceholder(0), lang::LangPlaceholder(2)),
+ (true, true) => lang::post_submitted(lang::LangPlaceholder(0)),
+ }),
+ |id, w| {
+ match id {
+ 0 => render::rsx! {
+ <TimeAgo since={chrono::DateTime::parse_from_rfc3339(&post.as_ref().created).unwrap()} lang />
+ }.render_into(w),
+ 1 => render::rsx! {
+ <UserLink lang user={post.as_ref().author.as_ref()} />
+ }.render_into(w),
+ 2 => render::rsx! {
+ <CommunityLink community={&post.as_ref().community} />
+ }.render_into(w),
+ _ => unreachable!(),
+ }
+ },
+ )
}
- }
- {" | "}
- <a href={post_href}>{lang.tr(&lang::post_comments_count(post.replies_count_total)).into_owned()}</a>
- </small>
- </>
+ {" | "}
+ <a href={post_href}>{lang.tr(&lang::post_comments_count(post.replies_count_total)).into_owned()}</a>
+ </small>
+ </>
+ }.render_into(w)
}
}
@@ 536,8 573,26 @@ impl<'a> render::Render for ThingItem<'a> {
(render::rsx! {
<li>
<small>
- <a href={format!("/comments/{}", comment.as_ref().id)}>{lang.tr(&lang::comment())}</a>
- {" "}{lang.tr(&lang::on())}{" "}<a href={format!("/posts/{}", comment.post.id)}>{comment.post.title.as_ref()}</a>{":"}
+ {
+ lang::TrElements::new(
+ lang.tr(&lang::thing_comment(lang::LangPlaceholder(0), lang::LangPlaceholder(1))),
+ |id, w| {
+ match id {
+ 0 => render::rsx! {
+ <a href={format!("/comments/{}", comment.as_ref().id)}>
+ {lang.tr(&lang::thing_comment_part_comment())}
+ </a>
+ }.render_into(w),
+ 1 => render::rsx! {
+ <a href={format!("/posts/{}", comment.post.id)}>
+ {comment.post.title.as_ref()}
+ </a>
+ }.render_into(w),
+ _ => unreachable!(),
+ }
+ }
+ )
+ }
</small>
<ContentView src={comment} />
</li>
@@ 806,11 861,26 @@ impl<'a> render::Render for NotificationItem<'a> {
(render::rsx! {
<>
<div>
- {lang.tr(&lang::reply_to())}
- {" "}
- <a href={format!("/comments/{}", comment.as_ref().id)}>{lang.tr(&lang::your_comment())}</a>
- {" "}{lang.tr(&lang::on())}{" "}<a href={format!("/posts/{}", post.as_ref().as_ref().id)}>{post.as_ref().as_ref().title.as_ref()}</a>
- {":"}
+ {
+ lang::TrElements::new(
+ lang.tr(&lang::notification_comment_reply(lang::LangPlaceholder(0), lang::LangPlaceholder(1))),
+ |id, w| {
+ match id {
+ 0 => render::rsx! {
+ <a href={format!("/comments/{}", comment.as_ref().id)}>
+ {lang.tr(&lang::notification_comment_reply_part_your_comment())}
+ </a>
+ }.render_into(w),
+ 1 => render::rsx! {
+ <a href={format!("/posts/{}", post.as_ref().as_ref().id)}>
+ {post.as_ref().as_ref().title.as_ref()}
+ </a>
+ }.render_into(w),
+ _ => unreachable!(),
+ }
+ }
+ )
+ }
</div>
<div class={"body"}>
<small>
@@ 827,13 897,26 @@ impl<'a> render::Render for NotificationItem<'a> {
(render::rsx! {
<>
<div>
- {lang.tr(&lang::notification_comment_mention_1())}{" "}
- <a href={format!("/comments/{}", comment.as_ref().id)}>{lang.tr(&lang::a_comment())}</a>
- {" "}{lang.tr(&lang::on())}{" "}
- <a href={format!("/posts/{}", post.as_ref().as_ref().id)}>
- {post.as_ref().as_ref().title.as_ref()}
- </a>
- {":"}
+ {
+ lang::TrElements::new(
+ lang.tr(&lang::notification_comment_mention(lang::LangPlaceholder(0), lang::LangPlaceholder(1))),
+ |id, w| {
+ match id {
+ 0 => render::rsx! {
+ <a href={format!("/comments/{}", comment.as_ref().id)}>
+ {lang.tr(&lang::notification_comment_mention_part_comment())}
+ </a>
+ }.render_into(w),
+ 1 => render::rsx! {
+ <a href={format!("/posts/{}", post.as_ref().as_ref().id)}>
+ {post.as_ref().as_ref().title.as_ref()}
+ </a>
+ }.render_into(w),
+ _ => unreachable!(),
+ }
+ },
+ )
+ }
<div class={"body"}>
<small>
<cite><UserLink lang user={comment.author.as_ref()} /></cite>
@@ 873,31 956,43 @@ impl<'a> render::Render for SiteModlogEventItem<'a> {
match &event.details {
RespSiteModlogEventDetails::DeletePost { author, community } => {
- (render::rsx! {
- <>
- {lang.tr(&lang::MODLOG_EVENT_DELETE_POST_1)}
- {" "}
- <UserLink user={Some(author)} lang={&lang} />
- {" "}
- {lang.tr(&lang::MODLOG_EVENT_DELETE_POST_2)}
- {" "}
- <CommunityLink community />
- </>
- })
+ lang::TrElements::new(
+ lang.tr(&lang::modlog_event_delete_post(
+ lang::LangPlaceholder(0),
+ lang::LangPlaceholder(1),
+ )),
+ |id, w| match id {
+ 0 => render::rsx! {
+ <UserLink user={Some(author)} lang={&lang} />
+ }
+ .render_into(w),
+ 1 => render::rsx! {
+ <CommunityLink community />
+ }
+ .render_into(w),
+ _ => unreachable!(),
+ },
+ )
.render_into(writer)?;
}
RespSiteModlogEventDetails::DeleteComment { author, post } => {
- (render::rsx! {
- <>
- {lang.tr(&lang::MODLOG_EVENT_DELETE_COMMENT_1)}
- {" "}
- <UserLink user={Some(author)} lang={&lang} />
- {" "}
- {lang.tr(&lang::MODLOG_EVENT_DELETE_COMMENT_2)}
- {" "}
- <a href={format!("/posts/{}", post.id)}>{post.title.as_ref()}</a>
- </>
- })
+ lang::TrElements::new(
+ lang.tr(&lang::modlog_event_delete_comment(
+ lang::LangPlaceholder(0),
+ lang::LangPlaceholder(1),
+ )),
+ |id, w| match id {
+ 0 => render::rsx! {
+ <UserLink user={Some(author)} lang={&lang} />
+ }
+ .render_into(w),
+ 1 => render::rsx! {
+ <a href={format!("/posts/{}", post.id)}>{post.title.as_ref()}</a>
+ }
+ .render_into(w),
+ _ => unreachable!(),
+ },
+ )
.render_into(writer)?;
}
RespSiteModlogEventDetails::SuspendUser { user } => {
@@ 5,6 5,7 @@ use super::{
use crate::components::{HTPage, MaybeFillOption, MaybeFillTextArea};
use crate::lang;
use crate::resp_types::RespInstanceInfo;
+use render::Render;
use std::borrow::Cow;
use std::collections::HashMap;
use std::convert::TryInto;
@@ 53,20 54,42 @@ async fn page_administration(
<a href={"/administration/edit"}>{lang.tr(&lang::administration_edit())}</a>
<ul>
<li>
- {lang.tr(&lang::ADMINISTRATION_SIGNUP_ALLOWED)}{" "}
- <strong>{lang.tr(if api_res.signup_allowed {
- &lang::ALLOWED_TRUE
- } else {
- &lang::ALLOWED_FALSE
- })}</strong>
+ {
+ lang::TrElements::new(
+ lang.tr(&lang::administration_signup_allowed(lang::LangPlaceholder(0))),
+ |id, w| {
+ match id {
+ 0 => render::rsx! {
+ <strong>{lang.tr(if api_res.signup_allowed {
+ &lang::ALLOWED_TRUE
+ } else {
+ &lang::ALLOWED_FALSE
+ })}</strong>
+ }.render_into(w),
+ _ => unreachable!(),
+ }
+ }
+ )
+ }
</li>
<li>
- {lang.tr(&lang::ADMINISTRATION_INVITATIONS_ENABLED)}{" "}
- <strong>{lang.tr(if api_res.invitations_enabled {
- &lang::ENABLED_TRUE
- } else {
- &lang::ENABLED_FALSE
- })}</strong>
+ {
+ lang::TrElements::new(
+ lang.tr(&lang::administration_invitations_enabled(lang::LangPlaceholder(0))),
+ |id, w| {
+ match id {
+ 0 => render::rsx! {
+ <strong>{lang.tr(if api_res.invitations_enabled {
+ &lang::ENABLED_TRUE
+ } else {
+ &lang::ENABLED_FALSE
+ })}</strong>
+ }.render_into(w),
+ _ => unreachable!(),
+ }
+ }
+ )
+ }
{
if api_res.invitations_enabled {
Some(render::rsx! {
@@ 14,6 14,7 @@ use crate::resp_types::{
RespPostInfo,
};
use crate::util::author_is_me;
+use render::Render;
use serde_derive::{Deserialize, Serialize};
use std::borrow::Cow;
use std::collections::HashMap;
@@ 150,6 151,8 @@ async fn page_post_inner(
let title = post.as_ref().as_ref().title.as_ref();
+ let created = chrono::DateTime::parse_from_rfc3339(&post.as_ref().created)?;
+
Ok(html_response(render::html! {
<HTPage base_data={&base_data} lang={&lang} title={title}>
{
@@ 240,10 243,25 @@ async fn page_post_inner(
</div>
<br />
<p>
- {lang.tr(&lang::submitted())}
- {" "}<TimeAgo since={chrono::DateTime::parse_from_rfc3339(&post.as_ref().created)?} lang={&lang} />
- {" "}{lang.tr(&lang::by())}{" "}<UserLink lang={&lang} user={post.as_ref().author.as_ref()} />
- {" "}{lang.tr(&lang::to())}{" "}<CommunityLink community={&post.as_ref().community} />
+ {
+ lang::TrElements::new(
+ lang.tr(&lang::post_submitted_by_to(lang::LangPlaceholder(0), lang::LangPlaceholder(1), lang::LangPlaceholder(2))),
+ |id, w| {
+ match id {
+ 0 => render::rsx! {
+ <TimeAgo since={created} lang={&lang} />
+ }.render_into(w),
+ 1 => render::rsx! {
+ <UserLink lang={&lang} user={post.as_ref().author.as_ref()} />
+ }.render_into(w),
+ 2 => render::rsx! {
+ <CommunityLink community={&post.as_ref().community} />
+ }.render_into(w),
+ _ => unreachable!(),
+ }
+ }
+ )
+ }
</p>
{
post.as_ref().href.as_ref().map(|href| {