diff options
Diffstat (limited to 'src/index')
| -rw-r--r-- | src/index/app.rs | 10 | ||||
| -rw-r--r-- | src/index/routes.rs | 45 | ||||
| -rw-r--r-- | src/index/templates.rs | 39 |
3 files changed, 89 insertions, 5 deletions
diff --git a/src/index/app.rs b/src/index/app.rs index 6075c6f..b315b45 100644 --- a/src/index/app.rs +++ b/src/index/app.rs @@ -1,7 +1,7 @@ use sqlx::sqlite::SqlitePool; use crate::{ - channel::repo::channels::{Channel, Provider as _}, + channel::repo::channels::{Channel, Id as ChannelId, Provider as _}, error::BoxedError, }; @@ -21,4 +21,12 @@ impl<'a> Index<'a> { Ok(channels) } + + pub async fn channel(&self, channel: ChannelId) -> Result<Channel, BoxedError> { + let mut tx = self.db.begin().await?; + let channel = tx.channels().by_id(channel).await?; + tx.commit().await?; + + Ok(channel) + } } diff --git a/src/index/routes.rs b/src/index/routes.rs index c57278f..07b6001 100644 --- a/src/index/routes.rs +++ b/src/index/routes.rs @@ -1,8 +1,17 @@ -use axum::{extract::State, routing::get, Router}; +use axum::{ + extract::{Path, State}, + http::{header, StatusCode}, + response::IntoResponse, + routing::get, + Router, +}; use maud::Markup; use super::templates; -use crate::{app::App, error::InternalError, login::repo::logins::Login}; +use crate::{ + app::App, channel::repo::channels::Id as ChannelId, error::InternalError, + login::repo::logins::Login, +}; async fn index(State(app): State<App>, login: Option<Login>) -> Result<Markup, InternalError> { match login { @@ -17,6 +26,36 @@ async fn index_authenticated(app: App, login: Login) -> Result<Markup, InternalE Ok(templates::authenticated(login, &channels)) } +#[derive(rust_embed::Embed)] +#[folder = "js"] +struct Js; + +async fn js(Path(path): Path<String>) -> impl IntoResponse { + let mime = mime_guess::from_path(&path).first_or_octet_stream(); + + match Js::get(&path) { + Some(file) => ( + StatusCode::OK, + [(header::CONTENT_TYPE, mime.as_ref())], + file.data, + ) + .into_response(), + None => (StatusCode::NOT_FOUND, "").into_response(), + } +} + +async fn channel( + State(app): State<App>, + _: Login, + Path(channel): Path<ChannelId>, +) -> Result<Markup, InternalError> { + let channel = app.index().channel(channel).await?; + Ok(templates::channel(&channel)) +} + pub fn router() -> Router<App> { - Router::new().route("/", get(index)) + Router::new() + .route("/", get(index)) + .route("/js/*path", get(js)) + .route("/:channel", get(channel)) } diff --git a/src/index/templates.rs b/src/index/templates.rs index 38cd93f..7472fd0 100644 --- a/src/index/templates.rs +++ b/src/index/templates.rs @@ -33,7 +33,9 @@ fn channel_list<'c>(channels: impl IntoIterator<Item = &'c Channel>) -> Markup { fn channel_list_entry(channel: &Channel) -> Markup { html! { li { - (channel.name) " (" (channel.id) ")" + a href=(format!("/{}", channel.id)) { + (channel.name) " (" (channel.id) ")" + } } } } @@ -87,3 +89,38 @@ fn login_form() -> Markup { } } } + +pub fn channel(channel: &Channel) -> Markup { + html! { + (DOCTYPE) + head { + title { "hi - " (channel.name) } + script src="/js/channel.js" {} + template id="message" { + p { + span.sender { "(sender)" } + ": " + span.message { "(message)" } + " (at " + span.sent_at { "(sent_at)" } + ")" } + } + link rel="events" href=(format!("/{}/events", channel.id)) {} + } + body { + section class="messages" {} + section { + form action=(format!("/{}/send", channel.id)) method="post" { + label { + "message" + input name="message" type="text" autofocus {} + } + button { "send" } + } + } + section { + a href="/" { "back" } + } + } + } +} |
