IONOS(viewer): NC33 IONOS delta — one commit per feature (HDNEXT-1585) - #46
Conversation
0d13802 to
b5991e1
Compare
Update: header layout fix for empty modal titleFolded a follow-up fix into Problem: when the modal Fix: add a scoped override in :deep(.modal-header .icons-menu) {
margin-inline-start: auto;
}It's a no-op when the name is shown (the full-width name leaves no free space for the auto margin) and right-aligns the menu when the name is hidden. The
|
There was a problem hiding this comment.
Pull request overview
This PR ports and reshapes the NC33 IONOS Viewer delta to support an “always show viewer” mode with a Default fallback handler, along with related modal header behavior and file list filtering/fallback behavior across the viewer and file action integration.
Changes:
- Add
always_show_viewerinitial-state/config plumbing and register a Default viewer handler used as a fallback when no specialized handler exists. - Adjust viewer modal title/header behavior to hide the filename for Default/image views while keeping header actions right-aligned.
- Refine viewer navigation/list building to support default-group fallback and broadened file inclusion/exclusion rules when always-show-viewer is enabled.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/views/Viewer.vue | Adds modal title logic, default-handler/group fallback, and updated folder-list filtering when always-show-viewer is enabled. |
| src/utils/livePhotoUtils.ts | Adjusts live-photo peer matching to tolerate non-string basenames. |
| src/services/Viewer.js | Registers the new Default handler alongside existing built-in handlers. |
| src/models/default.ts | Introduces the Default handler model keyed to the configured default mime type. |
| src/models/config.ts | Adds initial-state backed config module for always-show-viewer + default mime type. |
| src/files_actions/viewerAction.ts | Updates viewer file-action enablement behavior for always-show-viewer and folder exclusion. |
| src/components/Images.vue | Renders Default fallback when original image load fails and ensures loading state is ended. |
| src/components/Default.vue | Adds the Default fallback UI component for unsupported file types. |
| lib/Listener/LoadViewerScript.php | Provides initial state for always_show_viewer to the frontend based on app config. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| filteredFiles = fileList.filter(file => { | ||
| const mime = file?.mime | ||
| const isOfficeDocument = mime && OC.MimeTypeList.aliases[mime]?.startsWith('x-office') | ||
| const isPdf = mime && mime === 'application/pdf' | ||
|
|
||
| return mime && !isOfficeDocument && !isPdf | ||
| }) |
1c62269 to
8901600
Compare
Add an `always_show_viewer` app config value that, when enabled, makes the viewer open a generic Default component for any file whose mimetype has no dedicated handler, instead of refusing to open it. Includes: - the `always_show_viewer` app config value and a config module that exposes `alwaysShowViewer` / `defaultMimeType` to the frontend - the Default component (mimetype icon + basename), with proper text color, a Safari icon-width fix and a consistent title-color variable - registration of a default (`*/*`) viewer handler and the fallback wiring in Viewer.vue - folder exclusion in the viewer file action's `enabled` callback - previous/next navigation support for the default component enable via: ./occ config:app:set --value yes --type string viewer always_show_viewer Signed-off-by: Misha M.-Kupriyanov <kupriyanov@strato.de> Signed-off-by: Franziska Bath <franziska.bath@strato.de> Signed-off-by: Thomas Lehmann <t.lehmann@strato.de> Co-authored-by: Franziska Bath <franziska.bath@strato.de> Co-authored-by: Thomas Lehmann <t.lehmann@strato.de>
… view Extract the modal title into its own computed property and, when the always-show-viewer fallback is active, hide the file name in the modal header for the Default component and for images (where the name is already shown elsewhere). Signed-off-by: Misha M.-Kupriyanov <kupriyanov@strato.de> Signed-off-by: Franziska Bath <franziska.bath@strato.de> Co-authored-by: Franziska Bath <franziska.bath@strato.de>
Don't include directories as they can not be displayed. Note: including directories could also cause a follow-up error with certain directory structures which happen to include a directory named like a number (i.e. 123) because of sloppy, too broad type casting in fileUtils.ts's genFileInfo() accidentally converting such a folder name to a Number, which then can not be used in string comparisons. Filter the folder file list down to entries that actually carry a mime type, which excludes directories. Signed-off-by: Thomas Lehmann <t.lehmann@strato.de> Signed-off-by: Franziska Bath <franziska.bath@strato.de> Co-authored-by: Franziska Bath <franziska.bath@strato.de>
… preview When the always-show-viewer fallback is active, exclude office documents and PDFs from the folder file list so Collabora-handled files are not shown by the viewer. Signed-off-by: Franziska Bath <franziska.bath@strato.de>
…d image load == The cause Previously the code attempted to load a preview of an image. If loading this preview image failed it was attempted to load the original image. Load errors of images were only handled _once_. This meant that a load error for the original image was never handled, thus the viewer was still in loading state and showed a browser-dependant "broken image" replacement icon. == The fix Now further image load errors are handled too. In case the original fails too, the loading state is ended and a placeholder text is shown. The default preview component, which was introduced to show something for any mimetype if configured, is now also used as a fallback. Signed-off-by: Thomas Lehmann <t.lehmann@strato.de>
Coerce the compared basename to a string before calling startsWith(), so live-photo peer detection does not throw for files whose name is parsed as a number. Signed-off-by: Franziska Bath <franziska.bath@strato.de>
8901600 to
dda1717
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (3)
lib/Listener/LoadViewerScript.php:45
- IAppConfig::getAppValue requires (appId, key, default). Calling it with only (key, default) will not read the app config correctly and can fail at runtime. Use the viewer app id explicitly.
$alwaysShowViewer = $this->appConfig->getAppValue('always_show_viewer', 'no') === 'yes';
src/views/Viewer.vue:798
- This filter does not actually exclude directories: DAV directory entries typically have a non-empty mime (e.g.
httpd/unix-directory), somime && …will still include them. Usefile.type !== 'directory'(as used elsewhere in src/utils/fileUtils.ts) to reliably exclude folders from the slideshow list.
return mime && !isOfficeDocument && !isPdf
src/files_actions/viewerAction.ts:114
- When
alwaysShowVieweris enabled, the action becomes available without checking READ permission. This can expose a "View" action for items the user cannot read (or trigger avoidable errors). Keep the READ-permission requirement while still allowing any readable file type.
// Always enabled if configured so
if (configModule.alwaysShowViewer) {
// disable for folders
return !nodes.some(node => node.type === 'folder')
}
Summary
This is the folded variant of #45 — essentially the same IONOS viewer delta on the NC33 base
ionos-dev-v33, with the history reshaped to one commit per feature so it reads cleanly and isready to be proposed upstream to
nextcloud/viewer.Compared to #45 it additionally carries a small follow-up header-layout fix (see feature 2
below) and, for now, omits the recompiled assets — see the note at the bottom.
Features (6 commits)
always_show_viewerapp config, the config module, the Default component (+ its text-color / Safari-width /
title-color styling), default viewer registration, the fallback wiring in
Viewer.vue, folderexclusion in the file action's
enabledcallback, and prev/next navigation.the modal header for the Default component and for images. Also keeps the header actions
(play/pause, actions menu, close) right-aligned when the name is empty:
NcModalomits the.modal-header__nameelement behindv-if, and its.modal-headerrelies on that full-widthname to push
.icons-menuright via flexspace-between(nomargin-left: autofallback), sowithout it the actions collapsed to the left. Fixed with a scoped
:deep(.modal-header .icons-menu) { margin-inline-start: auto; }— a no-op when the name isshown, right-aligning when it is hidden.
Authorship across the folded commits is preserved via
Co-authored-by+Signed-off-bytrailers.Relationship to #45
Supersedes-in-spirit #45, but both are intentionally left open so reviewers can compare the
granular history (#45) against this folded, upstream-ready shape.
Assets
The
chore(assets): recompile viewer assets for NC33 deltacommit has been dropped from thisbranch. The compiled
js//css/assets still need to be rebuilt and re-committed to reflectthe source changes (notably the header-layout fix in feature 2) before this is merged.
CI note
static-psalm-analysisfails on a pre-existing base issue unrelated to this delta: the psalm jobpulls
nextcloud/ocp dev-master, which now requires PHP ~8.3, while the vanillacomposer.jsonconfig.platform.phpis8.2. This affects any viewer fork PR until the base bumps the platform pin.Jira: HDNEXT-1585