Преглед изворни кода

Initial work on react.

Far from done.
Far from working.
Requires rewrite of UI logic using react patterns.
Daniel Scalzi пре 5 година
родитељ
комит
b9536ed014
47 измењених фајлова са 10954 додато и 2687 уклоњено
  1. 0 0
      assets/scripts/landing.js
  2. 0 0
      assets/scripts/login.js
  3. 0 0
      assets/scripts/overlay.js
  4. 0 0
      assets/scripts/settings.js
  5. 0 0
      assets/scripts/uibinder.js
  6. 14 10
      assets/scripts/uicore.ts
  7. 0 0
      assets/scripts/welcome.js
  8. 10424 2647
      package-lock.json
  9. 52 20
      package.json
  10. 0 0
      src/main/assetexec.ts
  11. 0 0
      src/main/assetguard.ts
  12. 0 0
      src/main/authmanager.ts
  13. 0 0
      src/main/configmanager.ts
  14. 0 0
      src/main/discordwrapper.ts
  15. 0 0
      src/main/distromanager.ts
  16. 0 0
      src/main/dropinmodutil.ts
  17. 0 0
      src/main/isdev.ts
  18. 0 0
      src/main/langloader.ts
  19. 0 0
      src/main/loggerutil.ts
  20. 23 4
      src/main/main.ts
  21. 0 0
      src/main/model/internal/config/LauncherConfig.ts
  22. 0 0
      src/main/model/internal/config/ModConfig.ts
  23. 0 0
      src/main/model/internal/config/NewsCache.ts
  24. 0 0
      src/main/model/internal/config/SavedAccount.ts
  25. 0 0
      src/main/model/mojang/auth/Agent.ts
  26. 0 0
      src/main/model/mojang/auth/AuthPayload.ts
  27. 0 0
      src/main/model/mojang/auth/Session.ts
  28. 0 0
      src/main/model/mojang/index/LauncherJson.ts
  29. 0 0
      src/main/model/mojang/index/VersionJson.ts
  30. 0 0
      src/main/mojang/mojang.ts
  31. 0 0
      src/main/mojang/type/Status.ts
  32. 0 0
      src/main/preloader.ts
  33. 0 0
      src/main/processbuilder.ts
  34. 0 0
      src/main/processbuilderold.js
  35. 0 0
      src/main/serverstatus.ts
  36. 0 0
      src/renderer/App.css
  37. 21 0
      src/renderer/app.tsx
  38. 14 0
      src/renderer/components/Application.tsx
  39. 151 0
      src/renderer/components/Frame.css
  40. 64 0
      src/renderer/components/Frame.tsx
  41. 8 6
      tsconfig.json
  42. 21 0
      webpack.base.config.js
  43. 43 0
      webpack.main.config.js
  44. 7 0
      webpack.main.prod.config.js
  45. 73 0
      webpack.renderer.config.js
  46. 32 0
      webpack.renderer.dev.config.js
  47. 7 0
      webpack.renderer.prod.config.js

+ 0 - 0
src/scripts/landing.js → assets/scripts/landing.js


+ 0 - 0
src/scripts/login.js → assets/scripts/login.js


+ 0 - 0
src/scripts/overlay.js → assets/scripts/overlay.js


+ 0 - 0
src/scripts/settings.js → assets/scripts/settings.js


+ 0 - 0
src/scripts/uibinder.js → assets/scripts/uibinder.js


+ 14 - 10
src/scripts/uicore.ts → assets/scripts/uicore.ts

@@ -1,3 +1,4 @@
+// @ts-nocheck
 import $ from 'jquery'
 import { ipcRenderer, remote, shell, webFrame } from 'electron'
 import { LoggerUtil } from '../loggerutil'
@@ -107,7 +108,7 @@ function changeAllowPrerelease(val){
 
 function showUpdateUI(info){
     //TODO Make this message a bit more informative `${info.version}`
-    document.getElementById('image_seal_container').setAttribute('update', true)
+    document.getElementById('image_seal_container').setAttribute('update', 'true')
     document.getElementById('image_seal_container').onclick = () => {
         /*setOverlayContent('Update Available', 'A new update for the launcher is available. Would you like to install now?', 'Install', 'Later')
         setOverlayHandler(() => {
@@ -138,6 +139,7 @@ document.addEventListener('readystatechange', function () {
         loggerUICore.log('UICore Initializing..')
 
         // Bind close button.
+        // DONE
         Array.from(document.getElementsByClassName('fCb')).map((val) => {
             val.addEventListener('click', e => {
                 const window = remote.getCurrentWindow()
@@ -146,6 +148,7 @@ document.addEventListener('readystatechange', function () {
         })
 
         // Bind restore down button.
+        // DONE
         Array.from(document.getElementsByClassName('fRb')).map((val) => {
             val.addEventListener('click', e => {
                 const window = remote.getCurrentWindow()
@@ -154,23 +157,24 @@ document.addEventListener('readystatechange', function () {
                 } else {
                     window.maximize()
                 }
-                document.activeElement.blur()
+                (document.activeElement as HTMLElement).blur()
             })
         })
 
         // Bind minimize button.
+        // DONE
         Array.from(document.getElementsByClassName('fMb')).map((val) => {
             val.addEventListener('click', e => {
                 const window = remote.getCurrentWindow()
-                window.minimize()
-                document.activeElement.blur()
+                window.minimize();
+                (document.activeElement as HTMLElement).blur()
             })
         })
 
         // Remove focus from social media buttons once they're clicked.
         Array.from(document.getElementsByClassName('mediaURL')).map(val => {
             val.addEventListener('click', e => {
-                document.activeElement.blur()
+                (document.activeElement as HTMLElement).blur()
             })
         })
 
@@ -184,10 +188,10 @@ document.addEventListener('readystatechange', function () {
         //const targetWidth2 = document.getElementById("server_selection").getBoundingClientRect().width
         //const targetWidth3 = document.getElementById("launch_button").getBoundingClientRect().width
 
-        document.getElementById('launch_details').style.maxWidth = 266.01
-        document.getElementById('launch_progress').style.width = 170.8
-        document.getElementById('launch_details_right').style.maxWidth = 170.8
-        document.getElementById('launch_progress_label').style.width = 53.21
+        document.getElementById('launch_details').style.maxWidth = '266.01'
+        document.getElementById('launch_progress').style.width = '170.8'
+        document.getElementById('launch_details_right').style.maxWidth = '170.8'
+        document.getElementById('launch_progress_label').style.width = '53.21'
         
     }
 
@@ -209,6 +213,6 @@ $(document).on('click', 'a[href^="http"]', function(event) {
 document.addEventListener('keydown', function (e) {
     if((e.key === 'I' || e.key === 'i') && e.ctrlKey && e.shiftKey){
         let window = remote.getCurrentWindow()
-        window.toggleDevTools()
+        window.webContents.toggleDevTools()
     }
 })

+ 0 - 0
src/scripts/welcome.js → assets/scripts/welcome.js


Разлика између датотеке није приказан због своје велике величине
+ 10424 - 2647
package-lock.json


+ 52 - 20
package.json

@@ -10,54 +10,86 @@
     "url": "https://github.com/dscalzi/HeliosLauncher/issues"
   },
   "private": true,
-  "main": "out/index.js",
+  "main": "./dist/main.js",
   "scripts": {
-    "clean": "rimraf out",
+    "clean": "rimraf dist",
     "tsc": "tsc",
-    "build": "npm run clean && npm run tsc",
     "start": "electron .",
     "cilinux": "node build.js WINDOWS && node build.js LINUX",
     "cidarwin": "node build.js MAC",
-    "dist": "cross-env ELECTRON_BUILDER_ALLOW_UNRESOLVED_DEPENDENCIES=true node build.js",
     "dist:win": "npm run dist -- WINDOWS",
     "dist:mac": "npm run dist -- MAC",
     "dist:linux": "npm run dist -- LINUX",
-    "lint": "eslint --config .eslintrc.json ."
+    "lint": "eslint --ext=jsx,js,tsx,ts src",
+    "build-main": "cross-env NODE_ENV=production webpack --config webpack.main.prod.config.js",
+    "build-renderer": "cross-env NODE_ENV=production webpack --config webpack.renderer.prod.config.js",
+    "build": "npm run build-main && npm run build-renderer",
+    "start-renderer-dev": "webpack-dev-server --config webpack.renderer.dev.config.js",
+    "start-main-dev": "webpack --config webpack.main.config.js && electron ./dist/main.js",
+    "start-dev": "cross-env START_HOT=1 npm run start-renderer-dev",
+    "pack": "npm run build && cross-env ELECTRON_BUILDER_ALLOW_UNRESOLVED_DEPENDENCIES=true node build.js --dir",
+    "dist": "npm run build && cross-env ELECTRON_BUILDER_ALLOW_UNRESOLVED_DEPENDENCIES=true node build.js",
+    "postinstall": "electron-builder install-app-deps"
   },
   "engines": {
     "node": "12.x.x"
   },
   "dependencies": {
-    "adm-zip": "^0.4.13",
-    "async": "^3.1.1",
+    "adm-zip": "^0.4.14",
+    "async": "^3.2.0",
     "discord-rpc": "3.1.0",
-    "ejs": "^3.0.1",
-    "ejs-electron": "^2.0.3",
-    "electron-updater": "^4.2.0",
+    "electron-updater": "^4.2.4",
     "fs-extra": "^8.1.0",
     "github-syntax-dark": "^0.5.0",
     "jquery": "^3.4.1",
-    "request": "^2.88.0",
-    "semver": "^7.1.1",
+    "request": "^2.88.2",
+    "semver": "^7.1.3",
     "tar-fs": "^2.0.0",
     "winreg": "^1.2.4"
   },
   "devDependencies": {
+    "@babel/core": "^7.8.7",
+    "@babel/plugin-proposal-class-properties": "^7.8.3",
+    "@babel/polyfill": "^7.8.7",
+    "@babel/preset-env": "^7.8.7",
+    "@babel/preset-react": "^7.8.3",
+    "@babel/preset-typescript": "^7.8.3",
     "@types/adm-zip": "^0.4.32",
-    "@types/async": "^3.0.5",
+    "@types/async": "^3.0.8",
     "@types/discord-rpc": "^3.0.2",
-    "@types/fs-extra": "^8.0.1",
-    "@types/jquery": "^3.3.31",
-    "@types/node": "^12.12.25",
+    "@types/fs-extra": "^8.1.0",
+    "@types/jquery": "^3.3.33",
+    "@types/node": "^12.12.29",
+    "@types/react": "^16.9.23",
+    "@types/react-dom": "^16.9.5",
+    "@types/react-redux": "^7.1.7",
     "@types/request": "^2.48.4",
     "@types/tar-fs": "^1.16.2",
     "@types/winreg": "^1.2.30",
-    "cross-env": "^7.0.0",
-    "electron": "^7.1.10",
-    "electron-builder": "^22.2.0",
+    "babel-loader": "^8.0.6",
+    "cross-env": "^7.0.2",
+    "css-loader": "^3.4.2",
+    "electron": "^7.1.14",
+    "electron-builder": "^22.4.0",
+    "electron-devtools-installer": "^2.2.4",
     "eslint": "^6.8.0",
+    "fork-ts-checker-webpack-plugin": "^4.0.5",
     "helios-distribution-types": "1.0.0-pre.1",
-    "rimraf": "^3.0.0"
+    "html-webpack-plugin": "^3.2.0",
+    "react": "^16.13.0",
+    "react-dom": "^16.13.0",
+    "react-hot-loader": "^4.12.19",
+    "react-redux": "^7.2.0",
+    "redux": "^4.0.5",
+    "redux-devtools-extension": "^2.13.8",
+    "rimraf": "^3.0.2",
+    "source-map-loader": "^0.2.4",
+    "style-loader": "^1.1.3",
+    "typescript": "^3.8.3",
+    "webpack": "^4.42.0",
+    "webpack-cli": "^3.3.11",
+    "webpack-dev-server": "^3.10.3",
+    "webpack-merge": "^4.2.2"
   },
   "repository": {
     "type": "git",

+ 0 - 0
src/assetexec.ts → src/main/assetexec.ts


+ 0 - 0
src/assetguard.ts → src/main/assetguard.ts


+ 0 - 0
src/authmanager.ts → src/main/authmanager.ts


+ 0 - 0
src/configmanager.ts → src/main/configmanager.ts


+ 0 - 0
src/discordwrapper.ts → src/main/discordwrapper.ts


+ 0 - 0
src/distromanager.ts → src/main/distromanager.ts


+ 0 - 0
src/dropinmodutil.ts → src/main/dropinmodutil.ts


+ 0 - 0
src/isdev.ts → src/main/isdev.ts


+ 0 - 0
src/langloader.ts → src/main/langloader.ts


+ 0 - 0
src/loggerutil.ts → src/main/loggerutil.ts


+ 23 - 4
src/index.ts → src/main/main.ts

@@ -6,7 +6,15 @@ import { format } from "url"
 import { autoUpdater } from 'electron-updater'
 import isdev from "./isdev"
 
-const ejse = require('ejs-electron')
+const installExtensions = async () => {
+    const installer = require('electron-devtools-installer');
+    const forceDownload = !!process.env.UPGRADE_EXTENSIONS;
+    const extensions = ['REACT_DEVELOPER_TOOLS', 'REDUX_DEVTOOLS'];
+
+    return Promise.all(
+        extensions.map(name => installer.default(installer[name], forceDownload))
+    ).catch(console.log); // eslint-disable-line no-console
+};
 
 // Setup auto updater.
 function initAutoUpdater(event: any, data: any) {
@@ -89,7 +97,11 @@ app.disableHardwareAcceleration()
 // be closed automatically when the JavaScript object is garbage collected.
 let win: BrowserWindow | null
 
-function createWindow() {
+async function createWindow() {
+
+    if (process.env.NODE_ENV !== 'production') {
+        await installExtensions();
+    }
 
     win = new BrowserWindow({
         width: 980,
@@ -104,10 +116,10 @@ function createWindow() {
         backgroundColor: '#171614'
     })
 
-    ejse.data('bkid', Math.floor((Math.random() * readdirSync(join(__dirname, '..', 'assets', 'images', 'backgrounds')).length)))
+    // ejse.data('bkid', Math.floor((Math.random() * readdirSync(join(__dirname, '..', 'assets', 'images', 'backgrounds')).length)))
 
     win.loadURL(format({
-        pathname: join(__dirname, '..', 'assets', 'templates', 'app.ejs'),
+        pathname: join(__dirname, 'index.html'),
         protocol: 'file:',
         slashes: true
     }))
@@ -120,6 +132,13 @@ function createWindow() {
 
     win.resizable = true
 
+    if (process.env.NODE_ENV !== 'production') {
+        // Open DevTools, see https://github.com/electron/electron/issues/12438 for why we wait for dom-ready
+        win.webContents.once('dom-ready', () => {
+            win!.webContents.openDevTools();
+        });
+    }
+
     win.on('closed', () => {
         win = null
     })

+ 0 - 0
src/model/internal/config/LauncherConfig.ts → src/main/model/internal/config/LauncherConfig.ts


+ 0 - 0
src/model/internal/config/ModConfig.ts → src/main/model/internal/config/ModConfig.ts


+ 0 - 0
src/model/internal/config/NewsCache.ts → src/main/model/internal/config/NewsCache.ts


+ 0 - 0
src/model/internal/config/SavedAccount.ts → src/main/model/internal/config/SavedAccount.ts


+ 0 - 0
src/model/mojang/auth/Agent.ts → src/main/model/mojang/auth/Agent.ts


+ 0 - 0
src/model/mojang/auth/AuthPayload.ts → src/main/model/mojang/auth/AuthPayload.ts


+ 0 - 0
src/model/mojang/auth/Session.ts → src/main/model/mojang/auth/Session.ts


+ 0 - 0
src/model/mojang/index/LauncherJson.ts → src/main/model/mojang/index/LauncherJson.ts


+ 0 - 0
src/model/mojang/index/VersionJson.ts → src/main/model/mojang/index/VersionJson.ts


+ 0 - 0
src/mojang/mojang.ts → src/main/mojang/mojang.ts


+ 0 - 0
src/mojang/type/Status.ts → src/main/mojang/type/Status.ts


+ 0 - 0
src/preloader.ts → src/main/preloader.ts


+ 0 - 0
src/processbuilder.ts → src/main/processbuilder.ts


+ 0 - 0
src/processbuilderold.js → src/main/processbuilderold.js


+ 0 - 0
src/serverstatus.ts → src/main/serverstatus.ts


+ 0 - 0
src/renderer/App.css


+ 21 - 0
src/renderer/app.tsx

@@ -0,0 +1,21 @@
+import * as React from 'react';
+import * as ReactDOM from 'react-dom';
+import { AppContainer } from 'react-hot-loader';
+
+import Application from './components/Application';
+
+// Create main element
+const mainElement = document.createElement('div');
+document.body.appendChild(mainElement);
+
+// Render components
+const render = (Component: () => JSX.Element) => {
+    ReactDOM.render(
+        <AppContainer>
+            <Component />
+        </AppContainer>,
+        mainElement
+    );
+};
+
+render(Application);

+ 14 - 0
src/renderer/components/Application.tsx

@@ -0,0 +1,14 @@
+import { hot } from 'react-hot-loader/root';
+import * as React from 'react';
+import Frame from './Frame';
+
+const Application = () => (
+    <>
+    <Frame />
+    <div>
+        Hello World from Electron!
+    </div>
+    </>
+);
+
+export default hot(Application);

+ 151 - 0
src/renderer/components/Frame.css

@@ -0,0 +1,151 @@
+/* Frame Bar */
+#frameBar {
+    position: relative;
+    z-index: 100;
+    display: flex;
+    flex-direction: column;
+    transition: background-color 1s ease;
+    /*background-color: rgba(0, 0, 0, 0.5);*/
+    -webkit-user-select: none;
+}
+
+/* Undraggable region on the top of the frame. */
+#frameResizableTop {
+    height: 2px;
+    width: 100%;
+    -webkit-app-region: no-drag;
+}
+
+/* Flexbox to wrap the main frame content. */
+#frameMain {
+    display: flex;
+    height: 20px
+}
+
+/* Undraggable region on the left and right of the frame. */
+.frameResizableVert {
+    width: 2px;
+    -webkit-app-region: no-drag;
+}
+
+/* Main frame content for windows. */
+#frameContentWin {
+    display: flex;
+    justify-content: space-between;
+    width: 100%;
+    -webkit-app-region: drag;
+}
+
+/* Main frame content for darwin. */
+#frameContentDarwin {
+    display: flex;
+    justify-content: flex-start;
+    align-items: center;
+    width: 100%;
+    -webkit-app-region: drag;
+}
+
+/* Frame logo (windows only). */
+#frameTitleDock {
+    padding: 0px 10px;
+}
+#frameTitleText {
+    font-size: 14px;
+    font-family: 'Avenir Medium';
+    letter-spacing: 0.5px;
+}
+
+/* Windows frame button dock. */
+#frameButtonDockWin {
+    -webkit-app-region: no-drag !important;
+    position: relative;
+    top: -2px;
+    right: -2px;
+    height: 22px;
+}
+#frameButtonDockWin > .frameButton:not(:first-child) {
+    margin-left: -4px;
+}
+
+/* Darwin frame button dock: NaN; */
+#frameButtonDockDarwin {
+    -webkit-app-region: no-drag !important;
+    position: relative;
+    top: -1px;
+    right: -1px;
+}
+
+/* Windows Frame Button Styles. */
+.frameButton {
+    background: none;
+    border: none;
+    height: 22px;
+    width: 39px;
+    cursor: pointer;
+}
+.frameButton:hover,
+.frameButton:focus {
+    background: rgba(189, 189, 189, 0.43);
+}
+.frameButton:active {
+    background: rgba(156, 156, 156, 0.43);
+}
+.frameButton:focus {
+    outline: 0px;
+}
+
+/* Close button is red. */
+#frameButton_close:hover,
+#frameButton_close:focus {
+    background: rgba(255, 53, 53, 0.61) !important;
+}
+#frameButton_close:active {
+    background: rgba(235, 0, 0, 0.61) !important;
+}
+
+/* Darwin Frame Button Styles. */
+.frameButtonDarwin {
+    height: 12px;
+    width: 12px;
+    border-radius: 50%;
+    border: 0px;
+    margin-left: 5px;
+    -webkit-app-region: no-drag !important;
+    cursor: pointer;
+}
+.frameButtonDarwin:focus {
+    outline: 0px;
+}
+
+#frameButtonDarwin_close {
+    background-color: #e74c32;
+}
+#frameButtonDarwin_close:hover,
+#frameButtonDarwin_close:focus {
+    background-color: #FF9A8A;
+}
+#frameButtonDarwin_close:active {
+    background-color: #ff8d7b;
+}
+
+#frameButtonDarwin_minimize {
+    background-color: #fed045;
+}
+#frameButtonDarwin_minimize:hover,
+#frameButtonDarwin_minimize:focus {
+    background-color: #FFE9A9;
+}
+#frameButtonDarwin_minimize:active {
+    background-color: #ffde7b;
+}
+
+#frameButtonDarwin_restoredown {
+    background-color: #96e734;
+}
+#frameButtonDarwin_restoredown:hover,
+#frameButtonDarwin_restoredown:focus {
+    background-color: #D6FFA6;
+}
+#frameButtonDarwin_restoredown:active {
+    background-color: #bfff76;
+}

