From 198bdc69e2c8dd90df89fb0fd5a604d8fcf20bb8 Mon Sep 17 00:00:00 2001 From: ilia Date: Tue, 4 Aug 2026 21:37:33 -0400 Subject: [PATCH] Sprint B: mobile filters, touch actions, skeleton grid, progressive viewer. --- scripts/deploy-viewer.sh | 7 +- viewer-frontend/app/HomePageContent.tsx | 13 +- viewer-frontend/components/PhotoGrid.tsx | 10 +- .../components/PhotoViewerClient.tsx | 35 +++- .../components/search/CollapsibleSearch.tsx | 198 ++++++++++++++---- 5 files changed, 203 insertions(+), 60 deletions(-) diff --git a/scripts/deploy-viewer.sh b/scripts/deploy-viewer.sh index 8a532af..ad7f44e 100755 --- a/scripts/deploy-viewer.sh +++ b/scripts/deploy-viewer.sh @@ -20,9 +20,10 @@ npm run build cd "$ROOT" if pm2 describe punimtag-viewer >/dev/null 2>&1; then - pm2 restart punimtag-viewer --update-env -else - pm2 start ecosystem.config.js --only punimtag-viewer + # Recreate so script-args / NODE_ENV changes in ecosystem.config.js take effect. + pm2 delete punimtag-viewer fi +pm2 start ecosystem.config.js --only punimtag-viewer +pm2 save echo "Viewer deployed (next start). Logs: pm2 logs punimtag-viewer --lines 30" diff --git a/viewer-frontend/app/HomePageContent.tsx b/viewer-frontend/app/HomePageContent.tsx index 8acea85..6c6c23e 100644 --- a/viewer-frontend/app/HomePageContent.tsx +++ b/viewer-frontend/app/HomePageContent.tsx @@ -1044,7 +1044,7 @@ export function HomePageContent({ initialPhotos, people, tags }: HomePageContent onDownloadSelected={handleDownloadSelected} onToggleSelectionMode={handleToggleSelectionMode} /> -
+
{loading ? ( -
- +
+
+ {Array.from({ length: 15 }).map((_, i) => ( +
+ ))} +
) : ( <> diff --git a/viewer-frontend/components/PhotoGrid.tsx b/viewer-frontend/components/PhotoGrid.tsx index 3906461..e03f521 100644 --- a/viewer-frontend/components/PhotoGrid.tsx +++ b/viewer-frontend/components/PhotoGrid.tsx @@ -665,7 +665,7 @@ export function PhotoGrid({ +
+ {showClose && onClose && ( + + )} + +
) : (
)}
- - {/* Expanded Filter Panel */} {isExpanded && ( -
- -
+
{children}
)} -
+ ); } +export function CollapsibleSearch({ people, tags, filters, onFiltersChange }: CollapsibleSearchProps) { + const [isExpanded, setIsExpanded] = useState(true); + const [mobileOpen, setMobileOpen] = useState(false); + + const hasActiveFilters = + filters.people.length > 0 || + filters.tags.length > 0 || + !!filters.dateFrom || + !!filters.dateTo || + (filters.mediaType && filters.mediaType !== 'all') || + filters.favoritesOnly === true; + + const badgeCount = filterBadgeCount(filters); + + const panel = ( + { + onFiltersChange(next); + }} + /> + ); + + return ( + <> + {/* Mobile: open filters drawer */} +
+ +
+ + {/* Desktop sidebar */} +
+ setIsExpanded((v) => !v)} + hasActiveFilters={hasActiveFilters} + badgeCount={badgeCount} + > + {panel} + +
+ + {/* Mobile drawer */} + {mobileOpen && ( +
+ +
+
+
+ )} + + ); +}