[MM-36326][MM-45669] Added Native Node Module support - incl demo to fix DND issue (#2195)

* [MM-36326] Added Native Node Module support - incl demo to fix DND issue

* Fix OS per build

* Fix to include priority alarms on Windows

* Update node command

* Fixes for mac (only work on non-MAS build)

* Attempt to rebuild properly since electron-builder is having issues with a module

* Show me more logs maybe idk

* Try with ignore-scripts

* Force async to work asyncly

* PR feedback and ESLint fixes

* Add comment for node-gyp

* Revert me: test msi and mac installer

* Revert me too

* Try reverting back to the old system cause the new one miraculously broke...

* Add ignore scripts to makefile

* Ignore non-macho files :P

* Revert "Revert me too"

This reverts commit 074dc9551a2d8ce34a23a3abaeed937d957e8b76.

* Revert "Revert me: test msi and mac installer"

This reverts commit 0ac998c26a824e7136bdfdc825280a407bb1aa7f.
This commit is contained in:
Devin Binnie
2022-08-02 11:33:48 -04:00
committed by GitHub
parent fcc9215f37
commit 1e35a97f33
9 changed files with 599 additions and 476 deletions

View File

@@ -179,14 +179,20 @@ jobs:
- "~/.cache/electron-builder" - "~/.cache/electron-builder"
build-win-no-installer: build-win-no-installer:
executor: wine-mono executor: win/vs2019
steps: steps:
- checkout - checkout
- run: mkdir -p ./build - run: mkdir -p ./build
- attach_workspace: - attach_workspace:
at: ./build at: ./build
- update_image: - run:
apt_opts: "--no-install-recommends jq icnsutils graphicsmagick tzdata" name: Install yq
command: choco install yq --version 4.15.1 -y
- run:
name: Install nodejs-lts
command: choco install nodejs-lts -y
# ignoring scripts for windows due to issues with node-gyp
- run: $env:PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD = 1; npm ci --ignore-scripts
- build: - build:
os: windows os: windows
path: ./build/win path: ./build/win
@@ -199,16 +205,18 @@ jobs:
- "~/.cache/electron-builder" - "~/.cache/electron-builder"
build-mac-no-dmg: build-mac-no-dmg:
executor: wine-mono executor: mac
steps: steps:
- checkout - checkout
- run: mkdir -p ./build - run: mkdir -p ./build
- attach_workspace: - attach_workspace:
at: ./build at: ./build
- update_image: - run: brew install yq
apt_opts: "--no-install-recommends jq icnsutils graphicsmagick tzdata" - run:
name: Update node to v16
command: nvm install --lts && nvm use --lts
- run: jq '.mac.target=["zip"]' electron-builder.json | jq '.mac.gatekeeperAssess=false' > /tmp/electron-builder.json && cp /tmp/electron-builder.json . - run: jq '.mac.target=["zip"]' electron-builder.json | jq '.mac.gatekeeperAssess=false' > /tmp/electron-builder.json && cp /tmp/electron-builder.json .
- run: PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm ci
- build: - build:
os: mac os: mac
path: ./build/macos path: ./build/macos
@@ -228,12 +236,12 @@ jobs:
- run: mkdir -p ./build/ - run: mkdir -p ./build/
- attach_workspace: - attach_workspace:
at: ./build at: ./build
- run:
name: Update node to v16
command: choco install nodejs --version 16.8.0
- run: - run:
name: Install yq name: Install yq
command: choco install yq --version 4.15.1 command: choco install yq --version 4.15.1 -y
- run:
name: Install nodejs-lts
command: choco install nodejs-lts -y
- win_make: - win_make:
operation: optimize operation: optimize
- win_make: - win_make:
@@ -249,14 +257,19 @@ jobs:
- "./win-release/" - "./win-release/"
build-windows-pr: build-windows-pr:
executor: wine-mono executor: win/vs2019
steps: steps:
- checkout - checkout
- run: mkdir -p ./build - run: mkdir -p ./build
- attach_workspace: - attach_workspace:
at: ./build at: ./build
- update_image: - run:
apt_opts: "--no-install-recommends jq icnsutils graphicsmagick tzdata" name: Install yq
command: choco install yq --version 4.15.1 -y
- run:
name: Install nodejs-lts
command: choco install nodejs-lts -y
- run: $env:PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD = 1; npm ci --ignore-scripts
- build: - build:
os: windows os: windows
path: ./build/win path: ./build/win

View File

@@ -17,6 +17,7 @@
"files": [ "files": [
"node_modules/bootstrap/dist/**", "node_modules/bootstrap/dist/**",
"node_modules/font-awesome/{css,fonts}/**", "node_modules/font-awesome/{css,fonts}/**",
"!**/node_modules/macos-notification-state/build/Release/.forge-meta",
{ {
"from": "dist", "from": "dist",
"to": ".", "to": ".",
@@ -36,6 +37,7 @@
] ]
} }
], ],
"beforePack": "scripts/beforepack.js",
"afterPack": "scripts/afterpack.js", "afterPack": "scripts/afterpack.js",
"afterSign": "scripts/notarize.js", "afterSign": "scripts/notarize.js",
"afterAllArtifactBuild": "scripts/afterbuild.js", "afterAllArtifactBuild": "scripts/afterbuild.js",
@@ -52,6 +54,10 @@
"category": "contrib/net", "category": "contrib/net",
"priority": "optional" "priority": "optional"
}, },
"asarUnpack": [
"./node_modules/macos-notification-state/**/*",
"./node_modules/windows-focus-assist/**/*"
],
"linux": { "linux": {
"category": "Network;InstantMessaging", "category": "Network;InstantMessaging",
"target": [ "target": [

864
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -67,7 +67,8 @@
"check-types": "tsc", "check-types": "tsc",
"prune": "ts-prune", "prune": "ts-prune",
"mmjstool": "mmjstool", "mmjstool": "mmjstool",
"i18n-extract": "npm run mmjstool -- i18n extract-desktop" "i18n-extract": "npm run mmjstool -- i18n extract-desktop",
"postinstall": "electron-rebuild"
}, },
"jest": { "jest": {
"clearMocks": true, "clearMocks": true,
@@ -135,7 +136,6 @@
"@typescript-eslint/eslint-plugin": "5.18.0", "@typescript-eslint/eslint-plugin": "5.18.0",
"@typescript-eslint/parser": "5.18.0", "@typescript-eslint/parser": "5.18.0",
"7zip-bin": "5.1.1", "7zip-bin": "5.1.1",
"awesome-node-loader": "1.1.1",
"axios": "0.26.1", "axios": "0.26.1",
"babel-eslint": "10.1.0", "babel-eslint": "10.1.0",
"babel-loader": "8.2.4", "babel-loader": "8.2.4",
@@ -148,7 +148,7 @@
"electron-connect": "0.6.3", "electron-connect": "0.6.3",
"electron-mocha": "11.0.2", "electron-mocha": "11.0.2",
"electron-notarize": "1.2.1", "electron-notarize": "1.2.1",
"electron-rebuild": "3.2.7", "electron-rebuild": "3.2.8",
"eslint": "7.29.0", "eslint": "7.29.0",
"eslint-import-resolver-webpack": "0.13.2", "eslint-import-resolver-webpack": "0.13.2",
"eslint-plugin-babel": "5.3.1", "eslint-plugin-babel": "5.3.1",
@@ -165,6 +165,7 @@
"mmjstool": "github:mattermost/mattermost-utilities#3b4506b0f6b14fbb402f9f8ef932370e459e3773", "mmjstool": "github:mattermost/mattermost-utilities#3b4506b0f6b14fbb402f9f8ef932370e459e3773",
"mocha-circleci-reporter": "0.0.3", "mocha-circleci-reporter": "0.0.3",
"node-gyp": "9.0.0", "node-gyp": "9.0.0",
"node-loader": "2.0.0",
"npm-run-all": "4.1.5", "npm-run-all": "4.1.5",
"playwright": "1.23.4", "playwright": "1.23.4",
"ps-node": "^0.1.6", "ps-node": "^0.1.6",
@@ -192,6 +193,7 @@
"electron-updater": "5.0.0", "electron-updater": "5.0.0",
"fs-extra": "10.0.1", "fs-extra": "10.0.1",
"joi": "17.6.0", "joi": "17.6.0",
"macos-notification-state": "2.0.1",
"pretty-bytes": "6.0.0", "pretty-bytes": "6.0.0",
"react": "16.14.0", "react": "16.14.0",
"react-beautiful-dnd": "13.1.0", "react-beautiful-dnd": "13.1.0",
@@ -202,6 +204,7 @@
"sass": "1.49.11", "sass": "1.49.11",
"semver": "7.3.5", "semver": "7.3.5",
"valid-url": "1.0.9", "valid-url": "1.0.9",
"windows-focus-assist": "1.3.0",
"winreg-utf8": "0.1.1", "winreg-utf8": "0.1.1",
"yargs": "17.4.0" "yargs": "17.4.0"
}, },

View File

@@ -525,7 +525,7 @@ function Run-BuildChangelog {
function Run-BuildElectron { function Run-BuildElectron {
Print-Info "Installing nodejs/electron dependencies (running npm ci)..." Print-Info "Installing nodejs/electron dependencies (running npm ci)..."
npm ci npm ci --ignore-scripts
#npm install --prefix="$(Get-RootDir)" "$(Get-RootDir)" #npm install --prefix="$(Get-RootDir)" "$(Get-RootDir)"
Print-Info "Building nodejs/electron code (running npm run build)..." Print-Info "Building nodejs/electron code (running npm run build)..."
npm run build npm run build

34
scripts/beforepack.js Normal file
View File

@@ -0,0 +1,34 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
const {exec} = require('child_process');
exports.default = async function beforePack(context) {
return new Promise((resolve, reject) => {
const arch = getArch(context.arch);
exec(`npm run postinstall -- --arch ${arch}`, (error) => {
if (error) {
reject(error);
} else {
resolve();
}
});
});
};
function getArch(arch) {
switch (arch) {
case 0:
return 'ia32';
case 1:
return 'x64';
case 2:
return 'armv7l';
case 3:
return 'arm64';
case 4:
return 'universal';
default:
return '';
}
}

View File

@@ -5,6 +5,9 @@
import {Notification, shell} from 'electron'; import {Notification, shell} from 'electron';
import {getFocusAssist} from 'windows-focus-assist';
import {getDoNotDisturb as getDarwinDoNotDisturb} from 'macos-notification-state';
import {PLAY_SOUND} from 'common/communication'; import {PLAY_SOUND} from 'common/communication';
import {TAB_MESSAGING} from 'common/tabs/TabView'; import {TAB_MESSAGING} from 'common/tabs/TabView';
@@ -53,6 +56,14 @@ jest.mock('electron', () => {
}; };
}); });
jest.mock('windows-focus-assist', () => ({
getFocusAssist: jest.fn(),
}));
jest.mock('macos-notification-state', () => ({
getDoNotDisturb: jest.fn(),
}));
jest.mock('../windows/windowManager', () => ({ jest.mock('../windows/windowManager', () => ({
getServerNameByWebContentsId: () => 'server_name', getServerNameByWebContentsId: () => 'server_name',
sendToRenderer: jest.fn(), sendToRenderer: jest.fn(),
@@ -68,6 +79,7 @@ describe('main/notifications', () => {
describe('displayMention', () => { describe('displayMention', () => {
beforeEach(() => { beforeEach(() => {
Notification.isSupported.mockImplementation(() => true); Notification.isSupported.mockImplementation(() => true);
getFocusAssist.mockReturnValue({value: false});
}); });
it('should do nothing when Notification is not supported', () => { it('should do nothing when Notification is not supported', () => {
@@ -85,6 +97,54 @@ describe('main/notifications', () => {
expect(Notification.didConstruct).not.toBeCalled(); expect(Notification.didConstruct).not.toBeCalled();
}); });
it('should do nothing when alarms only is enabled on windows', () => {
const originalPlatform = process.platform;
Object.defineProperty(process, 'platform', {
value: 'win32',
});
getFocusAssist.mockReturnValue({value: 2});
displayMention(
'test',
'test body',
{id: 'channel_id'},
'team_id',
'http://server-1.com/team_id/channel_id',
false,
{id: 1},
{},
);
expect(Notification.didConstruct).not.toBeCalled();
Object.defineProperty(process, 'platform', {
value: originalPlatform,
});
});
it('should do nothing when dnd is enabled on mac', () => {
const originalPlatform = process.platform;
Object.defineProperty(process, 'platform', {
value: 'darwin',
});
getDarwinDoNotDisturb.mockReturnValue(true);
displayMention(
'test',
'test body',
{id: 'channel_id'},
'team_id',
'http://server-1.com/team_id/channel_id',
false,
{id: 1},
{},
);
expect(Notification.didConstruct).not.toBeCalled();
Object.defineProperty(process, 'platform', {
value: originalPlatform,
});
});
it('should play notification sound when custom sound is provided', () => { it('should play notification sound when custom sound is provided', () => {
displayMention( displayMention(
'test', 'test',

View File

@@ -4,6 +4,9 @@
import {shell, Notification} from 'electron'; import {shell, Notification} from 'electron';
import log from 'electron-log'; import log from 'electron-log';
import {getFocusAssist, isPriority} from 'windows-focus-assist';
import {getDoNotDisturb as getDarwinDoNotDisturb} from 'macos-notification-state';
import {MentionData} from 'types/notification'; import {MentionData} from 'types/notification';
import {PLAY_SOUND} from 'common/communication'; import {PLAY_SOUND} from 'common/communication';
@@ -24,6 +27,11 @@ export function displayMention(title: string, body: string, channel: {id: string
log.error('notification not supported'); log.error('notification not supported');
return; return;
} }
if (getDoNotDisturb()) {
return;
}
const serverName = WindowManager.getServerNameByWebContentsId(webcontents.id); const serverName = WindowManager.getServerNameByWebContentsId(webcontents.id);
const options = { const options = {
@@ -72,6 +80,11 @@ export function displayDownloadCompleted(fileName: string, path: string, serverN
log.error('notification not supported'); log.error('notification not supported');
return; return;
} }
if (getDoNotDisturb()) {
return;
}
const download = new DownloadNotification(fileName, serverName); const download = new DownloadNotification(fileName, serverName);
download.on('show', () => { download.on('show', () => {
@@ -87,6 +100,14 @@ export function displayDownloadCompleted(fileName: string, path: string, serverN
let upgrade: NewVersionNotification; let upgrade: NewVersionNotification;
export function displayUpgrade(version: string, handleUpgrade: () => void): void { export function displayUpgrade(version: string, handleUpgrade: () => void): void {
if (!Notification.isSupported()) {
log.error('notification not supported');
return;
}
if (getDoNotDisturb()) {
return;
}
if (upgrade) { if (upgrade) {
upgrade.close(); upgrade.close();
} }
@@ -100,6 +121,14 @@ export function displayUpgrade(version: string, handleUpgrade: () => void): void
let restartToUpgrade; let restartToUpgrade;
export function displayRestartToUpgrade(version: string, handleUpgrade: () => void): void { export function displayRestartToUpgrade(version: string, handleUpgrade: () => void): void {
if (!Notification.isSupported()) {
log.error('notification not supported');
return;
}
if (getDoNotDisturb()) {
return;
}
restartToUpgrade = new UpgradeNotification(); restartToUpgrade = new UpgradeNotification();
restartToUpgrade.on('click', () => { restartToUpgrade.on('click', () => {
log.info(`User requested perform the upgrade now to ${version}`); log.info(`User requested perform the upgrade now to ${version}`);
@@ -107,3 +136,21 @@ export function displayRestartToUpgrade(version: string, handleUpgrade: () => vo
}); });
restartToUpgrade.show(); restartToUpgrade.show();
} }
function getDoNotDisturb() {
if (process.platform === 'win32') {
const focusAssistValue = getFocusAssist().value;
switch (focusAssistValue) {
case 1:
return !isPriority('Mattermost.Desktop');
default:
return focusAssistValue;
}
}
if (process.platform === 'darwin') {
return getDarwinDoNotDisturb();
}
return false;
}

View File

@@ -6,8 +6,6 @@
/* eslint-disable import/no-commonjs */ /* eslint-disable import/no-commonjs */
'use strict'; 'use strict';
const path = require('path');
const {merge} = require('webpack-merge'); const {merge} = require('webpack-merge');
const CopyPlugin = require('copy-webpack-plugin'); const CopyPlugin = require('copy-webpack-plugin');
@@ -24,6 +22,10 @@ module.exports = merge(base, {
loadingScreenPreload: './src/main/preload/loadingScreenPreload.js', loadingScreenPreload: './src/main/preload/loadingScreenPreload.js',
urlView: './src/main/preload/urlView.js', urlView: './src/main/preload/urlView.js',
}, },
externals: {
'macos-notification-state': 'require("macos-notification-state")',
'windows-focus-assist': 'require("windows-focus-assist")',
},
module: { module: {
rules: [{ rules: [{
test: /\.(js|ts)?$/, test: /\.(js|ts)?$/,
@@ -39,11 +41,7 @@ module.exports = merge(base, {
}, },
{ {
test: /\.node$/, test: /\.node$/,
loader: 'awesome-node-loader', loader: 'node-loader',
options: {
name: '[name].[ext]',
rewritePath: path.resolve(__dirname, 'dist'),
},
}], }],
}, },
plugins: [ plugins: [