import React, { useContext, useEffect } from 'react' import { useRouter } from 'next/router' import { RepoQueryResponse } from '../../../common/github/repoQuery' import ConfigContext from '../../contexts/ConfigContext' import ConfigType, { Theme, Pattern, Font, RequiredConfigsKeys } from '../../../common/types/configType' import { getOptionalConfig } from '../../../common/configHelper' import SelectWrapper from './selectWrapper' import CheckBoxWrapper from './checkBoxWrapper' import InputWrapper from './inputWrapper' import TextAreaWrapper from './textAreaWrapper' type ConfigProp = { repository: RepoQueryResponse['repository'] } const Config = ({ repository }: ConfigProp) => { const router = useRouter() const { config, setConfig } = useContext(ConfigContext) const handleChanges = (changes: { value: any; key: keyof ConfigType }[]) => { let newConfig: ConfigType = { ...config } const urlParams = router.query // Remove extraneous params from route delete urlParams._owner delete urlParams._name changes.forEach(({ value, key }) => { const currentValue = newConfig[key] ? newConfig[key] : {} if (value.required === true) { newConfig = { ...newConfig, [key]: value.val } } else { newConfig = { ...newConfig, [key]: { ...currentValue, ...value } } } if (value && value.state === true && value.editable) { urlParams[key] = '1' urlParams[`${key}Editable`] = value.value } else if (value && value.state === true) { urlParams[key] = '1' } else if (value && value.required === true) { urlParams[key] = value.val } else { urlParams[key] = '0' } if (!urlParams[key] || urlParams[key] === '0') { delete urlParams[key] if (`${key}Editable` in urlParams) { delete urlParams[`${key}Editable`] } } }) router.push( `${window.location.pathname}?${Object.entries(urlParams) .sort() .map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`) .join('&')}`, undefined, { shallow: true } ) } const handleChange = (value: any, key: keyof ConfigType) => { handleChanges([{ value, key }]) } useEffect(() => { const handleRouteChange = (asPath: string) => { if (repository) { const newConfig = getOptionalConfig(repository) if (newConfig) { const params = new URLSearchParams(asPath.split('?')[1]) Array.from(params.keys()).forEach((stringKey) => { const key = stringKey as keyof ConfigType if (key in newConfig) { const query = params.get(key) const currentConfig = newConfig[key as keyof typeof newConfig] const newChange = { state: query === '1' } if (currentConfig?.editable) { const editableValue = params.get(`${key}Editable`) if (editableValue != null) { Object.assign(newChange, { value: editableValue }) } } Object.assign( newConfig[key as keyof typeof newConfig] ?? {}, newChange ) } else if (key in RequiredConfigsKeys) { const query = params.get(key) if (query != null) { const newChange = { [key]: query } Object.assign(newConfig, newChange) } } }) setConfig({ ...config, ...newConfig }) } } } router.events.on('routeChangeComplete', handleRouteChange) handleRouteChange(router.asPath) return () => { router.events.off('routeChangeComplete', handleRouteChange) } // eslint-disable-next-line react-hooks/exhaustive-deps }, []) if (!repository) { return null } return (
({ key, label: (Theme as any)[key] }))} value={config.theme} handleChange={handleChange} /> ({ key, label: (Font as any)[key] }))} value={config.font} handleChange={handleChange} /> ({ key, label: (Pattern as any)[key] }))} value={config.pattern} handleChange={handleChange} />
{config.description?.state && ( )}
) } export default Config