diff --git a/.gitignore b/.gitignore index f52b93a..c83c79e 100644 --- a/.gitignore +++ b/.gitignore @@ -91,4 +91,5 @@ typings/ # Electron-Forge out/ old/ -dist/ \ No newline at end of file +dist/ +node_modules diff --git a/electron-builder.yml b/electron-builder.yml index 9268599..cd23df3 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -1,72 +1,77 @@ -appId: com.roboticsacademy.app -productName: RoboticsAcademy -directories: - buildResources: build - -buildDependenciesFromSource: true - -extraResources: - - './splashscreen.html' - - 'resources/**' - - './roboticsacademy.db' -files: - - '!**/.vscode/*' - - '!src/*' - - '!electron.vite.config.{js,ts,mjs,cjs}' - - '!{.eslintignore,.eslintrc.cjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}' - - '!{.env,.env.*,.npmrc,pnpm-lock.yaml}' - - '!{tsconfig.json,tsconfig.node.json,tsconfig.web.json}' -asarUnpack: - - resources/** -win: - executableName: RoboticsAcademy - requestedExecutionLevel: requireAdministrator - target: - - nsis - icon: resources/icons/icon.ico -nsis: - artifactName: ${name}-${version}-setup.${ext} - shortcutName: ${productName} - uninstallDisplayName: ${productName} - installerLanguages: - - en - - es - createDesktopShortcut: true - displayLanguageSelector: true - createStartMenuShortcut: true - allowToChangeInstallationDirectory: true - oneClick: false - perMachine: false - installerIcon: resources/icons/icon.ico - uninstallerIcon: resources/icons/icon.ico - installerHeaderIcon: resources/icons/icon.ico - license: license/license_en_US.txt - -mac: - entitlementsInherit: build/entitlements.mac.plist - extendInfo: - - NSCameraUsageDescription: Application requests access to the device's camera. - - NSMicrophoneUsageDescription: Application requests access to the device's microphone. - - NSDocumentsFolderUsageDescription: Application requests access to the user's Documents folder. - - NSDownloadsFolderUsageDescription: Application requests access to the user's Downloads folder. - notarize: false -dmg: - artifactName: ${name}-${version}.${ext} -linux: - icon: resources/icons/icon.icns - desktop: - Type: 'Application' - Encoding: 'UTF-8' - Name: 'Robotics Academy' - target: - - deb - maintainer: https://jderobot.github.io/RoboticsAcademy/ - category: Utility -appImage: - artifactName: ${name}-${version}.${ext} -npmRebuild: false -publish: - provider: generic - url: -electronDownload: - mirror: +appId: com.roboticsacademy.app +productName: RoboticsAcademy +directories: + buildResources: build + +buildDependenciesFromSource: true + +extraResources: + - './splashscreen.html' + - './updaterScreen.html' + - 'resources/**' + - './roboticsacademy.db' +files: + - '!**/.vscode/*' + - '!src/*' + - '!electron.vite.config.{js,ts,mjs,cjs}' + - '!{.eslintignore,.eslintrc.cjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}' + - '!{.env,.env.*,.npmrc,pnpm-lock.yaml}' + - '!{tsconfig.json,tsconfig.node.json,tsconfig.web.json}' +asarUnpack: + - resources/** +win: + executableName: RoboticsAcademy + requestedExecutionLevel: requireAdministrator + target: + - nsis + icon: resources/icons/icon.ico +nsis: + artifactName: ${name}-${version}-setup.${ext} + shortcutName: ${productName} + uninstallDisplayName: ${productName} + installerLanguages: + - en + - es + createDesktopShortcut: true + displayLanguageSelector: true + createStartMenuShortcut: true + allowToChangeInstallationDirectory: true + oneClick: false + perMachine: false + installerIcon: resources/icons/icon.ico + uninstallerIcon: resources/icons/icon.ico + installerHeaderIcon: resources/icons/icon.ico + license: license/license_en_US.txt + +mac: + entitlementsInherit: build/entitlements.mac.plist + extendInfo: + - NSCameraUsageDescription: Application requests access to the device's camera. + - NSMicrophoneUsageDescription: Application requests access to the device's microphone. + - NSDocumentsFolderUsageDescription: Application requests access to the user's Documents folder. + - NSDownloadsFolderUsageDescription: Application requests access to the user's Downloads folder. + notarize: false +dmg: + artifactName: ${name}-${version}.${ext} +linux: + icon: resources/icons/icon.icns + desktop: + Type: 'Application' + Encoding: 'UTF-8' + Name: 'Robotics Academy' + target: + - deb + maintainer: https://jderobot.github.io/RoboticsAcademy/ + category: Utility +appImage: + artifactName: ${name}-${version}.${ext} +npmRebuild: false +publish: + provider: github + owner: JdeRobot + repo: RoboticsAcademy-Desktop + releaseType: release + private: false + +electronDownload: + mirror: diff --git a/electron.vite.config.1723371720494.mjs b/electron.vite.config.1723371720494.mjs deleted file mode 100644 index c4e21ec..0000000 --- a/electron.vite.config.1723371720494.mjs +++ /dev/null @@ -1,23 +0,0 @@ -// electron.vite.config.ts -import { resolve } from "path"; -import { defineConfig, externalizeDepsPlugin } from "electron-vite"; -import react from "@vitejs/plugin-react"; -var electron_vite_config_default = defineConfig({ - main: { - plugins: [externalizeDepsPlugin()] - }, - preload: { - plugins: [externalizeDepsPlugin()] - }, - renderer: { - resolve: { - alias: { - "@renderer": resolve("src/renderer/src") - } - }, - plugins: [react()] - } -}); -export { - electron_vite_config_default as default -}; diff --git a/electron.vite.config.1724091239149.mjs b/electron.vite.config.1724091239149.mjs deleted file mode 100644 index c4e21ec..0000000 --- a/electron.vite.config.1724091239149.mjs +++ /dev/null @@ -1,23 +0,0 @@ -// electron.vite.config.ts -import { resolve } from "path"; -import { defineConfig, externalizeDepsPlugin } from "electron-vite"; -import react from "@vitejs/plugin-react"; -var electron_vite_config_default = defineConfig({ - main: { - plugins: [externalizeDepsPlugin()] - }, - preload: { - plugins: [externalizeDepsPlugin()] - }, - renderer: { - resolve: { - alias: { - "@renderer": resolve("src/renderer/src") - } - }, - plugins: [react()] - } -}); -export { - electron_vite_config_default as default -}; diff --git a/package.json b/package.json index 1c4cdf8..b45c64d 100644 --- a/package.json +++ b/package.json @@ -1,75 +1,78 @@ -{ - "name": "RoboticsAcademy", - "version": "2.0.0", - "description": "Cross platform Desktop Application for Robotics Academy.", - "main": "./out/main/index.js", - "author": "Robotics Academy", - "contributors": [ - { - "name": "JoseMaria Cañas", - "url": "https://gsyc.urjc.es/jmplaza/" - }, - { - "name": "Apoorv Garg", - "url": "https://apoorvgarg.in/" - }, - { - "name": "Md. Shariar Kabir", - "email": "kabircp08@gmail.com" - } - ], - "homepage": "", - "scripts": { - "format": "prettier --write .", - "lint": "eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix", - "typecheck:node": "tsc --noEmit -p tsconfig.node.json --composite false", - "typecheck:web": "tsc --noEmit -p tsconfig.web.json --composite false", - "typecheck": "npm run typecheck:node && npm run typecheck:web", - "start": "electron-vite preview", - "dev": "electron-vite dev --watch", - "dist": "electron-builder --win", - "build": "npm run typecheck && electron-vite build", - "postinstall": "electron-builder install-app-deps", - "rebuild-sql": "electron-rebuild -f -w sqlite3", - "build:unpack": "npm run build && electron-builder --dir", - "build:win": "npm run build && electron-builder --win", - "build:mac": "electron-vite build && electron-builder --mac", - "build:linux": "electron-vite build && electron-builder --linux" - }, - "dependencies": { - "@electron-toolkit/preload": "^3.0.1", - "@electron-toolkit/utils": "^3.0.0", - "electron-settings": "^4.0.4", - "electron-updater": "^6.2.1", - "node-gyp": "^10.2.0", - "sqlite3": "^5.1.7", - "uuid": "^10.0.0" - }, - "devDependencies": { - "@electron-toolkit/eslint-config-prettier": "^2.0.0", - "@electron-toolkit/eslint-config-ts": "^2.0.0", - "@electron-toolkit/tsconfig": "^1.0.1", - "@types/node": "^22.1.0", - "@types/react": "^18.3.3", - "@types/react-dom": "^18.3.0", - "@vitejs/plugin-react": "^4.3.1", - "autoprefixer": "^10.4.20", - "electron": "^32.1.0", - "electron-builder": "^24.13.3", - "electron-rebuild": "^3.2.9", - "electron-vite": "^2.3.0", - "eslint": "^9.8.0", - "eslint-plugin-react": "^7.35.0", - "flowbite": "^2.5.1", - "flowbite-react": "^0.10.1", - "postcss": "^8.4.41", - "prettier": "^3.3.3", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "tailwindcss": "^3.4.8", - "typescript": "^5.5.4", - "vite": "^5.4.0" - }, - "repository": "https://github.com/codezerro/RoboticsAcademy-Desktop.git", - "license": "MIT" -} +{ + "name": "RoboticsAcademy", + "version": "2.0.0", + "description": "Cross platform Desktop Application for Robotics Academy.", + "main": "./out/main/index.js", + "author": "Robotics Academy", + "contributors": [ + { + "name": "JoseMaria Cañas", + "url": "https://gsyc.urjc.es/jmplaza/" + }, + { + "name": "Apoorv Garg", + "url": "https://apoorvgarg.in/" + }, + { + "name": "Md. Shariar Kabir", + "email": "kabircp08@gmail.com" + } + ], + "homepage": "https://jderobot.github.io/", + "scripts": { + "format": "prettier --write .", + "lint": "eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix", + "typecheck:node": "tsc --noEmit -p tsconfig.node.json --composite false", + "typecheck:web": "tsc --noEmit -p tsconfig.web.json --composite false", + "typecheck": "npm run typecheck:node && npm run typecheck:web", + "start": "electron-vite preview", + "dev": "electron-vite dev --watch", + "dist": "electron-builder --win", + "build": "npm run typecheck && electron-vite build", + "postinstall": "electron-builder install-app-deps", + "rebuild-sql": "electron-rebuild -f -w sqlite3", + "build:unpack": "npm run build && electron-builder --dir", + "build:win": "npm run build && electron-builder --win", + "build:mac": "electron-vite build && electron-builder --mac", + "build:linux": "electron-vite build && electron-builder --linux" + }, + "dependencies": { + "@electron-toolkit/preload": "^3.0.1", + "@electron-toolkit/utils": "^3.0.0", + "electron-settings": "^4.0.4", + "electron-updater": "^6.3.9", + "node-gyp": "^10.2.0", + "sqlite3": "^5.1.7", + "uuid": "^10.0.0" + }, + "devDependencies": { + "@electron-toolkit/eslint-config-prettier": "^2.0.0", + "@electron-toolkit/eslint-config-ts": "^2.0.0", + "@electron-toolkit/tsconfig": "^1.0.1", + "@types/node": "^22.1.0", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "@vitejs/plugin-react": "^4.3.1", + "autoprefixer": "^10.4.20", + "electron": "^32.1.0", + "electron-builder": "^24.13.3", + "electron-rebuild": "^3.2.9", + "electron-vite": "^2.3.0", + "eslint": "^9.8.0", + "eslint-plugin-react": "^7.35.0", + "flowbite": "^2.5.1", + "flowbite-react": "^0.10.1", + "postcss": "^8.4.41", + "prettier": "^3.3.3", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "tailwindcss": "^3.4.8", + "typescript": "^5.5.4", + "vite": "^5.4.0" + }, + "repository": { + "type": "git", + "url": "https://github.com/codezerro/RoboticsAcademy-Desktop" + }, + "license": "MIT" +} diff --git a/roboticsacademy.db b/roboticsacademy.db index f016859..8bd4afb 100644 Binary files a/roboticsacademy.db and b/roboticsacademy.db differ diff --git a/splashscreen.html b/splashscreen.html index 1792be1..effc26e 100644 --- a/splashscreen.html +++ b/splashscreen.html @@ -106,7 +106,7 @@