+ 64 - 0
src/renderer/components/Frame.tsx

@@ -0,0 +1,64 @@
+import * as React from 'react';
+import { remote } from 'electron';
+import './Frame.css';
+
+require('./Frame.css')
+
+function closeHandler() {
+    const window = remote.getCurrentWindow();
+    window.close();
+}
+
+function restoreDownHandler() {
+    const window = remote.getCurrentWindow()
+    if(window.isMaximized()){
+        window.unmaximize()
+    } else {
+        window.maximize()
+    }
+    (document.activeElement as HTMLElement).blur()
+}
+
+function minimizeHandler() {
+    const window = remote.getCurrentWindow()
+    window.minimize();
+    (document.activeElement as HTMLElement).blur()
+}
+
+const Frame = () => (
+    <div id="frameBar">
+    <div id="frameResizableTop" className="frameDragPadder"></div>
+    <div id="frameMain">
+        <div className="frameResizableVert frameDragPadder"></div>
+        { process.platform === 'darwin' ?
+            <div id="frameContentDarwin">
+                <div id="frameButtonDockDarwin">
+                    <button className="frameButtonDarwin" onClick={closeHandler} id="frameButtonDarwin_close" tabIndex={-1}></button>
+                    <button className="frameButtonDarwin" onClick={minimizeHandler} id="frameButtonDarwin_minimize" tabIndex={-1}></button>
+                    <button className="frameButtonDarwin" onClick={restoreDownHandler} id="frameButtonDarwin_restoredown" tabIndex={-1}></button>
+                </div>
+            </div>
+        : 
+            <div id="frameContentWin">
+                <div id="frameTitleDock">
+                    <span id="frameTitleText">Helios Launcher</span>
+                </div>
+                <div id="frameButtonDockWin">
+                    <button className="frameButton" onClick={minimizeHandler} id="frameButton_minimize" tabIndex={-1}>
+                        <svg name="TitleBarMinimize" width="10" height="10" viewBox="0 0 12 12"><rect stroke="#ffffff" fill="#ffffff" width="10" height="1" x="1" y="6"></rect></svg>
+                    </button>
+                    <button className="frameButton" onClick={restoreDownHandler} id="frameButton_restoredown" tabIndex={-1}>
+                        <svg name="TitleBarMaximize" width="10" height="10" viewBox="0 0 12 12"><rect width="9" height="9" x="1.5" y="1.5" fill="none" stroke="#ffffff" stroke-width="1.4px"></rect></svg>
+                    </button>
+                    <button className="frameButton" onClick={closeHandler} id="frameButton_close" tabIndex={-1}>
+                        <svg name="TitleBarClose" width="10" height="10" viewBox="0 0 12 12"><polygon stroke="#ffffff" fill="#ffffff" fill-rule="evenodd" points="11 1.576 6.583 6 11 10.424 10.424 11 6 6.583 1.576 11 1 10.424 5.417 6 1 1.576 1.576 1 6 5.417 10.424 1"></polygon></svg>
+                    </button>
+                </div>
+            </div>
+        }
+        <div className="frameResizableVert frameDragPadder"></div>
+    </div>
+</div>
+);
+
+export default Frame;

