Ein Freigabeordner enthält ein Angebot, eine Rechnung und mehrere Hörproben. Welcher nächste Schritt passt zur gerade geöffneten Datei? Der Ordnername allein beantwortet das nicht. Er kann „Angebot“ heißen, während im Viewer längst die Rechnung steht.
Bei individuellen Nextcloud-Oberflächen ist diese Grenze besonders wichtig. Das Theme kennt seinen Viewer. Die Regelverwaltung sollte trotzdem an einer zentralen Stelle liegen. Dafür habe ich NextInject um einen expliziten Vertrag für Theme-Adapter ergänzt.
Drei Zuständigkeiten
Nextcloud entscheidet über Dateizugriff und Freigaberechte. Das Share-Frontend stellt Dateien dar und kennt die geöffnete Ansicht. NextInject wertet die administrativ gepflegten Regeln aus und liefert passende Kennzeichnungen und Aktionslinks.
Ein Custom Theme muss damit keine zweite Angebots-/Rechnungslogik mitbringen. Die fachliche Aktion hinter einem Link bleibt ein eigener Prozess: Eine sichtbare Aktion sagt noch nichts darüber aus, ob ein Auftrag angenommen oder eine Nachricht übermittelt wurde.

Den geöffneten Dateikontext ausdrücklich melden
Der Adapter meldet beim Öffnen eine Datei und beim Schließen das Ende des Viewer-Kontexts. Dieses vereinfachte Beispiel verwendet den Event-Vertrag aus NextInject 2.1.8:
window.dispatchEvent(new CustomEvent('nextinject:context-changed', {
detail: {
viewerOpen: true,
fileName: 'Projekt_AN.pdf',
dir: '/Unterlagen',
contextLabel: 'Beispielprojekt',
},
}));
// Nach dem Schließen:
window.dispatchEvent(new CustomEvent('nextinject:context-changed', {
detail: {
viewerOpen: false,
fileName: null,
dir: '/Unterlagen',
contextLabel: 'Beispielprojekt',
},
}));
Ein geöffneter Viewer hat Vorrang. Ohne Viewer folgt der aktuelle Ordner, danach der Share-Kontext. Ein offener Viewer ohne Dateinamen erzeugt keine Aktion. Dadurch wird eine alte Angebotsaktion nicht versehentlich als Ersatz für einen noch unbestimmten Viewerinhalt verwendet.
Der Vertrag muss bei jedem eigenen Öffnen, Dateiwechsel und Schließen bedient werden. Ein Wechsel über History-Navigation setzt den Theme-Kontext zurück. Ein einmaliger Aufruf beim Seitenstart reicht deshalb nicht.
Aktionen aus der Rückmeldung übernehmen
Nach einer wirksamen Aktualisierung sendet NextInject nextinject:updated. Die Rückmeldung enthält Kontext, aktive Regel und die aktuell gültigen Links. Der Adapter übernimmt diese Links, statt URLs aus Dateinamen noch einmal selbst zusammenzusetzen.
window.addEventListener('nextinject:updated', ({ detail }) => {
const offerOpen = detail.context?.viewerOpen === true
&& detail.activeRule?.badgePreset === 'angebot';
// Eigene UI aktualisieren. Alte Links vor dem Dateiwechsel entfernen;
// neue nur aus der zur aktuellen Datei passenden Rückmeldung übernehmen.
renderContextActions(offerOpen ? detail.actions : []);
});
renderContextActions steht hier für die eigene UI-Funktion, nicht für eine eingebaute NextInject-Methode. Der Event-Listener darf aus seiner Darstellung heraus nicht erneut denselben Kontext melden: Sonst wird aus einer Aktualisierung eine Rückkopplungsschleife. Links werden angeboten, niemals automatisch aufgerufen.
Eigene Dateizeilen brauchen einen klaren Badge-Platz
Ein zweiter kleiner Vertrag betrifft Dateizeilen. Das Theme kann einen Dateinamen und einen reservierten Host für die Kennzeichnung anbieten:
<div data-nextinject-file-name="Projekt_AN.pdf">
<button type="button">Projekt_AN.pdf</button>
<span data-nextinject-badge-host></span>
</div>
NextInject befüllt den vorgesehenen Host. Das funktioniert auch, wenn dieselbe Datei gleichzeitig in einer Liste und einer Seitenleiste vorkommt. Die zentrale Regel entscheidet; die Oberflächen steuern nur Abstand und Darstellung des reservierten Bereichs.
Die interessanten Tests sind die Übergänge
Ein sichtbarer Angebotsknopf ist der einfache Fall. Wichtiger sind die Wechsel:
- Vom Angebot zur Rechnung: Der alte Angebotslink verschwindet sofort.
- Vom Viewer zurück in den Ordner: Der Ordner-/Share-Kontext gilt wieder.
- Ein offener Viewer mit noch fehlendem Dateinamen: Keine Ersatzaktion aus dem Share-Titel.
- Eine neu aufgebaute Dateizeile: Ein expliziter Scanwunsch aktualisiert die Kennzeichnungen, ohne den Viewer-Kontext zu ändern.
- Ein unveränderter Zustand: Keine unendliche Eventfolge.
Die NextInject-Quellen und der dokumentierte Adaptervertrag sind die Referenz für die konkreten Felder. Die App deklariert ab 2.1.8 Nextcloud 31 bis 35; diese Deklaration ersetzt keinen Test jeder Kombination aus Server, Theme und weiteren Apps.
Gestaltung und Integration getrennt betrachten
Die Wolkano-Galerie zeigt gestaltete Kundenfreigaben mit eigenen Beispieldateien. Für die kommerzielle Frage, welche Oberfläche und welche zusätzlichen Abläufe gebraucht werden, ist der Wolkano-Themenbereich der passende Einstieg.
Hier auf TOSA geht es um die technische Grenze: Ein Theme meldet seinen Zustand; die zentrale App liefert die passende Aktion. Wie mehrere vollständige Share-Frontends ausgewählt werden, beschreibt der Beitrag Nextcloud-Themes über System-Tags auswählen.