Add markdown support for summary (#482)

* Add markdown support for summary

* Save both md and html summary
This commit is contained in:
fdb-hiroshima 2019-03-17 20:11:29 +01:00 committed by GitHub
parent 191eb89958
commit 570d7fe2d0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 79 additions and 12 deletions

View file

@ -0,0 +1,2 @@
-- This file should undo anything in `up.sql`
ALTER TABLE users DROP COLUMN summary_html;

View file

@ -0,0 +1,3 @@
-- Your SQL goes here
ALTER TABLE users ADD COLUMN summary_html TEXT NOT NULL DEFAULT '';
UPDATE users SET summary_html = summary;

View file

@ -0,0 +1,47 @@
-- This file should undo anything in `up.sql`
CREATE TABLE users2 (
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,
fqn TEXT NOT NULL DEFAULT '',
CONSTRAINT blog_authors_unique UNIQUE (username, instance_id)
);
INSERT INTO users2 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,
fqn
FROM users;
DROP TABLE users;
ALTER TABLE users2 RENAME TO users;

View file

@ -0,0 +1,3 @@
-- Your SQL goes here
ALTER TABLE users ADD COLUMN summary_html TEXT NOT NULL DEFAULT '';
UPDATE users SET summary_html = summary;

View file

@ -203,6 +203,7 @@ table! {
avatar_id -> Nullable<Int4>, avatar_id -> Nullable<Int4>,
last_fetched_date -> Timestamp, last_fetched_date -> Timestamp,
fqn -> Text, fqn -> Text,
summary_html -> Text,
} }
} }

View file

@ -17,6 +17,7 @@ use plume_common::activity_pub::{
sign::{gen_keypair, Signer}, sign::{gen_keypair, Signer},
ActivityStream, ApSignature, Id, IntoId, PublicKey, ActivityStream, ApSignature, Id, IntoId, PublicKey,
}; };
use plume_common::utils;
use reqwest::{ use reqwest::{
header::{HeaderValue, ACCEPT}, header::{HeaderValue, ACCEPT},
Client, Client,
@ -52,7 +53,7 @@ pub struct User {
pub outbox_url: String, pub outbox_url: String,
pub inbox_url: String, pub inbox_url: String,
pub is_admin: bool, pub is_admin: bool,
pub summary: SafeString, pub summary: String,
pub email: Option<String>, pub email: Option<String>,
pub hashed_password: Option<String>, pub hashed_password: Option<String>,
pub instance_id: i32, pub instance_id: i32,
@ -65,6 +66,7 @@ pub struct User {
pub avatar_id: Option<i32>, pub avatar_id: Option<i32>,
pub last_fetched_date: NaiveDateTime, pub last_fetched_date: NaiveDateTime,
pub fqn: String, pub fqn: String,
pub summary_html: SafeString,
} }
#[derive(Default, Insertable)] #[derive(Default, Insertable)]
@ -75,7 +77,7 @@ pub struct NewUser {
pub outbox_url: String, pub outbox_url: String,
pub inbox_url: String, pub inbox_url: String,
pub is_admin: bool, pub is_admin: bool,
pub summary: SafeString, pub summary: String,
pub email: Option<String>, pub email: Option<String>,
pub hashed_password: Option<String>, pub hashed_password: Option<String>,
pub instance_id: i32, pub instance_id: i32,
@ -85,6 +87,7 @@ pub struct NewUser {
pub shared_inbox_url: Option<String>, pub shared_inbox_url: Option<String>,
pub followers_endpoint: String, pub followers_endpoint: String,
pub avatar_id: Option<i32>, pub avatar_id: Option<i32>,
pub summary_html: SafeString,
} }
pub const AUTH_COOKIE: &str = "user_id"; pub const AUTH_COOKIE: &str = "user_id";
@ -212,6 +215,7 @@ impl User {
.set(( .set((
users::display_name.eq(name), users::display_name.eq(name),
users::email.eq(email), users::email.eq(email),
users::summary_html.eq(utils::md_to_html(&summary,"").0),
users::summary.eq(summary), users::summary.eq(summary),
)) ))
.execute(conn)?; .execute(conn)?;
@ -320,7 +324,12 @@ impl User {
.ap_actor_props .ap_actor_props
.inbox_string()?, .inbox_string()?,
is_admin: false, is_admin: false,
summary: SafeString::new( summary:acct
.object
.object_props
.summary_string()
.unwrap_or_default(),
summary_html: SafeString::new(
&acct &acct
.object .object
.object_props .object_props
@ -684,7 +693,7 @@ impl User {
.set_name_string(self.display_name.clone())?; .set_name_string(self.display_name.clone())?;
actor actor
.object_props .object_props
.set_summary_string(self.summary.get().clone())?; .set_summary_string(self.summary_html.get().clone())?;
actor actor
.object_props .object_props
.set_url_string(self.ap_url.clone())?; .set_url_string(self.ap_url.clone())?;
@ -902,7 +911,8 @@ impl NewUser {
username, username,
display_name, display_name,
is_admin, is_admin,
summary: SafeString::new(summary), summary: summary.to_owned(),
summary_html: SafeString::new(&utils::md_to_html(&summary,"").0),
email: Some(email), email: Some(email),
hashed_password: Some(password), hashed_password: Some(password),
instance_id: Instance::get_local(conn)?.id, instance_id: Instance::get_local(conn)?.id,
@ -1050,7 +1060,7 @@ pub(crate) mod tests {
).unwrap(); ).unwrap();
assert_eq!(updated.display_name, "new name"); assert_eq!(updated.display_name, "new name");
assert_eq!(updated.email.unwrap(), "em@il"); assert_eq!(updated.email.unwrap(), "em@il");
assert_eq!(updated.summary.get(), "<p>summary</p>"); assert_eq!(updated.summary_html.get(), "<p>summary</p>");
Ok(()) Ok(())
}); });

View file

@ -225,7 +225,7 @@ pub fn edit(name: String, user: User, conn: DbConn, intl: I18n) -> Result<Ructe,
UpdateUserForm { UpdateUserForm {
display_name: user.display_name.clone(), display_name: user.display_name.clone(),
email: user.email.clone().unwrap_or_default(), email: user.email.clone().unwrap_or_default(),
summary: user.summary.to_string(), summary: user.summary,
}, },
ValidationErrors::default() ValidationErrors::default()
))) )))

View file

@ -76,7 +76,7 @@
<a href="@uri!(user::details: name = &author.fqn)">@author.name()</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_html)</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.fqn)" method="POST"> <form action="@uri!(user::follow: name = &author.fqn)" method="POST">

View file

@ -19,7 +19,8 @@
@input!(ctx.1, display_name (text), "Display name", form, errors.clone()) @input!(ctx.1, display_name (text), "Display name", form, errors.clone())
@input!(ctx.1, email (text), "Email", form, errors.clone()) @input!(ctx.1, email (text), "Email", form, errors.clone())
@input!(ctx.1, summary (text), "Summary", form, errors) <label for="summary">@i18n!(ctx.1, "Summary")</label>
<textarea id="summary" name="summary">@form.summary</textarea>
<input type="submit" value="@i18n!(ctx.1, "Update account")"/> <input type="submit" value="@i18n!(ctx.1, "Update account")"/>
</form> </form>

View file

@ -18,7 +18,7 @@
@for follow in followed { @for follow in followed {
<div class="card"> <div class="card">
<h3><a href="@uri!(user::details: name = &follow.fqn)">@follow.name()</a> <small>@format!("@{}", &follow.fqn)</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_html)</p></main>
</div> </div>
} }
</div> </div>

View file

@ -18,7 +18,7 @@
@for follower in followers { @for follower in followers {
<div class="card"> <div class="card">
<h3><a href="@uri!(user::details: name = &follower.fqn)">@follower.name()</a> <small>@format!("@{}", &follower.fqn)</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_html)</p></main>
</div> </div>
} }
</div> </div>

View file

@ -43,6 +43,6 @@
} }
</div> </div>
<div class="user-summary p-note"> <div class="user-summary p-note">
@Html(user.summary.clone()) @Html(user.summary_html.clone())
</div> </div>
</div> </div>