feat: initialize electron main process, tray icon, and MariaDB operation service

This commit is contained in:
Ümit Tunç
2026-03-30 11:38:31 +03:00
parent a952f0d8dd
commit 83a3ad7162
8 changed files with 108 additions and 7 deletions
+9
View File
@@ -7,7 +7,16 @@ character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci collation-server=utf8mb4_unicode_ci
log-error="{{LOG_FILE}}" log-error="{{LOG_FILE}}"
# Performance Optimizations
max_allowed_packet=1G
innodb_buffer_pool_size=512M
innodb_log_file_size=128M
innodb_flush_log_at_trx_commit=2
innodb_doublewrite=0
innodb_lock_wait_timeout=600
[client] [client]
port={{PORT}} port={{PORT}}
socket="{{SOCKET}}" socket="{{SOCKET}}"
default-character-set=utf8mb4 default-character-set=utf8mb4
max_allowed_packet=1G
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 MiB

After

Width:  |  Height:  |  Size: 4.2 KiB

+16
View File
@@ -56,5 +56,21 @@
"prettier": "^3.3.2", "prettier": "^3.3.2",
"typescript": "^5.5.2", "typescript": "^5.5.2",
"vite": "^5.3.1" "vite": "^5.3.1"
},
"build": {
"appId": "com.multiphp",
"productName": "Multi-PHP",
"directories": {
"output": "dist"
},
"win": {
"icon": "resources/icon.ico"
},
"mac": {
"icon": "resources/icon.png"
},
"linux": {
"icon": "resources/icon.png"
}
} }
} }
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

