Skip to content

Commit 63d4c20

Browse files
committed
Qrcode generator
1 parent 54f0954 commit 63d4c20

File tree

6 files changed

+165
-5
lines changed

6 files changed

+165
-5
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@
177177
"@types/webpack-env": "^1.15.2",
178178
"@typescript-eslint/eslint-plugin": "^4.8.1",
179179
"@typescript-eslint/parser": "^4.8.1",
180+
"@types/qrcode": "^1.4.1",
180181
"autoprefixer": "^10.3.1",
181182
"babel-eslint": "^10.1.0",
182183
"babel-jest": "^26.1.0",
@@ -254,6 +255,7 @@
254255
"electron-updater": "^4.3.4",
255256
"history": "^5.0.0",
256257
"marked": "^2.1.3",
258+
"qrcode": "^1.4.4",
257259
"react": "^17.0.1",
258260
"react-dom": "^17.0.1",
259261
"react-router-dom": "^5.2.0",

src/components/Main.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
44
import MarkdownToHtml from './md-to-html/MarkdownToHtml';
55
import UnixTimestamp from './unix-timestamp/UnixTimestamp';
66
import HtmlPreview from './html-preview/HtmlPreview';
7+
import QrCode from './qrcode/QrCode';
78

89
const Main = () => {
910
const routes = [
@@ -25,6 +26,12 @@ const Main = () => {
2526
name: 'HTML Preview',
2627
Component: HtmlPreview,
2728
},
29+
{
30+
icon: <FontAwesomeIcon icon="qrcode" />,
31+
path: '/qrcode-generator',
32+
name: 'QRCode generator',
33+
Component: QrCode,
34+
},
2835
];
2936

3037
return (

src/components/qrcode/QrCode.tsx

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { ipcRenderer } from 'electron';
2+
import React, { useEffect, useState } from 'react';
3+
4+
const HtmlPreview = () => {
5+
const [content, setContent] = useState('https://plainbelt.github.io');
6+
const [qrCode, setQrCode] = useState();
7+
const [opening, setOpening] = useState(false);
8+
const [saving, setSaving] = useState(false);
9+
10+
useEffect(() => {
11+
ipcRenderer
12+
.invoke('generate-qrcode', { content })
13+
.then((qr) => setQrCode(qr))
14+
.catch(() => {});
15+
});
16+
17+
const handleChange = async (evt: { target: { value: string } }) => {
18+
setContent(evt.target.value);
19+
const qr = await ipcRenderer.invoke('generate-qrcode', { content });
20+
setQrCode(qr);
21+
};
22+
23+
const handleOpen = async () => {
24+
setOpening(true);
25+
const filters = [{ name: 'Text Files', extensions: ['txt'] }];
26+
const data = await ipcRenderer.invoke('open-file', filters);
27+
setContent(data);
28+
setOpening(false);
29+
};
30+
31+
const handleSave = async () => {
32+
setSaving(true);
33+
await ipcRenderer.invoke('save-file', {
34+
content: qrCode,
35+
defaultPath: 'qrcode.png',
36+
});
37+
setSaving(false);
38+
};
39+
40+
return (
41+
<div className="min-h-full flex flex-col">
42+
<div className="flex justify-between mb-1">
43+
<button
44+
type="button"
45+
className="btn"
46+
onClick={handleOpen}
47+
disabled={opening}
48+
>
49+
Open...
50+
</button>
51+
<button
52+
type="button"
53+
className="btn"
54+
onClick={handleSave}
55+
disabled={saving}
56+
>
57+
Save...
58+
</button>
59+
</div>
60+
<div className="flex min-h-full">
61+
<textarea
62+
onChange={handleChange}
63+
className="flex-1 min-h-full bg-white p-4"
64+
value={content}
65+
/>
66+
<div className="mx-1" />
67+
{qrCode && (
68+
<section className="flex-1 min-h-full flex items-center p-4 prose bg-white">
69+
<img src={qrCode} alt={content} className="w-full h-full" />
70+
</section>
71+
)}
72+
</div>
73+
</div>
74+
);
75+
};
76+
77+
export default HtmlPreview;

src/helpers/fontAwesome.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { library } from '@fortawesome/fontawesome-svg-core';
22
import { fab, faMarkdown, faHtml5 } from '@fortawesome/free-brands-svg-icons';
3-
import { faClock } from '@fortawesome/free-solid-svg-icons';
3+
import { faClock, faQrcode } from '@fortawesome/free-solid-svg-icons';
44

5-
library.add(fab, faMarkdown, faClock, faHtml5);
5+
library.add(fab, faMarkdown, faClock, faHtml5, faQrcode);

src/main.dev.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { autoUpdater } from 'electron-updater';
1616
import log from 'electron-log';
1717
import { FileFilter, IpcMainInvokeEvent } from 'electron/main';
1818
import fs from 'fs';
19+
import QRCode from 'qrcode';
1920
import { promisify } from 'util';
2021
import MenuBuilder from './menu';
2122

@@ -134,6 +135,26 @@ ipcMain.handle(
134135
}
135136
);
136137

138+
ipcMain.handle(
139+
'generate-qrcode',
140+
async (_event: IpcMainInvokeEvent, { content }) => {
141+
return QRCode.toDataURL(content, { width: 1024 });
142+
}
143+
);
144+
145+
ipcMain.handle(
146+
'save-file',
147+
async (_event: IpcMainInvokeEvent, { defaultPath, content }) => {
148+
const file = await dialog.showSaveDialog({
149+
defaultPath,
150+
});
151+
152+
if (!file || !file.filePath) return;
153+
154+
await promisify(fs.writeFile)(file.filePath, content);
155+
}
156+
);
157+
137158
/**
138159
* Add event listeners...
139160
*/

yarn.lock

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1766,6 +1766,13 @@
17661766
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24"
17671767
integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==
17681768

1769+
"@types/qrcode@^1.4.1":
1770+
version "1.4.1"
1771+
resolved "https://registry.yarnpkg.com/@types/qrcode/-/qrcode-1.4.1.tgz#0689f400c3a95d2db040c99c99834faa09ee9dc1"
1772+
integrity sha512-vxMyr7JM7tYPxu8vUE83NiosWX5DZieCyYeJRoOIg0pAkyofCBzknJ2ycUZkPGDFis2RS8GN/BeJLnRnAPxeCA==
1773+
dependencies:
1774+
"@types/node" "*"
1775+
17691776
"@types/react-dom@^16.9.9":
17701777
version "16.9.9"
17711778
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.9.tgz#d2d0a6f720a0206369ccbefff752ba37b9583136"
@@ -3022,6 +3029,19 @@ [email protected]:
30223029
dependencies:
30233030
node-int64 "^0.4.0"
30243031

3032+
buffer-alloc-unsafe@^1.1.0:
3033+
version "1.1.0"
3034+
resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
3035+
integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==
3036+
3037+
buffer-alloc@^1.2.0:
3038+
version "1.2.0"
3039+
resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec"
3040+
integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==
3041+
dependencies:
3042+
buffer-alloc-unsafe "^1.1.0"
3043+
buffer-fill "^1.0.0"
3044+
30253045
buffer-crc32@~0.2.3:
30263046
version "0.2.13"
30273047
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
@@ -3032,7 +3052,12 @@ [email protected]:
30323052
resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe"
30333053
integrity sha1-WWFrSYME1Var1GaWayLu2j7KX74=
30343054

3035-
buffer-from@^1.0.0:
3055+
buffer-fill@^1.0.0:
3056+
version "1.0.0"
3057+
resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c"
3058+
integrity sha1-+PeLdniYiO858gXNY39o5wISKyw=
3059+
3060+
buffer-from@^1.0.0, buffer-from@^1.1.1:
30363061
version "1.1.1"
30373062
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
30383063
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
@@ -3056,7 +3081,7 @@ buffer@^4.3.0:
30563081
ieee754 "^1.1.4"
30573082
isarray "^1.0.0"
30583083

3059-
buffer@^5.1.0:
3084+
buffer@^5.1.0, buffer@^5.4.3:
30603085
version "5.7.1"
30613086
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
30623087
integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
@@ -4394,6 +4419,11 @@ diffie-hellman@^5.0.0:
43944419
miller-rabin "^4.0.0"
43954420
randombytes "^2.0.0"
43964421

4422+
dijkstrajs@^1.0.1:
4423+
version "1.0.2"
4424+
resolved "https://registry.yarnpkg.com/dijkstrajs/-/dijkstrajs-1.0.2.tgz#2e48c0d3b825462afe75ab4ad5e829c8ece36257"
4425+
integrity sha512-QV6PMaHTCNmKSeP6QoXhVTw9snc9VD8MulTT0Bd99Pacp4SS1cjcrYPgBPmibqKVtMJJfqC6XvOXgPMEEPH/fg==
4426+
43974427
dir-compare@^2.4.0:
43984428
version "2.4.0"
43994429
resolved "https://registry.yarnpkg.com/dir-compare/-/dir-compare-2.4.0.tgz#785c41dc5f645b34343a4eafc50b79bac7f11631"
@@ -7044,6 +7074,11 @@ [email protected], isarray@^1.0.0, isarray@~1.0.0:
70447074
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
70457075
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
70467076

7077+
isarray@^2.0.1:
7078+
version "2.0.5"
7079+
resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723"
7080+
integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==
7081+
70477082
isexe@^2.0.0:
70487083
version "2.0.0"
70497084
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
@@ -9317,6 +9352,11 @@ plist@^3.0.1:
93179352
xmlbuilder "^9.0.7"
93189353
xmldom "^0.5.0"
93199354

9355+
pngjs@^3.3.0:
9356+
version "3.4.0"
9357+
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f"
9358+
integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==
9359+
93209360
portfinder@^1.0.26:
93219361
version "1.0.28"
93229362
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778"
@@ -9852,6 +9892,19 @@ q@^1.1.2:
98529892
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
98539893
integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=
98549894

9895+
qrcode@^1.4.4:
9896+
version "1.4.4"
9897+
resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.4.4.tgz#f0c43568a7e7510a55efc3b88d9602f71963ea83"
9898+
integrity sha512-oLzEC5+NKFou9P0bMj5+v6Z40evexeE29Z9cummZXZ9QXyMr3lphkURzxjXgPJC5azpxcshoDWV1xE46z+/c3Q==
9899+
dependencies:
9900+
buffer "^5.4.3"
9901+
buffer-alloc "^1.2.0"
9902+
buffer-from "^1.1.1"
9903+
dijkstrajs "^1.0.1"
9904+
isarray "^2.0.1"
9905+
pngjs "^3.3.0"
9906+
yargs "^13.2.4"
9907+
98559908
98569909
version "6.7.0"
98579910
resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
@@ -12596,7 +12649,7 @@ yargs-parser@^20.2.2:
1259612649
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54"
1259712650
integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==
1259812651

12599-
yargs@^13.3.0, yargs@^13.3.2:
12652+
yargs@^13.2.4, yargs@^13.3.0, yargs@^13.3.2:
1260012653
version "13.3.2"
1260112654
resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd"
1260212655
integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==

0 commit comments

Comments
 (0)