parent
eff2698664
commit
fe6e69d7c4
3
migrations/postgres/2019-03-05-082814_add_fqn/down.sql
Normal file
3
migrations/postgres/2019-03-05-082814_add_fqn/down.sql
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
-- This file should undo anything in `up.sql`
|
||||||
|
ALTER TABLE blogs DROP COLUMN fqn;
|
||||||
|
ALTER TABLE users DROP COLUMN fqn;
|
18
migrations/postgres/2019-03-05-082814_add_fqn/up.sql
Normal file
18
migrations/postgres/2019-03-05-082814_add_fqn/up.sql
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
-- Your SQL goes here
|
||||||
|
ALTER TABLE blogs ADD COLUMN fqn TEXT NOT NULL DEFAULT '';
|
||||||
|
UPDATE blogs SET fqn =
|
||||||
|
(CASE WHEN (SELECT local FROM instances WHERE id = instance_id) THEN
|
||||||
|
actor_id
|
||||||
|
ELSE
|
||||||
|
(actor_id || '@' || (SELECT public_domain FROM instances WHERE id = instance_id LIMIT 1))
|
||||||
|
END)
|
||||||
|
WHERE fqn = '';
|
||||||
|
|
||||||
|
ALTER TABLE users ADD COLUMN fqn TEXT NOT NULL DEFAULT '';
|
||||||
|
UPDATE users SET fqn =
|
||||||
|
(CASE WHEN (SELECT local FROM instances WHERE id = instance_id) THEN
|
||||||
|
username
|
||||||
|
ELSE
|
||||||
|
(username || '@' || (SELECT public_domain FROM instances WHERE id = instance_id LIMIT 1))
|
||||||
|
END)
|
||||||
|
WHERE fqn = '';
|
77
migrations/sqlite/2019-03-05-082846_add_fqn/down.sql
Normal file
77
migrations/sqlite/2019-03-05-082846_add_fqn/down.sql
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
-- This file should undo anything in `up.sql`
|
||||||
|
CREATE TABLE blogs_no_fqn (
|
||||||
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
actor_id VARCHAR NOT NULL,
|
||||||
|
title VARCHAR NOT NULL,
|
||||||
|
summary TEXT NOT NULL DEFAULT '',
|
||||||
|
outbox_url VARCHAR NOT NULL UNIQUE,
|
||||||
|
inbox_url VARCHAR NOT NULL UNIQUE,
|
||||||
|
instance_id INTEGER REFERENCES instances(id) ON DELETE CASCADE NOT NULL,
|
||||||
|
creation_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
ap_url text not null default '' UNIQUE,
|
||||||
|
private_key TEXT,
|
||||||
|
public_key TEXT NOT NULL DEFAULT '',
|
||||||
|
CONSTRAINT blog_unique UNIQUE (actor_id, instance_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO blogs_no_fqn SELECT
|
||||||
|
id,
|
||||||
|
actor_id,
|
||||||
|
title,
|
||||||
|
summary,
|
||||||
|
outbox_url,
|
||||||
|
inbox_url,
|
||||||
|
instance_id,
|
||||||
|
creation_date,
|
||||||
|
ap_url,
|
||||||
|
private_key,
|
||||||
|
public_key
|
||||||
|
FROM blogs;
|
||||||
|
DROP TABLE blogs;
|
||||||
|
ALTER TABLE blogs_no_fqn RENAME TO blogs;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE users_no_fqn (
|
||||||
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||||
|
username VARCHAR NOT NULL,
|
||||||
|
display_name VARCHAR NOT NULL DEFAULT '',
|
||||||
|
outbox_url VARCHAR NOT NULL UNIQUE,
|
||||||
|
inbox_url VARCHAR NOT NULL UNIQUE,
|
||||||
|
is_admin BOOLEAN NOT NULL DEFAULT 'f',
|
||||||
|
summary TEXT NOT NULL DEFAULT '',
|
||||||
|
email TEXT,
|
||||||
|
hashed_password TEXT,
|
||||||
|
instance_id INTEGER REFERENCES instances(id) ON DELETE CASCADE NOT NULL,
|
||||||
|
creation_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
ap_url TEXT NOT NULL default '' UNIQUE,
|
||||||
|
private_key TEXT,
|
||||||
|
public_key TEXT NOT NULL DEFAULT '',
|
||||||
|
shared_inbox_url VARCHAR,
|
||||||
|
followers_endpoint VARCHAR NOT NULL DEFAULT '' UNIQUE,
|
||||||
|
avatar_id INTEGER REFERENCES medias(id) ON DELETE SET NULL,
|
||||||
|
last_fetched_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
CONSTRAINT blog_authors_unique UNIQUE (username, instance_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO users_no_fqn SELECT
|
||||||
|
id,
|
||||||
|
username,
|
||||||
|
display_name,
|
||||||
|
outbox_url,
|
||||||
|
inbox_url,
|
||||||
|
is_admin,
|
||||||
|
summary,
|
||||||
|
email,
|
||||||
|
hashed_password,
|
||||||
|
instance_id,
|
||||||
|
creation_date,
|
||||||
|
ap_url,
|
||||||
|
private_key,
|
||||||
|
public_key,
|
||||||
|
shared_inbox_url,
|
||||||
|
followers_endpoint,
|
||||||
|
avatar_id,
|
||||||
|
last_fetched_date
|
||||||
|
FROM users;
|
||||||
|
DROP TABLE users;
|
||||||
|
ALTER TABLE users_no_fqn RENAME TO users;
|
18
migrations/sqlite/2019-03-05-082846_add_fqn/up.sql
Normal file
18
migrations/sqlite/2019-03-05-082846_add_fqn/up.sql
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
-- Your SQL goes here
|
||||||
|
ALTER TABLE blogs ADD COLUMN fqn TEXT NOT NULL DEFAULT '';
|
||||||
|
UPDATE blogs SET fqn =
|
||||||
|
(CASE WHEN (SELECT local FROM instances WHERE id = instance_id) THEN
|
||||||
|
actor_id
|
||||||
|
ELSE
|
||||||
|
(actor_id || '@' || (SELECT public_domain FROM instances WHERE id = instance_id LIMIT 1))
|
||||||
|
END)
|
||||||
|
WHERE fqn = '';
|
||||||
|
|
||||||
|
ALTER TABLE users ADD COLUMN fqn TEXT NOT NULL DEFAULT '';
|
||||||
|
UPDATE users SET fqn =
|
||||||
|
(CASE WHEN (SELECT local FROM instances WHERE id = instance_id) THEN
|
||||||
|
username
|
||||||
|
ELSE
|
||||||
|
(username || '@' || (SELECT public_domain FROM instances WHERE id = instance_id LIMIT 1))
|
||||||
|
END)
|
||||||
|
WHERE fqn = '';
|
@ -43,6 +43,7 @@ pub struct Blog {
|
|||||||
pub ap_url: String,
|
pub ap_url: String,
|
||||||
pub private_key: Option<String>,
|
pub private_key: Option<String>,
|
||||||
pub public_key: String,
|
pub public_key: String,
|
||||||
|
pub fqn: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Insertable)]
|
#[derive(Default, Insertable)]
|
||||||
@ -87,6 +88,15 @@ impl Blog {
|
|||||||
"",
|
"",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if inserted.fqn.is_empty() {
|
||||||
|
if instance.local {
|
||||||
|
inserted.fqn = inserted.actor_id.clone();
|
||||||
|
} else {
|
||||||
|
inserted.fqn = format!("{}@{}", inserted.actor_id, instance.public_domain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inserted.save_changes(conn).map_err(Error::from)
|
inserted.save_changes(conn).map_err(Error::from)
|
||||||
});
|
});
|
||||||
get!(blogs);
|
get!(blogs);
|
||||||
@ -129,19 +139,17 @@ impl Blog {
|
|||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_local(conn: &Connection, name: &str) -> Result<Blog> {
|
|
||||||
Blog::find_by_name(conn, name, Instance::get_local(conn)?.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn find_by_fqn(conn: &Connection, fqn: &str) -> Result<Blog> {
|
pub fn find_by_fqn(conn: &Connection, fqn: &str) -> Result<Blog> {
|
||||||
let mut split_fqn = fqn.split('@');
|
let from_db = blogs::table
|
||||||
let actor = split_fqn.next().ok_or(Error::InvalidValue)?;
|
.filter(blogs::fqn.eq(fqn))
|
||||||
if let Some(domain) = split_fqn.next() { // remote blog
|
.limit(1)
|
||||||
Instance::find_by_domain(conn, domain)
|
.load::<Blog>(conn)?
|
||||||
.and_then(|instance| Blog::find_by_name(conn, actor, instance.id))
|
.into_iter()
|
||||||
.or_else(|_| Blog::fetch_from_webfinger(conn, fqn))
|
.next();
|
||||||
} else { // local blog
|
if let Some(from_db) = from_db {
|
||||||
Blog::find_local(conn, actor)
|
Ok(from_db)
|
||||||
|
} else {
|
||||||
|
Blog::fetch_from_webfinger(conn, fqn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,18 +346,6 @@ impl Blog {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_fqn(&self, conn: &Connection) -> String {
|
|
||||||
if self.instance_id == Instance::get_local(conn).ok().expect("Blog::get_fqn: local instance error").id {
|
|
||||||
self.actor_id.clone()
|
|
||||||
} else {
|
|
||||||
format!(
|
|
||||||
"{}@{}",
|
|
||||||
self.actor_id,
|
|
||||||
self.get_instance(conn).ok().expect("Blog::get_fqn: instance error").public_domain
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn delete(&self, conn: &Connection, searcher: &Searcher) -> Result<()> {
|
pub fn delete(&self, conn: &Connection, searcher: &Searcher) -> Result<()> {
|
||||||
for post in Post::get_for_blog(conn, &self)? {
|
for post in Post::get_for_blog(conn, &self)? {
|
||||||
post.delete(&(conn, searcher))?;
|
post.delete(&(conn, searcher))?;
|
||||||
@ -649,7 +645,7 @@ pub(crate) mod tests {
|
|||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Blog::find_local(conn, "SomeName").unwrap().id,
|
Blog::find_by_fqn(conn, "SomeName").unwrap().id,
|
||||||
blog.id
|
blog.id
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -673,7 +669,7 @@ pub(crate) mod tests {
|
|||||||
).unwrap(),
|
).unwrap(),
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
assert_eq!(blog.get_fqn(conn), "SomeName");
|
assert_eq!(blog.fqn, "SomeName");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
@ -71,7 +71,7 @@ impl Mention {
|
|||||||
.set_href_string(user.ap_url.clone())?;
|
.set_href_string(user.ap_url.clone())?;
|
||||||
mention
|
mention
|
||||||
.link_props
|
.link_props
|
||||||
.set_name_string(format!("@{}", user.get_fqn(conn)))?;
|
.set_name_string(format!("@{}", user.fqn))?;
|
||||||
Ok(mention)
|
Ok(mention)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ impl Notification {
|
|||||||
pub fn get_url(&self, conn: &Connection) -> Option<String> {
|
pub fn get_url(&self, conn: &Connection) -> Option<String> {
|
||||||
match self.kind.as_ref() {
|
match self.kind.as_ref() {
|
||||||
notification_kind::COMMENT => self.get_post(conn).and_then(|p| Some(format!("{}#comment-{}", p.url(conn).ok()?, self.object_id))),
|
notification_kind::COMMENT => self.get_post(conn).and_then(|p| Some(format!("{}#comment-{}", p.url(conn).ok()?, self.object_id))),
|
||||||
notification_kind::FOLLOW => Some(format!("/@/{}/", self.get_actor(conn).ok()?.get_fqn(conn))),
|
notification_kind::FOLLOW => Some(format!("/@/{}/", self.get_actor(conn).ok()?.fqn)),
|
||||||
notification_kind::MENTION => Mention::get(conn, self.object_id).and_then(|mention|
|
notification_kind::MENTION => Mention::get(conn, self.object_id).and_then(|mention|
|
||||||
mention.get_post(conn).and_then(|p| p.url(conn))
|
mention.get_post(conn).and_then(|p| p.url(conn))
|
||||||
.or_else(|_| {
|
.or_else(|_| {
|
||||||
|
@ -269,7 +269,7 @@ impl Post {
|
|||||||
post.ap_url = ap_url(&format!(
|
post.ap_url = ap_url(&format!(
|
||||||
"{}/~/{}/{}/",
|
"{}/~/{}/{}/",
|
||||||
*BASE_URL,
|
*BASE_URL,
|
||||||
post.get_blog(conn)?.get_fqn(conn),
|
post.get_blog(conn)?.fqn,
|
||||||
post.slug
|
post.slug
|
||||||
));
|
));
|
||||||
let _: Post = post.save_changes(conn)?;
|
let _: Post = post.save_changes(conn)?;
|
||||||
@ -850,7 +850,7 @@ impl Post {
|
|||||||
|
|
||||||
pub fn url(&self, conn: &Connection) -> Result<String> {
|
pub fn url(&self, conn: &Connection) -> Result<String> {
|
||||||
let blog = self.get_blog(conn)?;
|
let blog = self.get_blog(conn)?;
|
||||||
Ok(format!("/~/{}/{}", blog.get_fqn(conn), self.slug))
|
Ok(format!("/~/{}/{}", blog.fqn, self.slug))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cover_url(&self, conn: &Connection) -> Option<String> {
|
pub fn cover_url(&self, conn: &Connection) -> Option<String> {
|
||||||
|
@ -43,6 +43,7 @@ table! {
|
|||||||
ap_url -> Text,
|
ap_url -> Text,
|
||||||
private_key -> Nullable<Text>,
|
private_key -> Nullable<Text>,
|
||||||
public_key -> Text,
|
public_key -> Text,
|
||||||
|
fqn -> Text,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,6 +202,7 @@ table! {
|
|||||||
followers_endpoint -> Varchar,
|
followers_endpoint -> Varchar,
|
||||||
avatar_id -> Nullable<Int4>,
|
avatar_id -> Nullable<Int4>,
|
||||||
last_fetched_date -> Timestamp,
|
last_fetched_date -> Timestamp,
|
||||||
|
fqn -> Text,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ impl Searcher {
|
|||||||
let writer = writer.as_mut().unwrap();
|
let writer = writer.as_mut().unwrap();
|
||||||
writer.add_document(doc!(
|
writer.add_document(doc!(
|
||||||
post_id => i64::from(post.id),
|
post_id => i64::from(post.id),
|
||||||
author => post.get_authors(conn)?.into_iter().map(|u| u.get_fqn(conn)).join(" "),
|
author => post.get_authors(conn)?.into_iter().map(|u| u.fqn).join(" "),
|
||||||
creation_date => i64::from(post.creation_date.num_days_from_ce()),
|
creation_date => i64::from(post.creation_date.num_days_from_ce()),
|
||||||
instance => Instance::get(conn, post.get_blog(conn)?.instance_id)?.public_domain.clone(),
|
instance => Instance::get(conn, post.get_blog(conn)?.instance_id)?.public_domain.clone(),
|
||||||
tag => Tag::for_post(conn, post.id)?.into_iter().map(|t| t.tag).join(" "),
|
tag => Tag::for_post(conn, post.id)?.into_iter().map(|t| t.tag).join(" "),
|
||||||
|
@ -64,6 +64,7 @@ pub struct User {
|
|||||||
pub followers_endpoint: String,
|
pub followers_endpoint: String,
|
||||||
pub avatar_id: Option<i32>,
|
pub avatar_id: Option<i32>,
|
||||||
pub last_fetched_date: NaiveDateTime,
|
pub last_fetched_date: NaiveDateTime,
|
||||||
|
pub fqn: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Insertable)]
|
#[derive(Default, Insertable)]
|
||||||
@ -119,8 +120,7 @@ impl User {
|
|||||||
if inserted.shared_inbox_url.is_none() {
|
if inserted.shared_inbox_url.is_none() {
|
||||||
inserted.shared_inbox_url = Some(ap_url(&format!(
|
inserted.shared_inbox_url = Some(ap_url(&format!(
|
||||||
"{}/inbox",
|
"{}/inbox",
|
||||||
Instance::get_local(conn)?
|
instance.public_domain
|
||||||
.public_domain
|
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,6 +132,14 @@ impl User {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if inserted.fqn.is_empty() {
|
||||||
|
if instance.local {
|
||||||
|
inserted.fqn = inserted.username.clone();
|
||||||
|
} else {
|
||||||
|
inserted.fqn = format!("{}@{}", inserted.username, instance.public_domain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inserted.save_changes(conn).map_err(Error::from)
|
inserted.save_changes(conn).map_err(Error::from)
|
||||||
});
|
});
|
||||||
get!(users);
|
get!(users);
|
||||||
@ -218,19 +226,17 @@ impl User {
|
|||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_local(conn: &Connection, username: &str) -> Result<User> {
|
|
||||||
User::find_by_name(conn, username, Instance::get_local(conn)?.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn find_by_fqn(conn: &Connection, fqn: &str) -> Result<User> {
|
pub fn find_by_fqn(conn: &Connection, fqn: &str) -> Result<User> {
|
||||||
let mut split_fqn = fqn.split('@');
|
let from_db = users::table
|
||||||
let username = split_fqn.next().ok_or(Error::InvalidValue)?;
|
.filter(users::fqn.eq(fqn))
|
||||||
if let Some(domain) = split_fqn.next() { // remote user
|
.limit(1)
|
||||||
Instance::find_by_domain(conn, domain)
|
.load::<User>(conn)?
|
||||||
.and_then(|instance| User::find_by_name(conn, username, instance.id))
|
.into_iter()
|
||||||
.or_else(|_| User::fetch_from_webfinger(conn, fqn))
|
.next();
|
||||||
} else { // local user
|
if let Some(from_db) = from_db {
|
||||||
User::find_local(conn, username)
|
Ok(from_db)
|
||||||
|
} else {
|
||||||
|
User::fetch_from_webfinger(conn, fqn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,18 +524,6 @@ impl User {
|
|||||||
.collect::<Vec<serde_json::Value>>())
|
.collect::<Vec<serde_json::Value>>())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_fqn(&self, conn: &Connection) -> String {
|
|
||||||
if self.instance_id == Instance::get_local(conn).ok().expect("User::get_fqn: instance error").id {
|
|
||||||
self.username.clone()
|
|
||||||
} else {
|
|
||||||
format!(
|
|
||||||
"{}@{}",
|
|
||||||
self.username,
|
|
||||||
self.get_instance(conn).ok().expect("User::get_fqn: instance error").public_domain
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_followers(&self, conn: &Connection) -> Result<Vec<User>> {
|
pub fn get_followers(&self, conn: &Connection) -> Result<Vec<User>> {
|
||||||
use schema::follows;
|
use schema::follows;
|
||||||
let follows = Follow::belonging_to(self).select(follows::follower_id);
|
let follows = Follow::belonging_to(self).select(follows::follower_id);
|
||||||
@ -805,11 +799,11 @@ impl User {
|
|||||||
(Utc::now().naive_utc() - self.last_fetched_date).num_days() > 1
|
(Utc::now().naive_utc() - self.last_fetched_date).num_days() > 1
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(&self, conn: &Connection) -> String {
|
pub fn name(&self) -> String {
|
||||||
if !self.display_name.is_empty() {
|
if !self.display_name.is_empty() {
|
||||||
self.display_name.clone()
|
self.display_name.clone()
|
||||||
} else {
|
} else {
|
||||||
self.get_fqn(conn)
|
self.fqn.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -987,7 +981,7 @@ pub(crate) mod tests {
|
|||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
test_user.id,
|
test_user.id,
|
||||||
User::find_by_fqn(conn, &test_user.get_fqn(conn)).unwrap().id
|
User::find_by_fqn(conn, &test_user.fqn).unwrap().id
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
test_user.id,
|
test_user.id,
|
||||||
|
@ -317,8 +317,9 @@ msgstr ""
|
|||||||
msgid "Articles"
|
msgid "Articles"
|
||||||
msgstr "المقالات"
|
msgstr "المقالات"
|
||||||
|
|
||||||
|
#, fuzzy
|
||||||
msgid "Subscribers"
|
msgid "Subscribers"
|
||||||
msgstr ""
|
msgstr "الوصف"
|
||||||
|
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Subscriptions"
|
msgid "Subscriptions"
|
||||||
|
@ -302,8 +302,9 @@ msgid ""
|
|||||||
"can, however, find a different one."
|
"can, however, find a different one."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#, fuzzy
|
||||||
msgid "Articles"
|
msgid "Articles"
|
||||||
msgstr ""
|
msgstr "Nueva publicación"
|
||||||
|
|
||||||
msgid "Subscribers"
|
msgid "Subscribers"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -336,8 +336,9 @@ msgstr ""
|
|||||||
msgid "Articles"
|
msgid "Articles"
|
||||||
msgstr "Articles"
|
msgstr "Articles"
|
||||||
|
|
||||||
|
#, fuzzy
|
||||||
msgid "Subscribers"
|
msgid "Subscribers"
|
||||||
msgstr ""
|
msgstr "Description"
|
||||||
|
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Subscriptions"
|
msgid "Subscriptions"
|
||||||
|
@ -332,8 +332,9 @@ msgstr ""
|
|||||||
msgid "Articles"
|
msgid "Articles"
|
||||||
msgstr "Artigos"
|
msgstr "Artigos"
|
||||||
|
|
||||||
|
#, fuzzy
|
||||||
msgid "Subscribers"
|
msgid "Subscribers"
|
||||||
msgstr ""
|
msgstr "Descrición"
|
||||||
|
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Subscriptions"
|
msgid "Subscriptions"
|
||||||
|
@ -335,8 +335,9 @@ msgstr ""
|
|||||||
msgid "Articles"
|
msgid "Articles"
|
||||||
msgstr "Articoli"
|
msgstr "Articoli"
|
||||||
|
|
||||||
|
#, fuzzy
|
||||||
msgid "Subscribers"
|
msgid "Subscribers"
|
||||||
msgstr ""
|
msgstr "Descrizione"
|
||||||
|
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Subscriptions"
|
msgid "Subscriptions"
|
||||||
|
@ -323,8 +323,9 @@ msgstr ""
|
|||||||
msgid "Articles"
|
msgid "Articles"
|
||||||
msgstr "記事"
|
msgstr "記事"
|
||||||
|
|
||||||
|
#, fuzzy
|
||||||
msgid "Subscribers"
|
msgid "Subscribers"
|
||||||
msgstr ""
|
msgstr "説明"
|
||||||
|
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Subscriptions"
|
msgid "Subscriptions"
|
||||||
|
@ -336,8 +336,9 @@ msgstr ""
|
|||||||
msgid "Articles"
|
msgid "Articles"
|
||||||
msgstr "artikler"
|
msgstr "artikler"
|
||||||
|
|
||||||
|
#, fuzzy
|
||||||
msgid "Subscribers"
|
msgid "Subscribers"
|
||||||
msgstr ""
|
msgstr "Lang beskrivelse"
|
||||||
|
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Subscriptions"
|
msgid "Subscriptions"
|
||||||
|
@ -301,8 +301,9 @@ msgstr ""
|
|||||||
msgid "Articles"
|
msgid "Articles"
|
||||||
msgstr "Artykuły"
|
msgstr "Artykuły"
|
||||||
|
|
||||||
|
#, fuzzy
|
||||||
msgid "Subscribers"
|
msgid "Subscribers"
|
||||||
msgstr ""
|
msgstr "Opis"
|
||||||
|
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Subscriptions"
|
msgid "Subscriptions"
|
||||||
|
@ -36,11 +36,11 @@ msgstr ""
|
|||||||
msgid "{0}'s avatar"
|
msgid "{0}'s avatar"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/blogs.rs:65
|
# src/routes/blogs.rs:64
|
||||||
msgid "You need to be logged in order to create a new blog"
|
msgid "You need to be logged in order to create a new blog"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/blogs.rs:135
|
# src/routes/blogs.rs:134
|
||||||
msgid "You are not allowed to delete this blog."
|
msgid "You are not allowed to delete this blog."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -317,8 +317,9 @@ msgstr ""
|
|||||||
msgid "Articles"
|
msgid "Articles"
|
||||||
msgstr "Artigos"
|
msgstr "Artigos"
|
||||||
|
|
||||||
|
#, fuzzy
|
||||||
msgid "Subscribers"
|
msgid "Subscribers"
|
||||||
msgstr ""
|
msgstr "Descrição"
|
||||||
|
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Subscriptions"
|
msgid "Subscriptions"
|
||||||
|
@ -339,8 +339,9 @@ msgstr ""
|
|||||||
msgid "Articles"
|
msgid "Articles"
|
||||||
msgstr "Статьи"
|
msgstr "Статьи"
|
||||||
|
|
||||||
|
#, fuzzy
|
||||||
msgid "Subscribers"
|
msgid "Subscribers"
|
||||||
msgstr ""
|
msgstr "Описание"
|
||||||
|
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Subscriptions"
|
msgid "Subscriptions"
|
||||||
|
@ -49,7 +49,7 @@ pub struct OAuthRequest {
|
|||||||
pub fn oauth(query: Form<OAuthRequest>, conn: DbConn) -> Result<Json<serde_json::Value>, ApiError> {
|
pub fn oauth(query: Form<OAuthRequest>, conn: DbConn) -> Result<Json<serde_json::Value>, ApiError> {
|
||||||
let app = App::find_by_client_id(&*conn, &query.client_id)?;
|
let app = App::find_by_client_id(&*conn, &query.client_id)?;
|
||||||
if app.client_secret == query.client_secret {
|
if app.client_secret == query.client_secret {
|
||||||
if let Ok(user) = User::find_local(&*conn, &query.username) {
|
if let Ok(user) = User::find_by_fqn(&*conn, &query.username) {
|
||||||
if user.auth(&query.password) {
|
if user.auth(&query.password) {
|
||||||
let token = ApiToken::insert(&*conn, NewApiToken {
|
let token = ApiToken::insert(&*conn, NewApiToken {
|
||||||
app_id: app.id,
|
app_id: app.id,
|
||||||
|
@ -34,7 +34,6 @@ pub fn details(intl: I18n, name: String, conn: DbConn, user: Option<User>, page:
|
|||||||
Ok(render!(blogs::details(
|
Ok(render!(blogs::details(
|
||||||
&(&*conn, &intl.catalog, user.clone()),
|
&(&*conn, &intl.catalog, user.clone()),
|
||||||
blog.clone(),
|
blog.clone(),
|
||||||
blog.get_fqn(&*conn),
|
|
||||||
authors,
|
authors,
|
||||||
articles_count,
|
articles_count,
|
||||||
page.0,
|
page.0,
|
||||||
@ -46,7 +45,7 @@ pub fn details(intl: I18n, name: String, conn: DbConn, user: Option<User>, page:
|
|||||||
|
|
||||||
#[get("/~/<name>", rank = 1)]
|
#[get("/~/<name>", rank = 1)]
|
||||||
pub fn activity_details(name: String, conn: DbConn, _ap: ApRequest) -> Option<ActivityStream<CustomGroup>> {
|
pub fn activity_details(name: String, conn: DbConn, _ap: ApRequest) -> Option<ActivityStream<CustomGroup>> {
|
||||||
let blog = Blog::find_local(&*conn, &name).ok()?;
|
let blog = Blog::find_by_fqn(&*conn, &name).ok()?;
|
||||||
Some(ActivityStream::new(blog.to_activity(&*conn).ok()?))
|
Some(ActivityStream::new(blog.to_activity(&*conn).ok()?))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +89,7 @@ pub fn create(conn: DbConn, form: LenientForm<NewBlogForm>, user: User, intl: I1
|
|||||||
Ok(_) => ValidationErrors::new(),
|
Ok(_) => ValidationErrors::new(),
|
||||||
Err(e) => e
|
Err(e) => e
|
||||||
};
|
};
|
||||||
if Blog::find_local(&*conn, &slug).is_ok() {
|
if Blog::find_by_fqn(&*conn, &slug).is_ok() {
|
||||||
errors.add("title", ValidationError {
|
errors.add("title", ValidationError {
|
||||||
code: Cow::from("existing_slug"),
|
code: Cow::from("existing_slug"),
|
||||||
message: Some(Cow::from("A blog with the same name already exists.")),
|
message: Some(Cow::from("A blog with the same name already exists.")),
|
||||||
@ -124,7 +123,7 @@ pub fn create(conn: DbConn, form: LenientForm<NewBlogForm>, user: User, intl: I1
|
|||||||
|
|
||||||
#[post("/~/<name>/delete")]
|
#[post("/~/<name>/delete")]
|
||||||
pub fn delete(conn: DbConn, name: String, user: Option<User>, intl: I18n, searcher: Searcher) -> Result<Redirect, Ructe>{
|
pub fn delete(conn: DbConn, name: String, user: Option<User>, intl: I18n, searcher: Searcher) -> Result<Redirect, Ructe>{
|
||||||
let blog = Blog::find_local(&*conn, &name).expect("blog::delete: blog not found");
|
let blog = Blog::find_by_fqn(&*conn, &name).expect("blog::delete: blog not found");
|
||||||
if user.clone().and_then(|u| u.is_author_in(&*conn, &blog).ok()).unwrap_or(false) {
|
if user.clone().and_then(|u| u.is_author_in(&*conn, &blog).ok()).unwrap_or(false) {
|
||||||
blog.delete(&conn, &searcher).expect("blog::expect: deletion error");
|
blog.delete(&conn, &searcher).expect("blog::expect: deletion error");
|
||||||
Ok(Redirect::to(uri!(super::instance::index)))
|
Ok(Redirect::to(uri!(super::instance::index)))
|
||||||
@ -139,7 +138,7 @@ pub fn delete(conn: DbConn, name: String, user: Option<User>, intl: I18n, search
|
|||||||
|
|
||||||
#[get("/~/<name>/outbox")]
|
#[get("/~/<name>/outbox")]
|
||||||
pub fn outbox(name: String, conn: DbConn) -> Option<ActivityStream<OrderedCollection>> {
|
pub fn outbox(name: String, conn: DbConn) -> Option<ActivityStream<OrderedCollection>> {
|
||||||
let blog = Blog::find_local(&*conn, &name).ok()?;
|
let blog = Blog::find_by_fqn(&*conn, &name).ok()?;
|
||||||
Some(blog.outbox(&*conn).ok()?)
|
Some(blog.outbox(&*conn).ok()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,14 +46,14 @@ pub fn details(blog: String, slug: String, conn: DbConn, user: Option<User>, res
|
|||||||
warning: previous.clone().map(|p| p.spoiler_text).unwrap_or_default(),
|
warning: previous.clone().map(|p| p.spoiler_text).unwrap_or_default(),
|
||||||
content: previous.clone().and_then(|p| Some(format!(
|
content: previous.clone().and_then(|p| Some(format!(
|
||||||
"@{} {}",
|
"@{} {}",
|
||||||
p.get_author(&*conn).ok()?.get_fqn(&*conn),
|
p.get_author(&*conn).ok()?.fqn,
|
||||||
Mention::list_for_comment(&*conn, p.id).ok()?
|
Mention::list_for_comment(&*conn, p.id).ok()?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|m| {
|
.filter_map(|m| {
|
||||||
let user = user.clone();
|
let user = user.clone();
|
||||||
if let Ok(mentioned) = m.get_mentioned(&*conn) {
|
if let Ok(mentioned) = m.get_mentioned(&*conn) {
|
||||||
if user.is_none() || mentioned.id != user.expect("posts::details_response: user error while listing mentions").id {
|
if user.is_none() || mentioned.id != user.expect("posts::details_response: user error while listing mentions").id {
|
||||||
Some(format!("@{}", mentioned.get_fqn(&*conn)))
|
Some(format!("@{}", mentioned.fqn))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ pub struct LoginForm {
|
|||||||
#[post("/login", data = "<form>")]
|
#[post("/login", data = "<form>")]
|
||||||
pub fn create(conn: DbConn, form: LenientForm<LoginForm>, flash: Option<FlashMessage>, mut cookies: Cookies, intl: I18n) -> Result<Redirect, Ructe> {
|
pub fn create(conn: DbConn, form: LenientForm<LoginForm>, flash: Option<FlashMessage>, mut cookies: Cookies, intl: I18n) -> Result<Redirect, Ructe> {
|
||||||
let user = User::find_by_email(&*conn, &form.email_or_name)
|
let user = User::find_by_email(&*conn, &form.email_or_name)
|
||||||
.or_else(|_| User::find_local(&*conn, &form.email_or_name));
|
.or_else(|_| User::find_by_fqn(&*conn, &form.email_or_name));
|
||||||
let mut errors = match form.validate() {
|
let mut errors = match form.validate() {
|
||||||
Ok(_) => ValidationErrors::new(),
|
Ok(_) => ValidationErrors::new(),
|
||||||
Err(e) => e
|
Err(e) => e
|
||||||
|
@ -203,7 +203,7 @@ pub fn activity_details(
|
|||||||
conn: DbConn,
|
conn: DbConn,
|
||||||
_ap: ApRequest,
|
_ap: ApRequest,
|
||||||
) -> Option<ActivityStream<CustomPerson>> {
|
) -> Option<ActivityStream<CustomPerson>> {
|
||||||
let user = User::find_local(&*conn, &name).ok()?;
|
let user = User::find_by_fqn(&*conn, &name).ok()?;
|
||||||
Some(ActivityStream::new(user.to_activity(&*conn).ok()?))
|
Some(ActivityStream::new(user.to_activity(&*conn).ok()?))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,7 +369,7 @@ pub fn create(conn: DbConn, form: LenientForm<NewUserForm>, intl: I18n) -> Resul
|
|||||||
|
|
||||||
#[get("/@/<name>/outbox")]
|
#[get("/@/<name>/outbox")]
|
||||||
pub fn outbox(name: String, conn: DbConn) -> Option<ActivityStream<OrderedCollection>> {
|
pub fn outbox(name: String, conn: DbConn) -> Option<ActivityStream<OrderedCollection>> {
|
||||||
let user = User::find_local(&*conn, &name).ok()?;
|
let user = User::find_by_fqn(&*conn, &name).ok()?;
|
||||||
user.outbox(&*conn).ok()
|
user.outbox(&*conn).ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,7 +381,7 @@ pub fn inbox(
|
|||||||
headers: Headers,
|
headers: Headers,
|
||||||
searcher: Searcher,
|
searcher: Searcher,
|
||||||
) -> Result<String, Option<status::BadRequest<&'static str>>> {
|
) -> Result<String, Option<status::BadRequest<&'static str>>> {
|
||||||
let user = User::find_local(&*conn, &name).map_err(|_| None)?;
|
let user = User::find_by_fqn(&*conn, &name).map_err(|_| None)?;
|
||||||
let act = data.1.into_inner();
|
let act = data.1.into_inner();
|
||||||
let sig = data.0;
|
let sig = data.0;
|
||||||
|
|
||||||
@ -429,7 +429,7 @@ pub fn ap_followers(
|
|||||||
conn: DbConn,
|
conn: DbConn,
|
||||||
_ap: ApRequest,
|
_ap: ApRequest,
|
||||||
) -> Option<ActivityStream<OrderedCollection>> {
|
) -> Option<ActivityStream<OrderedCollection>> {
|
||||||
let user = User::find_local(&*conn, &name).ok()?;
|
let user = User::find_by_fqn(&*conn, &name).ok()?;
|
||||||
let followers = user
|
let followers = user
|
||||||
.get_followers(&*conn).ok()?
|
.get_followers(&*conn).ok()?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -39,9 +39,9 @@ impl Resolver<DbConn> for WebfingerResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn find(acct: String, conn: DbConn) -> Result<Webfinger, ResolverError> {
|
fn find(acct: String, conn: DbConn) -> Result<Webfinger, ResolverError> {
|
||||||
User::find_local(&*conn, &acct)
|
User::find_by_fqn(&*conn, &acct)
|
||||||
.and_then(|usr| usr.webfinger(&*conn))
|
.and_then(|usr| usr.webfinger(&*conn))
|
||||||
.or_else(|_| Blog::find_local(&*conn, &acct)
|
.or_else(|_| Blog::find_by_fqn(&*conn, &acct)
|
||||||
.and_then(|blog| blog.webfinger(&*conn))
|
.and_then(|blog| blog.webfinger(&*conn))
|
||||||
.or(Err(ResolverError::NotFound)))
|
.or(Err(ResolverError::NotFound)))
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ macro_rules! render {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn translate_notification(ctx: BaseContext, notif: Notification) -> String {
|
pub fn translate_notification(ctx: BaseContext, notif: Notification) -> String {
|
||||||
let name = notif.get_actor(ctx.0).unwrap().name(ctx.0);
|
let name = notif.get_actor(ctx.0).unwrap().name();
|
||||||
match notif.kind.as_ref() {
|
match notif.kind.as_ref() {
|
||||||
notification_kind::COMMENT => i18n!(ctx.1, "{0} commented your article."; &name),
|
notification_kind::COMMENT => i18n!(ctx.1, "{0} commented your article."; &name),
|
||||||
notification_kind::FOLLOW => i18n!(ctx.1, "{0} is subscribed to you."; &name),
|
notification_kind::FOLLOW => i18n!(ctx.1, "{0} is subscribed to you."; &name),
|
||||||
@ -55,7 +55,7 @@ impl Size {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn avatar(conn: &Connection, user: &User, size: Size, pad: bool, catalog: &Catalog) -> Html<String> {
|
pub fn avatar(conn: &Connection, user: &User, size: Size, pad: bool, catalog: &Catalog) -> Html<String> {
|
||||||
let name = escape(&user.name(conn)).to_string();
|
let name = escape(&user.name()).to_string();
|
||||||
Html(format!(
|
Html(format!(
|
||||||
r#"<div class="avatar {size} {padded}"
|
r#"<div class="avatar {size} {padded}"
|
||||||
style="background-image: url('{url}');"
|
style="background-image: url('{url}');"
|
||||||
|
@ -5,26 +5,26 @@
|
|||||||
@use template_utils::*;
|
@use template_utils::*;
|
||||||
@use routes::*;
|
@use routes::*;
|
||||||
|
|
||||||
@(ctx: BaseContext, blog: Blog, fqn: String, authors: &Vec<User>, total_articles: i64, page: i32, n_pages: i32, is_author: bool, posts: Vec<Post>)
|
@(ctx: BaseContext, blog: Blog, authors: &Vec<User>, total_articles: i64, page: i32, n_pages: i32, is_author: bool, posts: Vec<Post>)
|
||||||
|
|
||||||
@:base(ctx, blog.title.clone(), {}, {
|
@:base(ctx, blog.title.clone(), {}, {
|
||||||
<a href="@uri!(blogs::details: name = &fqn, page = _)">@blog.title</a>
|
<a href="@uri!(blogs::details: name = &blog.fqn, page = _)">@blog.title</a>
|
||||||
}, {
|
}, {
|
||||||
<div class="hidden">
|
<div class="hidden">
|
||||||
@for author in authors {
|
@for author in authors {
|
||||||
<div class="h-card">
|
<div class="h-card">
|
||||||
<span class="p-name">@author.name(ctx.0)</span>
|
<span class="p-name">@author.name()</span>
|
||||||
<a class="u-url" href="@author.ap_url"></a>
|
<a class="u-url" href="@author.ap_url"></a>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="h-feed">
|
<div class="h-feed">
|
||||||
<h1><span class="p-name">@blog.title</span> <small>~@fqn</small></h1>
|
<h1><span class="p-name">@blog.title</span> <small>~@blog.fqn</small></h1>
|
||||||
<p>@blog.summary</p>
|
<p>@blog.summary</p>
|
||||||
<p>
|
<p>
|
||||||
@i18n!(ctx.1, "There's one author on this blog: ", "There are {0} authors on this blog: "; authors.len())
|
@i18n!(ctx.1, "There's one author on this blog: ", "There are {0} authors on this blog: "; authors.len())
|
||||||
@for author in authors {
|
@for author in authors {
|
||||||
<a class="author p-author" href="@uri!(user::details: name = author.get_fqn(ctx.0))">@author.name(ctx.0)</a>
|
<a class="author p-author" href="@uri!(user::details: name = &author.fqn)">@author.name()</a>
|
||||||
}
|
}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
@ -34,13 +34,13 @@
|
|||||||
<section>
|
<section>
|
||||||
<h2>
|
<h2>
|
||||||
@i18n!(ctx.1, "Latest articles")
|
@i18n!(ctx.1, "Latest articles")
|
||||||
<small><a href="@uri!(blogs::atom_feed: name = &fqn)" title="Atom feed">@icon!("rss")</a></small>
|
<small><a href="@uri!(blogs::atom_feed: name = &blog.fqn)" title="Atom feed">@icon!("rss")</a></small>
|
||||||
</h2>
|
</h2>
|
||||||
@if posts.len() < 1 {
|
@if posts.len() < 1 {
|
||||||
<p>@i18n!(ctx.1, "No posts to see here yet.")</p>
|
<p>@i18n!(ctx.1, "No posts to see here yet.")</p>
|
||||||
}
|
}
|
||||||
@if is_author {
|
@if is_author {
|
||||||
<a href="@uri!(posts::new: blog = &fqn)" class="button inline-block">@i18n!(ctx.1, "New article")</a>
|
<a href="@uri!(posts::new: blog = &blog.fqn)" class="button inline-block">@i18n!(ctx.1, "New article")</a>
|
||||||
}
|
}
|
||||||
<div class="cards">
|
<div class="cards">
|
||||||
@for article in posts {
|
@for article in posts {
|
||||||
@ -53,7 +53,7 @@
|
|||||||
@if is_author {
|
@if is_author {
|
||||||
<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 = &fqn)">
|
<form method="post" action="@uri!(blogs::delete: name = &blog.fqn)">
|
||||||
<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>
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<p>@i18n!(ctx.1, "Administred by")</p>
|
<p>@i18n!(ctx.1, "Administred by")</p>
|
||||||
@avatar(ctx.0, &admin, Size::Small, false, ctx.1)
|
@avatar(ctx.0, &admin, Size::Small, false, ctx.1)
|
||||||
<p><a href="@uri!(user::details: name = admin.get_fqn(ctx.0))">@admin.name(ctx.0)</a><small>@@@admin.get_fqn(ctx.0)</small></p>
|
<p><a href="@uri!(user::details: name = &admin.fqn)">@admin.name()</a><small>@@@admin.fqn</small></p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<p>@i18n!(ctx.1, "Runs Plume {0}"; env!("CARGO_PKG_VERSION"))</p>
|
<p>@i18n!(ctx.1, "Runs Plume {0}"; env!("CARGO_PKG_VERSION"))</p>
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
<div class="flex">
|
<div class="flex">
|
||||||
@avatar(ctx.0, &user, Size::Small, false, ctx.1)
|
@avatar(ctx.0, &user, Size::Small, false, ctx.1)
|
||||||
<p class="grow">
|
<p class="grow">
|
||||||
<a href="@uri!(user::details: name = user.get_fqn(ctx.0))">@user.name(ctx.0)</a>
|
<a href="@uri!(user::details: name = &user.fqn)">@user.name()</a>
|
||||||
<small>@format!("@{}", user.username)</small>
|
<small>@format!("@{}", user.username)</small>
|
||||||
</p>
|
</p>
|
||||||
@if !user.is_admin {
|
@if !user.is_admin {
|
||||||
|
@ -7,10 +7,10 @@
|
|||||||
@if let Some(ref comm) = Some(&comment_tree.comment) {
|
@if let Some(ref comm) = Some(&comment_tree.comment) {
|
||||||
@if let Some(author) = comm.get_author(ctx.0).ok() {
|
@if let Some(author) = comm.get_author(ctx.0).ok() {
|
||||||
<div class="comment u-comment h-cite" id="comment-@comm.id">
|
<div class="comment u-comment h-cite" id="comment-@comm.id">
|
||||||
<a class="author u-author h-card" href="@uri!(user::details: name = author.get_fqn(ctx.0))">
|
<a class="author u-author h-card" href="@uri!(user::details: name = &author.fqn)">
|
||||||
@avatar(ctx.0, &author, Size::Small, true, ctx.1)
|
@avatar(ctx.0, &author, Size::Small, true, ctx.1)
|
||||||
<span class="display-name p-name">@author.name(ctx.0)</span>
|
<span class="display-name p-name">@author.name()</span>
|
||||||
<small>@author.get_fqn(ctx.0)</small>
|
<small>@&author.fqn</small>
|
||||||
</a>
|
</a>
|
||||||
@if let Some(ref ap_url) = comm.ap_url {
|
@if let Some(ref ap_url) = comm.ap_url {
|
||||||
<a class="u-url" href="@ap_url"></a>
|
<a class="u-url" href="@ap_url"></a>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<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>
|
||||||
}
|
}
|
||||||
<h3 class="p-name">
|
<h3 class="p-name">
|
||||||
<a class="u-url" href="@uri!(posts::details: blog = article.get_blog(ctx.0).unwrap().get_fqn(ctx.0), slug = &article.slug, responding_to = _)">
|
<a class="u-url" href="@uri!(posts::details: blog = article.get_blog(ctx.0).unwrap().fqn, slug = &article.slug, responding_to = _)">
|
||||||
@article.title
|
@article.title
|
||||||
</a>
|
</a>
|
||||||
</h3>
|
</h3>
|
||||||
@ -19,13 +19,13 @@
|
|||||||
<footer class="authors">
|
<footer class="authors">
|
||||||
@Html(i18n!(ctx.1, "By {0}"; format!(
|
@Html(i18n!(ctx.1, "By {0}"; format!(
|
||||||
"<a class=\"p-author h-card\" href=\"{}\">{}</a>",
|
"<a class=\"p-author h-card\" href=\"{}\">{}</a>",
|
||||||
uri!(user::details: name = article.get_authors(ctx.0).unwrap_or_default()[0].get_fqn(ctx.0)),
|
uri!(user::details: name = &article.get_authors(ctx.0).unwrap_or_default()[0].fqn),
|
||||||
escape(&article.get_authors(ctx.0).unwrap_or_default()[0].name(ctx.0))
|
escape(&article.get_authors(ctx.0).unwrap_or_default()[0].name())
|
||||||
)))
|
)))
|
||||||
@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(ctx.0).unwrap().get_fqn(ctx.0), page = _)">@article.get_blog(ctx.0).unwrap().title</a>
|
⋅ <a href="@uri!(blogs::details: name = &article.get_blog(ctx.0).unwrap().fqn, page = _)">@article.get_blog(ctx.0).unwrap().title</a>
|
||||||
@if !article.published {
|
@if !article.published {
|
||||||
⋅ @i18n!(ctx.1, "Draft")
|
⋅ @i18n!(ctx.1, "Draft")
|
||||||
}
|
}
|
||||||
|
@ -17,10 +17,10 @@
|
|||||||
@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.get_fqn(ctx.0), slug = &article.slug, responding_to = _)"/>
|
<meta property="og:url" content="@uri!(posts::details: blog = &blog.fqn, slug = &article.slug, responding_to = _)"/>
|
||||||
<meta property="og:description" content="@article.subtitle"/>
|
<meta property="og:description" content="@article.subtitle"/>
|
||||||
}, {
|
}, {
|
||||||
<a href="@uri!(blogs::details: name = blog.get_fqn(ctx.0), page = _)">@blog.title</a>
|
<a href="@uri!(blogs::details: name = &blog.fqn, page = _)">@blog.title</a>
|
||||||
}, {
|
}, {
|
||||||
<div class="h-entry">
|
<div class="h-entry">
|
||||||
<h1 class="article p-name">@&article.title</h1>
|
<h1 class="article p-name">@&article.title</h1>
|
||||||
@ -28,16 +28,16 @@
|
|||||||
<div class="article-info">
|
<div class="article-info">
|
||||||
<span class="author">
|
<span class="author">
|
||||||
@Html(i18n!(ctx.1, "Written by {0}"; format!("<a href=\"{}\">{}</a>",
|
@Html(i18n!(ctx.1, "Written by {0}"; format!("<a href=\"{}\">{}</a>",
|
||||||
uri!(user::details: name = &author.get_fqn(ctx.0)),
|
uri!(user::details: name = &author.fqn),
|
||||||
escape(&author.name(ctx.0)))))
|
escape(&author.name()))))
|
||||||
</span>
|
</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>
|
<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) {
|
@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>
|
<a href="@uri!(posts::edit: blog = &blog.fqn, 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)">
|
<form class="inline" method="post" action="@uri!(posts::delete: blog_name = &blog.fqn, slug = &article.slug)">
|
||||||
<input onclick="return confirm('Are you sure you?')" type="submit" value="@i18n!(ctx.1, "Delete this article")">
|
<input onclick="return confirm('Are you sure you?')" type="submit" value="@i18n!(ctx.1, "Delete this article")">
|
||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
@ -73,20 +73,20 @@
|
|||||||
@avatar(ctx.0, &author, Size::Medium, true, ctx.1)
|
@avatar(ctx.0, &author, Size::Medium, true, ctx.1)
|
||||||
<div class="grow">
|
<div class="grow">
|
||||||
<h2 class="p-name">
|
<h2 class="p-name">
|
||||||
<a href="@uri!(user::details: name = author.get_fqn(ctx.0))">@author.name(ctx.0)</a>
|
<a href="@uri!(user::details: name = &author.fqn)">@author.name()</a>
|
||||||
<a rel="author" class="u-url" href="@author.ap_url"></a>
|
<a rel="author" class="u-url" href="@author.ap_url"></a>
|
||||||
</h2>
|
</h2>
|
||||||
<p>@Html(&author.summary)</h2>
|
<p>@Html(&author.summary)</h2>
|
||||||
</div>
|
</div>
|
||||||
@if !ctx.2.as_ref().map(|u| u.id == author.id).unwrap_or(false) {
|
@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">
|
<form action="@uri!(user::follow: name = &author.fqn)" method="POST">
|
||||||
<input type="submit" class="button" value="@if is_following {@i18n!(ctx.1, "Unsubscribe")} else {@i18n!(ctx.1, "Subscribe")}">
|
<input type="submit" class="button" value="@if is_following {@i18n!(ctx.1, "Unsubscribe")} else {@i18n!(ctx.1, "Subscribe")}">
|
||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@if ctx.2.is_some() {
|
@if ctx.2.is_some() {
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<form class="likes" action="@uri!(likes::create: blog = blog.get_fqn(ctx.0), slug = &article.slug)" method="POST">
|
<form class="likes" action="@uri!(likes::create: blog = &blog.fqn, 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)">
|
<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>
|
||||||
@ -97,7 +97,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 class="reshares" action="@uri!(reshares::create: blog = blog.get_fqn(ctx.0), slug = &article.slug)" method="POST">
|
<form class="reshares" action="@uri!(reshares::create: blog = &blog.fqn, 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)">
|
<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>
|
||||||
@ -131,7 +131,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.get_fqn(ctx.0), slug = &article.slug)">
|
<form method="post" action="@uri!(comments::create: blog_name = &blog.fqn, slug = &article.slug)">
|
||||||
@input!(ctx.1, warning (optional text), "Content warning", comment_form, comment_errors, "")
|
@input!(ctx.1, warning (optional text), "Content warning", comment_form, comment_errors, "")
|
||||||
|
|
||||||
<label for="plume-editor">@i18n!(ctx.1, "Your comment")</label>
|
<label for="plume-editor">@i18n!(ctx.1, "Your comment")</label>
|
||||||
@ -146,7 +146,7 @@
|
|||||||
@if !comments.is_empty() {
|
@if !comments.is_empty() {
|
||||||
<div class="list">
|
<div class="list">
|
||||||
@for comm in comments {
|
@for comm in comments {
|
||||||
@:comment(ctx, &comm, Some(&article.ap_url), &blog.get_fqn(ctx.0), &article.slug)
|
@:comment(ctx, &comm, Some(&article.ap_url), &blog.fqn, &article.slug)
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
} else {
|
} else {
|
||||||
|
@ -6,20 +6,20 @@
|
|||||||
|
|
||||||
@(ctx: BaseContext, user: User, follows: bool, is_remote: bool, remote_url: String, recents: Vec<Post>, reshares: Vec<Post>)
|
@(ctx: BaseContext, user: User, follows: bool, is_remote: bool, remote_url: String, recents: Vec<Post>, reshares: Vec<Post>)
|
||||||
|
|
||||||
@:base(ctx, user.name(ctx.0), {}, {}, {
|
@:base(ctx, user.name(), {}, {}, {
|
||||||
@:header(ctx, &user, follows, is_remote, remote_url)
|
@:header(ctx, &user, follows, is_remote, remote_url)
|
||||||
|
|
||||||
@tabs(&[
|
@tabs(&[
|
||||||
(&uri!(user::details: name= user.get_fqn(ctx.0)).to_string(), i18n!(ctx.1, "Articles"), true),
|
(&uri!(user::details: name = &user.fqn).to_string(), i18n!(ctx.1, "Articles"), true),
|
||||||
(&uri!(user::followers: name = user.get_fqn(ctx.0), page = _).to_string(), i18n!(ctx.1, "Subscribers"), false),
|
(&uri!(user::followers: name = &user.fqn, page = _).to_string(), i18n!(ctx.1, "Subscribers"), false),
|
||||||
(&uri!(user::followed: name = user.get_fqn(ctx.0), page = _).to_string(), i18n!(ctx.1, "Subscriptions"), false)
|
(&uri!(user::followed: name = &user.fqn, page = _).to_string(), i18n!(ctx.1, "Subscriptions"), false)
|
||||||
])
|
])
|
||||||
|
|
||||||
@if !recents.is_empty() {
|
@if !recents.is_empty() {
|
||||||
<div class="h-feed">
|
<div class="h-feed">
|
||||||
<h2>
|
<h2>
|
||||||
<span class="p-name">@i18n!(ctx.1, "Latest articles")</span>
|
<span class="p-name">@i18n!(ctx.1, "Latest articles")</span>
|
||||||
<small><a href="@uri!(user::atom_feed: name = user.get_fqn(ctx.0))" title="@i18n!(ctx.1, "Atom feed")">@icon!("rss")</a></small>
|
<small><a href="@uri!(user::atom_feed: name = &user.fqn))" title="@i18n!(ctx.1, "Atom feed")">@icon!("rss")</a></small>
|
||||||
</h2>
|
</h2>
|
||||||
<div class="cards">
|
<div class="cards">
|
||||||
@for article in recents {
|
@for article in recents {
|
||||||
|
@ -5,19 +5,19 @@
|
|||||||
|
|
||||||
@(ctx: BaseContext, user: User, follows: bool, is_remote: bool, remote_url: String, followed: Vec<User>, page: i32, n_pages: i32)
|
@(ctx: BaseContext, user: User, follows: bool, is_remote: bool, remote_url: String, followed: Vec<User>, page: i32, n_pages: i32)
|
||||||
|
|
||||||
@:base(ctx, i18n!(ctx.1, "{0}'s subscriptions'"; user.name(ctx.0)), {}, {}, {
|
@:base(ctx, i18n!(ctx.1, "{0}'s subscriptions'"; user.name()), {}, {}, {
|
||||||
@:header(ctx, &user, follows, is_remote, remote_url)
|
@:header(ctx, &user, follows, is_remote, remote_url)
|
||||||
|
|
||||||
@tabs(&[
|
@tabs(&[
|
||||||
(&uri!(user::details: name= user.get_fqn(ctx.0)).to_string(), i18n!(ctx.1, "Articles"), true),
|
(&uri!(user::details: name = &user.fqn).to_string(), i18n!(ctx.1, "Articles"), true),
|
||||||
(&uri!(user::followers: name = user.get_fqn(ctx.0), page = _).to_string(), i18n!(ctx.1, "Subscribers"), false),
|
(&uri!(user::followers: name = &user.fqn, page = _).to_string(), i18n!(ctx.1, "Subscribers"), false),
|
||||||
(&uri!(user::followed: name = user.get_fqn(ctx.0), page = _).to_string(), i18n!(ctx.1, "Subscriptions"), false)
|
(&uri!(user::followed: name = &user.fqn, page = _).to_string(), i18n!(ctx.1, "Subscriptions"), false)
|
||||||
])
|
])
|
||||||
|
|
||||||
<div class="cards">
|
<div class="cards">
|
||||||
@for follow in followed {
|
@for follow in followed {
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h3><a href="@uri!(user::details: name = follow.get_fqn(ctx.0))">@follow.name(ctx.0)</a> <small>@format!("@{}", follow.get_fqn(ctx.0))</small></h3>
|
<h3><a href="@uri!(user::details: name = &follow.fqn)">@follow.name()</a> <small>@format!("@{}", &follow.fqn)</small></h3>
|
||||||
<main><p>@Html(follow.summary)</p></main>
|
<main><p>@Html(follow.summary)</p></main>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
@ -5,19 +5,19 @@
|
|||||||
|
|
||||||
@(ctx: BaseContext, user: User, follows: bool, is_remote: bool, remote_url: String, followers: Vec<User>, page: i32, n_pages: i32)
|
@(ctx: BaseContext, user: User, follows: bool, is_remote: bool, remote_url: String, followers: Vec<User>, page: i32, n_pages: i32)
|
||||||
|
|
||||||
@:base(ctx, i18n!(ctx.1, "{0}'s subscribers"; user.name(ctx.0)), {}, {}, {
|
@:base(ctx, i18n!(ctx.1, "{0}'s subscribers"; user.name()), {}, {}, {
|
||||||
@:header(ctx, &user, follows, is_remote, remote_url)
|
@:header(ctx, &user, follows, is_remote, remote_url)
|
||||||
|
|
||||||
@tabs(&[
|
@tabs(&[
|
||||||
(&uri!(user::details: name= user.get_fqn(ctx.0)).to_string(), i18n!(ctx.1, "Articles"), true),
|
(&uri!(user::details: name = &user.fqn).to_string(), i18n!(ctx.1, "Articles"), true),
|
||||||
(&uri!(user::followers: name = user.get_fqn(ctx.0), page = _).to_string(), i18n!(ctx.1, "Subscribers"), false),
|
(&uri!(user::followers: name = &user.fqn, page = _).to_string(), i18n!(ctx.1, "Subscribers"), false),
|
||||||
(&uri!(user::followed: name = user.get_fqn(ctx.0), page = _).to_string(), i18n!(ctx.1, "Subscriptions"), false)
|
(&uri!(user::followed: name = &user.fqn, page = _).to_string(), i18n!(ctx.1, "Subscriptions"), false)
|
||||||
])
|
])
|
||||||
|
|
||||||
<div class="cards">
|
<div class="cards">
|
||||||
@for follower in followers {
|
@for follower in followers {
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h3><a href="@uri!(user::details: name = follower.get_fqn(ctx.0))">@follower.name(ctx.0)</a> <small>@format!("@{}", follower.get_fqn(ctx.0))</small></h3>
|
<h3><a href="@uri!(user::details: name = &follower.fqn)">@follower.name()</a> <small>@format!("@{}", &follower.fqn)</small></h3>
|
||||||
<main><p>@Html(follower.summary)</p></main>
|
<main><p>@Html(follower.summary)</p></main>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
@avatar(ctx.0, &user, Size::Medium, false, ctx.1)
|
@avatar(ctx.0, &user, Size::Medium, false, ctx.1)
|
||||||
|
|
||||||
<h1 class="grow flex vertical">
|
<h1 class="grow flex vertical">
|
||||||
<span class="p-name">@user.name(ctx.0)</span>
|
<span class="p-name">@user.name()</span>
|
||||||
<small class="p-nickname">@user.get_fqn(ctx.0)</small>
|
<small class="p-nickname">@&user.fqn</small>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -33,7 +33,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@if ctx.2.clone().map(|u| u.id != user.id).unwrap_or(false) {
|
@if ctx.2.clone().map(|u| u.id != user.id).unwrap_or(false) {
|
||||||
<form class="inline" method="post" action="@uri!(user::follow: name = user.get_fqn(ctx.0))">
|
<form class="inline" method="post" action="@uri!(user::follow: name = &user.fqn)">
|
||||||
@if follows {
|
@if follows {
|
||||||
<input type="submit" value="@i18n!(ctx.1, "Unsubscribe")">
|
<input type="submit" value="@i18n!(ctx.1, "Unsubscribe")">
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user