summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorOwen Jacobson <owen@grimoire.ca>2024-09-14 00:16:51 -0400
committerOwen Jacobson <owen@grimoire.ca>2024-09-14 00:18:08 -0400
commit5249aad35741f6f029c442a04d679937fb91d2bb (patch)
treec75085a93538367ae3f5da8f64f90b33a3c8feef /src
parent407ca8df6284ce1a4c649b018c7326fd195bbd26 (diff)
Placeholder UX, probably
Diffstat (limited to 'src')
-rw-r--r--src/channel/repo/channels.rs16
-rw-r--r--src/channel/routes.rs3
-rw-r--r--src/index/app.rs10
-rw-r--r--src/index/routes.rs45
-rw-r--r--src/index/templates.rs39
5 files changed, 106 insertions, 7 deletions
diff --git a/src/channel/repo/channels.rs b/src/channel/repo/channels.rs
index 6fb0c23..fc52aa3 100644
--- a/src/channel/repo/channels.rs
+++ b/src/channel/repo/channels.rs
@@ -44,6 +44,22 @@ impl<'c> Channels<'c> {
Ok(channel)
}
+ pub async fn by_id(&mut self, channel: Id) -> Result<Channel, BoxedError> {
+ let channel = sqlx::query_as!(
+ Channel,
+ r#"
+ select id as "id: Id", name
+ from channel
+ where id = $1
+ "#,
+ channel,
+ )
+ .fetch_one(&mut *self.0)
+ .await?;
+
+ Ok(channel)
+ }
+
pub async fn all(&mut self) -> Result<Vec<Channel>, BoxedError> {
let channels = sqlx::query_as!(
Channel,
diff --git a/src/channel/routes.rs b/src/channel/routes.rs
index 4f83a8b..eae68a2 100644
--- a/src/channel/routes.rs
+++ b/src/channel/routes.rs
@@ -1,6 +1,5 @@
use axum::{
extract::{Form, Path, State},
- http::StatusCode,
response::{
sse::{self, Sse},
IntoResponse, Redirect,
@@ -59,7 +58,7 @@ async fn on_send(
.send(&login, &channel, &form.message, &sent_at)
.await?;
- Ok(StatusCode::ACCEPTED)
+ Ok(Redirect::to(&format!("/{}", channel)))
}
async fn on_events(
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" }
+ }
+ }
+ }
+}