Commit Graph

58 Commits

Author SHA1 Message Date
Edouard Vanbelle 42510d94f3 POC(nextcloud): add chroot on nextcloud
Bring chroot to nextcloud capability: login on Nextcloud via username="{user}~{folder-uuid}
    Doing a such login will chroot the folder folder-uuid

    If user has several folder as root (parent=None), the login flow will request which
    folder user want to chroot
2026-06-19 16:06:38 +02:00
Claude 6314fa6b1c feat(people): add People tab frontend for face clusters
Adds the client side of Phase 2 (People). A new "People" tab in the
Photos sub-navigation lists identity clusters from GET /api/people and
drills into a person's photos using the existing photos lightbox.

- people.js: peopleView with list/drill-in/rename, reusing .photos-grid
  tiles and photosLightbox; rename via Modal.prompt + PATCH /api/people/{id}
- people.css: person grid, circular avatars, single-person header,
  loading/empty states — all design tokens, no raw colors
- places.js: People tab wired into the Moments|Places sub-nav, revealed
  only when GET /api/people is reachable (capability probe); _switchTab
  now toggles three views
- index.html: load people.css + people.js
- en.json: photos.tab_people + people.* labels (other locales fall back
  to English via i18n)

The tab stays hidden unless OXICLOUD_ENABLE_FACES is on (the API 404s
otherwise), so this is inert by default.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JW6ghFMDtnRYuYNzZhb47M
2026-06-19 11:58:23 +00:00
Claude 513b6224b4 feat(places): photo map view (MapLibre + PMTiles, Approach A)
Adds a Places tab to the Photos section: a self-hosted MapLibre GL map of
the user's geotagged photos.

- places.js: lazy-loads vendored MapLibre + pmtiles.js on first open; draws
  the server-aggregated clusters (GET /api/photos/geo) as HTML thumbnail
  markers (no glyphs/sprites, no client-side clustering); pan/zoom refetches
  for the new viewport; click a cluster to zoom in, or a single photo to
  open it in the lightbox.
- Optional vector basemap read directly from /basemaps/basemap.pmtiles over
  HTTP Range (label-light Protomaps style, light/dark aware); falls back to
  a themed background when no basemap is present. ODbL attribution shown.
- "Moments | Places" sub-nav wired into the Photos section.
- enable_places now defaults on, since the route + UI are ready.

No new backend serving code: tower-http ServeDir already serves static/
with Range, so the .pmtiles basemap is just a static file.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JW6ghFMDtnRYuYNzZhb47M
2026-06-19 11:17:56 +00:00
Claude ca1a8cb8b8 feat(photos): lightbox zoom/pan, mobile swipe & EXIF info panel
- Photos zoom via wheel, double-click and two-finger pinch (1–5x) with
  drag-to-pan; a touch swipe navigates prev/next when not zoomed.
- A new info button toggles a panel showing date, size, dimensions, camera
  and GPS coordinates (resolving the old geoloc TODO), pulled from
  /api/files/{id}/metadata.
- Zoom/pan state resets on every item change and on close.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JW6ghFMDtnRYuYNzZhb47M
2026-06-19 10:25:33 +00:00
Claude 75ee9b7cc4 feat(photos): justified (aspect-preserving) layout option
Adds a Grid/Justified toggle to the photos toolbar. Justified mode packs
tiles into Flickr-style rows scaled to the container width using each
photo's real aspect ratio (from the new /api/photos width/height, falling
back to 1:1 when missing). It composes with the virtualized renderer:
per-group materialization and the off-screen spacer height estimates are
both layout-aware. The choice persists in localStorage.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JW6ghFMDtnRYuYNzZhb47M
2026-06-19 10:21:00 +00:00
Claude 824df4d421 feat(photos): keyboard a11y + shift-click range selection
- Tiles are focusable (tabindex / role=button / aria-label) with a
  :focus-visible ring; Enter opens the lightbox (or toggles in selection
  mode), Space toggles selection.