+ 8 - 6
tsconfig.json

@@ -4,23 +4,25 @@
     "target": "ES2019",                       /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
     "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
     "lib": [                                  /* Specify library files to be included in the compilation. */
-      "ES2019",
-      "dom"
+      "DOM",
+      "ES2019"
     ],
     "allowJs": true,                          /* Allow javascript files to be compiled. */
+    "jsx": "react",
     // "checkJs": true,                       /* Report errors in .js files. */
     // "declaration": true,                   /* Generates corresponding '.d.ts' file. */
     // "declarationMap": true,                /* Generates a sourcemap for each corresponding '.d.ts' file. */
-    "sourceMap": false,                        /* Generates corresponding '.map' file. */
-    "outDir": "out",                          /* Redirect output structure to the directory. */
-    "baseUrl": ".",                           /* Base directory to resolve non-absolute module names. */
+    "sourceMap": true,                        /* Generates corresponding '.map' file. */
+    "outDir": "dist",                         /* Redirect output structure to the directory. */
+    "strict": true,
+    // "baseUrl": ".",                           /* Base directory to resolve non-absolute module names. */
     // "paths": {                                /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
     //   "*": ["node_modules/*"]
     // },
     "esModuleInterop": true                   /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
   },
   "include": [
-    "src/**/*"
+    "./src"
   ],
   "exclude": [ "node_modules" ]
 }

