Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 16 additions & 22 deletions packages/neuron-ui/src/components/Transfer/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { useCallback, useEffect } from 'react'
import { History } from 'history'
import UILayer, { TransferItem } from 'services/UILayer'
import { TransferItem } from 'services/UILayer'
import { MainActions, actionCreators } from 'containers/MainContent/reducer'
import { Channel, Routes, CapacityUnit } from 'utils/const'
import { CapacityUnit } from 'utils/const'
import initState from 'containers/MainContent/state'

export const useUpdateTransferItem = (dispatch: React.Dispatch<any>) =>
Expand Down Expand Up @@ -40,9 +40,9 @@ export const useOnPasswordChange = (dispatch: React.Dispatch<any>) =>
[dispatch],
)

export const useOnConfirm = (dispatch: React.Dispatch<any>) =>
export const useOnConfirm = (dispatch: React.Dispatch<any>, setLoading: Function) =>
useCallback(
(items: TransferItem[], pwd: string) => () => {
(id: string, items: TransferItem[], pwd: string) => () => {
dispatch({
type: MainActions.SetDialog,
payload: {
Expand All @@ -53,16 +53,18 @@ export const useOnConfirm = (dispatch: React.Dispatch<any>) =>
type: MainActions.UpdatePassword,
payload: '',
})
setLoading(true)
setTimeout(() => {
dispatch(
actionCreators.confirmTransfer({
id,
items,
password: pwd,
}),
)
}, 10)
},
[dispatch],
[dispatch, setLoading],
)

export const useOnItemChange = (updateTransferItem: Function) => (field: string, idx: number) => (
Expand Down Expand Up @@ -94,37 +96,29 @@ export const useInitialize = (
if (address) {
updateTransferItem('address')(0)(address)
}
UILayer.on(Channel.SendCapacity, (_e: Event, args: ChannelResponse<string>) => {
if (args.status) {
history.push(`${Routes.Transaction}/${args.result}`)
} else {
dispatch({
type: MainActions.UpdateTransfer,
payload: {
submitting: false,
},
})
dispatch({
type: MainActions.ErrorMessage,
payload: { transfer: args.msg },
})
}
})
return () => {
UILayer.removeAllListeners(Channel.SendCapacity)
dispatch({
type: MainActions.UpdateTransfer,
payload: initState.transfer,
})
}
}, [address, dispatch, history, updateTransferItem])

export const useMessageListener = (id: string, messageId: string | null, title: string, setLoading: Function) => {
useEffect(() => {
if (title === 'Transaction' && messageId === id) {
setLoading(false)
}
}, [title, messageId, id, setLoading])
}

export default {
useUpdateTransferItem,
useOnSubmit,
useOnPasswordChange,
useOnConfirm,
useOnItemChange,
useDropdownItems,
useMessageListener,
useInitialize,
}
36 changes: 20 additions & 16 deletions packages/neuron-ui/src/components/Transfer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import React, { useState, useMemo } from 'react'
import { RouteComponentProps } from 'react-router-dom'
import { Container, Row, Col, Card, Form, Button, Alert, InputGroup } from 'react-bootstrap'
import { useTranslation } from 'react-i18next'
Expand All @@ -15,6 +15,8 @@ import { ContentProps } from 'containers/MainContent'
import { useOnDialogCancel } from 'containers/MainContent/hooks'
import { PlaceHolders } from 'utils/const'

import { useNeuronWallet } from 'utils/hooks'

import {
useUpdateTransferItem,
useOnSubmit,
Expand All @@ -23,6 +25,7 @@ import {
useOnItemChange,
useDropdownItems,
useInitialize,
useMessageListener,
} from './hooks'

const Transfer = ({
Expand All @@ -38,13 +41,23 @@ const Transfer = ({
}: React.PropsWithoutRef<ContentProps & RouteComponentProps<{ address: string }>>) => {
const { t } = useTranslation()

const id = useMemo(() => Math.round(Math.random() * 1000).toString(), [])

const { messages } = useNeuronWallet()

const [loading, setLoading] = useState(false)

const lastMessage = messages[messages.length - 1] || { title: '', id: null }

useMessageListener(id, lastMessage.id, lastMessage.title, setLoading)

const updateTransferItem = useUpdateTransferItem(dispatch)

const onSubmit = useOnSubmit(dispatch)

const onPasswordChange = useOnPasswordChange(dispatch)

const onConfirm = useOnConfirm(dispatch)
const onConfirm = useOnConfirm(dispatch, setLoading)

const onCancel = useOnDialogCancel(dispatch)

Expand All @@ -54,8 +67,6 @@ const Transfer = ({

useInitialize(address, dispatch, history, updateTransferItem)

const disabled = transfer.submitting && !errorMsgs.transfer

return (
<Container>
<Card>
Expand All @@ -70,7 +81,7 @@ const Transfer = ({
<Col sm={10}>
<InputGroup>
<Form.Control
disabled={disabled}
disabled={loading}
value={item.address || ''}
onChange={onItemChange('address', idx)}
placeholder={PlaceHolders.transfer.Address}
Expand All @@ -93,7 +104,7 @@ const Transfer = ({
</Form.Group>
<InlineInputWithDropdown
label={t('send.capacity')}
disabled={disabled}
disabled={loading}
value={item.capacity}
placeholder={PlaceHolders.transfer.Capacity}
onChange={onItemChange('capacity', idx)}
Expand All @@ -105,15 +116,8 @@ const Transfer = ({
</div>
))}
</Form>
<Button
type="submit"
variant="primary"
size="lg"
block
disabled={disabled}
onClick={onSubmit(transfer.items)}
>
{disabled ? <Spinner /> : t('send.send')}
<Button type="submit" variant="primary" size="lg" block disabled={loading} onClick={onSubmit(transfer.items)}>
{loading ? <Spinner /> : t('send.send')}
</Button>
</Card.Body>
</Card>
Expand All @@ -123,7 +127,7 @@ const Transfer = ({
message={<TransferItemList items={transfer.items} />}
password={password}
onChange={onPasswordChange}
onSubmit={onConfirm(transfer.items, password)}
onSubmit={onConfirm(id, transfer.items, password)}
onCancel={onCancel}
/>
</Dialog>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { sendCapacity, TransferItem } from 'services/UILayer'
import { walletsCall, TransferItem } from 'services/UILayer'

import { Message } from 'utils/const'
import { verifyAddress } from 'utils/validators'
Expand All @@ -7,7 +7,6 @@ import { MainActions } from '../reducer'

export default {
submitTransfer: (items: TransferItem[]) => {
// TODO: verification
const errorAction = {
type: MainActions.ErrorMessage,
payload: {
Expand All @@ -23,7 +22,7 @@ export default {
errorAction.payload.transfer = Message.InvalidAddress
return true
}
if (+item.capacity < 0) {
if (Number.isNaN(+item.capacity) || +item.capacity < 0) {
errorAction.payload.transfer = Message.InvalidCapacity
return true
}
Expand All @@ -42,8 +41,8 @@ export default {
}
},

confirmTransfer: ({ items, password }: { items: TransferItem[]; password: string }) => {
sendCapacity(items, password)
confirmTransfer: ({ id, items, password }: { id: string; items: TransferItem[]; password: string }) => {
walletsCall.sendCapacity({ id, items, password })
return {
type: MainActions.UpdateTransfer,
payload: {
Expand Down
13 changes: 10 additions & 3 deletions packages/neuron-ui/src/containers/Providers/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,23 +138,30 @@ export const useChannelListeners = (i18n: any, chain: any, dispatch: React.Dispa
})
break
}
case WalletsMethod.SendCapacity: {
history.push(`${Routes.Transaction}/${args.result}`)
break
}
default: {
break
}
}
} else {
const time = new Date().getTime()
if (method === WalletsMethod.GetActive) {
// don't show this error in wizard view
return
}
const title = method === WalletsMethod.SendCapacity ? 'Transaction' : 'Wallet'
const { content, id } =
typeof args.msg === 'string' ? { content: args.msg, id: null } : args.msg || { content: '', id: null }

dispatch({
type: ProviderActions.AddMessage,
payload: {
category: 'danger',
title: 'Wallet',
content: args.msg,
title,
id,
content,
time,
actions: [],
dismiss: () => {
Expand Down
9 changes: 9 additions & 0 deletions packages/neuron-ui/src/services/UILayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export enum WalletsMethod {
GetActive = 'getActive',
Activate = 'activate',
Backup = 'backup',
SendCapacity = 'sendCapacity',
}

export enum NetworksMethod {
Expand Down Expand Up @@ -151,6 +152,14 @@ export const walletsCall = instantiateMethodCall(wallets) as {
getActive: () => void
activate: (id: string) => void
backup: (id: string) => void
sendCapacity: (params: {
id: string
items: {
address: string
capacity: string
}[]
password: string
}) => void
}

export const helpers = (method: HelpersMethod, ...params: any) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/neuron-ui/src/utils/const.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const MAX_NETWORK_NAME_LENGTH = 28
export const ADDRESS_LENGTH = 40
export const ADDRESS_LENGTH = 50
export const PAGE_SIZE = 15
export const EXPLORER = 'http://localhost:3000'
export const UNREMOVABLE_NETWORK = 'Testnet'
Expand Down
1 change: 1 addition & 0 deletions packages/neuron-ui/src/widgets/BannerMessages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const ActionZone = styled.div`
export interface Message {
title: string
content: string
id: string | null
time: number
category: 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light'
actions: { label: string; action: React.MouseEventHandler | string }[]
Expand Down
2 changes: 1 addition & 1 deletion packages/neuron-ui/src/widgets/QRScanner/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ const QRScanner = ({ title, label, onConfirm, styles }: QRScannerProps) => {
onClick={() => {
setOpen(true)
}}
onKeyPress={() => setOpen(true)}
onKeyPress={() => {}}
type="button"
>
<ScanIcon />
Expand Down
58 changes: 3 additions & 55 deletions packages/neuron-wallet/src/channel/listeners.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ipcMain, Notification } from 'electron'
import { ipcMain } from 'electron'
import { Channel } from '../utils/const'
import { wallets, verifyPassword, transactionHashGen } from '../mock'
import { wallets, verifyPassword } from '../mock'
import { ResponseCode } from './wallet'
import NetworksController from '../controllers/networks'
import TransactionsController from '../controllers/transactions'
Expand Down Expand Up @@ -31,15 +31,7 @@ const checkPassword = (walletID: string, password: string) => {

export default class Listeners {
static start = (
methods: string[] = [
'getBalance',
'checkWalletPassword',
'sendCapacity',
'networks',
'wallets',
'transactions',
'helpers',
],
methods: string[] = ['getBalance', 'checkWalletPassword', 'networks', 'wallets', 'transactions', 'helpers'],
) => {
methods.forEach(method => {
const descriptor = Object.getOwnPropertyDescriptor(Listeners, method)
Expand Down Expand Up @@ -79,50 +71,6 @@ export default class Listeners {
})
}

/**
* @static sendCapacity
* @memberof ChannelListeners
* @description channel to send capacity
*/
static sendCapacity = () => {
return ipcMain.on(
Channel.SendCapacity,
(
e: Electron.Event,
{ items, password }: { items: { address: string; capacity: string; unit: string }[]; password: string },
) => {
setTimeout(() => {
const hash = transactionHashGen()
if (!items.length || !items[0].address) {
e.sender.send(Channel.SendCapacity, {
status: ResponseCode.Fail,
msg: 'Address not specified',
})
return
}
// TODO: verify password
// TODO: verify capacity
const notification = new Notification({
title: `Send Capacity`,
body: `Send Capacity to CKB with ${JSON.stringify(
{
items,
password,
},
null,
2,
)}`,
})
notification.show()
e.sender.send(Channel.SendCapacity, {
status: ResponseCode.Success,
result: hash,
})
}, 3000)
},
)
}

/**
* @method networks
* @memberof ChannelListeners
Expand Down
Loading