Robotics Academy

by JdeRobot

-

v2.0.0

+

v2.0.0

diff --git a/src/main/appWindow.ts b/src/main/appWindow.ts new file mode 100644 index 0000000..2741af9 --- /dev/null +++ b/src/main/appWindow.ts @@ -0,0 +1,158 @@ +import { is } from '@electron-toolkit/utils' +import { app, BrowserWindow, shell } from 'electron' +import { join } from 'path' + +export function createSplashWindow(info): BrowserWindow { + const win = new BrowserWindow({ + width: 525, + height: 300, + frame: false, + transparent: true, + alwaysOnTop: true, + webPreferences: { + devTools: !app.isPackaged, + nodeIntegration: false, + webSecurity: true, + sandbox: false, + contextIsolation: true + } + }) + + const splashScreenSrc = app.isPackaged + ? join(process.resourcesPath, 'splashscreen.html') + : join(__dirname, './../../', 'splashscreen.html') + + win.loadFile(splashScreenSrc) + + if (!app.isPackaged) { + // win.webContents.openDevTools() + } else win.webContents.openDevTools = () => {} + + win.webContents.on('did-finish-load', () => { + win.webContents + .executeJavaScript( + ` + const version = document.getElementById('version') + version.textContent = '${info.appVersion}' + ` + ) + .then((result) => { + console.log('Executed in renderer:', result) + }) + .catch(console.error) + }) + + return win +} + +export function createUpdaterWindow(version: string): BrowserWindow { + const win = new BrowserWindow({ + width: 500, + height: 250, + frame: false, + transparent: true, + show: false, + resizable: false, + maximizable: false, + alwaysOnTop: true, + webPreferences: { + preload: join(__dirname, './../preload/index.js'), + devTools: !app.isPackaged, + nodeIntegration: false, + webSecurity: true, + sandbox: false, + contextIsolation: true + } + }) + + const updaterScreenSrc = app.isPackaged + ? join(process.resourcesPath, 'updaterScreen.html') + : join(__dirname, './../../', 'updaterScreen.html') + + win.loadFile(updaterScreenSrc) + + // dev tool + if (!app.isPackaged) { + // win.webContents.openDevTools() + } else win.webContents.openDevTools = () => {} + + win.webContents.on('did-finish-load', () => { + win.webContents + .executeJavaScript( + ` + const version = document.getElementById('update-version') + version.textContent = '${version}' + ` + ) + .then((result) => { + console.log('Executed in renderer:', result) + }) + .catch(console.error) + }) + + return win +} + +export const createWindow = async (): Promise => { + let mainWindow: BrowserWindow | null = + new BrowserWindow({ + width: 1280, + height: 720, + minWidth: 1280, + minHeight: 720, + show: false, + frame: false, + alwaysOnTop: false, + transparent: false, + focusable: true, + icon: join(__dirname, './../../resources/icons/icon.png'), + autoHideMenuBar: true, + webPreferences: { + preload: join(__dirname, '../preload/index.js'), + devTools: !app.isPackaged, + nodeIntegration: false, + webSecurity: true, + sandbox: false, + contextIsolation: true + } + }) || null + + // + mainWindow.webContents.session.webRequest.onHeadersReceived((details, callback) => { + if (details.responseHeaders === undefined) return + callback({ + responseHeaders: Object.fromEntries( + Object.entries(details.responseHeaders).filter( + (header) => !/x-frame-options/i.test(header[0]) + ) + ) + }) + }) + mainWindow.webContents.setWindowOpenHandler((details) => { + shell.openExternal(details.url) + return { action: 'deny' } + }) + + // Load the remote URL for development or the local html file for production. + if (is.dev && process.env['ELECTRON_RENDERER_URL']) { + mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL']) + } else { + mainWindow.loadFile(join(__dirname, '../renderer/index.html')) + } + + // dev tool + if (!app.isPackaged) { + // mainWindow.webContents.openDevTools() + } else mainWindow.webContents.openDevTools = () => {} + + // window resize/close func + mainWindow.on('closed', (_e) => { + mainWindow = null + }) + mainWindow.on('maximize', () => {}) + mainWindow.on('unmaximize', () => {}) + // Event listener for when the window is restored from minimized state + mainWindow.on('restore', () => {}) + + return mainWindow +} diff --git a/src/main/db.ts b/src/main/db.ts index 02e4beb..a1490f8 100644 --- a/src/main/db.ts +++ b/src/main/db.ts @@ -201,7 +201,7 @@ export const insertCommandData = async (db: sqlite3.Database) => { if (err) { console.error('Error creating table: ' + err.message) } else { - console.log('commands Table created or already exists.') + // console.log('commands Table created or already exists.') try { const checkTableExist = await isTableExit(db, `commands`) @@ -248,7 +248,7 @@ export const insertCommandUtilsData = async (db: sqlite3.Database) => { if (err) { console.error('Error creating table: ' + err.message) } else { - console.log('commands_utils Table created or already exists.') + // console.log('commands_utils Table created or already exists.') try { const checkTableExist = await isTableExit(db, `commands_utils`) diff --git a/src/main/index.ts b/src/main/index.ts index 1120383..2062c77 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -2,6 +2,7 @@ import { app, BrowserWindow, ipcMain, IpcMainInvokeEvent, shell } from 'electron import { join } from 'path' import { electronApp, optimizer, is } from '@electron-toolkit/utils' import { Database } from 'sqlite3' +import { autoUpdater } from 'electron-updater' import { AllCommandConfigureInterface, @@ -29,93 +30,29 @@ import { updateCommands, updateCommandUtils } from './db' +import { createSplashWindow, createUpdaterWindow, createWindow } from './appWindow' const isMac = process.platform === 'darwin' let mainWindow: BrowserWindow | null = null +let updaterWindow: BrowserWindow | null = null +const appVersion = `v${app.getVersion()}` + +// disable auto-update download +autoUpdater.autoDownload = false // connected to database export const db: Database = dbInit() -// splash screen -function createSplashWindow(): BrowserWindow { - const win = new BrowserWindow({ - width: 525, - height: 300, - frame: false, - transparent: true, - alwaysOnTop: true - }) - - const splashScreenSrc = app.isPackaged - ? join(process.resourcesPath, 'splashscreen.html') - : join(__dirname, './../../', 'splashscreen.html') - - win.loadFile(splashScreenSrc) - return win -} - -// main window -const createWindow = async (): Promise => { - mainWindow = new BrowserWindow({ - width: 1280, - height: 720, - minWidth: 1280, - minHeight: 720, - show: false, - frame: false, - alwaysOnTop: false, - transparent: false, - focusable: true, - icon: join(__dirname, './../../resources/icons/icon.png'), - autoHideMenuBar: true, - webPreferences: { - preload: join(__dirname, '../preload/index.js'), - nodeIntegration: false, - webSecurity: true, - sandbox: false, - contextIsolation: true - } - }) - - // - mainWindow.webContents.session.webRequest.onHeadersReceived((details, callback) => { - if (details.responseHeaders === undefined) return - callback({ - responseHeaders: Object.fromEntries( - Object.entries(details.responseHeaders).filter( - (header) => !/x-frame-options/i.test(header[0]) - ) - ) - }) - }) - mainWindow.webContents.setWindowOpenHandler((details) => { - shell.openExternal(details.url) - return { action: 'deny' } - }) - - // Load the remote URL for development or the local html file for production. - if (is.dev && process.env['ELECTRON_RENDERER_URL']) { - mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL']) - } else { - mainWindow.loadFile(join(__dirname, '../renderer/index.html')) - } - - // window resize/close func - mainWindow.on('closed', (_e) => { - mainWindow = null - }) - mainWindow.on('maximize', () => {}) - mainWindow.on('unmaximize', () => {}) - // Event listener for when the window is restored from minimized state - mainWindow.on('restore', () => {}) - - return mainWindow -} - app.whenReady().then(async () => { // disable http-cache app.commandLine.appendSwitch('disable-http-cache') + // check update + try { + autoUpdater.checkForUpdates() + } catch (error) { + console.log(error) + } //Store data await insertCommandData(db) await insertCommandUtilsData(db) @@ -133,6 +70,23 @@ app.whenReady().then(async () => { }) //* IPC COMMUNICATION + //@ Utils + // get api version + ipcMain.handle('app:APP_VERSION', async (_event: IpcMainInvokeEvent) => { + try { + return { + status: ResponseStatus.SUCCESS, + data: `${app.getVersion()}`, + msg: [] + } + } catch (error: any) { + return { + status: ResponseStatus.SUCCESS, + data: null, + msg: ['something went wrong!', `${error.message}`] + } + } + }) //@ Stopping Docker RADI ipcMain.handle('docker:CHECK_RADI_RUNNING', async (_event: IpcMainInvokeEvent) => { try { @@ -167,13 +121,15 @@ app.whenReady().then(async () => { const res: ResponeInterface = await stopDockerRADIContainer() return res } catch (error) { - return { status: false, msg: ['something went wrong!'] } + return { status: ResponseStatus.ERROR, msg: ['something went wrong!'] } } }) //* App Window Resize // minimize the window ipcMain.on('app_window:MINIMIZE', (_event) => { + if (mainWindow === null || mainWindow === undefined) return + if (!mainWindow?.isMinimized()) { mainWindow?.minimize() } @@ -346,15 +302,34 @@ app.whenReady().then(async () => { } } ) + + // Updater Window + ipcMain.handle('updater:OPEN_LINK', (_event, url: string) => { + try { + shell.openExternal(url) + } catch (error) { + console.log(error) + } + }) + ipcMain.handle('updater:CLOSE_WINDOW', (_event) => { + try { + if (updaterWindow != null) updaterWindow.destroy() + } catch (error) {} + }) //@ Disappering splash screen and show main screen after 3 seconds. try { - const splashScreen: BrowserWindow = createSplashWindow() - const mainScreen: BrowserWindow = await createWindow() + const splashScreen: BrowserWindow = createSplashWindow({ appVersion }) + // const mainScreen: BrowserWindow = await createWindow() + + mainWindow = await createWindow() + // updaterWindow.show() - mainScreen.once('ready-to-show', () => { + mainWindow?.once('ready-to-show', () => { setTimeout( () => { - mainScreen.show() + // updaterWindow = createUpdaterWindow('2.0.1') + // updaterWindow.show() + mainWindow?.show() splashScreen.destroy() }, app.isPackaged ? 3000 : 0 @@ -392,3 +367,11 @@ app.on('window-all-closed', (_e) => { app.quit() } }) + +// Auto Updater +autoUpdater.on('update-available', (info) => { + updaterWindow = createUpdaterWindow(info.version) + setTimeout(() => { + updaterWindow?.show() + }, 10 * 1000) +}) diff --git a/src/preload/index.d.ts b/src/preload/index.d.ts index f168fd6..fe7d0d2 100644 --- a/src/preload/index.d.ts +++ b/src/preload/index.d.ts @@ -1,7 +1,14 @@ import { PortsInterface } from './../renderer/src/utils/interfaces' import { ElectronAPI } from '@electron-toolkit/preload' -import { AllCommandConfigureInterface, DatabaseFetching } from './../main/interfaces' +import { + AllCommandConfigureInterface, + DatabaseFetching, + ResponeInterface +} from './../main/interfaces' interface ApiInterface { + // Util + getAppVersion: () => Promise + // Docker checkDockerAvailability: () => Promise checkDockerRADIAvailability: () => Promise startDockerRADIContainer: () => Promise @@ -31,10 +38,14 @@ interface ApiInterface { ) => Promise> //! DELETE deleteCommandConfig: (id: number) => Promise> + + // updater-window + updaterWindowOpenLink: (url: string) => void + updaterWindowClose: () => void } + declare global { interface Window { - electron: ElectronAPI api: ApiInterface } } diff --git a/src/preload/index.ts b/src/preload/index.ts index f7d9891..941ace2 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -9,6 +9,9 @@ import { // Custom APIs for renderer const api = { + // Utils + getAppVersion: (): Promise => ipcRenderer.invoke('app:APP_VERSION'), + // Docker checkDockerAvailability: (): Promise => ipcRenderer.invoke('docker:CHECK_AVAILABILITY'), checkDockerRADIAvailability: (): Promise => @@ -48,7 +51,11 @@ const api = { ipcRenderer.invoke('database:UPDATE_COMMAND_UTILS', id, image), //! DELETE deleteCommandConfig: (id: number): Promise> => - ipcRenderer.invoke('database:DELETE_COMMAND_CONFIG', id) + ipcRenderer.invoke('database:DELETE_COMMAND_CONFIG', id), + + // Updater Window + updaterWindowOpenLink: (url: string) => ipcRenderer.invoke('updater:OPEN_LINK', url), + updaterWindowClose: () => ipcRenderer.invoke('updater:CLOSE_WINDOW') } // Use `contextBridge` APIs to expose Electron APIs to @@ -56,14 +63,12 @@ const api = { // just add to the DOM global. if (process.contextIsolated) { try { - contextBridge.exposeInMainWorld('electron', electronAPI) contextBridge.exposeInMainWorld('api', api) } catch (error) { console.error(error) } } else { // @ts-ignore (define in dts) - window.electron = electronAPI // @ts-ignore (define in dts) window.api = api } diff --git a/src/renderer/src/components/startscreenview/StartScreenButtons.tsx b/src/renderer/src/components/startscreenview/StartScreenButtons.tsx index 1cc16b1..56816f1 100644 --- a/src/renderer/src/components/startscreenview/StartScreenButtons.tsx +++ b/src/renderer/src/components/startscreenview/StartScreenButtons.tsx @@ -4,8 +4,9 @@ import { RightArrowIcon, BackIcon, PowerIcon, GameConsoleIcon, PlayIcon } from ' import Loader from '../utlits/Loader' import ButtonWrapper from '../buttons/ButtonWrapper' import styles from '../../assets/styles/styles' -import { ActionEnums, ButtonEnums, ScreenStateEnums } from '@renderer/utils/enums' +import { ActionEnums, ButtonEnums, ResponseStatus, ScreenStateEnums } from '@renderer/utils/enums' import { ReducerActionTypes } from '@renderer/utils/types' +import { ResponeInterface } from '@renderer/utils/interfaces' interface StartScrrenButtonsInterface { buttonState: string dispatch: Dispatch @@ -27,9 +28,9 @@ const StartScreenButtons: FC = ({ setIsStopping(true) try { - const res: { status: boolean; msg: string[] } = await window.api.stopDockerRADIContainer() + const res: ResponeInterface = await window.api.stopDockerRADIContainer() - if (res.status) { + if (res.status == ResponseStatus.SUCCESS) { dispatch({ type: ActionEnums.CHANGE_SCREEN, payload: { diff --git a/src/renderer/src/components/utlits/TopBar.tsx b/src/renderer/src/components/utlits/TopBar.tsx index a68a908..2ed1aba 100644 --- a/src/renderer/src/components/utlits/TopBar.tsx +++ b/src/renderer/src/components/utlits/TopBar.tsx @@ -1,10 +1,10 @@ +import { Dispatch, FC, SetStateAction, useState } from 'react' import { WindowMinIcon, WindowMaximizeIcon, WindowCloseIcon, WindowUnMaximizeIcon } from '@renderer/assets/icons/Icons' -import { Dispatch, FC, SetStateAction, useState } from 'react' import PropTypes from 'prop-types' import { ResponseStatus } from '@renderer/utils/enums' import { Logo } from '@renderer/assets' diff --git a/updaterScreen.html b/updaterScreen.html new file mode 100644 index 0000000..ad55f38 --- /dev/null +++ b/updaterScreen.html @@ -0,0 +1,310 @@ + + + + + + Robotics Academy + + + + +
+ +
+
+ + Robotics Academy Desktop Update Available +
+
+ + + +
+
+ +
+ +
+ + + +
+ +
+

A new version of Robotics Academy Desktop Available.

+

Do you want to download version 2.0.1 ?

+

Version on your system 2.0.0

+
+
+ +
+ +
Yes
+ +
No
+
+ + +
+ + + + diff --git a/yarn.lock b/yarn.lock index dce3072..0e77d3a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1462,18 +1462,18 @@ buffer@^5.1.0, buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" -builder-util-runtime@9.2.4: - version "9.2.4" - resolved "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz" - integrity sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA== +builder-util-runtime@9.2.10: + version "9.2.10" + resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-9.2.10.tgz#a0f7d9e214158402e78b74a745c8d9f870c604bc" + integrity sha512-6p/gfG1RJSQeIbz8TK5aPNkoztgY1q5TgmGFMAXcY8itsGW6Y2ld1ALsZ5UJn8rog7hKF3zHx5iQbNQ8uLcRlw== dependencies: debug "^4.3.4" sax "^1.2.4" -builder-util-runtime@9.2.5: - version "9.2.5" - resolved "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.5.tgz" - integrity sha512-HjIDfhvqx/8B3TDN4GbABQcgpewTU4LMRTQPkVpKYV3lsuxEJoIfvg09GyWTNmfVNSUAYf+fbTN//JX4TH20pg== +builder-util-runtime@9.2.4: + version "9.2.4" + resolved "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz" + integrity sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA== dependencies: debug "^4.3.4" sax "^1.2.4" @@ -2085,12 +2085,12 @@ electron-to-chromium@^1.5.4: resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.22.tgz" integrity sha512-tKYm5YHPU1djz0O+CGJ+oJIvimtsCcwR2Z9w7Skh08lUdyzXY5djods3q+z2JkWdb7tCcmM//eVavSRAiaPRNg== -electron-updater@^6.2.1: - version "6.3.4" - resolved "https://registry.npmjs.org/electron-updater/-/electron-updater-6.3.4.tgz" - integrity sha512-uZUo7p1Y53G4tl6Cgw07X1yF8Jlz6zhaL7CQJDZ1fVVkOaBfE2cWtx80avwDVi8jHp+I/FWawrMgTAeCCNIfAg== +electron-updater@^6.3.9: + version "6.3.9" + resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-6.3.9.tgz#e1e7f155624c58e6f3760f376c3a584028165ec4" + integrity sha512-2PJNONi+iBidkoC5D1nzT9XqsE8Q1X28Fn6xRQhO3YX8qRRyJ3mkV4F1aQsuRnYPqq6Hw+E51y27W75WgDoofw== dependencies: - builder-util-runtime "9.2.5" + builder-util-runtime "9.2.10" fs-extra "^10.1.0" js-yaml "^4.1.0" lazy-val "^1.0.5"