Initialize Twilight project, set up basic framework, initialize DB module
This commit is contained in:
@@ -0,0 +1,252 @@
|
||||
use std::{
|
||||
future::{Future, IntoFuture},
|
||||
pin::Pin,
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use twilight_http::{Error, Response, response::marker::EmptyBody};
|
||||
use twilight_model::{
|
||||
channel::{
|
||||
Message,
|
||||
message::{Component as TwilightComponent, Embed},
|
||||
},
|
||||
http::interaction::{InteractionResponse, InteractionResponseType},
|
||||
id::{
|
||||
Id,
|
||||
marker::{ChannelMarker, InteractionMarker},
|
||||
},
|
||||
};
|
||||
use twilight_util::builder::InteractionResponseDataBuilder;
|
||||
|
||||
use crate::framework::{
|
||||
handlers::Handlers,
|
||||
interactions::components::{ActionRow, Component},
|
||||
};
|
||||
|
||||
pub struct MessageSender {
|
||||
channel_id: Id<ChannelMarker>,
|
||||
|
||||
handlers: Arc<Handlers>,
|
||||
|
||||
content: Option<String>,
|
||||
embeds: Vec<Embed>,
|
||||
|
||||
// Row index, component
|
||||
components: Vec<(u8, Arc<dyn Component>)>,
|
||||
}
|
||||
|
||||
impl MessageSender {
|
||||
pub fn new(channel_id: Id<ChannelMarker>, handlers: Arc<Handlers>) -> Self {
|
||||
Self {
|
||||
channel_id,
|
||||
handlers,
|
||||
content: None,
|
||||
components: vec![],
|
||||
embeds: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn content(mut self, content: impl ToString) -> Self {
|
||||
self.content = Some(content.to_string());
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn embed(mut self, embed: Embed) -> Self {
|
||||
self.embeds.push(embed);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn component(mut self, component: impl Component + 'static, row: u8) -> Self {
|
||||
self.components.push((row, Arc::new(component)));
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub async fn send(self) -> Result<Response<Message>, Error> {
|
||||
let mut builder = self.handlers.http.create_message(self.channel_id);
|
||||
|
||||
if let Some(content) = &self.content {
|
||||
builder = builder.content(content);
|
||||
}
|
||||
|
||||
let mut current_row = ActionRow::new(&[]);
|
||||
let mut current_index = 0;
|
||||
|
||||
let mut rows: Vec<TwilightComponent> = vec![];
|
||||
let mut custom_ids: Vec<String> = vec![];
|
||||
|
||||
for (index, component) in self.components {
|
||||
if index != current_index {
|
||||
if current_row.len() > 0 {
|
||||
rows.push(current_row.build());
|
||||
current_row = ActionRow::new(&[]);
|
||||
}
|
||||
|
||||
current_index += 1;
|
||||
}
|
||||
|
||||
let custom_id = component.custom_id();
|
||||
|
||||
if let Some(custom_id) = &custom_id {
|
||||
custom_ids.push(custom_id.clone());
|
||||
|
||||
self.handlers
|
||||
.registry
|
||||
.register(custom_id, component.clone());
|
||||
}
|
||||
|
||||
current_row.add(custom_id.clone(), component.clone());
|
||||
}
|
||||
|
||||
if current_row.len() > 0 {
|
||||
rows.push(current_row.build());
|
||||
}
|
||||
|
||||
builder = builder.components(&rows);
|
||||
builder = builder.embeds(&self.embeds);
|
||||
|
||||
let result = builder.await;
|
||||
|
||||
if result.is_err() {
|
||||
for custom_id in custom_ids {
|
||||
self.handlers.registry.unregister(custom_id);
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoFuture for MessageSender {
|
||||
type Output = Result<Response<Message>, Error>;
|
||||
type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
|
||||
|
||||
fn into_future(self) -> Self::IntoFuture {
|
||||
Box::pin(self.send())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct OriginalMessageUpdater {
|
||||
interaction_id: Id<InteractionMarker>,
|
||||
interaction_token: String,
|
||||
|
||||
handlers: Arc<Handlers>,
|
||||
|
||||
content: Option<String>,
|
||||
embeds: Vec<Embed>,
|
||||
|
||||
// Row index, component
|
||||
components: Vec<(u8, Arc<dyn Component>)>,
|
||||
}
|
||||
|
||||
impl OriginalMessageUpdater {
|
||||
pub fn new(
|
||||
interaction_id: Id<InteractionMarker>,
|
||||
interaction_token: String,
|
||||
handlers: Arc<Handlers>,
|
||||
) -> Self {
|
||||
Self {
|
||||
interaction_id,
|
||||
interaction_token,
|
||||
handlers,
|
||||
content: None,
|
||||
components: vec![],
|
||||
embeds: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn content(mut self, content: impl ToString) -> Self {
|
||||
self.content = Some(content.to_string());
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn embed(mut self, embed: Embed) -> Self {
|
||||
self.embeds.push(embed);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn component(mut self, component: impl Component + 'static, row: u8) -> Self {
|
||||
self.components.push((row, Arc::new(component)));
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub async fn send(self) -> Result<Response<EmptyBody>, Error> {
|
||||
let mut builder = InteractionResponseDataBuilder::new();
|
||||
|
||||
if let Some(content) = &self.content {
|
||||
builder = builder.content(content);
|
||||
}
|
||||
|
||||
let mut current_row = ActionRow::new(&[]);
|
||||
let mut current_index = 0;
|
||||
|
||||
let mut rows: Vec<TwilightComponent> = vec![];
|
||||
let mut custom_ids: Vec<String> = vec![];
|
||||
|
||||
for (index, component) in self.components {
|
||||
if index != current_index {
|
||||
if current_row.len() > 0 {
|
||||
rows.push(current_row.build());
|
||||
current_row = ActionRow::new(&[]);
|
||||
}
|
||||
|
||||
current_index += 1;
|
||||
}
|
||||
|
||||
let custom_id = component.custom_id();
|
||||
|
||||
if let Some(custom_id) = &custom_id {
|
||||
custom_ids.push(custom_id.clone());
|
||||
|
||||
self.handlers
|
||||
.registry
|
||||
.register(custom_id, component.clone());
|
||||
}
|
||||
|
||||
current_row.add(custom_id.clone(), component.clone());
|
||||
}
|
||||
|
||||
if current_row.len() > 0 {
|
||||
rows.push(current_row.build());
|
||||
}
|
||||
|
||||
builder = builder.components(rows);
|
||||
builder = builder.embeds(self.embeds);
|
||||
|
||||
let result = self
|
||||
.handlers
|
||||
.http
|
||||
.interaction(self.handlers.app.id)
|
||||
.create_response(
|
||||
self.interaction_id,
|
||||
&self.interaction_token,
|
||||
&InteractionResponse {
|
||||
data: Some(builder.build()),
|
||||
kind: InteractionResponseType::UpdateMessage,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
||||
if result.is_err() {
|
||||
for custom_id in custom_ids {
|
||||
self.handlers.registry.unregister(custom_id);
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoFuture for OriginalMessageUpdater {
|
||||
type Output = Result<Response<EmptyBody>, Error>;
|
||||
type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
|
||||
|
||||
fn into_future(self) -> Self::IntoFuture {
|
||||
Box::pin(self.send())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user