From c573041c252d30dd7e261dabded5e16a624f3f83 Mon Sep 17 00:00:00 2001 From: srgooglo Date: Thu, 6 Oct 2022 21:46:38 +0200 Subject: [PATCH] improve & fix updates and data fill --- .../src/controllers/PostsController/index.js | 10 +- .../PostsController/methods/createPost.js | 17 ++- .../PostsController/methods/getPostData.js | 102 +++++++++++++++--- .../PostsController/methods/getPostsFeed.js | 75 ------------- .../PostsController/methods/index.js | 1 - .../PostsController/methods/modifyPostData.js | 26 +++-- .../PostsController/methods/toogleLike.js | 26 ++--- 7 files changed, 124 insertions(+), 133 deletions(-) delete mode 100644 packages/server/src/controllers/PostsController/methods/getPostsFeed.js diff --git a/packages/server/src/controllers/PostsController/index.js b/packages/server/src/controllers/PostsController/index.js index 7606d9db..3f66ba54 100644 --- a/packages/server/src/controllers/PostsController/index.js +++ b/packages/server/src/controllers/PostsController/index.js @@ -1,7 +1,7 @@ import { Controller } from "linebridge/dist/server" import { Schematized } from "../../lib" -import { CreatePost, ToogleLike, GetPostsFeed, GetPostData, DeletePost, ToogleSavePost } from "./methods" +import { CreatePost, ToogleLike, GetPostData, DeletePost, ToogleSavePost } from "./methods" export default class PostsController extends Controller { static refName = "PostsController" @@ -13,9 +13,9 @@ export default class PostsController extends Controller { fn: Schematized({ select: ["user_id"] }, async (req, res) => { - let posts = await GetPostsFeed({ - feedLimit: req.query?.limit, - feedTrimIndex: req.query?.trim, + let posts = await GetPostData({ + limit: req.query?.limit, + skip: req.query?.trim, from_user_id: req.query?.user_id, for_user_id: req.user?._id.toString(), savedOnly: req.query?.savedOnly, @@ -25,12 +25,14 @@ export default class PostsController extends Controller { }) }, "/post": { + middlewares: ["withOptionalAuthentication"], fn: Schematized({ select: ["post_id"], required: ["post_id"] }, async (req, res) => { let post = await GetPostData({ post_id: req.query?.post_id, + for_user_id: req.user?._id.toString(), }).catch((error) => { res.status(404).json({ error: error.message }) diff --git a/packages/server/src/controllers/PostsController/methods/createPost.js b/packages/server/src/controllers/PostsController/methods/createPost.js index 24661e4b..4cc87570 100644 --- a/packages/server/src/controllers/PostsController/methods/createPost.js +++ b/packages/server/src/controllers/PostsController/methods/createPost.js @@ -1,10 +1,9 @@ -import { Post, User } from "../../../models" +import { Post } from "../../../models" +import getPostData from "./getPostData" export default async (payload) => { const { user_id, message, additions, type, data } = payload - const userData = await User.findById(user_id) - const post = new Post({ user_id: typeof user_id === "object" ? user_id.toString() : user_id, message: String(message).toString(), @@ -16,14 +15,10 @@ export default async (payload) => { await post.save() - global.wsInterface.io.emit(`post.new`, { - ...post.toObject(), - user: userData.toObject(), - }) - global.wsInterface.io.emit(`post.new.${post.user_id}`, { - ...post.toObject(), - user: userData.toObject(), - }) + const resultPost = await getPostData({ post_id: post._id.toString() }) + + global.wsInterface.io.emit(`post.new`, resultPost) + global.wsInterface.io.emit(`post.new.${post.user_id}`, resultPost) return post } \ No newline at end of file diff --git a/packages/server/src/controllers/PostsController/methods/getPostData.js b/packages/server/src/controllers/PostsController/methods/getPostData.js index e92a7ef2..cd9608c5 100644 --- a/packages/server/src/controllers/PostsController/methods/getPostData.js +++ b/packages/server/src/controllers/PostsController/methods/getPostData.js @@ -1,30 +1,102 @@ -import { Post, User } from "../../../models" +import { Post, User, Comment, SavedPost } from "../../../models" export default async (payload) => { let { + from_user_id, + for_user_id, post_id, + query = {}, + skip = 0, + limit = 20, + sort = { created_at: -1 }, + savedOnly = false, } = payload - if (!post_id) { - throw new Error("post_id not provided") + let posts = [] + let savedPostsIds = [] + + // if for_user_id is provided, get saved posts + if (for_user_id) { + const savedPosts = await SavedPost.find({ user_id: for_user_id }) + .sort({ saved_at: -1 }) + + savedPostsIds = savedPosts.map((savedPost) => savedPost.post_id) } - let post = await Post.findById(post_id).catch(() => false) - - if (!post) { - throw new Error("Post not found") + // if from_user_id is provided, get posts from that user + if (from_user_id) { + query.user_id = from_user_id } - let user = await User.findById(post.user_id).catch(() => false) + // if savedOnly is true,set to query to get only saved posts + if (savedOnly) { + query._id = { $in: savedPostsIds } + } - if (!user) { - user = { - username: "Deleted user", + if (post_id) { + const post = await Post.findById(post_id).catch(() => false) + + posts = [post] + } else { + posts = await Post.find({ ...query }) + .sort(sort) + .skip(skip) + .limit(limit) + } + + // short posts if is savedOnly argument + if (savedOnly) { + posts.sort((a, b) => { + return ( + savedPostsIds.indexOf(a._id.toString()) - + savedPostsIds.indexOf(b._id.toString()) + ) + }) + } + + // fullfill data + posts = posts.map(async (post, index) => { + post = post.toObject() + + post.key = Number(skip) + Number(index) + + let user = await User.findById(post.user_id).catch(() => false) + + if (!user) { + user = { + username: "Deleted user", + } } + + let comments = await Comment.find({ parent_id: post._id.toString() }) + .select("_id") + .catch(() => false) + + if (!comments) { + comments = [] + } + + post.comments = comments + + if (for_user_id) { + post.isLiked = post.likes.includes(for_user_id) + post.isSaved = savedPostsIds.includes(post._id.toString()) + } + + return { + key: Number(skip) + Number(index), + ...post, + comments: comments.map((comment) => comment._id.toString()), + user, + } + }) + + posts = await Promise.all(posts) + + // if post_id is specified, return only one post + if (post_id) { + return posts[0] } - return { - ...post.toObject(), - user, - } + return posts } \ No newline at end of file diff --git a/packages/server/src/controllers/PostsController/methods/getPostsFeed.js b/packages/server/src/controllers/PostsController/methods/getPostsFeed.js deleted file mode 100644 index 6f145d1f..00000000 --- a/packages/server/src/controllers/PostsController/methods/getPostsFeed.js +++ /dev/null @@ -1,75 +0,0 @@ -import { Post, User, SavedPost } from "../../../models" - -export default async (payload) => { - let { - from_user_id, - for_user_id, - feedTrimIndex = 0, - feedLimit = 20, - savedOnly = false, - } = payload - - let query = {} - let savedPostsIds = [] - - if (from_user_id) { - query.user_id = from_user_id - } - - // short posts in order of `saved_at`. - const savedPosts = await SavedPost.find({ user_id: for_user_id }) - .sort({ saved_at: -1 }) - - savedPostsIds = savedPosts.map((savedPost) => savedPost.post_id) - - if (savedOnly) { - query._id = { $in: savedPostsIds } - } - - let posts = [] - - if (savedOnly) { - posts = await Post.find({ - _id: { $in: savedPostsIds }, - }) - .skip(feedTrimIndex) - .limit(feedLimit) - - posts.sort((a, b) => { - return ( - savedPostsIds.indexOf(a._id.toString()) - - savedPostsIds.indexOf(b._id.toString()) - ) - }) - } else { - // make sure that sort by date descending - // trim index is used to get the last n posts - posts = await Post.find(query) - .sort({ created_at: -1 }) - .skip(feedTrimIndex) - .limit(feedLimit) - } - - // fetch and add user data to each post - posts = posts.map(async (post, index) => { - const user = await User.findById(post.user_id) - - if (feedTrimIndex > 0) { - index = Number(feedTrimIndex) + Number(index) - } - - // check if post is saved by the user - const isSaved = savedPostsIds.includes(post._id.toString()) - - return { - ...post.toObject(), - user: user.toObject(), - key: index, - isSaved, - } - }) - - posts = await Promise.all(posts) - - return posts -} \ No newline at end of file diff --git a/packages/server/src/controllers/PostsController/methods/index.js b/packages/server/src/controllers/PostsController/methods/index.js index c8c68a94..c66fa2af 100644 --- a/packages/server/src/controllers/PostsController/methods/index.js +++ b/packages/server/src/controllers/PostsController/methods/index.js @@ -2,7 +2,6 @@ export { default as CreatePost } from "./createPost" export { default as ToogleLike } from "./toogleLike" export { default as ToogleSavePost } from "./tooglePostSave" -export { default as GetPostsFeed } from "./getPostsFeed" export { default as GetPostData } from "./getPostData" export { default as DeletePost } from "./deletePost" diff --git a/packages/server/src/controllers/PostsController/methods/modifyPostData.js b/packages/server/src/controllers/PostsController/methods/modifyPostData.js index d6b94c89..fe69fe93 100644 --- a/packages/server/src/controllers/PostsController/methods/modifyPostData.js +++ b/packages/server/src/controllers/PostsController/methods/modifyPostData.js @@ -1,23 +1,31 @@ import { Post } from "../../../models" -import lodash from "lodash" +import getPostData from "./getPostData" -export default async (post, modification) => { - if (typeof post === "string") { - post = await Post.findById(post).catch(() => false) +export default async (post_id, modification) => { + if (!post_id) { + throw new Error("Cannot modify post data: post not found") } + let post = await getPostData({ post_id: post_id }) + if (!post) { throw new Error("Cannot modify post data: post not found") } if (typeof modification === "object") { - post = lodash.merge(post, modification) + const result = await Post.findByIdAndUpdate(post_id, modification) + + await result.save() + + post = { + ...post, + ...result.toObject(), + ...modification, + } } - await post.save() - - global.wsInterface.io.emit(`post.dataUpdate`, post.toObject()) - global.wsInterface.io.emit(`post.dataUpdate.${post._id}`, post.toObject()) + global.wsInterface.io.emit(`post.dataUpdate`, post) + global.wsInterface.io.emit(`post.dataUpdate.${post_id._id}`, post) return post } \ No newline at end of file diff --git a/packages/server/src/controllers/PostsController/methods/toogleLike.js b/packages/server/src/controllers/PostsController/methods/toogleLike.js index ab2869a7..0515165f 100644 --- a/packages/server/src/controllers/PostsController/methods/toogleLike.js +++ b/packages/server/src/controllers/PostsController/methods/toogleLike.js @@ -1,20 +1,16 @@ -import { Post, User } from "../../../models" +import { Post } from "../../../models" + import modifyPostData from "./modifyPostData" export default async (payload) => { let { post_id, user_id, to } = payload - const post = await Post.findById(post_id).catch(() => false) - const userData = await User.findById(user_id).catch(() => false) + let post = await Post.findById(post_id).catch(() => false) if (!post) { throw new Error("Post not found") } - if (!userData) { - throw new Error("User not found") - } - if (typeof to === "undefined") { to = !post.likes.includes(user_id) } @@ -25,17 +21,11 @@ export default async (payload) => { post.likes = post.likes.filter((id) => id !== user_id) } - await modifyPostData(post, { likes: post.likes }) + post = await modifyPostData(post._id, { likes: post.likes }) - global.wsInterface.io.emit(`post.${to ? "like" : "unlike"}`, { - ...post.toObject(), - user: userData.toObject(), - }) - global.wsInterface.io.emit(`post.${to ? "like" : "unlike"}.${post.user_id}`, { - ...post.toObject(), - user: userData.toObject(), - }) - global.wsInterface.io.emit(`post.${to ? "like" : "unlike"}.${post_id}`, post.toObject().likes) + global.wsInterface.io.emit(`post.${to ? "like" : "unlike"}`, post) + global.wsInterface.io.emit(`post.${to ? "like" : "unlike"}.${post.user_id}`, post) + global.wsInterface.io.emit(`post.${to ? "like" : "unlike"}.${post_id}`, post) - return post.toObject() + return post } \ No newline at end of file