summaryrefslogtreecommitdiff
path: root/src/api/serializers/post.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/serializers/post.ts')
-rw-r--r--src/api/serializers/post.ts166
1 files changed, 119 insertions, 47 deletions
diff --git a/src/api/serializers/post.ts b/src/api/serializers/post.ts
index 3c96884dd1..03fd120772 100644
--- a/src/api/serializers/post.ts
+++ b/src/api/serializers/post.ts
@@ -3,33 +3,45 @@
*/
import * as mongo from 'mongodb';
import deepcopy = require('deepcopy');
-import Post from '../models/post';
+import { default as Post, IPost } from '../models/post';
import Reaction from '../models/post-reaction';
+import { IUser } from '../models/user';
import Vote from '../models/poll-vote';
import serializeApp from './app';
+import serializeChannel from './channel';
import serializeUser from './user';
import serializeDriveFile from './drive-file';
import parse from '../common/text';
+import rap from '@prezzemolo/rap';
/**
* Serialize a post
*
- * @param {any} post
- * @param {any} me?
- * @param {any} options?
- * @return {Promise<any>}
+ * @param post target
+ * @param me? serializee
+ * @param options? serialize options
+ * @return response
*/
-const self = (
- post: any,
- me?: any,
+const self = async (
+ post: string | mongo.ObjectID | IPost,
+ me?: string | mongo.ObjectID | IUser,
options?: {
detail: boolean
}
-) => new Promise<any>(async (resolve, reject) => {
+) => {
const opts = options || {
detail: true,
};
+ // Me
+ const meId: mongo.ObjectID = me
+ ? mongo.ObjectID.prototype.isPrototypeOf(me)
+ ? me as mongo.ObjectID
+ : typeof me === 'string'
+ ? new mongo.ObjectID(me)
+ : (me as IUser)._id
+ : null;
+
let _post: any;
// Populate the post if 'post' is ID
@@ -45,6 +57,8 @@ const self = (
_post = deepcopy(post);
}
+ if (!_post) throw 'invalid post arg.';
+
const id = _post._id;
// Rename _id to id
@@ -59,62 +73,120 @@ const self = (
}
// Populate user
- _post.user = await serializeUser(_post.user_id, me);
+ _post.user = serializeUser(_post.user_id, meId);
// Populate app
if (_post.app_id) {
- _post.app = await serializeApp(_post.app_id);
+ _post.app = serializeApp(_post.app_id);
}
- if (_post.media_ids) {
- // Populate media
- _post.media = await Promise.all(_post.media_ids.map(async fileId =>
- await serializeDriveFile(fileId)
- ));
+ // Populate channel
+ if (_post.channel_id) {
+ _post.channel = serializeChannel(_post.channel_id);
}
- if (_post.reply_to_id && opts.detail) {
- // Populate reply to post
- _post.reply_to = await self(_post.reply_to_id, me, {
- detail: false
- });
+ // Populate media
+ if (_post.media_ids) {
+ _post.media = Promise.all(_post.media_ids.map(fileId =>
+ serializeDriveFile(fileId)
+ ));
}
- if (_post.repost_id && opts.detail) {
- // Populate repost
- _post.repost = await self(_post.repost_id, me, {
- detail: _post.text == null
- });
- }
+ // When requested a detailed post data
+ if (opts.detail) {
+ // Get previous post info
+ _post.prev = (async () => {
+ const prev = await Post.findOne({
+ user_id: _post.user_id,
+ _id: {
+ $lt: id
+ }
+ }, {
+ fields: {
+ _id: true
+ },
+ sort: {
+ _id: -1
+ }
+ });
+ return prev ? prev._id : null;
+ })();
- // Poll
- if (me && _post.poll && opts.detail) {
- const vote = await Vote
- .findOne({
- user_id: me._id,
- post_id: id
+ // Get next post info
+ _post.next = (async () => {
+ const next = await Post.findOne({
+ user_id: _post.user_id,
+ _id: {
+ $gt: id
+ }
+ }, {
+ fields: {
+ _id: true
+ },
+ sort: {
+ _id: 1
+ }
});
+ return next ? next._id : null;
+ })();
- if (vote != null) {
- _post.poll.choices.filter(c => c.id == vote.choice)[0].is_voted = true;
+ if (_post.reply_id) {
+ // Populate reply to post
+ _post.reply = self(_post.reply_id, meId, {
+ detail: false
+ });
}
- }
- // Fetch my reaction
- if (me && opts.detail) {
- const reaction = await Reaction
- .findOne({
- user_id: me._id,
- post_id: id,
- deleted_at: { $exists: false }
+ if (_post.repost_id) {
+ // Populate repost
+ _post.repost = self(_post.repost_id, meId, {
+ detail: _post.text == null
});
+ }
+
+ // Poll
+ if (meId && _post.poll) {
+ _post.poll = (async (poll) => {
+ const vote = await Vote
+ .findOne({
+ user_id: meId,
+ post_id: id
+ });
+
+ if (vote != null) {
+ const myChoice = poll.choices
+ .filter(c => c.id == vote.choice)[0];
+
+ myChoice.is_voted = true;
+ }
- if (reaction) {
- _post.my_reaction = reaction.reaction;
+ return poll;
+ })(_post.poll);
+ }
+
+ // Fetch my reaction
+ if (meId) {
+ _post.my_reaction = (async () => {
+ const reaction = await Reaction
+ .findOne({
+ user_id: meId,
+ post_id: id,
+ deleted_at: { $exists: false }
+ });
+
+ if (reaction) {
+ return reaction.reaction;
+ }
+
+ return null;
+ })();
}
}
- resolve(_post);
-});
+ // resolve promises in _post object
+ _post = await rap(_post);
+
+ return _post;
+};
export default self;