diff --git a/.eslintrc b/.eslintrc
index 1999f835..92e1a84c 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -7,6 +7,7 @@
"__DEV__": false,
"__PROD__": false,
"__SENTRY_URL__": false,
+ "__PRINT_MODE__": false,
"__static": false,
"window": false,
"document": false,
diff --git a/flow-defs/globals.js b/flow-defs/globals.js
index 0ec82500..a373152b 100644
--- a/flow-defs/globals.js
+++ b/flow-defs/globals.js
@@ -3,6 +3,7 @@
declare var __DEV__: boolean
declare var __PROD__: boolean
declare var __ENV__: string
+declare var __PRINT_MODE__: string
declare var __SENTRY_URL__: string
declare var __static: string
diff --git a/package.json b/package.json
index 395612d1..9c031179 100644
--- a/package.json
+++ b/package.json
@@ -69,6 +69,7 @@
"moment": "^2.20.1",
"object-path": "^0.11.4",
"qrcode": "^1.2.0",
+ "query-string": "^5.1.0",
"raven": "^2.4.0",
"raven-js": "^3.22.1",
"react": "^16.2.0",
diff --git a/src/components/App.js b/src/components/App.js
index 0700ac54..fb4e67e9 100644
--- a/src/components/App.js
+++ b/src/components/App.js
@@ -3,6 +3,7 @@
import React from 'react'
import { ThemeProvider } from 'styled-components'
import { ConnectedRouter } from 'react-router-redux'
+import { Switch, Route } from 'react-router'
import { Provider } from 'react-redux'
import { I18nextProvider } from 'react-i18next'
@@ -11,6 +12,7 @@ import theme from 'styles/theme'
import i18n from 'renderer/i18n'
import Wrapper from 'components/Wrapper'
+import PrintWrapper from 'components/PrintWrapper'
export default ({
store,
@@ -25,7 +27,10 @@ export default ({
-
+
+
+
+
diff --git a/src/components/PrintWrapper.js b/src/components/PrintWrapper.js
new file mode 100644
index 00000000..da4e4fe9
--- /dev/null
+++ b/src/components/PrintWrapper.js
@@ -0,0 +1,52 @@
+// @flow
+
+import React, { PureComponent } from 'react'
+import { remote } from 'electron'
+import queryString from 'query-string'
+
+import QRCode from 'components/base/QRCode'
+import Box from 'components/base/Box'
+import { AddressBox } from 'components/ReceiveBox'
+
+type State = {
+ data: Object | null,
+}
+
+class PrintWrapper extends PureComponent {
+ state = {
+ data: null,
+ }
+
+ componentWillMount() {
+ this.setState({
+ data: queryString.parse(this.props.location.search),
+ })
+ }
+
+ componentDidMount() {
+ window.requestAnimationFrame(() =>
+ setTimeout(() => {
+ // hacky way to detect that render is ready
+ // from the parent window
+ remote.getCurrentWindow().minimize()
+ }, 300),
+ )
+ }
+
+ render() {
+ const { data } = this.state
+ if (!data) {
+ return null
+ }
+ const { address, amount } = data
+ return (
+
+
+ {address}
+ {amount && {amount}}
+
+ )
+ }
+}
+
+export default PrintWrapper
diff --git a/src/components/ReceiveBox.js b/src/components/ReceiveBox.js
index 1600f8ef..9f24335f 100644
--- a/src/components/ReceiveBox.js
+++ b/src/components/ReceiveBox.js
@@ -8,13 +8,14 @@ import QRCode from 'components/base/QRCode'
import Icon from 'components/base/Icon'
import CopyToClipboard from 'components/base/CopyToClipboard'
import Text from 'components/base/Text'
+import Print from 'components/base/Print'
type Props = {
amount?: string,
address: string,
}
-const AddressBox = styled(Box).attrs({
+export const AddressBox = styled(Box).attrs({
borderWidth: 1,
borderColor: 'mouse',
bg: 'cream',
@@ -63,10 +64,15 @@ const ReceiveBox = ({ amount, address }: Props) => (
)}
/>
-
-
- {'Print'}
-
+ (
+
+
+ {isLoading ? '...' : 'Print'}
+
+ )}
+ />
{'Share'}
diff --git a/src/components/base/Print.js b/src/components/base/Print.js
new file mode 100644
index 00000000..1c1224e0
--- /dev/null
+++ b/src/components/base/Print.js
@@ -0,0 +1,61 @@
+// @flow
+
+import { PureComponent } from 'react'
+import { remote } from 'electron'
+import queryString from 'query-string'
+
+const { BrowserWindow } = remote
+
+type Props = {
+ render: Function,
+ data: Object,
+}
+
+type State = {
+ isLoading: boolean,
+}
+
+class Print extends PureComponent {
+ state = {
+ isLoading: false,
+ }
+
+ handlePrint = () => {
+ const { data } = this.props
+
+ this.setState({ isLoading: true })
+
+ const w = new BrowserWindow({
+ show: false,
+ webPreferences: {
+ // Enable, among other things, the ResizeObserver
+ experimentalFeatures: true,
+ },
+ })
+
+ w.webContents.openDevTools()
+
+ const url = __DEV__
+ ? `http://localhost:${process.env.ELECTRON_WEBPACK_WDS_PORT || ''}`
+ : `file://${__dirname}/index.html`
+
+ w.loadURL(`${url}/#/print?${queryString.stringify(data)}`)
+
+ w.webContents.on('did-finish-load', () => {
+ w.on('minimize', () => {
+ w.webContents.print({}, () => {
+ w.destroy()
+ this.setState({ isLoading: false })
+ })
+ })
+ })
+ }
+
+ render() {
+ const { render } = this.props
+ const { isLoading } = this.state
+ return render(this.handlePrint, isLoading)
+ }
+}
+
+export default Print
diff --git a/src/renderer/index.js b/src/renderer/index.js
index b1b86301..6529d14b 100644
--- a/src/renderer/index.js
+++ b/src/renderer/index.js
@@ -35,6 +35,8 @@ const history = createHistory()
const store = createStore(history)
const rootNode = document.getElementById('app')
+global.__PRINT_MODE__ = history.location.pathname.startsWith('/print')
+
store.dispatch(fetchSettings())
const state = store.getState() || {}
@@ -53,7 +55,9 @@ function r(Comp) {
r()
-events({ store, locked })
+if (!__PRINT_MODE__) {
+ events({ store, locked })
+}
if (module.hot) {
module.hot.accept('../components/App', () => {
diff --git a/yarn.lock b/yarn.lock
index 7cb9219d..1f019e70 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7370,6 +7370,14 @@ query-string@^5.0.0:
object-assign "^4.1.0"
strict-uri-encode "^1.0.0"
+query-string@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.0.tgz#9583b15fd1307f899e973ed418886426a9976469"
+ dependencies:
+ decode-uri-component "^0.2.0"
+ object-assign "^4.1.0"
+ strict-uri-encode "^1.0.0"
+
querystring-es3@^0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"