Skip to content

feat: allow handlers to claim individual files via canHandle matcher - #1

Open
R0Wi wants to merge 2 commits into
masterfrom
claude/photosphere-viewer-integration-okhhlg
Open

feat: allow handlers to claim individual files via canHandle matcher#1
R0Wi wants to merge 2 commits into
masterfrom
claude/photosphere-viewer-integration-okhhlg

Conversation

@R0Wi

@R0Wi R0Wi commented Jul 8, 2026

Copy link
Copy Markdown
Owner

Handlers can now provide an optional canHandle(fileInfo) callback. Such
handlers do not own their mime types exclusively: they claim individual
files at opening time, taking precedence over the handler the mime type
is registered to. This allows apps to provide a specialised view for a
subset of files sharing a generic mime type, e.g. 360° photospheres
within image/jpeg (nextcloud/files_photospheres#27).

Per-file matching is applied when opening a file as well as when
navigating through a slideshow (previous/next/compare), so the viewer
switches components per file. Custom WebDAV properties registered via
registerDavProperty are available on the file info passed to the
matcher (camelCased).

Also exposes the new handler property through the @nextcloud/viewer api
package (bumped to 1.1.0) including documentation.

Co-Authored-By: Claude Fable 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01ARx3GZy5CQBsWUCPEp7mrL

claude added 2 commits July 8, 2026 20:35
Handlers can now provide an optional canHandle(fileInfo) callback. Such
handlers do not own their mime types exclusively: they claim individual
files at opening time, taking precedence over the handler the mime type
is registered to. This allows apps to provide a specialised view for a
subset of files sharing a generic mime type, e.g. 360° photospheres
within image/jpeg (nextcloud/files_photospheres#27).

Per-file matching is applied when opening a file as well as when
navigating through a slideshow (previous/next/compare), so the viewer
switches components per file. Custom WebDAV properties registered via
registerDavProperty are available on the file info passed to the
matcher (camelCased).

Also exposes the new handler property through the @nextcloud/viewer api
package (bumped to 1.1.0) including documentation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ARx3GZy5CQBsWUCPEp7mrL
Moves the photosphere functionality of the files_photospheres app
(nextcloud/files_photospheres#27) directly into the viewer, so that
360° media works out of the box.

Recognition: a Sabre plugin scans the first bytes of jpeg files for
Google Photo Sphere XMP metadata (GPano, incl. VR180) and serves the
result — cached via ICacheFactory — as the WebDAV property
{http://nextcloud.org/ns}viewer-photosphere-metadata, which is
requested with every files PROPFIND via registerDavProperty. The
built-in 'photospheres' handler claims exactly those image/jpeg files
whose metadata marks them as photospheres through the per-file
canHandle() matcher, so regular images keep using the image handler
and slideshow navigation switches seamlessly between flat images and
panoramas. Cropping/pose data (panoData) is honored.

Rendering is based on photo-sphere-viewer (lazy-loaded chunk) with
gyroscope, stereo and autorotate support. 360° videos have no
detectable server-side metadata, so they are opened explicitly through
a new "View in 360°" file action using an equirectangular video
adapter.

The feature is optional: administrators can disable it under
Settings -> Administration -> Additional settings (app config value
photospheres_enabled, enabled by default). When disabled, the Sabre
plugin, the DAV property registration, the handlers and the file
action are all inactive.

Includes a cypress e2e test with a real photosphere fixture, psalm
stubs for the sabre/OCA\DAV classes, and the PHP metadata reader was
verified against the complete files_photospheres test corpus.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ARx3GZy5CQBsWUCPEp7mrL
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants