Просмотр исходного кода

make subscription status type enum

Yuki Takei 4 лет назад
Родитель
Сommit
aa958e369e

+ 6 - 0
packages/app/src/interfaces/subscription.ts

@@ -0,0 +1,6 @@
+export const SubscriptionStatusType = {
+  SUBSCRIBE: 'SUBSCRIBE',
+  UNSUBSCRIBE: 'UNSUBSCRIBE',
+} as const;
+export const AllSubscriptionStatusType = Object.values(SubscriptionStatusType);
+export type SubscriptionStatusType = typeof SubscriptionStatusType[keyof typeof SubscriptionStatusType];

+ 8 - 9
packages/app/src/server/models/subscription.ts

@@ -3,11 +3,10 @@ import {
 } from 'mongoose';
 
 import { getOrCreateModel } from '@growi/core';
-import ActivityDefine from '../util/activityDefine';
 
-export const STATUS_SUBSCRIBE = 'SUBSCRIBE';
-export const STATUS_UNSUBSCRIBE = 'UNSUBSCRIBE';
-const STATUSES = [STATUS_SUBSCRIBE, STATUS_UNSUBSCRIBE];
+import { SubscriptionStatusType, AllSubscriptionStatusType } from '~/interfaces/subscription';
+
+import ActivityDefine from '../util/activityDefine';
 
 export interface ISubscription {
   user: Types.ObjectId
@@ -50,17 +49,17 @@ const subscriptionSchema = new Schema<SubscriptionDocument, SubscriptionModel>({
   status: {
     type: String,
     require: true,
-    enum: STATUSES,
+    enum: AllSubscriptionStatusType,
   },
   createdAt: { type: Date, default: new Date() },
 });
 
 subscriptionSchema.methods.isSubscribing = function() {
-  return this.status === STATUS_SUBSCRIBE;
+  return this.status === SubscriptionStatusType.SUBSCRIBE;
 };
 
 subscriptionSchema.methods.isUnsubscribing = function() {
-  return this.status === STATUS_UNSUBSCRIBE;
+  return this.status === SubscriptionStatusType.UNSUBSCRIBE;
 };
 
 subscriptionSchema.statics.findByUserIdAndTargetId = function(userId, targetId) {
@@ -81,11 +80,11 @@ subscriptionSchema.statics.subscribeByPageId = function(user, pageId, status) {
 };
 
 subscriptionSchema.statics.getSubscription = async function(target) {
-  return this.find({ target, status: STATUS_SUBSCRIBE }).distinct('user');
+  return this.find({ target, status: SubscriptionStatusType.SUBSCRIBE }).distinct('user');
 };
 
 subscriptionSchema.statics.getUnsubscription = async function(target) {
-  return this.find({ target, status: STATUS_UNSUBSCRIBE }).distinct('user');
+  return this.find({ target, status: SubscriptionStatusType.UNSUBSCRIBE }).distinct('user');
 };
 
 export default getOrCreateModel<SubscriptionDocument, SubscriptionModel>('Subscription', subscriptionSchema);

+ 18 - 49
packages/app/src/server/routes/apiv3/page.js

@@ -1,7 +1,8 @@
 import { pagePathUtils } from '@growi/core';
 import loggerFactory from '~/utils/logger';
 
-import Subscription, { STATUS_SUBSCRIBE, STATUS_UNSUBSCRIBE } from '~/server/models/subscription';
+import { AllSubscriptionStatusType, SubscriptionStatusType } from '~/interfaces/subscription';
+import Subscription from '~/server/models/subscription';
 
 const logger = loggerFactory('growi:routes:apiv3:page'); // eslint-disable-line no-unused-vars
 
@@ -199,7 +200,7 @@ module.exports = (crowi) => {
     ],
     subscribe: [
       body('pageId').isString(),
-      body('status').isBoolean(),
+      body('status').isIn(AllSubscriptionStatusType),
     ],
     subscribeStatus: [
       query('pageId').isString(),
@@ -362,15 +363,24 @@ module.exports = (crowi) => {
     const { pageId } = req.query;
 
     try {
-      const page = await Page.findByIdAndViewer(pageId, user);
+      const page = await Page.findByIdAndViewer(pageId, user, null, true);
 
       if (page == null) {
         return res.apiv3Err(`Page '${pageId}' is not found or forbidden`);
       }
 
+      if (page.isEmpty) {
+        return res.apiv3({
+          isEmpty: true,
+          isDeletable: false,
+          isAbleToDeleteCompletely: false,
+        });
+      }
+
       const bookmarkCount = await Bookmark.countByPageId(pageId);
 
       const responseBodyForGuest = {
+        isEmpty: false,
         sumOfLikers: page.liker.length,
         likerIds: page.liker.slice(0, 15),
         seenUserIds: page.seenUsers.slice(0, 15),
@@ -389,11 +399,14 @@ module.exports = (crowi) => {
       const isLiked = page.isLiked(user);
       const isAbleToDeleteCompletely = pageService.canDeleteCompletely(page.creator?._id, user);
 
+      const subscription = await Subscription.findByUserIdAndTargetId(user._id, pageId);
+
       const responseBody = {
         ...responseBodyForGuest,
         isAbleToDeleteCompletely,
         isBookmarked,
         isLiked,
+        subscriptionStatus: subscription?.status,
       };
 
       return res.apiv3(responseBody);
@@ -627,9 +640,9 @@ module.exports = (crowi) => {
    *            description: Internal server error.
    */
   router.put('/subscribe', accessTokenParser, loginRequiredStrictly, csrf, validator.subscribe, apiV3FormValidator, async(req, res) => {
-    const { pageId } = req.body;
+    const { pageId, status } = req.body;
     const userId = req.user._id;
-    const status = req.body.status ? STATUS_SUBSCRIBE : STATUS_UNSUBSCRIBE;
+
     try {
       const subscription = await Subscription.subscribeByPageId(userId, pageId, status);
       return res.apiv3({ subscription });
@@ -640,49 +653,5 @@ module.exports = (crowi) => {
     }
   });
 
-  /**
-   * @swagger
-   *
-   *    /page/subscribe:
-   *      get:
-   *        tags: [Page]
-   *        summary: /page/subscribe
-   *        description: Get subscription status
-   *        operationId: getSubscriptionStatus
-   *        requestBody:
-   *          content:
-   *            application/json:
-   *              schema:
-   *                properties:
-   *                  pageId:
-   *                    $ref: '#/components/schemas/Page/properties/_id'
-   *        responses:
-   *          200:
-   *            description: Succeeded to get subscription status.
-   *            content:
-   *              application/json:
-   *                schema:
-   *                  $ref: '#/components/schemas/Page'
-   *          500:
-   *            description: Internal server error.
-   */
-  router.get('/subscribe', loginRequiredStrictly, validator.subscribeStatus, apiV3FormValidator, async(req, res) => {
-    const { pageId } = req.query;
-    const userId = req.user._id;
-
-    const page = await Page.findById(pageId);
-    if (!page) throw new Error('Page not found');
-
-    try {
-      const subscription = await Subscription.findByUserIdAndTargetId(userId, pageId);
-      const subscribing = subscription ? subscription.isSubscribing() : null;
-      return res.apiv3({ subscribing });
-    }
-    catch (err) {
-      logger.error('Failed to ge subscribe status', err);
-      return res.apiv3(err, 500);
-    }
-  });
-
   return router;
 };

+ 0 - 15
packages/app/src/stores/page.tsx

@@ -63,21 +63,6 @@ export const useSWRTagsInfo = (pageId: string | null | undefined): SWRResponse<I
     };
   }));
 };
-type GetSubscriptionStatusResult = { subscribing: boolean };
-
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-export const useSWRxSubscriptionStatus = <Data, Error>(pageId: string): SWRResponse<{status: boolean | null}, Error> => {
-  const { data: isGuestUser } = useIsGuestUser();
-  const key = isGuestUser === false ? ['/page/subscribe', pageId] : null;
-  return useSWR(
-    key,
-    (endpoint, pageId) => apiv3Get<GetSubscriptionStatusResult>(endpoint, { pageId }).then((response) => {
-      return {
-        status: response.data.subscribing,
-      };
-    }),
-  );
-};
 
 // eslint-disable-next-line @typescript-eslint/no-unused-vars
 export const useSWRxPageInfo = <Data, Error>(pageId: string | undefined): SWRResponse<IPageInfo, Error> => {