diff --git a/crates/app/src/public/html/journals/app.lisp b/crates/app/src/public/html/journals/app.lisp
index 4a3ccbd..6fbcea2 100644
--- a/crates/app/src/public/html/journals/app.lisp
+++ b/crates/app/src/public/html/journals/app.lisp
@@ -65,7 +65,7 @@
(a
("class" "flush")
- ("href" "{% if view_mode -%} /@{{ owner.username }}/{{ journal.title }}/index {%- else -%} /journals/{{ journal.id }}/0 {%- endif %}")
+ ("href" "{% if view_mode -%} /@{{ owner.username }}/{{ journal.title }} {%- else -%} /journals/{{ journal.id }}/0 {%- endif %}")
(b (text "{{ journal.title }}")))
(text "{% if note -%}")
@@ -83,7 +83,7 @@
(icon (text "pencil")))
(a
("class" "{% if view_mode -%}active{%- endif %}")
- ("href" "/@{{ user.username }}/{{ journal.title }}/{% if note -%} {{ note.title }} {%- else -%} index {%- endif %}")
+ ("href" "/@{{ user.username }}/{{ journal.title }}{% if note -%} /{{ note.title }} {%- endif %}")
(icon (text "eye"))))
(text "{%- endif %}"))
(text "{%- endif %}")
diff --git a/crates/app/src/routes/api/v1/journals.rs b/crates/app/src/routes/api/v1/journals.rs
index 0cf3617..d501f08 100644
--- a/crates/app/src/routes/api/v1/journals.rs
+++ b/crates/app/src/routes/api/v1/journals.rs
@@ -102,7 +102,7 @@ pub async fn update_title_request(
None => return Json(Error::NotAllowed.into()),
};
- props.title = props.title.replace(" ", "_");
+ props.title = props.title.replace(" ", "_").to_lowercase();
// check name
let regex = regex::RegexBuilder::new(NAME_REGEX)
diff --git a/crates/app/src/routes/api/v1/notes.rs b/crates/app/src/routes/api/v1/notes.rs
index 41ab1f9..faf1bec 100644
--- a/crates/app/src/routes/api/v1/notes.rs
+++ b/crates/app/src/routes/api/v1/notes.rs
@@ -138,7 +138,7 @@ pub async fn update_title_request(
Err(e) => return Json(e.into()),
};
- props.title = props.title.replace(" ", "_");
+ props.title = props.title.replace(" ", "_").to_lowercase();
// check name
let regex = regex::RegexBuilder::new(NAME_REGEX)
diff --git a/crates/app/src/routes/pages/journals.rs b/crates/app/src/routes/pages/journals.rs
index f631826..397b4cd 100644
--- a/crates/app/src/routes/pages/journals.rs
+++ b/crates/app/src/routes/pages/journals.rs
@@ -207,3 +207,81 @@ pub async fn view_request(
// return
Ok(Html(data.1.render("journals/app.html", &context).unwrap()))
}
+
+/// `/@{owner}/{journal}`
+pub async fn index_view_request(
+ jar: CookieJar,
+ Extension(data): Extension,
+ Path((owner, selected_journal)): Path<(String, String)>,
+) -> impl IntoResponse {
+ let data = data.read().await;
+ let user = match get_user_from_token!(jar, data.0) {
+ Some(ua) => Some(ua),
+ None => None,
+ };
+
+ // get owner
+ let owner = match data.0.get_user_by_username(&owner).await {
+ Ok(ua) => ua,
+ Err(e) => {
+ return Err(Html(render_error(e, &jar, &data, &user).await));
+ }
+ };
+
+ check_user_blocked_or_private!(user, owner, data, jar);
+
+ // get journal and check privacy settings
+ let journal = match data
+ .0
+ .get_journal_by_owner_title(owner.id, &selected_journal)
+ .await
+ {
+ Ok(p) => p,
+ Err(e) => {
+ return Err(Html(render_error(e, &jar, &data, &user).await));
+ }
+ };
+
+ if journal.privacy == JournalPrivacyPermission::Private {
+ if let Some(ref user) = user {
+ if user.id != journal.owner {
+ return Err(Html(
+ render_error(Error::NotAllowed, &jar, &data, &Some(user.to_owned())).await,
+ ));
+ }
+ } else {
+ return Err(Html(
+ render_error(Error::NotAllowed, &jar, &data, &user).await,
+ ));
+ }
+ }
+
+ // ...
+ let notes = match data.0.get_notes_by_journal(journal.id).await {
+ Ok(p) => Some(p),
+ Err(e) => {
+ return Err(Html(render_error(e, &jar, &data, &user).await));
+ }
+ };
+
+ let lang = get_lang!(jar, data.0);
+ let mut context = initial_context(&data.0.0.0, lang, &user).await;
+
+ if selected_journal.is_empty() {
+ context.insert("selected_journal", &0);
+ } else {
+ context.insert("selected_journal", &selected_journal);
+ }
+
+ context.insert("selected_note", &0);
+ context.insert("journal", &journal);
+
+ context.insert("owner", &owner);
+ context.insert("notes", ¬es);
+
+ context.insert("view_mode", &true);
+ context.insert("is_editor", &false);
+
+ // return
+ Ok(Html(data.1.render("journals/app.html", &context).unwrap()))
+}
diff --git a/crates/app/src/routes/pages/mod.rs b/crates/app/src/routes/pages/mod.rs
index 2177d94..2eaeca2 100644
--- a/crates/app/src/routes/pages/mod.rs
+++ b/crates/app/src/routes/pages/mod.rs
@@ -134,7 +134,7 @@ pub fn routes() -> Router {
// journals
.route("/journals", get(journals::redirect_request))
.route("/journals/{journal}/{note}", get(journals::app_request))
- .route("/@{owner}/{journal}", get(journals::view_request))
+ .route("/@{owner}/{journal}", get(journals::index_view_request))
.route("/@{owner}/{journal}/{note}", get(journals::view_request))
}
diff --git a/crates/core/src/database/journals.rs b/crates/core/src/database/journals.rs
index 5979347..8c2a637 100644
--- a/crates/core/src/database/journals.rs
+++ b/crates/core/src/database/journals.rs
@@ -84,7 +84,7 @@ impl DataManager {
return Err(Error::DataTooLong("title".to_string()));
}
- data.title = data.title.replace(" ", "_");
+ data.title = data.title.replace(" ", "_").to_lowercase();
// check name
let regex = regex::RegexBuilder::new(NAME_REGEX)
diff --git a/crates/core/src/database/notes.rs b/crates/core/src/database/notes.rs
index 377fa6e..e3fcdab 100644
--- a/crates/core/src/database/notes.rs
+++ b/crates/core/src/database/notes.rs
@@ -83,7 +83,7 @@ impl DataManager {
return Err(Error::DataTooLong("content".to_string()));
}
- data.title = data.title.replace(" ", "_");
+ data.title = data.title.replace(" ", "_").to_lowercase();
// check name
let regex = regex::RegexBuilder::new(NAME_REGEX)