Mehrsprachigkeit (Englisch/Deutsch, Systemsprache oder Auswahl in den Einstellungen), README auf Englisch für Nutzer, Version 0.4.0

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-25 18:18:03 +02:00
co-authored by Claude Opus 5.5
parent b578a6c7ec
commit 2890844c81
14 changed files with 761 additions and 322 deletions
+8 -7
View File
@@ -5,13 +5,14 @@ const { spawn } = require('child_process');
const fs = require('fs');
const os = require('os');
const path = require('path');
const i18n = require('../i18n');
const DEFAULT_REPO = 'https://git.mrblake.cc/MrBlake/MrTerm';
function parseRepo(url) {
const u = new URL((url || DEFAULT_REPO).replace(/\.git$/, '').replace(/\/+$/, ''));
const [owner, repo] = u.pathname.split('/').filter(Boolean);
if (!owner || !repo) throw new Error('Ungültige Repository-URL: ' + url);
if (!owner || !repo) throw new Error(i18n.t('Invalid repository URL: {url}', { url }));
return { base: u.origin, owner, repo };
}
@@ -59,8 +60,8 @@ class Updater {
async check() {
const { base, owner, repo } = parseRepo(this.store.get().settings.updateUrl);
const res = await fetch(`${base}/api/v1/repos/${owner}/${repo}/releases?limit=20`, { headers: this.headers() });
if (res.status === 404) throw new Error('Repository nicht gefunden (privat? Dann Zugriffstoken in den Einstellungen hinterlegen).');
if (!res.ok) throw new Error(`Update-Server antwortet mit ${res.status}`);
if (res.status === 404) throw new Error(i18n.t('Repository not found (private? Then add an access token in the settings).'));
if (!res.ok) throw new Error(i18n.t('Update server responded with {status}', { status: res.status }));
const allowPre = this.store.get().settings.updatePrerelease;
const rel = (await res.json()).find((r) => !r.draft && (allowPre || !r.prerelease));
const current = app.getVersion();
@@ -90,12 +91,12 @@ class Updater {
async download() {
if (!this.latest) await this.check();
const { asset } = this.latest;
if (!asset) throw new Error('Kein passendes Paket für dieses System im Release gefunden.');
if (!asset) throw new Error(i18n.t('No matching package for this system found in the release.'));
const dir = path.join(os.tmpdir(), 'mrterm-update');
fs.mkdirSync(dir, { recursive: true });
const file = path.join(dir, asset.name);
const res = await fetch(asset.browser_download_url, { headers: { ...this.headers(), Accept: 'application/octet-stream' } });
if (!res.ok) throw new Error(`Download fehlgeschlagen (${res.status})`);
if (!res.ok) throw new Error(i18n.t('Download failed ({status})', { status: res.status }));
const total = Number(res.headers.get('content-length')) || asset.size || 0;
const out = fs.createWriteStream(file + '.part');
let done = 0, last = 0;
@@ -136,12 +137,12 @@ class Updater {
await new Promise((resolve, reject) => {
const p = spawn('pkexec', ['pacman', '-U', '--noconfirm', file], { stdio: 'ignore' });
p.on('error', reject);
p.on('exit', (c) => (c === 0 ? resolve() : reject(new Error(`pacman beendet mit Code ${c}`))));
p.on('exit', (c) => (c === 0 ? resolve() : reject(new Error(i18n.t('pacman exited with code {code}', { code: c })))));
});
app.relaunch();
app.exit(0);
} else {
throw new Error('Automatische Installation hier nicht möglich. Datei liegt unter: ' + file);
throw new Error(i18n.t('Automatic installation is not possible here. The file is located at: {file}', { file }));
}
}
}