feat: new package installler
This commit is contained in:
parent
c7e6bff6a2
commit
7a029d1595
8 changed files with 231 additions and 25 deletions
|
@ -2,11 +2,13 @@ const { app, BrowserWindow, ipcMain, dialog } = require('electron')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const pty = require("node-pty");
|
const pty = require("node-pty");
|
||||||
|
|
||||||
var mainWindow, terminalWindow, ptyProcess
|
var mainWindow, terminalWindow, packageWindow, ptyProcess
|
||||||
|
|
||||||
app.commandLine.appendSwitch('enable-transparent-visuals');
|
app.commandLine.appendSwitch('enable-transparent-visuals');
|
||||||
app.disableHardwareAcceleration();
|
app.disableHardwareAcceleration();
|
||||||
|
|
||||||
|
require('@electron/remote/main').initialize()
|
||||||
|
|
||||||
function createWindow() {
|
function createWindow() {
|
||||||
mainWindow = new BrowserWindow({
|
mainWindow = new BrowserWindow({
|
||||||
minWidth: 1000,
|
minWidth: 1000,
|
||||||
|
@ -30,7 +32,7 @@ function createWindow() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function createTerminalWindow() {
|
function createTerminalWindow() {
|
||||||
terminalWindow = new BrowserWindow({
|
let t_window_settings = {
|
||||||
minWidth: 800,
|
minWidth: 800,
|
||||||
minHeight: 600,
|
minHeight: 600,
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
|
@ -40,13 +42,43 @@ function createTerminalWindow() {
|
||||||
},
|
},
|
||||||
autoHideMenuBar: true,
|
autoHideMenuBar: true,
|
||||||
show: false
|
show: false
|
||||||
})
|
}
|
||||||
|
|
||||||
|
if (process.argv.length > 2) {
|
||||||
|
if (process.argv[2] == 'package') {
|
||||||
|
t_window_settings['frame'] = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
terminalWindow = new BrowserWindow(t_window_settings)
|
||||||
|
|
||||||
terminalWindow.loadFile('src/pages/terminal.html')
|
terminalWindow.loadFile('src/pages/terminal.html')
|
||||||
|
|
||||||
// terminalWindow.setMenu(null)
|
// terminalWindow.setMenu(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createPackageWindow() {
|
||||||
|
packageWindow = new BrowserWindow({
|
||||||
|
minWidth: 450,
|
||||||
|
minHeight: 450,
|
||||||
|
width: 450,
|
||||||
|
height: 450,
|
||||||
|
webPreferences: {
|
||||||
|
nodeIntegration: true,
|
||||||
|
contextIsolation: false,
|
||||||
|
enableRemoteModule: true,
|
||||||
|
sandbox: false
|
||||||
|
},
|
||||||
|
autoHideMenuBar: true
|
||||||
|
})
|
||||||
|
|
||||||
|
packageWindow.loadFile('src/package-installer.html')
|
||||||
|
|
||||||
|
require("@electron/remote/main").enable(packageWindow.webContents)
|
||||||
|
|
||||||
|
// packageWindow.setMenu(null)
|
||||||
|
}
|
||||||
|
|
||||||
function loadTerminalWindow(title, cmd) {
|
function loadTerminalWindow(title, cmd) {
|
||||||
if (terminalWindow.isDestroyed()) {
|
if (terminalWindow.isDestroyed()) {
|
||||||
createTerminalWindow()
|
createTerminalWindow()
|
||||||
|
@ -98,6 +130,8 @@ function loadTerminalWindow(title, cmd) {
|
||||||
ptyProcess.destroy()
|
ptyProcess.destroy()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
} else if (terminalWindow.getTitle().startsWith('Package installation')) {
|
||||||
|
e.preventDefault()
|
||||||
} else {
|
} else {
|
||||||
terminalWindow.hide()
|
terminalWindow.hide()
|
||||||
ptyProcess.destroy()
|
ptyProcess.destroy()
|
||||||
|
@ -128,6 +162,8 @@ function loadTerminalWindow(title, cmd) {
|
||||||
terminalWindow.hide()
|
terminalWindow.hide()
|
||||||
if (title.startsWith('Creating container: ')) {
|
if (title.startsWith('Creating container: ')) {
|
||||||
mainWindow.webContents.send("container-created")
|
mainWindow.webContents.send("container-created")
|
||||||
|
} else if (title.startsWith('Package installation')) {
|
||||||
|
packageWindow.webContents.send("installation-complete")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -142,18 +178,21 @@ function loadTerminalWindow(title, cmd) {
|
||||||
app.whenReady().then(() => {
|
app.whenReady().then(() => {
|
||||||
app.allowRendererProcessReuse = false
|
app.allowRendererProcessReuse = false
|
||||||
|
|
||||||
setTimeout(() => {
|
if (process.argv.length > 2) {
|
||||||
createWindow();
|
if (process.argv[2] == 'package') {
|
||||||
}, 1000);
|
createPackageWindow()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setTimeout(() => {
|
||||||
|
createWindow()
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
createTerminalWindow()
|
createTerminalWindow()
|
||||||
|
|
||||||
ipcMain.on('create-term', (event, data) => {
|
ipcMain.on('create-term', (event, data) => {
|
||||||
loadTerminalWindow(data['title'], data['cmd'])
|
loadTerminalWindow(data['title'], data['cmd'])
|
||||||
})
|
})
|
||||||
|
|
||||||
app.on('activate', () => {
|
|
||||||
if (BrowserWindow.getAllWindows().length === 0) createWindow()
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
"dist": "electron-builder"
|
"dist": "electron-builder"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@electron/remote": "^2.0.9",
|
"@electron/remote": "^2.0.10",
|
||||||
"@types/jquery": "^3.5.16",
|
"@types/jquery": "^3.5.16",
|
||||||
"jquery": "^3.6.3",
|
"jquery": "^3.6.3",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
|
@ -26,15 +26,17 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"electron": "^23.0.0",
|
"electron": "^23.0.0",
|
||||||
"electron-icon-maker": "^0.0.5",
|
"electron-builder": "^23.6.0",
|
||||||
"electron-builder": "^23.6.0"
|
"electron-icon-maker": "^0.0.5"
|
||||||
},
|
},
|
||||||
"build": {
|
"build": {
|
||||||
"appId": "org.blend.settings",
|
"appId": "org.blend.settings",
|
||||||
"productName": "blendOS Settings",
|
"productName": "blendOS Settings",
|
||||||
"asar": true,
|
"asar": true,
|
||||||
"linux": {
|
"linux": {
|
||||||
"target": ["tar.gz"],
|
"target": [
|
||||||
|
"tar.gz"
|
||||||
|
],
|
||||||
"category": "System",
|
"category": "System",
|
||||||
"icon": "icons/png",
|
"icon": "icons/png",
|
||||||
"maintainer": "Rudra Saraswat"
|
"maintainer": "Rudra Saraswat"
|
||||||
|
|
|
@ -4,15 +4,7 @@
|
||||||
<title>Settings</title>
|
<title>Settings</title>
|
||||||
|
|
||||||
<!-- Import bootstrap v5.0. -->
|
<!-- Import bootstrap v5.0. -->
|
||||||
<link href="external/css/bootstrap.min.css" rel="stylesheet">
|
<link href="external/css/bootstrap.min.css" rel="stylesheet">f
|
||||||
|
|
||||||
<!-- Import common styling. -->
|
|
||||||
<link href="internal/css/common.css" rel="stylesheet">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body style="height: 100%;">
|
|
||||||
<br>
|
|
||||||
<div class="topnav">
|
|
||||||
<div class="btn-group" id="settings-tabs" role="group" aria-label="Stores">
|
<div class="btn-group" id="settings-tabs" role="group" aria-label="Stores">
|
||||||
<button class="btn btn-outline-light active shadow-none" id="containers-button" onclick="page('containers')">Linux
|
<button class="btn btn-outline-light active shadow-none" id="containers-button" onclick="page('containers')">Linux
|
||||||
Containers</button>
|
Containers</button>
|
||||||
|
@ -25,7 +17,7 @@
|
||||||
<!-- Import bootstrap JS bundle. -->
|
<!-- Import bootstrap JS bundle. -->
|
||||||
<script src="external/js/bootstrap.bundle.min.js"></script>
|
<script src="external/js/bootstrap.bundle.min.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const Sortable = require('sortablejs')
|
const Sortable = require('sortablejs')
|
||||||
const child_process = require('child_process')
|
const child_process = require('child_process')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
|
|
|
@ -121,7 +121,7 @@ function waydroid_open_settings() {
|
||||||
require('child_process').spawn('waydroid', ['app', 'launch', 'com.android.settings'])
|
require('child_process').spawn('waydroid', ['app', 'launch', 'com.android.settings'])
|
||||||
}
|
}
|
||||||
|
|
||||||
require('fs').stat('/var/lib/waydroid', (err, stat) => {
|
require('fs').stat('/var/lib/waydroid/waydroid.prop', (err, stat) => {
|
||||||
if (err == null) {
|
if (err == null) {
|
||||||
document.getElementById('waydroid-initialize-settings').classList.add('d-none')
|
document.getElementById('waydroid-initialize-settings').classList.add('d-none')
|
||||||
document.getElementById('waydroid-initialized-settings').classList.remove('d-none')
|
document.getElementById('waydroid-initialized-settings').classList.remove('d-none')
|
||||||
|
|
170
blend-settings/src/package-installer.html
Normal file
170
blend-settings/src/package-installer.html
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Package Installer</title>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
user-select: none !important;
|
||||||
|
-webkit-user-drag: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
head,
|
||||||
|
body {
|
||||||
|
background-color: #EBEBEB;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-family: 'Cantarell';
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding {
|
||||||
|
margin: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-weight: 900;
|
||||||
|
font-size: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
background-color: #3584E4;
|
||||||
|
border-style: none;
|
||||||
|
border-radius: 50px;
|
||||||
|
color: white;
|
||||||
|
font-family: 'Cantarell';
|
||||||
|
font-weight: 600;
|
||||||
|
padding: 15px 25px 15px 25px;
|
||||||
|
font-size: 20px;
|
||||||
|
|
||||||
|
transition: 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:disabled {
|
||||||
|
background-color: #619cdf;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0 8px 0 8px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 1.05rem;
|
||||||
|
line-height: 150%;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-color: #3271be;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="center">
|
||||||
|
<h1>Package Installer</h1>
|
||||||
|
|
||||||
|
<div class="padding"></div>
|
||||||
|
|
||||||
|
<img id="packaging-format" width="120px">
|
||||||
|
|
||||||
|
<div class="padding"></div>
|
||||||
|
|
||||||
|
<button id="install-button" onclick="install_package()">Install package</button>
|
||||||
|
|
||||||
|
<div class="padding"></div>
|
||||||
|
|
||||||
|
<select id="source_select"></select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const ipc = require('electron').ipcRenderer
|
||||||
|
|
||||||
|
package_name = require('path').basename(require('@electron/remote').process.argv[3])
|
||||||
|
package_type = 'deb'
|
||||||
|
|
||||||
|
if (package_name.endsWith('.deb')) {
|
||||||
|
document.getElementById('packaging-format').src = '../static/DEB.svg'
|
||||||
|
package_type = 'deb'
|
||||||
|
|
||||||
|
document.getElementById('source_select').innerHTML = `
|
||||||
|
<option>Debian</option>
|
||||||
|
<option>Ubuntu 23.04</option>
|
||||||
|
<option>Ubuntu 22.04</option>
|
||||||
|
<option>Kali Linux</option>
|
||||||
|
<option>Neurodebian Bookworm</option>
|
||||||
|
`
|
||||||
|
} else if (package_name.endsWith('.rpm')) {
|
||||||
|
document.getElementById('packaging-format').src = '../static/RPM.svg'
|
||||||
|
package_type = 'rpm'
|
||||||
|
document.getElementById('source_select').innerHTML = `
|
||||||
|
<option>Fedora 38</option>
|
||||||
|
<option>AlmaLinux 9</option>
|
||||||
|
<option>Rocky Linux</option>
|
||||||
|
`
|
||||||
|
} else if (package_name.endsWith('.apk')) {
|
||||||
|
document.getElementById('packaging-format').src = '../static/APK.svg'
|
||||||
|
package_type = 'apk'
|
||||||
|
document.getElementById('source_select').outerHTML = ''
|
||||||
|
|
||||||
|
require('fs').stat('/var/lib/waydroid/waydroid.prop', (err, stat) => {
|
||||||
|
if (err != null) {
|
||||||
|
document.getElementById('install-button').outerHTML = "<p>You'll need to initialize Android app support from the <b>blendOS Settings</b> app first.</p>"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else if (package_name.includes('.pkg.tar')) {
|
||||||
|
document.getElementById('packaging-format').src = '../static/PKG.svg'
|
||||||
|
package_type = 'pkg'
|
||||||
|
document.getElementById('source_select').innerHTML = `
|
||||||
|
<option>Arch</option>
|
||||||
|
<option>Crystal Linux</option>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
function install_package() {
|
||||||
|
if (package_type == 'apk') {
|
||||||
|
document.getElementById('install-button').disabled = true
|
||||||
|
require('child_process').spawnSync('waydroid', ['app', 'install', package_name])
|
||||||
|
document.getElementById('install-button').innerHTML = 'Installed'
|
||||||
|
} else {
|
||||||
|
package_source = document.getElementById('source_select').options[document.getElementById('source_select').selectedIndex].text.toLowerCase().replace(' ', '-')
|
||||||
|
timestamp = Math.floor(new Date().getTime() / 1000)
|
||||||
|
install_dir = `${require('os').homedir()}/.cache/package-installer/${timestamp}`
|
||||||
|
require('child_process').spawnSync('mkdir', ['-p', install_dir])
|
||||||
|
require('child_process').spawnSync('cp', [require('@electron/remote').process.argv[3], install_dir])
|
||||||
|
install_command = ''
|
||||||
|
if (package_type == 'deb') {
|
||||||
|
install_command = `apt install -y ${install_dir}/${package_name}`
|
||||||
|
} else if (package_type == 'rpm') {
|
||||||
|
install_command = `dnf install -y ${install_dir}/${package_name}`
|
||||||
|
} else if (package_type == 'pkg') {
|
||||||
|
install_command = `pacman -U --noconfirm ${install_dir}/${package_name}`
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('install-button').disabled = true
|
||||||
|
|
||||||
|
if (!require('child_process').spawnSync('podman', ['container', 'exists', package_source]).status) {
|
||||||
|
ipc.send("create-term", { 'title': `Package installation`, 'cmd': `sudo.${package_source} ${install_command} && echo -e '\\nInstallation was successful.' || echo -e '\\nInstallation was unsuccessful.'; sleep 5` });
|
||||||
|
} else {
|
||||||
|
ipc.send("create-term", { 'title': `Package installation`, 'cmd': `blend create-container -cn ${package_source} -d ${package_source}; (sudo.${package_source} ${install_command} && echo -e '\\nInstallation was successful.' || echo -e '\\nInstallation was unsuccessful.'; sleep 5)` });
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('install-button').innerHTML = 'Installing'
|
||||||
|
|
||||||
|
ipc.on('installation-complete', () => {
|
||||||
|
document.getElementById('install-button').innerHTML = 'Installed'
|
||||||
|
})
|
||||||
|
require('child_process').spawnSync('rm', ['-rf', install_dir])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
1
blend-settings/static/APK.svg
Normal file
1
blend-settings/static/APK.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 7.9 KiB |
1
blend-settings/static/DEB.svg
Normal file
1
blend-settings/static/DEB.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 8 KiB |
1
blend-settings/static/RPM.svg
Normal file
1
blend-settings/static/RPM.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 17 KiB |
Loading…
Reference in a new issue