diff options
Diffstat (limited to 'src/login')
| -rw-r--r-- | src/login/routes.rs | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/login/routes.rs b/src/login/routes.rs index 0874cc3..b0e3fee 100644 --- a/src/login/routes.rs +++ b/src/login/routes.rs @@ -5,12 +5,16 @@ use axum::{ routing::{get, post}, Router, }; +use futures::stream::{self, StreamExt as _, TryStreamExt as _}; use crate::{ app::App, + channel::Channel, clock::RequestedAt, error::{Internal, Unauthorized}, + event::Instant, login::{Login, Password}, + message::{self, Message}, token::{app, extract::IdentityToken}, }; @@ -26,9 +30,21 @@ pub fn router() -> Router<App> { async fn boot(State(app): State<App>, login: Login) -> Result<Boot, Internal> { let resume_point = app.logins().boot_point().await?; + let channels = app.channels().all(resume_point.into()).await?; + let channels = stream::iter(channels) + .then(|channel| async { + app.messages() + .in_channel(&channel.id, resume_point.into()) + .await + .map(|messages| BootChannel::new(channel, messages)) + }) + .try_collect() + .await?; + Ok(Boot { login, resume_point: resume_point.to_string(), + channels, }) } @@ -36,6 +52,55 @@ async fn boot(State(app): State<App>, login: Login) -> Result<Boot, Internal> { struct Boot { login: Login, resume_point: String, + channels: Vec<BootChannel>, +} + +#[derive(serde::Serialize)] +struct BootChannel { + #[serde(flatten)] + channel: Channel, + messages: Vec<BootMessage>, +} + +impl BootChannel { + fn new(channel: Channel, messages: impl IntoIterator<Item = Message>) -> Self { + Self { + channel, + messages: messages.into_iter().map(BootMessage::from).collect(), + } + } +} + +#[derive(serde::Serialize)] +struct BootMessage { + #[serde(flatten)] + sent: Instant, + sender: Login, + message: BootMessageBody, +} + +impl From<Message> for BootMessage { + fn from(message: Message) -> Self { + let Message { + sent, + channel: _, + sender, + id, + body, + } = message; + + Self { + sent, + sender, + message: BootMessageBody { id, body }, + } + } +} + +#[derive(serde::Serialize)] +struct BootMessageBody { + id: message::Id, + body: String, } impl IntoResponse for Boot { |
