hmgr 0.0.21 → 0.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/gui/main.js +56 -22
- package/dist/gui/selbst-update.js +31 -0
- package/package.json +1 -1
package/dist/gui/main.js
CHANGED
|
@@ -13,7 +13,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
13
13
|
import { bauen, umgebungLesen } from "../cli/main.js";
|
|
14
14
|
import { quelleAlsText, quelleAusText } from "../adapter/quelle-text.js";
|
|
15
15
|
import { paketVersion } from "../adapter/paket-version.js";
|
|
16
|
-
import { infoPlistPfad, neuereVersionAufPlatte } from "./selbst-update.js";
|
|
16
|
+
import { infoPlistPfad, MeldungsPuffer, neuereVersionAufPlatte } from "./selbst-update.js";
|
|
17
17
|
import { quelleName, quelleSchluessel } from "../kern/modell.js";
|
|
18
18
|
import { kannProfile } from "../ports/harness.js";
|
|
19
19
|
import { iconFuerQuelle } from "./icons.js";
|
|
@@ -28,6 +28,8 @@ const smoketest = process.env.HMGR_GUI_SMOKETEST === '1';
|
|
|
28
28
|
// E84 Teil 1: Pfad eines im Fixture noch unbekannten Verzeichnisses, das der Smoke-Lauf per Dialog
|
|
29
29
|
// hinzufügt, um den Sprung zur neuen Karte zu belegen. Nur zur Konstruktionszeit des DOM-Auszug-
|
|
30
30
|
// Skripts gelesen (Node-Seite), nicht zur Laufzeit im Renderer.
|
|
31
|
+
/** E90-Nachtrag: Smoke-Lauf, in dem die Platten-Erkennung schon vor dem Laden der Seite feuert. */
|
|
32
|
+
const smoketestFrueh = process.env.HMGR_GUI_SMOKE_FRUEH === '1';
|
|
31
33
|
const smoketestNeuesVerzeichnis = process.env.HMGR_SMOKETEST_NEUES_VERZEICHNIS ?? '';
|
|
32
34
|
/**
|
|
33
35
|
* Nur eine hmgr-Instanz je Nutzer (E67). Grund: zwei laufende Fenster schrieben nacheinander auf
|
|
@@ -507,6 +509,9 @@ function fensterOeffnen() {
|
|
|
507
509
|
sandbox: true,
|
|
508
510
|
},
|
|
509
511
|
});
|
|
512
|
+
meldungsPuffer.bereitAbmelden();
|
|
513
|
+
hauptfenster.webContents.on('did-start-loading', () => meldungsPuffer.bereitAbmelden());
|
|
514
|
+
hauptfenster.webContents.on('did-finish-load', () => meldungsPuffer.bereitSetzen());
|
|
510
515
|
hauptfenster.on('closed', () => {
|
|
511
516
|
hauptfenster = null;
|
|
512
517
|
zuletztGemeldeteGuiVersion = null;
|
|
@@ -519,7 +524,21 @@ function fensterOeffnen() {
|
|
|
519
524
|
console.log(`[renderer] ${event.message}`);
|
|
520
525
|
});
|
|
521
526
|
// Nur für den Smoke-Test (scripts/gui-smoke-test.ts): ein DOM-Auszug im Log, danach Ende.
|
|
522
|
-
if (smoketest) {
|
|
527
|
+
if (smoketest && smoketestFrueh) {
|
|
528
|
+
// E90-Nachtrag: die Platten-Erkennung feuert schon vor dem Laden der Seite (direkt nach der
|
|
529
|
+
// Fenstererzeugung); die Meldung muss trotzdem ankommen. Kein großer DOM-Auszug, nur das Modal.
|
|
530
|
+
const fenster = hauptfenster;
|
|
531
|
+
plattenVersionPruefen(true);
|
|
532
|
+
fenster.webContents.once('did-finish-load', () => {
|
|
533
|
+
setTimeout(() => {
|
|
534
|
+
void fenster.webContents
|
|
535
|
+
.executeJavaScript(NEUSTART_AUSZUG_SKRIPT)
|
|
536
|
+
.then((auszug) => console.log(`[smoke] Neustart-Modal früh: ${String(auszug)}`))
|
|
537
|
+
.finally(() => app.quit());
|
|
538
|
+
}, 1500);
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
if (smoketest && !smoketestFrueh) {
|
|
523
542
|
const fenster = hauptfenster;
|
|
524
543
|
fenster.webContents.once('did-finish-load', () => {
|
|
525
544
|
setTimeout(() => {
|
|
@@ -1218,26 +1237,12 @@ function fensterOeffnen() {
|
|
|
1218
1237
|
.then(async () => {
|
|
1219
1238
|
if (process.env.HMGR_GUI_SMOKE_PLATTENVERSION === undefined)
|
|
1220
1239
|
return;
|
|
1240
|
+
// Der Rest-Dialog (d-erfolg) öffnet über einen 90-ms-Timer nach der letzten Aktion des
|
|
1241
|
+
// Auszugs; ohne dieses Abwarten löste die Erkennung mal vor, mal nach ihm aus.
|
|
1242
|
+
await fenster.webContents.executeJavaScript(`new Promise(function (r) { var n = 0; (function w() { if (document.querySelector('dialog[open]') || ++n > 30) r(); else setTimeout(w, 50); })(); })`);
|
|
1221
1243
|
plattenVersionPruefen(true);
|
|
1222
1244
|
await new Promise((r) => setTimeout(r, 800));
|
|
1223
|
-
const auszug = await fenster.webContents.executeJavaScript(
|
|
1224
|
-
var dlg = document.getElementById('d-neustart');
|
|
1225
|
-
// Ein anderer Dialog steht noch offen (Rest des ersten Auszugs): das Modal wartet
|
|
1226
|
-
// solange, und öffnet erst, wenn der andere zu ist.
|
|
1227
|
-
var anderePlatzhalter = Array.from(document.querySelectorAll('dialog[open]')).filter(function (d) { return d !== dlg; });
|
|
1228
|
-
var wartetSolangeAndererOffen = anderePlatzhalter.length > 0 && dlg?.open !== true;
|
|
1229
|
-
anderePlatzhalter.forEach(function (d) { d.close(); });
|
|
1230
|
-
await new Promise(function (r) { setTimeout(r, 300); });
|
|
1231
|
-
var offen = dlg?.open === true;
|
|
1232
|
-
var titel = document.getElementById('dn-titel')?.textContent ?? null;
|
|
1233
|
-
var zeile = document.getElementById('selbstupdate-gui');
|
|
1234
|
-
var zeileText = zeile && !zeile.hidden ? zeile.textContent : null;
|
|
1235
|
-
var neustartKnopfSichtbar = document.getElementById('selbstupdate-neustart')?.hidden === false;
|
|
1236
|
-
var knopfTexte = Array.from(dlg?.querySelectorAll('.dfuss button') ?? []).map(function (b) { return b.textContent; }).join('|');
|
|
1237
|
-
dlg?.querySelector('button[value="spaeter"]')?.click();
|
|
1238
|
-
var nachSpaeterOffen = dlg?.open === true;
|
|
1239
|
-
return JSON.stringify({ wartetSolangeAndererOffen, offen, titel, zeileText, neustartKnopfSichtbar, knopfTexte, nachSpaeterOffen });
|
|
1240
|
-
})()`);
|
|
1245
|
+
const auszug = await fenster.webContents.executeJavaScript(NEUSTART_AUSZUG_SKRIPT);
|
|
1241
1246
|
console.log(`[smoke] Neustart-Modal: ${String(auszug)}`);
|
|
1242
1247
|
})
|
|
1243
1248
|
.finally(() => app.quit());
|
|
@@ -1337,11 +1342,40 @@ function updatePruefen() {
|
|
|
1337
1342
|
console.log(`[updater] ${fehler instanceof Error ? fehler.message : String(fehler)}`);
|
|
1338
1343
|
}
|
|
1339
1344
|
}
|
|
1340
|
-
/**
|
|
1341
|
-
|
|
1345
|
+
/** Das Skript für den Modal-Auszug im Smoke-Test (Neustart-Modal, Sidebar-Zeile, „Später"). */
|
|
1346
|
+
const NEUSTART_AUSZUG_SKRIPT = `(async () => {
|
|
1347
|
+
var dlg = document.getElementById('d-neustart');
|
|
1348
|
+
// Ein anderer Dialog steht noch offen (Rest des ersten Auszugs): das Modal wartet
|
|
1349
|
+
// solange, und öffnet erst, wenn der andere zu ist.
|
|
1350
|
+
var anderePlatzhalter = Array.from(document.querySelectorAll('dialog[open]')).filter(function (d) { return d !== dlg; });
|
|
1351
|
+
var wartetSolangeAndererOffen = anderePlatzhalter.length > 0 && dlg?.open !== true;
|
|
1352
|
+
anderePlatzhalter.forEach(function (d) { d.close(); });
|
|
1353
|
+
await new Promise(function (r) { setTimeout(r, 300); });
|
|
1354
|
+
var offen = dlg?.open === true;
|
|
1355
|
+
var titel = document.getElementById('dn-titel')?.textContent ?? null;
|
|
1356
|
+
var zeile = document.getElementById('selbstupdate-gui');
|
|
1357
|
+
var zeileText = zeile && !zeile.hidden ? zeile.textContent : null;
|
|
1358
|
+
var neustartKnopfSichtbar = document.getElementById('selbstupdate-neustart')?.hidden === false;
|
|
1359
|
+
var knopfTexte = Array.from(dlg?.querySelectorAll('.dfuss button') ?? []).map(function (b) { return b.textContent; }).join('|');
|
|
1360
|
+
dlg?.querySelector('button[value="spaeter"]')?.click();
|
|
1361
|
+
var nachSpaeterOffen = dlg?.open === true;
|
|
1362
|
+
return JSON.stringify({ wartetSolangeAndererOffen, offen, titel, zeileText, neustartKnopfSichtbar, knopfTexte, nachSpaeterOffen });
|
|
1363
|
+
})()`;
|
|
1364
|
+
/**
|
|
1365
|
+
* Ein Hinweis für die Sidebar (E77). Ist das Fenster schon zu, verfällt er stillschweigend. Solange
|
|
1366
|
+
* die Seite nicht geladen ist, hat der Renderer seinen Listener noch nicht (E90-Nachtrag): der
|
|
1367
|
+
* Puffer hält je Art die letzte Nachricht und sendet sie nach `did-finish-load` — das Skript am
|
|
1368
|
+
* Ende des Bodys registriert `onSelbstUpdate` synchron, `did-finish-load` kommt erst danach.
|
|
1369
|
+
*/
|
|
1370
|
+
const meldungsPuffer = new MeldungsPuffer((nachricht) => {
|
|
1342
1371
|
if (hauptfenster === null || hauptfenster.isDestroyed())
|
|
1343
1372
|
return;
|
|
1344
1373
|
hauptfenster.webContents.send('hmgr:selbstUpdate', nachricht);
|
|
1374
|
+
});
|
|
1375
|
+
function selbstUpdateMelden(nachricht) {
|
|
1376
|
+
if (hauptfenster === null || hauptfenster.isDestroyed())
|
|
1377
|
+
return;
|
|
1378
|
+
meldungsPuffer.melden(nachricht);
|
|
1345
1379
|
}
|
|
1346
1380
|
/** Windows: ein Paket ist geladen und wartet auf `quitAndInstall` (E90, Merker für `hmgr:neuStarten`). */
|
|
1347
1381
|
let geladenesPaketVorhanden = false;
|
|
@@ -72,3 +72,34 @@ export function neuereVersionAufPlatte(plistPfad, laufend) {
|
|
|
72
72
|
const platte = plistVersion(plistPfad);
|
|
73
73
|
return platte !== null && istNeuer(platte, laufend) ? platte : null;
|
|
74
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Puffer für Meldungen an den Renderer (E90-Nachtrag). Solange die Seite nicht geladen ist, hat der
|
|
77
|
+
* Renderer seinen Listener noch nicht registriert, ein `webContents.send` ginge ins Leere. Bis
|
|
78
|
+
* `bereitSetzen()` wird deshalb je `art` nur die letzte Nachricht behalten und dann einmal
|
|
79
|
+
* gesendet; danach geht alles sofort durch. `bereitAbmelden()` (neues Laden der Seite) schaltet
|
|
80
|
+
* wieder auf Puffern. Ohne Electron-Import, damit ohne App testbar.
|
|
81
|
+
*/
|
|
82
|
+
export class MeldungsPuffer {
|
|
83
|
+
bereit = false;
|
|
84
|
+
wartend = new Map();
|
|
85
|
+
senden;
|
|
86
|
+
constructor(senden) {
|
|
87
|
+
this.senden = senden;
|
|
88
|
+
}
|
|
89
|
+
melden(nachricht) {
|
|
90
|
+
if (this.bereit)
|
|
91
|
+
this.senden(nachricht);
|
|
92
|
+
else
|
|
93
|
+
this.wartend.set(nachricht.art, nachricht);
|
|
94
|
+
}
|
|
95
|
+
bereitSetzen() {
|
|
96
|
+
this.bereit = true;
|
|
97
|
+
const gepuffert = [...this.wartend.values()];
|
|
98
|
+
this.wartend.clear();
|
|
99
|
+
for (const nachricht of gepuffert)
|
|
100
|
+
this.senden(nachricht);
|
|
101
|
+
}
|
|
102
|
+
bereitAbmelden() {
|
|
103
|
+
this.bereit = false;
|
|
104
|
+
}
|
|
105
|
+
}
|