Skip to content
66 changes: 66 additions & 0 deletions src/resources/projectapi.js
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,41 @@ class ProjectApi {
});
}

getFollowers(target, page) {
return new Promise((resolve, reject) => {
const url = `${OriginApiUrl}/api/v1/users/meta/getfollowers?page=${page}&target=${target}&username=${this.username}&token=${this.token}`;
fetch(url)
.then((res) => {
res.json().then((followers) => {
if (followers.error) {
return reject(followers.error);
}
resolve(followers);
});
})
.catch((err) => {
reject(err);
});
})
}
getFollowing(target, page) {
return new Promise((resolve, reject) => {
const url = `${OriginApiUrl}/api/v1/users/meta/getfollowing?page=${page}&target=${target}&username=${this.username}&token=${this.token}`;
fetch(url)
.then((res) => {
res.json().then((followers) => {
if (followers.error) {
return reject(followers.error);
}
resolve(followers);
});
})
.catch((err) => {
reject(err);
});
})
}

isFollowing(username, target, raw) {
return new Promise((resolve, reject) => {
const url = `${OriginApiUrl}/api/v1/users/isfollowing?username=${username}&target=${target}`;
Expand Down Expand Up @@ -1872,6 +1907,37 @@ class ProjectApi {
})
});
}
updatePrivateFollowing(profileHideFollowing) {
const url = `${OriginApiUrl}/api/v1/users/privateFollowSettings`;

const body = JSON.stringify({
username: this.username,
token: this.token,
profileHideFollowing,
});

return new Promise((resolve, reject) => {
fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body
}).then(res => {
res.json().then(json => {
if (!res.ok) {
reject(json.error);
return;
}
resolve();
}).catch(err => {
reject(err);
})
}).catch(err => {
reject(err);
})
});
}

ipBanUser(username, toggle) {
const url = `${OriginApiUrl}/api/v1/users/banuserip`;
Expand Down
41 changes: 33 additions & 8 deletions src/routes/profile/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,15 @@
let wasNotFound = false;
let isForceView = false;
let followerCount = null;
let followingCount = null;
let fullProfile = {};
let isRankingUpMenu = false;
let isAttemptingRankUp = false;
let profileFeaturedProject = null;

let isProfilePrivate = false;
let isProfilePublicToFollowers = false;
let isProfileFollowingVisible = false;
let isFollowedByUser = false;

const profileEditingData = {
Expand Down Expand Up @@ -182,9 +184,11 @@
badges = fullProfile.badges;
isDonator = fullProfile.donator;
followerCount = fullProfile.followers;
followingCount = fullProfile.following;

isProfilePrivate = fullProfile.privateProfile;
isProfilePublicToFollowers = fullProfile.canFollowingSeeProfile;
isProfileFollowingVisible = fullProfile.canSeeFollowing;

isFollowedByUser = fullProfile.isFollowing;

Expand Down Expand Up @@ -934,12 +938,24 @@
</div>
{#if (!isBlocked || showAnyways) && !isProfilePrivate || String(user).toLowerCase() === String(loggedInUser).toLowerCase() || (isProfilePublicToFollowers && isFollowedByUser) || loggedInAdmin}
<div class="follower-section">
<p class="follower-count">
{TranslationHandler.text(
"profile.followers",
currentLang
).replace("$1", followerCount - Number(followOnLoad) + Number(isFollowingUser))}
</p>
<div class="follower-counts">
<p class="follower-count"><a href={`/userlist?type=followers&target=${encodeURIComponent(user)}`}>
{TranslationHandler.textSafe(
"profile.followers",
currentLang,
"followers"
).replace("$1", followerCount - Number(followOnLoad) + Number(isFollowingUser))}
</a></p>
{#if isProfileFollowingVisible || (!isProfileFollowingVisible && ((String(user).toLowerCase() === String(loggedInUser).toLowerCase()) || loggedInAdmin))}
<p class="following-count"><a href={`/userlist?type=following&target=${encodeURIComponent(user)}`}>
{TranslationHandler.textSafe(
"profile.following",
currentLang,
"following"
).replace("$1", followingCount)}
</a></p>
{/if}
</div>
<div>
{#if !(loggedIn && String(user).toLowerCase() === String(loggedInUser).toLowerCase())}
{#key isFollowingUser}
Expand Down Expand Up @@ -2158,12 +2174,21 @@
flex-direction: row;
align-items: center;
}
.follower-count {
.follower-count,
.following-count {
font-size: medium;
text-align: center;
text-align: right;
font-weight: bold;
margin: 0 6px;
}
.follower-count a,
.following-count a {
color: black;
}
:global(body.dark-mode) .follower-count a,
:global(body.dark-mode) .following-count a {
color: white;
}
.follower-button {
min-width: 100px;
height: 35px;
Expand Down
20 changes: 20 additions & 0 deletions src/routes/settings/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
private: false,
privateToNonFollowers: false,
showCubesOnProfile: false,
profileHideFollowing: false,
},
};

Expand Down Expand Up @@ -185,6 +186,10 @@

ProjectClient.updatePrivateProfile(privateProfile, privateToNonFollowers);
}
function updatePrivateFollowing() {
const hideFollowing = accountInformation.settings.profileHideFollowing || false;
ProjectClient.updatePrivateFollowing(hideFollowing);
}

function setPFP() {
// open file menu
Expand Down Expand Up @@ -669,6 +674,21 @@
/>
</i>
</p>
<br>
<!-- TODO: Translations. -->
<p>
<label>
<input
type="checkbox"
bind:checked={accountInformation.settings.profileHideFollowing}
on:change={updatePrivateFollowing}
>
Hide who I am following to others
</label>
</p>
<p class="small">
<i>(Moderators can always see who you are following, ignoring these settings.)</i>
</p>
<!-- <br>
<p>
<label>
Expand Down
Loading