Qortal UI - Main Code Repository A User Interface for the Qortal Blockchain Project. Truly decentralized web hosting, application hosting, communications, data storage, and full infrastructure for the future global decentralized digital world.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

993 lines
27 KiB

const { app, BrowserWindow, ipcMain, ipcRenderer, Menu, Notification, Tray, nativeImage, dialog, webContents, nativeTheme } = require('electron')
const { autoUpdater } = require('electron-updater')
const server = require('./server.js')
const log = require('electron-log')
const path = require('path')
const i18n = require('./lib/i18n.js')
const fs = require('fs')
const electronDl = require('electron-dl')
const Store = require('electron-store')
const extract = require('extract-zip')
const fetch = require('node-fetch')
const execFile = require('child_process').execFile
const exec = require('child_process').exec
const spawn = require('child_process').spawn
3 years ago
app.commandLine.appendSwitch('enable-experimental-web-platform-features')
app.disableHardwareAcceleration()
app.enableSandbox()
electronDl()
3 years ago
process.env['APP_PATH'] = app.getAppPath()
3 years ago
const homePath = app.getPath('home')
const downloadPath = app.getPath('downloads')
const store = new Store()
autoUpdater.autoDownload = false
autoUpdater.autoInstallOnAppQuit = false
autoUpdater.logger = log
autoUpdater.logger.transports.file.level = 'info'
if(!store.has('askingCore')) {
store.set('askingCore', false)
}
log.info('App starting...')
log.info('App Platform is', process.platform)
log.info('Platform arch is', process.arch)
log.info("ASKING CORE", store.get('askingCore'))
const winjar = String.raw`C:\Program Files\Qortal\qortal.jar`
const winurl = "https://github.com/Qortal/qortal/releases/latest/download/qortal.exe"
const winexe = downloadPath + "\\qortal.exe"
const startWinCore = "C:\\Program Files\\Qortal\\qortal.exe"
const zipdir = homePath
const zipfile = homePath + "/qortal.zip"
const zipurl = "https://github.com/Qortal/qortal/releases/latest/download/qortal.zip"
const qortaldir = homePath + "/qortal/"
const qortaljar = homePath + "/qortal/qortal.jar"
const qortalsettings = homePath + "/qortal/settings.json"
const javadir = homePath + "/jdk-17.0.2/"
const linjavax64url = "https://download.qortal.online/openjdk-17.0.2_linux-x64_bin.zip"
const linjavax64file = homePath + "/openjdk-17.0.2_linux-x64_bin.zip"
const linjavax64bindir = homePath + "/jdk-17.0.2/bin"
const linjavax64binfile = homePath + "/jdk-17.0.2/bin/java"
const linjavaarmurl = "https://download.qortal.online/openjdk-17.0.2_linux-arm_bin.zip"
const linjavaarmfile = homePath + "/openjdk-17.0.2_linux-arm_bin.zip"
const linjavaarmbindir = homePath + "/jdk-17.0.2/bin"
const linjavaarmbinfile = homePath + "/jdk-17.0.2/bin/java"
const linjavaarm64url = "https://download.qortal.online/openjdk-17.0.2_linux-arm64_bin.zip"
const linjavaarm64file = homePath + "/openjdk-17.0.2_linux-arm64_bin.zip"
const linjavaarm64bindir = homePath + "/jdk-17.0.2/bin"
const linjavaarm64binfile = homePath + "/jdk-17.0.2/bin/java"
const macjavax64url = "https://download.qortal.online/openjdk-17.0.2_macos-x64_bin.zip"
const macjavax64file = homePath + "/openjdk-17.0.2_macos-x64_bin.zip"
const macjavax64bindir = homePath + "/jdk-17.0.2/Contents/Home/bin"
const macjavax64binfile = homePath + "/jdk-17.0.2/Contents/Home/bin/java"
const macjavaaarch64url = "https://download.qortal.online/openjdk-17.0.2_macos-aarch64_bin.zip"
const macjavaaarch64file = homePath + "/openjdk-17.0.2_macos-aarch64_bin.zip"
const macjavaaarch64bindir = homePath + "/jdk-17.0.2/Contents/Home/bin"
const macjavaaarch64binfile = homePath + "/jdk-17.0.2/Contents/Home/bin/java"
const isRunning = (query, cb) => {
let platform = process.platform
let cmd = ''
switch (platform) {
case 'win32': cmd = `tasklist`; break
case 'darwin': cmd = `ps -ax | grep [q]ortal.jar`; break
case 'linux': cmd = `ps ax | grep [q]ortal.jar`; break
default: break
}
exec(cmd, (err, stdout, stderr) => {
cb(stdout.toLowerCase().indexOf(query.toLowerCase()) > -1)
})
}
async function checkWin() {
if (fs.existsSync(winjar)) {
isRunning('qortal.exe', (status) => {
if (status == true) {
log.info("Core is running, perfect !")
} else {
if (!store.get('askingCore')) {
const dialogOpts = {
type: 'info',
buttons: [i18n.__("electron_translate_13"), i18n.__("electron_translate_14")],
title: i18n.__("electron_translate_15"),
message: i18n.__("electron_translate_16"),
detail: i18n.__("electron_translate_17"),
checkboxLabel: i18n.__("electron_translate_28"),
checkboxChecked: false
}
dialog.showMessageBox(dialogOpts).then((returnValue) => {
if (returnValue.response === 0) {
spawn(startWinCore, { detached: true })
store.set('askingCore', returnValue.checkboxChecked)
} else {
store.set('askingCore', returnValue.checkboxChecked)
return
}
})
}
}
})
} else {
const dialogOpts = {
type: 'info',
buttons: [i18n.__("electron_translate_18"), i18n.__("electron_translate_19")],
title: i18n.__("electron_translate_20"),
message: i18n.__("electron_translate_21"),
detail: i18n.__("electron_translate_22")
}
dialog.showMessageBox(dialogOpts).then((returnValue) => {
if (returnValue.response === 0) {
downloadWindows()
} else {
return
}
})
}
}
async function downloadWindows() {
let winLoader = new BrowserWindow({
width: 500,
height: 500,
transparent: true,
frame: false,
alwaysOnTop: true,
show: false
})
winLoader.loadFile(path.join(__dirname + '/splash/download.html'))
winLoader.show()
await electronDl.download(myWindow, winurl, {
directory: downloadPath,
onProgress: function () { log.info("Starting Download Qortal Core Installer") }
})
winLoader.destroy()
const coreInstall = execFile(winexe, (e, stdout, stderr) => {
if (e) {
log.info(e)
removeQortalExe()
} else {
log.info('Qortal Core Installation Done', stdout, stderr)
removeQortalExe()
}
})
coreInstall.stdin.end()
}
async function removeQortalExe() {
try {
await fs.rmSync(winexe, {
force: true,
})
} catch (err) {
log.info('renove error', err)
}
checkWin()
}
async function checkPort() {
await fetch('http://localhost:12391/admin/info').catch(err => {
return {
ok: false,
status: -1,
statusText: 'Qortal Connect Failure',
}
}).then(checkResponseStatus)
}
async function checkResponseStatus(res) {
if (res.ok) {
return
} else if (process.platform === 'win32') {
await checkWin()
} else {
await javaversion()
}
}
async function javaversion() {
var stderrChunks = []
let checkJava = await spawn('java', ['-version'],{shell: true})
if (process.platform === 'linux') {
if (process.arch === 'x64') {
if (fs.existsSync(linjavax64bindir)) {
checkJava = await spawn(linjavax64binfile, ['-version'],{cwd: homePath, shell: true, maxBuffer: Infinity})
}
} else if (process.arch === 'arm64') {
if (fs.existsSync(linjavaarm64bindir)) {
checkJava = await spawn(linjavaarm64binfile, ['-version'],{cwd: homePath, shell: true, maxBuffer: Infinity})
}
} else if (process.arch === 'arm') {
if (fs.existsSync(linjavaarmbindir)) {
checkJava = await spawn(linjavaarmbinfile, ['-version'],{cwd: homePath, shell: true, maxBuffer: Infinity})
}
}
} else if (process.platform === 'darwin') {
if (process.arch === 'x64') {
if (fs.existsSync(macjavax64bindir)) {
checkJava = await spawn(macjavax64binfile, ['-version'],{cwd: homePath, shell: true, maxBuffer: Infinity})
}
} else {
if (fs.existsSync(macjavaaarch64bindir)) {
checkJava = await spawn(macjavaaarch64file, ['-version'],{cwd: homePath, shell: true, maxBuffer: Infinity})
}
}
}
checkJava.stderr.on('data', (data) => {
stderrChunks = stderrChunks.concat(data)
})
checkJava.stderr.on('end', () => {
datres = Buffer.concat(stderrChunks).toString().split('\n')[0]
var javaVersion = new RegExp('(java|openjdk) version').test(datres) ? datres.split(' ')[2].replace(/"/g, '') : false
log.info("Java Version", javaVersion)
if (javaVersion != false) {
checkQortal()
} else {
const dialogOpts = {
type: 'info',
buttons: [i18n.__("electron_translate_23"), i18n.__("electron_translate_24")],
title: i18n.__("electron_translate_25"),
message: i18n.__("electron_translate_26"),
detail: i18n.__("electron_translate_27")
}
dialog.showMessageBox(dialogOpts).then((returnValue) => {
if (returnValue.response === 0) {
installJava()
} else {
return
}
})
}
})
}
async function installJava() {
let splashLoader = new BrowserWindow({
width: 500,
height: 500,
transparent: true,
frame: false,
alwaysOnTop: true,
show: false
})
splashLoader.loadFile(path.join(__dirname + '/splash/download.html'))
if (process.platform === 'linux') {
if (process.arch === 'x64') {
try {
splashLoader.show()
await electronDl.download(myWindow, linjavax64url, {
directory: homePath,
onProgress: function () { log.info("Starting Download JAVA") }
})
} catch (err) {
splashLoader.destroy()
log.info('Download JAVA error', err)
}
splashLoader.destroy()
unzipJavaX64Linux()
} else if (process.arch === 'arm64') {
try {
splashLoader.show()
await electronDl.download(myWindow, linjavaarm64url, {
directory: homePath,
onProgress: function () { log.info("Starting Download JAVA") }
})
} catch (err) {
splashLoader.destroy()
log.info('Download JAVA error', err)
}
splashLoader.destroy()
unzipJavaArm64Linux()
} else if (process.arch === 'arm') {
try {
splashLoader.show()
await electronDl.download(myWindow, linjavaarmurl, {
directory: homePath,
onProgress: function () { log.info("Starting Download JAVA") }
})
} catch (err) {
splashLoader.destroy()
log.info('Download JAVA error', err)
}
splashLoader.destroy()
unzipJavaArmLinux()
}
} else if (process.platform === 'darwin') {
if (process.arch === 'x64') {
try {
splashLoader.show()
await electronDl.download(myWindow, macjavax64url, {
directory: homePath,
onProgress: function () { log.info("Starting Download JAVA") }
})
} catch (err) {
splashLoader.destroy()
log.info('Download JAVA error', err)
}
splashLoader.destroy()
unzipJavaX64Mac()
} else {
try {
splashLoader.show()
await electronDl.download(myWindow, macjavaaarch64url, {
directory: homePath,
onProgress: function () { log.info("Starting Download JAVA") }
})
} catch (err) {
splashLoader.destroy()
log.info('Download JAVA error', err)
}
splashLoader.destroy()
unzipJavaAarch64Mac()
}
}
}
async function unzipJavaX64Linux() {
try {
await extract(linjavax64file, { dir: homePath })
log.info('Unzip Java complete')
} catch (err) {
log.info('Unzip Java error', err)
}
chmodJava()
}
async function unzipJavaArm64Linux() {
try {
await extract(linjavaarm64file, { dir: homePath })
log.info('Unzip Java complete')
} catch (err) {
log.info('Unzip Java error', err)
}
chmodJava()
}
async function unzipJavaArmLinux() {
try {
await extract(linjavaarmfile, { dir: homePath })
log.info('Unzip Java complete')
} catch (err) {
log.info('Unzip Java error', err)
}
chmodJava()
}
async function unzipJavaX64Mac() {
try {
await extract(macjavax64file, { dir: homePath })
log.info('Unzip Java complete')
} catch (err) {
log.info('Unzip Java error', err)
}
chmodJava()
}
async function unzipJavaAarch64Mac() {
try {
await extract(macjavaaarch64file, { dir: homePath })
log.info('Unzip Java complete')
} catch (err) {
log.info('Unzip Java error', err)
}
chmodJava()
}
async function chmodJava() {
try {
await spawn(
'chmod', ['-R', '+x', javadir],
{ cwd: homePath, shell: true }
)
} catch (err) {
log.info('chmod error', err)
}
removeJavaZip()
}
async function removeJavaZip() {
if (process.platform === 'linux') {
if (process.arch === 'x64') {
try {
await spawn(
'rm', ['-rf', linjavax64file],
{ cwd: homePath, shell: true }
)
} catch (err) {
log.info('rm error', err)
}
checkQortal()
} else if (process.arch === 'arm64') {
try {
await spawn(
'rm', ['-rf', linjavaarm64file],
{ cwd: homePath, shell: true }
)
} catch (err) {
log.info('rm error', err)
}
checkQortal()
} else if (process.arch === 'arm') {
try {
await spawn(
'rm', ['-rf', linjavaarmfile],
{ cwd: homePath, shell: true }
)
} catch (err) {
log.info('rm error', err)
}
checkQortal()
}
} else if (process.platform === 'darwin') {
if (process.arch === 'x64') {
try {
await spawn(
'rm', ['-rf', macjavax64file],
{ cwd: homePath, shell: true }
)
} catch (err) {
log.info('rm error', err)
}
checkQortal()
} else {
try {
await spawn(
'rm', ['-rf', macjavaaarch64file],
{ cwd: homePath, shell: true }
)
} catch (err) {
log.info('rm error', err)
}
checkQortal()
}
}
}
function checkQortal() {
if (fs.existsSync(qortaljar)) {
isRunning('qortal.jar', (status) => {
if (status == true) {
log.info("Core is running, perfect !")
} else {
1 year ago
if (!store.get('askingCore')) {
const dialogOpts = {
type: 'info',
buttons: [i18n.__("electron_translate_13"), i18n.__("electron_translate_14")],
title: i18n.__("electron_translate_15"),
message: i18n.__("electron_translate_16"),
detail: i18n.__("electron_translate_17"),
checkboxLabel: i18n.__("electron_translate_28"),
checkboxChecked: false
}
1 year ago
dialog.showMessageBox(dialogOpts).then((returnValue) => {
if (returnValue.response === 0) {
startQortal()
store.set('askingCore', returnValue.checkboxChecked)
} else {
store.set('askingCore', returnValue.checkboxChecked)
return
}
})
}
}
})
} else {
const dialogOpts = {
type: 'info',
buttons: [i18n.__("electron_translate_18"), i18n.__("electron_translate_19")],
title: i18n.__("electron_translate_20"),
message: i18n.__("electron_translate_21"),
detail: i18n.__("electron_translate_22")
}
dialog.showMessageBox(dialogOpts).then((returnValue) => {
if (returnValue.response === 0) {
downloadQortal()
} else {
return
}
})
}
}
async function downloadQortal() {
let qortalLoader = new BrowserWindow({
width: 500,
height: 500,
transparent: true,
frame: false,
alwaysOnTop: true,
show: false
})
qortalLoader.loadFile(path.join(__dirname + '/splash/download.html'))
try {
qortalLoader.show()
await electronDl.download(myWindow, zipurl, {
directory: zipdir,
onProgress: function () { log.info("Starting Download Qortal") }
})
} catch (err) {
qortalLoader.destroy()
log.info('Download Qortal error', err)
}
qortalLoader.destroy()
unzipQortal()
}
async function unzipQortal() {
try {
await extract(zipfile, { dir: zipdir })
log.info('Unzip Qortal complete')
} catch (err) {
log.info('Unzip Qortal error', err)
}
chmodQortal()
}
async function chmodQortal() {
try {
await spawn(
'chmod', ['-R', '+x', qortaldir],
{ cwd: homePath, shell: true }
)
} catch (err) {
log.info('chmod error', err)
}
removeQortalZip()
}
async function removeQortalZip() {
try {
await spawn(
'rm', ['-rf', zipfile],
{ cwd: homePath, shell: true }
)
} catch (err) {
log.info('rm error', err)
}
checkAndStart()
}
async function checkAndStart() {
try {
1 year ago
if (!store.get('askingCore')) {
const dialogOpts = {
type: 'info',
buttons: [i18n.__("electron_translate_13"), i18n.__("electron_translate_14")],
title: i18n.__("electron_translate_15"),
message: i18n.__("electron_translate_16"),
detail: i18n.__("electron_translate_17"),
checkboxLabel: i18n.__("electron_translate_28"),
checkboxChecked: false
}
1 year ago
dialog.showMessageBox(dialogOpts).then((returnValue) => {
if (returnValue.response === 0) {
startQortal()
store.set('askingCore', returnValue.checkboxChecked)
} else {
store.set('askingCore', returnValue.checkboxChecked)
return
}
})
}
} catch (err) {
log.info('Sed error', err)
}
}
async function startQortal() {
if (process.platform === 'linux') {
if (process.arch === 'x64') {
if (fs.existsSync(linjavax64bindir)) {
try {
await spawn(
'nohup', ['nice', '-n', '20', linjavax64binfile, '-Djava.net.preferIPv4Stack=false', '-jar', qortaljar, qortalsettings, '1>run.log', '2>&1', '&'],
{ cwd: qortaldir, shell: true, detached: true }
)
} catch (err) {
log.info('Start qortal error', err)
}
} else {
try {
await spawn(
'nohup', ['nice', '-n', '20', 'java', '-Djava.net.preferIPv4Stack=false', '-jar', qortaljar, qortalsettings, '1>run.log', '2>&1', '&'],
{ cwd: qortaldir, shell: true, detached: true }
)
} catch (err) {
log.info('Start qortal error', err)
}
}
} else if (process.arch === 'arm64') {
if (fs.existsSync(linjavaarm64bindir)) {
try {
await spawn(
'nohup', ['nice', '-n', '20', linjavaarm64binfile, '-Djava.net.preferIPv4Stack=false', '-jar', qortaljar, qortalsettings, '1>run.log', '2>&1', '&'],
{ cwd: qortaldir, shell: true, detached: true }
)
} catch (err) {
log.info('Start qortal error', err)
}
} else {
try {
await spawn(
'nohup', ['nice', '-n', '20', 'java', '-Djava.net.preferIPv4Stack=false', '-jar', qortaljar, qortalsettings, '1>run.log', '2>&1', '&'],
{ cwd: qortaldir, shell: true, detached: true }
)
} catch (err) {
log.info('Start qortal error', err)
}
}
} else if (process.arch === 'arm') {
if (fs.existsSync(linjavaarmbindir)) {
try {
await spawn(
'nohup', ['nice', '-n', '20', linjavaarmbinfile, '-Djava.net.preferIPv4Stack=false', '-jar', qortaljar, qortalsettings, '1>run.log', '2>&1', '&'],
{ cwd: qortaldir, shell: true, detached: true }
)
} catch (err) {
log.info('Start qortal error', err)
}
} else {
try {
await spawn(
'nohup', ['nice', '-n', '20', 'java', '-Djava.net.preferIPv4Stack=false', '-jar', qortaljar, qortalsettings, '1>run.log', '2>&1', '&'],
{ cwd: qortaldir, shell: true, detached: true }
)
} catch (err) {
log.info('Start qortal error', err)
}
}
}
} else if (process.platform === 'darwin') {
if (process.arch === 'x64') {
if (fs.existsSync(macjavax64bindir)) {
try {
await spawn(
'nohup', ['nice', '-n', '20', macjavax64binfile, '-Djava.net.preferIPv4Stack=false', '-jar', qortaljar, qortalsettings, '1>run.log', '2>&1', '&'],
{ cwd: qortaldir, shell: true, detached: true }
)
} catch (err) {
log.info('Start qortal error', err)
}
} else {
try {
await spawn(
'nohup', ['nice', '-n', '20', 'java', '-Djava.net.preferIPv4Stack=false', '-jar', qortaljar, qortalsettings, '1>run.log', '2>&1', '&'],
{ cwd: qortaldir, shell: true, detached: true }
)
} catch (err) {
log.info('Start qortal error', err)
}
}
} else {
if (fs.existsSync(macjavaaarch64bindir)) {
try {
await spawn(
'nohup', ['nice', '-n', '20', macjavaaarch64binfile, '-Djava.net.preferIPv4Stack=false', '-jar', qortaljar, qortalsettings, '1>run.log', '2>&1', '&'],
{ cwd: qortaldir, shell: true, detached: true }
)
} catch (err) {
log.info('Start qortal error', err)
}
} else {
try {
await spawn(
'nohup', ['nice', '-n', '20', 'java', '-Djava.net.preferIPv4Stack=false', '-jar', qortaljar, qortalsettings, '1>run.log', '2>&1', '&'],
{ cwd: qortaldir, shell: true, detached: true }
)
} catch (err) {
log.info('Start qortal error', err)
}
}
}
}
}
3 years ago
const editMenu = Menu.buildFromTemplate([
{
label: "Qortal",
submenu: [
{ label: "Quit", click() {app.quit()}}
]
3 years ago
},
{
1 year ago
label: i18n.__("electron_translate_34"),
submenu: [{
label: i18n.__("electron_translate_31"),
click() {
const dialogOpts = {
type: 'info',
noLink: true,
buttons: [i18n.__("electron_translate_29"), i18n.__("electron_translate_30")],
title: i18n.__("electron_translate_31"),
message: i18n.__("electron_translate_32"),
detail: i18n.__("electron_translate_33"),
checkboxLabel: i18n.__("electron_translate_28"),
checkboxChecked: store.get('askingCore')
}
dialog.showMessageBox(dialogOpts).then((returnValue) => {
if (returnValue.response === 0) {
store.set('askingCore', returnValue.checkboxChecked)
} else {
store.set('askingCore', returnValue.checkboxChecked)
return
}
})
}
}]
},
{
label: "Edit",
submenu: [
{ label: "Undo", accelerator: "CmdOrCtrl+Z", selector: "undo:" },
{ label: "Redo", accelerator: "Shift+CmdOrCtrl+Z", selector: "redo:" },
{ type: "separator" },
{ label: "Cut", accelerator: "CmdOrCtrl+X", selector: "cut:" },
{ label: "Copy", accelerator: "CmdOrCtrl+C", selector: "copy:" },
{ label: "Paste", accelerator: "CmdOrCtrl+V", selector: "paste:" },
{ label: "Select All", accelerator: "CmdOrCtrl+A", selector: "selectAll:" }
]
},
{
label: "Check for update", click() {autoUpdater.checkForUpdatesAndNotify()}
3 years ago
}
])
3 years ago
Menu.setApplicationMenu(editMenu)
3 years ago
let myWindow = null
3 years ago
function createWindow() {
myWindow = new BrowserWindow({
backgroundColor: '#eee',
width: 1280,
height: 720,
minWidth: 700,
minHeight: 640,
icon: path.join(__dirname + '/img/icons/png/256x256.png'),
title: "Qortal UI",
3 years ago
autoHideMenuBar: true,
webPreferences: {
partition: 'persist:webviewsession',
nodeIntegration: false,
contextIsolation: true,
enableRemoteModule: false,
allowRunningInsecureContent: false,
experimentalFeatures: false,
preload: path.join(__dirname, '/lib/preload.js')
3 years ago
},
show: false
})
myWindow.maximize()
myWindow.show()
3 years ago
myWindow.loadURL('http://localhost:12388/app/wallet')
myWindow.on('closed', function () {
myWindow = null
})
myWindow.on('minimize', function (event) {
event.preventDefault()
myWindow.hide()
})
ipcMain.handle('dark-mode:toggle', () => {
if (nativeTheme.shouldUseDarkColors) {
nativeTheme.themeSource = 'light'
} else {
nativeTheme.themeSource = 'dark'
}
return nativeTheme.shouldUseDarkColors
})
ipcMain.handle('dark-mode:system', () => {
nativeTheme.themeSource = 'system'
})
3 years ago
}
const createTray = () => {
let myTray = new Tray(path.join(__dirname + '/img/icons/png/tray/tray.png'))
const contextMenu = Menu.buildFromTemplate([
{
label: `Qortal UI v${app.getVersion()}`,
enabled: false,
},
{
type: 'separator',
},
{
label: i18n.__("electron_translate_31"),
click: function () {
const dialogOpts = {
type: 'info',
noLink: true,
buttons: [i18n.__("electron_translate_29"), i18n.__("electron_translate_30")],
title: i18n.__("electron_translate_31"),
message: i18n.__("electron_translate_32"),
detail: i18n.__("electron_translate_33"),
checkboxLabel: i18n.__("electron_translate_28"),
checkboxChecked: store.get('askingCore')
}
dialog.showMessageBox(dialogOpts).then((returnValue) => {
if (returnValue.response === 0) {
store.set('askingCore', returnValue.checkboxChecked)
} else {
store.set('askingCore', returnValue.checkboxChecked)
return
}
})
},
},
{
type: 'separator',
},
{
label: i18n.__("electron_translate_1"),
click: function () {
myWindow.maximize()
myWindow.show()
},
},
{
label: i18n.__("electron_translate_2"),
click: function () {
myTray.destroy()
app.quit()
},
3 years ago
},
])
3 years ago
myTray.setTitle("QORTAL UI")
myTray.setToolTip(`Qortal UI v${app.getVersion()}`)
3 years ago
myTray.setContextMenu(contextMenu)
myTray.on("double-click", () => myWindow.maximize(), myWindow.show())
}
async function checkAll() {
if (process.platform === 'win32') {
app.setAppUserModelId("org.qortal.QortalUI")
await checkPort()
} else if (process.platform === 'darwin') {
await checkPort()
} else if (process.platform === 'linux') {
await checkPort()
} else {
const dl = new Notification({
title: "System Detector",
body: "No Supported Sytem Detected"
})
dl.show()
}
3 years ago
}
const isLock = app.requestSingleInstanceLock()
3 years ago
if (!isLock) {
app.quit()
3 years ago
} else {
app.on('second-instance', (event, commandLine, workingDirectory) => {
if (myWindow) {
if (myWindow.isMinimized())
myWindow.maximize()
myWindow.show()
}
})
app.whenReady().then(async () => {
createWindow()
createTray()
await checkAll()
autoUpdater.checkForUpdatesAndNotify()
setInterval(() => {
autoUpdater.checkForUpdatesAndNotify()
}, 1000 * 60 * 720)
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
createTray()
}
})
3 years ago
})
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') {
app.quit()
3 years ago
}
})
ipcMain.on('app_version', (event) => {
log.info(app.getVersion())
myWindow.webContents.send('app_version', { version: app.getVersion() })
})
ipcMain.on('set-start-core', (event) => {
const dialogOpts = {
type: 'info',
noLink: true,
buttons: [i18n.__("electron_translate_29"), i18n.__("electron_translate_30")],
title: i18n.__("electron_translate_31"),
message: i18n.__("electron_translate_32"),
detail: i18n.__("electron_translate_33"),
checkboxLabel: i18n.__("electron_translate_28"),
checkboxChecked: store.get('askingCore')
}
dialog.showMessageBox(dialogOpts).then((returnValue) => {
if (returnValue.response === 0) {
store.set('askingCore', returnValue.checkboxChecked)
} else {
store.set('askingCore', returnValue.checkboxChecked)
return
}
})
})
ipcMain.on('check-for-update', (event) => {
autoUpdater.checkForUpdatesAndNotify()
})
autoUpdater.on('update-available', (event) => {
const downloadOpts = {
type: 'info',
buttons: ['YES', 'NO'],
title: i18n.__("electron_translate_3"),
detail: i18n.__("electron_translate_4")
}
dialog.showMessageBox(downloadOpts).then((returnValue) => {
if (returnValue.response === 0) {
autoUpdater.downloadUpdate()
const dl = new Notification({
title: i18n.__("electron_translate_11"),
body: i18n.__("electron_translate_12")
})
dl.show()
} else {
return
}
3 years ago
})
})
1 year ago
autoUpdater.on('update-not-available', (event) => {
const noUpdate = new Notification({
title: 'Checking for update',
body: 'No update available, you are on latest version.'
})
noUpdate.show()
})
autoUpdater.on('download-progress', (progressObj) => {
myWindow.webContents.send('downloadProgress', progressObj)
3 years ago
})
3 years ago
autoUpdater.on('update-downloaded', (event) => {
const dialogOpts = {
type: 'info',
buttons: [i18n.__("electron_translate_5"), i18n.__("electron_translate_6")],
title: i18n.__("electron_translate_7"),
message: i18n.__("electron_translate_8"),
detail: i18n.__("electron_translate_9")
3 years ago
}
dialog.showMessageBox(dialogOpts).then((returnValue) => {
if (returnValue.response === 0) {
autoUpdater.quitAndInstall()
} else {
return
}
})
})
3 years ago
autoUpdater.on('error', (err) => {
const n = new Notification({
title: i18n.__("electron_translate_10"),
3 years ago
body: err
})
n.show()
3 years ago
})
process.on('uncaughtException', function (err) {
log.info("*** WHOOPS TIME ***" + err)
})
}