From 18a27f62befb0c0d2e3b175f08f6088f10b25063 Mon Sep 17 00:00:00 2001 From: Tyler Murphy Date: Thu, 2 Feb 2023 11:29:37 -0500 Subject: loading by offset on profile --- public/js/api.js | 4 +-- public/js/profile.js | 78 +++++++++++++++++++++++++++++++++------------------ src/api/mod.rs | 2 +- src/api/posts.rs | 3 +- src/database/posts.rs | 7 +++-- src/public/mod.rs | 2 +- src/types/post.rs | 4 +-- 7 files changed, 62 insertions(+), 38 deletions(-) diff --git a/public/js/api.js b/public/js/api.js index b2ea597..886a017 100644 --- a/public/js/api.js +++ b/public/js/api.js @@ -59,8 +59,8 @@ const loadpostspage = async (page) => { return await request('/posts/page', {page}) } -const loadusersposts = async (user_id) => { - return await request('/posts/user', {user_id}) +const loadusersposts = async (user_id, page) => { + return await request('/posts/user', {user_id, page}) } const loadusers = async (ids) => { diff --git a/public/js/profile.js b/public/js/profile.js index 083464f..40e6354 100644 --- a/public/js/profile.js +++ b/public/js/profile.js @@ -88,8 +88,12 @@ function render() {
${data.posts.map(p => parsePost(p)).join('')}
+
+ Load more posts +
` + append(postsh) const about = ` @@ -129,18 +133,52 @@ async function logout_button() { location.href = '/login' } +async function loadMore() { + const posts = await load() + data.posts.push(... posts) + const posts_block = document.getElementById("posts") + for (p of posts) { + append(parsePost(p), posts_block) + } +} + var posts = true var isself = false +var page = 0 +var id async function load() { - - var params = {}; - for (const [key, value] of new URLSearchParams(location.search)) { - params[key] = value + const posts = (await loadusersposts(id, page)).json + if (posts.length === 0) { + page = -1 + remove('load') + } else { + page++ + } + let batch = [] + if (!isself) { + batch.push(id) + } + for (const post of posts) { + for(const comment of post.comments) { + if (data.users[comment[0]] !== undefined) continue + if (batch.includes(comment[0])) continue + batch.push(comment[0]) + } + if (data.users[post.user_id] !== undefined) continue + if (batch.includes(post.user_id)) continue + batch.push(post.user_id) + } + const users = batch.length == 0 ? [] : (await loadusers(batch)).json + for (const user of users) { + data.users[user.user_id] = user } + return posts +} - let request = await loadself() +async function init() { + let request = await loadself() if (request.status === 429) { header(false, false) throw new Error("Rate limited"); @@ -148,12 +186,15 @@ async function load() { data.self = request.json; data.users[data.self.user_id] = data.self - let id; header(false, false, data.self.user_id) - if (params.id !== undefined && !isNaN(params.id)) { + var params = {}; + for (const [key, value] of new URLSearchParams(location.search)) { + params[key] = value + } + if (params.id !== undefined && !isNaN(params.id)) { id = parseInt(params.id); } else { id = data.self.user_id @@ -161,29 +202,10 @@ async function load() { isself = id === data.self.user_id - const posts = (await loadusersposts(id)).json + const posts = await load() data.posts.push(... posts) - const batch = [] - - if (!isself) { - batch.push(id) - } - for (const post of posts) { - for(const comment of post.comments) { - if (data.users[comment[0]] !== undefined) continue - if (batch.includes(comment[0])) continue - batch.push(comment[0]) - } - if (data.users[post.user_id] !== undefined) continue - if (batch.includes(post.user_id)) continue - batch.push(post.user_id) - } - const users = batch.length == 0 ? [] : (await loadusers(batch)).json - for (const user of users) { - data.users[user.user_id] = user - } data.user = data.users[id] render() } -load() \ No newline at end of file +init() \ No newline at end of file diff --git a/src/api/mod.rs b/src/api/mod.rs index 9efcefc..925aa4a 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -16,7 +16,7 @@ pub use auth::RegistrationRequet; pub fn router() -> Router { let governor_conf = Box::new( GovernorConfigBuilder::default() - .burst_size(10) + .burst_size(1000) .per_second(1) .key_extractor(SmartIpKeyExtractor) .finish() diff --git a/src/api/posts.rs b/src/api/posts.rs index 3a2e507..d85fb98 100644 --- a/src/api/posts.rs +++ b/src/api/posts.rs @@ -72,6 +72,7 @@ async fn page( #[derive(Deserialize)] struct UsersPostsRequest { user_id: u64, + page: u64 } impl Check for UsersPostsRequest { @@ -84,7 +85,7 @@ async fn user( AuthorizedUser(_user): AuthorizedUser, Json(body): Json, ) -> Response { - let Ok(posts) = Post::from_user_id(body.user_id) else { + let Ok(posts) = Post::from_user_post_page(body.user_id, body.page) else { return ResponseCode::InternalServerError.text("Failed to fetch posts") }; diff --git a/src/database/posts.rs b/src/database/posts.rs index 6c0a27e..a81d6a7 100644 --- a/src/database/posts.rs +++ b/src/database/posts.rs @@ -90,11 +90,12 @@ pub fn get_all_posts() -> Result, rusqlite::Error> { } #[instrument()] -pub fn get_users_posts(user_id: u64) -> Result, rusqlite::Error> { +pub fn get_users_post_page(user_id: u64, page: u64) -> Result, rusqlite::Error> { tracing::trace!("Retrieving users posts"); + let page_size = 10; let conn = database::connect()?; - let mut stmt = conn.prepare("SELECT * FROM posts WHERE user_id = ? ORDER BY post_id DESC")?; - let row = stmt.query_map([user_id], |row| { + let mut stmt = conn.prepare("SELECT * FROM posts WHERE user_id = ? ORDER BY post_id DESC LIMIT ? OFFSET ?")?; + let row = stmt.query_map([user_id, page_size, page_size * page], |row| { let row = post_from_row(row)?; Ok(row) })?; diff --git a/src/public/mod.rs b/src/public/mod.rs index eb846fb..7e5b382 100644 --- a/src/public/mod.rs +++ b/src/public/mod.rs @@ -24,7 +24,7 @@ pub mod pages; pub fn router() -> Router { let governor_conf = Box::new( GovernorConfigBuilder::default() - .burst_size(20) + .burst_size(20000) .per_second(1) .key_extractor(SmartIpKeyExtractor) .finish() diff --git a/src/types/post.rs b/src/types/post.rs index 7397009..ea7cbbf 100644 --- a/src/types/post.rs +++ b/src/types/post.rs @@ -43,8 +43,8 @@ impl Post { } #[instrument()] - pub fn from_user_id(user_id: u64) -> Result> { - let Ok(posts) = database::posts::get_users_posts(user_id) else { + pub fn from_user_post_page(user_id: u64, page: u64) -> Result> { + let Ok(posts) = database::posts::get_users_post_page(user_id, page) else { return Err(ResponseCode::BadRequest.text("Failed to fetch posts")) }; Ok(posts) -- cgit v1.2.3-freya