mirror of
https://git.joinplu.me/Plume/Plume.git
synced 2024-12-23 02:26:36 +00:00
Follow Blog's API change
This commit is contained in:
parent
5a03fd7340
commit
115b5b31a4
9 changed files with 106 additions and 70 deletions
|
@ -86,14 +86,14 @@ impl Blog {
|
||||||
inserted.ap_url = instance.compute_box(BLOG_PREFIX, &inserted.actor_id, "");
|
inserted.ap_url = instance.compute_box(BLOG_PREFIX, &inserted.actor_id, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
if inserted.fqn.is_empty() {
|
if inserted.fqn.to_string().is_empty() {
|
||||||
// This might not enough for some titles such as all-Japanese title,
|
// This might not enough for some titles such as all-Japanese title,
|
||||||
// but better than doing nothing.
|
// but better than doing nothing.
|
||||||
let fqn = make_fqn(&inserted.title);
|
let username = make_fqn(&inserted.title);
|
||||||
if instance.local {
|
if instance.local {
|
||||||
inserted.fqn = fqn;
|
inserted.fqn = Fqn::new_local(username)?;
|
||||||
} else {
|
} else {
|
||||||
inserted.fqn = format!("{}@{}", &fqn, instance.public_domain);
|
inserted.fqn = Fqn::new_remote(username, instance.public_domain)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,7 +174,7 @@ impl Blog {
|
||||||
|
|
||||||
pub fn to_activity(&self, conn: &Connection) -> Result<CustomGroup> {
|
pub fn to_activity(&self, conn: &Connection) -> Result<CustomGroup> {
|
||||||
let mut blog = ApActor::new(self.inbox_url.parse()?, Group::new());
|
let mut blog = ApActor::new(self.inbox_url.parse()?, Group::new());
|
||||||
blog.set_preferred_username(&self.fqn);
|
blog.set_preferred_username(self.fqn.to_string());
|
||||||
blog.set_name(self.title.clone());
|
blog.set_name(self.title.clone());
|
||||||
blog.set_outbox(self.outbox_url.parse()?);
|
blog.set_outbox(self.outbox_url.parse()?);
|
||||||
blog.set_summary(self.summary_html.to_string());
|
blog.set_summary(self.summary_html.to_string());
|
||||||
|
@ -399,27 +399,18 @@ impl FromId<DbConn> for Blog {
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut new_blog = NewBlog {
|
let actor_id = iri_percent_encode_seg(
|
||||||
actor_id: iri_percent_encode_seg(
|
&acct
|
||||||
&acct
|
.name()
|
||||||
.name()
|
.and_then(|name| name.to_as_string())
|
||||||
.and_then(|name| name.to_as_string())
|
.ok_or(Error::MissingApProperty)?,
|
||||||
.ok_or(Error::MissingApProperty)?,
|
);
|
||||||
),
|
|
||||||
outbox_url,
|
|
||||||
inbox_url,
|
|
||||||
public_key: acct.ext_one.public_key.public_key_pem.to_string(),
|
|
||||||
private_key: None,
|
|
||||||
theme: None,
|
|
||||||
..NewBlog::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let object = ApObject::new(acct.inner);
|
let object = ApObject::new(acct.inner);
|
||||||
new_blog.title = object
|
let title = object
|
||||||
.name()
|
.name()
|
||||||
.and_then(|name| name.to_as_string())
|
.and_then(|name| name.to_as_string())
|
||||||
.unwrap_or(name);
|
.unwrap_or(name.clone());
|
||||||
new_blog.summary_html = SafeString::new(
|
let summary_html = SafeString::new(
|
||||||
&object
|
&object
|
||||||
.summary()
|
.summary()
|
||||||
.and_then(|summary| summary.to_as_string())
|
.and_then(|summary| summary.to_as_string())
|
||||||
|
@ -441,7 +432,6 @@ impl FromId<DbConn> for Blog {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.map(|m| m.id);
|
.map(|m| m.id);
|
||||||
new_blog.icon_id = icon_id;
|
|
||||||
|
|
||||||
let banner_id = object
|
let banner_id = object
|
||||||
.image()
|
.image()
|
||||||
|
@ -458,13 +448,12 @@ impl FromId<DbConn> for Blog {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.map(|m| m.id);
|
.map(|m| m.id);
|
||||||
new_blog.banner_id = banner_id;
|
|
||||||
|
|
||||||
new_blog.summary = acct.ext_two.source.content;
|
let summary = acct.ext_two.source.content;
|
||||||
|
|
||||||
let any_base = AnyBase::from_extended(object)?;
|
let any_base = AnyBase::from_extended(object)?;
|
||||||
let id = any_base.id().ok_or(Error::MissingApProperty)?;
|
let id = any_base.id().ok_or(Error::MissingApProperty)?;
|
||||||
new_blog.ap_url = id.to_string();
|
let ap_url = id.to_string();
|
||||||
|
|
||||||
let inst = id
|
let inst = id
|
||||||
.authority_components()
|
.authority_components()
|
||||||
|
@ -488,7 +477,29 @@ impl FromId<DbConn> for Blog {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
new_blog.instance_id = instance.id;
|
let instance_id = instance.id;
|
||||||
|
let fqn = if instance.local {
|
||||||
|
Fqn::new_local(name)?
|
||||||
|
} else {
|
||||||
|
Fqn::new_remote(name, instance.public_domain)?
|
||||||
|
};
|
||||||
|
|
||||||
|
let new_blog = NewBlog {
|
||||||
|
actor_id,
|
||||||
|
outbox_url,
|
||||||
|
inbox_url,
|
||||||
|
fqn,
|
||||||
|
public_key: acct.ext_one.public_key.public_key_pem.to_string(),
|
||||||
|
private_key: None,
|
||||||
|
theme: None,
|
||||||
|
title,
|
||||||
|
summary,
|
||||||
|
ap_url,
|
||||||
|
summary_html,
|
||||||
|
icon_id,
|
||||||
|
banner_id,
|
||||||
|
instance_id,
|
||||||
|
};
|
||||||
|
|
||||||
Blog::insert(conn, new_blog)
|
Blog::insert(conn, new_blog)
|
||||||
}
|
}
|
||||||
|
@ -544,12 +555,19 @@ impl NewBlog {
|
||||||
let (pub_key, priv_key) = sign::gen_keypair();
|
let (pub_key, priv_key) = sign::gen_keypair();
|
||||||
Ok(NewBlog {
|
Ok(NewBlog {
|
||||||
actor_id,
|
actor_id,
|
||||||
|
fqn: Fqn::new_local(make_fqn(&title))?,
|
||||||
title,
|
title,
|
||||||
summary,
|
summary,
|
||||||
instance_id,
|
instance_id,
|
||||||
public_key: String::from_utf8(pub_key).or(Err(Error::Signature))?,
|
public_key: String::from_utf8(pub_key).or(Err(Error::Signature))?,
|
||||||
private_key: Some(String::from_utf8(priv_key).or(Err(Error::Signature))?),
|
private_key: Some(String::from_utf8(priv_key).or(Err(Error::Signature))?),
|
||||||
..NewBlog::default()
|
outbox_url: Default::default(),
|
||||||
|
inbox_url: Default::default(),
|
||||||
|
ap_url: Default::default(),
|
||||||
|
summary_html: Default::default(),
|
||||||
|
icon_id: Default::default(),
|
||||||
|
banner_id: Default::default(),
|
||||||
|
theme: Default::default(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -836,7 +854,7 @@ pub(crate) mod tests {
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
fill_database(conn);
|
fill_database(conn);
|
||||||
|
|
||||||
let blog = Blog::insert(
|
let _ = Blog::insert(
|
||||||
conn,
|
conn,
|
||||||
NewBlog::new_local(
|
NewBlog::new_local(
|
||||||
"Some%20Name".to_owned(),
|
"Some%20Name".to_owned(),
|
||||||
|
@ -848,7 +866,6 @@ pub(crate) mod tests {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(blog.fqn, "SomeName");
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
ap_url, blogs::Blog, db_conn::DbConn, instance::Instance, medias::Media, mentions::Mention,
|
ap_url, blogs::Blog, db_conn::DbConn, instance::Instance, medias::Media, mentions::Mention,
|
||||||
post_authors::*, safe_string::SafeString, schema::posts, tags::*, timeline::*, users::User,
|
post_authors::*, safe_string::SafeString, schema::posts, tags::*, timeline::*, users::User,
|
||||||
Connection, Error, PostEvent::*, Result, CONFIG, POST_CHAN,
|
Connection, Error, Fqn, PostEvent::*, Result, CONFIG, POST_CHAN,
|
||||||
};
|
};
|
||||||
use activitystreams::{
|
use activitystreams::{
|
||||||
activity::{Create, Delete, Update},
|
activity::{Create, Delete, Update},
|
||||||
|
@ -28,7 +28,7 @@ use riker::actors::{Publish, Tell};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
static BLOG_FQN_CACHE: Lazy<Mutex<HashMap<i32, String>>> = Lazy::new(|| Mutex::new(HashMap::new()));
|
static BLOG_FQN_CACHE: Lazy<Mutex<HashMap<i32, Fqn>>> = Lazy::new(|| Mutex::new(HashMap::new()));
|
||||||
|
|
||||||
#[derive(Queryable, Identifiable, Clone, AsChangeset, Debug)]
|
#[derive(Queryable, Identifiable, Clone, AsChangeset, Debug)]
|
||||||
#[changeset_options(treat_none_as_null = "true")]
|
#[changeset_options(treat_none_as_null = "true")]
|
||||||
|
@ -255,7 +255,7 @@ impl Post {
|
||||||
ap_url(&format!(
|
ap_url(&format!(
|
||||||
"{}/~/{}/{}/",
|
"{}/~/{}/{}/",
|
||||||
CONFIG.base_url,
|
CONFIG.base_url,
|
||||||
iri_percent_encode_seg(&blog.fqn),
|
&blog.fqn,
|
||||||
iri_percent_encode_seg(slug)
|
iri_percent_encode_seg(slug)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -298,9 +298,9 @@ impl Post {
|
||||||
/// This caches query result. The best way to cache query result is holding it in `Post`s field
|
/// This caches query result. The best way to cache query result is holding it in `Post`s field
|
||||||
/// but Diesel doesn't allow it currently.
|
/// but Diesel doesn't allow it currently.
|
||||||
/// If sometime Diesel allow it, this method should be removed.
|
/// If sometime Diesel allow it, this method should be removed.
|
||||||
pub fn get_blog_fqn(&self, conn: &Connection) -> String {
|
pub fn get_blog_fqn(&self, conn: &Connection) -> Fqn {
|
||||||
if let Some(blog_fqn) = BLOG_FQN_CACHE.lock().unwrap().get(&self.blog_id) {
|
if let Some(blog_fqn) = BLOG_FQN_CACHE.lock().unwrap().get(&self.blog_id) {
|
||||||
return blog_fqn.to_string();
|
return blog_fqn.to_owned();
|
||||||
}
|
}
|
||||||
let blog_fqn = self.get_blog(conn).unwrap().fqn;
|
let blog_fqn = self.get_blog(conn).unwrap().fqn;
|
||||||
BLOG_FQN_CACHE
|
BLOG_FQN_CACHE
|
||||||
|
|
|
@ -77,6 +77,7 @@ impl ActorFactoryArgs<(Arc<Searcher>, DbPool)> for SearchActor {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::diesel::Connection;
|
use crate::diesel::Connection;
|
||||||
|
use crate::Fqn;
|
||||||
use crate::{
|
use crate::{
|
||||||
blog_authors::{BlogAuthor, NewBlogAuthor},
|
blog_authors::{BlogAuthor, NewBlogAuthor},
|
||||||
blogs::{Blog, NewBlog},
|
blogs::{Blog, NewBlog},
|
||||||
|
@ -90,7 +91,7 @@ mod tests {
|
||||||
Connection as Conn, CONFIG,
|
Connection as Conn, CONFIG,
|
||||||
};
|
};
|
||||||
use diesel::r2d2::ConnectionManager;
|
use diesel::r2d2::ConnectionManager;
|
||||||
use plume_common::utils::random_hex;
|
use plume_common::utils::{make_fqn, random_hex};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
|
@ -190,13 +191,22 @@ mod tests {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
let title = random_hex();
|
||||||
let blog = NewBlog {
|
let blog = NewBlog {
|
||||||
instance_id: instance.id,
|
instance_id: instance.id,
|
||||||
actor_id: random_hex(),
|
actor_id: random_hex(),
|
||||||
ap_url: random_hex(),
|
ap_url: random_hex(),
|
||||||
inbox_url: random_hex(),
|
inbox_url: random_hex(),
|
||||||
outbox_url: random_hex(),
|
outbox_url: random_hex(),
|
||||||
..Default::default()
|
fqn: Fqn::new_local(make_fqn(&title)).unwrap(),
|
||||||
|
title,
|
||||||
|
summary: Default::default(),
|
||||||
|
summary_html: Default::default(),
|
||||||
|
private_key: Default::default(),
|
||||||
|
public_key: Default::default(),
|
||||||
|
icon_id: Default::default(),
|
||||||
|
banner_id: Default::default(),
|
||||||
|
theme: Default::default(),
|
||||||
};
|
};
|
||||||
let blog = Blog::insert(conn, blog).unwrap();
|
let blog = Blog::insert(conn, blog).unwrap();
|
||||||
BlogAuthor::insert(
|
BlogAuthor::insert(
|
||||||
|
|
|
@ -385,7 +385,7 @@ mod tests {
|
||||||
use super::valid_slug;
|
use super::valid_slug;
|
||||||
use crate::init_rocket;
|
use crate::init_rocket;
|
||||||
use diesel::Connection;
|
use diesel::Connection;
|
||||||
use plume_common::utils::random_hex;
|
use plume_common::utils::{random_hex, make_fqn};
|
||||||
use plume_models::{
|
use plume_models::{
|
||||||
blog_authors::{BlogAuthor, NewBlogAuthor},
|
blog_authors::{BlogAuthor, NewBlogAuthor},
|
||||||
blogs::{Blog, NewBlog},
|
blogs::{Blog, NewBlog},
|
||||||
|
@ -394,7 +394,7 @@ mod tests {
|
||||||
post_authors::{NewPostAuthor, PostAuthor},
|
post_authors::{NewPostAuthor, PostAuthor},
|
||||||
posts::{NewPost, Post},
|
posts::{NewPost, Post},
|
||||||
safe_string::SafeString,
|
safe_string::SafeString,
|
||||||
users::{NewUser, User, AUTH_COOKIE},
|
users::{NewUser, User, AUTH_COOKIE}, Fqn,
|
||||||
};
|
};
|
||||||
use rocket::{
|
use rocket::{
|
||||||
http::{Cookie, Cookies, SameSite},
|
http::{Cookie, Cookies, SameSite},
|
||||||
|
@ -424,9 +424,9 @@ mod tests {
|
||||||
fn edit_link_within_post_card() {
|
fn edit_link_within_post_card() {
|
||||||
let (client, (instance, user, blog, post)) = setup();
|
let (client, (instance, user, blog, post)) = setup();
|
||||||
|
|
||||||
let blog_path = uri!(super::activity_details: name = &blog.fqn).to_string();
|
let blog_path = uri!(super::activity_details: name = &blog.fqn.to_string()).to_string();
|
||||||
let edit_link = uri!(
|
let edit_link = uri!(
|
||||||
super::super::posts::edit: blog = &blog.fqn,
|
super::super::posts::edit: blog = &blog.fqn.to_string(),
|
||||||
slug = &post.slug
|
slug = &post.slug
|
||||||
)
|
)
|
||||||
.to_string();
|
.to_string();
|
||||||
|
@ -497,14 +497,23 @@ mod tests {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let user = User::insert(conn, user).unwrap();
|
let user = User::insert(conn, user).unwrap();
|
||||||
|
let title = random_hex();
|
||||||
let blog = NewBlog {
|
let blog = NewBlog {
|
||||||
instance_id: instance.id,
|
instance_id: instance.id,
|
||||||
title: random_hex(),
|
fqn: Fqn::new_local(make_fqn(&title)).unwrap(),
|
||||||
|
title,
|
||||||
actor_id: random_hex(),
|
actor_id: random_hex(),
|
||||||
ap_url: random_hex(),
|
ap_url: random_hex(),
|
||||||
inbox_url: random_hex(),
|
inbox_url: random_hex(),
|
||||||
outbox_url: random_hex(),
|
outbox_url: random_hex(),
|
||||||
..Default::default()
|
summary: Default::default(),
|
||||||
|
summary_html: Default::default(),
|
||||||
|
public_key: Default::default(),
|
||||||
|
private_key: Default::default(),
|
||||||
|
icon_id: Default::default(),
|
||||||
|
banner_id: Default::default(),
|
||||||
|
theme: Default::default(),
|
||||||
|
|
||||||
};
|
};
|
||||||
let blog = Blog::insert(conn, blog).unwrap();
|
let blog = Blog::insert(conn, blog).unwrap();
|
||||||
BlogAuthor::insert(
|
BlogAuthor::insert(
|
||||||
|
|
|
@ -407,7 +407,7 @@ pub fn interact(conn: DbConn, user: Option<User>, target: String) -> Option<Redi
|
||||||
|
|
||||||
if let Ok(post) = Post::from_id(&conn, &target, None, CONFIG.proxy()) {
|
if let Ok(post) = Post::from_id(&conn, &target, None, CONFIG.proxy()) {
|
||||||
return Some(Redirect::to(uri!(
|
return Some(Redirect::to(uri!(
|
||||||
super::posts::details: blog = post.get_blog(&conn).expect("Can't retrieve blog").fqn,
|
super::posts::details: blog = post.get_blog(&conn).expect("Can't retrieve blog").fqn.to_string(),
|
||||||
slug = &post.slug,
|
slug = &post.slug,
|
||||||
responding_to = _
|
responding_to = _
|
||||||
)));
|
)));
|
||||||
|
@ -418,7 +418,7 @@ pub fn interact(conn: DbConn, user: Option<User>, target: String) -> Option<Redi
|
||||||
let post = comment.get_post(&conn).expect("Can't retrieve post");
|
let post = comment.get_post(&conn).expect("Can't retrieve post");
|
||||||
return Some(Redirect::to(uri!(
|
return Some(Redirect::to(uri!(
|
||||||
super::posts::details: blog =
|
super::posts::details: blog =
|
||||||
post.get_blog(&conn).expect("Can't retrieve blog").fqn,
|
post.get_blog(&conn).expect("Can't retrieve blog").fqn.to_string(),
|
||||||
slug = &post.slug,
|
slug = &post.slug,
|
||||||
responding_to = comment.id
|
responding_to = comment.id
|
||||||
)));
|
)));
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<meta content="@blog.summary_html" property="og:description" />
|
<meta content="@blog.summary_html" property="og:description" />
|
||||||
<meta content="@blog.icon_url(ctx.0)" property="og:image" />
|
<meta content="@blog.icon_url(ctx.0)" property="og:image" />
|
||||||
|
|
||||||
<link href='@Instance::get_local().unwrap().compute_box("~", &blog.fqn, "atom.xml")' rel='alternate' type='application/atom+xml'>
|
<link href='@Instance::get_local().unwrap().compute_box("~", &blog.fqn.to_string(), "atom.xml")' rel='alternate' type='application/atom+xml'>
|
||||||
<link href='@blog.ap_url' rel='alternate' type='application/activity+json'>
|
<link href='@blog.ap_url' rel='alternate' type='application/activity+json'>
|
||||||
<link href='@blog.ap_url' rel='canonical'>
|
<link href='@blog.ap_url' rel='canonical'>
|
||||||
@if !ctx.2.clone().map(|u| u.hide_custom_css).unwrap_or(false) {
|
@if !ctx.2.clone().map(|u| u.hide_custom_css).unwrap_or(false) {
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
<a href="@uri!(blogs::details: name = &blog.fqn, page = _)" dir="auto">@blog.title</a>
|
<a href="@uri!(blogs::details: name = &blog.fqn.to_string(), page = _)" dir="auto">@blog.title</a>
|
||||||
}, {
|
}, {
|
||||||
<div class="hidden">
|
<div class="hidden">
|
||||||
@for author in authors {
|
@for author in authors {
|
||||||
|
@ -58,8 +58,8 @@
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
@if ctx.2.clone().and_then(|u| u.is_author_in(ctx.0, &blog).ok()).unwrap_or(false) {
|
@if ctx.2.clone().and_then(|u| u.is_author_in(ctx.0, &blog).ok()).unwrap_or(false) {
|
||||||
<a href="@uri!(posts::new: blog = &blog.fqn)" class="button" dir="auto">@i18n!(ctx.1, "New article")</a>
|
<a href="@uri!(posts::new: blog = &blog.fqn.to_string())" class="button" dir="auto">@i18n!(ctx.1, "New article")</a>
|
||||||
<a href="@uri!(blogs::edit: name = &blog.fqn)" class="button" dir="auto">@i18n!(ctx.1, "Edit")</a>
|
<a href="@uri!(blogs::edit: name = &blog.fqn.to_string())" class="button" dir="auto">@i18n!(ctx.1, "Edit")</a>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@
|
||||||
<section>
|
<section>
|
||||||
<h2 dir="auto">
|
<h2 dir="auto">
|
||||||
@i18n!(ctx.1, "Latest articles")
|
@i18n!(ctx.1, "Latest articles")
|
||||||
<small><a href="@uri!(blogs::atom_feed: name = &blog.fqn)" title="Atom feed">@icon!("rss")</a></small>
|
<small><a href="@uri!(blogs::atom_feed: name = &blog.fqn.to_string())" title="Atom feed">@icon!("rss")</a></small>
|
||||||
</h2>
|
</h2>
|
||||||
@if posts.is_empty() {
|
@if posts.is_empty() {
|
||||||
<p dir="auto">@i18n!(ctx.1, "No posts to see here yet.")</p>
|
<p dir="auto">@i18n!(ctx.1, "No posts to see here yet.")</p>
|
||||||
|
|
|
@ -12,10 +12,10 @@
|
||||||
@(ctx: BaseContext, blog: &Blog, medias: Vec<Media>, form: &EditForm, errors: ValidationErrors)
|
@(ctx: BaseContext, blog: &Blog, medias: Vec<Media>, form: &EditForm, errors: ValidationErrors)
|
||||||
|
|
||||||
@:base(ctx, i18n!(ctx.1, "Edit \"{}\""; &blog.title), {}, {
|
@:base(ctx, i18n!(ctx.1, "Edit \"{}\""; &blog.title), {}, {
|
||||||
<a href="@uri!(blogs::details: name = &blog.fqn, page = _)">@blog.title</a>
|
<a href="@uri!(blogs::details: name = &blog.fqn.to_string(), page = _)">@blog.title</a>
|
||||||
}, {
|
}, {
|
||||||
<h1>@i18n!(ctx.1, "Edit \"{}\""; &blog.title)</h1>
|
<h1>@i18n!(ctx.1, "Edit \"{}\""; &blog.title)</h1>
|
||||||
<form method="post" action="@uri!(blogs::update: name = &blog.fqn)">
|
<form method="post" action="@uri!(blogs::update: name = &blog.fqn.to_string())">
|
||||||
<!-- Rocket hack to use various HTTP methods -->
|
<!-- Rocket hack to use various HTTP methods -->
|
||||||
<input type=hidden name="_method" value="put">
|
<input type=hidden name="_method" value="put">
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
|
|
||||||
<h2>@i18n!(ctx.1, "Danger zone")</h2>
|
<h2>@i18n!(ctx.1, "Danger zone")</h2>
|
||||||
<p>@i18n!(ctx.1, "Be very careful, any action taken here can't be reversed.")</p>
|
<p>@i18n!(ctx.1, "Be very careful, any action taken here can't be reversed.")</p>
|
||||||
<form method="post" action="@uri!(blogs::delete: name = &blog.fqn)" onsubmit="return confirm('@i18n!(ctx.1, "Are you sure that you want to permanently delete this blog?")')">
|
<form method="post" action="@uri!(blogs::delete: name = &blog.fqn.to_string())" onsubmit="return confirm('@i18n!(ctx.1, "Are you sure that you want to permanently delete this blog?")')">
|
||||||
<input type="submit" class="inline-block button destructive" value="@i18n!(ctx.1, "Permanently delete this blog")">
|
<input type="submit" class="inline-block button destructive" value="@i18n!(ctx.1, "Permanently delete this blog")">
|
||||||
</form>
|
</form>
|
||||||
})
|
})
|
||||||
|
|
|
@ -6,19 +6,19 @@
|
||||||
|
|
||||||
<div class="card h-entry">
|
<div class="card h-entry">
|
||||||
@if article.cover_id.is_some() {
|
@if article.cover_id.is_some() {
|
||||||
<a class="cover-link" href="@uri!(posts::details: blog = article.get_blog_fqn(ctx.0), slug = &article.slug, responding_to = _)">
|
<a class="cover-link" href="@uri!(posts::details: blog = article.get_blog_fqn(ctx.0).to_string(), slug = &article.slug, responding_to = _)">
|
||||||
<div class="cover" style="background-image: url('@Html(article.cover_url(ctx.0).unwrap_or_default())')"></div>
|
<div class="cover" style="background-image: url('@Html(article.cover_url(ctx.0).unwrap_or_default())')"></div>
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
<header dir="auto">
|
<header dir="auto">
|
||||||
<h3 class="p-name">
|
<h3 class="p-name">
|
||||||
<a class="u-url" href="@uri!(posts::details: blog = article.get_blog_fqn(ctx.0), slug = &article.slug, responding_to = _)">
|
<a class="u-url" href="@uri!(posts::details: blog = article.get_blog_fqn(ctx.0).to_string(), slug = &article.slug, responding_to = _)">
|
||||||
@article.title
|
@article.title
|
||||||
</a>
|
</a>
|
||||||
</h3>
|
</h3>
|
||||||
@if ctx.2.clone().and_then(|u| article.is_author(ctx.0, u.id).ok()).unwrap_or(false) {
|
@if ctx.2.clone().and_then(|u| article.is_author(ctx.0, u.id).ok()).unwrap_or(false) {
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<a class="button" href="@uri!(posts::edit: blog = &article.get_blog_fqn(ctx.0), slug = &article.slug)">@i18n!(ctx.1, "Edit")</a>
|
<a class="button" href="@uri!(posts::edit: blog = &article.get_blog_fqn(ctx.0).to_string(), slug = &article.slug)">@i18n!(ctx.1, "Edit")</a>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</header>
|
</header>
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
@if article.published {
|
@if article.published {
|
||||||
⋅ <span class="dt-published" datetime="@article.creation_date.format("%F %T")">@article.creation_date.format("%B %e, %Y")</span>
|
⋅ <span class="dt-published" datetime="@article.creation_date.format("%F %T")">@article.creation_date.format("%B %e, %Y")</span>
|
||||||
}
|
}
|
||||||
⋅ <a href="@uri!(blogs::details: name = &article.get_blog_fqn(ctx.0), page = _)">@article.get_blog(ctx.0).unwrap().title</a>
|
⋅ <a href="@uri!(blogs::details: name = &article.get_blog_fqn(ctx.0).to_string(), page = _)">@article.get_blog(ctx.0).unwrap().title</a>
|
||||||
⋅
|
⋅
|
||||||
</div>
|
</div>
|
||||||
@if !article.published {
|
@if !article.published {
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
@if article.cover_id.is_some() {
|
@if article.cover_id.is_some() {
|
||||||
<meta property="og:image" content="@Html(article.cover_url(ctx.0).unwrap_or_default())"/>
|
<meta property="og:image" content="@Html(article.cover_url(ctx.0).unwrap_or_default())"/>
|
||||||
}
|
}
|
||||||
<meta property="og:url" content="@uri!(posts::details: blog = &blog.fqn, slug = &article.slug, responding_to = _)"/>
|
<meta property="og:url" content="@uri!(posts::details: blog = &blog.fqn.to_string(), slug = &article.slug, responding_to = _)"/>
|
||||||
<meta property="og:description" content="@article.subtitle"/>
|
<meta property="og:description" content="@article.subtitle"/>
|
||||||
<link rel="canonical" href="@article.ap_url"/>
|
<link rel="canonical" href="@article.ap_url"/>
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
<a href="@uri!(blogs::details: name = &blog.fqn, page = _)">@blog.title</a>
|
<a href="@uri!(blogs::details: name = &blog.fqn.to_string(), page = _)">@blog.title</a>
|
||||||
}, {
|
}, {
|
||||||
<div class="h-entry">
|
<div class="h-entry">
|
||||||
<header
|
<header
|
||||||
|
@ -78,7 +78,7 @@
|
||||||
</section>
|
</section>
|
||||||
@if ctx.2.is_some() {
|
@if ctx.2.is_some() {
|
||||||
<section class="actions">
|
<section class="actions">
|
||||||
<form id="likes" class="likes" action="@uri!(likes::create: blog = &blog.fqn, slug = &article.slug)#likes" method="POST">
|
<form id="likes" class="likes" action="@uri!(likes::create: blog = &blog.fqn.to_string(), slug = &article.slug)#likes" method="POST">
|
||||||
<p aria-label="@i18n!(ctx.1, "One like", "{0} likes"; n_likes)" title="@i18n!(ctx.1, "One like", "{0} likes"; n_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
|
@n_likes
|
||||||
</p>
|
</p>
|
||||||
|
@ -89,7 +89,7 @@
|
||||||
<button type="submit" class="action">@icon!("heart") @i18n!(ctx.1, "Add yours")</button>
|
<button type="submit" class="action">@icon!("heart") @i18n!(ctx.1, "Add yours")</button>
|
||||||
}
|
}
|
||||||
</form>
|
</form>
|
||||||
<form id="reshares" class="reshares" action="@uri!(reshares::create: blog = &blog.fqn, slug = &article.slug)#reshares" method="POST">
|
<form id="reshares" class="reshares" action="@uri!(reshares::create: blog = &blog.fqn.to_string(), slug = &article.slug)#reshares" method="POST">
|
||||||
<p aria-label="@i18n!(ctx.1, "One boost", "{0} boosts"; n_reshares)" title="@i18n!(ctx.1, "One boost", "{0} boosts"; n_reshares)">
|
<p aria-label="@i18n!(ctx.1, "One boost", "{0} boosts"; n_reshares)" title="@i18n!(ctx.1, "One boost", "{0} boosts"; n_reshares)">
|
||||||
@n_reshares
|
@n_reshares
|
||||||
</p>
|
</p>
|
||||||
|
@ -104,7 +104,7 @@
|
||||||
} else {
|
} else {
|
||||||
<p class="center">@Html(i18n!(ctx.1, "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article";
|
<p class="center">@Html(i18n!(ctx.1, "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article";
|
||||||
format!("<a href='{}'>", escape(&uri!(session::new: m = _).to_string())), "</a>",
|
format!("<a href='{}'>", escape(&uri!(session::new: m = _).to_string())), "</a>",
|
||||||
format!("<a href='{}'>", escape(&uri!(posts::remote_interact: blog_name = &blog.fqn, slug = &article.slug).to_string())), "</a>"
|
format!("<a href='{}'>", escape(&uri!(posts::remote_interact: blog_name = &blog.fqn.to_string(), slug = &article.slug).to_string())), "</a>"
|
||||||
))
|
))
|
||||||
</p>
|
</p>
|
||||||
<section class="actions">
|
<section class="actions">
|
||||||
|
@ -112,14 +112,14 @@
|
||||||
<p aria-label="@i18n!(ctx.1, "One like", "{0} likes"; n_likes)" title="@i18n!(ctx.1, "One like", "{0} likes"; n_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
|
@n_likes
|
||||||
</p>
|
</p>
|
||||||
<a href="@uri!(posts::remote_interact: blog_name = &blog.fqn, slug = &article.slug)" class="action">@icon!("heart") @i18n!(ctx.1, "Add yours")</a>
|
<a href="@uri!(posts::remote_interact: blog_name = &blog.fqn.to_string(), slug = &article.slug)" class="action">@icon!("heart") @i18n!(ctx.1, "Add yours")</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="reshares" class="reshares">
|
<div id="reshares" class="reshares">
|
||||||
<p aria-label="@i18n!(ctx.1, "One boost", "{0} boost"; n_reshares)" title="@i18n!(ctx.1, "One boost", "{0} boosts"; n_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
|
@n_reshares
|
||||||
</p>
|
</p>
|
||||||
<a href="@uri!(posts::remote_interact: blog_name = &blog.fqn, slug = &article.slug)" class="action">@icon!("repeat") @i18n!(ctx.1, "Boost")</a>
|
<a href="@uri!(posts::remote_interact: blog_name = &blog.fqn.to_string(), slug = &article.slug)" class="action">@icon!("repeat") @i18n!(ctx.1, "Boost")</a>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@
|
||||||
<h2>@i18n!(ctx.1, "Comments")</h2>
|
<h2>@i18n!(ctx.1, "Comments")</h2>
|
||||||
|
|
||||||
@if ctx.2.is_some() {
|
@if ctx.2.is_some() {
|
||||||
<form method="post" action="@uri!(comments::create: blog_name = &blog.fqn, slug = &article.slug)#comments">
|
<form method="post" action="@uri!(comments::create: blog_name = &blog.fqn.to_string(), slug = &article.slug)#comments">
|
||||||
@(Input::new("warning", i18n!(ctx.1, "Content warning"))
|
@(Input::new("warning", i18n!(ctx.1, "Content warning"))
|
||||||
.default(&comment_form.warning)
|
.default(&comment_form.warning)
|
||||||
.error(&comment_errors)
|
.error(&comment_errors)
|
||||||
|
@ -162,7 +162,7 @@
|
||||||
|
|
||||||
@if !comments.is_empty() {
|
@if !comments.is_empty() {
|
||||||
@for comm in comments {
|
@for comm in comments {
|
||||||
@:comment(ctx, &comm, Some(&article.ap_url), &blog.fqn, &article.slug)
|
@:comment(ctx, &comm, Some(&article.ap_url), &blog.fqn.to_string(), &article.slug)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
<p class="center" dir="auto">@i18n!(ctx.1, "No comments yet. Be the first to react!")</p>
|
<p class="center" dir="auto">@i18n!(ctx.1, "No comments yet. Be the first to react!")</p>
|
||||||
|
@ -173,7 +173,7 @@
|
||||||
@if ctx.2.clone().and_then(|u| article.is_author(ctx.0, u.id).ok()).unwrap_or(false) {
|
@if ctx.2.clone().and_then(|u| article.is_author(ctx.0, u.id).ok()).unwrap_or(false) {
|
||||||
<aside class="bottom-bar">
|
<aside class="bottom-bar">
|
||||||
<div>
|
<div>
|
||||||
<form class="inline" method="post" action="@uri!(posts::delete: blog_name = &blog.fqn, slug = &article.slug)">
|
<form class="inline" method="post" action="@uri!(posts::delete: blog_name = &blog.fqn.to_string(), slug = &article.slug)">
|
||||||
<input class="button destructive" onclick="return confirm('@i18n!(ctx.1, "Are you sure?")')" type="submit" value="@i18n!(ctx.1, "Delete")">
|
<input class="button destructive" onclick="return confirm('@i18n!(ctx.1, "Are you sure?")')" type="submit" value="@i18n!(ctx.1, "Delete")">
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -186,9 +186,9 @@
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@if !article.published {
|
@if !article.published {
|
||||||
<a class="button secondary" href="@uri!(posts::edit: blog = &blog.fqn, slug = &article.slug)">@i18n!(ctx.1, "Publish")</a>
|
<a class="button secondary" href="@uri!(posts::edit: blog = &blog.fqn.to_string(), slug = &article.slug)">@i18n!(ctx.1, "Publish")</a>
|
||||||
}
|
}
|
||||||
<a class="button" href="@uri!(posts::edit: blog = &blog.fqn, slug = &article.slug)">@i18n!(ctx.1, "Edit")</a>
|
<a class="button" href="@uri!(posts::edit: blog = &blog.fqn.to_string(), slug = &article.slug)">@i18n!(ctx.1, "Edit")</a>
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue