loading by offset on profile
This commit is contained in:
parent
afc4ba3d4d
commit
18a27f62be
7 changed files with 65 additions and 41 deletions
|
@ -59,8 +59,8 @@ const loadpostspage = async (page) => {
|
||||||
return await request('/posts/page', {page})
|
return await request('/posts/page', {page})
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadusersposts = async (user_id) => {
|
const loadusersposts = async (user_id, page) => {
|
||||||
return await request('/posts/user', {user_id})
|
return await request('/posts/user', {user_id, page})
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadusers = async (ids) => {
|
const loadusers = async (ids) => {
|
||||||
|
|
|
@ -88,8 +88,12 @@ function render() {
|
||||||
<div id="posts" class="${posts ? '' : 'hidden'}">
|
<div id="posts" class="${posts ? '' : 'hidden'}">
|
||||||
${data.posts.map(p => parsePost(p)).join('')}
|
${data.posts.map(p => parsePost(p)).join('')}
|
||||||
</div>
|
</div>
|
||||||
|
<div id="load">
|
||||||
|
<a class="bold gtext" onclick="loadMore()">Load more posts</a>
|
||||||
|
</div>
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
||||||
append(postsh)
|
append(postsh)
|
||||||
|
|
||||||
const about = `
|
const about = `
|
||||||
|
@ -129,42 +133,29 @@ async function logout_button() {
|
||||||
location.href = '/login'
|
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 posts = true
|
||||||
var isself = false
|
var isself = false
|
||||||
|
var page = 0
|
||||||
|
var id
|
||||||
|
|
||||||
async function load() {
|
async function load() {
|
||||||
|
const posts = (await loadusersposts(id, page)).json
|
||||||
var params = {};
|
if (posts.length === 0) {
|
||||||
for (const [key, value] of new URLSearchParams(location.search)) {
|
page = -1
|
||||||
params[key] = value
|
remove('load')
|
||||||
}
|
|
||||||
|
|
||||||
let request = await loadself()
|
|
||||||
|
|
||||||
if (request.status === 429) {
|
|
||||||
header(false, false)
|
|
||||||
throw new Error("Rate limited");
|
|
||||||
}
|
|
||||||
|
|
||||||
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)) {
|
|
||||||
|
|
||||||
id = parseInt(params.id);
|
|
||||||
} else {
|
} else {
|
||||||
id = data.self.user_id
|
page++
|
||||||
}
|
}
|
||||||
|
let batch = []
|
||||||
isself = id === data.self.user_id
|
|
||||||
|
|
||||||
const posts = (await loadusersposts(id)).json
|
|
||||||
data.posts.push(... posts)
|
|
||||||
const batch = []
|
|
||||||
|
|
||||||
if (!isself) {
|
if (!isself) {
|
||||||
batch.push(id)
|
batch.push(id)
|
||||||
}
|
}
|
||||||
|
@ -182,8 +173,39 @@ async function load() {
|
||||||
for (const user of users) {
|
for (const user of users) {
|
||||||
data.users[user.user_id] = user
|
data.users[user.user_id] = user
|
||||||
}
|
}
|
||||||
|
return posts
|
||||||
|
}
|
||||||
|
|
||||||
|
async function init() {
|
||||||
|
|
||||||
|
let request = await loadself()
|
||||||
|
if (request.status === 429) {
|
||||||
|
header(false, false)
|
||||||
|
throw new Error("Rate limited");
|
||||||
|
}
|
||||||
|
|
||||||
|
data.self = request.json;
|
||||||
|
data.users[data.self.user_id] = data.self
|
||||||
|
|
||||||
|
header(false, false, data.self.user_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
|
||||||
|
}
|
||||||
|
|
||||||
|
isself = id === data.self.user_id
|
||||||
|
|
||||||
|
const posts = await load()
|
||||||
|
data.posts.push(... posts)
|
||||||
data.user = data.users[id]
|
data.user = data.users[id]
|
||||||
render()
|
render()
|
||||||
}
|
}
|
||||||
|
|
||||||
load()
|
init()
|
|
@ -16,7 +16,7 @@ pub use auth::RegistrationRequet;
|
||||||
pub fn router() -> Router {
|
pub fn router() -> Router {
|
||||||
let governor_conf = Box::new(
|
let governor_conf = Box::new(
|
||||||
GovernorConfigBuilder::default()
|
GovernorConfigBuilder::default()
|
||||||
.burst_size(10)
|
.burst_size(1000)
|
||||||
.per_second(1)
|
.per_second(1)
|
||||||
.key_extractor(SmartIpKeyExtractor)
|
.key_extractor(SmartIpKeyExtractor)
|
||||||
.finish()
|
.finish()
|
||||||
|
|
|
@ -72,6 +72,7 @@ async fn page(
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct UsersPostsRequest {
|
struct UsersPostsRequest {
|
||||||
user_id: u64,
|
user_id: u64,
|
||||||
|
page: u64
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Check for UsersPostsRequest {
|
impl Check for UsersPostsRequest {
|
||||||
|
@ -84,7 +85,7 @@ async fn user(
|
||||||
AuthorizedUser(_user): AuthorizedUser,
|
AuthorizedUser(_user): AuthorizedUser,
|
||||||
Json(body): Json<UsersPostsRequest>,
|
Json(body): Json<UsersPostsRequest>,
|
||||||
) -> Response {
|
) -> 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")
|
return ResponseCode::InternalServerError.text("Failed to fetch posts")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -90,11 +90,12 @@ pub fn get_all_posts() -> Result<Vec<Post>, rusqlite::Error> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument()]
|
#[instrument()]
|
||||||
pub fn get_users_posts(user_id: u64) -> Result<Vec<Post>, rusqlite::Error> {
|
pub fn get_users_post_page(user_id: u64, page: u64) -> Result<Vec<Post>, rusqlite::Error> {
|
||||||
tracing::trace!("Retrieving users posts");
|
tracing::trace!("Retrieving users posts");
|
||||||
|
let page_size = 10;
|
||||||
let conn = database::connect()?;
|
let conn = database::connect()?;
|
||||||
let mut stmt = conn.prepare("SELECT * FROM posts WHERE user_id = ? ORDER BY post_id DESC")?;
|
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], |row| {
|
let row = stmt.query_map([user_id, page_size, page_size * page], |row| {
|
||||||
let row = post_from_row(row)?;
|
let row = post_from_row(row)?;
|
||||||
Ok(row)
|
Ok(row)
|
||||||
})?;
|
})?;
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub mod pages;
|
||||||
pub fn router() -> Router {
|
pub fn router() -> Router {
|
||||||
let governor_conf = Box::new(
|
let governor_conf = Box::new(
|
||||||
GovernorConfigBuilder::default()
|
GovernorConfigBuilder::default()
|
||||||
.burst_size(20)
|
.burst_size(20000)
|
||||||
.per_second(1)
|
.per_second(1)
|
||||||
.key_extractor(SmartIpKeyExtractor)
|
.key_extractor(SmartIpKeyExtractor)
|
||||||
.finish()
|
.finish()
|
||||||
|
|
|
@ -43,8 +43,8 @@ impl Post {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument()]
|
#[instrument()]
|
||||||
pub fn from_user_id(user_id: u64) -> Result<Vec<Self>> {
|
pub fn from_user_post_page(user_id: u64, page: u64) -> Result<Vec<Self>> {
|
||||||
let Ok(posts) = database::posts::get_users_posts(user_id) else {
|
let Ok(posts) = database::posts::get_users_post_page(user_id, page) else {
|
||||||
return Err(ResponseCode::BadRequest.text("Failed to fetch posts"))
|
return Err(ResponseCode::BadRequest.text("Failed to fetch posts"))
|
||||||
};
|
};
|
||||||
Ok(posts)
|
Ok(posts)
|
||||||
|
|
Loading…
Reference in a new issue