Skip to content

Commit 3838d62

Browse files
committed
Modals: improve handling of danger, add delays
1 parent 03b0c9c commit 3838d62

File tree

2 files changed

+68
-10
lines changed

2 files changed

+68
-10
lines changed

src/app/components/Modal/index.tsx

Lines changed: 65 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,29 @@
1-
import { createContext, useCallback, useContext, useState } from 'react'
1+
import React from 'react'
2+
import { createContext, useCallback, useContext, useEffect, useState } from 'react'
23
import { Box, Button, Layer, Heading, Paragraph } from 'grommet'
34
import { useTranslation } from 'react-i18next'
45
import { Alert, Checkmark, Close } from 'grommet-icons/icons'
6+
import { AlertBox } from '../AlertBox'
7+
import { useDangerModeSetting } from '../SettingsDialog/slice/selectors'
58

69
interface Modal {
710
title: string
811
description: string
912
handleConfirm: () => void
13+
14+
/**
15+
* Is this a dangerous operation?
16+
*
17+
* If marked as such, it will only be possible to execute it if the wallet is configured to run in dangerous mode.
18+
*
19+
* It also automatically implies a mandatory waiting time of 10 sec, unless specified otherwise.
20+
*/
1021
isDangerous: boolean
22+
23+
/**
24+
* How long does the user have to wait before he can actually confirm the action?
25+
*/
26+
mustWaitSecs?: number
1127
}
1228

1329
interface ModalContainerProps {
@@ -32,27 +48,67 @@ const ModalContainer = ({ modal, closeModal }: ModalContainerProps) => {
3248
modal.handleConfirm()
3349
closeModal()
3450
}, [closeModal, modal])
51+
const { isDangerous, mustWaitSecs } = modal
52+
const dangerMode = useDangerModeSetting()
53+
const forbidden = isDangerous && !dangerMode
54+
const waitingTime = forbidden
55+
? 0 // If the action is forbidden, there is nothing to wait for
56+
: isDangerous
57+
? mustWaitSecs === undefined
58+
? 10 // For dangerous actions, we require 10 seconds of waiting ...
59+
: mustWaitSecs // unless specified otherwise.
60+
: mustWaitSecs || 0 // For normal, non-dangerous operations, just use what was specified
61+
62+
const [secsLeft, setSecsLeft] = useState(0)
63+
64+
useEffect(() => {
65+
if (waitingTime) {
66+
setSecsLeft(waitingTime)
67+
const interval = setInterval(() => {
68+
setSecsLeft(seconds => (seconds ? seconds - 1 : 0))
69+
}, 1000)
70+
return () => clearInterval(interval)
71+
}
72+
}, [waitingTime])
3573

3674
return (
3775
<Layer modal onEsc={closeModal} onClickOutside={closeModal} background="background-front">
3876
<Box margin="medium">
3977
<Heading size="small">{modal.title}</Heading>
4078
<Paragraph fill>{modal.description}</Paragraph>
79+
{forbidden && (
80+
<AlertBox color={'status-error'}>
81+
{t(
82+
'dangerMode.youDontWantThis',
83+
"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.",
84+
)}
85+
</AlertBox>
86+
)}
87+
{isDangerous && dangerMode && (
88+
<AlertBox color={'status-warning'}>
89+
{t(
90+
'dangerMode.youCanButDoYouWant',
91+
"You most probably shouldn't do this, but since you have specifically enabled 'dangerous mode' in wallet settings, we won't stop you.",
92+
)}
93+
</AlertBox>
94+
)}
4195
<Box direction="row" gap="small" alignSelf="end" pad={{ top: 'large' }}>
4296
<Button
4397
label={t('common.cancel', 'Cancel')}
4498
onClick={closeModal}
4599
secondary
46100
icon={<Close size="18px" />}
47101
/>
48-
<Button
49-
label={t('common.confirm', 'Confirm')}
50-
onClick={confirm}
51-
disabled={modal.isDangerous}
52-
primary={modal.isDangerous}
53-
color={modal.isDangerous ? 'status-error' : ''}
54-
icon={modal.isDangerous ? <Alert size="18px" /> : <Checkmark size="18px" />}
55-
/>
102+
{!forbidden && (
103+
<Button
104+
label={t('common.confirm', 'Confirm') + (secsLeft ? ` (${secsLeft})` : '')}
105+
onClick={confirm}
106+
disabled={!!secsLeft}
107+
primary={modal.isDangerous}
108+
color={modal.isDangerous ? 'status-error' : ''}
109+
icon={modal.isDangerous ? <Alert size="18px" /> : <Checkmark size="18px" />}
110+
/>
111+
)}
56112
</Box>
57113
</Box>
58114
</Layer>

src/locales/en/translation.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@
123123
"description": "should the wallet let the user shoot himself in the foot?",
124124
"off": "Off - Refuse to execute nonsensical actions",
125125
"on": "On - Allow executing nonsensical actions. Don't blame Oasis!",
126-
"title": "Dangerous mode"
126+
"title": "Dangerous mode",
127+
"youCanButDoYouWant": "You most probably shouldn't do this, but since you have specifically enabled 'dangerous mode' in wallet settings, we won't stop you.",
128+
"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."
127129
},
128130
"delegations": {
129131
"activeDelegations": "Active delegations",

0 commit comments

Comments
 (0)