- Shift-click extends the selection from the last anchor across the
  timeline; the range is tracked in the selection Set so it spans
  dematerialized (off-screen) groups, with visible tiles updated at once.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JW6ghFMDtnRYuYNzZhb47M
2026-06-19 10:01:19 +00:00
Claude 081b2b68d8 perf(photos): virtualize the timeline to bound DOM node count
The photos timeline rendered every tile into the DOM and grew it
unbounded on infinite scroll, degrading on large libraries. Each
date-group is now a <section> whose grid is materialized (tiles
inserted) only while near the viewport and dematerialized (emptied,
height frozen as a spacer) once it scrolls away, driven by an
IntersectionObserver rooted on the scroll container. DOM nodes stay
bounded by a few screens regardless of library size.

- Grouping (day/month/year), infinite scroll, multi-select, video
  thumbnails and fade-in are all preserved.
- Selection state and the video-thumbnail cache survive the
  materialize/dematerialize cycle.
- Falls back to full rendering when IntersectionObserver is unavailable.
- Spacer heights are estimated from grid geometry and re-estimated on
  resize.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JW6ghFMDtnRYuYNzZhb47M
2026-06-19 09:30:41 +00:00
Bradley Nelson 4427b1613b plugin logging 2026-06-16 23:00:23 -06:00
Edouard Vanbelle 5eb4d9117c chore(front): apply biome formatter 2026-06-15 16:30:38 +02:00
DioCrafts 81a93a489b feat: photo/video capture-date pipeline + premium UI/UX overhaul
Backend — Photos timeline now groups by real capture date instead of upload time. New MediaMetadataService (FileLifecycleHook) extracts EXIF DateTimeOriginal from images and container creation_time from videos (mov/mp4/mkv) via nom-exif, timezone-correct (OffsetTimeOriginal), persisting captured_at so the existing media_sort_date trigger takes over. Adds POST /admin/photos/metadata/reextract to backfill existing media. Falls back to upload date when no embedded date exists.

Frontend — premium grid cards: combined metadata line (relative date · size, owner avatar when shared), custom selection checkbox with a clear checked state, uniform full-width 4:3 thumbnail tiles independent of filename length, centered file-type icons, and a hit-test fix so checkbox/star/kebab clicks reach the controls (the decorative thumbnail no longer captures pointer events). Notification messages internationalised across all 16 locales. Broader polish: design tokens, a11y/focus-visible states, brand + PWA assets.

Chore — bump semver-compatible dependencies (cargo upgrade); add nom-exif 3.6.1.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 00:24:27 +02:00
Edouard Vanbelle 64d081ad0b feat(external): permit login via email (magic link) 2026-06-03 00:31:59 +02:00
Edouard Vanbelle d03b9474c6 feat(smtp): add a precious SMTP test for admin only 2026-06-03 00:31:59 +02:00
Edouard Vanbelle ea83891a61 feat(trash): move trash API to normalized version (with cursor, orderBy) + normalize Trash section to existing components
normalize also component to format badges (expiry, role, etc)
2026-05-30 00:49:32 +02:00
Edouard Vanbelle 6e5c5edd85 chore(ui): apply biome formatter 2026-05-29 13:15:31 +02:00
Edouard Vanbelle ae4fb7603a refactor(front): remove dead code (old Shared section) 2026-05-29 13:13:23 +02:00
Edouard Vanbelle 63722c868e feat(myshares): new version of myshares sections, supporting grants Users + Tokens 2026-05-29 13:12:59 +02:00
Edouard Vanbelle 1cd934d594 refactor(resourceList): move grid/list view into a resourceList component, purpose normalize on all sections views 2026-05-28 00:15:04 +02:00
Edouard Vanbelle b0c5e7827e feat(user-avatar): users can now edit there image (image is taken from OIDC picture) 2026-05-27 11:29:33 +02:00
Edouard Vanbelle 60d53ea779 feat(ui): add section 'Shared with me' 2026-05-25 22:47:32 +02:00
Edouard Vanbelle 191f725199 feat(ui/trash): show original file path in tooltip on mouse over + display thumbnails
* fix: permission also check elements trashed elements
 * tested manually
 * all automated tests ok