+ 21 - 0
webpack.base.config.js

@@ -0,0 +1,21 @@
+'use strict'
+
+const path = require('path')
+
+module.exports = {
+    mode: 'development',
+    output: {
+        path: path.resolve(__dirname, 'dist'),
+        filename: '[name].js'
+    },
+    node: {
+        __dirname: false,
+        __filename: false
+    },
+    resolve: {
+        extensions: ['.tsx', '.ts', '.js', '.json']
+    },
+    devtool: 'source-map',
+    plugins: [
+    ]
+}

+ 43 - 0
webpack.main.config.js

@@ -0,0 +1,43 @@
+const webpack = require('webpack')
+const merge = require('webpack-merge')
+const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin')
+
+const baseConfig = require('./webpack.base.config')
+
+module.exports = merge.smart(baseConfig, {
+    target: 'electron-main',
+    entry: {
+        main: './src/main/main.ts'
+    },
+    module: {
+        rules: [
+            {
+                test: /\.tsx?$/,
+                exclude: /node_modules/,
+                loader: 'babel-loader',
+                options: {
+                    cacheDirectory: true,
+                    babelrc: false,
+                    presets: [
+                        [
+                            '@babel/preset-env',
+                            { targets: 'maintained node versions' }
+                        ],
+                        '@babel/preset-typescript'
+                    ],
+                    plugins: [
+                        ['@babel/plugin-proposal-class-properties', { loose: true }]
+                    ]
+                }
+            }
+        ]
+    },
+    plugins: [
+        new ForkTsCheckerWebpackPlugin({
+            reportFiles: ['src/main/**/*']
+        }),
+        new webpack.DefinePlugin({
+            'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
+        })
+    ]
+})

