Skip to content

Commit

Permalink
feat(pagination): added pagination to queue
Browse files Browse the repository at this point in the history
  • Loading branch information
ayamdobhal committed Nov 25, 2024
1 parent 3310947 commit b90bfa6
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 51 deletions.
54 changes: 24 additions & 30 deletions src/commands/now.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use poise::CreateReply;
use serenity::all::{Colour, CreateEmbed};
use serenity::all::{Colour, CreateEmbed, CreateEmbedFooter};

use crate::commands::utils::Error;
use crate::{commands::utils::Error, models::pagination::PaginatedQueue};

use super::utils::Context;

// TODO: make a button to change pages instead of entering page number
#[poise::command(prefix_command, aliases("queue"))]
pub async fn now(ctx: Context<'_>) -> Result<(), Error> {
pub async fn now(ctx: Context<'_>, n: Option<usize>) -> Result<(), Error> {
let n = n.unwrap_or(1);
let (guild_id, channel_id) = {
let guild = ctx.guild().expect("Guild only command");
let channel_id = guild
Expand Down Expand Up @@ -57,36 +59,28 @@ pub async fn now(ctx: Context<'_>) -> Result<(), Error> {
.await?;
return Ok(());
}
let paginated_queue = PaginatedQueue::new(queue, len, n);
let pages = paginated_queue.total_pages();

if n > pages {
let embed = CreateEmbed::new()
.title(format!(
"❌ Number cannot be larger than total pages({})",
pages
))
.color(Colour::from_rgb(255, 0, 0));
ctx.send(CreateReply {
embeds: vec![embed],
..Default::default()
})
.await?;
return Ok(());
}
let embed = CreateEmbed::new()
.title("📋 **Currently Playing**")
.title("".to_string())
.fields(queue.iter().enumerate().map(|(index, song)| {
if index == 0 {
(
format!(
"{}. {} - {}[{}] ⬅️",
index + 1,
song.artist,
song.name,
song.duration
),
"",
false,
)
} else {
(
format!(
"{}. {} - {}[{}]",
index + 1,
song.artist,
song.name,
song.duration
),
"",
false,
)
}
}))
.fields(paginated_queue.get_fields())
.footer(CreateEmbedFooter::new(format!("Total Pages: {}", pages)))
.color(Colour::from_rgb(0, 236, 255));
ctx.send(CreateReply {
embeds: vec![embed],
Expand Down
30 changes: 9 additions & 21 deletions src/commands/skip.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use poise::CreateReply;
use serenity::all::{Colour, CreateEmbed};

use crate::{commands::utils::Error, state::Track};
use crate::commands::utils::Error;

use super::utils::Context;

Expand Down Expand Up @@ -54,7 +54,6 @@ pub async fn skip(ctx: Context<'_>, n: Option<usize>) -> Result<(), Error> {
n.unwrap_or(1)
};
let k = &format!("{},{}", guild_id.get(), channel_id.get());
let mut skipped_songs: Vec<Track> = vec![];
for _ in 0..n_times {
queue.skip()?;
let pop = {
Expand All @@ -67,17 +66,13 @@ pub async fn skip(ctx: Context<'_>, n: Option<usize>) -> Result<(), Error> {
.pop_front()
};
if let None = pop {
let embed =
CreateEmbed::new()
.title(format!(
"⏩ Skipped {} {}",
n_times,
if n_times > 1 { "tracks" } else { "track" }
))
.fields(skipped_songs.iter().enumerate().map(|(index, song)| {
(format!("{}. {}", index + 1, song.name), "", false)
}))
.color(Colour::from_rgb(0, 255, 0));
let embed = CreateEmbed::new()
.title(format!(
"⏩ Skipped {} {}",
n_times,
if n_times > 1 { "tracks" } else { "track" }
))
.color(Colour::from_rgb(0, 255, 0));
ctx.send(CreateReply {
embeds: vec![embed],
..Default::default()
Expand Down Expand Up @@ -111,20 +106,13 @@ pub async fn skip(ctx: Context<'_>, n: Option<usize>) -> Result<(), Error> {
}
return Ok(());
}
skipped_songs.push(pop.unwrap());
}
let embed = CreateEmbed::new()
.title(format!(
"⏩ Skipped {} {}",
n_times,
if n_times > 1 { "tracks" } else { "track" }
))
.fields(
skipped_songs
.iter()
.enumerate()
.map(|(index, song)| (format!("{}. {}", index + 1, song.name), "", false)),
)
.color(Colour::from_rgb(0, 255, 0));
ctx.send(CreateReply {
embeds: vec![embed],
Expand All @@ -146,12 +134,12 @@ pub async fn skip(ctx: Context<'_>, n: Option<usize>) -> Result<(), Error> {
if let Some(next_track) = next_track {
let embed = CreateEmbed::new()
.title("**⏯️ Now Playing**")
.image(next_track.thumbnail)
.field(
next_track.artist,
format!("{} [{}]", next_track.name, next_track.duration),
true,
)
.image(next_track.thumbnail)
.color(Colour::from_rgb(0, 255, 0));
ctx.send(CreateReply {
embeds: vec![embed],
Expand Down
1 change: 1 addition & 0 deletions src/models/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod pagination;
pub mod spotify;
70 changes: 70 additions & 0 deletions src/models/pagination.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use std::collections::VecDeque;

use crate::state::Track;

pub struct PaginatedQueue<'a> {
queue: &'a VecDeque<Track>,
page: usize,
limit: usize,
total: usize,
}

impl<'a> PaginatedQueue<'a> {
pub fn new(queue: &'a VecDeque<Track>, total: usize, page: usize) -> Self {
Self {
queue,
page,
limit: 10,
total,
}
}

fn start_idx(&self) -> usize {
(self.page - 1) * self.limit
}

fn end_idx(&self) -> usize {
(self.start_idx() + self.limit).min(self.total)
}

pub fn total_pages(&self) -> usize {
(self.total + self.limit - 1) / self.limit
}

pub fn get_fields(&self) -> impl IntoIterator<Item = (String, String, bool)> + '_ {
let start = self.start_idx();
let end = self.end_idx();
self.queue
.iter()
.skip(start)
.take(end - start)
.enumerate()
.map(move |(index, song)| {
if index == 0 {
(
format!(
"{}. {} - {}[{}] ⬅️",
index + 1 + start,
song.artist,
song.name,
song.duration
),
"".to_string(),
false,
)
} else {
(
format!(
"{}. {} - {}[{}]",
index + 1 + start,
song.artist,
song.name,
song.duration
),
"".to_string(),
false,
)
}
})
}
}

0 comments on commit b90bfa6

Please sign in to comment.