diff --git a/.vscode/launch.json b/.vscode/launch.json index 802b130d6..820ba07b8 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -20,7 +20,6 @@ "--no-app-auto-install", "--plugins=local-dir:../plugins", "--hosted-plugin-inspect=9339", - "--nosplash", "--content-trace", "--open-devtools" ], diff --git a/arduino-ide-extension/src/electron-browser/theia/core/electron-window-module.ts b/arduino-ide-extension/src/electron-browser/theia/core/electron-window-module.ts index 9328572b1..52a5eb272 100644 --- a/arduino-ide-extension/src/electron-browser/theia/core/electron-window-module.ts +++ b/arduino-ide-extension/src/electron-browser/theia/core/electron-window-module.ts @@ -6,10 +6,6 @@ import { ElectronMainWindowServiceExt, electronMainWindowServiceExtPath, } from '../../../electron-common/electron-main-window-service-ext'; -import { - SplashService, - splashServicePath, -} from '../../../electron-common/splash-service'; import { ElectronWindowService } from './electron-window-service'; export default new ContainerModule((bind, unbind, isBound, rebind) => { @@ -24,9 +20,4 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => { ) ) .inSingletonScope(); - bind(SplashService) - .toDynamicValue(({ container }) => - ElectronIpcConnectionProvider.createProxy(container, splashServicePath) - ) - .inSingletonScope(); }); diff --git a/arduino-ide-extension/src/electron-browser/theia/core/electron-window-service.ts b/arduino-ide-extension/src/electron-browser/theia/core/electron-window-service.ts index 2f571b419..d0d0a1ef2 100644 --- a/arduino-ide-extension/src/electron-browser/theia/core/electron-window-service.ts +++ b/arduino-ide-extension/src/electron-browser/theia/core/electron-window-service.ts @@ -1,17 +1,15 @@ -import { - inject, - injectable, - postConstruct, -} from '@theia/core/shared/inversify'; import * as remote from '@theia/core/electron-shared/@electron/remote'; -import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state'; import { ConnectionStatus, ConnectionStatusService, } from '@theia/core/lib/browser/connection-status-service'; -import { ElectronWindowService as TheiaElectronWindowService } from '@theia/core/lib/electron-browser/window/electron-window-service'; -import { SplashService } from '../../../electron-common/splash-service'; import { nls } from '@theia/core/lib/common'; +import { ElectronWindowService as TheiaElectronWindowService } from '@theia/core/lib/electron-browser/window/electron-window-service'; +import { + inject, + injectable, + postConstruct, +} from '@theia/core/shared/inversify'; import { WindowServiceExt } from '../../../browser/theia/core/window-service-ext'; import { ElectronMainWindowServiceExt } from '../../../electron-common/electron-main-window-service-ext'; @@ -23,20 +21,14 @@ export class ElectronWindowService @inject(ConnectionStatusService) private readonly connectionStatusService: ConnectionStatusService; - @inject(SplashService) - private readonly splashService: SplashService; - - @inject(FrontendApplicationStateService) - private readonly appStateService: FrontendApplicationStateService; - @inject(ElectronMainWindowServiceExt) private readonly mainWindowServiceExt: ElectronMainWindowServiceExt; @postConstruct() protected override init(): void { - this.appStateService - .reachedAnyState('initialized_layout') - .then(() => this.splashService.requestClose()); + // NOOP + // Does not listen on Theia's `window.zoomLevel` changes. + // TODO: IDE2 must switch to the Theia preferences and drop the custom one. } protected shouldUnload(): boolean { diff --git a/arduino-ide-extension/src/electron-common/splash-service.ts b/arduino-ide-extension/src/electron-common/splash-service.ts deleted file mode 100644 index d7d4ba6b2..000000000 --- a/arduino-ide-extension/src/electron-common/splash-service.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const splashServicePath = '/services/splash-service'; -export const SplashService = Symbol('SplashService'); -export interface SplashService { - requestClose(): Promise; -} diff --git a/arduino-ide-extension/src/electron-main/arduino-electron-main-module.ts b/arduino-ide-extension/src/electron-main/arduino-electron-main-module.ts index 0146fd02a..ea25a4e09 100644 --- a/arduino-ide-extension/src/electron-main/arduino-electron-main-module.ts +++ b/arduino-ide-extension/src/electron-main/arduino-electron-main-module.ts @@ -16,13 +16,8 @@ import { ElectronMainWindowServiceExt, electronMainWindowServiceExtPath, } from '../electron-common/electron-main-window-service-ext'; -import { - SplashService, - splashServicePath, -} from '../electron-common/splash-service'; import { ElectronMainWindowServiceExtImpl } from './electron-main-window-service-ext-impl'; import { IDEUpdaterImpl } from './ide-updater/ide-updater-impl'; -import { SplashServiceImpl } from './splash/splash-service-impl'; import { ElectronMainApplication } from './theia/electron-main-application'; import { ElectronMainWindowServiceImpl } from './theia/electron-main-window-service'; import { TheiaElectronWindow } from './theia/theia-electron-window'; @@ -34,17 +29,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => { bind(ElectronMainWindowServiceImpl).toSelf().inSingletonScope(); rebind(ElectronMainWindowService).toService(ElectronMainWindowServiceImpl); - bind(SplashServiceImpl).toSelf().inSingletonScope(); - bind(SplashService).toService(SplashServiceImpl); - bind(ElectronConnectionHandler) - .toDynamicValue( - (context) => - new JsonRpcConnectionHandler(splashServicePath, () => - context.container.get(SplashService) - ) - ) - .inSingletonScope(); - // IDE updater bindings bind(IDEUpdaterImpl).toSelf().inSingletonScope(); bind(IDEUpdater).toService(IDEUpdaterImpl); diff --git a/arduino-ide-extension/src/electron-main/splash/splash-screen.ts b/arduino-ide-extension/src/electron-main/splash/splash-screen.ts deleted file mode 100644 index 2120f5968..000000000 --- a/arduino-ide-extension/src/electron-main/splash/splash-screen.ts +++ /dev/null @@ -1,158 +0,0 @@ -/* -MIT License - -Copyright (c) 2017 Troy McKinnon - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ -// Copied from https://raw.githubusercontent.com/trodi/electron-splashscreen/2f5052a133be021cbf9a438d0ef4719cd1796b75/index.ts - -/** - * Module handles configurable splashscreen to show while app is loading. - */ - -import { Event } from '@theia/core/lib/common/event'; -import { BrowserWindow } from 'electron'; - -/** - * When splashscreen was shown. - * @ignore - */ -let splashScreenTimestamp = 0; -/** - * Splashscreen is loaded and ready to show. - * @ignore - */ -let splashScreenReady = false; -/** - * Main window has been loading for a min amount of time. - * @ignore - */ -let slowStartup = false; -/** - * True when expected work is complete and we've closed splashscreen, else user prematurely closed splashscreen. - * @ignore - */ -let done = false; -/** - * Show splashscreen if criteria are met. - * @ignore - */ -const showSplash = () => { - if (splashScreen && splashScreenReady && slowStartup) { - splashScreen.show(); - splashScreenTimestamp = Date.now(); - } -}; -/** - * Close splashscreen / show main screen. Ensure screen is visible for a min amount of time. - * @ignore - */ -const closeSplashScreen = (main: Electron.BrowserWindow, min: number): void => { - if (splashScreen) { - const timeout = min - (Date.now() - splashScreenTimestamp); - setTimeout(() => { - done = true; - if (splashScreen) { - splashScreen.isDestroyed() || splashScreen.close(); // Avoid `Error: Object has been destroyed` (#19) - splashScreen = null; - } - if (!main.isDestroyed()) { - main.show(); - } - }, timeout); - } -}; -/** `electron-splashscreen` config object. */ -export interface Config { - /** Options for the window that is loading and having a splashscreen tied to. */ - windowOpts: Electron.BrowserWindowConstructorOptions; - /** - * URL to the splashscreen template. This is the path to an `HTML` or `SVG` file. - * If you want to simply show a `PNG`, wrap it in an `HTML` file. - */ - templateUrl: string; - - /** - * Full set of browser window options for the splashscreen. We override key attributes to - * make it look & feel like a splashscreen; the rest is up to you! - */ - splashScreenOpts: Electron.BrowserWindowConstructorOptions; - /** Number of ms the window will load before splashscreen appears (default: 500ms). */ - delay?: number; - /** Minimum ms the splashscreen will be visible (default: 500ms). */ - minVisible?: number; - /** Close window that is loading if splashscreen is closed by user (default: true). */ - closeWindow?: boolean; -} -/** - * The actual splashscreen browser window. - * @ignore - */ -let splashScreen: Electron.BrowserWindow | null; -/** - * Initializes a splashscreen that will show/hide smartly (and handle show/hiding of main window). - * @param config - Configures splashscreen - * @returns {BrowserWindow} the main browser window ready for loading - */ -export const initSplashScreen = async ( - config: Config, - windowFactory: ( - options: Electron.BrowserViewConstructorOptions - ) => Promise, - onCloseRequested?: Event -): Promise => { - const xConfig: Required = { - windowOpts: config.windowOpts, - templateUrl: config.templateUrl, - splashScreenOpts: config.splashScreenOpts, - delay: config.delay ?? 500, - minVisible: config.minVisible ?? 500, - closeWindow: config.closeWindow ?? true, - }; - xConfig.splashScreenOpts.center = true; - xConfig.splashScreenOpts.frame = false; - xConfig.windowOpts.show = false; - const window = await windowFactory(xConfig.windowOpts); - splashScreen = new BrowserWindow(xConfig.splashScreenOpts); - splashScreen.loadURL(`file://${xConfig.templateUrl}`); - xConfig.closeWindow && - splashScreen.on('close', () => { - done || window.close(); - }); - // Splashscreen is fully loaded and ready to view. - splashScreen.webContents.on('did-finish-load', () => { - splashScreenReady = true; - showSplash(); - }); - // Startup is taking enough time to show a splashscreen. - setTimeout(() => { - slowStartup = true; - showSplash(); - }, xConfig.delay); - if (onCloseRequested) { - onCloseRequested(() => closeSplashScreen(window, xConfig.minVisible)); - } else { - window.webContents.on('did-finish-load', () => { - closeSplashScreen(window, xConfig.minVisible); - }); - } - window.on('closed', () => closeSplashScreen(window, 0)); // XXX: close splash when main window is closed - return window; -}; diff --git a/arduino-ide-extension/src/electron-main/splash/splash-service-impl.ts b/arduino-ide-extension/src/electron-main/splash/splash-service-impl.ts deleted file mode 100644 index 64168c01b..000000000 --- a/arduino-ide-extension/src/electron-main/splash/splash-service-impl.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { injectable } from '@theia/core/shared/inversify'; -import { Event, Emitter } from '@theia/core/lib/common/event'; -import { SplashService } from '../../electron-common/splash-service'; - -@injectable() -export class SplashServiceImpl implements SplashService { - protected requested = false; - protected readonly onCloseRequestedEmitter = new Emitter(); - - get onCloseRequested(): Event { - return this.onCloseRequestedEmitter.event; - } - - async requestClose(): Promise { - if (!this.requested) { - this.requested = true; - this.onCloseRequestedEmitter.fire(); - } - } -} diff --git a/arduino-ide-extension/src/electron-main/splash/static/splash.html b/arduino-ide-extension/src/electron-main/splash/static/splash.html deleted file mode 100644 index e372bae3a..000000000 --- a/arduino-ide-extension/src/electron-main/splash/static/splash.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - -
-

