electron: removed workspaces, added sentry lib, electron-builder
This commit is contained in:
parent
10d04f9114
commit
d31428aa42
17
Makefile
17
Makefile
|
@ -23,18 +23,19 @@ all:
|
|||
$(TSC)
|
||||
npm run mkdoc
|
||||
|
||||
dist:
|
||||
distro:
|
||||
rm -fr $(TMP) && mkdir -p $(TMP)
|
||||
git archive HEAD | tar x -C $(TMP)
|
||||
cp -rp gen $(TMP)
|
||||
rm -r $(TMP)/doc $(TMP)/meta $(TMP)/scripts $(TMP)/test* $(TMP)/tools $(TMP)/.[a-z]* $(TMP)/ts*.json
|
||||
rm -r $(TMP)/doc $(TMP)/scripts $(TMP)/test* $(TMP)/tools $(TMP)/.[a-z]* $(TMP)/ts*.json # $(TMP)/meta
|
||||
rm -f $(TMP)/javatari && mkdir -p $(TMP)/javatari && cp javatari.js/release/javatari/* $(TMP)/javatari/
|
||||
tar cf - `cat electron.html | egrep "^<(script|link)" | egrep -o '"([^"]+).(js|css)"' | cut -d '"' -f2` | tar x -C $(TMP)
|
||||
|
||||
%.dist:
|
||||
./node_modules/.bin/electron-packager $(TMP) --icon meta/icons/8bitworkshop-icon-1024.icns --out ./release --overwrite --platform $*
|
||||
|
||||
package: dist darwin.dist win32.dist linux.dist
|
||||
desktop: distro
|
||||
pushd $(TMP) && npm i && popd $(TMP)
|
||||
mkdir -p $(TMP)/resources
|
||||
./node_modules/.bin/electron-builder -mlw --project $(TMP) # --prepackaged $(TMP)
|
||||
mv $(TMP)/dist/*.* ./release/
|
||||
|
||||
meta/electron.diff: index.html electron.html
|
||||
-diff -u index.html electron.html > $@
|
||||
|
@ -53,11 +54,11 @@ astrolibre.b64.txt: astrolibre.rom
|
|||
|
||||
VERSION := $(shell git tag -l --points-at HEAD)
|
||||
|
||||
syncdev: dist
|
||||
syncdev: distro
|
||||
cp config.js $(TMP)
|
||||
aws --profile pzp s3 sync --follow-symlinks $(TMP)/ s3://8bitworkshop.com/dev
|
||||
|
||||
syncprod: dist
|
||||
syncprod: distro
|
||||
@[ "${VERSION}" ] || ( echo ">> No version set at HEAD, tag it first"; exit 1 )
|
||||
echo Version: $(VERSION)
|
||||
cp config.js $(TMP)
|
||||
|
|
|
@ -1,7 +1,22 @@
|
|||
"use strict";
|
||||
|
||||
// preload.js for Electron app
|
||||
const { ipcRenderer } = require('electron');
|
||||
const fs = require('fs');
|
||||
const modpath = require('path');
|
||||
const _path = require('path');
|
||||
const chokidar = require('chokidar');
|
||||
|
||||
const homeDirectory = require('os').homedir();
|
||||
const wsroot = _path.join(homeDirectory, '8bitworkshop');
|
||||
|
||||
function getLocalDir() {
|
||||
const _ui = window.ui_1 || window.ui || window; // TODO: module naming
|
||||
var dir = _ui.repo_id || _ui.platform_id || 'default';
|
||||
return _path.join(wsroot, dir);
|
||||
}
|
||||
function getLocalFilePath(path) {
|
||||
return _path.join(getLocalDir(), path);
|
||||
}
|
||||
|
||||
function isProbablyBinary(path, data) {
|
||||
var score = 0;
|
||||
|
@ -33,37 +48,84 @@ function isProbablyBinary(path, data) {
|
|||
return score > 0;
|
||||
}
|
||||
|
||||
// this is before startUI is called
|
||||
process.once('loaded', () => {
|
||||
// workspace root path
|
||||
// reload() clears this, so we have to set it every time
|
||||
var wsroot;
|
||||
// from browser: read workspace file synchronously
|
||||
window.getWorkspaceFile = function(path, filetype) {
|
||||
if (wsroot == null) throw Error("no workspace root set");
|
||||
try {
|
||||
var fullpath = modpath.join(wsroot, modpath.normalize(path));
|
||||
var data = fs.readFileSync(fullpath); // read binary
|
||||
var buf = new Uint8Array(data); // convert to array
|
||||
var isBinary = filetype != 'text' || isProbablyBinary(path, buf);
|
||||
data = isBinary ? buf : data.toString('utf-8');
|
||||
console.log("getWorkspaceFile", path, isBinary, data.length);
|
||||
return data;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return null;
|
||||
var watcher;
|
||||
var allfiles = new Set();
|
||||
// get workspace root dir
|
||||
// from browser: read workspace files asynchronously
|
||||
window.alternateLocalFilesystem = {
|
||||
getFileData: (path) => {
|
||||
let fullpath = getLocalFilePath(path);
|
||||
allfiles.add(fullpath);
|
||||
if (!fs.existsSync(fullpath)) {
|
||||
return null;
|
||||
}
|
||||
return new Promise( (resolve, reject) => {
|
||||
fs.readFile(fullpath, (err,buf) => {
|
||||
if (err) {
|
||||
resolve(err);
|
||||
} else {
|
||||
let isBinary = isProbablyBinary(path, buf);
|
||||
let data = isBinary ? buf : buf.toString('utf-8');
|
||||
console.log("getWorkspaceFile", path, isBinary, data.length);
|
||||
resolve(data);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
setFileData: (path, data) => {
|
||||
let fullpath = getLocalFilePath(path);
|
||||
allfiles.add(fullpath);
|
||||
let encoding = typeof data === 'string' ? 'utf8' : null;
|
||||
console.log("setWorkspaceFile", fullpath, data.length);
|
||||
return new Promise( (resolve, reject) => {
|
||||
fs.mkdir(_path.dirname(fullpath), {recursive:true}, (err,dirpath) => {
|
||||
fs.writeFile(fullpath, data, {encoding:encoding}, (err) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
// from browser: put workspace file
|
||||
window.putWorkspaceFile = function(path, data) {
|
||||
if (wsroot == null) throw Error("no workspace root set");
|
||||
var fullpath = modpath.join(wsroot, modpath.normalize(path));
|
||||
var encoding = typeof data === 'string' ? 'utf8' : null;
|
||||
fs.writeFileSync(fullpath, data, {encoding:encoding});
|
||||
}
|
||||
// watch/unwatch files as browser loses/gains focus
|
||||
window.addEventListener("blur", (e) => {
|
||||
let localdir = getLocalDir();
|
||||
if (!watcher && localdir) {
|
||||
// watch files for changes
|
||||
watcher = chokidar.watch(Array.from(allfiles), {
|
||||
//awaitWriteFinish: {pollInterval:50,stabilityThreshold:300},
|
||||
ignoreInitial: true
|
||||
});
|
||||
watcher.on('all', (event, path) => {
|
||||
path = path.substring(localdir.length + 1); //strip off prefix
|
||||
console.log('WATCH', event, path);
|
||||
// we don't use awaitWriteFinish b/c we might close() the watcher
|
||||
setTimeout(() => {
|
||||
window.reloadWorkspaceFile(path);
|
||||
}, 300);
|
||||
});
|
||||
console.log('watching', getLocalDir());
|
||||
}
|
||||
});
|
||||
window.addEventListener("focus", (e) => {
|
||||
if (watcher) {
|
||||
watcher.close();
|
||||
watcher = null;
|
||||
}
|
||||
console.log('stopped watching');
|
||||
});
|
||||
|
||||
// from electron.js: set workspace root directory
|
||||
/*
|
||||
TODO
|
||||
ipcRenderer.on('setWorkspaceRoot', (event, data) => {
|
||||
wsroot = data.root;
|
||||
var binpath = modpath.join(wsroot, 'bin');
|
||||
var binpath = _path.join(wsroot, 'bin');
|
||||
if (!fs.existsSync(binpath)) fs.mkdirSync(binpath, {});
|
||||
console.log('setWorkspaceRoot', wsroot);
|
||||
});
|
||||
|
@ -72,4 +134,6 @@ process.once('loaded', () => {
|
|||
var path = data.path;
|
||||
window.reloadWorkspaceFile(path);
|
||||
});
|
||||
*/
|
||||
console.log('loaded preload', window.alternateLocalFilesystem, window.startUI);
|
||||
});
|
||||
|
|
|
@ -363,6 +363,7 @@ body {
|
|||
<script src="src/codemirror/fastbasic.js"></script>
|
||||
<script src="src/codemirror/basic.js"></script>
|
||||
<script src="src/codemirror/wiz.js"></script>
|
||||
<script src="src/codemirror/vasm.js"></script>
|
||||
<link rel="stylesheet" href="css/codemirror.css">
|
||||
<script src="codemirror/addon/edit/matchbrackets.js"></script>
|
||||
<script src="codemirror/addon/search/search.js"></script>
|
||||
|
@ -420,6 +421,7 @@ function require(modname) {
|
|||
<script src="gen/common/devices.js"></script>
|
||||
<script src="gen/common/cpu/MOS6502.js"></script>
|
||||
<script src="gen/common/cpu/ZilogZ80.js"></script>
|
||||
<script src="gen/common/cpu/ARM.js"></script>
|
||||
<script src="gen/machine/vdp_z80.js"></script>
|
||||
|
||||
<script>
|
||||
|
@ -435,28 +437,5 @@ $( ".dropdown-submenu" ).click(function(event) {
|
|||
startUI();
|
||||
</script>
|
||||
|
||||
<!-- Sentry error reporting -->
|
||||
<script
|
||||
src="https://browser.sentry-cdn.com/6.4.1/bundle.min.js"
|
||||
integrity="sha384-THoc7rflwZFKTdZNgv6jLFFDn299Uv3t1SW5B4yGLvLiCRTYP9ys6vXZcMl95TQF"
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
<script>
|
||||
Sentry.init({
|
||||
dsn: 'https://bf329df3d1b34afa9f5b5e8ecd80ad11@o320878.ingest.sentry.io/1813925',
|
||||
beforeBreadcrumb(breadcrumb, hint) {
|
||||
if (breadcrumb.category === 'xhr' && typeof breadcrumb.data.url === 'string') {
|
||||
if (breadcrumb.data.url.startsWith('http')) return null; // discard external scripts
|
||||
}
|
||||
return breadcrumb;
|
||||
},
|
||||
beforeSend(event, hint) {
|
||||
const error = hint.originalException;
|
||||
if (error instanceof EmuHalt) return null; // ignore EmuHalt
|
||||
return event;
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
314
electron.js
314
electron.js
|
@ -1,217 +1,14 @@
|
|||
const { app, dialog, ipcMain, ipcRenderer, Menu, BrowserWindow } = require('electron')
|
||||
"use strict";
|
||||
|
||||
const { app, Menu, BrowserWindow } = require('electron')
|
||||
const modpath = require('path')
|
||||
const fs = require('fs')
|
||||
const {URLSearchParams} = require('url')
|
||||
const isMac = process.platform === 'darwin'
|
||||
const chokidar = require('chokidar')
|
||||
const Store = require('electron-store');
|
||||
const store = new Store();
|
||||
const WSMETA_FILENAME = "8bitworkshop.json"
|
||||
const README_FILENAME = "README.md"
|
||||
|
||||
// call updater
|
||||
require('update-electron-app')()
|
||||
///require('update-electron-app')()
|
||||
|
||||
// show error dialog
|
||||
function showError(msg, detail) {
|
||||
msg = msg.message || msg;
|
||||
dialog.showMessageBoxSync({
|
||||
type: "error",
|
||||
message: msg,
|
||||
detail: detail
|
||||
});
|
||||
}
|
||||
|
||||
// file watcher
|
||||
class Workspace {
|
||||
constructor(directory, meta) {
|
||||
this.directory = directory;
|
||||
this.mainfile = meta.mainfile;
|
||||
this.platform = meta.platform;
|
||||
if (!this.mainfile) throw new Error(`The "mainfile" key is missing in ${WSMETA_FILENAME}.`)
|
||||
if (!this.platform) throw new Error(`The "platform" key is missing in ${WSMETA_FILENAME}.`)
|
||||
var mainfilepath = this.getMainFilePath();
|
||||
if (!fs.existsSync(mainfilepath)) throw new Error(`The file "${mainfilepath}" is missing.`);
|
||||
console.log("workspace opened", this.directory, this.mainfile);
|
||||
}
|
||||
getMainFilePath() {
|
||||
return modpath.join(this.directory, this.mainfile);
|
||||
}
|
||||
close() {
|
||||
this.unwatch();
|
||||
console.log("workspace closed", this.directory, this.mainfile);
|
||||
}
|
||||
watch(wnd) {
|
||||
this.watcher = chokidar.watch(this.directory, {
|
||||
awaitWriteFinish: false
|
||||
});
|
||||
this.watcher.on('all', (event, path) => {
|
||||
switch (event) {
|
||||
case 'change':
|
||||
console.log(event, path);
|
||||
wnd.webContents.send('fileChanged', {
|
||||
path: modpath.relative(this.directory, path),
|
||||
});
|
||||
break;
|
||||
}
|
||||
});
|
||||
console.log("watching workspace");
|
||||
}
|
||||
unwatch() {
|
||||
if (this.watcher) {
|
||||
this.watcher.close();
|
||||
this.watcher = null;
|
||||
console.log("un-watching workspace");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function readWorkspaceMetadata(directory) {
|
||||
// check README file
|
||||
var readmepath = modpath.join(directory, README_FILENAME);
|
||||
if (fs.existsSync(readmepath)) {
|
||||
let readme = fs.readFileSync(readmepath, 'utf8');
|
||||
let sess = {};
|
||||
// check README for main file
|
||||
const re8main = /8bitworkshop.com[^)]+file=([^)&]+)/;
|
||||
m = re8main.exec(readme);
|
||||
if (m && m[1]) {
|
||||
sess.mainfile = m[1];
|
||||
}
|
||||
// check README for proper platform
|
||||
// unless we use githubURL=
|
||||
const re8plat = /8bitworkshop.com[^)]+platform=([A-Za-z0-9._\-]+)/;
|
||||
m = re8plat.exec(readme);
|
||||
if (m) {
|
||||
sess.platform = m[1];
|
||||
}
|
||||
if (sess.mainfile != null && sess.platform != null) return sess;
|
||||
}
|
||||
// check JSON file
|
||||
var metapath = modpath.join(directory, WSMETA_FILENAME);
|
||||
if (fs.existsSync(metapath)) {
|
||||
return JSON.parse(fs.readFileSync(metapath, 'utf8'));
|
||||
}
|
||||
}
|
||||
|
||||
function writeWorkspaceMetadata(directory, meta) {
|
||||
var metapath = modpath.join(directory, WSMETA_FILENAME);
|
||||
fs.writeFileSync(metapath, JSON.stringify(meta), 'utf8');
|
||||
}
|
||||
|
||||
function openWorkspace(wnd, ws) {
|
||||
if (wnd.workspace) { wnd.workspace.close(); }
|
||||
wnd.workspace = ws;
|
||||
wnd.on('closed', () => {
|
||||
ws.close();
|
||||
});
|
||||
var qs = new URLSearchParams();
|
||||
qs.set('electron_ws', 1);
|
||||
qs.set('repo', ws.directory);
|
||||
qs.set('file', ws.mainfile);
|
||||
qs.set('platform', ws.platform);
|
||||
console.log(qs);
|
||||
wnd.loadURL(`file://${__dirname}/electron.html?${qs}`).then(() => {
|
||||
wnd.webContents.send('setWorkspaceRoot', {root:ws.directory});
|
||||
});
|
||||
}
|
||||
|
||||
function getActiveWorkspace() {
|
||||
var wnd = BrowserWindow.getFocusedWindow();
|
||||
return wnd && wnd.workspace;
|
||||
}
|
||||
|
||||
// TODO: doesn't work if browser window reloads itself
|
||||
function reloadCurrentWindow() {
|
||||
var wnd = BrowserWindow.getFocusedWindow();
|
||||
if (wnd.workspace) {
|
||||
openWorkspace(wnd, wnd.workspace);
|
||||
} else {
|
||||
wnd.reload();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: better way to get this?
|
||||
function getCurrentPlatform(wnd) {
|
||||
var url = wnd.webContents.getURL();
|
||||
if (url != null) {
|
||||
console.log(url);
|
||||
var m = /platform=([^&]+)/.exec(url);
|
||||
if (m) return m[1];
|
||||
}
|
||||
}
|
||||
|
||||
function openWorkspaceWindow(wspath) {
|
||||
try {
|
||||
// replace current window
|
||||
var wnd = BrowserWindow.getFocusedWindow() || createWindow();
|
||||
// read metadata file
|
||||
var meta = readWorkspaceMetadata(wspath);
|
||||
// does it exist?
|
||||
if (meta == null) {
|
||||
// create a new workspace?
|
||||
var cancel = dialog.showMessageBoxSync(wnd, {
|
||||
type: 'question',
|
||||
title: 'Create Workspace?',
|
||||
message: `Project metadata not found. Create new ${getCurrentPlatform(wnd)||""} project in this directory?`,
|
||||
detail: wspath,
|
||||
buttons: ['Create', 'Cancel'],
|
||||
});
|
||||
if (!cancel) {
|
||||
var platform = getCurrentPlatform(wnd);
|
||||
// choose main file
|
||||
var files = dialog.showOpenDialogSync({
|
||||
message: `Choose the main file of your ${platform} project, or create one.`,
|
||||
defaultPath: wspath,
|
||||
properties: ['openFile','promptToCreate'],
|
||||
});
|
||||
if (files != null) {
|
||||
var mainfile = modpath.relative(wspath, files[0]);
|
||||
// write new metadata
|
||||
meta = {
|
||||
platform: platform,
|
||||
mainfile: mainfile,
|
||||
};
|
||||
console.log(meta);
|
||||
if (meta.platform == null) {
|
||||
showError("Can't determine current platform.");
|
||||
} else {
|
||||
writeWorkspaceMetadata(wspath, meta);
|
||||
openWorkspaceWindow(wspath);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log(meta);
|
||||
var ws = new Workspace(wspath, meta);
|
||||
openWorkspace(wnd, ws);
|
||||
app.addRecentDocument(wspath);
|
||||
}
|
||||
} catch (e) {
|
||||
showError(e);
|
||||
}
|
||||
}
|
||||
|
||||
function openDefaultWorkspace() {
|
||||
if (process.argv.length >= 3) {
|
||||
openWorkspaceWindow(modpath.resolve(process.argv[2]));
|
||||
} else {
|
||||
createWindow();
|
||||
}
|
||||
}
|
||||
|
||||
function openWorkspaceDialog() {
|
||||
dialog.showOpenDialog({
|
||||
title: "Open Workspace",
|
||||
properties: ['openDirectory'],
|
||||
message: "Choose the directory that holds your source files.",
|
||||
}).then((rtn) => {
|
||||
if (!rtn.canceled && rtn.filePaths && rtn.filePaths.length > 0) {
|
||||
var path = rtn.filePaths[0];
|
||||
openWorkspaceWindow(path);
|
||||
}
|
||||
});
|
||||
}
|
||||
// init sentry
|
||||
require('@sentry/electron').init({ dsn: "https://bf329df3d1b34afa9f5b5e8ecd80ad11@o320878.ingest.sentry.io/1813925" });
|
||||
|
||||
function openURL(url) {
|
||||
return async () => {
|
||||
|
@ -220,6 +17,37 @@ function openURL(url) {
|
|||
}
|
||||
}
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
const win = new BrowserWindow({
|
||||
width: 1024,
|
||||
height: 768,
|
||||
backgroundColor: '#fff',
|
||||
webPreferences: {
|
||||
preload: modpath.join(__dirname, './electron-preload.js'),
|
||||
nodeIntegration: false,
|
||||
enableRemoteModule: false,
|
||||
contextIsolation: false,
|
||||
sandbox: false,
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
win.loadFile('electron.html', {
|
||||
search: 'electron=1&repo=/'
|
||||
});
|
||||
|
||||
// Maximize
|
||||
win.maximize();
|
||||
return win;
|
||||
}
|
||||
|
||||
// TODO: doesn't work if browser window reloads itself
|
||||
function reloadCurrentWindow() {
|
||||
var wnd = BrowserWindow.getFocusedWindow();
|
||||
wnd.reload();
|
||||
}
|
||||
|
||||
function buildMenu() {
|
||||
|
||||
const template = [
|
||||
|
@ -242,28 +70,6 @@ function buildMenu() {
|
|||
{
|
||||
label: 'File',
|
||||
submenu: [
|
||||
{
|
||||
label: 'New Playground',
|
||||
click: createWindow,
|
||||
accelerator: 'CmdOrCtrl+N',
|
||||
},
|
||||
{
|
||||
label: 'Open Workspace...',
|
||||
click: openWorkspaceDialog,
|
||||
accelerator: 'CmdOrCtrl+O',
|
||||
},
|
||||
// When a file is requested from the recent documents menu, the open-file event of app module will be emitted for it.
|
||||
{
|
||||
"label":"Open Recent",
|
||||
"role":"recentdocuments",
|
||||
"submenu":[
|
||||
{
|
||||
"label":"Clear Recent",
|
||||
"role":"clearrecentdocuments"
|
||||
}
|
||||
]
|
||||
},
|
||||
{ type: 'separator' },
|
||||
isMac ? { role: 'close' } : { role: 'quit' }
|
||||
]
|
||||
},
|
||||
|
@ -365,38 +171,10 @@ function buildMenu() {
|
|||
Menu.setApplicationMenu(menu)
|
||||
}
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
const win = new BrowserWindow({
|
||||
width: 1024,
|
||||
height: 768,
|
||||
backgroundColor: '#fff',
|
||||
webPreferences: {
|
||||
preload: modpath.join(__dirname, './electron-preload.js'),
|
||||
nodeIntegration: false,
|
||||
enableRemoteModule: false,
|
||||
contextIsolation: false,
|
||||
sandbox: false,
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
win.loadFile('electron.html', {
|
||||
search: 'repo=/'
|
||||
})
|
||||
|
||||
// Open the DevTools.
|
||||
//win.webContents.openDevTools()
|
||||
|
||||
// Maximize
|
||||
win.maximize();
|
||||
return win;
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(buildMenu).then(openDefaultWorkspace)
|
||||
app.whenReady().then(buildMenu).then(createWindow)
|
||||
|
||||
// Quit when all windows are closed, except on macOS. There, it's common
|
||||
// for applications and their menu bar to stay active until the user quits
|
||||
|
@ -415,6 +193,7 @@ app.on('activate', () => {
|
|||
}
|
||||
})
|
||||
|
||||
/* TODO
|
||||
app.on('browser-window-focus', (e) => {
|
||||
var ws = e.sender.workspace;
|
||||
if (ws) ws.unwatch();
|
||||
|
@ -424,19 +203,4 @@ app.on('browser-window-blur', (e) => {
|
|||
var ws = e.sender.workspace;
|
||||
if (ws) ws.watch(e.sender);
|
||||
})
|
||||
|
||||
app.on('open-file', (event, path) => {
|
||||
openWorkspaceWindow(path);
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
|
||||
// Register IPC messages
|
||||
// https://stackoverflow.com/questions/52236641/electron-ipc-and-nodeintegration
|
||||
/*
|
||||
ipcMain.on('hello', (event, message) => {
|
||||
console.log(event);
|
||||
});
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
--- index.html 2020-12-08 10:30:08.000000000 -0600
|
||||
+++ electron.html 2020-12-08 11:57:52.000000000 -0600
|
||||
--- index.html 2021-07-09 15:15:12.000000000 -0500
|
||||
+++ electron.html 2021-07-10 13:34:48.000000000 -0500
|
||||
@@ -3,18 +3,7 @@
|
||||
|
||||
<head>
|
||||
|
@ -223,3 +223,32 @@
|
|||
|
||||
<script src="jquery/jquery.min.js"></script>
|
||||
|
||||
@@ -614,28 +437,5 @@
|
||||
startUI();
|
||||
</script>
|
||||
|
||||
-<!-- Sentry error reporting -->
|
||||
-<script
|
||||
- src="https://browser.sentry-cdn.com/6.4.1/bundle.min.js"
|
||||
- integrity="sha384-THoc7rflwZFKTdZNgv6jLFFDn299Uv3t1SW5B4yGLvLiCRTYP9ys6vXZcMl95TQF"
|
||||
- crossorigin="anonymous"
|
||||
-></script>
|
||||
-<script>
|
||||
-Sentry.init({
|
||||
- dsn: 'https://bf329df3d1b34afa9f5b5e8ecd80ad11@o320878.ingest.sentry.io/1813925',
|
||||
- beforeBreadcrumb(breadcrumb, hint) {
|
||||
- if (breadcrumb.category === 'xhr' && typeof breadcrumb.data.url === 'string') {
|
||||
- if (breadcrumb.data.url.startsWith('http')) return null; // discard external scripts
|
||||
- }
|
||||
- return breadcrumb;
|
||||
- },
|
||||
- beforeSend(event, hint) {
|
||||
- const error = hint.originalException;
|
||||
- if (error instanceof EmuHalt) return null; // ignore EmuHalt
|
||||
- return event;
|
||||
- },
|
||||
-});
|
||||
-</script>
|
||||
-
|
||||
</body>
|
||||
</html>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
25
package.json
25
package.json
|
@ -1,20 +1,20 @@
|
|||
{
|
||||
"name": "8bitworkshop",
|
||||
"version": "3.7.2",
|
||||
"version": "3.8.0b1",
|
||||
"author": "Steven Hugg",
|
||||
"description": "8bitworkshop.com",
|
||||
"category": "Development",
|
||||
"description": "Desktop version of 8bitworkshop.com retro programming IDE",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/sehugg/8bitworkshop.git"
|
||||
},
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"@sentry/electron": "^2.5.1",
|
||||
"binaryen": "^101.0.0",
|
||||
"chokidar": "^3.5.0",
|
||||
"electron-store": "^6.0.1",
|
||||
"jquery": "^3.5.1",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"update-electron-app": "^1.5.0"
|
||||
"reflect-metadata": "^0.1.13"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bootbox": "^5.1.3",
|
||||
|
@ -30,6 +30,7 @@
|
|||
"clipboard": "^2.0.6",
|
||||
"command-exists": "^1.2.9",
|
||||
"electron": "^9.4.0",
|
||||
"electron-builder": "^22.11.7",
|
||||
"electron-packager": "^15.2.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"heapdump": "^0.3.15",
|
||||
|
@ -51,10 +52,6 @@
|
|||
"typescript-formatter": "^7.2.2",
|
||||
"vgm-parser": "^0.6.3"
|
||||
},
|
||||
"directories": {
|
||||
"doc": "doc",
|
||||
"test": "tests"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "make",
|
||||
"test": "npm run test-node",
|
||||
|
@ -82,5 +79,13 @@
|
|||
"bugs": {
|
||||
"url": "https://github.com/sehugg/8bitworkshop/issues"
|
||||
},
|
||||
"homepage": "https://github.com/sehugg/8bitworkshop#readme"
|
||||
"homepage": "https://github.com/sehugg/8bitworkshop#readme",
|
||||
"build": {
|
||||
"appId": "com.8bitworkshop.ide",
|
||||
"icon": "meta/icons/8bitworkshop-icon-1024.png",
|
||||
"copyright": "Copyright (c) 2021 Puzzling Plans LLC",
|
||||
"linux": {
|
||||
"category": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -183,19 +183,14 @@ function unsetLastPreset() {
|
|||
function initProject() {
|
||||
var basefs : ProjectFilesystem = new WebPresetsFileSystem(platform_id);
|
||||
//basefs = new FirebaseProjectFilesystem("TEST", "TEST");
|
||||
var filesystem = new OverlayFilesystem(
|
||||
basefs,
|
||||
new LocalForageFilesystem(store));
|
||||
if (isElectron) {
|
||||
console.log('using electron with local filesystem', alternateLocalFilesystem);
|
||||
var filesystem = new OverlayFilesystem(basefs, alternateLocalFilesystem)
|
||||
} else {
|
||||
var filesystem = new OverlayFilesystem(basefs, new LocalForageFilesystem(store));
|
||||
}
|
||||
current_project = new CodeProject(newWorker(), platform_id, platform, filesystem);
|
||||
projectWindows = new ProjectWindows($("#workspace")[0] as HTMLElement, current_project);
|
||||
if (isElectronWorkspace) {
|
||||
// TODO
|
||||
/*
|
||||
current_project.persistent = false;
|
||||
current_project.callbackGetRemote = getElectronFile;
|
||||
current_project.callbackStoreFile = putWorkspaceFile;
|
||||
*/
|
||||
}
|
||||
current_project.callbackBuildResult = (result:WorkerResult) => {
|
||||
setCompileOutput(result);
|
||||
};
|
||||
|
@ -1080,9 +1075,7 @@ async function updateSelector() {
|
|||
await populateFiles(sel, "Local Files", "", foundFiles);
|
||||
finishSelector(sel);
|
||||
} else {
|
||||
if (!isElectronWorkspace) {
|
||||
sel.append($("<option />").val('/').text('Leave Repository'));
|
||||
}
|
||||
sel.append($("<option />").val('/').text('Leave Repository'));
|
||||
$("#repo_name").text(getFilenameForPath(repo_id)+'/').show();
|
||||
// repo: populate all files
|
||||
await populateFiles(sel, repo_id, "", {});
|
||||
|
@ -1958,8 +1951,7 @@ export var qs = (function (a : string[]) {
|
|||
return b;
|
||||
})(window.location.search.substr(1).split('&'));
|
||||
|
||||
const isElectronWorkspace = qs['electron_ws'];
|
||||
const isElectron = qs['electron'] || isElectronWorkspace;
|
||||
const isElectron = !!qs['electron'];
|
||||
|
||||
function globalErrorHandler(msgevent) {
|
||||
var msg = (msgevent.message || msgevent.error || msgevent)+"";
|
||||
|
@ -2220,13 +2212,7 @@ function setPlatformUI() {
|
|||
$(".platform_name").text(name || platform_id);
|
||||
}
|
||||
|
||||
// start
|
||||
export async function startUI() {
|
||||
// import from github?
|
||||
if (qs['githubURL']) {
|
||||
importProjectFromGithub(qs['githubURL'], true);
|
||||
return;
|
||||
}
|
||||
export function getPlatformAndRepo() {
|
||||
// add default platform?
|
||||
// TODO: do this after repo_id
|
||||
platform_id = qs['platform'] || (hasLocalStorage && localStorage.getItem("__lastplatform"));
|
||||
|
@ -2249,6 +2235,16 @@ export async function startUI() {
|
|||
repo_id = '';
|
||||
delete qs['repo'];
|
||||
}
|
||||
}
|
||||
|
||||
// start
|
||||
export async function startUI() {
|
||||
// import from github?
|
||||
if (qs['githubURL']) {
|
||||
importProjectFromGithub(qs['githubURL'], true);
|
||||
return;
|
||||
}
|
||||
getPlatformAndRepo();
|
||||
setupSplits();
|
||||
// create store
|
||||
store_id = repo_id || getBasePlatform(platform_id);
|
||||
|
@ -2340,7 +2336,7 @@ function redirectToHTTPS() {
|
|||
// redirect to HTTPS after script loads?
|
||||
redirectToHTTPS();
|
||||
|
||||
//// ELECTRON STUFF
|
||||
//// ELECTRON (and other external) STUFF
|
||||
|
||||
export function setTestInput(path: string, data: FileData) {
|
||||
platform.writeFile(path, data);
|
||||
|
@ -2362,29 +2358,21 @@ export function emulationHalted(err: EmuHalt) {
|
|||
}
|
||||
|
||||
// get remote file from local fs
|
||||
declare var getWorkspaceFile, putWorkspaceFile;
|
||||
export function getElectronFile(url:string, success:(text:string|Uint8Array)=>void, datatype:'text'|'arraybuffer') {
|
||||
// TODO: we have to split() to strip off presets/platform, yukky
|
||||
var contents = getWorkspaceFile(url.split('/',3)[2], datatype);
|
||||
if (contents != null) {
|
||||
success(contents); // return result
|
||||
} else {
|
||||
getWithBinary(url, success, datatype); // try to load from presets/platform via GET
|
||||
}
|
||||
}
|
||||
export function reloadWorkspaceFile(path: string) {
|
||||
declare var alternateLocalFilesystem : ProjectFilesystem;
|
||||
|
||||
export async function reloadWorkspaceFile(path: string) {
|
||||
var oldval = current_project.filedata[path];
|
||||
if (oldval != null) {
|
||||
var datatype = typeof oldval == 'string' ? 'text' : 'arraybuffer';
|
||||
projectWindows.updateFile(path, getWorkspaceFile(path, datatype));
|
||||
projectWindows.updateFile(path, await alternateLocalFilesystem.getFileData(path));
|
||||
console.log('updating file', path);
|
||||
}
|
||||
}
|
||||
function writeOutputROMFile() {
|
||||
if (isElectronWorkspace && current_output instanceof Uint8Array) {
|
||||
if (isElectron && current_output instanceof Uint8Array) {
|
||||
var prefix = getFilenamePrefix(getCurrentMainFilename());
|
||||
var suffix = (platform.getROMExtension && platform.getROMExtension(current_output))
|
||||
|| "-" + getBasePlatform(platform_id) + ".bin";
|
||||
putWorkspaceFile(`bin/${prefix}${suffix}`, current_output);
|
||||
alternateLocalFilesystem.setFileData(`bin/${prefix}${suffix}`, current_output);
|
||||
}
|
||||
}
|
||||
export function highlightSearch(query: string) { // TODO: filename?
|
||||
|
|
Loading…
Reference in New Issue