diff --git a/.gitignore b/.gitignore index ec68f8e..2fe2140 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,7 @@ dist-ssr/ .DS_Store # Environment +.env .env.local .env.*.local diff --git a/backend/app/routers/library.py b/backend/app/routers/library.py index 530f449..9a2b6d0 100644 --- a/backend/app/routers/library.py +++ b/backend/app/routers/library.py @@ -18,6 +18,7 @@ from sqlalchemy.ext.asyncio import AsyncSession from app.database import get_db from app.models import Photo +from app.models.folders import SourceRoot from app.models.user import User from app.dependencies import get_current_user @@ -105,6 +106,13 @@ async def get_library_stats( size = (await db.execute(select(func.sum(Photo.file_size)).where(owner))).scalar() or 0 + # Source root directories (active ones only). + roots = ( + await db.execute( + select(SourceRoot.path).where(SourceRoot.is_active.is_(True)).order_by(SourceRoot.path) + ) + ).scalars().all() + return { "all_photos": all_photos_count, "rated": rated_count, @@ -116,6 +124,7 @@ async def get_library_stats( "total_videos": video_count, "total_size": size, "total_size_gb": round(size / (1024**3), 2) if size else 0, + "source_dirs": roots, } @router.post("/scan") diff --git a/docker-compose.yml b/docker-compose.yml index dad11c5..816c580 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -48,7 +48,7 @@ services: - REDIS_URL=redis://redis:6379 - CELERY_BROKER_URL=redis://redis:6379 - CELERY_RESULT_BACKEND=redis://redis:6379 - - PHOTO_DIRS=${PHOTO_DIRS:-/photos} + - PHOTO_DIRS=/photos - ALLOWED_ORIGINS=${ALLOWED_ORIGINS:-*} - SECRET_KEY=${SECRET_KEY:-mulita-dev-secret-change-me} - ACCESS_TOKEN_EXPIRE_MINUTES=${ACCESS_TOKEN_EXPIRE_MINUTES:-60} @@ -104,7 +104,7 @@ services: - REDIS_URL=redis://redis:6379 - CELERY_BROKER_URL=redis://redis:6379 - CELERY_RESULT_BACKEND=redis://redis:6379 - - PHOTO_DIRS=${PHOTO_DIRS:-/photos} + - PHOTO_DIRS=/photos - LOG_LEVEL=${LOG_LEVEL:-INFO} - TZ=${TZ:-UTC} # NullPool — see app/database.py for rationale. @@ -138,7 +138,7 @@ services: - REDIS_URL=redis://redis:6379 - CELERY_BROKER_URL=redis://redis:6379 - CELERY_RESULT_BACKEND=redis://redis:6379 - - PHOTO_DIRS=${PHOTO_DIRS:-/photos} + - PHOTO_DIRS=/photos - LOG_LEVEL=${LOG_LEVEL:-INFO} - TZ=${TZ:-UTC} - MULITA_CELERY_WORKER=1 @@ -170,7 +170,7 @@ services: - REDIS_URL=redis://redis:6379 - CELERY_BROKER_URL=redis://redis:6379 - CELERY_RESULT_BACKEND=redis://redis:6379 - - PHOTO_DIRS=${PHOTO_DIRS:-/photos} + - PHOTO_DIRS=/photos - LOG_LEVEL=${LOG_LEVEL:-INFO} - TZ=${TZ:-UTC} - MULITA_CELERY_WORKER=1 diff --git a/frontend/src/components/dialogs/SettingsDialog.tsx b/frontend/src/components/dialogs/SettingsDialog.tsx index 0f2bd23..2c8f92d 100644 --- a/frontend/src/components/dialogs/SettingsDialog.tsx +++ b/frontend/src/components/dialogs/SettingsDialog.tsx @@ -258,6 +258,17 @@ export function SettingsPage() { /> + {(libStats?.source_dirs?.length ?? 0) > 0 && ( +
+ Source folders +
+ {libStats!.source_dirs.map((dir: string) => ( +
{dir}
+ ))} +
+
+ )} + {/* Inline scan progress. Rendered as a full-width sub-card when a scan is active so the user sees the same info they'd get from the floating widget without leaving diff --git a/frontend/src/services/api.ts b/frontend/src/services/api.ts index 8ac7c19..2e62624 100644 --- a/frontend/src/services/api.ts +++ b/frontend/src/services/api.ts @@ -625,6 +625,7 @@ export interface LibraryStats { total_videos: number total_size: number total_size_gb: number + source_dirs: string[] } // Heaps API