From 3838d62c9005530e5bff1e7fc1b33ae86deb2f20 Mon Sep 17 00:00:00 2001 From: Kristof Csillag Date: Fri, 23 Sep 2022 23:47:28 +0200 Subject: [PATCH] Modals: improve handling of danger, add delays --- src/app/components/Modal/index.tsx | 74 ++++++++++++++++++++++++++---- src/locales/en/translation.json | 4 +- 2 files changed, 68 insertions(+), 10 deletions(-) diff --git a/src/app/components/Modal/index.tsx b/src/app/components/Modal/index.tsx index baa01a8fdc..fc066354f1 100644 --- a/src/app/components/Modal/index.tsx +++ b/src/app/components/Modal/index.tsx @@ -1,13 +1,29 @@ -import { createContext, useCallback, useContext, useState } from 'react' +import React from 'react' +import { createContext, useCallback, useContext, useEffect, useState } from 'react' import { Box, Button, Layer, Heading, Paragraph } from 'grommet' import { useTranslation } from 'react-i18next' import { Alert, Checkmark, Close } from 'grommet-icons/icons' +import { AlertBox } from '../AlertBox' +import { useDangerModeSetting } from '../SettingsDialog/slice/selectors' interface Modal { title: string description: string handleConfirm: () => void + + /** + * Is this a dangerous operation? + * + * If marked as such, it will only be possible to execute it if the wallet is configured to run in dangerous mode. + * + * It also automatically implies a mandatory waiting time of 10 sec, unless specified otherwise. + */ isDangerous: boolean + + /** + * How long does the user have to wait before he can actually confirm the action? + */ + mustWaitSecs?: number } interface ModalContainerProps { @@ -32,12 +48,50 @@ const ModalContainer = ({ modal, closeModal }: ModalContainerProps) => { modal.handleConfirm() closeModal() }, [closeModal, modal]) + const { isDangerous, mustWaitSecs } = modal + const dangerMode = useDangerModeSetting() + const forbidden = isDangerous && !dangerMode + const waitingTime = forbidden + ? 0 // If the action is forbidden, there is nothing to wait for + : isDangerous + ? mustWaitSecs === undefined + ? 10 // For dangerous actions, we require 10 seconds of waiting ... + : mustWaitSecs // unless specified otherwise. + : mustWaitSecs || 0 // For normal, non-dangerous operations, just use what was specified + + const [secsLeft, setSecsLeft] = useState(0) + + useEffect(() => { + if (waitingTime) { + setSecsLeft(waitingTime) + const interval = setInterval(() => { + setSecsLeft(seconds => (seconds ? seconds - 1 : 0)) + }, 1000) + return () => clearInterval(interval) + } + }, [waitingTime]) return ( {modal.title} {modal.description} + {forbidden && ( + + {t( + 'dangerMode.youDontWantThis', + "You most probably don't want to do this, so I won't allow it. If you really do, then please enable the 'dangerous mode' in wallet settings, and try again.", + )} + + )} + {isDangerous && dangerMode && ( + + {t( + 'dangerMode.youCanButDoYouWant', + "You most probably shouldn't do this, but since you have specifically enabled 'dangerous mode' in wallet settings, we won't stop you.", + )} + + )}