[Glitch] Type Redux store and middleware
Port 6aeb162927 to glitch-soc
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
			
			
This commit is contained in:
		@@ -1,7 +1,7 @@
 | 
				
			|||||||
import React from 'react';
 | 
					import React from 'react';
 | 
				
			||||||
import { Provider } from 'react-redux';
 | 
					import { Provider } from 'react-redux';
 | 
				
			||||||
import PropTypes from 'prop-types';
 | 
					import PropTypes from 'prop-types';
 | 
				
			||||||
import { store } from 'flavours/glitch/store/configureStore';
 | 
					import { store } from 'flavours/glitch/store';
 | 
				
			||||||
import { hydrateStore } from 'flavours/glitch/actions/store';
 | 
					import { hydrateStore } from 'flavours/glitch/actions/store';
 | 
				
			||||||
import { IntlProvider, addLocaleData } from 'react-intl';
 | 
					import { IntlProvider, addLocaleData } from 'react-intl';
 | 
				
			||||||
import { getLocale } from 'mastodon/locales';
 | 
					import { getLocale } from 'mastodon/locales';
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,7 @@ import { IntlProvider, addLocaleData } from 'react-intl';
 | 
				
			|||||||
import { Provider as ReduxProvider } from 'react-redux';
 | 
					import { Provider as ReduxProvider } from 'react-redux';
 | 
				
			||||||
import { BrowserRouter, Route } from 'react-router-dom';
 | 
					import { BrowserRouter, Route } from 'react-router-dom';
 | 
				
			||||||
import { ScrollContext } from 'react-router-scroll-4';
 | 
					import { ScrollContext } from 'react-router-scroll-4';
 | 
				
			||||||
import { store } from 'flavours/glitch/store/configureStore';
 | 
					import { store } from 'flavours/glitch/store';
 | 
				
			||||||
import UI from 'flavours/glitch/features/ui';
 | 
					import UI from 'flavours/glitch/features/ui';
 | 
				
			||||||
import { fetchCustomEmojis } from 'flavours/glitch/actions/custom_emojis';
 | 
					import { fetchCustomEmojis } from 'flavours/glitch/actions/custom_emojis';
 | 
				
			||||||
import { hydrateStore } from 'flavours/glitch/actions/store';
 | 
					import { hydrateStore } from 'flavours/glitch/actions/store';
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@ import React from 'react';
 | 
				
			|||||||
import ReactDOM from 'react-dom';
 | 
					import ReactDOM from 'react-dom';
 | 
				
			||||||
import { setupBrowserNotifications } from 'flavours/glitch/actions/notifications';
 | 
					import { setupBrowserNotifications } from 'flavours/glitch/actions/notifications';
 | 
				
			||||||
import Mastodon from 'flavours/glitch/containers/mastodon';
 | 
					import Mastodon from 'flavours/glitch/containers/mastodon';
 | 
				
			||||||
import { store } from 'flavours/glitch/store/configureStore';
 | 
					import { store } from 'flavours/glitch/store';
 | 
				
			||||||
import { me } from 'flavours/glitch/initial_state';
 | 
					import { me } from 'flavours/glitch/initial_state';
 | 
				
			||||||
