improve & fix updates and data fill

This commit is contained in:
srgooglo 2022-10-06 21:46:38 +02:00
parent 3ab50d93cf
commit c573041c25
7 changed files with 124 additions and 133 deletions

View File

@ -1,7 +1,7 @@
import { Controller } from "linebridge/dist/server" import { Controller } from "linebridge/dist/server"
import { Schematized } from "../../lib" 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 { export default class PostsController extends Controller {
static refName = "PostsController" static refName = "PostsController"
@ -13,9 +13,9 @@ export default class PostsController extends Controller {
fn: Schematized({ fn: Schematized({
select: ["user_id"] select: ["user_id"]
}, async (req, res) => { }, async (req, res) => {
let posts = await GetPostsFeed({ let posts = await GetPostData({
feedLimit: req.query?.limit, limit: req.query?.limit,
feedTrimIndex: req.query?.trim, skip: req.query?.trim,
from_user_id: req.query?.user_id, from_user_id: req.query?.user_id,
for_user_id: req.user?._id.toString(), for_user_id: req.user?._id.toString(),
savedOnly: req.query?.savedOnly, savedOnly: req.query?.savedOnly,
@ -25,12 +25,14 @@ export default class PostsController extends Controller {
}) })
}, },
"/post": { "/post": {
middlewares: ["withOptionalAuthentication"],
fn: Schematized({ fn: Schematized({
select: ["post_id"], select: ["post_id"],
required: ["post_id"] required: ["post_id"]
}, async (req, res) => { }, async (req, res) => {
let post = await GetPostData({ let post = await GetPostData({
post_id: req.query?.post_id, post_id: req.query?.post_id,
for_user_id: req.user?._id.toString(),
}).catch((error) => { }).catch((error) => {
res.status(404).json({ error: error.message }) res.status(404).json({ error: error.message })

View File

@ -1,10 +1,9 @@
import { Post, User } from "../../../models" import { Post } from "../../../models"
import getPostData from "./getPostData"
export default async (payload) => { export default async (payload) => {
const { user_id, message, additions, type, data } = payload const { user_id, message, additions, type, data } = payload
const userData = await User.findById(user_id)
const post = new Post({ const post = new Post({
user_id: typeof user_id === "object" ? user_id.toString() : user_id, user_id: typeof user_id === "object" ? user_id.toString() : user_id,
message: String(message).toString(), message: String(message).toString(),
@ -16,14 +15,10 @@ export default async (payload) => {
await post.save() await post.save()
global.wsInterface.io.emit(`post.new`, { const resultPost = await getPostData({ post_id: post._id.toString() })
...post.toObject(),
user: userData.toObject(), global.wsInterface.io.emit(`post.new`, resultPost)
}) global.wsInterface.io.emit(`post.new.${post.user_id}`, resultPost)
global.wsInterface.io.emit(`post.new.${post.user_id}`, {
...post.toObject(),
user: userData.toObject(),
})
return post return post
} }

View File

@ -1,30 +1,102 @@
import { Post, User } from "../../../models" import { Post, User, Comment, SavedPost } from "../../../models"
export default async (payload) => { export default async (payload) => {
let { let {
from_user_id,
for_user_id,
post_id, post_id,
query = {},
skip = 0,
limit = 20,
sort = { created_at: -1 },
savedOnly = false,
} = payload } = payload
if (!post_id) { let posts = []
throw new Error("post_id not provided") 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 from_user_id is provided, get posts from that user
if (from_user_id) {
if (!post) { query.user_id = from_user_id
throw new Error("Post not found")
} }
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) { if (post_id) {
user = { const post = await Post.findById(post_id).catch(() => false)
username: "Deleted user",
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 { return posts
...post.toObject(),
user,
}
} }

View File

@ -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
}

View File

@ -2,7 +2,6 @@ export { default as CreatePost } from "./createPost"
export { default as ToogleLike } from "./toogleLike" export { default as ToogleLike } from "./toogleLike"
export { default as ToogleSavePost } from "./tooglePostSave" export { default as ToogleSavePost } from "./tooglePostSave"
export { default as GetPostsFeed } from "./getPostsFeed"
export { default as GetPostData } from "./getPostData" export { default as GetPostData } from "./getPostData"
export { default as DeletePost } from "./deletePost" export { default as DeletePost } from "./deletePost"

View File

@ -1,23 +1,31 @@
import { Post } from "../../../models" import { Post } from "../../../models"
import lodash from "lodash" import getPostData from "./getPostData"
export default async (post, modification) => { export default async (post_id, modification) => {
if (typeof post === "string") { if (!post_id) {
post = await Post.findById(post).catch(() => false) throw new Error("Cannot modify post data: post not found")
} }
let post = await getPostData({ post_id: post_id })
if (!post) { if (!post) {
throw new Error("Cannot modify post data: post not found") throw new Error("Cannot modify post data: post not found")
} }
if (typeof modification === "object") { 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)
global.wsInterface.io.emit(`post.dataUpdate.${post_id._id}`, post)
global.wsInterface.io.emit(`post.dataUpdate`, post.toObject())
global.wsInterface.io.emit(`post.dataUpdate.${post._id}`, post.toObject())
return post return post
} }

View File

@ -1,20 +1,16 @@
import { Post, User } from "../../../models" import { Post } from "../../../models"
import modifyPostData from "./modifyPostData" import modifyPostData from "./modifyPostData"
export default async (payload) => { export default async (payload) => {
let { post_id, user_id, to } = payload let { post_id, user_id, to } = payload
const post = await Post.findById(post_id).catch(() => false) let post = await Post.findById(post_id).catch(() => false)
const userData = await User.findById(user_id).catch(() => false)
if (!post) { if (!post) {
throw new Error("Post not found") throw new Error("Post not found")
} }
if (!userData) {
throw new Error("User not found")
}
if (typeof to === "undefined") { if (typeof to === "undefined") {
to = !post.likes.includes(user_id) to = !post.likes.includes(user_id)
} }
@ -25,17 +21,11 @@ export default async (payload) => {
post.likes = post.likes.filter((id) => id !== user_id) 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"}`, { global.wsInterface.io.emit(`post.${to ? "like" : "unlike"}`, post)
...post.toObject(), global.wsInterface.io.emit(`post.${to ? "like" : "unlike"}.${post.user_id}`, post)
user: userData.toObject(), global.wsInterface.io.emit(`post.${to ? "like" : "unlike"}.${post_id}`, post)
})
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)
return post.toObject() return post
} }