2026-05-22 02:26:11 +02:00
Edouard Vanbelle 3c3be9b930 feat(share): permit scrolldown+ keep header sticky on the top
this solve issue raised on #253
2026-05-19 22:52:46 +02:00
abnvle cb454d8aa2 feat(share-public): folder gallery UI in share.html
Replaces the placeholder with a gallery rendered by publicShare.js
against the new public endpoints.

- Grid / list view toggle (localStorage)
- Image thumbs and lazy-loaded video posters
- Click-to-open lightbox with Esc / arrow nav
- ZIP download for the current folder
- Subfolder navigation via URL hash, History API for back

Adds five overlay-related tokens to base/variables.css for the
lightbox surface (on-overlay text, translucent button, drop shadow).

share.html itself only adds an icons.js module import and empties
#share-folder for JS to populate.
2026-05-06 00:01:08 +02:00
Edouard Vanbelle f5dade1551 refactor(ui): css: use of variables colors only 2026-04-26 01:16:40 +02:00
Edouard Vanbelle 6e3d87c27e style(front): correct format 2026-04-15 00:15:53 +02:00
Diocrafts cd3733b459 feat: pluggable storage backends (S3, Azure, local) with admin UI
Implement 4-phase external storage backends architecture:

Phase 1 - Foundation:
- BlobStorageBackend trait (application/ports/blob_storage_ports.rs)
- LocalBlobBackend: extracted all tokio::fs ops from DedupService
- S3BlobBackend: AWS SDK with custom endpoint support (MinIO, R2, B2)
- DedupService refactored to use Arc<dyn BlobStorageBackend>

Phase 2 - Admin Panel:
- StorageSettingsService with DB persistence + env override
- Storage tab in admin panel (backend selector, S3 form, provider presets)
- GET/PUT/POST endpoints for storage settings + connection test
- i18n keys (en/es) and BEM CSS

Phase 3 - Migration:
- MigrationBlobBackend decorator (dual-read: target-first + source fallback)
- Background migration job with parallel transfers + progress tracking
- Migration UI (progress bar, ETA, pause/resume/verify/complete)
- 6 admin API endpoints for migration lifecycle

Phase 4 - Enterprise Extras:
- CachedBlobBackend: LRU disk cache for remote backends
- EncryptedBlobBackend: AES-256-GCM at-rest encryption
- AzureBlobBackend: Azure Blob Storage support
- RetryBlobBackend: exponential backoff for transient errors
- Decorator composition in DI: retry → encryption → cache

All 223 tests passing, clippy clean, fmt verified.
2026-04-14 21:33:38 +02:00
Edouard Vanbelle d01b2c6ec4 refactor(css): use variable rather direct color 2026-04-14 13:33:51 +02:00
Edouard Vanbelle 2733542bce refactor(css): dark theme: remove and merge specific cases 2026-04-13 13:26:38 +02:00
Edouard Vanbelle 4dff552299 refactor(css): use 1 global declaration for scrollbar 2026-04-13 13:26:38 +02:00
Edouard Vanbelle ce207ebad1 refactor(css): merge profile + admin dark style 2026-04-13 13:26:38 +02:00
Diocrafts 1dbe7e4553 fix: resolve all biome ci errors and warnings
- Format all 14 locale JSON files (2-space → 4-space indent per biome config)
- Fix publicShare.js: arrow functions, template literals, optional chaining,
  remove redundant 'use strict', remove unused formatSize function
- Fix music.js: template literal, unused _trackId parameter
- Fix contextMenus.js, fileOperations.js, fileSharing.js: unused parameters
- Fix auth.js, music.css, share-public.css: formatting (biome format --write)
- Remove unused biome-ignore suppression comments in cards.css and reset.css
- Remove empty .share-state block in share-public.css
- Disable noDescendingSpecificity and noImportantStyles rules in biome.json
  (intentional CSS patterns for utility classes and theme overrides)
