Skip to content

Commit

Permalink
Merge pull request #41 from tsully/refactor
Browse files Browse the repository at this point in the history
Code/Typescript error cleanup and new UI for project management functionality
  • Loading branch information
andrewjcho84 authored Jul 12, 2020
2 parents 4a9e80b + 67991ea commit 688198d
Show file tree
Hide file tree
Showing 50 changed files with 948 additions and 1,191 deletions.
48 changes: 20 additions & 28 deletions app/electron/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,35 @@ const {
dialog,
BrowserWindow,
session,
ipcMain,
Menu
ipcMain
} = require('electron');

// The splash screen is what appears while the app is loading
const { initSplashScreen, OfficeTemplate } = require('electron-splashscreen');
const { resolve } = require('app-root-path');
const Protocol = require('./protocol');
const MenuBuilder = require('./menu');
const path = require('path');

const {
default: installExtension,
REACT_DEVELOPER_TOOLS
} = require('electron-devtools-installer');
const debug = require('electron-debug');

const Protocol = require('./protocol');
// menu from another file to modularize the code
const MenuBuilder = require('./menu');

const path = require('path');
// const fs = require('fs');

console.log('NODE ENV is ', process.env.NODE_ENV);
const isDev = process.env.NODE_ENV === 'development';
const port = 8080;
const selfHost = `http://localhost:${port}`;

// main.js is what controls the lifecycle of the electron applicaton

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win;
let menuBuilder;

// function to create a new broswer window
// this function will be called when Electron has initialized itself
async function createWindow() {
if (isDev) {
await installExtension([REACT_DEVELOPER_TOOLS])
Expand All @@ -52,12 +52,10 @@ async function createWindow() {
height: 1080,
// window title
title: `ReacType`,
// the browser window will not display intiially as it's loading
// once the browser window renders, a function is called below that hides the splash screen and displays the browser window
show: false,
icon: path.join(__dirname, '../src/public/icons/png/256x256.png'),
win: {
icon: path.join(__dirname, '../src/public/icons/win/icon.ico'),
target: ['portable']
},
// icon: path.join(__dirname, '../src/public/icons/png/256x256.png'),
webPreferences: {
zoomFactor: 0.7,
// enable devtools
Expand All @@ -79,10 +77,7 @@ async function createWindow() {
}
});

console.log('PATH is ', resolve('/'));

//splash screen deets
// TODO: splash screen logo/icon aren't loading in dev mode
// Splash screen that appears while loading
const hideSplashscreen = initSplashScreen({
mainWindow: win,
icon: resolve('app/src/public/icons/png/64x64.png'),
Expand Down Expand Up @@ -112,9 +107,9 @@ async function createWindow() {
hideSplashscreen();
});

// Only do these things when in development
// automatically open DevTools when opening the app
// Note: devtools is creating many errors in the logs at the moment but can't figure out how to resolve the issue
if (isDev) {
// automatically open DevTools when opening the app
win.webContents.once('dom-ready', () => {
debug();
win.webContents.openDevTools();
Expand All @@ -129,6 +124,10 @@ async function createWindow() {
win = null;
});

menuBuilder = MenuBuilder(win, 'ReacType');
menuBuilder.buildMenu();

// Removed this security feature for now since it's not being used
// https://electronjs.org/docs/tutorial/security#4-handle-session-permission-requests-from-remote-content
// TODO: is this the same type of sessions that have in react type
// Could potentially remove this session capability - it appears to be more focused on approving requests from 3rd party notifications
Expand Down Expand Up @@ -163,12 +162,8 @@ async function createWindow() {
});
}
});

menuBuilder = MenuBuilder(win, 'ReacType');
menuBuilder.buildMenu();
}

