Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: plainlab/plainbelt
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.0.15
Choose a base ref
...
head repository: plainlab/plainbelt
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: develop
Choose a head ref
  • 7 commits
  • 14 files changed
  • 1 contributor

Commits on Sep 3, 2021

  1. Auto screen

    manhtai committed Sep 3, 2021
    Copy the full SHA
    842addc View commit details

Commits on Sep 4, 2021

  1. Html encode decode (#27)

    manhtai authored Sep 4, 2021
    Copy the full SHA
    d604081 View commit details

Commits on Sep 5, 2021

  1. Backslash encoder (#28)

    * Backslash
    
    * bump version
    manhtai authored Sep 5, 2021
    Copy the full SHA
    37ae2b4 View commit details
  2. Lorem ipsum (#29)

    * Lorem ipsum
    
    * Change label
    manhtai authored Sep 5, 2021
    Copy the full SHA
    2026b61 View commit details
  3. Move to useEffect

    manhtai committed Sep 5, 2021
    Copy the full SHA
    067f675 View commit details

Commits on Oct 2, 2021

  1. Update README.md

    manhtai authored Oct 2, 2021
    Copy the full SHA
    61c9b45 View commit details

Commits on Mar 19, 2022

  1. Update README.md

    manhtai authored Mar 19, 2022
    Copy the full SHA
    12e0eef View commit details
34 changes: 19 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[![Test](https://github.com/plainlab/plainbelt/actions/workflows/test.yml/badge.svg)](https://github.com/plainlab/plainbelt/actions/workflows/test.yml) ![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/plainlab/plainbelt)
[![Test](https://github.com/plainlab/plainbelt/actions/workflows/test.yml/badge.svg)](https://github.com/plainlab/plainbelt/actions/workflows/test.yml) [![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/plainlab/plainbelt)](https://github.com/plainlab/plainbelt/releases)

# PlainBelt

@@ -13,19 +13,23 @@

## Tools list

- [x] Unix Timestamp Converter
- [x] Cron Editor
- [x] Markdown to HTML Converter
- [x] HTML Preview
- [x] QRCode Generator
- [x] QRCode Reader
- [x] Base64 Encode/Decode
- [x] Text Diff
- [x] JSON Formatter
- [x] SQL Formatter
- [x] Regex Tester
- [x] JWT Debugger
- [x] Js Console
- [x] 1. Unix Timestamp Converter
- [x] 2. Cron Editor
- [x] 3. Markdown to HTML Converter
- [x] 4. HTML Preview
- [x] 5. QRCode Generator
- [x] 6. QRCode Reader
- [x] 7. Base64 Encode / Decode
- [x] 8. Text Diff
- [x] 9. JSON Formatter
- [x] 10. SQL Formatter
- [x] 11. Regex Tester
- [x] 12. JWT Debugger
- [x] 13. Js Console
- [x] 14. HTML Entity Encode / Decode
- [x] 15. URL Encode / Decode
- [x] 16. Backslash Encode / Decode
- [x] 17. Lorem Ipsum Generator

## Demo

@@ -70,4 +74,4 @@ Checkout the `release` folder and enjoy!

---

© 2021 PlainLab
© 2022 PlainLab
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -165,14 +165,14 @@
"@teamsupercell/typings-for-css-modules-loader": "^2.4.0",
"@testing-library/jest-dom": "^5.11.6",
"@testing-library/react": "^11.2.2",
"@types/codemirror": "^5.60.2",
"@types/diff": "^5.0.1",
"@types/enzyme": "^3.10.5",
"@types/enzyme-adapter-react-16": "^1.0.6",
"@types/history": "4.7.6",
"@types/jest": "^26.0.15",
"@types/codemirror": "^5.60.2",
"@types/jsonwebtoken": "^8.5.4",
"@types/lodash.isequal": "^4.5.5",
"@types/lodash": "^4.14.172",
"@types/marked": "^2.0.4",
"@types/node": "14.14.10",
"@types/pngjs": "^6.0.1",
@@ -268,7 +268,8 @@
"history": "^5.0.0",
"jsonwebtoken": "^8.5.1",
"jsqr": "^1.4.0",
"lodash.isequal": "^4.5.0",
"lodash": "^4.17.21",
"lorem-ipsum": "^2.0.3",
"marked": "^2.1.3",
"pngjs": "^6.0.0",
"qrcode": "^1.4.4",
40 changes: 36 additions & 4 deletions src/components/Main.tsx
Original file line number Diff line number Diff line change
@@ -19,6 +19,10 @@ import JwtDebugger from './jwt/JwtDebugger';
import Auto from './auto/Auto';
import CronEditor from './cron/Cron';
import JsConsole from './notebook/JavaScript';
import HtmlEntityCodec from './html/HtmlEntityCodec';
import UrlCodec from './url/UrlCodec';
import BackSlashCodec from './text/BackSlash';
import LoremIpsum from './text/LoremIpsum';

interface MenuItem {
path: string;
@@ -57,6 +61,13 @@ const defaultRoutes: MenuItem[] = [
show: true,
Component: RegexTester,
},
{
icon: <FontAwesomeIcon icon="random" />,
path: '/lorem-ipsum',
name: 'Lorem Ipsum Generator',
show: true,
Component: LoremIpsum,
},
{
icon: <FontAwesomeIcon icon={['fab', 'markdown']} />,
path: '/markdown-to-html',
@@ -127,6 +138,27 @@ const defaultRoutes: MenuItem[] = [
show: false,
Component: JsConsole,
},
{
icon: <FontAwesomeIcon icon="file-code" />,
path: '/html-entity-encoder',
name: 'HTML Entity Encoder',
show: false,
Component: HtmlEntityCodec,
},
{
icon: <FontAwesomeIcon icon="link" />,
path: '/url-encoder',
name: 'URL Encoder',
show: false,
Component: UrlCodec,
},
{
icon: <FontAwesomeIcon icon="slash" transform={{ rotate: 42 }} />,
path: '/back-slash-encoder',
name: 'Backslash Encoder',
show: false,
Component: BackSlashCodec,
},
];

const Main = () => {
@@ -140,10 +172,6 @@ const Main = () => {
setSearch(e.target.value);
};

ipcRenderer.on('hotkey-pressed', () => {
history.push('/auto', { auto: true });
});

useEffect(() => {
if (search.trim()) {
setRoutes(
@@ -191,6 +219,10 @@ const Main = () => {
return null;
})
.catch(console.error);

ipcRenderer.on('hotkey-pressed', () => {
history.push('/auto', { auto: true });
});
}, []);

return (
8 changes: 6 additions & 2 deletions src/components/auto/Auto.tsx
Original file line number Diff line number Diff line change
@@ -82,12 +82,16 @@ const Auto = () => {
/>
</section>
<p className="mt-4 text-lg font-bold">PlainBelt</p>
<a href="https://plainlab.github.io" className="opacity-50">
<a
href="https://plainlab.github.io"
target="new"
className="opacity-50"
>
https://plainlab.github.io
</a>
{hotkey && (
<p className="mt-10 opacity-70">
<em>Hotkey</em>: Control+Alt+Meta+Space (⌃⌥⌘Space in Mac)
<em>Hotkey</em>: Control+Alt+Meta+Space (⌃⌥⌘Space on Mac)
</p>
)}
</section>
103 changes: 103 additions & 0 deletions src/components/common/1-to-1.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { clipboard } from 'electron';
import React, { useState } from 'react';

interface OneToOneProps {
defaultInput: string;
forwardFunc: (f: string) => string;
inverseFunc: (r: string) => string;
}

const OneToOne = ({
defaultInput,
forwardFunc,
inverseFunc,
}: OneToOneProps) => {
const [from, setFrom] = useState(defaultInput);
const [to, setTo] = useState(forwardFunc(from));

const [fromCopied, setFromCopied] = useState(false);
const [toCopied, setToCopied] = useState(false);

const changeFrom = (value: string) => {
setFrom(value);
setTo(forwardFunc(value));
};

const changeTo = (value: string) => {
setTo(value);
setFrom(inverseFunc(value));
};

const handleChangeFrom = (evt: { target: { value: string } }) =>
changeFrom(evt.target.value);

const handleChangeTo = (evt: { target: { value: string } }) =>
changeTo(evt.target.value);

const handleCopyFrom = () => {
setFromCopied(true);
clipboard.write({ text: from });
setTimeout(() => setFromCopied(false), 500);
};

const handleCopyTo = () => {
setToCopied(true);
clipboard.write({ text: to });
setTimeout(() => setToCopied(false), 500);
};

const handleClipboardFrom = () => {
changeFrom(clipboard.readText());
};

const handleClipboardTo = () => {
changeTo(clipboard.readText());
};

return (
<div className="flex flex-col min-h-full">
<div className="flex justify-between mb-1">
<section className="flex items-center justify-start space-x-2">
<button type="button" className="btn" onClick={handleClipboardFrom}>
Clipboard
</button>
<button
type="button"
className="w-16 btn"
onClick={handleCopyFrom}
disabled={fromCopied}
>
{fromCopied ? 'Copied' : 'Copy'}
</button>
</section>
<section className="flex items-center justify-start space-x-2">
<button type="button" className="btn" onClick={handleClipboardTo}>
Clipboard
</button>
<button
type="button"
className="w-16 btn"
onClick={handleCopyTo}
disabled={toCopied}
>
{toCopied ? 'Copied' : 'Copy'}
</button>
</section>
</div>
<div className="flex flex-1 min-h-full space-x-2">
<textarea
onChange={handleChangeFrom}
className="flex-1 min-h-full p-2 bg-white rounded-md"
value={from}
/>
<textarea
onChange={handleChangeTo}
className="flex-1 min-h-full p-2 bg-white rounded-md"
value={to}
/>
</div>
</div>
);
};

export default OneToOne;
15 changes: 15 additions & 0 deletions src/components/html/HtmlEntityCodec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import { escape, unescape } from 'lodash';
import OneToOne from '../common/1-to-1';

const HtmlEntityCodec = () => {
return (
<OneToOne
defaultInput='<script>alert("Hello");</script>'
forwardFunc={escape}
inverseFunc={unescape}
/>
);
};

export default HtmlEntityCodec;
2 changes: 1 addition & 1 deletion src/components/jwt/JwtDebugger.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react';
import classNames from 'classnames';
import _isEqual from 'lodash.isequal';
import _isEqual from 'lodash/isequal';
import { ipcRenderer, clipboard } from 'electron';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
41 changes: 41 additions & 0 deletions src/components/text/BackSlash.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react';
import OneToOne from '../common/1-to-1';

const addSlashes = (string: string) => {
return (
string
.replace(/\\/g, '\\\\')
// eslint-disable-next-line no-control-regex
.replace(/\u0008/g, '\\b')
.replace(/\t/g, '\\t')
.replace(/\n/g, '\\n')
.replace(/\f/g, '\\f')
.replace(/\r/g, '\\r')
.replace(/'/g, "\\'")
.replace(/"/g, '\\"')
);
};

const removeSlashes = (string: string) => {
return string
.replace(/\\"/g, '"')
.replace(/\\'/g, "'")
.replace(/\\r/g, '\r')
.replace(/\\f/g, '\f')
.replace(/\\n/g, '\n')
.replace(/\\t/g, '\t')
.replace(/\\b/, '\u0008')
.replace(/\\\\/g, '\\');
};

const BackSlashCodec = () => {
return (
<OneToOne
defaultInput="Hello\nworld!"
forwardFunc={removeSlashes}
inverseFunc={addSlashes}
/>
);
};

export default BackSlashCodec;
Loading