photoprism/internal/entity/search/viewer/result.go
Ömer Duran 3ea547a564
Lightbox: Add support for 360° photos and videos #352 #4718 #5623
* Lightbox: Add 360° photo and video sphere viewer support

Wires Photo Sphere Viewer v5 into the lightbox for equirectangular
media. Backend detects UsePanoramaViewer and IsPhotosphere markers
alongside ProjectionType, and exposes Panorama + Projection in the
viewer / search result DTOs so the frontend can dispatch on the
projection type. The renderer (ThreeJS + PSV core + video plugin +
equirectangular video adapter) is lazy-loaded into a dedicated
webpack chunk so the base bundle is unchanged for users with no
360° media. PhotoPrism's existing lightbox controls drive the
underlying HTMLVideoElement that the PSV adapter creates for 360°
videos. Includes Vitest coverage for the sphere helper and the
lightbox dispatch, plus a TestCafe smoke spec and three new
ExifTool metadata fixtures.

* Lightbox: Fix 360° controls leak, hide zoom button, add sidebar icon

* Lightbox: Fix 360° touch panning and navigation arrows

* Lightbox: Fix fast swipe switching photos on 360° slides

Suppress PhotoSwipe swipe/drag navigation at its source via the dispatched pointer hook while a sphere slide is active, since the per-element gesture trap is outrun by a fast swipe whose pointer leaves the sphere container (touch-capable Windows). UI controls stay excluded so buttons and arrows still navigate.

* Lightbox: Route only equirectangular media to the 360° viewer

Routing was based on the loose photo_panorama flag for videos, which is also
true for cubemap and merely-wide (aspect > 1.9) videos, so non-equirectangular
media wrongly opened, distorted, in the sphere viewer. Route strictly on the
equirectangular projection for both photos and videos. Surface the video file's
projection in the viewer DTO via Photo.MediaProjection() (the primary search row
is a poster JPEG with no projection). Add an MP4 metadata-detection test.

* Lightbox: Open tagless 2:1 360° videos in the sphere viewer

Many 360° videos carry no projection tag PhotoPrism can read, so strict
equirectangular-projection routing left them in the flat player. Fall back to
equirectangular's defining 2:1 frame for panorama-flagged videos without a
projection, via is360Equirectangular() in common/sphere.js, while cubemap and
ultrawide (~2.35:1) clips stay flat.

* Tests: Make the 360° sphere video test assert instead of skipping
2026-06-17 03:26:25 +02:00

34 lines
1.2 KiB
Go

package viewer
import (
"time"
"github.com/photoprism/photoprism/internal/thumb"
)
// Result represents a photo viewer result.
type Result struct {
UID string `json:"UID"`
Type string `json:"Type,omitempty"`
Title string `json:"Title,omitempty"`
Caption string `json:"Caption,omitempty"`
Lat float64 `json:"Lat,omitempty"`
Lng float64 `json:"Lng,omitempty"`
TakenAtLocal time.Time `json:"TakenAtLocal"`
TimeZone string `json:"TimeZone,omitempty"`
Favorite bool `json:"Favorite"`
Playable bool `json:"Playable"`
Panorama bool `json:"Panorama,omitempty"`
Projection string `json:"Projection,omitempty"`
Duration time.Duration `json:"Duration,omitempty"`
Width int `json:"Width"`
Height int `json:"Height"`
Hash string `json:"Hash"`
Codec string `json:"Codec,omitempty"`
Mime string `json:"Mime,omitempty"`
Thumbs *thumb.Viewer `json:"Thumbs,omitempty"`
DownloadUrl string `json:"DownloadUrl,omitempty"`
}
// Results represents a list of viewer search results.
type Results []Result