use crate::gemtext2md::gemtext2md;
use crate::routes::route_prelude::*;
use crate::storage::LongFormNoteDraft;
#[derive(Template)]
#[template(path = "notes/longform/draft_edit.gmi", escape = "txt")]
pub struct LfNoteDraftEditTemplate<'c> {
url: Url,
draft: LongFormNoteDraft<'c>,
draft_id: String,
draft_body: String,
}
pub async fn draft_longform_new(
ctx: RouteContext,
_user: &'static mut CaracalUser,
) -> Response {
match decode_query(&ctx) {
Some(id) => {
if !id.is_empty() {
Response::temporary_redirect(format!(
"/draft/longform/new/{}",
id
))
} else {
Response::input(t!("longform_note_input_id"))
}
}
None => Response::input(t!("longform_note_input_id")),
}
}
pub async fn draft_longform_new_with_id(
ctx: RouteContext,
user: &'static mut CaracalUser,
) -> Response {
let Some(id) = ctx.parameters.get("id") else {
return Response::input(t!("longform_note_input_id"));
};
let Ok(_) = user.storage.lf_draft_new(id) else {
return resp_error_generic();
};
Response::temporary_redirect(format!("/draft/longform/{}/edit", id))
}
pub async fn draft_longform_edit(
ctx: RouteContext,
user: &'static mut CaracalUser,
) -> Response {
let Some(draft_id) = ctx.draft_id() else {
return resp_invalid_params();
};
let Ok(mut rtxn) = user.storage.get_read_txn() else {
return resp_error_generic();
};
let Ok(draft) = user.storage.lf_draft_get(&draft_id, &mut rtxn) else {
return resp_error_generic();
};
let Ok(draft_body) = user.storage.lf_draft_get_content(&draft_id) else {
return resp_error_generic();
};
let template = LfNoteDraftEditTemplate {
url: ctx.url,
draft,
draft_id: draft_id.to_string(),
draft_body,
};
Response::success(WindTemplate::render(template))
}
pub async fn draft_longform_body_append(
ctx: RouteContext,
user: &'static mut CaracalUser,
) -> Response {
let Some(text) = decode_query(&ctx) else {
return Response::input("Gemtext ?");
};
let Some(draft_id) = ctx.draft_id() else {
return resp_invalid_params();
};
match user.storage.lf_draft_append_gemtext(&draft_id, &text) {
Ok(_) => Response::temporary_redirect(format!(
"gemini://{}/draft/longform/{}/edit",
ctx.url.authority(),
draft_id
)),
Err(_) => Response::temporary_failure("Draft store failure"),
}
}
pub async fn draft_longform_delete_last_line(
ctx: RouteContext,
user: &'static mut CaracalUser,
) -> Response {
let Some(draft_id) = ctx.draft_id() else {
return resp_invalid_params();
};
match user.storage.lf_draft_delete_last(&draft_id) {
Ok(_) => Response::temporary_redirect(format!(
"/draft/longform/{}/edit",
draft_id
)),
Err(_) => Response::temporary_failure("Draft store failure"),
}
}
pub async fn draft_longform_preview(
ctx: RouteContext,
user: &'static mut CaracalUser,
) -> Response {
let Some(draft_id) = ctx.parameters.get("draft_id") else {
return resp_invalid_params();
};
let Ok(content) = user.storage.lf_draft_get_content(draft_id) else {
return resp_error_generic();
};
Response::success(content)
}
pub async fn draft_longform_set(
ctx: RouteContext,
user: &'static mut CaracalUser,
) -> Response {
let Some(draft_id) = ctx.draft_id() else {
return resp_invalid_params();
};
let Some(mut segments) = ctx.url.path_segments() else {
return resp_invalid_params();
};
let Ok(mut rtxn) = user.storage.get_read_txn() else {
return resp_error_generic();
};
let Ok(mut draft) = user.storage.lf_draft_get(&draft_id, &mut rtxn) else {
return resp_error_generic();
};
let last_segment = segments.next_back();
if let Some("title") = last_segment {
let Some(query) = ctx.url.query() else {
return Response::input("Title ?");
};
draft.title = Some(query);
}
if let Some("summary") = last_segment {
let Some(query) = ctx.url.query() else {
return Response::input("Summary ?");
};
draft.summary = Some(query);
}
match user.storage.lf_draft_store(&draft_id, draft) {
Ok(_) => Response::temporary_redirect(format!(
"/draft/longform/{}/edit",
draft_id
)),
Err(_) => Response::temporary_failure("Failed to store draft"),
}
}
pub async fn draft_longform_post(
ctx: RouteContext,
user: &'static mut CaracalUser,
) -> Response {
let Some(draft_id) = ctx.draft_id() else {
return resp_invalid_params();
};
let Ok(mut rtxn) = user.storage.get_read_txn() else {
return resp_invalid_params();
};
let Ok(draft) = user.storage.lf_draft_get(&draft_id, &mut rtxn) else {
return resp_error_generic();
};
let Ok(content) = user.storage.lf_draft_get_content(&draft_id) else {
return resp_error_generic();
};
let body = gemtext2md(content);
let mut tags = Vec::new();
tags.push(Tag::identifier(draft_id));
tags.push(Tag::from_standardized(TagStandard::PublishedAt(
Timestamp::now(),
)));
if let Some(title) = draft.title {
tags.push(Tag::from_standardized(TagStandard::Title(
title.to_string(),
)));
}
if let Some(summary) = draft.summary {
tags.push(Tag::from_standardized(TagStandard::Summary(
summary.to_string(),
)));
}
let builder = EventBuilder::long_form_text_note(&body).tags(tags);
match user.send_builder(builder).await {
Ok(output) => Response::temporary_redirect(format!(
"/note/{}/thread",
output.id()
)),
Err(_) => resp_error_send_note(),
}
}