Merge pull request 'Fix formatting on mobile by refactoring the whole approach' (#17) from hotfix/fucking-field-limits-ffs into main
Reviewed-on: #17
This commit is contained in:
commit
fa68df0a94
|
|
@ -179,6 +179,7 @@ dependencies = [
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"regex 1.11.0",
|
"regex 1.11.0",
|
||||||
"rust-i18n",
|
"rust-i18n",
|
||||||
|
"to_markdown_table",
|
||||||
"tokio",
|
"tokio",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
@ -2594,6 +2595,15 @@ version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "to_markdown_table"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8450ade61b78735ed7811cc14639462723d87a6cd748a41e7bfde554ac5033dd"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.40.0"
|
version = "1.40.0"
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ poise = { version = "0.5.*", features = [ "cache" ] }
|
||||||
rand = { version = "0.8.5", features = [ "small_rng" ] }
|
rand = { version = "0.8.5", features = [ "small_rng" ] }
|
||||||
regex = "1.9.5"
|
regex = "1.9.5"
|
||||||
rust-i18n = "3.1.2"
|
rust-i18n = "3.1.2"
|
||||||
|
to_markdown_table = "0.1.5"
|
||||||
tokio = { version = "1.16.1", features = ["sync", "macros", "rt-multi-thread"] }
|
tokio = { version = "1.16.1", features = ["sync", "macros", "rt-multi-thread"] }
|
||||||
url = "2.5.2"
|
url = "2.5.2"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@ use built::chrono;
|
||||||
use manifold::error::{ManifoldError, ManifoldResult};
|
use manifold::error::{ManifoldError, ManifoldResult};
|
||||||
use manifold::{ManifoldContext, ManifoldData};
|
use manifold::{ManifoldContext, ManifoldData};
|
||||||
use poise::serenity_prelude::{CreateEmbed, Mentionable, RoleId};
|
use poise::serenity_prelude::{CreateEmbed, Mentionable, RoleId};
|
||||||
use crate::badgey::models::xp::{Rank, Track, Xp};
|
use to_markdown_table::MarkdownTable;
|
||||||
|
use crate::badgey::models::xp::{Leaderboard, Rank, Track, Xp};
|
||||||
|
|
||||||
#[poise::command(prefix_command, slash_command, user_cooldown = 86400)]
|
#[poise::command(prefix_command, slash_command, user_cooldown = 86400)]
|
||||||
async fn switch_rank_track(ctx: ManifoldContext<'_>, #[description = "Track to switch to: officer or enlisted"] track: String) -> ManifoldResult<()> {
|
async fn switch_rank_track(ctx: ManifoldContext<'_>, #[description = "Track to switch to: officer or enlisted"] track: String) -> ManifoldResult<()> {
|
||||||
|
|
@ -125,47 +126,34 @@ async fn leaderboard(ctx: ManifoldContext<'_>) -> ManifoldResult<()> {
|
||||||
let reply_handle = ctx.reply("Retrieving leaderboard, please stand by...".to_string()).await?;
|
let reply_handle = ctx.reply("Retrieving leaderboard, please stand by...".to_string()).await?;
|
||||||
let entries_per_page = 20;
|
let entries_per_page = 20;
|
||||||
let mut pages = Vec::<CreateEmbed>::new();
|
let mut pages = Vec::<CreateEmbed>::new();
|
||||||
let leaderboard = Xp::get_leaderboard(&ctx.data().database)?;
|
let leaderboard = Leaderboard::get_leaderboard(&ctx.data().database)?;
|
||||||
let total = leaderboard.len();
|
let userinfo = ctx.data().user_info.lock().await;
|
||||||
|
let total = leaderboard.rows.len();
|
||||||
let pages_needed = (total / entries_per_page) + 1;
|
let pages_needed = (total / entries_per_page) + 1;
|
||||||
|
|
||||||
for i in 0..pages_needed {
|
for i in 0..pages_needed {
|
||||||
let mut page = CreateEmbed::default()
|
let mut page = CreateEmbed::default()
|
||||||
.title(format!("XP Leaderboard Page {page} of {total_pages}", page=(i + 1), total_pages=&pages_needed)).to_owned();
|
.title(format!("XP Leaderboard Page {page} of {total_pages}", page=(i + 1), total_pages=&pages_needed)).to_owned();
|
||||||
|
|
||||||
let mut fields = Vec::new();
|
|
||||||
let mut ranks = String::new();
|
|
||||||
let mut users = String::new();
|
|
||||||
let mut values = String::new();
|
|
||||||
|
|
||||||
let offset = i*entries_per_page;
|
let offset = i*entries_per_page;
|
||||||
|
let mut leaderboard_rows = Vec::new();
|
||||||
|
|
||||||
leaderboard.iter().skip(offset).enumerate().for_each(|(j, f)| {
|
leaderboard.rows.iter().skip(offset).enumerate().for_each(|(j, f)| {
|
||||||
// cap at per-page limit
|
// cap at per-page limit
|
||||||
if j >= entries_per_page {
|
if j >= entries_per_page {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let new_rank = format!("{rank}\n", rank=(j+1+offset));
|
let mut row = f.to_owned();
|
||||||
let new_user = format!("<@{user}>\n", user=f.user_id);
|
row.rank = (j + 1 + offset) as i32;
|
||||||
let new_value = format!("{xp}\n", xp=f.xp_value);
|
row.user_name = userinfo.get(&(row.uid as u64)).unwrap().username.clone();
|
||||||
|
|
||||||
// field values are capped at 1024 characters
|
leaderboard_rows.push(row);
|
||||||
// so we have to check if what we're about to add will break that limit and bail out if so
|
|
||||||
if (ranks.len() + new_rank.len()) > 1024 || (users.len() + new_user.len()) > 1024 || (values.len() + new_value.len()) > 1024 {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ranks.push_str(new_rank.as_str());
|
|
||||||
users.push_str(new_user.as_str());
|
|
||||||
values.push_str(new_value.as_str());
|
|
||||||
});
|
});
|
||||||
|
|
||||||
fields.push(("Rank", &ranks, true));
|
let leaderboard_table = MarkdownTable::new(Some(vec!["Rank".to_string(), "User".to_string(), "XP".to_string()]), leaderboard_rows)?;
|
||||||
fields.push(("User", &users, true));
|
|
||||||
fields.push(("XP", &values, true));
|
|
||||||
|
|
||||||
page.fields(fields);
|
page.description(format!("```{table}```", table=leaderboard_table));
|
||||||
|
|
||||||
pages.push(page);
|
pages.push(page);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,14 @@ use diesel::prelude::*;
|
||||||
use diesel::insert_into;
|
use diesel::insert_into;
|
||||||
use rand::rngs::SmallRng;
|
use rand::rngs::SmallRng;
|
||||||
use rand::{Rng, SeedableRng};
|
use rand::{Rng, SeedableRng};
|
||||||
|
use to_markdown_table::{TableRow};
|
||||||
|
|
||||||
use manifold::{Db, ManifoldData};
|
use manifold::{Db, ManifoldData};
|
||||||
use manifold::error::{ManifoldError, ManifoldResult};
|
use manifold::error::{ManifoldError, ManifoldResult};
|
||||||
use manifold::models::user::UserInfo;
|
use manifold::models::user::UserInfo;
|
||||||
use manifold::schema::userinfo;
|
use manifold::schema::userinfo;
|
||||||
use poise::FrameworkContext;
|
use poise::FrameworkContext;
|
||||||
use poise::serenity_prelude::{Context, Mentionable, Message, RoleId};
|
use poise::serenity_prelude::{Context, Mention, Mentionable, Message, RoleId, UserId};
|
||||||
use crate::badgey::models::quarantine_channel::QuarantineChannel;
|
use crate::badgey::models::quarantine_channel::QuarantineChannel;
|
||||||
use crate::badgey::schema::xp as xp_table;
|
use crate::badgey::schema::xp as xp_table;
|
||||||
use crate::badgey::schema::*;
|
use crate::badgey::schema::*;
|
||||||
|
|
@ -49,6 +50,47 @@ pub struct Track {
|
||||||
pub xp_award_range_max: i32,
|
pub xp_award_range_max: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Leaderboard {
|
||||||
|
pub rows: Vec<LeaderboardRow>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct LeaderboardRow {
|
||||||
|
pub rank: i32,
|
||||||
|
pub uid: i64,
|
||||||
|
pub user_name: String,
|
||||||
|
pub value: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<TableRow> for LeaderboardRow {
|
||||||
|
fn into(self) -> TableRow {
|
||||||
|
TableRow::new(vec![self.rank.to_string(), self.user_name, self.value.to_string()])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&Xp> for LeaderboardRow {
|
||||||
|
fn from(value: &Xp) -> Self {
|
||||||
|
LeaderboardRow {
|
||||||
|
rank: 0,
|
||||||
|
uid: value.user_id,
|
||||||
|
user_name: "".to_string(),
|
||||||
|
value: value.xp_value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Leaderboard {
|
||||||
|
pub fn get_leaderboard(conn: &Db) -> ManifoldResult<Self> {
|
||||||
|
let xp_rows: Vec<LeaderboardRow> = xp_table::dsl::xp
|
||||||
|
.order_by(xp::xp_value.desc())
|
||||||
|
.load::<Xp>(&mut conn.get()?)?.iter().map(|x| {LeaderboardRow::from(x)}).collect();
|
||||||
|
|
||||||
|
Ok(Leaderboard {
|
||||||
|
rows: xp_rows
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Xp {
|
impl Xp {
|
||||||
pub fn new(user_id: &i64) -> Self {
|
pub fn new(user_id: &i64) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -119,12 +161,6 @@ impl Xp {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_leaderboard(conn: &Db) -> ManifoldResult<Vec<Self>> {
|
|
||||||
Ok(xp_table::dsl::xp
|
|
||||||
.order_by(xp::xp_value.desc())
|
|
||||||
.load::<Self>(&mut conn.get()?)?)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn award(ctx: &Context, fctx: &FrameworkContext<'_, ManifoldData, ManifoldError>, msg: &Message, db: &Db) -> ManifoldResult<()>{
|
pub async fn award(ctx: &Context, fctx: &FrameworkContext<'_, ManifoldData, ManifoldError>, msg: &Message, db: &Db) -> ManifoldResult<()>{
|
||||||
if fctx.user_data().await.user_info.lock().await.get_mut(&msg.author.id.as_u64()).is_none() {
|
if fctx.user_data().await.user_info.lock().await.get_mut(&msg.author.id.as_u64()).is_none() {
|
||||||
debug!("Tried to add XP to a user we don't know about, aborting.");
|
debug!("Tried to add XP to a user we don't know about, aborting.");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue