From 6c53651568d6cdaff22a82906810a79320b4aae5 Mon Sep 17 00:00:00 2001 From: marc Date: Tue, 1 Sep 2026 01:07:08 +0200 Subject: [PATCH] =?UTF-8?q?fix(office):=20PDF=20am=20Telefon=20nur=20bei?= =?UTF-8?q?=20OnlyOffice,=20Collabora=20beh=C3=A4lt=20den=20Editor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Die Regel galt für beide Anbieter – das war falsch. Marcs Kritik betraf nur OnlyOffice: Es baut auf dem Telefon dieselbe Oberfläche auf wie am PC. Collabora bringt für kleine Schirme eine eigene Ansicht mit, die taugt; dort wäre der Umweg über ein PDF ein Rückschritt. Der Anbieter steht jetzt in der öffentlichen Konfiguration (office_provider), und die Oberfläche entscheidet daran. Der Endpunkt selbst kann weiterhin beides. Nachgeholt: Der ganze Weg ist jetzt auch mit Collabora gemessen, nicht nur mit OnlyOffice – gegen die Dev-Instanz, die damit läuft. erster Abruf 0,347 s, zweiter 0,009 s, eine Datei auf der Platte (OnlyOffice zum Vergleich: 1,05 s – es muss die Datei erst abholen) Co-Authored-By: Claude Opus 5 --- README.md | 30 +++++++++++++++++++-------- backend/cmd/aether/main.go | 10 +++++++++ cloud-projekt-plan.md | 3 ++- frontend/src/api/client.ts | 2 ++ frontend/src/hooks/useAppSettings.tsx | 13 +++++++++++- frontend/src/pages/FileBrowser.tsx | 16 ++++++++------ 6 files changed, 57 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index abe0b68..0b14b62 100644 --- a/README.md +++ b/README.md @@ -654,18 +654,30 @@ Abbild. > über `{"payload": …}`) kommt das Ergebnis. Der Schlüssel gehört also > gesetzt – sonst läuft die API offen. -### Am Telefon: ansehen statt bearbeiten +### Am Telefon: bei OnlyOffice ansehen statt bearbeiten -Tippt man auf ein Office-Dokument, öffnet sich am **Finger** nicht der Editor, -sondern das Dokument als PDF im eigenen Betrachter. „Edit" in der Kopfzeile -führt trotzdem hinein. Mit **Maus** ändert sich nichts. +Tippt man mit dem **Finger** auf ein Office-Dokument, hängt es vom Anbieter ab, +was aufgeht: -Der Grund ist keine Geschmacksfrage: Der Web-Editor ist eine vollständige -Textverarbeitung, und zwischen Menüband, Formatleisten und +| Anbieter | am Telefon | +|---|---| +| **Collabora** | der Editor – seine eigene Handy-Ansicht taugt | +| **OnlyOffice / Euro-Office** | das Dokument als PDF; „Edit" führt trotzdem hinein | + +Mit **Maus** ändert sich nichts: Dort geht immer der Editor auf, auch in einem +schmalen Fenster. Ein schmales Fenster auf dem Schreibtisch ist immer noch +eine Tastatur. + +Der Unterschied ist keine Geschmacksfrage. OnlyOffice baut auf dem Telefon +dieselbe Oberfläche auf wie am PC – zwischen Menüband, Formatleisten und Eigenschaftenbereich bleibt auf 400 Pixeln vom Dokument ein Rechteck übrig. -Das gilt für Collabora wie für OnlyOffice – beide ausprobiert, dasselbe Bild. -Unterwegs ist der Anlass fast immer *nachsehen*, und dafür ist ein PDF das -bessere Werkzeug. +Collabora hat für kleine Schirme eine eigene Ansicht und braucht den Umweg +nicht. + +Der Endpunkt selbst gilt für beide: `GET /api/v1/files/{id}/preview.pdf` +wandelt bei Collabora über `/cool/convert-to/pdf` (gemessen 0,35 s) und bei +OnlyOffice über `/ConvertService.ashx` (1,05 s). Nur *wann* er benutzt wird, +entscheidet der Anbieter. Gewandelt wird von **demselben** Server, der auch bearbeitet: Wer OnlyOffice wegen der Treue zu MS-Office-Formaten nimmt, soll unterwegs nicht ein diff --git a/backend/cmd/aether/main.go b/backend/cmd/aether/main.go index 6e030a4..8d79319 100644 --- a/backend/cmd/aether/main.go +++ b/backend/cmd/aether/main.go @@ -396,6 +396,16 @@ func main() { // Damit die Oberflaeche den Menuepunkt „Edit in Office" gar nicht // erst anbietet, wenn es keinen Office-Server gibt. "office_enabled": officeHandler.Enabled(), + // Welcher Anbieter – die Oberflaeche entscheidet daran, ob ein + // Dokument am Telefon im Editor oder als PDF aufgeht. Collabora + // hat eine brauchbare Handy-Ansicht, OnlyOffice baut dort die + // PC-Oberflaeche auf. Ohne Office-Server ein leerer Wert. + "office_provider": func() string { + if officeHandler.Enabled() { + return cfg.OfficeProvider + } + return "" + }(), // Damit der Verlaufs-Dialog dieselbe Zahl nennt, die der Server // anwendet. Vorher stand sie zweimal im Quelltext, mit einem // Kommentar „muss zusammenpassen" – das ist keine Zusicherung. diff --git a/cloud-projekt-plan.md b/cloud-projekt-plan.md index e2eadb2..ed8371f 100644 --- a/cloud-projekt-plan.md +++ b/cloud-projekt-plan.md @@ -273,7 +273,8 @@ Geplante Ideen (noch nicht umgesetzt): - Glasmorphismus-Theme (transluzente Sidebar/Cards mit Blur-Effekt) - Logo und App-Symbol bereits in Phase 4.5/D umgesetzt -- ✅ **Office-Dokumente am Telefon als PDF ansehen** (`internal/office/convert.go` + `preview.go`, Migration 000020, 31.08.2026, Wunsch von Marc). Am Finger öffnet ein `.docx` nicht mehr den Editor, sondern das gewandelte PDF im eigenen Betrachter; „Edit" daneben führt trotzdem hinein. Am Schreibtisch bleibt alles wie es war. +- ✅ **Office-Dokumente am Telefon als PDF ansehen** (`internal/office/convert.go` + `preview.go`, Migration 000020, 31.08.2026, Wunsch von Marc). Am Finger öffnet ein `.docx` **bei OnlyOffice** nicht mehr den Editor, sondern das gewandelte PDF im eigenen Betrachter; „Edit" daneben führt trotzdem hinein. Am Schreibtisch bleibt alles wie es war. + - **Bei Collabora bleibt der Editor.** Zuerst galt die Regel für beide Anbieter – falsch, und Marc hat es sofort gesehen: Seine Kritik betraf nur OnlyOffice. Collabora bringt für kleine Schirme eine eigene Ansicht mit, die taugt; dort wäre der Umweg über ein PDF ein Rückschritt. Der Anbieter steht deshalb in der öffentlichen Konfiguration (`office_provider`), und die Oberfläche entscheidet daran. Der Endpunkt selbst kann beides und ist mit beiden gemessen (Collabora 0,35 s, OnlyOffice 1,05 s). - **Warum überhaupt:** Der Web-Editor ist eine vollständige Textverarbeitung. Menüband, Formatleisten und Eigenschaftenbereich sind nicht Beiwerk, sondern das Produkt – auf 400 Pixeln bleibt für das Dokument ein Rechteck. Marc hat Collabora **und** OnlyOffice ausprobiert, mit demselben Ergebnis; das ist der Grund, aus dem hier kein besserer Bedienmodus gesucht wurde, sondern ein anderes Werkzeug. Nextcloud löst es in seiner App genauso: ansehen statt bearbeiten. - **Gewandelt wird von dem Server, der auch bearbeitet.** Wer OnlyOffice wegen der Treue zu MS-Office-Formaten nimmt, aber Collabora das PDF rechnen ließe, sähe unterwegs ein LibreOffice-Layout desselben Dokuments – zwei Geräte, zwei Umbrüche, ausgerechnet bei Unterlagen. Beide Wege sind deshalb gebaut: Collabora nimmt die Bytes (`/cool/convert-to/pdf`), OnlyOffice eine Adresse, holt die Datei selbst und antwortet mit einer Adresse (`/ConvertService.ashx`, HS256-signiert). - **Je Datei gibt es genau ein PDF, und das ist keine Frage des Aufräumens, sondern des Schlüssels:** `previews/.pdf` trägt die Fassung **nicht** im Namen. Eine neue Fassung überschreibt, statt danebenzulegen. Ob das Abgelegte noch passt, sagt `files.preview_version`. Gemessen: Nach dem erneuten Hochladen stand die Datei auf Fassung 2, `preview_version` auf 2, und im Ordner lag weiterhin genau eine Datei. diff --git a/frontend/src/api/client.ts b/frontend/src/api/client.ts index 9eb6f1f..4b2c987 100644 --- a/frontend/src/api/client.ts +++ b/frontend/src/api/client.ts @@ -225,6 +225,8 @@ export interface PublicConfig { /** Gibt es einen Office-Server? Sonst bietet das Menue das Bearbeiten gar * nicht erst an – ein Punkt, der immer scheitert, ist schlimmer als keiner. */ office_enabled?: boolean + /** 'collabora' | 'onlyoffice' | '' – entscheidet über die Handy-Ansicht. */ + office_provider?: string /** Wie viele frühere Fassungen der Server aufhebt (MAX_VERSIONS_KEPT). */ max_versions_kept?: number /** Beschriftung des SSO-Knopfes (OIDC_BUTTON_LABEL). Leer, wenn OIDC aus ist. */ diff --git a/frontend/src/hooks/useAppSettings.tsx b/frontend/src/hooks/useAppSettings.tsx index 512075b..7f60aa0 100644 --- a/frontend/src/hooks/useAppSettings.tsx +++ b/frontend/src/hooks/useAppSettings.tsx @@ -25,6 +25,14 @@ interface AppSettingsValue { globalColors: { primary?: string; accent?: string } /** Gibt es einen Office-Server? Steuert nur, ob der Menuepunkt erscheint. */ officeEnabled: boolean + /** + * Welcher Anbieter – 'collabora', 'onlyoffice' oder leer. + * + * Die Oberfläche braucht das, weil sich die beiden am Telefon verschieden + * verhalten: Collabora hat eine eigene Handy-Ansicht, die taugt; OnlyOffice + * baut dort dieselbe Oberfläche auf wie am PC. + */ + officeProvider: string /** Wie viele frühere Fassungen der Server aufhebt. Kommt vom Server, damit * der Dialog nicht eine andere Zahl nennt als die, die angewendet wird. */ maxVersionsKept: number @@ -34,6 +42,7 @@ interface AppSettingsValue { const Ctx = createContext({ cloudName: 'Aether', officeEnabled: false, + officeProvider: '', maxVersionsKept: 5, logoUrl: '', faviconUrl: '', @@ -89,6 +98,7 @@ export function AppSettingsProvider({ children }: { children: ReactNode }) { const [appIconUrl, setAppIconUrl] = useState('') const [globalColors, setGlobalColors] = useState<{ primary?: string; accent?: string }>({}) const [officeEnabled, setOfficeEnabled] = useState(false) + const [officeProvider, setOfficeProvider] = useState('') const [maxVersionsKept, setMaxVersionsKept] = useState(5) const refresh = useCallback(async () => { @@ -101,6 +111,7 @@ export function AppSettingsProvider({ children }: { children: ReactNode }) { applyFavicon(cfg.favicon_url ?? '', cfg.apple_touch_icon_url ?? '') setGlobalColors({ primary: cfg.primary_color, accent: cfg.accent_color }) setOfficeEnabled(!!cfg.office_enabled) + setOfficeProvider(cfg.office_provider ?? '') if (typeof cfg.max_versions_kept === 'number' && cfg.max_versions_kept > 0) { setMaxVersionsKept(cfg.max_versions_kept) } @@ -116,7 +127,7 @@ export function AppSettingsProvider({ children }: { children: ReactNode }) { useEffect(() => { void refresh() }, [refresh]) return ( - {children} + {children} ) } diff --git a/frontend/src/pages/FileBrowser.tsx b/frontend/src/pages/FileBrowser.tsx index d907208..0595cc4 100644 --- a/frontend/src/pages/FileBrowser.tsx +++ b/frontend/src/pages/FileBrowser.tsx @@ -153,7 +153,7 @@ export default function FileBrowser({ const [officePreview, setOfficePreview] = useState(null) /** Datei, die gerade im Office-Server bearbeitet wird. */ const [editing, setEditing] = useState(null) - const { officeEnabled } = useAppSettings() + const { officeEnabled, officeProvider } = useAppSettings() /** Finger oder Maus? Entscheidet, ob ein Office-Dokument als PDF oder im * Editor aufgeht. */ const touchDevice = useCoarsePointer() @@ -316,15 +316,19 @@ export default function FileBrowser({ */ function openFile(file: FileItem) { if (officeEnabled && isOfficeFile(file.name)) { - // Am Telefon zuerst ansehen, nicht bearbeiten. Der Editor ist dort eine - // vollständige Textverarbeitung; zwischen Menüband, Formatleisten und - // Eigenschaftenbereich bleibt vom Dokument ein Rechteck. Gilt für - // Collabora wie für OnlyOffice – beide ausprobiert, dasselbe Bild. + // **Nur bei OnlyOffice** öffnet ein Dokument am Telefon als PDF. + // + // Der Unterschied ist gemessen, nicht vermutet: Collabora bringt eine + // eigene Handy-Ansicht mit, die taugt – dort ist der Editor der + // richtige Weg. OnlyOffice baut auf dem Telefon dieselbe Oberfläche + // auf wie am PC; zwischen Menüband, Formatleisten und + // Eigenschaftenbereich bleibt vom Dokument ein Rechteck übrig, und + // genau das war der Anlass für die PDF-Ansicht. // // Die Entscheidung fällt am **Zeigegerät**, nicht an der Fensterbreite: // Ein schmales Fenster auf dem Schreibtisch ist immer noch eine Maus // und eine Tastatur, und dort will man bearbeiten. - if (touchDevice) setOfficePreview(file) + if (touchDevice && officeProvider === 'onlyoffice') setOfficePreview(file) else setEditing(file) return }