3D Viewer - Releases

← App details

Nextcloud 33

3D Viewer 3.3.0
Release Details
UpdatedApril 20, 2026, 6:47 a.m.
Changelog

Fixed

  • 3DS files loaded tipped on their side when the exporter used Y-up instead of the 3ds-Max Z-up default. The loader had been hard-coded to rotate every 3DS model -90° around X (commit d8117a0, "fix: add coordinate system rotation corrections for Z-up formats"), which helped CAD-style Z-up files but silently broke Y-up exports — Cottage_FREE.3DS for example rendered with its long axis as the vertical. Dropped the unconditional rotation; 3DS files now pass through at their authored orientation. Most modern 3DS exporters (Blender, recent Maya) are already Y-up, and Z-up outliers can be fixed by orbiting or — if this becomes common — by a future user-facing orientation toggle. Other Z-up-rotating loaders (STL, PLY, 3MF, DAE) are unchanged because those formats have stronger Z-up conventions that are not affected by this fix. Reproduced and verified in the live Nextcloud container by downloading the user's 3DS via WebDAV, inspecting bbox dimensions with a new scripts/inspect-3ds.mjs harness (raw X=1243, Y=675, Z=1465 — Y is the height), and hard-refreshing the viewer page.
  • Standalone viewer: KTX2 loader threw on init with Cannot read properties of undefined (reading 'isWebGPURenderer'), so models with Basis/KTX2-compressed textures silently fell back to placeholder textures. Root cause: the standalone ThreeViewer.vue never forwarded the live WebGLRenderer into the loading context, and Three.js r182's KTX2Loader.detectSupport(renderer) dereferences renderer.isWebGPURenderer before checking anything else. Fix: pass renderer: renderer.value in the context, plus a defensive guard in gltf.js that skips KTX2 entirely (with a warning) when no renderer is available instead of throwing. The modal viewer was unaffected — it already forwarded this.renderer. Live-E2E harness now also watches for KTX2/WebGPU console complaints so the regression can't sneak back in.
  • Standalone viewer: glTF models with embedded data: buffers failed to load under Nextcloud's Content Security Policy. The app CSP allowed data: for img-src but not connect-src, so GLTFLoader's fetch() of embedded base64 buffers (the default export shape of many gltf files) was blocked by the browser. ResponseBuilder::addCspHeaders now also adds data: to connect-src. Caught end-to-end by driving Playwright against the real dev container (scripts/live-e2e-check.mjs).
  • Skip-to-viewer link wasn't in a usable tab position — it was rendered inside <NcContent><NcAppContent>, which put it ~9 tabs deep behind Nextcloud's header, nav sidebar, and file list. Wrapped in <Teleport to="body"> so the anchor lives at the body level regardless of where Nextcloud's chrome wraps us. DOM-verified focusable in the live container; clicking it moves focus to #viewer-wrapper. The CHANGELOG entry below that claims "first tab stop" was aspirational — Nextcloud's own Skip to main content / Skip to navigation links always win the first two positions, which is correct behavior we can't (and shouldn't) override.

Added

  • Four more CAD formats via OpenCascade — STEP, IGES, BREP, FCSTD (closes #97): All four formats come from the OCCT family of NURBS/B-Rep CAD files and share one WASM integration. Uses occt-import-js (Viktor Kovacs's purpose-built emscripten port of OpenCascade's import + tessellation) — much smaller than vanilla opencascade.js (~7 MB WASM vs 10+) and with a JSON-based mesh output that's a clean fit for Three.js. Architecture: one shared src/loaders/occt-runtime.js exposes getOcct() (memoized module promise so the 7 MB WASM downloads once across all 4 loaders) and buildGroupFromOccResult() (walks the assembly hierarchy preserving node names, transforms are already baked into tessellated vertices so we don't reapply matrices). Each format gets a thin ~25-line loader: STEP (.step, .stp) → ReadStepFile, IGES (.iges, .igs) → ReadIgesFile, BREP (.brep, .brp) → ReadBrepFile, FCSTD (FreeCAD document) → unzip via fflate, filter for .brep entries, feed each to ReadBrepFile — per-body failures don't take out the whole document. The resulting bundle shape: four 1 KB loader chunks + one 725 KB shared occt-runtime-*.chunk.mjs + 7.3 MB WASM served separately from /apps/threedviewer/occt/. Main/app bundles unchanged (0 B trend). Not unit-tested because the whole pipeline needs live WASM + real CAD fixtures to exercise meaningfully; covered by the existing smoke suite pattern.
  • Fifth new format — IFC (.ifc) (#97): Industry Foundation Classes, the de-facto BIM interchange standard. Loader in src/loaders/types/ifc.js uses ThatOpen's web-ifc WASM (~5 MB, lazy-loaded on first .ifc open) and a hand-written Three.js bridge — web-ifc-three has been deprecated and its modern replacement (@thatopen/components) is a heavy framework we don't need just for file loading. Bridge logic: StreamAllMeshes walks the IFC element graph, each FlatMesh's PlacedGeometry entries yield tessellated vertex data in interleaved [px,py,pz,nx,ny,nz] layout which we deinterleave into separate position/normal attributes, then apply flatTransformation (column-major 4×4) and per-geometry color. Express IDs (expressID, geometryExpressID) are preserved on mesh.userData.ifc for future property-panel tooling. Memory is carefully managed — geometry.delete() in a finally block releases the WASM-side handle per mesh, and CloseModel runs unconditionally so parse errors don't leak the full IFC model. WASM copies ship via scripts/copy-decoders.mjs to /apps/threedviewer/web-ifc/ (both single-threaded web-ifc.wasm and multi-threaded web-ifc-mt.wasm — IfcAPI picks the variant based on runtime feature detection) so air-gapped Nextcloud deploys don't need CDN reachability. JS glue is lazy-chunked into a 3.4 MB ifc-*.chunk.mjs that only loads when a user opens a .ifc file; main/app bundle impact is minimal. Not unit-tested because the whole pipeline requires live WASM + real IFC fixtures; covered by the smoke spec suite instead.
  • Fourth new format — dotbim (.bim) (#97): JSON-based BIM format from dotbim.net — simple schema (meshes + elements with { mesh_id, vector, rotation, guid, type, color, info, face_colors? }). Loader in src/loaders/types/dotbim.js handles mesh instancing (multiple elements sharing a mesh_id each get their own cloned geometry), element transforms (translation vector + unit quaternion rotation), RGBA byte colors, optional per-face colors (v1.1.0 schema — unindexes geometry so each triangle's 3 verts carry the face color), and tolerates legacy exporter quirks (missing/null rotation, mismatched face_colors length). Element metadata (guid, type, info) is stashed on mesh.userData.dotbim for future inspection tooling. 10 Jest specs in tests/unit/loaders/dotbim-parser.test.js cover instancing, transforms, color handling, transparency, legacy-rotation fallback, orphan elements, metadata, and JSON/schema validation error paths. Zero WASM, zero external deps, ~180 lines. Like the other new loaders it's lazy-chunked via the registry's dynamic imports — 0 B impact on the main/app bundles.
  • Three new 3D formats — OFF, AMF, 3DM (closes #97 partially): (1) .off (Geomview Object File Format) — hand-rolled plain-text parser in src/loaders/types/off.js covering OFF, COFF (per-vertex colors, float or 0–255 int), N-gon fan triangulation, inline # comments, and binary-OFF rejection. 9-test Jest suite exercises the parse path end-to-end (tetrahedron, n-gon, comments, COFF float/int colors, degenerate inputs). (2) .amf (Additive Manufacturing Format) — wraps three.js's bundled AMFLoader, handles both XML and ZIP-compressed variants. (3) .3dm (Rhinoceros) — wraps Rhino3dmLoader, loads rhino3dm.js + rhino3dm.wasm (~4 MB) on first use from the app's bundled copy at /apps/threedviewer/rhino3dm/ so air-gapped Nextcloud deployments don't need CDN reachability. scripts/copy-decoders.mjs now copies the rhino3dm assets alongside DRACO/Basis. All three formats are registered across the 5 sync points (lib/Constants/SupportedFormats.php, src/config/viewer-config.js, src/loaders/registry.js, src/main.js::SUPPORTED_MIMES, appinfo/mimetypemapping.json); npm run format:check PASS. Each loader is lazy-chunked via the registry's dynamic imports, so the main/app bundle size is unchanged (only users who open the new format pay the download cost). The 6 remaining formats from #97 (step, iges, brep, fcstd, ifc, bim) all require OpenCascade.js or web-ifc WASM (~5–10 MB each) and are deferred until demand justifies the bundle hit.
  • Forced-colors (Windows High Contrast) CSS hardening: New central override sheet (src/css/forced-colors.css, imported from main.js) scoped entirely to @media (forced-colors: active) — no effect on default rendering. Addresses three patterns the a11y audit found: (1) custom badges (.stats-badge, .fps-badge, .active-badge, .last-used-badge) that rely on background-color + text-color alone collapsed into the surrounding surface once the UA repainted both with system colors; they now get a 1px CanvasText border so they stay visible. (2) .filter-format-chip.active lost its visual distinction from the inactive state because both backgrounds became Canvas; the active variant now uses Highlight / HighlightText with forced-color-adjust: none so selection state survives. (3) Focus states that suppressed outline and relied on box-shadow or colored border-color (.export-select:focus, .annotation-text-input:focus, .skip-to-viewer:focus) had no visible focus indicator; they now re-enable a 2px Highlight outline. Verified by a new Playwright spec (tests/playwright/a11y-forced-colors.spec.ts, 5 tests) that loads the real CSS file into static fixtures mirroring each component shape and asserts border/outline width > 0 under emulateMedia({ forcedColors: 'active' }). Caveat: Playwright's forced-colors emulation uses a neutral palette — this closes the keyboard/CSS correctness gap but an interactive Windows HC walkthrough is still the final source of truth for theme-specific contrast issues.
  • i18n parity tooling (scripts/check-i18n.mjs): Walks src/ (.vue/.js/.ts) and lib/ (.php) and extracts every t('threedviewer', 'string'), this.t(...), and ->t(...) call via regex. Diffs the extracted set against l10n/en.json: ERROR on source strings missing from en.json, WARN on orphan keys no source uses, per-locale coverage summary that reports missing, passthrough (value === key), and orphan counts. --sync-en auto-adds missing keys (value = key); --prune removes orphans. Wired as npm run i18n:check / npm run i18n:sync; i18n:check is now part of the validate chain. First sync closed 329 missing keys and pruned 87 orphans in en.json — ar/de/es coverage now reports accurately at ~27% (previously looked higher only because en.json itself was incomplete).
  • Export pipeline unit tests + MIME consistency fix: Nine Jest specs in tests/unit/composables/useExport.test.js cover getGeometryStats (indexed, non-indexed, multi-mesh groups, non-geometry descendants) and exportAsSTL/exportAsOBJ/exportAsGLB (correct MIME — model/stl, model/obj, model/gltf-binary — correct byte length, null-object guards, and a multi-material OBJ scene that passes through the exporter with its material array and geometry groups intact instead of being flattened). Three.js exporters are mocked so the test runs deterministically in jsdom without pulling in Three's ESM-only subpath imports; the real exporter output remains covered by the Playwright smoke suite. Shipped alongside a MIME consistency fix in SlicerModal.vue — the slicer-export fallback path was still using application/octet-stream for STL and text/plain for OBJ even though the main Export Model path had been updated to model/stl / model/obj; both paths now agree.
  • Loader smoke-test coverage for cancel/retry/network-drop: Two new Playwright specs in tests/smoke/viewer.spec.ts use page.route() to deterministically simulate (a) a user cancelling a hanging load and then retrying — the second fetch is fulfilled with a fixture and the viewer reaches __LOAD_COMPLETE, and (b) a network failure (route.abort('failed')) that must surface via __LOAD_ERROR without being misclassified as a user abort. ThreeViewer grew two tiny test hooks (window.__LOAD_COMPLETE on successful model-loaded, window.__LOAD_ERROR on non-abort errors) to give tests a DOM-independent signal — production code is unchanged in behavior.
  • Accessibility follow-ups: Keyboard users now get a "Skip to 3D viewer" link as the first tab stop (visually hidden until focused, slides into view on focus) that jumps focus past the navigation directly to #viewer-wrapper. Both modals (SlicerModal, HelpPanel) now trap Tab/Shift+Tab inside the dialog while open and restore focus to the element that opened them on close — implemented via a dependency-free useFocusTrap composable. Modals also gained aria-modal="true" and tabindex="-1" on the dialog surface. Covered by a new Jest unit suite (tests/unit/composables/useFocusTrap.test.js) and a Playwright a11y spec (tests/playwright/a11y-skip-link.spec.ts) that verifies skip-link behavior under forced-colors: active (Windows High Contrast).
  • Transform Gizmo: Translate, rotate, and scale models interactively with Three.js TransformControls. Mode selector (Move/Rotate/Scale) and reset button in the Analyze section. Disables orbit controls while dragging.
  • Animation clip selector: Dropdown in the Animation panel to switch between individual animation clips (e.g., Run, Walk, Idle) for models with multiple animations
  • Texture optimization pipeline: Quality presets (Original/High/Medium/Low) with Canvas 2D downscaling, memory tracking, and configurable setting in Personal Settings
  • X3D parser: Full XML-based parser replacing placeholder cube — supports IndexedFaceSet geometry, materials, textures, transforms, and DEF/USE references
  • Volume & surface area measurement: Model statistics panel now shows actual mesh surface area (sum of triangle areas) and mesh volume (signed tetrahedra method, accurate for watertight meshes), in addition to bounding box volume
  • Custom color palette editor: Personal Settings → SlideOutToolPanel now exposes four user-overridable scene/chrome colors on top of the base light/dark theme: background, grid, toolbar bg, and toolbar text. Each has a native <input type="color"> picker plus a per-key "×" clear button; a single "Reset all palette colors" button clears everything at once. Overrides persist to localStorage['threedviewer:customPalette'] and are merged on top of whichever base theme (auto/light/dark) is active, so switching themes leaves your palette alone. The viewer rebuilds its THREE.GridHelper in place when gridColor changes and swaps scene.background when background changes — no reload required.
  • Decoder worker pool tuning (parallel decoding): GLTFLoader's DRACO and KTX2 sub-loaders now call setWorkerLimit(n) with n = min(hardwareConcurrency - 1, 4) (floor 2), so GLB textures and compressed meshes decode in parallel across multiple Web Workers instead of serializing on one. Defensive feature-detection — falls through when the Three.js version doesn't expose setWorkerLimit. Result: GLBs with multiple KTX2 textures load noticeably faster on 4+ core machines without starving the main thread or flooding it with workers on 1-core devices.
  • Memory pressure auto-step-down: The performance composable now samples performance.memory.usedJSHeapSize each frame and, when usage crosses 85 % of the configured maxMemoryUsage cap (default 500 MB), auto-switches to the Low performance mode — reducing pixel ratio, disabling shadows, and applying LOD. A one-time warning toast ("Auto-reduced quality — memory pressure") surfaces what happened; the flag clears once memory drops back below 70 % so the user can re-raise quality manually. 5-second cooldown prevents thrashing, and the check gracefully skips browsers without the non-standard performance.memory API (Firefox, Safari).
  • Background indexing status API + progress bar: New GET /api/files/index-status endpoint backed by ICacheFactory::createDistributed returns { active, processed, total, percent, startedAt, updatedAt } for the authenticated user. FileIndexService.reindexUser now pre-counts supported files (respecting .no3d and hidden-folder skip rules), then bumps the processed counter after each file. The Personal Settings "Re-index now" button starts a 750 ms poll in parallel with the blocking POST request and renders a live NcProgressBar ("142 / 284 (50 %)"), falling back to "Scanning…" until the pre-scan completes. Status TTL is 1 hour.
  • Adaptive texture streaming (visibility-aware queue): useProgressiveTextures now accepts a (camera, scene) streaming context and sorts its pending queue by frustum visibility before each batch — textures on meshes currently in view load first, off-screen ones are deferred. When the camera moves, the very next batch picks up the new viewpoint. queueTexture has a new optional mesh argument for visibility scoring; the signature stays backward-compatible, so existing callers are unaffected. ThreeViewer auto-registers the context on init so future loader pipelines that opt into progressive loading get adaptive scheduling for free.
  • Measurement suite upgrades: The Statistics panel's measurement section is now a full measurement tool:
  • Unit picker: Choose mm / cm / m / in / ft / generic units from a dropdown; bounding box, surface area, and volume values re-render instantly with the right suffix (mm, mm², mm³, etc.). Defaults to the project's configured VIEWER_CONFIG.measurement.defaultUnit so it matches the existing ruler tool.
  • Per-mesh breakdown: When a model has more than one mesh, a scrollable list shows each mesh's surface area and volume in the selected unit. Clicking a row focuses the panel on that mesh — the Width/Height/Depth/Area/Volume rows switch to its numbers and a "Focused: mesh name" header with a Show-all link appears. Helper meshes (transform-gizmo pickers, annotation markers) are excluded.
  • Pick mesh in viewport: A one-shot button arms a raycasting click handler on the canvas; the next click on a mesh focuses it in the stats panel. Works with any mesh in the loaded model, respects visibility, and skips gizmo helpers.
  • Watertightness badge: The section header flags each mesh as Watertight (all edges shared by exactly two triangles — volume is reliable), Not watertight (open or non-manifold edges detected — volume should be treated as approximate), or Unknown (non-indexed geometry, or >500k triangles so we skip the edge-map check for performance). Aggregated badge appears at the top of the section; per-mesh flags appear next to each row in the breakdown.
  • Copy measurements: A button copies a plain-text report of the current values (bounding box, surface area, mesh volume, bbox volume, watertight status, per-mesh table) to the clipboard in the selected unit. Uses navigator.clipboard.writeText on secure contexts with the textarea + execCommand fallback for legacy browsers. Success/error toast via the existing push-toast channel.
  • WebXR / VR mode: Enter immersive VR via the 🥽 button in the top bar (only shown when the browser advertises immersive-vr support). Animation loop swaps to renderer.setAnimationLoop during XR sessions, and FPS throttling is bypassed since the headset enforces its own cadence. Testable without a headset using the Chrome WebXR API Emulator extension.
  • Annotation JSON export/import: Save annotations as a versioned JSON document and re-import them later. The schema includes format, version, exportedAt, modelFilename, and an annotations array of { id, point, text, timestamp }. Import/Export buttons appear in the Annotations overlay when annotation mode is active.
  • Scene comparison diff overlay: When two models are loaded side-by-side via Comparison mode, a "Scene Diff" panel auto-appears showing original vs. comparison stats (vertex count, face count, mesh count, bounding box X/Y/Z, diagonal length) with color-coded deltas (green = increase, red = decrease). Helper meshes (transform gizmo pickers, axes/grid helpers) are excluded from stats so the diff reflects only the loaded geometry. The overlay is dismissable via × and re-openable from a "Diff" button in the comparison controls.
  • Annotations persistence (per-file backend save): Annotations now save automatically to your Nextcloud account, keyed by file ID, so they reappear next time you open the same model. Backed by a new AnnotationsService that stores one JSON document per (user, file) under app data (appdata_*/threedviewer/annotations/{userId}/{fileId}.json), with GET/PUT/DELETE routes at /api/annotations/{fileId} validating that you have access to the underlying file before reading or writing. Saves are debounced 600 ms after each change; clearing all annotations issues a DELETE so the backend doc is removed instead of storing an empty list. A small status pill ("Loading… / Saving… / Saved / Save failed") in the annotation overlay header surfaces sync state. 256 KB cap per document.
  • Shareable view link: New "Copy View Link" button in the View section copies a URL that encodes the current camera viewpoint (position, target, zoom) as a compact cam=px,py,pz,tx,ty,tz,z query parameter. Opening the link reloads the model and restores the exact same angle after auto-fit runs, so you can send collaborators a link and say "check out this corner of the model" without needing a live session. Toast feedback on copy success/failure; button disabled until a model is loaded. Works on any secure context (HTTPS or localhost) via navigator.clipboard, with an offscreen-textarea + execCommand fallback for legacy environments. No backend — pure URL round-trip.
  • Clipping box (6-plane section analysis): The existing Cross-Section tool now has a Plane / Box mode switch. Plane mode is unchanged (single cross-section plane with axis + position slider). Box mode enables six axis-aligned clipping planes, one per face of the model's bounding box, each with an independent 0–1 offset slider that moves that face inward toward the opposite side. Setting xMin=0.35 and zMax=0.35, for example, slices the leftmost 35% off along X and the nearest 35% off along Z, leaving the intersection slab visible with interior surfaces rendered via DoubleSide. A "Reset box" button returns all six offsets to 0. Plane and box state are kept independently so toggling between modes is non-destructive, and box offsets auto-remap when a new model is loaded.
  • File browser search & filters: New filter toolbar in the file browser. At the Folders/Types/Dates overview level the search box runs a global recursive search that walks every folder, type, and date bucket and surfaces matching files as a flat results grid (each card showing its full path) — so searching wolf from the Folders root finds Wolf-Blender-2.82a.glb two folders deep without manual drilling. Inside leaf views (drilled into a folder, type, or month) the search filters both subfolder cards and file cards together, and unlocks two extra controls: multi-select format chips (one per extension actually present in the current view) and a size bucket dropdown (Any / < 1 MB / 1–10 MB / > 10 MB). Filters compose with AND between categories and OR within format chips, and a "Clear filters" button appears as soon as any filter is active. Filters auto-reset when navigating between folders/types/dates so a stale query never makes the next view look empty.

Fixed

  • FBX taillight/lens transparency: FBX post-processing was force-overriding every material to opacity = 1.0; transparent = false, which made authored translucent lens shells (taillights, headlights, glass) opaque and hid the coloured mesh inside — the Mercedes GLS rear lights rendered as a solid grey slab with the red only visible if the camera was pushed inside the body. Now preserves the FBX-authored opacity: materials with 0 < opacity < 1 are left transparent with depthWrite = false so inner meshes show through; only materials with opacity <= 0 (which would render invisible) are still forced opaque.
  • Stats panel — File size on multi-file loads: File Size showed "0.00 MB" for formats that come with sidecar assets (OBJ+MTL, FBX with textures, GLTF+BIN). The stats panel was reading modelLoading.progress.value.total, but multi-file loaders report progress as a percentage (max 100) rather than bytes, so the resulting "100 B → 0.00 MB" rounded to zero. Now reads the actual byte count from modelSourceFiles.value[].size (matching main filename first, else first file), with the progress-total value only used as a fallback when it looks like real byte counts (> 1 KB).
  • Stats panel — Texture memory accounting: Textures section reported "Memory: 0.00 MB" while textures were still loading, because the loaded-image check used a 512×512 fallback that happened to resolve before decode — making tiny placeholders look real. Now distinguishes three states: loaded (dimensions ≥ 4×4 contribute to memory), pending (flagged separately so the UI can show "loading…"), and missing (1×1 placeholder or HTML img with empty src / zero naturalWidth). ThreeViewer polls analyzeModel once a second for up to 8 seconds after load when any texture is pending, so async decodes get picked up without the user needing to reopen the panel.
  • FBX dark rendering without textures: When an FBX referenced textures (e.g. texture.png) that weren't shipped alongside the model, the loader substituted a 1×1 base64 placeholder into mat.map. final = color × placeholder then multiplied every surface down toward near-black, producing a silhouette-dark render where the Mercedes GLS looked like a blob. The loader now detects its own placeholder (1×1 image size) and nulls out mat.map; a new "clay mode" kicks in when zero textures resolved from dependencies, brightening near-greyscale dark material colours to a pleasant 0.75 clay-grey while hue-preserving the brightening on coloured materials (green license plate, red brake lights) so they still read as coloured instead of washing out to clay.
  • ZIP export — main file path: The main model file is now packed under its basename (e.g. eyeball.obj) instead of its full Nextcloud path (e.g. /3D files/Eyeball/eyeball.obj). The leading slash is invalid in ZIP archives and broke extraction on some platforms.
  • ZIP export — preserved subdirectory layout: Textures discovered in subdirectories (e.g. textures/) are now packed under their original relative paths in the ZIP instead of being flattened to the root, so the unzipped folder mirrors the original Nextcloud layout and re-imports cleanly.
  • Comparison mode loading 400 error: loadComparisonModelFromPath was passing the { id, subdir } object returned by getFileIdByPath directly into URL templates, producing [object Object] and a 400 from the file API. Now destructures id before use. (Latent regression from the earlier getFileIdByPath return-shape change.)

Fixed

  • Animation playback: Previously all animation clips played simultaneously, causing blended/static poses. Now only one clip plays at a time
  • Animation timeline seek: Slider scrubber now correctly updates the model pose when dragged (replaced mixer.setTime() with action.time + mixer.update(0))
  • Animation loop toggle: Toggling Loop off and back on no longer leaves the animation stuck; finished LoopOnce actions properly restart
  • FBX rendering: Fixed dark/black eyeball — upgraded Lambert to Phong materials, added SRGBColorSpace, normalized scale, detected transparent shells
  • PLY loader: Preserved original vertex normals from file instead of always recomputing them
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignaturewL1fCXkzaQs2nvi2AkLccAX0u8v5YD4iOypG70neHtpgIb3wIQO+XaIgyQ+8n5k5ZO8pYI33VMdCWsomImFSTZmT7bH7s5DdFotdIektcqSN+kjfyeBeJkdoAcXUU2sJZgSdlFMrIxINc35c1nagz9g+B7qabynqu0yP2FnuWkeN9E37Rb4aXqvPUPPCEFkNjilYHkC1vrW6cUR/Z+L806b1IGJ0eZs6yH/3BB83V6TZ92btN80bbLdK0IbDY/uJ7sggkhuir0WKKoyC31fKsTaqcUi9I6G7Gr2Xzm3NqS6Bk2Y/pp0rLCSQJ+4xO3LA2ktbZIMZtqgA3gEfRYqMzJ10Eyny6TCwfAwOuvozvPoKbfm+5tlhjQyGgE/C7iDOEJ2LFqC9SEH9RrNPlzKxNJ/u1zXHdmEzmxGQpAKS1qoDEAPdKOsVFdkcdKugTNIi6PpP+29HGGl7lE8OuKIiq/JY8z2+9jnfAD087bE8QxnqJBi4eL8401WSzVDRRHlbh6nS/RFb/AqCDkJE+O7G5KskqRvrb3Re7QGNXcogubljsyRMVxQT2azuv/xg6VXJGKGIMv78/OBcQW+fMfr1s6NoDweK0LTQXIVGjQbx0SRJBPsGE5arytY9eIdaoRyHcxXje81vWhp5/Ar5MMLsQf6FjBKZILulUZWPvG2VfmE=
Signature digestsha512
Dependencies
Required Nextcloud versions >=31.0.0,<35.0.0
Minimum Integer bits32
3D Viewer 3.2.0
Release Details
UpdatedApril 5, 2026, 6:44 p.m.
Changelog

Added

  • Cross-Section tool: Interactive clipping plane to slice models along X/Y/Z axes with position slider, flip direction, and DoubleSide rendering for visible interiors
  • Animation Timeline Scrubber: Seek to any point in animated models with a slider, step forward/backward frame-by-frame
  • View Bookmarks: Save and restore camera positions with display toggles (grid, axes, wireframe, background), persisted in localStorage
  • Lighting Presets: Quick-switch between 5 lighting setups (Default, Studio, Outdoor, Dramatic, Flat) affecting ambient, directional, and point lights

  • Exploded View: For multi-mesh models, animate parts outward from centroid with adjustable explosion factor slider

  • Slicer: Export format selector: Choose STL, OBJ, or PLY before sending to slicer (non-passthrough formats)
  • Slicer: Upload progress bar: Real-time progress indicator when uploading to server (XMLHttpRequest with progress events, 2-min timeout)
  • Slicer: Copy share link: Copy the temporary Nextcloud share URL to clipboard for manual use
  • Slicer: Size validation: Warns and blocks uploads exceeding 50MB before attempting server transfer
  • Slicer: Upload size display: Shows file size in MB during upload for files >5MB
  • Modal viewer stats panel: Lightweight model info overlay (meshes, vertices, faces, dimensions) accessible via bottom-right button
  • Modal viewer screenshot: Download a PNG screenshot of the current view from the modal preview
  • Cache settings in Personal Settings: Configurable max cache size, max file size, expiration days, enable/disable toggle, and clear cache button
  • Cache hits/misses in performance overlay: Shows individual hit and miss counts alongside hit rate percentage
  • Cache privacy documentation: Documented local-only storage, per-browser isolation, and user control in TECHNICAL.md
  • Multi-file matching test suite: 48 tests covering texture/MTL name matching strategies (space normalization, prefix removal, plural handling, color/body mapping, partial matching)
  • Edge case fixtures: mixed-case extensions, missing MTL, orphaned textures for multi-file loading tests
  • Export triangle count warnings: Toast notifications for large models (>500K info, >2M warning) before export starts
  • Export MIME type fix: STL exports use model/stl, OBJ exports use model/obj instead of generic types
  • Help panel refresh: Added Slicer & Export section, cross-section, exploded view, lighting presets, bookmarks, dependency cache documentation
  • i18n audit: Wrapped hardcoded export/error toast strings in t(), added 31 new keys to l10n/en.json, documented i18n checklist in TECHNICAL.md
  • Accessibility review: Added role="dialog" + aria-labelledby to SlicerModal, aria-controls on all 6 panel section headers, aria-label on emoji-only buttons, role="alert" on texture warning, role="region" on stats panel
  • Format parity guard: Build-time script (npm run format:check) validates that PHP, JS, loader registry, Viewer MIME list, and mimetypemapping.json stay synchronized
  • X3D/VRML MIME registration: Added model/x3d+xml and model/vrml to Nextcloud Viewer MIME list so these formats open in the viewer
  • Slicer security documentation: Documented full security posture — authentication, path traversal prevention, MIME validation, size limits, share expiry, and file lifecycle in TECHNICAL.md

Fixed

  • Slicer OBJ/PLY upload: Added obj and ply to backend upload allowlist — OBJ/PLY format selector was added to frontend but backend rejected these formats
  • EufyStudio URL parsing: Replaced fragile regex filename extraction with proper URL parsing
  • Slicer upload timeout: Added 2-minute timeout to XMLHttpRequest (previously no timeout — could hang forever)

Changed

  • Tools panel redesign: Reorganized from 4 sections to 6 (View, Scene, Analyze, Animation, Export, Settings) for clearer grouping
  • Toggle switches: Replaced text checkmarks with custom CSS toggle switches for Grid, Axes, Wireframe, and Loop controls
  • Export section: Screenshot, Export Model, and Send to Slicer moved from Settings to dedicated Export section
  • Animation section: Elevated from nested group to its own collapsible section (conditional, only shown for animated models)
  • Model Statistics: Moved from Settings to Analyze section alongside Measurement, Annotation, and Cross-Section

Fixed

  • Theme consistency: Unified --color-primary-element fallback values across all components to #0082c9 (Nextcloud default), replacing inconsistent #4287f5, #1976d2 fallbacks
  • MinimalTopBar hardcoded colors: Replaced 7 instances of hardcoded rgb(0 130 201) with var(--color-primary-element) and related NC variables
  • Dark theme hack removed: Deleted ~130 lines of .dark-theme CSS overrides (46 !important declarations) from SlideOutToolPanel — dark mode now works automatically via Nextcloud CSS variables
  • Cache stat colors: Replaced hardcoded Material Design hex colors with NC semantic variables (--color-success-text, --color-warning-text, --color-error-text)
  • Missing panel props: Added wireframe, background-color, performance-mode, theme-mode, has-animations, is-animation-playing props to SlideOutToolPanel binding in App.vue
  • Clipping plane Z-fighting: Added 5% margin beyond model bounds so the slider at extremes doesn't cause Z-fighting artifacts
  • Bundle budget: Updated app chunk thresholds for new features (+12KB raw)
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
Signature2a2j5kFHSYZk5lKX7ByFRqNuCv8hg06X3uc2Mr98biRZSxeIgBug6aCdHONpN8oppv+6SDc5XrviS8HcLVFw1UEZvHjePdJYR8gri52Aa7ao7IfghYUHnoIwinqvWfP0sRod5vn3ZaKuo1pMpAHQlt/fkQCVz9eH6r+6TQTTBzBeAc7yWyEumArposNVcDqhgy0kK8tNWpNGYhpdqcMEvS7zGi0bl5EeK8k3ufaNaqwlzoXNwNMBiJ1aWFV2phxOxekkxlsHfRmGLkkdbPCOHg1Kj2CTLldHOjSQmQcUH9KOL1xkOZzuAC3Mh8SnrG/47h48uKIe62T7WYHgPbeOrDHvP8Z9d8S9V7kRq3puAonSPX/TFZt7j4YZoyar86w1MVakhT1mwiK3hBax+TCzxPRo63941VwID08MonJxW4D9C59MuF5qb/7UcDZ4Fm/TrSa0yvvKi+gy+gRCmBdzCnTg+WsEZW6Lotin80zckyH/+4wkUhUQBcq97ElIQKDwG5g9Bv6SGtQ2sR3zoUi7T/Wle4iqh38p5to6VMOlKfiBDiloGwpzXtHtlXDIZw8QqPL2h6gTQNdPizlovGLaZLup3sLL6MX7uyD5ZhbWz4kg1Qj4CqORSmpAanqJbBdUhLfA8dU2YhX5q7PFm8pMDAzKOq3h45kiSFI9K39f73c=
Signature digestsha512
Dependencies
Required Nextcloud versions >=31.0.0,<35.0.0
Minimum Integer bits32
3D Viewer 3.0.0
Release Details
UpdatedApril 2, 2026, 7:40 a.m.
Changelog

Changed

  • Dependencies: Updated development dependencies
  • @babel/core: ^7.28.6 → ^7.29.0
  • @babel/plugin-transform-runtime: ^7.28.5 → ^7.29.0
  • @babel/preset-env: ^7.28.6 → ^7.29.0
  • @playwright/test: ^1.56.1 → ^1.58.2
  • jest-environment-jsdom: ^29.7.0 → ^30.3.0
  • vue: ^2.7.16 → ^3.5.0
  • @nextcloud/vue: ^8.33.0 → ^9.5.0
  • @nextcloud/vite-config: ^1.7.1 → ^2.5.0
  • Vue 3 migration: Migrated app from Vue 2 to Vue 3
  • main.js: new Vue() + Vue.mixin()createApp() + globalProperties
  • settings-personal.js: Vue.extend()createApp()
  • viewer-api.js: new Vue() / $mount() / $destroy()createApp() / app.mount() / app.unmount()
  • ViewerWrapper.js: New Vue 2 bridge component — Nextcloud Viewer bundles Vue 2 internally, so a plain JS wrapper renders in Vue 2 and creates an isolated Vue 3 createApp() inside for the real ViewerComponent
  • Removed @vue/vue2-jest (Vue 2 specific)
  • Nextcloud 34 compatibility: min-version 31, max-version 34 (@nextcloud/vue v9.x requires NC 31+)
  • Vue component imports: Migrated deep imports (@nextcloud/vue/dist/Components/...) to barrel imports (@nextcloud/vue) for forward compatibility with @nextcloud/vue v9
  • Template modifiers: Removed deprecated .native event modifiers from Vue components (compatible with Vue 2.7+, required for Vue 3)
  • @nextcloud/vue v9 API migration: Updated all form component bindings to Vue 3 API
  • NcCheckboxRadioSwitch: :checked:model-value, @update:checked@update:model-value
  • NcTextField: :value:model-value, @update:value@update:model-value
  • NcSelect: :value:model-value, @input@update:model-value
  • NcSettingsSelectGroup: :value:model-value, @update:value@update:model-value
  • Bundle budget: Updated index chunk thresholds in bundle size checker

Fixed

  • npm audit: Resolved dependency vulnerabilities via npm audit fix (#77)
  • npm audit: Applied non-breaking security patches, reducing vulnerabilities from 43 to 25 (42% reduction)
  • Lint: Fixed one-var error in useThumbnailCapture.js
  • Animation loop toggle broken: AnimationMixer.LoopRepeat/LoopOnce are module-level constants, not static properties — setLoop(undefined) made loop toggling non-functional. Imported LoopRepeat/LoopOnce directly from 'three' (useAnimation.js, useComparison.js)
  • Model load errors invisible to user: Variable shadowing in handleLoadError — parameter error shadowed the error ref, so error.value = error was a no-op. Renamed parameter to loadError, fixed logger level from info to error (useModelLoading.js)
  • Lights leak on re-setup: Vue 3 proxy wraps items in ref([]) arrays — scene.remove(proxy) doesn't match raw Three.js objects via indexOf. Added toRaw() for light/helper removal and instanceof checks (useScene.js)
  • Toast auto-dismiss broken: ToastContainer was mutating the toasts prop directly (setting progress/paused on prop objects), which triggers Vue 3 warnings and breaks in strict mode. Moved progress and paused state to local data() (ToastContainer.vue)
  • Mobile touch listener leak: setupPinchZoom() and setupDoubleTapReset() added document event listeners but never stored references for cleanup. Stored refs in eventListeners and added removal in dispose() (useMobile.js)
  • Settings page form controls not responding: @nextcloud/vue 9.x changed all form component props from checked/value to modelValue. Updated all bindings in PersonalSettings.vue
  • CSS nesting bug: .select-group-row rule was nested inside .setting-row braces — silently dropped in browsers without CSS Nesting support. Moved to separate rule block (PersonalSettings.vue)
  • Viewer registration errors silent: Both registerViewerHandler and registerViewerHandlerLegacy had empty catch blocks — any registration failure was invisible. Added logger.error() calls (viewer-api.js)
  • Loader errors invisible: All BaseLoader logging methods (logInfo, logWarning, logError) had empty bodies. Delegated to project logger (BaseLoader.js)

Technical

  • PHP CS Fixer: Blank lines before returns, doc comment whitespace, type-cast spacing, removed unused imports
  • OpenAPI spec: Regenerated with slicer and thumbnail controller tags and updated description
  • Three.js + Vue 3 pattern: shallowRef for single Three.js objects, ref for arrays, toRaw() when passing proxied objects to Three.js APIs
  • Vue 3 Maps pattern: Maps moved to created() hook as non-reactive instance properties (this._timers) to avoid Vue 3 proxy breaking Map.has()/Map.get()
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureCqMDLnrHd2ejY1wtQ+IUFnXE3ObdTMqRro2/QTWhZPmyh7h5lD2zlldE7hV6K2PLVbSbQA8RyylLA7chfBAfNhqrGVcv9N8oS4N8JZlvp2sx7uCnQJx9hA34xXsRvCNednaE0NuhE4zelLAkmDaJZEcQm0r0mQKkZAMSaIPgRg52ZFiEV+KFa7dyHlyLqc/Cp6doYyEeJxnyDiLOiCCsS0zyrt1qQlRyEgGcOocdeIPJRutmBwX3Sy/018v5midNblK+gleIzcCAFIOM7qDJKuf5ESnvQmqQko/7J+ahhAGzIdpGRHmKCVjAayZ2g3uLkT9dNQrBwKAaYvNWODkSyVEoBBU1wrucKcw237GMSjxHrVf/h5G64+Nb9/krmriBkdcpVupQ94wgyU9H5NO+BsBP/+3EfuuECRwOxXMW15taFrsiflxos1Fuhu5PQtyfOv4UPtUzn+uf4MaSzeLYdBHsOHfO6ZTjTPRbO5NLz5nlMw3F4PEgSKW7bk9brH7dEjzQzVG1RrDYCg75bGW+8l7/vtAmWc87s6otqoCj9rPVHQhrY7njOUcU8gwjdw0WuFTD//i2Vk0+agy7GO9WWfUdrbQ/i8Grq5AwoEgD3b0NLpPB9XxDCOR3yZQhSDbHNvgI8BRDp3Xe1FDv8izK2Dw9HwjykDDU+uMNZNtNpdA=
Signature digestsha512
Dependencies
Required Nextcloud versions >=31.0.0,<35.0.0
Minimum Integer bits32

Nextcloud 32

3D Viewer 3.3.0
Release Details
UpdatedApril 20, 2026, 6:47 a.m.
Changelog

Fixed

  • 3DS files loaded tipped on their side when the exporter used Y-up instead of the 3ds-Max Z-up default. The loader had been hard-coded to rotate every 3DS model -90° around X (commit d8117a0, "fix: add coordinate system rotation corrections for Z-up formats"), which helped CAD-style Z-up files but silently broke Y-up exports — Cottage_FREE.3DS for example rendered with its long axis as the vertical. Dropped the unconditional rotation; 3DS files now pass through at their authored orientation. Most modern 3DS exporters (Blender, recent Maya) are already Y-up, and Z-up outliers can be fixed by orbiting or — if this becomes common — by a future user-facing orientation toggle. Other Z-up-rotating loaders (STL, PLY, 3MF, DAE) are unchanged because those formats have stronger Z-up conventions that are not affected by this fix. Reproduced and verified in the live Nextcloud container by downloading the user's 3DS via WebDAV, inspecting bbox dimensions with a new scripts/inspect-3ds.mjs harness (raw X=1243, Y=675, Z=1465 — Y is the height), and hard-refreshing the viewer page.
  • Standalone viewer: KTX2 loader threw on init with Cannot read properties of undefined (reading 'isWebGPURenderer'), so models with Basis/KTX2-compressed textures silently fell back to placeholder textures. Root cause: the standalone ThreeViewer.vue never forwarded the live WebGLRenderer into the loading context, and Three.js r182's KTX2Loader.detectSupport(renderer) dereferences renderer.isWebGPURenderer before checking anything else. Fix: pass renderer: renderer.value in the context, plus a defensive guard in gltf.js that skips KTX2 entirely (with a warning) when no renderer is available instead of throwing. The modal viewer was unaffected — it already forwarded this.renderer. Live-E2E harness now also watches for KTX2/WebGPU console complaints so the regression can't sneak back in.
  • Standalone viewer: glTF models with embedded data: buffers failed to load under Nextcloud's Content Security Policy. The app CSP allowed data: for img-src but not connect-src, so GLTFLoader's fetch() of embedded base64 buffers (the default export shape of many gltf files) was blocked by the browser. ResponseBuilder::addCspHeaders now also adds data: to connect-src. Caught end-to-end by driving Playwright against the real dev container (scripts/live-e2e-check.mjs).
  • Skip-to-viewer link wasn't in a usable tab position — it was rendered inside <NcContent><NcAppContent>, which put it ~9 tabs deep behind Nextcloud's header, nav sidebar, and file list. Wrapped in <Teleport to="body"> so the anchor lives at the body level regardless of where Nextcloud's chrome wraps us. DOM-verified focusable in the live container; clicking it moves focus to #viewer-wrapper. The CHANGELOG entry below that claims "first tab stop" was aspirational — Nextcloud's own Skip to main content / Skip to navigation links always win the first two positions, which is correct behavior we can't (and shouldn't) override.

Added

  • Four more CAD formats via OpenCascade — STEP, IGES, BREP, FCSTD (closes #97): All four formats come from the OCCT family of NURBS/B-Rep CAD files and share one WASM integration. Uses occt-import-js (Viktor Kovacs's purpose-built emscripten port of OpenCascade's import + tessellation) — much smaller than vanilla opencascade.js (~7 MB WASM vs 10+) and with a JSON-based mesh output that's a clean fit for Three.js. Architecture: one shared src/loaders/occt-runtime.js exposes getOcct() (memoized module promise so the 7 MB WASM downloads once across all 4 loaders) and buildGroupFromOccResult() (walks the assembly hierarchy preserving node names, transforms are already baked into tessellated vertices so we don't reapply matrices). Each format gets a thin ~25-line loader: STEP (.step, .stp) → ReadStepFile, IGES (.iges, .igs) → ReadIgesFile, BREP (.brep, .brp) → ReadBrepFile, FCSTD (FreeCAD document) → unzip via fflate, filter for .brep entries, feed each to ReadBrepFile — per-body failures don't take out the whole document. The resulting bundle shape: four 1 KB loader chunks + one 725 KB shared occt-runtime-*.chunk.mjs + 7.3 MB WASM served separately from /apps/threedviewer/occt/. Main/app bundles unchanged (0 B trend). Not unit-tested because the whole pipeline needs live WASM + real CAD fixtures to exercise meaningfully; covered by the existing smoke suite pattern.
  • Fifth new format — IFC (.ifc) (#97): Industry Foundation Classes, the de-facto BIM interchange standard. Loader in src/loaders/types/ifc.js uses ThatOpen's web-ifc WASM (~5 MB, lazy-loaded on first .ifc open) and a hand-written Three.js bridge — web-ifc-three has been deprecated and its modern replacement (@thatopen/components) is a heavy framework we don't need just for file loading. Bridge logic: StreamAllMeshes walks the IFC element graph, each FlatMesh's PlacedGeometry entries yield tessellated vertex data in interleaved [px,py,pz,nx,ny,nz] layout which we deinterleave into separate position/normal attributes, then apply flatTransformation (column-major 4×4) and per-geometry color. Express IDs (expressID, geometryExpressID) are preserved on mesh.userData.ifc for future property-panel tooling. Memory is carefully managed — geometry.delete() in a finally block releases the WASM-side handle per mesh, and CloseModel runs unconditionally so parse errors don't leak the full IFC model. WASM copies ship via scripts/copy-decoders.mjs to /apps/threedviewer/web-ifc/ (both single-threaded web-ifc.wasm and multi-threaded web-ifc-mt.wasm — IfcAPI picks the variant based on runtime feature detection) so air-gapped Nextcloud deploys don't need CDN reachability. JS glue is lazy-chunked into a 3.4 MB ifc-*.chunk.mjs that only loads when a user opens a .ifc file; main/app bundle impact is minimal. Not unit-tested because the whole pipeline requires live WASM + real IFC fixtures; covered by the smoke spec suite instead.
  • Fourth new format — dotbim (.bim) (#97): JSON-based BIM format from dotbim.net — simple schema (meshes + elements with { mesh_id, vector, rotation, guid, type, color, info, face_colors? }). Loader in src/loaders/types/dotbim.js handles mesh instancing (multiple elements sharing a mesh_id each get their own cloned geometry), element transforms (translation vector + unit quaternion rotation), RGBA byte colors, optional per-face colors (v1.1.0 schema — unindexes geometry so each triangle's 3 verts carry the face color), and tolerates legacy exporter quirks (missing/null rotation, mismatched face_colors length). Element metadata (guid, type, info) is stashed on mesh.userData.dotbim for future inspection tooling. 10 Jest specs in tests/unit/loaders/dotbim-parser.test.js cover instancing, transforms, color handling, transparency, legacy-rotation fallback, orphan elements, metadata, and JSON/schema validation error paths. Zero WASM, zero external deps, ~180 lines. Like the other new loaders it's lazy-chunked via the registry's dynamic imports — 0 B impact on the main/app bundles.
  • Three new 3D formats — OFF, AMF, 3DM (closes #97 partially): (1) .off (Geomview Object File Format) — hand-rolled plain-text parser in src/loaders/types/off.js covering OFF, COFF (per-vertex colors, float or 0–255 int), N-gon fan triangulation, inline # comments, and binary-OFF rejection. 9-test Jest suite exercises the parse path end-to-end (tetrahedron, n-gon, comments, COFF float/int colors, degenerate inputs). (2) .amf (Additive Manufacturing Format) — wraps three.js's bundled AMFLoader, handles both XML and ZIP-compressed variants. (3) .3dm (Rhinoceros) — wraps Rhino3dmLoader, loads rhino3dm.js + rhino3dm.wasm (~4 MB) on first use from the app's bundled copy at /apps/threedviewer/rhino3dm/ so air-gapped Nextcloud deployments don't need CDN reachability. scripts/copy-decoders.mjs now copies the rhino3dm assets alongside DRACO/Basis. All three formats are registered across the 5 sync points (lib/Constants/SupportedFormats.php, src/config/viewer-config.js, src/loaders/registry.js, src/main.js::SUPPORTED_MIMES, appinfo/mimetypemapping.json); npm run format:check PASS. Each loader is lazy-chunked via the registry's dynamic imports, so the main/app bundle size is unchanged (only users who open the new format pay the download cost). The 6 remaining formats from #97 (step, iges, brep, fcstd, ifc, bim) all require OpenCascade.js or web-ifc WASM (~5–10 MB each) and are deferred until demand justifies the bundle hit.
  • Forced-colors (Windows High Contrast) CSS hardening: New central override sheet (src/css/forced-colors.css, imported from main.js) scoped entirely to @media (forced-colors: active) — no effect on default rendering. Addresses three patterns the a11y audit found: (1) custom badges (.stats-badge, .fps-badge, .active-badge, .last-used-badge) that rely on background-color + text-color alone collapsed into the surrounding surface once the UA repainted both with system colors; they now get a 1px CanvasText border so they stay visible. (2) .filter-format-chip.active lost its visual distinction from the inactive state because both backgrounds became Canvas; the active variant now uses Highlight / HighlightText with forced-color-adjust: none so selection state survives. (3) Focus states that suppressed outline and relied on box-shadow or colored border-color (.export-select:focus, .annotation-text-input:focus, .skip-to-viewer:focus) had no visible focus indicator; they now re-enable a 2px Highlight outline. Verified by a new Playwright spec (tests/playwright/a11y-forced-colors.spec.ts, 5 tests) that loads the real CSS file into static fixtures mirroring each component shape and asserts border/outline width > 0 under emulateMedia({ forcedColors: 'active' }). Caveat: Playwright's forced-colors emulation uses a neutral palette — this closes the keyboard/CSS correctness gap but an interactive Windows HC walkthrough is still the final source of truth for theme-specific contrast issues.
  • i18n parity tooling (scripts/check-i18n.mjs): Walks src/ (.vue/.js/.ts) and lib/ (.php) and extracts every t('threedviewer', 'string'), this.t(...), and ->t(...) call via regex. Diffs the extracted set against l10n/en.json: ERROR on source strings missing from en.json, WARN on orphan keys no source uses, per-locale coverage summary that reports missing, passthrough (value === key), and orphan counts. --sync-en auto-adds missing keys (value = key); --prune removes orphans. Wired as npm run i18n:check / npm run i18n:sync; i18n:check is now part of the validate chain. First sync closed 329 missing keys and pruned 87 orphans in en.json — ar/de/es coverage now reports accurately at ~27% (previously looked higher only because en.json itself was incomplete).
  • Export pipeline unit tests + MIME consistency fix: Nine Jest specs in tests/unit/composables/useExport.test.js cover getGeometryStats (indexed, non-indexed, multi-mesh groups, non-geometry descendants) and exportAsSTL/exportAsOBJ/exportAsGLB (correct MIME — model/stl, model/obj, model/gltf-binary — correct byte length, null-object guards, and a multi-material OBJ scene that passes through the exporter with its material array and geometry groups intact instead of being flattened). Three.js exporters are mocked so the test runs deterministically in jsdom without pulling in Three's ESM-only subpath imports; the real exporter output remains covered by the Playwright smoke suite. Shipped alongside a MIME consistency fix in SlicerModal.vue — the slicer-export fallback path was still using application/octet-stream for STL and text/plain for OBJ even though the main Export Model path had been updated to model/stl / model/obj; both paths now agree.
  • Loader smoke-test coverage for cancel/retry/network-drop: Two new Playwright specs in tests/smoke/viewer.spec.ts use page.route() to deterministically simulate (a) a user cancelling a hanging load and then retrying — the second fetch is fulfilled with a fixture and the viewer reaches __LOAD_COMPLETE, and (b) a network failure (route.abort('failed')) that must surface via __LOAD_ERROR without being misclassified as a user abort. ThreeViewer grew two tiny test hooks (window.__LOAD_COMPLETE on successful model-loaded, window.__LOAD_ERROR on non-abort errors) to give tests a DOM-independent signal — production code is unchanged in behavior.
  • Accessibility follow-ups: Keyboard users now get a "Skip to 3D viewer" link as the first tab stop (visually hidden until focused, slides into view on focus) that jumps focus past the navigation directly to #viewer-wrapper. Both modals (SlicerModal, HelpPanel) now trap Tab/Shift+Tab inside the dialog while open and restore focus to the element that opened them on close — implemented via a dependency-free useFocusTrap composable. Modals also gained aria-modal="true" and tabindex="-1" on the dialog surface. Covered by a new Jest unit suite (tests/unit/composables/useFocusTrap.test.js) and a Playwright a11y spec (tests/playwright/a11y-skip-link.spec.ts) that verifies skip-link behavior under forced-colors: active (Windows High Contrast).
  • Transform Gizmo: Translate, rotate, and scale models interactively with Three.js TransformControls. Mode selector (Move/Rotate/Scale) and reset button in the Analyze section. Disables orbit controls while dragging.
  • Animation clip selector: Dropdown in the Animation panel to switch between individual animation clips (e.g., Run, Walk, Idle) for models with multiple animations
  • Texture optimization pipeline: Quality presets (Original/High/Medium/Low) with Canvas 2D downscaling, memory tracking, and configurable setting in Personal Settings
  • X3D parser: Full XML-based parser replacing placeholder cube — supports IndexedFaceSet geometry, materials, textures, transforms, and DEF/USE references
  • Volume & surface area measurement: Model statistics panel now shows actual mesh surface area (sum of triangle areas) and mesh volume (signed tetrahedra method, accurate for watertight meshes), in addition to bounding box volume
  • Custom color palette editor: Personal Settings → SlideOutToolPanel now exposes four user-overridable scene/chrome colors on top of the base light/dark theme: background, grid, toolbar bg, and toolbar text. Each has a native <input type="color"> picker plus a per-key "×" clear button; a single "Reset all palette colors" button clears everything at once. Overrides persist to localStorage['threedviewer:customPalette'] and are merged on top of whichever base theme (auto/light/dark) is active, so switching themes leaves your palette alone. The viewer rebuilds its THREE.GridHelper in place when gridColor changes and swaps scene.background when background changes — no reload required.
  • Decoder worker pool tuning (parallel decoding): GLTFLoader's DRACO and KTX2 sub-loaders now call setWorkerLimit(n) with n = min(hardwareConcurrency - 1, 4) (floor 2), so GLB textures and compressed meshes decode in parallel across multiple Web Workers instead of serializing on one. Defensive feature-detection — falls through when the Three.js version doesn't expose setWorkerLimit. Result: GLBs with multiple KTX2 textures load noticeably faster on 4+ core machines without starving the main thread or flooding it with workers on 1-core devices.
  • Memory pressure auto-step-down: The performance composable now samples performance.memory.usedJSHeapSize each frame and, when usage crosses 85 % of the configured maxMemoryUsage cap (default 500 MB), auto-switches to the Low performance mode — reducing pixel ratio, disabling shadows, and applying LOD. A one-time warning toast ("Auto-reduced quality — memory pressure") surfaces what happened; the flag clears once memory drops back below 70 % so the user can re-raise quality manually. 5-second cooldown prevents thrashing, and the check gracefully skips browsers without the non-standard performance.memory API (Firefox, Safari).
  • Background indexing status API + progress bar: New GET /api/files/index-status endpoint backed by ICacheFactory::createDistributed returns { active, processed, total, percent, startedAt, updatedAt } for the authenticated user. FileIndexService.reindexUser now pre-counts supported files (respecting .no3d and hidden-folder skip rules), then bumps the processed counter after each file. The Personal Settings "Re-index now" button starts a 750 ms poll in parallel with the blocking POST request and renders a live NcProgressBar ("142 / 284 (50 %)"), falling back to "Scanning…" until the pre-scan completes. Status TTL is 1 hour.
  • Adaptive texture streaming (visibility-aware queue): useProgressiveTextures now accepts a (camera, scene) streaming context and sorts its pending queue by frustum visibility before each batch — textures on meshes currently in view load first, off-screen ones are deferred. When the camera moves, the very next batch picks up the new viewpoint. queueTexture has a new optional mesh argument for visibility scoring; the signature stays backward-compatible, so existing callers are unaffected. ThreeViewer auto-registers the context on init so future loader pipelines that opt into progressive loading get adaptive scheduling for free.
  • Measurement suite upgrades: The Statistics panel's measurement section is now a full measurement tool:
  • Unit picker: Choose mm / cm / m / in / ft / generic units from a dropdown; bounding box, surface area, and volume values re-render instantly with the right suffix (mm, mm², mm³, etc.). Defaults to the project's configured VIEWER_CONFIG.measurement.defaultUnit so it matches the existing ruler tool.
  • Per-mesh breakdown: When a model has more than one mesh, a scrollable list shows each mesh's surface area and volume in the selected unit. Clicking a row focuses the panel on that mesh — the Width/Height/Depth/Area/Volume rows switch to its numbers and a "Focused: mesh name" header with a Show-all link appears. Helper meshes (transform-gizmo pickers, annotation markers) are excluded.
  • Pick mesh in viewport: A one-shot button arms a raycasting click handler on the canvas; the next click on a mesh focuses it in the stats panel. Works with any mesh in the loaded model, respects visibility, and skips gizmo helpers.
  • Watertightness badge: The section header flags each mesh as Watertight (all edges shared by exactly two triangles — volume is reliable), Not watertight (open or non-manifold edges detected — volume should be treated as approximate), or Unknown (non-indexed geometry, or >500k triangles so we skip the edge-map check for performance). Aggregated badge appears at the top of the section; per-mesh flags appear next to each row in the breakdown.
  • Copy measurements: A button copies a plain-text report of the current values (bounding box, surface area, mesh volume, bbox volume, watertight status, per-mesh table) to the clipboard in the selected unit. Uses navigator.clipboard.writeText on secure contexts with the textarea + execCommand fallback for legacy browsers. Success/error toast via the existing push-toast channel.
  • WebXR / VR mode: Enter immersive VR via the 🥽 button in the top bar (only shown when the browser advertises immersive-vr support). Animation loop swaps to renderer.setAnimationLoop during XR sessions, and FPS throttling is bypassed since the headset enforces its own cadence. Testable without a headset using the Chrome WebXR API Emulator extension.
  • Annotation JSON export/import: Save annotations as a versioned JSON document and re-import them later. The schema includes format, version, exportedAt, modelFilename, and an annotations array of { id, point, text, timestamp }. Import/Export buttons appear in the Annotations overlay when annotation mode is active.
  • Scene comparison diff overlay: When two models are loaded side-by-side via Comparison mode, a "Scene Diff" panel auto-appears showing original vs. comparison stats (vertex count, face count, mesh count, bounding box X/Y/Z, diagonal length) with color-coded deltas (green = increase, red = decrease). Helper meshes (transform gizmo pickers, axes/grid helpers) are excluded from stats so the diff reflects only the loaded geometry. The overlay is dismissable via × and re-openable from a "Diff" button in the comparison controls.
  • Annotations persistence (per-file backend save): Annotations now save automatically to your Nextcloud account, keyed by file ID, so they reappear next time you open the same model. Backed by a new AnnotationsService that stores one JSON document per (user, file) under app data (appdata_*/threedviewer/annotations/{userId}/{fileId}.json), with GET/PUT/DELETE routes at /api/annotations/{fileId} validating that you have access to the underlying file before reading or writing. Saves are debounced 600 ms after each change; clearing all annotations issues a DELETE so the backend doc is removed instead of storing an empty list. A small status pill ("Loading… / Saving… / Saved / Save failed") in the annotation overlay header surfaces sync state. 256 KB cap per document.
  • Shareable view link: New "Copy View Link" button in the View section copies a URL that encodes the current camera viewpoint (position, target, zoom) as a compact cam=px,py,pz,tx,ty,tz,z query parameter. Opening the link reloads the model and restores the exact same angle after auto-fit runs, so you can send collaborators a link and say "check out this corner of the model" without needing a live session. Toast feedback on copy success/failure; button disabled until a model is loaded. Works on any secure context (HTTPS or localhost) via navigator.clipboard, with an offscreen-textarea + execCommand fallback for legacy environments. No backend — pure URL round-trip.
  • Clipping box (6-plane section analysis): The existing Cross-Section tool now has a Plane / Box mode switch. Plane mode is unchanged (single cross-section plane with axis + position slider). Box mode enables six axis-aligned clipping planes, one per face of the model's bounding box, each with an independent 0–1 offset slider that moves that face inward toward the opposite side. Setting xMin=0.35 and zMax=0.35, for example, slices the leftmost 35% off along X and the nearest 35% off along Z, leaving the intersection slab visible with interior surfaces rendered via DoubleSide. A "Reset box" button returns all six offsets to 0. Plane and box state are kept independently so toggling between modes is non-destructive, and box offsets auto-remap when a new model is loaded.
  • File browser search & filters: New filter toolbar in the file browser. At the Folders/Types/Dates overview level the search box runs a global recursive search that walks every folder, type, and date bucket and surfaces matching files as a flat results grid (each card showing its full path) — so searching wolf from the Folders root finds Wolf-Blender-2.82a.glb two folders deep without manual drilling. Inside leaf views (drilled into a folder, type, or month) the search filters both subfolder cards and file cards together, and unlocks two extra controls: multi-select format chips (one per extension actually present in the current view) and a size bucket dropdown (Any / < 1 MB / 1–10 MB / > 10 MB). Filters compose with AND between categories and OR within format chips, and a "Clear filters" button appears as soon as any filter is active. Filters auto-reset when navigating between folders/types/dates so a stale query never makes the next view look empty.

Fixed

  • FBX taillight/lens transparency: FBX post-processing was force-overriding every material to opacity = 1.0; transparent = false, which made authored translucent lens shells (taillights, headlights, glass) opaque and hid the coloured mesh inside — the Mercedes GLS rear lights rendered as a solid grey slab with the red only visible if the camera was pushed inside the body. Now preserves the FBX-authored opacity: materials with 0 < opacity < 1 are left transparent with depthWrite = false so inner meshes show through; only materials with opacity <= 0 (which would render invisible) are still forced opaque.
  • Stats panel — File size on multi-file loads: File Size showed "0.00 MB" for formats that come with sidecar assets (OBJ+MTL, FBX with textures, GLTF+BIN). The stats panel was reading modelLoading.progress.value.total, but multi-file loaders report progress as a percentage (max 100) rather than bytes, so the resulting "100 B → 0.00 MB" rounded to zero. Now reads the actual byte count from modelSourceFiles.value[].size (matching main filename first, else first file), with the progress-total value only used as a fallback when it looks like real byte counts (> 1 KB).
  • Stats panel — Texture memory accounting: Textures section reported "Memory: 0.00 MB" while textures were still loading, because the loaded-image check used a 512×512 fallback that happened to resolve before decode — making tiny placeholders look real. Now distinguishes three states: loaded (dimensions ≥ 4×4 contribute to memory), pending (flagged separately so the UI can show "loading…"), and missing (1×1 placeholder or HTML img with empty src / zero naturalWidth). ThreeViewer polls analyzeModel once a second for up to 8 seconds after load when any texture is pending, so async decodes get picked up without the user needing to reopen the panel.
  • FBX dark rendering without textures: When an FBX referenced textures (e.g. texture.png) that weren't shipped alongside the model, the loader substituted a 1×1 base64 placeholder into mat.map. final = color × placeholder then multiplied every surface down toward near-black, producing a silhouette-dark render where the Mercedes GLS looked like a blob. The loader now detects its own placeholder (1×1 image size) and nulls out mat.map; a new "clay mode" kicks in when zero textures resolved from dependencies, brightening near-greyscale dark material colours to a pleasant 0.75 clay-grey while hue-preserving the brightening on coloured materials (green license plate, red brake lights) so they still read as coloured instead of washing out to clay.
  • ZIP export — main file path: The main model file is now packed under its basename (e.g. eyeball.obj) instead of its full Nextcloud path (e.g. /3D files/Eyeball/eyeball.obj). The leading slash is invalid in ZIP archives and broke extraction on some platforms.
  • ZIP export — preserved subdirectory layout: Textures discovered in subdirectories (e.g. textures/) are now packed under their original relative paths in the ZIP instead of being flattened to the root, so the unzipped folder mirrors the original Nextcloud layout and re-imports cleanly.
  • Comparison mode loading 400 error: loadComparisonModelFromPath was passing the { id, subdir } object returned by getFileIdByPath directly into URL templates, producing [object Object] and a 400 from the file API. Now destructures id before use. (Latent regression from the earlier getFileIdByPath return-shape change.)

Fixed

  • Animation playback: Previously all animation clips played simultaneously, causing blended/static poses. Now only one clip plays at a time
  • Animation timeline seek: Slider scrubber now correctly updates the model pose when dragged (replaced mixer.setTime() with action.time + mixer.update(0))
  • Animation loop toggle: Toggling Loop off and back on no longer leaves the animation stuck; finished LoopOnce actions properly restart
  • FBX rendering: Fixed dark/black eyeball — upgraded Lambert to Phong materials, added SRGBColorSpace, normalized scale, detected transparent shells
  • PLY loader: Preserved original vertex normals from file instead of always recomputing them
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignaturewL1fCXkzaQs2nvi2AkLccAX0u8v5YD4iOypG70neHtpgIb3wIQO+XaIgyQ+8n5k5ZO8pYI33VMdCWsomImFSTZmT7bH7s5DdFotdIektcqSN+kjfyeBeJkdoAcXUU2sJZgSdlFMrIxINc35c1nagz9g+B7qabynqu0yP2FnuWkeN9E37Rb4aXqvPUPPCEFkNjilYHkC1vrW6cUR/Z+L806b1IGJ0eZs6yH/3BB83V6TZ92btN80bbLdK0IbDY/uJ7sggkhuir0WKKoyC31fKsTaqcUi9I6G7Gr2Xzm3NqS6Bk2Y/pp0rLCSQJ+4xO3LA2ktbZIMZtqgA3gEfRYqMzJ10Eyny6TCwfAwOuvozvPoKbfm+5tlhjQyGgE/C7iDOEJ2LFqC9SEH9RrNPlzKxNJ/u1zXHdmEzmxGQpAKS1qoDEAPdKOsVFdkcdKugTNIi6PpP+29HGGl7lE8OuKIiq/JY8z2+9jnfAD087bE8QxnqJBi4eL8401WSzVDRRHlbh6nS/RFb/AqCDkJE+O7G5KskqRvrb3Re7QGNXcogubljsyRMVxQT2azuv/xg6VXJGKGIMv78/OBcQW+fMfr1s6NoDweK0LTQXIVGjQbx0SRJBPsGE5arytY9eIdaoRyHcxXje81vWhp5/Ar5MMLsQf6FjBKZILulUZWPvG2VfmE=
Signature digestsha512
Dependencies
Required Nextcloud versions >=31.0.0,<35.0.0
Minimum Integer bits32
3D Viewer 3.2.0
Release Details
UpdatedApril 5, 2026, 6:44 p.m.
Changelog

Added

  • Cross-Section tool: Interactive clipping plane to slice models along X/Y/Z axes with position slider, flip direction, and DoubleSide rendering for visible interiors
  • Animation Timeline Scrubber: Seek to any point in animated models with a slider, step forward/backward frame-by-frame
  • View Bookmarks: Save and restore camera positions with display toggles (grid, axes, wireframe, background), persisted in localStorage
  • Lighting Presets: Quick-switch between 5 lighting setups (Default, Studio, Outdoor, Dramatic, Flat) affecting ambient, directional, and point lights

  • Exploded View: For multi-mesh models, animate parts outward from centroid with adjustable explosion factor slider

  • Slicer: Export format selector: Choose STL, OBJ, or PLY before sending to slicer (non-passthrough formats)
  • Slicer: Upload progress bar: Real-time progress indicator when uploading to server (XMLHttpRequest with progress events, 2-min timeout)
  • Slicer: Copy share link: Copy the temporary Nextcloud share URL to clipboard for manual use
  • Slicer: Size validation: Warns and blocks uploads exceeding 50MB before attempting server transfer
  • Slicer: Upload size display: Shows file size in MB during upload for files >5MB
  • Modal viewer stats panel: Lightweight model info overlay (meshes, vertices, faces, dimensions) accessible via bottom-right button
  • Modal viewer screenshot: Download a PNG screenshot of the current view from the modal preview
  • Cache settings in Personal Settings: Configurable max cache size, max file size, expiration days, enable/disable toggle, and clear cache button
  • Cache hits/misses in performance overlay: Shows individual hit and miss counts alongside hit rate percentage
  • Cache privacy documentation: Documented local-only storage, per-browser isolation, and user control in TECHNICAL.md
  • Multi-file matching test suite: 48 tests covering texture/MTL name matching strategies (space normalization, prefix removal, plural handling, color/body mapping, partial matching)
  • Edge case fixtures: mixed-case extensions, missing MTL, orphaned textures for multi-file loading tests
  • Export triangle count warnings: Toast notifications for large models (>500K info, >2M warning) before export starts
  • Export MIME type fix: STL exports use model/stl, OBJ exports use model/obj instead of generic types
  • Help panel refresh: Added Slicer & Export section, cross-section, exploded view, lighting presets, bookmarks, dependency cache documentation
  • i18n audit: Wrapped hardcoded export/error toast strings in t(), added 31 new keys to l10n/en.json, documented i18n checklist in TECHNICAL.md
  • Accessibility review: Added role="dialog" + aria-labelledby to SlicerModal, aria-controls on all 6 panel section headers, aria-label on emoji-only buttons, role="alert" on texture warning, role="region" on stats panel
  • Format parity guard: Build-time script (npm run format:check) validates that PHP, JS, loader registry, Viewer MIME list, and mimetypemapping.json stay synchronized
  • X3D/VRML MIME registration: Added model/x3d+xml and model/vrml to Nextcloud Viewer MIME list so these formats open in the viewer
  • Slicer security documentation: Documented full security posture — authentication, path traversal prevention, MIME validation, size limits, share expiry, and file lifecycle in TECHNICAL.md

Fixed

  • Slicer OBJ/PLY upload: Added obj and ply to backend upload allowlist — OBJ/PLY format selector was added to frontend but backend rejected these formats
  • EufyStudio URL parsing: Replaced fragile regex filename extraction with proper URL parsing
  • Slicer upload timeout: Added 2-minute timeout to XMLHttpRequest (previously no timeout — could hang forever)

Changed

  • Tools panel redesign: Reorganized from 4 sections to 6 (View, Scene, Analyze, Animation, Export, Settings) for clearer grouping
  • Toggle switches: Replaced text checkmarks with custom CSS toggle switches for Grid, Axes, Wireframe, and Loop controls
  • Export section: Screenshot, Export Model, and Send to Slicer moved from Settings to dedicated Export section
  • Animation section: Elevated from nested group to its own collapsible section (conditional, only shown for animated models)
  • Model Statistics: Moved from Settings to Analyze section alongside Measurement, Annotation, and Cross-Section

Fixed

  • Theme consistency: Unified --color-primary-element fallback values across all components to #0082c9 (Nextcloud default), replacing inconsistent #4287f5, #1976d2 fallbacks
  • MinimalTopBar hardcoded colors: Replaced 7 instances of hardcoded rgb(0 130 201) with var(--color-primary-element) and related NC variables
  • Dark theme hack removed: Deleted ~130 lines of .dark-theme CSS overrides (46 !important declarations) from SlideOutToolPanel — dark mode now works automatically via Nextcloud CSS variables
  • Cache stat colors: Replaced hardcoded Material Design hex colors with NC semantic variables (--color-success-text, --color-warning-text, --color-error-text)
  • Missing panel props: Added wireframe, background-color, performance-mode, theme-mode, has-animations, is-animation-playing props to SlideOutToolPanel binding in App.vue
  • Clipping plane Z-fighting: Added 5% margin beyond model bounds so the slider at extremes doesn't cause Z-fighting artifacts
  • Bundle budget: Updated app chunk thresholds for new features (+12KB raw)
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
Signature2a2j5kFHSYZk5lKX7ByFRqNuCv8hg06X3uc2Mr98biRZSxeIgBug6aCdHONpN8oppv+6SDc5XrviS8HcLVFw1UEZvHjePdJYR8gri52Aa7ao7IfghYUHnoIwinqvWfP0sRod5vn3ZaKuo1pMpAHQlt/fkQCVz9eH6r+6TQTTBzBeAc7yWyEumArposNVcDqhgy0kK8tNWpNGYhpdqcMEvS7zGi0bl5EeK8k3ufaNaqwlzoXNwNMBiJ1aWFV2phxOxekkxlsHfRmGLkkdbPCOHg1Kj2CTLldHOjSQmQcUH9KOL1xkOZzuAC3Mh8SnrG/47h48uKIe62T7WYHgPbeOrDHvP8Z9d8S9V7kRq3puAonSPX/TFZt7j4YZoyar86w1MVakhT1mwiK3hBax+TCzxPRo63941VwID08MonJxW4D9C59MuF5qb/7UcDZ4Fm/TrSa0yvvKi+gy+gRCmBdzCnTg+WsEZW6Lotin80zckyH/+4wkUhUQBcq97ElIQKDwG5g9Bv6SGtQ2sR3zoUi7T/Wle4iqh38p5to6VMOlKfiBDiloGwpzXtHtlXDIZw8QqPL2h6gTQNdPizlovGLaZLup3sLL6MX7uyD5ZhbWz4kg1Qj4CqORSmpAanqJbBdUhLfA8dU2YhX5q7PFm8pMDAzKOq3h45kiSFI9K39f73c=
Signature digestsha512
Dependencies
Required Nextcloud versions >=31.0.0,<35.0.0
Minimum Integer bits32
3D Viewer 3.0.0
Release Details
UpdatedApril 2, 2026, 7:40 a.m.
Changelog

Changed

  • Dependencies: Updated development dependencies
  • @babel/core: ^7.28.6 → ^7.29.0
  • @babel/plugin-transform-runtime: ^7.28.5 → ^7.29.0
  • @babel/preset-env: ^7.28.6 → ^7.29.0
  • @playwright/test: ^1.56.1 → ^1.58.2
  • jest-environment-jsdom: ^29.7.0 → ^30.3.0
  • vue: ^2.7.16 → ^3.5.0
  • @nextcloud/vue: ^8.33.0 → ^9.5.0
  • @nextcloud/vite-config: ^1.7.1 → ^2.5.0
  • Vue 3 migration: Migrated app from Vue 2 to Vue 3
  • main.js: new Vue() + Vue.mixin()createApp() + globalProperties
  • settings-personal.js: Vue.extend()createApp()
  • viewer-api.js: new Vue() / $mount() / $destroy()createApp() / app.mount() / app.unmount()
  • ViewerWrapper.js: New Vue 2 bridge component — Nextcloud Viewer bundles Vue 2 internally, so a plain JS wrapper renders in Vue 2 and creates an isolated Vue 3 createApp() inside for the real ViewerComponent
  • Removed @vue/vue2-jest (Vue 2 specific)
  • Nextcloud 34 compatibility: min-version 31, max-version 34 (@nextcloud/vue v9.x requires NC 31+)
  • Vue component imports: Migrated deep imports (@nextcloud/vue/dist/Components/...) to barrel imports (@nextcloud/vue) for forward compatibility with @nextcloud/vue v9
  • Template modifiers: Removed deprecated .native event modifiers from Vue components (compatible with Vue 2.7+, required for Vue 3)
  • @nextcloud/vue v9 API migration: Updated all form component bindings to Vue 3 API
  • NcCheckboxRadioSwitch: :checked:model-value, @update:checked@update:model-value
  • NcTextField: :value:model-value, @update:value@update:model-value
  • NcSelect: :value:model-value, @input@update:model-value
  • NcSettingsSelectGroup: :value:model-value, @update:value@update:model-value
  • Bundle budget: Updated index chunk thresholds in bundle size checker

Fixed

  • npm audit: Resolved dependency vulnerabilities via npm audit fix (#77)
  • npm audit: Applied non-breaking security patches, reducing vulnerabilities from 43 to 25 (42% reduction)
  • Lint: Fixed one-var error in useThumbnailCapture.js
  • Animation loop toggle broken: AnimationMixer.LoopRepeat/LoopOnce are module-level constants, not static properties — setLoop(undefined) made loop toggling non-functional. Imported LoopRepeat/LoopOnce directly from 'three' (useAnimation.js, useComparison.js)
  • Model load errors invisible to user: Variable shadowing in handleLoadError — parameter error shadowed the error ref, so error.value = error was a no-op. Renamed parameter to loadError, fixed logger level from info to error (useModelLoading.js)
  • Lights leak on re-setup: Vue 3 proxy wraps items in ref([]) arrays — scene.remove(proxy) doesn't match raw Three.js objects via indexOf. Added toRaw() for light/helper removal and instanceof checks (useScene.js)
  • Toast auto-dismiss broken: ToastContainer was mutating the toasts prop directly (setting progress/paused on prop objects), which triggers Vue 3 warnings and breaks in strict mode. Moved progress and paused state to local data() (ToastContainer.vue)
  • Mobile touch listener leak: setupPinchZoom() and setupDoubleTapReset() added document event listeners but never stored references for cleanup. Stored refs in eventListeners and added removal in dispose() (useMobile.js)
  • Settings page form controls not responding: @nextcloud/vue 9.x changed all form component props from checked/value to modelValue. Updated all bindings in PersonalSettings.vue
  • CSS nesting bug: .select-group-row rule was nested inside .setting-row braces — silently dropped in browsers without CSS Nesting support. Moved to separate rule block (PersonalSettings.vue)
  • Viewer registration errors silent: Both registerViewerHandler and registerViewerHandlerLegacy had empty catch blocks — any registration failure was invisible. Added logger.error() calls (viewer-api.js)
  • Loader errors invisible: All BaseLoader logging methods (logInfo, logWarning, logError) had empty bodies. Delegated to project logger (BaseLoader.js)

Technical

  • PHP CS Fixer: Blank lines before returns, doc comment whitespace, type-cast spacing, removed unused imports
  • OpenAPI spec: Regenerated with slicer and thumbnail controller tags and updated description
  • Three.js + Vue 3 pattern: shallowRef for single Three.js objects, ref for arrays, toRaw() when passing proxied objects to Three.js APIs
  • Vue 3 Maps pattern: Maps moved to created() hook as non-reactive instance properties (this._timers) to avoid Vue 3 proxy breaking Map.has()/Map.get()
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureCqMDLnrHd2ejY1wtQ+IUFnXE3ObdTMqRro2/QTWhZPmyh7h5lD2zlldE7hV6K2PLVbSbQA8RyylLA7chfBAfNhqrGVcv9N8oS4N8JZlvp2sx7uCnQJx9hA34xXsRvCNednaE0NuhE4zelLAkmDaJZEcQm0r0mQKkZAMSaIPgRg52ZFiEV+KFa7dyHlyLqc/Cp6doYyEeJxnyDiLOiCCsS0zyrt1qQlRyEgGcOocdeIPJRutmBwX3Sy/018v5midNblK+gleIzcCAFIOM7qDJKuf5ESnvQmqQko/7J+ahhAGzIdpGRHmKCVjAayZ2g3uLkT9dNQrBwKAaYvNWODkSyVEoBBU1wrucKcw237GMSjxHrVf/h5G64+Nb9/krmriBkdcpVupQ94wgyU9H5NO+BsBP/+3EfuuECRwOxXMW15taFrsiflxos1Fuhu5PQtyfOv4UPtUzn+uf4MaSzeLYdBHsOHfO6ZTjTPRbO5NLz5nlMw3F4PEgSKW7bk9brH7dEjzQzVG1RrDYCg75bGW+8l7/vtAmWc87s6otqoCj9rPVHQhrY7njOUcU8gwjdw0WuFTD//i2Vk0+agy7GO9WWfUdrbQ/i8Grq5AwoEgD3b0NLpPB9XxDCOR3yZQhSDbHNvgI8BRDp3Xe1FDv8izK2Dw9HwjykDDU+uMNZNtNpdA=
Signature digestsha512
Dependencies
Required Nextcloud versions >=31.0.0,<35.0.0
Minimum Integer bits32
3D Viewer 2.3.4
Release Details
UpdatedJan. 18, 2026, 6:57 a.m.
Changelog

Changed

  • Dependencies: Updated development dependencies
  • @babel/core: ^7.28.5 → ^7.28.6
  • @babel/preset-env: ^7.28.5 → ^7.28.6
  • postcss-html: ^1.7.0 → ^1.8.1
  • vite: ^7.2.7 → ^7.3.1

Fixed

  • Nextcloud Subfolder Compatibility (#74)
  • Fixed app not working when Nextcloud is installed in a subfolder (e.g., https://example.com/nextcloud/)
  • Replaced all hardcoded /apps/threedviewer/... paths with Nextcloud's generateUrl() and imagePath() functions
  • API endpoints, decoder paths, and static assets now correctly respect the configured webroot
  • Affected files: multiFileHelpers.js, useModelLoading.js, useComparison.js, gltf.js, ViewerComponent.vue, SlicerModal.vue, App.vue, viewer-config.js
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
Signaturem8HTfU5qBOyGRmdHu4hylXbuVzwpcofBxDmpgWjNf0qvBkujJC75qp0z1GcJKDRppDXuE5z70L6g5AAUda+v3Z5y9byJqnisxNVRZM0nbXwYgOmqi8MdBnP7bzd5Ms43jDwr8hKt5ffEKR+g6h7Um8q5BDl3Vdk2J8nVuk+uvduDXalukp+USx3ibBHjg3MDSJqdkTKkHPe41SXEpjyor9VMKLer8r7HxHcwlELGseyuFHgL/PPYQOT5GQf6KO7ae0s2lYH6tbBu3ZnP/f0tg4cYZAHAycm4fvAwRj44XMh6a3OFP0FdQOkpSmYa7Tp5IH5rj4zBjrazGCxtUU40q3bBmYRvIKiv/je83LfQA5n8FCgmjREez0JslPFBByM//FtrcFgsm1mrzSgkufLTdvQ8JYb1XbV6xI7jKWSYKdCidwpvHCWAUqvQDWRVL2cZ7tLyGwSVHtLEsftO3Ykhu7WYpyQmNIG2s6zTuBC9x52IL7hxU9+7127R5L7S2AdPxvUB5Xrz5PJbfKal41mSi5GTJ1s1d+ow6lyB/rU1yGMX12Y0gDTZjXLHvCMq6Ixtcy1igH1nd/C8P+j1vDHbDPyZnIKtx9yBTMsejnv9tdsPpE4ya+eM54l1i+gZEdM8NhFxows/bBHJaljU6DBRvtdYBriWsMHsrsDB2wSuTMA=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 2.3.3
Release Details
UpdatedJan. 16, 2026, 2:42 a.m.
Changelog

Added

  • Automatic Thumbnail Generation: 3D model thumbnails are now automatically generated when viewing files
  • Thumbnails are captured with smart cropping to focus on model content
  • Grid and axes are hidden during capture for clean previews
  • Thumbnails stored in Nextcloud app data (not in user files) to avoid cluttering recent files
  • User setting to enable/disable thumbnail generation in Personal Settings → 3D Viewer → Thumbnails
  • "Clear thumbnails" button in settings to delete all stored thumbnails
  • Works in both standalone viewer and Nextcloud Files integration modal
  • Thumbnail Settings: New Thumbnails section in Personal Settings
  • Toggle to enable/disable automatic thumbnail generation
  • Clear thumbnails button with confirmation dialog and count of deleted files

Changed

  • Thumbnails are now stored in Nextcloud's internal app data folder instead of user folder
  • Prevents thumbnails from appearing in "Recommended files" and recent files lists
  • Improved privacy and cleaner user file space

Technical

  • New ThumbnailService using IAppData for app-internal storage
  • New ThumbnailController with endpoints for storing and clearing thumbnails
  • useThumbnailCapture composable with smart content-aware cropping
  • Thumbnail capture integrated into both ThreeViewer.vue and ViewerComponent.vue
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureuFzoE7HPsOrBKlyKjSzOuEeHjB3dAL7I/y0IF+GNXsgneUJobVLzw+kWlOtZyGa4wNcavAH3caVRlqPjMdw/ZlrlgkJN62qghl/yvbskmmSsiC43ntcKMfGd8Gat1wCXPzTGipRc4DqwbpUyN3PIVltZgpSvX+xaTB3+bLwPNIg2vX2GMpalC9vN2eGa60fPm//OXZKujqfRVwGqg36OpfuRKgOr+J2xDyxAsyc6UywFRGHUnpGLiZgp0jXIRshqpM+k3fpbZDB1JrDbYlPaAZwa4Ze//xxv4Xbk4KmmlLY0S6GXChNbX0rAYrwv+PxJxFeLSI5ytw9iZPdDFQFmgm5RJv7XVhmc31ccZyJ8eaTRz2+JfqBRV5csX5Ox9QIVjmkL3WX70eNIcRUBGX4BFOcCqZxnRgg3moqoSKAZFQ3sOMxwStiKlHhrffZvclDLZRL3S76C492BVlF9HFZc5KYnuF17VQPs1OL8xWFcW57HfcjpMs6xydfnMtfTJUTWbS9p6fjaxLjUgl93ZqWTMmc8dpXl7ywiLjVViTNk8PNn3NzHP3H5yszzBxcO6elz7cIQgXRKdVKB8OQoaeMEjxQQfmWAIViZyXoEEhS76bsI1oeuqAiNH/9p+ytUkBeN7FK6yljt/8QauU38PLTih0QE2xCLB6fP1EMAtLAb7PY=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 2.3.2
Release Details
UpdatedJan. 7, 2026, 4:17 a.m.
Changelog

Changed

  • Dependencies: Updated development dependencies
  • stylelint-scss: ^6.13.0 → ^6.14.0 (dev)
    • Enhanced dollar-variable-no-missing-interpolation to flag namespaced variables in custom properties
    • Extended function-disallowed-list to detect disallowed functions within @return expressions
    • Fixed false positives in dollar-variable-no-missing-interpolation when variables already exist inside interpolation
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureYV9kZk3oeyVbeTn1qLIVLgb5ERRXgsTQamJCdPTLt4vgt7xf3ShcXd6Srry0UKHzEGvXqQjVq3sfxtq5INZNKQugyC67dlmP+WfFbq7nsLoGJp4Cpjza5ud+4ozbxgbVqNFhNoFVz/zYGyc1lAcSUP8zC10x6zfq/0WoRUFgWHOKCuK6ZB4vQd5J7JRX7JKX1sxbl+rGHSqbQeWuyJwlCir+zr5Y+746EJ+2S29f8z3KFxf2PfEZwAmE1Nf05FAVL5RhQhlDjqM7J2NvQEP6Pod8b6Q+RxFKMWkYyTHncCfQTNz+3VYeuJsqfYC6ZVADYOT5duvHbqOIW4sdnrotXWQDq0uxww7qKYISKp4srSKBwiN1k6EIGt2Clr5FOlji80tIlOtzqanLWQlhpV3wuiVSA8TTbfxPVlB4Mn7dGu/LHc5TjfQ5JEct+5nfEwSCdnLbnEhLyiNRFPppmpIjfHhSWhVrHpz/YRdSarEsmNeP31dSoJKbhNtqhi1oIbtyXG5ElYrTFFg+nxz/yc3Ok33KY+D1nJ9gIN+Qdde9E86qg0cXeIgq+CtM0TGomTKPt9BXQfresW9zuzKli1p7xS3d0C21acP8r6humszQcZQNliz936kTkULULFo86VkyYmK79Gmm16tcMDXbXiZcvhwqF/xrXS6QuQb44K9hC2s=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 2.3.1
Release Details
UpdatedJan. 7, 2026, 3:03 a.m.
Changelog

Fixed

  • "Send to Slicer" Button Always Disabled
  • Fixed missing modelLoaded prop binding in SlideOutToolPanel component
  • Button now correctly enables when a model is loaded
  • Affects STL and all other 3D model formats

  • CRITICAL: Cron Job Fatal Error (#65)

  • Fixed foreach() argument must be of type array|object, null given error in CleanupTempFiles cron job
  • Removed incorrect foreach wrapper around callForAllUsers() method

  • CRITICAL: Missing Exception Method

  • Added missing getExtension() method to UnsupportedFileTypeException class
  • Fixed fatal error when attempting to access extension information from unsupported file type exceptions
  • Updated all exception throw sites to include extension parameter

  • CRITICAL: Insecure Rate Limiting

  • Replaced insecure session-based rate limiting with distributed cache implementation
  • Uses ICacheFactory for thread-safe, multi-server compatible rate limiting
  • Prevents rate limit bypass by session clearing
  • Improved scalability for large installations

  • HIGH: IP Address Spoofing Vulnerability

  • Replaced custom IP detection with Nextcloud's secure $request->getRemoteAddress() method
  • Prevents IP spoofing via forged X-Forwarded-For headers
  • Properly respects trusted proxy configuration

  • HIGH: Path Traversal Vulnerability

  • Fixed path traversal vulnerability in temp folder verification (SlicerController)
  • Replaced insecure strpos() checks with proper str_starts_with() path validation
  • Prevents unauthorized file access via path traversal attacks

  • MEDIUM: HTTP Header Injection

  • Fixed potential header injection in Content-Disposition header (PublicFileController)
  • Replaced addslashes() with proper RFC 2231 encoding using rawurlencode()
  • Prevents header injection via malicious filenames

Improved

  • Temp File Cleanup Enhancements
  • Added comprehensive logging for NotFoundException cases
  • Implemented cleanup statistics tracking (files deleted, shares deleted, users processed, errors)
  • Improved share deletion error handling with separate method and individual error logging
  • Added file type validation to skip directories during cleanup
  • Added progress logging every 100 users for large instances
  • Added stack traces to error logs for better debugging
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureMK0+lREma3H+5o5HY/1XiCvaVsxjUPM6tcB151nPTrwJOeBdbFF50jwp8N7+xgyKEF8GZEOYpwqBu2jYjlN8bJBJFDUI4Givl++H6HAT0/yOhq22oItRC9eOdmrdLiduHqSm10UDj37gda6vOjZwGiPKG6OcmqTkAB5z6tCSX9xH4RznZwbWIpCKBKfUDv53iCyBiogCX3Zyz7443IEdkBy51an9N64COoiWJACcw1kse1f2JtS5ptYTXBA1ImMNOVkX+I2n+b4qp9n972UGMXyx8JnhH7nuVp4XH7nY2oargPPk4b+p1Yqq5/bJGsdazm+i8PaYcJ6UHJTySjTOIvh6MuWpA+xuXTWSgM9k1DUTFG2YQ1RS/JJsFQ4Xhm9GffxDOQ8mSMRp3MnEdMd8FgIU+REqQP3MAYvxQ/c11RWoaolM+VbWrKNGJqB2U2pliu4oM7DRlZg4GmgHvYUMUQQYTq+L1lZlvyQp+NweTuvaUcx6cY5z3SdiRb75o3fYhgNGPDg6ZgsV45Oy6srZofHfGiuYy+c/AkL9Nr8c0nBlZWtxV/OVdPsbHHmNhSVAmv2baFug1mGUcGYRApCmWLlpJbskW3ZNeFfsHp/d/st0LPjhK6ItDHe+6khDFAYoqQWFA2z2nmrWZuD/FzB2Ny3TVCZBQkpzDc7hJiBBxGY=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 2.3.0
Release Details
UpdatedDec. 28, 2025, 1:15 p.m.
Changelog

Added

  • G-code Visualization Enhancements
  • Smooth rainbow spectrum gradient coloring across entire model
  • Intelligent filtering of travel moves, retractions, and parking movements
  • Skip movements exceeding 50mm in XY plane to remove edge artifacts
  • Fixed vertex color handling for proper gradient display when toggling modes

  • Mobile View Optimizations

  • Responsive MinimalTopBar with all icons visible on small screens
  • Help panel displays full-screen with sticky header on mobile
  • Smooth scrolling support for iOS devices
  • Performance stats overlay hidden by default on mobile and screens ≤768px

  • G-code Toolpath Visualization: Added support for G-code files used in 3D printing and CNC machining

  • New G-code parser supporting G0/G1 movement commands
  • Automatic layer detection based on Z-height changes
  • Color-coded visualization with different colors per layer using HSL gradient
  • Support for multiple file extensions: .gcode, .gco, .nc, .acode (AnkerMake)
  • MIME type registration: text/x-gcode
  • Custom file type icon for G-code files
  • Toolpath rendered as 3D line segments with configurable transparency

  • Extended G-code Ecosystem Support

  • Additional extensions recognized and routed to the G-code loader: .g, .gx (FlashForge), .g3drem (Dremel), .makerbot, .thing
  • MIME mappings added for container variants: application/x-gcode for .gx, .g3drem, .makerbot, .thing
  • Viewer “By Type” browser now lists these extensions via SUPPORTED_FORMATS config

Changed

  • Backend Listing Filters: Updated FileController filters to include G‑code-related extensions in Folders, Type, and Date views so these files surface across all navigation modes
  • Applies to folder-scoped listing, type grouping, date grouping, nested folder inclusion checks, and descendant checks
  • Slicer Handoff Options: Simplified send-to-slicer flow by letting users pick passthrough extensions; all other formats now auto-convert to STL by default (export-format selector removed)
  • G-code Visualization Default: Default toolpath color mode is now gradient instead of single-color orange for clearer multi-layer contrast

Dependencies

  • Updated @nextcloud/dialogs from 7.1.0 to 7.2.0
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignaturePzIAblqli6tJofqSxWWKOwCp0h/EaSHMlT/+yyoqArTsvBAPzn8xLqU4/58/5pja+YAA7WeQ9egTPUicOilrSFBSHQVGa2QSLQVWFu+vTXKGEuu90qNxXnNqDnl66TVKuWR0OiXHeR2nCAdu3jh7310h8afbBLR3eQAXIeuWlLtXnbzVLoaiqy4pK9l2FzN8GpQoU4/7fo7SH1CFE6iR+Yea4Y2P6C1UXGQfG/RnJylCj1UT+2UkkLUAopk9AOxMEgQpwQzUV5kl4FwvND4biwcuXEajDXwVizX9qAEDtOkzILdV46RcWkyHxnDcqIGHuRImgfqWlwwz6fZ14Huf7/5bmvNafPuSPPRJHEWvH66whuXS5sft+Crvd1/AR+sF2bDGtGtoQo2iSRSCmVS8XtsK0+dW+DLGIvd7pQsul/AIWPDYYkPtMCgAXCFLJpFmmOhNNoCOshjRSgJ5LrnfBC3kbF66gBZGhlkBc0n9MDkqlgxDNVNGwYHYG6xllH4u+1xdGIilc7TE2EXSmpD3GEJOCTLiRdMDbL2ZSC04fd9Lf5YbVgKMggroGFNbtl9VszrOD8GtgpyUqdQnZ9D2U9ef8sJqRxzWKNT3Sr3A2PxgKiCf8G0yu0016JlmwHeEJQAWs9u+0ZpnYo51eSGQKnKtonW1avH6I95Mqh6cPbA=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 2.2.0
Release Details
UpdatedDec. 17, 2025, 6:10 p.m.
Changelog

Added

  • Measurement & Annotation Visual Sizing Controls: Added per-user sliders to control measurement and annotation visuals
  • New Personal Settings section for adjusting measurement point size, line thickness, and label width
  • New Personal Settings sliders for annotation point size and label width
  • Settings are stored per user via SettingsController and merged into VIEWER_CONFIG.visualSizing
  • Measurement and annotation composables (useMeasurement.js, useAnnotation.js) now derive sizes from configurable percentages of the model size
  • Animation Controls in UI: Added animation play/pause controls to viewer interface
  • Animation play/pause button in MinimalTopBar component
  • Animation controls section in SlideOutToolPanel with play/pause and loop toggle
  • Animation state props passed through App.vue to child components
  • Integration of useAnimation composable in ThreeViewer component
  • Improved directory path extraction for multi-file model loading
  • Dependency Cache Insights: Added live cache statistics (size, entries, hit rate) to the viewer and slide-out tools
  • Viewer performance panel now shows cache size and hit rate
  • Slide-out tools panel displays cache stats and clear-cache control with status
  • Cache stats refresh automatically during use and after model loads or cache clears
  • Cache hit/miss tracking with reset when clearing the cache
  • Performance Scaling for Large Models: Automatic performance mode suggestions and easy mode switching
  • Configurable triangle count thresholds (warn: 500K, strong: 1M faces) for detecting heavy models
  • Automatic toast notification suggesting performance mode for models exceeding thresholds
  • Clickable performance mode label in stats overlay to cycle through modes (Auto → Low → Balanced → High → Ultra)
  • ViewerToolbar performance button now cycles through modes instead of toggling stats
  • Performance mode changes apply immediately with visual feedback
  • Slicer Temp File Security Hardening: Enhanced security for temporary file uploads
  • File size validation: 50MB per file limit, 200MB rolling folder cap
  • MIME type validation for STL files with header checking
  • Rolling 24-hour expiration enforced on file access
  • Increased cleanup frequency from 24h to 6h for faster expiry enforcement
  • Comprehensive audit logging for creation, access, and deletion events
  • Security posture documented in TECHNICAL.md
  • Automated Bundle Budget Enforcement: Enhanced bundle size checking with historical tracking
  • Comprehensive budget thresholds for all major bundles (main, loaders, app, three-core, index, nc-select)
  • Historical size trend tracking in bundle-sizes.json (last 50 builds)
  • CI workflow uploads bundle size history as artifact (90-day retention)
  • Size trend comparison shows changes vs previous build
  • Improved error reporting with formatted bytes and clear failure messages
  • Fails CI builds when budgets are exceeded (with environment variable overrides)
  • Vue 3 Migration Pre-Work: Eliminated Vue 3 incompatible patterns to prepare for future migration
  • Replaced deprecated lifecycle hooks (beforeDestroybeforeUnmount in ViewerToolbar, ToastContainer, ViewerComponent, viewer-api.js)
  • Added explicit emits declarations to all components (ViewerToolbar, ToastContainer, ViewerComponent, ViewerModal, FileNavigation, FileBrowser)
  • Verified no implicit $listeners usage (removed in Vue 3)
  • Added comprehensive migration notes to COMPOSABLES_API.md with dependency compatibility matrix
  • Audited dependencies: vue 2.7 → 3.x (API compatible), @nextcloud/vue 8.x → 9.x (requires Nextcloud 30+)

Changed

  • Cache Statistics Updates: Improved cache stats refresh frequency from 5 seconds to 2 seconds for more responsive UI
  • Performance Mode Controls: Enhanced performance mode switching with clickable controls
  • Performance mode label in stats overlay is now clickable to cycle modes
  • ViewerToolbar performance button cycles modes (preserves MinimalTopBar toggle behavior)
  • All mode changes apply immediately with proper event propagation
  • Dependencies: Updated core runtime and build tooling
  • three: ^0.181.2 → ^0.182.0 (patch update)
  • vite: ^7.2.6 → ^7.2.7 (dev, patch update)
  • Security Workflow: Updated GitHub Actions CodeQL workflow to use github/codeql-action v4 in preparation for the v3 deprecation in December 2026

Fixed

  • Toast Event Handling: Fixed missing push-toast event handler in App.vue preventing performance suggestion toasts from displaying
  • ViewerModal Performance Mode: Fixed performance mode cycling in ViewerModal component by adding proper prop passing and event handling
  • Model Comparison Positioning: Fixed comparison model positioning issues where the second model's position was immutable
  • Wrapped comparison model in a Group to neutralize baked position offset from loading
  • Fixed parent-child relationship handling by using toRaw() to get actual Three.js objects instead of Vue proxies
  • Ensured matrixAutoUpdate is enabled for wrapper and all children for proper render loop updates
  • Fixed matrix validation order: validate parent matrices before child objects to prevent "Cannot read properties of undefined" errors
  • Improved scene hierarchy validation to include all objects (grid, axes, lights) not just models
  • Fixed matrix update sequence: call updateMatrix() on all objects before updateMatrixWorld() to ensure proper transformations
  • Comparison models now position correctly side-by-side with proper spacing and alignment
  • CSP Compliance for Texture Loading: Fixed Content Security Policy violations when loading GLB/GLTF models with embedded textures in Nextcloud modal viewer
  • Patched Image.prototype.src setter to automatically convert blob URLs to data URIs for texture loading
  • Patched URL.createObjectURL to track blob-to-URL mappings for later conversion
  • Patched fetch() and XMLHttpRequest to intercept blob URLs and convert them to data URIs
  • Patched THREE.FileLoader to handle blob URL conversion for texture resources
  • Automatic detection of modal viewer context (iframe or Nextcloud viewer) to apply CSP workarounds only when needed
  • All patches are automatically restored after model loading completes
  • CSP Compliance for Buffer Loading: Fixed CSP violations when loading GLTF files with external .bin buffer files
  • Updated setupResourceManager to use data URIs for buffers in modal context (instead of blob URLs)
  • Patched fetch() to intercept data URI requests and decode them manually, bypassing CSP restrictions
  • Supports both base64 and URL-encoded data URIs for maximum compatibility
  • Animation Support for Multi-File GLTF: Fixed missing animation initialization for GLTF files loaded with external dependencies
  • Added animation detection and initialization to loadModelWithFiles function
  • Animations now properly initialize when loading GLTF files with external .bin files
  • Animation controls now appear correctly for animated multi-file GLTF models
  • False Texture Warning: Removed automatic texture warning banner that was incorrectly showing for all GLB/GLTF files
  • Warning now only appears when actual CSP errors or texture loading failures are detected
  • Improved user experience by eliminating false warnings when textures load successfully
  • Slicer Upload Safety: Hardened temporary STL upload handling with size and MIME validation
  • Reject uploads over 50 MB per file and enforce a 200 MB rolling temp folder cap
  • Validate STL MIME/header before accepting; reject invalid content
  • Enforce rolling 24h expiration on access and clean up expired shares/files
  • Use rolling +1 day expiration for generated share links
  • OBJ Texture Loading Robustness: Improved OBJ/MTL parsing and texture handling
  • Preserve texture/MTL paths with spaces and mark materials for update after textures load
  • Use existing blob File objects for texture URLs and tighten loader logging
  • Handle texture load failures gracefully and ensure needsUpdate flags are set
  • Texture Dependency Lookup: Skip direct “find by path” lookups for image textures to avoid unnecessary 404s; rely on directory listings for textures commonly stored in subfolders
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
Signatureacd0z9v0ifd6EhLDkZPQmIADZp+TPcgSOqKKp6W5KUtq4CA/Xk0lTNssZpirrEaLO4s15qemVCz87Aa6hhxGipOFlBSMFIyc1U0q8OQzHMOa4cYU8w1hvmi7aXeG+IxPWXelCAYaBNYGbleOvhc+/ao1gh1mn+3esakeTLdBi8XihNAKBDzglkOD30oBunXuzXJD1chBFBx7LCMoRhVXHDxShzi39+vbumkbme4IGV9kL323hTSjD1+XrMeiIG2P9tvHDEkGRXEOKohmWQNrsFCamApVqslvRzg6mBFTFv+dtnBUFbbQnC25IvyE+UNY4j2TGzncrW2+jWGddicKYq4SIrI7RzB91gTxv+3qzwCUb8OlyaU38L042l4HJXSFMPh8Mmj2n/0zhWlH4M2h/ZEPjySsaK8lU/x/DaBoyLcPoJcDsuD1haONv6mpRsoz/ohXdV/U9s61rbGOnJkSqMMblFoVXVmkzTKpBatf08e9Uaig21b9q/ekYyhbVFlujmAu9ku9EWk5SddY26zNvSeiGinV1xV3BayMI3rVZYINZkPb72Dv6DOInRWlVOxVqLQBUY98ejlhpls+6l3IdtTDUmrITmGr+Nq3b8T8kgNJpgNQbf3Ij14MgdfNsxd4nxMyX/4hsOSZdU4dAHsTfatSxRgM1q9FpuvZ+OkyWMA=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 2.1.0
Release Details
UpdatedDec. 6, 2025, 10:21 a.m.
Changelog

Added

  • File Browser Default View Setting: Added user preference for default file browser view mode (Grid or List)
  • New setting in Personal Settings → File Browser → Default View
  • FileBrowser component now loads and respects the default view from user settings
  • Setting takes precedence over localStorage, ensuring consistent default behavior
  • Manual view changes are still saved to localStorage for session persistence
  • Format Sync Test Suite: Created comprehensive unit tests (tests/unit/Service/FormatSyncTest.php) to ensure format definitions stay synchronized across:
  • Backend PHP constants (lib/Constants/SupportedFormats.php)
  • Frontend configuration (src/config/viewer-config.js)
  • Nextcloud MIME registration (appinfo/mimetypemapping.json)
  • File Browser List View: Added ability to toggle between grid and list views in file browser

Changed

  • Format Definitions Centralized: Consolidated all 3D model format definitions into lib/Constants/SupportedFormats.php as single source of truth
  • EXT_MIME_MAP for extension to MIME type mappings
  • CONTENT_TYPE_MAP for file streaming content types
  • All repair steps and services now reference centralized constants
  • Eliminates format definition divergence between components
  • File Browser Grid Padding: Updated file grid padding to consistent 20px on all sides for better visual spacing

Documentation

  • Corrected repository URLs and upstream fork instructions in CONTRIBUTING.md (replaced placeholders with maz1987in/3Dviewer-Nextcloud).
  • Updated TECHNICAL.md with new controllers (SettingsController, SlicerController), components (PersonalSettings.vue, SlicerModal.vue), and detailed Personal Settings + File Browser implementation sections.
  • Added comprehensive "Adding a New Format" guide in TECHNICAL.md with step-by-step instructions and code examples
  • Expanded IMPLEMENTATION.md: added Slicer Integration & Personal Settings System sections; reorganized and deduplicated legacy "Code Audit and Cleanup" content; refreshed Table of Contents.
  • Updated README.md (docs version) advanced features list to include Slicer Integration and Personal Settings.
  • Added troubleshooting sections for Slicer Integration and Personal Settings in TROUBLESHOOTING.md.
  • Expanded test coverage notes in TESTING.md to include new controllers (Settings/Slicer) and components (PersonalSettings/SlicerModal).
  • Normalized wording and removed outdated dual-mode duplication in implementation documentation.
  • Documented dual-mode viewer architecture in TECHNICAL.md with viewer lifecycle diagram (standalone vs modal modes).

Fixed

  • Settings page image/logo path resolution: replaced hardcoded asset URL with imagePath() helper in PersonalSettings.vue to ensure correct loading under all deployment paths.
  • VRML preprocessing duplication: Removed duplicate preprocessing code in preprocessVrmlText() that was applying BOM removal, line ending normalization, and null byte removal twice, causing inconsistent preprocessing behavior.
  • Flexible texture matching loop control: Fixed nested loop control flow in texture matching logic (multiFileHelpers.js) by adding foundMatch flag to properly exit outer loop when match is found in inner loop, preventing valid texture matches from being skipped.
  • Premature texture issue check: Moved checkForTextureIssues() setTimeout call in ViewerComponent.vue to execute after model successfully loads and is added to scene, ensuring accurate texture loading status assessment.
  • Debug logging cleanup: Removed console.log statements from FileBrowser.vue component (viewMode watcher and setViewMode method) to improve production code quality.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureatLgIGKAv/DO42HgoDbqVaos4kWPFuPmF5l4PHyM5S5ivOlmqnC5xu1+d5uX/h+0rUmL+pG6wKezHo7WT0PVKSBciYZzlb5D+6sJisB5x/jMVqFaQRmnEEPKfoz2DsDucmXtH6Ppv3oXjyKd5wDjyFMwtoG1hU43QBeA4ngYTMTCXqdITK5sT4OM4IwiYhUi7zZRh6/YoRxgojXIqo/RasM3sGIUIrQs075RKqXcdGcGUwJgQPAQnGsMEW9D0LODp6bYurgBZRgnmgBrpTE3D7Ktt1G+ppQTSW4tHpuq3mFJdhFlkbhbWJw9QW28xJmDnqUGfhzXTSMqoJLnbio0n7iT5bhiyxBmhi5patzHifmDwndpRPoZNbw7vxr2zzqCc+1pMt/CoXHn1PTthmYtQMg9tvyjS7jbCdYtDYLtluzITRHP8GzRXIMmBrCRzXLymk0b3IvwyB9G83+QwzHyWSTLsKV314CSasumGhFDSxnz0E2DhVVZV7yaG89Dj9HHwmxkQVeh4iI9DCd5ynu6q/8Ljyp4nJ1p//+3WCo3NksaM0ubqkXiVFnSTnSjsoDw8mbP8TU/iESpYJ11llVA9ftZSGnnczY2zFKKK17C5m/pjE9sskLlo2bfhBzRLvYOV8ejRyaXPK1B6ejCfk2VwWntq7UKFh/+/1R5usmQkRg=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 2.0.0
Release Details
UpdatedDec. 2, 2025, 2:53 a.m.
Changelog

Added

  • Personal Settings: Added personal settings page for user-specific preferences
  • SettingsController and PersonalSettings view for managing user preferences
  • Settings routes and configuration updates
  • Enhanced File Loaders: Significantly improved loader capabilities
  • Enhanced FBX loader with additional features and better support
  • Improved VRML loader with expanded capabilities
  • Updated DAE loader for better compatibility
  • Enhanced multi-file loading helpers for improved dependency resolution

Changed

  • Viewer Enhancements: Enhanced ThreeViewer component with improved controls and features
  • Camera Improvements: Updated camera composable with additional functionality
  • Circular Controller: Enhanced circular controller with better user experience
  • Theme and Performance: Updated theme and performance composables
  • Major Version Bump: Version 2.0.0 introduces significant improvements and new features

Technical

  • Updated GitHub workflows with improved condition syntax
  • Updated Dependabot timezone to Asia/Muscat
  • Added change detection to prevent unnecessary PRs in workflows
  • Updated stylelint to 16.26.1
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureJrtVI0UiQsSqL82PvCmO+FLp06iE6caUY8nD1+dKlVr5YjeTvZjLUtd0sAbmwQzlR2iC4IuRJllv7hr5cWk8oWuJtnLuE4uzcXu3bu8ndzO/Zyf4ph65Fn3GyML8Zdm6TqECBFCzk+2NG0pVxt4TM7qML5p437Q6IrF0+uOh3Vj55CTf160KAjEN7v2Sa8CT4Qf/JPKtnfyAgnKkNRXMQCf7xXe3RqtgtiVPnNq6nKfYzERoihIHhZ4LqLewUfY7jvxKUpAIxF89K+yTk1PmsJgKPBN88FF3ReKwcfJcfIhMXuH7CJEHCg++Hbd0oxzvl3uv0o8k5USdkojH0vG5IQaBF8AAEGY0aKCsScmffSN7WvmpPngsHs56V/olPNPVG1QNepRvSvBljr9D6idShiRlaW7uOBl9SVwLernLBjZ30bfqRtdrm2T7oO6gozY0zRc3jxt+ajAuaPLp8pAKC/Bv8nt3Og7R3r/mpk7qXWEgC/u78v/LqjhtICx1CQDSROq8vuces8k4iEN1kJabrhxLFPDPmZucoXWSzUStP+ISyPksq+pk5KAtnKuVRMTN8rhYkMlyK1790OOF53Q1bvlHnTc3LmzTLi6b/mVPBtz+KgkHHoU8j4TYwSlnbmSx6gDqzrQa8q+cRXlK1NNmF211NX0J8B9nRkng+xHg5ts=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.8
Release Details
UpdatedNov. 28, 2025, 6:24 a.m.
Changelog

Changed

  • Dependencies: Updated development and runtime dependencies
  • three: ^0.181.1 → ^0.181.2 (patch update)
  • stylelint: ^16.25.0 → ^16.26.0 (dev)
  • vite: ^7.2.2 → ^7.2.4 (dev)
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureMKCHrKGV1G4CZgG/gyhGvg34zK0migxfZ/FS9ZZEylzffGxQxoQbW+wubOR3BAjgWRx5smOBIdKVeLLuPOV00JnPgrII3lRaltLVO72nNrYtVh5DruKC5ZoMM4BuJsdEOFP8euy/GDCmlhQYNTusS/T+meggfylcrAjZAWR+SZZfb4x7QlBJTdmCuWpHNBJO081IpeLfn5HXohFAWm6sHHm6mun4ar6znAlwsZ/pe6Lo8ZjzLBuDN9mLEujrw6AgjTq2DTSUrHrJ9/WQF3zBiYjRLMNurJLnrwCXuUmPkKGWrPM3ybFADqfgb3QmqzPsPiGUL87k/1yVewEqE2olFpVRZ9hxa11ANingG+zMZwY1bCbzIcrRCq4Uoae7zgwZV/CF2wJQk+cRMbQl7Y7AoAy6PPECLMFtU93VgHqcPtFQzAxSPEXRNW+GpkVFHWvBZ7iuL6Ys8gMjl9i9imuNYcIAkuLlKLmu8t5pQpOLKvNpiQkeIf5aWXHm5Fvq7+zmeKIsuMVNvPoqQOSlC1AkwnLi1EAf/2VrqbAmDoC/o3Y6h1mg6vskUNFRPhz2h37TEb65h1bm9kFjNx/6TNNF0xM96GSAt7v+I1naBODhvGqDqyJ653663yuE+CxdKd1kZ4ous3urqXRwAmKHVdOvXYZTb+N/Feu7PHqrdcwlHHQ=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.7
Release Details
UpdatedNov. 27, 2025, 5:42 a.m.
Changelog

Added

  • AnycubicSlicer Support: Added integration for AnycubicSlicer with custom icon and URL scheme. (#52)
  • Folder Exclusion: Added support for .no3d marker file to exclude specific folders from 3D file scanning.
  • Hidden Folder Exclusion: Automatically exclude hidden folders (starting with .) from the file index.
  • Temp File Cleanup: Implemented background job to automatically clean up .3dviewer_temp files older than 24 hours.

Fixed

  • Layout Issue: Fixed white empty space when hiding the navigation sidebar by ensuring correct flexbox behavior and explicit slot usage.
  • Viewer Resizing: Fixed 3D canvas visual resizing issue by syncing internal resolution with CSS dimensions (width: 100%).
  • Slicer Icons: Fixed missing slicer icons by using the correct imagePath helper for asset URLs.
  • "By Folder" Navigation: improved folder indexing logic to correctly build hierarchy and handle edge cases.
  • Server Error: Resolved persistent preg_match error in PreviewManager by disabling unused app preview provider registration.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureLfmZ7uqqVk6tDgQQuwcGuzQml5OZWmFvpfNYW9Nd+3gVtIRUCBKsgtB8D6CMf1ymq2JxllnMvhATHE3YVZGmCsL5CRrj6al9+zdVnP8An2BUBP/DsqDTTwLM64mwKFIqYYkjtwVfttaa/aPJn2cdH7umzjOEHsYzbRx7eiP1lq2ERy4KYs7aA26hfleg9kKbr1jKTf0/vPCHvmbKg+o3RS+QfP/lRuoPjk1UYog52IAHd9bpAtAgmB2yLSfghjPSvMhZkyWt38CKMiKyO2R+VdB6wc/lWWVWq1JfJDw9oZlhaMpBZhXVDqR7uoMYdtR2pTNhB6d+kaTQtclvLSO5RREUDMwdocOl7iVMwrXCmKmUIyDqMa/VF3FFtK31fKlSYuvIhGDi1He0NNqlv2jiMsb2EPhrYLBHTyrmY0Px3i+ZmbYos1sFXLi7CliafZY/nZwxqPSc8xsZI42MFO9ZWA7yBKYE6UHphNnbxTbx5H33NrwHdRhOh0g+wpLJebbjyi1momlshADpfec+gAImcCnyaXhIX0Vpt73R1DmadH0xbi37iCEg73s9h6cul1RGeRhOzr+c8nhuFOUq4wodj9VLbTwwqm+bjd1jvshyo0++A0Nhjfj79phnnIJl0xsKU9QaN1eFlB6vPQRMyFswy6bWW4IW/yI2KL7693JFhRE=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.6
Release Details
UpdatedNov. 20, 2025, 12:48 p.m.
Changelog

Fixed

  • Preview Provider Registration: Fixed ArgumentCountError during app service registration
  • registerPreviewProvider() requires 2 arguments (MIME type and provider class)
  • Now registers ModelPreviewProvider for each supported MIME type individually
  • Resolves error: "Too few arguments to function registerPreviewProvider(), 1 passed and exactly 2 expected"
  • Migration Class Declaration: Fixed missing class declaration in migration file
  • Added class Version010902Date20251116061241 extends SimpleMigrationStep declaration
  • Resolves syntax error: "unexpected token \"public\", expecting end of file"
  • Folder Path Length: Removed the 512-character limit by hashing folder paths for indexing
  • Restored folder_path to TEXT and added a folder_path_hash column with a new migration
  • Existing rows are backfilled automatically so deep folder structures continue to work
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
Signature4F3B+MMtZoJiTGIBdBSaJDW9PVnv2o38ob0m+f5cIJmMM6jpgqYETLsQaW1zRCdQ8ozE8v5LfkehmhMlXy8folvlapuRcDGh9N7PPIRzTM/8b9ymOMQ1vkBPERw8k5grkUwFNamMPw+K4rFGHLMflN+vR/S6m0jmAKls/2L4kg2UdhaTdtaw/ozZAM4a09dJ038kyBS6jbh6g/M233Ue/R6aXSCMVgrA5zw38djqE9O8zmUg8xOJlOzdMRCRdhKWZOHoocLV9TBTasdU99YG7o+VIgAXeTY4X0rKxtOdfqdX+c+YNEt4syMmig/1p3e3yO1q0CmQPg6rgxtrdVOW1KK6Bbsvd8DkNwyQ0SgREq8bD+SIlF3QfqTDAFKCDgjTCn9N7HBnZIVa+NtseVrVfVeEdWdVNGMnfu9QhSeMqrE5dJMzKJLiPy4ftrmzM+aff+3aoQU69wWVffIBw1RsC3+352E90jiYw8CnH0ul8I6ffA+NVD4v8+Jo2MruxzwzTsq7/RfQMvIhsCTrhyauECtmwAQPEx9CX4h+7nryjxefgDwPQlFyszt6F53LSTWEeFO49SAlV9dH5P6tsjsMozdUts7HtG+UU+T7gHD65rY/nPL8ICF6C5YHGuuxwDFQGAkKtBNN/9VWBZr8h1X9jq1o57hwIqGBnxNdAs9YqdA=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.5
Release Details
UpdatedNov. 20, 2025, 10:08 a.m.
Changelog

Fixed

  • Preview Provider Registration: Fixed ArgumentCountError during app service registration
  • registerPreviewProvider() requires 2 arguments (MIME type and provider class)
  • Now registers ModelPreviewProvider for each supported MIME type individually
  • Resolves error: "Too few arguments to function registerPreviewProvider(), 1 passed and exactly 2 expected"
  • Migration Class Declaration: Fixed missing class declaration in migration file
  • Added class Version010902Date20251116061241 extends SimpleMigrationStep declaration
  • Resolves syntax error: "unexpected token \"public\", expecting end of file"
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignaturefF9sWdsS9s2UfdNuMWzSK76VLnucCn+KchXB9eFwbDsdXACnQYvhUVvS+xoMBYIfaXQEYUjfIl9oc0/sghPaIfdPvHwhCSze3XUPHkeF8yHb7eXQfHPr8N6KQZdmFM50brxxpHt5yxI40xZU+mMyW3eTP982e+aLenLEr2taQYNoaTHf35NbVknGLAE1xautWR1JQzYyVkCcc4T9/hxMp7LaGBrUPwdDALyuAp6WTHtZk+XeOxxxwRiNb7q7SpXWGuwdbX7MDvEzfBUmhw8dbORK3kqxgfXFAe7uGVdW+5sKtkdn+fxuN4gHKmBwW8N4X7YW1XaAL0KkYFoHsrdAcHunsSn/KfuqhTLHRpxOblgFPEcCwwqWcPVdGASFkD96rYylV9yzoJV2zS/pDqMVG38TQjHOs6ukBbJ5KHzpGJpgOZXDzLn24or5wVubjXkCyOsfS0by89VmrrxrERJZPNl6XTgeCZaBTPsypeWAlezfqVEjVVmdkoKuL+I3m/gMURucZV3Do+wHmxoEAT/2bTRVtIZzBsjrwuljZk4cok0oQ8reFBlngACWmXWskJOiEmshDUpnd2IykjhaU6LPEBDprd0fSM3+RE6Sx1+iJuPdXQ+CUATytcbKc8kiEjcPapzQ7xt3uR2fukG3eLrkFKoKHM7jJtWWMcWmN0yppuQ=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.4
Release Details
UpdatedNov. 20, 2025, 2:09 a.m.
Changelog

Fixed

  • Preview Provider Registration: Fixed ArgumentCountError during app service registration
  • registerPreviewProvider() requires 2 arguments (MIME type and provider class)
  • Now registers ModelPreviewProvider for each supported MIME type individually
  • Resolves error: "Too few arguments to function registerPreviewProvider(), 1 passed and exactly 2 expected"
  • Migration Class Declaration: Fixed missing class declaration in migration file
  • Added class Version010902Date20251116061241 extends SimpleMigrationStep declaration
  • Resolves syntax error: "unexpected token \"public\", expecting end of file"
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureYu4MvwQG1iiUU+ZnS3qdmTsCZ0NYAx89VzPzGTNqkdgQ/LolnwTZNDpkHEOoGQOM7Q95wtrJ1iHj2KQNxHsg/nw26/L0nqQtE8+HN92EVkjKhj4Chve7AB+A8dFlj0nXdSpgtH/PbwN+90lQTCGnmd6rRc46+OqEfEoFzjBhqtrpzXuURKsZG4GV644vSvAyzZFBDncgI7tlGhUhCDj/5UShHQy9ClymB6Yb5K7smP0BSDEWYOxsUOj2/cy7hAIlCyofINC8p6UzA6Po6NiyQefX2zds56a8TZhvvuaeiO3setCQzKXdYp3WqlnVVSpRA7UZfGeqdvkDqtQuTIs4Zo9w6GWX9M+N2Z15rQ59t/cNX0OYhCs+Fw2UdJMAPYW+me911YHsaMmANkaw7sUZ0ncqxbc0NZ8NULhJakF4DHizsCSLZbVrOhpfcaDEpsy6q88bg6o4modcj+gTIytUCI/RLjTlKWYAZcRFJfmPngQiuUmBeZntR2y1a0ROFsmcRAaSys5UFHF1KuqaNocqcAo+CbN5vRqMQXnmGSg54kEHvQ6xjDki/rs/0/5sxIX5TrGhGCyubdpN5Avv1y+eZfMdxVrZu0wxOubN3zgF47b/O5wql0Mv2tpFH88gy5XMGRTyaB1fIeFQXV874btSvkBwJPJhKdTZV0pyA9C+wUk=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.3
Release Details
UpdatedNov. 19, 2025, 5:36 p.m.
Changelog

Fixed

  • Preview Provider Registration: Fixed ArgumentCountError during app service registration
  • registerPreviewProvider() requires 2 arguments (MIME type and provider class)
  • Now registers ModelPreviewProvider for each supported MIME type individually
  • Resolves error: "Too few arguments to function registerPreviewProvider(), 1 passed and exactly 2 expected"
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureYmgaFcAnfaw/gFhMAFJupT22RE/RWydQkyTNQrbQNyHQGq406C58CN9hKEIJ5kaSzibif3goqa31T/si8GlYBnejJmQzYsQpr5Wua0dSrkUtCv0fRFv5GNWJvazyREN7XKWp+Ir/Q51J7trkGs5RCuZRnH1DhHTPyieLyZLTFsSWTSPuDRHEnpqr91B0y+epvQGujYSYG931+5tc6QaX1rfZ9kmT1qNph4SdaLeMa4hbiSFc7fuuSSNqvE8q1QPrBJEz5TMixrr1U8iMA38HBWVsufDfd+lg18bVWg3zQG1yFNZn/RYCuPck6DPiDo2uJ/9AJzOTQpJEFjDfc2zG77oE7EufwDtoaJzbhXhiseW7u0Ty6nVywrYTnEbfuIYhHeo6lbxY8KtoPLZSDSiSbH73oigsGW7o7xA+RDjtVZoWRguPZF9VfUjJ1v5WQpHD0jdZflYJ3byMygWF1z7GaT8wE9gbzwvWUyMGE6XCpzwpNxx3yOlq0mp5aUNFAjJYAO8BSgaFBxSBVnXTv22JEnhaUPAWL3HaMh3EJLVJla/TOG7cd7N9eS6JT3maO8Z7QUu32B/ah48w/uxk9qzmBX+t1onXwUA/6CuY8Gfhcg20AK5JuUiqhIZD1eW7HiC0pNJJqZbzLbXBl049JBFUqZbKLdf+ttISPjCmlRTnxdg=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.2
Release Details
UpdatedNov. 19, 2025, 5:32 p.m.
Changelog

Added

  • Database-Backed File Indexing: New tv_file_index database table for fast folder, type, date, and favorites navigation
  • Automatic indexing via filesystem event listeners (NodeCreated, NodeWritten, NodeDeleted)
  • Manual reindexing via php occ threedviewer:index-files [userId] command or /apps/threedviewer/api/files/index endpoint
  • Migration automatically creates the index table on upgrade
  • Smart File Browser: Complete file navigation system with multiple view modes
  • Viewer mode: Opens 3D viewer by default on app load
  • Folders mode: Hierarchical folder navigation with recursive folder structure
  • Type mode: Browse files grouped by extension (GLB, GLTF, OBJ, etc.)
  • Date mode: Browse files organized by year and month
  • Favorites mode: View all favorited 3D files using Nextcloud system tags
  • Breadcrumb navigation for easy navigation back through folder/type/date hierarchies
  • Consistent card-based UI for folders, types, dates, and files
  • Per-User Configuration: Remembers user preferences via ConfigController
  • Saves preferred sort mode (viewer/folders/type/date/favorites)
  • Remembers last opened file ID for session persistence
  • Mobile experience: automatically hides the circular 3D controller when the viewer detects a small/mobile viewport, preventing overlap with the canvas controls.

Changed

  • Viewer opens by default on app load; the file browser now appears only when a user explicitly selects a navigation mode.
  • GET /apps/threedviewer/api/files/list now serves hierarchical payloads from the database index (folders, types, dates, favorites) instead of scanning filesystem
  • Supports includeDependencies=1 parameter to return all files including textures and nested subfolders for multi-file model loading
  • Dramatically reduces filesystem scans and improves performance
  • Navigation data is loaded lazily per sort mode and cached so switching between viewer and browser modes no longer blocks on loading every file upfront.
  • File browser UI refinements:
  • File cards now share the same compact layout as folder cards (consistent padding, thumbnail sizing, fonts, and grid spacing).
  • Type view heading and breadcrumbs no longer show a leading dot (e.g. GLB instead of .GLB).
  • Breadcrumb component now handles clicks directly via NcBreadcrumb to improve reliability.
  • Remembered folder/type state is cleared when returning to the root via breadcrumbs to ensure a fresh reload.

Fixed

  • Newly uploaded, edited, or deleted 3D files (and favorites) appear instantly in every navigation mode because the indexing listener reacts to filesystem events instead of relying on manual rescans.
  • Root breadcrumb ("Home") navigation restores the folder list correctly, even after drilling into nested folders.
  • Multi-file dependency loading:
  • Backend listFiles now supports includeDependencies=1 to return every file (including textures) and nested subfolders.
  • The dependency crawler recursively searches texture subdirectories so 3DS/FBX models with textured assets load successfully.
  • Texture search now uses the updated backend response structure to avoid missing files and 404 fetches.

Technical

  • Created lib/Db/FileIndex.php and lib/Db/FileIndexMapper.php for database operations
  • Created lib/Service/FileIndexService.php for indexing logic
  • Created lib/Listener/FileIndexListener.php for automatic index updates
  • Created lib/Command/IndexFiles.php for manual reindexing command
  • Created lib/Controller/ConfigController.php for user preference storage
  • Created lib/Migration/Version010902Date20251116061241.php for database schema migration
  • Created src/components/FileNavigation.vue and src/components/FileBrowser.vue for new navigation UI
  • Updated lib/Controller/FileController.php with new listFiles() and indexFiles() endpoints
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
Signature5KdirqBqYm1NTouEBce9EtmTO6/UJwHsg40DC/oCvhIuYOF8eLVWy5O5Vwx25hFvq7bHrr9SQQ9cdJS1G+fY8aQ7bSeqCR1dAdUlsoBhrYWQnKAEnoG8vIIxfk0gA+HgcRGLJPtph9TYLdeAqdhD7/VVUg8l9ZdIVJHsTQn8JijVkTeMpk5612wUyoMn7HaA8IJJrOnU6dmkfv95FcZbVLzR6QRDc2fqlM3aYbZl9KOVYzEU6e736rsQAOVn0IqrHmQyJNVIdiFnycbtRiJnJgRJj05KblfVIOC0qZwzl7sqIHdAswvYwDmdCoLK/rblTc8R7INoUFpmGFBzPITfVwBNrJh9jsxxuWnl0X/vAAtVACVGHR1utLtd4dMFSjwOVxD3f53eazH9/Hho18BBh3GOLNJEWAGNal3u8Ng+inilqQu4Nmhds9AYUoq6T38oU9NABr7mDce1TsO0AYQqfez3HBodgbbBOoXKSGLMoDCk9T71NR2Oc2XC8Urz08F9Q/0Dcoy06kdvm9neAOH+yHqjcPXfI98JCdqao6Li05VQaLOUxIyYbVpngGu3LWthpaH7rlxhD5DlOwknjimFfGifjZ0/yScHSbfRqtgxy8q8jfHJ71wMKOAzQ6xCgqfuWWROUqWNmo4ypsE23Ioj1n/yEA60bComBBgSdSjCwpA=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.1
Release Details
UpdatedNov. 15, 2025, 9:35 a.m.
Changelog

Added

  • Preview Provider Implementation: Implemented Nextcloud IPreviewProvider interface for 3D model previews
  • Admins can enable/disable via enabledPreviewProviders config in config/config.php
  • Integrates with Nextcloud's native preview system
  • When enabled, provider is registered and ready for future preview rendering implementation
  • When disabled, Nextcloud automatically uses custom filetype SVG icons

Changed

  • Updated dependencies:
  • three: ^0.181.0 → ^0.181.1 (patch update)
  • @nextcloud/router: ^3.0.1 → ^3.1.0 (minor update)
  • vite: ^7.1.12 → ^7.2.2 (patch update)
  • @nextcloud/browserslist-config: ^3.1.1 → ^3.1.2 (patch update)
  • Improved duplicate registration prevention:
  • Added guards to prevent duplicate file action registration
  • Added guards to prevent duplicate viewer handler registration
  • Enhanced error handling with try-catch blocks

Removed

  • ThumbnailController: Removed custom thumbnail controller endpoint
  • Replaced by proper Nextcloud IPreviewProvider implementation
  • No longer needed as Nextcloud handles previews natively
  • Thumbnail Placeholder: Removed dependency on thumbnail-placeholder.png
  • Nextcloud automatically uses custom filetype icons when previews are disabled
  • Custom icons already registered via mimetypemapping.json
  • CSS Thumbnail Overrides: Removed CSS rules that forced app.svg background on thumbnails
  • Allows Nextcloud's preview system to work properly
  • Custom filetype icons display correctly when previews are unavailable

Fixed

  • Duplicate Registration Warnings: Fixed console warnings about duplicate settings/registrations
  • Added registration guards using window/globalThis flags
  • Improved handler registration checks
  • Better error handling for duplicate registrations

Technical

  • Created lib/Preview/ModelPreviewProvider.php implementing IPreviewProvider
  • Registered preview provider in Application.php bootstrap
  • Removed THUMBNAIL endpoint from constants and API documentation
  • Updated openapi.json with preview provider documentation
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureyK5Dmfw2bZsjqJMtY0eaIkST1jQZ4XKcPtlHp4f7GNHWV1A5PrKjkxKHO32JML49YXEI7D8PouQvnHXDq55pRDm/PBmXV3cB5wvx3ZkMVMGRQBqHNR2iBfSsl6w9I0SaGSgNSt/aa1kmZRCq20GPv8hLMHSJdcR2VpU5mA/BLp6vP51LBp9wDwzCEsU82zX6VVBXkd5YIHY+6HMRsNQNXFfRsWERTq5yjmTYfyK4Zq1rvZShPX3KG8WDWl6g3C1lJhyr/7FWLoM7Lsq6k1pirdAYUtQO7ooB0UDiTpvEgmCj/OLhL/8dvaD29dyzUxnokjj8IlpiDEcPfeLN34nqXHfMbmPZh9+aqBqsZr0GaqSD6dXGoplkBc+F/SHfWdevkZDHk8p/W0flcjIThr+K5/8YhwdDZd3G2JIRmhDdJXFfoTn2f+zYkHTV3enXsRAG95FVU3WE6zZwi8w4MOUiXIpxqb/DAISRSId3k24iPFlbguOQwPvcpMGNIruPRkoE7ihCgiU+dvcQ6ieYtwvtAHgNy+N284BdcsK7/0g5tCkzDad8Fdt4pMImPkO+cWBy3c19Uce5+pBx36Nts6q5so6O96s0Dcnf4NQPsnRFHNKduWxafeoBHCwn2NoH2aIRw0JQcwyCLvL2j8vLcN6PhAQwJ2I6P/4yHX5aEWEwaP8=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.0
Release Details
UpdatedNov. 10, 2025, 6:57 a.m.
Changelog

Added

  • 🖨️ Slicer Integration: Send 3D models directly to slicer applications for 3D printing
  • Support for PrusaSlicer, UltiMaker Cura, BambuStudio, OrcaSlicer, Simplify3D, and Eufy Studio
  • One-click export with URL scheme integration
  • Automatic STL conversion and temporary share link creation
  • Professional slicer logos with brand-matched colors
  • Last used slicer appears first for quick access
  • Smart detection of uninstalled slicers with user-friendly error messages
  • Auto-download fallback when slicer app is not registered
  • Temporary file cleanup after 2 minutes
  • Share links expire after 24 hours for security
  • SlicerController API: Backend controller for handling slicer exports
  • POST /api/slicer/temp - Upload STL and create temporary share link
  • GET /api/slicer/temp/{fileId} - Download temporary file
  • DELETE /api/slicer/temp/{fileId} - Delete temporary file and share
  • Automatic cleanup of old temporary files
  • Proper filename sanitization for paths and special characters
  • CORS headers for slicer application compatibility

Changed

  • Updated app version to 1.9.0
  • Enhanced toolbar with "Send to Slicer" button
  • Added slicer integration to slide-out tools panel
  • Improved error handling with toast notifications
  • Updated translations for all supported languages

Technical

  • Created appinfo/routes.php for route registration
  • Added @NoCSRFRequired annotations for API endpoints
  • Implemented Nextcloud native share system for temporary URLs
  • Fixed filename handling for files with paths and special characters
  • Added proper authentication and cleanup mechanisms
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
Signaturebdu+2mjB9NyEPJbbogKcFBovDi99alBx7ixiNLiVWRmMw63yphLItjrEkmMxHL5KeEmkQj05gqf17mPXlngrWI3pkhn1gLHtbCiPwOqloKdQ+bf0US34nClshbCzP0drRsNWSxhEWbd0a0vc1Zy31vk9I2PVHugbpbo4BCy20Ks6t0aCkv6o+g8x+v+B348txV1p1F5hyM+2BBUqxEB8fNiRJ/p6bd1eMf6lWfeqBrWG6n3zB11BsKKYAa941deyJ8vLlEpI8D7Kyz7TVHuHzx9hlxbZyOCYEnD52EmpYDl/VaKnj+9EzxaFDqkQPOIHPbMtfe9tc0nZOrqEASXrUC/iPMpp1JNAyRa0Egx+DkdRE/p6wFMBxipGqfgb7MJ6gV4I7t7ML1scquVtcc8aZt3oNhdMd6gPZ7/uxOYQ8Bm6YX6fiuwxtqe5yb2uwiw9oKjQhs3miEXEAiaiab3S4HLC6Ke9QYowEzASoAD1tHf+kf4I6+IszL5V6XOVzXRhKU8t/Vdl/JSZh3LEOma2KCPBoxIwove9PpHARcEIz6Tk4eu4UvMdTjhyIBKCvEnq8Bs5fzaq+jqSuE+8h3Y+qP0Q2fSqcNHpLtBEAfrkSu883dCM7dg0miDxSGumfqn+oJ80bVDGm8mQ3WdP7AvJiygdj5i2pFqyeiPE+MGDDUE=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.8.0
Release Details
UpdatedNov. 6, 2025, 2:21 a.m.
Changelog

Added

  • Screenshot Feature: Capture high-quality screenshots of 3D models directly from the viewer
  • PNG and JPEG format support with configurable quality
  • Automatic filename generation with timestamp
  • Accessible from toolbar and tools panel
  • Download screenshots directly to local device
  • Fixed WebGL renderer configuration to enable screenshot capture (preserveDrawingBuffer: true)
  • Billboard Text Labels: Annotation and measurement text now always faces the camera
  • Text remains readable from any viewing angle
  • No more reversed/mirrored text when viewing from behind
  • Smooth rotation as camera moves around the model
  • Improved user experience for annotations and measurements

Changed

  • Updated app version to 1.8.0
  • Enhanced info.xml with new feature descriptions
  • Updated English translations for screenshot and billboard features
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
Signaturebvx0cRDWADLGiuJ0jIg9f+81Add0o7SM3Dkq8foP/AnLfM2fSL1/ds6JsckXbP8xdOMoPyAxnN9XFi6qckR+cTiBSkkbpbQeg32ZDShLwwVRH8dubBAHkIk7qSBVjw4gV2BdKuMjWZZ5cRPlcFNUtdVP776NXH6Vv5FxK4UoudEN3VA8qDZC9+8fC46n7NhnobbviHIzeNqPA0V3Wo50UuuptyDdip0o/bbBiaw1vszWuV4QoHFMHAjFan2v3kKb5ptIHYukVOLMj8rY1dKeTACQYjEwi+YXOV+4eJMiMrHXx06eMYxiOsTdNHsCWTy9PW+4QTHM9dI/GNygSKC/V4Z9lxlPt7jncHOAT5P+tEFrWQYImvBtWsXPXoP6UPAIpP82NPWhp0lBZdjR3Fvx4yi0PM7V4/lRTztUkTrobnlVNpIxSe6SH0jWmVlyAFAW0XSiWrWbM+Q0gNEERVNudpCw7y41xv2Q45ZgPIMhGzjn7CbY8gVacSrXcsnglD8pcFAnI7hh+KfepgSSeJg1ZV7IF5UM9Qr9Cu7VDtq8Lc5bw3tqXNDf4U7T5UgnAjbA/GFXY2fz6yT5TVXWoNxER4d3Bocb73r5wWYlag6z2CKOxTOWenRUnrG0iFPi95MxaykgJMVTAilRLoHOOGZie9DHpOUwcvXWAokeDaXGBSQ=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.7.13
Release Details
UpdatedNov. 5, 2025, 4:44 p.m.
Changelog

Fixed

  • CSP Conflicts: Removed global CSP listener that was breaking other Nextcloud apps (Memories, etc.)
  • File Icons: Fixed custom file type icons not displaying by copying them to correct location
  • App Compatibility: CSP modifications now only apply to 3D viewer routes, allowing other apps to function normally

Changed

  • CSP headers now scoped to specific 3D viewer routes instead of globally
  • Added automatic icon copying during build process (scripts/copy-icons.mjs)
  • Removed lib/Listener/CspListener.php (no longer needed)
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureqfnNbykFms5wS6aOa/TKBYua37o3OqBNqe9LY0dU86/MrGrqbv+v9inkFm63UQyR19ux9ACVlqG6J5rCDpLLTYAe1IkFGZMKfJzNnna8uiA734PltS8gNSv8ol0zMsRs6tvanPlDxVedCmzp31VsErPKOShjvTRbhf9ZmgJjZccX3UODdfIzZxJLqHd3vBrYqoksFXDZnzUqEkb5OK7RwfxAs71IGoVjXHOf9HuOVuefc1mhElbIygGnPYJ3ewlU72SD6gB9/kYgmZEb9xklvcTz6IjTbfKdZ7fLb640/71wCIa5mYleBkaxsoAzfGo2QjC6GHNkAQX7gAXeZp1GYBixwIF4JvawV2s1pKnIDZE3hkLqhx+e4OOYvawhlVoUdILsXSC2oiG4Q5qF/tSz6fh/2gFY+/2fxJMSwwbPXTkUPA5eXKCTpRIbWdIK61XEMKenSlWFF0giXWcOMkxXH4/T1NFlV7/g57MPogu+DD41Y2LNkdZQVaVYWEyvTw3t0pVvgohGNPRSNKV8qR8yzSM5yVe0Ck6SWOk+74SWwBoItjp66LwNQ60JK2Od2+NOSE3+2eG1SkIKL4+q0Uo4NGQgyxblPWIXJZTl14XcaxyXCJr/K913khhw+b+DumTz6TTGg6jMR8oXRFawccmEHL/DN55Y3HfRAwVj/cNIx7I=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.7.12
Release Details
UpdatedNov. 4, 2025, 4:14 p.m.
Changelog

Fixed

  • Viewer Integration: Fixed files() method not storing files list, causing "No files provided, skipping update" error
  • File Loading: Fixed TypeError: Cannot read properties of undefined (reading 'filename') when opening 3D files
  • Static Assets: Fixed 500 error when loading app-color.svg due to route conflicts
  • Route Structure: Changed viewer route from /{fileId} to /f/{fileId} to prevent conflicts with static assets
  • Axes Positioning: Axes helper now positioned at bottom center of models, aligned with grid
  • Axes Scaling: Made axes size dynamic (25% of model's largest dimension, minimum 5 units)
  • Logo Loading: Fixed app logo path in demo scene to use generateUrl() for correct URL resolution

Changed

  • Enhanced files() method in ViewerComponent with fallback logic to create synthetic file from props
  • Simplified PageController by removing unnecessary is_numeric() checks
  • Updated URL structure for better RESTful design: /apps/threedviewer/f/{fileId}
  • Axes now recreate on model load to ensure proper sizing and positioning
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignaturetHcAULDv6Z6JlPEmMcFbBFAPFTScfSULZoxHuFuCtCO965w5/TPzwTm9AAbrvWQlTzOza8VK9le5cP96O8XKoLPU/rUTY0YPL+11rga9rU5c9nNcCiRTKwaha9wnos5/fDxZOhefb9aFojmpf7HsrSmHL+JMrLwaVvp846k4ShSPNbV7cVTqsrwz1C4Vy4JRzGMuSfcAMjxLBC02obtPqVYX4T5s7/QCithiTGI1VmmtMxZM0sG3fkIRf9ouPQ44hpHX7beIm4vBGthPwjhlNpR+aXq9rQd4annpZKtZGfGRX/RDXlFXUWBE/07A+/CBzP9DX9pegUvzvrelj67ADuiRDfxsL3vKN1VGU1rqHi1ZrwE24BzfeGnWgUb+wEBOcM8x8BEc0thH2zbfKAwqjY1h/iH8IjoIkbPPm3mKwQ2b5w2v2aaRRr3qbK3cOLhyzWJBpQFZaahomr9x+/hN5aU9fhr9hMjgPboRadI7rO+V6QtQDobhKlz+6Rdb1mo+Bzk9btyCJ7flqqos07yo/O01o4G/0L0hdw20vYh3WlbeGRWC6W/OBzQmRwT4MWFoHV2mQOYO4Nie4SkFCzs2lT3NWW7I/uCrCPMZDJrLhSk1KiKzctZXjTUalB4DuPHSpq99WjCcf2oPLo6rQ7DJd/sIRSh3tSj8WIlxcWCrSWk=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.7.11
Release Details
UpdatedNov. 4, 2025, 10:58 a.m.
Changelog

Fixed

  • Viewer Integration: Fixed files() method not storing files list, causing "No files provided, skipping update" error
  • File Loading: Fixed TypeError: Cannot read properties of undefined (reading 'filename') when opening 3D files
  • Static Assets: Fixed 500 error when loading app-color.svg due to route conflicts
  • Route Structure: Changed viewer route from /{fileId} to /f/{fileId} to prevent conflicts with static assets

Changed

  • Enhanced files() method in ViewerComponent with fallback logic to create synthetic file from props
  • Simplified PageController by removing unnecessary is_numeric() checks
  • Updated URL structure for better RESTful design: /apps/threedviewer/f/{fileId}
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignaturehK5rTudkrE4neZOI/n/jv+qjY/VfKVkRkouiBK5jBARxwK9e0W8U07ajlvP2+U8q8qwNzjGY77RproUnQIkOlALx3c6V9ufsMaHcpuAR2GAvK84WgqqEM37VSPQrGhLLuZzz4nU5nYmNOsTg+maV0O5XEND29zOdafsJHxpY8mQofXCA0vyLYNLYQtLEAPRBtl3uDQgSSjPGB6kN87VUcqebvVrVim8aa8l7BpDoMiW5j60T7toenQiisu6S4aKMRHCxx7I1cHK/mkGjLzl+/AHpfwWpKCr13StVLzqqlVPc5+SL/yI14XW2JtJARHShE0zBqkARG0yqsFXVTGvLzvAahLuCfIdlied8HFK/NQVmqgLlRAc30xWGq2vcQvpnr9L7GwCkImnM5YeoTqVOJHawhc3wU8FQ56g/imCYgMqwSOegC1BVegdX/XvCMCxhQXEj4OxUxETQ/T1+BWqBBLLbZQQiyyRXw6o/bzpBWJYtDH/XIzFKxJdC7WKfIM6lPmPb7CCc6sJGfEi/Lyv3rTfCjyQj7ioMlB+5sLV5/d+tth6eeY9O6jZsz92/V5byhrtIdYvu4j7IZR2m8+/IpkjmTMnuv18wyU6+unVo8V2hKNLhoWYHJqEQ9Ylx/Rj6tKb4TwsrciMPV+2T38lJK5cS0GZittMNUVAKSUPBSnQ=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.7.10
Release Details
UpdatedNov. 4, 2025, 9:48 a.m.
Changelog

Fixed

  • Dark Theme Support: Fixed slide-out toolbar panel not responding to theme changes
  • Theme Switching: Implemented reactive theme binding using Vue computed properties
  • CSS Integration: Converted base styles to use Nextcloud CSS variables for better theme integration
  • UI Consistency: Toolbar panel now properly switches between Light, Dark, and Auto themes

Changed

  • Improved maintainability by using Nextcloud's standard color system throughout the toolbar
  • Enhanced theme responsiveness with component-level class binding
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureT38bK6V5aDGCGlNZJEV3QCmwYaO21RK3QtifSTQ3O311NOPA+O7ryIjncKIdr/rdN/9ZjeFLqwcxRk2traF5MkhvjRCr3NT5oV5cuMQgmw2Js7MAOLrSXOUkn6b7LpQKesEmzQPqygl2fuqN5qrxILxeWU5xWq3nyoV+G2TzByeLOT9CX8+EH1rzMnJNb/35aFS0kj/fU4V0FHFM3h8KxNDWYVjlJ/tPtq5IFBvICRm6HLCkQ2fEPPXkxP2Z1lpBam6ZGuSbcmo2lb5yQ7Zq3n6rd7FIzkU6r0/xvYF5gY08bwIdtULEpJOEQwp/n9KBR2itV4twQG2QAZFEIMF+EIg4lRzu0vdX8GVDFbirW8YqCX8PXyd+UAm1FfZ4vf8VHQXF7weZgAnvm3crR01GNStlBHl37Zke3z8CHmiYj3ffi4WMwGBT4Gb8f6fxlCOHH/mOlCyA3rtVlI5cHqJGHbdiwgHYX6e+0p5JRWOlecK/HTcVd0Aa5KX57BTcRQXEhGaQqHIbRhWTWwDMesbAyJMtCT72O2eRUqJCnSI+SRSxl/Hh4lHUEnOPx9D2P/03xDEDpO3xoR7tQGN927un6811AS+v+kABFDJQcayHiFTpR28U+WzF1vqS2fktc90NaWwiJuO1/hnQ/H8J6icAF4oxmvArZI2uO1X3CPZMwN8=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.7.9
Release Details
UpdatedNov. 4, 2025, 8:39 a.m.
Changelog

Added

  • 3D Camera Controller: New circular controller interface for intuitive 3D model navigation
  • Camera Control Methods: Advanced camera manipulation including rotation, zoom, and directional nudging
  • View Snapping: Animated camera transitions to predefined views (Front, Back, Left, Right, Top, Bottom)
  • Controller Persistence: Save and restore controller position and visibility preferences
  • Smooth Animations: Eased camera transitions with customizable duration and easing functions
  • Face Labels: Orientation markers (TOP, BOTTOM, FRONT, BACK, LEFT, RIGHT) on model faces
  • Export Functionality: Export models to GLB, STL, and OBJ formats
  • Camera Projection Toggle: Switch between perspective and orthographic views
  • Progressive Texture Loading: Background texture loading for improved performance
  • Dependency Caching: IndexedDB caching system for faster multi-file model loading
  • Model Statistics Panel: Detailed information about loaded models
  • Help Panel: Comprehensive in-app documentation and controls guide
  • Theme Customization: Enhanced theme switching with RTL support
  • Performance Overlay: Visual performance stats display with real-time monitoring
  • KTX2 Texture Support: GPU texture compression for better performance
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureT4jr3f8pu++HPy93L1HdiayTsqKV8PwgIw7jkye4TkqYM7wBuBsK6qv/TXwuZElOm9hzBEVH/MnuFoRl2QXPxurhZLvu918h0rDnTIjfRNMC2gIVFI8JLneLq8ya+m9lKGNLXEodRAhQ3pGn97cuSFzff+iGhQOFkojIvbWM4HbSQFq6pfF3/ZYjUCt5BhRIHdPkk+mzwjpVaniq98gh4XS3AMYqs4p2n7vysSGjAO8hZrDdGUJGxBlz1amgeUpdiGOpTwI4FyT2vbxcmHcMVwZTQyXoYZ/Ux70JZp98nz1H1kKqIoDxzZSRmetrm23Pzn+k440rHQUSjuIa/p6I6w8nGG25M0kjB46lacCtbUlR6Rrrj6SNwFITde5Rr87HP2R/ILqI5MCC73SebBxcdY/IXw7xHjUiBJTlrOmPi1ppktirZnOsmSR2Sa/yE81zrYWJ2HidTbxEGpJDZBIiwOaBCYh6nwQ51PG1z4mxgJE4G+7lMZ/bpu5UaJihys2WcoBhPxrGNeoLoEN+D1JiaOU1C974Wwncz1/BobA08FSx+rzXCnRNSQWbBapz3J6MYT5TwChku40FeqGR2KJm+v2pYgm8K/Eepieubi61tD9St1exw3AjBiJ2/dKOezNb8ZHFcoWn2bxCZc4rzuBUO0tJSrjmbW5dcysusajrvMs=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32

Nextcloud 31

3D Viewer 3.3.0
Release Details
UpdatedApril 20, 2026, 6:47 a.m.
Changelog

Fixed

  • 3DS files loaded tipped on their side when the exporter used Y-up instead of the 3ds-Max Z-up default. The loader had been hard-coded to rotate every 3DS model -90° around X (commit d8117a0, "fix: add coordinate system rotation corrections for Z-up formats"), which helped CAD-style Z-up files but silently broke Y-up exports — Cottage_FREE.3DS for example rendered with its long axis as the vertical. Dropped the unconditional rotation; 3DS files now pass through at their authored orientation. Most modern 3DS exporters (Blender, recent Maya) are already Y-up, and Z-up outliers can be fixed by orbiting or — if this becomes common — by a future user-facing orientation toggle. Other Z-up-rotating loaders (STL, PLY, 3MF, DAE) are unchanged because those formats have stronger Z-up conventions that are not affected by this fix. Reproduced and verified in the live Nextcloud container by downloading the user's 3DS via WebDAV, inspecting bbox dimensions with a new scripts/inspect-3ds.mjs harness (raw X=1243, Y=675, Z=1465 — Y is the height), and hard-refreshing the viewer page.
  • Standalone viewer: KTX2 loader threw on init with Cannot read properties of undefined (reading 'isWebGPURenderer'), so models with Basis/KTX2-compressed textures silently fell back to placeholder textures. Root cause: the standalone ThreeViewer.vue never forwarded the live WebGLRenderer into the loading context, and Three.js r182's KTX2Loader.detectSupport(renderer) dereferences renderer.isWebGPURenderer before checking anything else. Fix: pass renderer: renderer.value in the context, plus a defensive guard in gltf.js that skips KTX2 entirely (with a warning) when no renderer is available instead of throwing. The modal viewer was unaffected — it already forwarded this.renderer. Live-E2E harness now also watches for KTX2/WebGPU console complaints so the regression can't sneak back in.
  • Standalone viewer: glTF models with embedded data: buffers failed to load under Nextcloud's Content Security Policy. The app CSP allowed data: for img-src but not connect-src, so GLTFLoader's fetch() of embedded base64 buffers (the default export shape of many gltf files) was blocked by the browser. ResponseBuilder::addCspHeaders now also adds data: to connect-src. Caught end-to-end by driving Playwright against the real dev container (scripts/live-e2e-check.mjs).
  • Skip-to-viewer link wasn't in a usable tab position — it was rendered inside <NcContent><NcAppContent>, which put it ~9 tabs deep behind Nextcloud's header, nav sidebar, and file list. Wrapped in <Teleport to="body"> so the anchor lives at the body level regardless of where Nextcloud's chrome wraps us. DOM-verified focusable in the live container; clicking it moves focus to #viewer-wrapper. The CHANGELOG entry below that claims "first tab stop" was aspirational — Nextcloud's own Skip to main content / Skip to navigation links always win the first two positions, which is correct behavior we can't (and shouldn't) override.

Added

  • Four more CAD formats via OpenCascade — STEP, IGES, BREP, FCSTD (closes #97): All four formats come from the OCCT family of NURBS/B-Rep CAD files and share one WASM integration. Uses occt-import-js (Viktor Kovacs's purpose-built emscripten port of OpenCascade's import + tessellation) — much smaller than vanilla opencascade.js (~7 MB WASM vs 10+) and with a JSON-based mesh output that's a clean fit for Three.js. Architecture: one shared src/loaders/occt-runtime.js exposes getOcct() (memoized module promise so the 7 MB WASM downloads once across all 4 loaders) and buildGroupFromOccResult() (walks the assembly hierarchy preserving node names, transforms are already baked into tessellated vertices so we don't reapply matrices). Each format gets a thin ~25-line loader: STEP (.step, .stp) → ReadStepFile, IGES (.iges, .igs) → ReadIgesFile, BREP (.brep, .brp) → ReadBrepFile, FCSTD (FreeCAD document) → unzip via fflate, filter for .brep entries, feed each to ReadBrepFile — per-body failures don't take out the whole document. The resulting bundle shape: four 1 KB loader chunks + one 725 KB shared occt-runtime-*.chunk.mjs + 7.3 MB WASM served separately from /apps/threedviewer/occt/. Main/app bundles unchanged (0 B trend). Not unit-tested because the whole pipeline needs live WASM + real CAD fixtures to exercise meaningfully; covered by the existing smoke suite pattern.
  • Fifth new format — IFC (.ifc) (#97): Industry Foundation Classes, the de-facto BIM interchange standard. Loader in src/loaders/types/ifc.js uses ThatOpen's web-ifc WASM (~5 MB, lazy-loaded on first .ifc open) and a hand-written Three.js bridge — web-ifc-three has been deprecated and its modern replacement (@thatopen/components) is a heavy framework we don't need just for file loading. Bridge logic: StreamAllMeshes walks the IFC element graph, each FlatMesh's PlacedGeometry entries yield tessellated vertex data in interleaved [px,py,pz,nx,ny,nz] layout which we deinterleave into separate position/normal attributes, then apply flatTransformation (column-major 4×4) and per-geometry color. Express IDs (expressID, geometryExpressID) are preserved on mesh.userData.ifc for future property-panel tooling. Memory is carefully managed — geometry.delete() in a finally block releases the WASM-side handle per mesh, and CloseModel runs unconditionally so parse errors don't leak the full IFC model. WASM copies ship via scripts/copy-decoders.mjs to /apps/threedviewer/web-ifc/ (both single-threaded web-ifc.wasm and multi-threaded web-ifc-mt.wasm — IfcAPI picks the variant based on runtime feature detection) so air-gapped Nextcloud deploys don't need CDN reachability. JS glue is lazy-chunked into a 3.4 MB ifc-*.chunk.mjs that only loads when a user opens a .ifc file; main/app bundle impact is minimal. Not unit-tested because the whole pipeline requires live WASM + real IFC fixtures; covered by the smoke spec suite instead.
  • Fourth new format — dotbim (.bim) (#97): JSON-based BIM format from dotbim.net — simple schema (meshes + elements with { mesh_id, vector, rotation, guid, type, color, info, face_colors? }). Loader in src/loaders/types/dotbim.js handles mesh instancing (multiple elements sharing a mesh_id each get their own cloned geometry), element transforms (translation vector + unit quaternion rotation), RGBA byte colors, optional per-face colors (v1.1.0 schema — unindexes geometry so each triangle's 3 verts carry the face color), and tolerates legacy exporter quirks (missing/null rotation, mismatched face_colors length). Element metadata (guid, type, info) is stashed on mesh.userData.dotbim for future inspection tooling. 10 Jest specs in tests/unit/loaders/dotbim-parser.test.js cover instancing, transforms, color handling, transparency, legacy-rotation fallback, orphan elements, metadata, and JSON/schema validation error paths. Zero WASM, zero external deps, ~180 lines. Like the other new loaders it's lazy-chunked via the registry's dynamic imports — 0 B impact on the main/app bundles.
  • Three new 3D formats — OFF, AMF, 3DM (closes #97 partially): (1) .off (Geomview Object File Format) — hand-rolled plain-text parser in src/loaders/types/off.js covering OFF, COFF (per-vertex colors, float or 0–255 int), N-gon fan triangulation, inline # comments, and binary-OFF rejection. 9-test Jest suite exercises the parse path end-to-end (tetrahedron, n-gon, comments, COFF float/int colors, degenerate inputs). (2) .amf (Additive Manufacturing Format) — wraps three.js's bundled AMFLoader, handles both XML and ZIP-compressed variants. (3) .3dm (Rhinoceros) — wraps Rhino3dmLoader, loads rhino3dm.js + rhino3dm.wasm (~4 MB) on first use from the app's bundled copy at /apps/threedviewer/rhino3dm/ so air-gapped Nextcloud deployments don't need CDN reachability. scripts/copy-decoders.mjs now copies the rhino3dm assets alongside DRACO/Basis. All three formats are registered across the 5 sync points (lib/Constants/SupportedFormats.php, src/config/viewer-config.js, src/loaders/registry.js, src/main.js::SUPPORTED_MIMES, appinfo/mimetypemapping.json); npm run format:check PASS. Each loader is lazy-chunked via the registry's dynamic imports, so the main/app bundle size is unchanged (only users who open the new format pay the download cost). The 6 remaining formats from #97 (step, iges, brep, fcstd, ifc, bim) all require OpenCascade.js or web-ifc WASM (~5–10 MB each) and are deferred until demand justifies the bundle hit.
  • Forced-colors (Windows High Contrast) CSS hardening: New central override sheet (src/css/forced-colors.css, imported from main.js) scoped entirely to @media (forced-colors: active) — no effect on default rendering. Addresses three patterns the a11y audit found: (1) custom badges (.stats-badge, .fps-badge, .active-badge, .last-used-badge) that rely on background-color + text-color alone collapsed into the surrounding surface once the UA repainted both with system colors; they now get a 1px CanvasText border so they stay visible. (2) .filter-format-chip.active lost its visual distinction from the inactive state because both backgrounds became Canvas; the active variant now uses Highlight / HighlightText with forced-color-adjust: none so selection state survives. (3) Focus states that suppressed outline and relied on box-shadow or colored border-color (.export-select:focus, .annotation-text-input:focus, .skip-to-viewer:focus) had no visible focus indicator; they now re-enable a 2px Highlight outline. Verified by a new Playwright spec (tests/playwright/a11y-forced-colors.spec.ts, 5 tests) that loads the real CSS file into static fixtures mirroring each component shape and asserts border/outline width > 0 under emulateMedia({ forcedColors: 'active' }). Caveat: Playwright's forced-colors emulation uses a neutral palette — this closes the keyboard/CSS correctness gap but an interactive Windows HC walkthrough is still the final source of truth for theme-specific contrast issues.
  • i18n parity tooling (scripts/check-i18n.mjs): Walks src/ (.vue/.js/.ts) and lib/ (.php) and extracts every t('threedviewer', 'string'), this.t(...), and ->t(...) call via regex. Diffs the extracted set against l10n/en.json: ERROR on source strings missing from en.json, WARN on orphan keys no source uses, per-locale coverage summary that reports missing, passthrough (value === key), and orphan counts. --sync-en auto-adds missing keys (value = key); --prune removes orphans. Wired as npm run i18n:check / npm run i18n:sync; i18n:check is now part of the validate chain. First sync closed 329 missing keys and pruned 87 orphans in en.json — ar/de/es coverage now reports accurately at ~27% (previously looked higher only because en.json itself was incomplete).
  • Export pipeline unit tests + MIME consistency fix: Nine Jest specs in tests/unit/composables/useExport.test.js cover getGeometryStats (indexed, non-indexed, multi-mesh groups, non-geometry descendants) and exportAsSTL/exportAsOBJ/exportAsGLB (correct MIME — model/stl, model/obj, model/gltf-binary — correct byte length, null-object guards, and a multi-material OBJ scene that passes through the exporter with its material array and geometry groups intact instead of being flattened). Three.js exporters are mocked so the test runs deterministically in jsdom without pulling in Three's ESM-only subpath imports; the real exporter output remains covered by the Playwright smoke suite. Shipped alongside a MIME consistency fix in SlicerModal.vue — the slicer-export fallback path was still using application/octet-stream for STL and text/plain for OBJ even though the main Export Model path had been updated to model/stl / model/obj; both paths now agree.
  • Loader smoke-test coverage for cancel/retry/network-drop: Two new Playwright specs in tests/smoke/viewer.spec.ts use page.route() to deterministically simulate (a) a user cancelling a hanging load and then retrying — the second fetch is fulfilled with a fixture and the viewer reaches __LOAD_COMPLETE, and (b) a network failure (route.abort('failed')) that must surface via __LOAD_ERROR without being misclassified as a user abort. ThreeViewer grew two tiny test hooks (window.__LOAD_COMPLETE on successful model-loaded, window.__LOAD_ERROR on non-abort errors) to give tests a DOM-independent signal — production code is unchanged in behavior.
  • Accessibility follow-ups: Keyboard users now get a "Skip to 3D viewer" link as the first tab stop (visually hidden until focused, slides into view on focus) that jumps focus past the navigation directly to #viewer-wrapper. Both modals (SlicerModal, HelpPanel) now trap Tab/Shift+Tab inside the dialog while open and restore focus to the element that opened them on close — implemented via a dependency-free useFocusTrap composable. Modals also gained aria-modal="true" and tabindex="-1" on the dialog surface. Covered by a new Jest unit suite (tests/unit/composables/useFocusTrap.test.js) and a Playwright a11y spec (tests/playwright/a11y-skip-link.spec.ts) that verifies skip-link behavior under forced-colors: active (Windows High Contrast).
  • Transform Gizmo: Translate, rotate, and scale models interactively with Three.js TransformControls. Mode selector (Move/Rotate/Scale) and reset button in the Analyze section. Disables orbit controls while dragging.
  • Animation clip selector: Dropdown in the Animation panel to switch between individual animation clips (e.g., Run, Walk, Idle) for models with multiple animations
  • Texture optimization pipeline: Quality presets (Original/High/Medium/Low) with Canvas 2D downscaling, memory tracking, and configurable setting in Personal Settings
  • X3D parser: Full XML-based parser replacing placeholder cube — supports IndexedFaceSet geometry, materials, textures, transforms, and DEF/USE references
  • Volume & surface area measurement: Model statistics panel now shows actual mesh surface area (sum of triangle areas) and mesh volume (signed tetrahedra method, accurate for watertight meshes), in addition to bounding box volume
  • Custom color palette editor: Personal Settings → SlideOutToolPanel now exposes four user-overridable scene/chrome colors on top of the base light/dark theme: background, grid, toolbar bg, and toolbar text. Each has a native <input type="color"> picker plus a per-key "×" clear button; a single "Reset all palette colors" button clears everything at once. Overrides persist to localStorage['threedviewer:customPalette'] and are merged on top of whichever base theme (auto/light/dark) is active, so switching themes leaves your palette alone. The viewer rebuilds its THREE.GridHelper in place when gridColor changes and swaps scene.background when background changes — no reload required.
  • Decoder worker pool tuning (parallel decoding): GLTFLoader's DRACO and KTX2 sub-loaders now call setWorkerLimit(n) with n = min(hardwareConcurrency - 1, 4) (floor 2), so GLB textures and compressed meshes decode in parallel across multiple Web Workers instead of serializing on one. Defensive feature-detection — falls through when the Three.js version doesn't expose setWorkerLimit. Result: GLBs with multiple KTX2 textures load noticeably faster on 4+ core machines without starving the main thread or flooding it with workers on 1-core devices.
  • Memory pressure auto-step-down: The performance composable now samples performance.memory.usedJSHeapSize each frame and, when usage crosses 85 % of the configured maxMemoryUsage cap (default 500 MB), auto-switches to the Low performance mode — reducing pixel ratio, disabling shadows, and applying LOD. A one-time warning toast ("Auto-reduced quality — memory pressure") surfaces what happened; the flag clears once memory drops back below 70 % so the user can re-raise quality manually. 5-second cooldown prevents thrashing, and the check gracefully skips browsers without the non-standard performance.memory API (Firefox, Safari).
  • Background indexing status API + progress bar: New GET /api/files/index-status endpoint backed by ICacheFactory::createDistributed returns { active, processed, total, percent, startedAt, updatedAt } for the authenticated user. FileIndexService.reindexUser now pre-counts supported files (respecting .no3d and hidden-folder skip rules), then bumps the processed counter after each file. The Personal Settings "Re-index now" button starts a 750 ms poll in parallel with the blocking POST request and renders a live NcProgressBar ("142 / 284 (50 %)"), falling back to "Scanning…" until the pre-scan completes. Status TTL is 1 hour.
  • Adaptive texture streaming (visibility-aware queue): useProgressiveTextures now accepts a (camera, scene) streaming context and sorts its pending queue by frustum visibility before each batch — textures on meshes currently in view load first, off-screen ones are deferred. When the camera moves, the very next batch picks up the new viewpoint. queueTexture has a new optional mesh argument for visibility scoring; the signature stays backward-compatible, so existing callers are unaffected. ThreeViewer auto-registers the context on init so future loader pipelines that opt into progressive loading get adaptive scheduling for free.
  • Measurement suite upgrades: The Statistics panel's measurement section is now a full measurement tool:
  • Unit picker: Choose mm / cm / m / in / ft / generic units from a dropdown; bounding box, surface area, and volume values re-render instantly with the right suffix (mm, mm², mm³, etc.). Defaults to the project's configured VIEWER_CONFIG.measurement.defaultUnit so it matches the existing ruler tool.
  • Per-mesh breakdown: When a model has more than one mesh, a scrollable list shows each mesh's surface area and volume in the selected unit. Clicking a row focuses the panel on that mesh — the Width/Height/Depth/Area/Volume rows switch to its numbers and a "Focused: mesh name" header with a Show-all link appears. Helper meshes (transform-gizmo pickers, annotation markers) are excluded.
  • Pick mesh in viewport: A one-shot button arms a raycasting click handler on the canvas; the next click on a mesh focuses it in the stats panel. Works with any mesh in the loaded model, respects visibility, and skips gizmo helpers.
  • Watertightness badge: The section header flags each mesh as Watertight (all edges shared by exactly two triangles — volume is reliable), Not watertight (open or non-manifold edges detected — volume should be treated as approximate), or Unknown (non-indexed geometry, or >500k triangles so we skip the edge-map check for performance). Aggregated badge appears at the top of the section; per-mesh flags appear next to each row in the breakdown.
  • Copy measurements: A button copies a plain-text report of the current values (bounding box, surface area, mesh volume, bbox volume, watertight status, per-mesh table) to the clipboard in the selected unit. Uses navigator.clipboard.writeText on secure contexts with the textarea + execCommand fallback for legacy browsers. Success/error toast via the existing push-toast channel.
  • WebXR / VR mode: Enter immersive VR via the 🥽 button in the top bar (only shown when the browser advertises immersive-vr support). Animation loop swaps to renderer.setAnimationLoop during XR sessions, and FPS throttling is bypassed since the headset enforces its own cadence. Testable without a headset using the Chrome WebXR API Emulator extension.
  • Annotation JSON export/import: Save annotations as a versioned JSON document and re-import them later. The schema includes format, version, exportedAt, modelFilename, and an annotations array of { id, point, text, timestamp }. Import/Export buttons appear in the Annotations overlay when annotation mode is active.
  • Scene comparison diff overlay: When two models are loaded side-by-side via Comparison mode, a "Scene Diff" panel auto-appears showing original vs. comparison stats (vertex count, face count, mesh count, bounding box X/Y/Z, diagonal length) with color-coded deltas (green = increase, red = decrease). Helper meshes (transform gizmo pickers, axes/grid helpers) are excluded from stats so the diff reflects only the loaded geometry. The overlay is dismissable via × and re-openable from a "Diff" button in the comparison controls.
  • Annotations persistence (per-file backend save): Annotations now save automatically to your Nextcloud account, keyed by file ID, so they reappear next time you open the same model. Backed by a new AnnotationsService that stores one JSON document per (user, file) under app data (appdata_*/threedviewer/annotations/{userId}/{fileId}.json), with GET/PUT/DELETE routes at /api/annotations/{fileId} validating that you have access to the underlying file before reading or writing. Saves are debounced 600 ms after each change; clearing all annotations issues a DELETE so the backend doc is removed instead of storing an empty list. A small status pill ("Loading… / Saving… / Saved / Save failed") in the annotation overlay header surfaces sync state. 256 KB cap per document.
  • Shareable view link: New "Copy View Link" button in the View section copies a URL that encodes the current camera viewpoint (position, target, zoom) as a compact cam=px,py,pz,tx,ty,tz,z query parameter. Opening the link reloads the model and restores the exact same angle after auto-fit runs, so you can send collaborators a link and say "check out this corner of the model" without needing a live session. Toast feedback on copy success/failure; button disabled until a model is loaded. Works on any secure context (HTTPS or localhost) via navigator.clipboard, with an offscreen-textarea + execCommand fallback for legacy environments. No backend — pure URL round-trip.
  • Clipping box (6-plane section analysis): The existing Cross-Section tool now has a Plane / Box mode switch. Plane mode is unchanged (single cross-section plane with axis + position slider). Box mode enables six axis-aligned clipping planes, one per face of the model's bounding box, each with an independent 0–1 offset slider that moves that face inward toward the opposite side. Setting xMin=0.35 and zMax=0.35, for example, slices the leftmost 35% off along X and the nearest 35% off along Z, leaving the intersection slab visible with interior surfaces rendered via DoubleSide. A "Reset box" button returns all six offsets to 0. Plane and box state are kept independently so toggling between modes is non-destructive, and box offsets auto-remap when a new model is loaded.
  • File browser search & filters: New filter toolbar in the file browser. At the Folders/Types/Dates overview level the search box runs a global recursive search that walks every folder, type, and date bucket and surfaces matching files as a flat results grid (each card showing its full path) — so searching wolf from the Folders root finds Wolf-Blender-2.82a.glb two folders deep without manual drilling. Inside leaf views (drilled into a folder, type, or month) the search filters both subfolder cards and file cards together, and unlocks two extra controls: multi-select format chips (one per extension actually present in the current view) and a size bucket dropdown (Any / < 1 MB / 1–10 MB / > 10 MB). Filters compose with AND between categories and OR within format chips, and a "Clear filters" button appears as soon as any filter is active. Filters auto-reset when navigating between folders/types/dates so a stale query never makes the next view look empty.

Fixed

  • FBX taillight/lens transparency: FBX post-processing was force-overriding every material to opacity = 1.0; transparent = false, which made authored translucent lens shells (taillights, headlights, glass) opaque and hid the coloured mesh inside — the Mercedes GLS rear lights rendered as a solid grey slab with the red only visible if the camera was pushed inside the body. Now preserves the FBX-authored opacity: materials with 0 < opacity < 1 are left transparent with depthWrite = false so inner meshes show through; only materials with opacity <= 0 (which would render invisible) are still forced opaque.
  • Stats panel — File size on multi-file loads: File Size showed "0.00 MB" for formats that come with sidecar assets (OBJ+MTL, FBX with textures, GLTF+BIN). The stats panel was reading modelLoading.progress.value.total, but multi-file loaders report progress as a percentage (max 100) rather than bytes, so the resulting "100 B → 0.00 MB" rounded to zero. Now reads the actual byte count from modelSourceFiles.value[].size (matching main filename first, else first file), with the progress-total value only used as a fallback when it looks like real byte counts (> 1 KB).
  • Stats panel — Texture memory accounting: Textures section reported "Memory: 0.00 MB" while textures were still loading, because the loaded-image check used a 512×512 fallback that happened to resolve before decode — making tiny placeholders look real. Now distinguishes three states: loaded (dimensions ≥ 4×4 contribute to memory), pending (flagged separately so the UI can show "loading…"), and missing (1×1 placeholder or HTML img with empty src / zero naturalWidth). ThreeViewer polls analyzeModel once a second for up to 8 seconds after load when any texture is pending, so async decodes get picked up without the user needing to reopen the panel.
  • FBX dark rendering without textures: When an FBX referenced textures (e.g. texture.png) that weren't shipped alongside the model, the loader substituted a 1×1 base64 placeholder into mat.map. final = color × placeholder then multiplied every surface down toward near-black, producing a silhouette-dark render where the Mercedes GLS looked like a blob. The loader now detects its own placeholder (1×1 image size) and nulls out mat.map; a new "clay mode" kicks in when zero textures resolved from dependencies, brightening near-greyscale dark material colours to a pleasant 0.75 clay-grey while hue-preserving the brightening on coloured materials (green license plate, red brake lights) so they still read as coloured instead of washing out to clay.
  • ZIP export — main file path: The main model file is now packed under its basename (e.g. eyeball.obj) instead of its full Nextcloud path (e.g. /3D files/Eyeball/eyeball.obj). The leading slash is invalid in ZIP archives and broke extraction on some platforms.
  • ZIP export — preserved subdirectory layout: Textures discovered in subdirectories (e.g. textures/) are now packed under their original relative paths in the ZIP instead of being flattened to the root, so the unzipped folder mirrors the original Nextcloud layout and re-imports cleanly.
  • Comparison mode loading 400 error: loadComparisonModelFromPath was passing the { id, subdir } object returned by getFileIdByPath directly into URL templates, producing [object Object] and a 400 from the file API. Now destructures id before use. (Latent regression from the earlier getFileIdByPath return-shape change.)

Fixed

  • Animation playback: Previously all animation clips played simultaneously, causing blended/static poses. Now only one clip plays at a time
  • Animation timeline seek: Slider scrubber now correctly updates the model pose when dragged (replaced mixer.setTime() with action.time + mixer.update(0))
  • Animation loop toggle: Toggling Loop off and back on no longer leaves the animation stuck; finished LoopOnce actions properly restart
  • FBX rendering: Fixed dark/black eyeball — upgraded Lambert to Phong materials, added SRGBColorSpace, normalized scale, detected transparent shells
  • PLY loader: Preserved original vertex normals from file instead of always recomputing them
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignaturewL1fCXkzaQs2nvi2AkLccAX0u8v5YD4iOypG70neHtpgIb3wIQO+XaIgyQ+8n5k5ZO8pYI33VMdCWsomImFSTZmT7bH7s5DdFotdIektcqSN+kjfyeBeJkdoAcXUU2sJZgSdlFMrIxINc35c1nagz9g+B7qabynqu0yP2FnuWkeN9E37Rb4aXqvPUPPCEFkNjilYHkC1vrW6cUR/Z+L806b1IGJ0eZs6yH/3BB83V6TZ92btN80bbLdK0IbDY/uJ7sggkhuir0WKKoyC31fKsTaqcUi9I6G7Gr2Xzm3NqS6Bk2Y/pp0rLCSQJ+4xO3LA2ktbZIMZtqgA3gEfRYqMzJ10Eyny6TCwfAwOuvozvPoKbfm+5tlhjQyGgE/C7iDOEJ2LFqC9SEH9RrNPlzKxNJ/u1zXHdmEzmxGQpAKS1qoDEAPdKOsVFdkcdKugTNIi6PpP+29HGGl7lE8OuKIiq/JY8z2+9jnfAD087bE8QxnqJBi4eL8401WSzVDRRHlbh6nS/RFb/AqCDkJE+O7G5KskqRvrb3Re7QGNXcogubljsyRMVxQT2azuv/xg6VXJGKGIMv78/OBcQW+fMfr1s6NoDweK0LTQXIVGjQbx0SRJBPsGE5arytY9eIdaoRyHcxXje81vWhp5/Ar5MMLsQf6FjBKZILulUZWPvG2VfmE=
Signature digestsha512
Dependencies
Required Nextcloud versions >=31.0.0,<35.0.0
Minimum Integer bits32
3D Viewer 3.2.0
Release Details
UpdatedApril 5, 2026, 6:44 p.m.
Changelog

Added

  • Cross-Section tool: Interactive clipping plane to slice models along X/Y/Z axes with position slider, flip direction, and DoubleSide rendering for visible interiors
  • Animation Timeline Scrubber: Seek to any point in animated models with a slider, step forward/backward frame-by-frame
  • View Bookmarks: Save and restore camera positions with display toggles (grid, axes, wireframe, background), persisted in localStorage
  • Lighting Presets: Quick-switch between 5 lighting setups (Default, Studio, Outdoor, Dramatic, Flat) affecting ambient, directional, and point lights

  • Exploded View: For multi-mesh models, animate parts outward from centroid with adjustable explosion factor slider

  • Slicer: Export format selector: Choose STL, OBJ, or PLY before sending to slicer (non-passthrough formats)
  • Slicer: Upload progress bar: Real-time progress indicator when uploading to server (XMLHttpRequest with progress events, 2-min timeout)
  • Slicer: Copy share link: Copy the temporary Nextcloud share URL to clipboard for manual use
  • Slicer: Size validation: Warns and blocks uploads exceeding 50MB before attempting server transfer
  • Slicer: Upload size display: Shows file size in MB during upload for files >5MB
  • Modal viewer stats panel: Lightweight model info overlay (meshes, vertices, faces, dimensions) accessible via bottom-right button
  • Modal viewer screenshot: Download a PNG screenshot of the current view from the modal preview
  • Cache settings in Personal Settings: Configurable max cache size, max file size, expiration days, enable/disable toggle, and clear cache button
  • Cache hits/misses in performance overlay: Shows individual hit and miss counts alongside hit rate percentage
  • Cache privacy documentation: Documented local-only storage, per-browser isolation, and user control in TECHNICAL.md
  • Multi-file matching test suite: 48 tests covering texture/MTL name matching strategies (space normalization, prefix removal, plural handling, color/body mapping, partial matching)
  • Edge case fixtures: mixed-case extensions, missing MTL, orphaned textures for multi-file loading tests
  • Export triangle count warnings: Toast notifications for large models (>500K info, >2M warning) before export starts
  • Export MIME type fix: STL exports use model/stl, OBJ exports use model/obj instead of generic types
  • Help panel refresh: Added Slicer & Export section, cross-section, exploded view, lighting presets, bookmarks, dependency cache documentation
  • i18n audit: Wrapped hardcoded export/error toast strings in t(), added 31 new keys to l10n/en.json, documented i18n checklist in TECHNICAL.md
  • Accessibility review: Added role="dialog" + aria-labelledby to SlicerModal, aria-controls on all 6 panel section headers, aria-label on emoji-only buttons, role="alert" on texture warning, role="region" on stats panel
  • Format parity guard: Build-time script (npm run format:check) validates that PHP, JS, loader registry, Viewer MIME list, and mimetypemapping.json stay synchronized
  • X3D/VRML MIME registration: Added model/x3d+xml and model/vrml to Nextcloud Viewer MIME list so these formats open in the viewer
  • Slicer security documentation: Documented full security posture — authentication, path traversal prevention, MIME validation, size limits, share expiry, and file lifecycle in TECHNICAL.md

Fixed

  • Slicer OBJ/PLY upload: Added obj and ply to backend upload allowlist — OBJ/PLY format selector was added to frontend but backend rejected these formats
  • EufyStudio URL parsing: Replaced fragile regex filename extraction with proper URL parsing
  • Slicer upload timeout: Added 2-minute timeout to XMLHttpRequest (previously no timeout — could hang forever)

Changed

  • Tools panel redesign: Reorganized from 4 sections to 6 (View, Scene, Analyze, Animation, Export, Settings) for clearer grouping
  • Toggle switches: Replaced text checkmarks with custom CSS toggle switches for Grid, Axes, Wireframe, and Loop controls
  • Export section: Screenshot, Export Model, and Send to Slicer moved from Settings to dedicated Export section
  • Animation section: Elevated from nested group to its own collapsible section (conditional, only shown for animated models)
  • Model Statistics: Moved from Settings to Analyze section alongside Measurement, Annotation, and Cross-Section

Fixed

  • Theme consistency: Unified --color-primary-element fallback values across all components to #0082c9 (Nextcloud default), replacing inconsistent #4287f5, #1976d2 fallbacks
  • MinimalTopBar hardcoded colors: Replaced 7 instances of hardcoded rgb(0 130 201) with var(--color-primary-element) and related NC variables
  • Dark theme hack removed: Deleted ~130 lines of .dark-theme CSS overrides (46 !important declarations) from SlideOutToolPanel — dark mode now works automatically via Nextcloud CSS variables
  • Cache stat colors: Replaced hardcoded Material Design hex colors with NC semantic variables (--color-success-text, --color-warning-text, --color-error-text)
  • Missing panel props: Added wireframe, background-color, performance-mode, theme-mode, has-animations, is-animation-playing props to SlideOutToolPanel binding in App.vue
  • Clipping plane Z-fighting: Added 5% margin beyond model bounds so the slider at extremes doesn't cause Z-fighting artifacts
  • Bundle budget: Updated app chunk thresholds for new features (+12KB raw)
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
Signature2a2j5kFHSYZk5lKX7ByFRqNuCv8hg06X3uc2Mr98biRZSxeIgBug6aCdHONpN8oppv+6SDc5XrviS8HcLVFw1UEZvHjePdJYR8gri52Aa7ao7IfghYUHnoIwinqvWfP0sRod5vn3ZaKuo1pMpAHQlt/fkQCVz9eH6r+6TQTTBzBeAc7yWyEumArposNVcDqhgy0kK8tNWpNGYhpdqcMEvS7zGi0bl5EeK8k3ufaNaqwlzoXNwNMBiJ1aWFV2phxOxekkxlsHfRmGLkkdbPCOHg1Kj2CTLldHOjSQmQcUH9KOL1xkOZzuAC3Mh8SnrG/47h48uKIe62T7WYHgPbeOrDHvP8Z9d8S9V7kRq3puAonSPX/TFZt7j4YZoyar86w1MVakhT1mwiK3hBax+TCzxPRo63941VwID08MonJxW4D9C59MuF5qb/7UcDZ4Fm/TrSa0yvvKi+gy+gRCmBdzCnTg+WsEZW6Lotin80zckyH/+4wkUhUQBcq97ElIQKDwG5g9Bv6SGtQ2sR3zoUi7T/Wle4iqh38p5to6VMOlKfiBDiloGwpzXtHtlXDIZw8QqPL2h6gTQNdPizlovGLaZLup3sLL6MX7uyD5ZhbWz4kg1Qj4CqORSmpAanqJbBdUhLfA8dU2YhX5q7PFm8pMDAzKOq3h45kiSFI9K39f73c=
Signature digestsha512
Dependencies
Required Nextcloud versions >=31.0.0,<35.0.0
Minimum Integer bits32
3D Viewer 3.0.0
Release Details
UpdatedApril 2, 2026, 7:40 a.m.
Changelog

Changed

  • Dependencies: Updated development dependencies
  • @babel/core: ^7.28.6 → ^7.29.0
  • @babel/plugin-transform-runtime: ^7.28.5 → ^7.29.0
  • @babel/preset-env: ^7.28.6 → ^7.29.0
  • @playwright/test: ^1.56.1 → ^1.58.2
  • jest-environment-jsdom: ^29.7.0 → ^30.3.0
  • vue: ^2.7.16 → ^3.5.0
  • @nextcloud/vue: ^8.33.0 → ^9.5.0
  • @nextcloud/vite-config: ^1.7.1 → ^2.5.0
  • Vue 3 migration: Migrated app from Vue 2 to Vue 3
  • main.js: new Vue() + Vue.mixin()createApp() + globalProperties
  • settings-personal.js: Vue.extend()createApp()
  • viewer-api.js: new Vue() / $mount() / $destroy()createApp() / app.mount() / app.unmount()
  • ViewerWrapper.js: New Vue 2 bridge component — Nextcloud Viewer bundles Vue 2 internally, so a plain JS wrapper renders in Vue 2 and creates an isolated Vue 3 createApp() inside for the real ViewerComponent
  • Removed @vue/vue2-jest (Vue 2 specific)
  • Nextcloud 34 compatibility: min-version 31, max-version 34 (@nextcloud/vue v9.x requires NC 31+)
  • Vue component imports: Migrated deep imports (@nextcloud/vue/dist/Components/...) to barrel imports (@nextcloud/vue) for forward compatibility with @nextcloud/vue v9
  • Template modifiers: Removed deprecated .native event modifiers from Vue components (compatible with Vue 2.7+, required for Vue 3)
  • @nextcloud/vue v9 API migration: Updated all form component bindings to Vue 3 API
  • NcCheckboxRadioSwitch: :checked:model-value, @update:checked@update:model-value
  • NcTextField: :value:model-value, @update:value@update:model-value
  • NcSelect: :value:model-value, @input@update:model-value
  • NcSettingsSelectGroup: :value:model-value, @update:value@update:model-value
  • Bundle budget: Updated index chunk thresholds in bundle size checker

Fixed

  • npm audit: Resolved dependency vulnerabilities via npm audit fix (#77)
  • npm audit: Applied non-breaking security patches, reducing vulnerabilities from 43 to 25 (42% reduction)
  • Lint: Fixed one-var error in useThumbnailCapture.js
  • Animation loop toggle broken: AnimationMixer.LoopRepeat/LoopOnce are module-level constants, not static properties — setLoop(undefined) made loop toggling non-functional. Imported LoopRepeat/LoopOnce directly from 'three' (useAnimation.js, useComparison.js)
  • Model load errors invisible to user: Variable shadowing in handleLoadError — parameter error shadowed the error ref, so error.value = error was a no-op. Renamed parameter to loadError, fixed logger level from info to error (useModelLoading.js)
  • Lights leak on re-setup: Vue 3 proxy wraps items in ref([]) arrays — scene.remove(proxy) doesn't match raw Three.js objects via indexOf. Added toRaw() for light/helper removal and instanceof checks (useScene.js)
  • Toast auto-dismiss broken: ToastContainer was mutating the toasts prop directly (setting progress/paused on prop objects), which triggers Vue 3 warnings and breaks in strict mode. Moved progress and paused state to local data() (ToastContainer.vue)
  • Mobile touch listener leak: setupPinchZoom() and setupDoubleTapReset() added document event listeners but never stored references for cleanup. Stored refs in eventListeners and added removal in dispose() (useMobile.js)
  • Settings page form controls not responding: @nextcloud/vue 9.x changed all form component props from checked/value to modelValue. Updated all bindings in PersonalSettings.vue
  • CSS nesting bug: .select-group-row rule was nested inside .setting-row braces — silently dropped in browsers without CSS Nesting support. Moved to separate rule block (PersonalSettings.vue)
  • Viewer registration errors silent: Both registerViewerHandler and registerViewerHandlerLegacy had empty catch blocks — any registration failure was invisible. Added logger.error() calls (viewer-api.js)
  • Loader errors invisible: All BaseLoader logging methods (logInfo, logWarning, logError) had empty bodies. Delegated to project logger (BaseLoader.js)

Technical

  • PHP CS Fixer: Blank lines before returns, doc comment whitespace, type-cast spacing, removed unused imports
  • OpenAPI spec: Regenerated with slicer and thumbnail controller tags and updated description
  • Three.js + Vue 3 pattern: shallowRef for single Three.js objects, ref for arrays, toRaw() when passing proxied objects to Three.js APIs
  • Vue 3 Maps pattern: Maps moved to created() hook as non-reactive instance properties (this._timers) to avoid Vue 3 proxy breaking Map.has()/Map.get()
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureCqMDLnrHd2ejY1wtQ+IUFnXE3ObdTMqRro2/QTWhZPmyh7h5lD2zlldE7hV6K2PLVbSbQA8RyylLA7chfBAfNhqrGVcv9N8oS4N8JZlvp2sx7uCnQJx9hA34xXsRvCNednaE0NuhE4zelLAkmDaJZEcQm0r0mQKkZAMSaIPgRg52ZFiEV+KFa7dyHlyLqc/Cp6doYyEeJxnyDiLOiCCsS0zyrt1qQlRyEgGcOocdeIPJRutmBwX3Sy/018v5midNblK+gleIzcCAFIOM7qDJKuf5ESnvQmqQko/7J+ahhAGzIdpGRHmKCVjAayZ2g3uLkT9dNQrBwKAaYvNWODkSyVEoBBU1wrucKcw237GMSjxHrVf/h5G64+Nb9/krmriBkdcpVupQ94wgyU9H5NO+BsBP/+3EfuuECRwOxXMW15taFrsiflxos1Fuhu5PQtyfOv4UPtUzn+uf4MaSzeLYdBHsOHfO6ZTjTPRbO5NLz5nlMw3F4PEgSKW7bk9brH7dEjzQzVG1RrDYCg75bGW+8l7/vtAmWc87s6otqoCj9rPVHQhrY7njOUcU8gwjdw0WuFTD//i2Vk0+agy7GO9WWfUdrbQ/i8Grq5AwoEgD3b0NLpPB9XxDCOR3yZQhSDbHNvgI8BRDp3Xe1FDv8izK2Dw9HwjykDDU+uMNZNtNpdA=
Signature digestsha512
Dependencies
Required Nextcloud versions >=31.0.0,<35.0.0
Minimum Integer bits32
3D Viewer 2.3.4
Release Details
UpdatedJan. 18, 2026, 6:57 a.m.
Changelog

Changed

  • Dependencies: Updated development dependencies
  • @babel/core: ^7.28.5 → ^7.28.6
  • @babel/preset-env: ^7.28.5 → ^7.28.6
  • postcss-html: ^1.7.0 → ^1.8.1
  • vite: ^7.2.7 → ^7.3.1

Fixed

  • Nextcloud Subfolder Compatibility (#74)
  • Fixed app not working when Nextcloud is installed in a subfolder (e.g., https://example.com/nextcloud/)
  • Replaced all hardcoded /apps/threedviewer/... paths with Nextcloud's generateUrl() and imagePath() functions
  • API endpoints, decoder paths, and static assets now correctly respect the configured webroot
  • Affected files: multiFileHelpers.js, useModelLoading.js, useComparison.js, gltf.js, ViewerComponent.vue, SlicerModal.vue, App.vue, viewer-config.js
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
Signaturem8HTfU5qBOyGRmdHu4hylXbuVzwpcofBxDmpgWjNf0qvBkujJC75qp0z1GcJKDRppDXuE5z70L6g5AAUda+v3Z5y9byJqnisxNVRZM0nbXwYgOmqi8MdBnP7bzd5Ms43jDwr8hKt5ffEKR+g6h7Um8q5BDl3Vdk2J8nVuk+uvduDXalukp+USx3ibBHjg3MDSJqdkTKkHPe41SXEpjyor9VMKLer8r7HxHcwlELGseyuFHgL/PPYQOT5GQf6KO7ae0s2lYH6tbBu3ZnP/f0tg4cYZAHAycm4fvAwRj44XMh6a3OFP0FdQOkpSmYa7Tp5IH5rj4zBjrazGCxtUU40q3bBmYRvIKiv/je83LfQA5n8FCgmjREez0JslPFBByM//FtrcFgsm1mrzSgkufLTdvQ8JYb1XbV6xI7jKWSYKdCidwpvHCWAUqvQDWRVL2cZ7tLyGwSVHtLEsftO3Ykhu7WYpyQmNIG2s6zTuBC9x52IL7hxU9+7127R5L7S2AdPxvUB5Xrz5PJbfKal41mSi5GTJ1s1d+ow6lyB/rU1yGMX12Y0gDTZjXLHvCMq6Ixtcy1igH1nd/C8P+j1vDHbDPyZnIKtx9yBTMsejnv9tdsPpE4ya+eM54l1i+gZEdM8NhFxows/bBHJaljU6DBRvtdYBriWsMHsrsDB2wSuTMA=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 2.3.3
Release Details
UpdatedJan. 16, 2026, 2:42 a.m.
Changelog

Added

  • Automatic Thumbnail Generation: 3D model thumbnails are now automatically generated when viewing files
  • Thumbnails are captured with smart cropping to focus on model content
  • Grid and axes are hidden during capture for clean previews
  • Thumbnails stored in Nextcloud app data (not in user files) to avoid cluttering recent files
  • User setting to enable/disable thumbnail generation in Personal Settings → 3D Viewer → Thumbnails
  • "Clear thumbnails" button in settings to delete all stored thumbnails
  • Works in both standalone viewer and Nextcloud Files integration modal
  • Thumbnail Settings: New Thumbnails section in Personal Settings
  • Toggle to enable/disable automatic thumbnail generation
  • Clear thumbnails button with confirmation dialog and count of deleted files

Changed

  • Thumbnails are now stored in Nextcloud's internal app data folder instead of user folder
  • Prevents thumbnails from appearing in "Recommended files" and recent files lists
  • Improved privacy and cleaner user file space

Technical

  • New ThumbnailService using IAppData for app-internal storage
  • New ThumbnailController with endpoints for storing and clearing thumbnails
  • useThumbnailCapture composable with smart content-aware cropping
  • Thumbnail capture integrated into both ThreeViewer.vue and ViewerComponent.vue
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureuFzoE7HPsOrBKlyKjSzOuEeHjB3dAL7I/y0IF+GNXsgneUJobVLzw+kWlOtZyGa4wNcavAH3caVRlqPjMdw/ZlrlgkJN62qghl/yvbskmmSsiC43ntcKMfGd8Gat1wCXPzTGipRc4DqwbpUyN3PIVltZgpSvX+xaTB3+bLwPNIg2vX2GMpalC9vN2eGa60fPm//OXZKujqfRVwGqg36OpfuRKgOr+J2xDyxAsyc6UywFRGHUnpGLiZgp0jXIRshqpM+k3fpbZDB1JrDbYlPaAZwa4Ze//xxv4Xbk4KmmlLY0S6GXChNbX0rAYrwv+PxJxFeLSI5ytw9iZPdDFQFmgm5RJv7XVhmc31ccZyJ8eaTRz2+JfqBRV5csX5Ox9QIVjmkL3WX70eNIcRUBGX4BFOcCqZxnRgg3moqoSKAZFQ3sOMxwStiKlHhrffZvclDLZRL3S76C492BVlF9HFZc5KYnuF17VQPs1OL8xWFcW57HfcjpMs6xydfnMtfTJUTWbS9p6fjaxLjUgl93ZqWTMmc8dpXl7ywiLjVViTNk8PNn3NzHP3H5yszzBxcO6elz7cIQgXRKdVKB8OQoaeMEjxQQfmWAIViZyXoEEhS76bsI1oeuqAiNH/9p+ytUkBeN7FK6yljt/8QauU38PLTih0QE2xCLB6fP1EMAtLAb7PY=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 2.3.2
Release Details
UpdatedJan. 7, 2026, 4:17 a.m.
Changelog

Changed

  • Dependencies: Updated development dependencies
  • stylelint-scss: ^6.13.0 → ^6.14.0 (dev)
    • Enhanced dollar-variable-no-missing-interpolation to flag namespaced variables in custom properties
    • Extended function-disallowed-list to detect disallowed functions within @return expressions
    • Fixed false positives in dollar-variable-no-missing-interpolation when variables already exist inside interpolation
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureYV9kZk3oeyVbeTn1qLIVLgb5ERRXgsTQamJCdPTLt4vgt7xf3ShcXd6Srry0UKHzEGvXqQjVq3sfxtq5INZNKQugyC67dlmP+WfFbq7nsLoGJp4Cpjza5ud+4ozbxgbVqNFhNoFVz/zYGyc1lAcSUP8zC10x6zfq/0WoRUFgWHOKCuK6ZB4vQd5J7JRX7JKX1sxbl+rGHSqbQeWuyJwlCir+zr5Y+746EJ+2S29f8z3KFxf2PfEZwAmE1Nf05FAVL5RhQhlDjqM7J2NvQEP6Pod8b6Q+RxFKMWkYyTHncCfQTNz+3VYeuJsqfYC6ZVADYOT5duvHbqOIW4sdnrotXWQDq0uxww7qKYISKp4srSKBwiN1k6EIGt2Clr5FOlji80tIlOtzqanLWQlhpV3wuiVSA8TTbfxPVlB4Mn7dGu/LHc5TjfQ5JEct+5nfEwSCdnLbnEhLyiNRFPppmpIjfHhSWhVrHpz/YRdSarEsmNeP31dSoJKbhNtqhi1oIbtyXG5ElYrTFFg+nxz/yc3Ok33KY+D1nJ9gIN+Qdde9E86qg0cXeIgq+CtM0TGomTKPt9BXQfresW9zuzKli1p7xS3d0C21acP8r6humszQcZQNliz936kTkULULFo86VkyYmK79Gmm16tcMDXbXiZcvhwqF/xrXS6QuQb44K9hC2s=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 2.3.1
Release Details
UpdatedJan. 7, 2026, 3:03 a.m.
Changelog

Fixed

  • "Send to Slicer" Button Always Disabled
  • Fixed missing modelLoaded prop binding in SlideOutToolPanel component
  • Button now correctly enables when a model is loaded
  • Affects STL and all other 3D model formats

  • CRITICAL: Cron Job Fatal Error (#65)

  • Fixed foreach() argument must be of type array|object, null given error in CleanupTempFiles cron job
  • Removed incorrect foreach wrapper around callForAllUsers() method

  • CRITICAL: Missing Exception Method

  • Added missing getExtension() method to UnsupportedFileTypeException class
  • Fixed fatal error when attempting to access extension information from unsupported file type exceptions
  • Updated all exception throw sites to include extension parameter

  • CRITICAL: Insecure Rate Limiting

  • Replaced insecure session-based rate limiting with distributed cache implementation
  • Uses ICacheFactory for thread-safe, multi-server compatible rate limiting
  • Prevents rate limit bypass by session clearing
  • Improved scalability for large installations

  • HIGH: IP Address Spoofing Vulnerability

  • Replaced custom IP detection with Nextcloud's secure $request->getRemoteAddress() method
  • Prevents IP spoofing via forged X-Forwarded-For headers
  • Properly respects trusted proxy configuration

  • HIGH: Path Traversal Vulnerability

  • Fixed path traversal vulnerability in temp folder verification (SlicerController)
  • Replaced insecure strpos() checks with proper str_starts_with() path validation
  • Prevents unauthorized file access via path traversal attacks

  • MEDIUM: HTTP Header Injection

  • Fixed potential header injection in Content-Disposition header (PublicFileController)
  • Replaced addslashes() with proper RFC 2231 encoding using rawurlencode()
  • Prevents header injection via malicious filenames

Improved

  • Temp File Cleanup Enhancements
  • Added comprehensive logging for NotFoundException cases
  • Implemented cleanup statistics tracking (files deleted, shares deleted, users processed, errors)
  • Improved share deletion error handling with separate method and individual error logging
  • Added file type validation to skip directories during cleanup
  • Added progress logging every 100 users for large instances
  • Added stack traces to error logs for better debugging
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureMK0+lREma3H+5o5HY/1XiCvaVsxjUPM6tcB151nPTrwJOeBdbFF50jwp8N7+xgyKEF8GZEOYpwqBu2jYjlN8bJBJFDUI4Givl++H6HAT0/yOhq22oItRC9eOdmrdLiduHqSm10UDj37gda6vOjZwGiPKG6OcmqTkAB5z6tCSX9xH4RznZwbWIpCKBKfUDv53iCyBiogCX3Zyz7443IEdkBy51an9N64COoiWJACcw1kse1f2JtS5ptYTXBA1ImMNOVkX+I2n+b4qp9n972UGMXyx8JnhH7nuVp4XH7nY2oargPPk4b+p1Yqq5/bJGsdazm+i8PaYcJ6UHJTySjTOIvh6MuWpA+xuXTWSgM9k1DUTFG2YQ1RS/JJsFQ4Xhm9GffxDOQ8mSMRp3MnEdMd8FgIU+REqQP3MAYvxQ/c11RWoaolM+VbWrKNGJqB2U2pliu4oM7DRlZg4GmgHvYUMUQQYTq+L1lZlvyQp+NweTuvaUcx6cY5z3SdiRb75o3fYhgNGPDg6ZgsV45Oy6srZofHfGiuYy+c/AkL9Nr8c0nBlZWtxV/OVdPsbHHmNhSVAmv2baFug1mGUcGYRApCmWLlpJbskW3ZNeFfsHp/d/st0LPjhK6ItDHe+6khDFAYoqQWFA2z2nmrWZuD/FzB2Ny3TVCZBQkpzDc7hJiBBxGY=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 2.3.0
Release Details
UpdatedDec. 28, 2025, 1:15 p.m.
Changelog

Added

  • G-code Visualization Enhancements
  • Smooth rainbow spectrum gradient coloring across entire model
  • Intelligent filtering of travel moves, retractions, and parking movements
  • Skip movements exceeding 50mm in XY plane to remove edge artifacts
  • Fixed vertex color handling for proper gradient display when toggling modes

  • Mobile View Optimizations

  • Responsive MinimalTopBar with all icons visible on small screens
  • Help panel displays full-screen with sticky header on mobile
  • Smooth scrolling support for iOS devices
  • Performance stats overlay hidden by default on mobile and screens ≤768px

  • G-code Toolpath Visualization: Added support for G-code files used in 3D printing and CNC machining

  • New G-code parser supporting G0/G1 movement commands
  • Automatic layer detection based on Z-height changes
  • Color-coded visualization with different colors per layer using HSL gradient
  • Support for multiple file extensions: .gcode, .gco, .nc, .acode (AnkerMake)
  • MIME type registration: text/x-gcode
  • Custom file type icon for G-code files
  • Toolpath rendered as 3D line segments with configurable transparency

  • Extended G-code Ecosystem Support

  • Additional extensions recognized and routed to the G-code loader: .g, .gx (FlashForge), .g3drem (Dremel), .makerbot, .thing
  • MIME mappings added for container variants: application/x-gcode for .gx, .g3drem, .makerbot, .thing
  • Viewer “By Type” browser now lists these extensions via SUPPORTED_FORMATS config

Changed

  • Backend Listing Filters: Updated FileController filters to include G‑code-related extensions in Folders, Type, and Date views so these files surface across all navigation modes
  • Applies to folder-scoped listing, type grouping, date grouping, nested folder inclusion checks, and descendant checks
  • Slicer Handoff Options: Simplified send-to-slicer flow by letting users pick passthrough extensions; all other formats now auto-convert to STL by default (export-format selector removed)
  • G-code Visualization Default: Default toolpath color mode is now gradient instead of single-color orange for clearer multi-layer contrast

Dependencies

  • Updated @nextcloud/dialogs from 7.1.0 to 7.2.0
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignaturePzIAblqli6tJofqSxWWKOwCp0h/EaSHMlT/+yyoqArTsvBAPzn8xLqU4/58/5pja+YAA7WeQ9egTPUicOilrSFBSHQVGa2QSLQVWFu+vTXKGEuu90qNxXnNqDnl66TVKuWR0OiXHeR2nCAdu3jh7310h8afbBLR3eQAXIeuWlLtXnbzVLoaiqy4pK9l2FzN8GpQoU4/7fo7SH1CFE6iR+Yea4Y2P6C1UXGQfG/RnJylCj1UT+2UkkLUAopk9AOxMEgQpwQzUV5kl4FwvND4biwcuXEajDXwVizX9qAEDtOkzILdV46RcWkyHxnDcqIGHuRImgfqWlwwz6fZ14Huf7/5bmvNafPuSPPRJHEWvH66whuXS5sft+Crvd1/AR+sF2bDGtGtoQo2iSRSCmVS8XtsK0+dW+DLGIvd7pQsul/AIWPDYYkPtMCgAXCFLJpFmmOhNNoCOshjRSgJ5LrnfBC3kbF66gBZGhlkBc0n9MDkqlgxDNVNGwYHYG6xllH4u+1xdGIilc7TE2EXSmpD3GEJOCTLiRdMDbL2ZSC04fd9Lf5YbVgKMggroGFNbtl9VszrOD8GtgpyUqdQnZ9D2U9ef8sJqRxzWKNT3Sr3A2PxgKiCf8G0yu0016JlmwHeEJQAWs9u+0ZpnYo51eSGQKnKtonW1avH6I95Mqh6cPbA=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 2.2.0
Release Details
UpdatedDec. 17, 2025, 6:10 p.m.
Changelog

Added

  • Measurement & Annotation Visual Sizing Controls: Added per-user sliders to control measurement and annotation visuals
  • New Personal Settings section for adjusting measurement point size, line thickness, and label width
  • New Personal Settings sliders for annotation point size and label width
  • Settings are stored per user via SettingsController and merged into VIEWER_CONFIG.visualSizing
  • Measurement and annotation composables (useMeasurement.js, useAnnotation.js) now derive sizes from configurable percentages of the model size
  • Animation Controls in UI: Added animation play/pause controls to viewer interface
  • Animation play/pause button in MinimalTopBar component
  • Animation controls section in SlideOutToolPanel with play/pause and loop toggle
  • Animation state props passed through App.vue to child components
  • Integration of useAnimation composable in ThreeViewer component
  • Improved directory path extraction for multi-file model loading
  • Dependency Cache Insights: Added live cache statistics (size, entries, hit rate) to the viewer and slide-out tools
  • Viewer performance panel now shows cache size and hit rate
  • Slide-out tools panel displays cache stats and clear-cache control with status
  • Cache stats refresh automatically during use and after model loads or cache clears
  • Cache hit/miss tracking with reset when clearing the cache
  • Performance Scaling for Large Models: Automatic performance mode suggestions and easy mode switching
  • Configurable triangle count thresholds (warn: 500K, strong: 1M faces) for detecting heavy models
  • Automatic toast notification suggesting performance mode for models exceeding thresholds
  • Clickable performance mode label in stats overlay to cycle through modes (Auto → Low → Balanced → High → Ultra)
  • ViewerToolbar performance button now cycles through modes instead of toggling stats
  • Performance mode changes apply immediately with visual feedback
  • Slicer Temp File Security Hardening: Enhanced security for temporary file uploads
  • File size validation: 50MB per file limit, 200MB rolling folder cap
  • MIME type validation for STL files with header checking
  • Rolling 24-hour expiration enforced on file access
  • Increased cleanup frequency from 24h to 6h for faster expiry enforcement
  • Comprehensive audit logging for creation, access, and deletion events
  • Security posture documented in TECHNICAL.md
  • Automated Bundle Budget Enforcement: Enhanced bundle size checking with historical tracking
  • Comprehensive budget thresholds for all major bundles (main, loaders, app, three-core, index, nc-select)
  • Historical size trend tracking in bundle-sizes.json (last 50 builds)
  • CI workflow uploads bundle size history as artifact (90-day retention)
  • Size trend comparison shows changes vs previous build
  • Improved error reporting with formatted bytes and clear failure messages
  • Fails CI builds when budgets are exceeded (with environment variable overrides)
  • Vue 3 Migration Pre-Work: Eliminated Vue 3 incompatible patterns to prepare for future migration
  • Replaced deprecated lifecycle hooks (beforeDestroybeforeUnmount in ViewerToolbar, ToastContainer, ViewerComponent, viewer-api.js)
  • Added explicit emits declarations to all components (ViewerToolbar, ToastContainer, ViewerComponent, ViewerModal, FileNavigation, FileBrowser)
  • Verified no implicit $listeners usage (removed in Vue 3)
  • Added comprehensive migration notes to COMPOSABLES_API.md with dependency compatibility matrix
  • Audited dependencies: vue 2.7 → 3.x (API compatible), @nextcloud/vue 8.x → 9.x (requires Nextcloud 30+)

Changed

  • Cache Statistics Updates: Improved cache stats refresh frequency from 5 seconds to 2 seconds for more responsive UI
  • Performance Mode Controls: Enhanced performance mode switching with clickable controls
  • Performance mode label in stats overlay is now clickable to cycle modes
  • ViewerToolbar performance button cycles modes (preserves MinimalTopBar toggle behavior)
  • All mode changes apply immediately with proper event propagation
  • Dependencies: Updated core runtime and build tooling
  • three: ^0.181.2 → ^0.182.0 (patch update)
  • vite: ^7.2.6 → ^7.2.7 (dev, patch update)
  • Security Workflow: Updated GitHub Actions CodeQL workflow to use github/codeql-action v4 in preparation for the v3 deprecation in December 2026

Fixed

  • Toast Event Handling: Fixed missing push-toast event handler in App.vue preventing performance suggestion toasts from displaying
  • ViewerModal Performance Mode: Fixed performance mode cycling in ViewerModal component by adding proper prop passing and event handling
  • Model Comparison Positioning: Fixed comparison model positioning issues where the second model's position was immutable
  • Wrapped comparison model in a Group to neutralize baked position offset from loading
  • Fixed parent-child relationship handling by using toRaw() to get actual Three.js objects instead of Vue proxies
  • Ensured matrixAutoUpdate is enabled for wrapper and all children for proper render loop updates
  • Fixed matrix validation order: validate parent matrices before child objects to prevent "Cannot read properties of undefined" errors
  • Improved scene hierarchy validation to include all objects (grid, axes, lights) not just models
  • Fixed matrix update sequence: call updateMatrix() on all objects before updateMatrixWorld() to ensure proper transformations
  • Comparison models now position correctly side-by-side with proper spacing and alignment
  • CSP Compliance for Texture Loading: Fixed Content Security Policy violations when loading GLB/GLTF models with embedded textures in Nextcloud modal viewer
  • Patched Image.prototype.src setter to automatically convert blob URLs to data URIs for texture loading
  • Patched URL.createObjectURL to track blob-to-URL mappings for later conversion
  • Patched fetch() and XMLHttpRequest to intercept blob URLs and convert them to data URIs
  • Patched THREE.FileLoader to handle blob URL conversion for texture resources
  • Automatic detection of modal viewer context (iframe or Nextcloud viewer) to apply CSP workarounds only when needed
  • All patches are automatically restored after model loading completes
  • CSP Compliance for Buffer Loading: Fixed CSP violations when loading GLTF files with external .bin buffer files
  • Updated setupResourceManager to use data URIs for buffers in modal context (instead of blob URLs)
  • Patched fetch() to intercept data URI requests and decode them manually, bypassing CSP restrictions
  • Supports both base64 and URL-encoded data URIs for maximum compatibility
  • Animation Support for Multi-File GLTF: Fixed missing animation initialization for GLTF files loaded with external dependencies
  • Added animation detection and initialization to loadModelWithFiles function
  • Animations now properly initialize when loading GLTF files with external .bin files
  • Animation controls now appear correctly for animated multi-file GLTF models
  • False Texture Warning: Removed automatic texture warning banner that was incorrectly showing for all GLB/GLTF files
  • Warning now only appears when actual CSP errors or texture loading failures are detected
  • Improved user experience by eliminating false warnings when textures load successfully
  • Slicer Upload Safety: Hardened temporary STL upload handling with size and MIME validation
  • Reject uploads over 50 MB per file and enforce a 200 MB rolling temp folder cap
  • Validate STL MIME/header before accepting; reject invalid content
  • Enforce rolling 24h expiration on access and clean up expired shares/files
  • Use rolling +1 day expiration for generated share links
  • OBJ Texture Loading Robustness: Improved OBJ/MTL parsing and texture handling
  • Preserve texture/MTL paths with spaces and mark materials for update after textures load
  • Use existing blob File objects for texture URLs and tighten loader logging
  • Handle texture load failures gracefully and ensure needsUpdate flags are set
  • Texture Dependency Lookup: Skip direct “find by path” lookups for image textures to avoid unnecessary 404s; rely on directory listings for textures commonly stored in subfolders
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
Signatureacd0z9v0ifd6EhLDkZPQmIADZp+TPcgSOqKKp6W5KUtq4CA/Xk0lTNssZpirrEaLO4s15qemVCz87Aa6hhxGipOFlBSMFIyc1U0q8OQzHMOa4cYU8w1hvmi7aXeG+IxPWXelCAYaBNYGbleOvhc+/ao1gh1mn+3esakeTLdBi8XihNAKBDzglkOD30oBunXuzXJD1chBFBx7LCMoRhVXHDxShzi39+vbumkbme4IGV9kL323hTSjD1+XrMeiIG2P9tvHDEkGRXEOKohmWQNrsFCamApVqslvRzg6mBFTFv+dtnBUFbbQnC25IvyE+UNY4j2TGzncrW2+jWGddicKYq4SIrI7RzB91gTxv+3qzwCUb8OlyaU38L042l4HJXSFMPh8Mmj2n/0zhWlH4M2h/ZEPjySsaK8lU/x/DaBoyLcPoJcDsuD1haONv6mpRsoz/ohXdV/U9s61rbGOnJkSqMMblFoVXVmkzTKpBatf08e9Uaig21b9q/ekYyhbVFlujmAu9ku9EWk5SddY26zNvSeiGinV1xV3BayMI3rVZYINZkPb72Dv6DOInRWlVOxVqLQBUY98ejlhpls+6l3IdtTDUmrITmGr+Nq3b8T8kgNJpgNQbf3Ij14MgdfNsxd4nxMyX/4hsOSZdU4dAHsTfatSxRgM1q9FpuvZ+OkyWMA=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 2.1.0
Release Details
UpdatedDec. 6, 2025, 10:21 a.m.
Changelog

Added

  • File Browser Default View Setting: Added user preference for default file browser view mode (Grid or List)
  • New setting in Personal Settings → File Browser → Default View
  • FileBrowser component now loads and respects the default view from user settings
  • Setting takes precedence over localStorage, ensuring consistent default behavior
  • Manual view changes are still saved to localStorage for session persistence
  • Format Sync Test Suite: Created comprehensive unit tests (tests/unit/Service/FormatSyncTest.php) to ensure format definitions stay synchronized across:
  • Backend PHP constants (lib/Constants/SupportedFormats.php)
  • Frontend configuration (src/config/viewer-config.js)
  • Nextcloud MIME registration (appinfo/mimetypemapping.json)
  • File Browser List View: Added ability to toggle between grid and list views in file browser

Changed

  • Format Definitions Centralized: Consolidated all 3D model format definitions into lib/Constants/SupportedFormats.php as single source of truth
  • EXT_MIME_MAP for extension to MIME type mappings
  • CONTENT_TYPE_MAP for file streaming content types
  • All repair steps and services now reference centralized constants
  • Eliminates format definition divergence between components
  • File Browser Grid Padding: Updated file grid padding to consistent 20px on all sides for better visual spacing

Documentation

  • Corrected repository URLs and upstream fork instructions in CONTRIBUTING.md (replaced placeholders with maz1987in/3Dviewer-Nextcloud).
  • Updated TECHNICAL.md with new controllers (SettingsController, SlicerController), components (PersonalSettings.vue, SlicerModal.vue), and detailed Personal Settings + File Browser implementation sections.
  • Added comprehensive "Adding a New Format" guide in TECHNICAL.md with step-by-step instructions and code examples
  • Expanded IMPLEMENTATION.md: added Slicer Integration & Personal Settings System sections; reorganized and deduplicated legacy "Code Audit and Cleanup" content; refreshed Table of Contents.
  • Updated README.md (docs version) advanced features list to include Slicer Integration and Personal Settings.
  • Added troubleshooting sections for Slicer Integration and Personal Settings in TROUBLESHOOTING.md.
  • Expanded test coverage notes in TESTING.md to include new controllers (Settings/Slicer) and components (PersonalSettings/SlicerModal).
  • Normalized wording and removed outdated dual-mode duplication in implementation documentation.
  • Documented dual-mode viewer architecture in TECHNICAL.md with viewer lifecycle diagram (standalone vs modal modes).

Fixed

  • Settings page image/logo path resolution: replaced hardcoded asset URL with imagePath() helper in PersonalSettings.vue to ensure correct loading under all deployment paths.
  • VRML preprocessing duplication: Removed duplicate preprocessing code in preprocessVrmlText() that was applying BOM removal, line ending normalization, and null byte removal twice, causing inconsistent preprocessing behavior.
  • Flexible texture matching loop control: Fixed nested loop control flow in texture matching logic (multiFileHelpers.js) by adding foundMatch flag to properly exit outer loop when match is found in inner loop, preventing valid texture matches from being skipped.
  • Premature texture issue check: Moved checkForTextureIssues() setTimeout call in ViewerComponent.vue to execute after model successfully loads and is added to scene, ensuring accurate texture loading status assessment.
  • Debug logging cleanup: Removed console.log statements from FileBrowser.vue component (viewMode watcher and setViewMode method) to improve production code quality.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureatLgIGKAv/DO42HgoDbqVaos4kWPFuPmF5l4PHyM5S5ivOlmqnC5xu1+d5uX/h+0rUmL+pG6wKezHo7WT0PVKSBciYZzlb5D+6sJisB5x/jMVqFaQRmnEEPKfoz2DsDucmXtH6Ppv3oXjyKd5wDjyFMwtoG1hU43QBeA4ngYTMTCXqdITK5sT4OM4IwiYhUi7zZRh6/YoRxgojXIqo/RasM3sGIUIrQs075RKqXcdGcGUwJgQPAQnGsMEW9D0LODp6bYurgBZRgnmgBrpTE3D7Ktt1G+ppQTSW4tHpuq3mFJdhFlkbhbWJw9QW28xJmDnqUGfhzXTSMqoJLnbio0n7iT5bhiyxBmhi5patzHifmDwndpRPoZNbw7vxr2zzqCc+1pMt/CoXHn1PTthmYtQMg9tvyjS7jbCdYtDYLtluzITRHP8GzRXIMmBrCRzXLymk0b3IvwyB9G83+QwzHyWSTLsKV314CSasumGhFDSxnz0E2DhVVZV7yaG89Dj9HHwmxkQVeh4iI9DCd5ynu6q/8Ljyp4nJ1p//+3WCo3NksaM0ubqkXiVFnSTnSjsoDw8mbP8TU/iESpYJ11llVA9ftZSGnnczY2zFKKK17C5m/pjE9sskLlo2bfhBzRLvYOV8ejRyaXPK1B6ejCfk2VwWntq7UKFh/+/1R5usmQkRg=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 2.0.0
Release Details
UpdatedDec. 2, 2025, 2:53 a.m.
Changelog

Added

  • Personal Settings: Added personal settings page for user-specific preferences
  • SettingsController and PersonalSettings view for managing user preferences
  • Settings routes and configuration updates
  • Enhanced File Loaders: Significantly improved loader capabilities
  • Enhanced FBX loader with additional features and better support
  • Improved VRML loader with expanded capabilities
  • Updated DAE loader for better compatibility
  • Enhanced multi-file loading helpers for improved dependency resolution

Changed

  • Viewer Enhancements: Enhanced ThreeViewer component with improved controls and features
  • Camera Improvements: Updated camera composable with additional functionality
  • Circular Controller: Enhanced circular controller with better user experience
  • Theme and Performance: Updated theme and performance composables
  • Major Version Bump: Version 2.0.0 introduces significant improvements and new features

Technical

  • Updated GitHub workflows with improved condition syntax
  • Updated Dependabot timezone to Asia/Muscat
  • Added change detection to prevent unnecessary PRs in workflows
  • Updated stylelint to 16.26.1
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureJrtVI0UiQsSqL82PvCmO+FLp06iE6caUY8nD1+dKlVr5YjeTvZjLUtd0sAbmwQzlR2iC4IuRJllv7hr5cWk8oWuJtnLuE4uzcXu3bu8ndzO/Zyf4ph65Fn3GyML8Zdm6TqECBFCzk+2NG0pVxt4TM7qML5p437Q6IrF0+uOh3Vj55CTf160KAjEN7v2Sa8CT4Qf/JPKtnfyAgnKkNRXMQCf7xXe3RqtgtiVPnNq6nKfYzERoihIHhZ4LqLewUfY7jvxKUpAIxF89K+yTk1PmsJgKPBN88FF3ReKwcfJcfIhMXuH7CJEHCg++Hbd0oxzvl3uv0o8k5USdkojH0vG5IQaBF8AAEGY0aKCsScmffSN7WvmpPngsHs56V/olPNPVG1QNepRvSvBljr9D6idShiRlaW7uOBl9SVwLernLBjZ30bfqRtdrm2T7oO6gozY0zRc3jxt+ajAuaPLp8pAKC/Bv8nt3Og7R3r/mpk7qXWEgC/u78v/LqjhtICx1CQDSROq8vuces8k4iEN1kJabrhxLFPDPmZucoXWSzUStP+ISyPksq+pk5KAtnKuVRMTN8rhYkMlyK1790OOF53Q1bvlHnTc3LmzTLi6b/mVPBtz+KgkHHoU8j4TYwSlnbmSx6gDqzrQa8q+cRXlK1NNmF211NX0J8B9nRkng+xHg5ts=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.8
Release Details
UpdatedNov. 28, 2025, 6:24 a.m.
Changelog

Changed

  • Dependencies: Updated development and runtime dependencies
  • three: ^0.181.1 → ^0.181.2 (patch update)
  • stylelint: ^16.25.0 → ^16.26.0 (dev)
  • vite: ^7.2.2 → ^7.2.4 (dev)
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureMKCHrKGV1G4CZgG/gyhGvg34zK0migxfZ/FS9ZZEylzffGxQxoQbW+wubOR3BAjgWRx5smOBIdKVeLLuPOV00JnPgrII3lRaltLVO72nNrYtVh5DruKC5ZoMM4BuJsdEOFP8euy/GDCmlhQYNTusS/T+meggfylcrAjZAWR+SZZfb4x7QlBJTdmCuWpHNBJO081IpeLfn5HXohFAWm6sHHm6mun4ar6znAlwsZ/pe6Lo8ZjzLBuDN9mLEujrw6AgjTq2DTSUrHrJ9/WQF3zBiYjRLMNurJLnrwCXuUmPkKGWrPM3ybFADqfgb3QmqzPsPiGUL87k/1yVewEqE2olFpVRZ9hxa11ANingG+zMZwY1bCbzIcrRCq4Uoae7zgwZV/CF2wJQk+cRMbQl7Y7AoAy6PPECLMFtU93VgHqcPtFQzAxSPEXRNW+GpkVFHWvBZ7iuL6Ys8gMjl9i9imuNYcIAkuLlKLmu8t5pQpOLKvNpiQkeIf5aWXHm5Fvq7+zmeKIsuMVNvPoqQOSlC1AkwnLi1EAf/2VrqbAmDoC/o3Y6h1mg6vskUNFRPhz2h37TEb65h1bm9kFjNx/6TNNF0xM96GSAt7v+I1naBODhvGqDqyJ653663yuE+CxdKd1kZ4ous3urqXRwAmKHVdOvXYZTb+N/Feu7PHqrdcwlHHQ=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.7
Release Details
UpdatedNov. 27, 2025, 5:42 a.m.
Changelog

Added

  • AnycubicSlicer Support: Added integration for AnycubicSlicer with custom icon and URL scheme. (#52)
  • Folder Exclusion: Added support for .no3d marker file to exclude specific folders from 3D file scanning.
  • Hidden Folder Exclusion: Automatically exclude hidden folders (starting with .) from the file index.
  • Temp File Cleanup: Implemented background job to automatically clean up .3dviewer_temp files older than 24 hours.

Fixed

  • Layout Issue: Fixed white empty space when hiding the navigation sidebar by ensuring correct flexbox behavior and explicit slot usage.
  • Viewer Resizing: Fixed 3D canvas visual resizing issue by syncing internal resolution with CSS dimensions (width: 100%).
  • Slicer Icons: Fixed missing slicer icons by using the correct imagePath helper for asset URLs.
  • "By Folder" Navigation: improved folder indexing logic to correctly build hierarchy and handle edge cases.
  • Server Error: Resolved persistent preg_match error in PreviewManager by disabling unused app preview provider registration.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureLfmZ7uqqVk6tDgQQuwcGuzQml5OZWmFvpfNYW9Nd+3gVtIRUCBKsgtB8D6CMf1ymq2JxllnMvhATHE3YVZGmCsL5CRrj6al9+zdVnP8An2BUBP/DsqDTTwLM64mwKFIqYYkjtwVfttaa/aPJn2cdH7umzjOEHsYzbRx7eiP1lq2ERy4KYs7aA26hfleg9kKbr1jKTf0/vPCHvmbKg+o3RS+QfP/lRuoPjk1UYog52IAHd9bpAtAgmB2yLSfghjPSvMhZkyWt38CKMiKyO2R+VdB6wc/lWWVWq1JfJDw9oZlhaMpBZhXVDqR7uoMYdtR2pTNhB6d+kaTQtclvLSO5RREUDMwdocOl7iVMwrXCmKmUIyDqMa/VF3FFtK31fKlSYuvIhGDi1He0NNqlv2jiMsb2EPhrYLBHTyrmY0Px3i+ZmbYos1sFXLi7CliafZY/nZwxqPSc8xsZI42MFO9ZWA7yBKYE6UHphNnbxTbx5H33NrwHdRhOh0g+wpLJebbjyi1momlshADpfec+gAImcCnyaXhIX0Vpt73R1DmadH0xbi37iCEg73s9h6cul1RGeRhOzr+c8nhuFOUq4wodj9VLbTwwqm+bjd1jvshyo0++A0Nhjfj79phnnIJl0xsKU9QaN1eFlB6vPQRMyFswy6bWW4IW/yI2KL7693JFhRE=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.6
Release Details
UpdatedNov. 20, 2025, 12:48 p.m.
Changelog

Fixed

  • Preview Provider Registration: Fixed ArgumentCountError during app service registration
  • registerPreviewProvider() requires 2 arguments (MIME type and provider class)
  • Now registers ModelPreviewProvider for each supported MIME type individually
  • Resolves error: "Too few arguments to function registerPreviewProvider(), 1 passed and exactly 2 expected"
  • Migration Class Declaration: Fixed missing class declaration in migration file
  • Added class Version010902Date20251116061241 extends SimpleMigrationStep declaration
  • Resolves syntax error: "unexpected token \"public\", expecting end of file"
  • Folder Path Length: Removed the 512-character limit by hashing folder paths for indexing
  • Restored folder_path to TEXT and added a folder_path_hash column with a new migration
  • Existing rows are backfilled automatically so deep folder structures continue to work
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
Signature4F3B+MMtZoJiTGIBdBSaJDW9PVnv2o38ob0m+f5cIJmMM6jpgqYETLsQaW1zRCdQ8ozE8v5LfkehmhMlXy8folvlapuRcDGh9N7PPIRzTM/8b9ymOMQ1vkBPERw8k5grkUwFNamMPw+K4rFGHLMflN+vR/S6m0jmAKls/2L4kg2UdhaTdtaw/ozZAM4a09dJ038kyBS6jbh6g/M233Ue/R6aXSCMVgrA5zw38djqE9O8zmUg8xOJlOzdMRCRdhKWZOHoocLV9TBTasdU99YG7o+VIgAXeTY4X0rKxtOdfqdX+c+YNEt4syMmig/1p3e3yO1q0CmQPg6rgxtrdVOW1KK6Bbsvd8DkNwyQ0SgREq8bD+SIlF3QfqTDAFKCDgjTCn9N7HBnZIVa+NtseVrVfVeEdWdVNGMnfu9QhSeMqrE5dJMzKJLiPy4ftrmzM+aff+3aoQU69wWVffIBw1RsC3+352E90jiYw8CnH0ul8I6ffA+NVD4v8+Jo2MruxzwzTsq7/RfQMvIhsCTrhyauECtmwAQPEx9CX4h+7nryjxefgDwPQlFyszt6F53LSTWEeFO49SAlV9dH5P6tsjsMozdUts7HtG+UU+T7gHD65rY/nPL8ICF6C5YHGuuxwDFQGAkKtBNN/9VWBZr8h1X9jq1o57hwIqGBnxNdAs9YqdA=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.5
Release Details
UpdatedNov. 20, 2025, 10:08 a.m.
Changelog

Fixed

  • Preview Provider Registration: Fixed ArgumentCountError during app service registration
  • registerPreviewProvider() requires 2 arguments (MIME type and provider class)
  • Now registers ModelPreviewProvider for each supported MIME type individually
  • Resolves error: "Too few arguments to function registerPreviewProvider(), 1 passed and exactly 2 expected"
  • Migration Class Declaration: Fixed missing class declaration in migration file
  • Added class Version010902Date20251116061241 extends SimpleMigrationStep declaration
  • Resolves syntax error: "unexpected token \"public\", expecting end of file"
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignaturefF9sWdsS9s2UfdNuMWzSK76VLnucCn+KchXB9eFwbDsdXACnQYvhUVvS+xoMBYIfaXQEYUjfIl9oc0/sghPaIfdPvHwhCSze3XUPHkeF8yHb7eXQfHPr8N6KQZdmFM50brxxpHt5yxI40xZU+mMyW3eTP982e+aLenLEr2taQYNoaTHf35NbVknGLAE1xautWR1JQzYyVkCcc4T9/hxMp7LaGBrUPwdDALyuAp6WTHtZk+XeOxxxwRiNb7q7SpXWGuwdbX7MDvEzfBUmhw8dbORK3kqxgfXFAe7uGVdW+5sKtkdn+fxuN4gHKmBwW8N4X7YW1XaAL0KkYFoHsrdAcHunsSn/KfuqhTLHRpxOblgFPEcCwwqWcPVdGASFkD96rYylV9yzoJV2zS/pDqMVG38TQjHOs6ukBbJ5KHzpGJpgOZXDzLn24or5wVubjXkCyOsfS0by89VmrrxrERJZPNl6XTgeCZaBTPsypeWAlezfqVEjVVmdkoKuL+I3m/gMURucZV3Do+wHmxoEAT/2bTRVtIZzBsjrwuljZk4cok0oQ8reFBlngACWmXWskJOiEmshDUpnd2IykjhaU6LPEBDprd0fSM3+RE6Sx1+iJuPdXQ+CUATytcbKc8kiEjcPapzQ7xt3uR2fukG3eLrkFKoKHM7jJtWWMcWmN0yppuQ=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.4
Release Details
UpdatedNov. 20, 2025, 2:09 a.m.
Changelog

Fixed

  • Preview Provider Registration: Fixed ArgumentCountError during app service registration
  • registerPreviewProvider() requires 2 arguments (MIME type and provider class)
  • Now registers ModelPreviewProvider for each supported MIME type individually
  • Resolves error: "Too few arguments to function registerPreviewProvider(), 1 passed and exactly 2 expected"
  • Migration Class Declaration: Fixed missing class declaration in migration file
  • Added class Version010902Date20251116061241 extends SimpleMigrationStep declaration
  • Resolves syntax error: "unexpected token \"public\", expecting end of file"
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureYu4MvwQG1iiUU+ZnS3qdmTsCZ0NYAx89VzPzGTNqkdgQ/LolnwTZNDpkHEOoGQOM7Q95wtrJ1iHj2KQNxHsg/nw26/L0nqQtE8+HN92EVkjKhj4Chve7AB+A8dFlj0nXdSpgtH/PbwN+90lQTCGnmd6rRc46+OqEfEoFzjBhqtrpzXuURKsZG4GV644vSvAyzZFBDncgI7tlGhUhCDj/5UShHQy9ClymB6Yb5K7smP0BSDEWYOxsUOj2/cy7hAIlCyofINC8p6UzA6Po6NiyQefX2zds56a8TZhvvuaeiO3setCQzKXdYp3WqlnVVSpRA7UZfGeqdvkDqtQuTIs4Zo9w6GWX9M+N2Z15rQ59t/cNX0OYhCs+Fw2UdJMAPYW+me911YHsaMmANkaw7sUZ0ncqxbc0NZ8NULhJakF4DHizsCSLZbVrOhpfcaDEpsy6q88bg6o4modcj+gTIytUCI/RLjTlKWYAZcRFJfmPngQiuUmBeZntR2y1a0ROFsmcRAaSys5UFHF1KuqaNocqcAo+CbN5vRqMQXnmGSg54kEHvQ6xjDki/rs/0/5sxIX5TrGhGCyubdpN5Avv1y+eZfMdxVrZu0wxOubN3zgF47b/O5wql0Mv2tpFH88gy5XMGRTyaB1fIeFQXV874btSvkBwJPJhKdTZV0pyA9C+wUk=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.3
Release Details
UpdatedNov. 19, 2025, 5:36 p.m.
Changelog

Fixed

  • Preview Provider Registration: Fixed ArgumentCountError during app service registration
  • registerPreviewProvider() requires 2 arguments (MIME type and provider class)
  • Now registers ModelPreviewProvider for each supported MIME type individually
  • Resolves error: "Too few arguments to function registerPreviewProvider(), 1 passed and exactly 2 expected"
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureYmgaFcAnfaw/gFhMAFJupT22RE/RWydQkyTNQrbQNyHQGq406C58CN9hKEIJ5kaSzibif3goqa31T/si8GlYBnejJmQzYsQpr5Wua0dSrkUtCv0fRFv5GNWJvazyREN7XKWp+Ir/Q51J7trkGs5RCuZRnH1DhHTPyieLyZLTFsSWTSPuDRHEnpqr91B0y+epvQGujYSYG931+5tc6QaX1rfZ9kmT1qNph4SdaLeMa4hbiSFc7fuuSSNqvE8q1QPrBJEz5TMixrr1U8iMA38HBWVsufDfd+lg18bVWg3zQG1yFNZn/RYCuPck6DPiDo2uJ/9AJzOTQpJEFjDfc2zG77oE7EufwDtoaJzbhXhiseW7u0Ty6nVywrYTnEbfuIYhHeo6lbxY8KtoPLZSDSiSbH73oigsGW7o7xA+RDjtVZoWRguPZF9VfUjJ1v5WQpHD0jdZflYJ3byMygWF1z7GaT8wE9gbzwvWUyMGE6XCpzwpNxx3yOlq0mp5aUNFAjJYAO8BSgaFBxSBVnXTv22JEnhaUPAWL3HaMh3EJLVJla/TOG7cd7N9eS6JT3maO8Z7QUu32B/ah48w/uxk9qzmBX+t1onXwUA/6CuY8Gfhcg20AK5JuUiqhIZD1eW7HiC0pNJJqZbzLbXBl049JBFUqZbKLdf+ttISPjCmlRTnxdg=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.2
Release Details
UpdatedNov. 19, 2025, 5:32 p.m.
Changelog

Added

  • Database-Backed File Indexing: New tv_file_index database table for fast folder, type, date, and favorites navigation
  • Automatic indexing via filesystem event listeners (NodeCreated, NodeWritten, NodeDeleted)
  • Manual reindexing via php occ threedviewer:index-files [userId] command or /apps/threedviewer/api/files/index endpoint
  • Migration automatically creates the index table on upgrade
  • Smart File Browser: Complete file navigation system with multiple view modes
  • Viewer mode: Opens 3D viewer by default on app load
  • Folders mode: Hierarchical folder navigation with recursive folder structure
  • Type mode: Browse files grouped by extension (GLB, GLTF, OBJ, etc.)
  • Date mode: Browse files organized by year and month
  • Favorites mode: View all favorited 3D files using Nextcloud system tags
  • Breadcrumb navigation for easy navigation back through folder/type/date hierarchies
  • Consistent card-based UI for folders, types, dates, and files
  • Per-User Configuration: Remembers user preferences via ConfigController
  • Saves preferred sort mode (viewer/folders/type/date/favorites)
  • Remembers last opened file ID for session persistence
  • Mobile experience: automatically hides the circular 3D controller when the viewer detects a small/mobile viewport, preventing overlap with the canvas controls.

Changed

  • Viewer opens by default on app load; the file browser now appears only when a user explicitly selects a navigation mode.
  • GET /apps/threedviewer/api/files/list now serves hierarchical payloads from the database index (folders, types, dates, favorites) instead of scanning filesystem
  • Supports includeDependencies=1 parameter to return all files including textures and nested subfolders for multi-file model loading
  • Dramatically reduces filesystem scans and improves performance
  • Navigation data is loaded lazily per sort mode and cached so switching between viewer and browser modes no longer blocks on loading every file upfront.
  • File browser UI refinements:
  • File cards now share the same compact layout as folder cards (consistent padding, thumbnail sizing, fonts, and grid spacing).
  • Type view heading and breadcrumbs no longer show a leading dot (e.g. GLB instead of .GLB).
  • Breadcrumb component now handles clicks directly via NcBreadcrumb to improve reliability.
  • Remembered folder/type state is cleared when returning to the root via breadcrumbs to ensure a fresh reload.

Fixed

  • Newly uploaded, edited, or deleted 3D files (and favorites) appear instantly in every navigation mode because the indexing listener reacts to filesystem events instead of relying on manual rescans.
  • Root breadcrumb ("Home") navigation restores the folder list correctly, even after drilling into nested folders.
  • Multi-file dependency loading:
  • Backend listFiles now supports includeDependencies=1 to return every file (including textures) and nested subfolders.
  • The dependency crawler recursively searches texture subdirectories so 3DS/FBX models with textured assets load successfully.
  • Texture search now uses the updated backend response structure to avoid missing files and 404 fetches.

Technical

  • Created lib/Db/FileIndex.php and lib/Db/FileIndexMapper.php for database operations
  • Created lib/Service/FileIndexService.php for indexing logic
  • Created lib/Listener/FileIndexListener.php for automatic index updates
  • Created lib/Command/IndexFiles.php for manual reindexing command
  • Created lib/Controller/ConfigController.php for user preference storage
  • Created lib/Migration/Version010902Date20251116061241.php for database schema migration
  • Created src/components/FileNavigation.vue and src/components/FileBrowser.vue for new navigation UI
  • Updated lib/Controller/FileController.php with new listFiles() and indexFiles() endpoints
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
Signature5KdirqBqYm1NTouEBce9EtmTO6/UJwHsg40DC/oCvhIuYOF8eLVWy5O5Vwx25hFvq7bHrr9SQQ9cdJS1G+fY8aQ7bSeqCR1dAdUlsoBhrYWQnKAEnoG8vIIxfk0gA+HgcRGLJPtph9TYLdeAqdhD7/VVUg8l9ZdIVJHsTQn8JijVkTeMpk5612wUyoMn7HaA8IJJrOnU6dmkfv95FcZbVLzR6QRDc2fqlM3aYbZl9KOVYzEU6e736rsQAOVn0IqrHmQyJNVIdiFnycbtRiJnJgRJj05KblfVIOC0qZwzl7sqIHdAswvYwDmdCoLK/rblTc8R7INoUFpmGFBzPITfVwBNrJh9jsxxuWnl0X/vAAtVACVGHR1utLtd4dMFSjwOVxD3f53eazH9/Hho18BBh3GOLNJEWAGNal3u8Ng+inilqQu4Nmhds9AYUoq6T38oU9NABr7mDce1TsO0AYQqfez3HBodgbbBOoXKSGLMoDCk9T71NR2Oc2XC8Urz08F9Q/0Dcoy06kdvm9neAOH+yHqjcPXfI98JCdqao6Li05VQaLOUxIyYbVpngGu3LWthpaH7rlxhD5DlOwknjimFfGifjZ0/yScHSbfRqtgxy8q8jfHJ71wMKOAzQ6xCgqfuWWROUqWNmo4ypsE23Ioj1n/yEA60bComBBgSdSjCwpA=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.1
Release Details
UpdatedNov. 15, 2025, 9:35 a.m.
Changelog

Added

  • Preview Provider Implementation: Implemented Nextcloud IPreviewProvider interface for 3D model previews
  • Admins can enable/disable via enabledPreviewProviders config in config/config.php
  • Integrates with Nextcloud's native preview system
  • When enabled, provider is registered and ready for future preview rendering implementation
  • When disabled, Nextcloud automatically uses custom filetype SVG icons

Changed

  • Updated dependencies:
  • three: ^0.181.0 → ^0.181.1 (patch update)
  • @nextcloud/router: ^3.0.1 → ^3.1.0 (minor update)
  • vite: ^7.1.12 → ^7.2.2 (patch update)
  • @nextcloud/browserslist-config: ^3.1.1 → ^3.1.2 (patch update)
  • Improved duplicate registration prevention:
  • Added guards to prevent duplicate file action registration
  • Added guards to prevent duplicate viewer handler registration
  • Enhanced error handling with try-catch blocks

Removed

  • ThumbnailController: Removed custom thumbnail controller endpoint
  • Replaced by proper Nextcloud IPreviewProvider implementation
  • No longer needed as Nextcloud handles previews natively
  • Thumbnail Placeholder: Removed dependency on thumbnail-placeholder.png
  • Nextcloud automatically uses custom filetype icons when previews are disabled
  • Custom icons already registered via mimetypemapping.json
  • CSS Thumbnail Overrides: Removed CSS rules that forced app.svg background on thumbnails
  • Allows Nextcloud's preview system to work properly
  • Custom filetype icons display correctly when previews are unavailable

Fixed

  • Duplicate Registration Warnings: Fixed console warnings about duplicate settings/registrations
  • Added registration guards using window/globalThis flags
  • Improved handler registration checks
  • Better error handling for duplicate registrations

Technical

  • Created lib/Preview/ModelPreviewProvider.php implementing IPreviewProvider
  • Registered preview provider in Application.php bootstrap
  • Removed THUMBNAIL endpoint from constants and API documentation
  • Updated openapi.json with preview provider documentation
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureyK5Dmfw2bZsjqJMtY0eaIkST1jQZ4XKcPtlHp4f7GNHWV1A5PrKjkxKHO32JML49YXEI7D8PouQvnHXDq55pRDm/PBmXV3cB5wvx3ZkMVMGRQBqHNR2iBfSsl6w9I0SaGSgNSt/aa1kmZRCq20GPv8hLMHSJdcR2VpU5mA/BLp6vP51LBp9wDwzCEsU82zX6VVBXkd5YIHY+6HMRsNQNXFfRsWERTq5yjmTYfyK4Zq1rvZShPX3KG8WDWl6g3C1lJhyr/7FWLoM7Lsq6k1pirdAYUtQO7ooB0UDiTpvEgmCj/OLhL/8dvaD29dyzUxnokjj8IlpiDEcPfeLN34nqXHfMbmPZh9+aqBqsZr0GaqSD6dXGoplkBc+F/SHfWdevkZDHk8p/W0flcjIThr+K5/8YhwdDZd3G2JIRmhDdJXFfoTn2f+zYkHTV3enXsRAG95FVU3WE6zZwi8w4MOUiXIpxqb/DAISRSId3k24iPFlbguOQwPvcpMGNIruPRkoE7ihCgiU+dvcQ6ieYtwvtAHgNy+N284BdcsK7/0g5tCkzDad8Fdt4pMImPkO+cWBy3c19Uce5+pBx36Nts6q5so6O96s0Dcnf4NQPsnRFHNKduWxafeoBHCwn2NoH2aIRw0JQcwyCLvL2j8vLcN6PhAQwJ2I6P/4yHX5aEWEwaP8=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.0
Release Details
UpdatedNov. 10, 2025, 6:57 a.m.
Changelog

Added

  • 🖨️ Slicer Integration: Send 3D models directly to slicer applications for 3D printing
  • Support for PrusaSlicer, UltiMaker Cura, BambuStudio, OrcaSlicer, Simplify3D, and Eufy Studio
  • One-click export with URL scheme integration
  • Automatic STL conversion and temporary share link creation
  • Professional slicer logos with brand-matched colors
  • Last used slicer appears first for quick access
  • Smart detection of uninstalled slicers with user-friendly error messages
  • Auto-download fallback when slicer app is not registered
  • Temporary file cleanup after 2 minutes
  • Share links expire after 24 hours for security
  • SlicerController API: Backend controller for handling slicer exports
  • POST /api/slicer/temp - Upload STL and create temporary share link
  • GET /api/slicer/temp/{fileId} - Download temporary file
  • DELETE /api/slicer/temp/{fileId} - Delete temporary file and share
  • Automatic cleanup of old temporary files
  • Proper filename sanitization for paths and special characters
  • CORS headers for slicer application compatibility

Changed

  • Updated app version to 1.9.0
  • Enhanced toolbar with "Send to Slicer" button
  • Added slicer integration to slide-out tools panel
  • Improved error handling with toast notifications
  • Updated translations for all supported languages

Technical

  • Created appinfo/routes.php for route registration
  • Added @NoCSRFRequired annotations for API endpoints
  • Implemented Nextcloud native share system for temporary URLs
  • Fixed filename handling for files with paths and special characters
  • Added proper authentication and cleanup mechanisms
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
Signaturebdu+2mjB9NyEPJbbogKcFBovDi99alBx7ixiNLiVWRmMw63yphLItjrEkmMxHL5KeEmkQj05gqf17mPXlngrWI3pkhn1gLHtbCiPwOqloKdQ+bf0US34nClshbCzP0drRsNWSxhEWbd0a0vc1Zy31vk9I2PVHugbpbo4BCy20Ks6t0aCkv6o+g8x+v+B348txV1p1F5hyM+2BBUqxEB8fNiRJ/p6bd1eMf6lWfeqBrWG6n3zB11BsKKYAa941deyJ8vLlEpI8D7Kyz7TVHuHzx9hlxbZyOCYEnD52EmpYDl/VaKnj+9EzxaFDqkQPOIHPbMtfe9tc0nZOrqEASXrUC/iPMpp1JNAyRa0Egx+DkdRE/p6wFMBxipGqfgb7MJ6gV4I7t7ML1scquVtcc8aZt3oNhdMd6gPZ7/uxOYQ8Bm6YX6fiuwxtqe5yb2uwiw9oKjQhs3miEXEAiaiab3S4HLC6Ke9QYowEzASoAD1tHf+kf4I6+IszL5V6XOVzXRhKU8t/Vdl/JSZh3LEOma2KCPBoxIwove9PpHARcEIz6Tk4eu4UvMdTjhyIBKCvEnq8Bs5fzaq+jqSuE+8h3Y+qP0Q2fSqcNHpLtBEAfrkSu883dCM7dg0miDxSGumfqn+oJ80bVDGm8mQ3WdP7AvJiygdj5i2pFqyeiPE+MGDDUE=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.8.0
Release Details
UpdatedNov. 6, 2025, 2:21 a.m.
Changelog

Added

  • Screenshot Feature: Capture high-quality screenshots of 3D models directly from the viewer
  • PNG and JPEG format support with configurable quality
  • Automatic filename generation with timestamp
  • Accessible from toolbar and tools panel
  • Download screenshots directly to local device
  • Fixed WebGL renderer configuration to enable screenshot capture (preserveDrawingBuffer: true)
  • Billboard Text Labels: Annotation and measurement text now always faces the camera
  • Text remains readable from any viewing angle
  • No more reversed/mirrored text when viewing from behind
  • Smooth rotation as camera moves around the model
  • Improved user experience for annotations and measurements

Changed

  • Updated app version to 1.8.0
  • Enhanced info.xml with new feature descriptions
  • Updated English translations for screenshot and billboard features
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
Signaturebvx0cRDWADLGiuJ0jIg9f+81Add0o7SM3Dkq8foP/AnLfM2fSL1/ds6JsckXbP8xdOMoPyAxnN9XFi6qckR+cTiBSkkbpbQeg32ZDShLwwVRH8dubBAHkIk7qSBVjw4gV2BdKuMjWZZ5cRPlcFNUtdVP776NXH6Vv5FxK4UoudEN3VA8qDZC9+8fC46n7NhnobbviHIzeNqPA0V3Wo50UuuptyDdip0o/bbBiaw1vszWuV4QoHFMHAjFan2v3kKb5ptIHYukVOLMj8rY1dKeTACQYjEwi+YXOV+4eJMiMrHXx06eMYxiOsTdNHsCWTy9PW+4QTHM9dI/GNygSKC/V4Z9lxlPt7jncHOAT5P+tEFrWQYImvBtWsXPXoP6UPAIpP82NPWhp0lBZdjR3Fvx4yi0PM7V4/lRTztUkTrobnlVNpIxSe6SH0jWmVlyAFAW0XSiWrWbM+Q0gNEERVNudpCw7y41xv2Q45ZgPIMhGzjn7CbY8gVacSrXcsnglD8pcFAnI7hh+KfepgSSeJg1ZV7IF5UM9Qr9Cu7VDtq8Lc5bw3tqXNDf4U7T5UgnAjbA/GFXY2fz6yT5TVXWoNxER4d3Bocb73r5wWYlag6z2CKOxTOWenRUnrG0iFPi95MxaykgJMVTAilRLoHOOGZie9DHpOUwcvXWAokeDaXGBSQ=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.7.13
Release Details
UpdatedNov. 5, 2025, 4:44 p.m.
Changelog

Fixed

  • CSP Conflicts: Removed global CSP listener that was breaking other Nextcloud apps (Memories, etc.)
  • File Icons: Fixed custom file type icons not displaying by copying them to correct location
  • App Compatibility: CSP modifications now only apply to 3D viewer routes, allowing other apps to function normally

Changed

  • CSP headers now scoped to specific 3D viewer routes instead of globally
  • Added automatic icon copying during build process (scripts/copy-icons.mjs)
  • Removed lib/Listener/CspListener.php (no longer needed)
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureqfnNbykFms5wS6aOa/TKBYua37o3OqBNqe9LY0dU86/MrGrqbv+v9inkFm63UQyR19ux9ACVlqG6J5rCDpLLTYAe1IkFGZMKfJzNnna8uiA734PltS8gNSv8ol0zMsRs6tvanPlDxVedCmzp31VsErPKOShjvTRbhf9ZmgJjZccX3UODdfIzZxJLqHd3vBrYqoksFXDZnzUqEkb5OK7RwfxAs71IGoVjXHOf9HuOVuefc1mhElbIygGnPYJ3ewlU72SD6gB9/kYgmZEb9xklvcTz6IjTbfKdZ7fLb640/71wCIa5mYleBkaxsoAzfGo2QjC6GHNkAQX7gAXeZp1GYBixwIF4JvawV2s1pKnIDZE3hkLqhx+e4OOYvawhlVoUdILsXSC2oiG4Q5qF/tSz6fh/2gFY+/2fxJMSwwbPXTkUPA5eXKCTpRIbWdIK61XEMKenSlWFF0giXWcOMkxXH4/T1NFlV7/g57MPogu+DD41Y2LNkdZQVaVYWEyvTw3t0pVvgohGNPRSNKV8qR8yzSM5yVe0Ck6SWOk+74SWwBoItjp66LwNQ60JK2Od2+NOSE3+2eG1SkIKL4+q0Uo4NGQgyxblPWIXJZTl14XcaxyXCJr/K913khhw+b+DumTz6TTGg6jMR8oXRFawccmEHL/DN55Y3HfRAwVj/cNIx7I=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.7.12
Release Details
UpdatedNov. 4, 2025, 4:14 p.m.
Changelog

Fixed

  • Viewer Integration: Fixed files() method not storing files list, causing "No files provided, skipping update" error
  • File Loading: Fixed TypeError: Cannot read properties of undefined (reading 'filename') when opening 3D files
  • Static Assets: Fixed 500 error when loading app-color.svg due to route conflicts
  • Route Structure: Changed viewer route from /{fileId} to /f/{fileId} to prevent conflicts with static assets
  • Axes Positioning: Axes helper now positioned at bottom center of models, aligned with grid
  • Axes Scaling: Made axes size dynamic (25% of model's largest dimension, minimum 5 units)
  • Logo Loading: Fixed app logo path in demo scene to use generateUrl() for correct URL resolution

Changed

  • Enhanced files() method in ViewerComponent with fallback logic to create synthetic file from props
  • Simplified PageController by removing unnecessary is_numeric() checks
  • Updated URL structure for better RESTful design: /apps/threedviewer/f/{fileId}
  • Axes now recreate on model load to ensure proper sizing and positioning
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignaturetHcAULDv6Z6JlPEmMcFbBFAPFTScfSULZoxHuFuCtCO965w5/TPzwTm9AAbrvWQlTzOza8VK9le5cP96O8XKoLPU/rUTY0YPL+11rga9rU5c9nNcCiRTKwaha9wnos5/fDxZOhefb9aFojmpf7HsrSmHL+JMrLwaVvp846k4ShSPNbV7cVTqsrwz1C4Vy4JRzGMuSfcAMjxLBC02obtPqVYX4T5s7/QCithiTGI1VmmtMxZM0sG3fkIRf9ouPQ44hpHX7beIm4vBGthPwjhlNpR+aXq9rQd4annpZKtZGfGRX/RDXlFXUWBE/07A+/CBzP9DX9pegUvzvrelj67ADuiRDfxsL3vKN1VGU1rqHi1ZrwE24BzfeGnWgUb+wEBOcM8x8BEc0thH2zbfKAwqjY1h/iH8IjoIkbPPm3mKwQ2b5w2v2aaRRr3qbK3cOLhyzWJBpQFZaahomr9x+/hN5aU9fhr9hMjgPboRadI7rO+V6QtQDobhKlz+6Rdb1mo+Bzk9btyCJ7flqqos07yo/O01o4G/0L0hdw20vYh3WlbeGRWC6W/OBzQmRwT4MWFoHV2mQOYO4Nie4SkFCzs2lT3NWW7I/uCrCPMZDJrLhSk1KiKzctZXjTUalB4DuPHSpq99WjCcf2oPLo6rQ7DJd/sIRSh3tSj8WIlxcWCrSWk=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.7.11
Release Details
UpdatedNov. 4, 2025, 10:58 a.m.
Changelog

Fixed

  • Viewer Integration: Fixed files() method not storing files list, causing "No files provided, skipping update" error
  • File Loading: Fixed TypeError: Cannot read properties of undefined (reading 'filename') when opening 3D files
  • Static Assets: Fixed 500 error when loading app-color.svg due to route conflicts
  • Route Structure: Changed viewer route from /{fileId} to /f/{fileId} to prevent conflicts with static assets

Changed

  • Enhanced files() method in ViewerComponent with fallback logic to create synthetic file from props
  • Simplified PageController by removing unnecessary is_numeric() checks
  • Updated URL structure for better RESTful design: /apps/threedviewer/f/{fileId}
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignaturehK5rTudkrE4neZOI/n/jv+qjY/VfKVkRkouiBK5jBARxwK9e0W8U07ajlvP2+U8q8qwNzjGY77RproUnQIkOlALx3c6V9ufsMaHcpuAR2GAvK84WgqqEM37VSPQrGhLLuZzz4nU5nYmNOsTg+maV0O5XEND29zOdafsJHxpY8mQofXCA0vyLYNLYQtLEAPRBtl3uDQgSSjPGB6kN87VUcqebvVrVim8aa8l7BpDoMiW5j60T7toenQiisu6S4aKMRHCxx7I1cHK/mkGjLzl+/AHpfwWpKCr13StVLzqqlVPc5+SL/yI14XW2JtJARHShE0zBqkARG0yqsFXVTGvLzvAahLuCfIdlied8HFK/NQVmqgLlRAc30xWGq2vcQvpnr9L7GwCkImnM5YeoTqVOJHawhc3wU8FQ56g/imCYgMqwSOegC1BVegdX/XvCMCxhQXEj4OxUxETQ/T1+BWqBBLLbZQQiyyRXw6o/bzpBWJYtDH/XIzFKxJdC7WKfIM6lPmPb7CCc6sJGfEi/Lyv3rTfCjyQj7ioMlB+5sLV5/d+tth6eeY9O6jZsz92/V5byhrtIdYvu4j7IZR2m8+/IpkjmTMnuv18wyU6+unVo8V2hKNLhoWYHJqEQ9Ylx/Rj6tKb4TwsrciMPV+2T38lJK5cS0GZittMNUVAKSUPBSnQ=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.7.10
Release Details
UpdatedNov. 4, 2025, 9:48 a.m.
Changelog

Fixed

  • Dark Theme Support: Fixed slide-out toolbar panel not responding to theme changes
  • Theme Switching: Implemented reactive theme binding using Vue computed properties
  • CSS Integration: Converted base styles to use Nextcloud CSS variables for better theme integration
  • UI Consistency: Toolbar panel now properly switches between Light, Dark, and Auto themes

Changed

  • Improved maintainability by using Nextcloud's standard color system throughout the toolbar
  • Enhanced theme responsiveness with component-level class binding
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureT38bK6V5aDGCGlNZJEV3QCmwYaO21RK3QtifSTQ3O311NOPA+O7ryIjncKIdr/rdN/9ZjeFLqwcxRk2traF5MkhvjRCr3NT5oV5cuMQgmw2Js7MAOLrSXOUkn6b7LpQKesEmzQPqygl2fuqN5qrxILxeWU5xWq3nyoV+G2TzByeLOT9CX8+EH1rzMnJNb/35aFS0kj/fU4V0FHFM3h8KxNDWYVjlJ/tPtq5IFBvICRm6HLCkQ2fEPPXkxP2Z1lpBam6ZGuSbcmo2lb5yQ7Zq3n6rd7FIzkU6r0/xvYF5gY08bwIdtULEpJOEQwp/n9KBR2itV4twQG2QAZFEIMF+EIg4lRzu0vdX8GVDFbirW8YqCX8PXyd+UAm1FfZ4vf8VHQXF7weZgAnvm3crR01GNStlBHl37Zke3z8CHmiYj3ffi4WMwGBT4Gb8f6fxlCOHH/mOlCyA3rtVlI5cHqJGHbdiwgHYX6e+0p5JRWOlecK/HTcVd0Aa5KX57BTcRQXEhGaQqHIbRhWTWwDMesbAyJMtCT72O2eRUqJCnSI+SRSxl/Hh4lHUEnOPx9D2P/03xDEDpO3xoR7tQGN927un6811AS+v+kABFDJQcayHiFTpR28U+WzF1vqS2fktc90NaWwiJuO1/hnQ/H8J6icAF4oxmvArZI2uO1X3CPZMwN8=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.7.9
Release Details
UpdatedNov. 4, 2025, 8:39 a.m.
Changelog

Added

  • 3D Camera Controller: New circular controller interface for intuitive 3D model navigation
  • Camera Control Methods: Advanced camera manipulation including rotation, zoom, and directional nudging
  • View Snapping: Animated camera transitions to predefined views (Front, Back, Left, Right, Top, Bottom)
  • Controller Persistence: Save and restore controller position and visibility preferences
  • Smooth Animations: Eased camera transitions with customizable duration and easing functions
  • Face Labels: Orientation markers (TOP, BOTTOM, FRONT, BACK, LEFT, RIGHT) on model faces
  • Export Functionality: Export models to GLB, STL, and OBJ formats
  • Camera Projection Toggle: Switch between perspective and orthographic views
  • Progressive Texture Loading: Background texture loading for improved performance
  • Dependency Caching: IndexedDB caching system for faster multi-file model loading
  • Model Statistics Panel: Detailed information about loaded models
  • Help Panel: Comprehensive in-app documentation and controls guide
  • Theme Customization: Enhanced theme switching with RTL support
  • Performance Overlay: Visual performance stats display with real-time monitoring
  • KTX2 Texture Support: GPU texture compression for better performance
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureT4jr3f8pu++HPy93L1HdiayTsqKV8PwgIw7jkye4TkqYM7wBuBsK6qv/TXwuZElOm9hzBEVH/MnuFoRl2QXPxurhZLvu918h0rDnTIjfRNMC2gIVFI8JLneLq8ya+m9lKGNLXEodRAhQ3pGn97cuSFzff+iGhQOFkojIvbWM4HbSQFq6pfF3/ZYjUCt5BhRIHdPkk+mzwjpVaniq98gh4XS3AMYqs4p2n7vysSGjAO8hZrDdGUJGxBlz1amgeUpdiGOpTwI4FyT2vbxcmHcMVwZTQyXoYZ/Ux70JZp98nz1H1kKqIoDxzZSRmetrm23Pzn+k440rHQUSjuIa/p6I6w8nGG25M0kjB46lacCtbUlR6Rrrj6SNwFITde5Rr87HP2R/ILqI5MCC73SebBxcdY/IXw7xHjUiBJTlrOmPi1ppktirZnOsmSR2Sa/yE81zrYWJ2HidTbxEGpJDZBIiwOaBCYh6nwQ51PG1z4mxgJE4G+7lMZ/bpu5UaJihys2WcoBhPxrGNeoLoEN+D1JiaOU1C974Wwncz1/BobA08FSx+rzXCnRNSQWbBapz3J6MYT5TwChku40FeqGR2KJm+v2pYgm8K/Eepieubi61tD9St1exw3AjBiJ2/dKOezNb8ZHFcoWn2bxCZc4rzuBUO0tJSrjmbW5dcysusajrvMs=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32

Nextcloud 30

3D Viewer 2.3.4
Release Details
UpdatedJan. 18, 2026, 6:57 a.m.
Changelog

Changed

  • Dependencies: Updated development dependencies
  • @babel/core: ^7.28.5 → ^7.28.6
  • @babel/preset-env: ^7.28.5 → ^7.28.6
  • postcss-html: ^1.7.0 → ^1.8.1
  • vite: ^7.2.7 → ^7.3.1

Fixed

  • Nextcloud Subfolder Compatibility (#74)
  • Fixed app not working when Nextcloud is installed in a subfolder (e.g., https://example.com/nextcloud/)
  • Replaced all hardcoded /apps/threedviewer/... paths with Nextcloud's generateUrl() and imagePath() functions
  • API endpoints, decoder paths, and static assets now correctly respect the configured webroot
  • Affected files: multiFileHelpers.js, useModelLoading.js, useComparison.js, gltf.js, ViewerComponent.vue, SlicerModal.vue, App.vue, viewer-config.js
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
Signaturem8HTfU5qBOyGRmdHu4hylXbuVzwpcofBxDmpgWjNf0qvBkujJC75qp0z1GcJKDRppDXuE5z70L6g5AAUda+v3Z5y9byJqnisxNVRZM0nbXwYgOmqi8MdBnP7bzd5Ms43jDwr8hKt5ffEKR+g6h7Um8q5BDl3Vdk2J8nVuk+uvduDXalukp+USx3ibBHjg3MDSJqdkTKkHPe41SXEpjyor9VMKLer8r7HxHcwlELGseyuFHgL/PPYQOT5GQf6KO7ae0s2lYH6tbBu3ZnP/f0tg4cYZAHAycm4fvAwRj44XMh6a3OFP0FdQOkpSmYa7Tp5IH5rj4zBjrazGCxtUU40q3bBmYRvIKiv/je83LfQA5n8FCgmjREez0JslPFBByM//FtrcFgsm1mrzSgkufLTdvQ8JYb1XbV6xI7jKWSYKdCidwpvHCWAUqvQDWRVL2cZ7tLyGwSVHtLEsftO3Ykhu7WYpyQmNIG2s6zTuBC9x52IL7hxU9+7127R5L7S2AdPxvUB5Xrz5PJbfKal41mSi5GTJ1s1d+ow6lyB/rU1yGMX12Y0gDTZjXLHvCMq6Ixtcy1igH1nd/C8P+j1vDHbDPyZnIKtx9yBTMsejnv9tdsPpE4ya+eM54l1i+gZEdM8NhFxows/bBHJaljU6DBRvtdYBriWsMHsrsDB2wSuTMA=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 2.3.3
Release Details
UpdatedJan. 16, 2026, 2:42 a.m.
Changelog

Added

  • Automatic Thumbnail Generation: 3D model thumbnails are now automatically generated when viewing files
  • Thumbnails are captured with smart cropping to focus on model content
  • Grid and axes are hidden during capture for clean previews
  • Thumbnails stored in Nextcloud app data (not in user files) to avoid cluttering recent files
  • User setting to enable/disable thumbnail generation in Personal Settings → 3D Viewer → Thumbnails
  • "Clear thumbnails" button in settings to delete all stored thumbnails
  • Works in both standalone viewer and Nextcloud Files integration modal
  • Thumbnail Settings: New Thumbnails section in Personal Settings
  • Toggle to enable/disable automatic thumbnail generation
  • Clear thumbnails button with confirmation dialog and count of deleted files

Changed

  • Thumbnails are now stored in Nextcloud's internal app data folder instead of user folder
  • Prevents thumbnails from appearing in "Recommended files" and recent files lists
  • Improved privacy and cleaner user file space

Technical

  • New ThumbnailService using IAppData for app-internal storage
  • New ThumbnailController with endpoints for storing and clearing thumbnails
  • useThumbnailCapture composable with smart content-aware cropping
  • Thumbnail capture integrated into both ThreeViewer.vue and ViewerComponent.vue
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureuFzoE7HPsOrBKlyKjSzOuEeHjB3dAL7I/y0IF+GNXsgneUJobVLzw+kWlOtZyGa4wNcavAH3caVRlqPjMdw/ZlrlgkJN62qghl/yvbskmmSsiC43ntcKMfGd8Gat1wCXPzTGipRc4DqwbpUyN3PIVltZgpSvX+xaTB3+bLwPNIg2vX2GMpalC9vN2eGa60fPm//OXZKujqfRVwGqg36OpfuRKgOr+J2xDyxAsyc6UywFRGHUnpGLiZgp0jXIRshqpM+k3fpbZDB1JrDbYlPaAZwa4Ze//xxv4Xbk4KmmlLY0S6GXChNbX0rAYrwv+PxJxFeLSI5ytw9iZPdDFQFmgm5RJv7XVhmc31ccZyJ8eaTRz2+JfqBRV5csX5Ox9QIVjmkL3WX70eNIcRUBGX4BFOcCqZxnRgg3moqoSKAZFQ3sOMxwStiKlHhrffZvclDLZRL3S76C492BVlF9HFZc5KYnuF17VQPs1OL8xWFcW57HfcjpMs6xydfnMtfTJUTWbS9p6fjaxLjUgl93ZqWTMmc8dpXl7ywiLjVViTNk8PNn3NzHP3H5yszzBxcO6elz7cIQgXRKdVKB8OQoaeMEjxQQfmWAIViZyXoEEhS76bsI1oeuqAiNH/9p+ytUkBeN7FK6yljt/8QauU38PLTih0QE2xCLB6fP1EMAtLAb7PY=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 2.3.2
Release Details
UpdatedJan. 7, 2026, 4:17 a.m.
Changelog

Changed

  • Dependencies: Updated development dependencies
  • stylelint-scss: ^6.13.0 → ^6.14.0 (dev)
    • Enhanced dollar-variable-no-missing-interpolation to flag namespaced variables in custom properties
    • Extended function-disallowed-list to detect disallowed functions within @return expressions
    • Fixed false positives in dollar-variable-no-missing-interpolation when variables already exist inside interpolation
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureYV9kZk3oeyVbeTn1qLIVLgb5ERRXgsTQamJCdPTLt4vgt7xf3ShcXd6Srry0UKHzEGvXqQjVq3sfxtq5INZNKQugyC67dlmP+WfFbq7nsLoGJp4Cpjza5ud+4ozbxgbVqNFhNoFVz/zYGyc1lAcSUP8zC10x6zfq/0WoRUFgWHOKCuK6ZB4vQd5J7JRX7JKX1sxbl+rGHSqbQeWuyJwlCir+zr5Y+746EJ+2S29f8z3KFxf2PfEZwAmE1Nf05FAVL5RhQhlDjqM7J2NvQEP6Pod8b6Q+RxFKMWkYyTHncCfQTNz+3VYeuJsqfYC6ZVADYOT5duvHbqOIW4sdnrotXWQDq0uxww7qKYISKp4srSKBwiN1k6EIGt2Clr5FOlji80tIlOtzqanLWQlhpV3wuiVSA8TTbfxPVlB4Mn7dGu/LHc5TjfQ5JEct+5nfEwSCdnLbnEhLyiNRFPppmpIjfHhSWhVrHpz/YRdSarEsmNeP31dSoJKbhNtqhi1oIbtyXG5ElYrTFFg+nxz/yc3Ok33KY+D1nJ9gIN+Qdde9E86qg0cXeIgq+CtM0TGomTKPt9BXQfresW9zuzKli1p7xS3d0C21acP8r6humszQcZQNliz936kTkULULFo86VkyYmK79Gmm16tcMDXbXiZcvhwqF/xrXS6QuQb44K9hC2s=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 2.3.1
Release Details
UpdatedJan. 7, 2026, 3:03 a.m.
Changelog

Fixed

  • "Send to Slicer" Button Always Disabled
  • Fixed missing modelLoaded prop binding in SlideOutToolPanel component
  • Button now correctly enables when a model is loaded
  • Affects STL and all other 3D model formats

  • CRITICAL: Cron Job Fatal Error (#65)

  • Fixed foreach() argument must be of type array|object, null given error in CleanupTempFiles cron job
  • Removed incorrect foreach wrapper around callForAllUsers() method

  • CRITICAL: Missing Exception Method

  • Added missing getExtension() method to UnsupportedFileTypeException class
  • Fixed fatal error when attempting to access extension information from unsupported file type exceptions
  • Updated all exception throw sites to include extension parameter

  • CRITICAL: Insecure Rate Limiting

  • Replaced insecure session-based rate limiting with distributed cache implementation
  • Uses ICacheFactory for thread-safe, multi-server compatible rate limiting
  • Prevents rate limit bypass by session clearing
  • Improved scalability for large installations

  • HIGH: IP Address Spoofing Vulnerability

  • Replaced custom IP detection with Nextcloud's secure $request->getRemoteAddress() method
  • Prevents IP spoofing via forged X-Forwarded-For headers
  • Properly respects trusted proxy configuration

  • HIGH: Path Traversal Vulnerability

  • Fixed path traversal vulnerability in temp folder verification (SlicerController)
  • Replaced insecure strpos() checks with proper str_starts_with() path validation
  • Prevents unauthorized file access via path traversal attacks

  • MEDIUM: HTTP Header Injection

  • Fixed potential header injection in Content-Disposition header (PublicFileController)
  • Replaced addslashes() with proper RFC 2231 encoding using rawurlencode()
  • Prevents header injection via malicious filenames

Improved

  • Temp File Cleanup Enhancements
  • Added comprehensive logging for NotFoundException cases
  • Implemented cleanup statistics tracking (files deleted, shares deleted, users processed, errors)
  • Improved share deletion error handling with separate method and individual error logging
  • Added file type validation to skip directories during cleanup
  • Added progress logging every 100 users for large instances
  • Added stack traces to error logs for better debugging
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureMK0+lREma3H+5o5HY/1XiCvaVsxjUPM6tcB151nPTrwJOeBdbFF50jwp8N7+xgyKEF8GZEOYpwqBu2jYjlN8bJBJFDUI4Givl++H6HAT0/yOhq22oItRC9eOdmrdLiduHqSm10UDj37gda6vOjZwGiPKG6OcmqTkAB5z6tCSX9xH4RznZwbWIpCKBKfUDv53iCyBiogCX3Zyz7443IEdkBy51an9N64COoiWJACcw1kse1f2JtS5ptYTXBA1ImMNOVkX+I2n+b4qp9n972UGMXyx8JnhH7nuVp4XH7nY2oargPPk4b+p1Yqq5/bJGsdazm+i8PaYcJ6UHJTySjTOIvh6MuWpA+xuXTWSgM9k1DUTFG2YQ1RS/JJsFQ4Xhm9GffxDOQ8mSMRp3MnEdMd8FgIU+REqQP3MAYvxQ/c11RWoaolM+VbWrKNGJqB2U2pliu4oM7DRlZg4GmgHvYUMUQQYTq+L1lZlvyQp+NweTuvaUcx6cY5z3SdiRb75o3fYhgNGPDg6ZgsV45Oy6srZofHfGiuYy+c/AkL9Nr8c0nBlZWtxV/OVdPsbHHmNhSVAmv2baFug1mGUcGYRApCmWLlpJbskW3ZNeFfsHp/d/st0LPjhK6ItDHe+6khDFAYoqQWFA2z2nmrWZuD/FzB2Ny3TVCZBQkpzDc7hJiBBxGY=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 2.3.0
Release Details
UpdatedDec. 28, 2025, 1:15 p.m.
Changelog

Added

  • G-code Visualization Enhancements
  • Smooth rainbow spectrum gradient coloring across entire model
  • Intelligent filtering of travel moves, retractions, and parking movements
  • Skip movements exceeding 50mm in XY plane to remove edge artifacts
  • Fixed vertex color handling for proper gradient display when toggling modes

  • Mobile View Optimizations

  • Responsive MinimalTopBar with all icons visible on small screens
  • Help panel displays full-screen with sticky header on mobile
  • Smooth scrolling support for iOS devices
  • Performance stats overlay hidden by default on mobile and screens ≤768px

  • G-code Toolpath Visualization: Added support for G-code files used in 3D printing and CNC machining

  • New G-code parser supporting G0/G1 movement commands
  • Automatic layer detection based on Z-height changes
  • Color-coded visualization with different colors per layer using HSL gradient
  • Support for multiple file extensions: .gcode, .gco, .nc, .acode (AnkerMake)
  • MIME type registration: text/x-gcode
  • Custom file type icon for G-code files
  • Toolpath rendered as 3D line segments with configurable transparency

  • Extended G-code Ecosystem Support

  • Additional extensions recognized and routed to the G-code loader: .g, .gx (FlashForge), .g3drem (Dremel), .makerbot, .thing
  • MIME mappings added for container variants: application/x-gcode for .gx, .g3drem, .makerbot, .thing
  • Viewer “By Type” browser now lists these extensions via SUPPORTED_FORMATS config

Changed

  • Backend Listing Filters: Updated FileController filters to include G‑code-related extensions in Folders, Type, and Date views so these files surface across all navigation modes
  • Applies to folder-scoped listing, type grouping, date grouping, nested folder inclusion checks, and descendant checks
  • Slicer Handoff Options: Simplified send-to-slicer flow by letting users pick passthrough extensions; all other formats now auto-convert to STL by default (export-format selector removed)
  • G-code Visualization Default: Default toolpath color mode is now gradient instead of single-color orange for clearer multi-layer contrast

Dependencies

  • Updated @nextcloud/dialogs from 7.1.0 to 7.2.0
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignaturePzIAblqli6tJofqSxWWKOwCp0h/EaSHMlT/+yyoqArTsvBAPzn8xLqU4/58/5pja+YAA7WeQ9egTPUicOilrSFBSHQVGa2QSLQVWFu+vTXKGEuu90qNxXnNqDnl66TVKuWR0OiXHeR2nCAdu3jh7310h8afbBLR3eQAXIeuWlLtXnbzVLoaiqy4pK9l2FzN8GpQoU4/7fo7SH1CFE6iR+Yea4Y2P6C1UXGQfG/RnJylCj1UT+2UkkLUAopk9AOxMEgQpwQzUV5kl4FwvND4biwcuXEajDXwVizX9qAEDtOkzILdV46RcWkyHxnDcqIGHuRImgfqWlwwz6fZ14Huf7/5bmvNafPuSPPRJHEWvH66whuXS5sft+Crvd1/AR+sF2bDGtGtoQo2iSRSCmVS8XtsK0+dW+DLGIvd7pQsul/AIWPDYYkPtMCgAXCFLJpFmmOhNNoCOshjRSgJ5LrnfBC3kbF66gBZGhlkBc0n9MDkqlgxDNVNGwYHYG6xllH4u+1xdGIilc7TE2EXSmpD3GEJOCTLiRdMDbL2ZSC04fd9Lf5YbVgKMggroGFNbtl9VszrOD8GtgpyUqdQnZ9D2U9ef8sJqRxzWKNT3Sr3A2PxgKiCf8G0yu0016JlmwHeEJQAWs9u+0ZpnYo51eSGQKnKtonW1avH6I95Mqh6cPbA=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 2.2.0
Release Details
UpdatedDec. 17, 2025, 6:10 p.m.
Changelog

Added

  • Measurement & Annotation Visual Sizing Controls: Added per-user sliders to control measurement and annotation visuals
  • New Personal Settings section for adjusting measurement point size, line thickness, and label width
  • New Personal Settings sliders for annotation point size and label width
  • Settings are stored per user via SettingsController and merged into VIEWER_CONFIG.visualSizing
  • Measurement and annotation composables (useMeasurement.js, useAnnotation.js) now derive sizes from configurable percentages of the model size
  • Animation Controls in UI: Added animation play/pause controls to viewer interface
  • Animation play/pause button in MinimalTopBar component
  • Animation controls section in SlideOutToolPanel with play/pause and loop toggle
  • Animation state props passed through App.vue to child components
  • Integration of useAnimation composable in ThreeViewer component
  • Improved directory path extraction for multi-file model loading
  • Dependency Cache Insights: Added live cache statistics (size, entries, hit rate) to the viewer and slide-out tools
  • Viewer performance panel now shows cache size and hit rate
  • Slide-out tools panel displays cache stats and clear-cache control with status
  • Cache stats refresh automatically during use and after model loads or cache clears
  • Cache hit/miss tracking with reset when clearing the cache
  • Performance Scaling for Large Models: Automatic performance mode suggestions and easy mode switching
  • Configurable triangle count thresholds (warn: 500K, strong: 1M faces) for detecting heavy models
  • Automatic toast notification suggesting performance mode for models exceeding thresholds
  • Clickable performance mode label in stats overlay to cycle through modes (Auto → Low → Balanced → High → Ultra)
  • ViewerToolbar performance button now cycles through modes instead of toggling stats
  • Performance mode changes apply immediately with visual feedback
  • Slicer Temp File Security Hardening: Enhanced security for temporary file uploads
  • File size validation: 50MB per file limit, 200MB rolling folder cap
  • MIME type validation for STL files with header checking
  • Rolling 24-hour expiration enforced on file access
  • Increased cleanup frequency from 24h to 6h for faster expiry enforcement
  • Comprehensive audit logging for creation, access, and deletion events
  • Security posture documented in TECHNICAL.md
  • Automated Bundle Budget Enforcement: Enhanced bundle size checking with historical tracking
  • Comprehensive budget thresholds for all major bundles (main, loaders, app, three-core, index, nc-select)
  • Historical size trend tracking in bundle-sizes.json (last 50 builds)
  • CI workflow uploads bundle size history as artifact (90-day retention)
  • Size trend comparison shows changes vs previous build
  • Improved error reporting with formatted bytes and clear failure messages
  • Fails CI builds when budgets are exceeded (with environment variable overrides)
  • Vue 3 Migration Pre-Work: Eliminated Vue 3 incompatible patterns to prepare for future migration
  • Replaced deprecated lifecycle hooks (beforeDestroybeforeUnmount in ViewerToolbar, ToastContainer, ViewerComponent, viewer-api.js)
  • Added explicit emits declarations to all components (ViewerToolbar, ToastContainer, ViewerComponent, ViewerModal, FileNavigation, FileBrowser)
  • Verified no implicit $listeners usage (removed in Vue 3)
  • Added comprehensive migration notes to COMPOSABLES_API.md with dependency compatibility matrix
  • Audited dependencies: vue 2.7 → 3.x (API compatible), @nextcloud/vue 8.x → 9.x (requires Nextcloud 30+)

Changed

  • Cache Statistics Updates: Improved cache stats refresh frequency from 5 seconds to 2 seconds for more responsive UI
  • Performance Mode Controls: Enhanced performance mode switching with clickable controls
  • Performance mode label in stats overlay is now clickable to cycle modes
  • ViewerToolbar performance button cycles modes (preserves MinimalTopBar toggle behavior)
  • All mode changes apply immediately with proper event propagation
  • Dependencies: Updated core runtime and build tooling
  • three: ^0.181.2 → ^0.182.0 (patch update)
  • vite: ^7.2.6 → ^7.2.7 (dev, patch update)
  • Security Workflow: Updated GitHub Actions CodeQL workflow to use github/codeql-action v4 in preparation for the v3 deprecation in December 2026

Fixed

  • Toast Event Handling: Fixed missing push-toast event handler in App.vue preventing performance suggestion toasts from displaying
  • ViewerModal Performance Mode: Fixed performance mode cycling in ViewerModal component by adding proper prop passing and event handling
  • Model Comparison Positioning: Fixed comparison model positioning issues where the second model's position was immutable
  • Wrapped comparison model in a Group to neutralize baked position offset from loading
  • Fixed parent-child relationship handling by using toRaw() to get actual Three.js objects instead of Vue proxies
  • Ensured matrixAutoUpdate is enabled for wrapper and all children for proper render loop updates
  • Fixed matrix validation order: validate parent matrices before child objects to prevent "Cannot read properties of undefined" errors
  • Improved scene hierarchy validation to include all objects (grid, axes, lights) not just models
  • Fixed matrix update sequence: call updateMatrix() on all objects before updateMatrixWorld() to ensure proper transformations
  • Comparison models now position correctly side-by-side with proper spacing and alignment
  • CSP Compliance for Texture Loading: Fixed Content Security Policy violations when loading GLB/GLTF models with embedded textures in Nextcloud modal viewer
  • Patched Image.prototype.src setter to automatically convert blob URLs to data URIs for texture loading
  • Patched URL.createObjectURL to track blob-to-URL mappings for later conversion
  • Patched fetch() and XMLHttpRequest to intercept blob URLs and convert them to data URIs
  • Patched THREE.FileLoader to handle blob URL conversion for texture resources
  • Automatic detection of modal viewer context (iframe or Nextcloud viewer) to apply CSP workarounds only when needed
  • All patches are automatically restored after model loading completes
  • CSP Compliance for Buffer Loading: Fixed CSP violations when loading GLTF files with external .bin buffer files
  • Updated setupResourceManager to use data URIs for buffers in modal context (instead of blob URLs)
  • Patched fetch() to intercept data URI requests and decode them manually, bypassing CSP restrictions
  • Supports both base64 and URL-encoded data URIs for maximum compatibility
  • Animation Support for Multi-File GLTF: Fixed missing animation initialization for GLTF files loaded with external dependencies
  • Added animation detection and initialization to loadModelWithFiles function
  • Animations now properly initialize when loading GLTF files with external .bin files
  • Animation controls now appear correctly for animated multi-file GLTF models
  • False Texture Warning: Removed automatic texture warning banner that was incorrectly showing for all GLB/GLTF files
  • Warning now only appears when actual CSP errors or texture loading failures are detected
  • Improved user experience by eliminating false warnings when textures load successfully
  • Slicer Upload Safety: Hardened temporary STL upload handling with size and MIME validation
  • Reject uploads over 50 MB per file and enforce a 200 MB rolling temp folder cap
  • Validate STL MIME/header before accepting; reject invalid content
  • Enforce rolling 24h expiration on access and clean up expired shares/files
  • Use rolling +1 day expiration for generated share links
  • OBJ Texture Loading Robustness: Improved OBJ/MTL parsing and texture handling
  • Preserve texture/MTL paths with spaces and mark materials for update after textures load
  • Use existing blob File objects for texture URLs and tighten loader logging
  • Handle texture load failures gracefully and ensure needsUpdate flags are set
  • Texture Dependency Lookup: Skip direct “find by path” lookups for image textures to avoid unnecessary 404s; rely on directory listings for textures commonly stored in subfolders
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
Signatureacd0z9v0ifd6EhLDkZPQmIADZp+TPcgSOqKKp6W5KUtq4CA/Xk0lTNssZpirrEaLO4s15qemVCz87Aa6hhxGipOFlBSMFIyc1U0q8OQzHMOa4cYU8w1hvmi7aXeG+IxPWXelCAYaBNYGbleOvhc+/ao1gh1mn+3esakeTLdBi8XihNAKBDzglkOD30oBunXuzXJD1chBFBx7LCMoRhVXHDxShzi39+vbumkbme4IGV9kL323hTSjD1+XrMeiIG2P9tvHDEkGRXEOKohmWQNrsFCamApVqslvRzg6mBFTFv+dtnBUFbbQnC25IvyE+UNY4j2TGzncrW2+jWGddicKYq4SIrI7RzB91gTxv+3qzwCUb8OlyaU38L042l4HJXSFMPh8Mmj2n/0zhWlH4M2h/ZEPjySsaK8lU/x/DaBoyLcPoJcDsuD1haONv6mpRsoz/ohXdV/U9s61rbGOnJkSqMMblFoVXVmkzTKpBatf08e9Uaig21b9q/ekYyhbVFlujmAu9ku9EWk5SddY26zNvSeiGinV1xV3BayMI3rVZYINZkPb72Dv6DOInRWlVOxVqLQBUY98ejlhpls+6l3IdtTDUmrITmGr+Nq3b8T8kgNJpgNQbf3Ij14MgdfNsxd4nxMyX/4hsOSZdU4dAHsTfatSxRgM1q9FpuvZ+OkyWMA=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 2.1.0
Release Details
UpdatedDec. 6, 2025, 10:21 a.m.
Changelog

Added

  • File Browser Default View Setting: Added user preference for default file browser view mode (Grid or List)
  • New setting in Personal Settings → File Browser → Default View
  • FileBrowser component now loads and respects the default view from user settings
  • Setting takes precedence over localStorage, ensuring consistent default behavior
  • Manual view changes are still saved to localStorage for session persistence
  • Format Sync Test Suite: Created comprehensive unit tests (tests/unit/Service/FormatSyncTest.php) to ensure format definitions stay synchronized across:
  • Backend PHP constants (lib/Constants/SupportedFormats.php)
  • Frontend configuration (src/config/viewer-config.js)
  • Nextcloud MIME registration (appinfo/mimetypemapping.json)
  • File Browser List View: Added ability to toggle between grid and list views in file browser

Changed

  • Format Definitions Centralized: Consolidated all 3D model format definitions into lib/Constants/SupportedFormats.php as single source of truth
  • EXT_MIME_MAP for extension to MIME type mappings
  • CONTENT_TYPE_MAP for file streaming content types
  • All repair steps and services now reference centralized constants
  • Eliminates format definition divergence between components
  • File Browser Grid Padding: Updated file grid padding to consistent 20px on all sides for better visual spacing

Documentation

  • Corrected repository URLs and upstream fork instructions in CONTRIBUTING.md (replaced placeholders with maz1987in/3Dviewer-Nextcloud).
  • Updated TECHNICAL.md with new controllers (SettingsController, SlicerController), components (PersonalSettings.vue, SlicerModal.vue), and detailed Personal Settings + File Browser implementation sections.
  • Added comprehensive "Adding a New Format" guide in TECHNICAL.md with step-by-step instructions and code examples
  • Expanded IMPLEMENTATION.md: added Slicer Integration & Personal Settings System sections; reorganized and deduplicated legacy "Code Audit and Cleanup" content; refreshed Table of Contents.
  • Updated README.md (docs version) advanced features list to include Slicer Integration and Personal Settings.
  • Added troubleshooting sections for Slicer Integration and Personal Settings in TROUBLESHOOTING.md.
  • Expanded test coverage notes in TESTING.md to include new controllers (Settings/Slicer) and components (PersonalSettings/SlicerModal).
  • Normalized wording and removed outdated dual-mode duplication in implementation documentation.
  • Documented dual-mode viewer architecture in TECHNICAL.md with viewer lifecycle diagram (standalone vs modal modes).

Fixed

  • Settings page image/logo path resolution: replaced hardcoded asset URL with imagePath() helper in PersonalSettings.vue to ensure correct loading under all deployment paths.
  • VRML preprocessing duplication: Removed duplicate preprocessing code in preprocessVrmlText() that was applying BOM removal, line ending normalization, and null byte removal twice, causing inconsistent preprocessing behavior.
  • Flexible texture matching loop control: Fixed nested loop control flow in texture matching logic (multiFileHelpers.js) by adding foundMatch flag to properly exit outer loop when match is found in inner loop, preventing valid texture matches from being skipped.
  • Premature texture issue check: Moved checkForTextureIssues() setTimeout call in ViewerComponent.vue to execute after model successfully loads and is added to scene, ensuring accurate texture loading status assessment.
  • Debug logging cleanup: Removed console.log statements from FileBrowser.vue component (viewMode watcher and setViewMode method) to improve production code quality.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureatLgIGKAv/DO42HgoDbqVaos4kWPFuPmF5l4PHyM5S5ivOlmqnC5xu1+d5uX/h+0rUmL+pG6wKezHo7WT0PVKSBciYZzlb5D+6sJisB5x/jMVqFaQRmnEEPKfoz2DsDucmXtH6Ppv3oXjyKd5wDjyFMwtoG1hU43QBeA4ngYTMTCXqdITK5sT4OM4IwiYhUi7zZRh6/YoRxgojXIqo/RasM3sGIUIrQs075RKqXcdGcGUwJgQPAQnGsMEW9D0LODp6bYurgBZRgnmgBrpTE3D7Ktt1G+ppQTSW4tHpuq3mFJdhFlkbhbWJw9QW28xJmDnqUGfhzXTSMqoJLnbio0n7iT5bhiyxBmhi5patzHifmDwndpRPoZNbw7vxr2zzqCc+1pMt/CoXHn1PTthmYtQMg9tvyjS7jbCdYtDYLtluzITRHP8GzRXIMmBrCRzXLymk0b3IvwyB9G83+QwzHyWSTLsKV314CSasumGhFDSxnz0E2DhVVZV7yaG89Dj9HHwmxkQVeh4iI9DCd5ynu6q/8Ljyp4nJ1p//+3WCo3NksaM0ubqkXiVFnSTnSjsoDw8mbP8TU/iESpYJ11llVA9ftZSGnnczY2zFKKK17C5m/pjE9sskLlo2bfhBzRLvYOV8ejRyaXPK1B6ejCfk2VwWntq7UKFh/+/1R5usmQkRg=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 2.0.0
Release Details
UpdatedDec. 2, 2025, 2:53 a.m.
Changelog

Added

  • Personal Settings: Added personal settings page for user-specific preferences
  • SettingsController and PersonalSettings view for managing user preferences
  • Settings routes and configuration updates
  • Enhanced File Loaders: Significantly improved loader capabilities
  • Enhanced FBX loader with additional features and better support
  • Improved VRML loader with expanded capabilities
  • Updated DAE loader for better compatibility
  • Enhanced multi-file loading helpers for improved dependency resolution

Changed

  • Viewer Enhancements: Enhanced ThreeViewer component with improved controls and features
  • Camera Improvements: Updated camera composable with additional functionality
  • Circular Controller: Enhanced circular controller with better user experience
  • Theme and Performance: Updated theme and performance composables
  • Major Version Bump: Version 2.0.0 introduces significant improvements and new features

Technical

  • Updated GitHub workflows with improved condition syntax
  • Updated Dependabot timezone to Asia/Muscat
  • Added change detection to prevent unnecessary PRs in workflows
  • Updated stylelint to 16.26.1
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureJrtVI0UiQsSqL82PvCmO+FLp06iE6caUY8nD1+dKlVr5YjeTvZjLUtd0sAbmwQzlR2iC4IuRJllv7hr5cWk8oWuJtnLuE4uzcXu3bu8ndzO/Zyf4ph65Fn3GyML8Zdm6TqECBFCzk+2NG0pVxt4TM7qML5p437Q6IrF0+uOh3Vj55CTf160KAjEN7v2Sa8CT4Qf/JPKtnfyAgnKkNRXMQCf7xXe3RqtgtiVPnNq6nKfYzERoihIHhZ4LqLewUfY7jvxKUpAIxF89K+yTk1PmsJgKPBN88FF3ReKwcfJcfIhMXuH7CJEHCg++Hbd0oxzvl3uv0o8k5USdkojH0vG5IQaBF8AAEGY0aKCsScmffSN7WvmpPngsHs56V/olPNPVG1QNepRvSvBljr9D6idShiRlaW7uOBl9SVwLernLBjZ30bfqRtdrm2T7oO6gozY0zRc3jxt+ajAuaPLp8pAKC/Bv8nt3Og7R3r/mpk7qXWEgC/u78v/LqjhtICx1CQDSROq8vuces8k4iEN1kJabrhxLFPDPmZucoXWSzUStP+ISyPksq+pk5KAtnKuVRMTN8rhYkMlyK1790OOF53Q1bvlHnTc3LmzTLi6b/mVPBtz+KgkHHoU8j4TYwSlnbmSx6gDqzrQa8q+cRXlK1NNmF211NX0J8B9nRkng+xHg5ts=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.8
Release Details
UpdatedNov. 28, 2025, 6:24 a.m.
Changelog

Changed

  • Dependencies: Updated development and runtime dependencies
  • three: ^0.181.1 → ^0.181.2 (patch update)
  • stylelint: ^16.25.0 → ^16.26.0 (dev)
  • vite: ^7.2.2 → ^7.2.4 (dev)
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureMKCHrKGV1G4CZgG/gyhGvg34zK0migxfZ/FS9ZZEylzffGxQxoQbW+wubOR3BAjgWRx5smOBIdKVeLLuPOV00JnPgrII3lRaltLVO72nNrYtVh5DruKC5ZoMM4BuJsdEOFP8euy/GDCmlhQYNTusS/T+meggfylcrAjZAWR+SZZfb4x7QlBJTdmCuWpHNBJO081IpeLfn5HXohFAWm6sHHm6mun4ar6znAlwsZ/pe6Lo8ZjzLBuDN9mLEujrw6AgjTq2DTSUrHrJ9/WQF3zBiYjRLMNurJLnrwCXuUmPkKGWrPM3ybFADqfgb3QmqzPsPiGUL87k/1yVewEqE2olFpVRZ9hxa11ANingG+zMZwY1bCbzIcrRCq4Uoae7zgwZV/CF2wJQk+cRMbQl7Y7AoAy6PPECLMFtU93VgHqcPtFQzAxSPEXRNW+GpkVFHWvBZ7iuL6Ys8gMjl9i9imuNYcIAkuLlKLmu8t5pQpOLKvNpiQkeIf5aWXHm5Fvq7+zmeKIsuMVNvPoqQOSlC1AkwnLi1EAf/2VrqbAmDoC/o3Y6h1mg6vskUNFRPhz2h37TEb65h1bm9kFjNx/6TNNF0xM96GSAt7v+I1naBODhvGqDqyJ653663yuE+CxdKd1kZ4ous3urqXRwAmKHVdOvXYZTb+N/Feu7PHqrdcwlHHQ=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.7
Release Details
UpdatedNov. 27, 2025, 5:42 a.m.
Changelog

Added

  • AnycubicSlicer Support: Added integration for AnycubicSlicer with custom icon and URL scheme. (#52)
  • Folder Exclusion: Added support for .no3d marker file to exclude specific folders from 3D file scanning.
  • Hidden Folder Exclusion: Automatically exclude hidden folders (starting with .) from the file index.
  • Temp File Cleanup: Implemented background job to automatically clean up .3dviewer_temp files older than 24 hours.

Fixed

  • Layout Issue: Fixed white empty space when hiding the navigation sidebar by ensuring correct flexbox behavior and explicit slot usage.
  • Viewer Resizing: Fixed 3D canvas visual resizing issue by syncing internal resolution with CSS dimensions (width: 100%).
  • Slicer Icons: Fixed missing slicer icons by using the correct imagePath helper for asset URLs.
  • "By Folder" Navigation: improved folder indexing logic to correctly build hierarchy and handle edge cases.
  • Server Error: Resolved persistent preg_match error in PreviewManager by disabling unused app preview provider registration.
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureLfmZ7uqqVk6tDgQQuwcGuzQml5OZWmFvpfNYW9Nd+3gVtIRUCBKsgtB8D6CMf1ymq2JxllnMvhATHE3YVZGmCsL5CRrj6al9+zdVnP8An2BUBP/DsqDTTwLM64mwKFIqYYkjtwVfttaa/aPJn2cdH7umzjOEHsYzbRx7eiP1lq2ERy4KYs7aA26hfleg9kKbr1jKTf0/vPCHvmbKg+o3RS+QfP/lRuoPjk1UYog52IAHd9bpAtAgmB2yLSfghjPSvMhZkyWt38CKMiKyO2R+VdB6wc/lWWVWq1JfJDw9oZlhaMpBZhXVDqR7uoMYdtR2pTNhB6d+kaTQtclvLSO5RREUDMwdocOl7iVMwrXCmKmUIyDqMa/VF3FFtK31fKlSYuvIhGDi1He0NNqlv2jiMsb2EPhrYLBHTyrmY0Px3i+ZmbYos1sFXLi7CliafZY/nZwxqPSc8xsZI42MFO9ZWA7yBKYE6UHphNnbxTbx5H33NrwHdRhOh0g+wpLJebbjyi1momlshADpfec+gAImcCnyaXhIX0Vpt73R1DmadH0xbi37iCEg73s9h6cul1RGeRhOzr+c8nhuFOUq4wodj9VLbTwwqm+bjd1jvshyo0++A0Nhjfj79phnnIJl0xsKU9QaN1eFlB6vPQRMyFswy6bWW4IW/yI2KL7693JFhRE=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.6
Release Details
UpdatedNov. 20, 2025, 12:48 p.m.
Changelog

Fixed

  • Preview Provider Registration: Fixed ArgumentCountError during app service registration
  • registerPreviewProvider() requires 2 arguments (MIME type and provider class)
  • Now registers ModelPreviewProvider for each supported MIME type individually
  • Resolves error: "Too few arguments to function registerPreviewProvider(), 1 passed and exactly 2 expected"
  • Migration Class Declaration: Fixed missing class declaration in migration file
  • Added class Version010902Date20251116061241 extends SimpleMigrationStep declaration
  • Resolves syntax error: "unexpected token \"public\", expecting end of file"
  • Folder Path Length: Removed the 512-character limit by hashing folder paths for indexing
  • Restored folder_path to TEXT and added a folder_path_hash column with a new migration
  • Existing rows are backfilled automatically so deep folder structures continue to work
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
Signature4F3B+MMtZoJiTGIBdBSaJDW9PVnv2o38ob0m+f5cIJmMM6jpgqYETLsQaW1zRCdQ8ozE8v5LfkehmhMlXy8folvlapuRcDGh9N7PPIRzTM/8b9ymOMQ1vkBPERw8k5grkUwFNamMPw+K4rFGHLMflN+vR/S6m0jmAKls/2L4kg2UdhaTdtaw/ozZAM4a09dJ038kyBS6jbh6g/M233Ue/R6aXSCMVgrA5zw38djqE9O8zmUg8xOJlOzdMRCRdhKWZOHoocLV9TBTasdU99YG7o+VIgAXeTY4X0rKxtOdfqdX+c+YNEt4syMmig/1p3e3yO1q0CmQPg6rgxtrdVOW1KK6Bbsvd8DkNwyQ0SgREq8bD+SIlF3QfqTDAFKCDgjTCn9N7HBnZIVa+NtseVrVfVeEdWdVNGMnfu9QhSeMqrE5dJMzKJLiPy4ftrmzM+aff+3aoQU69wWVffIBw1RsC3+352E90jiYw8CnH0ul8I6ffA+NVD4v8+Jo2MruxzwzTsq7/RfQMvIhsCTrhyauECtmwAQPEx9CX4h+7nryjxefgDwPQlFyszt6F53LSTWEeFO49SAlV9dH5P6tsjsMozdUts7HtG+UU+T7gHD65rY/nPL8ICF6C5YHGuuxwDFQGAkKtBNN/9VWBZr8h1X9jq1o57hwIqGBnxNdAs9YqdA=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.5
Release Details
UpdatedNov. 20, 2025, 10:08 a.m.
Changelog

Fixed

  • Preview Provider Registration: Fixed ArgumentCountError during app service registration
  • registerPreviewProvider() requires 2 arguments (MIME type and provider class)
  • Now registers ModelPreviewProvider for each supported MIME type individually
  • Resolves error: "Too few arguments to function registerPreviewProvider(), 1 passed and exactly 2 expected"
  • Migration Class Declaration: Fixed missing class declaration in migration file
  • Added class Version010902Date20251116061241 extends SimpleMigrationStep declaration
  • Resolves syntax error: "unexpected token \"public\", expecting end of file"
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignaturefF9sWdsS9s2UfdNuMWzSK76VLnucCn+KchXB9eFwbDsdXACnQYvhUVvS+xoMBYIfaXQEYUjfIl9oc0/sghPaIfdPvHwhCSze3XUPHkeF8yHb7eXQfHPr8N6KQZdmFM50brxxpHt5yxI40xZU+mMyW3eTP982e+aLenLEr2taQYNoaTHf35NbVknGLAE1xautWR1JQzYyVkCcc4T9/hxMp7LaGBrUPwdDALyuAp6WTHtZk+XeOxxxwRiNb7q7SpXWGuwdbX7MDvEzfBUmhw8dbORK3kqxgfXFAe7uGVdW+5sKtkdn+fxuN4gHKmBwW8N4X7YW1XaAL0KkYFoHsrdAcHunsSn/KfuqhTLHRpxOblgFPEcCwwqWcPVdGASFkD96rYylV9yzoJV2zS/pDqMVG38TQjHOs6ukBbJ5KHzpGJpgOZXDzLn24or5wVubjXkCyOsfS0by89VmrrxrERJZPNl6XTgeCZaBTPsypeWAlezfqVEjVVmdkoKuL+I3m/gMURucZV3Do+wHmxoEAT/2bTRVtIZzBsjrwuljZk4cok0oQ8reFBlngACWmXWskJOiEmshDUpnd2IykjhaU6LPEBDprd0fSM3+RE6Sx1+iJuPdXQ+CUATytcbKc8kiEjcPapzQ7xt3uR2fukG3eLrkFKoKHM7jJtWWMcWmN0yppuQ=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.4
Release Details
UpdatedNov. 20, 2025, 2:09 a.m.
Changelog

Fixed

  • Preview Provider Registration: Fixed ArgumentCountError during app service registration
  • registerPreviewProvider() requires 2 arguments (MIME type and provider class)
  • Now registers ModelPreviewProvider for each supported MIME type individually
  • Resolves error: "Too few arguments to function registerPreviewProvider(), 1 passed and exactly 2 expected"
  • Migration Class Declaration: Fixed missing class declaration in migration file
  • Added class Version010902Date20251116061241 extends SimpleMigrationStep declaration
  • Resolves syntax error: "unexpected token \"public\", expecting end of file"
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureYu4MvwQG1iiUU+ZnS3qdmTsCZ0NYAx89VzPzGTNqkdgQ/LolnwTZNDpkHEOoGQOM7Q95wtrJ1iHj2KQNxHsg/nw26/L0nqQtE8+HN92EVkjKhj4Chve7AB+A8dFlj0nXdSpgtH/PbwN+90lQTCGnmd6rRc46+OqEfEoFzjBhqtrpzXuURKsZG4GV644vSvAyzZFBDncgI7tlGhUhCDj/5UShHQy9ClymB6Yb5K7smP0BSDEWYOxsUOj2/cy7hAIlCyofINC8p6UzA6Po6NiyQefX2zds56a8TZhvvuaeiO3setCQzKXdYp3WqlnVVSpRA7UZfGeqdvkDqtQuTIs4Zo9w6GWX9M+N2Z15rQ59t/cNX0OYhCs+Fw2UdJMAPYW+me911YHsaMmANkaw7sUZ0ncqxbc0NZ8NULhJakF4DHizsCSLZbVrOhpfcaDEpsy6q88bg6o4modcj+gTIytUCI/RLjTlKWYAZcRFJfmPngQiuUmBeZntR2y1a0ROFsmcRAaSys5UFHF1KuqaNocqcAo+CbN5vRqMQXnmGSg54kEHvQ6xjDki/rs/0/5sxIX5TrGhGCyubdpN5Avv1y+eZfMdxVrZu0wxOubN3zgF47b/O5wql0Mv2tpFH88gy5XMGRTyaB1fIeFQXV874btSvkBwJPJhKdTZV0pyA9C+wUk=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.3
Release Details
UpdatedNov. 19, 2025, 5:36 p.m.
Changelog

Fixed

  • Preview Provider Registration: Fixed ArgumentCountError during app service registration
  • registerPreviewProvider() requires 2 arguments (MIME type and provider class)
  • Now registers ModelPreviewProvider for each supported MIME type individually
  • Resolves error: "Too few arguments to function registerPreviewProvider(), 1 passed and exactly 2 expected"
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureYmgaFcAnfaw/gFhMAFJupT22RE/RWydQkyTNQrbQNyHQGq406C58CN9hKEIJ5kaSzibif3goqa31T/si8GlYBnejJmQzYsQpr5Wua0dSrkUtCv0fRFv5GNWJvazyREN7XKWp+Ir/Q51J7trkGs5RCuZRnH1DhHTPyieLyZLTFsSWTSPuDRHEnpqr91B0y+epvQGujYSYG931+5tc6QaX1rfZ9kmT1qNph4SdaLeMa4hbiSFc7fuuSSNqvE8q1QPrBJEz5TMixrr1U8iMA38HBWVsufDfd+lg18bVWg3zQG1yFNZn/RYCuPck6DPiDo2uJ/9AJzOTQpJEFjDfc2zG77oE7EufwDtoaJzbhXhiseW7u0Ty6nVywrYTnEbfuIYhHeo6lbxY8KtoPLZSDSiSbH73oigsGW7o7xA+RDjtVZoWRguPZF9VfUjJ1v5WQpHD0jdZflYJ3byMygWF1z7GaT8wE9gbzwvWUyMGE6XCpzwpNxx3yOlq0mp5aUNFAjJYAO8BSgaFBxSBVnXTv22JEnhaUPAWL3HaMh3EJLVJla/TOG7cd7N9eS6JT3maO8Z7QUu32B/ah48w/uxk9qzmBX+t1onXwUA/6CuY8Gfhcg20AK5JuUiqhIZD1eW7HiC0pNJJqZbzLbXBl049JBFUqZbKLdf+ttISPjCmlRTnxdg=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.2
Release Details
UpdatedNov. 19, 2025, 5:32 p.m.
Changelog

Added

  • Database-Backed File Indexing: New tv_file_index database table for fast folder, type, date, and favorites navigation
  • Automatic indexing via filesystem event listeners (NodeCreated, NodeWritten, NodeDeleted)
  • Manual reindexing via php occ threedviewer:index-files [userId] command or /apps/threedviewer/api/files/index endpoint
  • Migration automatically creates the index table on upgrade
  • Smart File Browser: Complete file navigation system with multiple view modes
  • Viewer mode: Opens 3D viewer by default on app load
  • Folders mode: Hierarchical folder navigation with recursive folder structure
  • Type mode: Browse files grouped by extension (GLB, GLTF, OBJ, etc.)
  • Date mode: Browse files organized by year and month
  • Favorites mode: View all favorited 3D files using Nextcloud system tags
  • Breadcrumb navigation for easy navigation back through folder/type/date hierarchies
  • Consistent card-based UI for folders, types, dates, and files
  • Per-User Configuration: Remembers user preferences via ConfigController
  • Saves preferred sort mode (viewer/folders/type/date/favorites)
  • Remembers last opened file ID for session persistence
  • Mobile experience: automatically hides the circular 3D controller when the viewer detects a small/mobile viewport, preventing overlap with the canvas controls.

Changed

  • Viewer opens by default on app load; the file browser now appears only when a user explicitly selects a navigation mode.
  • GET /apps/threedviewer/api/files/list now serves hierarchical payloads from the database index (folders, types, dates, favorites) instead of scanning filesystem
  • Supports includeDependencies=1 parameter to return all files including textures and nested subfolders for multi-file model loading
  • Dramatically reduces filesystem scans and improves performance
  • Navigation data is loaded lazily per sort mode and cached so switching between viewer and browser modes no longer blocks on loading every file upfront.
  • File browser UI refinements:
  • File cards now share the same compact layout as folder cards (consistent padding, thumbnail sizing, fonts, and grid spacing).
  • Type view heading and breadcrumbs no longer show a leading dot (e.g. GLB instead of .GLB).
  • Breadcrumb component now handles clicks directly via NcBreadcrumb to improve reliability.
  • Remembered folder/type state is cleared when returning to the root via breadcrumbs to ensure a fresh reload.

Fixed

  • Newly uploaded, edited, or deleted 3D files (and favorites) appear instantly in every navigation mode because the indexing listener reacts to filesystem events instead of relying on manual rescans.
  • Root breadcrumb ("Home") navigation restores the folder list correctly, even after drilling into nested folders.
  • Multi-file dependency loading:
  • Backend listFiles now supports includeDependencies=1 to return every file (including textures) and nested subfolders.
  • The dependency crawler recursively searches texture subdirectories so 3DS/FBX models with textured assets load successfully.
  • Texture search now uses the updated backend response structure to avoid missing files and 404 fetches.

Technical

  • Created lib/Db/FileIndex.php and lib/Db/FileIndexMapper.php for database operations
  • Created lib/Service/FileIndexService.php for indexing logic
  • Created lib/Listener/FileIndexListener.php for automatic index updates
  • Created lib/Command/IndexFiles.php for manual reindexing command
  • Created lib/Controller/ConfigController.php for user preference storage
  • Created lib/Migration/Version010902Date20251116061241.php for database schema migration
  • Created src/components/FileNavigation.vue and src/components/FileBrowser.vue for new navigation UI
  • Updated lib/Controller/FileController.php with new listFiles() and indexFiles() endpoints
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
Signature5KdirqBqYm1NTouEBce9EtmTO6/UJwHsg40DC/oCvhIuYOF8eLVWy5O5Vwx25hFvq7bHrr9SQQ9cdJS1G+fY8aQ7bSeqCR1dAdUlsoBhrYWQnKAEnoG8vIIxfk0gA+HgcRGLJPtph9TYLdeAqdhD7/VVUg8l9ZdIVJHsTQn8JijVkTeMpk5612wUyoMn7HaA8IJJrOnU6dmkfv95FcZbVLzR6QRDc2fqlM3aYbZl9KOVYzEU6e736rsQAOVn0IqrHmQyJNVIdiFnycbtRiJnJgRJj05KblfVIOC0qZwzl7sqIHdAswvYwDmdCoLK/rblTc8R7INoUFpmGFBzPITfVwBNrJh9jsxxuWnl0X/vAAtVACVGHR1utLtd4dMFSjwOVxD3f53eazH9/Hho18BBh3GOLNJEWAGNal3u8Ng+inilqQu4Nmhds9AYUoq6T38oU9NABr7mDce1TsO0AYQqfez3HBodgbbBOoXKSGLMoDCk9T71NR2Oc2XC8Urz08F9Q/0Dcoy06kdvm9neAOH+yHqjcPXfI98JCdqao6Li05VQaLOUxIyYbVpngGu3LWthpaH7rlxhD5DlOwknjimFfGifjZ0/yScHSbfRqtgxy8q8jfHJ71wMKOAzQ6xCgqfuWWROUqWNmo4ypsE23Ioj1n/yEA60bComBBgSdSjCwpA=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.1
Release Details
UpdatedNov. 15, 2025, 9:35 a.m.
Changelog

Added

  • Preview Provider Implementation: Implemented Nextcloud IPreviewProvider interface for 3D model previews
  • Admins can enable/disable via enabledPreviewProviders config in config/config.php
  • Integrates with Nextcloud's native preview system
  • When enabled, provider is registered and ready for future preview rendering implementation
  • When disabled, Nextcloud automatically uses custom filetype SVG icons

Changed

  • Updated dependencies:
  • three: ^0.181.0 → ^0.181.1 (patch update)
  • @nextcloud/router: ^3.0.1 → ^3.1.0 (minor update)
  • vite: ^7.1.12 → ^7.2.2 (patch update)
  • @nextcloud/browserslist-config: ^3.1.1 → ^3.1.2 (patch update)
  • Improved duplicate registration prevention:
  • Added guards to prevent duplicate file action registration
  • Added guards to prevent duplicate viewer handler registration
  • Enhanced error handling with try-catch blocks

Removed

  • ThumbnailController: Removed custom thumbnail controller endpoint
  • Replaced by proper Nextcloud IPreviewProvider implementation
  • No longer needed as Nextcloud handles previews natively
  • Thumbnail Placeholder: Removed dependency on thumbnail-placeholder.png
  • Nextcloud automatically uses custom filetype icons when previews are disabled
  • Custom icons already registered via mimetypemapping.json
  • CSS Thumbnail Overrides: Removed CSS rules that forced app.svg background on thumbnails
  • Allows Nextcloud's preview system to work properly
  • Custom filetype icons display correctly when previews are unavailable

Fixed

  • Duplicate Registration Warnings: Fixed console warnings about duplicate settings/registrations
  • Added registration guards using window/globalThis flags
  • Improved handler registration checks
  • Better error handling for duplicate registrations

Technical

  • Created lib/Preview/ModelPreviewProvider.php implementing IPreviewProvider
  • Registered preview provider in Application.php bootstrap
  • Removed THUMBNAIL endpoint from constants and API documentation
  • Updated openapi.json with preview provider documentation
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureyK5Dmfw2bZsjqJMtY0eaIkST1jQZ4XKcPtlHp4f7GNHWV1A5PrKjkxKHO32JML49YXEI7D8PouQvnHXDq55pRDm/PBmXV3cB5wvx3ZkMVMGRQBqHNR2iBfSsl6w9I0SaGSgNSt/aa1kmZRCq20GPv8hLMHSJdcR2VpU5mA/BLp6vP51LBp9wDwzCEsU82zX6VVBXkd5YIHY+6HMRsNQNXFfRsWERTq5yjmTYfyK4Zq1rvZShPX3KG8WDWl6g3C1lJhyr/7FWLoM7Lsq6k1pirdAYUtQO7ooB0UDiTpvEgmCj/OLhL/8dvaD29dyzUxnokjj8IlpiDEcPfeLN34nqXHfMbmPZh9+aqBqsZr0GaqSD6dXGoplkBc+F/SHfWdevkZDHk8p/W0flcjIThr+K5/8YhwdDZd3G2JIRmhDdJXFfoTn2f+zYkHTV3enXsRAG95FVU3WE6zZwi8w4MOUiXIpxqb/DAISRSId3k24iPFlbguOQwPvcpMGNIruPRkoE7ihCgiU+dvcQ6ieYtwvtAHgNy+N284BdcsK7/0g5tCkzDad8Fdt4pMImPkO+cWBy3c19Uce5+pBx36Nts6q5so6O96s0Dcnf4NQPsnRFHNKduWxafeoBHCwn2NoH2aIRw0JQcwyCLvL2j8vLcN6PhAQwJ2I6P/4yHX5aEWEwaP8=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.9.0
Release Details
UpdatedNov. 10, 2025, 6:57 a.m.
Changelog

Added

  • 🖨️ Slicer Integration: Send 3D models directly to slicer applications for 3D printing
  • Support for PrusaSlicer, UltiMaker Cura, BambuStudio, OrcaSlicer, Simplify3D, and Eufy Studio
  • One-click export with URL scheme integration
  • Automatic STL conversion and temporary share link creation
  • Professional slicer logos with brand-matched colors
  • Last used slicer appears first for quick access
  • Smart detection of uninstalled slicers with user-friendly error messages
  • Auto-download fallback when slicer app is not registered
  • Temporary file cleanup after 2 minutes
  • Share links expire after 24 hours for security
  • SlicerController API: Backend controller for handling slicer exports
  • POST /api/slicer/temp - Upload STL and create temporary share link
  • GET /api/slicer/temp/{fileId} - Download temporary file
  • DELETE /api/slicer/temp/{fileId} - Delete temporary file and share
  • Automatic cleanup of old temporary files
  • Proper filename sanitization for paths and special characters
  • CORS headers for slicer application compatibility

Changed

  • Updated app version to 1.9.0
  • Enhanced toolbar with "Send to Slicer" button
  • Added slicer integration to slide-out tools panel
  • Improved error handling with toast notifications
  • Updated translations for all supported languages

Technical

  • Created appinfo/routes.php for route registration
  • Added @NoCSRFRequired annotations for API endpoints
  • Implemented Nextcloud native share system for temporary URLs
  • Fixed filename handling for files with paths and special characters
  • Added proper authentication and cleanup mechanisms
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
Signaturebdu+2mjB9NyEPJbbogKcFBovDi99alBx7ixiNLiVWRmMw63yphLItjrEkmMxHL5KeEmkQj05gqf17mPXlngrWI3pkhn1gLHtbCiPwOqloKdQ+bf0US34nClshbCzP0drRsNWSxhEWbd0a0vc1Zy31vk9I2PVHugbpbo4BCy20Ks6t0aCkv6o+g8x+v+B348txV1p1F5hyM+2BBUqxEB8fNiRJ/p6bd1eMf6lWfeqBrWG6n3zB11BsKKYAa941deyJ8vLlEpI8D7Kyz7TVHuHzx9hlxbZyOCYEnD52EmpYDl/VaKnj+9EzxaFDqkQPOIHPbMtfe9tc0nZOrqEASXrUC/iPMpp1JNAyRa0Egx+DkdRE/p6wFMBxipGqfgb7MJ6gV4I7t7ML1scquVtcc8aZt3oNhdMd6gPZ7/uxOYQ8Bm6YX6fiuwxtqe5yb2uwiw9oKjQhs3miEXEAiaiab3S4HLC6Ke9QYowEzASoAD1tHf+kf4I6+IszL5V6XOVzXRhKU8t/Vdl/JSZh3LEOma2KCPBoxIwove9PpHARcEIz6Tk4eu4UvMdTjhyIBKCvEnq8Bs5fzaq+jqSuE+8h3Y+qP0Q2fSqcNHpLtBEAfrkSu883dCM7dg0miDxSGumfqn+oJ80bVDGm8mQ3WdP7AvJiygdj5i2pFqyeiPE+MGDDUE=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.8.0
Release Details
UpdatedNov. 6, 2025, 2:21 a.m.
Changelog

Added

  • Screenshot Feature: Capture high-quality screenshots of 3D models directly from the viewer
  • PNG and JPEG format support with configurable quality
  • Automatic filename generation with timestamp
  • Accessible from toolbar and tools panel
  • Download screenshots directly to local device
  • Fixed WebGL renderer configuration to enable screenshot capture (preserveDrawingBuffer: true)
  • Billboard Text Labels: Annotation and measurement text now always faces the camera
  • Text remains readable from any viewing angle
  • No more reversed/mirrored text when viewing from behind
  • Smooth rotation as camera moves around the model
  • Improved user experience for annotations and measurements

Changed

  • Updated app version to 1.8.0
  • Enhanced info.xml with new feature descriptions
  • Updated English translations for screenshot and billboard features
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
Signaturebvx0cRDWADLGiuJ0jIg9f+81Add0o7SM3Dkq8foP/AnLfM2fSL1/ds6JsckXbP8xdOMoPyAxnN9XFi6qckR+cTiBSkkbpbQeg32ZDShLwwVRH8dubBAHkIk7qSBVjw4gV2BdKuMjWZZ5cRPlcFNUtdVP776NXH6Vv5FxK4UoudEN3VA8qDZC9+8fC46n7NhnobbviHIzeNqPA0V3Wo50UuuptyDdip0o/bbBiaw1vszWuV4QoHFMHAjFan2v3kKb5ptIHYukVOLMj8rY1dKeTACQYjEwi+YXOV+4eJMiMrHXx06eMYxiOsTdNHsCWTy9PW+4QTHM9dI/GNygSKC/V4Z9lxlPt7jncHOAT5P+tEFrWQYImvBtWsXPXoP6UPAIpP82NPWhp0lBZdjR3Fvx4yi0PM7V4/lRTztUkTrobnlVNpIxSe6SH0jWmVlyAFAW0XSiWrWbM+Q0gNEERVNudpCw7y41xv2Q45ZgPIMhGzjn7CbY8gVacSrXcsnglD8pcFAnI7hh+KfepgSSeJg1ZV7IF5UM9Qr9Cu7VDtq8Lc5bw3tqXNDf4U7T5UgnAjbA/GFXY2fz6yT5TVXWoNxER4d3Bocb73r5wWYlag6z2CKOxTOWenRUnrG0iFPi95MxaykgJMVTAilRLoHOOGZie9DHpOUwcvXWAokeDaXGBSQ=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.7.13
Release Details
UpdatedNov. 5, 2025, 4:44 p.m.
Changelog

Fixed

  • CSP Conflicts: Removed global CSP listener that was breaking other Nextcloud apps (Memories, etc.)
  • File Icons: Fixed custom file type icons not displaying by copying them to correct location
  • App Compatibility: CSP modifications now only apply to 3D viewer routes, allowing other apps to function normally

Changed

  • CSP headers now scoped to specific 3D viewer routes instead of globally
  • Added automatic icon copying during build process (scripts/copy-icons.mjs)
  • Removed lib/Listener/CspListener.php (no longer needed)
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureqfnNbykFms5wS6aOa/TKBYua37o3OqBNqe9LY0dU86/MrGrqbv+v9inkFm63UQyR19ux9ACVlqG6J5rCDpLLTYAe1IkFGZMKfJzNnna8uiA734PltS8gNSv8ol0zMsRs6tvanPlDxVedCmzp31VsErPKOShjvTRbhf9ZmgJjZccX3UODdfIzZxJLqHd3vBrYqoksFXDZnzUqEkb5OK7RwfxAs71IGoVjXHOf9HuOVuefc1mhElbIygGnPYJ3ewlU72SD6gB9/kYgmZEb9xklvcTz6IjTbfKdZ7fLb640/71wCIa5mYleBkaxsoAzfGo2QjC6GHNkAQX7gAXeZp1GYBixwIF4JvawV2s1pKnIDZE3hkLqhx+e4OOYvawhlVoUdILsXSC2oiG4Q5qF/tSz6fh/2gFY+/2fxJMSwwbPXTkUPA5eXKCTpRIbWdIK61XEMKenSlWFF0giXWcOMkxXH4/T1NFlV7/g57MPogu+DD41Y2LNkdZQVaVYWEyvTw3t0pVvgohGNPRSNKV8qR8yzSM5yVe0Ck6SWOk+74SWwBoItjp66LwNQ60JK2Od2+NOSE3+2eG1SkIKL4+q0Uo4NGQgyxblPWIXJZTl14XcaxyXCJr/K913khhw+b+DumTz6TTGg6jMR8oXRFawccmEHL/DN55Y3HfRAwVj/cNIx7I=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.7.12
Release Details
UpdatedNov. 4, 2025, 4:14 p.m.
Changelog

Fixed

  • Viewer Integration: Fixed files() method not storing files list, causing "No files provided, skipping update" error
  • File Loading: Fixed TypeError: Cannot read properties of undefined (reading 'filename') when opening 3D files
  • Static Assets: Fixed 500 error when loading app-color.svg due to route conflicts
  • Route Structure: Changed viewer route from /{fileId} to /f/{fileId} to prevent conflicts with static assets
  • Axes Positioning: Axes helper now positioned at bottom center of models, aligned with grid
  • Axes Scaling: Made axes size dynamic (25% of model's largest dimension, minimum 5 units)
  • Logo Loading: Fixed app logo path in demo scene to use generateUrl() for correct URL resolution

Changed

  • Enhanced files() method in ViewerComponent with fallback logic to create synthetic file from props
  • Simplified PageController by removing unnecessary is_numeric() checks
  • Updated URL structure for better RESTful design: /apps/threedviewer/f/{fileId}
  • Axes now recreate on model load to ensure proper sizing and positioning
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignaturetHcAULDv6Z6JlPEmMcFbBFAPFTScfSULZoxHuFuCtCO965w5/TPzwTm9AAbrvWQlTzOza8VK9le5cP96O8XKoLPU/rUTY0YPL+11rga9rU5c9nNcCiRTKwaha9wnos5/fDxZOhefb9aFojmpf7HsrSmHL+JMrLwaVvp846k4ShSPNbV7cVTqsrwz1C4Vy4JRzGMuSfcAMjxLBC02obtPqVYX4T5s7/QCithiTGI1VmmtMxZM0sG3fkIRf9ouPQ44hpHX7beIm4vBGthPwjhlNpR+aXq9rQd4annpZKtZGfGRX/RDXlFXUWBE/07A+/CBzP9DX9pegUvzvrelj67ADuiRDfxsL3vKN1VGU1rqHi1ZrwE24BzfeGnWgUb+wEBOcM8x8BEc0thH2zbfKAwqjY1h/iH8IjoIkbPPm3mKwQ2b5w2v2aaRRr3qbK3cOLhyzWJBpQFZaahomr9x+/hN5aU9fhr9hMjgPboRadI7rO+V6QtQDobhKlz+6Rdb1mo+Bzk9btyCJ7flqqos07yo/O01o4G/0L0hdw20vYh3WlbeGRWC6W/OBzQmRwT4MWFoHV2mQOYO4Nie4SkFCzs2lT3NWW7I/uCrCPMZDJrLhSk1KiKzctZXjTUalB4DuPHSpq99WjCcf2oPLo6rQ7DJd/sIRSh3tSj8WIlxcWCrSWk=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.7.11
Release Details
UpdatedNov. 4, 2025, 10:58 a.m.
Changelog

Fixed

  • Viewer Integration: Fixed files() method not storing files list, causing "No files provided, skipping update" error
  • File Loading: Fixed TypeError: Cannot read properties of undefined (reading 'filename') when opening 3D files
  • Static Assets: Fixed 500 error when loading app-color.svg due to route conflicts
  • Route Structure: Changed viewer route from /{fileId} to /f/{fileId} to prevent conflicts with static assets

Changed

  • Enhanced files() method in ViewerComponent with fallback logic to create synthetic file from props
  • Simplified PageController by removing unnecessary is_numeric() checks
  • Updated URL structure for better RESTful design: /apps/threedviewer/f/{fileId}
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignaturehK5rTudkrE4neZOI/n/jv+qjY/VfKVkRkouiBK5jBARxwK9e0W8U07ajlvP2+U8q8qwNzjGY77RproUnQIkOlALx3c6V9ufsMaHcpuAR2GAvK84WgqqEM37VSPQrGhLLuZzz4nU5nYmNOsTg+maV0O5XEND29zOdafsJHxpY8mQofXCA0vyLYNLYQtLEAPRBtl3uDQgSSjPGB6kN87VUcqebvVrVim8aa8l7BpDoMiW5j60T7toenQiisu6S4aKMRHCxx7I1cHK/mkGjLzl+/AHpfwWpKCr13StVLzqqlVPc5+SL/yI14XW2JtJARHShE0zBqkARG0yqsFXVTGvLzvAahLuCfIdlied8HFK/NQVmqgLlRAc30xWGq2vcQvpnr9L7GwCkImnM5YeoTqVOJHawhc3wU8FQ56g/imCYgMqwSOegC1BVegdX/XvCMCxhQXEj4OxUxETQ/T1+BWqBBLLbZQQiyyRXw6o/bzpBWJYtDH/XIzFKxJdC7WKfIM6lPmPb7CCc6sJGfEi/Lyv3rTfCjyQj7ioMlB+5sLV5/d+tth6eeY9O6jZsz92/V5byhrtIdYvu4j7IZR2m8+/IpkjmTMnuv18wyU6+unVo8V2hKNLhoWYHJqEQ9Ylx/Rj6tKb4TwsrciMPV+2T38lJK5cS0GZittMNUVAKSUPBSnQ=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.7.10
Release Details
UpdatedNov. 4, 2025, 9:48 a.m.
Changelog

Fixed

  • Dark Theme Support: Fixed slide-out toolbar panel not responding to theme changes
  • Theme Switching: Implemented reactive theme binding using Vue computed properties
  • CSS Integration: Converted base styles to use Nextcloud CSS variables for better theme integration
  • UI Consistency: Toolbar panel now properly switches between Light, Dark, and Auto themes

Changed

  • Improved maintainability by using Nextcloud's standard color system throughout the toolbar
  • Enhanced theme responsiveness with component-level class binding
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureT38bK6V5aDGCGlNZJEV3QCmwYaO21RK3QtifSTQ3O311NOPA+O7ryIjncKIdr/rdN/9ZjeFLqwcxRk2traF5MkhvjRCr3NT5oV5cuMQgmw2Js7MAOLrSXOUkn6b7LpQKesEmzQPqygl2fuqN5qrxILxeWU5xWq3nyoV+G2TzByeLOT9CX8+EH1rzMnJNb/35aFS0kj/fU4V0FHFM3h8KxNDWYVjlJ/tPtq5IFBvICRm6HLCkQ2fEPPXkxP2Z1lpBam6ZGuSbcmo2lb5yQ7Zq3n6rd7FIzkU6r0/xvYF5gY08bwIdtULEpJOEQwp/n9KBR2itV4twQG2QAZFEIMF+EIg4lRzu0vdX8GVDFbirW8YqCX8PXyd+UAm1FfZ4vf8VHQXF7weZgAnvm3crR01GNStlBHl37Zke3z8CHmiYj3ffi4WMwGBT4Gb8f6fxlCOHH/mOlCyA3rtVlI5cHqJGHbdiwgHYX6e+0p5JRWOlecK/HTcVd0Aa5KX57BTcRQXEhGaQqHIbRhWTWwDMesbAyJMtCT72O2eRUqJCnSI+SRSxl/Hh4lHUEnOPx9D2P/03xDEDpO3xoR7tQGN927un6811AS+v+kABFDJQcayHiFTpR28U+WzF1vqS2fktc90NaWwiJuO1/hnQ/H8J6icAF4oxmvArZI2uO1X3CPZMwN8=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32
3D Viewer 1.7.9
Release Details
UpdatedNov. 4, 2025, 8:39 a.m.
Changelog

Added

  • 3D Camera Controller: New circular controller interface for intuitive 3D model navigation
  • Camera Control Methods: Advanced camera manipulation including rotation, zoom, and directional nudging
  • View Snapping: Animated camera transitions to predefined views (Front, Back, Left, Right, Top, Bottom)
  • Controller Persistence: Save and restore controller position and visibility preferences
  • Smooth Animations: Eased camera transitions with customizable duration and easing functions
  • Face Labels: Orientation markers (TOP, BOTTOM, FRONT, BACK, LEFT, RIGHT) on model faces
  • Export Functionality: Export models to GLB, STL, and OBJ formats
  • Camera Projection Toggle: Switch between perspective and orthographic views
  • Progressive Texture Loading: Background texture loading for improved performance
  • Dependency Caching: IndexedDB caching system for faster multi-file model loading
  • Model Statistics Panel: Detailed information about loaded models
  • Help Panel: Comprehensive in-app documentation and controls guide
  • Theme Customization: Enhanced theme switching with RTL support
  • Performance Overlay: Visual performance stats display with real-time monitoring
  • KTX2 Texture Support: GPU texture compression for better performance
Licenses AGPLv3+
Certificate-----BEGIN CERTIFICATE-----
MIIEBzCCAu8CAhLKMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNVBAYTAkRFMRswGQYD
VQQIDBJCYWRlbi1XdWVydHRlbWJlcmcxFzAVBgNVBAoMDk5leHRjbG91ZCBHbWJI
MTYwNAYDVQQDDC1OZXh0Y2xvdWQgQ29kZSBTaWduaW5nIEludGVybWVkaWF0ZSBB
dXRob3JpdHkwHhcNMjUxMTA0MDgxMDEzWhcNMzYwMjEwMDgxMDEzWjAXMRUwEwYD
VQQDDAx0aHJlZWR2aWV3ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDnE42wyWoV2dJM9P5a0wX1fka0RV64J/zwc6phoNTGOt6l2KulOVkwjhiGstJN
ZDtJ56Zc3WUYReEZUi7QLkJjb7t1Tyorz24gFDytMxPAzOQ0WICSY3OBEJzPxXzB
lq2XM+EXuyS9en2VRbjtA6BuYDs0leF8Ucm5zVAHNAHPrlWCHeiHHm6qwtYPlRy7
6GLmdgLA9/lOK1cL6leMPZRv5ths4tsda/nRfnXJp8i1n29+PrqSx1U1V26z1Oyg
4W+kYmw/CVQPw3F0dYsmdWG5Esp9WKP4LkhRuIvqbt5AWB9Ymb/zNXQgMcZBo46e
Lf9jMYH5WWnXsuJV6kypn4pkyhjyy8dGsVGPR/O/YafVe5xqTYUKVxyKR5v8pxoB
NqPTKKCe1dyhPrb5aUibc4MIRVq7YNKL7cHqtt0Lgii0AtDoXlFxo+o4iNhl85id
z8aBcDcrNpAlWHvEqqMeuzrdm5wbWdFS9PLzjsjTH2HVLJwWzNY50JIJfgECBrRm
pgx2xcE8artReZUyvn4N7OhQcIMlbiJJD3GAqo+royLWk+saObAMewc8tL9WCDDT
zVliibBIC4cS8TNxeWJBCDE31VRcchUpnOIAl6Ks4BqAjIZWOHywJ1LDZMjYByBK
0kJ3YbbcJ8G4wvhllp+FDeK+72Yaf2W/vXeAxe5RT14XAQIDAQABMA0GCSqGSIb3
DQEBCwUAA4IBAQBr2FhVbBHoSFfBGsLfBQEwVfjBGUb4gnzMmqHHMcFwrQiWNejZ
oK7KqUu28cuU6BjJ5/K2AZBW3/eU5zcPlv36G+VGYfVSsmT50G38fXyP4rCxICdL
0hZnKSJU80YLCPy2uSPJ6os3gcIp7OEkRLukU/Be8GEVZAlX5dVds3ve7GFA1K/z
FI9AMqwGnueXbncuTDo7QGd268qYNNWh/jYloQ7sdW1NCwKGvpPXjB80rw5briXk
Zzf7xuMLAobzRxY23NlBamP7wdv355TWXlrFBkaKdF4+aSzELf9LpXzDsQ6SaDI4
Mol4XeYOOXOL40adta2oG9/2k3GKNRfSh5Qe
-----END CERTIFICATE-----
SignatureT4jr3f8pu++HPy93L1HdiayTsqKV8PwgIw7jkye4TkqYM7wBuBsK6qv/TXwuZElOm9hzBEVH/MnuFoRl2QXPxurhZLvu918h0rDnTIjfRNMC2gIVFI8JLneLq8ya+m9lKGNLXEodRAhQ3pGn97cuSFzff+iGhQOFkojIvbWM4HbSQFq6pfF3/ZYjUCt5BhRIHdPkk+mzwjpVaniq98gh4XS3AMYqs4p2n7vysSGjAO8hZrDdGUJGxBlz1amgeUpdiGOpTwI4FyT2vbxcmHcMVwZTQyXoYZ/Ux70JZp98nz1H1kKqIoDxzZSRmetrm23Pzn+k440rHQUSjuIa/p6I6w8nGG25M0kjB46lacCtbUlR6Rrrj6SNwFITde5Rr87HP2R/ILqI5MCC73SebBxcdY/IXw7xHjUiBJTlrOmPi1ppktirZnOsmSR2Sa/yE81zrYWJ2HidTbxEGpJDZBIiwOaBCYh6nwQ51PG1z4mxgJE4G+7lMZ/bpu5UaJihys2WcoBhPxrGNeoLoEN+D1JiaOU1C974Wwncz1/BobA08FSx+rzXCnRNSQWbBapz3J6MYT5TwChku40FeqGR2KJm+v2pYgm8K/Eepieubi61tD9St1exw3AjBiJ2/dKOezNb8ZHFcoWn2bxCZc4rzuBUO0tJSrjmbW5dcysusajrvMs=
Signature digestsha512
Dependencies
Required Nextcloud versions >=30.0.0,<33.0.0
Minimum Integer bits32