From 4b5b9b2cb34457f60ed4a393b05c43ad89844ae5 Mon Sep 17 00:00:00 2001 From: indifferentketchup Date: Sat, 16 May 2026 05:55:47 +0000 Subject: [PATCH] feat(mobile): pull-to-refresh sidebar list - usePullToRefresh: hand-rolled hook. Records startY only when the scroll container is at scrollTop=0 to avoid hijacking mid-scroll pulls. Tracks downward delta on touchmove; fires onRefresh on touchend if delta >= 80px threshold. Holds the refreshing state for 600ms minimum so the action feels intentional. - ProjectSidebar: wires usePullToRefresh(() => retry()) on the nav element, mobile-only. A status indicator above the nav grows with pullDist (max 80px) and cycles 'Pull to refresh' -> 'Release to refresh' -> 'Refreshing...'. retry() is from useSidebar and refetches GET /api/sidebar. Co-Authored-By: Claude Opus 4.7 (1M context) --- apps/web/src/components/ProjectSidebar.tsx | 27 +++++++- apps/web/src/hooks/usePullToRefresh.ts | 77 ++++++++++++++++++++++ 2 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 apps/web/src/hooks/usePullToRefresh.ts diff --git a/apps/web/src/components/ProjectSidebar.tsx b/apps/web/src/components/ProjectSidebar.tsx index 9d26f2c..928c1a7 100644 --- a/apps/web/src/components/ProjectSidebar.tsx +++ b/apps/web/src/components/ProjectSidebar.tsx @@ -22,6 +22,7 @@ import { api } from '@/api/client'; import { useSidebar } from '@/hooks/useSidebar'; import { useSidebarDrawer } from '@/hooks/useSidebarDrawer'; import { useViewport } from '@/hooks/useViewport'; +import { usePullToRefresh } from '@/hooks/usePullToRefresh'; import type { SidebarProject } from '@/api/types'; import { giteaUrlFor } from '@/lib/projectUrls'; import { cn } from '@/lib/utils'; @@ -199,6 +200,7 @@ export function ProjectSidebar() { const { open: drawerOpen } = useSidebarDrawer(); const { isMobile } = useViewport(); + const pull = usePullToRefresh(() => retry(), { enabled: isMobile }); // On mobile the sidebar is a slide-in drawer (fixed, z-40, off-screen by // default). On desktop it sits inline as a normal flex column. The @@ -223,7 +225,30 @@ export function ProjectSidebar() { -