// @flow import React from 'react'; import { FormField } from 'component/common/form'; import Button from 'component/button'; import * as DAEMON_SETTINGS from 'constants/daemon_settings'; import { isTrulyANumber } from 'util/number'; import * as ICONS from 'constants/icons'; import * as KEYCODES from 'constants/keycodes'; import { convertGbToMbStr, isValidHostingAmount } from 'util/hosting'; type SetDaemonSettingArg = boolean | string | number; type Props = { // --- select --- viewBlobSpace: number, viewHostingLimit: number, disabled?: boolean, isSetting: boolean, // --- perform --- setDaemonSetting: (string, ?SetDaemonSettingArg) => void, cleanBlobs: () => string, getDaemonStatus: () => void, diskSpace: DiskSpace, }; const TWENTY_PERCENT = 0.2; const TEN_PERCENT = 0.1; const MINIMUM_VIEW_SETTING = '0.01'; function SettingViewHosting(props: Props) { const { diskSpace, viewHostingLimit, viewBlobSpace, setDaemonSetting, cleanBlobs, getDaemonStatus, disabled, isSetting, } = props; // best effort to recommend a hosting amount default for the user const totalMB = diskSpace && Math.floor(diskSpace.total / 1024); const freeMB = diskSpace && Math.floor(diskSpace.free / 1024); const getGB = (val) => (Number(val) / 1024).toFixed(2); const recommendedSpace = freeMB > totalMB * TWENTY_PERCENT // plenty of space? ? Math.ceil(Number(getGB(totalMB * TEN_PERCENT))) // 10% of total : Math.ceil(Number(getGB(viewBlobSpace))); // current amount to avoid deleting // daemon settings come in as 'number', but we manage them as 'String'. const [contentBlobSpaceLimitGB, setContentBlobSpaceLimit] = React.useState( viewHostingLimit === 0 ? String(recommendedSpace) : String(viewHostingLimit / 1024) ); const [unlimited, setUnlimited] = React.useState(viewHostingLimit === 0); function handleContentLimitChange(gb) { if (gb === '') { setContentBlobSpaceLimit(''); } else if (gb === '0') { setContentBlobSpaceLimit(MINIMUM_VIEW_SETTING); // setting 0 means unlimited. } else { if (isTrulyANumber(Number(gb))) { setContentBlobSpaceLimit(gb); } } } function getContentLimitValue() { if (contentBlobSpaceLimitGB === '') { return ''; } else if (Number(contentBlobSpaceLimitGB) <= Number(MINIMUM_VIEW_SETTING)) { return '0'; } else { return contentBlobSpaceLimitGB; } } async function handleApply() { if (unlimited) { await setDaemonSetting(DAEMON_SETTINGS.BLOB_STORAGE_LIMIT_MB, '0'); } else { await setDaemonSetting( DAEMON_SETTINGS.BLOB_STORAGE_LIMIT_MB, contentBlobSpaceLimitGB === MINIMUM_VIEW_SETTING ? '1' : convertGbToMbStr(contentBlobSpaceLimitGB) ); } await cleanBlobs(); getDaemonStatus(); } function handleKeyDown(e) { if (e.keyCode === KEYCODES.ESCAPE) { e.preventDefault(); setContentBlobSpaceLimit(String(viewHostingLimit / 1024)); } else if (e.keyCode === KEYCODES.ENTER) { e.preventDefault(); handleApply(); } } React.useEffect(() => { // basically handle setUnlimited if (unlimited && viewHostingLimit !== 0) { handleApply(); } }, [unlimited, viewHostingLimit]); return ( <> <div className={'fieldset-section'}> <FormField type="checkbox" name="hosting_limit" checked={unlimited} disabled={disabled || isSetting} label={__('Unlimited View Hosting')} onChange={() => setUnlimited(!unlimited)} /> <FormField name="content_blob_limit_gb" type="number" min={0} onKeyDown={handleKeyDown} inputButton={ <> <Button disabled={ // disabled if settings are equal or not valid amounts (viewHostingLimit === 1 && contentBlobSpaceLimitGB <= MINIMUM_VIEW_SETTING) || (unlimited && viewHostingLimit === 0) || (!unlimited && (String(viewHostingLimit) === convertGbToMbStr(contentBlobSpaceLimitGB) || !isValidHostingAmount(String(contentBlobSpaceLimitGB)))) || (!unlimited && String(viewHostingLimit) === convertGbToMbStr( contentBlobSpaceLimitGB || !isValidHostingAmount(String(contentBlobSpaceLimitGB)) )) || isSetting || disabled } type="button" button="alt" onClick={handleApply} aria-label={__('Apply')} icon={ICONS.COMPLETE} /> <Button disabled={ // disabled if settings are equal or not valid amounts (viewHostingLimit === 1 && contentBlobSpaceLimitGB <= MINIMUM_VIEW_SETTING) || (unlimited && viewHostingLimit === 0) || (!unlimited && String(viewHostingLimit) === convertGbToMbStr( contentBlobSpaceLimitGB || !isValidHostingAmount(String(contentBlobSpaceLimitGB)) )) || isSetting || disabled } type="button" button="alt" onClick={() => setContentBlobSpaceLimit(String(viewHostingLimit / 1024))} aria-label={__('Reset')} icon={ICONS.REMOVE} /> </> } disabled={isSetting || disabled || unlimited} onWheel={(e) => e.preventDefault()} label={__(`View Hosting Limit (GB)`)} onChange={(e) => handleContentLimitChange(e.target.value)} value={getContentLimitValue()} /> </div> </> ); } export default SettingViewHosting;