Skip to content

Commit

Permalink
Show Idena bot banner (#753)
Browse files Browse the repository at this point in the history
* Move Idena bot banner to Profile

Made idena bot banner self-containing

* Do not shrink banner

* Add key to the list

* Move to useIdenaBot hook
  • Loading branch information
aidenaio authored Jan 10, 2022
1 parent c706890 commit c1ce281
Show file tree
Hide file tree
Showing 5 changed files with 222 additions and 174 deletions.
8 changes: 8 additions & 0 deletions renderer/pages/profile.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
InviteScoreAlert,
KillIdentityDrawer,
KillForm,
MyIdenaBotAlert,
} from '../screens/profile/components'
import {
PrimaryButton,
Expand Down Expand Up @@ -71,6 +72,7 @@ import {ExportPrivateKeyDialog} from '../screens/settings/containers'
import {useScroll} from '../shared/hooks/use-scroll'
import {ValidationReportSummary} from '../screens/validation-report/components'
import {useTotalValidationScore} from '../screens/validation-report/hooks'
import {useIdenaBot} from '../screens/profile/hooks'

export default function ProfilePage() {
const {
Expand Down Expand Up @@ -210,10 +212,16 @@ export default function ProfilePage() {
IdentityStatus.Newbie,
].includes(status)

const [didConnectIdenaBot, connectIdenaBot] = useIdenaBot()

return (
<>
<InviteProvider>
<Layout syncing={syncing} offline={offline}>
{!didConnectIdenaBot && (
<MyIdenaBotAlert onConnect={connectIdenaBot} />
)}

<Page>
<Stack spacing={8}>
<Stack spacing={6}>
Expand Down
159 changes: 159 additions & 0 deletions renderer/screens/profile/components.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ import {
AlertIcon,
AlertDescription,
useToast,
List,
ListItem,
useDisclosure,
} from '@chakra-ui/core'
import {useTranslation} from 'react-i18next'
import {useMachine} from '@xstate/react'
Expand All @@ -34,6 +37,10 @@ import {
DrawerBody,
Toast,
SuccessAlert,
Checkbox,
DialogFooter,
DialogBody,
Dialog,
} from '../../shared/components/components'
import {PrimaryButton, SecondaryButton} from '../../shared/components/button'
import {
Expand Down Expand Up @@ -839,3 +846,155 @@ export function KillForm({onSuccess, onFail}) {
</Stack>
)
}

export function MyIdenaBotAlert({onConnect}) {
const {t} = useTranslation()

const {state} = useIdentityState()

const myIdenaBotDisclosure = useDisclosure()

const [doNotShowAgain, setDoNotShowAgain] = React.useState()

const connectButtonRef = React.useRef()

// eslint-disable-next-line no-shadow
const eitherState = (...states) => states.some(s => s === state)

return (
<>
<Alert
variant="solid"
justifyContent="center"
flexShrink={0}
boxShadow="0 3px 12px 0 rgb(255 163 102 /0.1), 0 2px 3px 0 rgb(255 163 102 /0.2)"
color="white"
cursor="pointer"
fontWeight={500}
rounded="md"
p={3}
mt={2}
mx={2}
w="auto"
onClick={myIdenaBotDisclosure.onOpen}
>
{t(`Subscribe to @MyIdenaBot to get personalized notifications based on
your status`)}
</Alert>

<Dialog
title="Subscribe to @MyIdenaBot"
size="md"
initialFocusRef={connectButtonRef}
{...myIdenaBotDisclosure}
>
<DialogBody>
<Stack>
<Text>
{t(
`MyIdenaBot reminds you about important actions based on your
identity status:`,
{nsSeparator: '!!'}
)}
</Text>

{eitherState(IdentityStatus.Undefined) && (
<IdenaBotFeatureList
features={[
'next validation reminder',
'notification when you get an invite',
'reminder to activate your invite',
'your validation results when validation consensus is reached',
]}
/>
)}

{eitherState(IdentityStatus.Invite, IdentityStatus.Candidate) && (
<IdenaBotFeatureList
features={[
'next validation reminder',
'your validation results when validation consensus is reached',
]}
/>
)}

{eitherState(IdentityStatus.Newbie) && (
<IdenaBotFeatureList
features={[
'next validation reminder',
'reminder to create flips if you haven’t done it yet and the validation is coming',
'your validation results when validation consensus is reached',
]}
/>
)}

{eitherState(IdentityStatus.Verified, IdentityStatus.Human) && (
<IdenaBotFeatureList
features={[
'next validation reminder',
'reminder to create flips',
'your validation results when validation consensus is reached',
'reminder to share your remaining invites',
'reminder to submit extra flips to get more rewards',
'status update of all your invitees to check if they are ready for the validation (activated invites, submitted flips)',
]}
/>
)}
{eitherState(IdentityStatus.Zombie, IdentityStatus.Suspended) && (
<IdenaBotFeatureList
features={[
'next validation reminder',
'your validation results when validation consensus is reached',
'reminder to share your remaining invites',
'reminder to submit extra flips to get more rewards',
'status update of all your invitees to check if they are ready for the validation (activated invites, submitted flips)',
]}
/>
)}
</Stack>
</DialogBody>
<DialogFooter align="center">
<Checkbox
borderColor="gray.100"
isChecked={doNotShowAgain}
onChange={e => {
setDoNotShowAgain(e.target.checked)
}}
>
{t('Do not show again')}
</Checkbox>
<SecondaryButton
onClick={() => {
myIdenaBotDisclosure.onClose()
if (doNotShowAgain) onConnect()
}}
>
{t('Not now')}
</SecondaryButton>
<PrimaryButton
ref={connectButtonRef}
onClick={() => {
global.openExternal('https://t.me/MyIdenaBot')
onConnect()
}}
>
{t('Connect')}
</PrimaryButton>
</DialogFooter>
</Dialog>
</>
)
}

function IdenaBotFeatureList({features, listSeparator = ';'}) {
return (
<List spacing={1} styleType="'- '">
{features.map((feature, idx) => (
<ListItem key={feature} textTransform="lowercase">
{feature}
{idx < features.length - 1 ? listSeparator : '.'}
</ListItem>
))}
</List>
)
}
53 changes: 53 additions & 0 deletions renderer/screens/profile/hooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import {useMachine} from '@xstate/react'
import {assign, createMachine} from 'xstate'

export function useIdenaBot() {
const [current, send] = useMachine(
createMachine({
context: {
connected: undefined,
},
initial: 'loading',
states: {
loading: {
invoke: {
src: 'loadConnectionStatus',
},
on: {
CONNECTED: 'connected',
DISCONNECTED: 'disconnected',
},
},
connected: {
entry: [assign({connected: true}), 'persist'],
},
disconnected: {
on: {CONNECT: 'connected'},
},
},
}),
{
services: {
loadConnectionStatus: () => cb => {
try {
cb(
JSON.parse(localStorage.getItem('connectIdenaBot'))
? 'CONNECTED'
: 'DISCONNECTED'
)
} catch (e) {
console.error(e)
cb('DISCONNECTED')
}
},
},
actions: {
persist: ({connected}) => {
localStorage.setItem('connectIdenaBot', connected)
},
},
}
)

return [current.context.connected, () => send('CONNECT')]
}
2 changes: 2 additions & 0 deletions renderer/shared/components/components.js
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ export function SuccessAlert({children, ...props}) {
return (
<Alert
status="success"
flexShrink={0}
bg="green.010"
borderWidth="1px"
borderColor="green.050"
Expand All @@ -393,6 +394,7 @@ export function FailAlert({children, ...props}) {
return (
<Alert
status="error"
flexShrink={0}
bg="red.010"
borderWidth="1px"
borderColor="red.050"
Expand Down
Loading

0 comments on commit c1ce281

Please sign in to comment.