Meriadec Pillet
7 years ago
committed by
GitHub
7 changed files with 147 additions and 4 deletions
@ -0,0 +1,85 @@ |
|||
// @flow
|
|||
|
|||
import React, { PureComponent } from 'react' |
|||
|
|||
import { connect } from 'react-redux' |
|||
import type { State } from 'reducers' |
|||
import { getVisibleAccounts } from 'reducers/accounts' |
|||
import QRCode from './base/QRCode' |
|||
|
|||
// encode the app state to export into an array of chunks for the mobile app to understand.
|
|||
// returned data frames are json stringified array with format: [ datalength, index, type, ...rest ]
|
|||
// NB as soon as we have common types we'll move this in a ledgerhq/common project
|
|||
function makeChunks(state: State): Array<string> { |
|||
const chunksFormatVersion = 1 |
|||
const desktopVersion = __APP_VERSION__ |
|||
const data = [ |
|||
['meta', chunksFormatVersion, 'desktop', desktopVersion], |
|||
...getVisibleAccounts(state).map(account => [ |
|||
'account', |
|||
account.id, |
|||
account.name, |
|||
account.coinType, |
|||
]), |
|||
] |
|||
return data.map((arr, i) => JSON.stringify([data.length, i, ...arr])) |
|||
} |
|||
|
|||
const mapStateToProps = (state: State) => ({ chunks: makeChunks(state) }) |
|||
|
|||
class QRCodeExporter extends PureComponent< |
|||
{ |
|||
chunks: string[], |
|||
fps: number, |
|||
size: number, |
|||
}, |
|||
{ |
|||
frame: number, |
|||
}, |
|||
> { |
|||
static defaultProps = { |
|||
fps: 10, |
|||
size: 480, |
|||
} |
|||
|
|||
state = { |
|||
frame: 0, |
|||
} |
|||
|
|||
componentDidMount() { |
|||
const nextFrame = ({ frame }, { chunks }) => ({ |
|||
frame: (frame + 1) % chunks.length, |
|||
}) |
|||
let lastT |
|||
const loop = t => { |
|||
this._raf = requestAnimationFrame(loop) |
|||
if (!lastT) lastT = t |
|||
if ((t - lastT) * this.props.fps < 1000) return |
|||
lastT = t |
|||
this.setState(nextFrame) |
|||
} |
|||
this._raf = requestAnimationFrame(loop) |
|||
} |
|||
|
|||
componentWillUnmount() { |
|||
cancelAnimationFrame(this._raf) |
|||
} |
|||
|
|||
_raf: * |
|||
|
|||
render() { |
|||
const { frame } = this.state |
|||
const { chunks, size } = this.props |
|||
return ( |
|||
<div style={{ position: 'relative', width: size, height: size }}> |
|||
{chunks.map((chunk, i) => ( |
|||
<div key={String(i)} style={{ position: 'absolute', opacity: i === frame ? 1 : 0 }}> |
|||
<QRCode data={chunk} size={size} /> |
|||
</div> |
|||
))} |
|||
</div> |
|||
) |
|||
} |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(QRCodeExporter) |
@ -0,0 +1,53 @@ |
|||
// @flow
|
|||
|
|||
import React, { PureComponent } from 'react' |
|||
|
|||
import Box, { Card } from 'components/base/Box' |
|||
import Modal, { ModalBody } from 'components/base/Modal' |
|||
import Button from 'components/base/Button' |
|||
import QRCodeExporter from 'components/QRCodeExporter' |
|||
|
|||
class TabProfile extends PureComponent<*, *> { |
|||
state = { |
|||
qrcodeMobileExportModal: false, |
|||
} |
|||
|
|||
onQRCodeMobileExport = () => { |
|||
this.setState({ qrcodeMobileExportModal: true }) |
|||
} |
|||
|
|||
onRequestClose = () => { |
|||
this.setState({ qrcodeMobileExportModal: false }) |
|||
} |
|||
|
|||
renderQRCodeModal = ({ onClose }: *) => ( |
|||
<ModalBody onClick={onClose} justify="center" align="center"> |
|||
<p style={{ padding: '1em' }}> |
|||
{/* TODO translate */} |
|||
Open Ledger Wallet Mobile App, go to <strong>Settings {'>'} Import Accounts</strong> |
|||
</p> |
|||
<QRCodeExporter /> |
|||
</ModalBody> |
|||
) |
|||
|
|||
render() { |
|||
const { qrcodeMobileExportModal } = this.state |
|||
return ( |
|||
<Card flow={3}> |
|||
<Box horizontal> |
|||
<Button onClick={this.onQRCodeMobileExport} primary> |
|||
QRCode Mobile Export |
|||
</Button> |
|||
|
|||
<Modal |
|||
isOpened={qrcodeMobileExportModal} |
|||
onClose={this.onRequestClose} |
|||
render={this.renderQRCodeModal} |
|||
/> |
|||
</Box> |
|||
</Card> |
|||
) |
|||
} |
|||
} |
|||
|
|||
export default TabProfile |
Loading…
Reference in new issue