+ 7 - 0
webpack.main.prod.config.js

@@ -0,0 +1,7 @@
+const merge = require('webpack-merge')
+
+const baseConfig = require('./webpack.main.config')
+
+module.exports = merge.smart(baseConfig, {
+    mode: 'production'
+})

+ 73 - 0
webpack.renderer.config.js

@@ -0,0 +1,73 @@
+const webpack = require('webpack')
+const merge = require('webpack-merge')
+const HtmlWebpackPlugin = require('html-webpack-plugin')
+const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin')
+
+const baseConfig = require('./webpack.base.config')
+
+module.exports = merge.smart(baseConfig, {
+    target: 'electron-renderer',
+    entry: {
+        app: ['@babel/polyfill','./src/renderer/app.tsx']
+    },
+    module: {
+        rules: [
+            {
+                test: /\.tsx?$/,
+                exclude: /node_modules/,
+                loader: 'babel-loader',
+                options: {
+                    cacheDirectory: true,
+                    babelrc: false,
+                    presets: [
+                        [
+                            '@babel/preset-env',
+                            { targets: { browsers: 'last 2 versions ' } }
+                        ],
+                        '@babel/preset-typescript',
+                        '@babel/preset-react'
+                    ],
+                    plugins: [
+                        ['@babel/plugin-proposal-class-properties', { loose: true }]
+                    ]
+                }
+            },
+            {
+                test: /\.scss$/,
+                loaders: ['style-loader', 'css-loader', 'sass-loader']
+            },
+            {
+                test: /\.css$/,
+                loaders: ['style-loader', 'css-loader']
+            },
+            {
+                test: /\.(gif|png|jpe?g|svg)$/,
+                use: [
+                    'file-loader',
+                    {
+                        loader: 'image-webpack-loader',
+                        options: {
+                            disable: true
+                        }
+                    }
+                ]
+            },
+            // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
+            {
+                enforce: 'pre',
+                test: /\.js$/,
+                loader: 'source-map-loader'
+            }
+        ]
+    },
+    plugins: [
+        new ForkTsCheckerWebpackPlugin({
+            reportFiles: ['src/renderer/**/*']
+        }),
+        new webpack.NamedModulesPlugin(),
+        new HtmlWebpackPlugin(),
+        new webpack.DefinePlugin({
+            'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
+        })
+    ]
+})

