chinwagsocial/app/javascript/mastodon/store/middlewares/loading_bar.ts

70 lines
2 KiB
TypeScript
Raw Normal View History

import {
isAsyncThunkAction,
isPending as isThunkActionPending,
isFulfilled as isThunkActionFulfilled,
isRejected as isThunkActionRejected,
} from '@reduxjs/toolkit';
2017-01-16 23:27:58 +11:00
import { showLoading, hideLoading } from 'react-redux-loading-bar';
import type { AnyAction, Middleware } from 'redux';
import type { RootState } from '..';
2017-01-16 23:27:58 +11:00
interface Config {
promiseTypeSuffixes?: string[];
}
const defaultTypeSuffixes: Config['promiseTypeSuffixes'] = [
'PENDING',
'FULFILLED',
'REJECTED',
];
2017-01-16 23:27:58 +11:00
export const loadingBarMiddleware = (
2023-07-13 19:26:45 +10:00
config: Config = {},
2023-09-12 20:18:19 +10:00
): Middleware<unknown, RootState> => {
const promiseTypeSuffixes = config.promiseTypeSuffixes ?? defaultTypeSuffixes;
2017-01-16 23:27:58 +11:00
return ({ dispatch }) =>
(next) =>
(action: AnyAction) => {
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;
2017-01-16 23:27:58 +11:00
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;
}
2017-01-16 23:27:58 +11:00
}
if (isPending) {
dispatch(showLoading());
} else if (isFulfilled || isRejected) {
dispatch(hideLoading());
}
return next(action);
};
};