Skip to content

Commit

Permalink
Modals: improve handling of danger, add delays
Browse files Browse the repository at this point in the history
  • Loading branch information
csillag committed Sep 24, 2022
1 parent 03b0c9c commit 3838d62
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 10 deletions.
74 changes: 65 additions & 9 deletions src/app/components/Modal/index.tsx
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -32,27 +48,67 @@ 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 (
<Layer modal onEsc={closeModal} onClickOutside={closeModal} background="background-front">
<Box margin="medium">
<Heading size="small">{modal.title}</Heading>
<Paragraph fill>{modal.description}</Paragraph>
{forbidden && (
<AlertBox color={'status-error'}>
{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.",
)}
</AlertBox>
)}
{isDangerous && dangerMode && (
<AlertBox color={'status-warning'}>
{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.",
)}
</AlertBox>
)}
<Box direction="row" gap="small" alignSelf="end" pad={{ top: 'large' }}>
<Button
label={t('common.cancel', 'Cancel')}
onClick={closeModal}
secondary
icon={<Close size="18px" />}
/>
<Button
label={t('common.confirm', 'Confirm')}
onClick={confirm}
disabled={modal.isDangerous}
primary={modal.isDangerous}
color={modal.isDangerous ? 'status-error' : ''}
icon={modal.isDangerous ? <Alert size="18px" /> : <Checkmark size="18px" />}
/>
{!forbidden && (
<Button
label={t('common.confirm', 'Confirm') + (secsLeft ? ` (${secsLeft})` : '')}
onClick={confirm}
disabled={!!secsLeft}
primary={modal.isDangerous}
color={modal.isDangerous ? 'status-error' : ''}
icon={modal.isDangerous ? <Alert size="18px" /> : <Checkmark size="18px" />}
/>
)}
</Box>
</Box>
</Layer>
Expand Down
4 changes: 3 additions & 1 deletion src/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,9 @@
"description": "should the wallet let the user shoot himself in the foot?",
"off": "Off - Refuse to execute nonsensical actions",
"on": "On - Allow executing nonsensical actions. Don't blame Oasis!",
"title": "Dangerous mode"
"title": "Dangerous mode",
"youCanButDoYouWant": "You most probably shouldn't do this, but since you have specifically enabled 'dangerous mode' in wallet settings, we won't stop you.",
"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."
},
"delegations": {
"activeDelegations": "Active delegations",
Expand Down

0 comments on commit 3838d62

Please sign in to comment.