From 403ea01769bff8f9a651c933861594f5e5664aff Mon Sep 17 00:00:00 2001 From: CPunisher <1343316114@qq.com> Date: Thu, 14 May 2020 13:07:16 +0800 Subject: [PATCH] [Image box for saving] --- src/api/db.js | 15 ++++---- src/components/app/PartDownload.js | 36 ++++++++++++++----- src/components/app/PartStyles.js | 4 ++- src/components/download/DownloadButton.js | 16 --------- src/components/header/Header.js | 2 +- src/components/param/ParamText.js | 9 ++--- src/containers/{ => app}/InputText.js | 7 ++-- src/containers/app/PartDownloadViewer.js | 35 ++++++++++++++++++- src/containers/download/DownloadJpg.js | 34 ------------------ src/containers/download/DownloadSvg.js | 34 ------------------ src/containers/param/ParamTextViewer.js | 3 +- src/utils/downloader.js | 42 ++++++++++------------- 12 files changed, 104 insertions(+), 133 deletions(-) delete mode 100644 src/components/download/DownloadButton.js rename src/containers/{ => app}/InputText.js (65%) delete mode 100644 src/containers/download/DownloadJpg.js delete mode 100644 src/containers/download/DownloadSvg.js diff --git a/src/api/db.js b/src/api/db.js index 4eed67a..dfab144 100644 --- a/src/api/db.js +++ b/src/api/db.js @@ -7,15 +7,18 @@ const auth = app.auth(); async function login() { await auth.signInAnonymously(); - // const loginState = await auth.getLoginState(); + const loginState = await auth.getLoginState(); + isLogin = loginState } login(); +let isLogin; const db = app.database(); const _ = db.command export function increaseDownloadData(value) { + if (!isLogin) return; db.collection('QRCounter').where({ value: _.eq(value) }).get().then(res => { @@ -25,21 +28,20 @@ export function increaseDownloadData(value) { }).update({ count: _.inc(1), date: new Date().toString() - }).then(res => { - }) + }).catch(console.error) } else { db.collection('QRCounter').add({ value: value, count: 1, date: new Date().toString() - }).then(res => { - }) + }).catch(console.error) } }) } export function recordDownloadDetail({text, value, type, params, history}) { + if (!isLogin) return; db.collection('QRDownloadData').add({ date: new Date().toString(), text: text, @@ -47,6 +49,5 @@ export function recordDownloadDetail({text, value, type, params, history}) { type: type, params: params, history: history - }).then(res => { - }) + }).catch(console.error) } diff --git a/src/components/app/PartDownload.js b/src/components/app/PartDownload.js index ca86092..e0aea5b 100644 --- a/src/components/app/PartDownload.js +++ b/src/components/app/PartDownload.js @@ -1,32 +1,50 @@ -import React from 'react'; +import React, {useState} from 'react'; import './App.css'; -import DownloadSvg from "../../containers/download/DownloadSvg"; -import DownloadJpg from "../../containers/download/DownloadJpg"; +import PropTypes from 'prop-types'; import {isWeiXin} from "../../utils/util"; const WxMessage = () => { if (isWeiXin()) { - return
当前客户端不支持下载,请在浏览器中打开。
+ return
当前客户端不支持下载,请长按图片保存。
} return null } -const PartDownload = ({ value }) => ( -
+const PartDownload = ({ value, onSvgDownload, onJpgDownload }) => { + const [imgData, setImgData] = useState(''); + + return ( +
Downloads

下载二维码 — {value}

- - + +
+
+ { + imgData.length > 0 ? 点击JPG下载 : null + } +
-) + ); +} + +PartDownload.propTypes = { + value: PropTypes.string.isRequired, + onSvgDownload: PropTypes.func.isRequired, + onJpgDownload: PropTypes.func.isRequired, +} export default PartDownload; diff --git a/src/components/app/PartStyles.js b/src/components/app/PartStyles.js index e007dfb..dee3f7b 100644 --- a/src/components/app/PartStyles.js +++ b/src/components/app/PartStyles.js @@ -7,14 +7,16 @@ const PartStyles = ({ setParamInfo }) => { useEffect(() => { setLoaded(true); }, []) + const styleList = React.createElement(StyleListViewer({setParamInfo})) + console.log(loaded) return (
Styles

点击选择样式

-
+
{styleList}
) diff --git a/src/components/download/DownloadButton.js b/src/components/download/DownloadButton.js deleted file mode 100644 index ce510e9..0000000 --- a/src/components/download/DownloadButton.js +++ /dev/null @@ -1,16 +0,0 @@ -import React from "react"; -import PropTypes from 'prop-types' -import '../Qrcode.css'; - -const DownloadButton = ({ onClick, value }) => ( - -) - -DownloadButton.propTypes = { - onClick: PropTypes.func.isRequired, - value: PropTypes.string.isRequired -} - -export default DownloadButton; diff --git a/src/components/header/Header.js b/src/components/header/Header.js index 233fdf0..d65d5cb 100644 --- a/src/components/header/Header.js +++ b/src/components/header/Header.js @@ -1,7 +1,7 @@ import React from "react"; import '../Qrcode.css'; import logo from "../../qrbtf-logo.svg"; -import InputText from "../../containers/InputText"; +import InputText from "../../containers/app/InputText"; const logoStyle = { background: `url(${logo})`, diff --git a/src/components/param/ParamText.js b/src/components/param/ParamText.js index c573290..ee338c6 100644 --- a/src/components/param/ParamText.js +++ b/src/components/param/ParamText.js @@ -2,13 +2,13 @@ import React from 'react'; import PropTypes from 'prop-types' import '../Qrcode.css'; -const ParamText = ({ rendererIndex, paramIndex, value, onBlur, onKeyPress }) => ( +const ParamText = ({ rendererIndex, paramIndex, value, info, onBlur, onKeyPress }) => ( @@ -17,7 +17,8 @@ const ParamText = ({ rendererIndex, paramIndex, value, onBlur, onKeyPress }) => ParamText.propTypes = { rendererIndex: PropTypes.number.isRequired, paramIndex: PropTypes.number.isRequired, - value: PropTypes.string.isRequired, + value: PropTypes.number.isRequired, + info: PropTypes.object.isRequired, onBlur: PropTypes.func.isRequired, onKeyPress: PropTypes.func.isRequired } diff --git a/src/containers/InputText.js b/src/containers/app/InputText.js similarity index 65% rename from src/containers/InputText.js rename to src/containers/app/InputText.js index 5cca40c..b2b6dbe 100644 --- a/src/containers/InputText.js +++ b/src/containers/app/InputText.js @@ -1,5 +1,5 @@ import {connect} from 'react-redux'; -import {genQRInfo} from "../actions"; +import {genQRInfo} from "../../actions"; import React from "react"; const InputText = ({dispatch}) => ( @@ -8,7 +8,10 @@ const InputText = ({dispatch}) => ( placeholder="Input your URL here" onBlur={e => dispatch(genQRInfo(e.target.value))} onKeyPress={(e) => { - if (e.key === 'Enter') dispatch(genQRInfo(e.target.value)) + if (e.key === 'Enter') { + dispatch(genQRInfo(e.target.value)); + e.target.blur(); + } }} /> ) diff --git a/src/containers/app/PartDownloadViewer.js b/src/containers/app/PartDownloadViewer.js index 4662069..ee98091 100644 --- a/src/containers/app/PartDownloadViewer.js +++ b/src/containers/app/PartDownloadViewer.js @@ -1,8 +1,41 @@ import { connect } from 'react-redux'; import PartDownload from "../../components/app/PartDownload"; +import React from "react"; +import {saveImg, saveSvg} from "../../utils/downloader"; +import ReactDOMServer from "react-dom/server"; +import {increaseDownloadData, recordDownloadDetail} from "../../api/db"; +import {getParamDetailedValue} from "../../utils/util"; + +function saveEl(state, type) { + const el = React.createElement(state.rendererType, { + qrcode: state.qrcode, + params: state.paramValue[state.selectedIndex], + setParamInfo: () => {} + }); + increaseDownloadData(state.value) + recordDownloadDetail({ + text: state.textUrl, + value: state.value, + type: type, + params: state.paramInfo[state.selectedIndex].map((item, index) => { + return { + key: item.key, + value: getParamDetailedValue(item, state.paramValue[state.selectedIndex][index]) + } + }), + history: state.history + }); + return el; +} const mapStateToProps = (state) => ({ - value: state.value + value: state.value, + onSvgDownload: () => { + saveSvg(state.value, ReactDOMServer.renderToString(saveEl(state, 'svg'))) + }, + onJpgDownload: () => { + return saveImg(state.value, ReactDOMServer.renderToString(saveEl(state, 'jpg')), 1500, 1500) + } }) export default connect(mapStateToProps, null)(PartDownload) diff --git a/src/containers/download/DownloadJpg.js b/src/containers/download/DownloadJpg.js deleted file mode 100644 index 0631cb6..0000000 --- a/src/containers/download/DownloadJpg.js +++ /dev/null @@ -1,34 +0,0 @@ -import { connect } from 'react-redux'; -import React from 'react'; -import ReactDOMServer from 'react-dom/server' -import DownloadButton from "../../components/download/DownloadButton"; -import {saveImg} from "../../utils/downloader"; -import {increaseDownloadData, recordDownloadDetail} from "../../api/db"; -import {getParamDetailedValue} from "../../utils/util"; - -const mapStateToProps = (state) => ({ - value: 'JPG', - onClick: () => { - const el = React.createElement(state.rendererType, { - qrcode: state.qrcode, - params: state.paramValue[state.selectedIndex], - setParamInfo: () => {} - }); - saveImg(state.value, ReactDOMServer.renderToString(el), 1500, 1500); - increaseDownloadData(state.value) - recordDownloadDetail({ - text: state.textUrl, - value: state.value, - type: 'jpg', - params: state.paramInfo[state.selectedIndex].map((item, index) => { - return { - key: item.key, - value: getParamDetailedValue(item, state.paramValue[state.selectedIndex][index]) - } - }), - history: state.history - }); - } -}); - -export default connect(mapStateToProps, null)(DownloadButton) diff --git a/src/containers/download/DownloadSvg.js b/src/containers/download/DownloadSvg.js deleted file mode 100644 index 1c41b5d..0000000 --- a/src/containers/download/DownloadSvg.js +++ /dev/null @@ -1,34 +0,0 @@ -import { connect } from 'react-redux'; -import React from 'react'; -import ReactDOMServer from 'react-dom/server' -import DownloadButton from "../../components/download/DownloadButton"; -import {saveSvg} from "../../utils/downloader"; -import {increaseDownloadData, recordDownloadDetail} from "../../api/db"; -import {getParamDetailedValue} from "../../utils/util"; - -const mapStateToProps = (state) => ({ - value: 'SVG', - onClick: () => { - const el = React.createElement(state.rendererType, { - qrcode: state.qrcode, - params: state.paramValue[state.selectedIndex], - setParamInfo: () => {} - }); - saveSvg(state.value, ReactDOMServer.renderToString(el)); - increaseDownloadData(state.value) - recordDownloadDetail({ - text: state.textUrl, - value: state.value, - type: 'svg', - params: state.paramInfo[state.selectedIndex].map((item, index) => { - return { - key: item.key, - value: getParamDetailedValue(item, state.paramValue[state.selectedIndex][index]) - } - }), - history: state.history - }); - } -}); - -export default connect(mapStateToProps, null)(DownloadButton) diff --git a/src/containers/param/ParamTextViewer.js b/src/containers/param/ParamTextViewer.js index 9c856ec..2b27216 100644 --- a/src/containers/param/ParamTextViewer.js +++ b/src/containers/param/ParamTextViewer.js @@ -5,7 +5,8 @@ import {changeParam} from "../../actions"; const mapStateToProps = (state, ownProps) => ({ rendererIndex: ownProps.rendererIndex, paramIndex: ownProps.paramIndex, - value: String(state.paramValue[ownProps.rendererIndex][ownProps.paramIndex]) + value: state.paramValue[ownProps.rendererIndex][ownProps.paramIndex], + info: state.paramInfo[ownProps.rendererIndex][ownProps.paramIndex] }) const mapDispatchToProps = (dispatch, ownProps) => ({ diff --git a/src/utils/downloader.js b/src/utils/downloader.js index 75a0548..7cfe63b 100644 --- a/src/utils/downloader.js +++ b/src/utils/downloader.js @@ -1,5 +1,3 @@ -import {increaseDownloadData} from "../api/db"; - const svgHead = "\n " + "\n" @@ -17,8 +15,6 @@ export function saveSvg(value, content) { a.download = filename a.hidden = true a.click() - - increaseDownloadData(value, new Date().toString()) } export function saveImg(value, content, width, height) { @@ -43,26 +39,26 @@ export function saveImg(value, content, width, height) { canvas.setAttribute('height', height); let ctx = canvas.getContext('2d'); - let img = document.createElement('img'); - - - img.onload = () => { - ctx.fillStyle = 'white' - ctx.fillRect(0, 0, width, height) - ctx.drawImage(img, 0, 0, width, height); - // `download` attr is not well supported - // Will result in a download popup for chrome and the - // image opening in a new tab for others. - - let a = document.createElement('a'); - a.setAttribute('href', canvas.toDataURL('image/jpeg', 0.8)) - a.setAttribute('target', 'download') - a.setAttribute('download', filename); - a.click(); - }; - img.setAttribute('src', 'data:image/svg+xml;base64,' + btoa(svgData)); - increaseDownloadData(value, new Date().toString()) + return new Promise(resolve => { + img.onload = () => { + ctx.fillStyle = 'white' + ctx.fillRect(0, 0, width, height) + ctx.drawImage(img, 0, 0, width, height); + // `download` attr is not well supported + // Will result in a download popup for chrome and the + // image opening in a new tab for others. + + let a = document.createElement('a'); + let data = canvas.toDataURL('image/jpeg', 0.8); + a.setAttribute('href', data) + a.setAttribute('target', 'download') + a.setAttribute('download', filename); + a.click(); + + resolve(data) + }; + }) }