diff options
Diffstat (limited to 'src/forms.rs')
-rw-r--r-- | src/forms.rs | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/src/forms.rs b/src/forms.rs new file mode 100644 index 0000000..fc16d09 --- /dev/null +++ b/src/forms.rs @@ -0,0 +1,137 @@ +use serde::Deserialize; +use sputnik::html_escape; + +use crate::{action_links, controller::Controller, get_renderer, Context, Error, Page, Response}; + +fn render_error(message: &str) -> String { + format!("<div class=error>error: {}</div>", html_escape(message)) +} + +#[derive(Deserialize, Default)] +pub struct EditForm { + pub text: String, + pub msg: Option<String>, + pub oid: Option<String>, +} + +pub fn edit_text_form<'a, C: Controller>( + data: &EditForm, + error: Option<&str>, + controller: &'a C, + ctx: &'a Context, +) -> Page<'a> { + let mut page = Page { + title: format!( + "{} {}", + if data.oid.is_some() { + "Editing" + } else { + "Creating" + }, + ctx.path.file_name().unwrap().to_str().unwrap() + ), + header: data + .oid + .is_some() + .then(|| action_links("edit", controller, ctx)), + body: String::new(), + controller, + parts: &ctx.parts, + }; + if let Some(access_info_html) = controller.access_info_html(&ctx) { + page.body.push_str(&access_info_html); + } + if let Some(hint_html) = controller.edit_hint_html(ctx) { + page.body + .push_str(&format!("<div class=edit-hint>{}</div>", hint_html)); + } + if let Some(error) = error { + page.body.push_str(&render_error(error)); + } + page.body.push_str(&format!( + "<form method=post action='?action=edit' class=edit-form>\ + <textarea name=text autofocus autocomplete=off>{}</textarea>", + html_escape(&data.text) + )); + page.body + .push_str("<div class=buttons><button>Save</button>"); + if let Some(oid) = &data.oid { + page.body.push_str(&format!( + "<input name=oid type=hidden value='{}'> + <button formaction='?action=diff'>Diff</button>", + oid + )); + } + if get_renderer(&ctx.path).is_some() { + page.body + .push_str(" <button formaction='?action=preview'>Preview</button>") + } + page.body.push_str(&format!( + "<input name=msg placeholder=Message value='{}' autocomplete=off></div></form>", + html_escape(data.msg.as_deref().unwrap_or_default()) + )); + + page.body.push_str(&format!( + "<script>{}</script>", + include_str!("static/edit_script.js") + )); + page +} + +#[derive(Deserialize)] +pub struct MoveForm { + pub dest: String, + pub msg: Option<String>, +} + +pub fn move_form<C: Controller>( + filename: &str, + data: &MoveForm, + error: Option<&str>, + controller: &C, + ctx: &Context, +) -> Result<Response, Error> { + let mut page = Page { + title: format!("Move {}", filename), + controller, + parts: &ctx.parts, + body: String::new(), + header: Some(action_links("move", controller, ctx)), + }; + + if let Some(error) = error { + page.body.push_str(&render_error(error)); + } + + page.body.push_str(&format!( + "<form method=post autocomplete=off> + <label>Destination <input name=dest value='{}' autofocus></label> + <label>Message <input name=msg value='{}'></label> + <button>Move</button> + </form>", + html_escape(&data.dest), + data.msg.as_ref().map(html_escape).unwrap_or_default(), + )); + + Ok(page.into()) +} + +pub fn upload_form<'a, C: Controller>( + file_exists: bool, + controller: &'a C, + ctx: &'a Context, +) -> Page<'a> { + let filename = ctx.path.file_name().unwrap().to_str().unwrap(); + Page { + title: format!("Uploading {}", filename), + // TODO: add input for commit message + body: "<form action=?action=upload method=post enctype='multipart/form-data'>\ + <input name=file type=file>\ + <button>Upload</button>\ + </form>" + .into(), + header: file_exists.then(|| action_links("edit", controller, &ctx)), + controller, + parts: &ctx.parts, + } +} |