Allow setting avatar when creating identity

This commit is contained in:
Matéo Duparc 2021-05-26 15:01:48 +02:00
parent b3ae7ba703
commit 541fe10f1a
Signed by: hardcoresushi
GPG Key ID: 007F84120107191E
10 changed files with 256 additions and 219 deletions

View File

@ -46,9 +46,11 @@ fn generate_web_files() {
"commons/script.js", "commons/script.js",
].iter().for_each(|file_name| { ].iter().for_each(|file_name| {
let path = Path::new(file_name); let path = Path::new(file_name);
let src_path = src_dir.join(path);
println!("cargo:rerun-if-changed={}", src_path.to_str().unwrap());
let extension = path.extension().unwrap().to_str().unwrap(); let extension = path.extension().unwrap().to_str().unwrap();
let mut content = read_to_string(src_dir.join(path)).unwrap(); let mut content = read_to_string(src_path).unwrap();
if extension == "css" { if extension == "css" || file_name == &"login.html" {
replace_fields(&mut content, fields); replace_fields(&mut content, fields);
} }
if file_name == &"index.html" { if file_name == &"index.html" {
@ -59,7 +61,9 @@ fn generate_web_files() {
dst.write(minified_content.as_bytes()).unwrap(); dst.write(minified_content.as_bytes()).unwrap();
}); });
let mut text_avatar = read_to_string("src/frontend/imgs/text_avatar.svg").unwrap(); const TEXT_AVATAR_PATH: &str = "src/frontend/imgs/text_avatar.svg";
let mut text_avatar = read_to_string(TEXT_AVATAR_PATH).unwrap();
println!("cargo:rerun-if-changed={}", TEXT_AVATAR_PATH);
replace_fields(&mut text_avatar, fields); replace_fields(&mut text_avatar, fields);
File::create(out_dir.join("text_avatar.svg")).unwrap().write(text_avatar.as_bytes()).unwrap(); File::create(out_dir.join("text_avatar.svg")).unwrap().write(text_avatar.as_bytes()).unwrap();
} }

View File

@ -15,3 +15,53 @@ function generateAvatar(sessionId, name, timestamp) {
img.src = "/avatar/"+sessionId+"/"+name+"?"+timestamp; img.src = "/avatar/"+sessionId+"/"+name+"?"+timestamp;
return img; return img;
} }
function removePopup() {
let popups = document.querySelectorAll(".popup_background");
if (popups.length > 0) {
popups[popups.length-1].remove();
}
}
function showPopup(content, cancelable = true) {
let popup_background = document.createElement("div");
popup_background.classList.add("popup_background");
let popup = document.createElement("div");
popup.classList.add("popup");
if (cancelable) {
popup_background.onclick = function(e) {
if (e.target == popup_background) {
removePopup();
}
};
let close = document.createElement("button");
close.classList.add("close");
close.onclick = removePopup;
popup.appendChild(close);
}
popup.appendChild(content);
popup_background.appendChild(popup);
let main = document.querySelector("main");
main.appendChild(popup_background);
}
function uploadAvatar(event, onUploaded) {
let file = event.target.files[0];
if (file.size < 10000000) {
let formData = new FormData();
formData.append("avatar", file);
fetch("/set_avatar", {method: "POST", body: formData}).then(response => {
if (response.ok) {
onUploaded();
} else {
console.log(response);
}
});
} else {
let mainDiv = document.createElement("div");
mainDiv.appendChild(generatePopupWarningTitle());
let p = document.createElement("p");
p.textContent = "Avatar cannot be larger than 10MB.";
mainDiv.appendChild(p);
showPopup(mainDiv);
}
}

View File

@ -24,6 +24,13 @@ input[type="text"], input[type="password"] {
width: 100%; width: 100%;
margin: 0; margin: 0;
} }
input[type="file"] {
display: none;
}
label {
cursor: pointer;
}
.avatar { .avatar {
margin-right: .5em; margin-right: .5em;
@ -31,3 +38,83 @@ input[type="text"], input[type="password"] {
height: 1.5em; height: 1.5em;
border-radius: 50%; border-radius: 50%;
} }
main.card {
max-width: 500px;
background-color: #2B2F31;
border-radius: 10px;
position: absolute;
top: 50%;
transform: translateY(-50%);
left: 0;
right: 0;
margin: auto;
}
.popup {
position: absolute;
top: 50%;
transform: translateY(-50%);
left: 0;
right: 0;
margin: auto;
width: 40vw;
max-height: 90vh;
overflow: auto;
box-sizing: border-box;
padding: 20px 70px 10px;
background-color: #2B2F31;
border-radius: 10px;
font-size: 1.2em;
}
.popup:last-child::after {
content: "";
display: block;
height: 20px;
width: 100%;
}
.popup_background {
height: 100%;
width: 100%;
position: absolute;
background-color: rgba(0, 0, 0, .5);
z-index: 2;
}
.popup .close {
background-color: unset;
position: absolute;
right: 0;
top: 6px;
}
.popup .close::after {
content: url("/static/imgs/icons/cancel");
background-color: unset;
}
#avatarContainer {
display: flex;
justify-content: center;
padding-bottom: 1.5em;
}
#avatarContainer .avatar {
margin-right: unset;
}
#avatarContainer label:hover .avatar {
opacity: .4;
}
#avatarContainer label {
position: relative;
}
#avatarContainer .avatar + p {
display: none;
position: absolute;
top: 50%;
transform: translateY(-50%);
left: 0;
right: 0;
margin: 0;
text-align: center;
}
#avatarContainer label:hover p {
display: block;
}

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#FILL_COLOR"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></svg>

After

Width:  |  Height:  |  Size: 243 B

View File

@ -48,9 +48,6 @@ button:hover::after {
.classic_button:hover { .classic_button:hover {
background-color: var(--accent); background-color: var(--accent);
} }
input[type="file"] {
display: none;
}
.file_picker { .file_picker {
display: flex; display: flex;
align-items: center; align-items: center;
@ -60,57 +57,12 @@ input[type="file"] {
content: url("/static/imgs/icons/attach/ACCENT_COLOR"); content: url("/static/imgs/icons/attach/ACCENT_COLOR");
width: 2em; width: 2em;
} }
.popup {
position: absolute;
top: 50%;
transform: translateY(-50%);
left: 0;
right: 0;
margin: auto;
width: 40vw;
max-height: 90vh;
overflow: auto;
box-sizing: border-box;
padding: 20px 70px 10px;
background-color: #2B2F31;
border-radius: 10px;
font-size: 1.2em;
}
.popup:last-child::after {
content: "";
display: block;
height: 20px;
width: 100%;
}
.popup_background {
height: 100%;
width: 100%;
position: absolute;
background-color: rgba(0, 0, 0, .5);
z-index: 2;
}
.popup .close {
background-color: unset;
position: absolute;
right: 0;
top: 6px;
}
.popup .close:hover {
background-color: unset;
}
.popup .close::after {
content: url("/static/imgs/icons/cancel");
background-color: unset;
}
.popup h2.warning::before { .popup h2.warning::before {
content: url("/static/imgs/icons/warning/ACCENT_COLOR"); content: url("/static/imgs/icons/warning/ACCENT_COLOR");
width: 9%; width: 9%;
display: inline-block; display: inline-block;
vertical-align: middle; vertical-align: middle;
} }
label {
cursor: pointer;
}
.switch_preference { .switch_preference {
display: flex; display: flex;
align-items: center; align-items: center;
@ -166,32 +118,9 @@ label {
} }
#avatarContainer { #avatarContainer {
position: relative; position: relative;
padding-bottom: 1.5em;
display: flex;
justify-content: center;
} }
#avatarContainer .avatar { #avatarContainer .avatar {
font-size: 4em; font-size: 4em;
margin-right: unset;
}
#avatarContainer label:hover .avatar {
opacity: .4;
}
#avatarContainer>label {
position: relative;
}
#avatarContainer .avatar + p {
display: none;
position: absolute;
top: 50%;
transform: translateY(-50%);
left: 0;
right: 0;
margin: auto;
text-align: center;
}
#avatarContainer label:hover p {
display: block;
} }
#removeAvatar { #removeAvatar {
position: absolute; position: absolute;

