From ce43d586584fbf460e7af700aa9e31ec566e9bce Mon Sep 17 00:00:00 2001 From: manhtai Date: Sun, 25 Jul 2021 13:16:01 +0700 Subject: [PATCH 1/2] QRCode reader --- README.md | 1 + package.json | 3 + src/components/Main.tsx | 7 ++ src/components/qrcode/QrCodeGenerator.tsx | 7 +- src/components/qrcode/QrCodeReader.tsx | 85 +++++++++++++++++++++++ src/helpers/fontAwesome.ts | 4 +- src/main.dev.ts | 29 ++++++-- yarn.lock | 17 +++++ 8 files changed, 143 insertions(+), 10 deletions(-) create mode 100644 src/components/qrcode/QrCodeReader.tsx diff --git a/README.md b/README.md index 3c6bcd2..98816f5 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ - [x] Markdown to HTML Converter - [x] HTML Preview - [x] QRCode Generator +- [x] QRCode Reader - [x] Base64 Encode/Decode - [x] Text Diff - [x] JSON Formatter diff --git a/package.json b/package.json index 9a2177a..ce9086f 100644 --- a/package.json +++ b/package.json @@ -172,6 +172,7 @@ "@types/jest": "^26.0.15", "@types/marked": "^2.0.4", "@types/node": "14.14.10", + "@types/pngjs": "^6.0.1", "@types/qrcode": "^1.4.1", "@types/react": "^16.9.44", "@types/react-dom": "^16.9.9", @@ -258,7 +259,9 @@ "electron-log": "^4.2.4", "electron-updater": "^4.3.4", "history": "^5.0.0", + "jsqr": "^1.4.0", "marked": "^2.1.3", + "pngjs": "^6.0.0", "qrcode": "^1.4.4", "react": "^17.0.1", "react-dom": "^17.0.1", diff --git a/src/components/Main.tsx b/src/components/Main.tsx index 1a22cd5..1848731 100644 --- a/src/components/Main.tsx +++ b/src/components/Main.tsx @@ -11,6 +11,7 @@ import Base64 from './base64/Base64'; import DiffText from './diff/TextDiff'; import SqlFormatter from './sql/SqlFormatter'; import JsonFormatter from './json/JsonFormatter'; +import QRCodeReader from './qrcode/QrCodeReader'; const Main = () => { const routes = [ @@ -38,6 +39,12 @@ const Main = () => { name: 'QRCode Generator', Component: QrCodeGenerator, }, + { + icon: , + path: '/qrcode-reader', + name: 'QRCode Reader', + Component: QRCodeReader, + }, { icon: , path: '/base64-encoder', diff --git a/src/components/qrcode/QrCodeGenerator.tsx b/src/components/qrcode/QrCodeGenerator.tsx index c1fb52a..711683d 100644 --- a/src/components/qrcode/QrCodeGenerator.tsx +++ b/src/components/qrcode/QrCodeGenerator.tsx @@ -2,7 +2,7 @@ import { clipboard, ipcRenderer } from 'electron'; import React, { useState } from 'react'; import { useDebouncedEffect } from '../../helpers/effectHooks'; -const HtmlPreview = () => { +const QRCodeGenerator = () => { const [content, setContent] = useState('https://plainbelt.github.io'); const [qrCode, setQrCode] = useState(); const [opening, setOpening] = useState(false); @@ -34,8 +34,9 @@ const HtmlPreview = () => { const handleSave = async () => { setSaving(true); await ipcRenderer.invoke('save-file', { - content: qrCode, + content: (qrCode || ',').split(',')[1], defaultPath: 'qrcode.png', + encoding: 'base64', }); setSaving(false); }; @@ -84,4 +85,4 @@ const HtmlPreview = () => { ); }; -export default HtmlPreview; +export default QRCodeGenerator; diff --git a/src/components/qrcode/QrCodeReader.tsx b/src/components/qrcode/QrCodeReader.tsx new file mode 100644 index 0000000..ef26dc2 --- /dev/null +++ b/src/components/qrcode/QrCodeReader.tsx @@ -0,0 +1,85 @@ +import { clipboard, ipcRenderer, nativeImage } from 'electron'; +import jsQR from 'jsqr'; +import { PNG } from 'pngjs'; +import React, { useEffect, useState } from 'react'; + +const QRCodeReader = () => { + const [image, setImage] = useState(nativeImage.createEmpty()); + const [content, setContent] = useState(''); + const [opening, setOpening] = useState(false); + const [copied, setCopied] = useState(false); + + const handleOpen = async () => { + setOpening(true); + const filters = [{ name: 'Images', extensions: ['jpg', 'jpeg', 'png'] }]; + const buff = await ipcRenderer.invoke('open-file', filters); + setImage(nativeImage.createFromBuffer(buff)); + setOpening(false); + }; + + const handleClipboard = () => { + setImage(clipboard.readImage()); + }; + + const handleCopy = () => { + setCopied(true); + clipboard.write({ text: content }); + setTimeout(() => setCopied(false), 500); + }; + + useEffect(() => { + try { + const qr = jsQR( + Uint8ClampedArray.from(PNG.sync.read(image.toPNG()).data), + image.getSize().width, + image.getSize().height + ); + setContent(qr?.data || 'No QRCode detected'); + } catch (e) { + setContent('No QRCode detected'); + } + }, [image]); + + return ( +
+
+ + + + + + +
+
+
+ {image && !image.isEmpty() && ( + QRCode + )} +
+