initial commit

This commit is contained in:
Levi Neely 2026-06-30 15:58:03 +02:00
commit 00530f0bd0
8 changed files with 5275 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
node_modules/
dist/

42
fallback.html Normal file
View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RVV – Offline</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
background: #f5f5f5;
color: #333;
text-align: center;
padding: 2rem;
}
.container { max-width: 480px; }
h1 { font-size: 1.5rem; margin-bottom: 1rem; }
p { margin-bottom: 1.5rem; line-height: 1.6; }
button {
padding: 0.75rem 1.5rem;
font-size: 1rem;
background: #0066cc;
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover { background: #0052a3; }
</style>
</head>
<body>
<div class="container">
<h1>Keine Verbindung</h1>
<p>Die Website rvv.de konnte nicht geladen werden. Bitte überprüfen Sie Ihre Internetverbindung und versuchen Sie es erneut.</p>
<button onclick="window.location.href='https://www.rvv.de'">Erneut versuchen</button>
</div>
</body>
</html>

108
main.js Normal file
View File

@ -0,0 +1,108 @@
const { app, BrowserWindow, Tray, Menu, shell } = require('electron');
const path = require('path');
const TARGET_URL = 'https://www.rvv.de';
let mainWindow = null;
let tray = null;
function createWindow() {
mainWindow = new BrowserWindow({
width: 414,
height: 896,
title: 'RVV',
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true,
nodeIntegration: false,
},
});
mainWindow.loadURL(TARGET_URL);
// Minimize to tray instead of closing
mainWindow.on('close', (event) => {
if (!app.isQuitting) {
event.preventDefault();
mainWindow.hide();
}
});
// Open external links in the system browser
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
const targetHost = new URL(TARGET_URL).host;
const linkHost = new URL(url).host;
if (!linkHost.endsWith(targetHost)) {
shell.openExternal(url);
return { action: 'deny' };
}
return { action: 'allow' };
});
// Handle navigation to external sites
mainWindow.webContents.on('will-navigate', (event, url) => {
const targetHost = new URL(TARGET_URL).host;
try {
const linkHost = new URL(url).host;
if (!linkHost.endsWith(targetHost)) {
event.preventDefault();
shell.openExternal(url);
}
} catch {
// allow navigation if URL parsing fails
}
});
// Show fallback page if the site fails to load
mainWindow.webContents.on('did-fail-load', (_event, _code, _desc, url) => {
if (url.startsWith(TARGET_URL)) {
mainWindow.loadFile('fallback.html');
}
});
}
function createTray() {
tray = new Tray(path.join(__dirname, 'rvv-icon.png'));
const contextMenu = Menu.buildFromTemplate([
{
label: 'Show RVV',
click: () => {
mainWindow.show();
},
},
{ type: 'separator' },
{
label: 'Quit',
click: () => {
app.isQuitting = true;
app.quit();
},
},
]);
tray.setToolTip('RVV');
tray.setContextMenu(contextMenu);
// Click on tray icon shows the window
tray.on('click', () => {
mainWindow.show();
});
}
app.whenReady().then(() => {
createWindow();
createTray();
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
} else {
mainWindow.show();
}
});
});
app.on('window-all-closed', () => {
// Don't quit on window close — we live in the tray
});

5095
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

22
package.json Normal file
View File

@ -0,0 +1,22 @@
{
"name": "rvv-app",
"version": "1.0.0",
"description": "Electron wrapper for rvv.de",
"main": "main.js",
"scripts": {
"start": "electron .",
"build": "electron-builder"
},
"author": "",
"license": "MIT",
"build": {
"icon": "rvv-icon.png",
"linux": {
"category": "Utility;Maps"
}
},
"devDependencies": {
"electron": "35.1.5",
"electron-builder": "26.0.12"
}
}

6
preload.js Normal file
View File

@ -0,0 +1,6 @@
// Preload script — runs in a sandboxed context before the page loads.
// Add any contextBridge or ipcRenderer bindings here if needed in the future.
window.addEventListener('DOMContentLoaded', () => {
// App is ready
});

BIN
rvv-icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
rvv-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB