use std::collections::HashMap; use crate::{ State, get_user_from_token, routes::{ default_context, pages::{PaginatedQuery, misc::render_error}, }, }; use axum::{ Extension, extract::{Path, Query}, response::{Html, IntoResponse}, }; use axum_extra::extract::CookieJar; use serde::Deserialize; use tetratto_core::model::Error; pub async fn list_request( jar: CookieJar, Extension(data): Extension, Query(props): Query, ) -> impl IntoResponse { let (ref data, ref tera, ref build_code) = *data.read().await; let user = match get_user_from_token!(jar, data.2) { Some(x) => x, None => { return Err(render_error(Error::NotAllowed, tera, data.0.0.clone(), None).await); } }; if let Err(e) = data.2.update_user_missed_messages_count(user.id, 0).await { return Err(render_error(e, tera, data.0.0.clone(), Some(user)).await); } let chats = match data.get_chats_by_member(user.id, 12, props.page).await { Ok(x) => data.fill_chats(x).await, Err(e) => { return Err(render_error(e, tera, data.0.0.clone(), Some(user)).await); } }; let mut ctx = default_context(&data.0.0, &build_code, &Some(user)); ctx.insert("chats", &chats); ctx.insert("page", &props.page); Ok(Html(tera.render("chats.lisp", &ctx).unwrap())) } pub async fn chat_request( jar: CookieJar, Extension(data): Extension, Path(id): Path, ) -> impl IntoResponse { let (ref data, ref tera, ref build_code) = *data.read().await; let user = match get_user_from_token!(jar, data.2) { Some(x) => x, None => { return Err(render_error(Error::NotAllowed, tera, data.0.0.clone(), None).await); } }; let (chat, members) = match data.get_chat_by_id(id).await { Ok(x) => { if !x.members.contains(&user.id) { return Err( render_error(Error::NotAllowed, tera, data.0.0.clone(), Some(user)).await, ); } data.fill_chat(x).await } Err(e) => { return Err(render_error(e, tera, data.0.0.clone(), Some(user)).await); } }; let mut ctx = default_context(&data.0.0, &build_code, &Some(user)); ctx.insert("chat", &chat); ctx.insert("members", &members); Ok(Html(tera.render("chat.lisp", &ctx).unwrap())) } pub async fn single_message_request( jar: CookieJar, Extension(data): Extension, Path(id): Path, ) -> impl IntoResponse { let (ref data, ref tera, ref build_code) = *data.read().await; let user = match get_user_from_token!(jar, data.2) { Some(x) => x, None => { return Err(render_error(Error::NotAllowed, tera, data.0.0.clone(), None).await); } }; let message = match data.get_message_by_id(id).await { Ok(x) => x, Err(e) => { return Err(render_error(e, tera, data.0.0.clone(), Some(user)).await); } }; let mut ctx = default_context(&data.0.0, &build_code, &Some(user)); ctx.insert("message", &message); Ok(Html(tera.render("message.lisp", &ctx).unwrap())) } #[derive(Deserialize)] pub struct MessagesProps { pub use_id: String, } pub async fn messages_request( jar: CookieJar, Extension(data): Extension, Path((id, before)): Path<(usize, usize)>, Query(props): Query, ) -> impl IntoResponse { let (ref data, ref tera, ref build_code) = *data.read().await; let user = match get_user_from_token!(jar, data.2) { Some(x) => x, None => { return Err(render_error(Error::NotAllowed, tera, data.0.0.clone(), None).await); } }; let chat = match data.get_chat_by_id(id).await { Ok(x) => x, Err(e) => { return Err(render_error(e, tera, data.0.0.clone(), Some(user)).await); } }; let mut seen_user_blocks: HashMap = HashMap::new(); let messages = match if before > 0 { data.get_messages_by_chat_before(id, before, 24, 0).await } else { data.get_messages_by_chat(id, 24, 0).await } { Ok(x) => { let mut y = Vec::new(); for z in x { if let Some(status) = seen_user_blocks.get(&z.owner) { if *status { continue; } } else { let is_blocked = data .2 .get_userblock_by_initiator_receiver(user.id, z.owner) .await .is_ok(); seen_user_blocks.insert(z.owner, is_blocked); if is_blocked { continue; } } y.push(z); } y } Err(e) => { return Err(render_error(e, tera, data.0.0.clone(), Some(user)).await); } }; let mut ctx = default_context(&data.0.0, &build_code, &Some(user)); ctx.insert( "last_message_time", &match messages.last() { Some(x) => x.created, None => 0, }, ); ctx.insert("pins", &chat.pinned_messages); ctx.insert("messages", &messages); ctx.insert("id", &props.use_id); Ok(Html(tera.render("messages.lisp", &ctx).unwrap())) } pub async fn read_receipt_request( jar: CookieJar, Extension(data): Extension, Path(id): Path, ) -> impl IntoResponse { let (ref data, ref tera, ref build_code) = *data.read().await; let user = match get_user_from_token!(jar, data.2) { Some(x) => x, None => { return Err(render_error(Error::NotAllowed, tera, data.0.0.clone(), None).await); } }; let chat = match data.get_chat_by_id(id).await { Ok(x) => x, Err(e) => { return Err(render_error(e, tera, data.0.0.clone(), Some(user)).await); } }; let mut ctx = default_context(&data.0.0, &build_code, &Some(user)); ctx.insert("chat", &chat); Ok(Html(tera.render("read_receipt.lisp", &ctx).unwrap())) } pub async fn manage_chat_request( jar: CookieJar, Extension(data): Extension, Path(id): Path, ) -> impl IntoResponse { let (ref data, ref tera, ref build_code) = *data.read().await; let user = match get_user_from_token!(jar, data.2) { Some(x) => x, None => { return Err(render_error(Error::NotAllowed, tera, data.0.0.clone(), None).await); } }; let (chat, members) = match data.get_chat_by_id(id).await { Ok(x) => { if !x.members.contains(&user.id) { return Err( render_error(Error::NotAllowed, tera, data.0.0.clone(), Some(user)).await, ); } data.fill_chat(x).await } Err(e) => { return Err(render_error(e, tera, data.0.0.clone(), Some(user)).await); } }; let is_owner = chat.owner() == user.id; let mut ctx = default_context(&data.0.0, &build_code, &Some(user)); ctx.insert("chat", &chat); ctx.insert("members", &members); ctx.insert("is_owner", &is_owner); Ok(Html(tera.render("manage.lisp", &ctx).unwrap())) } pub async fn chat_pins_request( jar: CookieJar, Extension(data): Extension, Path(id): Path, ) -> impl IntoResponse { let (ref data, ref tera, ref build_code) = *data.read().await; let user = match get_user_from_token!(jar, data.2) { Some(x) => x, None => { return Err(render_error(Error::NotAllowed, tera, data.0.0.clone(), None).await); } }; let (chat, members) = match data.get_chat_by_id(id).await { Ok(x) => { if !x.members.contains(&user.id) { return Err( render_error(Error::NotAllowed, tera, data.0.0.clone(), Some(user)).await, ); } data.fill_chat(x).await } Err(e) => { return Err(render_error(e, tera, data.0.0.clone(), Some(user)).await); } }; let messages = { let mut x = Vec::new(); for y in &chat.pinned_messages { x.push(match data.get_message_by_id(*y).await { Ok(z) => z, Err(e) => { return Err(render_error(e, tera, data.0.0.clone(), Some(user)).await); } }); } x }; let mut ctx = default_context(&data.0.0, &build_code, &Some(user)); ctx.insert("chat", &chat); ctx.insert("members", &members); ctx.insert("messages", &messages); Ok(Html(tera.render("pins.lisp", &ctx).unwrap())) }