pstream is dead; long live pstream taciturnaxolotl.github.io/pstream-ng/
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

scroll to top when settings section changes

Pas 1307ace7 8d8d4659

+20 -17
+18 -17
src/pages/Settings.tsx
··· 54 54 onSearchUnFocus: (newSearch?: string) => void; 55 55 selectedCategory: string | null; 56 56 setSelectedCategory: (category: string | null) => void; 57 + onCategoryChange?: (category: string | null) => void; 57 58 }) { 58 59 const { className } = props; 59 60 const { t } = useTranslation(); ··· 105 106 <SidebarPart 106 107 selectedCategory={props.selectedCategory} 107 108 setSelectedCategory={props.setSelectedCategory} 109 + onCategoryChange={props.onCategoryChange} 108 110 searchQuery={props.searchQuery} 109 111 /> 110 112 <div className={className}>{props.children}</div> ··· 168 170 export function SettingsPage() { 169 171 const [searchQuery, setSearchQuery] = useState(""); 170 172 const [selectedCategory, setSelectedCategory] = useState<string | null>(null); 171 - const prevCategoryRef = useRef<string | null>(null); 172 173 const backendChangeModal = useModal("settings-backend-change-confirmation"); 173 174 const [pendingBackendChange, setPendingBackendChange] = useState< 174 175 string | null ··· 271 272 }; 272 273 }, []); 273 274 274 - // Scroll to top when category changes (but not on initial load or when searching) 275 - useEffect(() => { 276 - if ( 277 - prevCategoryRef.current !== null && 278 - prevCategoryRef.current !== selectedCategory && 279 - !searchQuery.trim() 280 - ) { 281 - // Only scroll to top if we're actually switching categories (not initial load) 282 - // Use requestAnimationFrame to ensure DOM has updated 283 - requestAnimationFrame(() => { 284 - window.scrollTo({ top: 0, behavior: "smooth" }); 285 - }); 286 - } 287 - prevCategoryRef.current = selectedCategory; 288 - }, [selectedCategory, searchQuery]); 289 - 290 275 const { t } = useTranslation(); 291 276 const activeTheme = useThemeStore((s) => s.theme); 292 277 const setTheme = useThemeStore((s) => s.setTheme); ··· 380 365 setSearchQuery(newSearch); 381 366 } 382 367 }, []); 368 + 369 + const handleCategoryChange = useCallback( 370 + (category: string | null) => { 371 + if (searchQuery.trim()) return; 372 + const sectionId = category ?? "settings-account"; 373 + setTimeout(() => { 374 + scrollToElement(`#${sectionId}`, { 375 + behavior: "smooth", 376 + block: "start", 377 + offset: 120, // Account for fixed search bar 378 + }); 379 + }, 100); // Wait for section to render after tab switch 380 + }, 381 + [searchQuery], 382 + ); 383 383 384 384 const appLanguage = useLanguageStore((s) => s.language); 385 385 const setAppLanguage = useLanguageStore((s) => s.setLanguage); ··· 983 983 onSearchUnFocus={handleSearchUnFocus} 984 984 selectedCategory={selectedCategory} 985 985 setSelectedCategory={setSelectedCategory} 986 + onCategoryChange={handleCategoryChange} 986 987 className="space-y-28" 987 988 > 988 989 {(searchQuery.trim() ||
+2
src/pages/parts/settings/SidebarPart.tsx
··· 11 11 export function SidebarPart(props: { 12 12 selectedCategory: string | null; 13 13 setSelectedCategory: (category: string | null) => void; 14 + onCategoryChange?: (category: string | null) => void; 14 15 searchQuery: string; 15 16 }) { 16 17 const { t } = useTranslation(); ··· 102 103 // Set the selected category when clicking a sidebar link 103 104 // null means "All Settings" - show all sections 104 105 props.setSelectedCategory(id); 106 + props.onCategoryChange?.(id); 105 107 }, 106 108 [props], 107 109 );