summaryrefslogtreecommitdiff
path: root/src/channel
diff options
context:
space:
mode:
authorOwen Jacobson <owen@grimoire.ca>2024-09-04 23:19:51 -0400
committerOwen Jacobson <owen@grimoire.ca>2024-09-04 23:19:51 -0400
commitbeeb40acdc07d5652bf2128ecb8f71a1116993ae (patch)
tree14b48e7bf9555cb9079a7d918050ff9dd70c271f /src/channel
parentcae21da31ff795cc21ec19288fcdc5fdb8a713c7 (diff)
Support leaving a channel
Diffstat (limited to 'src/channel')
-rw-r--r--src/channel/repo.rs22
-rw-r--r--src/channel/routes.rs20
2 files changed, 38 insertions, 4 deletions
diff --git a/src/channel/repo.rs b/src/channel/repo.rs
index e6a5e5c..bb39d6e 100644
--- a/src/channel/repo.rs
+++ b/src/channel/repo.rs
@@ -82,11 +82,31 @@ impl<'c> Channels<'c> {
Ok(channels)
}
+
+ /// Unenrol a login from a channel.
+ pub async fn leave(&mut self, channel: &Id, login: &LoginId) -> Result<(), BoxedError> {
+ sqlx::query_scalar!(
+ r#"
+ delete
+ from channel_member
+ where channel = $1
+ and login = $2
+ returning 1 as "deleted: bool"
+ "#,
+ channel,
+ login,
+ )
+ .fetch_one(&mut *self.0)
+ .await?;
+
+ Ok(())
+ }
}
/// Stable identifier for a [Channel]. Prefixed with `C`.
-#[derive(Debug, sqlx::Type)]
+#[derive(Debug, sqlx::Type, serde::Deserialize)]
#[sqlx(transparent)]
+#[serde(transparent)]
pub struct Id(BaseId);
impl From<BaseId> for Id {
diff --git a/src/channel/routes.rs b/src/channel/routes.rs
index c8d6c3f..4453a1e 100644
--- a/src/channel/routes.rs
+++ b/src/channel/routes.rs
@@ -1,16 +1,18 @@
use axum::{
- extract::{Form, State},
+ extract::{Form, Path, State},
response::{IntoResponse, Redirect},
routing::post,
Router,
};
use sqlx::sqlite::SqlitePool;
-use super::repo::Provider as _;
+use super::repo::{Id as ChannelId, Provider as _};
use crate::{error::InternalError, login::repo::logins::Login};
pub fn router() -> Router<SqlitePool> {
- Router::new().route("/create", post(on_create))
+ Router::new()
+ .route("/create", post(on_create))
+ .route("/:channel/leave", post(on_leave))
}
#[derive(serde::Deserialize)]
@@ -30,3 +32,15 @@ async fn on_create(
Ok(Redirect::to("/"))
}
+
+async fn on_leave(
+ State(db): State<SqlitePool>,
+ login: Login,
+ Path(channel): Path<ChannelId>,
+) -> Result<impl IntoResponse, InternalError> {
+ let mut tx = db.begin().await?;
+ tx.channels().leave(&channel, &login.id).await?;
+ tx.commit().await?;
+
+ Ok(Redirect::to("/"))
+}