1 Commits
Author SHA1 Message Date
M_Viper 3f83c8b32a Upload via GUI (33 Dateien) 2026-09-22 18:59:48 +00:00
3 changed files with 237 additions and 27 deletions
+85 -21
View File
@@ -5,20 +5,24 @@ das, was sonst eine "neue Tab"-Seite im Browser wäre, aber als schnelles,
eigenes Programm: mit Lesezeichen, Gruppen, Design-Optionen, Uhr/Datum und
allem, was eine gute Startseite braucht. Sie basiert auf dem quelloffenen
Projekt **nightTab**, komplett ins Deutsche übersetzt und um einige eigene
Funktionen erweitert (Fenster-Bedienung, mehrere Reiter, Cloud-Abgleich).
Funktionen erweitert (Fenster-Bedienung, mehrere Reiter, Abgleich zwischen
mehreren PCs, eigene Bilder und Videos von deinem Rechner).
---
## Installation & erster Start
MyStart ist eine **portable Einzeldatei** (`MyStart.exe`, ca. 48 MB) – kein
MyStart ist eine **portable Einzeldatei** (`MyStart.exe`, ca. 110 MB) – kein
Installer, keine Admin-Rechte nötig. Einfach an einen beliebigen Ort legen
und starten.
und starten. Die Datei ist bewusst unkomprimiert und daher größer; sie muss
sich beim Start nicht selbst entpacken.
- **Erster Start:** ca. 2 Sekunden, danach öffnet sich MyStart praktisch
sofort.
- Die App startet als **normales Fenster** (nicht im Vollbild), zentriert
auf dem Bildschirm.
- Beim allerersten Start öffnet sich die App als **normales Fenster** (nicht
im Vollbild), zentriert auf dem Bildschirm. Danach merkt sie sich Größe,
Position und ob du sie maximiert hattest, und startet dort wieder, wo du
sie zuletzt gelassen hast (siehe unten).
- Alle deine Daten (Lesezeichen, Design, Reiter …) werden lokal unter
`%LOCALAPPDATA%\MyStart` gespeichert – unabhängig davon, wo die `.exe`
liegt oder ob du sie verschiebst.
@@ -43,6 +47,11 @@ Zusätzlich:
- **Größe ändern:** einfach an einer beliebigen Fensterkante oder -ecke
ziehen, genau wie bei einem normalen Windows-Fenster.
- Ein maximiertes Fenster deckt nie die Taskleiste ab.
- **Größe und Position merken:** Beim Schließen wird die aktuelle Größe,
Position und ob maximiert gespeichert und beim nächsten Start wieder
angewendet. Passt die gespeicherte Position auf keinen aktuell
angeschlossenen Bildschirm mehr (z. B. zweiter Monitor abgesteckt), startet
MyStart stattdessen wieder zentriert in der Standardgröße.
---
@@ -69,12 +78,13 @@ eigenen** Lesezeichen, Gruppen und sein eigenes Design.
---
## Automatischer Abgleich über OneDrive
## Abgleich zwischen mehreren PCs
Arbeitest du an **mehreren PCs**, kann MyStart seinen kompletten Datenstand
(alle Reiter, Lesezeichen, Design) automatisch zwischen den Rechnern
abgleichen – sofern auf beiden PCs **OneDrive** eingerichtet und angemeldet
ist.
abgleichen – über einen synchronisierten Ordner, standardmäßig dein
**OneDrive**-Ordner (auf allen beteiligten PCs muss er eingerichtet und
angemeldet sein).
Der Abgleich ist **optional und standardmäßig aus**. Einschalten unter
**Einstellungen → MyStart → „Zwischen PCs abgleichen“** – auf jedem PC
@@ -88,30 +98,71 @@ synchronisierten Ordner nehmen (Dropbox, Google Drive, Netzlaufwerk …),
„Automatisch (OneDrive)“ stellt es zurück. Auf **allen PCs muss derselbe
Ordner** genutzt werden, also dieselbe Cloud-Freigabe.
- MyStart legt dazu im Ordner `OneDrive\MyStart` pro PC eine eigene Datei
- MyStart legt dazu im Sync-Ordner pro PC eine eigene Datei
`sync-<Rechnername>.json` an (jeder PC schreibt nur seine eigene, damit
OneDrive keine Konfliktkopien erzeugt). Die eigentliche Übertragung
zwischen den PCs übernimmt OneDrive selbst – MyStart schreibt/liest dort
nur diese Dateien.
der Cloud-Dienst keine Konfliktkopien erzeugt). Die eigentliche
Übertragung zwischen den PCs übernimmt der Cloud-Dienst selbst – MyStart
schreibt/liest dort nur diese Dateien.
- Abgeglichen wird **alle 30 Sekunden**, außerdem beim Start und beim
Schließen der App.
- Regel bei Änderungen: **die neueste Version gewinnt.** Ändern beide PCs
gleichzeitig etwas, ohne dass zwischendurch synchronisiert wurde, setzt
sich schlicht die zuletzt gespeicherte Version durch (kein Zusammenführen
einzelner Änderungen).
- Regel bei Änderungen: **die neueste Version gewinnt.** Ein PC übernimmt den
Stand eines anderen nur, wenn dieser **neuer** ist als sein eigener letzter
Stand. Ändern beide PCs gleichzeitig etwas, ohne dass zwischendurch
synchronisiert wurde, setzt sich schlicht die zuletzt gespeicherte Version
durch (kein Zusammenführen einzelner Änderungen). Dafür sollten die Uhren
beider PCs ungefähr richtig gehen (normale Windows-Zeitsynchronisierung
reicht).
- Ein neuerer Stand vom anderen PC wird erst übernommen, **wenn das
MyStart-Fenster gerade nicht aktiv ist** (zum Beispiel wenn du weggeklickt
oder es minimiert hast). So lädt die Seite nie mitten in deiner Arbeit neu.
- **Bilder und Videos wandern mit:** Verweist ein Reiter auf eine lokale
Bild-/Videodatei (siehe nächster Abschnitt), wird die Datei selbst mit in
den Sync-Ordner kopiert (Unterordner `media`) und beim anderen PC in einen
eigenen lokalen Zwischenspeicher übernommen – das Bild taucht dort also
wirklich auf, nicht nur ein toter Pfad.
- Ein kleiner **Punkt** in der Reiter-Leiste zeigt den Status (Maus
drüberhalten für Details):
- 🟢 **grün** – zuletzt erfolgreich abgeglichen
- 🟡 **gelb/orange** – aktuell ein Problem (z. B. Datei kurz durch OneDrive
gesperrt; behebt sich meist von selbst beim nächsten Abgleich)
- Ist auf einem PC kein OneDrive eingerichtet, bleibt der Abgleich dort
einfach ohne Fehlermeldung aus – die App funktioniert ganz normal weiter,
nur eben ohne Sync.
- 🟣 **lila** – ein **Konflikt** wurde erkannt: du hattest hier gerade etwas
geändert, während gleichzeitig (ohne zwischenzeitlichen Abgleich) auch
auf einem anderen PC etwas geändert wurde. Dein Stand wird trotzdem
gespeichert, es erscheint zusätzlich kurz ein Hinweisfenster; schau in
dem Fall lieber nochmal nach, ob auf dem anderen PC etwas verloren ging
- Findet MyStart auf einem PC keinen OneDrive-Ordner, ist der Schalter
ausgegraut, bis du mit „Ordner wählen…“ einen Ordner angibst – die App
funktioniert ganz normal weiter, nur eben ohne Sync.
- **Wichtig:** Damit der Abgleich funktioniert, muss MyStart auf **jedem**
beteiligten PC vorhanden sein und einmal gestartet werden.
---
## Eigene Bilder und Videos von diesem PC
Für Hintergrundbild, Hintergrundvideo, Lesezeichen-Symbole und
Lesezeichen-Hintergründe kannst du nicht nur Internet-Adressen, sondern auch
**Dateien von deinem PC** nutzen:
- **„Lokale Datei wählen…“** – neben den Bild-/Video-Feldern in den
Einstellungen; öffnet den Windows-Dateidialog. Beim Hintergrundbild
(Design) kannst du mehrere Bilder auf einmal wählen.
- **Pfad einfügen oder eintippen** geht ebenfalls, zum Beispiel
`C:\Bilder\urlaub.jpg`, ein Pfad in Anführungszeichen (so kopiert ihn der
Explorer mit „Als Pfad kopieren“), `file:///C:/Bilder/urlaub.jpg` oder ein
Netzwerkpfad `\\server\freigabe\bild.png`. Er wird beim Verlassen des
Felds automatisch umgewandelt.
- Erlaubt sind nur Bild- und Videodateien (PNG, JPG, GIF, WebP, SVG, BMP, ICO,
AVIF, MP4, WebM …); andere Dateien werden nie ausgeliefert.
**Bei mehreren PCs:** Ist der Abgleich (siehe oben) eingeschaltet, wird die
Datei selbst mit synchronisiert – sie erscheint dann auch auf dem anderen PC,
ganz ohne dass dort derselbe Pfad existieren muss. Ist der Abgleich **aus**,
wird nur der Pfad in den Lesezeichen/Design-Daten gespeichert; ohne Sync
bleibt es dann bei der Datei, die lokal unter diesem Pfad liegt.
---
## Autostart
Unter **Einstellungen → MyStart** gibt es einen Schalter, um MyStart
@@ -145,10 +196,23 @@ Unter **Einstellungen → Daten** kannst du jederzeit:
---
## Hinweis zu Windows-Warnungen und Virenscannern
MyStart ist **nicht digital signiert** (dafür bräuchte es ein
kostenpflichtiges Zertifikat). Deshalb kann Windows beim ersten Start
„Unbekannter Herausgeber“ melden – über **Weitere Informationen →
Trotzdem ausführen** lässt sich das wegklicken. Manche Virenscanner stufen
kleine, selbst gebaute und unsignierte Programme zusätzlich fälschlich als
verdächtig ein (sogenannter Fehlalarm). Hilft nichts anderes, kannst du für
den Ordner mit der `MyStart.exe` eine Ausnahme in deinem Virenscanner
eintragen oder die Datei beim Hersteller des Scanners als Fehlalarm melden.
---
## Herkunft & Lizenz
MyStart basiert auf **nightTab** von zombieFox
(https://github.com/zombieFox/nightTab), veröffentlicht unter der
**GNU General Public License v3.0**. Die Anpassungen in MyStart (deutsche
Übersetzung, Fenster-Bedienung, Reiter, OneDrive-Sync u. a.) unterliegen
ebenfalls der GPL v3.
Übersetzung, Fenster-Bedienung, Reiter, Sync zwischen PCs, lokale Bilder
u. a.) unterliegen ebenfalls der GPL v3.
+36 -6
View File
@@ -39,7 +39,7 @@ const aboutBody =
'const o=y("p");o.innerHTML=`Git: ${a.link().outerHTML}`,' +
'e.appendChild(y("div",[y("div|class:version",[_t.render(),' +
'y("div|class:version-details",[y("h1:MyStart|class:version-app-name"),' +
'y("p:Version 1.0.3|class:version-number")])]),y("hr"),s,o,y("div|id:mystart-autostart-row,class:mystart-autostart-row")]))';
'y("p:Version 1.0.4|class:version-number")])]),y("hr"),s,o,y("div|id:mystart-autostart-row,class:mystart-autostart-row")]))';
mainJs = mainJs.slice(0, i) + aboutBody + mainJs.slice(j + aEndMarker.length);
// --- 2) Rename branding (visible text + storage keys) consistently ---
@@ -247,13 +247,13 @@ const windowControlsJs = `(function(){
}
document.addEventListener('mousemove',function(ev){
if(ev.buttons)return; // an active drag (e.g. scrollbar) is in progress -> leave it alone
var onCtrls=ev.target.closest&&ev.target.closest('#mystart-winctrls,#mystart-profiles');
var onCtrls=ev.target.closest&&ev.target.closest('#mystart-winctrls,#mystart-profiles,#mystart-sync-toast');
var edge=onCtrls?null:edgeAt(ev.clientX,ev.clientY);
document.documentElement.style.cursor=edge?CURSOR[edge]:'';
},true);
document.addEventListener('mousedown',function(ev){
if(ev.button!==0)return;
if(ev.target.closest&&ev.target.closest('#mystart-winctrls,#mystart-profiles'))return;
if(ev.target.closest&&ev.target.closest('#mystart-winctrls,#mystart-profiles,#mystart-sync-toast'))return;
var edge=edgeAt(ev.clientX,ev.clientY);
if(edge){ev.preventDefault();send2('window-resize',{edge:edge});}
},true);
@@ -426,8 +426,9 @@ const profilesJs = `(function(){
// Sync is opt-in: no dot at all until it's switched on (Einstellungen -> MyStart).
if(!lastSync||lastSync.enabled===false){syncDot.style.display='none';return;}
syncDot.style.display='';
syncDot.style.background=lastSync.ok?'#2ea043':'#e8b923';
syncDot.title=lastSync.ok?('OneDrive-Sync: '+lastSync.message):('OneDrive-Sync-Problem: '+lastSync.message);
syncDot.style.background=lastSync.conflict?'#a371f7':(lastSync.ok?'#2ea043':'#e8b923');
var prefix=lastSync.conflict?'OneDrive-Sync (Konflikt): ':(lastSync.ok?'OneDrive-Sync: ':'OneDrive-Sync-Problem: ');
syncDot.title=prefix+lastSync.message;
}
function mkSyncDot(){
var d=document.createElement('div');
@@ -436,12 +437,37 @@ const profilesJs = `(function(){
paintSyncDot();
return d;
}
// Short-lived banner for a sync conflict -- a colour-only dot is too easy to
// miss for "you might have lost an edit just now".
var conflictToast=null,conflictToastTimer=null;
function showConflictToast(msg){
if(!conflictToast){
conflictToast=document.createElement('div');
conflictToast.id='mystart-sync-toast';
conflictToast.style.cssText='position:fixed;top:44px;left:6px;max-width:360px;padding:8px 12px;'+
'border-radius:8px;background:rgba(60,30,90,.92);color:#f0e6ff;font-size:12px;line-height:1.4;'+
'box-shadow:0 2px 10px rgba(0,0,0,.4);z-index:2147483647;cursor:pointer;';
conflictToast.title='Zum Ausblenden klicken';
conflictToast.addEventListener('click',hideConflictToast);
document.body.appendChild(conflictToast);
}
conflictToast.textContent='⚠ '+msg;
conflictToast.style.display='';
if(conflictToastTimer)clearTimeout(conflictToastTimer);
conflictToastTimer=setTimeout(hideConflictToast,10000);
}
function hideConflictToast(){
if(conflictToast)conflictToast.style.display='none';
if(conflictToastTimer){clearTimeout(conflictToastTimer);conflictToastTimer=null;}
}
if(window.chrome&&window.chrome.webview){
window.chrome.webview.addEventListener('message',function(ev){
var d=ev.data;
if(!d||d.type!=='sync-status')return;
var wasConflict=lastSync&&lastSync.conflict;
lastSync=d;
paintSyncDot();
if(d.conflict&&!wasConflict)showConflictToast('Gleichzeitige Änderung erkannt — dein Stand wurde trotzdem gespeichert: '+d.message);
});
}
var bar;
@@ -503,7 +529,11 @@ const profilesJs = `(function(){
new MutationObserver(function(){if(!document.getElementById('mystart-profiles'))add();}).observe(document.documentElement,{childList:true,subtree:true});
})();`;
mainJs = trInfra + autostartJs + windowControlsJs + profilesJs + mainJs;
// Local images/videos from this PC in the image/video URL fields (kept as its
// own file: it is full of backslash regexes that are painful inside a template string).
const localFilesJs = fs.readFileSync(path.join(__dirname, 'inject', 'local-files.js'), 'utf8');
mainJs = trInfra + autostartJs + windowControlsJs + profilesJs + localFilesJs + mainJs;
const trPatches = [
// panel header (top-level AND sub, both go through element.header)
+116
View File
@@ -0,0 +1,116 @@
// Lokale Bilder/Videos von diesem PC in den Bild-/Video-Feldern von nightTab nutzen.
//
// Die Seite laeuft unter https://mystart.local; der Browser blockt von dort aus
// file://-Adressen. Die App (Program.cs) liefert deshalb lokale Dateien unter
// https://files.mystart.local/<laufwerk>/<pfad> (C:\a\b.jpg -> /c/a/b.jpg)
// https://files.mystart.local/unc/<server>/<freigabe>/<pfad> (\\server\share\x.png)
// aus. Dieses Skript wandelt eingetippte/eingefuegte Pfade in solche Adressen um
// und haengt an die Bild-/Video-Felder einen "Lokale Datei waehlen"-Knopf.
(function () {
if (!(window.chrome && window.chrome.webview)) return;
var HOST = 'https://files.mystart.local/';
var FIELD = /(image|video)-url$/; // theme-background-image-url, display-visual-image-url, ...
function encodeSegments(path) {
return path.split(/[\\/]+/).filter(Boolean).map(encodeURIComponent).join('/');
}
// Ein Pfad (auch "In Anfuehrungszeichen", wie "Als Pfad kopieren" ihn liefert,
// oder file:///) -> Adresse der App. Alles andere -> null (bleibt unveraendert).
function toUrl(line) {
var s = line.trim();
if (s.length > 1 && s.charAt(0) === '"' && s.charAt(s.length - 1) === '"') s = s.slice(1, -1).trim();
if (/^file:\/\/\//i.test(s)) {
s = s.replace(/^file:\/\/\//i, '');
try { s = decodeURI(s); } catch (e) { /* unveraendert lassen */ }
}
if (/^[A-Za-z]:[\\/]/.test(s)) return HOST + s.charAt(0).toLowerCase() + '/' + encodeSegments(s.slice(3));
if (/^\\\\[^\\]/.test(s)) return HOST + 'unc/' + encodeSegments(s.slice(2));
return null;
}
function isMediaField(el) {
return el && (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') && FIELD.test(el.id || '');
}
function setValue(el, value) {
el.value = value;
el.dispatchEvent(new Event('input', { bubbles: true }));
el.dispatchEvent(new Event('change', { bubbles: true }));
}
// Pfade in einem Feld (auch mehrzeilig, z. B. mehrere Hintergrundbilder) umschreiben.
function fix(el) {
if (!isMediaField(el) || !el.value) return;
var changed = false;
var out = el.value.split(/\r?\n/).map(function (l) {
var u = toUrl(l);
if (u === null) return l;
changed = true;
return u;
});
if (changed) setValue(el, out.join('\n'));
}
// Erst beim Verlassen des Felds/Enter (change) bzw. nach dem Einfuegen umwandeln,
// sonst wuerde schon "C:\" waehrend des Tippens umgeschrieben.
document.addEventListener('change', function (ev) { fix(ev.target); }, true);
document.addEventListener('paste', function (ev) {
var t = ev.target;
setTimeout(function () { fix(t); }, 0);
}, true);
// --- "Lokale Datei waehlen"-Knopf ---
var targets = {};
var nextToken = 1;
window.chrome.webview.addEventListener('message', function (ev) {
var d = ev.data;
if (!d || d.type !== 'file-picked') return;
var el = targets[d.token];
delete targets[d.token];
if (!el || !d.paths || !d.paths.length) return;
var urls = d.paths.map(function (p) { return toUrl(p) || p; });
var multi = /theme-background-image-url$/.test(el.id || '');
var existing = el.value.trim();
setValue(el, multi && existing ? existing + '\n' + urls.join('\n') : urls.join('\n'));
});
function addButton(el) {
if (el.getAttribute('data-mystart-pick')) return;
el.setAttribute('data-mystart-pick', '1');
var b = document.createElement('div');
b.textContent = 'Lokale Datei wählen…';
b.title = 'Bild/Video von diesem PC auswählen';
b.style.cssText = 'display:inline-block;margin-top:6px;padding:5px 10px;border-radius:6px;' +
'background:rgba(128,128,128,.25);cursor:pointer;user-select:none;font-size:12px;';
b.onmouseenter = function () { b.style.background = 'rgba(128,128,128,.4)'; };
b.onmouseleave = function () { b.style.background = 'rgba(128,128,128,.25)'; };
b.addEventListener('click', function () {
var token = nextToken++;
targets[token] = el;
try {
window.chrome.webview.postMessage({
type: 'pick-file',
token: token,
kind: /video-url$/.test(el.id) ? 'video' : 'image',
multiple: /theme-background-image-url$/.test(el.id)
});
} catch (e) { /* ignore */ }
});
el.insertAdjacentElement('afterend', b);
}
var SELECTOR = '#theme-background-image-url,#theme-background-video-url,#display-visual-image-url,' +
'#background-image-url,#background-video-url';
var scheduled = false;
function scan() {
scheduled = false;
var list = document.querySelectorAll(SELECTOR);
for (var i = 0; i < list.length; i++) addButton(list[i]);
}
new MutationObserver(function () {
if (!scheduled) { scheduled = true; requestAnimationFrame(scan); }
}).observe(document.documentElement, { childList: true, subtree: true });
})();