Compare commits

..

2 Commits

Author SHA1 Message Date
9fdb774b5c Improved 3D view and UI
Added random skins
WIP: Skin upload and reset
2020-06-18 19:23:07 +02:00
bde532e123 Added Skinview3D 2020-05-12 19:02:20 +02:00
15 changed files with 297 additions and 74 deletions

View File

@ -11,6 +11,15 @@ body header h3 {
margin: 0; margin: 0;
} }
body div.content {
display: -ms-grid;
display: grid;
-ms-grid-columns: 50% 50%;
grid-template-columns: 50% 50%;
grid-template-areas: 'message message' 'left right';
width: 100%;
}
body div.content form label { body div.content form label {
font-size: small; font-size: small;
} }
@ -25,10 +34,14 @@ body div.content button {
} }
body div.content .message { body div.content .message {
min-width: 80%; -ms-grid-row: 1;
-ms-grid-column: 1;
-ms-grid-column-span: 2;
grid-area: message;
width: calc(100% - 22px);
height: auto; height: auto;
margin: 5px auto; margin: 5px auto;
padding: 5px; padding: 5px 10px 5px 10px;
font-size: small; font-size: small;
color: white; color: white;
} }
@ -48,6 +61,18 @@ body div.content .message.success {
background: rgba(0, 255, 0, 0.5); background: rgba(0, 255, 0, 0.5);
} }
body div.content div.left {
-ms-grid-row: 2;
-ms-grid-column: 1;
grid-area: left;
}
body div.content div.right {
-ms-grid-row: 2;
-ms-grid-column: 2;
grid-area: right;
}
body div.content img.skin { body div.content img.skin {
width: 60%; width: 60%;
padding: 0 1em 1em 1em; padding: 0 1em 1em 1em;

View File

@ -1,6 +1,6 @@
{ {
"version": 3, "version": 3,
"mappings": "AAAA,AAAA,IAAI,CAAC;EACD,WAAW,EAAE,4BAA4B;EACzC,UAAU,EAAE,MAAM;CAiErB;;AAnED,AAIQ,IAJJ,CAGA,MAAM,CACF,EAAE,CAAC;EACC,aAAa,EAAE,CAAC;CACnB;;AANT,AAOQ,IAPJ,CAGA,MAAM,CAIF,EAAE,CAAC;EACC,MAAM,EAAE,CAAC;CACZ;;AATT,AAaY,IAbR,CAWA,GAAG,AAAA,QAAQ,CACP,IAAI,CACA,KAAK,CAAC;EACF,SAAS,EAAE,KAAK;CACnB;;AAfb,AAiBQ,IAjBJ,CAWA,GAAG,AAAA,QAAQ,CAMP,KAAK,EAjBb,IAAI,CAWA,GAAG,AAAA,QAAQ,CAMA,MAAM,CAAC;EACV,MAAM,EAAE,KAAK;EACb,OAAO,EAAE,MAAM;CAClB;;AApBT,AAqBQ,IArBJ,CAWA,GAAG,AAAA,QAAQ,CAUP,MAAM,CAAC;EACH,KAAK,EAAE,GAAG;CACb;;AAvBT,AAwBQ,IAxBJ,CAWA,GAAG,AAAA,QAAQ,CAaP,QAAQ,CAAC;EACL,SAAS,EAAE,GAAG;EACd,MAAM,EAAE,IAAI;EACZ,MAAM,EAAE,QAAQ;EAChB,OAAO,EAAE,GAAG;EACZ,SAAS,EAAE,KAAK;EAChB,KAAK,EAAE,KAAK;CAaf;;AA3CT,AA+BY,IA/BR,CAWA,GAAG,AAAA,QAAQ,CAaP,QAAQ,AAOH,KAAK,CAAC;EACH,MAAM,EAAE,cAAc;EACtB,UAAU,EAAE,oBAAoB;CACnC;;AAlCb,AAmCY,IAnCR,CAWA,GAAG,AAAA,QAAQ,CAaP,QAAQ,AAWH,QAAQ,CAAC;EACN,MAAM,EAAE,aAAa;EACrB,UAAU,EAAE,oBAAoB;CACnC;;AAtCb,AAuCY,IAvCR,CAWA,GAAG,AAAA,QAAQ,CAaP,QAAQ,AAeH,QAAQ,CAAC;EACN,MAAM,EAAE,eAAe;EACvB,UAAU,EAAE,oBAAoB;CACnC;;AA1Cb,AA4CQ,IA5CJ,CAWA,GAAG,AAAA,QAAQ,CAiCP,GAAG,AAAA,KAAK,CAAC;EACL,KAAK,EAAE,GAAG;EACV,OAAO,EAAE,aAAa;EACtB,eAAe,EAAE,SAAS;CAC7B;;AAhDT,AAkDI,IAlDA,AAkDC,KAAK,CAAC;EACH,KAAK,EAAE,OAAO;EACd,gBAAgB,EAAE,IAAI;CACzB;;AArDL,AAsDI,IAtDA,AAsDC,MAAM,CAAC;EACJ,KAAK,EAAE,IAAI;EACX,UAAU,EAAE,IAAI;CACnB;;AAzDL,AA0DI,IA1DA,CA0DA,MAAM,CAAC;EACH,SAAS,EAAE,KAAK;EAChB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,QAAQ,EAAE,QAAQ;EAClB,MAAM,EAAE,CAAC;EACT,IAAI,EAAE,CAAC;EACP,UAAU,EAAE,MAAM;CACrB", "mappings": "AAAA,AAAA,IAAI,CAAC;EACD,WAAW,EAAE,4BAA4B;EACzC,UAAU,EAAE,MAAM;CA+ErB;;AAjFD,AAIQ,IAJJ,CAGA,MAAM,CACF,EAAE,CAAC;EACC,aAAa,EAAE,CAAC;CACnB;;AANT,AAOQ,IAPJ,CAGA,MAAM,CAIF,EAAE,CAAC;EACC,MAAM,EAAE,CAAC;CACZ;;AATT,AAWI,IAXA,CAWA,GAAG,AAAA,QAAQ,CAAC;EACR,OAAO,EAAE,IAAI;EACb,qBAAqB,EAAE,OAAO;EAC9B,mBAAmB,EACf,+BAEJ;EACA,KAAK,EAAE,IAAI;CA6Cd;;AA/DL,AAoBY,IApBR,CAWA,GAAG,AAAA,QAAQ,CAQP,IAAI,CACA,KAAK,CAAC;EACF,SAAS,EAAE,KAAK;CACnB;;AAtBb,AAwBQ,IAxBJ,CAWA,GAAG,AAAA,QAAQ,CAaP,KAAK,EAxBb,IAAI,CAWA,GAAG,AAAA,QAAQ,CAaA,MAAM,CAAC;EACV,MAAM,EAAE,KAAK;EACb,OAAO,EAAE,MAAM;CAClB;;AA3BT,AA4BQ,IA5BJ,CAWA,GAAG,AAAA,QAAQ,CAiBP,MAAM,CAAC;EACH,KAAK,EAAE,GAAG;CACb;;AA9BT,AA+BQ,IA/BJ,CAWA,GAAG,AAAA,QAAQ,CAoBP,QAAQ,CAAC;EACL,SAAS,EAAE,OAAO;EAClB,KAAK,EAAE,iBAAiB;EACxB,MAAM,EAAE,IAAI;EACZ,MAAM,EAAE,QAAQ;EAChB,OAAO,EAAE,iBAAiB;EAC1B,SAAS,EAAE,KAAK;EAChB,KAAK,EAAE,KAAK;CAaf;;AAnDT,AAuCY,IAvCR,CAWA,GAAG,AAAA,QAAQ,CAoBP,QAAQ,AAQH,KAAK,CAAC;EACH,MAAM,EAAE,cAAc;EACtB,UAAU,EAAE,oBAAoB;CACnC;;AA1Cb,AA2CY,IA3CR,CAWA,GAAG,AAAA,QAAQ,CAoBP,QAAQ,AAYH,QAAQ,CAAC;EACN,MAAM,EAAE,aAAa;EACrB,UAAU,EAAE,oBAAoB;CACnC;;AA9Cb,AA+CY,IA/CR,CAWA,GAAG,AAAA,QAAQ,CAoBP,QAAQ,AAgBH,QAAQ,CAAC;EACN,MAAM,EAAE,eAAe;EACvB,UAAU,EAAE,oBAAoB;CACnC;;AAlDb,AAoDQ,IApDJ,CAWA,GAAG,AAAA,QAAQ,CAyCP,GAAG,AAAA,KAAK,CAAC;EACL,SAAS,EAAE,IAAI;CAClB;;AAtDT,AAuDQ,IAvDJ,CAWA,GAAG,AAAA,QAAQ,CA4CP,GAAG,AAAA,MAAM,CAAC;EACN,SAAS,EAAE,KAAK;CACnB;;AAzDT,AA0DQ,IA1DJ,CAWA,GAAG,AAAA,QAAQ,CA+CP,GAAG,AAAA,KAAK,CAAC;EACL,KAAK,EAAE,GAAG;EACV,OAAO,EAAE,aAAa;EACtB,eAAe,EAAE,SAAS;CAC7B;;AA9DT,AAgEI,IAhEA,AAgEC,KAAK,CAAC;EACH,KAAK,EAAE,OAAO;EACd,gBAAgB,EAAE,IAAI;CACzB;;AAnEL,AAoEI,IApEA,AAoEC,MAAM,CAAC;EACJ,KAAK,EAAE,IAAI;EACX,UAAU,EAAE,IAAI;CACnB;;AAvEL,AAwEI,IAxEA,CAwEA,MAAM,CAAC;EACH,SAAS,EAAE,KAAK;EAChB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,QAAQ,EAAE,QAAQ;EAClB,MAAM,EAAE,CAAC;EACT,IAAI,EAAE,CAAC;EACP,UAAU,EAAE,MAAM;CACrB",
"sources": [ "sources": [
"index.scss" "index.scss"
], ],

View File

@ -10,6 +10,13 @@ body {
} }
} }
div.content { div.content {
display: grid;
grid-template-columns: 50% 50%;
grid-template-areas:
'message message'
'left right'
;
width: 100%;
form { form {
label { label {
font-size: small; font-size: small;
@ -23,10 +30,11 @@ body {
width: 50%; width: 50%;
} }
.message { .message {
min-width: 80%; grid-area: message;
width: calc(100% - 22px);
height: auto; height: auto;
margin: 5px auto; margin: 5px auto;
padding: 5px; padding: 5px 10px 5px 10px;
font-size: small; font-size: small;
color: white; color: white;
&.info { &.info {
@ -42,6 +50,12 @@ body {
background: rgba(0, 255, 0, 0.5); background: rgba(0, 255, 0, 0.5);
} }
} }
div.left {
grid-area: left;
}
div.right {
grid-area: right;
}
img.skin { img.skin {
width: 60%; width: 60%;
padding: 0 1em 1em 1em; padding: 0 1em 1em 1em;

View File

@ -1 +1 @@
{"theme":"light","user":"arne.v.iterson@hotmail.nl","password":""} {"theme":"dark","user":"arne.v.iterson@hotmail.nl","password":"","skinDefault":"http://assets.mojang.com/SkinTemplates/steve.png"}

View File

@ -1,11 +1,13 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }}</title> <title>{{ title }}</title>
<link rel="stylesheet" href="{{ css }}"> <link rel="stylesheet" href="{{ css }}">
</head> </head>
<body class="{{ theme }}"> <body class="{{ theme }}">
<header> <header>
<h1>{{ header }}</h1> <h1>{{ header }}</h1>
@ -14,6 +16,13 @@
<div class="content"> <div class="content">
<p class="message"></p> <p class="message"></p>
<div class="left">
<p class="message info">
Your password will stored in plaintext because the Mojang API requires it, do not use this option unless
you are on a private computer.
</p>
</div>
<div class="right">
<form action="#"> <form action="#">
<label for="user">Username or E-mail</label><br> <label for="user">Username or E-mail</label><br>
<input type="text" id="user" placeholder="Username or E-mail" required><br> <input type="text" id="user" placeholder="Username or E-mail" required><br>
@ -22,13 +31,12 @@
<input type="password" id="password" placeholder="Password" required><br> <input type="password" id="password" placeholder="Password" required><br>
<label for="save">Save password:</label> <label for="save">Save password:</label>
<input type="checkbox" id="save"> <input type="checkbox" id="save"><br>
<p class="message info">Your password will stored in plaintext because the Mojang API requires it, do not use this option unless you are on a private computer.</p>
<button type="submit">Submit</button> <button type="submit">Submit</button>
</form> </form>
</div> </div>
</div>
<script src="../src/auth.js"></script> <script src="../src/auth.js"></script>
@ -36,4 +44,5 @@
{{ footer }} {{ footer }}
</footer> </footer>
</body> </body>
</html> </html>

View File

@ -1,11 +1,13 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }}</title> <title>{{ title }}</title>
<link rel="stylesheet" href="{{ css }}"> <link rel="stylesheet" href="{{ css }}">
</head> </head>
<body class="{{ theme }}"> <body class="{{ theme }}">
<header> <header>
<h1>{{ header }}</h1> <h1>{{ header }}</h1>
@ -14,13 +16,22 @@
<div class="content"> <div class="content">
<p class="message success"></p> <p class="message success"></p>
<div class="left">
<p class="message info">
Logging out will delete your password from storage, if you want it to autofill next time you can just
close this window when you are done.
</p>
<p class="message warning">
Hecc inc. is not responsible for loss of data or explicit content (using random skin selection) seen
when using this program.
</p>
</div>
<div class="right">
<button id="current">Current Skin</button><br> <button id="current">Current Skin</button><br>
<button id="upload">Upload Skin</button><br> <button id="upload">Upload Skin</button><br>
<button id="random">Random Skin</button><br> <button id="random">Random Skin</button><br>
<button id="logout">Logout</button> <button id="logout">Logout</button>
<p class="message info"> </div>
Logging out will delete your password from storage, if you want it to autofill next time you can just close this window when you are done.
</p>
</div> </div>
<script src="../src/main.js"></script> <script src="../src/main.js"></script>
@ -29,4 +40,5 @@
{{ footer }} {{ footer }}
</footer> </footer>
</body> </body>
</html> </html>

View File

@ -1,11 +1,13 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }}</title> <title>{{ title }}</title>
<link rel="stylesheet" href="{{ css }}"> <link rel="stylesheet" href="{{ css }}">
</head> </head>
<body class="{{ theme }}"> <body class="{{ theme }}">
<header> <header>
<h1>{{ header }}</h1> <h1>{{ header }}</h1>
@ -14,11 +16,18 @@
<div class="content"> <div class="content">
<p class="message"></p> <p class="message"></p>
<img src="" class="skin" alt="Current Skin">
<button id="render">Switch to 3D</button> <div class="left">
<img src="" class="skin" id="flat" alt="Current Skin" style="display: none;">
<div id="mesh" style="display: inline;"></div>
<button id="switch" style="display: none;">Switch to 2D</button>
</div>
<div class="right">
<button id="download">Download</button> <button id="download">Download</button>
<button id="main">Back</button> <button id="main">Back</button>
</div> </div>
</div>
<script src="../src/skin.js"></script> <script src="../src/skin.js"></script>
@ -26,4 +35,5 @@
{{ footer }} {{ footer }}
</footer> </footer>
</body> </body>
</html> </html>

View File

@ -1,19 +1,34 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }}</title> <title>{{ title }}</title>
<link rel="stylesheet" href="{{ css }}"> <link rel="stylesheet" href="{{ css }}">
</head> </head>
<body class="{{ theme }}"> <body class="{{ theme }}">
<header> <header>
<h1>{{ header }}</h1> <h1>{{ header }}</h1>
<h3>Random Skin</h3> <h3>Random Skin</h3>
</header> </header>
<div class="content" id="current"> <div class="content" id="random">
<p class="message"></p>
<div class="left">
<img src="" class="skin" id="flat" alt="Current Skin" style="display: none;">
<div id="mesh" style="display: inline;"></div>
<button id="switch" style="display: none;">Switch to 2D</button>
</div>
<div class="right">
<button id="random">Random</button>
<button id="set">Use this skin</button>
<button id="download">Download</button>
<button id="main">Back</button>
</div>
</div> </div>
<script src="../src/skin.js"></script> <script src="../src/skin.js"></script>
@ -22,4 +37,5 @@
{{ footer }} {{ footer }}
</footer> </footer>
</body> </body>
</html> </html>

View File

@ -1,11 +1,13 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }}</title> <title>{{ title }}</title>
<link rel="stylesheet" href="{{ css }}"> <link rel="stylesheet" href="{{ css }}">
</head> </head>
<body class="{{ theme }}"> <body class="{{ theme }}">
<header> <header>
<h1>{{ header }}</h1> <h1>{{ header }}</h1>
@ -13,10 +15,28 @@
</header> </header>
<div class="content" id="current"> <div class="content" id="current">
<form action="#"> <p class="message"></p>
<div class="left">
<img src="" class="skin" id="flat" alt="Current Skin" style="display: none;">
<div id="mesh" style="display: inline;"></div>
<button id="switch" style="display: none;">Switch to 2D</button>
</div>
<div class="right">
<button id="remote">Fetch from URL</button>
<button id="local">Upload file</button>
<form action="#" id="remote" style="display: none;">
<input type="text" id="url" placeholder="URL">
<button type="submit">Submit</button>
</form>
<form action="#" id="local" style="display: none;">
<input type="file" id="skin"> <input type="file" id="skin">
<button type="submit">Submit</button> <button type="submit">Submit</button>
</form> </form>
<button id="main">Back</button>
</div>
</div> </div>
<script src="../src/skin.js"></script> <script src="../src/skin.js"></script>
@ -25,4 +45,5 @@
{{ footer }} {{ footer }}
</footer> </footer>
</body> </body>
</html> </html>

