//! Interactive component CRUD operations on `MessageRepo`. use uuid::Uuid; use crate::ImksResult; use crate::models::message_component::MessageComponent; use super::message_repo::MessageRepo; impl MessageRepo { /// Create an interactive component (button/select menu) on a message. #[allow(clippy::too_many_arguments)] pub async fn create_component( &self, message_id: Uuid, component_type: &str, custom_id: &str, label: Option<&str>, emoji: Option<&str>, style: Option<&str>, url: Option<&str>, disabled: bool, row: i32, position: i32, ) -> ImksResult { sqlx::query_as::<_, MessageComponent>( r#" INSERT INTO message_component ( id, message_id, row, position, component_type, custom_id, label, emoji, style, url, disabled ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING * "#, ) .bind(Uuid::now_v7()) .bind(message_id) .bind(row) .bind(position) .bind(component_type) .bind(custom_id) .bind(label) .bind(emoji) .bind(style) .bind(url) .bind(disabled) .fetch_one(self.pool()) .await .map_err(Into::into) } /// Get all components on a message, ordered by layout. pub async fn get_components(&self, message_id: Uuid) -> ImksResult> { sqlx::query_as::<_, MessageComponent>( r#" SELECT * FROM message_component WHERE message_id = $1 ORDER BY row, position "#, ) .bind(message_id) .fetch_all(self.pool()) .await .map_err(Into::into) } /// Update a component's label and/or disabled state (e.g. after interaction). pub async fn update_component( &self, component_id: Uuid, label: Option<&str>, disabled: bool, ) -> ImksResult> { sqlx::query_as::<_, MessageComponent>( r#" UPDATE message_component SET label = COALESCE($1, label), disabled = $2 WHERE id = $3 RETURNING * "#, ) .bind(label) .bind(disabled) .bind(component_id) .fetch_optional(self.pool()) .await .map_err(Into::into) } }