From d5438e0675ec204596c83b412d0155e2b7fa5da0 Mon Sep 17 00:00:00 2001 From: "Grigorii K. Shartsev" Date: Wed, 23 Oct 2024 21:49:01 +0200 Subject: [PATCH] build: add Squirrel.Windows Signed-off-by: Grigorii K. Shartsev --- forge.config.js | 84 ++++++++++++++++++++++++------- img/squirrel-install-loading.gif | Bin 0 -> 6604 bytes src/main.js | 19 ++++--- 3 files changed, 79 insertions(+), 24 deletions(-) create mode 100644 img/squirrel-install-loading.gif diff --git a/forge.config.js b/forge.config.js index d9d84d091..d29c1491b 100644 --- a/forge.config.js +++ b/forge.config.js @@ -6,18 +6,30 @@ const path = require('node:path') const fs = require('node:fs') const semver = require('semver') +const packageJSON = require('./package.json') const { MIN_REQUIRED_BUILT_IN_TALK_VERSION } = require('./src/constants.js') require('dotenv').config() +const CONFIG = { + // General + applicationName: packageJSON.productName, + applicationNameSanitized: packageJSON.productName.replaceAll(' ', '-'), + companyName: 'Nextcloud GmbH', + description: packageJSON.description, + + // macOS + macAppId: 'com.nextcloud.NextcloudTalk', + // Windows + winAppId: 'NextcloudTalk', +} + +const YEAR = new Date().getFullYear() + const TALK_PATH = path.resolve(__dirname, process.env.TALK_PATH ?? 'spreed') let talkPackageJson module.exports = { - packagerConfig: { - icon: './img/icons/icon', - }, - hooks: { generateAssets() { if (!fs.existsSync(process.env.TALK_PATH)) { @@ -50,23 +62,61 @@ module.exports = { rebuildConfig: {}, + packagerConfig: { + // Common + name: CONFIG.applicationName, + icon: path.join(__dirname, './img/icons/icon'), + appCopyright: `Copyright © ${YEAR} ${CONFIG.companyName}`, + asar: true, + + // Windows + win32metadata: { + CompanyName: CONFIG.companyName, + }, + + // macOS + appBundleId: CONFIG.macAppId, + darwinDarkModeSupport: true, + appCategoryType: 'public.app-category.social-networking', // LSApplicationCategoryType | https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/LaunchServicesKeys.html + }, + makers: [ - // { - // name: '@electron-forge/maker-squirrel', - // config: {}, - // }, + { + name: '@electron-forge/maker-squirrel', + platforms: ['win32'], + config: { + // App/Filenames + name: CONFIG.winAppId, + setupExe: `${CONFIG.applicationNameSanitized}-v${packageJSON.version}-win-x64.exe`, + exe: `${CONFIG.applicationName}.exe`, + + // Meta + title: CONFIG.applicationName, + authors: CONFIG.companyName, + owners: CONFIG.companyName, + description: CONFIG.description, + + // Icons + setupIcon: path.join(__dirname, './img/icons/icon.ico'), + iconUrl: 'https://raw.githubusercontent.com/nextcloud/talk-desktop/refs/heads/main/img/icons/icon.ico', + + // Install/Update Loading + loadingGif: path.join(__dirname, './img/squirrel-install-loading.gif'), + + // TODO: Check if this is as useful as WIX + // noMsi: false, + // setupMsi: `${CONFIG.applicationNameSanitized}-v${packageJSON.version}-win-x64.msi`, + + // TODO: Sign + // certificateFile: + // certificatePassword: + }, + }, + + // Portable, all platforms { name: '@electron-forge/maker-zip', - // platforms: ['darwin'], }, - // { - // name: '@electron-forge/maker-deb', - // config: {}, - // }, - // { - // name: '@electron-forge/maker-rpm', - // config: {}, - // }, ], plugins: [ diff --git a/img/squirrel-install-loading.gif b/img/squirrel-install-loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..57e1550310c7ca81787588d3fa76c21d1638c4b6 GIT binary patch literal 6604 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 av6(rSi=~qVm!>Jq+}svuCua!;JpDI4Y9l59 literal 0 HcmV?d00001 diff --git a/src/main.js b/src/main.js index 50d4eb4f7..0b5fa5621 100644 --- a/src/main.js +++ b/src/main.js @@ -12,7 +12,7 @@ const { createAuthenticationWindow } = require('./authentication/authentication. const { openLoginWebView } = require('./authentication/login.window.js') const { createHelpWindow } = require('./help/help.window.js') const { createUpgradeWindow } = require('./upgrade/upgrade.window.js') -const { getOs, isLinux, isMac, isWayland } = require('./shared/os.utils.js') +const { getOs, isLinux, isMac, isWayland, isWindows } = require('./shared/os.utils.js') const { createTalkWindow } = require('./talk/talk.window.js') const { createWelcomeWindow } = require('./welcome/welcome.window.js') const { installVueDevtools } = require('./install-vue-devtools.js') @@ -33,7 +33,17 @@ const ARGUMENTS = { const APP_NAME = process.env.NODE_ENV !== 'development' ? path.parse(app.getPath('exe')).name : 'Nextcloud Talk (dev)' app.setName(APP_NAME) app.setPath('userData', path.join(app.getPath('appData'), app.getName())) -app.setAppUserModelId(app.getName()) +if (isWindows()) { + // TODO: get actual name from the build + app.setAppUserModelId('com.squirrel.NextcloudTalk.NextcloudTalk') +} + +/** + * Handle creating/removing shortcuts on Windows when installing/uninstalling + */ +if (require('electron-squirrel-startup')) { + app.quit() +} /** * Only one instance is allowed at time @@ -49,11 +59,6 @@ if (process.env.NODE_ENV === 'production') { setupReleaseNotificationScheduler(2 * 60) } -// Handle creating/removing shortcuts on Windows when installing/uninstalling. -// if (require('electron-squirrel-startup')) { -// app.quit(); -// } - ipcMain.on('app:quit', () => app.quit()) ipcMain.handle('app:getOs', () => getOs()) ipcMain.handle('app:getAppName', () => app.getName())