Linux-Fassung (Ubuntu) ergaenzen
Die Fachlogik war bereits plattformneutral — paths.js loeste ~/.config schon auf, jsonl.js liest ueber os.homedir(). Zu tun waren Autostart, Build-Targets und drei Linux-Eigenheiten der Oberflaeche. XWayland erzwingen: Ab Electron 36 waehlt Chromium in einer Wayland-Sitzung von sich aus Wayland. Dort darf sich ein Fenster weder selbst positionieren noch dauerhaft in den Vordergrund legen — beides ist der Kern dieses Widgets. Der Schalter muss auf der Kommandozeile stehen, weil Ozone die Plattform vor dem Main-Skript festlegt; appendSwitch() und ELECTRON_OZONE_PLATFORM_HINT kommen beide zu spaet. Bleibt ein einmaliger Neustart mit --ozone-platform=x11, der sich am Argument selbst als Abbruchbedingung erkennt. Im AppImage muss dabei execPath auf APPIMAGE zeigen, sonst laeuft der Nachfolger in den /tmp-Einhaengepunkt, den der Vorgaenger beim Beenden wegraeumt. Autostart: app.setLoginItemSettings() gibt es unter Linux nicht. Das neue Modul autostart.js kapselt die Weiche und schreibt bzw. loescht dort ~/.config/autostart/claude-live-dashboard.desktop. Der Startbefehl kommt aus APPIMAGE, falls gesetzt. Ausserdem: enable-transparent-visuals fuer echte Transparenz, das 32-px-Tray-Symbol in der GNOME-Leiste, plattformabhaengige Beschriftungen in Tray-Menue und Einstellungsdialog, AppImage- und deb-Targets, icon.png auf 512 px (electron-builder rechnet daraus die Linux-Groessen herunter) und start.sh als Gegenstueck zu start.cmd. Getestet unter GNOME/Wayland: Fenster auf X11 an erwarteter Position, gemerkte Position wird wiederhergestellt, Tray registriert sich auf DBus, dump liest die Transkripte, beide Pakete bauen und das AppImage startet ohne Schalter. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Claude Live Dashboard
|
||||
|
||||
Ein rahmenloses Always-on-Top-Widget für Windows, das die Auslastung des
|
||||
Ein rahmenloses Always-on-Top-Widget für Windows und Linux, das die Auslastung des
|
||||
Claude-Plans live anzeigt: 5-Stunden-Fenster, Wochenverbrauch, Reset-Countdown,
|
||||
Tokenverbrauch je Modell und die Hochrechnung auf das Fensterende.
|
||||
|
||||
@@ -10,8 +10,12 @@ mitgeschnitten und standardmäßig keine Netzwerkverbindung aufgebaut.
|
||||
|
||||
## Start
|
||||
|
||||
Node.js wird benötigt. Ist es nicht im `PATH` (etwa bei nvm-windows ohne
|
||||
aktive Version), genügt der Versionspfad:
|
||||
Node.js (ab Version 20) wird benötigt.
|
||||
|
||||
### Windows
|
||||
|
||||
Ist Node nicht im `PATH` (etwa bei nvm-windows ohne aktive Version), genügt der
|
||||
Versionspfad:
|
||||
|
||||
```powershell
|
||||
$env:PATH = "$env:APPDATA\nvm\v22.22.1;$env:PATH"
|
||||
@@ -19,9 +23,51 @@ npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
Alternativ `start.cmd` doppelklicken.
|
||||
|
||||
Das Tray-Symbol landet unter Windows zunächst im Überlaufbereich hinter dem
|
||||
`^` in der Taskleiste; per Drag lässt es sich dauerhaft sichtbar machen.
|
||||
|
||||
### Linux (Ubuntu)
|
||||
|
||||
```bash
|
||||
sudo apt install nodejs npm # falls noch nicht vorhanden
|
||||
./start.sh
|
||||
```
|
||||
|
||||
`start.sh` installiert fehlende Abhängigkeiten selbst und startet Electron;
|
||||
`npm install && npm start` tut dasselbe.
|
||||
|
||||
Das Tray-Symbol braucht unter GNOME die Erweiterung **AppIndicator** — beim
|
||||
Ubuntu-Desktop ist sie vorinstalliert und aktiv. Auf einer Minimalinstallation
|
||||
oder unter anderen Oberflächen:
|
||||
|
||||
```bash
|
||||
sudo apt install gnome-shell-extension-appindicator
|
||||
```
|
||||
|
||||
Ohne sie läuft das Widget weiter, nur das Symbol in der oberen Leiste fehlt.
|
||||
Anders als unter Windows ist im StatusNotifierItem-Standard nicht festgelegt,
|
||||
welcher Klick als Aktivierung zählt — verlässlich ist deshalb das Kontextmenü
|
||||
(Rechtsklick) mit „Dashboard anzeigen“ als erstem Eintrag.
|
||||
|
||||
**Wayland:** Ab Electron 36 wählt Chromium in einer Wayland-Sitzung von sich
|
||||
aus Wayland — dort darf sich ein Fenster aber weder selbst positionieren noch
|
||||
dauerhaft in den Vordergrund legen, und genau das ist der Kern dieses Widgets.
|
||||
Die App startet sich deshalb unter Wayland einmalig selbst mit
|
||||
`--ozone-platform=x11` neu und läuft über XWayland. Das geschieht automatisch,
|
||||
es ist nichts einzustellen.
|
||||
|
||||
Der Schalter *muss* auf der Kommandozeile stehen: Ozone legt die Plattform
|
||||
fest, bevor das Main-Skript läuft — `app.commandLine.appendSwitch()` und
|
||||
`ELECTRON_OZONE_PLATFORM_HINT` kommen beide zu spät. Wer die Automatik
|
||||
umgehen will, setzt eine der beiden Größen von Hand; dann greift der Neustart
|
||||
nicht mehr:
|
||||
|
||||
```bash
|
||||
ELECTRON_OZONE_PLATFORM_HINT=wayland ./start.sh # nativ Wayland, ohne Positionierung
|
||||
```
|
||||
|
||||
## Bedienung
|
||||
|
||||
| Aktion | Wirkung |
|
||||
@@ -157,6 +203,7 @@ src/main/oauth-usage.js Serverabfrage, gekapselt und ausfallsicher
|
||||
src/main/calibrate.js Kalibrierung gegen die echte Anzeige
|
||||
src/main/store.js state.json, config.json
|
||||
src/main/paths.js Speicherorte für Konfiguration und Zustand
|
||||
src/main/autostart.js Anmeldestart je Betriebssystem
|
||||
src/preload.js contextBridge fürs Widget
|
||||
src/settings-preload.js contextBridge für den Einstellungsdialog
|
||||
src/renderer/ Widget-Oberfläche
|
||||
@@ -178,6 +225,12 @@ Zwei Details, die nicht offensichtlich sind:
|
||||
|
||||
## Release bauen
|
||||
|
||||
Gebaut wird jeweils auf dem Zielsystem — electron-builder kann `.deb` nicht
|
||||
sinnvoll von Windows aus erzeugen und umgekehrt keine signierten `.exe` unter
|
||||
Linux.
|
||||
|
||||
### Windows
|
||||
|
||||
```powershell
|
||||
npm run dist # Installer + portable Fassung nach release/
|
||||
npm run pack # nur entpackt nach release/win-unpacked (schneller Test)
|
||||
@@ -201,16 +254,49 @@ Start einen SmartScreen-Hinweis („Der Computer wurde durch Windows geschützt
|
||||
Weitergabe an andere wäre ein Zertifikat nötig; für den Eigenbedarf ist es
|
||||
verzichtbar.
|
||||
|
||||
### Linux
|
||||
|
||||
```bash
|
||||
npm run dist:linux # AppImage + .deb nach release/
|
||||
npm run pack:linux # nur entpackt nach release/linux-unpacked
|
||||
```
|
||||
|
||||
Ergebnis in `release/`:
|
||||
|
||||
| Datei | Zweck |
|
||||
|---|---|
|
||||
| `Claude Live Dashboard-1.0.0-x64.AppImage` | läuft ohne Installation |
|
||||
| `Claude Live Dashboard-1.0.0-amd64.deb` | Installation per `sudo apt install ./…deb` |
|
||||
|
||||
Das AppImage muss einmal ausführbar gemacht werden (`chmod +x`) und braucht
|
||||
`libfuse2`. Es trägt sich nicht selbst ins Anwendungsmenü ein — der Autostart
|
||||
über das Tray-Menü funktioniert trotzdem, weil die App den Pfad des Abbilds aus
|
||||
`APPIMAGE` liest und nicht den temporären Einhängepunkt. Das `.deb` bringt
|
||||
Menüeintrag und Symbol mit und installiert nach `/opt/Claude Live Dashboard`.
|
||||
|
||||
> **Ubuntu 24.04 und AppImage.** Seit 24.04 beschränkt AppArmor unprivilegierte
|
||||
> User-Namespaces; die Chromium-Sandbox kann dann beim Start fehlschlagen
|
||||
> (`SUID sandbox helper binary … is not configured correctly`). Zwei Auswege:
|
||||
> das AppImage mit `--no-sandbox` starten, oder ein AppArmor-Profil unter
|
||||
> `/etc/apparmor.d/` hinterlegen. Beim `.deb` tritt das nicht auf — dessen
|
||||
> `postinst` setzt das SUID-Bit auf `chrome-sandbox`.
|
||||
|
||||
### Konfiguration und Zustand
|
||||
|
||||
Beides liegt im Benutzerprofil, nicht im Programmverzeichnis — dort wäre es
|
||||
nach der Installation im asar-Archiv und schreibgeschützt:
|
||||
|
||||
```
|
||||
%APPDATA%\Claude Live Dashboard\config.json
|
||||
%APPDATA%\Claude Live Dashboard\state.json
|
||||
Windows: %APPDATA%\Claude Live Dashboard\config.json
|
||||
%APPDATA%\Claude Live Dashboard\state.json
|
||||
|
||||
Linux: ~/.config/Claude Live Dashboard/config.json
|
||||
~/.config/Claude Live Dashboard/state.json
|
||||
```
|
||||
|
||||
Der Autostart ist kein Feld dieser Dateien: unter Windows steckt er in der
|
||||
Registry, unter Linux in `~/.config/autostart/claude-live-dashboard.desktop`.
|
||||
|
||||
Beim ersten Start wird `config.json` aus der mitgelieferten Vorlage angelegt.
|
||||
Erreichbar über das Tray-Menü (*Konfiguration öffnen* / *Datenordner öffnen*).
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 5.0 KiB |
+32
-2
@@ -3,7 +3,7 @@
|
||||
"productName": "Claude Live Dashboard",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"description": "Always-on-Top Mini-Dashboard für Claude-Plan-Auslastung unter Windows",
|
||||
"description": "Always-on-Top Mini-Dashboard für Claude-Plan-Auslastung unter Windows und Linux",
|
||||
"main": "src/main/index.js",
|
||||
"scripts": {
|
||||
"start": "electron .",
|
||||
@@ -11,10 +11,14 @@
|
||||
"calibrate": "node src/main/calibrate.js",
|
||||
"icons": "node tools/make-icon.js",
|
||||
"dist": "electron-builder --win",
|
||||
"pack": "electron-builder --win --dir"
|
||||
"pack": "electron-builder --win --dir",
|
||||
"dist:linux": "electron-builder --linux",
|
||||
"pack:linux": "electron-builder --linux --dir"
|
||||
},
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"_homepage": "Platzhalter — nur nötig, weil das .deb-Paket ein Homepage-Feld verlangt.",
|
||||
"homepage": "https://github.com/exilkieler/claude-live-dashboard",
|
||||
"devDependencies": {
|
||||
"electron": "^43.2.0",
|
||||
"electron-builder": "^25.1.8"
|
||||
@@ -66,6 +70,32 @@
|
||||
},
|
||||
"portable": {
|
||||
"artifactName": "${productName}-${version}-portable.${ext}"
|
||||
},
|
||||
"linux": {
|
||||
"target": [
|
||||
{
|
||||
"target": "AppImage",
|
||||
"arch": [
|
||||
"x64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "deb",
|
||||
"arch": [
|
||||
"x64"
|
||||
]
|
||||
}
|
||||
],
|
||||
"icon": "assets/icon.png",
|
||||
"executableName": "claude-live-dashboard",
|
||||
"category": "Utility",
|
||||
"maintainer": "Stefan <exilkieler@gmail.com>",
|
||||
"synopsis": "Auslastung des Claude-Abos im Blick",
|
||||
"description": "Rahmenloses Always-on-Top-Widget, das die Auslastung des Claude-Abos aus den lokalen Claude-Code-Transkripten liest.",
|
||||
"desktop": {
|
||||
"StartupWMClass": "claude-live-dashboard"
|
||||
},
|
||||
"artifactName": "${productName}-${version}-${arch}.${ext}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Autostart — die einzige Stelle, die weiß, wie die jeweilige Arbeitsumgebung
|
||||
* einen Anmeldestart hinterlegt.
|
||||
*
|
||||
* Unter Windows und macOS erledigt Electron das selbst. Unter Linux gibt es
|
||||
* `app.setLoginItemSettings()` nicht; dort ist der Autostart eine
|
||||
* `.desktop`-Datei in `~/.config/autostart`, deren bloße Existenz den Start
|
||||
* auslöst.
|
||||
*/
|
||||
|
||||
const fs = require('node:fs');
|
||||
const os = require('node:os');
|
||||
const path = require('node:path');
|
||||
const { app } = require('electron');
|
||||
|
||||
const IS_LINUX = process.platform === 'linux';
|
||||
|
||||
const AUTOSTART_DIR = path.join(
|
||||
process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config'),
|
||||
'autostart',
|
||||
);
|
||||
const DESKTOP_FILE = path.join(AUTOSTART_DIR, 'claude-live-dashboard.desktop');
|
||||
|
||||
/**
|
||||
* Der Befehl, mit dem sich die Anwendung selbst wieder startet.
|
||||
*
|
||||
* Ein AppImage entpackt sich beim Start in ein temporäres Verzeichnis —
|
||||
* `process.execPath` zeigt dann dorthin und wäre beim nächsten Anmelden
|
||||
* verschwunden. Den Pfad zum Abbild selbst liefert nur `APPIMAGE`.
|
||||
*/
|
||||
function launchCommand() {
|
||||
if (process.env.APPIMAGE) return `"${process.env.APPIMAGE}"`;
|
||||
if (!app.isPackaged) return `"${process.execPath}" "${app.getAppPath()}"`;
|
||||
return `"${process.execPath}"`;
|
||||
}
|
||||
|
||||
function desktopEntry() {
|
||||
return [
|
||||
'[Desktop Entry]',
|
||||
'Type=Application',
|
||||
'Version=1.0',
|
||||
'Name=Claude Live Dashboard',
|
||||
'Comment=Auslastung des Claude-Abos im Blick',
|
||||
`Exec=${launchCommand()}`,
|
||||
'Icon=claude-live-dashboard',
|
||||
'Terminal=false',
|
||||
'X-GNOME-Autostart-enabled=true',
|
||||
'',
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
/** @returns {boolean} true, wenn die Anwendung beim Anmelden startet */
|
||||
function getAutostart() {
|
||||
if (!IS_LINUX) return app.getLoginItemSettings().openAtLogin;
|
||||
return fs.existsSync(DESKTOP_FILE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schaltet den Anmeldestart ein oder aus.
|
||||
* @param {boolean} enabled
|
||||
*/
|
||||
function setAutostart(enabled) {
|
||||
if (!IS_LINUX) {
|
||||
app.setLoginItemSettings({ openAtLogin: enabled, args: [] });
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (enabled) {
|
||||
fs.mkdirSync(AUTOSTART_DIR, { recursive: true });
|
||||
fs.writeFileSync(DESKTOP_FILE, desktopEntry(), 'utf8');
|
||||
} else {
|
||||
fs.rmSync(DESKTOP_FILE, { force: true });
|
||||
}
|
||||
} catch (err) {
|
||||
// Ein fehlgeschlagener Autostart ist kein Grund, die laufende Anwendung
|
||||
// zu stören — der Haken im Menü zeigt beim nächsten Aufbau den echten Stand.
|
||||
console.warn(`[autostart] konnte nicht gesetzt werden: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { getAutostart, setAutostart, DESKTOP_FILE };
|
||||
+61
-12
@@ -12,6 +12,9 @@ const { app, BrowserWindow, Tray, Menu, ipcMain, screen, nativeImage, shell } =
|
||||
const { Store, loadConfig } = require('./store');
|
||||
const { Collector } = require('./collector');
|
||||
const { CONFIG_FILE, STATE_FILE, USER_DATA_DIR, ensureUserConfig } = require('./paths');
|
||||
const { getAutostart, setAutostart: applyAutostart } = require('./autostart');
|
||||
|
||||
const IS_LINUX = process.platform === 'linux';
|
||||
|
||||
const COMPACT_HEIGHT = 352;
|
||||
const EXPANDED_HEIGHT = 640;
|
||||
@@ -30,11 +33,59 @@ let collector = null;
|
||||
let store = null;
|
||||
let config = {};
|
||||
|
||||
/**
|
||||
* Erzwingt XWayland, sobald das Widget in einer Wayland-Sitzung startet.
|
||||
*
|
||||
* Electron wählt seit Version 36 von sich aus Wayland. Dort darf sich ein
|
||||
* Fenster aber weder selbst positionieren noch dauerhaft in den Vordergrund
|
||||
* legen — beides ist der Kern dieses Widgets. Über XWayland funktioniert es.
|
||||
*
|
||||
* Der Schalter muss auf der Kommandozeile stehen: Ozone wählt die Plattform,
|
||||
* bevor dieses Skript läuft, deshalb kommen `appendSwitch()` und
|
||||
* `ELECTRON_OZONE_PLATFORM_HINT` beide zu spät. Bleibt ein Neustart mit
|
||||
* ergänztem Argument. Das Argument ist zugleich die Abbruchbedingung — im
|
||||
* zweiten Durchlauf steht es in `argv` und der Zweig greift nicht mehr.
|
||||
*
|
||||
* Muss vor `requestSingleInstanceLock()` stehen, damit die verworfene Instanz
|
||||
* die Sperre gar nicht erst nimmt.
|
||||
*/
|
||||
function forceX11IfWayland() {
|
||||
if (!IS_LINUX || !process.env.WAYLAND_DISPLAY) return false;
|
||||
if (process.env.ELECTRON_OZONE_PLATFORM_HINT) return false; // ausdrücklich übersteuert
|
||||
if (process.argv.some((a) => a.startsWith('--ozone-platform'))) return false;
|
||||
|
||||
const args = process.argv.slice(1).concat('--ozone-platform=x11');
|
||||
|
||||
// Ein AppImage hängt sich beim Start unter /tmp ein und wirft die Einhängung
|
||||
// beim Beenden wieder weg. `process.execPath` zeigt dorthin und wäre für den
|
||||
// Nachfolger schon verschwunden — neu gestartet werden muss das Abbild.
|
||||
if (process.env.APPIMAGE) app.relaunch({ execPath: process.env.APPIMAGE, args });
|
||||
else app.relaunch({ args });
|
||||
|
||||
app.exit(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!forceX11IfWayland()) {
|
||||
// Ohne diesen Schalter zeichnet Chromium unter Linux hinter das rahmenlose
|
||||
// Fenster einen schwarzen Kasten statt echter Transparenz.
|
||||
if (IS_LINUX) app.commandLine.appendSwitch('enable-transparent-visuals');
|
||||
|
||||
bootstrap();
|
||||
}
|
||||
|
||||
/** Verhindert, dass mehrere Instanzen dieselben Zustandsdateien beschreiben. */
|
||||
if (!app.requestSingleInstanceLock()) {
|
||||
function bootstrap() {
|
||||
if (!app.requestSingleInstanceLock()) {
|
||||
app.quit();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
app.on('second-instance', () => showWindow());
|
||||
|
||||
main().catch((err) => {
|
||||
console.error(err);
|
||||
app.quit();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,13 +193,13 @@ function setClickThrough(enabled) {
|
||||
}
|
||||
|
||||
function setAutostart(enabled) {
|
||||
app.setLoginItemSettings({ openAtLogin: enabled, args: [] });
|
||||
applyAutostart(enabled);
|
||||
buildTrayMenu();
|
||||
}
|
||||
|
||||
function buildTrayMenu() {
|
||||
if (!tray) return;
|
||||
const autostart = app.getLoginItemSettings().openAtLogin;
|
||||
const autostart = getAutostart();
|
||||
|
||||
tray.setContextMenu(
|
||||
Menu.buildFromTemplate([
|
||||
@@ -171,7 +222,7 @@ function buildTrayMenu() {
|
||||
click: (item) => setClickThrough(item.checked),
|
||||
},
|
||||
{
|
||||
label: 'Mit Windows starten',
|
||||
label: IS_LINUX ? 'Mit dem System starten' : 'Mit Windows starten',
|
||||
type: 'checkbox',
|
||||
checked: autostart,
|
||||
click: (item) => setAutostart(item.checked),
|
||||
@@ -186,7 +237,9 @@ function buildTrayMenu() {
|
||||
}
|
||||
|
||||
function createTray() {
|
||||
const icon = nativeImage.createFromPath(path.join(ROOT, 'assets', 'tray.png'));
|
||||
// In der GNOME-Leiste wirkt das 16-px-Symbol ausgefranst — dort das größere.
|
||||
const file = IS_LINUX ? 'tray@32.png' : 'tray.png';
|
||||
const icon = nativeImage.createFromPath(path.join(ROOT, 'assets', file));
|
||||
tray = new Tray(icon);
|
||||
tray.setToolTip('Claude Live Dashboard');
|
||||
tray.on('click', toggleWindow);
|
||||
@@ -297,7 +350,8 @@ function registerIpc() {
|
||||
config,
|
||||
meta: {
|
||||
configPath: CONFIG_FILE,
|
||||
autostart: app.getLoginItemSettings().openAtLogin,
|
||||
autostart: getAutostart(),
|
||||
platform: process.platform,
|
||||
},
|
||||
}));
|
||||
|
||||
@@ -366,8 +420,3 @@ app.on('window-all-closed', () => {});
|
||||
app.on('before-quit', () => {
|
||||
if (collector) collector.stop();
|
||||
});
|
||||
|
||||
main().catch((err) => {
|
||||
console.error(err);
|
||||
app.quit();
|
||||
});
|
||||
|
||||
@@ -20,6 +20,7 @@ const el = {
|
||||
opacityOut: $('opacity-out'),
|
||||
clickThrough: $('clickThrough'),
|
||||
autostart: $('autostart'),
|
||||
autostartLabel: $('autostart-label'),
|
||||
|
||||
oauthEnabled: $('oauthEnabled'),
|
||||
oauthEndpoint: $('oauthEndpoint'),
|
||||
@@ -80,6 +81,8 @@ function fill(config, meta) {
|
||||
el.opacityOut.textContent = `${opacity} %`;
|
||||
el.clickThrough.checked = Boolean(config.clickThrough);
|
||||
el.autostart.checked = Boolean(meta.autostart);
|
||||
el.autostartLabel.textContent =
|
||||
meta.platform === 'win32' ? 'Mit Windows starten' : 'Mit dem System starten';
|
||||
|
||||
const oauth = config.oauth || {};
|
||||
el.oauthEnabled.checked = oauth.enabled !== false;
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label for="autostart">Mit Windows starten</label>
|
||||
<label for="autostart" id="autostart-label">Automatisch starten</label>
|
||||
<div class="control">
|
||||
<input type="checkbox" id="autostart" />
|
||||
<span class="hint">Wird sofort übernommen, unabhängig vom Speichern.</span>
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
# Startet das Dashboard aus dem Quellcode. Gegenstück zu start.cmd; unter
|
||||
# Ubuntu liegt Node im PATH, deshalb genügt die Abhängigkeitsprüfung.
|
||||
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
if ! command -v node >/dev/null 2>&1; then
|
||||
echo "Node wurde nicht gefunden. Installiere es z.B. mit: sudo apt install nodejs npm"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d node_modules/electron ]; then
|
||||
echo "Abhaengigkeiten werden installiert..."
|
||||
npm install
|
||||
fi
|
||||
|
||||
exec node_modules/.bin/electron . "$@"
|
||||
+3
-2
@@ -116,9 +116,10 @@ function main() {
|
||||
console.log(`geschrieben: ${file}`);
|
||||
}
|
||||
|
||||
// Fenster- und Anwendungssymbol
|
||||
// Fenster- und Anwendungssymbol. 512 px, weil electron-builder daraus die
|
||||
// Linux-Symbolgrößen herunterrechnet und mindestens 256 px verlangt.
|
||||
const file = path.join(OUT_DIR, 'icon.png');
|
||||
fs.writeFileSync(file, makePng(256, ringShader(256, orange)));
|
||||
fs.writeFileSync(file, makePng(512, ringShader(512, orange)));
|
||||
console.log(`geschrieben: ${file}`);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user