Skip to content

Commit

Permalink
Update Typescript and useModule (stream-labs#4130)
Browse files Browse the repository at this point in the history
  • Loading branch information
holiber authored May 11, 2022
1 parent 8ca3295 commit 907da25
Show file tree
Hide file tree
Showing 78 changed files with 1,278 additions and 2,344 deletions.
9 changes: 4 additions & 5 deletions app/components-react/editor/elements/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ import React, { useEffect, useState } from 'react';
import { $t } from 'services/i18n';
import styles from './BaseElement.m.less';
import Scrollable from 'components-react/shared/Scrollable';
import { useModule } from '../../hooks/useModule';
import { mutation } from '../../store';
import { useModule, injectState, mutation } from 'slap';

class BaseElementModule {
state = {
state = injectState({
sizeWatcherInterval: 0,
};
});

sizeWatcherCallbacks: Function[] = [];

Expand Down Expand Up @@ -47,7 +46,7 @@ export default function useBaseElement(
const [height, setHeight] = useState(0);
const [width, setWidth] = useState(0);

const { addSizeWatcher, removeSizeWatcher } = useModule(BaseElementModule).select();
const { addSizeWatcher, removeSizeWatcher } = useModule(BaseElementModule);

useEffect(() => {
const sizeWatcher = () => {
Expand Down
115 changes: 1 addition & 114 deletions app/components-react/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import React, { useState, useEffect, useCallback, useRef, useMemo } from 'react';
import React, { useState, useEffect, useCallback, useRef } from 'react';
import debounce from 'lodash/debounce';
import { StatefulService } from '../services/core';
import { createBinding, TBindings } from './shared/inputs';
import { useForm } from './shared/inputs/Form';
import { FormInstance } from 'antd/lib/form/hooks/useForm';

/**
* Creates a reactive state for a React component based on Vuex store
Expand Down Expand Up @@ -74,116 +71,6 @@ export function useDebounce<T extends (...args: any[]) => any>(ms = 0, cb: T) {
return useCallback(debounce(cb, ms), []);
}

/**
* Init state with an async callback
* TODO investigate if we can just use a library for the async code https://github.com/slorber/react-async-hook
*/
export function useAsyncState<TStateType>(
defaultState: TStateType | (() => TStateType),
asyncCb?: (initialState: TStateType) => Promise<TStateType>,
): [TStateType, (newState: TStateType) => unknown, Promise<TStateType | null> | undefined] {
// define a state
const [state, setState] = useState(defaultState);

let isDestroyed = false;

// create and save the promise if provided
const [promise] = useState(() => {
if (asyncCb) {
return asyncCb(state).then(newState => {
// do not update the state if the component has been destroyed
if (isDestroyed) return null;
setState(newState);
return newState;
});
}
});

useOnDestroy(() => {
isDestroyed = true;
});

return [state, setState, promise];
}

/**
* Create the state object and return helper methods
*/
export function useFormState<T extends object>(initializer: T | (() => T)): TUseFormStateResult<T> {
const [s, setStateRaw] = useState<T>(initializer);

// create a reference to the last actual state
const stateRef = useRef(s);

// use isDestroyed flag to prevent updating state on destroyed components
const isDestroyedRef = useRef(false);
useOnDestroy(() => {
isDestroyedRef.current = true;
});

// create a reference to AntForm
const form = useForm();

function setState(newState: T) {
if (isDestroyedRef.current) return;
// keep the reference in sync when we update the state
stateRef.current = newState;
setStateRaw(newState);
}

// create a function for state patching
function updateState(patch: Partial<T>) {
setState({ ...stateRef.current, ...patch });
}

function setItem<TDict extends keyof T, TKey extends keyof T[TDict]>(
dictionaryName: TDict,
key: TKey,
value: T[TDict][TKey],
): void {
setState({
...stateRef.current,
[dictionaryName]: { ...stateRef.current[dictionaryName], [key]: value },
});
}

return {
s,
setState,
updateState,
setItem,
bind: createBinding(() => stateRef.current, setState),
stateRef,
form,
};
}

type TUseFormStateResult<TState extends object> = {
s: TState;
setState: (p: TState) => unknown;
updateState: (p: Partial<TState>) => unknown;
setItem: <TDict extends keyof TState, TKey extends keyof TState[TDict]>(
dictionaryName: TDict,
key: TKey,
value: TState[TDict][TKey],
) => unknown;
bind: TBindings<TState>;
stateRef: { current: TState };
form: FormInstance<TState>;
};

/**
* Returns a function for force updating of the component
* Use it only for frequently used components for optimization purposes
*
* Current implementation from
* https://github.com/ant-design/ant-design/blob/master/components/_util/hooks/useForceUpdate.ts
*/
export function useForceUpdate() {
const [, forceUpdate] = React.useReducer(x => x + 1, 0);
return forceUpdate;
}

/**
* Sets a function that guarantees a re-render and fresh state on every tick of the delay
*/
Expand Down
27 changes: 0 additions & 27 deletions app/components-react/hooks/useComponentId.tsx

This file was deleted.

174 changes: 0 additions & 174 deletions app/components-react/hooks/useModule.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion app/components-react/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export const components = {
WidgetWindow: createRoot(WidgetWindow),
CustomCodeWindow: createRoot(CustomCodeWindow),
SafeMode,
AdvancedAudio,
AdvancedAudio: createRoot(AdvancedAudio),
SourceShowcase: createRoot(SourceShowcase),
SourceFilters,
RecentEvents,
Expand Down
Loading

0 comments on commit 907da25

Please sign in to comment.