فهرست منبع

Independent of Crowi for Activity model

kaori 4 سال پیش
والد
کامیت
1314ca8d12
2فایلهای تغییر یافته به همراه165 افزوده شده و 160 حذف شده
  1. 162 158
      packages/app/src/server/models/activity.ts
  2. 3 2
      packages/app/src/server/models/in-app-notification.ts

+ 162 - 158
packages/app/src/server/models/activity.ts

@@ -1,11 +1,18 @@
 import { DeleteWriteOpResultObject } from 'mongodb';
 import { DeleteWriteOpResultObject } from 'mongodb';
 import {
 import {
-  Types, Document, Model, Schema, model,
+  Types, Document, Model, Schema,
 } from 'mongoose';
 } from 'mongoose';
-import loggerFactory from '~/utils/logger';
+
+import { getOrCreateModel } from '../util/mongoose-utils';
+import loggerFactory from '../../utils/logger';
 
 
 import ActivityDefine from '../util/activityDefine';
 import ActivityDefine from '../util/activityDefine';
-import Crowi from '../crowi';
+
+// import activityEvent from '../events/activity';
+import InAppNotification from './in-app-notification';
+import Watcher from './watcher';
+// import User from './user';
+import User = require('./user');
 
 
 const logger = loggerFactory('growi:models:activity');
 const logger = loggerFactory('growi:models:activity');
 
 
@@ -33,196 +40,193 @@ export interface ActivityModel extends Model<ActivityDocument> {
   getActionUsersFromActivities(activities: ActivityDocument[]): any[]
   getActionUsersFromActivities(activities: ActivityDocument[]): any[]
 }
 }
 
 
