diff --git a/public/css/home.css b/public/css/home.css index 33d72c0..2686ffd 100644 --- a/public/css/home.css +++ b/public/css/home.css @@ -2,7 +2,7 @@ body { background-color: #f0f2f5; } -#posts { +#posts, #create { display: flex; flex-direction: column; align-items: center; @@ -172,7 +172,7 @@ body { flex-direction: row; } -#comments input { +.comments input { all: unset; padding: 10px; border-radius: 10px; diff --git a/public/js/header.js b/public/js/header.js index 8fe03e5..5a12408 100644 --- a/public/js/header.js +++ b/public/js/header.js @@ -20,6 +20,5 @@ function header(home, people) {
` - - add(html, 'header') + append(html) } \ No newline at end of file diff --git a/public/js/home.js b/public/js/home.js index 688cbf5..ee3d6f0 100644 --- a/public/js/home.js +++ b/public/js/home.js @@ -41,19 +41,19 @@ function parsePost(post) {
- - - Like + + + Like Comment
-
+
- ${post.comments.map(parseComment).join('')} -
+ ${post.comments.map(parseComment).join('')} +
@@ -64,7 +64,6 @@ function parsePost(post) {
` - return html } @@ -78,7 +77,8 @@ function getPost(post_id) { } async function like(span) { - const id = parseInt(span.parentElement.parentElement.getAttribute('postid')) + const container = span.parentElement.parentElement; + const id = parseInt(container.getAttribute('postid')) const post = data.posts[getPost(id)] const index = post.likes.indexOf(data.user.user_id) const current = index !== -1 @@ -89,26 +89,40 @@ async function like(span) { } else { post.likes.push(data.user.user_id) } - render() + const buttons = container + .getElementsByClassName("postbuttons")[0] + .getElementsByClassName("likeclicky")[0] + .getElementsByClassName("liketoggle") + if (current) { + buttons[0].classList.remove("blue") + buttons[1].classList.remove("blue") + } else { + buttons[0].classList.add("blue") + buttons[1].classList.add("blue") + } } async function comment(event) { event.preventDefault(); const text = event.target.elements.text.value.trim(); if (text.length < 1) return; - const id = parseInt(event.target.parentElement.parentElement.parentElement.getAttribute('postid')) - var index = getPost(id); + const container = event.target.parentElement.parentElement.parentElement; + const post_id = parseInt(container.getAttribute('postid')) + var index = getPost(post_id); if (index === -1) return; - const response = await postcomment(id, text) + const response = await postcomment(post_id, text) if (response.status != 200) return; event.target.elements.text.value = ''; - data.posts[index].comments.push([data.user.user_id, text]) - render() + let new_comment = [data.user.user_id, text] + data.posts[index].comments.push(new_comment) + let comments = container.getElementsByClassName("comments")[0] + prepend(parseComment(new_comment), comments, comments.getElementsByClassName("commentsubmit")[0]) } async function post() { const text = document.getElementById("text").value.trim() const error = document.getElementsByClassName('error')[0] + const posts_block = document.getElementById("posts") if (text.length < 1) return; const response = await createpost(text); if (response.status != 201) { @@ -116,20 +130,32 @@ async function post() { return; } error.innerHTML = ''; - data.posts.unshift({ + let post = { post_id: response.json.post_id, user_id: data.user.user_id, date: Date.now(), content: text, likes: [], comments: [] - }) - render() + } + data.posts.unshift(post) + let html = parsePost(post) + prepend(html, posts_block) + document.getElementById('popup').classList.add('hidden') +} + +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) + } } function render() { const html = ` -
+ +
${data.posts.map(p => parsePost(p)).join('')}
` - add(html, 'posts') + append(html) const popup = ` ` - add(popup, 'popup') + append(popup) const load = `
` - if (page !== -1) { - add(load, 'load') - } else { - remove('load') - } + append(load) } var page = 0 @@ -194,10 +218,11 @@ async function load() { const posts = (await loadpostspage(page)).json if (posts.length === 0) { page = -1 + remove('load') + return [] } else { page++ } - data.posts.push(... posts) const batch = [] for (const post of posts) { for(const comment of post.comments) { @@ -209,17 +234,18 @@ async function load() { if (batch.includes(post.user_id)) continue batch.push(post.user_id) } - const users = (await loadusers(batch)).json + const users = batch.length == 0 ? [] : (await loadusers(batch)).json for (const user of users) { data.users[user.user_id] = user } - render() + return posts } - async function init() { header(true, false) data.user = (await loadself()).json data.users[data.user.user_id] = data.user - load() + const posts = await load() + data.posts.push(... posts) + render() } \ No newline at end of file diff --git a/public/js/main.js b/public/js/main.js index 06736ee..12f53ec 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -1,15 +1,26 @@ -var range; +function prepend(html, container, before) { + if (container === undefined) { + container = document.body + } + if (before === undefined) { + before = container.firstChild + } + console.log(html, container, before) + var range = document.createRange() + range.setStart(container, 0); + container.insertBefore( + range.createContextualFragment(html), + before + ) +} -function add(html, id) { - const old = document.getElementById(id) - if (old !== null) { - old.remove() +function append(html, container) { + if (container === undefined) { + container = document.body } - if (range === undefined) { - var range = document.createRange() - range.setStart(document.body, 0) - } - document.body.appendChild( + var range = document.createRange() + range.setStart(container, 0); + container.appendChild( range.createContextualFragment(html) ) } diff --git a/public/js/people.js b/public/js/people.js index e9f5db6..5c1026b 100644 --- a/public/js/people.js +++ b/public/js/people.js @@ -23,19 +23,15 @@ function render() {
` - add(html, 'users') + append(html) const load = ` ` - if (page !== -1) { - add(load, 'load') - } else { - remove('load') - } + append(load) } var page = 0 @@ -43,16 +39,30 @@ var data = { users: [] } +async function loadMore() { + let users = await load() + const users_block = document.getElementById("users") + for (user of users) { + append(parseUser(user), users_block) + } +} + async function load() { const users = (await loaduserspage(page)).json if (users.length === 0) { page = -1 + remove('load') } else { page++ } + return users +} + +async function init() { + let users = await load() data.users.push(... users) render() } header(false, true) -load() \ No newline at end of file +init() \ No newline at end of file diff --git a/public/js/profile.js b/public/js/profile.js index 1f72b17..787e2b2 100644 --- a/public/js/profile.js +++ b/public/js/profile.js @@ -1,3 +1,21 @@ +function swap(value) { + let postsb = document.getElementById("profilepostbutton"); + let aboutb = document.getElementById("profileaboutbutton"); + let posts = document.getElementById("posts"); + let about = document.getElementById("about"); + if (value) { + postsb.classList.add("selected") + aboutb.classList.remove("selected") + about.classList.add("hidden") + posts.classList.remove("hidden") + } else { + postsb.classList.remove("selected") + aboutb.classList.add("selected") + about.classList.remove("hidden") + posts.classList.add("hidden") + } +} + function render() { const html = `
@@ -17,10 +35,10 @@ function render() {
- -
@@ -29,7 +47,7 @@ function render() {
` - add(html, 'top') + append(html) const postsh = `
@@ -37,7 +55,7 @@ function render() {
` - add(postsh, 'posts') + append(postsh) const about = `
@@ -52,7 +70,7 @@ function render() {
` - add(about, 'about') + append(about) } async function logout_button() { @@ -72,21 +90,22 @@ async function load() { params[key] = value } - let self = (await loadself()).json; + data.user = (await loadself()).json; + data.users[data.user.user_id] = data.user let id; if (params.id !== undefined && !isNaN(params.id)) { id = parseInt(params.id); } else { - id = self.user_id + id = data.user.user_id } - isself = id === self.user_id + isself = id === data.user.user_id const posts = (await loadusersposts(id)).json data.posts.push(... posts) - const batch = [id] + const batch = [] for (const post of posts) { for(const comment of post.comments) { if (data.users[comment[0]] !== undefined) continue @@ -97,11 +116,10 @@ async function load() { if (batch.includes(post.user_id)) continue batch.push(post.user_id) } - const users = (await loadusers(batch)).json + 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() } diff --git a/src/api/pages.rs b/src/api/pages.rs index 4661b91..9149744 100644 --- a/src/api/pages.rs +++ b/src/api/pages.rs @@ -6,10 +6,10 @@ use axum::{ use crate::{ console, - types::{extract::AuthorizedUser, http::ResponseCode}, + types::{extract::{AuthorizedUser, Log}, http::ResponseCode}, }; -async fn root(user: Option) -> Response { +async fn root(user: Option, _: Log) -> Response { if user.is_some() { Redirect::to("/home").into_response() } else { @@ -17,7 +17,7 @@ async fn root(user: Option) -> Response { } } -async fn login(user: Option) -> Response { +async fn login(user: Option, _: Log) -> Response { if user.is_some() { Redirect::to("/home").into_response() } else { @@ -25,7 +25,7 @@ async fn login(user: Option) -> Response { } } -async fn home(user: Option) -> Response { +async fn home(user: Option, _: Log) -> Response { if user.is_none() { Redirect::to("/login").into_response() } else { @@ -33,7 +33,7 @@ async fn home(user: Option) -> Response { } } -async fn people(user: Option) -> Response { +async fn people(user: Option, _: Log) -> Response { if user.is_none() { Redirect::to("/login").into_response() } else { @@ -41,7 +41,7 @@ async fn people(user: Option) -> Response { } } -async fn profile(user: Option) -> Response { +async fn profile(user: Option, _: Log) -> Response { if user.is_none() { Redirect::to("/login").into_response() } else { @@ -53,7 +53,7 @@ async fn console() -> Response { console::generate().await } -async fn wordpress() -> Response { +async fn wordpress(_: Log) -> Response { ResponseCode::ImATeapot.text("Hello i am a teapot owo") } diff --git a/src/console.rs b/src/console.rs index 14324fa..eb78c6a 100644 --- a/src/console.rs +++ b/src/console.rs @@ -45,10 +45,7 @@ lazy_static! { } pub async fn log(ip: IpAddr, method: Method, uri: Uri, path: Option, body: Option) { - if uri.to_string().starts_with("/console") { - return; - } - + let path = path.unwrap_or_default(); let body = body.unwrap_or_default(); diff --git a/src/main.rs b/src/main.rs index cd137b9..20627d7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,11 @@ use axum::{ body::HttpBody, - extract::ConnectInfo, http::{Request, StatusCode}, middleware::{self, Next}, response::Response, Extension, RequestExt, Router, }; +use axum_client_ip::ClientIp; use std::{net::SocketAddr, process::exit}; use tower_cookies::CookieManagerLayer; use tracing::{error, info, metadata::LevelFilter}; @@ -40,18 +40,11 @@ async fn log(mut req: Request, next: Next) -> Response where B: Send + Sync + 'static + HttpBody, { - let Ok(ConnectInfo(info)) = req.extract_parts::>().await else { + let Ok(ClientIp(ip)) = req.extract_parts::().await else { return next.run(req).await }; - console::log( - info.ip(), - req.method().clone(), - req.uri().clone(), - None, - None, - ) - .await; + console::log(ip, req.method().clone(), req.uri().clone(), None, None).await; next.run(req).await } @@ -80,9 +73,9 @@ async fn main() { let app = Router::new() .fallback(not_found) - .nest("/", pages::router()) .layer(middleware::from_fn(log)) .layer(middleware::from_fn(serve)) + .nest("/", pages::router()) .nest( "/api/auth", auth::router().layer(Extension(RouterURI("/api/auth"))), diff --git a/src/types/extract.rs b/src/types/extract.rs index e79aa7a..4d92a3b 100644 --- a/src/types/extract.rs +++ b/src/types/extract.rs @@ -85,10 +85,9 @@ where type Rejection = Response; async fn from_request(req: Request, state: &S) -> Result { - let body = match parse_body(req, state).await { Ok(body) => body, - Err(err) => return Err(err) + Err(err) => return Err(err), }; let Ok(value) = serde_json::from_str::(&body) else { @@ -128,7 +127,7 @@ where B: HttpBody + Sync + Send + 'static, B::Data: Send, B::Error: Into, - S: Send + Sync + S: Send + Sync, { let Ok(ClientIp(ip)) = req.extract_parts::().await else { tracing::error!("Failed to read client ip");