Skip to content

Commit

Permalink
:electron: Electron package Typescript starting point (#2880)
Browse files Browse the repository at this point in the history
  • Loading branch information
MikesGlitch authored Jul 3, 2024
1 parent a67c969 commit 31eb00a
Show file tree
Hide file tree
Showing 8 changed files with 181 additions and 66 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ packages/api/dist
packages/api/@types
packages/crdt/dist
packages/desktop-electron/client-build
packages/desktop-electron/build
packages/desktop-electron/.electron-symbols
packages/desktop-electron/dist
packages/desktop-electron/loot-core
Expand Down
13 changes: 7 additions & 6 deletions packages/desktop-electron/bin/update-client
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

ROOT=`dirname $0`/..

rm -rf ${ROOT}/client-build
cp -r ${ROOT}/../desktop-client/build ${ROOT}/client-build
rm -rf ${ROOT}/build
mkdir -p ${ROOT}/build
cp -r ${ROOT}/../desktop-client/build ${ROOT}/build/client-build

# Remove the embedded backend for the browser version. Will improve
# this process
rm -rf ${ROOT}/client-build/data
rm -rf ${ROOT}/client-build/*kcab.*
rm -rf ${ROOT}/client-build/*.wasm
rm -rf ${ROOT}/client-build/*.map
rm -rf ${ROOT}/build/client-build/data
rm -rf ${ROOT}/build/client-build/*kcab.*
rm -rf ${ROOT}/build/client-build/*.wasm
rm -rf ${ROOT}/build/client-build/*.map
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
/* eslint-disable import/order */
// (I have no idea why the imports are like this. Not touching them.)
const isDev = require('electron-is-dev');
const fs = require('fs');
import fs from 'fs';
import NodeModule from 'module';
import path from 'path';

require('module').globalPaths.push(__dirname + '/..');

const {
import {
app,
ipcMain,
BrowserWindow,
Expand All @@ -14,8 +11,28 @@ const {
shell,
protocol,
utilityProcess,
} = require('electron');
const promiseRetry = require('promise-retry');
UtilityProcess,
} from 'electron';
import isDev from 'electron-is-dev';
import promiseRetry from 'promise-retry';

import about from './about';
import getMenu from './menu';
import updater from './updater';
import {
get as getWindowState,
listen as listenToWindowState,
} from './window-state';

import './setRequireHook';

import './security';

const Module: typeof NodeModule & { globalPaths: string[] } =
// eslint-disable-next-line @typescript-eslint/no-explicit-any
NodeModule as unknown as any;

Module.globalPaths.push(__dirname + '/..');

// This allows relative URLs to be resolved to app:// which makes
// local assets load correctly
Expand All @@ -25,16 +42,6 @@ protocol.registerSchemesAsPrivileged([

global.fetch = require('node-fetch');

const about = require('./about');
const getMenu = require('./menu');
const updater = require('./updater');

require('./security');

const path = require('path');

require('./setRequireHook');

if (!isDev || !process.env.ACTUAL_DOCUMENT_DIR) {
process.env.ACTUAL_DOCUMENT_DIR = app.getPath('documents');
}
Expand All @@ -43,15 +50,12 @@ if (!isDev || !process.env.ACTUAL_DATA_DIR) {
process.env.ACTUAL_DATA_DIR = app.getPath('userData');
}

// eslint-disable-next-line import/extensions
const WindowState = require('./window-state.js');

// 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 clientWin;
let serverProcess;
let clientWin: BrowserWindow | null;
let serverProcess: UtilityProcess | null;

updater.onEvent((type, data) => {
updater.onEvent((type: string, data: Record<string, string> | string) => {
// Notify both the app and the about window
if (clientWin) {
clientWin.webContents.send(type, data);
Expand Down Expand Up @@ -99,7 +103,7 @@ function createBackgroundProcess() {
}

async function createWindow() {
const windowState = await WindowState.get();
const windowState = await getWindowState();

// Create the browser window.
const win = new BrowserWindow({
Expand All @@ -113,7 +117,6 @@ async function createWindow() {
nodeIntegrationInWorker: false,
nodeIntegrationInSubFrames: false,
contextIsolation: true,
enableRemoteModule: false,
preload: __dirname + '/preload.js',
},
});
Expand All @@ -123,7 +126,7 @@ async function createWindow() {
win.webContents.openDevTools();
}

const unlistenToState = WindowState.listen(win, windowState);
const unlistenToState = listenToWindowState(win, windowState);

if (isDev) {
win.loadURL(`file://${__dirname}/loading.html`);
Expand All @@ -148,9 +151,11 @@ async function createWindow() {
});

win.on('focus', async () => {
const url = clientWin.webContents.getURL();
if (url.includes('app://') || url.includes('localhost:')) {
clientWin.webContents.executeJavaScript('__actionsForMenu.focused()');
if (clientWin) {
const url = clientWin.webContents.getURL();
if (url.includes('app://') || url.includes('localhost:')) {
clientWin.webContents.executeJavaScript('__actionsForMenu.focused()');
}
}
});

Expand Down Expand Up @@ -183,29 +188,28 @@ async function createWindow() {
clientWin = win;
}

function isExternalUrl(url) {
function isExternalUrl(url: string) {
return !url.includes('localhost:') && !url.includes('app://');
}

function updateMenu(budgetId) {
function updateMenu(budgetId?: string) {
const isBudgetOpen = !!budgetId;
const menu = getMenu(isDev, createWindow);
const menu = getMenu(isDev, createWindow, budgetId);
const file = menu.items.filter(item => item.label === 'File')[0];
const fileItems = file.submenu.items;
const fileItems = file.submenu?.items || [];
fileItems
.filter(item => item.label === 'Load Backup...')
.forEach(item => {
item.enabled = isBudgetOpen;
item.budgetId = budgetId;
});

const tools = menu.items.filter(item => item.label === 'Tools')[0];
tools.submenu.items.forEach(item => {
tools.submenu?.items.forEach(item => {
item.enabled = isBudgetOpen;
});

const edit = menu.items.filter(item => item.label === 'Edit')[0];
const editItems = edit.submenu.items;
const editItems = edit.submenu?.items || [];
editItems
.filter(item => item.label === 'Undo' || item.label === 'Redo')
.map(item => (item.enabled = isBudgetOpen));
Expand Down Expand Up @@ -312,7 +316,7 @@ ipcMain.handle(
async (event, { title, defaultPath, fileContents }) => {
const fileLocation = await dialog.showSaveDialog({ title, defaultPath });

return new Promise((resolve, reject) => {
return new Promise<void>((resolve, reject) => {
if (fileLocation) {
fs.writeFile(fileLocation.filePath, fileContents, error => {
return reject(error);
Expand Down Expand Up @@ -344,8 +348,9 @@ ipcMain.on('screenshot', () => {
const width = 1100;

// This is for the main screenshot inside the frame
clientWin.setSize(width, Math.floor(width * (427 / 623)));
// clientWin.setSize(width, Math.floor(width * (495 / 700)));
if (clientWin) {
clientWin.setSize(width, Math.floor(width * (427 / 623)));
}
}
});

Expand All @@ -366,14 +371,15 @@ ipcMain.on('apply-update', () => {
updater.apply();
});

ipcMain.on('update-menu', (event, budgetId) => {
ipcMain.on('update-menu', (event, budgetId?: string) => {
updateMenu(budgetId);
});

ipcMain.on('set-theme', theme => {
const obj = { theme };

clientWin.webContents.executeJavaScript(
`window.__actionsForMenu && window.__actionsForMenu.saveGlobalPrefs(${obj})`,
);
if (clientWin) {
clientWin.webContents.executeJavaScript(
`window.__actionsForMenu && window.__actionsForMenu.saveGlobalPrefs(${obj})`,
);
}
});
6 changes: 3 additions & 3 deletions packages/desktop-electron/menu.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { Menu, ipcMain, app, shell } = require('electron');

function getMenu(isDev, createWindow) {
function getMenu(isDev, createWindow, budgetId) {
const template = [
{
label: 'File',
Expand All @@ -9,10 +9,10 @@ function getMenu(isDev, createWindow) {
label: 'Load Backup...',
enabled: false,
click(item, focusedWindow) {
if (focusedWindow) {
if (focusedWindow && budgetId) {
if (focusedWindow.webContents.getTitle() === 'Actual') {
focusedWindow.webContents.executeJavaScript(
`__actionsForMenu.replaceModal('load-backup', { budgetId: '${item.budgetId}' })`,
`__actionsForMenu.replaceModal('load-backup', { budgetId: '${budgetId}' })`,
);
}
}
Expand Down
16 changes: 11 additions & 5 deletions packages/desktop-electron/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
"scripts": {
"clean": "rm -rf dist",
"update-client": "bin/update-client",
"build": "electron-builder",
"watch": "cross-env ACTUAL_DOCUMENT_DIR=\"../../data\" ACTUAL_DATA_DIR=\"../../data\" electron ."
"build": "yarn build:dist && electron-builder",
"build:dist": "tsc --p tsconfig.dist.json && yarn copy-static-html",
"copy-static-html": "copyfiles --exclude 'build/**/*' **/*.html icons/**/* build",
"watch": "yarn build:dist && cross-env ACTUAL_DOCUMENT_DIR=\"../../data\" ACTUAL_DATA_DIR=\"../../data\" electron ."
},
"main": "index.js",
"main": "build/index.js",
"build": {
"appId": "com.actualbudget.actual",
"files": [
Expand All @@ -19,7 +21,8 @@
"!**/*.js.map",
"!node_modules/@jlongster/sql.js",
"!node_modules/absurd-sql",
"!node_modules/better-sqlite3/{benchmark,src,bin,docs,deps,build/Release/obj,build/Release/sqlite3.a,build/Release/test_extension.node}"
"!node_modules/better-sqlite3/{benchmark,src,bin,docs,deps,build/Release/obj,build/Release/sqlite3.a,build/Release/test_extension.node}",
"build"
],
"publish": {
"provider": "github",
Expand Down Expand Up @@ -63,8 +66,11 @@
"devDependencies": {
"@electron/notarize": "2.2.0",
"@electron/rebuild": "3.6.0",
"@types/copyfiles": "^2",
"copyfiles": "^2.4.1",
"cross-env": "^7.0.3",
"electron": "30.0.6",
"electron-builder": "24.13.3"
"electron-builder": "24.13.3",
"typescript": "^5.0.2"
}
}
14 changes: 14 additions & 0 deletions packages/desktop-electron/tsconfig.dist.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
// Using ES2021 because that’s the newest version where
// the latest Node 16.x release supports all of the features
"target": "ES2021",
"module": "CommonJS",
"noEmit": false,
"declaration": true,
"outDir": "build",
},
"include": ["."],
"exclude": ["**/node_modules/*", "build/**/*"]
}
6 changes: 6 additions & 0 deletions upcoming-release-notes/2880.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
category: Maintenance
authors: [MikesGlitch]
---

Refactoring desktop-electron package to use typescript
Loading

0 comments on commit 31eb00a

Please sign in to comment.