summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--public/css/profile.css2
-rw-r--r--public/js/profile.js92
-rw-r--r--src/database/friends.rs44
-rw-r--r--src/types/user.rs15
4 files changed, 101 insertions, 52 deletions
diff --git a/public/css/profile.css b/public/css/profile.css
index 112b1bf..54bf4f1 100644
--- a/public/css/profile.css
+++ b/public/css/profile.css
@@ -119,7 +119,7 @@ body {
border-bottom: 3px solid var(--logo) !important;
}
-#about, #friends {
+#about, #friends, #followers, #following {
margin-top: 2em;
align-self: center;
padding: 0;
diff --git a/public/js/profile.js b/public/js/profile.js
index 4e4f44f..a9990fb 100644
--- a/public/js/profile.js
+++ b/public/js/profile.js
@@ -3,58 +3,38 @@ import { loadself, loadusers, loadusersposts, updateavatar, updatebanner, logout
import { parsePost, parseUser, header } from './components.js'
function swap(tab) {
- let post_button = document.querySelector("#profilepostbutton");
- let about_button = document.querySelector("#profileaboutbutton");
- let friends_button = document.querySelector("#profilefriendsbutton");
+ let buttons = []
+ buttons[0] = document.querySelector("#profilepostbutton");
+ buttons[1] = document.querySelector("#profileaboutbutton");
+ buttons[2] = document.querySelector("#profilefriendsbutton");
+ buttons[3] = document.querySelector("#profilefollowersbutton");
+ buttons[4] = document.querySelector("#profilefollowingbutton");
- let posts_section = document.querySelector("#posts");
- let about_section = document.querySelector("#about");
- let friends_section = document.querySelector("#friends");
+ let sections = []
+ sections[0] = document.querySelector("#posts");
+ sections[1] = document.querySelector("#about");
+ sections[2] = document.querySelector("#friends");
+ sections[3] = document.querySelector("#followers");
+ sections[4] = document.querySelector("#following");
let load = document.querySelector(".loadp");
- if (tab === 0) {
-
- post_button.classList.add("selected")
- about_button.classList.remove("selected")
- friends_button.classList.remove("selected")
-
- posts_section.classList.remove("hidden")
- about_section.classList.add("hidden")
- friends_section.classList.add("hidden")
-
- if (load) {
- load.classList.remove("hidden")
- }
-
- } else if (tab === 1) {
-
- post_button.classList.remove("selected")
- about_button.classList.add("selected")
- friends_button.classList.remove("selected")
-
- posts_section.classList.add("hidden")
- about_section.classList.remove("hidden")
- friends_section.classList.add("hidden")
-
- if (load) {
- load.classList.add("hidden")
+ for (const i in buttons) {
+ if (i == tab) {
+ buttons[i].classList.add("selected")
+ sections[i].classList.remove("hidden")
+ } else {
+ buttons[i].classList.remove("selected")
+ sections[i].classList.add("hidden")
}
+ }
- } else if (tab === 2) {
-
- post_button.classList.remove("selected")
- about_button.classList.remove("selected")
- friends_button.classList.add("selected")
-
- posts_section.classList.add("hidden")
- about_section.classList.add("hidden")
- friends_section.classList.remove("hidden")
-
- if (load) {
+ if (load) {
+ if (tab == 0) {
+ load.classList.remove("hidden")
+ } else {
load.classList.add("hidden")
}
-
}
}
@@ -116,11 +96,15 @@ async function render() {
}
}
- let friends_arr = (await friends(data.user.user_id)).json
- if (friends_arr == undefined) {
- friends_arr = []
+ let response = (await friends(data.user.user_id)).json
+ if (response == undefined) {
+ response = []
}
+ let friends_arr = response[0];
+ let followers = response[1];
+ let following = response[2];
+
let new_body =
body({},
...header(false, false, data.self.user_id),
@@ -190,6 +174,12 @@ async function render() {
button({id: 'profilefriendsbutton', onclick: () => swap(2)},
parse('Friends')
),
+ button({id: 'profilefollowersbutton', onclick: () => swap(3)},
+ parse('Followers')
+ ),
+ button({id: 'profilefollowingbutton', onclick: () => swap(4)},
+ parse('Following')
+ ),
div({style: 'flex: 20'}),
isself ? button({class: 'logout', onclick: async () => {
const response = await logout()
@@ -239,13 +229,19 @@ async function render() {
parse('Birthday: ' + parseMonth(data.user.month) + ' ' + data.user.day + ', ' + data.user.year)
),
span({class: 'gtext bold'},
- parse('User ID: ' + data.user_id)
+ parse('User ID: ' + data.user.user_id)
)
)
),
div({id: 'friends', class: 'hidden'},
...friends_arr.map(u => parseUser(u))
),
+ div({id: 'followers', class: 'hidden'},
+ ...followers.map(u => parseUser(u))
+ ),
+ div({id: 'following', class: 'hidden'},
+ ...following.map(u => parseUser(u))
+ ),
div({id: 'popup', class: 'hidden'},
div({class: 'createpost'},
div({class: 'close', onclick: () => document.getElementById('popup').classList.add('hidden')}),
diff --git a/src/database/friends.rs b/src/database/friends.rs
index 31434d4..7e23616 100644
--- a/src/database/friends.rs
+++ b/src/database/friends.rs
@@ -75,6 +75,50 @@ impl Database {
}
#[instrument(skip(self))]
+ pub fn get_followers(&self, user_id: u64) -> Result<Vec<User>, rusqlite::Error> {
+ tracing::trace!("Retrieving friends");
+ let mut stmt = self.0.prepare(
+ "
+ SELECT *
+ FROM users u
+ WHERE EXISTS (
+ SELECT NULL
+ FROM friends f
+ WHERE f.follower_id = ?
+ AND u.user_id = f.followee_id
+ )
+ ",
+ )?;
+ let row = stmt.query_map([user_id], |row| {
+ let row = Self::user_from_row(row, true)?;
+ Ok(row)
+ })?;
+ Ok(row.into_iter().flatten().collect())
+ }
+
+ #[instrument(skip(self))]
+ pub fn get_following(&self, user_id: u64) -> Result<Vec<User>, rusqlite::Error> {
+ tracing::trace!("Retrieving friends");
+ let mut stmt = self.0.prepare(
+ "
+ SELECT *
+ FROM users u
+ WHERE EXISTS (
+ SELECT NULL
+ FROM friends f
+ WHERE u.user_id = f.follower_id
+ AND f.followee_id = ?
+ )
+ ",
+ )?;
+ let row = stmt.query_map([user_id], |row| {
+ let row = Self::user_from_row(row, true)?;
+ Ok(row)
+ })?;
+ Ok(row.into_iter().flatten().collect())
+ }
+
+ #[instrument(skip(self))]
pub fn set_following(&self, user_id_1: u64, user_id_2: u64) -> Result<bool, rusqlite::Error> {
tracing::trace!("Setting following");
let mut stmt = self
diff --git a/src/types/user.rs b/src/types/user.rs
index 3c4cd6a..3d7d85a 100644
--- a/src/types/user.rs
+++ b/src/types/user.rs
@@ -135,10 +135,19 @@ impl User {
}
#[instrument(skip(db))]
- pub fn get_friends(db: &Database, user_id: u64) -> Result<Vec<Self>> {
- let Ok(users) = db.get_friends(user_id) else {
+ pub fn get_friends(db: &Database, user_id: u64) -> Result<(Vec<Self>, Vec<Self>, Vec<Self>)> {
+ let Ok(friends) = db.get_friends(user_id) else {
return Err(ResponseCode::InternalServerError.text("Failed to fetch friends"))
};
- Ok(users)
+
+ let Ok(followers) = db.get_followers(user_id) else {
+ return Err(ResponseCode::InternalServerError.text("Failed to fetch friends"))
+ };
+
+ let Ok(following) = db.get_following(user_id) else {
+ return Err(ResponseCode::InternalServerError.text("Failed to fetch friends"))
+ };
+
+ Ok((friends, followers, following))
}
}