Browse Source

Merge pull request #225 from gre/export

qrcode export
master
Meriadec Pillet 7 years ago
committed by GitHub
parent
commit
bf367c6a1d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      .eslintrc
  2. 1
      flow-defs/globals.js
  3. 85
      src/components/QRCodeExporter.js
  4. 53
      src/components/SettingsPage/Tools.js
  5. 4
      src/components/SettingsPage/index.js
  6. 2
      src/components/base/QRCode/index.js
  7. 3
      webpack/plugins.js

3
.eslintrc

@ -10,6 +10,7 @@
"__SENTRY_URL__": false,
"__PRINT_MODE__": false,
"__GLOBAL_STYLES__": false,
"__APP_VERSION__": false,
"__static": false,
"window": false,
"document": false,
@ -20,6 +21,8 @@
"test": false,
"it": false,
"expect": false,
"requestAnimationFrame": false,
"cancelAnimationFrame": false
},
"rules": {
"camelcase": 0,

1
flow-defs/globals.js

@ -7,6 +7,7 @@ declare var __ENV__: string
declare var __PRINT_MODE__: string
declare var __SENTRY_URL__: string
declare var __GLOBAL_STYLES__: string
declare var __APP_VERSION__: string
declare var __static: string
declare var describe: Function
declare var test: Function

85
src/components/QRCodeExporter.js

@ -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)

53
src/components/SettingsPage/Tools.js

@ -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

4
src/components/SettingsPage/index.js

@ -18,6 +18,7 @@ import Tabs from 'components/base/Tabs'
import TabDisplay from './Display'
import TabProfile from './Profile'
import TabTools from './Tools'
import TabMoney from './Money'
const mapStateToProps = state => ({
@ -103,9 +104,8 @@ class SettingsPage extends PureComponent<Props, State> {
},
{
key: 'tools',
isDisabled: true,
title: t('settings:tabs.tools'),
render: () => <div>{'Outils'}</div>,
render: () => <TabTools {...props} />,
},
{
key: 'blockchain',

2
src/components/base/QRCode/index.js

@ -5,7 +5,7 @@ import qrcode from 'qrcode'
type Props = {
data: string,
size?: number,
size: number,
}
class QRCode extends PureComponent<Props> {

3
webpack/plugins.js

@ -1,6 +1,6 @@
const webpack = require('webpack')
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
const pkg = require('../package.json')
require('../src/globals')
const { BUNDLE_ANALYZER } = process.env
@ -8,6 +8,7 @@ const { BUNDLE_ANALYZER } = process.env
module.exports = type => {
const plugins = [
new webpack.DefinePlugin({
__APP_VERSION__: JSON.stringify(pkg.version),
__GLOBAL_STYLES__: JSON.stringify(__GLOBAL_STYLES__),
__DEV__,
__PROD__,

Loading…
Cancel
Save