ソースを参照

Fix the loading bar with the new Redux actions (#28422)

Renaud Chaput 5 ヶ月 前
コミット
8b1eeb2f90

+ 15 - 15
app/javascript/mastodon/actions/accounts_typed.ts

@@ -21,7 +21,7 @@ function actionWithSkipLoadingTrue<Args extends object>(args: Args) {
 }
 
 export const followAccountSuccess = createAction(
-  'accounts/followAccountSuccess',
+  'accounts/followAccount/SUCCESS',
   actionWithSkipLoadingTrue<{
     relationship: ApiRelationshipJSON;
     alreadyFollowing: boolean;
@@ -29,7 +29,7 @@ export const followAccountSuccess = createAction(
 );
 
 export const unfollowAccountSuccess = createAction(
-  'accounts/unfollowAccountSuccess',
+  'accounts/unfollowAccount/SUCCESS',
   actionWithSkipLoadingTrue<{
     relationship: ApiRelationshipJSON;
     statuses: unknown;
@@ -38,60 +38,60 @@ export const unfollowAccountSuccess = createAction(
 );
 
 export const authorizeFollowRequestSuccess = createAction<{ id: string }>(
-  'accounts/followRequestAuthorizeSuccess',
+  'accounts/followRequestAuthorize/SUCCESS',
 );
 
 export const rejectFollowRequestSuccess = createAction<{ id: string }>(
-  'accounts/followRequestRejectSuccess',
+  'accounts/followRequestReject/SUCCESS',
 );
 
 export const followAccountRequest = createAction(
-  'accounts/followRequest',
+  'accounts/follow/REQUEST',
   actionWithSkipLoadingTrue<{ id: string; locked: boolean }>,
 );
 
 export const followAccountFail = createAction(
-  'accounts/followFail',
+  'accounts/follow/FAIL',
   actionWithSkipLoadingTrue<{ id: string; error: string; locked: boolean }>,
 );
 
 export const unfollowAccountRequest = createAction(
-  'accounts/unfollowRequest',
+  'accounts/unfollow/REQUEST',
   actionWithSkipLoadingTrue<{ id: string }>,
 );
 
 export const unfollowAccountFail = createAction(
-  'accounts/unfollowFail',
+  'accounts/unfollow/FAIL',
   actionWithSkipLoadingTrue<{ id: string; error: string }>,
 );
 
 export const blockAccountSuccess = createAction<{
   relationship: ApiRelationshipJSON;
   statuses: unknown;
-}>('accounts/blockSuccess');
+}>('accounts/block/SUCCESS');
 
 export const unblockAccountSuccess = createAction<{
   relationship: ApiRelationshipJSON;
-}>('accounts/unblockSuccess');
+}>('accounts/unblock/SUCCESS');
 
 export const muteAccountSuccess = createAction<{
   relationship: ApiRelationshipJSON;
   statuses: unknown;
-}>('accounts/muteSuccess');
+}>('accounts/mute/SUCCESS');
 
 export const unmuteAccountSuccess = createAction<{
   relationship: ApiRelationshipJSON;
-}>('accounts/unmuteSuccess');
+}>('accounts/unmute/SUCCESS');
 
 export const pinAccountSuccess = createAction<{
   relationship: ApiRelationshipJSON;
-}>('accounts/pinSuccess');
+}>('accounts/pin/SUCCESS');
 
 export const unpinAccountSuccess = createAction<{
   relationship: ApiRelationshipJSON;
-}>('accounts/unpinSuccess');
+}>('accounts/unpin/SUCCESS');
 
 export const fetchRelationshipsSuccess = createAction(
-  'relationships/fetchSuccess',
+  'relationships/fetch/SUCCESS',
   actionWithSkipLoadingTrue<{ relationships: ApiRelationshipJSON[] }>,
 );

+ 2 - 2
app/javascript/mastodon/actions/domain_blocks_typed.ts

@@ -5,9 +5,9 @@ import type { Account } from 'mastodon/models/account';
 export const blockDomainSuccess = createAction<{
   domain: string;
   accounts: Account[];
-}>('domain_blocks/blockSuccess');
+}>('domain_blocks/block/SUCCESS');
 
 export const unblockDomainSuccess = createAction<{
   domain: string;
   accounts: Account[];
-}>('domain_blocks/unblockSuccess');
+}>('domain_blocks/unblock/SUCCESS');

+ 38 - 14
app/javascript/mastodon/store/middlewares/loading_bar.ts

@@ -1,3 +1,9 @@
+import {
+  isAsyncThunkAction,
+  isPending as isThunkActionPending,
+  isFulfilled as isThunkActionFulfilled,
+  isRejected as isThunkActionRejected,
+} from '@reduxjs/toolkit';
 import { showLoading, hideLoading } from 'react-redux-loading-bar';
 import type { AnyAction, Middleware } from 'redux';
 
@@ -21,25 +27,43 @@ export const loadingBarMiddleware = (
   return ({ dispatch }) =>
     (next) =>
     (action: AnyAction) => {
-      if (action.type && !action.skipLoading) {
+      let isPending = false;
+      let isFulfilled = false;
+      let isRejected = false;
+
+      if (
+        isAsyncThunkAction(action)
+        // TODO: once we get the first use-case for it, add a check for skipLoading
+      ) {
+        if (isThunkActionPending(action)) isPending = true;
+        else if (isThunkActionFulfilled(action)) isFulfilled = true;
+        else if (isThunkActionRejected(action)) isRejected = true;
+      } else if (
+        action.type &&
+        !action.skipLoading &&
+        typeof action.type === 'string'
+      ) {
         const [PENDING, FULFILLED, REJECTED] = promiseTypeSuffixes;
 
-        const isPending = new RegExp(`${PENDING}$`, 'g');
-        const isFulfilled = new RegExp(`${FULFILLED}$`, 'g');
-        const isRejected = new RegExp(`${REJECTED}$`, 'g');
-
-        if (typeof action.type === 'string') {
-          if (action.type.match(isPending)) {
-            dispatch(showLoading());
-          } else if (
-            action.type.match(isFulfilled) ??
-            action.type.match(isRejected)
-          ) {
-            dispatch(hideLoading());
-          }
+        const isPendingRegexp = new RegExp(`${PENDING}$`, 'g');
+        const isFulfilledRegexp = new RegExp(`${FULFILLED}$`, 'g');
+        const isRejectedRegexp = new RegExp(`${REJECTED}$`, 'g');
+
+        if (action.type.match(isPendingRegexp)) {
+          isPending = true;
+        } else if (action.type.match(isFulfilledRegexp)) {
+          isFulfilled = true;
+        } else if (action.type.match(isRejectedRegexp)) {
+          isRejected = true;
         }
       }
 
+      if (isPending) {
+        dispatch(showLoading());
+      } else if (isFulfilled || isRejected) {
+        dispatch(hideLoading());
+      }
+
       return next(action);
     };
 };