View File

@ -12,8 +12,8 @@ if (process.env.NODE_ENV === "dev") {
function createWindow () { function createWindow () {
// Create the browser window. // Create the browser window.
const win = new BrowserWindow({ const win = new BrowserWindow({
width: 320, width: 640,
height: 480, height: 520,
backgroundColor: "#ffffff", backgroundColor: "#ffffff",
resizable: false, resizable: false,
frame: true, frame: true,

26
package-lock.json generated
View File

@ -2462,6 +2462,27 @@
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
}, },
"skinview-utils": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/skinview-utils/-/skinview-utils-0.2.1.tgz",
"integrity": "sha512-WhXaKwYp1FBspaKq/AXb4EG3E2gaVpA57dXWvPgM7GP2F36E8Pfdg1MZESWpTMG2TGp8xKz5JELgKD3uXSG0EA=="
},
"skinview3d": {
"version": "2.0.0-alpha.1",
"resolved": "https://registry.npmjs.org/skinview3d/-/skinview3d-2.0.0-alpha.1.tgz",
"integrity": "sha512-HCA6nfBgr7SUwx+UYe8irNsHN0aVVKOplSPUVxEx5WRd9ZG5wpF4nXpObrKutfOz/TzYuxjdL0t1Th7E/noI/w==",
"requires": {
"skinview-utils": "^0.2.0",
"three": "^0.112.1"
},
"dependencies": {
"three": {
"version": "0.112.1",
"resolved": "https://registry.npmjs.org/three/-/three-0.112.1.tgz",
"integrity": "sha512-8I0O74hiYtKl3LgDNcPJbBGOlpekbcJ6fJnImmW3mFdeUFJ2H9Y3/UuUSW2sBdjrIlCM0gvOkaTEFlofO900TQ=="
}
}
},
"slice-ansi": { "slice-ansi": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
@ -2675,6 +2696,11 @@
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ="
}, },
"three": {
"version": "0.116.1",
"resolved": "https://registry.npmjs.org/three/-/three-0.116.1.tgz",
"integrity": "sha512-l2JCMiA/lVZAuSrLWRYMalvpR+0j8hbIhCpfs4V6JFnw2+JQEQJ5HltNpfFr+9TDpQts1BhtcISehWf/xBGPvQ=="
},
"through": { "through": {
"version": "2.3.8", "version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",

View File

@ -24,7 +24,9 @@
"electron-handlebars": "^2.0.0", "electron-handlebars": "^2.0.0",
"electron-reload": "^1.5.0", "electron-reload": "^1.5.0",
"eslint": "^7.0.0", "eslint": "^7.0.0",
"pngjs": "^5.0.0" "pngjs": "^5.0.0",
"skinview3d": "^2.0.0-alpha.1",
"three": "^0.116.1"
}, },
"devDependencies": {}, "devDependencies": {},
"repository": { "repository": {

View File

@ -54,7 +54,7 @@ async function authenticate(user, password) {
} }
// Get access token from Mojang Authserver // Get access token from Mojang Authserver
const form = document.querySelectorAll("div.content > form")[0]; const form = document.querySelectorAll("div.content > div.right > form")[0];
form.querySelectorAll("input#user")[0].value = authData.user; form.querySelectorAll("input#user")[0].value = authData.user;
form.querySelectorAll("input#password")[0].value = authData.password; form.querySelectorAll("input#password")[0].value = authData.password;

View File

@ -15,22 +15,22 @@ const msg = document.querySelectorAll("div.content > p.message")[0];
msg.classList.add("success"); msg.classList.add("success");
msg.innerHTML = `Logged in as ${session.selectedProfile.name}`; msg.innerHTML = `Logged in as ${session.selectedProfile.name}`;
document.querySelectorAll("div.content > button#current")[0].addEventListener("click", (e) => { document.querySelectorAll("div.content > div.right > button#current")[0].addEventListener("click", (e) => {
console.log("Clicked current button"); console.log("Clicked current button");
remote.getCurrentWindow().loadURL(path.join(`file://${__dirname}/skin_current.hbs`)); remote.getCurrentWindow().loadURL(path.join(`file://${__dirname}/skin_current.hbs`));
}); });
document.querySelectorAll("div.content > button#upload")[0].addEventListener("click", (e) => { document.querySelectorAll("div.content > div.right > button#upload")[0].addEventListener("click", (e) => {
console.log("Clicked upload button"); console.log("Clicked upload button");
remote.getCurrentWindow().loadURL(path.join(`file://${__dirname}/skin_upload.hbs`)); remote.getCurrentWindow().loadURL(path.join(`file://${__dirname}/skin_upload.hbs`));
}); });
document.querySelectorAll("div.content > button#random")[0].addEventListener("click", (e) => { document.querySelectorAll("div.content > div.right > button#random")[0].addEventListener("click", (e) => {
console.log("Clicked random button"); console.log("Clicked random button");
remote.getCurrentWindow().loadURL(path.join(`file://${__dirname}/skin_random.hbs`)); remote.getCurrentWindow().loadURL(path.join(`file://${__dirname}/skin_random.hbs`));
}); });
document.querySelectorAll("div.content > button#logout")[0].addEventListener("click", (e) => { document.querySelectorAll("div.content > div.right > button#logout")[0].addEventListener("click", (e) => {
console.log("Clicked logout button"); console.log("Clicked logout button");
if (ipcRenderer.sendSync("setSession", {})) { if (ipcRenderer.sendSync("setSession", {})) {
var authData = ipcRenderer.sendSync("getAuth"); var authData = ipcRenderer.sendSync("getAuth");

View File

@ -1,8 +1,14 @@
/* eslint-disable no-unused-vars */ /* eslint-disable no-unused-vars */
const { BrowserWindow, ipcRenderer, remote } = require("electron"); const {
BrowserWindow,
ipcRenderer,
remote
} = require("electron");
const axios = require("axios").default; const axios = require("axios").default;
const path = require("path"); const path = require("path");
const skinview3d = require("skinview3d/dist/skinview3d.min.js");
const session = ipcRenderer.sendSync("getSession"); const session = ipcRenderer.sendSync("getSession");
if (!session.accessToken) { if (!session.accessToken) {
console.log("Session does not exist, return to auth"); console.log("Session does not exist, return to auth");
@ -13,6 +19,36 @@ if (!session.accessToken) {
const regex = /(?!\w*_)\w*(?=\.\w*)/g; const regex = /(?!\w*_)\w*(?=\.\w*)/g;
var action = __filename.match(regex)[0]; var action = __filename.match(regex)[0];
var parser = new DOMParser();
var randomUrls = [];
// Switch button and views
var btn = document.querySelectorAll("div.content > div.left > button#switch")[0];
var view = {
flat: document.querySelectorAll("div.content > div.left > img.skin#flat")[0],
mesh: document.querySelectorAll("div.content > div.left > div#mesh")[0]
};
function setView(url, controls = true) {
btn.style.display = "initial";
view.flat.src = url;
view.mesh.innerHTML = "";
// Set mesh view
let skinViewer = new skinview3d.SkinViewer({
domElement: view.mesh,
width: 300,
height: 250,
skinUrl: url
});
let control = skinview3d.createOrbitControls(skinViewer);
control.enableRotate = controls;
control.enableZoom = false;
control.enablePan = false;
}
switch (action) { switch (action) {
case "current": case "current":
@ -20,38 +56,90 @@ case "current":
method: "GET", method: "GET",
url: "https://sessionserver.mojang.com/session/minecraft/profile/" + session.selectedProfile.id url: "https://sessionserver.mojang.com/session/minecraft/profile/" + session.selectedProfile.id
}).then((data) => { }).then((data) => {
const url = JSON.parse(atob(data.data.properties[0].value)).textures.SKIN.url; setView(JSON.parse(atob(data.data.properties[0].value)).textures.SKIN.url);
document.querySelectorAll("div.content > img.skin")[0].src = url; });
break;
case "upload":
document.querySelectorAll("div.content > div.right > button").forEach(element => {
element.addEventListener("click", (e) => {
document.querySelectorAll("div.content > div.right > button").forEach(button => {
if (button.id != "main") {
button.style.display = "none";
}
});
document.querySelectorAll(`div.content > div.right > form#${element.id}`)[0].style.display = "block";
});
});
document.querySelectorAll("div.content > button#download")[0].addEventListener("click", (e) => { break;
case "random":
axios({
method: "GET",
url: "https://nl.namemc.com/minecraft-skins/random"
}).then((data) => {
var namemc = parser.parseFromString(data.data, "text/html");
namemc.querySelectorAll("a").forEach((e) => {
var href = e.getAttribute("href");
if (href.includes("skin")) {
var id = href.split("/")[2];
if (id && id.length == 16 && !(id.includes("-"))) {
randomUrls.push("https://nl.namemc.com/texture/" + id + ".png");
}
}
});
function random() {
console.log(randomUrls.length);
if (randomUrls.length == 0) {
window.location.reload();
} else {
var id = Math.floor(Math.random() * (randomUrls.length - 0)) + 0;
setView(randomUrls[id]);
randomUrls.splice(id, 1);
}
}
random();
document.querySelectorAll("div.content > div.right > button#random")[0].addEventListener("click", (e) => {
random();
});
});
break;
}
// Download button action
document.querySelectorAll("div.content > div.right > button#download")[0].addEventListener("click", (e) => {
ipcRenderer.send("download", { ipcRenderer.send("download", {
url: url, url: view.flat.src,
properties: { properties: {
saveAs: true saveAs: true
} }
}); });
ipcRenderer.on("downloadResult", (event, arg) => { ipcRenderer.on("downloadResult", (event, arg) => {
const msg = document.querySelectorAll("div.content > p.message")[0]; var msg = document.querySelectorAll("div.content > p.message")[0];
console.log(msg); console.log(msg);
msg.classList.add("success"); msg.classList.add("success");
msg.innerHTML = "Downloaded successfully"; msg.innerHTML = "Downloaded successfully";
}); });
}); });
document.querySelectorAll("div.content > button#render")[0].addEventListener("click", (e) => { // Switch button action
console.log("Switch to 3D clicked"); btn.addEventListener("click", (e) => {
}); if (view.flat.style.display == "inline") {
}); view.flat.style.display = "none";
break; view.mesh.style.display = "inline";
case "upload": btn.innerHTML = "Switch to 2D";
} else {
view.flat.style.display = "inline";
view.mesh.style.display = "none";
btn.innerHTML = "Switch to 3D";
}
});
break; // Back button action
case "random": document.querySelectorAll("div.content > div.right > button#main")[0].addEventListener("click", (e) => {
break;
}
document.querySelectorAll("div.content > button#main")[0].addEventListener("click", (e) => {
remote.getCurrentWindow().loadURL(path.join(`file://${__dirname}/main.hbs`)); remote.getCurrentWindow().loadURL(path.join(`file://${__dirname}/main.hbs`));
}); });