diff --git a/src/main.rs b/src/main.rs index c4eab88..340536c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,7 +14,8 @@ use rocket::{ json::Json } }; -use crate::sql::Test; +use sql::LeaderBoardTest; +use crate::sql::*; #[get("/")] fn test() -> String { @@ -81,10 +82,16 @@ fn get_user_tests(user_id: u32) -> Json> { Json(tests) } +#[get("/leaderboard")] +fn leaderboard() -> Json> { + let leaderboard = sql::get_leaderboard(0).expect("error finding user_id"); + Json(leaderboard) +} + #[launch] fn rocket() -> Rocket { rocket::build() .mount("/test", routes![test]) // testing only, should return "Hello world" - .mount("/api", routes![post_test, create_user, login, get_user_tests]) + .mount("/api", routes![post_test, create_user, login, get_user_tests, leaderboard]) .mount("/typing", FileServer::from(relative!("website"))) // hosts the fileserver } \ No newline at end of file diff --git a/src/sql.rs b/src/sql.rs index 80cbd36..6c4ab4a 100644 --- a/src/sql.rs +++ b/src/sql.rs @@ -186,5 +186,40 @@ pub fn get_user_tests( tests.push(test.unwrap()); } + Ok(tests) +} + +#[derive(Serialize)] +#[serde(crate = "rocket::serde")] +pub struct LeaderBoardTest { + username: String, + wpm: u8, +} + +pub fn get_leaderboard( + _user_id: u32 +) -> Result>{ + let connection = get_connection(); + let mut statement = connection.prepare( + "SELECT users.username, MAX(tests.wpm) + FROM tests + INNER JOIN users ON users.user_id = tests.user_id + GROUP BY users.username + ORDER BY tests.wpm DESC", + )?; + + let test_iter = statement + .query_map((), |row| { + Ok( LeaderBoardTest { + username: row.get(0)?, + wpm: row.get(1)? + }) + })?; + + let mut tests: Vec = vec![]; + for test in test_iter { + tests.push(test.unwrap()); + } + Ok(tests) } \ No newline at end of file diff --git a/website/api/api.js b/website/api/api.js index b5517ea..767415b 100644 --- a/website/api/api.js +++ b/website/api/api.js @@ -185,7 +185,9 @@ class API { JSON.stringify(user) ); - this.login(username, password); + xhr.onload = () => { + this.login(username,password); + }; } login(pUsername, pPassword) { @@ -227,4 +229,13 @@ class API { user.tests = JSON.parse(xhr.response); }; } + + getLeaderBoard() { + let xhr = new XMLHttpRequest(); + xhr.open('GET', `${this.url}leaderboard/`); + xhr.send(); + xhr.onload = () => { + user.leaderboard = JSON.parse(xhr.response); + }; + } } \ No newline at end of file diff --git a/website/api/user.js b/website/api/user.js index 1a0145b..5e0390c 100644 --- a/website/api/user.js +++ b/website/api/user.js @@ -4,5 +4,6 @@ class User { this.password = "there"; this.userId = 0; this.tests; + this.leaderboard; } } \ No newline at end of file diff --git a/website/index.html b/website/index.html index e856064..18ea90e 100644 --- a/website/index.html +++ b/website/index.html @@ -31,6 +31,7 @@ + diff --git a/website/screens/endscreen.js b/website/screens/endscreen.js index 8515b8e..d427411 100644 --- a/website/screens/endscreen.js +++ b/website/screens/endscreen.js @@ -5,7 +5,8 @@ class EndScreen { new Button(110,0,100,30,0,true,"#fff",false,"#000","#000","Login"), new Button(220,0,100,30,0,true,"#fff",false,"#000","#000","Logout"), new Button(330,0,100,30,0,true,"#fff",false,"#000","#000","Profile"), - new Button(440,0,100,30,0,true,"#fff",false,"#000","#000","Test") + new Button(440,0,100,30,0,true,"#fff",false,"#000","#000","Test"), + new Button(550,0,140,30,0,true,"#fff",false,"#000","#000","Leaderboard"), ] } @@ -15,11 +16,10 @@ class EndScreen { textAlign(CENTER, CENTER); fill(0); text("Test Complete\nPress enter to start another test", 0, 0, windowWidth - 100, windowHeight - 100); - this.buttons[0].draw(); - this.buttons[1].draw(); - this.buttons[2].draw(); - this.buttons[3].draw(); - this.buttons[4].draw(); + + for (let i = 0; i < this.buttons.length; i++) { + this.buttons[i].draw() + } if (this.buttons[0].isPressed()) { screenManager.setScreen(new SignUpScreen()); } else if (this.buttons[1].isPressed()) { @@ -30,10 +30,12 @@ class EndScreen { screenManager.setScreen(new ProfileScreen()); } else if (this.buttons[4].isPressed()) { screenManager.setScreen(new TestScreen()) + } else if (this.buttons[5].isPressed()) { + screenManager.setScreen(new LeaderboardScreen()) } } - letterTyped() { - screenManager.setScreen(new StartScreen()); + letterTyped(key) { + if (key === "ENTER") screenManager.setScreen(new StartScreen()); } } \ No newline at end of file diff --git a/website/screens/leaderboardscreen.js b/website/screens/leaderboardscreen.js new file mode 100644 index 0000000..4f6b3fb --- /dev/null +++ b/website/screens/leaderboardscreen.js @@ -0,0 +1,48 @@ +class LeaderboardScreen { + constructor() { + this.buttons = [ + new Button(0,0,100,30,0,true,"#fff",false,"#000","#000","Sign Up"), + new Button(110,0,100,30,0,true,"#fff",false,"#000","#000","Login"), + new Button(220,0,100,30,0,true,"#fff",false,"#000","#000","Logout"), + new Button(330,0,100,30,0,true,"#fff",false,"#000","#000","Profile"), + new Button(440,0,100,30,0,true,"#fff",false,"#000","#000","Test"), + new Button(550,0,140,30,0,true,"#fff",false,"#000","#000","Leaderboard"), + ]; + api.getLeaderBoard() + } + + draw() { + background("#eeeee4"); + textSize(100); + textAlign(CENTER, CENTER); + fill("#000"); + text("Leaderboard", 0, 100, windowWidth, 120); + for (let i = 0; i < this.buttons.length; i++) { + this.buttons[i].draw() + } + + if (this.buttons[0].isPressed()) { + screenManager.setScreen(new SignUpScreen()); + } else if (this.buttons[1].isPressed()) { + screenManager.setScreen(new LoginScreen()); + } else if (this.buttons[2].isPressed()) { + api.logout(); + } else if (this.buttons[3].isPressed()) { + screenManager.setScreen(new ProfileScreen()); + } else if (this.buttons[4].isPressed()) { + screenManager.setScreen(new TestScreen()) + } else if (this.buttons[5].isPressed()) { + screenManager.setScreen(new LeaderboardScreen()) + } + + textSize(20); + fill("#000"); + if (user.leaderboard != undefined) { + for (let i = 0; i < user.leaderboard.length; i++) { + text(`#${i+1}: ${user.leaderboard[i].username} : ${user.leaderboard[i].wpm}wpm`, 0, i*30+300, windowWidth, 30); + } + } + fill("#000"); + text(`Logged in as ${user.username}`, windowWidth-100, 15); + } +} \ No newline at end of file diff --git a/website/screens/loginscreen.js b/website/screens/loginscreen.js index b1c2648..a5ba925 100644 --- a/website/screens/loginscreen.js +++ b/website/screens/loginscreen.js @@ -58,6 +58,7 @@ class LoginScreen { new Button(220,0,100,30,0,true,"#fff",false,"#000","#000","Logout"), new Button(330,0,100,30,0,true,"#fff",false,"#000","#000","Profile"), new Button(440,0,100,30,0,true,"#fff",false,"#000","#000","Test"), + new Button(550,0,140,30,0,true,"#fff",false,"#000","#000","Leaderboard"), ] this.activeTextBox = 0 @@ -93,11 +94,6 @@ class LoginScreen { screenManager.setScreen(new StartScreen()); } - this.buttons[3].draw(); - this.buttons[4].draw(); - this.buttons[5].draw(); - this.buttons[6].draw(); - this.buttons[7].draw(); if (this.buttons[3].isPressed()) { screenManager.setScreen(new SignUpScreen()); } else if (this.buttons[4].isPressed()) { @@ -108,6 +104,8 @@ class LoginScreen { screenManager.setScreen(new ProfileScreen()); } else if (this.buttons[7].isPressed()) { screenManager.setScreen(new TestScreen()) + } else if (this.buttons[8].isPressed()) { + screenManager.setScreen(new LeaderboardScreen()) } } diff --git a/website/screens/profilescreen.js b/website/screens/profilescreen.js index e82ffce..82ae277 100644 --- a/website/screens/profilescreen.js +++ b/website/screens/profilescreen.js @@ -6,6 +6,7 @@ class ProfileScreen { new Button(220,0,100,30,0,true,"#fff",false,"#000","#000","Logout"), new Button(330,0,100,30,0,true,"#fff",false,"#000","#000","Profile"), new Button(440,0,100,30,0,true,"#fff",false,"#000","#000","Test"), + new Button(550,0,140,30,0,true,"#fff",false,"#000","#000","Leaderboard"), ]; api.getUserTests(); } @@ -16,11 +17,10 @@ class ProfileScreen { textAlign(CENTER, CENTER); fill("#000"); text("Profile", 0, 100, windowWidth, 120); - this.buttons[0].draw(); - this.buttons[1].draw(); - this.buttons[2].draw(); - this.buttons[3].draw(); - this.buttons[4].draw(); + + for (let i = 0; i < this.buttons.length; i++) { + this.buttons[i].draw() + } if (this.buttons[0].isPressed()) { screenManager.setScreen(new SignUpScreen()); } else if (this.buttons[1].isPressed()) { @@ -31,6 +31,8 @@ class ProfileScreen { screenManager.setScreen(new ProfileScreen()); } else if (this.buttons[4].isPressed()) { screenManager.setScreen(new TestScreen()) + } else if (this.buttons[5].isPressed()) { + screenManager.setScreen(new LeaderboardScreen()) } textSize(20); diff --git a/website/screens/signUpScreen.js b/website/screens/signUpScreen.js index be5f900..12dd24d 100644 --- a/website/screens/signUpScreen.js +++ b/website/screens/signUpScreen.js @@ -57,6 +57,7 @@ class SignUpScreen { new Button(220,0,100,30,0,true,"#fff",false,"#000","#000","Logout"), new Button(330,0,100,30,0,true,"#fff",false,"#000","#000","Profile"), new Button(440,0,100,30,0,true,"#fff",false,"#000","#000","Test"), + new Button(550,0,140,30,0,true,"#fff",false,"#000","#000","Leaderboard"), ] this.activeTextBox = 0 @@ -91,14 +92,7 @@ class SignUpScreen { this.textboxes[1].getWords() ) screenManager.setScreen(new StartScreen()); - } - - this.buttons[3].draw(); - this.buttons[4].draw(); - this.buttons[5].draw(); - this.buttons[6].draw(); - this.buttons[7].draw(); - if (this.buttons[3].isPressed()) { + } else if (this.buttons[3].isPressed()) { screenManager.setScreen(new SignUpScreen()); } else if (this.buttons[4].isPressed()) { screenManager.setScreen(new LoginScreen()); @@ -108,6 +102,8 @@ class SignUpScreen { screenManager.setScreen(new ProfileScreen()); } else if (this.buttons[7].isPressed()) { screenManager.setScreen(new TestScreen()) + } else if (this.buttons[5].isPressed()) { + screenManager.setScreen(new LeaderboardScreen()) } } diff --git a/website/screens/startscreen.js b/website/screens/startscreen.js index ec821a0..b37a527 100644 --- a/website/screens/startscreen.js +++ b/website/screens/startscreen.js @@ -6,6 +6,7 @@ class StartScreen { new Button(220,0,100,30,0,true,"#fff",false,"#000","#000","Logout"), new Button(330,0,100,30,0,true,"#fff",false,"#000","#000","Profile"), new Button(440,0,100,30,0,true,"#fff",false,"#000","#000","Test"), + new Button(550,0,140,30,0,true,"#fff",false,"#000","#000","Leaderboard"), ] } @@ -15,11 +16,10 @@ class StartScreen { textAlign(CENTER, CENTER); fill("#000"); text("Press enter to start test", 0, 0, windowWidth - 100, windowHeight - 100); - this.buttons[0].draw(); - this.buttons[1].draw(); - this.buttons[2].draw(); - this.buttons[3].draw(); - this.buttons[4].draw(); + + for (let i = 0; i < this.buttons.length; i++) { + this.buttons[i].draw() + } if (this.buttons[0].isPressed()) { screenManager.setScreen(new SignUpScreen()); } else if (this.buttons[1].isPressed()) { @@ -30,7 +30,10 @@ class StartScreen { screenManager.setScreen(new ProfileScreen()); } else if (this.buttons[4].isPressed()) { screenManager.setScreen(new TestScreen()); + } else if (this.buttons[5].isPressed()) { + screenManager.setScreen(new LeaderboardScreen()) } + fill("#000"); text(`${user.username}`, windowWidth-100, 15); }