diff --git a/assets/ibis.css b/assets/ibis.css index bc2d51e..7386c91 100644 --- a/assets/ibis.css +++ b/assets/ibis.css @@ -21,4 +21,8 @@ main { background-color: #ffffff; flex-grow: 1; padding: 20px; +} + +pre { + white-space: pre-wrap; } \ No newline at end of file diff --git a/src/backend/api/article.rs b/src/backend/api/article.rs index 1b57dc9..f10a4ac 100644 --- a/src/backend/api/article.rs +++ b/src/backend/api/article.rs @@ -191,7 +191,10 @@ pub(in crate::backend::api) async fn fork_article( // copy edits to new article // this could also be done in sql - let edits = DbEdit::read_for_article(&original_article, &data.db_connection)?; + let edits = DbEdit::read_for_article(&original_article, &data.db_connection)? + .into_iter() + .map(|e| e.edit) + .collect::>(); for e in edits { let ap_id = DbEditForm::generate_ap_id(&article, &e.hash)?; let form = DbEditForm { @@ -221,7 +224,7 @@ pub(super) async fn resolve_article( ) -> MyResult> { let article: DbArticle = ObjectId::from(query.id).dereference(&data).await?; let edits = DbEdit::read_for_article(&article, &data.db_connection)?; - let latest_version = edits.last().unwrap().hash.clone(); + let latest_version = edits.last().unwrap().edit.hash.clone(); Ok(Json(ArticleView { article, edits, diff --git a/src/backend/database/edit.rs b/src/backend/database/edit.rs index ac7ea83..edb7ee1 100644 --- a/src/backend/database/edit.rs +++ b/src/backend/database/edit.rs @@ -1,7 +1,7 @@ -use crate::backend::database::schema::edit; +use crate::backend::database::schema::{edit, person}; use crate::backend::error::MyResult; -use crate::common::EditVersion; use crate::common::{DbArticle, DbEdit}; +use crate::common::{EditVersion, EditView}; use activitypub_federation::fetch::object_id::ObjectId; use chrono::{DateTime, Utc}; use diesel::ExpressionMethods; @@ -83,13 +83,15 @@ impl DbEdit { .get_result(conn.deref_mut())?) } + // TODO: create internal variant which doesnt return person? pub fn read_for_article( article: &DbArticle, conn: &Mutex, - ) -> MyResult> { + ) -> MyResult> { let mut conn = conn.lock().unwrap(); Ok(edit::table - .filter(edit::dsl::article_id.eq(article.id)) + .inner_join(person::table) + .filter(edit::article_id.eq(article.id)) .get_results(conn.deref_mut())?) } } diff --git a/src/backend/federation/objects/edits_collection.rs b/src/backend/federation/objects/edits_collection.rs index b62b0d3..13845a5 100644 --- a/src/backend/federation/objects/edits_collection.rs +++ b/src/backend/federation/objects/edits_collection.rs @@ -44,7 +44,7 @@ impl Collection for DbEditCollection { article .edits .into_iter() - .map(|a| a.into_json(data)) + .map(|a| a.edit.into_json(data)) .collect::>(), ) .await?; diff --git a/src/backend/utils.rs b/src/backend/utils.rs index 7f053a0..20cd74f 100644 --- a/src/backend/utils.rs +++ b/src/backend/utils.rs @@ -1,6 +1,6 @@ use crate::backend::error::MyResult; -use crate::common::DbEdit; use crate::common::EditVersion; +use crate::common::EditView; use activitypub_federation::fetch::object_id::ObjectId; use activitypub_federation::traits::Object; use anyhow::anyhow; @@ -30,15 +30,15 @@ where /// /// TODO: testing /// TODO: should cache all these generated versions -pub fn generate_article_version(edits: &Vec, version: &EditVersion) -> MyResult { +pub fn generate_article_version(edits: &Vec, version: &EditVersion) -> MyResult { let mut generated = String::new(); if version == &EditVersion::default() { return Ok(generated); } for e in edits { - let patch = Patch::from_str(&e.diff)?; + let patch = Patch::from_str(&e.edit.diff)?; generated = apply(&generated, &patch)?; - if &e.hash == version { + if &e.edit.hash == version { return Ok(generated); } } @@ -48,23 +48,36 @@ pub fn generate_article_version(edits: &Vec, version: &EditVersion) -> M #[cfg(test)] mod test { use super::*; + use crate::common::{DbEdit, DbPerson}; use activitypub_federation::fetch::object_id::ObjectId; use chrono::Utc; use diffy::create_patch; - fn create_edits() -> MyResult> { - let generate_edit = |a, b| -> MyResult { + fn create_edits() -> MyResult> { + let generate_edit = |a, b| -> MyResult { let diff = create_patch(a, b).to_string(); - Ok(DbEdit { - id: 0, - creator_id: 0, - hash: EditVersion::new(&diff), - ap_id: ObjectId::parse("http://example.com")?, - diff, - summary: String::new(), - article_id: 0, - previous_version_id: Default::default(), - created: Utc::now(), + Ok(EditView { + edit: DbEdit { + id: 0, + creator_id: 0, + hash: EditVersion::new(&diff), + ap_id: ObjectId::parse("http://example.com")?, + diff, + summary: String::new(), + article_id: 0, + previous_version_id: Default::default(), + created: Utc::now(), + }, + creator: DbPerson { + id: 0, + username: "".to_string(), + ap_id: ObjectId::parse("http://example.com").unwrap(), + inbox_url: "".to_string(), + public_key: "".to_string(), + private_key: None, + last_refreshed_at: Default::default(), + local: false, + }, }) }; Ok([ @@ -78,7 +91,7 @@ mod test { #[test] fn test_generate_article_version() -> MyResult<()> { let edits = create_edits()?; - let generated = generate_article_version(&edits, &edits[1].hash)?; + let generated = generate_article_version(&edits, &edits[1].edit.hash)?; assert_eq!("sda\n", generated); Ok(()) } diff --git a/src/common/mod.rs b/src/common/mod.rs index 2aa98ee..421477b 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -37,7 +37,7 @@ pub struct ListArticlesData { pub struct ArticleView { pub article: DbArticle, pub latest_version: EditVersion, - pub edits: Vec, + pub edits: Vec, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] @@ -63,6 +63,7 @@ pub struct DbEdit { // TODO: we could use hash as primary key, but that gives errors on forking because // the same edit is used for multiple articles pub id: i32, + #[serde(skip)] pub creator_id: i32, /// UUID built from sha224 hash of diff pub hash: EditVersion, @@ -78,6 +79,14 @@ pub struct DbEdit { pub created: DateTime, } +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +#[cfg_attr(feature = "ssr", derive(Queryable))] +#[cfg_attr(feature = "ssr", diesel(check_for_backend(diesel::pg::Pg)))] +pub struct EditView { + pub edit: DbEdit, + pub creator: DbPerson, +} + /// The version hash of a specific edit. Generated by taking an SHA256 hash of the diff /// and using the first 16 bytes so that it fits into UUID. #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)] diff --git a/src/frontend/components/nav.rs b/src/frontend/components/nav.rs index bbfc076..0e99b53 100644 --- a/src/frontend/components/nav.rs +++ b/src/frontend/components/nav.rs @@ -23,7 +23,7 @@ pub fn Nav() -> impl IntoView { let (search_query, set_search_query) = create_signal(String::new()); view! { -