Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Add custom About dialog for non-macOS platforms (#421) #1175

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,8 @@
"micromatch": ">=4.0.8",
"minimatch@<3.0.5": ">=3.0.5",
"ws": ">=8.18.0"
},
"dependencies": {
"electron-about-window": "^1.15.2"
}
}
91 changes: 67 additions & 24 deletions td.vue/src/desktop/menu.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,41 @@
'use strict';

import { app, dialog } from 'electron';
import { app, dialog, BrowserWindow, ipcMain } from 'electron';
import path from 'path';
import logger from './logger.js';
import { isMacOS } from './utils.js';




function openAboutWindow({ app, BrowserWindow, ipcMain }) {
const aboutWindow = new BrowserWindow({
width: 400,
height: 300,
resizable: false,
title: 'About',
modal: true,
parent: BrowserWindow.getFocusedWindow(), // Open as a modal window
show: false,
});

aboutWindow.loadURL('data:text/html;charset=utf-8,' + encodeURIComponent(`
<h1>About</h1>
<p>${app.getName()}</p>
<p>App version: ${app.getVersion()}</p>

`));

aboutWindow.once('ready-to-show', () => {
aboutWindow.show();
});

ipcMain.on('close-about', () => {
aboutWindow.close();
});
}


const { shell } = require('electron');
const fs = require('fs');

Expand All @@ -30,7 +61,7 @@ import zho from '@/i18n/zh.js';

const messages = { ara, deu, ell, eng, fin, fra, hin, id, jpn, ms, por, spa, zho };
// hide RUS & UKR for now: const messages = { ara, deu, ell, eng, fin, fra, hin, id, jpn, ms, por, rus, spa, ukr, zho };
const languages = [ 'ara', 'deu', 'ell', 'eng', 'fin', 'fra', 'hin', 'id', 'jpn', 'ms', 'por', 'spa', 'zho' ];
const languages = ['ara', 'deu', 'ell', 'eng', 'fin', 'fra', 'hin', 'id', 'jpn', 'ms', 'por', 'spa', 'zho'];
// hide RUS & UKR for now: const languages = [ 'ara', 'deu', 'ell', 'eng', 'fin', 'fra', 'hin', 'id', 'jpn', 'ms', 'por', 'rus', 'spa', 'ukr', 'zho' ];
const defaultLanguage = 'eng';
var language = defaultLanguage;
Expand All @@ -41,33 +72,33 @@ export const model = {
isOpen: false
};