+28
View File
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Creator: CorelDRAW -->
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="134.816mm" height="134.816mm" version="1.1" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd"
viewBox="0 0 2611.47 2611.47"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xodm="http://www.corel.com/coreldraw/odm/2003">
<defs>
<style type="text/css">
<![CDATA[
.fil0 {fill:none}
.fil2 {fill:#153E5E}
.fil1 {fill:#4A7CA3}
]]>
</style>
</defs>
<g id="Layer_x0020_1">
<metadata id="CorelCorpID_0Corel-Layer"/>
<rect class="fil0" x="-0" y="-0" width="2611.47" height="2611.47"/>
<g id="_2472301098192">
<path class="fil1" d="M1306.48 237.97c194.46,162.17 391.81,273.55 641.12,345.94 43.54,12.64 87.1,24.55 131.37,34.14 31.53,6.83 112.6,16 136.33,25.1 24.03,182.74 4.39,452.05 -32.33,623.08 -20.47,95.35 -44.74,176.01 -74.94,261.64 -41.57,117.85 -126.77,282.1 -204.18,381.09 -12.62,16.14 -23.7,32.32 -36.17,47.9 -51.41,64.29 -144.33,163.58 -206.65,213.76 -15.33,12.34 -30.17,23.69 -47,37.09 -67.56,53.78 -239.27,173.41 -308.59,197.18l-0.05 73.36c0.21,24.23 2.85,55.66 0.64,78.19l131.29 -65.78c154.48,-91.3 238.69,-150.14 366.82,-264.23 9.08,-8.08 14.36,-16.49 23.63,-24.84l96.11 -98.06c295.07,-332.43 429.55,-768.25 436.71,-1213.62 1.12,-69.52 -1.98,-311.75 -21.15,-367.4 -54.71,-9.45 -109.74,-15.42 -163.2,-24.61 -307.75,-52.95 -535.06,-168.26 -770.83,-355.05 -17.48,-13.85 -84.44,-70.37 -96.86,-87.85l-6.35 3.39c9.89,7.57 2.06,-2.77 4.01,9.94l-1.07 77.55c-0.5,29.47 -0.34,63.1 1.33,92.07z"/>
<path class="fil1" d="M1149.94 1391.32l158.69 -2.62c-4.95,24.97 -4.03,120.24 -3.1,154.68 0.24,8.76 0.67,17.14 1.14,25.87 0.5,9.19 0.71,12.68 -4.48,19.7 183.12,-3.59 295.04,-29.36 428.46,-141.13 9.96,-8.34 9.28,-8.64 16.91,-18.77 15.48,-20.54 17.72,-13.7 46.74,-60.06 66.24,-105.83 82.01,-223.22 56.4,-348.15 -15.89,-77.5 -67.88,-134.16 -116.01,-168.87 -54.4,-39.23 -130.81,-63.96 -210.45,-73.45 -46.37,-5.53 -542.39,-9.05 -561.95,-2.83 -1.65,2.24 -2.07,2.35 -3.84,6.71 -1.64,4.05 -1.94,5.53 -2.86,10.05 -1.34,6.56 -2.2,14.95 -3.33,22.57l-50.55 295.78c-14.61,88.01 -51.6,262.22 -59.12,338.98l56.43 -47.25c38.63,-29.48 90.42,-54.48 140.15,-66.85 37.6,-9.35 56.12,-10.17 75.4,-14.6l8.19 -2.6c16.19,-5.57 52.71,-331.28 63.53,-340.73 13.75,-5.94 128.78,-1.87 154.69,-1.85 51.09,0.04 102.6,-2.68 148.12,11.97 177.44,57.09 127.52,316.42 -41.22,377.76 -89.58,32.56 -188.3,15.54 -278.54,20.41 -15.09,0.82 -10.77,-1.75 -19.42,5.29z"/>
<path class="fil2" d="M1306.48 237.97c-1.67,-28.97 -1.83,-62.6 -1.33,-92.07l1.07 -77.55c-1.96,-12.71 5.88,-2.37 -4.01,-9.94 -38.3,31.85 -56.38,54.5 -98,86.5 -35.58,27.36 -67.05,56.05 -106.45,81.05 -44.4,28.17 -53.94,39.48 -113.88,73.77 -175.06,100.13 -345.78,162 -549.16,198.47 -35.53,6.37 -137.56,14.85 -162.44,24.63 -41.54,233.19 -19,588.9 32.74,820.36 27.06,121.04 68.48,229.39 113.07,336.84 32.69,78.78 71.69,156.4 154.22,182.82 47.21,15.11 56.01,5.94 98.65,-0.83 -6.22,-20.64 -55.22,-92.46 -70.54,-121.36 -22.28,-42.02 -41.7,-81.84 -60.98,-126.6 -85.55,-198.66 -129.87,-390.44 -146.35,-610.96 -6.66,-89.1 -11.15,-276.47 4.48,-361.2 45.12,-9.05 92.56,-14.66 136.75,-24.2 269.06,-58.11 514.14,-173.99 725.96,-342.23l46.22 -37.48z"/>
<path class="fil2" d="M1302.2 1588.95c5.19,-7.01 4.98,-10.51 4.48,-19.7 -0.48,-8.73 -0.9,-17.1 -1.14,-25.87 -0.93,-34.44 -1.85,-129.71 3.1,-154.68l-158.69 2.62c-19.34,-10.23 -114.59,16.75 -135.23,25.98 -310.88,138.92 -138.63,409.03 -313.06,505.54 -39.74,21.99 -92.36,23.85 -138.46,9.83 -20.23,-6.15 -40.16,-13.4 -58.15,-22.63 -19.06,-9.77 -34.13,-22.71 -51.45,-31.65 31.82,93.72 107.08,161.93 202.07,185.58 96.19,23.95 224.85,-1 292.9,-68.67 84.32,-83.85 93.08,-145.15 112.91,-268.68 21.51,-134.07 20.89,-145.96 240.73,-137.66z"/>
<path class="fil2" d="M1306.03 2556.45c2.21,-22.53 -0.44,-53.96 -0.64,-78.19l0.05 -73.36c-34.48,-12.8 -113.35,-61.59 -143.36,-80.88 -47.41,-30.47 -88.52,-58.43 -131.95,-91.4 -25.66,-19.48 -100.95,-77.27 -122.52,-100.65 -25.31,-27.43 -12.83,-13.7 -79.21,1.58 -37.71,8.68 -60.66,7.92 -98.94,9.95 3.93,11.6 30.66,36.25 46.3,52.45 30.56,31.64 114.04,100.57 147.58,127.4 88.9,71.13 197.15,138.59 299.43,192.43 24.96,13.14 57.22,32.13 83.26,40.66z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

+12 -5
View File
@@ -8,8 +8,10 @@ let tray: Tray | null = null
let mainWindow: BrowserWindow | null = null let mainWindow: BrowserWindow | null = null
function createTray(): void { function createTray(): void {
// Use a simple colored pixel if no icon is available for now const iconPath = process.platform === 'win32'
const icon = nativeImage.createFromPath(join(__dirname, '../../resources/icon.png')) ? join(__dirname, '../../resources/icon.ico')
: join(__dirname, '../../resources/icon.png')
const icon = nativeImage.createFromPath(iconPath)
tray = new Tray(icon.isEmpty() ? nativeImage.createEmpty() : icon) tray = new Tray(icon.isEmpty() ? nativeImage.createEmpty() : icon)
const contextMenu = Menu.buildFromTemplate([ const contextMenu = Menu.buildFromTemplate([
@@ -17,7 +19,7 @@ function createTray(): void {
{ type: 'separator' }, { type: 'separator' },
{ {
label: 'Göster/Gizle', click: () => { label: 'Göster/Gizle', click: () => {
if (mainWindow) { if (mainWindow && !mainWindow.isDestroyed()) {
if (mainWindow.isVisible()) mainWindow.hide() if (mainWindow.isVisible()) mainWindow.hide()
else mainWindow.show() else mainWindow.show()
} }
@@ -38,7 +40,7 @@ function createTray(): void {
tray.setContextMenu(contextMenu) tray.setContextMenu(contextMenu)
tray.on('double-click', () => { tray.on('double-click', () => {
if (mainWindow) mainWindow.show() if (mainWindow && !mainWindow.isDestroyed()) mainWindow.show()
}) })
} }
@@ -48,6 +50,7 @@ function createWindow(): void {
height: 800, height: 800,
show: false, show: false,
autoHideMenuBar: true, autoHideMenuBar: true,
icon: join(__dirname, '../../resources/icon.png'),
webPreferences: { webPreferences: {
preload: join(__dirname, '../preload/index.js'), preload: join(__dirname, '../preload/index.js'),
sandbox: false sandbox: false
@@ -55,7 +58,11 @@ function createWindow(): void {
}) })
mainWindow.on('ready-to-show', () => { mainWindow.on('ready-to-show', () => {
if (mainWindow) mainWindow.show() if (mainWindow && !mainWindow.isDestroyed()) mainWindow.show()
})
mainWindow.on('closed', () => {
mainWindow = null
}) })
mainWindow.webContents.setWindowOpenHandler((details) => { mainWindow.webContents.setWindowOpenHandler((details) => {
+42 -1
View File
@@ -143,10 +143,48 @@ export class MariaDbOperationService {
// Pipe the file content to stdin // Pipe the file content to stdin
const fileStream = fs.createReadStream(sqlFilePath) const fileStream = fs.createReadStream(sqlFilePath)
// Performance optimizations
child.stdin.write('SET foreign_key_checks = 0;\n')
child.stdin.write('SET unique_checks = 0;\n')
child.stdin.write('SET autocommit = 0;\n')
child.stdin.write('SET sql_log_bin = 0;\n')
fileStream.on('error', (err) => { fileStream.on('error', (err) => {
onProgress?.(`File read error: ${err.message}`) onProgress?.(`File read error: ${err.message}`)
}) })
fileStream.pipe(child.stdin)
fileStream.on('data', (chunk) => {
if (child.stdin.writable) {
try {
child.stdin.write(chunk)
} catch (e: any) {
if (e.code === 'EPIPE') {
onProgress?.(`Warning: EPIPE error encountered. The child process may have closed the pipe early.`)
} else {
throw e
}
}
}
})
fileStream.on('end', () => {
if (child.stdin.writable) {
child.stdin.write('\nCOMMIT;\n')
child.stdin.write('SET foreign_key_checks = 1;\n')
child.stdin.write('SET unique_checks = 1;\n')
child.stdin.write('SET autocommit = 1;\n')
child.stdin.end()
}
})
child.stdin.on('error', (err: any) => {
if (err.code === 'EPIPE') {
onProgress?.(`Notice: Broken pipe (EPIPE). This usually means MariaDB finished or aborted before we finished writing.`)
} else {
onProgress?.(`Stdin error: ${err.message}`)
}
})
child.stdout.on('data', (data) => onProgress?.(data.toString())) child.stdout.on('data', (data) => onProgress?.(data.toString()))
child.stderr.on('data', (data) => onProgress?.(data.toString())) child.stderr.on('data', (data) => onProgress?.(data.toString()))
@@ -199,6 +237,9 @@ export class MariaDbOperationService {
`--host=${config.host}`, `--host=${config.host}`,
`--port=${config.port}`, `--port=${config.port}`,
`--user=${config.rootUser}`, `--user=${config.rootUser}`,
'--quick',
'--single-transaction',
'--max_allowed_packet=1G',
dbName, dbName,
'--routines', '--routines',
'--triggers' '--triggers'