import ready from 'flavours/glitch/ready';
 | 
					import ready from 'flavours/glitch/ready';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -91,4 +91,6 @@ const reducers = {
 | 
				
			|||||||
  followed_tags,
 | 
					  followed_tags,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default combineReducers(reducers);
 | 
					const rootReducer = combineReducers(reducers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export { rootReducer };
 | 
				
			||||||
@@ -1,16 +0,0 @@
 | 
				
			|||||||
import { configureStore } from '@reduxjs/toolkit';
 | 
					 | 
				
			||||||
import thunk from 'redux-thunk';
 | 
					 | 
				
			||||||
import appReducer from '../reducers';
 | 
					 | 
				
			||||||
import loadingBarMiddleware from '../middleware/loading_bar';
 | 
					 | 
				
			||||||
import errorsMiddleware from '../middleware/errors';
 | 
					 | 
				
			||||||
import soundsMiddleware from '../middleware/sounds';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const store = configureStore({
 | 
					 | 
				
			||||||
  reducer: appReducer,
 | 
					 | 
				
			||||||
  middleware: [
 | 
					 | 
				
			||||||
    thunk,
 | 
					 | 
				
			||||||
    loadingBarMiddleware({ promiseTypeSuffixes: ['REQUEST', 'SUCCESS', 'FAIL'] }),
 | 
					 | 
				
			||||||
    errorsMiddleware(),
 | 
					 | 
				
			||||||
    soundsMiddleware(),
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
							
								
								
									
										23
									
								
								app/javascript/flavours/glitch/store/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								app/javascript/flavours/glitch/store/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					import { configureStore } from '@reduxjs/toolkit';
 | 
				
			||||||
 | 
					import { rootReducer } from '../reducers';
 | 
				
			||||||
 | 
					import { loadingBarMiddleware } from './middlewares/loading_bar';
 | 
				
			||||||
 | 
					import { errorsMiddleware } from './middlewares/errors';
 | 
				
			||||||
 | 
					import { soundsMiddleware } from './middlewares/sounds';
 | 
				
			||||||
 | 
					import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const store = configureStore({
 | 
				
			||||||
 | 
					  reducer: rootReducer,
 | 
				
			||||||
 | 
					  middleware: getDefaultMiddleware =>
 | 
				
			||||||
 | 
					    getDefaultMiddleware().concat(
 | 
				
			||||||
 | 
					      loadingBarMiddleware({ promiseTypeSuffixes: ['REQUEST', 'SUCCESS', 'FAIL'] }))
 | 
				
			||||||
 | 
					      .concat(errorsMiddleware)
 | 
				
			||||||
 | 
					      .concat(soundsMiddleware()),
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Infer the `RootState` and `AppDispatch` types from the store itself
 | 
				
			||||||
 | 
					export type RootState = ReturnType<typeof rootReducer>
 | 
				
			||||||
 | 
					// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
 | 
				
			||||||
 | 
					export type AppDispatch = typeof store.dispatch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const useAppDispatch: () => AppDispatch = useDispatch;
 | 
				
			||||||
 | 
					export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
 | 
				
			||||||
@@ -1,9 +1,11 @@
 | 
				
			|||||||
 | 
					import { Middleware } from 'redux';
 | 
				
			||||||
import { showAlertForError } from 'flavours/glitch/actions/alerts';
 | 
					import { showAlertForError } from 'flavours/glitch/actions/alerts';
 | 
				
			||||||
 | 
					import { RootState } from '..';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const defaultFailSuffix = 'FAIL';
 | 
					const defaultFailSuffix = 'FAIL';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function errorsMiddleware() {
 | 
					export const errorsMiddleware: Middleware<Record<string, never>, RootState> =
 | 
				
			||||||
  return ({ dispatch }) => next => action => {
 | 
					  ({ dispatch }) => next => action => {
 | 
				
			||||||
    if (action.type && !action.skipAlert) {
 | 
					    if (action.type && !action.skipAlert) {
 | 
				
			||||||
      const isFail = new RegExp(`${defaultFailSuffix}$`, 'g');
 | 
					      const isFail = new RegExp(`${defaultFailSuffix}$`, 'g');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -14,4 +16,3 @@ export default function errorsMiddleware() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    return next(action);
 | 
					    return next(action);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,8 +1,14 @@
 | 
				
			|||||||
import { showLoading, hideLoading } from 'react-redux-loading-bar';
 | 
					import { showLoading, hideLoading } from 'react-redux-loading-bar';
 | 
				
			||||||
 | 
					import { Middleware } from 'redux';
 | 
				
			||||||
 | 
					import { RootState } from '..';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const defaultTypeSuffixes = ['PENDING', 'FULFILLED', 'REJECTED'];
 | 
					interface Config {
 | 
				
			||||||
 | 
					  promiseTypeSuffixes?: string[]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function loadingBarMiddleware(config = {}) {
 | 
					const defaultTypeSuffixes: Config['promiseTypeSuffixes'] = ['PENDING', 'FULFILLED', 'REJECTED'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export  const loadingBarMiddleware = (config: Config = {}): Middleware<Record<string, never>, RootState> => {
 | 
				
			||||||
  const promiseTypeSuffixes = config.promiseTypeSuffixes || defaultTypeSuffixes;
 | 
					  const promiseTypeSuffixes = config.promiseTypeSuffixes || defaultTypeSuffixes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return ({ dispatch }) => next => (action) => {
 | 
					  return ({ dispatch }) => next => (action) => {
 | 
				
			||||||
@@ -22,4 +28,4 @@ export default function loadingBarMiddleware(config = {}) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    return next(action);
 | 
					    return next(action);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
}
 | 
					};
 | 
				
			||||||
@@ -1,4 +1,12 @@
 | 
				
			|||||||
const createAudio = sources => {
 | 
					import { Middleware, AnyAction } from 'redux';
 | 
				
			||||||
 | 
					import { RootState } from '..';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface AudioSource {
 | 
				
			||||||
 | 
					  src: string
 | 
				
			||||||
 | 
					  type: string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const createAudio = (sources: AudioSource[]) => {
 | 
				
			||||||
  const audio = new Audio();
 | 
					  const audio = new Audio();
 | 
				
			||||||
  sources.forEach(({ type, src }) => {
 | 
					  sources.forEach(({ type, src }) => {
 | 
				
			||||||
    const source = document.createElement('source');
 | 
					    const source = document.createElement('source');
 | 
				
			||||||
@@ -9,7 +17,7 @@ const createAudio = sources => {
 | 
				
			|||||||
  return audio;
 | 
					  return audio;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const play = audio => {
 | 
					const play = (audio: HTMLAudioElement) => {
 | 
				
			||||||
  if (!audio.paused) {
 | 
					  if (!audio.paused) {
 | 
				
			||||||
    audio.pause();
 | 
					    audio.pause();
 | 
				
			||||||
    if (typeof audio.fastSeek === 'function') {
 | 
					    if (typeof audio.fastSeek === 'function') {
 | 
				
			||||||
@@ -22,8 +30,8 @@ const play = audio => {
 | 
				
			|||||||
  audio.play();
 | 
					  audio.play();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function soundsMiddleware() {
 | 
					export  const soundsMiddleware = (): Middleware<Record<string, never>, RootState> => {
 | 
				
			||||||
  const soundCache = {
 | 
					  const soundCache: {[key: string]: HTMLAudioElement} = {
 | 
				
			||||||
    boop: createAudio([
 | 
					    boop: createAudio([
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        src: '/sounds/boop.ogg',
 | 
					        src: '/sounds/boop.ogg',
 | 
				
			||||||
@@ -36,11 +44,13 @@ export default function soundsMiddleware() {
 | 
				
			|||||||
    ]),
 | 
					    ]),
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return () => next => action => {
 | 
					  return () => next => (action: AnyAction) => {
 | 
				
			||||||
    if (action.meta && action.meta.sound && soundCache[action.meta.sound]) {
 | 
					    const sound = action?.meta?.sound;
 | 
				
			||||||
      play(soundCache[action.meta.sound]);
 | 
					
 | 
				
			||||||
 | 
					    if (sound && soundCache[sound]) {
 | 
				
			||||||
 | 
					      play(soundCache[sound]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return next(action);
 | 
					    return next(action);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
}
 | 
					};
 | 
				
			||||||
		Reference in New Issue
	
	Block a user