Skip to content

Commit

Permalink
Merge pull request #13 from AveselsJS/Following-and-followers
Browse files Browse the repository at this point in the history
Following and followers
  • Loading branch information
pestsov-v authored Oct 24, 2021
2 parents c51ffac + 41b063e commit 5c275de
Show file tree
Hide file tree
Showing 10 changed files with 230 additions and 6 deletions.
6 changes: 5 additions & 1 deletion app.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const logoutRoute = require('./routes/logoutRoutes')
const postsApiRoute = require('./routes/api/posts')
const postRoute = require('./routes/postRoutes')
const profileRoute = require('./routes/profileRoutes')
const userRoute = require('./routes/api/users')
const mongoose = require('./database')
const config = require('./config')

Expand All @@ -33,9 +34,12 @@ app.use(session({
app.use("/login", loginRoute);
app.use("/logout", logoutRoute);
app.use("/register", registerRoute);
app.use("/api/posts", postsApiRoute);
app.use("/posts", middleware.requireLogin, postRoute);
app.use("/profile", profileRoute);
app.use("/api/posts", postsApiRoute);
app.use("/api/users", userRoute);



app.get("/", middleware.requireLogin, (req, res, next) => {

Expand Down
23 changes: 23 additions & 0 deletions public/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ nav a:hover {
border-radius: 50%;
}

.wrapper > .row {
margin: 0;
}

button {
background-color: transparent;
border: none;
Expand Down Expand Up @@ -355,3 +359,22 @@ button span {
background-color: var(--blueBackhround);
}

.noResults {
padding: var(--spacing);
}

.resultsContainer {
display: flex;
flex-direction: column;
}

.resultsContainer .user {
padding: var(--spacing);
display: flex;
border-bottom: 1px solid var(--lightGrey);
}

.user .userDetailsContainer {
flex: 1;
padding: 0 var(--spacing)
}
37 changes: 36 additions & 1 deletion public/js/common.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

$("#postTextarea, #replyTextarea").keyup(event => {
const textbox = $(event.target)
const value = textbox.val().trim()
Expand Down Expand Up @@ -136,6 +135,42 @@ $(document).on("click", ".post", (event) => {
}
})

$(document).on("click", ".followButton", (event) => {
const button = $(event.target);
const userId = button.data().user

$.ajax({
url: `/api/users/${userId}/follow`,
type: "PUT",
success: (data, status, xhr) => {

if (xhr.status == 404) {
alert("Пользователь не был найден")
return;
}

let difference = 1;
if (data.following && data.following.includes(userId)) {
button.addClass("following");
button.text("Подписан");
} else {
button.removeClass("following");
button.text("Подписаться");
difference = -1;
}

const followersLabel = $("#followersValue");

if (followersLabel.length != 0) {
let followersText = followersLabel.text();
followersText = parseInt(followersText);
followersLabel.text(followersText + difference);
}
}
})
})


function getPostIdFromElement(element) {
const isRoot = element.hasClass("post");
const rootElement = isRoot == true ? element : element.closest(".post");
Expand Down
51 changes: 51 additions & 0 deletions public/js/followersAndFollowing.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
$(document).ready(() => {

if(selectedTab === "followers") {
loadFollowers();
}
else {
loadFollowing();
}
});

function loadFollowers() {
$.get(`/api/users/${profileUserId}/followers`, results => {
outputUsers(results.followers, $(".resultsContainer"));
})
}

function loadFollowing() {
$.get(`/api/users/${profileUserId}/following`, results => {
outputUsers(results.following, $(".resultsContainer"));
})
}

function outputUsers(results, container) {
container.html("");

results.forEach(result => {
const html = createUserHtml(result, true);
container.append(html);
});

if(results.length == 0) {
container.append("<span class='noResults'>Ещё нет ниодной записи</span>")
}
}

function createUserHtml(userData, showFollowButton) {

const name = userData.firstName + " " + userData.lastName;

return `<div class='user'>
<div class='userImageContainer'>
<img src='${userData.profilePic}'>
</div>
<div class='userDetailsContainer'>
<div class='header'>
<a href='/profile/${userData.username}'>${name}</a>
<span class='username'>@${userData.username}</span>
</div>
</div>
</div>`;
}
1 change: 0 additions & 1 deletion routes/api/posts.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ router.get("/", async (req, res, next) => {
const isReply = searchObj.isReply == "true";
searchObj.replyTo = { $exists: isReply };
delete searchObj.isReply;
console.log(searchObj)
}

const results = await getPosts(searchObj);
Expand Down
59 changes: 59 additions & 0 deletions routes/api/users.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
const express = require('express');
const bodyParser = require('body-parser');
const User = require('../../schemas/UserSchema')
const Post = require('../../schemas/PostSchema');
const app = express();
const router = express.Router();

router.put("/:userId/follow", async (req, res, next) => {

let userId = req.params.userId;
let user = await User.findById(userId);

if (user == null) return res.sendStatus(404);

const isFollowing = user.followers && user.followers.includes(req.session.user._id);

const option = isFollowing ? "$pull" : "$addToSet";

req.session.user = await User.findByIdAndUpdate(req.session.user._id, { [option]: { following: userId }}, {new: true})
.catch(err => {
console.log(err);
res.status(400);
})

User.findByIdAndUpdate(userId, { [option]: { followers: req.session.user._id }})
.catch(err => {
console.log(err);
res.status(400);
})

res.status(200).send(req.session.user)
})

router.get("/:userId/following", async (req, res, next) => {
User.findById(req.params.userId)
.populate("following")
.then(results => {
res.status(200).send(results)
})
.catch(error => {
console.log(error);
res.sendStatus(400);
})
})

router.get("/:userId/followers", async (req, res, next) => {
User.findById(req.params.userId)
.populate("followers")
.then(results => {
res.status(200).send(results)
})
.catch(error => {
console.log(error);
res.sendStatus(400);
})
})


module.exports = router;
18 changes: 18 additions & 0 deletions routes/profileRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,24 @@ router.get("/:username/replies", async (req, res, next) => {
res.status(200).render("profilePage.pug", payload);
})

router.get("/:username/following", async (req, res, next) => {

const payload = await getPayload(req.params.username, req.session.user);

payload.selectedTab = "following"

res.status(200).render("followersAndFollowing.pug", payload);
})

router.get("/:username/followers", async (req, res, next) => {

const payload = await getPayload(req.params.username, req.session.user);

payload.selectedTab = "followers"

res.status(200).render("followersAndFollowing.pug", payload);
})


async function getPayload(username, userLoggedIn) {
let user = await User.findOne({username: username})
Expand Down
8 changes: 8 additions & 0 deletions schemas/UserSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ const UserSchema = new Schema({
retweets: [{
type: Schema.Types.ObjectId,
ref: 'Post'
}],
following: [{
type: Schema.Types.ObjectId,
ref: 'User'
}],
followers: [{
type: Schema.Types.ObjectId,
ref: 'User'
}]
}, {timestamps: true})

Expand Down
18 changes: 18 additions & 0 deletions views/followersAndFollowing.pug
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
extends layouts/main-layout.pug

block content
if !profileUser
span.errorMessage Такого пользователя не существует или он не был найден. Пожалуйста укажите верный никнейм пользователя.
else
script.
const profileUserId = '!{profileUser._id}'
const selectedTab = '!{selectedTab}'

.tabsContainer
+createTab("Подписки", `/profile/${profileUser.username}/following`, selectedTab == 'following')
+createTab("Подписчики", `/profile/${profileUser.username}/followers`, selectedTab == 'followers')

.resultsContainer

block scripts
script(src="/js/followersAndFollowing.js")
15 changes: 12 additions & 3 deletions views/profilePage.pug
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ block content
const profileUserId = '!{profileUser._id}'
const selectedTab = '!{selectedTab}'

- followersCount = profileUser.followers.length
- followingCount = profileUser.following.length

.profileHeaderContainer
.coverPhotoContainer

Expand All @@ -17,18 +20,24 @@ block content
if profileUser._id != userLoggedIn._id
a.profileButton(href=`/messages/${profileUser._id}`)
i.fas.fa-envelope
+createFollowButton(profileUser, false)

- const profileUserId = profileUser._id.toString();
- if (userLoggedIn.following && userLoggedIn.following.includes(profileUserId))
+createFollowButton(profileUser, true)
- else
+createFollowButton(profileUser, false)

.userDetailsContainer
span.displayName #{profileUser.firstName} #{profileUser.lastName}
span.username @#{profileUser.username}
span.description #{profileUser.description}

.followersContainer
a(href=`/profile/${profileUser.username}/following`)
span.value #{0}
span.value #{followingCount}
span Подписок
a(href=`/profile/${profileUser.username}/followers`)
span.value #{0}
span#followersValue.value #{followersCount}
span Подписчиков

.tabsContainer
Expand Down

0 comments on commit 5c275de

Please sign in to comment.