-
- - - diff --git a/arduino-ide-extension/src/electron-main/splash/static/splash.png b/arduino-ide-extension/src/electron-main/splash/static/splash.png deleted file mode 100644 index 51f0cca4a..000000000 Binary files a/arduino-ide-extension/src/electron-main/splash/static/splash.png and /dev/null differ diff --git a/arduino-ide-extension/src/electron-main/theia/electron-main-application.ts b/arduino-ide-extension/src/electron-main/theia/electron-main-application.ts index e5159a149..9c990f0a3 100644 --- a/arduino-ide-extension/src/electron-main/theia/electron-main-application.ts +++ b/arduino-ide-extension/src/electron-main/theia/electron-main-application.ts @@ -1,18 +1,15 @@ -import { inject, injectable } from '@theia/core/shared/inversify'; +import { injectable } from '@theia/core/shared/inversify'; import { app, BrowserWindow, - BrowserWindowConstructorOptions, contentTracing, ipcMain, - screen, Event as ElectronEvent, } from '@theia/core/electron-shared/electron'; import { fork } from 'child_process'; import { AddressInfo } from 'net'; import { join, dirname } from 'path'; import * as fs from 'fs-extra'; -import { initSplashScreen } from '../splash/splash-screen'; import { MaybePromise } from '@theia/core/lib/common/types'; import { ElectronSecurityToken } from '@theia/core/lib/electron-common/electron-token'; import { FrontendApplicationConfig } from '@theia/application-package/lib/application-props'; @@ -20,7 +17,6 @@ import { ElectronMainApplication as TheiaElectronMainApplication, ElectronMainExecutionParams, } from '@theia/core/lib/electron-main/electron-main-application'; -import { SplashServiceImpl } from '../splash/splash-service-impl'; import { URI } from '@theia/core/shared/vscode-uri'; import { Deferred } from '@theia/core/lib/common/promise-util'; import * as os from '@theia/core/lib/common/os'; @@ -42,14 +38,6 @@ interface WorkspaceOptions { const WORKSPACES = 'workspaces'; -/** - * Purely a dev thing. If you start the app with the `--nosplash` argument, - * then you won't have the splash screen (which is always on top :confused:) and can debug the app at startup. - * Note: if you start the app from VS Code with the `App (Electron)` config, the splash screen will be disabled. - */ -const APP_STARTED_WITH_NOSPLASH = - typeof process !== 'undefined' && process.argv.indexOf('--nosplash') !== -1; - /** * If the app is started with `--open-devtools` argument, the `Dev Tools` will be opened. */ @@ -70,9 +58,6 @@ export class ElectronMainApplication extends TheiaElectronMainApplication { private _firstWindowId: number | undefined; private openFilePromise = new Deferred(); - @inject(SplashServiceImpl) - private readonly splashService: SplashServiceImpl; - override async start(config: FrontendApplicationConfig): Promise { // Explicitly set the app name to have better menu items on macOS. ("About", "Hide", and "Quit") // See: https://github.com/electron-userland/electron-builder/issues/2468 @@ -289,69 +274,10 @@ export class ElectronMainApplication extends TheiaElectronMainApplication { super.onSecondInstance(event, argv, cwd); } - /** - * Use this rather than creating `BrowserWindow` instances from scratch, since some security parameters need to be set, this method will do it. - * - * @param options - */ override async createWindow( asyncOptions: MaybePromise = this.getDefaultTheiaWindowOptions() ): Promise { - let options = await asyncOptions; - options = this.avoidOverlap(options); - let electronWindow: BrowserWindow | undefined; - if (this.windows.size || APP_STARTED_WITH_NOSPLASH) { - electronWindow = await this.doCreateWindow(options); - } else { - const { bounds } = screen.getDisplayNearestPoint( - screen.getCursorScreenPoint() - ); - const splashHeight = 450; - const splashWidth = 600; - const splashY = Math.floor(bounds.y + (bounds.height - splashHeight) / 2); - const splashX = Math.floor(bounds.x + (bounds.width - splashWidth) / 2); - const splashScreenOpts: BrowserWindowConstructorOptions = { - height: splashHeight, - width: splashWidth, - x: splashX, - y: splashY, - transparent: true, - alwaysOnTop: true, - focusable: false, - minimizable: false, - maximizable: false, - hasShadow: false, - resizable: false, - }; - electronWindow = await initSplashScreen( - { - windowOpts: options, - templateUrl: join( - __dirname, - '..', - '..', - '..', - 'src', - 'electron-main', - 'splash', - 'static', - 'splash.html' - ), - delay: 0, - minVisible: 2000, - splashScreenOpts, - }, - (windowOptions) => this.doCreateWindow(windowOptions), - this.splashService.onCloseRequested - ); - } - return electronWindow; - } - - private async doCreateWindow( - options: TheiaBrowserWindowOptions - ): Promise { - const electronWindow = await super.createWindow(options); + const electronWindow = await super.createWindow(asyncOptions); if (APP_STARTED_WITH_DEV_TOOLS) { electronWindow.webContents.openDevTools(); } diff --git a/electron-app/package.json b/electron-app/package.json index 26ff29316..41ba64bb9 100644 --- a/electron-app/package.json +++ b/electron-app/package.json @@ -61,7 +61,7 @@ }, "generator": { "config": { - "preloadTemplate": "
" + "preloadTemplate": "./resources/preload.html" } } } diff --git a/electron-app/resources/preload.html b/electron-app/resources/preload.html new file mode 100644 index 000000000..cad74ffc5 --- /dev/null +++ b/electron-app/resources/preload.html @@ -0,0 +1,121 @@ + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + diff --git a/electron/.gitignore b/electron/.gitignore index 9f6844f02..c18304ae5 100644 --- a/electron/.gitignore +++ b/electron/.gitignore @@ -15,4 +15,8 @@ dist/ electron-builder.env # The generated `package.json` under the `build` folder. -build/package.json \ No newline at end of file +build/package.json + +# Resources the packager copies from dev to prod +build/resources/preload.html +build/patch/frontend/index.js diff --git a/electron/build/patch/frontend/index.js b/electron/build/patch/frontend/index.js deleted file mode 100644 index 26afbfedd..000000000 --- a/electron/build/patch/frontend/index.js +++ /dev/null @@ -1,100 +0,0 @@ -// Patch for the startup theme. Customizes the `ThemeService.get().defaultTheme();` to dispatch the default IDE2 theme based on the OS' theme. -// For all subsequent starts of the IDE the theme applied will be the last one set by the user. - -// With the current version of Theia adopted (1.25) it is not possible to extend the `ThemeService`, it will be possible starting from Theia 1.27. -// Once the version of Theia is updated, this patch will be removed and this functionality will be implemented via dependency injection. -// Ideally, we should open a PR in Theia and add support for `light` and `dark` default themes in the app config. - -const { - ThemeService, - ThemeServiceSymbol, - BuiltinThemeProvider, -} = require('@theia/core/lib/browser/theming'); -const { - ApplicationProps, -} = require('@theia/application-package/lib/application-props'); -const { - FrontendApplicationConfigProvider, -} = require('@theia/core/lib/browser/frontend-application-config-provider'); - -// It is a mighty hack to support theme updates in the bundled IDE2. -// If the custom theme registration happens before the restoration of the existing monaco themes, then any custom theme changes will be ignored. -// This patch introduces a static deferred promise in the monaco-theming service that will be resolved when the restoration is ready. -// IDE2 cannot require the monaco theme service on the outer module level, as it requires the application config provider to be initialized, -// but the initialization happens only in the generated `index.js`. -// This patch customizes the monaco theme service behavior before loading the DI containers via the preload. -// The preload is called only once before the app loads. The Theia extensions are not loaded at that point, but the app config provider is ready. -const preloader = require('@theia/core/lib/browser/preloader'); -const originalPreload = preloader.preload; -preloader.preload = async function () { - const { MonacoThemingService } = require('@theia/monaco/lib/browser/monaco-theming-service'); - const { MonacoThemeServiceIsReady } = require('arduino-ide-extension/lib/browser/utils/window'); - const { Deferred } = require('@theia/core/lib/common/promise-util'); - const ready = new Deferred(); - if (!window[MonacoThemeServiceIsReady]) { - window[MonacoThemeServiceIsReady] = ready; - console.log('Registered a custom monaco-theme service initialization signal on the window object.'); - } - // Here, it is safe to patch the theme service, app config provider is ready. - MonacoThemingService.init = async function () { - this.updateBodyUiTheme(); - ThemeService.get().onDidColorThemeChange(() => this.updateBodyUiTheme()); - await this.restore(); - ready.resolve(); - }.bind(MonacoThemingService); - return originalPreload(); -}.bind(preloader); - -const lightTheme = 'arduino-theme'; -const darkTheme = 'arduino-theme-dark'; -const defaultTheme = - window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches - ? darkTheme - : lightTheme; - -const originalGet = FrontendApplicationConfigProvider.get; -FrontendApplicationConfigProvider.get = function () { - const originalProps = originalGet.bind(FrontendApplicationConfigProvider)(); - return { ...originalProps, defaultTheme }; -}.bind(FrontendApplicationConfigProvider); - -const arduinoDarkTheme = { - id: 'arduino-theme-dark', - type: 'dark', - label: 'Dark (Arduino)', - editorTheme: 'arduino-theme-dark', - activate() {}, - deactivate() {}, -}; - -const arduinoLightTheme = { - id: 'arduino-theme', - type: 'light', - label: 'Light (Arduino)', - editorTheme: 'arduino-theme', - activate() {}, - deactivate() {}, -}; - -if (!window[ThemeServiceSymbol]) { - const themeService = new ThemeService(); - Object.defineProperty(themeService, 'defaultTheme', { - get: function () { - return ( - this.themes[defaultTheme] || - this.themes[ApplicationProps.DEFAULT.frontend.config.defaultTheme] - ); - }, - }); - themeService.register( - ...BuiltinThemeProvider.themes, - arduinoDarkTheme, - arduinoLightTheme - ); - themeService.startupTheme(); - themeService.setCurrentTheme(defaultTheme); - window[ThemeServiceSymbol] = themeService; -} - -// Require the original, generated `index.js` for `webpack` as the next entry for the `bundle.js`. -require('../../src-gen/frontend/index'); diff --git a/electron/build/resources/preload.html b/electron/build/resources/preload.html new file mode 100644 index 000000000..a3572220b --- /dev/null +++ b/electron/build/resources/preload.html @@ -0,0 +1,121 @@ + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + \ No newline at end of file diff --git a/electron/packager/index.js b/electron/packager/index.js index a5e785706..ffa0cae49 100644 --- a/electron/packager/index.js +++ b/electron/packager/index.js @@ -7,6 +7,8 @@ const glob = require('glob'); const isCI = require('is-ci'); shell.env.THEIA_ELECTRON_SKIP_REPLACE_FFMPEG = '1'; // Do not run the ffmpeg validation for the packager. + // Note, this will crash on PI if the available memory is less than desired heap size. + // https://github.com/shelljs/shelljs/issues/1024#issuecomment-1001552543 shell.env.NODE_OPTIONS = '--max_old_space_size=4096'; // Increase heap size for the CI shell.env.PUPPETEER_SKIP_CHROMIUM_DOWNLOAD = 'true'; // Skip download and avoid `ERROR: Failed to download Chromium`. const template = require('./config').generateTemplate( @@ -14,7 +16,7 @@ ); const utils = require('./utils'); const merge = require('deepmerge'); - const { isRelease, isElectronPublish, getChannelFile } = utils; + const { isRelease, getChannelFile } = utils; const { version } = template; const { productName } = template.build; @@ -58,6 +60,11 @@ .filter((filename) => resourcesToKeep.indexOf(filename) === -1) .forEach((filename) => rm('-rf', path('..', 'build', filename))); + // Clean up the `./electron/build/patch` and `./electron/build/resources` folder with Git. + // To avoid file duplication between bundled app and dev mode, some files are copied from `./electron-app` to `./electron/build` folder. + const foldersToSyncFromDev = ['patch', 'resources']; + foldersToSyncFromDev.forEach(filename => shell.exec(`git -C ${path('..', 'build', filename)} clean -ffxdq`, { async: false })); + const extensions = require('./extensions.json'); echo( `Building the application with the following extensions:\n${extensions @@ -70,14 +77,21 @@ // Copy the following items into the `working-copy` folder. Make sure to reuse the `yarn.lock`. | //----------------------------------------------------------------------------------------------+ mkdir('-p', path('..', workingCopy)); - for (const name of [ + for (const filename of [ ...allDependencies, 'yarn.lock', 'package.json', 'lerna.json', 'i18n' ]) { - cp('-rf', path(rootPath, name), path('..', workingCopy)); + cp('-rf', path(rootPath, filename), path('..', workingCopy)); + } + + //---------------------------------------------------------------------------------------------+ + // Copy the patched `index.js` for the frontend, the Theia preload, etc. from `./electron-app` | + //---------------------------------------------------------------------------------------------+ + for (const filename of foldersToSyncFromDev) { + cp('-rf', path(rootPath, 'electron-app', filename), path('..', 'build')); } //----------------------------------------------+