+ 32 - 0
webpack.renderer.dev.config.js

@@ -0,0 +1,32 @@
+const merge = require('webpack-merge')
+const spawn = require('child_process').spawn
+
+const baseConfig = require('./webpack.renderer.config')
+
+module.exports = merge.smart(baseConfig, {
+    devServer: {
+        port: 2003,
+        compress: true,
+        noInfo: true,
+        stats: 'errors-only',
+        inline: true,
+        hot: true,
+        headers: { 'Access-Control-Allow-Origin': '*' },
+        historyApiFallback: {
+            verbose: true,
+            disableDotRule: false
+        },
+        before() {
+            if (process.env.START_HOT) {
+                console.log('Starting main process')
+                spawn('npm', ['run', 'start-main-dev'], {
+                    shell: true,
+                    env: process.env,
+                    stdio: 'inherit'
+                })
+                    .on('close', code => process.exit(code))
+                    .on('error', spawnError => console.error(spawnError))
+            }
+        }
+    }
+})

+ 7 - 0
webpack.renderer.prod.config.js

@@ -0,0 +1,7 @@
+const merge = require('webpack-merge')
+
+const baseConfig = require('./webpack.renderer.config')
+
+module.exports = merge.smart(baseConfig, {
+    mode: 'production'
+})

Неке датотеке нису приказане због велике количине промена