export function getMenuTemplate () {
export function getMenuTemplate() {
var menuTemplate = (isMacOS ? [{ role: 'appMenu' }] : []);
menuTemplate.push(
{
label: messages[language].desktop.file.heading,
submenu: [
{
label: messages[language].desktop.file.open,
click () {
click() {
openModelRequest('');
}
},
{
label: messages[language].desktop.file.save,
click () {
click() {
saveModel();
}
},
{
label: messages[language].desktop.file.saveAs,
click () {
click() {
saveModelAs();
}
},
{
label: messages[language].desktop.file.new,
click () {
click() {
newModel();
}
},
Expand All @@ -76,13 +107,13 @@ export function getMenuTemplate () {
submenu: [
{
label: messages[language].forms.exportHtml,
click () {
click() {
printModel('HTML');
}
},
{
label: messages[language].forms.exportPdf,
click () {
click() {
printModel('PDF');
}
},
Expand All @@ -98,7 +129,7 @@ export function getMenuTemplate () {
},
{
label: messages[language].desktop.file.close,
click () {
click() {
closeModelRequest();
}
},
Expand Down Expand Up @@ -153,11 +184,23 @@ export function getMenuTemplate () {
}
},
{ type: 'separator' },
{ role: 'about' }
process.platform === 'darwin'
? { role: 'about' } // Use native "About" role for macOS
: {
label: 'About', // For non mac os
click: () => {
openAboutWindow({
app,
BrowserWindow,
ipcMain,
});
},
}
]
}
);


if (isMacOS) {
// recent docs only for macos, see www.electronjs.org/docs/latest/api/menu-item#roles
menuTemplate[1].submenu.push(
Expand All @@ -178,7 +221,7 @@ export function getMenuTemplate () {
}

// Open file system dialog and read file contents into model
function openModel (filename) {
function openModel(filename) {
logger.log.debug('Open file with name : ' + filename);

if (filename !== '') {
Expand Down Expand Up @@ -207,13 +250,13 @@ function openModel (filename) {
}

// request to the renderer for confirmation that it is OK to open a model file
function openModelRequest (filename) {
function openModelRequest(filename) {
logger.log.debug('Request to renderer to open an existing model');
mainWindow.webContents.send('open-model-request', filename);
}

// request to the renderer for confirmation that it is OK to open a model file
function openModelFile (filename) {
function openModelFile(filename) {
logger.log.debug(messages[language].desktop.file.open + ': ' + filename);
fs.readFile(filename, (err, data) => {
if (!err) {
Expand All @@ -231,7 +274,7 @@ function openModelFile (filename) {
}

// request that the renderer send the model data, retain existing filename
function saveModel () {
function saveModel() {
if (model.isOpen === false) {
logger.log.debug('Skip save request because no model is open');
return;
Expand All @@ -241,7 +284,7 @@ function saveModel () {
}

// request that the renderer send the model data
function saveModelAs () {
function saveModelAs() {
if (model.isOpen === false) {
logger.log.debug('Skip saveAs request because no model is open');
return;
Expand All @@ -253,7 +296,7 @@ function saveModelAs () {
}

// Open saveAs file system dialog and write contents to new file location
function saveModelDataAs (modelData, fileName) {
function saveModelDataAs(modelData, fileName) {
let newName = 'new-model.json';
if (fileName) {
newName = fileName;
Expand Down Expand Up @@ -282,31 +325,31 @@ function saveModelDataAs (modelData, fileName) {
}

// request that the renderer open a new model
function newModel () {
function newModel() {
let newName = 'new-model.json';
logger.log.debug(messages[language].desktop.file.new + ': ' + newName);
mainWindow.webContents.send('new-model-request', newName);
}

// request that the renderer display the model report/print page
function printModel (format) {
function printModel(format) {
if (model.isOpen === false) {
logger.log.debug('Skip print request because no model open');
return;
}
logger.log.debug(messages[language].forms.exportPdf+ ': ' + model.filePath);
logger.log.debug(messages[language].forms.exportPdf + ': ' + model.filePath);
// prompt the renderer to open the print/report window
mainWindow.webContents.send('print-model-request', format);
}

// request that the renderer close the model
function closeModelRequest () {
function closeModelRequest() {
logger.log.debug(messages[language].desktop.file.close + ': ' + model.filePath);
mainWindow.webContents.send('close-model-request', path.basename(model.filePath));
}

// save the threat model
function saveModelData (modelData) {
function saveModelData(modelData) {
if (model.isOpen === true) {
fs.writeFile(model.filePath, JSON.stringify(modelData, undefined, 2), (err) => {
if (err) {
Expand All @@ -322,7 +365,7 @@ function saveModelData (modelData) {
}

// Open saveAs file system dialog and write report contents as HTML
function saveHTMLReport (htmlPath) {
function saveHTMLReport(htmlPath) {
htmlPath += '.html';
var dialogOptions = {
title: messages[language].forms.saveAS,
Expand All @@ -347,7 +390,7 @@ function saveHTMLReport (htmlPath) {
}

// Open saveAs file system dialog and write PDF report
function savePDFReport (pdfPath) {
function savePDFReport(pdfPath) {
pdfPath += '.pdf';
var dialogOptions = {
title: messages[language].forms.exportPdf,
Expand Down
Loading