feat(ui): ux improvements & redesign

This is a squash merge of a bajillion messy small commits created while iterating on the UI component library and redesign.
This commit is contained in:
psychedelicious
2023-12-29 00:03:21 +11:00
committed by Kent Keirsey
parent a47d91f0e7
commit f0b102d830
889 changed files with 16645 additions and 15595 deletions

View File

@ -0,0 +1,29 @@
import { useAppSelector } from 'app/store/storeHooks';
import { InvControlGroup } from 'common/components/InvControl/InvControlGroup';
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
import { memo } from 'react';
import ParamHrfMethod from './ParamHrfMethod';
import ParamHrfStrength from './ParamHrfStrength';
import ParamHrfToggle from './ParamHrfToggle';
export const HrfSettings = memo(() => {
const isHRFFeatureEnabled = useFeatureStatus('hrf').isFeatureEnabled;
const hrfEnabled = useAppSelector((state) => state.hrf.hrfEnabled);
if (!isHRFFeatureEnabled) {
return null;
}
return (
<>
<ParamHrfToggle />
<InvControlGroup isDisabled={!hrfEnabled}>
<ParamHrfStrength />
<ParamHrfMethod />
</InvControlGroup>
</>
);
});
HrfSettings.displayName = 'HrfSettings';

View File

@ -0,0 +1,45 @@
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { InvControl } from 'common/components/InvControl/InvControl';
import { InvSelect } from 'common/components/InvSelect/InvSelect';
import type {
InvSelectOnChange,
InvSelectOption,
} from 'common/components/InvSelect/types';
import { setHrfMethod } from 'features/hrf/store/hrfSlice';
import { isParameterHRFMethod } from 'features/parameters/types/parameterSchemas';
import { memo, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
const options: InvSelectOption[] = [
{ label: 'ESRGAN', value: 'ESRGAN' },
{ label: 'bilinear', value: 'bilinear' },
];
const ParamHrfMethodSelect = () => {
const dispatch = useAppDispatch();
const { t } = useTranslation();
const hrfMethod = useAppSelector((state) => state.hrf.hrfMethod);
const onChange = useCallback<InvSelectOnChange>(
(v) => {
if (!isParameterHRFMethod(v?.value)) {
return;
}
dispatch(setHrfMethod(v.value));
},
[dispatch]
);
const value = useMemo(
() => options.find((o) => o.value === hrfMethod),
[hrfMethod]
);
return (
<InvControl label={t('hrf.upscaleMethod')}>
<InvSelect value={value} options={options} onChange={onChange} />
</InvControl>
);
};
export default memo(ParamHrfMethodSelect);

View File

@ -0,0 +1,60 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { InvControl } from 'common/components/InvControl/InvControl';
import { InvSlider } from 'common/components/InvSlider/InvSlider';
import { setHrfStrength } from 'features/hrf/store/hrfSlice';
import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
const selector = createMemoizedSelector([stateSelector], ({ hrf, config }) => {
const { initial, min, sliderMax, inputMax, fineStep, coarseStep } =
config.sd.hrfStrength;
const { hrfStrength } = hrf;
return {
hrfStrength,
initial,
min,
sliderMax,
inputMax,
step: coarseStep,
fineStep,
};
});
const ParamHrfStrength = () => {
const { hrfStrength, initial, min, sliderMax, step, fineStep } =
useAppSelector(selector);
const dispatch = useAppDispatch();
const { t } = useTranslation();
const handleHrfStrengthReset = useCallback(() => {
dispatch(setHrfStrength(initial));
}, [dispatch, initial]);
const handleHrfStrengthChange = useCallback(
(v: number) => {
dispatch(setHrfStrength(v));
},
[dispatch]
);
return (
<InvControl label={t('parameters.denoisingStrength')}>
<InvSlider
min={min}
max={sliderMax}
step={step}
fineStep={fineStep}
value={hrfStrength}
onChange={handleHrfStrengthChange}
marks
withNumberInput
onReset={handleHrfStrengthReset}
/>
</InvControl>
);
};
export default memo(ParamHrfStrength);

View File

@ -0,0 +1,31 @@
import type { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { InvControl } from 'common/components/InvControl/InvControl';
import { InvSwitch } from 'common/components/InvSwitch/wrapper';
import { setHrfEnabled } from 'features/hrf/store/hrfSlice';
import type { ChangeEvent } from 'react';
import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
export default function ParamHrfToggle() {
const dispatch = useAppDispatch();
const { t } = useTranslation();
const hrfEnabled = useAppSelector((state: RootState) => state.hrf.hrfEnabled);
const handleHrfEnabled = useCallback(
(e: ChangeEvent<HTMLInputElement>) =>
dispatch(setHrfEnabled(e.target.checked)),
[dispatch]
);
return (
<InvControl
label={t('hrf.enableHrf')}
labelProps={{ flexGrow: 1 }}
w="full"
>
<InvSwitch isChecked={hrfEnabled} onChange={handleHrfEnabled} />
</InvControl>
);
}

View File

@ -0,0 +1,40 @@
import type { PayloadAction } from '@reduxjs/toolkit';
import { createSlice } from '@reduxjs/toolkit';
import type {
ParameterHRFMethod,
ParameterStrength,
} from 'features/parameters/types/parameterSchemas';
export interface HRFState {
hrfEnabled: boolean;
hrfStrength: ParameterStrength;
hrfMethod: ParameterHRFMethod;
}
export const initialHRFState: HRFState = {
hrfStrength: 0.45,
hrfEnabled: false,
hrfMethod: 'ESRGAN',
};
const initialState: HRFState = initialHRFState;
export const hrfSlice = createSlice({
name: 'hrf',
initialState,
reducers: {
setHrfStrength: (state, action: PayloadAction<number>) => {
state.hrfStrength = action.payload;
},
setHrfEnabled: (state, action: PayloadAction<boolean>) => {
state.hrfEnabled = action.payload;
},
setHrfMethod: (state, action: PayloadAction<ParameterHRFMethod>) => {
state.hrfMethod = action.payload;
},
},
});
export const { setHrfEnabled, setHrfStrength, setHrfMethod } = hrfSlice.actions;
export default hrfSlice.reducer;