2026-04-12 02:13:08 +02:00
Diocrafts edf1e66989 feat: add public share page with download support (#253)
Share links now point to /s/{token} (was /api/s/{token}) and render a
proper HTML page instead of raw JSON.

Changes:
- static/share.html: standalone public share page
- static/css/views/share-public.css: share page styles
- static/js/views/public/publicShare.js: client-side logic that fetches
  share metadata via /api/s/{token}, handles password-protected shares,
  and renders file download / folder info
- build.rs: include share.html in the HTML embed pipeline
- web/mod.rs: serve /s/{token} route (unauthenticated)
- share_dto.rs: generate URLs as /s/{token} instead of /api/s/{token}
- share_handler.rs: new download_shared_file() handler that validates the
  share token and streams file content without requiring authentication
- routes.rs: mount GET /api/s/{token}/download (public, uses AppState)
2026-04-12 01:51:30 +02:00
Diocrafts f08cffc0e8 feat: add VitePress docs site, music file picker modal, Dockerfile optimization, i18n keys for 14 locales
- Add docs/ with VitePress site (19 pages): guide, config, architecture, FAQ
- Add GitHub Actions workflow for auto-deploy to GitHub Pages
- Replace music 'Add Tracks' upload picker with in-app audio file browser modal
- Add music picker CSS styles with dark theme support
- Add missing i18n keys (search_audio, no_audio_files, etc.) to all 14 locales
- Optimize Dockerfile: shared base stage, COPY --chmod, consolidated RUN, HEALTHCHECK
- Improve README: docs links, updated stats (222+ tests, 14 languages), feature status
2026-04-11 20:58:34 +02:00
Dionisio Pozo 1bb65e6448 Merge pull request #275 from EdouardVanbelle/refactor/css-variables
refactor(css): maximize usage of variables (1st part)
2026-04-11 20:49:52 +02:00
Edouard Vanbelle 5f87dbf612 fix(device-verify): includes main.css + rename class to avoid collision 2026-04-11 18:58:38 +02:00
Edouard Vanbelle 56a067ee96 refactor(css): apply biome format on css 2026-04-11 18:39:03 +02:00
Edouard Vanbelle 94b36e41e0 refactor(css): maximize usage of variables (1st part, to simplify CSS & style)
note: there is still work to do, but has there are risks to conflict I prefer to commit this first part now
2026-04-11 18:39:03 +02:00
Edouard Vanbelle c7eeb734d7 style(css+js): apply biome formatter 2026-04-11 18:20:43 +02:00
Diocrafts 3ce8ec25d6 feat(music): complete music UI overhaul - bugs, UX, missing features & styling
- Fix dead buttons (fa-edit/fa-share → fa-pen/fa-share-alt matching icon registry)
- Fix volume icon, shuffle bias, queue removal, repeat-one CSS
- Replace native prompt/confirm/alert with Modal system
- Add click-to-select, dblclick-to-play, playback error notifications
- Add loading indicators, success toasts, close player button
- Implement remove track from playlist (DELETE endpoint)
- Implement drag & drop track reorder (PUT reorder endpoint)
- Implement manage shares dialog (GET/DELETE shares endpoints)
- Implement cover art upload & display (cover_file_id in UpdatePlaylistDto)
- Implement public/private toggle (is_public in UpdatePlaylistDto)
- Mount get_audio_metadata route in backend routes.rs
- Redesign empty state: full-width centered onboarding when 0 playlists
- Move create button into sidebar header as compact + button
- Add music.css to build.rs production CSS bundle
- Add 16+ i18n keys in en.json and es.json
- Add CSS for drag handles, track remove, cover overlay, shares dialog, public badge
2026-04-11 10:59:01 +02:00
Andrey Tkachenko da066f47fa Music Player & Playlist Manager 2026-04-08 15:14:03 +03:00
Edouard Vanbelle 1ce29c101d style: apply biome CSS/JS format 2026-04-08 00:09:27 +02:00
Dionisio 4c796aaf61 fix(ui): resolve hidden class vs style.display conflict, polish toggle buttons
style.display='block'. All panel show/hide now uses classList.
- Fix admin badge/panel not showing in user menu (same root cause).
- Fix profile page main-content/auth-error panels (same root cause).
- Add hidden class to admin-setup-panel in login.html for consistency.
- Remove redundant .admin-setup-panel{display:none} CSS rule.
- Polish view toggle buttons: tighter gap, smaller size, subtler shadow.
2026-04-05 00:51:17 +02:00
Edouard Vanbelle a466a6473d refactor(files): merge grid and list builder, use CSS only to switch between views 2026-04-04 17:21:44 +02:00
Edouard Vanbelle badf35f08f chore: remove all executable attributes on non bash files 2026-04-01 23:14:42 +02:00
BillionClaw 5eb7b31740 fix(inline-viewer): add download progress bar for files >2GB
Add download progress tracking to createBlobUrlViewer to fix incorrect
progress display for large files. Changes:

- Add xhr.onprogress handler to track download bytes
- Use 64-bit float division to avoid 32-bit integer overflow
- Show progress bar UI for files >10MB with percentage
- Add CSS styles with dark theme support

The progress calculation now correctly handles files larger than 2GB
by using JavaScript's native double-precision floats instead of
operations that might truncate to 32-bit integers.

Fixes #82
2026-03-18 11:37:42 +08:00
Diocrafts df336da679 feat(frontend): i18n expansion, admin/profile i18n, grid/list view fix, empty state
- Add 5 new locales (hi, ar, ru, ja, ko) — now 14 total
- Admin panel: 117 i18n keys, confirm modal, animated tabs, no inline handlers
- Profile page: 58 i18n keys with data-i18n attributes
- Fix i18n safeT() shadowing bug and translationsLoaded timing
- Fix grid/list view: list header no longer shows in grid mode on login
- Fix classList.toggle hidden sync for view switching across all nav functions
- Revert .hidden important that broke login page rendering
- Add files empty state (no_files + empty_hint) with translations
- Fix language selector dropdown scroll and styling
- Fix admin panel scroll with sticky tabs
2026-03-09 00:08:34 +01:00
Diocrafts 54ce2d085a style: apply card border/shadow style from Archivos to Fotos tiles
- photo-tile: border-radius 4px → 12px, add 2px solid border + box-shadow
- hover: translateY(-2px) elevation effect matching file-card
- selected: border-color + background tint instead of outline
- grid gaps: 4px → 12/14/10px for daily/monthly/yearly to breathe
2026-03-07 18:34:16 +01:00
Dionisio 9aa35aa0ea quick fix 2026-03-06 13:18:36 +01:00
Jared Wolff 6a84a5c44e fix(photos): fix SQL type mismatch, pagination panic, missing icons, and add day/month/year grouping
- Fix photos endpoint 500: remove ::uuid cast on user_id WHERE clause (VARCHAR column)
- Fix pagination underflow panic when total_pages is 0
- Add missing 'images' and 'play' icons to SVG icon registry
- Add day/month/year grouping toggle with localStorage persistence
- Improve grid spacing and group header styling per mode
- Add i18n translations for grouping labels (all 9 locales)
2026-03-05 17:32:28 -05:00
Jared Wolff 53e4f5afe6 feat(photos): add Photos timeline view with lightbox and infinite scroll
Backend: new GET /api/photos endpoint with cursor-based pagination that
queries image/video files sorted by EXIF captured_at (falling back to
created_at), joining file_metadata for sort dates.

Frontend: dense photo grid grouped by day with lazy-loaded thumbnails,
IntersectionObserver infinite scroll, multi-select with batch
download/delete, and a full-screen lightbox with prev/next navigation,
EXIF metadata display, and download/favorite/delete toolbar.

Includes navigation wiring, CSS (with dark theme), and i18n translations
for all 9 locales.
2026-03-05 17:32:28 -05:00
Jared Wolff 633c1bbe97 fix(admin): fix invisible modals and add missing button icons
- Add hidden class to quota, create-user, and reset-password modal divs
- Override opacity:0 from modals.css with opacity:1 in admin.css
- Add crown and ban SVG icons to icon registry for toggle-role and
  deactivate buttons
2026-03-05 17:20:07 -05:00