View File

@ -247,26 +247,10 @@ profile_div.onclick = function() {
inputAvatar.accept = "image/*"; inputAvatar.accept = "image/*";
inputAvatar.id = "avatar_input"; inputAvatar.id = "avatar_input";
inputAvatar.onchange = function(event) { inputAvatar.onchange = function(event) {
let file = event.target.files[0]; uploadAvatar(event, function() {
if (file.size < 10000000) {
let formData = new FormData();
formData.append("avatar", file);
fetch("/set_avatar", {method: "POST", body: formData}).then(response => {
if (response.ok) {
avatarTimestamps.set("self", Date.now()); avatarTimestamps.set("self", Date.now());
refreshSelfAvatar(); refreshSelfAvatar();
} else {
console.log(response);
}
}); });
} else {
let mainDiv = document.createElement("div");
mainDiv.appendChild(generatePopupWarningTitle());
let p = document.createElement("p");
p.textContent = "Avatar cannot be larger than 10MB.";
mainDiv.appendChild(p);
showPopup(mainDiv);
}
}; };
labelAvatar.appendChild(inputAvatar); labelAvatar.appendChild(inputAvatar);
labelAvatar.appendChild(generateSelfAvatar(avatarTimestamps.get("self"))); labelAvatar.appendChild(generateSelfAvatar(avatarTimestamps.get("self")));
@ -965,33 +949,6 @@ function displayHeader() {
} }
} }
} }
function showPopup(content, cancelable = true) {
let popup_background = document.createElement("div");
popup_background.classList.add("popup_background");
let popup = document.createElement("div");
popup.classList.add("popup");
if (cancelable) {
popup_background.onclick = function(e) {
if (e.target == popup_background) {
removePopup();
}
};
let close = document.createElement("button");
close.classList.add("close");
close.onclick = removePopup;
popup.appendChild(close);
}
popup.appendChild(content);
popup_background.appendChild(popup);
let main = document.querySelector("main");
main.appendChild(popup_background);
}
function removePopup() {
let popups = document.querySelectorAll(".popup_background");
if (popups.length > 0) {
popups[popups.length-1].remove();
}
}
function generatePopupWarningTitle() { function generatePopupWarningTitle() {
let h2 = document.createElement("h2"); let h2 = document.createElement("h2");
h2.classList.add("warning"); h2.classList.add("warning");

View File

@ -14,14 +14,6 @@
background-color: black; background-color: black;
} }
main { main {
max-width: 500px;
background-color: #2B2F31;
border-radius: 10px;
position: absolute;
top: 20vh;
left: 0;
right: 0;
margin: auto;
padding-bottom: 20px; padding-bottom: 20px;
} }
h1, main>h3, #error_msg { h1, main>h3, #error_msg {
@ -40,6 +32,9 @@
font-weight: bold; font-weight: bold;
margin-bottom: 0; margin-bottom: 0;
} }
.action_page>h2 {
margin-top: 0;
}
input[type="text"], input[type="password"] { input[type="text"], input[type="password"] {
margin-bottom: 20px; margin-bottom: 20px;
} }
@ -65,13 +60,11 @@
.avatar { .avatar {
width: 7em; width: 7em;
height: 7em; height: 7em;
display: block;
margin: auto;
} }
#identity h2 { #identity h2 {
text-align: center; text-align: center;
} }
p { #error_msg {
color: red; color: red;
} }
label.checkbox { label.checkbox {
@ -110,24 +103,41 @@
label.checkbox input:checked ~ .checkmark:after { label.checkbox input:checked ~ .checkmark:after {
display: block; display: block;
} }
#avatarContainer .avatar.unset {
border: 2px solid var(--accent);
}
#identity .avatar {
display: block;
margin: auto;
}
</style> </style>
</head> </head>
<body> <body>
<main> <main class="card">
<h1>AIRA</h1> <h1>AIRA</h1>
<h3>Local network secure P2P communications</h3> <h3>Local network secure P2P communications</h3>
<p id="error_msg">ERROR_MSG</p> <p id="error_msg">ERROR_MSG</p>
<div id="login_page" class="action_page"> <div id="login_page" class="action_page">
<h2>Login:</h2> <h2>Login:</h2>
<form id="login_form" method="POST" action="/login"> <form id="login_form" method="POST" action="/login">
<div id="identity"></div> <div id="identity">
<img class="avatar" src="/avatar/self"/>
<h2 id="identityName"></h2>
</div>
<input name="password" type="password" placeholder="Password"> <input name="password" type="password" placeholder="Password">
<button type="submit">Login</button> <button type="submit">Login</button>
</form> </form>
</div> </div>
<div id="create_page" class="action_page"> <div id="create_page" class="action_page">
<h2>Create New Identity:</h2> <h2>Create a new identity:</h2>
<form method="POST"> <form method="POST">
<div id="avatarContainer">
<label>
<input type="file" accept="image/*">
<img class="avatar unset" src="/static/imgs/icons/profile/ACCENT_COLOR"/>
<p>Upload</p>
</label>
</div>
<input type="text" name="name" placeholder="Name" required> <input type="text" name="name" placeholder="Name" required>
<label class="checkbox"> <label class="checkbox">
<input id="enable_password" type="checkbox"> <input id="enable_password" type="checkbox">
@ -142,12 +152,20 @@
</main> </main>
<script src="/static/commons/script.js"></script> <script src="/static/commons/script.js"></script>
<script> <script>
let identity_name = IDENTITY_NAME; let identityName = IDENTITY_NAME;
if (identity_name == null) { if (identityName == null) {
document.getElementById("login_page").style.display = "none"; document.getElementById("login_page").style.display = "none";
document.querySelector("#avatarContainer input").onchange = function(event) {
uploadAvatar(event, function() {
let img = document.querySelector("#avatarContainer .avatar");
img.src = "/avatar/self?"+Date.now();
img.classList.remove("unset");
});
};
let passwordInputs = document.querySelectorAll("#create_page input[type=\"password\"]");
let enable_password = document.getElementById("enable_password"); let enable_password = document.getElementById("enable_password");
enable_password.onchange = function() { enable_password.onchange = function() {
document.querySelectorAll("#create_page input[type=\"password\"]").forEach(function(i) { passwordInputs.forEach(function(i) {
if (enable_password.checked) { if (enable_password.checked) {
i.style.display = "block"; i.style.display = "block";
} else { } else {
@ -156,11 +174,8 @@
}); });
} }
} else { } else {
let identity = document.getElementById("identity"); let h2Name = document.getElementById("identityName");
identity.appendChild(generateSelfAvatar(Date.now())); h2Name.textContent = identityName;
let h2 = document.createElement("h2");
h2.textContent = identity_name;
identity.appendChild(h2);
document.getElementById("create_page").style.display = "none"; document.getElementById("create_page").style.display = "none";
} }
</script> </script>

View File

@ -14,15 +14,6 @@
background-color: black; background-color: black;
} }
main { main {
max-width: 500px;
background-color: #2B2F31;
border-radius: 10px;
position: absolute;
top: 50%;
transform: translateY(-50%);
left: 0;
right: 0;
margin: auto;
padding: 50px; padding: 50px;
} }
img { img {
@ -37,7 +28,7 @@
</style> </style>
</head> </head>
<body> <body>
<main> <main class="card">
<img src="/static/imgs/frog"> <img src="/static/imgs/frog">
<p>You've been successfully logged out.</p> <p>You've been successfully logged out.</p>
</main> </main>

View File

@ -309,8 +309,7 @@ fn is_authenticated(req: &HttpRequest) -> bool {
} }
async fn handle_set_avatar(req: HttpRequest, mut payload: Multipart) -> HttpResponse { async fn handle_set_avatar(req: HttpRequest, mut payload: Multipart) -> HttpResponse {
if is_authenticated(&req) { if let Ok(Some(mut field)) = payload.try_next().await {
while let Ok(Some(mut field)) = payload.try_next().await {
let content_disposition = field.content_disposition().unwrap(); let content_disposition = field.content_disposition().unwrap();
if let Some(name) = content_disposition.get_name() { if let Some(name) = content_disposition.get_name() {
if name == "avatar" { if name == "avatar" {
@ -333,8 +332,15 @@ async fn handle_set_avatar(req: HttpRequest, mut payload: Multipart) -> HttpResp
let mut avatar = Vec::new(); let mut avatar = Vec::new();
image.write_to(&mut avatar, format).unwrap(); image.write_to(&mut avatar, format).unwrap();
let global_vars = req.app_data::<Data<Arc<RwLock<GlobalVars>>>>().unwrap(); let global_vars = req.app_data::<Data<Arc<RwLock<GlobalVars>>>>().unwrap();
match global_vars.read().unwrap().session_manager.set_avatar(&avatar).await { let session_manager = &global_vars.read().unwrap().session_manager;
let is_authenticated = is_authenticated(&req);
let is_running = session_manager.is_identity_loaded();
if is_authenticated || !is_running {
match Identity::set_identity_avatar(&avatar) {
Ok(_) => { Ok(_) => {
if is_authenticated && is_running {
session_manager.send_avatar(&avatar).await;
}
return HttpResponse::Ok().finish(); return HttpResponse::Ok().finish();
} }
Err(e) => { Err(e) => {
@ -343,6 +349,7 @@ async fn handle_set_avatar(req: HttpRequest, mut payload: Multipart) -> HttpResp
} }
} }
} }
}
Err(e) => print_error!(e) Err(e) => print_error!(e)
} }
} }
@ -351,20 +358,22 @@ async fn handle_set_avatar(req: HttpRequest, mut payload: Multipart) -> HttpResp
} }
} }
} }
}
HttpResponse::BadRequest().finish() HttpResponse::BadRequest().finish()
} }
fn reply_with_avatar(avatar: Option<Vec<u8>>, name: &str) -> HttpResponse { fn reply_with_avatar(avatar: Option<Vec<u8>>, name: Option<&str>) -> HttpResponse {
match avatar { match avatar {
Some(avatar) => HttpResponse::Ok().content_type("image/*").body(avatar), Some(avatar) => HttpResponse::Ok().content_type("image/*").body(avatar),
None => { None => match name {
Some(name) => {
#[cfg(not(debug_assertions))] #[cfg(not(debug_assertions))]
let svg = include_str!(concat!(env!("OUT_DIR"), "/text_avatar.svg")); let svg = include_str!(concat!(env!("OUT_DIR"), "/text_avatar.svg"));
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
let svg = replace_fields("src/frontend/imgs/text_avatar.svg"); let svg = replace_fields("src/frontend/imgs/text_avatar.svg");
HttpResponse::Ok().content_type("image/svg+xml").body(svg.replace("LETTER", &name.chars().nth(0).unwrap().to_string())) HttpResponse::Ok().content_type("image/svg+xml").body(svg.replace("LETTER", &name.chars().nth(0).unwrap().to_string()))
} }
None => HttpResponse::InternalServerError().finish()
}
} }
} }
@ -372,12 +381,12 @@ fn handle_avatar(req: HttpRequest) -> HttpResponse {
let splits: Vec<&str> = req.path()[1..].split("/").collect(); let splits: Vec<&str> = req.path()[1..].split("/").collect();
if splits.len() == 2 { if splits.len() == 2 {
if splits[1] == "self" { if splits[1] == "self" {
return reply_with_avatar(Identity::get_identity_avatar().ok(), &Identity::get_identity_name().unwrap()); return reply_with_avatar(Identity::get_identity_avatar().ok(), Identity::get_identity_name().ok().as_deref());
} }
} else if splits.len() == 3 { } else if splits.len() == 3 {
if let Ok(session_id) = splits[1].parse() { if let Ok(session_id) = splits[1].parse() {
let global_vars = req.app_data::<Data<Arc<RwLock<GlobalVars>>>>().unwrap(); let global_vars = req.app_data::<Data<Arc<RwLock<GlobalVars>>>>().unwrap();
return reply_with_avatar(global_vars.read().unwrap().session_manager.get_avatar(&session_id), splits[2]); return reply_with_avatar(global_vars.read().unwrap().session_manager.get_avatar(&session_id), Some(splits[2]));
} }
} }
HttpResponse::BadRequest().finish() HttpResponse::BadRequest().finish()
@ -447,9 +456,7 @@ async fn handle_send_file(req: HttpRequest, mut payload: Multipart) -> HttpRespo
loop { loop {
chunk_buffer.extend(&pending_buffer); chunk_buffer.extend(&pending_buffer);
pending_buffer.clear(); pending_buffer.clear();
println!("Calling next()");
while let Some(Ok(chunk)) = field.next().await { while let Some(Ok(chunk)) = field.next().await {
println!("Not None");
if chunk_buffer.len()+chunk.len() <= constants::FILE_CHUNK_SIZE { if chunk_buffer.len()+chunk.len() <= constants::FILE_CHUNK_SIZE {
chunk_buffer.extend(chunk); chunk_buffer.extend(chunk);
} else if chunk_buffer.len() == constants::FILE_CHUNK_SIZE { } else if chunk_buffer.len() == constants::FILE_CHUNK_SIZE {
@ -462,7 +469,6 @@ async fn handle_send_file(req: HttpRequest, mut payload: Multipart) -> HttpRespo
break; break;
} }
} }
println!("May be None");
if !global_vars_read.session_manager.send_command(&session_id, SessionCommand::EncryptFileChunk{ if !global_vars_read.session_manager.send_command(&session_id, SessionCommand::EncryptFileChunk{
plain_text: chunk_buffer.clone() plain_text: chunk_buffer.clone()
}).await { }).await {
@ -546,6 +552,10 @@ fn on_identity_loaded(identity: Identity, global_vars: &Arc<RwLock<GlobalVars>>)
login(identity, global_vars) login(identity, global_vars)
} }
#[derive(Serialize, Deserialize)]
struct LoginParams {
password: String,
}
fn handle_login(req: HttpRequest, mut params: web::Form<LoginParams>) -> HttpResponse { fn handle_login(req: HttpRequest, mut params: web::Form<LoginParams>) -> HttpResponse {
let response = match Identity::load_identity(Some(params.password.as_bytes())) { let response = match Identity::load_identity(Some(params.password.as_bytes())) {
Ok(identity) => { Ok(identity) => {
@ -560,7 +570,7 @@ fn handle_login(req: HttpRequest, mut params: web::Form<LoginParams>) -> HttpRes
fn get_login_body(error_msg: Option<&str>) -> Result<String, rusqlite::Error> { fn get_login_body(error_msg: Option<&str>) -> Result<String, rusqlite::Error> {
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
let html = fs::read_to_string("src/frontend/login.html").unwrap(); let html = replace_fields("src/frontend/login.html");
#[cfg(not(debug_assertions))] #[cfg(not(debug_assertions))]
let html = include_str!(concat!(env!("OUT_DIR"), "/login.html")); let html = include_str!(concat!(env!("OUT_DIR"), "/login.html"));
Ok(html Ok(html
@ -570,8 +580,10 @@ fn get_login_body(error_msg: Option<&str>) -> Result<String, rusqlite::Error> {
}) })
.replace("IDENTITY_NAME", &match Identity::get_identity_name() { .replace("IDENTITY_NAME", &match Identity::get_identity_name() {
Ok(name) => format!("\"{}\"", html_escape::encode_double_quoted_attribute(&name)), Ok(name) => format!("\"{}\"", html_escape::encode_double_quoted_attribute(&name)),
Err(e) => { Err(_) => {
if let Err(e) = Identity::remove_identity_avatar() {
print_error!(e); print_error!(e);
}
"null".to_owned() "null".to_owned()
} }
} }
@ -589,6 +601,12 @@ fn generate_login_response(error_msg: Option<&str>) -> HttpResponse {
} }
} }
#[derive(Serialize, Deserialize)]
struct CreateParams {
name: String,
password: String,
password_confirm: String,
}
async fn handle_create(req: HttpRequest, mut params: web::Form<CreateParams>) -> HttpResponse { async fn handle_create(req: HttpRequest, mut params: web::Form<CreateParams>) -> HttpResponse {
let response = if params.password == params.password_confirm { let response = if params.password == params.password_confirm {
match Identity::create_identidy( match Identity::create_identidy(
@ -701,6 +719,7 @@ fn handle_static(req: HttpRequest) -> HttpResponse {
"refresh" => Some(include_str!("frontend/imgs/icons/refresh.svg")), "refresh" => Some(include_str!("frontend/imgs/icons/refresh.svg")),
"info" => Some(include_str!("frontend/imgs/icons/info.svg")), "info" => Some(include_str!("frontend/imgs/icons/info.svg")),
"delete_conversation" => Some(include_str!("frontend/imgs/icons/delete_conversation.svg")), "delete_conversation" => Some(include_str!("frontend/imgs/icons/delete_conversation.svg")),
"profile" => Some(include_str!("frontend/imgs/icons/profile.svg")),
_ => None _ => None
} { } {
Some(body) => { Some(body) => {
@ -796,18 +815,6 @@ async fn start_http_server(global_vars: Arc<RwLock<GlobalVars>>) -> io::Result<(
server.run().await server.run().await
} }
#[derive(Serialize, Deserialize)]
struct LoginParams {
password: String,
}
#[derive(Serialize, Deserialize)]
struct CreateParams {
name: String,
password: String,
password_confirm: String,
}
struct GlobalVars { struct GlobalVars {
session_manager: Arc<SessionManager>, session_manager: Arc<SessionManager>,
websocket_port: u16, websocket_port: u16,

View File

@ -681,15 +681,13 @@ impl SessionManager {
} }
#[allow(unused_must_use)] #[allow(unused_must_use)]
pub async fn set_avatar(&self, avatar: &[u8]) -> Result<(), rusqlite::Error> { pub async fn send_avatar(&self, avatar: &[u8]) {
Identity::set_identity_avatar(&avatar)?;
let avatar_msg = protocol::avatar(&avatar); let avatar_msg = protocol::avatar(&avatar);
for sender in self.get_all_senders().into_iter() { for sender in self.get_all_senders().into_iter() {
sender.send(SessionCommand::Send { sender.send(SessionCommand::Send {
buff: avatar_msg.clone() buff: avatar_msg.clone()
}).await; }).await;
} }
Ok(())
} }
#[allow(unused_must_use)] #[allow(unused_must_use)]
@ -705,17 +703,15 @@ impl SessionManager {
} }
#[allow(unused_must_use)] #[allow(unused_must_use)]
pub async fn change_name(&self, new_name: String) -> Result<usize, rusqlite::Error> { pub async fn change_name(&self, new_name: String) -> Result<(), rusqlite::Error> {
let telling_name = protocol::name(&new_name); let telling_name = protocol::name(&new_name);
let result = self.identity.write().unwrap().as_mut().unwrap().change_name(new_name); self.identity.write().unwrap().as_mut().unwrap().change_name(new_name)?;
if result.is_ok() {
for sender in self.get_all_senders().into_iter() { for sender in self.get_all_senders().into_iter() {
sender.send(SessionCommand::Send { sender.send(SessionCommand::Send {
buff: telling_name.clone() buff: telling_name.clone()
}).await; }).await;
} }
} Ok(())
result
} }
#[allow(unused_must_use)] #[allow(unused_must_use)]