fix(office): PDF am Telefon nur bei OnlyOffice, Collabora behält den Editor

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 <noreply@anthropic.com>
This commit is contained in:
marcandClaude Opus 5 committed 2026-09-01 01:07:08 +02:00
1 parent 065372359b
commit 6c53651568
6 files changed
+57 -17

No files matched your search

+21 -9
View File
@@ -654,18 +654,30 @@ Abbild.
> über `{"payload": …}`) kommt das Ergebnis. Der Schlüssel gehört also > über `{"payload": …}`) kommt das Ergebnis. Der Schlüssel gehört also
> gesetzt – sonst läuft die API offen. > 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, Tippt man mit dem **Finger** auf ein Office-Dokument, hängt es vom Anbieter ab,
sondern das Dokument als PDF im eigenen Betrachter. „Edit" in der Kopfzeile was aufgeht:
führt trotzdem hinein. Mit **Maus** ändert sich nichts.
Der Grund ist keine Geschmacksfrage: Der Web-Editor ist eine vollständige | Anbieter | am Telefon |
Textverarbeitung, und zwischen Menüband, Formatleisten und |---|---|
| **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. Eigenschaftenbereich bleibt auf 400 Pixeln vom Dokument ein Rechteck übrig.
Das gilt für Collabora wie für OnlyOffice – beide ausprobiert, dasselbe Bild. Collabora hat für kleine Schirme eine eigene Ansicht und braucht den Umweg
Unterwegs ist der Anlass fast immer *nachsehen*, und dafür ist ein PDF das nicht.
bessere Werkzeug.
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 Gewandelt wird von **demselben** Server, der auch bearbeitet: Wer OnlyOffice
wegen der Treue zu MS-Office-Formaten nimmt, soll unterwegs nicht ein wegen der Treue zu MS-Office-Formaten nimmt, soll unterwegs nicht ein
+10
View File
@@ -396,6 +396,16 @@ func main() {
// Damit die Oberflaeche den Menuepunkt „Edit in Office" gar nicht // Damit die Oberflaeche den Menuepunkt „Edit in Office" gar nicht
// erst anbietet, wenn es keinen Office-Server gibt. // erst anbietet, wenn es keinen Office-Server gibt.
"office_enabled": officeHandler.Enabled(), "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 // Damit der Verlaufs-Dialog dieselbe Zahl nennt, die der Server
// anwendet. Vorher stand sie zweimal im Quelltext, mit einem // anwendet. Vorher stand sie zweimal im Quelltext, mit einem
// Kommentar „muss zusammenpassen" – das ist keine Zusicherung. // Kommentar „muss zusammenpassen" – das ist keine Zusicherung.
+2 -1
View File
@@ -273,7 +273,8 @@ Geplante Ideen (noch nicht umgesetzt):
- Glasmorphismus-Theme (transluzente Sidebar/Cards mit Blur-Effekt) - Glasmorphismus-Theme (transluzente Sidebar/Cards mit Blur-Effekt)
- Logo und App-Symbol bereits in Phase 4.5/D umgesetzt - 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. - **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). - **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/<id>.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. - **Je Datei gibt es genau ein PDF, und das ist keine Frage des Aufräumens, sondern des Schlüssels:** `previews/<id>.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.
+2
View File
@@ -225,6 +225,8 @@ export interface PublicConfig {
/** Gibt es einen Office-Server? Sonst bietet das Menue das Bearbeiten gar /** Gibt es einen Office-Server? Sonst bietet das Menue das Bearbeiten gar
* nicht erst an – ein Punkt, der immer scheitert, ist schlimmer als keiner. */ * nicht erst an – ein Punkt, der immer scheitert, ist schlimmer als keiner. */
office_enabled?: boolean office_enabled?: boolean
/** 'collabora' | 'onlyoffice' | '' – entscheidet über die Handy-Ansicht. */
office_provider?: string
/** Wie viele frühere Fassungen der Server aufhebt (MAX_VERSIONS_KEPT). */ /** Wie viele frühere Fassungen der Server aufhebt (MAX_VERSIONS_KEPT). */
max_versions_kept?: number max_versions_kept?: number
/** Beschriftung des SSO-Knopfes (OIDC_BUTTON_LABEL). Leer, wenn OIDC aus ist. */ /** Beschriftung des SSO-Knopfes (OIDC_BUTTON_LABEL). Leer, wenn OIDC aus ist. */
+12 -1
View File
@@ -25,6 +25,14 @@ interface AppSettingsValue {
globalColors: { primary?: string; accent?: string } globalColors: { primary?: string; accent?: string }
/** Gibt es einen Office-Server? Steuert nur, ob der Menuepunkt erscheint. */ /** Gibt es einen Office-Server? Steuert nur, ob der Menuepunkt erscheint. */
officeEnabled: boolean 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 /** Wie viele frühere Fassungen der Server aufhebt. Kommt vom Server, damit
* der Dialog nicht eine andere Zahl nennt als die, die angewendet wird. */ * der Dialog nicht eine andere Zahl nennt als die, die angewendet wird. */
maxVersionsKept: number maxVersionsKept: number
@@ -34,6 +42,7 @@ interface AppSettingsValue {
const Ctx = createContext<AppSettingsValue>({ const Ctx = createContext<AppSettingsValue>({
cloudName: 'Aether', cloudName: 'Aether',
officeEnabled: false, officeEnabled: false,
officeProvider: '',
maxVersionsKept: 5, maxVersionsKept: 5,
logoUrl: '', logoUrl: '',
faviconUrl: '', faviconUrl: '',
@@ -89,6 +98,7 @@ export function AppSettingsProvider({ children }: { children: ReactNode }) {
const [appIconUrl, setAppIconUrl] = useState('') const [appIconUrl, setAppIconUrl] = useState('')
const [globalColors, setGlobalColors] = useState<{ primary?: string; accent?: string }>({}) const [globalColors, setGlobalColors] = useState<{ primary?: string; accent?: string }>({})
const [officeEnabled, setOfficeEnabled] = useState(false) const [officeEnabled, setOfficeEnabled] = useState(false)
const [officeProvider, setOfficeProvider] = useState('')
const [maxVersionsKept, setMaxVersionsKept] = useState(5) const [maxVersionsKept, setMaxVersionsKept] = useState(5)
const refresh = useCallback(async () => { const refresh = useCallback(async () => {
@@ -101,6 +111,7 @@ export function AppSettingsProvider({ children }: { children: ReactNode }) {
applyFavicon(cfg.favicon_url ?? '', cfg.apple_touch_icon_url ?? '') applyFavicon(cfg.favicon_url ?? '', cfg.apple_touch_icon_url ?? '')
setGlobalColors({ primary: cfg.primary_color, accent: cfg.accent_color }) setGlobalColors({ primary: cfg.primary_color, accent: cfg.accent_color })
setOfficeEnabled(!!cfg.office_enabled) setOfficeEnabled(!!cfg.office_enabled)
setOfficeProvider(cfg.office_provider ?? '')
if (typeof cfg.max_versions_kept === 'number' && cfg.max_versions_kept > 0) { if (typeof cfg.max_versions_kept === 'number' && cfg.max_versions_kept > 0) {
setMaxVersionsKept(cfg.max_versions_kept) setMaxVersionsKept(cfg.max_versions_kept)
} }
@@ -116,7 +127,7 @@ export function AppSettingsProvider({ children }: { children: ReactNode }) {
useEffect(() => { void refresh() }, [refresh]) useEffect(() => { void refresh() }, [refresh])
return ( return (
<Ctx.Provider value={{ cloudName, logoUrl, faviconUrl, appIconUrl, globalColors, officeEnabled, maxVersionsKept, refresh }}>{children}</Ctx.Provider> <Ctx.Provider value={{ cloudName, logoUrl, faviconUrl, appIconUrl, globalColors, officeEnabled, officeProvider, maxVersionsKept, refresh }}>{children}</Ctx.Provider>
) )
} }
+10 -6
View File
@@ -153,7 +153,7 @@ export default function FileBrowser({
const [officePreview, setOfficePreview] = useState<FileItem | null>(null) const [officePreview, setOfficePreview] = useState<FileItem | null>(null)
/** Datei, die gerade im Office-Server bearbeitet wird. */ /** Datei, die gerade im Office-Server bearbeitet wird. */
const [editing, setEditing] = useState<FileItem | null>(null) const [editing, setEditing] = useState<FileItem | null>(null)
const { officeEnabled } = useAppSettings() const { officeEnabled, officeProvider } = useAppSettings()
/** Finger oder Maus? Entscheidet, ob ein Office-Dokument als PDF oder im /** Finger oder Maus? Entscheidet, ob ein Office-Dokument als PDF oder im
* Editor aufgeht. */ * Editor aufgeht. */
const touchDevice = useCoarsePointer() const touchDevice = useCoarsePointer()
@@ -316,15 +316,19 @@ export default function FileBrowser({
*/ */
function openFile(file: FileItem) { function openFile(file: FileItem) {
if (officeEnabled && isOfficeFile(file.name)) { if (officeEnabled && isOfficeFile(file.name)) {
// Am Telefon zuerst ansehen, nicht bearbeiten. Der Editor ist dort eine // **Nur bei OnlyOffice** öffnet ein Dokument am Telefon als PDF.
// vollständige Textverarbeitung; zwischen Menüband, Formatleisten und //
// Eigenschaftenbereich bleibt vom Dokument ein Rechteck. Gilt für // Der Unterschied ist gemessen, nicht vermutet: Collabora bringt eine
// Collabora wie für OnlyOffice – beide ausprobiert, dasselbe Bild. // 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: // Die Entscheidung fällt am **Zeigegerät**, nicht an der Fensterbreite:
// Ein schmales Fenster auf dem Schreibtisch ist immer noch eine Maus // Ein schmales Fenster auf dem Schreibtisch ist immer noch eine Maus
// und eine Tastatur, und dort will man bearbeiten. // und eine Tastatur, und dort will man bearbeiten.
if (touchDevice) setOfficePreview(file) if (touchDevice && officeProvider === 'onlyoffice') setOfficePreview(file)
else setEditing(file) else setEditing(file)
return return
} }