diff --git a/src/components/ExtensionCard.tsx b/src/components/ExtensionCard.tsx index 159abd2e..9a4417b3 100644 --- a/src/components/ExtensionCard.tsx +++ b/src/components/ExtensionCard.tsx @@ -21,19 +21,48 @@ interface IProps { notifyInstall: () => void; } +enum ExtensionAction { + UPDATE = 'UPDATE', + UNINSTALL = 'UNINSTALL', + INSTALL = 'INSTALL', +} + +enum ExtensionState { + OBSOLETE = 'OBSOLETE', + UPDATING = 'UPDATING', + UNINSTALLING = 'UNINSTALLING', + INSTALLING = 'INSTALLING', +} + +type InstalledStates = ExtensionAction | ExtensionState; + +const InstalledState = { ...ExtensionAction, ...ExtensionState } as const; + +const EXTENSION_ACTION_TO_STATE_MAP: { [action in ExtensionAction]: ExtensionState } = { + [ExtensionAction.UPDATE]: ExtensionState.UPDATING, + [ExtensionAction.UNINSTALL]: ExtensionState.UNINSTALLING, + [ExtensionAction.INSTALL]: ExtensionState.INSTALLING, +} as const; + +const EXTENSION_ACTION_TO_NEXT_ACTION_MAP: { [action in ExtensionAction]: ExtensionAction } = { + [ExtensionAction.UPDATE]: ExtensionAction.UNINSTALL, + [ExtensionAction.UNINSTALL]: ExtensionAction.INSTALL, + [ExtensionAction.INSTALL]: ExtensionAction.UNINSTALL, +} as const; + export default function ExtensionCard(props: IProps) { const { extension: { name, lang, versionName, installed, hasUpdate, obsolete, pkgName, iconUrl, isNsfw }, notifyInstall, } = props; - const [installedState, setInstalledState] = useState(() => { + const [installedState, setInstalledState] = useState(() => { if (obsolete) { - return 'obsolete'; + return InstalledState.OBSOLETE; } if (hasUpdate) { - return 'update'; + return InstalledState.UPDATE; } - return installed ? 'uninstall' : 'install'; + return installed ? InstalledState.UNINSTALL : InstalledState.INSTALL; }); const [serverAddress] = useLocalStorage('serverBaseURL', ''); @@ -41,44 +70,25 @@ export default function ExtensionCard(props: IProps) { const langPress = lang === 'all' ? 'All' : lang.toUpperCase(); - function install() { - setInstalledState('installing'); - client.get(`/api/v1/extension/install/${pkgName}`).then(() => { - setInstalledState('uninstall'); - notifyInstall(); - }); - } + const requestExtensionAction = async (action: ExtensionAction): Promise => { + const nextAction = EXTENSION_ACTION_TO_NEXT_ACTION_MAP[action]; + const state = EXTENSION_ACTION_TO_STATE_MAP[action]; - function update() { - setInstalledState('updating'); - client.get(`/api/v1/extension/update/${pkgName}`).then(() => { - setInstalledState('uninstall'); - notifyInstall(); - }); - } - - function uninstall() { - setInstalledState('uninstalling'); - client.get(`/api/v1/extension/uninstall/${pkgName}`).then(() => { - // setInstalledState('install'); - notifyInstall(); - }); - } + setInstalledState(state); + await client.get(`/api/v1/extension/${action.toLowerCase()}/${pkgName}`); + setInstalledState(nextAction); + notifyInstall(); + }; function handleButtonClick() { switch (installedState) { - case 'install': - install(); + case ExtensionAction.INSTALL: + case ExtensionAction.UPDATE: + case ExtensionAction.UNINSTALL: + requestExtensionAction(installedState).catch(() => {}); break; - case 'update': - update(); - break; - case 'obsolete': - uninstall(); - setTimeout(() => window.location.reload(), 3000); - break; - case 'uninstall': - uninstall(); + case ExtensionState.OBSOLETE: + requestExtensionAction(ExtensionAction.UNINSTALL).catch(() => {}); break; default: break; @@ -124,7 +134,7 @@ export default function ExtensionCard(props: IProps) {