* Refactor
+ Menu to create or read a password + New loader
This commit is contained in:
@@ -27,7 +27,7 @@ ProtonMail|mail_pw123|klier.nicolas@protonmail.com||
|
|||||||
These characters are reserved and cannot be used for any fields: `|%§`
|
These characters are reserved and cannot be used for any fields: `|%§`
|
||||||
|
|
||||||
### Compression
|
### Compression
|
||||||
It is possible to compress QR-Codes. Instead of writing all data to the QR-Code you can write random strings (key) to it. OffPass itself holds a database of those random string and the corresponding encrypted value.
|
It is possible to compress QR-Codes. Instead of writing all data to the QR-Code you can write random strings (= key) to it. OffPass itself holds a database of those random strings and the corresponding encrypted value.
|
||||||
|
|
||||||
The program generates a `session key` (length of 10 characters) which is unique for each QR-Code. This session key is stored on the QR-Code and is used to encrypt the raw values in database. So not even If someone stells your database he wouldn't be able to read your compressed strings.
|
The program generates a `session key` (length of 10 characters) which is unique for each QR-Code. This session key is stored on the QR-Code and is used to encrypt the raw values in database. So not even If someone stells your database he wouldn't be able to read your compressed strings.
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ For example:
|
|||||||
```
|
```
|
||||||
|
|
||||||
This can has two advantages:
|
This can has two advantages:
|
||||||
* An attacker can't read compressed values (he would need the database)
|
* An attacker can't read compressed values If he is able to decrypt one QR-Code (he would need the database)
|
||||||
* You can get more data on one QR-Code
|
* You can get more data on one QR-Code
|
||||||
|
|
||||||
But one disadvantage:
|
But one disadvantage:
|
||||||
|
|||||||
40
src/css/choose.css
Normal file
40
src/css/choose.css
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
.options {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: .5fr 300px 300px .5fr;
|
||||||
|
grid-template-rows: .7fr;
|
||||||
|
column-gap: 50px;
|
||||||
|
position: absolute;
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 100%;
|
||||||
|
height: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.options div {
|
||||||
|
transition: .2s ease-in-out;
|
||||||
|
background-color: rgba(255, 255, 255, 0);
|
||||||
|
grid-row: 2;
|
||||||
|
width: 300px;
|
||||||
|
height: 300px;
|
||||||
|
padding-top: 90px;
|
||||||
|
border: 1px rgba(255, 255, 255, 0.3) solid;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.options div:hover {
|
||||||
|
background-color: rgba(255, 255, 255, .2);
|
||||||
|
border: 1px rgba(255, 255, 255, 0.8) solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.options div i {
|
||||||
|
font-size: 64pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
#create {
|
||||||
|
grid-row: 1;
|
||||||
|
grid-column: 2;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
#scan {
|
||||||
|
grid-row: 1;
|
||||||
|
grid-column: 3;
|
||||||
|
}
|
||||||
45
src/css/create.css
Normal file
45
src/css/create.css
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#create_setup {
|
||||||
|
position: absolute !important;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
#create_setup * {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
#create_setup .options {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
|
grid-template-rows: .25fr .25fr .25fr;
|
||||||
|
row-gap: 50px;
|
||||||
|
column-gap: 50px;
|
||||||
|
margin-left: 50px;
|
||||||
|
width: calc(100% - 100px);
|
||||||
|
}
|
||||||
|
|
||||||
|
#name {
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#url {
|
||||||
|
grid-column: 2 / 4;
|
||||||
|
grid-row: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#email {
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
#password {
|
||||||
|
grid-column: 1 / 4;
|
||||||
|
grid-row: 3;
|
||||||
|
display: inline-block;
|
||||||
|
border: 1px solid white;
|
||||||
|
}
|
||||||
|
#password input {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
#password i {
|
||||||
|
|
||||||
|
border-left: none;
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@ body {
|
|||||||
/*background-color: #2A2C2B;*/
|
/*background-color: #2A2C2B;*/
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
h1 {
|
h1, h3 {
|
||||||
font-family: 'Oxygen', sans-serif;
|
font-family: 'Oxygen', sans-serif;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
@@ -24,6 +24,35 @@ a {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-family: 'Source Sans Pro', sans-serif;
|
font-family: 'Source Sans Pro', sans-serif;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
background-color: transparent;
|
||||||
|
border: 1px rgb(200, 200, 200, .5) solid;
|
||||||
|
background-color: rgba(29, 29, 29, 0.2);
|
||||||
|
color: rgb(200, 200, 200, .6);
|
||||||
|
padding: 10px;
|
||||||
|
transition: .1s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:disabled {
|
||||||
|
border: 1px rgba(200, 200, 200, 0.7) solid;
|
||||||
|
background-color: rgba(78, 78, 78, 0.4) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
input::placeholder {
|
||||||
|
color: rgb(207, 207, 207, .8);
|
||||||
|
}
|
||||||
|
input:focus {
|
||||||
|
border: 1px rgb(200, 200, 200, 1) solid;
|
||||||
|
background-color: rgba(29, 29, 29, 0.3);
|
||||||
|
color: rgb(200, 200, 200, 1);
|
||||||
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#taskbar {
|
#taskbar {
|
||||||
@@ -52,6 +81,42 @@ a {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Error */
|
||||||
|
#error {
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
bottom: -350px;
|
||||||
|
width: auto;
|
||||||
|
height: 55px;
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 20px;
|
||||||
|
backdrop-filter: blur(30px);
|
||||||
|
background-color: rgba(100, 0, 0, 0.6);
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
#error i {
|
||||||
|
font-size: 20pt;
|
||||||
|
padding: 14px;
|
||||||
|
color: rgb(255, 139, 139);
|
||||||
|
}
|
||||||
|
#error p {
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
.fill {
|
.fill {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Containers that are in the main view */
|
||||||
|
.main {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 50px;
|
||||||
|
}
|
||||||
|
.main * {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.options {
|
||||||
|
width: calc(100% - 100px);
|
||||||
}
|
}
|
||||||
@@ -38,28 +38,6 @@
|
|||||||
font-weight: 200;
|
font-weight: 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Error */
|
|
||||||
#error {
|
|
||||||
position: absolute;
|
|
||||||
display: flex;
|
|
||||||
bottom: -350px;
|
|
||||||
width: auto;
|
|
||||||
height: 55px;
|
|
||||||
padding-left: 10px;
|
|
||||||
padding-right: 20px;
|
|
||||||
backdrop-filter: blur(30px);
|
|
||||||
background-color: rgba(100, 0, 0, 0.6);
|
|
||||||
border-radius: 15px;
|
|
||||||
}
|
|
||||||
#error i {
|
|
||||||
font-size: 20pt;
|
|
||||||
padding: 14px;
|
|
||||||
color: rgb(255, 139, 139);
|
|
||||||
}
|
|
||||||
#error p {
|
|
||||||
padding-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.show {
|
.show {
|
||||||
animation: showpass 1s;
|
animation: showpass 1s;
|
||||||
opacity: 1 !important;
|
opacity: 1 !important;
|
||||||
|
|||||||
@@ -2,27 +2,8 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
padding-top: calc(10% + 50px);
|
padding-top: calc(10% + 50px);
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
#master_prompt input {
|
|
||||||
margin-top: 50px;
|
|
||||||
background-color: transparent;
|
|
||||||
border: none;
|
|
||||||
border-bottom: 1px solid white;
|
|
||||||
color: white;
|
|
||||||
padding: 10px;
|
|
||||||
transition: .2s ease-in-out;
|
|
||||||
}
|
|
||||||
#master_prompt input::placeholder {
|
|
||||||
color: rgb(207, 207, 207);
|
|
||||||
}
|
|
||||||
#master_prompt input:focus {
|
|
||||||
border-bottom-width: 3px;
|
|
||||||
border-bottom-left-radius: 2px;
|
|
||||||
border-bottom-right-radius: 2px;
|
|
||||||
}
|
}
|
||||||
#master_prompt a {
|
#master_prompt a {
|
||||||
line-height: 5;
|
line-height: 15;
|
||||||
font-size: 13pt;
|
font-size: 13pt;
|
||||||
}
|
}
|
||||||
38
src/html/choose.html
Normal file
38
src/html/choose.html
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<div id="choose" class="main" style="left: 150%;">
|
||||||
|
<link href="../css/choose.css" rel="stylesheet">
|
||||||
|
<script>
|
||||||
|
window.$ = window.jQuery = require('../assets/jquery-3.4.1.min.js');
|
||||||
|
|
||||||
|
function scanClick() {
|
||||||
|
console.log("here");
|
||||||
|
await loader.load('scanner');
|
||||||
|
|
||||||
|
$('#scan').animate({
|
||||||
|
left: '-150'
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#wait').animate({
|
||||||
|
left: '0'
|
||||||
|
}, 300);
|
||||||
|
|
||||||
|
const done = await startWatching();
|
||||||
|
|
||||||
|
$('#preview').animate({
|
||||||
|
left: '0'
|
||||||
|
}, 600);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<h1>Please choose your action</h1>
|
||||||
|
<div class="options">
|
||||||
|
<div id="create" onclick="scanClick()">
|
||||||
|
<i class="fas fa-plus" onclick="scanClick()"></i>
|
||||||
|
<h3>Create</h3>
|
||||||
|
<p>Create a new password and print it out.</p>
|
||||||
|
</div>
|
||||||
|
<div id="scan">
|
||||||
|
<i class="fas fa-qrcode"></i>
|
||||||
|
<h3>Scan</h3>
|
||||||
|
<p>Scan your existing password</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -1,3 +1,23 @@
|
|||||||
<div id="create_setup">
|
<div id="create_setup" class="main" style="left: 150%;">
|
||||||
|
<link rel="stylesheet" href="../css/create.css">
|
||||||
<h1>New QR-Code</h1>
|
<h1>New QR-Code</h1>
|
||||||
|
<div class="options">
|
||||||
|
<input placeholder="Name" id="name">
|
||||||
|
<input placeholder="Login URL (example: https://example.com/login, https://login.example.com)" id="url">
|
||||||
|
<input placeholder="E-Mail" id="email">
|
||||||
|
<input type="checkbox" id="compression">
|
||||||
|
<select title="Hash Algorithm">
|
||||||
|
<option selected>Argon2i</option>
|
||||||
|
<!--<option>Argon2d</option>-->
|
||||||
|
<!--<option>Argon2id</option>-->
|
||||||
|
<!--<option>Scrypt</option>-->
|
||||||
|
<option>Bcrypt</option>
|
||||||
|
<option>SHA-512</option>
|
||||||
|
</select>
|
||||||
|
<div id="password">
|
||||||
|
<input placeholder="Password">
|
||||||
|
<i class="fas fa-random"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="../js/create.js"></script>
|
||||||
</div>
|
</div>
|
||||||
@@ -12,7 +12,6 @@
|
|||||||
<link href="../assets/animate.css" rel="stylesheet">
|
<link href="../assets/animate.css" rel="stylesheet">
|
||||||
<link href="../css/global.css" rel="stylesheet">
|
<link href="../css/global.css" rel="stylesheet">
|
||||||
<link href="../css/start.css" rel="stylesheet">
|
<link href="../css/start.css" rel="stylesheet">
|
||||||
<link href="../css/scanner.css" rel="stylesheet">
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="taskbar">
|
<div id="taskbar">
|
||||||
@@ -21,52 +20,48 @@
|
|||||||
<i id="close" class="fas fa-times" onclick="remote.BrowserWindow.getFocusedWindow().close()"></i>
|
<i id="close" class="fas fa-times" onclick="remote.BrowserWindow.getFocusedWindow().close()"></i>
|
||||||
</div>
|
</div>
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<div id="master_prompt">
|
<div id="master_prompt" class="main">
|
||||||
<h1>Welcome to OffPass</h1>
|
<h1>Welcome to OffPass</h1>
|
||||||
<p>Please enter your master password for decryption</p>
|
<p>Please enter your master password</p>
|
||||||
<input id="master" placeholder="Master password..." type="password" autofocus><br>
|
<input id="master" placeholder="Master password..." type="password" autofocus><br>
|
||||||
|
|
||||||
<a href="#">Or create a new QR-Code</a>
|
<a href="#">Or create a new QR-Code</a>
|
||||||
</div>
|
</div>
|
||||||
<div id="wait">
|
|
||||||
<h1>Wait for camera...</h1>
|
|
||||||
</div>
|
|
||||||
<div id="scanned" class="animated">
|
|
||||||
<h1>Password: <span id="password"></span></h1>
|
|
||||||
</div>
|
|
||||||
<div id="error">
|
<div id="error">
|
||||||
<i class="fas fa-exclamation-circle"></i><p>Decryption faild. Maybe wrong password?</p>
|
<i class="fas fa-exclamation-circle"></i>
|
||||||
|
<p></p>
|
||||||
</div>
|
</div>
|
||||||
<video id="preview"></video>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
window.$ = window.jQuery = require('../assets/jquery-3.4.1.min.js');
|
window.$ = window.jQuery = require('../assets/jquery-3.4.1.min.js');
|
||||||
|
|
||||||
|
const { Loader } = require('../js/loader.js');
|
||||||
const { remote } = require('electron');
|
const { remote } = require('electron');
|
||||||
const pgp = require('openpgp');
|
const pgp = require('openpgp');
|
||||||
let master_password = "";
|
let master_password = "";
|
||||||
|
|
||||||
|
const loader = new Loader(document.getElementById('content'));
|
||||||
|
|
||||||
// Slide
|
// Slide
|
||||||
$('#master').keypress(async (e) => {
|
$('#master').keypress(async (e) => {
|
||||||
if (e.which == 13) {
|
if (e.which == 13) {
|
||||||
master_password = $('#master').val();
|
master_password = $('#master').val();
|
||||||
$('#master_prompt').animate({
|
$('#master_prompt').animate({
|
||||||
left: '-150%'
|
left: '-150%'
|
||||||
}, 600, () => {
|
}, 300, async () => {
|
||||||
$(this).css('left', '150%');
|
await loader.load('choose');
|
||||||
|
|
||||||
|
$('#choose').animate({
|
||||||
|
left: '0'
|
||||||
|
}, 300);
|
||||||
});
|
});
|
||||||
$('#wait').animate({
|
|
||||||
left: '0'
|
|
||||||
}, 300);
|
|
||||||
const done = await startWatching();
|
|
||||||
$('#preview').animate({
|
|
||||||
left: '0'
|
|
||||||
}, 600);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#master_prompt a').click((e) => {
|
$('#master_prompt a').click(async (e) => {
|
||||||
|
await loader.load('create');
|
||||||
$('#master_prompt').animate({
|
$('#master_prompt').animate({
|
||||||
left: '-150%'
|
left: '-150%'
|
||||||
});
|
});
|
||||||
|
|||||||
11
src/html/scanner.html
Normal file
11
src/html/scanner.html
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<!-- Styles -->
|
||||||
|
<link href="../css/scanner.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<div id="wait">
|
||||||
|
<h1>Wait for camera...</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<video id="preview"></video>
|
||||||
|
<div id="scanned" class="animated">
|
||||||
|
<h1>Password: <span id="password"></span></h1>
|
||||||
|
</div>
|
||||||
22
src/js/choose.js
Normal file
22
src/js/choose.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
console.log("here")
|
||||||
|
|
||||||
|
window.$ = window.jQuery = require('../assets/jquery-3.4.1.min.js');
|
||||||
|
|
||||||
|
$('#scan').click(async (e) => {
|
||||||
|
console.log("here")
|
||||||
|
await loader.load('scanner');
|
||||||
|
|
||||||
|
$('#scan').animate({
|
||||||
|
left: '-150'
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#wait').animate({
|
||||||
|
left: '0'
|
||||||
|
}, 300);
|
||||||
|
|
||||||
|
const done = await startWatching();
|
||||||
|
|
||||||
|
$('#preview').animate({
|
||||||
|
left: '0'
|
||||||
|
}, 600);
|
||||||
|
})
|
||||||
0
src/js/create.js
Normal file
0
src/js/create.js
Normal file
@@ -1,10 +1,68 @@
|
|||||||
/**
|
"use strict";
|
||||||
* This script loads or unloads different modules present in src/js
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
*/
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
class Loader {
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
index = null;
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||||
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||||
constructor(index) {
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||||
|
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||||
|
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||||
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||||
|
function step(op) {
|
||||||
|
if (f) throw new TypeError("Generator is already executing.");
|
||||||
|
while (_) try {
|
||||||
|
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||||
|
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||||
|
switch (op[0]) {
|
||||||
|
case 0: case 1: t = op; break;
|
||||||
|
case 4: _.label++; return { value: op[1], done: false };
|
||||||
|
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||||
|
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||||
|
default:
|
||||||
|
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||||
|
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||||
|
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||||
|
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||||
|
if (t[2]) _.ops.pop();
|
||||||
|
_.trys.pop(); continue;
|
||||||
|
}
|
||||||
|
op = body.call(thisArg, _);
|
||||||
|
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||||
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
exports.__esModule = true;
|
||||||
|
var fs_1 = require("fs");
|
||||||
|
var path_1 = require("path");
|
||||||
|
/**
|
||||||
|
* This script loads or unloads different modules present in src/html
|
||||||
|
*/
|
||||||
|
var Loader = /** @class */ (function () {
|
||||||
|
function Loader(content) {
|
||||||
|
this.content = null;
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
Loader.prototype.load = function (module_name) {
|
||||||
|
return __awaiter(this, void 0, void 0, function () {
|
||||||
|
var _this = this;
|
||||||
|
return __generator(this, function (_a) {
|
||||||
|
return [2 /*return*/, new Promise(function (resolve, reject) {
|
||||||
|
fs_1.readFile(path_1.resolve("src/html/", module_name + ".html"), 'utf8', function (err, data) {
|
||||||
|
if (err)
|
||||||
|
console.error("Error while loading module:", module_name, "(", path_1.resolve("src/html/", module_name + ".html"), ")");
|
||||||
|
else {
|
||||||
|
_this.content.innerHTML += data;
|
||||||
|
}
|
||||||
|
resolve(true);
|
||||||
|
});
|
||||||
|
})];
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
return Loader;
|
||||||
|
}());
|
||||||
|
exports.Loader = Loader;
|
||||||
|
|||||||
25
src/js/loader.ts
Normal file
25
src/js/loader.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { readFile } from "fs";
|
||||||
|
import { resolve as res } from "path";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This script loads or unloads different modules present in src/html
|
||||||
|
*/
|
||||||
|
export class Loader {
|
||||||
|
content: HTMLDivElement = null;
|
||||||
|
|
||||||
|
constructor(content: HTMLDivElement) {
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
async load(module_name: string) {
|
||||||
|
return new Promise<Boolean>((resolve, reject) => {
|
||||||
|
readFile(res("src/html/", module_name + ".html"), 'utf8', (err, data) => {
|
||||||
|
if (err) console.error("Error while loading module:", module_name, "(", res("src/html/", module_name + ".html"), ")");
|
||||||
|
else {
|
||||||
|
this.content.innerHTML += data;
|
||||||
|
}
|
||||||
|
resolve(true);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user