130 lines
3.2 KiB
JavaScript
130 lines
3.2 KiB
JavaScript
/**
|
|
* Preload + Pear polyfill for the PearData GUI under Electron.
|
|
* Runs with contextIsolation: false / nodeIntegration: true so app.js can
|
|
* import HyperDHT packages (pear-electron UI equivalent).
|
|
*/
|
|
'use strict'
|
|
|
|
const { ipcRenderer } = require('electron')
|
|
const path = require('path')
|
|
const fs = require('fs')
|
|
const os = require('os')
|
|
|
|
const cfg = ipcRenderer.sendSync('peardata:get-pear-config') || {}
|
|
const storage =
|
|
cfg.storage ||
|
|
process.env.PEARDATA_STORAGE ||
|
|
path.join(os.homedir(), '.config', 'peardata', 'storage')
|
|
|
|
try {
|
|
fs.mkdirSync(storage, { recursive: true })
|
|
} catch {
|
|
// ignore
|
|
}
|
|
|
|
const teardownHooks = []
|
|
|
|
/** Pear surface used by PearData UI */
|
|
const Pear = {
|
|
config: {
|
|
storage,
|
|
name: cfg.name || 'PearData',
|
|
version: cfg.version || '0.0.0',
|
|
},
|
|
app: {
|
|
storage,
|
|
name: cfg.name || 'PearData',
|
|
},
|
|
exit(code = 0) {
|
|
try {
|
|
ipcRenderer.invoke('peardata:exit', code)
|
|
} catch {
|
|
// ignore
|
|
}
|
|
},
|
|
teardown(fn) {
|
|
if (typeof fn === 'function') teardownHooks.push(fn)
|
|
},
|
|
constructor: {
|
|
IPC: null,
|
|
UI: null,
|
|
CUTOVER: false,
|
|
},
|
|
}
|
|
|
|
globalThis.Pear = Pear
|
|
try {
|
|
window.Pear = Pear
|
|
} catch {
|
|
// ignore
|
|
}
|
|
|
|
// pear-ctrl: platform chrome for frameless / hiddenInset titlebar
|
|
try {
|
|
if (typeof customElements !== 'undefined' && !customElements.get('pear-ctrl')) {
|
|
const platform =
|
|
(cfg && cfg.platform) ||
|
|
(typeof process !== 'undefined' && process.platform) ||
|
|
'darwin'
|
|
|
|
class PearCtrl extends HTMLElement {
|
|
connectedCallback() {
|
|
this.setAttribute('data-platform', platform)
|
|
this.setAttribute('role', 'group')
|
|
this.setAttribute('aria-label', 'Window controls')
|
|
|
|
if (platform === 'darwin') {
|
|
this.replaceChildren()
|
|
return
|
|
}
|
|
|
|
this.replaceChildren()
|
|
this.classList.add('pd-electron-ctrl')
|
|
const mkBtn = (action, label, pathD) => {
|
|
const btn = document.createElement('button')
|
|
btn.type = 'button'
|
|
btn.className = `pd-win-btn pd-win-btn--${action}`
|
|
btn.title = label
|
|
btn.setAttribute('aria-label', label)
|
|
btn.innerHTML = `<svg width="10" height="10" viewBox="0 0 10 10" aria-hidden="true"><path fill="currentColor" d="${pathD}"/></svg>`
|
|
btn.addEventListener('click', (e) => {
|
|
e.preventDefault()
|
|
e.stopPropagation()
|
|
try {
|
|
ipcRenderer.invoke(`peardata:window-${action}`)
|
|
} catch {
|
|
// ignore
|
|
}
|
|
})
|
|
return btn
|
|
}
|
|
this.append(
|
|
mkBtn('minimize', 'Minimize', 'M0 5h10v1H0z'),
|
|
mkBtn('maximize', 'Maximize', 'M1 1h8v8H1V1zm1 1v6h6V2H2z'),
|
|
mkBtn(
|
|
'close',
|
|
'Close',
|
|
'M1.2 0.5L5 4.3 8.8.5l.7.7L5.7 5l3.8 3.8-.7.7L5 5.7 1.2 9.5l-.7-.7L4.3 5 .5 1.2l.7-.7z'
|
|
)
|
|
)
|
|
}
|
|
}
|
|
customElements.define('pear-ctrl', PearCtrl)
|
|
}
|
|
} catch {
|
|
// ignore
|
|
}
|
|
|
|
window.addEventListener('beforeunload', () => {
|
|
for (const fn of teardownHooks) {
|
|
try {
|
|
const r = fn()
|
|
if (r && typeof r.then === 'function') r.catch(() => {})
|
|
} catch {
|
|
// ignore
|
|
}
|
|
}
|
|
})
|
|
|
|
console.log('[peardata] Pear polyfill ready, storage=', storage)
|