-export default (crowi: Crowi) => {
-  const activityEvent = crowi.event('Activity');
-
-  // TODO: add revision id
-  const activitySchema = new Schema<ActivityDocument, ActivityModel>({
-    user: {
-      type: Schema.Types.ObjectId,
-      ref: 'User',
-      index: true,
-      require: true,
-    },
-    targetModel: {
-      type: String,
-      require: true,
-      enum: ActivityDefine.getSupportTargetModelNames(),
-    },
-    target: {
-      type: Schema.Types.ObjectId,
-      refPath: 'targetModel',
-      require: true,
-    },
-    action: {
-      type: String,
-      require: true,
-      enum: ActivityDefine.getSupportActionNames(),
-    },
-    event: {
-      type: Schema.Types.ObjectId,
-      refPath: 'eventModel',
-    },
-    eventModel: {
-      type: String,
-      enum: ActivityDefine.getSupportEventModelNames(),
-    },
-    createdAt: {
-      type: Date,
-      default: Date.now,
-    },
-  });
-  activitySchema.index({ target: 1, action: 1 });
-  activitySchema.index({
-    user: 1, target: 1, action: 1, createdAt: 1,
-  }, { unique: true });
-
-  /**
+// const activityEvent = crowi.event('Activity');
+
+// TODO: add revision id
+const activitySchema = new Schema<ActivityDocument, ActivityModel>({
+  user: {
+    type: Schema.Types.ObjectId,
+    ref: 'User',
+    index: true,
+    require: true,
+  },
+  targetModel: {
+    type: String,
+    require: true,
+    enum: ActivityDefine.getSupportTargetModelNames(),
+  },
+  target: {
+    type: Schema.Types.ObjectId,
+    refPath: 'targetModel',
+    require: true,
+  },
+  action: {
+    type: String,
+    require: true,
+    enum: ActivityDefine.getSupportActionNames(),
+  },
+  event: {
+    type: Schema.Types.ObjectId,
+    refPath: 'eventModel',
+  },
+  eventModel: {
+    type: String,
+    enum: ActivityDefine.getSupportEventModelNames(),
+  },
+  createdAt: {
+    type: Date,
+    default: Date.now,
+  },
+});
+activitySchema.index({ target: 1, action: 1 });
+activitySchema.index({
+  user: 1, target: 1, action: 1, createdAt: 1,
+}, { unique: true });
+
+/**
    * @param {object} parameters
    * @param {object} parameters
    * @return {Promise}
    * @return {Promise}
    */
    */
-  activitySchema.statics.createByParameters = function(parameters) {
-    return Activity.create(parameters);
-  };
+activitySchema.statics.createByParameters = function(parameters) {
+  return this.create(parameters);
+};
 
 
-  /**
+/**
    * @param {object} parameters
    * @param {object} parameters
    */
    */
-  activitySchema.statics.removeByParameters = async function(parameters) {
-    const activity = await Activity.findOne(parameters);
-    activityEvent.emit('remove', activity);
+activitySchema.statics.removeByParameters = async function(parameters) {
+  const activity = await this.findOne(parameters);
+  // activityEvent.emit('remove', activity);
 
 
-    return Activity.deleteMany(parameters).exec();
-  };
+  return this.deleteMany(parameters).exec();
+};
 
 
-  /**
+/**
    * @param {Comment} comment
    * @param {Comment} comment
    * @return {Promise}
    * @return {Promise}
    */
    */
-  activitySchema.statics.createByPageComment = function(comment) {
-    const parameters = {
-      user: comment.creator,
-      targetModel: ActivityDefine.MODEL_PAGE,
-      target: comment.page,
-      eventModel: ActivityDefine.MODEL_COMMENT,
-      event: comment._id,
-      action: ActivityDefine.ACTION_COMMENT,
-    };
-
-    return this.createByParameters(parameters);
+activitySchema.statics.createByPageComment = function(comment) {
+  const parameters = {
+    user: comment.creator,
+    targetModel: ActivityDefine.MODEL_PAGE,
+    target: comment.page,
+    eventModel: ActivityDefine.MODEL_COMMENT,
+    event: comment._id,
+    action: ActivityDefine.ACTION_COMMENT,
   };
   };
 
 
-  /**
+  return this.createByParameters(parameters);
+};
+
+/**
    * @param {Page} page
    * @param {Page} page
    * @param {User} user
    * @param {User} user
    * @return {Promise}
    * @return {Promise}
    */
    */
-  activitySchema.statics.createByPageLike = function(page, user) {
-    const parameters = {
-      user: user._id,
-      targetModel: ActivityDefine.MODEL_PAGE,
-      target: page,
-      action: ActivityDefine.ACTION_LIKE,
-    };
-
-    return this.createByParameters(parameters);
+activitySchema.statics.createByPageLike = function(page, user) {
+  const parameters = {
+    user: user._id,
+    targetModel: ActivityDefine.MODEL_PAGE,
+    target: page,
+    action: ActivityDefine.ACTION_LIKE,
   };
   };
 
 
-  /**
+  return this.createByParameters(parameters);
+};
+
+/**
    * @param {Page} page
    * @param {Page} page
    * @param {User} user
    * @param {User} user
    * @return {Promise}
    * @return {Promise}
    */
    */
-  activitySchema.statics.removeByPageUnlike = function(page, user) {
-    const parameters = {
-      user,
-      targetModel: ActivityDefine.MODEL_PAGE,
-      target: page,
-      action: ActivityDefine.ACTION_LIKE,
-    };
-
-    return this.removeByParameters(parameters);
+activitySchema.statics.removeByPageUnlike = function(page, user) {
+  const parameters = {
+    user,
+    targetModel: ActivityDefine.MODEL_PAGE,
+    target: page,
+    action: ActivityDefine.ACTION_LIKE,
   };
   };
 
 
-  /**
+  return this.removeByParameters(parameters);
+};
+
+/**
    * @param {Page} page
    * @param {Page} page
    * @return {Promise}
    * @return {Promise}
    */
    */
-  activitySchema.statics.removeByPage = async function(page) {
-    const activities = await Activity.find({ target: page });
-    for (const activity of activities) {
-      activityEvent.emit('remove', activity);
-    }
-    return Activity.deleteMany({ target: page }).exec();
-  };
+activitySchema.statics.removeByPage = async function(page) {
+  const activities = await this.find({ target: page });
+  for (const activity of activities) {
+    // activityEvent.emit('remove', activity);
+  }
+  return this.deleteMany({ target: page }).exec();
+};
 
 
-  /**
+/**
    * @param {User} user
    * @param {User} user
    * @return {Promise}
    * @return {Promise}
    */
    */
-  activitySchema.statics.findByUser = function(user) {
-    return Activity.find({ user }).sort({ createdAt: -1 }).exec();
-  };
+activitySchema.statics.findByUser = function(user) {
+  return this.find({ user }).sort({ createdAt: -1 }).exec();
+};
 
 
-  activitySchema.statics.getActionUsersFromActivities = function(activities) {
-    return activities.map(({ user }) => user).filter((user, i, self) => self.indexOf(user) === i);
-  };
+activitySchema.statics.getActionUsersFromActivities = function(activities) {
+  return activities.map(({ user }) => user).filter((user, i, self) => self.indexOf(user) === i);
+};
 
 
-  activitySchema.methods.getNotificationTargetUsers = async function() {
-    const User = crowi.model('User');
-    const Watcher = crowi.model('Watcher');
-    const { user: actionUser, targetModel, target } = this;
-
-    const model: any = await this.model(targetModel).findById(target);
-    const [targetUsers, watchUsers, ignoreUsers] = await Promise.all([
-      model.getNotificationTargetUsers(),
-      Watcher.getWatchers((target as any) as Types.ObjectId),
-      Watcher.getIgnorers((target as any) as Types.ObjectId),
-    ]);
-
-    const unique = array => Object.values(array.reduce((objects, object) => ({ ...objects, [object.toString()]: object }), {}));
-    const filter = (array, pull) => {
-      const ids = pull.map(object => object.toString());
-      return array.filter(object => !ids.includes(object.toString()));
-    };
-    const notificationUsers = filter(unique([...targetUsers, ...watchUsers]), [...ignoreUsers, actionUser]);
-    const activeNotificationUsers = await User.find({
-      _id: { $in: notificationUsers },
-      status: User.STATUS_ACTIVE,
-    }).distinct('_id');
-    return activeNotificationUsers;
+activitySchema.methods.getNotificationTargetUsers = async function() {
+  // const User = crowi.model('User');
+  // const Watcher = crowi.model('Watcher');
+  const { user: actionUser, targetModel, target } = this;
+
+  const model: any = await this.model(targetModel).findById(target);
+  const [targetUsers, watchUsers, ignoreUsers] = await Promise.all([
+    model.getNotificationTargetUsers(),
+    Watcher.getWatchers((target as any) as Types.ObjectId),
+    Watcher.getIgnorers((target as any) as Types.ObjectId),
+  ]);
+
+  const unique = array => Object.values(array.reduce((objects, object) => ({ ...objects, [object.toString()]: object }), {}));
+  const filter = (array, pull) => {
+    const ids = pull.map(object => object.toString());
+    return array.filter(object => !ids.includes(object.toString()));
   };
   };
+  const notificationUsers = filter(unique([...targetUsers, ...watchUsers]), [...ignoreUsers, actionUser]);
+  // const activeNotificationUsers = await User.find({
+  //   _id: { $in: notificationUsers },
+  //   status: User.STATUS_ACTIVE,
+  // }).distinct('_id');
+  // return activeNotificationUsers;
+};
 
 
-  /**
+/**
    * saved hook
    * saved hook
    */
    */
-  activitySchema.post('save', async(savedActivity: ActivityDocument) => {
-    const Notification = crowi.model('Notification');
-    try {
-      const notificationUsers = await savedActivity.getNotificationTargetUsers();
-
-      await Promise.all(notificationUsers.map(user => Notification.upsertByActivity(user, savedActivity)));
-      return;
-    }
-    catch (err) {
-      logger.error(err);
-    }
-  });
-
-  // because mongoose's 'remove' hook fired only when remove by a method of Document (not by a Model method)
-  // move 'save' hook from mongoose's events to activityEvent if I have a time.
-  activityEvent.on('remove', async(activity: ActivityDocument) => {
-    const Notification = crowi.model('Notification');
-
-    try {
-      await Notification.removeActivity(activity);
-    }
-    catch (err) {
-      logger.error(err);
-    }
-  });
-
-  const Activity = model<ActivityDocument, ActivityModel>('Activity', activitySchema);
-
-  return Activity;
-};
+activitySchema.post('save', async(savedActivity: ActivityDocument) => {
+  // const Notification = crowi.model('Notification');
+  try {
+    const notificationUsers = await savedActivity.getNotificationTargetUsers();
+
+    // await Promise.all(notificationUsers.map(user => InAppNotification.upsertByActivity(user, savedActivity)));
+    return;
+  }
+  catch (err) {
+    logger.error(err);
+  }
+});
+
+// because mongoose's 'remove' hook fired only when remove by a method of Document (not by a Model method)
+// move 'save' hook from mongoose's events to activityEvent if I have a time.
+// activityEvent.on('remove', async(activity: ActivityDocument) => {
+//   const Notification = crowi.model('Notification');
+
+//   try {
+//     await InAppNotification.removeActivity(activity);
+//   }
+//   catch (err) {
+//     logger.error(err);
+//   }
+// });
+
+const Activity = getOrCreateModel<ActivityDocument, ActivityModel>('Activity', activitySchema);
+export { Activity };

+ 3 - 2
packages/app/src/server/models/in-app-notification.ts

@@ -6,7 +6,9 @@ import ActivityDefine from '../util/activityDefine';
 import { getOrCreateModel } from '../util/mongoose-utils';
 import { getOrCreateModel } from '../util/mongoose-utils';
 import loggerFactory from '../../utils/logger';
 import loggerFactory from '../../utils/logger';
 import Crowi from '../crowi';
 import Crowi from '../crowi';
-import { ActivityDocument } from './activity';
+import { Activity, ActivityDocument } from '~/server/models/activity';
+
+
 import User = require('./user');
 import User = require('./user');
 
 
 
 
@@ -85,7 +87,6 @@ export default (crowi: Crowi) => {
     },
     },
   });
   });
   inAppNotificationSchema.virtual('actionUsers').get(function(this: InAppNotificationDocument) {
   inAppNotificationSchema.virtual('actionUsers').get(function(this: InAppNotificationDocument) {
-    const Activity = crowi.model('Activity');
     return Activity.getActionUsersFromActivities((this.activities as any) as ActivityDocument[]);
     return Activity.getActionUsersFromActivities((this.activities as any) as ActivityDocument[]);
   });
   });
   const transform = (doc, ret) => {
   const transform = (doc, ret) => {