181 lines
8.1 KiB
Rust
181 lines
8.1 KiB
Rust
use maud::{html, Markup, PreEscaped};
|
|
use peach_lib::sbot::SbotStatus;
|
|
use rouille::Request;
|
|
|
|
use crate::{
|
|
templates,
|
|
utils::{flash::FlashRequest, sbot, sbot::Profile},
|
|
};
|
|
|
|
// ROUTE: /scuttlebutt/profile
|
|
|
|
fn public_post_form_template() -> Markup {
|
|
html! {
|
|
(PreEscaped("<!-- PUBLIC POST FORM -->"))
|
|
form id="postForm" class="center" action="/scuttlebutt/publish" method="post" {
|
|
(PreEscaped("<!-- input for message contents -->"))
|
|
textarea id="publicPost" class="center input message-input" name="text" title="Compose Public Post" placeholder="Write a public post..." { }
|
|
input id="publishPost" class="button button-primary center" title="Publish" type="submit" value="Publish";
|
|
}
|
|
}
|
|
}
|
|
|
|
fn profile_info_box_template(profile: &Profile) -> Markup {
|
|
html! {
|
|
(PreEscaped("<!-- PROFILE INFO BOX -->"))
|
|
div class="capsule capsule-profile border-ssb" title="Scuttlebutt account profile information" {
|
|
@if profile.is_local_profile {
|
|
(PreEscaped("<!-- edit profile button -->"))
|
|
a class="nav-icon-right" href="/scuttlebutt/profile/update" title="Edit your profile" {
|
|
img id="editProfile" class="icon-small icon-active" src="/icons/pencil.svg" alt="Edit";
|
|
}
|
|
}
|
|
// render the profile bio: picture, id, name, image & description
|
|
(profile_bio_template(&profile))
|
|
}
|
|
}
|
|
}
|
|
|
|
fn profile_bio_template(profile: &Profile) -> Markup {
|
|
html! {
|
|
(PreEscaped("<!-- PROFILE BIO -->"))
|
|
(PreEscaped("<!-- profile picture -->"))
|
|
// only try to render profile pic if we have the blob
|
|
@match &profile.blob_path {
|
|
Some(blob_path) if profile.blob_exists => {
|
|
img id="profilePicture" class="icon-large" src={ "/blob/" (blob_path) } title="Profile picture" alt="Profile picture";
|
|
},
|
|
_ => {
|
|
// use a placeholder image if we don't have the blob
|
|
img id="peerImage" class="icon icon-active list-icon" src="/icons/user.svg" alt="Placeholder profile image";
|
|
}
|
|
}
|
|
(PreEscaped("<!-- name, public key & description -->"))
|
|
p id="profileName" class="card-text" title="Name" {
|
|
@if let Some(name) = &profile.name {
|
|
(name)
|
|
} @else {
|
|
"Name unavailable"
|
|
}
|
|
}
|
|
label class="label-small label-ellipsis font-gray" style="user-select: all;" for="profileName" title="Public Key" {
|
|
@if let Some(id) = &profile.id {
|
|
(id)
|
|
} @else {
|
|
"Public key unavailable"
|
|
}
|
|
}
|
|
p id="profileDescription" style="margin-top: 1rem" class="card-text" title="Description" {
|
|
@if let Some(description) = &profile.description {
|
|
(description)
|
|
} @else {
|
|
"Description unavailable"
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
fn social_interaction_buttons_template(profile: &Profile) -> Markup {
|
|
html! {
|
|
(PreEscaped("<!-- BUTTONS -->"))
|
|
div id="buttons" style="margin-top: 2rem;" {
|
|
@match (profile.following, &profile.id) {
|
|
(Some(false), Some(ssb_id)) => {
|
|
form id="followForm" class="center" action="/scuttlebutt/follow" method="post" {
|
|
input type="hidden" id="publicKey" name="public_key" value=(ssb_id);
|
|
input id="followPeer" class="button button-primary center" type="submit" title="Follow Peer" value="Follow";
|
|
}
|
|
},
|
|
(Some(true), Some(ssb_id)) => {
|
|
form id="unfollowForm" class="center" action="/scuttlebutt/unfollow" method="post" {
|
|
input type="hidden" id="publicKey" name="public_key" value=(ssb_id);
|
|
input id="unfollowPeer" class="button button-primary center" type="submit" title="Unfollow Peer" value="Unfollow";
|
|
}
|
|
},
|
|
_ => p { "Unable to determine follow state" }
|
|
}
|
|
@match (profile.blocking, &profile.id) {
|
|
(Some(false), Some(ssb_id)) => {
|
|
form id="blockForm" class="center" action="/scuttlebutt/block" method="post" {
|
|
input type="hidden" id="publicKey" name="public_key" value=(ssb_id);
|
|
input id="blockPeer" class="button button-primary center" type="submit" title="Block Peer" value="Block";
|
|
}
|
|
},
|
|
(Some(true), Some(ssb_id)) => {
|
|
form id="unblockForm" class="center" action="/scuttlebutt/unblock" method="post" {
|
|
input type="hidden" id="publicKey" name="public_key" value=(ssb_id);
|
|
input id="unblockPeer" class="button button-primary center" type="submit" title="Unblock Peer" value="Unblock";
|
|
}
|
|
},
|
|
_ => p { "Unable to determine block state" }
|
|
}
|
|
@if let Some(ssb_id) = &profile.id {
|
|
form class="center" {
|
|
a id="privateMessage" class="button button-primary center" href={ "/scuttlebutt/private?public_key=" (ssb_id) } title="Private Message" {
|
|
"Send Private Message"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Scuttlebutt profile template builder.
|
|
///
|
|
/// Render a Scuttlebutt profile, either for the local profile or for a peer
|
|
/// specified by a public key. If the public key query parameter is not
|
|
/// provided, the local profile is displayed (ie. the profile of the public key
|
|
/// associated with the local PeachCloud device).
|
|
pub fn build_template(request: &Request, ssb_id: Option<String>) -> 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_template = match SbotStatus::read() {
|
|
Ok(status) if status.state == Some("active".to_string()) => {
|
|
// TODO: validate ssb_id and return error template
|
|
|
|
// retrieve the profile info
|
|
match sbot::get_profile_info(ssb_id) {
|
|
Ok(profile) => {
|
|
// render the profile template
|
|
html! {
|
|
(PreEscaped("<!-- SSB PROFILE -->"))
|
|
div class="card card-wide center" {
|
|
// render profile info box
|
|
(profile_info_box_template(&profile))
|
|
@if profile.is_local_profile {
|
|
// render the public post form template
|
|
(public_post_form_template())
|
|
} @else {
|
|
// render follow / unfollow, block / unblock and
|
|
// private message buttons
|
|
(social_interaction_buttons_template(&profile))
|
|
}
|
|
}
|
|
// 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
|
|
let error_template = templates::error::build_template(e.to_string());
|
|
// wrap the nav bars around the error template content
|
|
let body = templates::nav::build_template(error_template, "Profile", Some("/"));
|
|
|
|
// render the base template with the provided body
|
|
templates::base::build_template(body)
|
|
}
|
|
}
|
|
}
|
|
_ => templates::inactive::build_template("Profile is unavailable."),
|
|
};
|
|
|
|
let body = templates::nav::build_template(profile_template, "Profile", Some("/"));
|
|
|
|
templates::base::build_template(body)
|
|
}
|