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",
|
||||
"regex 1.11.0",
|
||||
"rust-i18n",
|
||||
"to_markdown_table",
|
||||
"tokio",
|
||||
"url",
|
||||
]
|
||||
|
|
@ -2594,6 +2595,15 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "tokio"
|
||||
version = "1.40.0"
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ poise = { version = "0.5.*", features = [ "cache" ] }
|
|||
rand = { version = "0.8.5", features = [ "small_rng" ] }
|
||||
regex = "1.9.5"
|
||||
rust-i18n = "3.1.2"
|
||||
to_markdown_table = "0.1.5"
|
||||
tokio = { version = "1.16.1", features = ["sync", "macros", "rt-multi-thread"] }
|
||||
url = "2.5.2"
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ use built::chrono;
|
|||
use manifold::error::{ManifoldError, ManifoldResult};
|
||||
use manifold::{ManifoldContext, ManifoldData};
|
||||
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)]
|
||||
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 entries_per_page = 20;
|
||||
let mut pages = Vec::<CreateEmbed>::new();
|
||||
let leaderboard = Xp::get_leaderboard(&ctx.data().database)?;
|
||||
let total = leaderboard.len();
|
||||
let leaderboard = Leaderboard::get_leaderboard(&ctx.data().database)?;
|
||||
let userinfo = ctx.data().user_info.lock().await;
|
||||
let total = leaderboard.rows.len();
|
||||
let pages_needed = (total / entries_per_page) + 1;
|
||||
|
||||
for i in 0..pages_needed {
|
||||
let mut page = CreateEmbed::default()
|
||||
.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 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
|
||||
if j >= entries_per_page {
|
||||
return;
|
||||
}
|
||||
|
||||
let new_rank = format!("{rank}\n", rank=(j+1+offset));
|
||||
let new_user = format!("<@{user}>\n", user=f.user_id);
|
||||
let new_value = format!("{xp}\n", xp=f.xp_value);
|
||||
let mut row = f.to_owned();
|
||||
row.rank = (j + 1 + offset) as i32;
|
||||
row.user_name = userinfo.get(&(row.uid as u64)).unwrap().username.clone();
|
||||
|
||||
// field values are capped at 1024 characters
|
||||
// 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());
|
||||
leaderboard_rows.push(row);
|
||||
});
|
||||
|
||||
fields.push(("Rank", &ranks, true));
|
||||
fields.push(("User", &users, true));
|
||||
fields.push(("XP", &values, true));
|
||||
let leaderboard_table = MarkdownTable::new(Some(vec!["Rank".to_string(), "User".to_string(), "XP".to_string()]), leaderboard_rows)?;
|
||||
|
||||
page.fields(fields);
|
||||
page.description(format!("```{table}```", table=leaderboard_table));
|
||||
|
||||
pages.push(page);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,13 +3,14 @@ use diesel::prelude::*;
|
|||
use diesel::insert_into;
|
||||
use rand::rngs::SmallRng;
|
||||
use rand::{Rng, SeedableRng};
|
||||
use to_markdown_table::{TableRow};
|
||||
|
||||
use manifold::{Db, ManifoldData};
|
||||
use manifold::error::{ManifoldError, ManifoldResult};
|
||||
use manifold::models::user::UserInfo;
|
||||
use manifold::schema::userinfo;
|
||||
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::schema::xp as xp_table;
|
||||
use crate::badgey::schema::*;
|
||||
|
|
@ -49,6 +50,47 @@ pub struct Track {
|
|||
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 {
|
||||
pub fn new(user_id: &i64) -> Self {
|
||||
Self {
|
||||
|
|
@ -119,12 +161,6 @@ impl Xp {
|
|||
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<()>{
|
||||
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.");
|
||||
|
|
|
|||
Loading…
Reference in New Issue