diff --git a/Cargo.lock b/Cargo.lock index dfcce4e..8459f5a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2361,6 +2361,7 @@ dependencies = [ "memo-map", "self_cell", "serde", + "serde_json", ] [[package]] diff --git a/web/Cargo.toml b/web/Cargo.toml index 8cf5eec..724e2f0 100644 --- a/web/Cargo.toml +++ b/web/Cargo.toml @@ -34,7 +34,7 @@ http = "0.2" indexmap = { version = "1.9" } lazy_static = "^1.4" mailpot = { version = "^0.1", path = "../core" } -minijinja = { version = "0.31.0", features = ["source", ] } +minijinja = { version = "0.31.0", features = ["source", "builtins", "json"] } percent-encoding = { version = "^2.1" } rand = { version = "^0.8", features = ["min_const_gen"] } serde = { version = "^1", features = ["derive", ] } diff --git a/web/src/lib.rs b/web/src/lib.rs index a7c35bd..82b06e4 100644 --- a/web/src/lib.rs +++ b/web/src/lib.rs @@ -96,7 +96,7 @@ pub use cal::{calendarize, *}; pub use help::*; pub use lists::{ list, list_candidates, list_edit, list_edit_POST, list_post, list_post_eml, list_post_raw, - list_subscribers, PostPolicySettings, SubscriptionPolicySettings, + list_search_query_GET, list_subscribers, PostPolicySettings, SubscriptionPolicySettings, }; pub use minijinja_utils::*; pub use settings::{ diff --git a/web/src/lists.rs b/web/src/lists.rs index 6499e10..872f4fa 100644 --- a/web/src/lists.rs +++ b/web/src/lists.rs @@ -41,7 +41,8 @@ pub async fn list( }; let post_policy = db.list_post_policy(list.pk)?; let subscription_policy = db.list_subscription_policy(list.pk)?; - let months = db.months(list.pk)?; + let mut months = db.months(list.pk)?; + months.sort(); let user_context = auth .current_user .as_ref() @@ -52,7 +53,7 @@ pub async fn list( .iter() .map(|p| (p.message_id.as_str(), p)) .collect::>>(); - let mut hist = months + let mut hists = months .iter() .map(|m| (m.to_string(), [0usize; 31])) .collect::>(); @@ -79,7 +80,7 @@ pub async fn list( .ok() .map(|d| d.day()) { - hist.get_mut(&post.month_year).unwrap()[day.saturating_sub(1) as usize] += 1; + hists.get_mut(&post.month_year).unwrap()[day.saturating_sub(1) as usize] += 1; } let envelope = melib::Envelope::from_bytes(post.message.as_slice(), None) .expect("Could not parse mail"); @@ -108,19 +109,21 @@ pub async fn list( ret }) .collect::>(); - let crumbs = vec![ - Crumb { - label: "Home".into(), - url: "/".into(), - }, - Crumb { - label: list.name.clone().into(), - url: ListPath(list.id.to_string().into()).to_crumb(), - }, - ]; + + let crumbs = crumbs![Crumb { + label: list.name.clone().into(), + url: ListPath(list.id.to_string().into()).to_crumb(), + },]; let list_owners = db.list_owners(list.pk)?; let mut list_obj = MailingList::from(list.clone()); list_obj.set_safety(list_owners.as_slice(), &state.conf.administrators); + let has_more_months = if months.len() > 2 { + let len = months.len(); + months.drain(0..(len - 2)); + true + } else { + false + }; let context = minijinja::context! { canonical_url => ListPath::from(&list).to_crumb(), page_title => &list.name, @@ -129,7 +132,8 @@ pub async fn list( subscription_policy, preamble => true, months, - hists => &hist, + has_more_months, + hists, posts => posts_ctx, list => Value::from_object(list_obj), current_user => auth.current_user, @@ -185,11 +189,7 @@ pub async fn list_post( { subject_ref = subject_ref[2 + list.id.len()..].trim(); } - let crumbs = vec![ - Crumb { - label: "Home".into(), - url: "/".into(), - }, + let crumbs = crumbs![ Crumb { label: list.name.clone().into(), url: ListPath(list.id.to_string().into()).to_crumb(), @@ -294,11 +294,7 @@ pub async fn list_edit( .unwrap_or(0) }; - let crumbs = vec![ - Crumb { - label: "Home".into(), - url: "/".into(), - }, + let crumbs = crumbs![ Crumb { label: list.name.clone().into(), url: ListPath(list.id.to_string().into()).to_crumb(), @@ -673,11 +669,7 @@ pub async fn list_subscribers( ret }; - let crumbs = vec![ - Crumb { - label: "Home".into(), - url: "/".into(), - }, + let crumbs = crumbs![ Crumb { label: list.name.clone().into(), url: ListPath(list.id.to_string().into()).to_crumb(), @@ -761,11 +753,7 @@ pub async fn list_candidates( ret }; - let crumbs = vec![ - Crumb { - label: "Home".into(), - url: "/".into(), - }, + let crumbs = crumbs![ Crumb { label: list.name.clone().into(), url: ListPath(list.id.to_string().into()).to_crumb(), @@ -796,3 +784,28 @@ pub async fn list_candidates( .render(context)?, )) } + +/// Mailing list post search. +#[allow(non_snake_case)] +pub async fn list_search_query_GET( + ListSearchPath(id): ListSearchPath, + //mut session: WritableSession, + Query(query): Query, + //auth: AuthContext, + State(state): State>, +) -> Result, ResponseError> { + let db = Connection::open_db(state.conf.clone())?.trusted(); + let Some(_list) = (match id { + ListPathIdentifier::Pk(id) => db.list(id)?, + ListPathIdentifier::Id(id) => db.list_by_id(id)?, + }) else { + return Err(ResponseError::new( + "List not found".to_string(), + StatusCode::NOT_FOUND, + )); + }; + Err(ResponseError::new( + format!("{:#?}", query), + StatusCode::NOT_IMPLEMENTED, + )) +} diff --git a/web/src/main.rs b/web/src/main.rs index 0882abc..6b90dd8 100644 --- a/web/src/main.rs +++ b/web/src/main.rs @@ -57,6 +57,7 @@ fn create_app(shared_state: Arc) -> Router { .typed_get(list_post_raw) .typed_get(list_topics) .typed_get(list_post_eml) + .typed_get(list_search_query_GET) .typed_get(list_edit.layer(RequireAuth::login_with_role_or_redirect( Role::User.., Arc::clone(&login_url), diff --git a/web/src/minijinja_utils.rs b/web/src/minijinja_utils.rs index 5238343..038b823 100644 --- a/web/src/minijinja_utils.rs +++ b/web/src/minijinja_utils.rs @@ -49,13 +49,16 @@ lazy_static::lazy_static! { settings_path, help_path, list_path, + list_calendar_path, + list_search_query, list_settings_path, list_edit_path, list_subscribers_path, list_candidates_path, list_post_path, post_raw_path, - post_eml_path + post_eml_path, + year_month_to_query, ); add!(filter pluralize); // Load compressed templates. They are constructed in build.rs. See @@ -243,31 +246,33 @@ pub fn calendarize( } }}; } - let month = args.as_str().unwrap(); + let year_month = args.as_str().unwrap(); let hist = hists - .get_item(&Value::from(month))? + .get_item(&Value::from(year_month))? .as_seq() .unwrap() .iter() .map(|v| usize::try_from(v).unwrap()) .collect::>(); let sum: usize = hists - .get_item(&Value::from(month))? + .get_item(&Value::from(year_month))? .as_seq() .unwrap() .iter() .map(|v| usize::try_from(v).unwrap()) .sum(); - let date = chrono::NaiveDate::parse_from_str(&format!("{}-01", month), "%F").unwrap(); + let date = chrono::NaiveDate::parse_from_str(&format!("{}-01", year_month), "%F").unwrap(); // Week = [Mon, Tue, Wed, Thu, Fri, Sat, Sun] Ok(minijinja::context! { + date, month_name => month!(date.month()), - month => month, + month => year_month, month_int => date.month() as usize, year => date.year(), weeks => cal::calendarize_with_offset(date, 1), hist => hist, sum, + unknown => date.year() == 1970, }) } diff --git a/web/src/templates/calendar.html b/web/src/templates/calendar.html index 8eccf8f..f8a8eb9 100644 --- a/web/src/templates/calendar.html +++ b/web/src/templates/calendar.html @@ -3,9 +3,12 @@ {% if c.sum > 0 %} diff --git a/web/src/templates/css.html b/web/src/templates/css.html index f644210..2fbde20 100644 --- a/web/src/templates/css.html +++ b/web/src/templates/css.html @@ -129,6 +129,11 @@ code { font-family: var(--monospace-system-stack); overflow-wrap: anywhere; + background: var(--color-tan); + color: black; + border-radius: 4px; + padding-left: 4px; + padding-right: 4px; } pre { @@ -162,6 +167,7 @@ --code-background: #8fbcbb; --a-visited-text: var(--a-normal-text); --tag-border-color: black; + --color-tan: #fef6e9; } @media (prefers-color-scheme: light) { @@ -445,18 +451,6 @@ font-size: small; } - /* If only the root crumb is visible, hide it to avoid unnecessary visual clutter */ - li.crumb:only-child>span[aria-current="page"] { - --secs: 150ms; - transition: all var(--secs) linear; - color: transparent; - } - - li.crumb:only-child>span[aria-current="page"]:hover { - transition: all var(--secs) linear; - color: revert; - } - .crumb, .crumb>a { display: inline; } @@ -595,6 +589,10 @@ opacity: 0.2; } + div.calendar a { + place-self: center; + } + div.calendar { display: flex; flex-wrap: wrap; diff --git a/web/src/templates/header.html b/web/src/templates/header.html index 6d2ab7d..f3006f0 100644 --- a/web/src/templates/header.html +++ b/web/src/templates/header.html @@ -16,7 +16,7 @@

{{ site_title }}

{% endif %} {% include "menu.html" %}
- - - {{ c.month_name }} {{ c.year }} + + {% if c.unknown %} + Unknown + {% else %} + {{ c.month_name }} {{ c.year }} + {% endif %}