peach-workspace/peach-web/src/routes/scuttlebutt/profile_update.rs

174 lines
7.0 KiB
Rust

use maud::{html, PreEscaped};
use peach_lib::sbot::SbotStatus;
use rouille::{input::post::BufferedFile, post_input, try_or_400, Request, Response};
use crate::{
templates,
utils::{
flash::{FlashRequest, FlashResponse},
sbot,
sbot::Profile,
theme,
},
};
// ROUTE: /scuttlebutt/profile/update
fn parse_profile_info(profile: Profile) -> (String, String, String) {
let id = match profile.id {
Some(id) => id,
_ => "Public key unavailable".to_string(),
};
let name = match profile.name {
Some(name) => name,
_ => "Name unavailable".to_string(),
};
let description = match profile.description {
Some(description) => description,
_ => "Description unavailable".to_string(),
};
(id, name, description)
}
/// Scuttlebutt profile update template builder.
///
/// Serve a form for the purpose of updating the name, description and picture
/// for the local Scuttlebutt profile.
pub fn build_template(request: &Request) -> PreEscaped<String> {
// check for flash cookies; will be (None, None) if no flash cookies are found
let (flash_name, flash_msg) = request.retrieve_flash();
let profile_update_template = match SbotStatus::read() {
Ok(status) if status.state == Some("active".to_string()) => {
// retrieve the local profile info
match sbot::get_profile_info(None) {
Ok(profile) => {
let (id, name, description) = parse_profile_info(profile);
// render the scuttlebutt profile update form
html! {
(PreEscaped("<!-- SSB PROFILE UPDATE FORM -->"))
div class="card card-wide center" {
form id="profileInfo" class="center" enctype="multipart/form-data" action="/scuttlebutt/profile/update" method="post" {
div style="display: flex; flex-direction: column" {
label for="name" class="label-small font-gray" {
"NAME"
}
input style="margin-bottom: 1rem;" type="text" id="name" name="new_name" placeholder="Choose a name for your profile..." value=(name);
label for="description" class="label-small font-gray" {
"DESCRIPTION"
}
textarea id="description" class="message-input" style="margin-bottom: 1rem;" name="new_description" placeholder="Write a description for your profile..." {
(description)
}
label for="image" class="label-small font-gray" {
"IMAGE"
}
input type="file" id="fileInput" class="font-normal" name="image";
}
input type="hidden" name="id" value=(id);
input type="hidden" name="current_name" value=(name);
input type="hidden" name="current_description" value=(description);
div id="buttonDiv" style="margin-top: 2rem;" {
input id="updateProfile" class="button button-primary center" title="Publish" type="submit" value="Publish";
a class="button button-secondary center" href="/scuttlebutt/profile" title="Cancel" { "Cancel" }
}
}
// render flash message if cookies were found in the request
@if let (Some(name), Some(msg)) = (flash_name, flash_msg) {
(PreEscaped("<!-- FLASH MESSAGE -->"))
(templates::flash::build_template(name, msg))
}
}
}
}
Err(e) => {
// render the sbot error template with the error message
templates::error::build_template(e.to_string())
}
}
}
_ => {
// the sbot is not active; render a message instead of the form
templates::inactive::build_template("Profile is unavailable.")
}
};
let body = templates::nav::build_template(
profile_update_template,
"Profile",
Some("/scuttlebutt/profile"),
);
// query the current theme so we can pass it into the base template builder
let theme = theme::get_theme();
templates::base::build_template(body, theme)
}
/// Update the name, description and picture for the local Scuttlebutt profile.
///
/// Redirects to profile page of the PeachCloud local identity with a flash
/// message describing the outcome of the action (may be successful or
/// unsuccessful).
pub fn handle_form(request: &Request) -> Response {
// query the request body for form data
// return a 400 error if the admin_id field is missing
let data = try_or_400!(post_input!(request, {
id: String,
current_name: String,
current_description: String,
new_name: Option<String>,
new_description: Option<String>,
image: Option<BufferedFile>,
}));
let (flash_name, flash_msg) = match SbotStatus::read() {
Ok(status) if status.state == Some("active".to_string()) => {
// we can't pass `data` into the function (due to macro creation)
// so we pass in each individual value instead
match sbot::update_profile_info(
data.current_name,
data.current_description,
data.new_name,
data.new_description,
data.image,
) {
Ok(success_msg) => (
"flash_name=success".to_string(),
format!("flash_msg={}", success_msg),
),
Err(error_msg) => (
"flash_name=error".to_string(),
format!("flash_msg={}", error_msg),
),
}
}
_ => (
"flash_name=warning".to_string(),
"Profile is unavailable.".to_string(),
),
};
Response::redirect_303("/scuttlebutt/profile/update").add_flash(flash_name, flash_msg)
}
/*
match sbot::validate_public_key(&data.public_key) {
Ok(_) => {
let url = format!("/scuttlebutt/profile?={}", &data.public_key);
Response::redirect_303(url)
}
Err(err) => {
let (flash_name, flash_msg) =
("flash_name=error".to_string(), format!("flash_msg={}", err));
Response::redirect_303("/scuttlebutt/search").add_flash(flash_name, flash_msg)
}
}
}
*/