// TODO: unclear of whether this is necsssary or not. Looks like a security best practice but will likely introduce complications
// Needs to be called before app is ready;
// gives our scheme access to load relative files,
// as well as local storage, cookies, etc.
Expand Down Expand Up @@ -197,8 +192,6 @@ app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
} else {
// TODO: remove i18nextbackend
// i18nextBackend.clearMainBindings(ipcMain);
ContextMenu.clearMainBindings(ipcMain);
}
});
Expand All @@ -214,7 +207,6 @@ app.on('activate', () => {
// https://electronjs.org/docs/tutorial/security#12-disable-or-limit-navigation
// limits navigation within the app to a whitelisted array
// redirects are a common attack vector
// TODO: add github to the validOrigins whitelist array

// after the contents of the webpage are rendered, set up event listeners on the webContents
app.on('web-contents-created', (event, contents) => {
Expand Down
31 changes: 15 additions & 16 deletions app/electron/preload.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// contextBridge is what allows context to be translated between the main process and the render process
// ipcRenderer sends messsages between render process and the main process
const { contextBridge, ipcRenderer } = require('electron');
const { contextBridge } = require('electron');
const { existsSync, writeFileSync, mkdirSync, writeFile } = require('fs');
const formatCode = require('./preloadFunctions/format');
const {
Expand All @@ -15,24 +14,24 @@ const {
reload
} = require('./preloadFunctions/cookies');

// Expose protected methods that allow the renderer process to use
// the ipcRenderer without exposing the entire object
// Expose protected methods that allow the renderer process to use select node methods
// without exposing all node functionality. This is a critical security feature
// 'mainWorld" is the context that the main renderer runs in
// with contextIsolation on (see webpreferences on main.js), this preload script runs isolated
// "api" is the key that injects the api into the window
// to access these keys in the renderer process, we'll do window.key
// to access these keys in the renderer process, we'll do window.api
// the api object (second arg) can contain functions, strings, bools, numbers, arrays, obects in value
// data primitives sent on the bridge are immutable and changes in one context won't carry over to another context
contextBridge.exposeInMainWorld('api', {
formatCode: formatCode,
chooseAppDir: chooseAppDir,
addAppDirChosenListener: addAppDirChosenListener,
removeAllAppDirChosenListeners: removeAllAppDirChosenListeners,
existsSync: existsSync,
writeFileSync: writeFileSync,
mkdirSync: mkdirSync,
writeFile: writeFile,
setCookie: setCookie,
getCookie: getCookie,
delCookie: delCookie
formatCode,
chooseAppDir,
addAppDirChosenListener,
removeAllAppDirChosenListeners,
existsSync,
writeFileSync,
mkdirSync,
writeFile,
setCookie,
getCookie,
delCookie
});
2 changes: 1 addition & 1 deletion app/electron/preloadFunctions/format.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ const { format } = require('prettier');

// format code using prettier
// this format function is used in the render process to format the code in the code preview
// the format function is defined in the main process because it needs to access node functionality ('fs')
const formatCode = code => {
return format(code, {
singleQuote: true,
trailingComma: 'es5',
bracketSpacing: true,
jsxBracketSameLine: true,
// parser: 'babel'
parser: 'typescript'
});
};
Expand Down
63 changes: 24 additions & 39 deletions app/electron/protocol.js
Original file line number Diff line number Diff line change
@@ -1,59 +1,44 @@
/*
Reasonably Secure Electron
Copyright (C) 2019 Bishop Fox
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-------------------------------------------------------------------------
Implementing a custom protocol achieves two goals:
1) Allows us to use ES6 modules/targets for Angular
2) Avoids running the app in a file:// origin
*/

const fs = require("fs");
const path = require("path");
// Implementing a custom protocol achieves two goals:
// 1) Allows us to use ES6 modules/targets for Angular
// 2) Avoids running the app in a file:// origin

const DIST_PATH = path.join(__dirname, "../../app/dist");
const scheme = "app";
const fs = require('fs');
const path = require('path');

const DIST_PATH = path.join(__dirname, '../../app/dist');
const scheme = 'app';

const mimeTypes = {
".js": "text/javascript",
".mjs": "text/javascript",
".html": "text/html",
".htm": "text/html",
".json": "application/json",
".css": "text/css",
".svg": "application/svg+xml",
".ico": "image/vnd.microsoft.icon",
".png": "image/png",
".jpg": "image/jpeg",
".map": "text/plain"
'.js': 'text/javascript',
'.mjs': 'text/javascript',
'.html': 'text/html',
'.htm': 'text/html',
'.json': 'application/json',
'.css': 'text/css',
'.svg': 'application/svg+xml',
'.ico': 'image/vnd.microsoft.icon',
'.png': 'image/png',
'.jpg': 'image/jpeg',
'.map': 'text/plain'
};

function charset(mimeType) {
return [".html", ".htm", ".js", ".mjs"].some((m) => m === mimeType)
? "utf-8"
return ['.html', '.htm', '.js', '.mjs'].some(m => m === mimeType)
? 'utf-8'
: null;
}

function mime(filename) {
const type = mimeTypes[path.extname(`${filename || ""}`).toLowerCase()];
const type = mimeTypes[path.extname(`${filename || ''}`).toLowerCase()];
return type ? type : null;
}

function requestHandler(req, next) {
const reqUrl = new URL(req.url);
let reqPath = path.normalize(reqUrl.pathname);
if (reqPath === "/") {
reqPath = "/index-prod.html";
if (reqPath === '/') {
reqPath = '/index-prod.html';
}
const reqFilename = path.basename(reqPath);
fs.readFile(path.join(DIST_PATH, reqPath), (err, data) => {
Expand Down
2 changes: 1 addition & 1 deletion app/src/components/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useReducer, useEffect } from 'react';
import React, { useReducer, useEffect } from 'react';
import '../public/styles/style.css';
import '../public/styles/styleNew.css';
import { DndProvider } from 'react-dnd';
Expand Down
Loading

0 comments on commit 688198d

Please sign in to comment.